`).join('');
}
function updateUI() {
tabs.forEach((tab, index) => {
tab.classList.toggle('hidden', index + 1 !== currentTab);
tab.classList.toggle('absolute', index + 1 !== currentTab);
tab.classList.toggle('relative', index + 1 === currentTab);
});
tabBtns.forEach((btn, index) => {
btn.classList.toggle('tab-active', index + 1 === currentTab);
btn.classList.toggle('tab-inactive', index + 1 !== currentTab);
});
}
window.changeTab = (tabNumber) => {
currentTab = tabNumber;
updateUI();
};
function findIngredients() {
const selectedConcerns = Array.from(document.querySelectorAll('input[name="skinConcern"]:checked')).map(el => el.value);
if (selectedConcerns.length === 0) {
alert("Please select at least one skin concern.");
return;
}
matchedIngredients = ingredients.filter(ing =>
ing.targets.some(target => selectedConcerns.includes(target))
).map(ing => {
// Add a score to sort the most relevant ingredients first
const score = ing.targets.reduce((acc, target) => acc + (selectedConcerns.includes(target) ? 1 : 0), 0);
return { ...ing, score };
}).sort((a, b) => b.score - a.score); // Sort by relevance
displayMatches(matchedIngredients);
currentTab = 2;
updateUI();
}
function displayMatches(matches) {
const matchesContainer = document.getElementById('ingredient-matches');
if (matches.length > 0) {
matchesContainer.innerHTML = matches.map(ing => `
`).join('');
resultsPlaceholder.classList.add('hidden');
resultsContent.classList.remove('hidden');
} else {
resultsContent.classList.add('hidden');
resultsPlaceholder.classList.remove('hidden');
resultsPlaceholder.innerHTML = `
${ing.name}
${ing.description}
How to Use:
${ing.usage}
No specific matches found.
Please visit the Ingredient Guide for general information.
`; } } function downloadPDF() { if (matchedIngredients.length === 0) { alert('Please find your ingredients first.'); return; } const { jsPDF } = window.jspdf; const doc = new jsPDF({ unit: 'pt', format: 'a4' }); const pageW = doc.internal.pageSize.getWidth(); const margin = 40; let currentY = 0; const primaryColor = [37, 99, 235], grayColor = [107, 114, 128], blackColor = [17, 24, 39]; // --- HEADER --- doc.setFillColor(...primaryColor); doc.rect(0, 0, pageW, 80, 'F'); doc.setFont('helvetica', 'bold'); doc.setFontSize(24); doc.setTextColor(255, 255, 255); doc.text('Your Recommended Skincare Ingredients', margin, 50); currentY = 110; // --- SELECTED CONCERNS --- const selectedConcerns = Array.from(document.querySelectorAll('input[name="skinConcern"]:checked')).map(el => el.nextElementSibling.textContent); doc.setFont('helvetica', 'bold'); doc.setFontSize(12); doc.setTextColor(...blackColor); doc.text('Based on your selected concerns:', margin, currentY); currentY += 15; doc.setFont('helvetica', 'normal'); doc.setFontSize(10); doc.setTextColor(...grayColor); doc.text(selectedConcerns.join(', '), margin, currentY); currentY += 30; // --- TABLE --- const ingredientData = matchedIngredients.map(ing => [ ing.name, ing.description, ing.usage ]); doc.autoTable({ startY: currentY, head: [['Ingredient', 'What It Does', 'How to Use']], body: ingredientData, theme: 'grid', headStyles: { fillColor: [59, 130, 246] }, styles: { font: 'helvetica', fontSize: 9, cellPadding: 6, valign: 'middle' }, columnStyles: { 0: { cellWidth: 100, fontStyle: 'bold' }, 2: { cellWidth: 150 } } }); currentY = doc.lastAutoTable.finalY + 30; // --- FOOTER --- const pageH = doc.internal.pageSize.getHeight(); doc.setDrawColor(...grayColor); doc.line(margin, pageH - 60, pageW - margin, pageH - 60); doc.setFont('helvetica', 'normal'); doc.setFontSize(8); doc.setTextColor(...grayColor); const footerText = 'This guide is for informational purposes only. Always patch-test new products and consult a board-certified dermatologist for personalized advice and treatment plans.'; doc.text(doc.splitTextToSize(footerText, pageW - (margin * 2)), margin, pageH - 45); doc.save('My-Skincare-Ingredients.pdf'); } // --- EVENT LISTENERS --- generateBtn.addEventListener('click', findIngredients); pdfDownloadBtn.addEventListener('click', downloadPDF); // --- KICKOFF --- populateOptions(); updateUI(); });