import { useState } from 'react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { TrashIcon, PlusIcon, PencilIcon } from '@heroicons/react/24/outline'; import { toast } from 'sonner'; import { api } from '../lib/api'; import { formatRial, rialToToman, tomanToRial } from '../lib/utils'; import SearchableSelect from './ui/SearchableSelect'; interface Contract { uuid: string; insurance_id: number; insurance_name: string | null; insurance_kind: string | null; version: number; coverage_percent: number; franchise_rials: number; annual_ceiling_rials: number | null; } interface InsuranceOption { insurance_id: number; insurance_name: string; type: string; } const KIND_LABEL: Record = { basic: 'پایه', supplementary: 'تکمیلی', }; export default function TenantInsuranceContracts() { const qc = useQueryClient(); const [addOpen, setAddOpen] = useState(false); const [editUuid, setEditUuid] = useState(null); const [insuranceId, setInsuranceId] = useState(''); const [coverage, setCoverage] = useState(''); const [franchise, setFranchise] = useState(''); const [ceiling, setCeiling] = useState(''); const contractsQuery = useQuery<{ data: Contract[] }>({ queryKey: ['tenant-insurances'], queryFn: () => api.get('/api/v1/billing/tenant-insurances'), }); const pricingQuery = useQuery<{ data: { insurances: InsuranceOption[] } }>({ queryKey: ['insurance-pricing'], queryFn: () => api.get('/api/v1/insurance-pricing'), }); const contracts = (contractsQuery.data as any)?.data?.data ?? []; const allInsurances: InsuranceOption[] = (pricingQuery.data as any)?.data?.insurances ?? []; const activeIds = new Set(contracts.map((c: Contract) => c.insurance_id)); const available = allInsurances.filter((i) => !activeIds.has(i.insurance_id)); const resetForm = () => { setInsuranceId(''); setCoverage(''); setFranchise(''); setCeiling(''); setAddOpen(false); setEditUuid(null); }; const openEdit = (c: Contract) => { setEditUuid(c.uuid); setAddOpen(false); setInsuranceId(String(c.insurance_id)); setCoverage(String(c.coverage_percent ?? '')); setFranchise(c.franchise_rials != null ? String(rialToToman(c.franchise_rials)) : ''); setCeiling(c.annual_ceiling_rials != null ? String(rialToToman(c.annual_ceiling_rials)) : ''); }; const editMut = useMutation({ mutationFn: () => api.patch(`/api/v1/billing/tenant-insurances/${editUuid}`, { coverage_percent: Number(coverage) || 0, franchise_rials: tomanToRial(Number(franchise) || 0), annual_ceiling_rials: ceiling === '' ? null : tomanToRial(Number(ceiling)), }), onSuccess: () => { toast.success('قرارداد بیمه ویرایش شد'); resetForm(); qc.invalidateQueries({ queryKey: ['tenant-insurances'] }); }, onError: (e: Error) => toast.error(e.message), }); const addMut = useMutation({ mutationFn: () => api.post('/api/v1/billing/tenant-insurances', { insurance_id: Number(insuranceId), coverage_percent: Number(coverage) || 0, franchise_rials: tomanToRial(Number(franchise) || 0), annual_ceiling_rials: ceiling === '' ? null : tomanToRial(Number(ceiling)), }), onSuccess: () => { toast.success('قرارداد بیمه فعال شد'); resetForm(); qc.invalidateQueries({ queryKey: ['tenant-insurances'] }); }, onError: (e: Error) => toast.error(e.message), }); const delMut = useMutation({ mutationFn: (uuid: string) => api.delete(`/api/v1/billing/tenant-insurances/${uuid}`), onSuccess: () => { toast.success('قرارداد غیرفعال شد'); qc.invalidateQueries({ queryKey: ['tenant-insurances'] }); }, onError: (e: Error) => toast.error(e.message), }); return (

قراردادهای بیمه

بیمه‌هایی که با آن‌ها قرارداد دارید. درصد پوشش، فرانشیز و سقف تعهد هر بیمه را تعیین کنید.

{!addOpen && available.length > 0 && ( )}
{(addOpen || editUuid) && (
({ value: String(i.insurance_id), label: `${i.insurance_name} (${KIND_LABEL[i.type] ?? i.type})` }))} value={insuranceId} onChange={(v) => setInsuranceId(v ? String(v) : '')} isDisabled={!!editUuid} placeholder="انتخاب..." />
setCoverage(e.target.value)} />
setFranchise(e.target.value)} />
setCeiling(e.target.value)} />
)} {contractsQuery.isLoading ? (
در حال بارگذاری...
) : contracts.length === 0 ? (
هنوز با هیچ بیمه‌ای قرارداد فعال ندارید.
) : (
{(['basic', 'supplementary'] as const).map((kind) => { const group = contracts.filter((c: Contract) => c.insurance_kind === kind); if (group.length === 0) return null; return (
بیمه {KIND_LABEL[kind]}
{group.map((c: Contract) => (
{c.insurance_name ?? `#${c.insurance_id}`}
پوشش {c.coverage_percent}٪ {c.franchise_rials > 0 && ` · فرانشیز ${formatRial(c.franchise_rials)}`} {c.annual_ceiling_rials != null && ` · سقف ${formatRial(c.annual_ceiling_rials)}`}
))}
); })}
)}
); }