This basically marks the favorites page completed. Updating the recipe repository to allow the search function to accept a userId and favorites flag. This flag will toggle a "favorites only" search. Which can be used to replicate the same functionality from the search page in the favorites page. This later can serve as a baseline for updating to also work for activity search. I am starting to think an ORM is a good idea...I heard Gorm is good, but for now, there is a bit too much tech debt.
128 lines
3.6 KiB
Go
128 lines
3.6 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
|
|
}
|
|
|
|
// We don't care about favorite status, so use nil and false
|
|
recipes, err := deps.RecipeService.SearchRecipes(filters, nil, 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{
|
|
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,
|
|
)
|
|
}
|
|
|
|
// 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, &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)
|
|
}
|