Hayden Hargreaves d29426290d (FEAT): Created engagement buttons, and wired most of them up!
The make button is pretty much done, just need to finish up by
rate limiting it. That will take place in the engagement repository.

Sharing works as well, just a UI change, there is no backend yet, maybe
there should be an engagement type for sharing recipes. But not totally
sure.

The viewing is also in a semi-working state. It does not create requests
for users that aren't signed in, which needs to come. With that update
there is a need to update HOW the requests come in, we don't need it
every time we load the page. Maybe just when we click to it, from
somewhere else?

Finally, the favoriting does not totally work. The entry into the
engagement table is complete, but the actual favorites table, favorite
creation, button toggling AND button rendering is not implemented yet.
2025-07-14 21:00:28 -07:00

127 lines
4.6 KiB
Plaintext

package templates
import (
"fmt"
"github.com/haydenhargreaves/Potion/internal/domain/recipe"
domainRecipe "github.com/haydenhargreaves/Potion/internal/domain/recipe"
domainServer "github.com/haydenhargreaves/Potion/internal/domain/server"
"github.com/haydenhargreaves/Potion/internal/templates/components"
)
templ SearchPage(filters domainRecipe.SearchFilters, searchOnLoad 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 min-h-screen border-l border-r border-gray-300
bg-white flex flex-col items-center"
>
@components.BannerText("Recipe Search")
@components.SearchBar(filters, false, searchOnLoad)
<hr class="text-gray-300 w-full"/>
@ResultList(nil)
</div>
</div>
}
templ ResultList(recipes []domain.Recipe) {
<div id="result-list" class="flex flex-col w-full p-4 items-center">
for _, recipe := range recipes {
@searchResult(recipe)
}
if len(recipes) == 0 || recipes == nil {
<p class="text-gray-700 text-sm py-4">No results</p>
} else {
<p class="text-gray-700 text-sm py-4">End of results</p>
}
</div>
}
templ searchResult(recipe domain.Recipe) {
<a
href={ templ.SafeURL(fmt.Sprintf(domainServer.WEB_RECIPE, recipe.Id)) }
class="w-full p-2 border-b border-gray-200 hover:bg-gray-100 duration-200 flex items-center flex-col md:flex-row even:bg-[#f8f8f8]"
>
<img class="bg-gray-50 size-56 md:size-40 rounded-md border-0" src=""/>
<div class="text-gray-700 p-4 flex flex-col items-center md:items-start">
<h3 class="text-xl font-semibold text-black pb-1">
{ recipe.Title } <span class="text-sm font-normal hidden md:inline">{ recipe.Category }</span>
</h3>
<div class="text-sm flex gap-x-3 gap-y-1 items-center flex-wrap">
<span class="flex gap-x-1 align-center">
@timeIconSm()
{ recipe.Duration.Total } min
</span>
<span class="flex gap-x-1 align-center">
for _ = range(recipe.Difficulty) {
@starIconSm(true)
}
for _ = range(5 - recipe.Difficulty) {
@starIconSm(false)
}
</span>
<span class="flex gap-x-1 align-center">
@servingIconSm()
Serves { recipe.Serves }
</span>
</div>
<p class="text-sm py-2 text-center md:text-left">{ recipe.Description }</p>
</div>
</a>
}
templ servingIconSm() {
<svg
class="h-5 text-blue-600"
fill="currentColor"
version="1.1"
id="Icons"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 32 32"
xml:space="preserve"
>
<g>
<circle cx="12" cy="16" r="5"></circle>
<path
d="M12,6C6.5,6,2,10.5,2,16s4.5,10,10,10s10-4.5,10-10S17.5,6,12,6z M12,23c-3.9,0-7-3.1-7-7s3.1-7,7-7s7,3.1,7,7
S15.9,23,12,23z"
></path>
<path
d="M30,10.5V5c0-0.6-0.4-1-1-1s-1,0.4-1,1v5.5c0,0.2,0,0.4,0,0.5h-1V5c0-0.6-0.4-1-1-1s-1,0.4-1,1v6h-1c0-0.2,0-0.4,0-0.5V5
c0-0.6-0.4-1-1-1s-1,0.4-1,1v5.5c0,1.9,0.5,3.4,1.4,4.3c0.7,0.8,1,1.8,0.9,2.7l-1,7.3c-0.1,0.8,0.1,1.6,0.6,2.2S25.2,28,26,28
s1.5-0.3,2.1-0.9s0.8-1.4,0.6-2.2l-1-7.3c-0.1-1,0.2-2,0.9-2.8C29.5,13.8,30,12.3,30,10.5z"
></path>
</g>
</svg>
}
templ timeIconSm() {
<svg class="h-5 text-blue-600" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M12 7V12L14.5 13.5M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z"
stroke="currentColor"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
></path>
</svg>
}
templ starIconSm(filled bool) {
if filled {
<svg class="h-4 text-blue-600" fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path
d="M23.632 9.201a.628.628 0 0 1-.22.678l-5.726 4.96 1.727 7.394a.606.606 0 0 1-.935.676l-6.503-3.953-6.503 3.953a.713.713 0 0 1-.374.112.57.57 0 0 1-.34-.109.629.629 0 0 1-.222-.679l1.729-7.393L.539 9.879A.607.607 0 0 1 .897 8.78l7.536-.635 2.965-7.083a.62.62 0 0 1 1.155.001l2.965 7.082 7.536.635a.63.63 0 0 1 .578.42z"
></path>
<path fill="none" d="M0 0h24v24H0z"></path>
</svg>
} else {
<svg class="h-4 text-gray-500" fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path
d="M23.054 8.781l-7.536-.635-2.965-7.082a.619.619 0 0 0-1.155 0L8.433 8.145.896 8.78a.607.607 0 0 0-.357 1.1l5.726 4.96-1.729 7.395a.63.63 0 0 0 .223.679.573.573 0 0 0 .339.108.717.717 0 0 0 .374-.111l6.503-3.954 6.503 3.953a.606.606 0 0 0 .935-.677l-1.727-7.392 5.725-4.96a.607.607 0 0 0-.357-1.099zm-6.48 5.698l1.662 7.113-6.261-3.806-6.262 3.807 1.663-7.114-5.513-4.776 7.257-.611 2.855-6.817 2.855 6.817 7.257.611z"
></path>
<path fill="none" d="M0 0h24v24H0z"></path>
</svg>
}
}