diff --git a/internal/app/handlers/page_handler.go b/internal/app/handlers/page_handler.go index cadcee1..26c43a3 100644 --- a/internal/app/handlers/page_handler.go +++ b/internal/app/handlers/page_handler.go @@ -29,8 +29,41 @@ func HomePage(ctx *gin.Context) { } 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" - page := pages.FavoritesPage() + 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(domainRecipe.SearchFilters{}) + } 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(domainRecipe.SearchFilters{}) + } else { + page = pages.FavoritesPage(filters) + } + } + + // Else, get the user's favorites + // BUG: Depreciated, not displaying a list, using search to drive this page as well + // deps := ctx.MustGet("deps").(*domainServer.InjectedDependencies) + // userId := ctx.MustGet("userId").(int) + // recipes, err := deps.RecipeService.GetUserFavoriteRecipes(userId) + // if err != nil { + // ctx.JSON(http.StatusInternalServerError, gin.H{ + // "status": http.StatusInternalServerError, + // "message": fmt.Sprintf("Error getting favorites. %s\n", err.Error()), + // }) + // return + // } ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page)) } @@ -67,6 +100,15 @@ func ProfilePage(ctx *gin.Context) { 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 { @@ -78,7 +120,7 @@ func ProfilePage(ctx *gin.Context) { } title := "Potion - Profile" - page := pages.ProfilePage(user, recipes, engagements) + page := pages.ProfilePage(user, recipes, favorites, engagements) ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page)) } diff --git a/internal/app/handlers/recipe_handler.go b/internal/app/handlers/recipe_handler.go index a256307..a37ffc2 100644 --- a/internal/app/handlers/recipe_handler.go +++ b/internal/app/handlers/recipe_handler.go @@ -47,6 +47,55 @@ func toBits(arr []string) (bits int) { func SearchRecipes(ctx *gin.Context) { deps := ctx.MustGet("deps").(*domain.InjectedDependencies) + // create filters + filters := domainRecipe.SearchFilters{ + Search: ctx.PostForm("search"), // string, search query for titles + MealType: toBits(ctx.PostFormArray("meal")), + Time: toBits(ctx.PostFormArray("time")), + Difficulty: toBits(ctx.PostFormArray("difficulty")), + ServingSize: toBits(ctx.PostFormArray("serving")), + } + + // Set the filters into the cookies, so they can be reloaded + if bytes, err := json.Marshal(filters); err == nil { + ctx.SetCookie( + "search-filters", + string(bytes), + int(time.Now().Add(24*time.Hour).Sub(time.Now()).Seconds()), + "/", + "", // TODO: Need an actual domain + false, // TODO: True in prod + true, + ) + } + + redirect := ctx.PostForm("redirect") + if redirect == "true" { + ctx.Header("HX-Redirect", domain.WEB_SEARCH) + ctx.Status(http.StatusOK) + return + } + + // Get user if logged in, so we can get favorite status + var userId *int = nil + if domain.IsLoggedIn(ctx) { + id := ctx.MustGet("userId").(int) + userId = &id + } + + // We don't care about favorite status, so use false + recipes, err := deps.RecipeService.SearchRecipes(filters, userId, false) + if err != nil { + ctx.JSON(http.StatusOK, gin.H{"error": err.Error()}) + } + + // Render content as the response + ctx.Status(200) + templates.ResultList(recipes).Render(ctx.Request.Context(), ctx.Writer) +} + +func SearchRecipesFavorites(ctx *gin.Context) { + deps := ctx.MustGet("deps").(*domain.InjectedDependencies) // create filters filters := domainRecipe.SearchFilters{ @@ -62,27 +111,24 @@ func SearchRecipes(ctx *gin.Context) { ctx.SetCookie( "search-filters", string(bytes), - int(time.Now().Add(24 * time.Hour).Sub(time.Now()).Seconds()), + int(time.Now().Add(24*time.Hour).Sub(time.Now()).Seconds()), "/", - "", // TODO: Need an actual domain - false, // TODO: True in prod + "", // TODO: Need an actual domain + false, // TODO: True in prod true, ) } - redirect := ctx.PostForm("redirect") - if redirect == "true" { - ctx.Header("HX-Redirect", domain.WEB_SEARCH) - ctx.Status(http.StatusOK) - return - } + // TODO: Error here if they're not logged in? + // Get user data (they should be logged in) + userId := ctx.MustGet("userId").(int) - recipes, err := deps.RecipeService.SearchRecipes(filters) + recipes, err := deps.RecipeService.SearchRecipes(filters, &userId, true) if err != nil { ctx.JSON(http.StatusOK, gin.H{"error": err.Error()}) } // Render content as the response ctx.Status(200) - templates.ResultList(recipes).Render(ctx.Request.Context(), ctx.Writer) + templates.FavoriteList(recipes).Render(ctx.Request.Context(), ctx.Writer) } diff --git a/internal/app/handlers/user_handler.go b/internal/app/handlers/user_handler.go index 261e199..c5508bf 100644 --- a/internal/app/handlers/user_handler.go +++ b/internal/app/handlers/user_handler.go @@ -47,3 +47,43 @@ func GetUserRecipes(ctx *gin.Context) { "recipes": recipes, }) } + +func GetUserFavoriteRecipes(ctx *gin.Context) { + deps := ctx.MustGet("deps").(*domain.InjectedDependencies) + + // Ensure logged in + if !domain.IsLoggedIn(ctx) { + ctx.JSON(http.StatusUnauthorized, gin.H{ + "status": http.StatusUnauthorized, + "message": "User is not authorized to access this endpoint. Please login to continue.", + "recipes": nil, + }) + return + } + + userId, ok := ctx.MustGet("userId").(int) + if !ok { + ctx.JSON(http.StatusInternalServerError, gin.H{ + "status": http.StatusInternalServerError, + "message": "Unable to access user id from store.", + "recipes": nil, + }) + return + } + + recipes, err := deps.RecipeService.GetUserFavoriteRecipes(userId) + if err != nil { + ctx.JSON(http.StatusBadRequest, gin.H{ + "status": http.StatusBadRequest, + "message": fmt.Sprintf("Could not get user recipes. %s", err.Error()), + "recipes": nil, + }) + return + } + + ctx.JSON(http.StatusOK, gin.H{ + "status": http.StatusOK, + "message": "User recipes successfully retrieved.", + "recipes": recipes, + }) +} diff --git a/internal/app/server/server.go b/internal/app/server/server.go index 091e464..325582a 100644 --- a/internal/app/server/server.go +++ b/internal/app/server/server.go @@ -184,7 +184,9 @@ func (s *Server) Setup() *Server { // Recipe endpoints router_api.POST("/recipe", handlers.CreateRecipe) router_api.POST("/recipe/search", handlers.SearchRecipes) + router_api.POST("/recipe/search/favorites", handlers.SearchRecipesFavorites) router_api.GET("/user/recipes", handlers.GetUserRecipes) + router_api.GET("/user/favorites", handlers.GetUserFavoriteRecipes) // Engagement endpoints router_api.POST("/engagement/view/:id", handlers.EngagementViewRecipe) diff --git a/internal/app/service/recipe_service.go b/internal/app/service/recipe_service.go index be4ba73..c0ceb3f 100644 --- a/internal/app/service/recipe_service.go +++ b/internal/app/service/recipe_service.go @@ -151,10 +151,20 @@ func (s *RecipeService) GetRecipe(id int, userId *int) (*domain.Recipe, error) { // the filter is provided. // A function `isBitActive` in the recipe repository provides an example of // testing of testing the filter parsing. -func (s *RecipeService) SearchRecipes(filters domain.SearchFilters) ([]domain.Recipe, error) { - return s.recipeRepository.SearchRecipes(filters) +// +// The favorites parameter is used to only return filters favorited by the userId provided. +func (s *RecipeService) SearchRecipes(filters domain.SearchFilters, userId *int, favorites bool) ([]domain.Recipe, error) { + return s.recipeRepository.SearchRecipes(filters, userId, favorites) } +// GetUserRecipes returns a list of the recipes that the user has created. The user's +// ID should be provided. Any errors will be bubbled to the caller. func (s *RecipeService) GetUserRecipes(id int) ([]domain.Recipe, error) { return s.recipeRepository.GetUserRecipes(id) } + +// GetUserFavoriteRecipes returns a list of the recipes that the user has marked as a +// favorite. The user's ID should be provided. Any errors will be bubbled to the caller. +func (s *RecipeService) GetUserFavoriteRecipes(id int) ([]domain.Recipe, error) { + return s.recipeRepository.GetUserFavoriteRecipes(id) +} diff --git a/internal/domain/recipe/repository.go b/internal/domain/recipe/repository.go index d1a3a6e..f0c69ad 100644 --- a/internal/domain/recipe/repository.go +++ b/internal/domain/recipe/repository.go @@ -3,9 +3,10 @@ package domain type RecipeRepository interface { CreateRecipe(recipe *Recipe) error GetRecipe(id int, userId *int) (*Recipe, error) - SearchRecipes(filters SearchFilters) ([]Recipe, error) + SearchRecipes(filters SearchFilters, userId *int, favorites bool) ([]Recipe, error) CreateRecipeTags(recipe Recipe, tags []string) error GetUserRecipes(id int) ([]Recipe, error) + GetUserFavoriteRecipes(id int) ([]Recipe, error) GetRecipeTags(recipe *Recipe) error GetRecipeFavorite(recipe *Recipe, userId int) error } diff --git a/internal/domain/recipe/service.go b/internal/domain/recipe/service.go index 33d919a..51d4bd6 100644 --- a/internal/domain/recipe/service.go +++ b/internal/domain/recipe/service.go @@ -5,6 +5,7 @@ import "github.com/gin-gonic/gin" type RecipeService interface { CreateRecipe(ctx *gin.Context) (*Recipe, error) GetRecipe(id int, userId *int) (*Recipe, error) - SearchRecipes(filters SearchFilters) ([]Recipe, error) + SearchRecipes(filters SearchFilters, userId *int, favorites bool) ([]Recipe, error) GetUserRecipes(id int) ([]Recipe, error) + GetUserFavoriteRecipes(id int) ([]Recipe, error) } diff --git a/internal/domain/server/routes.go b/internal/domain/server/routes.go index b6823da..19053ce 100644 --- a/internal/domain/server/routes.go +++ b/internal/domain/server/routes.go @@ -24,6 +24,7 @@ const API_AUTH_CALLBACK = VERSION + API + "/auth/callback" const API_AUTH_LOGOUT = VERSION + API + "/auth/logout" const API_CREATE_RECIPE = VERSION + API + "/recipe" const API_SEARCH_RECIPES = VERSION + API + "/recipe/search" +const API_SEARCH_FAVORITES = VERSION + API + "/recipe/search/favorites" const API_ENGAGEMENT_VIEW = VERSION + API + "/engagement/view/%d" const API_ENGAGEMENT_SHARE = VERSION + API + "/engagement/share/%d" diff --git a/internal/infrastructure/database/repository/recipe_repository.go b/internal/infrastructure/database/repository/recipe_repository.go index a0a578d..eb3c542 100644 --- a/internal/infrastructure/database/repository/recipe_repository.go +++ b/internal/infrastructure/database/repository/recipe_repository.go @@ -184,8 +184,10 @@ func isBitActive(bits, pos int) bool { // description can be found in the recipe service implementation. Any errors will be bubbled to the // caller. // +// The favorites parameter is used to only return filters favorited by the userId provided. +// // TODO: Pagination is required, to provide infinite scroll. -func (r *RecipeRepository) SearchRecipes(filters domain.SearchFilters) ([]domain.Recipe, error) { +func (r *RecipeRepository) SearchRecipes(filters domain.SearchFilters, userId *int, favorites bool) ([]domain.Recipe, error) { tx, err := r.db.Begin() if err != nil { tx.Rollback() @@ -274,20 +276,25 @@ func (r *RecipeRepository) SearchRecipes(filters domain.SearchFilters) ([]domain // Define columns to select. More fields can be added if the full text search is required columns := []string{ - "id", - "title", - "description", - "instructions", - "serves", - "difficulty", - "duration", - "category", - "ingredients", - "userid", - "modified", - "created", + "r.id", + "r.title", + "r.description", + "r.instructions", + "r.serves", + "r.difficulty", + "r.duration", + "r.category", + "r.ingredients", + "r.userid", + "r.modified", + "r.created", } + // TODO: Need to add these to the query + + // FROM ... JOIN favorites f ON f.recipeId = r.id + // WHERE ... AND f.userId = 3 + // Create search vector query var orderBy string = "" if filters.Search != "" { @@ -295,19 +302,30 @@ func (r *RecipeRepository) SearchRecipes(filters domain.SearchFilters) ([]domain conditions = append( conditions, - fmt.Sprintf("search_vector @@ to_tsquery('english', '%s')", vector_query), + fmt.Sprintf("r.search_vector @@ to_tsquery('english', '%s')", vector_query), ) template := ` ORDER BY - ts_rank(search_vector, to_tsquery('english', '%s')) DESC, - ts_rank_cd(search_vector, to_tsquery('english', '%s')) DESC + ts_rank(r.search_vector, to_tsquery('english', '%s')) DESC, + ts_rank_cd(r.search_vector, to_tsquery('english', '%s')) DESC ` orderBy = fmt.Sprintf(template, vector_query, vector_query) } // Generate the query - query := fmt.Sprintf("SELECT %s FROM recipes", strings.Join(columns, ",")) + var query string + if favorites && userId != nil { + query = fmt.Sprintf( + "SELECT %s FROM recipes r JOIN favorites f ON f.recipeId = r.id", + strings.Join(columns, ","), + ) + + // Add new favorite condition to the conditions list + conditions = append(conditions, fmt.Sprintf("f.userid = %d", *userId)) + } else { + query = fmt.Sprintf("SELECT %s FROM recipes r", strings.Join(columns, ",")) + } // Convert and append conditions if provided if len(conditions) > 0 { @@ -381,6 +399,17 @@ func (r *RecipeRepository) SearchRecipes(filters domain.SearchFilters) ([]domain fmt.Printf("ERROR getting recipe tags. %s\n", err.Error()) } + // Add recipe if not a favorite search + if !favorites && userId != nil { + if err := r.GetRecipeFavorite(&recipe, *userId); err != nil { + fmt.Printf("ERROR getting recipe tags. %s\n", err.Error()) + } + } + + if favorites { + recipe.Favorite = true + } + recipes = append(recipes, recipe) } @@ -548,6 +577,94 @@ func (r *RecipeRepository) GetUserRecipes(id int) ([]domain.Recipe, error) { return recipes, nil } +func (r *RecipeRepository) GetUserFavoriteRecipes(id int) ([]domain.Recipe, error) { + tx, err := r.db.Begin() + if err != nil { + tx.Rollback() + return nil, err + } + + query := ` + SELECT r.id, r.title, r.description, r.instructions, r.serves, r.difficulty, r.duration, r.category, r.ingredients, r. + userid, r.modified, r.created + FROM favorites f + JOIN recipes r ON r.id = f.recipeid + WHERE f.userid = $1 + ORDER BY f.created DESC; + ` + rows, err := tx.Query(query, id) + if err != nil { + return nil, fmt.Errorf("Failed to query DB for user recipes. %s\n", err.Error()) + } + defer rows.Close() + + var recipes []domain.Recipe + for rows.Next() { + var recipe domain.Recipe + var durationBytes []byte + var ingredientBytes []byte + + // Scan results from recipe query onto recipe object + if err := rows.Scan( + &recipe.Id, + &recipe.Title, + &recipe.Description, + pq.Array(&recipe.Instructions), + &recipe.Serves, + &recipe.Difficulty, + &durationBytes, + &recipe.Category, + &ingredientBytes, + &recipe.UserId, + &recipe.Modified, + &recipe.Created, + ); err != nil { + return nil, fmt.Errorf("Failed to scan row onto recipe object. %s\n", err.Error()) + } + + // Parse duration + if len(durationBytes) > 0 { + var duration domain.RecipeDuration + if err := json.Unmarshal(durationBytes, &duration); err != nil { + return nil, fmt.Errorf("Failed to parse duration from database: %s", err.Error()) + } + + recipe.Duration = duration + } else { + recipe.Duration = domain.RecipeDuration{} + } + + // Parse ingredient + if len(ingredientBytes) > 0 { + var ingredients []domain.RecipeIngredient + if err := json.Unmarshal(ingredientBytes, &ingredients); err != nil { + return nil, fmt.Errorf("Failed to parse ingredients from database: %s", err.Error()) + } + + recipe.Ingredients = ingredients + } else { + recipe.Ingredients = []domain.RecipeIngredient{} + } + + // Add tags + if err := r.GetRecipeTags(&recipe); err != nil { + fmt.Printf("ERROR getting recipe tags. %s\n", err.Error()) + } + + // Set favorite status (they're always true!) + recipe.Favorite = true + + recipes = append(recipes, recipe) + } + + if err := tx.Commit(); err != nil { + tx.Rollback() + return nil, err + } + + return recipes, nil +} + // GetRecipeTags requires a recipe to be filled with at least an ID. This function will use the ID // defined in the provided recipe to fill the Tags array with the recipe's tags from the database. // The recipe is modified in place and is not returned. Any errors will be bubbled to the caller. diff --git a/internal/templates/components/search_bar.templ b/internal/templates/components/search_bar.templ index 3d4071f..a2e5613 100644 --- a/internal/templates/components/search_bar.templ +++ b/internal/templates/components/search_bar.templ @@ -3,9 +3,13 @@ package components import domainServer "github.com/haydenhargreaves/Potion/internal/domain/server" import domainRecipe "github.com/haydenhargreaves/Potion/internal/domain/recipe" -templ SearchBar(filters domainRecipe.SearchFilters, redirect bool, searchOnLoad bool) { +templ SearchBar(filters domainRecipe.SearchFilters, redirect, searchOnLoad, favorites bool) {
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\">
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -94,7 +122,7 @@ func SearchBar(filters domainRecipe.SearchFilters, redirect bool, searchOnLoad b if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -102,7 +130,7 @@ func SearchBar(filters domainRecipe.SearchFilters, redirect bool, searchOnLoad b if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -126,12 +154,12 @@ func filterButton() templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var5 := templ.GetChildren(ctx) - if templ_7745c5c3_Var5 == nil { - templ_7745c5c3_Var5 = templ.NopComponent + templ_7745c5c3_Var6 := templ.GetChildren(ctx) + if templ_7745c5c3_Var6 == nil { + templ_7745c5c3_Var6 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/internal/templates/pages/favorites.templ b/internal/templates/pages/favorites.templ index 853262f..230931c 100644 --- a/internal/templates/pages/favorites.templ +++ b/internal/templates/pages/favorites.templ @@ -1,15 +1,73 @@ package templates +import "fmt" import "github.com/haydenhargreaves/Potion/internal/templates/components" +import "github.com/haydenhargreaves/Potion/internal/domain/recipe" +import domainServer "github.com/haydenhargreaves/Potion/internal/domain/server" -templ FavoritesPage() { -@components.Navbar("favorites") -
-
-
-

Page Under Construction

-

Sit tight, this page is coming soon!

+templ FavoriteList(recipes []domain.Recipe) { +
+ for _, recipe := range recipes { + @favoriteResult(recipe) + } + if len(recipes) == 0 || recipes == nil { +

No results

+ } else { +

End of results

+ } +
+} + +templ favoriteResult(recipe domain.Recipe) { +
+ +
+
+
+

+ { recipe.Title } +

+
+ + @timeIconSm() + { recipe.Duration.Total } min + + + for _ = range(recipe.Difficulty) { + @starIconSm(true) + } + for _ = range(5 - recipe.Difficulty) { + @starIconSm(false) + } + + + @servingIconSm() + Serves { recipe.Serves } + +
+
+
+

{ recipe.Description }

+
+
+} + +templ FavoritesPage(filters domain.SearchFilters) { +@components.Navbar("favorites") +
+
+ @components.BannerText("Favorites") + @components.SearchBar(filters, false, true, true) +
+ @FavoriteList(nil)
} diff --git a/internal/templates/pages/favorites_templ.go b/internal/templates/pages/favorites_templ.go index a09f819..7f56398 100644 --- a/internal/templates/pages/favorites_templ.go +++ b/internal/templates/pages/favorites_templ.go @@ -8,9 +8,12 @@ package templates import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" +import "fmt" import "github.com/haydenhargreaves/Potion/internal/templates/components" +import "github.com/haydenhargreaves/Potion/internal/domain/recipe" +import domainServer "github.com/haydenhargreaves/Potion/internal/domain/server" -func FavoritesPage() templ.Component { +func FavoriteList(recipes []domain.Recipe) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { @@ -31,11 +34,216 @@ func FavoritesPage() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, recipe := range recipes { + templ_7745c5c3_Err = favoriteResult(recipe).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + if len(recipes) == 0 || recipes == nil { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "

No results

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "

End of results

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func favoriteResult(recipe domain.Recipe) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var2 := templ.GetChildren(ctx) + if templ_7745c5c3_Var2 == nil { + templ_7745c5c3_Var2 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(recipe.Title) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/favorites.templ`, Line: 29, Col: 24} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = timeIconSm().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var6 string + templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(recipe.Duration.Total) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/favorites.templ`, Line: 34, Col: 35} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, " min ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _ = range recipe.Difficulty { + templ_7745c5c3_Err = starIconSm(true).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + for _ = range 5 - recipe.Difficulty { + templ_7745c5c3_Err = starIconSm(false).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = servingIconSm().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "Serves ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var7 string + templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(recipe.Serves) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/favorites.templ`, Line: 46, Col: 34} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var8 string + templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(recipe.Description) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/favorites.templ`, Line: 58, Col: 73} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +func FavoritesPage(filters domain.SearchFilters) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var9 := templ.GetChildren(ctx) + if templ_7745c5c3_Var9 == nil { + templ_7745c5c3_Var9 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) templ_7745c5c3_Err = components.Navbar("favorites").Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

Page Under Construction

Sit tight, this page is coming soon!

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = components.BannerText("Favorites").Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = components.SearchBar(filters, false, true, true).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = FavoriteList(nil).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/internal/templates/pages/home.templ b/internal/templates/pages/home.templ index 09bf1c3..24ff670 100644 --- a/internal/templates/pages/home.templ +++ b/internal/templates/pages/home.templ @@ -5,106 +5,112 @@ import "github.com/haydenhargreaves/Potion/internal/domain/server" import domainRecipe "github.com/haydenhargreaves/Potion/internal/domain/recipe" templ introSection() { -
-
- -

- Discover Your Next Favorite Meal -

-
-

- Welcome to your ultimate recipe hub! Whether you're a seasoned chef or just starting your culinary adventure, - we're here to inspire. Explore thousands of delicious recipes, from quick weeknight dinners to gourmet delights, - all at your fingertips. Find exactly what you're craving with our powerful search and intuitive filters, or - browse our trending dishes for fresh ideas. -

-
+
+
+ +

+ Discover Your Next Favorite Meal +

+
+

+ Welcome to your ultimate recipe hub! Whether you're a seasoned chef or just starting your culinary adventure, + we're here to inspire. Explore thousands of delicious recipes, from quick weeknight dinners to gourmet delights, + all at your fingertips. Find exactly what you're craving with our powerful search and intuitive filters, or + browse our trending dishes for fresh ideas. +

+
} templ searchSection() { -
- @components.BannerText("Craving Something Specific?") -
- @components.SearchBar(domainRecipe.SearchFilters{}, true, false) -
- -
+
+ @components.BannerText("Craving Something Specific?") +
+ @components.SearchBar(domainRecipe.SearchFilters{}, true, false, false) +
+ +
} templ highlightSection(liked bool) { -
- @components.BannerText("Recipe of the Week!") -

- Our 'Recipe of the Week' is the cream of the crop! We handpick it by looking at what recipes - our community loves most. This isn't just about how many people view a recipe; it's also about - how many times it's been made, liked, reviewed, and its average rating, all combined to find - the true fan favorite of the week. It's our way of highlighting the best recipes that truly - resonate with our users! -

-
- @components.RecipeCardLarge(false) -
-
+
+ @components.BannerText("Recipe of the Week!") +

+ Our 'Recipe of the Week' is the cream of the crop! We handpick it by looking at what recipes + our community loves most. This isn't just about how many people view a recipe; it's also about + how many times it's been made, liked, reviewed, and its average rating, all combined to find + the true fan favorite of the week. It's our way of highlighting the best recipes that truly + resonate with our users! +

+
+ @components.RecipeCardLarge(false) +
+
} templ listsSection() { -
- @components.BannerText("Take Another Look.") -
-

Recently viewed

-
- @components.RecipeCardSmall("Avocado Toast", "Breakfast - 15 min", "Hayden Hargreaves", true) - @components.RecipeCardSmall("Fried Chicken", "Dinner - 120 min", "Hayden Hargreaves", false) - @components.RecipeCardSmall("Classic Butter Chicken", "Dinner - 60 min", "Hayden Hargreaves", false) - @components.RecipeCardSmall("Avocado Toast", "Breakfast - 15 min", "Hayden Hargreaves", true) - @components.RecipeCardSmall("Fried Chicken", "Dinner - 120 min", "Hayden Hargreaves", false) - @components.RecipeCardSmall("Classic Butter Chicken", "Dinner - 60 min", "Hayden Hargreaves", false) -
-

Make again

-
- @components.RecipeCardSmall("Avocado Toast", "Breakfast - 15 min", "Hayden Hargreaves", true) - @components.RecipeCardSmall("Fried Chicken", "Dinner - 120 min", "Hayden Hargreaves", false) - @components.RecipeCardSmall("Classic Butter Chicken", "Dinner - 60 min", "Hayden Hargreaves", false) - @components.RecipeCardSmall("Avocado Toast", "Breakfast - 15 min", "Hayden Hargreaves", true) - @components.RecipeCardSmall("Fried Chicken", "Dinner - 120 min", "Hayden Hargreaves", false) - @components.RecipeCardSmall("Classic Butter Chicken", "Dinner - 60 min", "Hayden Hargreaves", false) -
-
-
+
+ @components.BannerText("Take Another Look.") +
+

Recently viewed

+
+ @components.RecipeCardSmall("Avocado Toast", "Breakfast - 15 min", "Hayden Hargreaves", true) + @components.RecipeCardSmall("Fried Chicken", "Dinner - 120 min", "Hayden Hargreaves", false) + @components.RecipeCardSmall("Classic Butter Chicken", "Dinner - 60 min", "Hayden Hargreaves", false) + @components.RecipeCardSmall("Avocado Toast", "Breakfast - 15 min", "Hayden Hargreaves", true) + @components.RecipeCardSmall("Fried Chicken", "Dinner - 120 min", "Hayden Hargreaves", false) + @components.RecipeCardSmall("Classic Butter Chicken", "Dinner - 60 min", "Hayden Hargreaves", false) +
+

Make again

+
+ @components.RecipeCardSmall("Avocado Toast", "Breakfast - 15 min", "Hayden Hargreaves", true) + @components.RecipeCardSmall("Fried Chicken", "Dinner - 120 min", "Hayden Hargreaves", false) + @components.RecipeCardSmall("Classic Butter Chicken", "Dinner - 60 min", "Hayden Hargreaves", false) + @components.RecipeCardSmall("Avocado Toast", "Breakfast - 15 min", "Hayden Hargreaves", true) + @components.RecipeCardSmall("Fried Chicken", "Dinner - 120 min", "Hayden Hargreaves", false) + @components.RecipeCardSmall("Classic Butter Chicken", "Dinner - 60 min", "Hayden Hargreaves", false) +
+
+
} templ ctaSection() { -
-

- Unleash Your Inner Chef! -

-

- Have a unique recipe idea? Want to share your culinary masterpiece with the world? - It's time to bring your creations to life! -

- +

+ Unleash Your Inner Chef! +

+

+ Have a unique recipe idea? Want to share your culinary masterpiece with the world? + It's time to bring your creations to life! +

+
- Create Your Recipe! - -
+ text-lg md:text-2xl font-bold uppercase tracking-wide" + > + Create Your Recipe! + + } templ HomePage() { -@components.Navbar("home") -
-
- @introSection() - @searchSection() - @highlightSection(false) - @listsSection() - @ctaSection() -
-
+ @components.Navbar("home") +
+
+ @introSection() + @searchSection() + @highlightSection(false) + @listsSection() + @ctaSection() +
+
} diff --git a/internal/templates/pages/home_templ.go b/internal/templates/pages/home_templ.go index 4e3c435..93a7dc5 100644 --- a/internal/templates/pages/home_templ.go +++ b/internal/templates/pages/home_templ.go @@ -74,7 +74,7 @@ func searchSection() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = components.SearchBar(domainRecipe.SearchFilters{}, true, false).Render(ctx, templ_7745c5c3_Buffer) + templ_7745c5c3_Err = components.SearchBar(domainRecipe.SearchFilters{}, true, false, false).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/internal/templates/pages/profile.templ b/internal/templates/pages/profile.templ index c13d33e..e06cd14 100644 --- a/internal/templates/pages/profile.templ +++ b/internal/templates/pages/profile.templ @@ -9,173 +9,177 @@ import domainUser "github.com/haydenhargreaves/Potion/internal/domain/user" import domainEngagement "github.com/haydenhargreaves/Potion/internal/domain/engagement" func displayDifficulty(diff int) string { - switch diff { - case 1: - return "Beginner" - case 2: - return "Easy" - case 3: - return "Intermediate" - case 4: - return "Challenging" - case 5: - return "Extreme" - default: - return "" - } + switch diff { + case 1: + return "Beginner" + case 2: + return "Easy" + case 3: + return "Intermediate" + case 4: + return "Challenging" + case 5: + return "Extreme" + default: + return "" + } } func displayTags(tags []domainRecipe.Tag) string { - names := make([]string, 0, len(tags)) - for _, tag := range tags { - names = append(names, tag.Name) - } - return strings.Join(names, ", ") + names := make([]string, 0, len(tags)) + for _, tag := range tags { + names = append(names, tag.Name) + } + return strings.Join(names, ", ") } -templ userDetailsSection(user domainUser.User, recipeCount int) { -
-
- if user.ImageUrl != "" { - - } else { - - } -
-
-

{ user.Name }

-

{ user.Email }

-
-
-

{ recipeCount } recipes

-

0 favorites

-
-
-
-
+templ userDetailsSection(user domainUser.User, recipeCount int, favoriteCount int) { +
+
+ if user.ImageUrl != "" { + + } else { + + } +
+
+

{ user.Name }

+

{ user.Email }

+
+
+

{ recipeCount } recipes

+

{ favoriteCount } favorites

+
+
+
+
} templ recipesSection(recipes []domainRecipe.Recipe) { -
-

My Recipes

-
    - if len(recipes) <= 4 { - for _, recipe := range recipes { - @recipeListItem(recipe) - } - } else { - for _, recipe := range recipes[:4] { - @recipeListItem(recipe) - } - } - -
  • - See all... -
  • -
    -
-
+
+

My Recipes

+
    + if len(recipes) <= 4 { + for _, recipe :=range recipes { + @recipeListItem(recipe) + } + } else { + for _, recipe :=range recipes[:4] { + @recipeListItem(recipe) + } + } + +
  • + See all... +
  • +
    +
+
} templ favoritesSection(recipes []domainRecipe.Recipe) { -
-

My Favorites

-

Favorites section is under construction!

-
+
+

My Favorites

+
    + if len(recipes) <= 4 { + for _, recipe := range recipes { + @recipeListItem(recipe) + } + } else { + for _, recipe := range recipes[:4] { + @recipeListItem(recipe) + } + } + +
  • + See all... +
  • +
    +
+
} templ activitySection(engagement []domainEngagement.Engagement) { -
-

Recent Activity

-

Activity section is under construction!

- -
+
+

Recent Activity

+

Activity section is under construction!

+ +
} templ recipeListItem(recipe domainRecipe.Recipe) { -
  • -

    - { recipe.Title } -

    - -

    - Difficulty: { displayDifficulty(recipe.Difficulty) } -

    -

    - Duration: { recipe.Duration.Total } min -

    -

    - Category: { recipe.Category } -

    - if len(recipe.Tags) > 0 { -

    - Tags: { displayTags(recipe.Tags) } -

    - } -
  • +
  • +

    + { recipe.Title } +

    + +

    + Difficulty: { displayDifficulty(recipe.Difficulty) } +

    +

    + Duration: { recipe.Duration.Total } min +

    +

    + Category: { recipe.Category } +

    + if len(recipe.Tags) > 0 { +

    + Tags: { displayTags(recipe.Tags) } +

    + } +
  • } templ activityListItem(engagement domainEngagement.Engagement) { -
  • -

    - { engagement.Message } -

    -

    - { engagement.Created.Format("01/02/2006") } -

    -
  • +
  • +

    + { engagement.Message } +

    +

    + { engagement.Created.Format("01/02/2006") } +

    +
  • } templ logoutSection() { -
    - - Logout - -
    +
    + + Logout + +
    } -templ ProfilePage(user domainUser.User, recipes []domainRecipe.Recipe, engagement []domainEngagement.Engagement) { - @components.Navbar(" profile") -
    -
    - @userDetailsSection(user, len(recipes)) - @recipesSection(recipes) - @favoritesSection(recipes) - @activitySection(engagement) - @logoutSection() -
    -
    +templ ProfilePage(user domainUser.User, recipes []domainRecipe.Recipe, favorites []domainRecipe.Recipe, engagement []domainEngagement.Engagement) { +@components.Navbar(" profile") +
    +
    + @userDetailsSection(user, len(recipes), len(favorites)) + @recipesSection(recipes) + @favoritesSection(favorites) + @activitySection(engagement) + @logoutSection() +
    +
    } diff --git a/internal/templates/pages/profile_templ.go b/internal/templates/pages/profile_templ.go index 88ed43b..16819ce 100644 --- a/internal/templates/pages/profile_templ.go +++ b/internal/templates/pages/profile_templ.go @@ -41,7 +41,7 @@ func displayTags(tags []domainRecipe.Tag) string { return strings.Join(names, ", ") } -func userDetailsSection(user domainUser.User, recipeCount int) templ.Component { +func userDetailsSection(user domainUser.User, recipeCount int, favoriteCount int) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { @@ -72,9 +72,10 @@ func userDetailsSection(user domainUser.User, recipeCount int) templ.Component { return templ_7745c5c3_Err } var templ_7745c5c3_Var2 string - templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(user.ImageUrl) + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs( + user.ImageUrl) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 42, Col: 24} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 41, Col: 19} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) if templ_7745c5c3_Err != nil { @@ -90,9 +91,11 @@ func userDetailsSection(user domainUser.User, recipeCount int) templ.Component { return templ_7745c5c3_Err } var templ_7745c5c3_Var3 string - templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("https://ui-avatars.com/api/?name=%s+%s&size=150", strings.Split(user.Name, " ")[0], strings.Split(user.Name, " ")[1])) + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs( + fmt.Sprintf("https://ui-avatars.com/api/?name=%s+%s&size=150", strings.Split(user.Name, " ")[0], + strings.Split(user.Name, " ")[1])) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 47, Col: 143} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 45, Col: 40} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) if templ_7745c5c3_Err != nil { @@ -110,7 +113,7 @@ func userDetailsSection(user domainUser.User, recipeCount int) templ.Component { var templ_7745c5c3_Var4 string templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(user.Name) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 52, Col: 62} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 49, Col: 65} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) if templ_7745c5c3_Err != nil { @@ -123,7 +126,7 @@ func userDetailsSection(user domainUser.User, recipeCount int) templ.Component { var templ_7745c5c3_Var5 string templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(user.Email) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 53, Col: 47} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 50, Col: 50} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) if templ_7745c5c3_Err != nil { @@ -136,13 +139,26 @@ func userDetailsSection(user domainUser.User, recipeCount int) templ.Component { var templ_7745c5c3_Var6 string templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(recipeCount) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 56, Col: 72} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 53, Col: 75} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, " recipes

    0 favorites

    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, " recipes

    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var7 string + templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(favoriteCount) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 54, Col: 77} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, " favorites

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -166,12 +182,12 @@ func recipesSection(recipes []domainRecipe.Recipe) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var7 := templ.GetChildren(ctx) - if templ_7745c5c3_Var7 == nil { - templ_7745c5c3_Var7 = templ.NopComponent + templ_7745c5c3_Var8 := templ.GetChildren(ctx) + if templ_7745c5c3_Var8 == nil { + templ_7745c5c3_Var8 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "

    My Recipes

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -214,12 +230,40 @@ func favoritesSection(recipes []domainRecipe.Recipe) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var8 := templ.GetChildren(ctx) - if templ_7745c5c3_Var8 == nil { - templ_7745c5c3_Var8 = templ.NopComponent + templ_7745c5c3_Var9 := templ.GetChildren(ctx) + if templ_7745c5c3_Var9 == nil { + templ_7745c5c3_Var9 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "

    My Favorites

    Favorites section is under construction!

    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "

    My Favorites

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -243,12 +287,12 @@ func activitySection(engagement []domainEngagement.Engagement) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var9 := templ.GetChildren(ctx) - if templ_7745c5c3_Var9 == nil { - templ_7745c5c3_Var9 = templ.NopComponent + templ_7745c5c3_Var11 := templ.GetChildren(ctx) + if templ_7745c5c3_Var11 == nil { + templ_7745c5c3_Var11 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "

    Recent Activity

    Activity section is under construction!

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -282,139 +326,139 @@ func recipeListItem(recipe domainRecipe.Recipe) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var10 := templ.GetChildren(ctx) - if templ_7745c5c3_Var10 == nil { - templ_7745c5c3_Var10 = templ.NopComponent + templ_7745c5c3_Var12 := templ.GetChildren(ctx) + if templ_7745c5c3_Var12 == nil { + templ_7745c5c3_Var12 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
  • ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var12 string - templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(recipe.Title) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 122, Col: 18} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "

    Difficulty: ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "

  • | Duration: ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "\" hx-trigger=\"click\" hx-swap=\"none\" class=\"text-base md:text-lg hover:text-blue-600 duration-100 cursor-pointer\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var14 string - templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(recipe.Duration.Total) + templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(recipe.Title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 126, Col: 66} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 129, Col: 18} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, " min | Category: ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "

    Difficulty: ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var15 string - templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(recipe.Category) + templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(displayDifficulty(recipe.Difficulty)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 127, Col: 60} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 132, Col: 82} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "

    Difficulty: ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, " | Duration: ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var16 string - templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(displayDifficulty(recipe.Difficulty)) + templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(recipe.Duration.Total) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 130, Col: 81} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 133, Col: 67} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "

    Duration: ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, " min | Category: ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var17 string - templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(recipe.Duration.Total) + templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(recipe.Category) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 133, Col: 64} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 134, Col: 61} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, " min

    Category: ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "

    Difficulty: ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var18 string - templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(recipe.Category) + templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(displayDifficulty(recipe.Difficulty)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 136, Col: 58} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 137, Col: 82} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "

    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "

    Duration: ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var19 string + templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(recipe.Duration.Total) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 140, Col: 65} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, " min

    Category: ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var20 string + templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(recipe.Category) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 143, Col: 59} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if len(recipe.Tags) > 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "

    Tags: ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "

    Tags: ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var19 string - templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(displayTags(recipe.Tags)) + var templ_7745c5c3_Var21 string + templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(displayTags(recipe.Tags)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 140, Col: 36} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 147, Col: 36} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "

    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "
  • ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -438,38 +482,38 @@ func activityListItem(engagement domainEngagement.Engagement) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var20 := templ.GetChildren(ctx) - if templ_7745c5c3_Var20 == nil { - templ_7745c5c3_Var20 = templ.NopComponent + templ_7745c5c3_Var22 := templ.GetChildren(ctx) + if templ_7745c5c3_Var22 == nil { + templ_7745c5c3_Var22 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "
  • ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "

  • ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var21 string - templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(engagement.Message) + var templ_7745c5c3_Var23 string + templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(engagement.Message) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 151, Col: 23} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 157, Col: 24} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "

    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var22 string - templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(engagement.Created.Format("01/02/2006")) + var templ_7745c5c3_Var24 string + templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(engagement.Created.Format("01/02/2006")) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 154, Col: 44} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 160, Col: 45} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "

  • ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -493,21 +537,21 @@ func logoutSection() templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var23 := templ.GetChildren(ctx) - if templ_7745c5c3_Var23 == nil { - templ_7745c5c3_Var23 = templ.NopComponent + templ_7745c5c3_Var25 := templ.GetChildren(ctx) + if templ_7745c5c3_Var25 == nil { + templ_7745c5c3_Var25 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "
    Logout
    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "\" class=\"text-center border border-red-500 text-red-500 w-9/10 md:w-1/3 py-2 rounded-lg hover:cursor-pointer hover:bg-red-100 duration-300\">Logout") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -515,7 +559,7 @@ func logoutSection() templ.Component { }) } -func ProfilePage(user domainUser.User, recipes []domainRecipe.Recipe, engagement []domainEngagement.Engagement) templ.Component { +func ProfilePage(user domainUser.User, recipes []domainRecipe.Recipe, favorites []domainRecipe.Recipe, engagement []domainEngagement.Engagement) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { @@ -531,20 +575,20 @@ func ProfilePage(user domainUser.User, recipes []domainRecipe.Recipe, engagement }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var25 := templ.GetChildren(ctx) - if templ_7745c5c3_Var25 == nil { - templ_7745c5c3_Var25 = templ.NopComponent + templ_7745c5c3_Var27 := templ.GetChildren(ctx) + if templ_7745c5c3_Var27 == nil { + templ_7745c5c3_Var27 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Err = components.Navbar(" profile").Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "
    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = userDetailsSection(user, len(recipes)).Render(ctx, templ_7745c5c3_Buffer) + templ_7745c5c3_Err = userDetailsSection(user, len(recipes), len(favorites)).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -552,7 +596,7 @@ func ProfilePage(user domainUser.User, recipes []domainRecipe.Recipe, engagement if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = favoritesSection(recipes).Render(ctx, templ_7745c5c3_Buffer) + templ_7745c5c3_Err = favoritesSection(favorites).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -564,7 +608,7 @@ func ProfilePage(user domainUser.User, recipes []domainRecipe.Recipe, engagement if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "
    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/internal/templates/pages/search.templ b/internal/templates/pages/search.templ index 58606fd..e5acc11 100644 --- a/internal/templates/pages/search.templ +++ b/internal/templates/pages/search.templ @@ -16,7 +16,7 @@ templ SearchPage(filters domainRecipe.SearchFilters, searchOnLoad bool) { bg-white flex flex-col items-center" > @components.BannerText("Recipe Search") - @components.SearchBar(filters, false, searchOnLoad) + @components.SearchBar(filters, false, searchOnLoad, false)
    @ResultList(nil) @@ -38,33 +38,47 @@ templ ResultList(recipes []domain.Recipe) { templ searchResult(recipe domain.Recipe) {
    -
    -

    - { recipe.Title } -

    -
    - - @timeIconSm() - { recipe.Duration.Total } min - - - for _ = range(recipe.Difficulty) { - @starIconSm(true) - } - for _ = range(5 - recipe.Difficulty) { - @starIconSm(false) - } - - - @servingIconSm() - Serves { recipe.Serves } - +
    +
    +
    +

    + { recipe.Title } +

    +
    + + @timeIconSm() + { recipe.Duration.Total } min + + + for _ = range(recipe.Difficulty) { + @starIconSm(true) + } + for _ = range(5 - recipe.Difficulty) { + @starIconSm(false) + } + + + @servingIconSm() + Serves { recipe.Serves } + +
    +
    +

    { recipe.Description }

    diff --git a/internal/templates/pages/search_templ.go b/internal/templates/pages/search_templ.go index 4402b67..c3bec1a 100644 --- a/internal/templates/pages/search_templ.go +++ b/internal/templates/pages/search_templ.go @@ -49,7 +49,7 @@ func SearchPage(filters domainRecipe.SearchFilters, searchOnLoad bool) templ.Com if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = components.SearchBar(filters, false, searchOnLoad).Render(ctx, templ_7745c5c3_Buffer) + templ_7745c5c3_Err = components.SearchBar(filters, false, searchOnLoad, false).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -147,20 +147,20 @@ func searchResult(recipe domain.Recipe) templ.Component { var templ_7745c5c3_Var4 string templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(domainServer.API_ENGAGEMENT_VIEW, recipe.Id)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/search.templ`, Line: 41, Col: 70} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/search.templ`, Line: 41, Col: 68} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\" hx-trigger=\"click\" hx-swap=\"none\" class=\"w-full p-2 border-b border-gray-200 hover:bg-gray-100 duration-200 flex items-center flex-col md:flex-row even:bg-[#f8f8f8] cursor-pointer\">

    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\" hx-trigger=\"click\" hx-swap=\"none\" class=\"w-full p-2 border-b border-gray-200 hover:bg-gray-100 duration-200 flex items-center flex-col md:flex-row even:bg-[#f8f8f8] cursor-pointer\">

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var5 string templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(recipe.Title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/search.templ`, Line: 49, Col: 18} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/search.templ`, Line: 51, Col: 20} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) if templ_7745c5c3_Err != nil { @@ -173,7 +173,7 @@ func searchResult(recipe domain.Recipe) templ.Component { var templ_7745c5c3_Var6 string templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(recipe.Category) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/search.templ`, Line: 49, Col: 89} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/search.templ`, Line: 51, Col: 91} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) if templ_7745c5c3_Err != nil { @@ -190,7 +190,7 @@ func searchResult(recipe domain.Recipe) templ.Component { var templ_7745c5c3_Var7 string templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(recipe.Duration.Total) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/search.templ`, Line: 54, Col: 28} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/search.templ`, Line: 56, Col: 30} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) if templ_7745c5c3_Err != nil { @@ -227,26 +227,36 @@ func searchResult(recipe domain.Recipe) templ.Component { var templ_7745c5c3_Var8 string templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(recipe.Serves) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/search.templ`, Line: 66, Col: 27} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/search.templ`, Line: 68, Col: 29} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "

    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var9 string templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(recipe.Description) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/search.templ`, Line: 69, Col: 72} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/search.templ`, Line: 83, Col: 72} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "

    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -275,7 +285,7 @@ func servingIconSm() templ.Component { templ_7745c5c3_Var10 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, " ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -304,7 +314,7 @@ func timeIconSm() templ.Component { templ_7745c5c3_Var11 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -334,12 +344,12 @@ func starIconSm(filled bool) templ.Component { } ctx = templ.ClearChildren(ctx) if filled { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, " ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, " ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/web/static/css/tailwind.css b/web/static/css/tailwind.css index 14b37e1..b1e6704 100644 --- a/web/static/css/tailwind.css +++ b/web/static/css/tailwind.css @@ -9,7 +9,6 @@ monospace; --color-red-100: oklch(93.6% 0.032 17.717); --color-red-500: oklch(63.7% 0.237 25.331); - --color-green-300: oklch(87.1% 0.15 154.449); --color-green-500: oklch(72.3% 0.219 149.579); --color-blue-50: oklch(97% 0.014 254.604); --color-blue-100: oklch(93.2% 0.032 255.585); @@ -239,6 +238,9 @@ .static { position: static; } + .top-1 { + top: calc(var(--spacing) * 1); + } .top-1\/2 { top: calc(1/2 * 100%); } @@ -248,6 +250,9 @@ .left-0 { left: calc(var(--spacing) * 0); } + .left-1 { + left: calc(var(--spacing) * 1); + } .left-1\/2 { left: calc(1/2 * 100%); } @@ -419,12 +424,18 @@ .min-h-screen { min-height: 100vh; } + .w-1 { + width: calc(var(--spacing) * 1); + } .w-1\/3 { width: calc(1/3 * 100%); } .w-1\/4 { width: calc(1/4 * 100%); } + .w-3 { + width: calc(var(--spacing) * 3); + } .w-3\/4 { width: calc(3/4 * 100%); } @@ -437,6 +448,9 @@ .w-5 { width: calc(var(--spacing) * 5); } + .w-9 { + width: calc(var(--spacing) * 9); + } .w-9\/10 { width: calc(9/10 * 100%); } @@ -455,6 +469,9 @@ .max-w-2xl { max-width: var(--container-2xl); } + .flex-shrink { + flex-shrink: 1; + } .flex-shrink-0 { flex-shrink: 0; } @@ -464,10 +481,21 @@ .flex-grow { flex-grow: 1; } + .border-collapse { + border-collapse: collapse; + } + .-translate-x-1 { + --tw-translate-x: calc(var(--spacing) * -1); + translate: var(--tw-translate-x) var(--tw-translate-y); + } .-translate-x-1\/2 { --tw-translate-x: calc(calc(1/2 * 100%) * -1); translate: var(--tw-translate-x) var(--tw-translate-y); } + .-translate-y-1 { + --tw-translate-y: calc(var(--spacing) * -1); + translate: var(--tw-translate-x) var(--tw-translate-y); + } .-translate-y-1\/2 { --tw-translate-y: calc(calc(1/2 * 100%) * -1); translate: var(--tw-translate-x) var(--tw-translate-y); @@ -480,9 +508,15 @@ --tw-scale-y: 50%; scale: var(--tw-scale-x) var(--tw-scale-y); } + .transform { + transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,); + } .cursor-pointer { cursor: pointer; } + .resize { + resize: both; + } .resize-none { resize: none; } @@ -1263,6 +1297,11 @@ margin-top: calc(var(--spacing) * -2); } } + .md\:mt-0 { + @media (width >= 48rem) { + margin-top: calc(var(--spacing) * 0); + } + } .md\:block { @media (width >= 48rem) { display: block; @@ -1368,6 +1407,11 @@ align-items: flex-start; } } + .md\:justify-between { + @media (width >= 48rem) { + justify-content: space-between; + } + } .md\:border-x { @media (width >= 48rem) { border-inline-style: var(--tw-border-style); @@ -1509,6 +1553,26 @@ inherits: false; initial-value: 1; } +@property --tw-rotate-x { + syntax: "*"; + inherits: false; +} +@property --tw-rotate-y { + syntax: "*"; + inherits: false; +} +@property --tw-rotate-z { + syntax: "*"; + inherits: false; +} +@property --tw-skew-x { + syntax: "*"; + inherits: false; +} +@property --tw-skew-y { + syntax: "*"; + inherits: false; +} @property --tw-border-style { syntax: "*"; inherits: false; @@ -1718,6 +1782,11 @@ --tw-scale-x: 1; --tw-scale-y: 1; --tw-scale-z: 1; + --tw-rotate-x: initial; + --tw-rotate-y: initial; + --tw-rotate-z: initial; + --tw-skew-x: initial; + --tw-skew-y: initial; --tw-border-style: solid; --tw-gradient-position: initial; --tw-gradient-from: #0000;