Files
mal/web/templates/studio.templ

105 lines
3.0 KiB
Plaintext

package templates
import (
"fmt"
"mal/integrations/jikan"
"mal/web/components"
"mal/web/shared"
)
templ StudioDetails(producer jikan.ProducerResponse, animes []jikan.Anime, hasNext bool, nextPage int) {
@Layout("mal - "+shared.GetProducerName(producer), true) {
<div class="grid gap-5">
<div class="grid gap-4 bg-(--panel) p-4">
<div class="flex items-start gap-4">
if producer.Data.Images.Jpg.ImageURL != "" {
<img
src={ producer.Data.Images.Jpg.ImageURL }
alt={ shared.GetProducerName(producer) }
class="h-24 w-24 object-contain"
/>
}
<div class="flex-1">
<h1 class="text-xl font-semibold">{ shared.GetProducerName(producer) }</h1>
if producer.Data.Established != "" {
<p class="mt-1 text-sm text-(--text-muted)">
Established: { shared.FormatEstablishedDate(producer.Data.Established) }
</p>
}
if producer.Data.Count > 0 {
<p class="text-sm text-(--text-faint)">
{ fmt.Sprintf("%d anime", producer.Data.Count) }
</p>
}
</div>
</div>
if producer.Data.About != "" {
<p class="text-sm text-(--text-muted) line-clamp-3">{ producer.Data.About }</p>
}
</div>
<div>
<h2 class="mb-3 text-lg font-semibold">Anime</h2>
<div class="grid grid-cols-2 gap-3 sm:grid-cols-3 md:gap-4 lg:grid-cols-4 xl:grid-cols-5" id="studio-anime-content">
for _, anime := range animes {
<div class="min-w-0" data-id={ fmt.Sprintf("%d", anime.MalID) }>
@components.AnimeCard(components.AnimeCardProps{
ID: anime.MalID,
Title: anime.DisplayTitle(),
ImageURL: anime.ImageURL(),
})
</div>
}
if hasNext {
@StudioLoadMore(producer.Data.MalID, nextPage)
}
</div>
</div>
</div>
}
}
templ StudioLoadMore(studioID int, nextPage int) {
<div
class="col-span-full h-px w-full"
hx-get={ string(templ.URL(fmt.Sprintf("/api/studios/%d/anime?page=%d", studioID, nextPage))) }
hx-trigger="revealed"
hx-swap="outerHTML"
></div>
}
templ StudioAnimeItems(animes []jikan.Anime, hasNext bool, studioID int, nextPage int) {
for _, anime := range animes {
<div class="min-w-0" data-id={ fmt.Sprintf("%d", anime.MalID) }>
@components.AnimeCard(components.AnimeCardProps{
ID: anime.MalID,
Title: anime.DisplayTitle(),
ImageURL: anime.ImageURL(),
})
</div>
}
if hasNext {
@StudioLoadMore(studioID, nextPage)
}
<script data-container="studio-anime-content">
(function() {
const scripts = document.querySelectorAll('script[data-container]');
const currentScript = scripts[scripts.length - 1];
const actualID = currentScript.getAttribute('data-container');
const container = document.getElementById(actualID) || document;
const items = container.querySelectorAll('[data-id]');
const seen = new Set();
items.forEach(item => {
const id = item.getAttribute('data-id');
if (id) {
if (seen.has(id)) {
item.remove();
} else {
seen.add(id);
}
}
});
})();
</script>
}