(DB/FEAT): Began the implementation of the user engagement! #18
@ -8,24 +8,55 @@ import (
|
||||
domain "github.com/haydenhargreaves/Potion/internal/domain/server"
|
||||
)
|
||||
|
||||
|
||||
|
||||
func EngagementViewRecipe(ctx *gin.Context) {
|
||||
deps := ctx.MustGet("deps").(*domain.InjectedDependencies)
|
||||
id := ctx.Param("id")
|
||||
recipeId, _ := strconv.Atoi(ctx.Param("id"))
|
||||
|
||||
if !domain.IsLoggedIn(ctx) {
|
||||
// TODO: Anon view
|
||||
ctx.Status(http.StatusNoContent)
|
||||
if _, err := deps.EngagementService.ViewRecipe(recipeId); err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, gin.H{
|
||||
"status": http.StatusInternalServerError,
|
||||
"message": err.Error(),
|
||||
})
|
||||
} else {
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
recipeId, _ := strconv.Atoi(id)
|
||||
userId := ctx.MustGet("userId").(int)
|
||||
|
||||
if _, err := deps.EngagementService.UserViewRecipe(userId, recipeId); err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, gin.H{
|
||||
"status": http.StatusInternalServerError,
|
||||
"status": http.StatusInternalServerError,
|
||||
"message": err.Error(),
|
||||
})
|
||||
} else {
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
}
|
||||
|
||||
func EngagementShareRecipe(ctx *gin.Context) {
|
||||
deps := ctx.MustGet("deps").(*domain.InjectedDependencies)
|
||||
recipeId, _ := strconv.Atoi(ctx.Param("id"))
|
||||
|
||||
if !domain.IsLoggedIn(ctx) {
|
||||
if _, err := deps.EngagementService.ShareRecipe(recipeId); err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, gin.H{
|
||||
"status": http.StatusInternalServerError,
|
||||
"message": err.Error(),
|
||||
})
|
||||
} else {
|
||||
ctx.Status(http.StatusNoContent)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
userId := ctx.MustGet("userId").(int)
|
||||
|
||||
if _, err := deps.EngagementService.UserShareRecipe(userId, recipeId); err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, gin.H{
|
||||
"status": http.StatusInternalServerError,
|
||||
"message": err.Error(),
|
||||
})
|
||||
} else {
|
||||
@ -48,7 +79,7 @@ func EngagementFavoriteRecipe(ctx *gin.Context) {
|
||||
|
||||
if _, err := deps.EngagementService.UserFavoriteRecipe(userId, recipeId); err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, gin.H{
|
||||
"status": http.StatusInternalServerError,
|
||||
"status": http.StatusInternalServerError,
|
||||
"message": err.Error(),
|
||||
})
|
||||
} else {
|
||||
@ -71,7 +102,7 @@ func EngagementMakeRecipe(ctx *gin.Context) {
|
||||
|
||||
if _, err := deps.EngagementService.UserMakeRecipe(userId, recipeId); err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, gin.H{
|
||||
"status": http.StatusInternalServerError,
|
||||
"status": http.StatusInternalServerError,
|
||||
"message": err.Error(),
|
||||
})
|
||||
} else {
|
||||
|
||||
@ -130,14 +130,12 @@ func RecipePage(ctx *gin.Context) {
|
||||
|
||||
// Add engagement
|
||||
if loggedIn {
|
||||
fmt.Println("CALLING USER VIEW")
|
||||
if _, err = deps.EngagementService.UserViewRecipe(*userId, recipe.Id); err != nil {
|
||||
fmt.Printf("ERROR: %s\n", err.Error())
|
||||
ctx.JSON(400, err.Error())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
fmt.Println("CALLING VIEW")
|
||||
if _, err = deps.EngagementService.ViewRecipe(recipe.Id); err != nil {
|
||||
fmt.Printf("ERROR: %s\n", err.Error())
|
||||
ctx.JSON(400, err.Error())
|
||||
|
||||
@ -188,6 +188,7 @@ func (s *Server) Setup() *Server {
|
||||
|
||||
// Engagement endpoints
|
||||
router_api.POST("/engagement/view/:id", handlers.EngagementViewRecipe)
|
||||
router_api.POST("/engagement/share/:id", handlers.EngagementShareRecipe)
|
||||
router_api.POST("/engagement/favorite/:id", handlers.EngagementFavoriteRecipe)
|
||||
router_api.POST("/engagement/make/:id", handlers.EngagementMakeRecipe)
|
||||
|
||||
|
||||
@ -39,6 +39,20 @@ func (s *EngagementService) ViewRecipe(recipeId int) (domain.Engagement, error)
|
||||
return s.engagementRepository.AddEntityEngagement(recipeId, message, domain.EngagementViewed)
|
||||
}
|
||||
|
||||
// ShareRecipe requires a user ID and a recipe ID to create an engagement record in the database.
|
||||
// A message will be generated using the recipe data and then used to add a view engagement to the
|
||||
// database.
|
||||
func (s *EngagementService) ShareRecipe(recipeId int) (domain.Engagement, error) {
|
||||
recipe, err := s.recipeRepository.GetRecipe(recipeId, nil)
|
||||
if err != nil {
|
||||
return domain.Engagement{}, err
|
||||
}
|
||||
|
||||
message := fmt.Sprintf("Shared \"%s\"", recipe.Title)
|
||||
|
||||
return s.engagementRepository.AddEntityEngagement(recipeId, message, domain.EngagementShared)
|
||||
}
|
||||
|
||||
// UserViewRecipe requires a user ID and a recipe ID to create an engagement record in the database.
|
||||
// A message will be generated using the recipe data and then used to add a view engagement to the
|
||||
// database.
|
||||
@ -94,6 +108,20 @@ func (s *EngagementService) UserMakeRecipe(userId, recipeId int) (domain.Engagem
|
||||
return s.engagementRepository.AddUserEntityEngagement(userId, recipeId, message, domain.EngagementMade)
|
||||
}
|
||||
|
||||
// UserShareRecipe requires a user ID and a recipe ID to create an engagement record in the database.
|
||||
// A message will be generated using the recipe data and then used to add a make engagement to the
|
||||
// database.
|
||||
func (s *EngagementService) UserShareRecipe(userId, recipeId int) (domain.Engagement, error) {
|
||||
recipe, err := s.recipeRepository.GetRecipe(recipeId, &userId)
|
||||
if err != nil {
|
||||
return domain.Engagement{}, err
|
||||
}
|
||||
|
||||
message := fmt.Sprintf("Shared \"%s\"", recipe.Title)
|
||||
|
||||
return s.engagementRepository.AddUserEntityEngagement(userId, recipeId, message, domain.EngagementShared)
|
||||
}
|
||||
|
||||
// GetUserEngagement returns a list of the users most recent engagement entries. The number of records
|
||||
// is determined by the limit passed into this function. The results are sorted, newest-to-oldest.
|
||||
func (s *EngagementService) GetUserEngagement(userId, limit int) ([]domain.Engagement, error) {
|
||||
|
||||
@ -2,8 +2,10 @@ package domain
|
||||
|
||||
type EngagementService interface {
|
||||
ViewRecipe(recipeId int) (Engagement, error)
|
||||
ShareRecipe(recipeId int) (Engagement, error)
|
||||
UserViewRecipe(userId, recipeId int) (Engagement, error)
|
||||
UserFavoriteRecipe(userId, recipeId int) (Engagement, error)
|
||||
UserMakeRecipe(userId, recipeId int) (Engagement, error)
|
||||
UserShareRecipe(userId, recipeId int) (Engagement, error)
|
||||
GetUserEngagement(userId, limit int) ([]Engagement, error)
|
||||
}
|
||||
|
||||
@ -26,6 +26,7 @@ const API_CREATE_RECIPE = VERSION + API + "/recipe"
|
||||
const API_SEARCH_RECIPES = VERSION + API + "/recipe/search"
|
||||
|
||||
const API_ENGAGEMENT_VIEW = VERSION + API + "/engagement/view/%d"
|
||||
const API_ENGAGEMENT_SHARE = VERSION + API + "/engagement/share/%d"
|
||||
const API_ENGAGEMENT_FAVORITE = VERSION + API + "/engagement/favorite/%d"
|
||||
const API_ENGAGEMENT_MAKE = VERSION + API + "/engagement/make/%d"
|
||||
|
||||
|
||||
@ -189,11 +189,11 @@ templ favoriteButton(favorited bool, id int, loggedIn bool) {
|
||||
hx-post={ fmt.Sprintf(domainServer.API_ENGAGEMENT_FAVORITE, id) }
|
||||
hx-trigger="click"
|
||||
hx-swap="none"
|
||||
if loggedIn {
|
||||
hx-on:click="favoriteButtonHandler();"
|
||||
}
|
||||
if loggedIn {
|
||||
hx-on:click="favoriteButtonHandler();"
|
||||
}
|
||||
class="flex items-center justify-center gap-x-1 rounded-lg border border-blue-300 bg-blue-50 text-gray-800 px-6 py-3 flex-grow hover:bg-blue-100 hover:border-blue-500 duration-300"
|
||||
id="favorite-button"
|
||||
id="favorite-button"
|
||||
>
|
||||
<svg class="h-6 text-red-500" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
@ -208,11 +208,11 @@ templ favoriteButton(favorited bool, id int, loggedIn bool) {
|
||||
hx-post={ fmt.Sprintf(domainServer.API_ENGAGEMENT_FAVORITE, id) }
|
||||
hx-trigger="click"
|
||||
hx-swap="none"
|
||||
if loggedIn {
|
||||
hx-on:click="favoriteButtonHandler();"
|
||||
}
|
||||
if loggedIn {
|
||||
hx-on:click="favoriteButtonHandler();"
|
||||
}
|
||||
class="flex items-center justify-center gap-x-1 rounded-lg border border-gray-300 text-gray-800 px-6 py-3 flex-grow hover:bg-gray-50 hover:border-blue-300 duration-300"
|
||||
id="favorite-button"
|
||||
id="favorite-button"
|
||||
>
|
||||
<svg class="h-6" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
@ -236,9 +236,9 @@ templ madeButton(id int, loggedIn bool) {
|
||||
hx-trigger="click"
|
||||
hx-swap="none"
|
||||
id="make-button"
|
||||
if loggedIn {
|
||||
hx-on:click="makeButtonHandler();"
|
||||
}
|
||||
if loggedIn {
|
||||
hx-on:click="makeButtonHandler();"
|
||||
}
|
||||
class="flex items-center justify-center gap-x-1 rounded-lg border border-gray-300 text-gray-800 px-6 py-3 flex-grow hover:bg-gray-50 hover:border-blue-300 duration-300"
|
||||
>
|
||||
<svg
|
||||
@ -262,10 +262,13 @@ templ madeButton(id int, loggedIn bool) {
|
||||
</button>
|
||||
}
|
||||
|
||||
templ shareButton() {
|
||||
templ shareButton(id int) {
|
||||
<button
|
||||
id="share-button"
|
||||
onclick="shareButtonHandler();"
|
||||
hx-post={ fmt.Sprintf(domainServer.API_ENGAGEMENT_SHARE, id) }
|
||||
hx-trigger="click"
|
||||
hx-swap="none"
|
||||
hx-on:click="shareButtonHandler();"
|
||||
class="flex items-center justify-center gap-x-1 rounded-lg border border-gray-300 text-gray-800 px-6 py-3 flex-grow hover:bg-gray-50 hover:border-blue-300 duration-300"
|
||||
>
|
||||
<svg class="h-7" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
@ -284,7 +287,7 @@ templ buttonSection(favorited bool, id int, loggedIn bool) {
|
||||
<section class="w-full flex flex-col md:flex-row gap-x-4 gap-y-2 py-8 px-4 md:px-8">
|
||||
@favoriteButton(favorited, id, loggedIn)
|
||||
@madeButton(id, loggedIn)
|
||||
@shareButton()
|
||||
@shareButton(id)
|
||||
</section>
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user