Type 2 Diabetes Risk Assessment

Type 2 Diabetes Risk Assessment

Answer a few questions to estimate your risk.

About You

Body Mass Index (BMI)

Your weight in relation to your height is a major risk factor.

Your Health History

A required library could not be loaded.

'; return; } const { jsPDF } = jspdf; // --- STATE --- let riskScore = 0; let userInputs = {}; // --- ELEMENT SELECTORS --- const tabs = document.querySelectorAll('.tab-btn'); const tabContents = document.querySelectorAll('.tab-content'); const prevBtn = document.getElementById('prevBtn'); const nextBtn = document.getElementById('nextBtn'); // Inputs const allInputs = { age: document.getElementById('age'), gender: document.getElementById('gender'), gestational: document.getElementById('gestational'), heightFt: document.getElementById('height-ft'), heightIn: document.getElementById('height-in'), weightLbs: document.getElementById('weight-lbs'), familyHistory: document.getElementById('family-history'), hbp: document.getElementById('hbp'), activity: document.getElementById('activity') }; const gestationalQ = document.getElementById('gestational-q'); const bmiResultEl = document.getElementById('bmi-result'); // Results const getResultsBtn = document.getElementById('get-results-btn'); const resultsLoader = document.getElementById('results-loader'); const resultsOutput = document.getElementById('results-output'); const summaryContentContainer = document.getElementById('summary-content-container'); const downloadPdfBtn = document.getElementById('download-pdf-btn'); // --- INITIALIZATION --- const initialize = () => { updateNavButtons(); attachEventListeners(); }; // --- EVENT LISTENERS --- const attachEventListeners = () => { tabs.forEach(tab => tab.addEventListener('click', () => switchTab(tab.dataset.tab))); prevBtn.addEventListener('click', navigatePrev); nextBtn.addEventListener('click', navigateNext); getResultsBtn.addEventListener('click', handleGetResults); downloadPdfBtn.addEventListener('click', handleDownloadPdf); allInputs.gender.addEventListener('change', () => { gestationalQ.classList.toggle('hidden', allInputs.gender.value !== 'Female'); }); [allInputs.heightFt, allInputs.heightIn, allInputs.weightLbs].forEach(el => { el.addEventListener('input', calculateAndShowBmi); }); }; // --- 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'; getResultsBtn.style.display = activeTabIndex === tabs.length - 1 ? 'block' : 'none'; resultsOutput.classList.add('hidden'); }; 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); }; // --- CALCULATIONS --- const calculateBmiPoints = () => { const { bmi } = calculateAndShowBmi(); if (bmi >= 39) return 3; if (bmi >= 32.5) return 2; if (bmi >= 26.2) return 1; return 0; }; const calculateAndShowBmi = () => { const ft = parseFloat(allInputs.heightFt.value) || 0; const inch = parseFloat(allInputs.heightIn.value) || 0; const lbs = parseFloat(allInputs.weightLbs.value) || 0; if (ft > 0 && lbs > 0) { const totalInches = (ft * 12) + inch; const bmi = (lbs / (totalInches * totalInches)) * 703; const bmiRounded = bmi.toFixed(1); let category = "Normal weight"; if (bmi >= 30) category = "Obese"; else if (bmi >= 25) category = "Overweight"; bmiResultEl.innerHTML = `Your BMI: ${bmiRounded} (${category})`; bmiResultEl.classList.remove('hidden'); return { bmi: bmiRounded, category }; } bmiResultEl.classList.add('hidden'); return { bmi: 0, category: '' }; }; const calculateRiskScore = () => { riskScore = 0; riskScore += parseInt(allInputs.age.value); riskScore += parseInt(allInputs.gestational.value); riskScore += parseInt(allInputs.familyHistory.value); riskScore += parseInt(allInputs.hbp.value); riskScore += parseInt(allInputs.activity.value); riskScore += calculateBmiPoints(); return riskScore; }; // --- API & RESULTS LOGIC --- const handleGetResults = async () => { if (!allInputs.heightFt.value || !allInputs.weightLbs.value) { alert("Please fill in your height and weight to calculate your risk."); return; } resultsLoader.classList.remove('hidden'); resultsOutput.classList.add('hidden'); getResultsBtn.style.display = 'none'; calculateRiskScore(); const { category: bmiCategory } = calculateAndShowBmi(); const prompt = buildPrompt(bmiCategory); const insightsText = await callGeminiApi(prompt); renderSummary(insightsText, bmiCategory); resultsLoader.classList.add('hidden'); resultsOutput.classList.remove('hidden'); }; const buildPrompt = (bmiCategory) => { const riskLevel = riskScore >= 5 ? "High Risk" : "Low Risk"; let contributingFactors = []; if (parseInt(allInputs.age.value) > 1) contributingFactors.push("age"); if (parseInt(allInputs.gestational.value) === 1) contributingFactors.push("history of gestational diabetes"); if (calculateBmiPoints() > 0) contributingFactors.push(`being in the ${bmiCategory} category`); if (parseInt(allInputs.familyHistory.value) === 1) contributingFactors.push("family history"); if (parseInt(allInputs.hbp.value) === 1) contributingFactors.push("high blood pressure"); if (parseInt(allInputs.activity.value) === 1) contributingFactors.push("low physical activity"); return ` As a health and wellness AI assistant (not a medical professional), analyze the following Type 2 Diabetes risk assessment results. **User's Results:** - Risk Score: ${riskScore} - Risk Level: ${riskLevel} - Key Contributing Factors: ${contributingFactors.join(', ') || 'N/A'} **Task:** Generate a supportive and informative summary. Structure your response into the following sections using the exact headings: ### Understanding Your Risk Score Explain what a score of ${riskScore} means. If the score is 5 or higher, state that the user is at high risk for type 2 diabetes but that there are many things they can do to reduce their risk. If the score is lower than 5, state they are at a lower risk but that it's still important to maintain a healthy lifestyle. ### Personalized Actionable Steps Provide 3-4 actionable, non-medical suggestions tailored to the user's key contributing factors. For example: - If a factor is 'low physical activity', suggest starting with 15-20 minute walks daily. - If a factor is 'being overweight/obese', suggest focusing on whole foods and portion sizes. - If a factor is 'family history', explain that while they can't change their genes, a healthy lifestyle is even more crucial. ### Next Steps Recommend that the user discuss these results with their doctor. Suggest they can use this report as a starting point for the conversation. **IMPORTANT:** Conclude the entire response with a clear, bolded disclaimer: **Disclaimer: This is a risk assessment tool, not a diagnosis. The information provided is for educational purposes only. Consult with a healthcare professional for medical advice and to discuss your personal risk.** `; }; const callGeminiApi = async (prompt) => { const apiKey = ""; // Provided by 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 insights. Please try again later.\n\n**Disclaimer:** This is not medical advice."; } }; const renderSummary = (insightsText, bmiCategory) => { document.getElementById('summary-date').textContent = `Report generated on ${new Date().toLocaleDateString('en-US')}`; const riskLevel = riskScore >= 5 ? "High Risk" : "Low Risk"; const riskColor = riskScore >= 5 ? "bg-red-100 text-red-800" : "bg-green-100 text-green-800"; const resultsHtml = `

