3d-arena / src /routes /Leaderboard.svelte
dylanebert's picture
dylanebert HF staff
vote layout
c99cc8d
raw
history blame
2 kB
<script lang="ts">
import { onMount } from "svelte";
import { ProgressBarRound } from "carbon-icons-svelte";
interface Entry {
name: string;
rank: number;
score: number;
votes: number;
}
export let onEntryClick: (entry: Entry) => void;
const baseUrl = "https://huggingface.co/datasets/dylanebert/3d-arena/resolve/main/outputs";
let leaderboard: Entry[] = [];
const fetchLeaderboardData = async () => {
const url = "https://dylanebert-3d-arena-backend.hf.space/leaderboard";
const response = await fetch(url, {
method: "GET",
headers: {
Authorization: "Bearer " + import.meta.env.VITE_HF_TOKEN,
"Cache-Control": "no-cache",
},
});
const data = (await response.json()) as Entry[];
data.sort((a, b) => a.rank - b.rank);
leaderboard = data;
};
onMount(async () => {
await fetchLeaderboardData();
});
</script>
{#if leaderboard.length > 0}
<div class="grid">
{#each leaderboard as entry}
<button class="grid-item" on:click={() => onEntryClick(entry)}>
<img src={`${baseUrl}/${entry.name}/thumbnail.png`} alt={entry.name} class="thumbnail" />
<div class="ranking">{entry.rank}</div>
<div class="title">{entry.name}</div>
<div class="score-container">
<div class="score">
<span class="label">Score:</span>
{entry.score}
</div>
<div class="votes">
<span class="label">Votes:</span>
{entry.votes}
</div>
</div>
</button>
{/each}
</div>
{:else}
<div class="loading-container">
<ProgressBarRound class="loading-icon" />
<div class="loading-text">Loading...</div>
</div>
{/if}