Add player leaderboard and homepage preview
This commit is contained in:
54
shared/leaderboard.ts
Normal file
54
shared/leaderboard.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
export const leaderboardDifficulties = [
|
||||
"all",
|
||||
"easy",
|
||||
"normal",
|
||||
"hard",
|
||||
] as const;
|
||||
export type LeaderboardDifficulty = (typeof leaderboardDifficulties)[number];
|
||||
export type LeaderboardEntry = {
|
||||
rank: number;
|
||||
player_id: string;
|
||||
display_name: string;
|
||||
best_score: number;
|
||||
average_score: number;
|
||||
games_played: number;
|
||||
};
|
||||
export type LeaderboardData = {
|
||||
entries: LeaderboardEntry[];
|
||||
leaders: LeaderboardEntry[];
|
||||
total_players: number;
|
||||
total_games: number;
|
||||
matching_players: number;
|
||||
page: number;
|
||||
pages: number;
|
||||
};
|
||||
|
||||
export function leaderboardFilters(
|
||||
params: Record<string, string | string[] | undefined>,
|
||||
) {
|
||||
const difficulty =
|
||||
leaderboardDifficulties.find((value) => value === params.difficulty) ??
|
||||
"all";
|
||||
const search =
|
||||
typeof params.q === "string" ? params.q.trim().slice(0, 64) : "";
|
||||
const rawPage = typeof params.page === "string" ? Number(params.page) : 1;
|
||||
const page =
|
||||
Number.isSafeInteger(rawPage) && rawPage > 0
|
||||
? Math.min(rawPage, 1_000_000)
|
||||
: 1;
|
||||
return { difficulty, search, page };
|
||||
}
|
||||
|
||||
export function leaderboardHref(
|
||||
difficulty: LeaderboardDifficulty,
|
||||
search = "",
|
||||
page = 1,
|
||||
) {
|
||||
const params = new URLSearchParams();
|
||||
if (difficulty !== "all") params.set("difficulty", difficulty);
|
||||
if (search) params.set("q", search);
|
||||
if (page > 1) params.set("page", String(page));
|
||||
return `/leaderboard${params.size ? `?${params}` : ""}`;
|
||||
}
|
||||
|
||||
export const formatScore = (score: number) => score.toLocaleString("en-US");
|
||||
Reference in New Issue
Block a user