From 88421b077ec4c8c864f98e6b214f9e110880e194 Mon Sep 17 00:00:00 2001 From: Stian Haga Date: Thu, 28 Mar 2024 07:38:27 +0100 Subject: [PATCH 1/8] chore: add stats page from gallery template --- src/lib/components/Header.svelte | 3 +- src/routes/stats/+page.server.ts | 29 ++++++++++ src/routes/stats/+page.svelte | 93 ++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 src/routes/stats/+page.server.ts create mode 100644 src/routes/stats/+page.svelte diff --git a/src/lib/components/Header.svelte b/src/lib/components/Header.svelte index 09be49f6..8a133a02 100644 --- a/src/lib/components/Header.svelte +++ b/src/lib/components/Header.svelte @@ -10,7 +10,8 @@ const links = [ { name: 'Games', href: '/games' }, - { name: 'Gallery', href: '/gallery' } + { name: 'Gallery', href: '/gallery' }, + { name: 'Stats', href: '/stats' } ]; let isMainMenuOpen = false; diff --git a/src/routes/stats/+page.server.ts b/src/routes/stats/+page.server.ts new file mode 100644 index 00000000..9322f649 --- /dev/null +++ b/src/routes/stats/+page.server.ts @@ -0,0 +1,29 @@ +import { fail, redirect } from '@sveltejs/kit'; +import type { PageServerLoad } from './$types'; + +export const load: PageServerLoad = async ({ locals: { getSession, supabase } }) => { + const session = await getSession(); + if (!session) { + redirect(303, '/auth/login'); + } + + const userId = session.user.id; + if (!userId) return fail(401, { message: 'User not found' }); + + const { data: games, error } = await supabase + .from('games') + .select( + 'id, creator, code, end_at, name, participation ( profile_id, score, total_score, nickname, nickname_image_url )' + ) + .eq('participation.profile_id', session.user.id); + + if (error) { + return fail(500, { message: error }); + } + + return { + games: games || [], + profileId: userId, + title: 'Gallery' + }; +}; diff --git a/src/routes/stats/+page.svelte b/src/routes/stats/+page.svelte new file mode 100644 index 00000000..29bc30cc --- /dev/null +++ b/src/routes/stats/+page.svelte @@ -0,0 +1,93 @@ + + +
+
+
+

Gallery of Legends

+

+ Your previous achievements are eternalized in the Gallery of Legends. Gaze upon your scores + and marvel at your own greatness. +

+
+ {#if games.length} + + {:else} +
+ +

No past games found

+

Get started by creating a new AuthentiClash session.

+ +
+ {/if} +
+
From 374fc46d48facf9b21f6733b34ae3544c5b9b970 Mon Sep 17 00:00:00 2001 From: Stian Haga Date: Thu, 28 Mar 2024 09:36:58 +0100 Subject: [PATCH 2/8] feat: add StatsCard component --- src/routes/stats/StatsCard.svelte | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/routes/stats/StatsCard.svelte diff --git a/src/routes/stats/StatsCard.svelte b/src/routes/stats/StatsCard.svelte new file mode 100644 index 00000000..1785735f --- /dev/null +++ b/src/routes/stats/StatsCard.svelte @@ -0,0 +1,24 @@ + + +
+

{title}

+ +
From afc7cbce77ba5cae9f5aed1b73d98ee9c1ab97cc Mon Sep 17 00:00:00 2001 From: Stian Haga Date: Thu, 28 Mar 2024 09:37:14 +0100 Subject: [PATCH 3/8] feat: add statsnumber component --- src/routes/stats/StatsNumber.svelte | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/routes/stats/StatsNumber.svelte diff --git a/src/routes/stats/StatsNumber.svelte b/src/routes/stats/StatsNumber.svelte new file mode 100644 index 00000000..09701d7b --- /dev/null +++ b/src/routes/stats/StatsNumber.svelte @@ -0,0 +1,11 @@ + + +{currentNum.toFixed(decimals)} From e35ace863efc82c0da2fad8c8eeb58b7dde3ea55 Mon Sep 17 00:00:00 2001 From: Stian Haga Date: Thu, 28 Mar 2024 09:37:31 +0100 Subject: [PATCH 4/8] fix: reduce air in layout on large screens --- src/routes/+layout.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index c0ceea9b..0fb0de8a 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -62,7 +62,7 @@
-
+
From bd636ef49c2606e215505f7374ebc1d03ae393d0 Mon Sep 17 00:00:00 2001 From: Stian Haga Date: Thu, 28 Mar 2024 09:37:46 +0100 Subject: [PATCH 5/8] fix: use correct title for stats page --- src/routes/stats/+page.server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/stats/+page.server.ts b/src/routes/stats/+page.server.ts index 9322f649..6a188552 100644 --- a/src/routes/stats/+page.server.ts +++ b/src/routes/stats/+page.server.ts @@ -24,6 +24,6 @@ export const load: PageServerLoad = async ({ locals: { getSession, supabase } }) return { games: games || [], profileId: userId, - title: 'Gallery' + title: 'Stats' }; }; From 5ecfcda9cb682bf95e55955e3fa07a42c7c86768 Mon Sep 17 00:00:00 2001 From: Stian Haga Date: Thu, 28 Mar 2024 09:39:06 +0100 Subject: [PATCH 6/8] feat: add stats to stats page --- src/routes/stats/+page.svelte | 129 +++++++++++++++------------------- 1 file changed, 58 insertions(+), 71 deletions(-) diff --git a/src/routes/stats/+page.svelte b/src/routes/stats/+page.svelte index 29bc30cc..4ddd50f6 100644 --- a/src/routes/stats/+page.svelte +++ b/src/routes/stats/+page.svelte @@ -1,6 +1,8 @@ -
-
-
-

