Personalized Anti-Inflammatory Diet Planner

Personalized Anti-Inflammatory Diet Planner

Build a custom meal plan to support your wellness goals.

Your Dietary Needs

Select Your Favorite Anti-Inflammatory Foods

Choose at least 5-10 items you enjoy. The more you select, the more varied your plan will be.

A required library could not be loaded. Please check your internet connection and try again.

'; return; } const { jsPDF } = jspdf; // --- DATA & STATE --- const FOOD_CATEGORIES = { "Leafy Greens": ["Spinach", "Kale", "Swiss Chard", "Arugula"], "Berries & Fruits": ["Blueberries", "Strawberries", "Cherries", "Oranges", "Apples", "Grapes"], "Vegetables": ["Broccoli", "Cauliflower", "Bell Peppers", "Mushrooms", "Tomatoes", "Beets"], "Healthy Fats": ["Avocado", "Olive Oil", "Chia Seeds", "Flax Seeds"], "Nuts & Seeds": ["Almonds", "Walnuts", "Sunflower Seeds", "Pumpkin Seeds"], "Fatty Fish": ["Salmon", "Sardines", "Mackerel", "Herring"], "Lean Proteins": ["Chicken Breast", "Turkey", "Lentils", "Chickpeas", "Tofu"], "Spices & Herbs": ["Turmeric", "Ginger", "Garlic", "Cinnamon", "Rosemary"], "Beverages": ["Green Tea", "Water"] }; let userState = { profile: { preference: 'Omnivore (includes everything)', restrictions: '', }, selectedFoods: [], }; // --- ELEMENT SELECTORS --- const tabs = document.querySelectorAll('.tab-btn'); const tabContents = document.querySelectorAll('.tab-content'); const prevBtn = document.getElementById('prevBtn'); const nextBtn = document.getElementById('nextBtn'); const foodSelectionContainer = document.getElementById('food-selection-container'); // Profile const dietPreferenceSelect = document.getElementById('diet-preference'); const restrictionsInput = document.getElementById('restrictions'); // Plan const getPlanBtn = document.getElementById('getPlanBtn'); const planLoader = document.getElementById('plan-loader'); const planOutput = document.getElementById('plan-output'); const planContentContainer = document.getElementById('plan-content-container'); const downloadPdfBtn = document.getElementById('downloadPdfBtn'); // --- INITIALIZATION --- const initialize = () => { renderFoodSelection(); updateNavButtons(); attachEventListeners(); }; // --- RENDER FUNCTIONS --- const renderFoodSelection = () => { foodSelectionContainer.innerHTML = Object.entries(FOOD_CATEGORIES).map(([category, foods]) => `

${category}

