diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 5c50b44..4760bc0 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -3,6 +3,15 @@ let { children } = $props(); </script> -<div class="flex min-h-screen items-center"> - {@render children()} +<div class="flex min-h-screen flex-col items-center justify-center"> + <header class="mb-12 flex flex-col items-center"> + <h1 class="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl">Paku biiti</h1> + <p class="text-xl text-muted-foreground"> + Lohista kokku õiged albumi <span class="text-orange-400">nimed</span>, + <span class="text-cyan-400">artistid</span> ja <span class="text-purple-400">pildid</span>. + </p> + </header> + <main class="w-full max-w-3xl"> + {@render children()} + </main> </div> diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 60fa13b..4e1a1a0 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,4 +1,5 @@ <script lang="ts"> + import LoaderCircle from 'lucide-svelte/icons/loader-circle'; import { Button } from '$lib/components/ui/button/index.js'; import * as AlertDialog from '$lib/components/ui/alert-dialog/index.js'; import { Skeleton } from '$lib/components/ui/skeleton/index.js'; @@ -9,40 +10,60 @@ let { data, form }: { data: PageData; form: FormData } = $props(); let loading = $state(true); - - let names: string[] | undefined = $state(); - let artists: string[] | undefined = $state(); - let images: string[] | undefined = $state(); + let oldAlbums: SpotifyApi.AlbumObjectSimplified[] = $state([]); $effect(() => { - loading = false; - console.log(form); + // this is a hack to disable grayscale, please ignore + // eslint-disable-next-line no-constant-binary-expression + loading = false && form?.success; }); - $inspect(data); + // Used when user answers wrong and no new data comes in + $effect(() => { + if (data.streamed?.albums) { + data.streamed.albums.then((data) => { + oldAlbums = data; + }); + } + }); </script> +{#snippet footer(loading: boolean)} + <div class="flex justify-evenly"> + <p class="text-lg font-semibold">Skoor: {data.stage}</p> + {#if loading} + <Button disabled> + <LoaderCircle class="animate-spin" /> + Oota korra + </Button> + {:else} + <Button type="submit">Saada</Button> + {/if} + <p class="text-lg font-semibold">Parim: {data.highscore}</p> + </div> +{/snippet} + <AlertDialog.Root open={form?.solved === false}> <AlertDialog.Content> <AlertDialog.Header> <AlertDialog.Title> {#if data?.highscore && data?.stage && data.highscore === data.stage} - New high score! + Uus parim tulemus! {:else} - Maybe next time + Seekord ei vedanud {/if} </AlertDialog.Title> <AlertDialog.Description> {#if data.stage === 0} - That's tough. <strong>0 right answers.</strong> + Valus. <strong>põrusid esimesel katsel.</strong> {:else} - You got it right <strong>{data.stage} times.</strong> + Vastasid õigesti <strong>{data.stage} korda.</strong> {/if} </AlertDialog.Description> </AlertDialog.Header> <AlertDialog.Footer> <form action="?/restart" method="POST" use:enhance> - <AlertDialog.Action type="submit">Try again</AlertDialog.Action> + <AlertDialog.Action type="submit">Uuesti</AlertDialog.Action> </form> </AlertDialog.Footer> </AlertDialog.Content> @@ -52,42 +73,39 @@ action="?/submit" method="POST" use:enhance - class="mx-auto grid w-full max-w-3xl gap-8 px-8 transition-all {loading || data?.playing === false + class="grid w-full gap-8 px-8 transition-all {loading || data?.playing === false ? 'grayscale' : ''}" - onsubmit={() => { - loading = true; - }} > - {#await data.streamed.albums} - {#each { length: 2 } as _} + {#if data?.streamed?.albums} + {#await data.streamed.albums} + {#each { length: 2 } as _} + <section class="grid grid-cols-3 items-center gap-16"> + {#each { length: 3 } as _} + <Skeleton class="h-[6rem] w-full rounded-xl " /> + {/each} + </section> + {/each} + <section class="grid grid-cols-3 items-center gap-16"> {#each { length: 3 } as _} - <Skeleton class="h-[6rem] w-full rounded-xl " /> + <Skeleton class="aspect-square h-auto max-w-full rounded-xl object-cover" /> {/each} </section> - {/each} - <section class="grid grid-cols-3 items-center gap-16"> - {#each { length: 3 } as _} - <Skeleton class="aspect-square h-auto max-w-full rounded-xl object-cover" /> - {/each} - </section> - {:then albums} - {#if albums.names && albums.artists && albums.images} + {@render footer(true)} + {:then albums} <DndGroup items={albums.names} type="names"></DndGroup> <DndGroup items={albums.artists} type="artists"></DndGroup> <DndGroup items={albums.images} image type="images"></DndGroup> - {:else} - <DndGroup items={names} type="names"></DndGroup> - <DndGroup items={artists} type="artists"></DndGroup> - <DndGroup items={images} image type="images"></DndGroup> - {/if} - {/await} - <div class="flex justify-evenly"> - <p>Stage: {data.stage}</p> - <Button type="submit" variant="outline">Submit</Button> - <p>High Score: {data.highscore}</p> - </div> + {@render footer(false)} + {/await} + {:else} + <DndGroup items={oldAlbums.names} type="names"></DndGroup> + <DndGroup items={oldAlbums.artists} type="artists"></DndGroup> + <DndGroup items={oldAlbums.images} image type="images"></DndGroup> + + {@render footer(false)} + {/if} </form>