You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

55 lines
2.0 KiB
TypeScript

export type LeaderboardRow = {
player: string
score: number
questions: number
successRate: number
durationSec: number
}
const baseUrl = import.meta.env.VITE_API_BASE_URL as string | undefined
const forceApi = import.meta.env.VITE_LEADERBOARD_FORCE_API === 'true'
const STORAGE_MODE_KEY = 'kf.leaderboard.mode'
const fallbackTop10: LeaderboardRow[] = [
{ player: 'Alice', score: 24, questions: 14, successRate: 86, durationSec: 1680 },
{ player: 'Bob', score: 22, questions: 13, successRate: 85, durationSec: 1500 },
{ player: 'Charlie', score: 20, questions: 12, successRate: 83, durationSec: 1800 },
{ player: 'Diana', score: 18, questions: 11, successRate: 82, durationSec: 1320 },
{ player: 'Eve', score: 16, questions: 10, successRate: 80, durationSec: 1620 },
{ player: 'Farah', score: 15, questions: 9, successRate: 78, durationSec: 1730 },
{ player: 'Gino', score: 14, questions: 9, successRate: 74, durationSec: 1780 },
{ player: 'Hugo', score: 13, questions: 8, successRate: 75, durationSec: 1650 },
{ player: 'Ines', score: 12, questions: 8, successRate: 71, durationSec: 1600 },
{ player: 'Jules', score: 11, questions: 7, successRate: 70, durationSec: 1710 },
]
function hasStorage(): boolean {
return typeof window !== 'undefined' && typeof window.localStorage !== 'undefined'
}
function shouldUseMockLeaderboard(): boolean {
if (forceApi) return false
if (hasStorage()) {
const mode = window.localStorage.getItem(STORAGE_MODE_KEY)
if (mode === 'api') return false
if (mode === 'mock') return true
}
return !baseUrl
}
async function json<T>(path: string): Promise<T> {
const url = baseUrl ? `${baseUrl}${path}` : path
const res = await fetch(url)
if (!res.ok) throw new Error(`HTTP ${res.status}`)
return (await res.json()) as T
}
export const leaderboardClient = {
async top10(): Promise<LeaderboardRow[]> {
if (shouldUseMockLeaderboard()) return fallbackTop10
const resp = await json<{ items?: LeaderboardRow[] }>(`/leaderboard/top10`)
return (resp.items ?? []).slice(0, 10)
},
}