handle series
This commit is contained in:
@@ -1,21 +1,34 @@
|
||||
<script lang="ts">
|
||||
import type { Game } from '$lib/types';
|
||||
import type { Game, Series } from '$lib/types';
|
||||
import GameCard from './GameCard.svelte';
|
||||
import SeriesCard from './SeriesCard.svelte';
|
||||
|
||||
let {
|
||||
games,
|
||||
series = [],
|
||||
loggedIn,
|
||||
filter = ''
|
||||
}: { games: Game[]; loggedIn: boolean; filter?: string } = $props();
|
||||
}: { games: Game[]; series?: Series[]; loggedIn: boolean; filter?: string } = $props();
|
||||
|
||||
type GameItem = { kind: 'game' } & Game;
|
||||
type SeriesItem = { kind: 'series' } & Series;
|
||||
type Item = GameItem | SeriesItem;
|
||||
|
||||
const allItems = $derived<Item[]>(
|
||||
[
|
||||
...games.map((g) => ({ kind: 'game' as const, ...g })),
|
||||
...series.map((s) => ({ kind: 'series' as const, ...s }))
|
||||
].sort((a, b) => a.title.localeCompare(b.title))
|
||||
);
|
||||
|
||||
const filtered = $derived(
|
||||
filter.trim()
|
||||
? games.filter(
|
||||
(g) =>
|
||||
g.title.toLowerCase().includes(filter.toLowerCase()) ||
|
||||
g.genre.toLowerCase().includes(filter.toLowerCase())
|
||||
? allItems.filter(
|
||||
(item) =>
|
||||
item.title.toLowerCase().includes(filter.toLowerCase()) ||
|
||||
(item.kind === 'game' && item.genre.toLowerCase().includes(filter.toLowerCase()))
|
||||
)
|
||||
: games
|
||||
: allItems
|
||||
);
|
||||
</script>
|
||||
|
||||
@@ -23,8 +36,12 @@
|
||||
<p class="text-gray-500 text-center py-16">No games found.</p>
|
||||
{:else}
|
||||
<div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-4">
|
||||
{#each filtered as game (game.id)}
|
||||
<GameCard {game} {loggedIn} />
|
||||
{#each filtered as item (item.kind + item.id)}
|
||||
{#if item.kind === 'game'}
|
||||
<GameCard game={item} {loggedIn} />
|
||||
{:else}
|
||||
<SeriesCard series={item} {loggedIn} />
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
43
src/lib/components/SeriesCard.svelte
Normal file
43
src/lib/components/SeriesCard.svelte
Normal file
@@ -0,0 +1,43 @@
|
||||
<script lang="ts">
|
||||
import type { Series } from '$lib/types';
|
||||
|
||||
let { series, loggedIn }: { series: Series; loggedIn: boolean } = $props();
|
||||
</script>
|
||||
|
||||
<a href="/series/{series.slug}" class="group block">
|
||||
<div
|
||||
class="relative aspect-[2/3] rounded-lg overflow-hidden bg-gray-800 shadow-md transition-transform duration-200 group-hover:-translate-y-1 group-hover:shadow-2xl"
|
||||
>
|
||||
{#if series.has_cover}
|
||||
<img
|
||||
src="/api/cover/series/{series.slug}"
|
||||
alt={series.title}
|
||||
class="w-full h-full object-cover"
|
||||
loading="lazy"
|
||||
/>
|
||||
{:else}
|
||||
<div class="w-full h-full flex items-end p-3 bg-gradient-to-br from-indigo-900 to-gray-900">
|
||||
<span class="text-sm font-medium text-gray-200 leading-tight line-clamp-3"
|
||||
>{series.title}</span
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div
|
||||
class="absolute top-2 left-2 bg-indigo-600 text-white text-xs font-medium px-2 py-0.5 rounded-full"
|
||||
>
|
||||
Series
|
||||
</div>
|
||||
|
||||
{#if series.library === 'private' && loggedIn}
|
||||
<div
|
||||
class="absolute top-2 right-2 bg-purple-600 text-white text-xs font-medium px-2 py-0.5 rounded-full"
|
||||
>
|
||||
Private
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<p class="mt-2 text-sm text-gray-300 truncate group-hover:text-white transition-colors">
|
||||
{series.title}
|
||||
</p>
|
||||
</a>
|
||||
Reference in New Issue
Block a user