77 lines
2.4 KiB
Svelte
77 lines
2.4 KiB
Svelte
<script lang="ts">
|
|
import { page } from '$app/stores';
|
|
|
|
import ChevronRight from 'lucide-svelte/icons/chevron-right';
|
|
|
|
import type { Puzzle } from '$lib/types';
|
|
import { cn } from '$lib/utils';
|
|
|
|
export let puzzle: Puzzle;
|
|
|
|
const chapterId = $page.params.chapterId;
|
|
</script>
|
|
|
|
<li
|
|
class={cn(
|
|
'group relative flex h-full w-full rounded border border-border bg-card transition-colors duration-150',
|
|
{
|
|
'border-green-500/30': puzzle.tags?.find((tag) => tag.name.toLowerCase() === 'easy'),
|
|
'border-yellow-500/30': puzzle.tags?.find((tag) => tag.name.toLowerCase() === 'medium'),
|
|
'border-red-500/30': puzzle.tags?.find((tag) => tag.name.toLowerCase() === 'hard'),
|
|
'hover:bg-card/80': puzzle.show,
|
|
'opacity-50': !puzzle.show
|
|
}
|
|
)}
|
|
>
|
|
{#if puzzle.show}
|
|
<a
|
|
class="flex h-full w-full items-center gap-4 p-4"
|
|
href="/chapters/{chapterId}/puzzle/{puzzle.id}"
|
|
>
|
|
<div class="flex w-full flex-col justify-between gap-2 sm:flex-row">
|
|
<h2 class="text-base font-semibold">
|
|
{puzzle.name}
|
|
<span class="text-highlight-secondary text-sm">
|
|
({puzzle.score ? `${puzzle.score}` : '?'}/{puzzle.scoreMax} points)
|
|
</span>
|
|
</h2>
|
|
{#if puzzle.tags?.length}
|
|
<div class="flex items-center gap-x-6">
|
|
<div class="flex gap-x-2 text-sm">
|
|
{#each puzzle.tags.filter((tag) => !['easy', 'medium', 'hard'].includes(tag.name.toLowerCase())) as tag}
|
|
<span class="inline-block rounded bg-muted px-2 py-1 text-muted-foreground">
|
|
{tag.name}
|
|
</span>
|
|
{/each}
|
|
</div>
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
<span class="translate-x-0 transform-gpu duration-300 group-hover:translate-x-2">
|
|
<ChevronRight />
|
|
</span>
|
|
</a>
|
|
{:else}
|
|
<span class="flex h-full w-full items-center gap-4 p-4">
|
|
<div class="flex w-full flex-col justify-between gap-2 sm:flex-row">
|
|
<h2 class="text-base font-semibold">
|
|
{puzzle.name}
|
|
<span class="text-highlight-secondary text-sm">
|
|
({puzzle.score ? `${puzzle.score}` : '?'}/{puzzle.scoreMax} points)
|
|
</span>
|
|
</h2>
|
|
<div class="flex items-center gap-x-6">
|
|
{#if puzzle.tags?.length}
|
|
<div class="flex gap-x-2 text-sm">
|
|
{#each puzzle.tags.filter( (tag) => ['easy', 'medium', 'hard'].includes(tag.name.toLowerCase()) ) as tag}
|
|
<span class="inline-block rounded bg-muted px-2 py-1 text-muted-foreground">
|
|
{tag.name}
|
|
</span>
|
|
{/each}
|
|
</div>
|
|
{/if}
|
|
</div>
|
|
</div>
|
|
</span>
|
|
{/if}
|
|
</li>
|