${foods.map(food => `
${food}
`).join('')}
`).join(''); }; // --- EVENT LISTENERS --- const attachEventListeners = () => { tabs.forEach(tab => tab.addEventListener('click', () => switchTab(tab.dataset.tab))); prevBtn.addEventListener('click', navigatePrev); nextBtn.addEventListener('click', navigateNext); // Profile inputs dietPreferenceSelect.addEventListener('change', (e) => userState.profile.preference = e.target.value); restrictionsInput.addEventListener('input', (e) => userState.profile.restrictions = e.target.value); // Food selection foodSelectionContainer.addEventListener('click', (e) => { const card = e.target.closest('.food-card'); if (card) { const food = card.dataset.food; card.classList.toggle('selected'); if (card.classList.contains('selected')) { userState.selectedFoods.push(food); } else { userState.selectedFoods = userState.selectedFoods.filter(f => f !== food); } } }); // Main action buttons getPlanBtn.addEventListener('click', handleGetPlan); downloadPdfBtn.addEventListener('click', handleDownloadPdf); }; // --- NAVIGATION --- const switchTab = (targetTab) => { tabs.forEach(tab => tab.classList.toggle('active', tab.dataset.tab === targetTab)); tabContents.forEach(content => content.classList.toggle('active', content.id === targetTab)); updateNavButtons(); }; const updateNavButtons = () => { const activeTabIndex = Array.from(tabs).findIndex(tab => tab.classList.contains('active')); prevBtn.style.visibility = activeTabIndex === 0 ? 'hidden' : 'visible'; nextBtn.style.visibility = activeTabIndex === tabs.length - 1 ? 'hidden' : 'visible'; }; const navigatePrev = () => { const activeTabIndex = Array.from(tabs).findIndex(tab => tab.classList.contains('active')); if (activeTabIndex > 0) switchTab(tabs[activeTabIndex - 1].dataset.tab); }; const navigateNext = () => { const activeTabIndex = Array.from(tabs).findIndex(tab => tab.classList.contains('active')); if (activeTabIndex < tabs.length - 1) switchTab(tabs[activeTabIndex + 1].dataset.tab); }; // --- API & PLAN LOGIC --- const handleGetPlan = async () => { if (userState.selectedFoods.length < 5) { alert("Please select at least 5 foods to generate a meaningful plan."); return; } planLoader.classList.remove('hidden'); planOutput.classList.add('hidden'); getPlanBtn.disabled = true; const prompt = buildPrompt(); const planText = await callGeminiApi(prompt); renderPlan(planText); planLoader.classList.add('hidden'); planOutput.classList.remove('hidden'); getPlanBtn.disabled = false; }; const buildPrompt = () => { const { preference, restrictions } = userState.profile; const foods = userState.selectedFoods.join(', '); return ` As a nutritionist AI, create a personalized 3-day anti-inflammatory meal plan based on the user's profile. **User Profile:** - Dietary Preference: ${preference} - Restrictions/Allergies: ${restrictions || 'None specified'} - Liked Anti-Inflammatory Foods: ${foods} **Instructions:** 1. Create a 3-day meal plan (Day 1, Day 2, Day 3). 2. For each day, provide simple, healthy ideas for Breakfast, Lunch, Dinner, and one Snack. 3. Heavily feature the user's "Liked" foods throughout the plan. 4. Strictly adhere to the user's dietary preference and restrictions. For example, if they are Vegan, do not include any animal products. If they are gluten-free, do not suggest meals with wheat, barley, or rye. 5. After the meal plan, provide a section titled "### Key Principles of Your Plan" with 3-4 bullet points explaining the benefits of the included foods and general tips for an anti-inflammatory lifestyle. 6. Conclude with a standard medical disclaimer. **Formatting:** - Use '##' for days (e.g., ## Day 1). - Use '###' for meals (e.g., ### Breakfast). - Use bullet points (-) for meal components. - Use '###' for the "Key Principles" section title. `; }; const callGeminiApi = async (prompt) => { const apiKey = ""; // Provided by the environment const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-05-20:generateContent?key=${apiKey}`; const payload = { contents: [{ role: "user", parts: [{ text: prompt }] }] }; try { const response = await fetch(apiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); if (!response.ok) throw new Error(`API Error: ${response.status}`); const data = await response.json(); return data.candidates[0].content.parts[0].text; } catch (error) { console.error("Gemini API Error:", error); return "## Error\nCould not generate a plan at this time. Please try again later.\n\n**Disclaimer:** This is not medical advice. Always consult a healthcare professional."; } }; const renderPlan = (planText) => { document.getElementById('summaryDate').textContent = `Plan generated on ${new Date().toLocaleDateString('en-US')}`; const html = planText .replace(/## (.*?)\n/g, '

$1

') .replace(/### (.*?)\n/g, '

$1

') .replace(/- (.*?)\n/g, '
  • $1
') .replace(/<\/ul>\s*
    /g, ''); // Merge consecutive lists planContentContainer.innerHTML = html; }; // --- PDF GENERATION --- const handleDownloadPdf = () => { const content = document.getElementById('pdf-content'); if (!content) return; html2canvas(content, { scale: 2, useCORS: true, backgroundColor: '#ffffff' }) .then(canvas => { const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const canvasWidth = canvas.width; const canvasHeight = canvas.height; const ratio = canvasWidth / canvasHeight; const imgWidth = pdfWidth - 20; const imgHeight = imgWidth / ratio; let heightLeft = imgHeight; let position = 10; pdf.addImage(imgData, 'PNG', 10, position, imgWidth, imgHeight); heightLeft -= (pdfHeight - 20); while (heightLeft > 0) { position = -heightLeft - 10; pdf.addPage(); pdf.addImage(imgData, 'PNG', 10, position, imgWidth, imgHeight); heightLeft -= (pdfHeight - 20); } pdf.save('My-Anti-Inflammatory-Plan.pdf'); }) .catch(err => console.error("PDF Generation Error:", err)); }; // --- START THE APP --- initialize(); });
Scroll to Top