package main import ( "fmt" "html/template" "log" "mealprep/auth" "mealprep/database" "mealprep/handlers" "net/http" "strings" ) func main() { // Print startup banner printBanner() // Initialize database if err := database.InitDB("mealprep.db"); err != nil { log.Fatalf("Failed to initialize database: %v", err) } defer database.DB.Close() log.Println("✅ Database initialized successfully") // Static files fs := http.FileServer(http.Dir("static")) http.Handle("/static/", http.StripPrefix("/static/", fs)) // Authentication routes (public) http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" { auth.RedirectIfAuthenticated(handlers.LoginPageHandler)(w, r) } else if r.Method == "POST" { handlers.LoginHandler(w, r) } else { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) } }) http.HandleFunc("/register", func(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" { auth.RedirectIfAuthenticated(handlers.RegisterPageHandler)(w, r) } else if r.Method == "POST" { handlers.RegisterHandler(w, r) } else { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) } }) http.HandleFunc("/logout", handlers.LogoutHandler) // Protected routes http.HandleFunc("/", auth.RequireAuth(indexHandler)) // Ingredients (protected) http.HandleFunc("/ingredients", auth.RequireAuth(func(w http.ResponseWriter, r *http.Request) { switch r.Method { case "GET": handlers.IngredientsHandler(w, r) case "POST": handlers.AddIngredientHandler(w, r) default: http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) } })) http.HandleFunc("/ingredients/", auth.RequireAuth(func(w http.ResponseWriter, r *http.Request) { if r.Method == "DELETE" { handlers.DeleteIngredientHandler(w, r) } else { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) } })) // Meals (protected) http.HandleFunc("/meals", auth.RequireAuth(func(w http.ResponseWriter, r *http.Request) { switch r.Method { case "GET": handlers.MealsHandler(w, r) case "POST": handlers.AddMealHandler(w, r) default: http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) } })) http.HandleFunc("/meals/", auth.RequireAuth(func(w http.ResponseWriter, r *http.Request) { path := r.URL.Path if strings.Contains(path, "/ingredients") { // Meal ingredients routes if r.Method == "GET" { handlers.GetMealIngredientsHandler(w, r) } else if r.Method == "POST" { handlers.AddMealIngredientHandler(w, r) } else if r.Method == "DELETE" { handlers.DeleteMealIngredientHandler(w, r) } else { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) } } else if strings.Contains(path, "/edit") { // Meal edit route if r.Method == "GET" { handlers.GetEditMealHandler(w, r) } else { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) } } else if strings.Contains(path, "/update") { // Meal update route if r.Method == "POST" { handlers.UpdateMealHandler(w, r) } else { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) } } else { // Meal delete route if r.Method == "DELETE" { handlers.DeleteMealHandler(w, r) } else { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) } } })) // Week Plan (protected) http.HandleFunc("/week-plan", auth.RequireAuth(func(w http.ResponseWriter, r *http.Request) { switch r.Method { case "GET": handlers.WeekPlanHandler(w, r) case "POST": handlers.AddWeekPlanEntryHandler(w, r) default: http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) } })) http.HandleFunc("/week-plan/", auth.RequireAuth(func(w http.ResponseWriter, r *http.Request) { if r.Method == "DELETE" { handlers.DeleteWeekPlanEntryHandler(w, r) } else { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) } })) // Grocery List (protected) http.HandleFunc("/grocery-list", auth.RequireAuth(func(w http.ResponseWriter, r *http.Request) { if r.Method == "GET" { handlers.GroceryListHandler(w, r) } else { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) } })) // Start server port := "8080" fmt.Println() log.Printf("🚀 Server running on http://localhost:%s", port) log.Println("📝 Press Ctrl+C to stop the server") fmt.Println() if err := http.ListenAndServe(":"+port, nil); err != nil { log.Fatalf("❌ Failed to start server: %v", err) } } func printBanner() { banner := ` ╔══════════════════════════════════════════════════════════════╗ ║ ║ ║ 🍽️ MEAL PREP PLANNER 🍽️ ║ ║ ║ ║ Plan your meals • Generate grocery lists ║ ║ ║ ╚══════════════════════════════════════════════════════════════╝ ` fmt.Println(banner) log.Println("🔧 Initializing application...") } func indexHandler(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/" { http.NotFound(w, r) return } tmpl := `