Your Risk Assessment

${riskScore} ${riskLevel}

Your Answers Summary

  • Age: ${allInputs.age.options[allInputs.age.selectedIndex].text}
  • BMI Category: ${bmiCategory}
  • Family History of Diabetes: ${allInputs.familyHistory.value === '1' ? 'Yes' : 'No'}
  • History of High Blood Pressure: ${allInputs.hbp.value === '1' ? 'Yes' : 'No'}
  • Physically Active: ${allInputs.activity.value === '0' ? 'Yes' : 'No'}
  • ${allInputs.gender.value === 'Female' ? `
  • History of Gestational Diabetes: ${allInputs.gestational.value === '1' ? 'Yes' : 'No'}
  • ` : ''}
`; const insightsHtml = insightsText .replace(/### (.*?)\n/g, '

$1

') .replace(/\n\n/g, '

') .replace(/\n- /g, '
  • ') .replace(/(\n- .*?)+/g, (match) => match.replace(/\n- /g, '
  • ') + '
') .replace(/
  • /,'') .replace(/\*\*(.*?)\*\*/g, '$1'); summaryContentContainer.innerHTML = resultsHtml + insightsHtml; }; // --- 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 ratio = canvas.width / canvas.height; const imgWidth = pdfWidth - 20; let imgHeight = imgWidth / ratio; let heightLeft = imgHeight; let position = 10; pdf.addImage(imgData, 'PNG', 10, position, imgWidth, imgHeight); heightLeft -= (pdf.internal.pageSize.getHeight() - 20); while (heightLeft > 0) { position = -heightLeft - 10; pdf.addPage(); pdf.addImage(imgData, 'PNG', 10, position, imgWidth, imgHeight); heightLeft -= (pdf.internal.pageSize.getHeight() - 20); } pdf.save('My-Diabetes-Risk-Report.pdf'); }) .catch(err => console.error("PDF Generation Error:", err)); }; // --- START THE APP --- initialize(); });
  • Scroll to Top