first commit

This commit is contained in:
2026-08-07 09:40:16 +03:30
commit 0c51b30059
37 changed files with 5146 additions and 0 deletions
+88
View File
@@ -0,0 +1,88 @@
"use client";
import { useEffect, useState } from "react";
import Shell from "@/components/Shell";
import EditableTable, { Col } from "@/components/EditableTable";
import { api } from "@/lib/api";
type Row = Record<string, unknown>;
const COLS: Col[] = [
{ key: "id", label: "شناسه" },
{ key: "title", label: "عنوان" },
{ key: "price_coins", label: "قیمت (سکه)", type: "number" },
{ key: "vip", label: "VIP رایگان", type: "bool" },
{ key: "c1", label: "رنگ ۱ (hex)" },
{ key: "c2", label: "رنگ ۲ (hex)" },
{ key: "sort", label: "ترتیب", type: "number" },
{ key: "enabled", label: "فعال", type: "bool" },
];
const hex = (s: unknown) => {
const v = String(s || "").replace("#", "").trim();
return /^[0-9a-fA-F]{6}$/.test(v) ? `#${v}` : null;
};
function FramePreview({ row }: { row: Record<string, unknown> }) {
const a = hex(row.c1);
const b = hex(row.c2);
if (!a || !b) {
return <span className="text-[#8aa] text-xs">رتبه</span>;
}
return (
<div
style={{
width: 34,
height: 34,
borderRadius: "50%",
background: `linear-gradient(160deg, ${a}, ${b})`,
border: "1px solid #1e3a63",
}}
/>
);
}
export default function FramesPage() {
const [rows, setRows] = useState<Row[]>([]);
async function load() {
const r = await api.get<{ frames: Row[] }>("/frames");
setRows(r.frames || []);
}
useEffect(() => {
load();
}, []);
return (
<Shell title="قاب‌ها">
<p className="text-sm text-[#8aa] mb-4">
قابِ آواتار (کازمتیک). رنگِ گرادیان را با دو کدِ hex (مثلِ <code>F3D27A</code>) تعیین
کنید؛ قابِ جدید بدونِ بهروزرسانیِ اپ در بازی دیده میشود. شناسهٔ <code>none</code> = قابِ رتبه.
</p>
<EditableTable
cols={COLS}
rows={rows}
newTemplate={{
id: "",
title: "",
price_coins: 0,
vip: false,
c1: "",
c2: "",
sort: 0,
enabled: true,
}}
onSave={async (row) => {
await api.post("/frames", row);
await load();
}}
onDelete={async (id) => {
if (!confirm("حذف قاب؟")) return;
await api.del(`/frames?id=${encodeURIComponent(id)}`);
await load();
}}
preview={(row) => <FramePreview row={row} />}
/>
</Shell>
);
}