Adds accounting-service PATCH/archive, fiscal helpers, COA templates and setup status, plus SuperApp Accounting UI (DS, scoreboard, masters, vouchers, ledger, ops modules) with session refresh and HTTPS public API URLs. Co-authored-by: Cursor <cursoragent@cursor.com>
71 lines
2.7 KiB
TypeScript
71 lines
2.7 KiB
TypeScript
"use client";
|
||
|
||
import Link from "next/link";
|
||
import { ACCOUNTING_MODULE_SCORES, overallCompletionPercent, type ScoreState } from "@/lib/accounting-scoreboard";
|
||
import { Badge, Card, CardContent, CardHeader, CardTitle } from "@/components/ds";
|
||
import { cn } from "@/lib/utils";
|
||
|
||
const tone: Record<ScoreState, "success" | "warning" | "danger" | "default"> = {
|
||
complete: "success",
|
||
partial: "warning",
|
||
missing: "danger",
|
||
blocked: "default",
|
||
};
|
||
|
||
const labelFa: Record<ScoreState, string> = {
|
||
complete: "کامل",
|
||
partial: "جزئی",
|
||
missing: "ناقص",
|
||
blocked: "مسدود",
|
||
};
|
||
|
||
export function CompletionScoreboard({ compact = false }: { compact?: boolean }) {
|
||
const overall = overallCompletionPercent();
|
||
const rows = compact ? ACCOUNTING_MODULE_SCORES.filter((s) => s.state !== "blocked").slice(0, 8) : ACCOUNTING_MODULE_SCORES;
|
||
|
||
return (
|
||
<Card>
|
||
<CardHeader className="flex flex-row items-center justify-between gap-3">
|
||
<div>
|
||
<CardTitle>میزان تکمیل ماژول حسابداری</CardTitle>
|
||
<p className="mt-1 text-xs text-[var(--muted)]">Scoreboard دائمی — بدون mock</p>
|
||
</div>
|
||
<Badge tone={overall >= 90 ? "success" : "primary"}>{overall}٪</Badge>
|
||
</CardHeader>
|
||
<CardContent className="space-y-2">
|
||
{rows.map((m) => (
|
||
<Link
|
||
key={m.id}
|
||
href={m.href}
|
||
className="flex items-center gap-3 rounded-xl px-2 py-2 hover:bg-[var(--surface-muted)]"
|
||
>
|
||
<div className="min-w-0 flex-1">
|
||
<div className="flex items-center justify-between gap-2">
|
||
<span className="truncate text-sm font-medium text-secondary">{m.label}</span>
|
||
<Badge tone={tone[m.state]}>{labelFa[m.state]}</Badge>
|
||
</div>
|
||
<div className="mt-1.5 h-1.5 overflow-hidden rounded-full bg-[var(--surface-muted)]">
|
||
<div
|
||
className={cn(
|
||
"h-full rounded-full",
|
||
m.state === "blocked" ? "bg-[var(--muted)]" : "bg-primary"
|
||
)}
|
||
style={{ width: `${m.percent}%` }}
|
||
/>
|
||
</div>
|
||
</div>
|
||
<span className="w-10 text-left text-xs tabular-nums text-[var(--muted)]" dir="ltr">
|
||
{m.percent}%
|
||
</span>
|
||
</Link>
|
||
))}
|
||
{compact ? (
|
||
<Link href="/accounting/setup" className="block pt-2 text-xs font-medium text-primary hover:underline">
|
||
راهاندازی و مشاهده همه ماژولها
|
||
</Link>
|
||
) : null}
|
||
</CardContent>
|
||
</Card>
|
||
);
|
||
}
|