Personal Finance Advisor

Personal Finance Advisor

What are your financial goals?

Current Financial Status

Your Personalized Financial Advice

Please fill out the previous sections and click "Get Advice" to see your personalized recommendations.

Generating personalized advice...

`; showNextTab(); // Automatically move to the advice tab // Construct prompt for the LLM const prompt = `As a personal finance advisor, provide actionable, concise advice based on the following financial situation. Use the US Dollar ($) for currency. User's Financial Goals: "${goals}" Monthly Net Income: $${income.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} Total Monthly Expenses: $${expenses.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} Current Savings: $${savings.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} Total Outstanding Debt: $${debt.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} Provide specific recommendations for budgeting, saving, debt management, and investment opportunities relevant to their goals and current status. Structure the advice with clear headings (e.g., "Budgeting", "Saving", "Debt Management", "Investing"). Do not include any disclaimers.`; let chatHistory = []; chatHistory.push({ role: "user", parts: [{ text: prompt }] }); const payload = { contents: chatHistory }; const apiKey = ""; // Canvas will automatically provide the API key at runtime. const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${apiKey}`; try { const response = await fetch(apiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); const result = await response.json(); // Ensure awaiting the json() parsing if (result.candidates && result.candidates.length > 0 && result.candidates[0].content && result.candidates[0].content.parts && result.candidates[0].content.parts.length > 0) { const text = result.candidates[0].content.parts[0].text; // Format the text for better readability const formattedText = text .replace(/\*\*(.*?)\*\*/g, '$1') // Bold text .replace(/\n/g, '
'); // Newlines to
for HTML display adviceOutput.innerHTML = formattedText; } else { adviceOutput.innerHTML = '

Failed to get advice. Please try again.

'; console.error('Unexpected API response structure:', result); showCustomAlert('Error', 'Could not generate advice. Please try again later.'); } } catch (error) { console.error('Error fetching advice:', error); adviceOutput.innerHTML = '

An error occurred while fetching advice. Please check your internet connection or try again later.

'; showCustomAlert('Network Error', 'Could not connect to the advice generator. Please check your internet.'); } } /** * Downloads the generated advice and input summary as a PDF. */ async function downloadPDF() { // Ensure advice is generated before downloading PDF if (adviceOutput.textContent.includes('Please fill out the previous sections')) { showCustomAlert('No Advice Yet', 'Please generate advice first by filling out the previous sections and clicking "Get Advice".'); return; } // Create a temporary div to gather all content for the PDF const pdfContentDiv = document.createElement('div'); pdfContentDiv.className = 'p-6'; // Add some padding for the PDF content // Add heading const heading = document.createElement('h1'); heading.className = 'text-2xl font-bold text-center mb-6 text-gray-800'; heading.textContent = 'Personal Finance Advice Report'; pdfContentDiv.appendChild(heading); // Add user inputs summary const inputsSummary = document.createElement('div'); inputsSummary.className = 'mb-8 bg-gray-50 p-4 rounded-lg border border-gray-200'; inputsSummary.innerHTML = `

Your Financial Overview

Financial Goals:${financialGoalsInput.value.trim()}
Monthly Net Income:$${parseFloat(monthlyIncomeInput.value).toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
Monthly Expenses:$${parseFloat(monthlyExpensesInput.value).toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
Current Savings:$${parseFloat(currentSavingsInput.value).toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
Total Outstanding Debt:$${parseFloat(totalDebtInput.value).toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
`; pdfContentDiv.appendChild(inputsSummary); // Add the generated advice content const adviceSection = document.createElement('div'); adviceSection.className = 'p-4 rounded-lg bg-white border border-gray-200'; adviceSection.innerHTML = `

Personalized Advice

${adviceOutput.innerHTML} `; pdfContentDiv.appendChild(adviceSection); // Temporarily append to body to render for html2canvas, then remove document.body.appendChild(pdfContentDiv); // Generate canvas from the PDF content div const canvas = await html2canvas(pdfContentDiv, { scale: 2, // Increase scale for better resolution in PDF useCORS: true, // Needed if external images are involved (though not in this case) logging: false, // Disable logging }); // Remove the temporary div document.body.removeChild(pdfContentDiv); const imgData = canvas.toDataURL('image/png'); const pdf = new window.jspdf.jsPDF({ orientation: 'portrait', unit: 'px', format: 'a4' }); const imgWidth = pdf.internal.pageSize.getWidth(); const imgHeight = (canvas.height * imgWidth) / canvas.width; let position = 0; pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight); // Handle multi-page PDF if content is too long let heightLeft = imgHeight; heightLeft -= pdf.internal.pageSize.getHeight(); while (heightLeft >= 0) { position = heightLeft - imgHeight; pdf.addPage(); pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight); heightLeft -= pdf.internal.pageSize.getHeight(); } pdf.save('Personal_Finance_Advice.pdf'); } // Initialize the first tab on DOM load document.addEventListener('DOMContentLoaded', () => { switchTab(0); // Set the first tab as active by default });
Scroll to Top