"use client"; import { useEffect, useState } from "react"; import Link from "next/link"; import { useForm } from "react-hook-form"; import { z } from "zod"; import { zodResolver } from "@hookform/resolvers/zod"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { toast } from "sonner"; import { CheckCircle2, Circle, X, Download, Eye } from "lucide-react"; import { accountingApi, type CoaTemplate } from "@/lib/accounting-api"; import { useTenantId } from "@/hooks/useTenantId"; import { PageHeader, Button, Card, CardContent, CardHeader, CardTitle, Badge, LoadingState, ErrorState, Dialog, Input, Label, FieldError, DataTable, EmptyState, } from "@/components/ds"; import { CompletionScoreboard } from "@/components/accounting/CompletionScoreboard"; const TOUR_KEY = "accounting-setup-tour-dismissed"; const importSchema = z.object({ chart_name: z.string().min(1, "نام دفتر الزامی است"), chart_code: z.string().min(1, "کد دفتر الزامی است"), }); type SetupStep = { key: keyof typeof STEP_LINKS; label: string; done: boolean; }; const STEP_LINKS = { has_chart: { href: "/accounting/chart-of-accounts", label: "دفتر حساب‌ها" }, has_accounts: { href: "/accounting/chart-of-accounts", label: "حساب‌ها" }, has_currency: { href: "/accounting/currencies", label: "ارزها" }, has_base_currency: { href: "/accounting/currencies", label: "ارز پایه" }, has_fiscal_year: { href: "/accounting/fiscal", label: "سال مالی" }, has_fiscal_period: { href: "/accounting/fiscal", label: "دوره مالی" }, has_cash_box: { href: "/accounting/treasury/cash-boxes", label: "صندوق" }, has_customer: { href: "/accounting/customers", label: "مشتری" }, has_voucher: { href: "/accounting/vouchers", label: "سند حسابداری" }, } as const; export default function SetupPage() { const { tenantId } = useTenantId(); const qc = useQueryClient(); const [showTour, setShowTour] = useState(false); const [previewTemplate, setPreviewTemplate] = useState(null); const [importTemplate, setImportTemplate] = useState(null); useEffect(() => { if (typeof window === "undefined") return; setShowTour(localStorage.getItem(TOUR_KEY) !== "1"); }, []); const dismissTour = () => { localStorage.setItem(TOUR_KEY, "1"); setShowTour(false); }; const statusQ = useQuery({ queryKey: ["accounting", tenantId, "setup-status"], queryFn: () => accountingApi.setup.status(tenantId!), enabled: !!tenantId, }); const templatesQ = useQuery({ queryKey: ["accounting", tenantId, "coa-templates"], queryFn: () => accountingApi.templates.list(tenantId!), enabled: !!tenantId, }); const importForm = useForm>({ resolver: zodResolver(importSchema), defaultValues: { chart_name: "", chart_code: "" }, }); const importM = useMutation({ mutationFn: (d: z.infer) => accountingApi.templates.import(tenantId!, importTemplate!.id, d), onSuccess: async (accounts) => { toast.success(`${accounts.length} حساب از قالب وارد شد`); setImportTemplate(null); importForm.reset(); await qc.invalidateQueries({ queryKey: ["accounting", tenantId, "setup-status"] }); await qc.invalidateQueries({ queryKey: ["accounting", tenantId, "charts"] }); await qc.invalidateQueries({ queryKey: ["accounting", tenantId, "accounts"] }); }, onError: (e: Error) => toast.error(e.message), }); if (!tenantId || statusQ.isLoading) return ; if (statusQ.error) { return statusQ.refetch()} />; } const s = statusQ.data!; const steps: SetupStep[] = [ { key: "has_chart", label: "ایجاد دفتر حساب", done: s.has_chart }, { key: "has_accounts", label: "تعریف حساب‌ها", done: s.has_accounts }, { key: "has_currency", label: "تعریف ارز", done: s.has_currency }, { key: "has_base_currency", label: "تعیین ارز پایه", done: s.has_base_currency }, { key: "has_fiscal_year", label: "سال مالی", done: s.has_fiscal_year }, { key: "has_fiscal_period", label: "دوره مالی", done: s.has_fiscal_period }, { key: "has_cash_box", label: "صندوق خزانه", done: s.has_cash_box }, { key: "has_customer", label: "مشتری", done: s.has_customer }, { key: "has_voucher", label: "اولین سند", done: s.has_voucher }, ]; return (
= 100 ? "success" : "primary"}>{s.percent}٪ } /> {showTour ? (

به ماژول حسابداری خوش آمدید

این چک‌لیست مراحل اولیه را نشان می‌دهد. می‌توانید از قالب آماده دفتر حساب وارد کنید یا هر مرحله را از منو تکمیل کنید.

) : null}
چک‌لیست راه‌اندازی {steps.map((step) => { const link = STEP_LINKS[step.key]; return ( {step.done ? ( ) : ( )} {step.label} {step.done ? "انجام شد" : "باقی‌مانده"} ); })}
ویزارد قالب دفتر حساب (COA) {templatesQ.isLoading ? ( ) : templatesQ.error ? ( templatesQ.refetch()} /> ) : !(templatesQ.data ?? []).length ? ( ) : (
{(templatesQ.data ?? []).map((t) => (

{t.name}

{t.description}

{t.accounts.length} حساب · {t.business_type}

))}
)}
setPreviewTemplate(null)} title={previewTemplate?.name ?? "پیش‌نمایش قالب"} > {previewTemplate ? ( (r.is_postable ? "بله" : "خیر"), }, ]} rows={previewTemplate.accounts as unknown as Record[]} /> ) : null} setImportTemplate(null)} title="وارد کردن قالب">
importM.mutate(d))} >

قالب «{importTemplate?.name}» — {importTemplate?.accounts.length} حساب

{importForm.formState.errors.chart_name?.message}
{importForm.formState.errors.chart_code?.message}
); }