AquaDX/AquaNet/src/pages/Ranking.svelte

130 lines
3.3 KiB
Svelte
Raw Normal View History

2024-02-29 13:55:46 +08:00
<script lang="ts">
import { title } from "../libs/ui";
2024-02-29 23:42:22 +08:00
import { GAME } from "../libs/sdk";
import type { GenericRanking } from "../libs/generalTypes";
2024-03-03 08:32:16 +08:00
import StatusOverlays from "../components/StatusOverlays.svelte";
2024-03-15 10:15:10 +08:00
import type { GameName } from "../libs/scoring";
2024-03-15 10:35:36 +08:00
import { GAME_TITLE } from "../libs/i18n";
2024-03-15 10:41:23 +08:00
import { t } from "../libs/i18n";
2024-04-22 22:30:34 +08:00
import UserCard from "../components/UserCard.svelte";
import Tooltip from "../components/Tooltip.svelte";
2024-03-15 10:15:10 +08:00
export let game: GameName = 'mai2';
title(`Ranking`);
let d: { users: GenericRanking[] };
2024-03-03 08:32:16 +08:00
let error: string | null;
2024-03-15 10:15:10 +08:00
Promise.all([GAME.ranking(game)])
.then(([users]) => {
console.log(users)
d = { users };
})
2024-03-03 08:32:16 +08:00
.catch((e) => error = e.message);
2024-04-22 22:30:34 +08:00
let hoveringUser = "";
2024-02-29 13:55:46 +08:00
</script>
2024-03-01 00:07:44 +08:00
<main class="content leaderboard">
2024-03-15 10:35:36 +08:00
<div class="outer-title-options">
2024-03-15 10:41:23 +08:00
<h2>{t("Leaderboard.Title")}</h2>
2024-03-15 10:35:36 +08:00
<nav>
{#each Object.entries(GAME_TITLE) as [k, v]}
<a href="/ranking/{k}" class:active={k === game}>{v}</a>
{/each}
</nav>
</div>
2024-02-29 13:55:46 +08:00
2024-02-29 23:42:22 +08:00
{#if d}
2024-03-01 00:07:44 +08:00
<div class="leaderboard-container">
2024-04-22 22:30:34 +08:00
<div class="lb-user" on:mouseenter={() => hoveringUser = d.users[0].username}>
2024-03-15 10:41:23 +08:00
<span class="rank">{t("Leaderboard.Rank")}</span>
2024-03-01 00:07:44 +08:00
<span class="name"></span>
2024-03-15 10:41:23 +08:00
<span class="rating">{t("Leaderboard.Rating")}</span>
<span class="accuracy">{t("Leaderboard.Accuracy")}</span>
<span class="fc">{t("Leaderboard.FC")}</span>
<span class="ap">{t("Leaderboard.AP")}</span>
2024-02-29 23:42:22 +08:00
</div>
2024-03-01 00:07:44 +08:00
{#each d.users as user, i (user.rank)}
2024-04-22 22:30:34 +08:00
<div class="lb-user" class:alternate={i % 2 === 1} on:mouseover={() => hoveringUser = user.username}>
2024-03-01 00:07:44 +08:00
<span class="rank">#{user.rank}</span>
2024-03-15 10:23:48 +08:00
<span class="name">
{#if user.username !== ""}
2024-03-15 10:59:26 +08:00
<a href="/u/{user.username}/{game}" class:registered={!(/user\d+/.test(user.username))}>{user.name}</a>
2024-03-15 10:23:48 +08:00
{:else}
<span>{user.name}</span>
{/if}
</span>
2024-03-01 00:07:44 +08:00
<span class="rating">{user.rating.toLocaleString()}</span>
<span class="accuracy">{(+user.accuracy).toFixed(2)}%</span>
<span class="fc">{user.fullCombo}</span>
<span class="ap">{user.allPerfect}</span>
</div>
{/each}
</div>
2024-04-22 22:30:34 +08:00
<Tooltip triggeredBy=".name">
<UserCard username={hoveringUser} {game} />
</Tooltip>
2024-02-29 23:42:22 +08:00
{/if}
2024-03-03 08:32:16 +08:00
<StatusOverlays error={error} loading={!d} />
2024-03-01 00:07:44 +08:00
</main>
<style lang="sass">
@import "../vars"
.leaderboard-container
display: flex
flex-direction: column
.lb-user
display: flex
align-items: center
justify-content: space-between
width: 100%
gap: 12px
2024-03-06 08:19:05 +08:00
border-radius: $border-radius
2024-03-01 00:07:44 +08:00
padding: 6px 12px
box-sizing: border-box
> *:not(.name)
text-align: center
.name
min-width: 100px
flex: 1
2024-03-15 10:23:48 +08:00
> a
color: unset
.registered
background: $grad-special
color: transparent
-webkit-background-clip: text
background-clip: text
2024-03-01 00:07:44 +08:00
.accuracy, .rating
width: 15%
min-width: 45px
.rating
font-weight: bold
color: white
.fc, .ap
width: 5%
min-width: 20px
@media (max-width: $w-mobile)
font-size: 0.9rem
.accuracy
display: none
&.alternate
background-color: $ov-light
2024-03-01 14:37:59 +08:00
2024-03-06 08:19:05 +08:00
</style>