feat(meal-planner): add auto-generate meal plan functionality

Add new utility function to generate daily meal plans based on user's calorie targets and food categories. Include auto-generate button in meal planner UI with confirmation prompt. Add new Filipino food items to seed data for better meal variety. Fix database column references to use capitalized field names consistently.
This commit is contained in:
Jp
2026-01-31 00:56:25 +08:00
parent cb2fe12c73
commit 0fa0343798
7 changed files with 300 additions and 27 deletions

View File

@@ -153,10 +153,10 @@ app.get('/dashboard', ensureAuthenticated, async (req, res) => {
const water = await utils.calculateWaterTotal(req.user.id, dateStr);
// Get user goals
let goals = await db.UserGoal.findOne({ where: { user_id: req.user.id } });
let goals = await db.UserGoal.findOne({ where: { UserId: req.user.id } });
if (!goals) {
goals = await db.UserGoal.create({
user_id: req.user.id,
UserId: req.user.id,
target_protein_g: 150,
target_carbs_g: 200,
target_fat_g: 60,
@@ -166,7 +166,7 @@ app.get('/dashboard', ensureAuthenticated, async (req, res) => {
// Get weight info
const weightLogToday = await db.WeightLog.findOne({
where: { user_id: req.user.id, date: dateStr }
where: { UserId: req.user.id, date: dateStr }
});
const yesterday = new Date(today);
@@ -174,7 +174,7 @@ app.get('/dashboard', ensureAuthenticated, async (req, res) => {
const yesterdayStr = yesterday.toISOString().split('T')[0];
const weightLogYesterday = await db.WeightLog.findOne({
where: { user_id: req.user.id, date: yesterdayStr }
where: { UserId: req.user.id, date: yesterdayStr }
});
let weightChange = null;
@@ -259,7 +259,7 @@ app.post('/add-meal', ensureAuthenticated, async (req, res) => {
}
const meal = await db.Meal.create({
user_id: req.user.id,
UserId: req.user.id,
date: date || new Date(),
meal_type,
time: time || null
@@ -337,7 +337,7 @@ app.post('/add-water', ensureAuthenticated, async (req, res) => {
const date = req.body.date || new Date().toISOString().split('T')[0];
await db.WaterLog.create({
user_id: req.user.id,
UserId: req.user.id,
date: date,
amount_ml: amountMl,
time: new Date()
@@ -360,7 +360,7 @@ app.post('/add-weight', ensureAuthenticated, async (req, res) => {
const date = req.body.date || new Date().toISOString().split('T')[0];
let weightLog = await db.WeightLog.findOne({
where: { user_id: req.user.id, date: date }
where: { UserId: req.user.id, date: date }
});
if (weightLog) {
@@ -369,7 +369,7 @@ app.post('/add-weight', ensureAuthenticated, async (req, res) => {
await weightLog.save();
} else {
await db.WeightLog.create({
user_id: req.user.id,
UserId: req.user.id,
date: date,
weight_kg: weightKg,
time: new Date()
@@ -388,7 +388,7 @@ app.post('/add-weight', ensureAuthenticated, async (req, res) => {
app.get('/goals', ensureAuthenticated, async (req, res) => {
try {
const userGoals = await db.UserGoal.findOne({ where: { user_id: req.user.id } });
const userGoals = await db.UserGoal.findOne({ where: { UserId: req.user.id } });
let bmr = null;
let tdee = null;
@@ -444,9 +444,9 @@ app.post('/goals', ensureAuthenticated, async (req, res) => {
await user.save();
// Update or create goals
let userGoals = await db.UserGoal.findOne({ where: { user_id: req.user.id } });
let userGoals = await db.UserGoal.findOne({ where: { UserId: req.user.id } });
if (!userGoals) {
userGoals = await db.UserGoal.create({ user_id: req.user.id });
userGoals = await db.UserGoal.create({ UserId: req.user.id });
}
userGoals.goal_type = goalType;
@@ -578,7 +578,7 @@ app.get('/meal-planner', ensureAuthenticated, async (req, res) => {
const dateStr = d.toISOString().split('T')[0];
const plans = await db.MealPlan.findAll({
where: { user_id: req.user.id, date: dateStr },
where: { UserId: req.user.id, date: dateStr },
include: [{
model: db.PlannedFood,
include: [db.FoodItem]
@@ -630,6 +630,26 @@ app.get('/meal-planner', ensureAuthenticated, async (req, res) => {
}
});
app.post('/meal-planner/auto-generate', ensureAuthenticated, async (req, res) => {
try {
const { date } = req.body;
if (!date) {
req.flash('error_msg', 'Please select a date');
return res.redirect('/meal-planner');
}
await utils.generateDailyMealPlan(req.user.id, date);
req.flash('success_msg', 'Meal plan generated successfully!');
res.redirect('/meal-planner');
} catch (err) {
console.error(err);
req.flash('error_msg', 'Error generating meal plan');
res.redirect('/meal-planner');
}
});
app.post('/meal-planner/add', ensureAuthenticated, async (req, res) => {
try {
let { date, meal_type, 'food_id[]': foodIds, 'quantity[]': quantities } = req.body;
@@ -648,7 +668,7 @@ app.post('/meal-planner/add', ensureAuthenticated, async (req, res) => {
// Find or create meal plan
let mealPlan = await db.MealPlan.findOne({
where: {
user_id: req.user.id,
UserId: req.user.id,
date: date,
meal_type: meal_type
}
@@ -656,7 +676,7 @@ app.post('/meal-planner/add', ensureAuthenticated, async (req, res) => {
if (!mealPlan) {
mealPlan = await db.MealPlan.create({
user_id: req.user.id,
UserId: req.user.id,
date: date,
meal_type: meal_type
});
@@ -688,7 +708,7 @@ app.post('/meal-planner/add', ensureAuthenticated, async (req, res) => {
app.post('/meal-planner/complete/:id', ensureAuthenticated, async (req, res) => {
try {
const plan = await db.MealPlan.findOne({
where: { id: req.params.id, user_id: req.user.id }
where: { id: req.params.id, UserId: req.user.id }
});
if (plan) {
@@ -710,7 +730,7 @@ app.post('/meal-planner/complete/:id', ensureAuthenticated, async (req, res) =>
app.post('/meal-planner/delete/:id', ensureAuthenticated, async (req, res) => {
try {
await db.MealPlan.destroy({
where: { id: req.params.id, user_id: req.user.id }
where: { id: req.params.id, UserId: req.user.id }
});
req.flash('success_msg', 'Meal plan deleted');
res.redirect('/meal-planner');