Files
clinicpro/assets/admin/components/InsuranceServiceCategoriesCard.tsx
T
hamed 0e7970d6e0 feat: replace checkboxes with Switch component for better UI consistency
- Updated DoctorDetailPage, MySecretariesPage, RecordNumberSettingsPage, RepresentationsPage, ResourcePoolsPage, ResourceTypesPage, SecretariesPage, SecretaryDetailPage, SettingsPage, SkillsPage, SmsWalletPage, and TagsSettingsPage to use the new Switch component instead of native checkboxes.
- Enhanced accessibility by ensuring the Switch component uses appropriate roles and labels.
- Added tests for the new Switch component to ensure functionality and accessibility compliance.
- Updated styles to accommodate the new Switch component design.
2026-08-05 16:09:46 +03:30

87 lines
3.2 KiB
TypeScript

import { useEffect, useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';
import { api } from '../lib/api';
import type { ApiResponse } from '../lib/api';
import { usePermissions } from '../hooks/usePermissions';
import Switch from './ui/Switch';
interface ServiceCategoryRow {
key: string;
label: string;
enabled: boolean;
}
/**
* «نوع خدمات بیمه» — تنظیمی سراسری برای همهٔ بیمه‌های این پزشک/کلینیک: بیمه‌ها کدام
* نوع خدمات را پوشش می‌دهند. اگر فقط یک نوع فعال بماند، همان به‌صورت خودکار مبنای
* محاسبه است و سرِ پذیرش چیزی پرسیده نمی‌شود.
*/
export default function InsuranceServiceCategoriesCard() {
const qc = useQueryClient();
const { can } = usePermissions();
const canUpdate = can('insurances', 'update');
const [rows, setRows] = useState<ServiceCategoryRow[]>([]);
const { data } = useQuery<ApiResponse<{ service_categories?: ServiceCategoryRow[] }>>({
queryKey: ['insurance-pricing'],
queryFn: () => api.get('/api/v1/insurance-pricing'),
});
const serverRows = data?.data?.service_categories ?? [];
useEffect(() => {
if (serverRows.length > 0) setRows(serverRows);
}, [data]);
const save = useMutation({
mutationFn: (next: ServiceCategoryRow[]) => api.put('/api/v1/insurance-pricing', {
service_categories: next.map((r) => ({ key: r.key, enabled: r.enabled })),
}),
onSuccess: () => {
toast.success('نوع خدمات بیمه ذخیره شد');
qc.invalidateQueries({ queryKey: ['insurance-pricing'] });
},
onError: (e: Error) => {
toast.error(e.message);
setRows(serverRows);
},
});
const toggle = (key: string) => {
const next = rows.map((r) => (r.key === key ? { ...r, enabled: !r.enabled } : r));
if (next.every((r) => !r.enabled)) {
toast.error('حداقل یک نوع خدمت باید فعال باشد');
return;
}
setRows(next);
save.mutate(next);
};
if (rows.length === 0) return null;
return (
<div className="card" style={{ padding: 20, marginBottom: 16 }}>
<h2 style={{ fontSize: 15, fontWeight: 700, margin: '0 0 6px' }}>نوع خدمات بیمه</h2>
<p style={{ margin: '0 0 14px', fontSize: 12, lineHeight: 1.9, color: 'var(--text-2)' }}>
بیمه‌های شما کدام نوع خدمات را پوشش می‌دهند؟ این تنظیم برای همهٔ بیمه‌ها یکسان است.
اگر فقط یک نوع فعال باشد، همان به‌صورت پیش‌فرض برای محاسبهٔ بیمه استفاده می‌شود؛
با فعال بودن هر دو، هنگام قطعی‌کردن نوبت نوع خدمت پرسیده می‌شود.
</p>
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 18 }}>
{rows.map((row) => (
<Switch
key={row.key}
inline
checked={row.enabled}
disabled={!canUpdate || save.isPending}
onChange={() => toggle(row.key)}
label={row.label}
/>
))}
</div>
</div>
);
}