FEATURE: Favorites Page Implementation #22
@ -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))
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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,
|
||||
})
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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) {
|
||||
<form
|
||||
hx-post={ domainServer.API_SEARCH_RECIPES }
|
||||
if favorites {
|
||||
hx-post={ domainServer.API_SEARCH_FAVORITES }
|
||||
} else {
|
||||
hx-post={ domainServer.API_SEARCH_RECIPES }
|
||||
}
|
||||
hx-swap="innerHTML"
|
||||
hx-target="#result-list"
|
||||
if searchOnLoad {
|
||||
|
||||
@ -11,7 +11,7 @@ import templruntime "github.com/a-h/templ/runtime"
|
||||
import domainServer "github.com/haydenhargreaves/Potion/internal/domain/server"
|
||||
import domainRecipe "github.com/haydenhargreaves/Potion/internal/domain/recipe"
|
||||
|
||||
func SearchBar(filters domainRecipe.SearchFilters, redirect bool, searchOnLoad bool) templ.Component {
|
||||
func SearchBar(filters domainRecipe.SearchFilters, redirect, searchOnLoad, favorites bool) 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 {
|
||||
@ -32,61 +32,89 @@ func SearchBar(filters domainRecipe.SearchFilters, redirect bool, searchOnLoad b
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<form hx-post=\"")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<form")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var2 string
|
||||
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(domainServer.API_SEARCH_RECIPES)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/components/search_bar.templ`, Line: 8, Col: 43}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\" hx-swap=\"innerHTML\" hx-target=\"#result-list\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if searchOnLoad {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, " hx-trigger=\"submit, load\"")
|
||||
if favorites {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " hx-post=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var2 string
|
||||
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(domainServer.API_SEARCH_FAVORITES)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/components/search_bar.templ`, Line: 9, Col: 46}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
} else {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " hx-trigger=\"submit\"")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " hx-post=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(domainServer.API_SEARCH_RECIPES)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/components/search_bar.templ`, Line: 11, Col: 44}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, " hx-encoding=\"multipart/form-data\" class=\"w-full px-4 my-8\"><div class=\"flex w-full gap-x-2\"><div class=\"relative w-full\"><input type=\"hidden\" name=\"redirect\" value=\"")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, " hx-swap=\"innerHTML\" hx-target=\"#result-list\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(redirect)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/components/search_bar.templ`, Line: 21, Col: 57}
|
||||
if searchOnLoad {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, " hx-trigger=\"submit, load\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
} else {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, " hx-trigger=\"submit\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "\"> <input type=\"search\" name=\"search\" placeholder=\"Search recipes, ingredients...\" value=\"")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, " hx-encoding=\"multipart/form-data\" class=\"w-full px-4 my-8\"><div class=\"flex w-full gap-x-2\"><div class=\"relative w-full\"><input type=\"hidden\" name=\"redirect\" value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(filters.Search)
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(redirect)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/components/search_bar.templ`, Line: 26, Col: 27}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/components/search_bar.templ`, Line: 25, Col: 57}
|
||||
}
|
||||
_, 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, "\" class=\"w-full pr-4 pl-10 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500\"> <button type=\"submit\" class=\"absolute left-3 top-1/2 -translate-y-1/2\"><svg class=\"h-5 w-5 text-gray-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"></path></svg></button></div>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\"> <input type=\"search\" name=\"search\" placeholder=\"Search recipes, ingredients...\" value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(filters.Search)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/components/search_bar.templ`, Line: 30, Col: 27}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "\" class=\"w-full pr-4 pl-10 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500\"> <button type=\"submit\" class=\"absolute left-3 top-1/2 -translate-y-1/2\"><svg class=\"h-5 w-5 text-gray-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"></path></svg></button></div>")
|
||||
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, "</div>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "</div>")
|
||||
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, "</form>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "</form>")
|
||||
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, "<button type=\"button\" id=\"filter-dropdown-button\" onclick=\"toggleDropdown()\" class=\"text-gray-400 border border-gray-300 rounded-lg p-2 focus:outline-none focus:ring-2 focus:ring-blue-500\"><svg class=\"h-6\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M6 11.1707L6 4C6 3.44771 5.55228 3 5 3C4.44771 3 4 3.44771 4 4L4 11.1707C2.83481 11.5825 2 12.6938 2 14C2 15.3062 2.83481 16.4175 4 16.8293L4 20C4 20.5523 4.44772 21 5 21C5.55228 21 6 20.5523 6 20L6 16.8293C7.16519 16.4175 8 15.3062 8 14C8 12.6938 7.16519 11.5825 6 11.1707ZM5 13C4.44772 13 4 13.4477 4 14C4 14.5523 4.44772 15 5 15C5.55228 15 6 14.5523 6 14C6 13.4477 5.55228 13 5 13Z\" fill=\"currentColor\"></path> <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M19 21C18.4477 21 18 20.5523 18 20L18 18C18 17.9435 18.0047 17.8881 18.0137 17.8341C16.8414 17.4262 16 16.3113 16 15C16 13.6887 16.8414 12.5738 18.0137 12.1659C18.0047 12.1119 18 12.0565 18 12L18 4C18 3.44771 18.4477 3 19 3C19.5523 3 20 3.44771 20 4L20 12C20 12.0565 19.9953 12.1119 19.9863 12.1659C21.1586 12.5738 22 13.6887 22 15C22 16.3113 21.1586 17.4262 19.9863 17.8341C19.9953 17.8881 20 17.9435 20 18V20C20 20.5523 19.5523 21 19 21ZM18 15C18 14.4477 18.4477 14 19 14C19.5523 14 20 14.4477 20 15C20 15.5523 19.5523 16 19 16C18.4477 16 18 15.5523 18 15Z\" fill=\"currentColor\"></path> <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M9 9C9 7.69378 9.83481 6.58254 11 6.17071V4C11 3.44772 11.4477 3 12 3C12.5523 3 13 3.44772 13 4V6.17071C14.1652 6.58254 15 7.69378 15 9C15 10.3113 14.1586 11.4262 12.9863 11.8341C12.9953 11.8881 13 11.9435 13 12L13 20C13 20.5523 12.5523 21 12 21C11.4477 21 11 20.5523 11 20L11 12C11 11.9435 11.0047 11.8881 11.0137 11.8341C9.84135 11.4262 9 10.3113 9 9ZM11 9C11 8.44772 11.4477 8 12 8C12.5523 8 13 8.44772 13 9C13 9.55229 12.5523 10 12 10C11.4477 10 11 9.55229 11 9Z\" fill=\"currentColor\"></path></svg></button>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "<button type=\"button\" id=\"filter-dropdown-button\" onclick=\"toggleDropdown()\" class=\"text-gray-400 border border-gray-300 rounded-lg p-2 focus:outline-none focus:ring-2 focus:ring-blue-500\"><svg class=\"h-6\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M6 11.1707L6 4C6 3.44771 5.55228 3 5 3C4.44771 3 4 3.44771 4 4L4 11.1707C2.83481 11.5825 2 12.6938 2 14C2 15.3062 2.83481 16.4175 4 16.8293L4 20C4 20.5523 4.44772 21 5 21C5.55228 21 6 20.5523 6 20L6 16.8293C7.16519 16.4175 8 15.3062 8 14C8 12.6938 7.16519 11.5825 6 11.1707ZM5 13C4.44772 13 4 13.4477 4 14C4 14.5523 4.44772 15 5 15C5.55228 15 6 14.5523 6 14C6 13.4477 5.55228 13 5 13Z\" fill=\"currentColor\"></path> <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M19 21C18.4477 21 18 20.5523 18 20L18 18C18 17.9435 18.0047 17.8881 18.0137 17.8341C16.8414 17.4262 16 16.3113 16 15C16 13.6887 16.8414 12.5738 18.0137 12.1659C18.0047 12.1119 18 12.0565 18 12L18 4C18 3.44771 18.4477 3 19 3C19.5523 3 20 3.44771 20 4L20 12C20 12.0565 19.9953 12.1119 19.9863 12.1659C21.1586 12.5738 22 13.6887 22 15C22 16.3113 21.1586 17.4262 19.9863 17.8341C19.9953 17.8881 20 17.9435 20 18V20C20 20.5523 19.5523 21 19 21ZM18 15C18 14.4477 18.4477 14 19 14C19.5523 14 20 14.4477 20 15C20 15.5523 19.5523 16 19 16C18.4477 16 18 15.5523 18 15Z\" fill=\"currentColor\"></path> <path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M9 9C9 7.69378 9.83481 6.58254 11 6.17071V4C11 3.44772 11.4477 3 12 3C12.5523 3 13 3.44772 13 4V6.17071C14.1652 6.58254 15 7.69378 15 9C15 10.3113 14.1586 11.4262 12.9863 11.8341C12.9953 11.8881 13 11.9435 13 12L13 20C13 20.5523 12.5523 21 12 21C11.4477 21 11 20.5523 11 20L11 12C11 11.9435 11.0047 11.8881 11.0137 11.8341C9.84135 11.4262 9 10.3113 9 9ZM11 9C11 8.44772 11.4477 8 12 8C12.5523 8 13 8.44772 13 9C13 9.55229 12.5523 10 12 10C11.4477 10 11 9.55229 11 9Z\" fill=\"currentColor\"></path></svg></button>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
||||
@ -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")
|
||||
<div class="w-full h-screen flex justify-center">
|
||||
<div class="mx-2 md:mx-0 w-full md:w-1/2 md:pt-14 h-full border-l border-r border-gray-300 bg-white">
|
||||
<div class="flex flex-col items-center justify-center h-full gap-y-2">
|
||||
<h1 class="text-4xl text-gray-800 font-semibold text-center">Page Under Construction </h1>
|
||||
<p class="text-gray-700">Sit tight, this page is coming soon!</p>
|
||||
templ FavoriteList(recipes []domain.Recipe) {
|
||||
<div id="result-list" class="flex flex-col w-full p-4 items-center">
|
||||
for _, recipe := range recipes {
|
||||
@favoriteResult(recipe)
|
||||
}
|
||||
if len(recipes) == 0 || recipes == nil {
|
||||
<p class="text-gray-700 text-sm py-4">No results</p>
|
||||
} else {
|
||||
<p class="text-gray-700 text-sm py-4">End of results</p>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
templ favoriteResult(recipe domain.Recipe) {
|
||||
<div hx-post={ fmt.Sprintf(domainServer.API_ENGAGEMENT_VIEW, recipe.Id) } 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">
|
||||
<img class="bg-gray-50 size-56 md:size-40 rounded-md border-0" src="" />
|
||||
<div class="text-gray-700 p-4 flex flex-col items-center md:items-start w-full">
|
||||
<div class="flex flex-col md:flex-row items-center md:items-start justify-between w-full">
|
||||
<div class="flex flex-col items-center md:items-start">
|
||||
<h3 class="text-xl font-semibold text-black pb-1">
|
||||
{ recipe.Title } <span class="text-sm font-normal hidden md:inline">{ recipe.Category }</span>
|
||||
</h3>
|
||||
<div class="text-sm flex gap-x-3 gap-y-1 items-center flex-wrap">
|
||||
<span class="flex gap-x-1 align-center">
|
||||
@timeIconSm()
|
||||
{ recipe.Duration.Total } min
|
||||
</span>
|
||||
<span class="flex gap-x-1 align-center">
|
||||
for _ = range(recipe.Difficulty) {
|
||||
@starIconSm(true)
|
||||
}
|
||||
for _ = range(5 - recipe.Difficulty) {
|
||||
@starIconSm(false)
|
||||
}
|
||||
</span>
|
||||
<span class="flex gap-x-1 align-center">
|
||||
@servingIconSm()
|
||||
Serves { recipe.Serves }
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-2 mt-4 md:my-0 hidden md:block">
|
||||
<svg class="h-6 text-red-500" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M2 9.1371C2 14 6.01943 16.5914 8.96173 18.9109C10 19.7294 11 20.5 12 20.5C13 20.5 14 19.7294 15.0383 18.9109C17.9806 16.5914 22 14 22 9.1371C22 4.27416 16.4998 0.825464 12 5.50063C7.50016 0.825464 2 4.27416 2 9.1371Z"
|
||||
fill="currentColor"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-sm py-2 text-center md:text-left">{ recipe.Description }</p>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
templ FavoritesPage(filters domain.SearchFilters) {
|
||||
@components.Navbar("favorites")
|
||||
<div class="w-full flex justify-center">
|
||||
<div class="mx-2 md:mx-0 w-full md:w-1/2 md:pt-14 min-h-screen border-l border-r border-gray-300 bg-white">
|
||||
@components.BannerText("Favorites")
|
||||
@components.SearchBar(filters, false, true, true)
|
||||
<hr class="text-gray-300 w-full" />
|
||||
@FavoriteList(nil)
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@ -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, "<div id=\"result-list\" class=\"flex flex-col w-full p-4 items-center\">")
|
||||
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, "<p class=\"text-gray-700 text-sm py-4\">No results</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
} else {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<p class=\"text-gray-700 text-sm py-4\">End of results</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "</div>")
|
||||
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, "<div hx-post=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, 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/favorites.templ`, Line: 22, Col: 71}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "\" 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\"><img class=\"bg-gray-50 size-56 md:size-40 rounded-md border-0\" src=\"\"><div class=\"text-gray-700 p-4 flex flex-col items-center md:items-start w-full\"><div class=\"flex flex-col md:flex-row items-center md:items-start justify-between w-full\"><div class=\"flex flex-col items-center md:items-start\"><h3 class=\"text-xl font-semibold text-black pb-1\">")
|
||||
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, " <span class=\"text-sm font-normal hidden md:inline\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(recipe.Category)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/favorites.templ`, Line: 29, Col: 95}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "</span></h3><div class=\"text-sm flex gap-x-3 gap-y-1 items-center flex-wrap\"><span class=\"flex gap-x-1 align-center\">")
|
||||
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</span> <span class=\"flex gap-x-1 align-center\">")
|
||||
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, "</span> <span class=\"flex gap-x-1 align-center\">")
|
||||
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, "</span></div></div><div class=\"mb-2 mt-4 md:my-0 hidden md:block\"><svg class=\"h-6 text-red-500\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M2 9.1371C2 14 6.01943 16.5914 8.96173 18.9109C10 19.7294 11 20.5 12 20.5C13 20.5 14 19.7294 15.0383 18.9109C17.9806 16.5914 22 14 22 9.1371C22 4.27416 16.4998 0.825464 12 5.50063C7.50016 0.825464 2 4.27416 2 9.1371Z\" fill=\"currentColor\"></path></svg></div></div><p class=\"text-sm py-2 text-center md:text-left\">")
|
||||
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, "</p></div></div>")
|
||||
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, "<div class=\"w-full h-screen flex justify-center\"><div class=\"mx-2 md:mx-0 w-full md:w-1/2 md:pt-14 h-full border-l border-r border-gray-300 bg-white\"><div class=\"flex flex-col items-center justify-center h-full gap-y-2\"><h1 class=\"text-4xl text-gray-800 font-semibold text-center\">Page Under Construction </h1><p class=\"text-gray-700\">Sit tight, this page is coming soon!</p></div></div></div>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "<div class=\"w-full flex justify-center\"><div class=\"mx-2 md:mx-0 w-full md:w-1/2 md:pt-14 min-h-screen border-l border-r border-gray-300 bg-white\">")
|
||||
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, "<hr class=\"text-gray-300 w-full\">")
|
||||
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, "</div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
||||
@ -5,106 +5,112 @@ import "github.com/haydenhargreaves/Potion/internal/domain/server"
|
||||
import domainRecipe "github.com/haydenhargreaves/Potion/internal/domain/recipe"
|
||||
|
||||
templ introSection() {
|
||||
<section class="w-full h-fit mb-16">
|
||||
<div class="relative">
|
||||
<video class="" autoplay loop muted playsinline>
|
||||
<source src="/v1/web/static/img/salmon_video.mp4" type="video/mp4" />
|
||||
</video>
|
||||
<h1 class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 text-center
|
||||
text-white text-3xl w-4/5 font-bold z-10">
|
||||
Discover Your Next Favorite Meal
|
||||
</h1>
|
||||
</div>
|
||||
<p class="leading-relaxed p-4 my-8">
|
||||
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.
|
||||
</p>
|
||||
</section>
|
||||
<section class="w-full h-fit mb-16">
|
||||
<div class="relative">
|
||||
<video class="" autoplay loop muted playsinline>
|
||||
<source src="/v1/web/static/img/salmon_video.mp4" type="video/mp4"/>
|
||||
</video>
|
||||
<h1
|
||||
class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 text-center
|
||||
text-white text-3xl w-4/5 font-bold z-10"
|
||||
>
|
||||
Discover Your Next Favorite Meal
|
||||
</h1>
|
||||
</div>
|
||||
<p class="leading-relaxed p-4 my-8">
|
||||
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.
|
||||
</p>
|
||||
</section>
|
||||
}
|
||||
|
||||
templ searchSection() {
|
||||
<section class="w-full flex flex-col items-center justify-center my-8 py-4">
|
||||
@components.BannerText("Craving Something Specific?")
|
||||
<div class="w-full md:w-3/4">
|
||||
@components.SearchBar(domainRecipe.SearchFilters{}, true, false)
|
||||
</div>
|
||||
<div class="hidden" id="result-list"></div>
|
||||
</section>
|
||||
<section class="w-full flex flex-col items-center justify-center my-8 py-4">
|
||||
@components.BannerText("Craving Something Specific?")
|
||||
<div class="w-full md:w-3/4">
|
||||
@components.SearchBar(domainRecipe.SearchFilters{}, true, false, false)
|
||||
</div>
|
||||
<div class="hidden" id="result-list"></div>
|
||||
</section>
|
||||
}
|
||||
|
||||
templ highlightSection(liked bool) {
|
||||
<section class="w-full flex flex-col items-center justify-center my-8 py-4">
|
||||
@components.BannerText("Recipe of the Week!")
|
||||
<p class="leading-relaxed p-4 my-8">
|
||||
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!
|
||||
</p>
|
||||
<div class="flex items-center justify-center w-full">
|
||||
@components.RecipeCardLarge(false)
|
||||
</div>
|
||||
</section>
|
||||
<section class="w-full flex flex-col items-center justify-center my-8 py-4">
|
||||
@components.BannerText("Recipe of the Week!")
|
||||
<p class="leading-relaxed p-4 my-8">
|
||||
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!
|
||||
</p>
|
||||
<div class="flex items-center justify-center w-full">
|
||||
@components.RecipeCardLarge(false)
|
||||
</div>
|
||||
</section>
|
||||
}
|
||||
|
||||
templ listsSection() {
|
||||
<section class="w-full flex flex-col items-center justify-center my-8 py-4">
|
||||
@components.BannerText("Take Another Look.")
|
||||
<div class="w-full">
|
||||
<h3 class="text-lg mt-8 mx-4">Recently viewed</h3>
|
||||
<div class="flex overflow-x-auto gap-x-4 mx-4 my-4">
|
||||
@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)
|
||||
</div>
|
||||
<h3 class="text-lg mt-8 mx-4">Make again</h3>
|
||||
<div class="flex overflow-x-auto gap-x-4 mx-4 my-4">
|
||||
@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)
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="w-full flex flex-col items-center justify-center my-8 py-4">
|
||||
@components.BannerText("Take Another Look.")
|
||||
<div class="w-full">
|
||||
<h3 class="text-lg mt-8 mx-4">Recently viewed</h3>
|
||||
<div class="flex overflow-x-auto gap-x-4 mx-4 my-4">
|
||||
@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)
|
||||
</div>
|
||||
<h3 class="text-lg mt-8 mx-4">Make again</h3>
|
||||
<div class="flex overflow-x-auto gap-x-4 mx-4 my-4">
|
||||
@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)
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
}
|
||||
|
||||
templ ctaSection() {
|
||||
<section
|
||||
class="w-full flex flex-col items-center justify-center mt-16 py-8 md:py-12 bg-gradient-to-br from-blue-100 to-purple-100 text-center">
|
||||
<h2 class="text-2xl md:text-3xl font-extrabold text-gray-800 mb-6 px-4">
|
||||
Unleash Your Inner Chef!
|
||||
</h2>
|
||||
<p class="text-md md:text-lg text-gray-700 max-w-2xl mb-10 px-4 leading-relaxed">
|
||||
Have a unique recipe idea? Want to share your culinary masterpiece with the world?
|
||||
It's time to bring your creations to life!
|
||||
</p>
|
||||
<a href={ domain.WEB_CREATE } class="flex items-center justify-center
|
||||
<section
|
||||
class="w-full flex flex-col items-center justify-center mt-16 py-8 md:py-12 bg-gradient-to-br from-blue-100 to-purple-100 text-center"
|
||||
>
|
||||
<h2 class="text-2xl md:text-3xl font-extrabold text-gray-800 mb-6 px-4">
|
||||
Unleash Your Inner Chef!
|
||||
</h2>
|
||||
<p class="text-md md:text-lg text-gray-700 max-w-2xl mb-10 px-4 leading-relaxed">
|
||||
Have a unique recipe idea? Want to share your culinary masterpiece with the world?
|
||||
It's time to bring your creations to life!
|
||||
</p>
|
||||
<a
|
||||
href={ domain.WEB_CREATE }
|
||||
class="flex items-center justify-center
|
||||
bg-gradient-to-r from-blue-400 to-blue-600 text-white
|
||||
px-12 py-5 rounded-full shadow-sm hover:shadow-md
|
||||
transition-all duration-300 ease-in-out shadow-blue-700
|
||||
text-lg md:text-2xl font-bold uppercase tracking-wide">
|
||||
Create Your Recipe!
|
||||
</a>
|
||||
</section>
|
||||
text-lg md:text-2xl font-bold uppercase tracking-wide"
|
||||
>
|
||||
Create Your Recipe!
|
||||
</a>
|
||||
</section>
|
||||
}
|
||||
|
||||
templ HomePage() {
|
||||
@components.Navbar("home")
|
||||
<div class="w-full h-fit flex justify-center">
|
||||
<div class="mx-2 md:mx-0 w-full md:w-1/2 md:pt-14 h-full border-l border-r border-gray-300 bg-white">
|
||||
@introSection()
|
||||
@searchSection()
|
||||
@highlightSection(false)
|
||||
@listsSection()
|
||||
@ctaSection()
|
||||
</div>
|
||||
</div>
|
||||
@components.Navbar("home")
|
||||
<div class="w-full h-fit flex justify-center">
|
||||
<div class="mx-2 md:mx-0 w-full md:w-1/2 md:pt-14 h-full border-l border-r border-gray-300 bg-white">
|
||||
@introSection()
|
||||
@searchSection()
|
||||
@highlightSection(false)
|
||||
@listsSection()
|
||||
@ctaSection()
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
<section class="w-full flex flex-col justify-center my-8 py-4 border-b border-gray-300">
|
||||
<div class="w-full p-4 md:p-8 flex items-center gap-x-8">
|
||||
if user.ImageUrl != "" {
|
||||
<img
|
||||
class="w-24 md:w-32 border-2 border-blue-500 rounded-full shadow-blue-500 shadow select-none"
|
||||
src={ user.ImageUrl }
|
||||
/>
|
||||
} else {
|
||||
<img
|
||||
class="w-24 md:w-32 border-2 border-blue-500 rounded-full shadow-blue-500 shadow select-none"
|
||||
src={ fmt.Sprintf("https://ui-avatars.com/api/?name=%s+%s&size=150", strings.Split(user.Name, " " )[0], strings.Split(user.Name, " " )[1]) }
|
||||
/>
|
||||
}
|
||||
<div class="flex flex-col gap-y-4">
|
||||
<div class="">
|
||||
<h1 class="text-md md:text-2xl font-semibold">{ user.Name }</h1>
|
||||
<p class="text-xs md:text-sm">{ user.Email }</p>
|
||||
</div>
|
||||
<div class="flex gap-x-4">
|
||||
<p class="text-xs md:text-sm"><span class="font-bold">{ recipeCount }</span> recipes</p>
|
||||
<p class="text-xs md:text-sm"><span class="font-bold">0</span> favorites</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
templ userDetailsSection(user domainUser.User, recipeCount int, favoriteCount int) {
|
||||
<section class="w-full flex flex-col justify-center my-8 py-4 border-b border-gray-300">
|
||||
<div class="w-full p-4 md:p-8 flex items-center gap-x-8">
|
||||
if user.ImageUrl != "" {
|
||||
<img class="w-24 md:w-32 border-2 border-blue-500 rounded-full shadow-blue-500 shadow select-none" src={
|
||||
user.ImageUrl } />
|
||||
} else {
|
||||
<img class="w-24 md:w-32 border-2 border-blue-500 rounded-full shadow-blue-500 shadow select-none" src={
|
||||
fmt.Sprintf("https://ui-avatars.com/api/?name=%s+%s&size=150", strings.Split(user.Name, " " )[0],
|
||||
strings.Split(user.Name, " " )[1]) } />
|
||||
}
|
||||
<div class="flex flex-col gap-y-4">
|
||||
<div class="">
|
||||
<h1 class="text-md md:text-2xl font-semibold">{ user.Name }</h1>
|
||||
<p class="text-xs md:text-sm">{ user.Email }</p>
|
||||
</div>
|
||||
<div class="flex gap-x-4">
|
||||
<p class="text-xs md:text-sm"><span class="font-bold">{ recipeCount }</span> recipes</p>
|
||||
<p class="text-xs md:text-sm"><span class="font-bold">{ favoriteCount }</span> favorites</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
}
|
||||
|
||||
templ recipesSection(recipes []domainRecipe.Recipe) {
|
||||
<section class="p-8">
|
||||
<h2 class="text-2xl font-semibold text-gray-800">My Recipes</h2>
|
||||
<ul class="w-full my-2">
|
||||
if len(recipes) <= 4 {
|
||||
for _, recipe := range recipes {
|
||||
@recipeListItem(recipe)
|
||||
}
|
||||
} else {
|
||||
for _, recipe := range recipes[:4] {
|
||||
@recipeListItem(recipe)
|
||||
}
|
||||
}
|
||||
<a href="/" class="bg-red-500">
|
||||
<li
|
||||
class="w-full border-b border-gray-300 px-2 py-4 even:bg-gray-50 hover:bg-gray-100 hover:text-blue-600 duration-150 text-center"
|
||||
>
|
||||
See all...
|
||||
</li>
|
||||
</a>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="p-8">
|
||||
<h2 class="text-2xl font-semibold text-gray-800">My Recipes</h2>
|
||||
<ul class="w-full my-2">
|
||||
if len(recipes) <= 4 {
|
||||
for _, recipe :=range recipes {
|
||||
@recipeListItem(recipe)
|
||||
}
|
||||
} else {
|
||||
for _, recipe :=range recipes[:4] {
|
||||
@recipeListItem(recipe)
|
||||
}
|
||||
}
|
||||
<a href="/">
|
||||
<li
|
||||
class="w-full border-b border-gray-300 px-2 py-4 even:bg-gray-50 hover:bg-gray-100 hover:text-blue-600 duration-150 text-center">
|
||||
See all...
|
||||
</li>
|
||||
</a>
|
||||
</ul>
|
||||
</section>
|
||||
}
|
||||
|
||||
templ favoritesSection(recipes []domainRecipe.Recipe) {
|
||||
<section class="p-8">
|
||||
<h2 class="text-2xl font-semibold text-gray-800">My Favorites</h2>
|
||||
<p class="text-sm my-2">Favorites section is under construction!</p>
|
||||
</section>
|
||||
<section class="p-8">
|
||||
<h2 class="text-2xl font-semibold text-gray-800">My Favorites</h2>
|
||||
<ul class="w-full my-2">
|
||||
if len(recipes) <= 4 {
|
||||
for _, recipe := range recipes {
|
||||
@recipeListItem(recipe)
|
||||
}
|
||||
} else {
|
||||
for _, recipe := range recipes[:4] {
|
||||
@recipeListItem(recipe)
|
||||
}
|
||||
}
|
||||
<a href={ domain.WEB_FAVORITES }>
|
||||
<li
|
||||
class="w-full border-b border-gray-300 px-2 py-4 even:bg-gray-50 hover:bg-gray-100 hover:text-blue-600 duration-150 text-center">
|
||||
See all...
|
||||
</li>
|
||||
</a>
|
||||
</ul>
|
||||
</section>
|
||||
}
|
||||
|
||||
templ activitySection(engagement []domainEngagement.Engagement) {
|
||||
<section class="p-8">
|
||||
<h2 class="text-2xl font-semibold text-gray-800">Recent Activity</h2>
|
||||
<p class="text-sm my-2">Activity section is under construction!</p>
|
||||
<ul class="w-full my-2">
|
||||
for _, eng := range engagement {
|
||||
@activityListItem(eng)
|
||||
}
|
||||
<a href="/" class="bg-red-500">
|
||||
<li
|
||||
class="w-full border-b border-gray-300 px-2 py-4 even:bg-gray-50 hover:bg-gray-100 hover:text-blue-600 duration-150 text-center"
|
||||
>
|
||||
See all...
|
||||
</li>
|
||||
</a>
|
||||
</ul>
|
||||
</section>
|
||||
<section class="p-8">
|
||||
<h2 class="text-2xl font-semibold text-gray-800">Recent Activity</h2>
|
||||
<p class="text-sm my-2">Activity section is under construction!</p>
|
||||
<ul class="w-full my-2">
|
||||
for _, eng := range engagement {
|
||||
@activityListItem(eng)
|
||||
}
|
||||
<a href="/" class="bg-red-500">
|
||||
<li
|
||||
class="w-full border-b border-gray-300 px-2 py-4 even:bg-gray-50 hover:bg-gray-100 hover:text-blue-600 duration-150 text-center">
|
||||
See all...
|
||||
</li>
|
||||
</a>
|
||||
</ul>
|
||||
</section>
|
||||
}
|
||||
|
||||
templ recipeListItem(recipe domainRecipe.Recipe) {
|
||||
<li class="w-full border-b border-gray-300 px-2 py-4 even:bg-gray-50 hover:bg-gray-100 duration-150">
|
||||
<p
|
||||
hx-post={ fmt.Sprintf(domain.API_ENGAGEMENT_VIEW, recipe.Id) }
|
||||
hx-trigger="click"
|
||||
hx-swap="none"
|
||||
class="text-base md:text-lg hover:text-blue-600 duration-100 cursor-pointer"
|
||||
>
|
||||
{ recipe.Title }
|
||||
</p>
|
||||
<p class="hidden md:block text-sm text-gray-700 my-1.5">
|
||||
Difficulty: <span class="font-semibold">{ displayDifficulty(recipe.Difficulty) }</span>
|
||||
| Duration: <span class="font-semibold">{ recipe.Duration.Total } min</span>
|
||||
| Category: <span class="font-semibold">{ recipe.Category }</span>
|
||||
</p>
|
||||
<p class="md:hidden text-xs md:text-sm text-gray-700 my-1">
|
||||
Difficulty: <span class="font-semibold">{ displayDifficulty(recipe.Difficulty) }</span>
|
||||
</p>
|
||||
<p class="md:hidden text-xs md:text-sm text-gray-700 my-1">
|
||||
Duration: <span class="font-semibold">{ recipe.Duration.Total } min</span>
|
||||
</p>
|
||||
<p class="md:hidden text-xs md:text-sm text-gray-700 my-1">
|
||||
Category: <span class="font-semibold">{ recipe.Category }</span>
|
||||
</p>
|
||||
if len(recipe.Tags) > 0 {
|
||||
<p class="text-xs italic text-gray-500">
|
||||
Tags: { displayTags(recipe.Tags) }
|
||||
</p>
|
||||
}
|
||||
</li>
|
||||
<li class="w-full border-b border-gray-300 px-2 py-4 even:bg-gray-50 hover:bg-gray-100 duration-150">
|
||||
<p hx-post={ fmt.Sprintf(domain.API_ENGAGEMENT_VIEW, recipe.Id) } hx-trigger="click" hx-swap="none"
|
||||
class="text-base md:text-lg hover:text-blue-600 duration-100 cursor-pointer">
|
||||
{ recipe.Title }
|
||||
</p>
|
||||
<p class="hidden md:block text-sm text-gray-700 my-1.5">
|
||||
Difficulty: <span class="font-semibold">{ displayDifficulty(recipe.Difficulty) }</span>
|
||||
| Duration: <span class="font-semibold">{ recipe.Duration.Total } min</span>
|
||||
| Category: <span class="font-semibold">{ recipe.Category }</span>
|
||||
</p>
|
||||
<p class="md:hidden text-xs md:text-sm text-gray-700 my-1">
|
||||
Difficulty: <span class="font-semibold">{ displayDifficulty(recipe.Difficulty) }</span>
|
||||
</p>
|
||||
<p class="md:hidden text-xs md:text-sm text-gray-700 my-1">
|
||||
Duration: <span class="font-semibold">{ recipe.Duration.Total } min</span>
|
||||
</p>
|
||||
<p class="md:hidden text-xs md:text-sm text-gray-700 my-1">
|
||||
Category: <span class="font-semibold">{ recipe.Category }</span>
|
||||
</p>
|
||||
if len(recipe.Tags) > 0 {
|
||||
<p class="text-xs italic text-gray-500">
|
||||
Tags: { displayTags(recipe.Tags) }
|
||||
</p>
|
||||
}
|
||||
</li>
|
||||
}
|
||||
|
||||
templ activityListItem(engagement domainEngagement.Engagement) {
|
||||
<li
|
||||
class="w-full border-b border-gray-300 px-2 py-4 even:bg-gray-50 hover:bg-gray-100 duration-150 flex justify-between items-center"
|
||||
>
|
||||
<p class="text-sm md:text-base text-gray-800">
|
||||
{ engagement.Message }
|
||||
</p>
|
||||
<p class="text-xs md:text-sm text-gray-600 w-fit shrink-0">
|
||||
{ engagement.Created.Format("01/02/2006") }
|
||||
</p>
|
||||
</li>
|
||||
<li
|
||||
class="w-full border-b border-gray-300 px-2 py-4 even:bg-gray-50 hover:bg-gray-100 duration-150 flex justify-between items-center">
|
||||
<p class="text-sm md:text-base text-gray-800">
|
||||
{ engagement.Message }
|
||||
</p>
|
||||
<p class="text-xs md:text-sm text-gray-600 w-fit shrink-0">
|
||||
{ engagement.Created.Format("01/02/2006") }
|
||||
</p>
|
||||
</li>
|
||||
}
|
||||
|
||||
templ logoutSection() {
|
||||
<section class="w-full flex flex-col justify-center items-center py-8 border-t border-gray-300 mt-auto">
|
||||
<a
|
||||
href={ domain.API_AUTH_LOGOUT }
|
||||
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
|
||||
</a>
|
||||
</section>
|
||||
<section class="w-full flex flex-col justify-center items-center py-8 border-t border-gray-300 mt-auto">
|
||||
<a href={ domain.API_AUTH_LOGOUT }
|
||||
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
|
||||
</a>
|
||||
</section>
|
||||
}
|
||||
|
||||
templ ProfilePage(user domainUser.User, recipes []domainRecipe.Recipe, engagement []domainEngagement.Engagement) {
|
||||
@components.Navbar(" profile")
|
||||
<div class="w-full h-fit flex justify-center">
|
||||
<div class="mx-2 md:mx-0 w-full md:w-1/2 md:pt-14 border-l border-r border-gray-300 bg-white flex flex-col">
|
||||
@userDetailsSection(user, len(recipes))
|
||||
@recipesSection(recipes)
|
||||
@favoritesSection(recipes)
|
||||
@activitySection(engagement)
|
||||
@logoutSection()
|
||||
</div>
|
||||
</div>
|
||||
templ ProfilePage(user domainUser.User, recipes []domainRecipe.Recipe, favorites []domainRecipe.Recipe, engagement []domainEngagement.Engagement) {
|
||||
@components.Navbar(" profile")
|
||||
<div class="w-full h-fit flex justify-center">
|
||||
<div class="mx-2 md:mx-0 w-full md:w-1/2 md:pt-14 border-l border-r border-gray-300 bg-white flex flex-col">
|
||||
@userDetailsSection(user, len(recipes), len(favorites))
|
||||
@recipesSection(recipes)
|
||||
@favoritesSection(favorites)
|
||||
@activitySection(engagement)
|
||||
@logoutSection()
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@ -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, "</span> recipes</p><p class=\"text-xs md:text-sm\"><span class=\"font-bold\">0</span> favorites</p></div></div></div></section>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "</span> recipes</p><p class=\"text-xs md:text-sm\"><span class=\"font-bold\">")
|
||||
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, "</span> favorites</p></div></div></div></section>")
|
||||
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, "<section class=\"p-8\"><h2 class=\"text-2xl font-semibold text-gray-800\">My Recipes</h2><ul class=\"w-full my-2\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "<section class=\"p-8\"><h2 class=\"text-2xl font-semibold text-gray-800\">My Recipes</h2><ul class=\"w-full my-2\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -190,7 +206,7 @@ func recipesSection(recipes []domainRecipe.Recipe) templ.Component {
|
||||
}
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "<a href=\"/\" class=\"bg-red-500\"><li class=\"w-full border-b border-gray-300 px-2 py-4 even:bg-gray-50 hover:bg-gray-100 hover:text-blue-600 duration-150 text-center\">See all...</li></a></ul></section>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "<a href=\"/\"><li class=\"w-full border-b border-gray-300 px-2 py-4 even:bg-gray-50 hover:bg-gray-100 hover:text-blue-600 duration-150 text-center\">See all...</li></a></ul></section>")
|
||||
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, "<section class=\"p-8\"><h2 class=\"text-2xl font-semibold text-gray-800\">My Favorites</h2><p class=\"text-sm my-2\">Favorites section is under construction!</p></section>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "<section class=\"p-8\"><h2 class=\"text-2xl font-semibold text-gray-800\">My Favorites</h2><ul class=\"w-full my-2\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if len(recipes) <= 4 {
|
||||
for _, recipe := range recipes {
|
||||
templ_7745c5c3_Err = recipeListItem(recipe).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, recipe := range recipes[:4] {
|
||||
templ_7745c5c3_Err = recipeListItem(recipe).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "<a href=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 templ.SafeURL = domain.WEB_FAVORITES
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var10)))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "\"><li class=\"w-full border-b border-gray-300 px-2 py-4 even:bg-gray-50 hover:bg-gray-100 hover:text-blue-600 duration-150 text-center\">See all...</li></a></ul></section>")
|
||||
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, "<section class=\"p-8\"><h2 class=\"text-2xl font-semibold text-gray-800\">Recent Activity</h2><p class=\"text-sm my-2\">Activity section is under construction!</p><ul class=\"w-full my-2\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "<section class=\"p-8\"><h2 class=\"text-2xl font-semibold text-gray-800\">Recent Activity</h2><p class=\"text-sm my-2\">Activity section is under construction!</p><ul class=\"w-full my-2\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -258,7 +302,7 @@ func activitySection(engagement []domainEngagement.Engagement) templ.Component {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "<a href=\"/\" class=\"bg-red-500\"><li class=\"w-full border-b border-gray-300 px-2 py-4 even:bg-gray-50 hover:bg-gray-100 hover:text-blue-600 duration-150 text-center\">See all...</li></a></ul></section>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "<a href=\"/\" class=\"bg-red-500\"><li class=\"w-full border-b border-gray-300 px-2 py-4 even:bg-gray-50 hover:bg-gray-100 hover:text-blue-600 duration-150 text-center\">See all...</li></a></ul></section>")
|
||||
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, "<li class=\"w-full border-b border-gray-300 px-2 py-4 even:bg-gray-50 hover:bg-gray-100 duration-150\"><p hx-post=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var11 string
|
||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(domain.API_ENGAGEMENT_VIEW, recipe.Id))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 117, Col: 66}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "\" 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_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, "</p><p class=\"hidden md:block text-sm text-gray-700 my-1.5\">Difficulty: <span class=\"font-semibold\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "<li class=\"w-full border-b border-gray-300 px-2 py-4 even:bg-gray-50 hover:bg-gray-100 duration-150\"><p hx-post=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var13 string
|
||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(displayDifficulty(recipe.Difficulty))
|
||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf(domain.API_ENGAGEMENT_VIEW, recipe.Id))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 125, Col: 81}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/profile.templ`, Line: 127, Col: 65}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "</span> | Duration: <span class=\"font-semibold\">")
|
||||
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</span> | Category: <span class=\"font-semibold\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "</p><p class=\"hidden md:block text-sm text-gray-700 my-1.5\">Difficulty: <span class=\"font-semibold\">")
|
||||
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, "</span></p><p class=\"md:hidden text-xs md:text-sm text-gray-700 my-1\">Difficulty: <span class=\"font-semibold\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "</span> | Duration: <span class=\"font-semibold\">")
|
||||
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, "</span></p><p class=\"md:hidden text-xs md:text-sm text-gray-700 my-1\">Duration: <span class=\"font-semibold\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, " min</span> | Category: <span class=\"font-semibold\">")
|
||||
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</span></p><p class=\"md:hidden text-xs md:text-sm text-gray-700 my-1\">Category: <span class=\"font-semibold\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "</span></p><p class=\"md:hidden text-xs md:text-sm text-gray-700 my-1\">Difficulty: <span class=\"font-semibold\">")
|
||||
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, "</span></p>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "</span></p><p class=\"md:hidden text-xs md:text-sm text-gray-700 my-1\">Duration: <span class=\"font-semibold\">")
|
||||
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</span></p><p class=\"md:hidden text-xs md:text-sm text-gray-700 my-1\">Category: <span class=\"font-semibold\">")
|
||||
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, "</span></p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if len(recipe.Tags) > 0 {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "<p class=\"text-xs italic text-gray-500\">Tags: ")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "<p class=\"text-xs italic text-gray-500\">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, "</p>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "</li>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "</li>")
|
||||
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, "<li class=\"w-full border-b border-gray-300 px-2 py-4 even:bg-gray-50 hover:bg-gray-100 duration-150 flex justify-between items-center\"><p class=\"text-sm md:text-base text-gray-800\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "<li class=\"w-full border-b border-gray-300 px-2 py-4 even:bg-gray-50 hover:bg-gray-100 duration-150 flex justify-between items-center\"><p class=\"text-sm md:text-base text-gray-800\">")
|
||||
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, "</p><p class=\"text-xs md:text-sm text-gray-600 w-fit shrink-0\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "</p><p class=\"text-xs md:text-sm text-gray-600 w-fit shrink-0\">")
|
||||
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, "</p></li>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "</p></li>")
|
||||
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, "<section class=\"w-full flex flex-col justify-center items-center py-8 border-t border-gray-300 mt-auto\"><a href=\"")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "<section class=\"w-full flex flex-col justify-center items-center py-8 border-t border-gray-300 mt-auto\"><a href=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var24 templ.SafeURL = domain.API_AUTH_LOGOUT
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var24)))
|
||||
var templ_7745c5c3_Var26 templ.SafeURL = domain.API_AUTH_LOGOUT
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var26)))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "\" 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</a></section>")
|
||||
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</a></section>")
|
||||
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, "<div class=\"w-full h-fit flex justify-center\"><div class=\"mx-2 md:mx-0 w-full md:w-1/2 md:pt-14 border-l border-r border-gray-300 bg-white flex flex-col\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "<div class=\"w-full h-fit flex justify-center\"><div class=\"mx-2 md:mx-0 w-full md:w-1/2 md:pt-14 border-l border-r border-gray-300 bg-white flex flex-col\">")
|
||||
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, "</div></div>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "</div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
||||
@ -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)
|
||||
<hr class="text-gray-300 w-full"/>
|
||||
@ResultList(nil)
|
||||
</div>
|
||||
@ -38,33 +38,47 @@ templ ResultList(recipes []domain.Recipe) {
|
||||
|
||||
templ searchResult(recipe domain.Recipe) {
|
||||
<div
|
||||
hx-post={ fmt.Sprintf(domainServer.API_ENGAGEMENT_VIEW, recipe.Id) }
|
||||
hx-trigger="click"
|
||||
hx-swap="none"
|
||||
hx-post={ fmt.Sprintf(domainServer.API_ENGAGEMENT_VIEW, recipe.Id) }
|
||||
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"
|
||||
>
|
||||
<img class="bg-gray-50 size-56 md:size-40 rounded-md border-0" src=""/>
|
||||
<div class="text-gray-700 p-4 flex flex-col items-center md:items-start">
|
||||
<h3 class="text-xl font-semibold text-black pb-1">
|
||||
{ recipe.Title } <span class="text-sm font-normal hidden md:inline">{ recipe.Category }</span>
|
||||
</h3>
|
||||
<div class="text-sm flex gap-x-3 gap-y-1 items-center flex-wrap">
|
||||
<span class="flex gap-x-1 align-center">
|
||||
@timeIconSm()
|
||||
{ recipe.Duration.Total } min
|
||||
</span>
|
||||
<span class="flex gap-x-1 align-center">
|
||||
for _ = range(recipe.Difficulty) {
|
||||
@starIconSm(true)
|
||||
}
|
||||
for _ = range(5 - recipe.Difficulty) {
|
||||
@starIconSm(false)
|
||||
}
|
||||
</span>
|
||||
<span class="flex gap-x-1 align-center">
|
||||
@servingIconSm()
|
||||
Serves { recipe.Serves }
|
||||
</span>
|
||||
<div class="text-gray-700 p-4 flex flex-col items-center md:items-start w-full">
|
||||
<div class="flex flex-col md:flex-row items-center md:items-start justify-between w-full">
|
||||
<div class="flex flex-col items-center md:items-start">
|
||||
<h3 class="text-xl font-semibold text-black pb-1">
|
||||
{ recipe.Title } <span class="text-sm font-normal hidden md:inline">{ recipe.Category }</span>
|
||||
</h3>
|
||||
<div class="text-sm flex gap-x-3 gap-y-1 items-center flex-wrap">
|
||||
<span class="flex gap-x-1 align-center">
|
||||
@timeIconSm()
|
||||
{ recipe.Duration.Total } min
|
||||
</span>
|
||||
<span class="flex gap-x-1 align-center">
|
||||
for _ = range(recipe.Difficulty) {
|
||||
@starIconSm(true)
|
||||
}
|
||||
for _ = range(5 - recipe.Difficulty) {
|
||||
@starIconSm(false)
|
||||
}
|
||||
</span>
|
||||
<span class="flex gap-x-1 align-center">
|
||||
@servingIconSm()
|
||||
Serves { recipe.Serves }
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-2 mt-4 md:my-0 hidden md:block">
|
||||
if recipe.Favorite {
|
||||
<svg class="h-6 text-red-500" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M2 9.1371C2 14 6.01943 16.5914 8.96173 18.9109C10 19.7294 11 20.5 12 20.5C13 20.5 14 19.7294 15.0383 18.9109C17.9806 16.5914 22 14 22 9.1371C22 4.27416 16.4998 0.825464 12 5.50063C7.50016 0.825464 2 4.27416 2 9.1371Z"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
</svg>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-sm py-2 text-center md:text-left">{ recipe.Description }</p>
|
||||
</div>
|
||||
|
||||
@ -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\"><img class=\"bg-gray-50 size-56 md:size-40 rounded-md border-0\" src=\"\"><div class=\"text-gray-700 p-4 flex flex-col items-center md:items-start\"><h3 class=\"text-xl font-semibold text-black pb-1\">")
|
||||
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\"><img class=\"bg-gray-50 size-56 md:size-40 rounded-md border-0\" src=\"\"><div class=\"text-gray-700 p-4 flex flex-col items-center md:items-start w-full\"><div class=\"flex flex-col md:flex-row items-center md:items-start justify-between w-full\"><div class=\"flex flex-col items-center md:items-start\"><h3 class=\"text-xl font-semibold text-black pb-1\">")
|
||||
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, "</span></div><p class=\"text-sm py-2 text-center md:text-left\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "</span></div></div><div class=\"mb-2 mt-4 md:my-0 hidden md:block\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if recipe.Favorite {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "<svg class=\"h-6 text-red-500\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M2 9.1371C2 14 6.01943 16.5914 8.96173 18.9109C10 19.7294 11 20.5 12 20.5C13 20.5 14 19.7294 15.0383 18.9109C17.9806 16.5914 22 14 22 9.1371C22 4.27416 16.4998 0.825464 12 5.50063C7.50016 0.825464 2 4.27416 2 9.1371Z\" fill=\"currentColor\"></path></svg>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "</div></div><p class=\"text-sm py-2 text-center md:text-left\">")
|
||||
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, "</p></div></div>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "</p></div></div>")
|
||||
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, "<svg class=\"h-5 text-blue-600\" fill=\"currentColor\" version=\"1.1\" id=\"Icons\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" xml:space=\"preserve\"><g><circle cx=\"12\" cy=\"16\" r=\"5\"></circle> <path d=\"M12,6C6.5,6,2,10.5,2,16s4.5,10,10,10s10-4.5,10-10S17.5,6,12,6z M12,23c-3.9,0-7-3.1-7-7s3.1-7,7-7s7,3.1,7,7\n\t\tS15.9,23,12,23z\"></path> <path d=\"M30,10.5V5c0-0.6-0.4-1-1-1s-1,0.4-1,1v5.5c0,0.2,0,0.4,0,0.5h-1V5c0-0.6-0.4-1-1-1s-1,0.4-1,1v6h-1c0-0.2,0-0.4,0-0.5V5\n\t\tc0-0.6-0.4-1-1-1s-1,0.4-1,1v5.5c0,1.9,0.5,3.4,1.4,4.3c0.7,0.8,1,1.8,0.9,2.7l-1,7.3c-0.1,0.8,0.1,1.6,0.6,2.2S25.2,28,26,28\n\t\ts1.5-0.3,2.1-0.9s0.8-1.4,0.6-2.2l-1-7.3c-0.1-1,0.2-2,0.9-2.8C29.5,13.8,30,12.3,30,10.5z\"></path></g></svg>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "<svg class=\"h-5 text-blue-600\" fill=\"currentColor\" version=\"1.1\" id=\"Icons\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" viewBox=\"0 0 32 32\" xml:space=\"preserve\"><g><circle cx=\"12\" cy=\"16\" r=\"5\"></circle> <path d=\"M12,6C6.5,6,2,10.5,2,16s4.5,10,10,10s10-4.5,10-10S17.5,6,12,6z M12,23c-3.9,0-7-3.1-7-7s3.1-7,7-7s7,3.1,7,7\n\t\tS15.9,23,12,23z\"></path> <path d=\"M30,10.5V5c0-0.6-0.4-1-1-1s-1,0.4-1,1v5.5c0,0.2,0,0.4,0,0.5h-1V5c0-0.6-0.4-1-1-1s-1,0.4-1,1v6h-1c0-0.2,0-0.4,0-0.5V5\n\t\tc0-0.6-0.4-1-1-1s-1,0.4-1,1v5.5c0,1.9,0.5,3.4,1.4,4.3c0.7,0.8,1,1.8,0.9,2.7l-1,7.3c-0.1,0.8,0.1,1.6,0.6,2.2S25.2,28,26,28\n\t\ts1.5-0.3,2.1-0.9s0.8-1.4,0.6-2.2l-1-7.3c-0.1-1,0.2-2,0.9-2.8C29.5,13.8,30,12.3,30,10.5z\"></path></g></svg>")
|
||||
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, "<svg class=\"h-5 text-blue-600\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M12 7V12L14.5 13.5M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path></svg>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "<svg class=\"h-5 text-blue-600\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M12 7V12L14.5 13.5M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path></svg>")
|
||||
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, "<svg class=\"h-4 text-blue-600\" fill=\"currentColor\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M23.632 9.201a.628.628 0 0 1-.22.678l-5.726 4.96 1.727 7.394a.606.606 0 0 1-.935.676l-6.503-3.953-6.503 3.953a.713.713 0 0 1-.374.112.57.57 0 0 1-.34-.109.629.629 0 0 1-.222-.679l1.729-7.393L.539 9.879A.607.607 0 0 1 .897 8.78l7.536-.635 2.965-7.083a.62.62 0 0 1 1.155.001l2.965 7.082 7.536.635a.63.63 0 0 1 .578.42z\"></path> <path fill=\"none\" d=\"M0 0h24v24H0z\"></path></svg>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "<svg class=\"h-4 text-blue-600\" fill=\"currentColor\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M23.632 9.201a.628.628 0 0 1-.22.678l-5.726 4.96 1.727 7.394a.606.606 0 0 1-.935.676l-6.503-3.953-6.503 3.953a.713.713 0 0 1-.374.112.57.57 0 0 1-.34-.109.629.629 0 0 1-.222-.679l1.729-7.393L.539 9.879A.607.607 0 0 1 .897 8.78l7.536-.635 2.965-7.083a.62.62 0 0 1 1.155.001l2.965 7.082 7.536.635a.63.63 0 0 1 .578.42z\"></path> <path fill=\"none\" d=\"M0 0h24v24H0z\"></path></svg>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
} else {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "<svg class=\"h-4 text-gray-500\" fill=\"currentColor\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M23.054 8.781l-7.536-.635-2.965-7.082a.619.619 0 0 0-1.155 0L8.433 8.145.896 8.78a.607.607 0 0 0-.357 1.1l5.726 4.96-1.729 7.395a.63.63 0 0 0 .223.679.573.573 0 0 0 .339.108.717.717 0 0 0 .374-.111l6.503-3.954 6.503 3.953a.606.606 0 0 0 .935-.677l-1.727-7.392 5.725-4.96a.607.607 0 0 0-.357-1.099zm-6.48 5.698l1.662 7.113-6.261-3.806-6.262 3.807 1.663-7.114-5.513-4.776 7.257-.611 2.855-6.817 2.855 6.817 7.257.611z\"></path> <path fill=\"none\" d=\"M0 0h24v24H0z\"></path></svg>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "<svg class=\"h-4 text-gray-500\" fill=\"currentColor\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M23.054 8.781l-7.536-.635-2.965-7.082a.619.619 0 0 0-1.155 0L8.433 8.145.896 8.78a.607.607 0 0 0-.357 1.1l5.726 4.96-1.729 7.395a.63.63 0 0 0 .223.679.573.573 0 0 0 .339.108.717.717 0 0 0 .374-.111l6.503-3.954 6.503 3.953a.606.606 0 0 0 .935-.677l-1.727-7.392 5.725-4.96a.607.607 0 0 0-.357-1.099zm-6.48 5.698l1.662 7.113-6.261-3.806-6.262 3.807 1.663-7.114-5.513-4.776 7.257-.611 2.855-6.817 2.855 6.817 7.257.611z\"></path> <path fill=\"none\" d=\"M0 0h24v24H0z\"></path></svg>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user