Gallery of Legends

-

- Your previous achievements are eternalized in the Gallery of Legends. Gaze upon your scores - and marvel at your own greatness. -

+
+ {#if games.length} +
+ +

+ +

+
+ +

+ +

+
+ +

+ +

+
+ +

+ +

+
+ + +
- {#if games.length} - - {:else} -
- -

No past games found

-

Get started by creating a new AuthentiClash session.

- - {/if} -
+
+ {/if}
From c0591914d21505734f00719f514e2ffd67ac105b Mon Sep 17 00:00:00 2001 From: Stian Haga Date: Thu, 28 Mar 2024 09:40:15 +0100 Subject: [PATCH 7/8] chore: add changeset --- .changeset/fifty-baboons-run.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/fifty-baboons-run.md diff --git a/.changeset/fifty-baboons-run.md b/.changeset/fifty-baboons-run.md new file mode 100644 index 00000000..3b929e10 --- /dev/null +++ b/.changeset/fifty-baboons-run.md @@ -0,0 +1,5 @@ +--- +"authenticlash": minor +--- + +Add stats page From 4f35d33bec1328546b7efea3b8ccdd6912d6cdae Mon Sep 17 00:00:00 2001 From: Stian Haga Date: Thu, 28 Mar 2024 20:01:54 +0100 Subject: [PATCH 8/8] feat: add more stats and calculate on the server --- src/routes/stats/+page.server.ts | 40 ++++++++++++++++++++++--- src/routes/stats/+page.svelte | 50 +++++++++++++++++--------------- 2 files changed, 62 insertions(+), 28 deletions(-) diff --git a/src/routes/stats/+page.server.ts b/src/routes/stats/+page.server.ts index 6a188552..de7fcc9b 100644 --- a/src/routes/stats/+page.server.ts +++ b/src/routes/stats/+page.server.ts @@ -14,16 +14,48 @@ export const load: PageServerLoad = async ({ locals: { getSession, supabase } }) .from('games') .select( 'id, creator, code, end_at, name, participation ( profile_id, score, total_score, nickname, nickname_image_url )' - ) - .eq('participation.profile_id', session.user.id); + ); if (error) { return fail(500, { message: error }); } + const participatedGames = games + .filter((game) => game.participation.some((p) => p.profile_id === userId)) + .sort((a, b) => new Date(b.end_at).getTime() - new Date(a.end_at).getTime()); + + const allParticipations = participatedGames.flatMap((game) => + game.participation.filter((p) => p.profile_id === userId) + ); + + const allScores = allParticipations.flatMap((p) => p.score); + + const totalScoreAcrossGames = allScores.reduce((acc, score) => acc + score, 0); + + const average2FAScore = totalScoreAcrossGames / allScores.length; + + const averageTotalScore = + allParticipations.reduce((acc, p) => acc + p.total_score, 0) / allParticipations.length; + + const median2FAscore = allScores.sort((a, b) => a - b)[Math.floor(allScores.length / 2)]; + + const wins = participatedGames + .map((game) => { + const highscoreList = game.participation.sort((a, b) => b.total_score - a.total_score); + return highscoreList[0].profile_id === userId; + }) + .filter(Boolean).length; + return { - games: games || [], - profileId: userId, + stats: { + numberOfGames: participatedGames.length, + allScores, + totalScoreAcrossGames, + average2FAScore, + averageTotalScore, + median2FAscore, + wins + }, title: 'Stats' }; }; diff --git a/src/routes/stats/+page.svelte b/src/routes/stats/+page.svelte index 4ddd50f6..bb5847c5 100644 --- a/src/routes/stats/+page.svelte +++ b/src/routes/stats/+page.svelte @@ -5,51 +5,53 @@ import ScoreGraph from '$lib/components/ScoreGraph.svelte'; export let data; - const games = - data.games - ?.filter((game) => game.participation.length > 0) - .sort((a, b) => { - return new Date(b.end_at).getTime() - new Date(a.end_at).getTime(); - }) - .map((game) => { - const [participation] = game.participation; - return { - code: game.code, - participation - }; - }) || []; - const averageGameScore = - games.reduce((acc, game) => acc + game.participation.total_score, 0) / games.length; - const allScores = games.flatMap((game) => game.participation.score); - const average2FAValue = allScores.reduce((acc, score) => acc + score, 0) / allScores.length; + const { + numberOfGames, + allScores, + totalScoreAcrossGames, + average2FAScore, + averageTotalScore, + median2FAscore, + wins + } = data.stats;
- {#if games.length} + {#if numberOfGames}

- +

- +

- +

- +

- +

- +

+ +

+ +

+
+ +

+ +

+
{:else}