|
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(); |
|
}); |
|
|