From fad6d9d5c2fcc7b8e6a1c874f0caf6038dfa3fa4 Mon Sep 17 00:00:00 2001 From: steel <mael.acier@ensiie.fr> Date: Sun, 1 Sep 2024 02:36:07 +0200 Subject: [PATCH] feat: random color --- src/app.html | 4 +- src/lib/auth/index.ts | 2 +- src/lib/data.ts | 6 +-- src/lib/graphql/queries.ts | 8 +-- src/routes/quiz/+layout.server.ts | 42 ++++++++++++++++ src/routes/quiz/+layout.svelte | 18 ++++--- src/routes/quiz/+page.svelte | 60 +++++++++++------------ src/routes/quiz/game-over/+page.server.ts | 2 + src/routes/quiz/game-over/+page.svelte | 6 +-- tailwind.config.ts | 8 +++ 10 files changed, 105 insertions(+), 51 deletions(-) create mode 100644 src/routes/quiz/+layout.server.ts diff --git a/src/app.html b/src/app.html index 0e11c0a..88d12e6 100644 --- a/src/app.html +++ b/src/app.html @@ -1,12 +1,12 @@ <!doctype html> -<html lang="en" class="h-full"> +<html lang="fr" class="h-full"> <head> <meta charset="utf-8" /> <link rel="icon" href="%sveltekit.assets%/favicon.png" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> %sveltekit.head% </head> - <body data-sveltekit-preload-data="hover" class="h-full font-game text-zinc-800"> + <body data-sveltekit-preload-data="hover"> <div style="display: contents">%sveltekit.body%</div> </body> </html> diff --git a/src/lib/auth/index.ts b/src/lib/auth/index.ts index e1c36b3..3f4b947 100644 --- a/src/lib/auth/index.ts +++ b/src/lib/auth/index.ts @@ -5,6 +5,6 @@ import { defaultLucia } from '@arise/aidc-sveltekit/default'; export const aidc = await AriseIdConnect.init({ client_id: env.AIDC_CLIENT_ID, client_secret: env.AIDC_CLIENT_SECRET, - scope: 'openid offline_access profile', + scope: 'openid offline profile', wrapper: defaultLucia }); diff --git a/src/lib/data.ts b/src/lib/data.ts index 73d4339..cf26ee6 100644 --- a/src/lib/data.ts +++ b/src/lib/data.ts @@ -20,9 +20,9 @@ async function cacheImages(users: UserId[]): Promise<void> { throw response.error; } - const url = response.data?.page.nodes[0].photo; - if (!url) continue; - await fetch(url, { method: 'HEAD' }); + const photo = response.data?.page.nodes[0].photo; + if (!photo?.url) continue; + await fetch(photo.url, { method: 'HEAD' }); } } diff --git a/src/lib/graphql/queries.ts b/src/lib/graphql/queries.ts index d568967..c9bb02d 100644 --- a/src/lib/graphql/queries.ts +++ b/src/lib/graphql/queries.ts @@ -5,7 +5,7 @@ export const PROMOTION_QUERY = graphql(` page: users( first: $first after: $after - filter: { promotion: { eq: [$promotion] }, nickname: { null: false } } + filter: { promotion: { eq: [$promotion] }, nickname: { null: false }, photo: { null: false } } ) { pageInfo { endCursor @@ -24,8 +24,10 @@ export const USER_DETAILS_QUERY = graphql(` nodes { id nickname - photo - photoThumbnailHash + photo { + url + thumbnailHash + } } } } diff --git a/src/routes/quiz/+layout.server.ts b/src/routes/quiz/+layout.server.ts new file mode 100644 index 0000000..3293ca2 --- /dev/null +++ b/src/routes/quiz/+layout.server.ts @@ -0,0 +1,42 @@ +import colors from 'tailwindcss/colors'; +import { getRandomItems } from '$lib/utils'; + +type Color = keyof typeof colors; + +function getColor(currentColor?: string): Color { + const palette: Color[] = [ + 'red', + 'orange', + 'amber', + 'yellow', + 'lime', + 'green', + 'emerald', + 'teal', + 'cyan', + 'sky', + 'blue', + 'indigo', + 'violet', + 'purple', + 'fuchsia', + 'pink', + 'rose' + ]; + + if (palette.includes(currentColor as Color)) { + return currentColor as Color; + } + + return getRandomItems(palette, 1)[0]; +} + +export function load({ cookies }) { + const colorName = getColor(cookies.get('color')); + + cookies.set('color', colorName, { path: '/' }); + + return { + color: colors[colorName] + }; +} diff --git a/src/routes/quiz/+layout.svelte b/src/routes/quiz/+layout.svelte index 3616541..2e001b9 100644 --- a/src/routes/quiz/+layout.svelte +++ b/src/routes/quiz/+layout.svelte @@ -1,9 +1,11 @@ -<slot></slot> +<script lang="ts"> + export let data; -<style> - :global(body) { - background-color: #f65a52; - font-size: 16px; - line-height: 1.875em; - } -</style> + $: cssVarStyles = Object.entries(data.color) + .map(([key, value]) => `--tw-random-color-${key}:${value}`) + .join(';'); +</script> + +<div style={cssVarStyles} class="flex min-h-screen flex-col bg-random-500 font-game text-zinc-800"> + <slot /> +</div> diff --git a/src/routes/quiz/+page.svelte b/src/routes/quiz/+page.svelte index 3e97318..5ef86b1 100644 --- a/src/routes/quiz/+page.svelte +++ b/src/routes/quiz/+page.svelte @@ -15,30 +15,28 @@ const questionAmount = 10; </script> -<form method="post" use:enhance> - <div class="relative mx-auto my-12 w-full"> - <section class="relative m-auto flex flex-col items-center"> - <h1 class="absolute -top-8 text-xl">Qui est-ce ?</h1> - <div class="relative"> - <span class="absolute -left-14 flex flex-col items-end"> - <span class="text-9xl leading-[0.4] text-red-300"> {data.step} </span> - <span> / {questionAmount} </span> - </span> - <span - class="absolute right-[calc(100%_+_0.5rem)] top-24 whitespace-nowrap pt-4 text-xl text-zinc-800 before:absolute before:right-0 before:top-0 before:h-1.5 before:w-10 before:bg-zinc-800" - > - {data.score} - <small>pts</small> - </span> - <div - class="relative z-10 flex h-64 w-64 items-center justify-center overflow-hidden rounded-2xl border-6 border-solid border-zinc-800 bg-white before:absolute before:-z-10 before:h-32 before:w-32 before:rounded-full before:bg-slate-300 before:opacity-100 before:transition-[0.65s] before:duration-[ease-in-out] after:absolute after:-z-10 after:h-32 after:w-32 after:scale-0 after:rounded-full after:border-solid after:border-slate-300 after:transition-[0.4s] after:duration-[ease-in-out]" - > - <img src={data.photo} alt="Chargement..." class="w-auto" /> - </div> +<div class="relative mx-auto my-12 w-full grow"> + <section class="relative m-auto flex flex-col items-center"> + <h1 class="absolute -top-8 text-xl">Qui est-ce ?</h1> + <div class="relative"> + <span class="absolute -left-14 flex flex-col items-end"> + <span class="text-9xl leading-[0.4] text-random-300"> {data.step} </span> + <span> / {questionAmount} </span> + </span> + <span + class="absolute right-[calc(100%_+_0.5rem)] top-24 whitespace-nowrap pt-4 text-xl text-zinc-800 before:absolute before:right-0 before:top-0 before:h-1.5 before:w-10 before:bg-zinc-800" + > + {data.score} + <small>pts</small> + </span> + <div + class="relative z-10 flex h-64 w-64 items-center justify-center overflow-hidden rounded-2xl border-6 border-solid border-zinc-800 bg-white before:absolute before:-z-10 before:h-32 before:w-32 before:rounded-full before:bg-slate-300 before:opacity-100 before:transition-[0.65s] before:duration-[ease-in-out] after:absolute after:-z-10 after:h-32 after:w-32 after:scale-0 after:rounded-full after:border-solid after:border-slate-300 after:transition-[0.4s] after:duration-[ease-in-out]" + > + <img src={data.photo?.url} alt="Chargement..." class="w-auto" /> + </div> + <form method="post" use:enhance> <Fieldset form={form2} name="choice"> - <transition-group - tag="div" - name="animate-options" + <div class="relative -top-6 z-20 mx-auto my-0 flex w-44 flex-col items-center space-y-0.5 rounded-2xl bg-zinc-800 px-5 py-0" > {#each data.options as option} @@ -56,21 +54,21 @@ <Label tabindex={0} data-solution={form?.solution || null} - class="relative block cursor-pointer select-none overflow-hidden rounded-2xl border-6 border-solid border-zinc-800 bg-slate-300 p-2 text-center text-lg transition-[0.45s] before:absolute before:left-2/4 before:top-2/4 before:-z-10 before:h-[200px] before:w-[200px] before:-translate-x-2/4 before:-translate-y-2/4 before:scale-0 before:rounded-full before:bg-slate-400 before:transition-[0.2s] before:duration-[ease-in-out] focus:[outline:none] active:before:-translate-x-2/4 active:before:-translate-y-2/4 active:before:scale-100 peer-checked:bg-[#94acbd] peer-enabled:hover:translate-y-[-3px] peer-enabled:hover:bg-indigo-300 peer-enabled:focus:border-indigo-500 data-[solution]:cursor-default data-[solution]:text-[#94acbd] peer-checked:data-[solution]:bg-red-400 peer-checked:data-[solution]:text-inherit peer-data-[valid]:!bg-lime-400 peer-data-[valid]:text-inherit" + class="relative block cursor-pointer select-none overflow-hidden rounded-2xl border-6 border-solid border-zinc-800 bg-slate-300 p-2 text-center text-lg transition-[0.45s] before:absolute before:left-2/4 before:top-2/4 before:-z-10 before:h-[200px] before:w-[200px] before:-translate-x-2/4 before:-translate-y-2/4 before:scale-0 before:rounded-full before:bg-indigo-300 before:transition-[0.2s] before:duration-[ease-in-out] focus:[outline:none] active:before:-translate-x-2/4 active:before:-translate-y-2/4 active:before:scale-100 peer-enabled:hover:translate-y-[-3px] peer-enabled:hover:bg-slate-400 peer-enabled:focus:border-indigo-500 peer-checked:peer-enabled:bg-indigo-300 data-[solution]:cursor-default data-[solution]:text-[#94acbd] peer-checked:data-[solution]:bg-red-400 peer-checked:data-[solution]:text-inherit peer-data-[valid]:!bg-lime-400 peer-data-[valid]:text-inherit" > {option.label} </Label> </Control> </div> {/each} - </transition-group> + </div> </Fieldset> <footer class="space-y-1.5 text-center sm:absolute sm:left-full sm:top-5"> <button type="submit" formaction="?/results" disabled={form?.solution !== undefined} - class="h-[100px] w-[110px] cursor-pointer rounded-2xl border-transparent bg-red-600 p-4 text-2xl text-white transition-[0.35s] duration-300 focus:border focus:border-dotted focus:border-[#f87f79] focus:[outline:none] enabled:hover:translate-x-0 enabled:hover:bg-[#333] enabled:hover:text-[#f65a52] disabled:cursor-default disabled:text-[#fa9f9b] disabled:opacity-70 sm:-translate-x-2.5 sm:rounded-bl-none sm:rounded-tl-none" + class="h-[100px] w-[110px] cursor-pointer rounded-2xl border-transparent bg-random-600 p-4 text-2xl text-white transition-[0.35s] duration-300 focus:border focus:border-dotted focus:border-random-400 focus:[outline:none] enabled:hover:translate-x-0 enabled:hover:bg-[#333] enabled:hover:text-random-500 disabled:cursor-default disabled:text-random-300 disabled:opacity-70 sm:-translate-x-2.5 sm:rounded-bl-none sm:rounded-tl-none" > OK </button> @@ -78,12 +76,12 @@ type="submit" formaction="?/next" disabled={form?.solution === undefined} - class="h-[100px] w-[110px] cursor-pointer rounded-2xl border-transparent bg-red-600 p-4 text-2xl text-white transition-[0.35s] duration-300 focus:border focus:border-dotted focus:border-[#f87f79] focus:[outline:none] enabled:hover:translate-x-0 enabled:hover:bg-[#333] enabled:hover:text-[#f65a52] disabled:cursor-default disabled:text-[#fa9f9b] disabled:opacity-70 sm:-translate-x-2.5 sm:rounded-bl-none sm:rounded-tl-none" + class="h-[100px] w-[110px] cursor-pointer rounded-2xl border-transparent bg-random-600 p-4 text-2xl text-white transition-[0.35s] duration-300 focus:border focus:border-dotted focus:border-random-400 focus:[outline:none] enabled:hover:translate-x-0 enabled:hover:bg-[#333] enabled:hover:text-random-500 disabled:cursor-default disabled:text-random-300 disabled:opacity-70 sm:-translate-x-2.5 sm:rounded-bl-none sm:rounded-tl-none" > Suivant </button> </footer> - </div> - </section> - </div> -</form> + </form> + </div> + </section> +</div> diff --git a/src/routes/quiz/game-over/+page.server.ts b/src/routes/quiz/game-over/+page.server.ts index 4c65ae4..c4d603a 100644 --- a/src/routes/quiz/game-over/+page.server.ts +++ b/src/routes/quiz/game-over/+page.server.ts @@ -14,5 +14,7 @@ export const actions = { const game = new Game(event.cookies); game.reset(); + + event.cookies.delete('color', { path: '/' }); } }; diff --git a/src/routes/quiz/game-over/+page.svelte b/src/routes/quiz/game-over/+page.svelte index 46bcb47..6bbf498 100644 --- a/src/routes/quiz/game-over/+page.svelte +++ b/src/routes/quiz/game-over/+page.svelte @@ -8,15 +8,15 @@ <section class="text-center"> <h2>Score final</h2> <span - class="relative mb-4 block before:absolute before:left-2/4 before:top-2/4 before:z-[-1] before:h-[100px] before:w-[100px] before:-translate-x-2/4 before:-translate-y-2/4 before:animate-[grow_2s_infinite_ease-in-out] before:rounded-[50%] before:border-6 before:border-solid before:border-[#f32c22] before:opacity-30 before:content-['']" + class="relative mb-4 block before:absolute before:left-2/4 before:top-2/4 before:z-[-1] before:h-[100px] before:w-[100px] before:-translate-x-2/4 before:-translate-y-2/4 before:animate-[grow_2s_infinite_ease-in-out] before:rounded-[50%] before:border-6 before:border-solid before:border-random-600 before:opacity-30" > - <span class="translate-y-[-30px] text-9xl text-[#fa9f9b]">{data.score}</span> + <span class="translate-y-[-30px] text-9xl text-random-300">{data.score}</span> pts </span> <form method="post" use:enhance> <button type="submit" - class="cursor-pointer rounded-2xl border-transparent bg-[#f32c22] px-[1.5em] py-[0.5em] text-2xl text-[#333] transition-[0.35s] hover:bg-[#333] hover:text-[#f65a52] focus:border focus:border-dotted focus:border-[#f87f79] focus:[outline:none]" + class="cursor-pointer rounded-2xl border-transparent bg-random-600 px-[1.5em] py-[0.5em] text-2xl text-white transition-[0.35s] hover:bg-zinc-800 hover:text-random-500 focus:border focus:border-dotted focus:border-random-400 focus:[outline:none]" > Rejouer </button> diff --git a/tailwind.config.ts b/tailwind.config.ts index f12d001..c7309ef 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -10,6 +10,14 @@ export default { }, borderWidth: { 6: '6px' + }, + colors: { + random: Object.fromEntries( + [50, 100, 200, 300, 400, 500, 600, 700, 800, 900].map((shade) => [ + shade, + `var(--tw-random-color-${shade})` + ]) + ) } } }, -- GitLab