This includes backend updates as well as frontend changes! The backend also includes a new repository to get a list of jobs via their IDs, which does respect order! The list displays for users that are logged in and a small message when the user is not logged in. The last piece is the recipe of the week segment, which can be as simple as a DB cron-job. But that will require stored procedures. Need to learn those next. Though I want to deploy the application soon, so I need to begin working on that.
252 lines
7.2 KiB
Go
252 lines
7.2 KiB
Go
package handlers
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/a-h/templ"
|
|
"github.com/gin-gonic/gin"
|
|
domainRecipe "github.com/haydenhargreaves/Potion/internal/domain/recipe"
|
|
domain "github.com/haydenhargreaves/Potion/internal/domain/server"
|
|
domainServer "github.com/haydenhargreaves/Potion/internal/domain/server"
|
|
layouts "github.com/haydenhargreaves/Potion/internal/templates/layouts"
|
|
pages "github.com/haydenhargreaves/Potion/internal/templates/pages"
|
|
templates "github.com/haydenhargreaves/Potion/internal/templates/pages"
|
|
)
|
|
|
|
func LoginPage(ctx *gin.Context) {
|
|
title := "Potion - Login"
|
|
page := pages.LoginPage()
|
|
|
|
ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page))
|
|
}
|
|
|
|
func HomePage(ctx *gin.Context) {
|
|
deps := ctx.MustGet("deps").(*domainServer.InjectedDependencies)
|
|
|
|
loggedIn := domain.IsLoggedIn(ctx)
|
|
|
|
var page templ.Component
|
|
if loggedIn {
|
|
userId := ctx.MustGet("userId").(int)
|
|
madeRecipes, err := deps.RecipeService.GetUserMadeRecipes(userId, 6)
|
|
if err != nil {
|
|
ctx.JSON(http.StatusInternalServerError, gin.H{
|
|
"status": http.StatusInternalServerError,
|
|
"message": fmt.Sprintf("Error getting made recipes. %s\n", err.Error()),
|
|
})
|
|
return
|
|
}
|
|
viewedRecipes, err := deps.RecipeService.GetUserViewedRecipes(userId, 6)
|
|
if err != nil {
|
|
ctx.JSON(http.StatusInternalServerError, gin.H{
|
|
"status": http.StatusInternalServerError,
|
|
"message": fmt.Sprintf("Error getting made recipes. %s\n", err.Error()),
|
|
})
|
|
return
|
|
}
|
|
|
|
page = templates.HomePage(true, viewedRecipes, madeRecipes)
|
|
} else {
|
|
page = templates.HomePage(false, nil, nil)
|
|
}
|
|
|
|
title := "Potion - Home"
|
|
|
|
ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page))
|
|
}
|
|
|
|
func FavoritesPage(ctx *gin.Context) {
|
|
// If not logged in, direct to the login page
|
|
if !domainServer.IsLoggedIn(ctx) {
|
|
ctx.Redirect(http.StatusSeeOther, domainServer.WEB_LOGIN)
|
|
return
|
|
}
|
|
|
|
title := "Potion - Favorites"
|
|
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.FavoritesPage(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.FavoritesPage(domainRecipe.SearchFilters{})
|
|
} else {
|
|
page = pages.FavoritesPage(filters)
|
|
}
|
|
}
|
|
|
|
// Else, get the user's favorites
|
|
// BUG: Depreciated, not displaying a list, using search to drive this page as well
|
|
// deps := ctx.MustGet("deps").(*domainServer.InjectedDependencies)
|
|
// userId := ctx.MustGet("userId").(int)
|
|
// recipes, err := deps.RecipeService.GetUserFavoriteRecipes(userId)
|
|
// if err != nil {
|
|
// ctx.JSON(http.StatusInternalServerError, gin.H{
|
|
// "status": http.StatusInternalServerError,
|
|
// "message": fmt.Sprintf("Error getting favorites. %s\n", err.Error()),
|
|
// })
|
|
// return
|
|
// }
|
|
|
|
ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page))
|
|
}
|
|
|
|
func CreatePage(ctx *gin.Context) {
|
|
// If not logged in, direct to the login page
|
|
if !domainServer.IsLoggedIn(ctx) {
|
|
ctx.Redirect(http.StatusSeeOther, domainServer.WEB_LOGIN)
|
|
return
|
|
}
|
|
|
|
title := "Potion - Create"
|
|
page := pages.CreatePage()
|
|
|
|
ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page))
|
|
}
|
|
|
|
func ProfilePage(ctx *gin.Context) {
|
|
// If not logged in, direct to the login page
|
|
if !domainServer.IsLoggedIn(ctx) {
|
|
ctx.Redirect(http.StatusSeeOther, domainServer.WEB_LOGIN)
|
|
return
|
|
}
|
|
|
|
// Else, get the user data
|
|
deps := ctx.MustGet("deps").(*domainServer.InjectedDependencies)
|
|
user := deps.UserService.GetAuthenicatedUser(ctx)
|
|
recipes, err := deps.RecipeService.GetUserRecipes(user.Id)
|
|
if err != nil {
|
|
ctx.JSON(http.StatusInternalServerError, gin.H{
|
|
"status": http.StatusInternalServerError,
|
|
"message": fmt.Sprintf("Error getting recipes. %s\n", err.Error()),
|
|
})
|
|
return
|
|
}
|
|
|
|
favorites, err := deps.RecipeService.GetUserFavoriteRecipes(user.Id)
|
|
if err != nil {
|
|
ctx.JSON(http.StatusInternalServerError, gin.H{
|
|
"status": http.StatusInternalServerError,
|
|
"message": fmt.Sprintf("Error getting recipes. %s\n", err.Error()),
|
|
})
|
|
return
|
|
}
|
|
|
|
// Get the engagement data, not sure what will happen when errors occur
|
|
engagements, err := deps.EngagementService.GetUserEngagement(user.Id, 6)
|
|
if err != nil {
|
|
ctx.JSON(http.StatusInternalServerError, gin.H{
|
|
"status": http.StatusInternalServerError,
|
|
"message": fmt.Sprintf("Error getting user engagements. %s\n", err.Error()),
|
|
})
|
|
return
|
|
}
|
|
|
|
title := "Potion - Profile"
|
|
page := pages.ProfilePage(user, recipes, favorites, engagements)
|
|
|
|
ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page))
|
|
}
|
|
|
|
func ListPage(ctx *gin.Context) {
|
|
title := "Potion - Shopping List"
|
|
page := pages.ListPage()
|
|
|
|
ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page))
|
|
}
|
|
|
|
// 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").(*domainServer.InjectedDependencies)
|
|
id := ctx.Param("id")
|
|
|
|
// Parse ID
|
|
parsed, err := strconv.Atoi(id)
|
|
if err != nil {
|
|
fmt.Printf("ERROR: %s\n", err.Error())
|
|
ctx.JSON(400, err.Error())
|
|
return
|
|
}
|
|
|
|
// Get signed in user, if they exist
|
|
var userId *int = nil
|
|
var loggedIn = domainServer.IsLoggedIn(ctx)
|
|
if loggedIn {
|
|
storeId := ctx.MustGet("userId").(int)
|
|
userId = &storeId
|
|
}
|
|
|
|
// Get recipe
|
|
recipe, err := deps.RecipeService.GetRecipe(parsed, userId)
|
|
if err != nil {
|
|
fmt.Printf("ERROR: %s\n", err.Error())
|
|
ctx.JSON(400, err.Error())
|
|
return
|
|
}
|
|
|
|
// Get user (owner)
|
|
user, err := deps.UserService.GetUser(recipe.UserId)
|
|
if err != nil {
|
|
fmt.Printf("ERROR: %s\n", err.Error())
|
|
ctx.JSON(400, err.Error())
|
|
return
|
|
}
|
|
|
|
// Add engagement
|
|
// BUG: Don't want to do this here
|
|
// if loggedIn {
|
|
// if _, err = deps.EngagementService.UserViewRecipe(*userId, recipe.Id); err != nil {
|
|
// fmt.Printf("ERROR: %s\n", err.Error())
|
|
// ctx.JSON(400, err.Error())
|
|
// return
|
|
// }
|
|
// } else {
|
|
// if _, err = deps.EngagementService.ViewRecipe(recipe.Id); err != nil {
|
|
// fmt.Printf("ERROR: %s\n", err.Error())
|
|
// ctx.JSON(400, err.Error())
|
|
// return
|
|
// }
|
|
// }
|
|
|
|
title := "Potion - View Recipe"
|
|
page := pages.RecipePage(*recipe, *user, loggedIn)
|
|
|
|
ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page))
|
|
}
|
|
|
|
func SearchPage(ctx *gin.Context) {
|
|
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{}, false)
|
|
} 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{}, false)
|
|
} else {
|
|
page = pages.SearchPage(filters, true)
|
|
}
|
|
}
|
|
|
|
title := "Potion - Recipe Search"
|
|
|
|
ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page))
|
|
}
|
|
|
|
func NotFoundPage(ctx *gin.Context) {
|
|
title := "Potion - Not Found"
|
|
page := pages.NotFoundPage()
|
|
|
|
ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page))
|
|
}
|