package handlers
import (
"html/template"
"mealprep/auth"
"mealprep/database"
"net/http"
"strconv"
"strings"
"time"
)
// WeekPlanHandler handles the week plan page
func WeekPlanHandler(w http.ResponseWriter, r *http.Request) {
userID := auth.GetUserID(r)
weekPlan, err := database.GetWeekPlan(userID)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
meals, err := database.GetAllMeals(userID)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Group by date
planByDate := make(map[string][]interface{})
for _, entry := range weekPlan {
dateStr := entry.Date.Format("2006-01-02")
planByDate[dateStr] = append(planByDate[dateStr], entry)
}
// Get next 7 days starting from upcoming Monday (or current Monday if today is Monday)
today := time.Now()
// Calculate the upcoming Monday
// If today is Monday, use today. Otherwise, find next Monday.
weekday := int(today.Weekday())
daysUntilMonday := (8 - weekday) % 7
if weekday == 1 { // Today is Monday
daysUntilMonday = 0
}
startDate := today.AddDate(0, 0, daysUntilMonday)
var dates []string
for i := 0; i < 7; i++ {
date := startDate.AddDate(0, 0, i)
dates = append(dates, date.Format("2006-01-02"))
}
tmpl := `
Week Plan
Planning week: {{.WeekStart}} - {{.WeekEnd}}
{{range $index, $date := .Dates}}
{{formatDate $date}}
{{$entries := index $.PlanByDate $date}}
{{range $entries}}
{{if eq .MealType "breakfast"}}
{{.MealName}}
{{end}}
{{end}}
{{$entries := index $.PlanByDate $date}}
{{range $entries}}
{{if eq .MealType "lunch"}}
{{.MealName}}
{{end}}
{{end}}
{{$entries := index $.PlanByDate $date}}
{{range $entries}}
{{if eq .MealType "snack"}}
{{.MealName}}
{{end}}
{{end}}
{{end}}
`
funcMap := template.FuncMap{
"formatDate": func(dateStr string) string {
date, _ := time.Parse("2006-01-02", dateStr)
// Show full date with day name
return date.Format("Monday, Jan 2")
},
"index": func(m map[string][]interface{}, key string) []interface{} {
return m[key]
},
}
// Format week range for display
weekStart := startDate.Format("Mon, Jan 2")
weekEnd := startDate.AddDate(0, 0, 6).Format("Mon, Jan 2")
// Separate meals by type
var breakfastMeals, lunchMeals, snackMeals []interface{}
for _, meal := range meals {
switch meal.MealType {
case "breakfast":
breakfastMeals = append(breakfastMeals, meal)
case "lunch":
lunchMeals = append(lunchMeals, meal)
case "snack":
snackMeals = append(snackMeals, meal)
}
}
data := struct {
Dates []string
PlanByDate map[string][]interface{}
BreakfastMeals interface{}
LunchMeals interface{}
SnackMeals interface{}
WeekStart string
WeekEnd string
}{
Dates: dates,
PlanByDate: planByDate,
BreakfastMeals: breakfastMeals,
LunchMeals: lunchMeals,
SnackMeals: snackMeals,
WeekStart: weekStart,
WeekEnd: weekEnd,
}
t := template.Must(template.New("weekplan").Funcs(funcMap).Parse(tmpl))
t.Execute(w, data)
}
// AddWeekPlanEntryHandler adds a meal to a specific day
func AddWeekPlanEntryHandler(w http.ResponseWriter, r *http.Request) {
userID := auth.GetUserID(r)
if err := r.ParseForm(); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
dateStr := r.FormValue("date")
mealType := r.FormValue("meal_type")
mealID, err := strconv.Atoi(r.FormValue("meal_id"))
if err != nil {
http.Error(w, "Invalid meal ID", http.StatusBadRequest)
return
}
// Validate meal type
if mealType != "breakfast" && mealType != "lunch" && mealType != "snack" {
http.Error(w, "Invalid meal type", http.StatusBadRequest)
return
}
date, err := time.Parse("2006-01-02", dateStr)
if err != nil {
http.Error(w, "Invalid date", http.StatusBadRequest)
return
}
if err := database.AddWeekPlanEntry(userID, date, mealID); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Get the meal details
meal, err := database.GetMealByID(userID, mealID)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Verify meal type matches
if meal.MealType != mealType {
http.Error(w, "Meal type does not match", http.StatusBadRequest)
return
}
// Get the ID of the entry we just added
weekPlan, err := database.GetWeekPlan(userID)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
var entryID int
for _, entry := range weekPlan {
if entry.Date.Format("2006-01-02") == dateStr && entry.MealID == mealID {
entryID = entry.ID
}
}
tmpl := `