Skincare Routine Tracker
0
Products Owned
$0.00
Shelf Value (USD)
0
Expiring Soon
☀️ Morning Routine
No steps added yet.
🌙 Evening Routine
No steps added yet.
Build Your Routine
Select a product from your inventory and assign it to your Morning or Evening routine.
Current Steps (Click 'Remove' to delete)
AM Steps:
PM Steps:
Add New Product
| Product | Category | Expires | Action |
|---|---|---|---|
| No products yet. | |||
No steps added yet.
'; return; } ids.forEach((id, index) => { const prod = products.find(p => p.id === id); if(prod) { const div = document.createElement('div'); div.className = 'skin-routine-item'; div.innerHTML = `
Step ${index + 1}
${prod.brand} ${prod.name}
${prod.type}
`;
container.appendChild(div);
}
});
};
renderDashList(routineAM, dashListAM);
renderDashList(routinePM, dashListPM);
}
function loadSampleData() {
// Sample USA Data
const samples = [
{ id: 1, name: "Hydrating Facial Cleanser", brand: "CeraVe", type: "Cleanser", cost: 14.99, opened: "", expiry: "2026-05-01" },
{ id: 2, name: "2% BHA Liquid Exfoliant", brand: "Paula's Choice", type: "Exfoliant", cost: 34.00, opened: "2024-01-10", expiry: "2025-01-10" },
{ id: 3, name: "Vitamin C Suspension 23%", brand: "The Ordinary", type: "Serum", cost: 7.50, opened: "", expiry: "2025-12-01" },
{ id: 4, name: "UV Clear Broad-Spectrum SPF 46", brand: "EltaMD", type: "Sunscreen", cost: 39.00, opened: "2024-02-01", expiry: "2025-02-01" },
{ id: 5, name: "Retinol Correxion Night Cream", brand: "RoC", type: "Moisturizer", cost: 24.99, opened: "", expiry: "2025-08-15" }
];
products = [...products, ...samples.map(s => ({...s, id: Date.now() + Math.random()}))];
updateInventoryUI();
// Assign rough routine
// Note: Using indexes of newly added items
const len = products.length;
routineAM.push(products[len-5].id); // Cleanser
routineAM.push(products[len-3].id); // Vit C
routineAM.push(products[len-2].id); // Sunscreen
routinePM.push(products[len-5].id); // Cleanser
routinePM.push(products[len-4].id); // BHA
routinePM.push(products[len-1].id); // Retinol
renderBuilder();
renderDashboard();
switchTab(0);
alert("Sample data loaded!");
}
function generatePDF() {
if (!window.jspdf) {
alert("PDF Library not loaded.");
return;
}
const { jsPDF } = window.jspdf;
const doc = new jsPDF();
// Header
doc.setFontSize(22);
doc.setTextColor(14, 165, 233); // Sky Blue
doc.text("Skincare Routine Guide", 105, 20, null, null, "center");
doc.setFontSize(10);
doc.setTextColor(100);
doc.text(`Generated: ${new Date().toLocaleDateString('en-US')}`, 105, 26, null, null, "center");
let currentY = 35;
// Helper for tables
const getTableData = (ids) => {
return ids.map((id, idx) => {
const p = products.find(prod => prod.id === id);
return p ? [`Step ${idx+1}`, p.type, p.brand, p.name] : [];
}).filter(row => row.length > 0);
};
// AM Routine
doc.setFontSize(14);
doc.setTextColor(0);
doc.text("Morning Routine ☀️", 14, currentY);
if (routineAM.length > 0) {
doc.autoTable({
startY: currentY + 5,
head: [['Order', 'Type', 'Brand', 'Product']],
body: getTableData(routineAM),
theme: 'striped',
headStyles: { fillColor: [253, 186, 116] } // Orange/Morning color
});
currentY = doc.lastAutoTable.finalY + 15;
} else {
doc.setFontSize(10);
doc.text("No steps defined.", 14, currentY + 10);
currentY += 20;
}
// PM Routine
doc.setFontSize(14);
doc.text("Evening Routine 🌙", 14, currentY);
if (routinePM.length > 0) {
doc.autoTable({
startY: currentY + 5,
head: [['Order', 'Type', 'Brand', 'Product']],
body: getTableData(routinePM),
theme: 'striped',
headStyles: { fillColor: [79, 70, 229] } // Indigo/Night color
});
currentY = doc.lastAutoTable.finalY + 15;
} else {
doc.setFontSize(10);
doc.text("No steps defined.", 14, currentY + 10);
currentY += 20;
}
// Inventory Summary
if (currentY > 220) {
doc.addPage();
currentY = 20;
}
doc.setFontSize(14);
doc.text("Full Inventory", 14, currentY);
const invData = products.map(p => [p.brand, p.name, p.type, p.expiry || '-']);
doc.autoTable({
startY: currentY + 5,
head: [['Brand', 'Name', 'Type', 'Expires']],
body: invData,
theme: 'grid'
});
doc.save('skincare-routine.pdf');
}
// --- Event Listeners ---
// Tabs
tabs.forEach((tab, idx) => tab.addEventListener('click', () => switchTab(idx)));
prevBtn.addEventListener('click', () => switchTab(currentTabIndex - 1));
nextBtn.addEventListener('click', () => switchTab(currentTabIndex + 1));
// Actions
btnAddInv.addEventListener('click', addProduct);
btnAddRoutine.addEventListener('click', addToRoutine);
btnSample.addEventListener('click', loadSampleData);
btnPdf.addEventListener('click', generatePDF);
// Initialize
updateInventoryUI();
});
