Potion/internal/app/handlers/recipe_handler.go
Hayden Hargreaves 9ac7356668 (DOC/FEAT): Updated doc comments and completed the search redirection!
The search is nearly complete for the initial implementation. Just need
to figure out what to do with the text search provided, make any
required UI changes, and eventual implement pagination via a "load more"
button.
2025-07-09 22:21:49 -07:00

89 lines
2.4 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(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
}
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)
}