package server import ( "encoding/json" "fmt" "net/http" "strconv" "github.com/a-h/templ" "github.com/gin-gonic/gin" domainRecipe "github.com/haydenhargreaves/Potion/internal/domain/recipe" domain "github.com/haydenhargreaves/Potion/internal/domain/server" "github.com/haydenhargreaves/Potion/internal/templates/components" layouts "github.com/haydenhargreaves/Potion/internal/templates/layouts" pages "github.com/haydenhargreaves/Potion/internal/templates/pages" ) func (s *Server) LoginPageHandler(ctx *gin.Context) { title := "Potion - Login" page := pages.LoginPage() ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page)) } func (s *Server) HomePageHandler(ctx *gin.Context) { loggedIn := domain.IsLoggedIn(ctx) // Ensure user is logged in with a valid account if user := s.deps.UserService.GetAuthenicatedUser(ctx); user == nil { // Log (stale) user out s.SetCookie(ctx, "jwt_token", "", -1) s.SetCookie(ctx, "search-filters", "", -1) loggedIn = false } var page templ.Component if loggedIn { userId := ctx.MustGet("userId").(int) madeRecipes, err := s.deps.RecipeService.GetUserMadeRecipes(userId, 6) if err != nil { components.RenderErrorBanner(ctx, fmt.Sprintf("Error getting made recipes. %s\n", err.Error())) ctx.JSON(http.StatusInternalServerError, gin.H{ "status": http.StatusInternalServerError, "message": fmt.Sprintf("Error getting made recipes. %s\n", err.Error()), }) return } viewedRecipes, err := s.deps.RecipeService.GetUserViewedRecipes(userId, 6) if err != nil { components.RenderErrorBanner(ctx, fmt.Sprintf("Error getting viewed recipes. %s\n", err.Error())) ctx.JSON(http.StatusInternalServerError, gin.H{ "status": http.StatusInternalServerError, "message": fmt.Sprintf("Error getting viewed recipes. %s\n", err.Error()), }) return } // Get the recipe of the week recipeOfTheWeek, err := s.deps.RecipeService.GetRecipeOfTheWeek(&userId) if err != nil { components.RenderErrorBanner(ctx, fmt.Sprintf("Error getting recipe of the week. %s\n", err.Error())) ctx.JSON(http.StatusInternalServerError, gin.H{ "status": http.StatusInternalServerError, "message": fmt.Sprintf("Error getting recipe of the week. %s\n", err.Error()), }) return } if bytes, err := ctx.Cookie("search-filters"); err != nil { fmt.Printf("ERROR: Failed to get search-filter cookie. %s\n", err.Error()) page = pages.HomePage(true, viewedRecipes, madeRecipes, recipeOfTheWeek, nil) } else { var filters domainRecipe.SearchFilters if err := json.Unmarshal([]byte(bytes), &filters); err != nil { fmt.Printf("ERROR: Failed to unmarshal search-filter cookie. %s\n", err.Error()) page = pages.HomePage(true, viewedRecipes, madeRecipes, recipeOfTheWeek, nil) } else { page = pages.HomePage(true, viewedRecipes, madeRecipes, recipeOfTheWeek, &filters) } } } else { // Get the recipe of the week recipeOfTheWeek, err := s.deps.RecipeService.GetRecipeOfTheWeek(nil) if err != nil { components.RenderErrorBanner(ctx, fmt.Sprintf("Error getting recipe of the week. %s\n", err.Error())) ctx.JSON(http.StatusInternalServerError, gin.H{ "status": http.StatusInternalServerError, "message": fmt.Sprintf("Error getting recipe of the week. %s\n", err.Error()), }) return } if bytes, err := ctx.Cookie("search-filters"); err != nil { fmt.Printf("ERROR: Failed to get search-filter cookie. %s\n", err.Error()) page = pages.HomePage(false, nil, nil, recipeOfTheWeek, nil) } else { var filters domainRecipe.SearchFilters if err := json.Unmarshal([]byte(bytes), &filters); err != nil { fmt.Printf("ERROR: Failed to unmarshal search-filter cookie. %s\n", err.Error()) page = pages.HomePage(false, nil, nil, recipeOfTheWeek, nil) } else { page = pages.HomePage(false, nil, nil, recipeOfTheWeek, &filters) } } } title := "Potion - Home" ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page)) } func (s *Server) FavoritesPageHandler(ctx *gin.Context) { // If not logged in, direct to the login page if !domain.IsLoggedIn(ctx) { ctx.Redirect(http.StatusSeeOther, domain.WEB_LOGIN) return } title := "Potion - Favorites" var page templ.Component // Get filters from cookies if bytes, err := ctx.Cookie("search-filters"); err != nil { fmt.Printf("ERROR: Failed to get search-filter cookie. %s\n", err.Error()) page = pages.FavoritesPage(nil) } else { var filters domainRecipe.SearchFilters if err := json.Unmarshal([]byte(bytes), &filters); err != nil { fmt.Printf("ERROR: Failed to unmarshal search-filter cookie. %s\n", err.Error()) page = pages.FavoritesPage(nil) } else { page = pages.FavoritesPage(&filters) } } ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page)) } func (s *Server) CreatePageHandler(ctx *gin.Context) { // If not logged in, direct to the login page if !domain.IsLoggedIn(ctx) { ctx.Redirect(http.StatusSeeOther, domain.WEB_LOGIN) return } // Ensure user is logged in with a valid account if user := s.deps.UserService.GetAuthenicatedUser(ctx); user == nil { // Log (stale) user out s.SetCookie(ctx, "jwt_token", "", -1) s.SetCookie(ctx, "search-filters", "", -1) ctx.Redirect(http.StatusSeeOther, domain.WEB_LOGIN) return } title := "Potion - Create" page := pages.CreatePage() ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page)) } func (s *Server) ProfilePageHandler(ctx *gin.Context) { // If not logged in, direct to the login page if !domain.IsLoggedIn(ctx) { ctx.Redirect(http.StatusSeeOther, domain.WEB_LOGIN) return } // Else, get the user data user := s.deps.UserService.GetAuthenicatedUser(ctx) if user == nil { // User is failing to be found, direct to the login page ctx.Redirect(http.StatusSeeOther, domain.WEB_LOGIN) return } recipes, err := s.deps.RecipeService.GetUserRecipes(user.Id) if err != nil { components.RenderErrorBanner(ctx, fmt.Sprintf("Error getting recipes. %s\n", err.Error())) ctx.JSON(http.StatusInternalServerError, gin.H{ "status": http.StatusInternalServerError, "message": fmt.Sprintf("Error getting recipes. %s\n", err.Error()), }) return } favorites, err := s.deps.RecipeService.GetUserFavoriteRecipes(user.Id) if err != nil { components.RenderErrorBanner(ctx, fmt.Sprintf("Error getting favorite recipes. %s\n", err.Error())) ctx.JSON(http.StatusInternalServerError, gin.H{ "status": http.StatusInternalServerError, "message": fmt.Sprintf("Error getting favorite recipes. %s\n", err.Error()), }) return } // Get the engagement data, not sure what will happen when errors occur engagements, err := s.deps.EngagementService.GetUserEngagement(user.Id, 6) if err != nil { components.RenderErrorBanner(ctx, fmt.Sprintf("Error getting user engagements. %s\n", err.Error())) ctx.JSON(http.StatusInternalServerError, gin.H{ "status": http.StatusInternalServerError, "message": fmt.Sprintf("Error getting user engagements. %s\n", err.Error()), }) return } title := "Potion - Profile" page := pages.ProfilePage(*user, recipes, favorites, engagements) ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page)) } func (s *Server) ListPageHandler(ctx *gin.Context) { title := "Potion - Shopping List" page := pages.ListPage() ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page)) } func (s *Server) RecipePageHandler(ctx *gin.Context) { // Call recipe service to get via ID id := ctx.Param("id") // Parse ID parsed, err := strconv.Atoi(id) if err != nil { components.RenderErrorBanner(ctx, fmt.Sprintf("ERROR: %s", err.Error())) ctx.JSON(400, err.Error()) return } // Get signed in user, if they exist var userId *int = nil var loggedIn = domain.IsLoggedIn(ctx) // Ensure user is logged in with a valid account if user := s.deps.UserService.GetAuthenicatedUser(ctx); user == nil { // Log (stale) user out s.SetCookie(ctx, "jwt_token", "", -1) s.SetCookie(ctx, "search-filters", "", -1) loggedIn = false } if loggedIn { storeId := ctx.MustGet("userId").(int) userId = &storeId } // Get recipe recipe, err := s.deps.RecipeService.GetRecipe(parsed, userId) if err != nil { components.RenderErrorBanner(ctx, fmt.Sprintf("ERROR: %s", err.Error())) ctx.JSON(400, err.Error()) return } // Get user (owner) user, err := s.deps.UserService.GetUser(recipe.UserId) if err != nil { components.RenderErrorBanner(ctx, fmt.Sprintf("ERROR: %s", err.Error())) ctx.JSON(400, err.Error()) return } title := "Potion - View Recipe" page := pages.RecipePage(*recipe, *user, loggedIn, s.deps.EnvironmentConfig.Domain) ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page)) } func (s *Server) SearchPageHandler(ctx *gin.Context) { var page templ.Component // Get filters from cookies if bytes, err := ctx.Cookie("search-filters"); err != nil { fmt.Printf("ERROR: Failed to get search-filter cookie. %s\n", err.Error()) page = pages.SearchPage(nil, false) } else { var filters domainRecipe.SearchFilters if err := json.Unmarshal([]byte(bytes), &filters); err != nil { fmt.Printf("ERROR: Failed to unmarshal search-filter cookie. %s\n", err.Error()) page = pages.SearchPage(nil, false) } else { page = pages.SearchPage(&filters, true) } } title := "Potion - Recipe Search" ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page)) } func (s *Server) NotFoundPageHandler(ctx *gin.Context) { title := "Potion - Not Found" page := pages.NotFoundPage() ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page)) }