feat(insurance): edit tenant insurance contracts

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
hamed
2026-06-23 20:32:34 +03:30
co-authored by Claude Opus 4.8
parent 2ef38f082d
commit d049e42ddc
@@ -1,6 +1,6 @@
import { useState } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { TrashIcon, PlusIcon } from '@heroicons/react/24/outline';
import { TrashIcon, PlusIcon, PencilIcon } from '@heroicons/react/24/outline';
import { toast } from 'sonner';
import { api } from '../lib/api';
import { formatRial } from '../lib/utils';
@@ -30,6 +30,7 @@ const KIND_LABEL: Record<string, string> = {
export default function TenantInsuranceContracts() {
const qc = useQueryClient();
const [addOpen, setAddOpen] = useState(false);
const [editUuid, setEditUuid] = useState<string | null>(null);
const [insuranceId, setInsuranceId] = useState('');
const [coverage, setCoverage] = useState('');
const [franchise, setFranchise] = useState('');
@@ -56,8 +57,33 @@ export default function TenantInsuranceContracts() {
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(String(c.franchise_rials ?? ''));
setCeiling(c.annual_ceiling_rials != null ? String(c.annual_ceiling_rials) : '');
};
const editMut = useMutation({
mutationFn: () =>
api.patch(`/api/v1/billing/tenant-insurances/${editUuid}`, {
coverage_percent: Number(coverage) || 0,
franchise_rials: Number(franchise) || 0,
annual_ceiling_rials: ceiling === '' ? null : 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', {
@@ -99,13 +125,13 @@ export default function TenantInsuranceContracts() {
)}
</div>
{addOpen && (
{(addOpen || editUuid) && (
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 10, alignItems: 'flex-end', padding: 14, borderRadius: 10, border: '1px solid var(--border)', background: 'var(--surface)', marginBottom: 14 }}>
<div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
<label style={{ fontSize: 11.5, fontWeight: 600 }}>بیمه</label>
<select className="input" style={{ minWidth: 160 }} value={insuranceId} onChange={(e) => setInsuranceId(e.target.value)}>
<select className="input" style={{ minWidth: 160 }} value={insuranceId} disabled={!!editUuid} onChange={(e) => setInsuranceId(e.target.value)}>
<option value="">انتخاب...</option>
{available.map((i) => (
{(editUuid ? allInsurances : available).map((i) => (
<option key={i.insurance_id} value={i.insurance_id}>{i.insurance_name} ({KIND_LABEL[i.type] ?? i.type})</option>
))}
</select>
@@ -123,8 +149,12 @@ export default function TenantInsuranceContracts() {
<input type="number" min={0} dir="ltr" className="input" style={{ width: 130 }} placeholder="بی‌نهایت" value={ceiling} onChange={(e) => setCeiling(e.target.value)} />
</div>
<div style={{ display: 'flex', gap: 6 }}>
<button className="btn primary sm" disabled={!insuranceId || addMut.isPending} onClick={() => addMut.mutate()}>
{addMut.isPending ? '...' : 'ذخیره'}
<button
className="btn primary sm"
disabled={!insuranceId || addMut.isPending || editMut.isPending}
onClick={() => (editUuid ? editMut.mutate() : addMut.mutate())}
>
{addMut.isPending || editMut.isPending ? '...' : 'ذخیره'}
</button>
<button className="btn ghost sm" onClick={resetForm}>لغو</button>
</div>
@@ -152,6 +182,9 @@ export default function TenantInsuranceContracts() {
{c.annual_ceiling_rials != null && ` · سقف ${formatRial(c.annual_ceiling_rials)}`}
</div>
</div>
<button className="mini-btn" title="ویرایش" onClick={() => openEdit(c)}>
<PencilIcon style={{ width: 15 }} />
</button>
<button className="mini-btn danger" title="غیرفعال‌سازی" disabled={delMut.isPending} onClick={() => delMut.mutate(c.uuid)}>
<TrashIcon style={{ width: 15 }} />
</button>