diff --git a/package.json b/package.json index 68277343b1a8c91cba01540c252c58d1ffa73a12..89d1c748418279f6d9ca53f15d6768114edc7e3e 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "@urql/core": "^5.0.6", "formsnap": "^1.0.1", "gql.tada": "^1.8.6", + "http-status-codes": "^2.3.0", "msgpackr": "^1.11.0", "sveltekit-superforms": "^2.17.0", "zod": "^3.23.8" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3fd4d270bab5ef2ce52a051bc4f11acba485fb04..25cde9dca77458c459ad06d3cab1fb0686e7fb4f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,6 +17,9 @@ importers: gql.tada: specifier: ^1.8.6 version: 1.8.6(graphql@15.9.0)(typescript@5.5.4) + http-status-codes: + specifier: ^2.3.0 + version: 2.3.0 msgpackr: specifier: ^1.11.0 version: 1.11.0 @@ -1232,6 +1235,9 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + http-status-codes@2.3.0: + resolution: {integrity: sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==} + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -3295,6 +3301,8 @@ snapshots: dependencies: function-bind: 1.1.2 + http-status-codes@2.3.0: {} + ignore@5.3.2: {} import-fresh@3.3.0: diff --git a/src/app.css b/src/app.css index a31e444117d00d0d7238ebc538007f6e224877da..716762262c022815d8a8ee32af068a1f67555d3e 100644 --- a/src/app.css +++ b/src/app.css @@ -1,3 +1,27 @@ @import 'tailwindcss/base'; @import 'tailwindcss/components'; @import 'tailwindcss/utilities'; + +@font-face { + font-family: 'Londrina Solid'; + font-weight: 100; + src: url('/fonts/LondrinaSolid-Thin.ttf'); +} + +@font-face { + font-family: 'Londrina Solid'; + font-weight: 300; + src: url('/fonts/LondrinaSolid-Light.ttf'); +} + +@font-face { + font-family: 'Londrina Solid'; + font-weight: 400; + src: url('/fonts/LondrinaSolid-Regular.ttf'); +} + +@font-face { + font-family: 'Londrina Solid'; + font-weight: 900; + src: url('/fonts/LondrinaSolid-Black.ttf'); +} diff --git a/src/app.html b/src/app.html index 9c53e5672bcb5fee0c05adb61df69174c7fe9682..e3461df3eff6b42492ae91ff9d5fb087d96b2242 100644 --- a/src/app.html +++ b/src/app.html @@ -4,10 +4,6 @@ <meta charset="utf-8" /> <link rel="icon" href="%sveltekit.assets%/favicon.png" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> - <link - rel="stylesheet" - href="https://fonts.googleapis.com/css?family=Londrina+Solid|Nunito:400,300" - /> %sveltekit.head% </head> <body data-sveltekit-preload-data="hover" class="h-full"> diff --git a/src/lib/graphql/error.ts b/src/lib/graphql/error.ts new file mode 100644 index 0000000000000000000000000000000000000000..9f6cf2354cdb6cbd1f280a107a62131b9027321a --- /dev/null +++ b/src/lib/graphql/error.ts @@ -0,0 +1,8 @@ +import { error } from '@sveltejs/kit'; +import type { OperationResult } from '@urql/core'; + +export function handleGqlError(result: OperationResult): void { + if (result.error) { + error(500, { message: result.error.message }); + } +} diff --git a/src/lib/graphql/query.ts b/src/lib/graphql/query.ts index c8d69de0300d6ce6a6862e21e007e172305cd762..3dad155df05315ae4f09297fd47c1232ba29928b 100644 --- a/src/lib/graphql/query.ts +++ b/src/lib/graphql/query.ts @@ -1,5 +1,6 @@ import { client } from '$lib/graphql'; import type { DocumentInput } from '@urql/core'; +import { handleGqlError } from './error'; type Page<T> = { page: { @@ -29,9 +30,8 @@ export async function* pageIterator<T, Variables extends PageArgs>( .query(query, { first: pageSize, after: cursor, ...variables } as Variables) .toPromise(); - if (result.error) { - throw result.error; - } + handleGqlError(result); + const page: Page<T>['page'] | undefined = result.data?.page; if (!page) return; diff --git a/src/routes/quiz/+error.svelte b/src/routes/quiz/+error.svelte new file mode 100644 index 0000000000000000000000000000000000000000..cdc25a7647395fbf44348924fe78dcf053a495cb --- /dev/null +++ b/src/routes/quiz/+error.svelte @@ -0,0 +1,14 @@ +<script> + import { page } from '$app/stores'; + import { getReasonPhrase } from 'http-status-codes'; +</script> + +<main class="grid min-h-full place-items-center px-6 py-24 sm:py-32 lg:px-8"> + <div class="max-w-lg text-center"> + <p class="text-7xl font-semibold text-red-200">{$page.status}</p> + <h1 class="mt-4 text-3xl tracking-tight text-white sm:text-5xl"> + {getReasonPhrase($page.status)} + </h1> + <p class="mt-6 text-lg font-light leading-7 text-red-100">{$page.error?.message}</p> + </div> +</main> diff --git a/src/routes/quiz/+layout.svelte b/src/routes/quiz/+layout.svelte new file mode 100644 index 0000000000000000000000000000000000000000..7afeea526e29313a4ff9b89c17910b58a8ff93fb --- /dev/null +++ b/src/routes/quiz/+layout.svelte @@ -0,0 +1,11 @@ +<slot></slot> + +<style> + :global(body) { + background-color: #f65a52; + font-family: 'Londrina Solid', monospace; + font-size: 16px; + line-height: 1.875em; + color: #333; + } +</style> diff --git a/src/routes/quiz/+page.server.ts b/src/routes/quiz/+page.server.ts index 59811a9af769bc9bfdeb49f6c1fe64a494e3b35f..ec9a25ef5e591c1b492d3ed9d296b267d27f31f0 100644 --- a/src/routes/quiz/+page.server.ts +++ b/src/routes/quiz/+page.server.ts @@ -7,6 +7,7 @@ import { GameStage, Game } from '$lib/game'; import { getPromotion } from '$lib/data'; import { client } from '$lib/graphql'; import { USER_DETAILS_QUERY } from '$lib/graphql/queries'; +import { handleGqlError } from '$lib/graphql/error'; type Option = { value: string; @@ -34,9 +35,7 @@ export async function load(event) { .query(USER_DETAILS_QUERY, { idList: game.state.options }) .toPromise(); - if (details.error) { - throw details.error; - } + handleGqlError(details); const users = details.data!.page.nodes ?? []; diff --git a/src/routes/quiz/+page.svelte b/src/routes/quiz/+page.svelte index bb662e8e1f27b871325aa59050e3ac33fa8ef6ab..3e97318a09828ab4261ed41f97d5cf4a0a69518d 100644 --- a/src/routes/quiz/+page.svelte +++ b/src/routes/quiz/+page.svelte @@ -87,13 +87,3 @@ </section> </div> </form> - -<style> - :global(body) { - background-color: #f65a52; - font-family: 'Londrina Solid', monospace; - font-size: 16px; - line-height: 1.875em; - color: #333; - } -</style> diff --git a/static/fonts/LondrinaSolid-Black.ttf b/static/fonts/LondrinaSolid-Black.ttf new file mode 100644 index 0000000000000000000000000000000000000000..3840ff320bb52ca4a61a191d48e797b9adeaf5ac Binary files /dev/null and b/static/fonts/LondrinaSolid-Black.ttf differ diff --git a/static/fonts/LondrinaSolid-Light.ttf b/static/fonts/LondrinaSolid-Light.ttf new file mode 100644 index 0000000000000000000000000000000000000000..651cf53a45a5c2d94b2271e9fb3e7f59fc12f5f1 Binary files /dev/null and b/static/fonts/LondrinaSolid-Light.ttf differ diff --git a/static/fonts/LondrinaSolid-Regular.ttf b/static/fonts/LondrinaSolid-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..7bf49231a6447864f6d726a4ca5b42d46f45d891 Binary files /dev/null and b/static/fonts/LondrinaSolid-Regular.ttf differ diff --git a/static/fonts/LondrinaSolid-Thin.ttf b/static/fonts/LondrinaSolid-Thin.ttf new file mode 100644 index 0000000000000000000000000000000000000000..3b4f77122f6950aaf4bb8a937ebcf1a1728f9de7 Binary files /dev/null and b/static/fonts/LondrinaSolid-Thin.ttf differ