Files
MineGeo/shared/leaderboard.ts
pavel444-byte a7085e4e80
Some checks failed
Deploy MineGeo to Dokploy / deploy (push) Failing after 2m37s
Improve MineGeo UI and application flows
2026-10-18 11:44:04 +05:00

62 lines
1.7 KiB
TypeScript

export const leaderboardDifficulties = [
"all",
"easy",
"normal",
"hard",
] as const;
export type LeaderboardDifficulty = (typeof leaderboardDifficulties)[number];
export type LeaderboardEntry =
import("./profile-appearance").ProfileAppearance & {
rank: number;
player_id: string;
display_name: string;
name_glow?: boolean;
best_score: number;
average_score: number;
games_played: number;
tournament_champion?: {
tournament_id: string;
name: string;
expires_at: string;
} | null;
};
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");