Files
2026-08-07 09:40:16 +03:30

152 lines
4.2 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { useEffect, useState } from "react";
import Shell from "@/components/Shell";
import { TableSkeleton } from "@/components/Skeleton";
import { api } from "@/lib/api";
import { toastError } from "@/lib/toast";
type Tier = {
id: string;
label: string;
c1: string;
c2: string;
sort: number;
};
const hex = (s: string) => {
const v = String(s || "").replace("#", "").trim();
return /^[0-9a-fA-F]{6}$/.test(v) ? `#${v}` : null;
};
function Swatch({ c1, c2 }: { c1: string; c2: string }) {
const a = hex(c1);
const b = hex(c2);
return (
<div
style={{
width: 40,
height: 40,
borderRadius: "50%",
background:
a && b ? `linear-gradient(160deg, ${a}, ${b})` : "#16305a",
border: "1px solid #1e3a63",
}}
/>
);
}
export default function RankTiersPage() {
const [tiers, setTiers] = useState<Tier[]>([]);
const [busy, setBusy] = useState<string | null>(null);
const [loading, setLoading] = useState(true);
async function load() {
setLoading(true);
try {
const r = await api.get<{ rank_tiers: Tier[] }>("/rank-tiers");
setTiers(r.rank_tiers || []);
} finally {
setLoading(false);
}
}
useEffect(() => {
load();
}, []);
const patch = (id: string, key: keyof Tier, val: string | number) =>
setTiers((ts) => ts.map((t) => (t.id === id ? { ...t, [key]: val } : t)));
async function save(t: Tier) {
setBusy(t.id);
try {
await api.post("/rank-tiers", t);
} catch (e) {
toastError((e as Error).message);
} finally {
setBusy(null);
}
}
return (
<Shell title="رتبه‌ها">
<p className="text-sm text-[#8aa] mb-4">
رنگ و برچسبِ رتبه‌ها (برنز تا پادشاه). این‌ها در حلقه‌ی آواتار و نشانِ
رتبه‌ی داخلِ بازی دیده می‌شوند و بدونِ به‌روزرسانیِ اپ اعمال می‌شوند.
رنگ را با کدِ hex (مثلِ <code>FFD54F</code>) وارد کنید.
</p>
{loading ? (
<TableSkeleton rows={5} cols={7} />
) : (
<div className="card overflow-x-auto">
<table>
<thead>
<tr>
<th>پیش‌نمایش</th>
<th>شناسه</th>
<th>برچسب</th>
<th>رنگ ۱ (hex)</th>
<th>رنگ ۲ (hex)</th>
<th>ترتیب</th>
<th></th>
</tr>
</thead>
<tbody>
{tiers.map((t) => (
<tr key={t.id}>
<td>
<Swatch c1={t.c1} c2={t.c2} />
</td>
<td className="text-[#8aa]">{t.id}</td>
<td>
<input
className="inp"
style={{ minWidth: 90 }}
value={t.label}
onChange={(e) => patch(t.id, "label", e.target.value)}
/>
</td>
<td>
<input
className="inp"
style={{ minWidth: 90 }}
value={t.c1}
onChange={(e) => patch(t.id, "c1", e.target.value)}
/>
</td>
<td>
<input
className="inp"
style={{ minWidth: 90 }}
value={t.c2}
onChange={(e) => patch(t.id, "c2", e.target.value)}
/>
</td>
<td>
<input
className="inp"
style={{ minWidth: 60 }}
type="number"
value={t.sort}
onChange={(e) => patch(t.id, "sort", +e.target.value)}
/>
</td>
<td>
<button
className="btn btn-gold"
disabled={busy === t.id}
onClick={() => save(t)}
>
ذخیره
</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
)}
</Shell>
);
}