Files
mal/web/templates/watchlist.templ

112 lines
3.1 KiB
Plaintext

package templates
import (
"fmt"
db "mal/internal/db"
components "mal/web/components"
"mal/web/components/watchlist"
"mal/web/shared"
"mal/web/shared/layout"
)
templ Watchlist(
entries []db.GetUserWatchListRow,
currentStatus string,
sortBy string,
sortOrder string,
) {
@layout.Layout("mal - watchlist", true) {
<div
class="mb-4 flex items-end justify-between gap-4 max-lg:flex-col max-lg:items-start"
>
<div class="grid gap-1">
<h2>Watchlist</h2>
<p class="m-0 text-sm text-(--text-muted)">
Track what you're watching with less noise.
</p>
</div>
</div>
<div
class="mb-3 flex flex-wrap gap-2 max-md:flex-nowrap max-md:overflow-x-auto max-md:pb-1"
>
<a
href={ templ.URL(shared.WatchlistURL("all", sortBy, sortOrder)) }
class={ shared.TabClass(currentStatus == "all") }
>
All
</a>
<a
href={ templ.URL(shared.WatchlistURL("plan_to_watch", sortBy, sortOrder)) }
class={ shared.TabClass(currentStatus == "plan_to_watch") }
>
Plan to watch
</a>
<a
href={ templ.URL(shared.WatchlistURL("dropped", sortBy, sortOrder)) }
class={ shared.TabClass(currentStatus == "dropped") }
>
Dropped
</a>
<a
href={ templ.URL(shared.WatchlistURL("completed", sortBy, sortOrder)) }
class={ shared.TabClass(currentStatus == "completed") }
>
Completed
</a>
</div>
@components.SortFilter(components.SortFilterOptions{
Sort: sortBy,
Order: sortOrder,
Status: currentStatus,
})
if len(entries) == 0 {
@components.EmptyState("Nothing here yet") {
if currentStatus == "all" {
Your watchlist is empty. <a href="/">Search for anime</a> to get started.
} else {
No anime in this category.
}
}
} else {
<div
class="grid grid-cols-2 gap-3 sm:grid-cols-3 md:gap-4 lg:grid-cols-4 xl:grid-cols-5"
>
for _, entry := range entries {
<div
class="group relative min-w-0"
id={ fmt.Sprintf("watchlist-entry-%d", entry.AnimeID) }
>
<a
href={ templ.URL(shared.AnimeURL(int(entry.AnimeID))) }
class="flex flex-col bg-transparent text-inherit no-underline"
>
<div class="relative flex w-full aspect-2/3 justify-center overflow-hidden">
<img
src={ entry.ImageUrl }
alt={ entry.DisplayTitle() }
class="block w-full object-cover object-center"
loading="lazy"
/>
<div class="absolute inset-0 bg-black/0 transition-colors duration-200 group-hover:bg-black/40"></div>
</div>
<div class="mt-2 line-clamp-2 text-sm leading-snug text-(--text)">
{ entry.DisplayTitle() }
</div>
@watchlist.Progress(entry)
</a>
<button
class="absolute right-2 top-2 h-6 w-6 cursor-pointer border-0 bg-(--overlay-subtle) text-(--text-muted) opacity-0 transition-opacity duration-150 group-hover:opacity-100 hover:text-(--danger)"
hx-delete={ string(templ.URL(fmt.Sprintf("/api/watchlist/%d?from=watchlist", entry.AnimeID))) }
hx-target={ fmt.Sprintf("#watchlist-entry-%d", entry.AnimeID) }
hx-swap="delete"
>
&times;
</button>
</div>
}
</div>
}
}
}