| document.addEventListener('DOMContentLoaded', () => { |
| const userForm = document.getElementById('user-form'); |
| const selectedFoodList = document.getElementById('selected-food-list'); |
| const canvas = document.getElementById('belly-fat-canvas'); |
| const ctx = canvas.getContext('2d'); |
| const searchInput = document.getElementById('food-search'); |
| const searchResults = document.getElementById('search-results'); |
|
|
| let selectedItems = []; |
| let userMetrics = {}; |
| let recommendedCalories = 2000; |
|
|
| function updateUserMetrics() { |
| userMetrics.age = parseInt(document.getElementById('age').value); |
| userMetrics.gender = document.getElementById('gender').value; |
| userMetrics.heightFeet = parseInt(document.getElementById('height-feet').value); |
| userMetrics.heightInches = parseInt(document.getElementById('height-inches').value); |
| userMetrics.weight = parseFloat(document.getElementById('weight').value); |
| userMetrics.targetWeight = parseFloat(document.getElementById('target-weight').value); |
| userMetrics.waist = parseFloat(document.getElementById('waist').value); |
| userMetrics.neck = parseFloat(document.getElementById('neck').value); |
| userMetrics.hip = parseFloat(document.getElementById('hip').value); |
| userMetrics.steps = parseInt(document.getElementById('steps').value); |
| userMetrics.standingHours = parseFloat(document.getElementById('standing-hours').value); |
| } |
|
|
| userForm.addEventListener('submit', (e) => { |
| e.preventDefault(); |
| updateUserMetrics(); |
| calculateMetrics(); |
| }); |
|
|
| function calculateMetrics() { |
| console.log('calculateMetrics function called'); |
| const heightInCm = (userMetrics.heightFeet * 30.48) + (userMetrics.heightInches * 2.54); |
| const weightInKg = userMetrics.weight * 0.45359237; |
| const targetWeightInKg = userMetrics.targetWeight * 0.45359237; |
| const waistInCm = userMetrics.waist * 2.54; |
| const neckInCm = userMetrics.neck * 2.54; |
| const hipInCm = userMetrics.hip * 2.54; |
|
|
| const metricsData = { |
| age: userMetrics.age, |
| gender: userMetrics.gender, |
| heightFeet: userMetrics.heightFeet, |
| heightInches: userMetrics.heightInches, |
| weight: weightInKg, |
| targetWeight: targetWeightInKg, |
| waist: waistInCm, |
| neck: neckInCm, |
| hip: hipInCm, |
| steps: userMetrics.steps, |
| standingHours: userMetrics.standingHours |
| }; |
|
|
| console.log('Sending metrics data:', metricsData); |
| fetch('/api/calculate-metrics', { |
| method: 'POST', |
| headers: { |
| 'Content-Type': 'application/json', |
| }, |
| body: JSON.stringify(metricsData), |
| }) |
| .then(response => { |
| console.log('Response status:', response.status); |
| return response.json(); |
| }) |
| .then(data => { |
| console.log('Received metrics data:', data); |
| if (data.error) { |
| console.error('Error calculating metrics:', data.error); |
| showNotification(`Error: ${data.error}`, 'error'); |
| return; |
| } |
| document.getElementById('bmi-value').textContent = data.bmi; |
| document.getElementById('recommended-calories').textContent = data.recommendedCalories; |
| document.getElementById('body-fat-percentage').textContent = data.bodyFatPercentage + '%'; |
| document.getElementById('lean-body-mass').textContent = (data.leanBodyMass * 2.20462).toFixed(2) + ' lbs'; |
| document.getElementById('target-weight-time').textContent = data.timeToTargetWeight; |
| recommendedCalories = data.recommendedCalories; |
| updateBellyFatVisualization({ calories: 0, protein: 0, carbs: 0, fat: 0 }); |
| getPersonalizedRecommendations(data); |
| }) |
| .catch(error => { |
| console.error('Error:', error); |
| showNotification(`Error: ${error.message}`, 'error'); |
| }); |
| } |
|
|
| function getPersonalizedRecommendations(metricsData) { |
| const recommendationData = { |
| ...userMetrics, |
| ...metricsData, |
| height: (userMetrics.heightFeet * 30.48) + (userMetrics.heightInches * 2.54) |
| }; |
|
|
| console.log('Sending recommendation data:', recommendationData); |
| fetch('/api/personalized-recommendations', { |
| method: 'POST', |
| headers: { |
| 'Content-Type': 'application/json', |
| }, |
| body: JSON.stringify(recommendationData), |
| }) |
| .then(response => response.json()) |
| .then(data => { |
| console.log('Received recommendations:', data); |
| if (data.error) { |
| console.error('Error getting recommendations:', data.error); |
| showNotification(`Error: ${data.error}`, 'error'); |
| return; |
| } |
| displayRecommendations(data); |
| }) |
| .catch(error => { |
| console.error('Error:', error); |
| showNotification(`Error: ${error.message}`, 'error'); |
| }); |
| } |
|
|
| function displayRecommendations(recommendations) { |
| const dietRecommendationsList = document.getElementById('diet-recommendations-list'); |
| const exerciseRecommendationsList = document.getElementById('exercise-recommendations-list'); |
|
|
| dietRecommendationsList.innerHTML = ''; |
| exerciseRecommendationsList.innerHTML = ''; |
|
|
| recommendations.dietRecommendations.forEach(recommendation => { |
| const li = document.createElement('li'); |
| li.textContent = recommendation; |
| dietRecommendationsList.appendChild(li); |
| }); |
|
|
| recommendations.exerciseRecommendations.forEach(recommendation => { |
| const li = document.createElement('li'); |
| li.textContent = recommendation; |
| exerciseRecommendationsList.appendChild(li); |
| }); |
| } |
|
|
| function searchFood() { |
| const query = searchInput.value.trim(); |
| if (query.length < 2) return; |
|
|
| fetch(`/api/search-food?query=${encodeURIComponent(query)}`) |
| .then(response => response.json()) |
| .then(data => { |
| displaySearchResults(data); |
| }) |
| .catch(error => console.error('Error:', error)); |
| } |
|
|
| function displaySearchResults(results) { |
| searchResults.innerHTML = ''; |
| results.forEach(item => { |
| const li = document.createElement('li'); |
| li.textContent = item.description; |
| li.addEventListener('click', () => addFoodItem(item)); |
| searchResults.appendChild(li); |
| }); |
| } |
|
|
| function addFoodItem(item) { |
| selectedItems.push(item); |
| updateSelectedFoodList(); |
| updateBellyFatVisualization(); |
| } |
|
|
| function updateSelectedFoodList() { |
| selectedFoodList.innerHTML = ''; |
| selectedItems.forEach(item => { |
| const li = document.createElement('li'); |
| li.textContent = `${item.description} (${item.calories} kcal) (${item.Protein} Protein) (${item.carbs} carbs) (${item.fat} fat)`; |
| selectedFoodList.appendChild(li); |
| }); |
| } |
|
|
| function updateBellyFatVisualization() { |
| const totalNutrients = calculateTotalNutrients(); |
| |
| |
| ctx.clearRect(0, 0, canvas.width, canvas.height); |
|
|
| |
| ctx.beginPath(); |
| ctx.arc(canvas.width / 2, canvas.height / 2, canvas.width / 3, 0, 2 * Math.PI); |
| ctx.fillStyle = 'yellow'; |
| ctx.fill(); |
|
|
| |
| const foodItems = Math.min(selectedItems.length, 20); |
| for (let i = 0; i < foodItems; i++) { |
| const angle = (i / foodItems) * 2 * Math.PI; |
| const radius = canvas.width / 4; |
| const x = canvas.width / 2 + radius * Math.cos(angle); |
| const y = canvas.height / 2 + radius * Math.sin(angle); |
|
|
| ctx.beginPath(); |
| ctx.arc(x, y, 10, 0, 2 * Math.PI); |
| ctx.fillStyle = 'green'; |
| ctx.fill(); |
| } |
|
|
| |
| drawStackGraph(totalNutrients); |
|
|
| |
| document.getElementById('total-calories').textContent = totalNutrients.calories; |
| } |
|
|
| function calculateTotalNutrients() { |
| return selectedItems.reduce((total, item) => { |
| total.calories += item.calories || 0; |
| total.protein += item.protein || 0; |
| total.carbs += item.carbs || 0; |
| total.fat += item.fat || 0; |
| return total; |
| }, { calories: 0, protein: 0, carbs: 0, fat: 0 }); |
| } |
|
|
| function drawStackGraph(nutrients) { |
| const barWidth = 40; |
| const barHeight = 100; |
| const startX = canvas.width - barWidth - 10; |
| const startY = canvas.height - 10; |
|
|
| const totalMacros = nutrients.protein + nutrients.carbs + nutrients.fat; |
| const proteinHeight = (nutrients.protein / totalMacros) * barHeight; |
| const carbsHeight = (nutrients.carbs / totalMacros) * barHeight; |
| const fatHeight = (nutrients.fat / totalMacros) * barHeight; |
|
|
| ctx.fillStyle = 'red'; |
| ctx.fillRect(startX, startY - fatHeight, barWidth, fatHeight); |
|
|
| ctx.fillStyle = 'blue'; |
| ctx.fillRect(startX, startY - fatHeight - carbsHeight, barWidth, carbsHeight); |
|
|
| ctx.fillStyle = 'green'; |
| ctx.fillRect(startX, startY - fatHeight - carbsHeight - proteinHeight, barWidth, proteinHeight); |
| } |
|
|
| |
| searchInput.addEventListener('input', searchFood); |
|
|
| |
| updateBellyFatVisualization(); |
| }); |
|
|