import { useEffect, useState } from 'react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { ShieldCheckIcon, CheckIcon } from '@heroicons/react/24/outline'; import { toast } from 'sonner'; import { api } from '../lib/api'; import Modal from './ui/Modal'; import PriceInput from './ui/PriceInput'; import type { ServiceItem } from '../types'; interface TenantInsurance { uuid: string; insurance_name: string | null; insurance_kind: 'basic' | 'supplementary' | null; coverage_percent: number; } interface CoverageRow { service_item_uuid: string | null; covered: boolean; coverage_percent: number | null; franchise_rials: number | null; ceiling_rials: number | null; } interface Draft { covered: boolean; coverage_percent: number | null; franchise_rials: number | null; ceiling_rials: number | null; } const KIND = { basic: { label: 'پایه', cls: 'blue' }, supplementary: { label: 'تکمیلی', cls: 'violet' }, } as const; function ContractCard({ contract, item }: { contract: TenantInsurance; item: ServiceItem }) { const qc = useQueryClient(); const { data, isLoading } = useQuery<{ data: { data: CoverageRow[] } }>({ queryKey: ['service-coverage', contract.uuid], queryFn: () => api.get(`/api/v1/billing/tenant-insurances/${contract.uuid}/service-coverage`), }); const rows = (data as any)?.data?.data as CoverageRow[] | undefined; const existing = rows?.find((r) => r.service_item_uuid === item.uuid); const [draft, setDraft] = useState({ covered: true, coverage_percent: null, franchise_rials: null, ceiling_rials: null }); useEffect(() => { setDraft(existing ? { covered: existing.covered, coverage_percent: existing.coverage_percent, franchise_rials: existing.franchise_rials, ceiling_rials: existing.ceiling_rials, } : { covered: true, coverage_percent: null, franchise_rials: null, ceiling_rials: null }); }, [existing]); const saveMut = useMutation({ mutationFn: () => api.put(`/api/v1/billing/tenant-insurances/${contract.uuid}/service-coverage`, { service_item_uuid: item.uuid, covered: draft.covered, coverage_percent: draft.coverage_percent, franchise_rials: draft.franchise_rials, ceiling_rials: draft.ceiling_rials, }), onSuccess: () => { toast.success('پوشش بیمه ذخیره شد'); qc.invalidateQueries({ queryKey: ['service-coverage', contract.uuid] }); }, onError: (e: Error) => toast.error(e.message), }); const kind = contract.insurance_kind ? KIND[contract.insurance_kind] : null; return (
{/* سربرگ کارت */}
{contract.insurance_name ?? 'بیمه'} {kind && {kind.label}} {existing && ( تنظیم‌شده )}
پوشش پیش‌فرض قرارداد: {contract.coverage_percent}٪
{/* بدنه — فقط وقتی پوشش فعال است */} {draft.covered && (
{isLoading ? (
در حال بارگذاری...
) : ( <>
setDraft((d) => ({ ...d, coverage_percent: e.target.value === '' ? null : Number(e.target.value) }))} />
setDraft((d) => ({ ...d, franchise_rials: v || null }))} placeholder="۰" min={0} />
setDraft((d) => ({ ...d, ceiling_rials: v || null }))} placeholder="بدون سقف" min={0} />
مقدار خالی از قرارداد بیمه ارث می‌برد
)}
)} {/* وقتی پوشش غیرفعال است — یک خط ذخیره */} {!draft.covered && !isLoading && (
این خدمت تحت این بیمه پوشش ندارد
)}
); } export default function ServiceInsuranceModal({ item, onClose }: { item: ServiceItem | null; onClose: () => void }) { const { data, isLoading } = useQuery<{ data: { data: TenantInsurance[] } }>({ queryKey: ['tenant-insurances'], queryFn: () => api.get('/api/v1/billing/tenant-insurances'), enabled: !!item, }); const contracts = ((data as any)?.data?.data as TenantInsurance[] | undefined) ?? []; return (
درصد پوشش، فرانشیز و سقف هر بیمه‌گر برای این خدمت تعیین می‌شود. این تنظیمات مبنای محاسبه‌ی سهم بیمار و ساخت مطالبات بیمه است.
{isLoading ? (
در حال بارگذاری...
) : contracts.length === 0 ? (
قرارداد بیمه‌ی فعالی ندارید
ابتدا از بخش بیمه‌ها یک بیمه را فعال کنید.
) : ( item && contracts.map((c) => ) )}
); }