I believe this can mark the tasks about fixing the deref issues with auth completed. Will test in production to find out!
143 lines
4.1 KiB
Go
143 lines
4.1 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 {
|
|
domain.SetCookie(ctx, "search-filters", string(bytes), time.Hour*24)
|
|
// 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
|
|
}
|
|
|
|
// TODO: Not sure if we need to ensure the user is valid here
|
|
|
|
// 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{
|
|
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 {
|
|
domain.SetCookie(ctx, "search-filters", string(bytes), time.Hour*24)
|
|
// 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)
|
|
if !domain.IsLoggedIn(ctx) {
|
|
ctx.JSON(http.StatusOK, gin.H{"error": "User is not logged in. User will be nil."})
|
|
}
|
|
|
|
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.FavoriteList(recipes).Render(ctx.Request.Context(), ctx.Writer)
|
|
}
|