Potion/internal/app/handlers/recipe_handler.go
Hayden Hargreaves d950e75540 (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!
2025-07-09 21:19:28 -07:00

81 lines
2.2 KiB
Go

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"
)
const CREATE_ERROR_HTML = `
<p id="response" class="text-sm text-red-500 px-4 py-1 bg-red-100 rounded-full w-fit">
Uh oh! Something went wrong when creating your recipe. Please try again. %s
</p>
`
func CreateRecipe(ctx *gin.Context) {
deps := ctx.MustGet("deps").(*domain.InjectedDependencies)
recipe, err := deps.RecipeService.CreateRecipe(ctx)
if err != nil {
ctx.String(http.StatusOK, CREATE_ERROR_HTML, err.Error())
return
}
// Send HTMX redirection
url := fmt.Sprintf(domain.WEB_RECIPE, recipe.Id)
ctx.Header("HX-Redirect", url)
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)
// 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()})
}
// Render content as the response
ctx.Status(200)
templates.ResultList(recipes).Render(ctx.Request.Context(), ctx.Writer)
}