(UI/FIX): Fixed the favorite button rendering and updating!
I don't like the way that templ requires JS, but it is what it is. I just don't want to return HTML from the server.
This commit is contained in:
parent
79bee1cde7
commit
7e355d5eda
@ -106,7 +106,8 @@ func RecipePage(ctx *gin.Context) {
|
||||
|
||||
// Get signed in user, if they exist
|
||||
var userId *int = nil
|
||||
if domainServer.IsLoggedIn(ctx) {
|
||||
var loggedIn = domainServer.IsLoggedIn(ctx)
|
||||
if loggedIn {
|
||||
storeId := ctx.MustGet("userId").(int)
|
||||
userId = &storeId
|
||||
}
|
||||
@ -139,7 +140,7 @@ func RecipePage(ctx *gin.Context) {
|
||||
// I also do not really like that this runs on refresh, might need some better handling
|
||||
|
||||
title := "Potion - View Recipe"
|
||||
page := pages.RecipePage(*recipe, *user)
|
||||
page := pages.RecipePage(*recipe, *user, loggedIn)
|
||||
|
||||
ctx.HTML(http.StatusOK, "", layouts.AppLayout(title, page))
|
||||
}
|
||||
|
||||
@ -123,6 +123,10 @@ func (s *RecipeService) CreateRecipe(ctx *gin.Context) (*domain.Recipe, error) {
|
||||
// GetRecipe will get a recipe via its ID. Any errors will be bubbled to the caller. Furthermore,
|
||||
// if the recipe is nil, an error will be returned, so the caller does not need to check for a nil
|
||||
// recipe (e.g., if the error is nil the recipe exists)
|
||||
//
|
||||
// A userId should be provided to allow the favorite status to be updated. Without a userId (nil),
|
||||
// the favorite status will return false, not because its not a favorite, but because it cannot find
|
||||
// out!
|
||||
func (s *RecipeService) GetRecipe(id int, userId *int) (*domain.Recipe, error) {
|
||||
recipe, err := s.recipeRepository.GetRecipe(id, userId)
|
||||
|
||||
|
||||
@ -151,7 +151,7 @@ templ tagList(tags []domain.Tag, created time.Time, modified *time.Time) {
|
||||
|
||||
templ ingredientListItem(name, quantity string) {
|
||||
<li
|
||||
class="text-sm md:text-base p-2 hover:bg-gray-100 transition-all duration-300 rounded-sm flex items-center justify-start odd:bg-[#f8f8f8]"
|
||||
class="p-2 hover:bg-gray-100 transition-all duration-300 rounded-sm flex items-center justify-start odd:bg-[#f8f8f8]"
|
||||
>
|
||||
<span class="mr-4">
|
||||
<svg class="h-4 text-gray-400" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
@ -173,7 +173,7 @@ templ instructionListItem(num int, content string) {
|
||||
<div class="size-8 md:size-10 bg-blue-50 rounded-full flex items-center justify-center flex-shrink-0">
|
||||
<h3 class="text-base md:text-xl text-blue-600 font-semibold">{ num }</h3>
|
||||
</div>
|
||||
<p class="text-sm md:text-base">{ content }</p>
|
||||
<p class="text-base">{ content }</p>
|
||||
</li>
|
||||
}
|
||||
|
||||
@ -183,13 +183,17 @@ templ tagListItem(content string) {
|
||||
</li>
|
||||
}
|
||||
|
||||
templ favoriteButton(favorited bool, id int) {
|
||||
templ favoriteButton(favorited bool, id int, loggedIn bool) {
|
||||
if favorited {
|
||||
<button
|
||||
hx-post={ fmt.Sprintf(domainServer.API_ENGAGEMENT_FAVORITE, id) }
|
||||
hx-trigger="click"
|
||||
hx-swap="none"
|
||||
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"
|
||||
>
|
||||
<svg class="h-6 text-red-500" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
@ -204,7 +208,11 @@ templ favoriteButton(favorited bool, id int) {
|
||||
hx-post={ fmt.Sprintf(domainServer.API_ENGAGEMENT_FAVORITE, id) }
|
||||
hx-trigger="click"
|
||||
hx-swap="none"
|
||||
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"
|
||||
>
|
||||
<svg class="h-6" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
@ -222,13 +230,15 @@ templ favoriteButton(favorited bool, id int) {
|
||||
}
|
||||
}
|
||||
|
||||
templ madeButton(id int) {
|
||||
templ madeButton(id int, loggedIn bool) {
|
||||
<button
|
||||
hx-post={ fmt.Sprintf(domainServer.API_ENGAGEMENT_MAKE, id) }
|
||||
hx-trigger="click"
|
||||
hx-swap="none"
|
||||
id="make-button"
|
||||
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
|
||||
@ -270,15 +280,15 @@ templ shareButton() {
|
||||
</button>
|
||||
}
|
||||
|
||||
templ buttonSection(favorited bool, id int) {
|
||||
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)
|
||||
@madeButton(id)
|
||||
@favoriteButton(favorited, id, loggedIn)
|
||||
@madeButton(id, loggedIn)
|
||||
@shareButton()
|
||||
</section>
|
||||
}
|
||||
|
||||
templ RecipePage(recipe domain.Recipe, user domainUser.User) {
|
||||
templ RecipePage(recipe domain.Recipe, user domainUser.User, loggedIn bool) {
|
||||
@components.Navbar("")
|
||||
<div class="w-full flex justify-center">
|
||||
<div class="mx-2 md:mx-0 w-full md:w-1/2 md:pt-14 h-full border-l border-r border-gray-300 bg-white">
|
||||
@ -289,7 +299,7 @@ templ RecipePage(recipe domain.Recipe, user domainUser.User) {
|
||||
<p class="text-sm mb-2 text-gray-700">Category: { recipe.Category }</p>
|
||||
</div>
|
||||
@metadataSection(recipe)
|
||||
@buttonSection(recipe.Favorite, recipe.Id)
|
||||
@buttonSection(recipe.Favorite, recipe.Id, loggedIn)
|
||||
<div class="px-4 py-8 md:px-8">
|
||||
<h3 class="text-xl text-gray-800 font-semibold mb-2">About this recipe</h3>
|
||||
<p class="text-gray-700">{ recipe.Description }</p>
|
||||
@ -377,9 +387,54 @@ templ scripts(id int) {
|
||||
</svg>
|
||||
Made This!
|
||||
</button>
|
||||
|
||||
`;
|
||||
}
|
||||
|
||||
function favoriteButtonHandler() {
|
||||
const button = document.getElementById("favorite-button");
|
||||
|
||||
console.log(button.classList);
|
||||
console.log(button.classList.contains("border-blue-300"));
|
||||
|
||||
const toggleClasses = [
|
||||
"border-gray-300", "hover:bg-gray-50", "hover:border-blue-300",
|
||||
"border-blue-300", "bg-blue-50", "hover:bg-blue-100", "hover:border-blue-500"
|
||||
];
|
||||
|
||||
for (const cls of toggleClasses) {
|
||||
console.log("toggling class " + cls);
|
||||
button.classList.toggle(cls);
|
||||
}
|
||||
|
||||
if (!button.classList.contains("border-blue-300")) {
|
||||
button.innerHTML = `
|
||||
<svg class="h-6" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M12 6.00019C10.2006 3.90317 7.19377 3.2551 4.93923 5.17534C2.68468 7.09558 2.36727 10.3061 4.13778 12.5772C5.60984 14.4654 10.0648 18.4479 11.5249 19.7369C11.6882 19.8811 11.7699 19.9532 11.8652 19.9815C11.9483 20.0062 12.0393 20.0062 12.1225 19.9815C12.2178 19.9532 12.2994 19.8811 12.4628 19.7369C13.9229 18.4479 18.3778 14.4654 19.8499 12.5772C21.6204 10.3061 21.3417 7.07538 19.0484 5.17534C16.7551 3.2753 13.7994 3.90317 12 6.00019Z"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
></path>
|
||||
</svg>
|
||||
Favorite
|
||||
`;
|
||||
|
||||
} else {
|
||||
button.innerHTML = `
|
||||
<svg class="h-6 text-red-500" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M2 9.1371C2 14 6.01943 16.5914 8.96173 18.9109C10 19.7294 11 20.5 12 20.5C13 20.5 14 19.7294 15.0383 18.9109C17.9806 16.5914 22 14 22 9.1371C22 4.27416 16.4998 0.825464 12 5.50063C7.50016 0.825464 2 4.27416 2 9.1371Z"
|
||||
fill="currentColor"
|
||||
></path>
|
||||
</svg>
|
||||
Unfavorite
|
||||
`;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user