package handlers 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" domainServer "github.com/haydenhargreaves/Potion/internal/domain/server" layouts "github.com/haydenhargreaves/Potion/internal/templates/layouts" pages "github.com/haydenhargreaves/Potion/internal/templates/pages" templates "github.com/haydenhargreaves/Potion/internal/templates/pages" ) func LoginPage(ctx *gin.Context) { title := "Potion - Login" page := pages.LoginPage() ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page)) } func HomePage(ctx *gin.Context) { deps := ctx.MustGet("deps").(*domainServer.InjectedDependencies) loggedIn := domain.IsLoggedIn(ctx) var page templ.Component if loggedIn { userId := ctx.MustGet("userId").(int) madeRecipes, err := deps.RecipeService.GetUserMadeRecipes(userId, 6) if err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{ "status": http.StatusInternalServerError, "message": fmt.Sprintf("Error getting made recipes. %s\n", err.Error()), }) return } viewedRecipes, err := deps.RecipeService.GetUserViewedRecipes(userId, 6) if err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{ "status": http.StatusInternalServerError, "message": fmt.Sprintf("Error getting made recipes. %s\n", err.Error()), }) return } // Get the recipe of the week recipeOfTheWeek, err := deps.RecipeService.GetRecipeOfTheWeek(&userId) if err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{ "status": http.StatusInternalServerError, "message": fmt.Sprintf("Error getting made recipes. %s\n", err.Error()), }) return } page = templates.HomePage(true, viewedRecipes, madeRecipes, recipeOfTheWeek) } else { // Get the recipe of the week recipeOfTheWeek, err := deps.RecipeService.GetRecipeOfTheWeek(nil) if err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{ "status": http.StatusInternalServerError, "message": fmt.Sprintf("Error getting made recipes. %s\n", err.Error()), }) return } page = templates.HomePage(false, nil, nil, recipeOfTheWeek) } title := "Potion - Home" ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page)) } func FavoritesPage(ctx *gin.Context) { // If not logged in, direct to the login page if !domainServer.IsLoggedIn(ctx) { ctx.Redirect(http.StatusSeeOther, domainServer.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 CreatePage(ctx *gin.Context) { // If not logged in, direct to the login page if !domainServer.IsLoggedIn(ctx) { ctx.Redirect(http.StatusSeeOther, domainServer.WEB_LOGIN) return } title := "Potion - Create" page := pages.CreatePage() ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page)) } func ProfilePage(ctx *gin.Context) { // If not logged in, direct to the login page if !domainServer.IsLoggedIn(ctx) { ctx.Redirect(http.StatusSeeOther, domainServer.WEB_LOGIN) return } // Else, get the user data deps := ctx.MustGet("deps").(*domainServer.InjectedDependencies) user := deps.UserService.GetAuthenicatedUser(ctx) recipes, err := deps.RecipeService.GetUserRecipes(user.Id) if err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{ "status": http.StatusInternalServerError, "message": fmt.Sprintf("Error getting recipes. %s\n", err.Error()), }) return } favorites, err := deps.RecipeService.GetUserFavoriteRecipes(user.Id) if err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{ "status": http.StatusInternalServerError, "message": fmt.Sprintf("Error getting recipes. %s\n", err.Error()), }) return } // Get the engagement data, not sure what will happen when errors occur engagements, err := deps.EngagementService.GetUserEngagement(user.Id, 6) if err != nil { 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 ListPage(ctx *gin.Context) { title := "Potion - Shopping List" page := pages.ListPage() ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page)) } // TODO: Figure out how to handle errors, think we just need a simple display. func RecipePage(ctx *gin.Context) { // Call recipe service to get via ID deps := ctx.MustGet("deps").(*domainServer.InjectedDependencies) id := ctx.Param("id") // Parse ID parsed, err := strconv.Atoi(id) if err != nil { fmt.Printf("ERROR: %s\n", err.Error()) ctx.JSON(400, err.Error()) return } // Get signed in user, if they exist var userId *int = nil var loggedIn = domainServer.IsLoggedIn(ctx) if loggedIn { storeId := ctx.MustGet("userId").(int) userId = &storeId } // Get recipe recipe, err := deps.RecipeService.GetRecipe(parsed, userId) if err != nil { fmt.Printf("ERROR: %s\n", err.Error()) ctx.JSON(400, err.Error()) return } // Get user (owner) user, err := deps.UserService.GetUser(recipe.UserId) if err != nil { fmt.Printf("ERROR: %s\n", err.Error()) ctx.JSON(400, err.Error()) return } title := "Potion - View Recipe" page := pages.RecipePage(*recipe, *user, loggedIn, deps.EnvironmentConfig.Domain) ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page)) } func SearchPage(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 NotFoundPage(ctx *gin.Context) { title := "Potion - Not Found" page := pages.NotFoundPage() ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page)) }