TorbatYar/frontend/app/accounting/settings/company/page.tsx
Mortezakoohjani 320d9cd547 Replace opaque company settings form with a real company profile page.
Users now fill legal name, national ID, economic code, address and contacts instead of generic setting key/value ops documents.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-26 18:37:50 +03:30

180 lines
6.6 KiB
TypeScript
Raw 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 } from "react";
import { useForm } from "react-hook-form";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { accountingApi } from "@/lib/accounting-api";
import { useTenantId } from "@/hooks/useTenantId";
import {
PageHeader,
LoadingState,
ErrorState,
Card,
CardContent,
CardHeader,
CardTitle,
Button,
Input,
FormField,
} from "@/components/ds";
type CompanyForm = {
legal_name: string;
trade_name: string;
national_id: string;
economic_code: string;
registration_number: string;
postal_code: string;
province: string;
city: string;
address: string;
phone: string;
mobile: string;
email: string;
website: string;
ceo_name: string;
accountant_name: string;
};
const EMPTY: CompanyForm = {
legal_name: "",
trade_name: "",
national_id: "",
economic_code: "",
registration_number: "",
postal_code: "",
province: "",
city: "",
address: "",
phone: "",
mobile: "",
email: "",
website: "",
ceo_name: "",
accountant_name: "",
};
export default function CompanySettingsPage() {
const { tenantId } = useTenantId();
const qc = useQueryClient();
const form = useForm<CompanyForm>({ defaultValues: EMPTY });
const profileQ = useQuery({
queryKey: ["accounting", tenantId, "company-profile"],
queryFn: () => accountingApi.setup.getCompanyProfile(tenantId!),
enabled: !!tenantId,
});
useEffect(() => {
if (profileQ.data) {
form.reset({ ...EMPTY, ...profileQ.data });
}
}, [profileQ.data, form]);
const saveM = useMutation({
mutationFn: (data: CompanyForm) => accountingApi.setup.updateCompanyProfile(tenantId!, data),
onSuccess: async () => {
toast.success("اطلاعات شرکت ذخیره شد");
await qc.invalidateQueries({ queryKey: ["accounting", tenantId, "company-profile"] });
},
onError: (e: Error) => toast.error(e.message),
});
if (!tenantId || profileQ.isLoading) return <LoadingState />;
if (profileQ.error) {
return <ErrorState message={profileQ.error.message} onRetry={() => profileQ.refetch()} />;
}
return (
<div>
<PageHeader
title="اطلاعات شرکت"
description="مشخصات حقوقی و تماس شرکت برای چاپ اسناد، گزارش‌ها و اظهارنامه‌ها. فقط فیلدهایی که دارید را پر کنید."
/>
<form className="space-y-6" onSubmit={form.handleSubmit((d) => saveM.mutate(d))}>
<Card>
<CardHeader>
<CardTitle>هویت حقوقی</CardTitle>
</CardHeader>
<CardContent className="grid gap-4 sm:grid-cols-2">
<FormField label="نام قانونی شرکت" hint="همان نام ثبت‌شده در روزنامه رسمی">
<Input placeholder="مثال: شرکت بازرگانی آفتاب سپاهان" {...form.register("legal_name")} />
</FormField>
<FormField label="نام تجاری / برند" hint="اگر با نام قانونی فرق دارد">
<Input placeholder="مثال: آفتاب‌مارکت" {...form.register("trade_name")} />
</FormField>
<FormField label="شناسه ملی" hint="۱۱ رقم برای اشخاص حقوقی">
<Input dir="ltr" placeholder="1400xxxxxxx" {...form.register("national_id")} />
</FormField>
<FormField label="کد اقتصادی" hint="برای فاکتور رسمی و مالیات">
<Input dir="ltr" placeholder="کد اقتصادی" {...form.register("economic_code")} />
</FormField>
<FormField label="شماره ثبت" hint="شماره ثبت در اداره ثبت شرکت‌ها">
<Input dir="ltr" placeholder="مثال: ۱۲۳۴۵۶" {...form.register("registration_number")} />
</FormField>
<FormField label="کد پستی" hint="۱۰ رقم">
<Input dir="ltr" placeholder="xxxxxxxxxx" {...form.register("postal_code")} />
</FormField>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>آدرس و تماس</CardTitle>
</CardHeader>
<CardContent className="grid gap-4 sm:grid-cols-2">
<FormField label="استان">
<Input placeholder="مثال: خراسان رضوی" {...form.register("province")} />
</FormField>
<FormField label="شهر">
<Input placeholder="مثال: تربت حیدریه" {...form.register("city")} />
</FormField>
<div className="sm:col-span-2">
<FormField label="آدرس کامل">
<Input placeholder="خیابان، پلاک، واحد…" {...form.register("address")} />
</FormField>
</div>
<FormField label="تلفن ثابت">
<Input dir="ltr" placeholder="051-xxxxx" {...form.register("phone")} />
</FormField>
<FormField label="موبایل">
<Input dir="ltr" placeholder="09xxxxxxxxx" {...form.register("mobile")} />
</FormField>
<FormField label="ایمیل">
<Input dir="ltr" type="email" placeholder="info@example.com" {...form.register("email")} />
</FormField>
<FormField label="وب‌سایت">
<Input dir="ltr" placeholder="https://…" {...form.register("website")} />
</FormField>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>اشخاص مرتبط (اختیاری)</CardTitle>
</CardHeader>
<CardContent className="grid gap-4 sm:grid-cols-2">
<FormField label="نام مدیرعامل / مدیر مسئول">
<Input {...form.register("ceo_name")} />
</FormField>
<FormField label="نام حسابدار مسئول">
<Input {...form.register("accountant_name")} />
</FormField>
</CardContent>
</Card>
<div className="flex flex-wrap justify-end gap-2">
<Button type="button" variant="outline" disabled={saveM.isPending} onClick={() => profileQ.refetch()}>
بازخوانی
</Button>
<Button type="submit" disabled={saveM.isPending}>
ذخیره اطلاعات شرکت
</Button>
</div>
</form>
</div>
);
}