(FIX): Using cookies to store filter data.
This means that we can use the cookie data to load the filters when the search page loads. The final step is making sure the search is complete and the simple redirection. Which will come in the next commit!
This commit is contained in:
parent
c0fc47c569
commit
d950e75540
@ -1,12 +1,15 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/a-h/templ"
|
||||
"github.com/gin-gonic/gin"
|
||||
domain "github.com/haydenhargreaves/Potion/internal/domain/server"
|
||||
domainRecipe "github.com/haydenhargreaves/Potion/internal/domain/recipe"
|
||||
domainServer "github.com/haydenhargreaves/Potion/internal/domain/server"
|
||||
layouts "github.com/haydenhargreaves/Potion/internal/templates/layouts"
|
||||
pages "github.com/haydenhargreaves/Potion/internal/templates/pages"
|
||||
)
|
||||
@ -34,8 +37,8 @@ func FavoritesPage(ctx *gin.Context) {
|
||||
|
||||
func CreatePage(ctx *gin.Context) {
|
||||
// If not logged in, direct to the login page
|
||||
if !domain.IsLoggedIn(ctx) {
|
||||
ctx.Redirect(http.StatusSeeOther, domain.WEB_LOGIN)
|
||||
if !domainServer.IsLoggedIn(ctx) {
|
||||
ctx.Redirect(http.StatusSeeOther, domainServer.WEB_LOGIN)
|
||||
return
|
||||
}
|
||||
|
||||
@ -47,13 +50,13 @@ func CreatePage(ctx *gin.Context) {
|
||||
|
||||
func ProfilePage(ctx *gin.Context) {
|
||||
// If not logged in, direct to the login page
|
||||
if !domain.IsLoggedIn(ctx) {
|
||||
ctx.Redirect(http.StatusSeeOther, domain.WEB_LOGIN)
|
||||
if !domainServer.IsLoggedIn(ctx) {
|
||||
ctx.Redirect(http.StatusSeeOther, domainServer.WEB_LOGIN)
|
||||
return
|
||||
}
|
||||
|
||||
// Else, get the user data
|
||||
deps := ctx.MustGet("deps").(*domain.InjectedDependencies)
|
||||
deps := ctx.MustGet("deps").(*domainServer.InjectedDependencies)
|
||||
user := deps.UserService.GetAuthenicatedUser(ctx)
|
||||
|
||||
title := "Potion - Profile"
|
||||
@ -72,7 +75,7 @@ func ListPage(ctx *gin.Context) {
|
||||
// TODO: Figure out how to handle errors, think we just need a simple display.
|
||||
func RecipePage(ctx *gin.Context) {
|
||||
// Call recipe service to get via ID
|
||||
deps := ctx.MustGet("deps").(*domain.InjectedDependencies)
|
||||
deps := ctx.MustGet("deps").(*domainServer.InjectedDependencies)
|
||||
id := ctx.Param("id")
|
||||
|
||||
// Parse ID
|
||||
@ -106,10 +109,22 @@ func RecipePage(ctx *gin.Context) {
|
||||
}
|
||||
|
||||
func SearchPage(ctx *gin.Context) {
|
||||
title := "Potion - Recipe Search"
|
||||
page := pages.SearchPage()
|
||||
var page templ.Component
|
||||
// Get filters from cookies
|
||||
if bytes, err := ctx.Cookie("search-filters"); err != nil {
|
||||
fmt.Printf("ERROR: Failed to get search-filter cookie. %s\n", err.Error())
|
||||
page = pages.SearchPage(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.SearchPage(domainRecipe.SearchFilters{})
|
||||
} else {
|
||||
page = pages.SearchPage(filters)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("I OPENED A PAGE!")
|
||||
title := "Potion - Recipe Search"
|
||||
|
||||
ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page))
|
||||
}
|
||||
|
||||
@ -1,10 +1,14 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
domainRecipe "github.com/haydenhargreaves/Potion/internal/domain/recipe"
|
||||
domain "github.com/haydenhargreaves/Potion/internal/domain/server"
|
||||
templates "github.com/haydenhargreaves/Potion/internal/templates/pages"
|
||||
)
|
||||
@ -30,10 +34,42 @@ func CreateRecipe(ctx *gin.Context) {
|
||||
ctx.Status(http.StatusCreated)
|
||||
}
|
||||
|
||||
// toBits converts an array of stringified numbers into a single summed value
|
||||
func toBits(arr []string) (bits int) {
|
||||
for _, x := range arr {
|
||||
num, _ := strconv.Atoi(x)
|
||||
bits += num
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: I don't love doing all of this here, but it seems to be the only way to get it to work...
|
||||
func SearchRecipes(ctx *gin.Context) {
|
||||
deps := ctx.MustGet("deps").(*domain.InjectedDependencies)
|
||||
|
||||
recipes, err := deps.RecipeService.SearchRecipes(ctx)
|
||||
// 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(2*time.Hour).Sub(time.Now()).Seconds()),
|
||||
"/",
|
||||
"localhost", // TODO: real domain
|
||||
false, // TODO: True in prod
|
||||
true,
|
||||
)
|
||||
}
|
||||
|
||||
recipes, err := deps.RecipeService.SearchRecipes(filters)
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusOK, gin.H{"error": err.Error()})
|
||||
}
|
||||
|
||||
@ -130,21 +130,7 @@ func (s *RecipeService) GetRecipe(id int) (*domain.Recipe, error) {
|
||||
return recipe, err
|
||||
}
|
||||
|
||||
// toBits converts an array of stringified numbers into a single summed value
|
||||
func toBits(arr []string) (bits int) {
|
||||
for _, x := range arr {
|
||||
num, _ := strconv.Atoi(x)
|
||||
bits += num
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// isBitActive returns true when the bit at pos (0 indexed) is true.
|
||||
func isBitActive(bits, pos int) bool {
|
||||
return (bits>>pos)&1 == 1
|
||||
}
|
||||
|
||||
func (s *RecipeService) SearchRecipes(ctx *gin.Context) ([]domain.Recipe, error) {
|
||||
func (s *RecipeService) SearchRecipes(filters domain.SearchFilters) ([]domain.Recipe, error) {
|
||||
// NOTE: How are the filters handled?
|
||||
// Each input is given a bit value (e.g., 00001 for 1) and will be passed
|
||||
// back to this handler as an array. The values are then added together
|
||||
@ -154,22 +140,8 @@ func (s *RecipeService) SearchRecipes(ctx *gin.Context) ([]domain.Recipe, error)
|
||||
// Parsing these is simple, for each filter option, use the bitwise and (&)
|
||||
// operator with the value we expect for the filter. When 1, we can ensure
|
||||
// the filter is provided.
|
||||
// A function above (isBitActive) provides an example of testing of testing
|
||||
// the filter parsing.
|
||||
|
||||
search := ctx.PostForm("search") // string, search query for titles
|
||||
meal := toBits(ctx.PostFormArray("meal"))
|
||||
time := toBits(ctx.PostFormArray("time"))
|
||||
difficulty := toBits(ctx.PostFormArray("difficulty"))
|
||||
serving := toBits(ctx.PostFormArray("serving"))
|
||||
|
||||
filters := domain.SearchFilters{
|
||||
Search: search,
|
||||
MealType: meal,
|
||||
Time: time,
|
||||
Difficulty: difficulty,
|
||||
ServingSize: serving,
|
||||
}
|
||||
// A function `isBitActive` in the recipe repository provides an example of
|
||||
// testing of testing the filter parsing.
|
||||
|
||||
return s.recipeRepository.SearchRecipes(filters)
|
||||
}
|
||||
|
||||
@ -5,5 +5,5 @@ import "github.com/gin-gonic/gin"
|
||||
type RecipeService interface {
|
||||
CreateRecipe(ctx *gin.Context) (*Recipe, error)
|
||||
GetRecipe(id int) (*Recipe, error)
|
||||
SearchRecipes(ctx *gin.Context) ([]Recipe, error)
|
||||
SearchRecipes(filters SearchFilters) ([]Recipe, error)
|
||||
}
|
||||
|
||||
@ -1,8 +1,21 @@
|
||||
package components
|
||||
|
||||
templ dropdownButton(content, name, value string) {
|
||||
import "fmt"
|
||||
import domainRecipe "github.com/haydenhargreaves/Potion/internal/domain/recipe"
|
||||
|
||||
// isBitActive returns true when the bit at pos (0 indexed) is true.
|
||||
func isBitActive(bits, pos int) bool {
|
||||
x := (bits>>pos)&1 == 1
|
||||
fmt.Printf("BITS: %d, POS: %d, VAL: %v\n", bits, pos, x)
|
||||
return x
|
||||
}
|
||||
|
||||
templ dropdownButton(content, name, value string, selected bool) {
|
||||
<label class="inline-block cursor-pointer select-none">
|
||||
<input type="checkbox" name={ name } value={ value } class="sr-only peer" />
|
||||
<input type="checkbox" name={ name } value={ value } class="sr-only peer"
|
||||
if selected {
|
||||
checked
|
||||
} />
|
||||
<span class="peer-checked:bg-blue-600 peer-checked:text-white peer-checked:border-blue-600
|
||||
px-2 py-1 border border-gray-300 rounded-lg">
|
||||
{ content }
|
||||
@ -10,7 +23,7 @@ templ dropdownButton(content, name, value string) {
|
||||
</label>
|
||||
}
|
||||
|
||||
templ FilterDropdown() {
|
||||
templ FilterDropdown(filters domainRecipe.SearchFilters) {
|
||||
<script>
|
||||
function toggleDropdown() {
|
||||
const menu = document.getElementById("filter-dropdown-menu");
|
||||
@ -31,13 +44,13 @@ templ FilterDropdown() {
|
||||
Meal
|
||||
</h3>
|
||||
<div class="flex text-xs flex-wrap gap-1 gap-y-3">
|
||||
@dropdownButton("Breakfast", "meal", "1")
|
||||
@dropdownButton("Lunch", "meal", "2")
|
||||
@dropdownButton("Dinner", "meal", "4")
|
||||
@dropdownButton("Desert", "meal", "8")
|
||||
@dropdownButton("Snack", "meal", "16")
|
||||
@dropdownButton("Side", "meal", "32")
|
||||
@dropdownButton("Other", "meal", "64")
|
||||
@dropdownButton("Breakfast", "meal", "1", isBitActive(filters.MealType, 0))
|
||||
@dropdownButton("Lunch", "meal", "2", isBitActive(filters.MealType, 1))
|
||||
@dropdownButton("Dinner", "meal", "4", isBitActive(filters.MealType, 2))
|
||||
@dropdownButton("Desert", "meal", "8", isBitActive(filters.MealType, 3))
|
||||
@dropdownButton("Snack", "meal", "16", isBitActive(filters.MealType, 4))
|
||||
@dropdownButton("Side", "meal", "32", isBitActive(filters.MealType, 5))
|
||||
@dropdownButton("Other", "meal", "64", isBitActive(filters.MealType, 6))
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full border-b border-gray-300 py-2">
|
||||
@ -45,23 +58,23 @@ templ FilterDropdown() {
|
||||
Cook Time
|
||||
</h3>
|
||||
<div class="flex text-xs flex-wrap gap-1 gap-y-3">
|
||||
@dropdownButton("< 15 min", "time" , "1")
|
||||
@dropdownButton("15 to 30 min", "time" , "2")
|
||||
@dropdownButton("30 to 60 min", "time" , "4")
|
||||
@dropdownButton("60 to 120 min", "time" , "8")
|
||||
@dropdownButton("+120 min", "time", "16")
|
||||
@dropdownButton("< 15 min", "time" , "1" , isBitActive(filters.Time, 0))
|
||||
@dropdownButton("15 to 30 min", "time", "2" , isBitActive(filters.Time, 1))
|
||||
@dropdownButton("30 to 60 min", "time" , "4" , isBitActive(filters.Time, 2))
|
||||
@dropdownButton("60 to 120 min", "time" , "8" , isBitActive(filters.Time, 3))
|
||||
@dropdownButton("+120 min", "time" , "16" , isBitActive(filters.Time, 4))
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full border-b border-gray-300 py-2">
|
||||
<h3 class="mb-2">
|
||||
Difficulty
|
||||
</h3>
|
||||
<div class="flex text-xs flex-wrap gap-1 gap-y-3">
|
||||
@dropdownButton("Beginner", "difficulty", "1")
|
||||
@dropdownButton("Easy", "difficulty", "2")
|
||||
@dropdownButton("Intermediate", "difficulty", "4")
|
||||
@dropdownButton("Challenging", "difficulty", "8")
|
||||
@dropdownButton("Extreme", "difficulty", "16")
|
||||
<div class="flex text-xs flex-wrap gap-1 gap-y-3">
|
||||
@dropdownButton("Beginner", "difficulty", "1", isBitActive(filters.Difficulty, 0))
|
||||
@dropdownButton("Easy", "difficulty", "2", isBitActive(filters.Difficulty, 1))
|
||||
@dropdownButton("Intermediate", "difficulty", "4", isBitActive(filters.Difficulty, 2))
|
||||
@dropdownButton("Challenging", "difficulty", "8", isBitActive(filters.Difficulty, 3))
|
||||
@dropdownButton("Extreme", "difficulty", "16", isBitActive(filters.Difficulty, 4))
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full border-b border-gray-300 py-2">
|
||||
@ -69,11 +82,11 @@ templ FilterDropdown() {
|
||||
Serving Size
|
||||
</h3>
|
||||
<div class="flex text-xs flex-wrap gap-1 gap-y-3">
|
||||
@dropdownButton("1 to 2", "serving", "1")
|
||||
@dropdownButton("2 to 4", "serving", "2")
|
||||
@dropdownButton("4 to 6", "serving", "4")
|
||||
@dropdownButton("6 to 8", "serving", "8")
|
||||
@dropdownButton("8+", "serving", "16")
|
||||
@dropdownButton("1 to 2", "serving", "1", isBitActive(filters.ServingSize, 0))
|
||||
@dropdownButton("2 to 4", "serving", "2", isBitActive(filters.ServingSize, 1))
|
||||
@dropdownButton("4 to 6", "serving", "4", isBitActive(filters.ServingSize, 2))
|
||||
@dropdownButton("6 to 8", "serving", "8", isBitActive(filters.ServingSize, 3))
|
||||
@dropdownButton("8+", "serving", "16", isBitActive(filters.ServingSize, 4))
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -8,7 +8,17 @@ package components
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
func dropdownButton(content, name, value string) templ.Component {
|
||||
import "fmt"
|
||||
import domainRecipe "github.com/haydenhargreaves/Potion/internal/domain/recipe"
|
||||
|
||||
// isBitActive returns true when the bit at pos (0 indexed) is true.
|
||||
func isBitActive(bits, pos int) bool {
|
||||
x := (bits>>pos)&1 == 1
|
||||
fmt.Printf("BITS: %d, POS: %d, VAL: %v\n", bits, pos, x)
|
||||
return x
|
||||
}
|
||||
|
||||
func dropdownButton(content, name, value string, selected 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 {
|
||||
@ -36,7 +46,7 @@ func dropdownButton(content, name, value string) templ.Component {
|
||||
var templ_7745c5c3_Var2 string
|
||||
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/components/dropdowns.templ`, Line: 5, Col: 36}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/components/dropdowns.templ`, Line: 15, Col: 36}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -49,26 +59,36 @@ func dropdownButton(content, name, value string) templ.Component {
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(value)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/components/dropdowns.templ`, Line: 5, Col: 52}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/components/dropdowns.templ`, Line: 15, Col: 52}
|
||||
}
|
||||
_, 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, 3, "\" class=\"sr-only peer\"> <span class=\"peer-checked:bg-blue-600 peer-checked:text-white peer-checked:border-blue-600\n px-2 py-1 border border-gray-300 rounded-lg\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\" class=\"sr-only peer\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
if selected {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " checked")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "> <span class=\"peer-checked:bg-blue-600 peer-checked:text-white peer-checked:border-blue-600\n px-2 py-1 border border-gray-300 rounded-lg\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(content)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/components/dropdowns.templ`, Line: 8, Col: 13}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/components/dropdowns.templ`, Line: 21, Col: 13}
|
||||
}
|
||||
_, 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, 4, "</span></label>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "</span></label>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -76,7 +96,7 @@ func dropdownButton(content, name, value string) templ.Component {
|
||||
})
|
||||
}
|
||||
|
||||
func FilterDropdown() templ.Component {
|
||||
func FilterDropdown(filters domainRecipe.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 {
|
||||
@ -97,111 +117,111 @@ func FilterDropdown() templ.Component {
|
||||
templ_7745c5c3_Var5 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<script>\n function toggleDropdown() {\n const menu = document.getElementById(\"filter-dropdown-menu\");\n const button = document.getElementById(\"filter-dropdown-button\");\n\n if (menu.classList.contains(\"block\")) {\n menu.classList.remove(\"block\");\n menu.classList.add(\"hidden\");\n } else {\n menu.classList.remove(\"hidden\");\n menu.classList.add(\"block\");\n }\n }\n</script><div id=\"filter-dropdown-menu\" class=\"hidden w-full p-2 border border-gray-300 my-2 rounded-lg\"><div class=\"w-full border-b border-gray-300 py-2\"><h3 class=\"mb-2\">Meal</h3><div class=\"flex text-xs flex-wrap gap-1 gap-y-3\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "<script>\n function toggleDropdown() {\n const menu = document.getElementById(\"filter-dropdown-menu\");\n const button = document.getElementById(\"filter-dropdown-button\");\n\n if (menu.classList.contains(\"block\")) {\n menu.classList.remove(\"block\");\n menu.classList.add(\"hidden\");\n } else {\n menu.classList.remove(\"hidden\");\n menu.classList.add(\"block\");\n }\n }\n</script><div id=\"filter-dropdown-menu\" class=\"hidden w-full p-2 border border-gray-300 my-2 rounded-lg\"><div class=\"w-full border-b border-gray-300 py-2\"><h3 class=\"mb-2\">Meal</h3><div class=\"flex text-xs flex-wrap gap-1 gap-y-3\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = dropdownButton("Breakfast", "meal", "1").Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = dropdownButton("Breakfast", "meal", "1", isBitActive(filters.MealType, 0)).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = dropdownButton("Lunch", "meal", "2").Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = dropdownButton("Lunch", "meal", "2", isBitActive(filters.MealType, 1)).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = dropdownButton("Dinner", "meal", "4").Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = dropdownButton("Dinner", "meal", "4", isBitActive(filters.MealType, 2)).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = dropdownButton("Desert", "meal", "8").Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = dropdownButton("Desert", "meal", "8", isBitActive(filters.MealType, 3)).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = dropdownButton("Snack", "meal", "16").Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = dropdownButton("Snack", "meal", "16", isBitActive(filters.MealType, 4)).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = dropdownButton("Side", "meal", "32").Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = dropdownButton("Side", "meal", "32", isBitActive(filters.MealType, 5)).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = dropdownButton("Other", "meal", "64").Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = dropdownButton("Other", "meal", "64", isBitActive(filters.MealType, 6)).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "</div></div><div class=\"w-full border-b border-gray-300 py-2\"><h3 class=\"mb-2\">Cook Time</h3><div class=\"flex text-xs flex-wrap gap-1 gap-y-3\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "</div></div><div class=\"w-full border-b border-gray-300 py-2\"><h3 class=\"mb-2\">Cook Time</h3><div class=\"flex text-xs flex-wrap gap-1 gap-y-3\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = dropdownButton("< 15 min", "time", "1").Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = dropdownButton("< 15 min", "time", "1", isBitActive(filters.Time, 0)).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = dropdownButton("15 to 30 min", "time", "2").Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = dropdownButton("15 to 30 min", "time", "2", isBitActive(filters.Time, 1)).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = dropdownButton("30 to 60 min", "time", "4").Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = dropdownButton("30 to 60 min", "time", "4", isBitActive(filters.Time, 2)).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = dropdownButton("60 to 120 min", "time", "8").Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = dropdownButton("60 to 120 min", "time", "8", isBitActive(filters.Time, 3)).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = dropdownButton("+120 min", "time", "16").Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = dropdownButton("+120 min", "time", "16", isBitActive(filters.Time, 4)).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</div></div><div class=\"w-full border-b border-gray-300 py-2\"><h3 class=\"mb-2\">Difficulty</h3><div class=\"flex text-xs flex-wrap gap-1 gap-y-3\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "</div></div><div class=\"w-full border-b border-gray-300 py-2\"><h3 class=\"mb-2\">Difficulty</h3><div class=\"flex text-xs flex-wrap gap-1 gap-y-3\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = dropdownButton("Beginner", "difficulty", "1").Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = dropdownButton("Beginner", "difficulty", "1", isBitActive(filters.Difficulty, 0)).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = dropdownButton("Easy", "difficulty", "2").Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = dropdownButton("Easy", "difficulty", "2", isBitActive(filters.Difficulty, 1)).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = dropdownButton("Intermediate", "difficulty", "4").Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = dropdownButton("Intermediate", "difficulty", "4", isBitActive(filters.Difficulty, 2)).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = dropdownButton("Challenging", "difficulty", "8").Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = dropdownButton("Challenging", "difficulty", "8", isBitActive(filters.Difficulty, 3)).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = dropdownButton("Extreme", "difficulty", "16").Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = dropdownButton("Extreme", "difficulty", "16", isBitActive(filters.Difficulty, 4)).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "</div></div><div class=\"w-full border-b border-gray-300 py-2\"><h3 class=\"mb-2\">Serving Size</h3><div class=\"flex text-xs flex-wrap gap-1 gap-y-3\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "</div></div><div class=\"w-full border-b border-gray-300 py-2\"><h3 class=\"mb-2\">Serving Size</h3><div class=\"flex text-xs flex-wrap gap-1 gap-y-3\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = dropdownButton("1 to 2", "serving", "1").Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = dropdownButton("1 to 2", "serving", "1", isBitActive(filters.ServingSize, 0)).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = dropdownButton("2 to 4", "serving", "2").Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = dropdownButton("2 to 4", "serving", "2", isBitActive(filters.ServingSize, 1)).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = dropdownButton("4 to 6", "serving", "4").Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = dropdownButton("4 to 6", "serving", "4", isBitActive(filters.ServingSize, 2)).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = dropdownButton("6 to 8", "serving", "8").Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = dropdownButton("6 to 8", "serving", "8", isBitActive(filters.ServingSize, 3)).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = dropdownButton("8+", "serving", "16").Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = dropdownButton("8+", "serving", "16", isBitActive(filters.ServingSize, 4)).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "</div></div></div>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "</div></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
||||
@ -1,23 +1,24 @@
|
||||
package components
|
||||
|
||||
import "github.com/haydenhargreaves/Potion/internal/domain/server"
|
||||
import domainServer "github.com/haydenhargreaves/Potion/internal/domain/server"
|
||||
import domainRecipe "github.com/haydenhargreaves/Potion/internal/domain/recipe"
|
||||
|
||||
templ SearchBar() {
|
||||
templ SearchBar(filters domainRecipe.SearchFilters) {
|
||||
<form
|
||||
hx-post={ domain.API_SEARCH_RECIPES }
|
||||
hx-post={ domainServer.API_SEARCH_RECIPES }
|
||||
hx-swap="innerHTML"
|
||||
hx-target="#result-list"
|
||||
hx-trigger="submit"
|
||||
hx-encoding="multipart/form-data"
|
||||
class="w-full px-4 my-8"
|
||||
>
|
||||
<p id="result"></p>
|
||||
<div class="flex w-full gap-x-2">
|
||||
<div class="relative w-full">
|
||||
<input
|
||||
type="search"
|
||||
name="search"
|
||||
placeholder="Search recipes, ingredients..."
|
||||
value={ filters.Search }
|
||||
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">
|
||||
@ -39,7 +40,7 @@ templ SearchBar() {
|
||||
</div>
|
||||
@filterButton()
|
||||
</div>
|
||||
@FilterDropdown()
|
||||
@FilterDropdown(filters)
|
||||
</form>
|
||||
}
|
||||
|
||||
|
||||
@ -8,9 +8,10 @@ package components
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/haydenhargreaves/Potion/internal/domain/server"
|
||||
import domainServer "github.com/haydenhargreaves/Potion/internal/domain/server"
|
||||
import domainRecipe "github.com/haydenhargreaves/Potion/internal/domain/recipe"
|
||||
|
||||
func SearchBar() templ.Component {
|
||||
func SearchBar(filters domainRecipe.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 {
|
||||
@ -36,15 +37,28 @@ func SearchBar() templ.Component {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var2 string
|
||||
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(domain.API_SEARCH_RECIPES)
|
||||
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: 7, Col: 37}
|
||||
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\" hx-trigger=\"submit\" hx-encoding=\"multipart/form-data\" class=\"w-full px-4 my-8\"><p id=\"result\"></p><div class=\"flex w-full gap-x-2\"><div class=\"relative w-full\"><input type=\"search\" name=\"search\" placeholder=\"Search recipes, ingredients...\" 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, 2, "\" hx-swap=\"innerHTML\" hx-target=\"#result-list\" hx-trigger=\"submit\" 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=\"search\" name=\"search\" placeholder=\"Search recipes, ingredients...\" value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, 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: 21, Col: 27}
|
||||
}
|
||||
_, 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, 3, "\" 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
|
||||
}
|
||||
@ -52,15 +66,15 @@ func SearchBar() templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</div>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = FilterDropdown().Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = FilterDropdown(filters).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "</form>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "</form>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -84,12 +98,12 @@ func filterButton() templ.Component {
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var3 == nil {
|
||||
templ_7745c5c3_Var3 = templ.NopComponent
|
||||
templ_7745c5c3_Var4 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var4 == nil {
|
||||
templ_7745c5c3_Var4 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<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, 6, "<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
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package templates
|
||||
|
||||
import "github.com/haydenhargreaves/Potion/internal/templates/components"
|
||||
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">
|
||||
@ -28,7 +29,7 @@ templ introSection() {
|
||||
templ searchSection() {
|
||||
<section class="w-full flex flex-col items-center justify-center my-8 py-4">
|
||||
@components.BannerText("Craving Something Specific?")
|
||||
@components.SearchBar()
|
||||
@components.SearchBar(domainRecipe.SearchFilters{})
|
||||
</section>
|
||||
}
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/haydenhargreaves/Potion/internal/templates/components"
|
||||
import "github.com/haydenhargreaves/Potion/internal/domain/server"
|
||||
import domainRecipe "github.com/haydenhargreaves/Potion/internal/domain/recipe"
|
||||
|
||||
func introSection() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
@ -69,7 +70,7 @@ func searchSection() templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.SearchBar().Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = components.SearchBar(domainRecipe.SearchFilters{}).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
||||
@ -1,13 +1,14 @@
|
||||
package templates
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/haydenhargreaves/Potion/internal/templates/components"
|
||||
"github.com/haydenhargreaves/Potion/internal/domain/recipe"
|
||||
domainServer "github.com/haydenhargreaves/Potion/internal/domain/server"
|
||||
"fmt"
|
||||
"github.com/haydenhargreaves/Potion/internal/domain/recipe"
|
||||
domainRecipe "github.com/haydenhargreaves/Potion/internal/domain/recipe"
|
||||
domainServer "github.com/haydenhargreaves/Potion/internal/domain/server"
|
||||
"github.com/haydenhargreaves/Potion/internal/templates/components"
|
||||
)
|
||||
|
||||
templ SearchPage() {
|
||||
templ SearchPage(filters domainRecipe.SearchFilters) {
|
||||
@components.Navbar("")
|
||||
<div class="w-full flex justify-center">
|
||||
<div
|
||||
@ -15,29 +16,29 @@ templ SearchPage() {
|
||||
bg-white flex flex-col items-center"
|
||||
>
|
||||
@components.BannerText("Recipe Search")
|
||||
@components.SearchBar()
|
||||
@components.SearchBar(filters)
|
||||
<hr class="text-gray-300 w-full"/>
|
||||
@ResultList(nil)
|
||||
@ResultList(nil)
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
templ ResultList(recipes []domain.Recipe) {
|
||||
<div id="result-list" class="flex flex-col w-full p-4 items-center">
|
||||
for i, recipe := range recipes {
|
||||
@searchResult(recipe, i % 2 == 1)
|
||||
}
|
||||
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>
|
||||
}
|
||||
for i, recipe := range recipes {
|
||||
@searchResult(recipe, i%2 == 1)
|
||||
}
|
||||
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 searchResult(recipe domain.Recipe, odd bool) {
|
||||
<a
|
||||
href={templ.SafeURL(fmt.Sprintf(domainServer.WEB_RECIPE, recipe.Id))}
|
||||
href={ templ.SafeURL(fmt.Sprintf(domainServer.WEB_RECIPE, recipe.Id)) }
|
||||
if odd {
|
||||
class="w-full p-2 border-b border-gray-200 hover:bg-gray-100 duration-200 flex items-center flex-col md:flex-row bg-[#f8f8f8]"
|
||||
} else {
|
||||
@ -47,20 +48,20 @@ templ searchResult(recipe domain.Recipe, odd bool) {
|
||||
<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">{ recipe.Category }</span>
|
||||
</h3>
|
||||
{ recipe.Title } <span class="text-sm font-normal">{ 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
|
||||
{ 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)
|
||||
}
|
||||
for _ = range(recipe.Difficulty) {
|
||||
@starIconSm(true)
|
||||
}
|
||||
for _ = range(5 - recipe.Difficulty) {
|
||||
@starIconSm(false)
|
||||
}
|
||||
</span>
|
||||
<span class="flex gap-x-1 align-center">
|
||||
@servingIconSm()
|
||||
|
||||
@ -11,11 +11,12 @@ import templruntime "github.com/a-h/templ/runtime"
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/haydenhargreaves/Potion/internal/domain/recipe"
|
||||
domainRecipe "github.com/haydenhargreaves/Potion/internal/domain/recipe"
|
||||
domainServer "github.com/haydenhargreaves/Potion/internal/domain/server"
|
||||
"github.com/haydenhargreaves/Potion/internal/templates/components"
|
||||
)
|
||||
|
||||
func SearchPage() templ.Component {
|
||||
func SearchPage(filters domainRecipe.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 {
|
||||
@ -48,7 +49,7 @@ func SearchPage() templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = components.SearchBar().Render(ctx, templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = components.SearchBar(filters).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -170,7 +171,7 @@ func searchResult(recipe domain.Recipe, odd bool) templ.Component {
|
||||
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: 50, Col: 20}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/search.templ`, Line: 51, Col: 18}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -183,7 +184,7 @@ func searchResult(recipe domain.Recipe, odd bool) 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: 50, Col: 74}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/search.templ`, Line: 51, Col: 72}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -200,7 +201,7 @@ func searchResult(recipe domain.Recipe, odd bool) 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: 55, Col: 33}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/search.templ`, Line: 56, Col: 28}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -237,7 +238,7 @@ func searchResult(recipe domain.Recipe, odd bool) 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: 67, Col: 27}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/search.templ`, Line: 68, Col: 27}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
@ -250,7 +251,7 @@ func searchResult(recipe domain.Recipe, odd bool) templ.Component {
|
||||
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: 70, Col: 72}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/templates/pages/search.templ`, Line: 71, Col: 72}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user