refactor: extract anime template sections into components
This commit is contained in:
@@ -1,115 +1,3 @@
|
||||
{{define "anime_characters"}}
|
||||
<div class="mt-12 w-full">
|
||||
<h2 class="mb-6 text-lg font-normal text-foreground">Characters & Cast</h2>
|
||||
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5">
|
||||
{{range (slice .Items 0 (min (len .Items) 10))}}
|
||||
<div class="flex gap-3 bg-background-surface p-3">
|
||||
<div class="h-16 w-12 shrink-0 overflow-hidden bg-background-surface">
|
||||
<img src="{{.Character.Images.Jpg.ImageURL}}" alt="{{.Character.Name}}" class="h-full w-full object-cover" loading="lazy" />
|
||||
</div>
|
||||
<div class="flex flex-col justify-center overflow-hidden">
|
||||
<span class="truncate text-sm font-medium text-foreground">{{.Character.Name}}</span>
|
||||
<span class="truncate text-xs text-foreground-muted">{{.Role}}</span>
|
||||
{{if .VoiceActors}}
|
||||
<span class="mt-1 truncate text-[11px] text-foreground-muted">{{(index .VoiceActors 0).Person.Name}}</span>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
{{define "anime_recommendations"}}
|
||||
{{if .Items}}
|
||||
<div class="w-full">
|
||||
<h2 class="mb-6 text-lg font-normal text-foreground">Recommendations</h2>
|
||||
<div class="grid grid-cols-2 gap-4 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 xl:grid-cols-8">
|
||||
{{range (slice .Items 0 (min (len .Items) 8))}}
|
||||
<a href="/anime/{{.Entry.MalID}}" class="group flex flex-col gap-2">
|
||||
<div class="aspect-2/3 overflow-hidden bg-background-surface shadow-md">
|
||||
<img src="{{.Entry.Images.Webp.LargeImageURL}}" alt="{{.Entry.Title}}" class="h-full w-full object-cover transition-transform duration-500 group-hover:scale-105" loading="lazy" />
|
||||
</div>
|
||||
<span class="truncate text-xs font-medium text-foreground-muted transition-colors group-hover:text-foreground">{{.Entry.Title}}</span>
|
||||
</a>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
{{define "anime_recommendations_loading"}}
|
||||
<div
|
||||
hx-get="/anime/{{.AnimeID}}?section=recommendations"
|
||||
hx-trigger="load delay:1500ms"
|
||||
hx-swap="outerHTML"
|
||||
>
|
||||
<div class="w-full">
|
||||
<h2 class="mb-6 text-lg font-normal text-foreground">Recommendations</h2>
|
||||
<div class="grid grid-cols-2 gap-4 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 xl:grid-cols-8">
|
||||
{{range (seq 8)}}
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="skeleton aspect-2/3"></div>
|
||||
<div class="skeleton h-3 w-full"></div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
{{define "anime_statistics"}}
|
||||
{{if .Items}}
|
||||
<div class="flex flex-col gap-1.5 pt-2">
|
||||
<div class="flex items-center justify-between text-xs">
|
||||
<span class="text-foreground-muted">Watching</span>
|
||||
<span class="text-foreground">{{.Items.Watching}}</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-xs">
|
||||
<span class="text-foreground-muted">Completed</span>
|
||||
<span class="text-foreground">{{.Items.Completed}}</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-xs">
|
||||
<span class="text-foreground-muted">On Hold</span>
|
||||
<span class="text-foreground">{{.Items.OnHold}}</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-xs">
|
||||
<span class="text-foreground-muted">Dropped</span>
|
||||
<span class="text-foreground">{{.Items.Dropped}}</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-xs">
|
||||
<span class="text-foreground-muted">Plan to Watch</span>
|
||||
<span class="text-foreground">{{.Items.PlanToWatch}}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
{{define "anime_themes"}}
|
||||
{{if or .Items.Openings .Items.Endings}}
|
||||
<div class="grid grid-cols-2 gap-6 p-6">
|
||||
<div>
|
||||
<h3 class="mb-4 text-sm font-medium text-foreground">Openings</h3>
|
||||
<div class="flex flex-col gap-3">
|
||||
{{range .Items.Openings}}
|
||||
<div class="text-sm leading-relaxed text-foreground-muted">{{.}}</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="mb-4 text-sm font-medium text-foreground">Endings</h3>
|
||||
<div class="flex flex-col gap-3">
|
||||
{{range .Items.Endings}}
|
||||
<div class="text-sm leading-relaxed text-foreground-muted">{{.}}</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="p-6 text-sm text-foreground-muted">No theme songs available.</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
{{define "title"}}{{.Anime.DisplayTitle}}{{end}}
|
||||
{{define "scripts"}}{{end}}
|
||||
{{define "content"}}
|
||||
@@ -169,15 +57,7 @@
|
||||
|
||||
<div class="flex flex-col gap-12 lg:flex-row">
|
||||
<div class="grow lg:max-w-4xl">
|
||||
<section>
|
||||
<h2 class="mb-4 mt-2 text-base font-normal text-foreground">Synopsis</h2>
|
||||
<p id="synopsis-container" data-synopsis-container class="text-foreground-muted text-base leading-relaxed line-clamp-6 md:line-clamp-none whitespace-pre-line">{{if $anime.Synopsis}}{{$anime.Synopsis}}{{else}}No synopsis available.{{end}}</p>
|
||||
{{if and $anime.Synopsis (gt (len $anime.Synopsis) 400)}}
|
||||
<button id="synopsis-toggle" data-synopsis-toggle class="mt-2 text-sm font-normal text-foreground-muted transition-colors hover:text-foreground md:hidden">
|
||||
Read more
|
||||
</button>
|
||||
{{end}}
|
||||
</section>
|
||||
{{template "anime_synopsis" dict "Anime" $anime}}
|
||||
</div>
|
||||
<aside class="fixed right-0 top-0 hidden h-screen w-80 shrink-0 flex-col overflow-y-auto border-l border-(--border-light) bg-background-sidebar p-8 lg:flex">
|
||||
<div class="flex flex-col gap-8">
|
||||
@@ -287,13 +167,7 @@
|
||||
|
||||
<section>
|
||||
<h3 class="mb-4 text-base font-normal text-foreground">Statistics</h3>
|
||||
<div hx-get="/anime/{{$anime.MalID}}?section=statistics" hx-trigger="load" hx-swap="innerHTML">
|
||||
<div class="flex flex-col gap-3 pt-1">
|
||||
{{range (seq 5)}}
|
||||
<div class="skeleton h-4"></div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{template "anime_statistics_loading" dict "AnimeID" $anime.MalID}}
|
||||
</section>
|
||||
|
||||
<section>
|
||||
@@ -322,22 +196,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div hx-get="/anime/{{$anime.MalID}}?section=characters" hx-trigger="load" hx-swap="outerHTML">
|
||||
<div class="mt-12 w-full">
|
||||
<h2 class="mb-6 text-lg font-normal text-foreground">Characters & Cast</h2>
|
||||
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5">
|
||||
{{range (seq 5)}}
|
||||
<div class="flex h-20 gap-3 bg-background-surface p-3">
|
||||
<div class="skeleton h-16 w-12 shrink-0"></div>
|
||||
<div class="flex flex-col justify-center gap-2 grow">
|
||||
<div class="skeleton h-3 w-2/3"></div>
|
||||
<div class="skeleton skeleton-subtle h-2 w-1/2"></div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{template "anime_characters_loading" dict "AnimeID" $anime.MalID}}
|
||||
|
||||
<div class="w-full">
|
||||
<div
|
||||
@@ -351,35 +210,9 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
hx-get="/anime/{{$anime.MalID}}?section=recommendations"
|
||||
hx-trigger="load"
|
||||
hx-swap="outerHTML"
|
||||
>
|
||||
<div class="w-full">
|
||||
<h2 class="mb-6 text-lg font-normal text-foreground">Recommendations</h2>
|
||||
<div class="grid grid-cols-2 gap-4 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 xl:grid-cols-8">
|
||||
{{range (seq 8)}}
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="skeleton aspect-2/3"></div>
|
||||
<div class="skeleton h-3 w-full"></div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{template "anime_recommendations_initial_loading" dict "AnimeID" $anime.MalID}}
|
||||
</div>
|
||||
|
||||
<div class="fixed inset-0 z-50 hidden items-start justify-center bg-black/50 px-4 pt-[12vh]" data-themes-dialog aria-hidden="true">
|
||||
<div class="w-full max-w-2xl overflow-hidden bg-background-button shadow-(--shadow-card)" role="dialog" aria-modal="true" aria-label="Theme Songs">
|
||||
<div class="flex items-center justify-between px-6 py-4">
|
||||
<h2 class="text-base font-normal text-foreground">Theme Songs</h2>
|
||||
<button type="button" data-themes-close class="px-2 py-1 text-xs text-foreground-muted transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-accent">Close</button>
|
||||
</div>
|
||||
<div data-themes-content class="max-h-[60vh] overflow-y-auto"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div data-themes-loader hx-get="/anime/{{$anime.MalID}}?section=themes" hx-trigger="theme-songs:load from:body" hx-target="[data-themes-content]" hx-swap="innerHTML"></div>
|
||||
{{template "anime_themes_dialog" dict "AnimeID" $anime.MalID}}
|
||||
|
||||
{{end}}
|
||||
|
||||
Reference in New Issue
Block a user