66 lines
1.5 KiB
TypeScript
66 lines
1.5 KiB
TypeScript
"use client";
|
|
|
|
import { useList } from "@/lib/useResource";
|
|
import { DataTable, type Column } from "@/components/DataTable";
|
|
import { PageHeader } from "@/components/ui";
|
|
import { toFa } from "@/lib/utils";
|
|
|
|
interface LeaderboardEntry {
|
|
id?: number;
|
|
rank?: number;
|
|
name?: string;
|
|
username?: string;
|
|
score?: number;
|
|
points?: number;
|
|
user?: {
|
|
name?: string;
|
|
};
|
|
}
|
|
|
|
export default function LeaderboardPage() {
|
|
const { data, loading, error, reload } =
|
|
useList<LeaderboardEntry>("/leader-board");
|
|
|
|
const columns: Column<LeaderboardEntry>[] = [
|
|
{
|
|
key: "rank",
|
|
header: "رتبه",
|
|
className: "w-20",
|
|
render: (r) =>
|
|
r.rank != null ? toFa(r.rank) : toFa(data.indexOf(r) + 1),
|
|
},
|
|
{
|
|
key: "user",
|
|
header: "کاربر",
|
|
render: (r) => r.user?.name ?? r.name ?? r.username ?? "—",
|
|
},
|
|
{
|
|
key: "score",
|
|
header: "امتیاز",
|
|
render: (r) => {
|
|
const value = r.score ?? r.points;
|
|
return value != null ? toFa(value) : "—";
|
|
},
|
|
},
|
|
];
|
|
|
|
return (
|
|
<div>
|
|
<PageHeader
|
|
title="جدول امتیازات"
|
|
subtitle="رتبهبندی کاربران بر اساس امتیاز"
|
|
/>
|
|
|
|
<DataTable
|
|
columns={columns}
|
|
rows={data}
|
|
loading={loading}
|
|
error={error}
|
|
onRetry={reload}
|
|
emptyTitle="جدول خالی است"
|
|
emptyMessage="هنوز امتیازی ثبت نشده است."
|
|
/>
|
|
</div>
|
|
);
|
|
}
|