feat: leaderboard improvements
All checks were successful
deploy to cloudflare pages / deploy (push) Successful in 32s
All checks were successful
deploy to cloudflare pages / deploy (push) Successful in 32s
This commit is contained in:
parent
a2c27899f7
commit
e96718c273
3 changed files with 114 additions and 48 deletions
19
src/routes/api/leaderboard/+server.ts
Normal file
19
src/routes/api/leaderboard/+server.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
import { parseOptions } from "$lib";
|
||||
import { error } from "@sveltejs/kit";
|
||||
import type { RequestHandler } from "./$types";
|
||||
|
||||
export const GET: RequestHandler = async ({ url, platform }) => {
|
||||
const db = platform?.env?.TCL_GUESSR_D1 ?? null;
|
||||
if (db === null) error(500, "could not connect to d1");
|
||||
|
||||
const options = parseOptions(url);
|
||||
|
||||
const { results } = await db
|
||||
.prepare(
|
||||
"SELECT game.id, game.total_score, user.name FROM game INNER JOIN user ON user.id = game.user_id WHERE game.mode = ? AND game.stops_type = ? ORDER BY game.total_score DESC, game.time ASC LIMIT 10",
|
||||
)
|
||||
.bind(options.mode, options.stopsType)
|
||||
.all();
|
||||
|
||||
return new Response(JSON.stringify(results));
|
||||
};
|
|
@ -6,12 +6,16 @@ export const load: PageServerLoad = async ({ platform }) => {
|
|||
if (db === null) error(500, "could not access d1");
|
||||
|
||||
const statement = db.prepare(
|
||||
"SELECT game.id, game.mode, game.total_score, user.name FROM game INNER JOIN user ON user.id = game.user_id WHERE game.mode = ? ORDER BY game.total_score DESC, game.time ASC LIMIT 20",
|
||||
"SELECT game.id, game.total_score, user.name FROM game INNER JOIN user ON user.id = game.user_id WHERE game.mode = ? ORDER BY game.total_score DESC, game.time ASC LIMIT 10",
|
||||
);
|
||||
|
||||
const { results: easy } = await statement.bind("easy").all();
|
||||
const { results: hard } = await statement.bind("hard").all();
|
||||
const { results: miguel } = await statement.bind("extreme demon ultra miguel").all();
|
||||
|
||||
return { easy, hard, miguel };
|
||||
return {
|
||||
"EXTREME DEMON ULTRA MIGUEL DE LA MORT QUI TUE": miguel,
|
||||
Difficile: hard,
|
||||
Facile: easy,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,56 +1,99 @@
|
|||
<script lang="ts">
|
||||
import type { PageData } from "./$types";
|
||||
|
||||
interface Props {
|
||||
data: PageData;
|
||||
interface LeaderboardGame {
|
||||
id: string;
|
||||
total_score: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
const props: Props = $props();
|
||||
let mode = $state("extreme demon ultra miguel");
|
||||
let stopsType = $state("metro");
|
||||
let leaderboardPromise = $derived(fetchLeaderboard(mode, stopsType));
|
||||
|
||||
async function fetchLeaderboard(mode: string, stops_type: string): Promise<LeaderboardGame[]> {
|
||||
const params = new URLSearchParams({ mode, stops_type });
|
||||
return await fetch("/api/leaderboard?" + params).then((r) => r.json());
|
||||
}
|
||||
</script>
|
||||
|
||||
<h1>LEADEBOARD !!!!!</h1>
|
||||
<h1>LEADERBOARD !!!!!</h1>
|
||||
|
||||
<h2>EXTREME DEMON ULTRA MIGUEL DE LA MORT QUI TUE</h2>
|
||||
<div>
|
||||
Mode: <select name="mode" bind:value={mode}>
|
||||
<option value="easy">Facile (pour les nuls)</option>
|
||||
<option value="hard">Dur (pour les gigaillards)</option>
|
||||
<option value="extreme demon ultra miguel" selected>
|
||||
EXTREME DEMON ULTRA MIGUEL DE LA MORT QUI TUE
|
||||
</option>
|
||||
</select>
|
||||
- Arrêts:
|
||||
<select name="stops_type" bind:value={stopsType}>
|
||||
<option value="metro" selected>Métro</option>
|
||||
<option value="tram">Tram</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{#if props.data.miguel.length !== 0}
|
||||
<ul>
|
||||
{#each props.data.miguel as game}
|
||||
<li>
|
||||
<b>{game.total_score}</b> points by {game.name} ({game.mode}) -
|
||||
<a href="/results?gameId={game.id}">Details</a>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
{:else}
|
||||
<span>No scores yet :(</span>
|
||||
{/if}
|
||||
<hr />
|
||||
|
||||
<h2>Difficile</h2>
|
||||
{#await leaderboardPromise}
|
||||
<h2>Loading...</h2>
|
||||
{:then games}
|
||||
{#if games.length === 0}
|
||||
<h2>No scores yet :(</h2>
|
||||
{:else}
|
||||
<ul>
|
||||
{#each games as game}
|
||||
<li class:rainbow={game.total_score === 25000}>
|
||||
<b>{game.total_score}</b> points by {game.name} -
|
||||
<a href="/results?gameId={game.id}">Details</a>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
{/if}
|
||||
{/await}
|
||||
|
||||
{#if props.data.hard.length !== 0}
|
||||
<ul>
|
||||
{#each props.data.hard as game}
|
||||
<li>
|
||||
<b>{game.total_score}</b> points by {game.name} ({game.mode}) -
|
||||
<a href="/results?gameId={game.id}">Details</a>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
{:else}
|
||||
<span>No scores yet :(</span>
|
||||
{/if}
|
||||
<style>
|
||||
.rainbow {
|
||||
animation: rainbow 5s linear;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
<h2>Facile</h2>
|
||||
|
||||
{#if props.data.easy.length !== 0}
|
||||
<ul>
|
||||
{#each props.data.easy as game}
|
||||
<li>
|
||||
<b>{game.total_score}</b> points by {game.name} ({game.mode}) -
|
||||
<a href="/results?gameId={game.id}">Details</a>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
{:else}
|
||||
<span>No scores yet :(</span>
|
||||
{/if}
|
||||
@keyframes rainbow {
|
||||
100%,
|
||||
0% {
|
||||
color: rgb(255, 0, 0);
|
||||
}
|
||||
8% {
|
||||
color: rgb(255, 127, 0);
|
||||
}
|
||||
16% {
|
||||
color: rgb(255, 255, 0);
|
||||
}
|
||||
25% {
|
||||
color: rgb(127, 255, 0);
|
||||
}
|
||||
33% {
|
||||
color: rgb(0, 255, 0);
|
||||
}
|
||||
41% {
|
||||
color: rgb(0, 255, 127);
|
||||
}
|
||||
50% {
|
||||
color: rgb(0, 255, 255);
|
||||
}
|
||||
58% {
|
||||
color: rgb(0, 127, 255);
|
||||
}
|
||||
66% {
|
||||
color: rgb(0, 0, 255);
|
||||
}
|
||||
75% {
|
||||
color: rgb(127, 0, 255);
|
||||
}
|
||||
83% {
|
||||
color: rgb(255, 0, 255);
|
||||
}
|
||||
91% {
|
||||
color: rgb(255, 0, 127);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue