# بازطراحی صفحه بیمه و قیمتگذاری — تفکیک نوع بیمه با Tab + ردیف Expandable + انتقال ویزیت آزاد
## پروژه
`clinicpro` (پنل ادمین React — فقط frontend؛ backend موجود کافی است)
## زمینه
مسیر `/admin/insurance-pricing` امروز سه بخش را در یک صفحه نشان میدهد: «قیمت ویزیت آزاد» (`FreeVisitPrice`)، و «مدیریت بیمه» (`TenantInsuranceContracts`) که همهی قراردادهای بیمهی پایه و تکمیلی را در یک جدول مسطح فهرست میکند. مدیر مطب هنگام افزودن بیمه باید نوع بیمه را دستی از یک `select` انتخاب کند و اطلاعات کلیدی هر بیمه (پوشش، فرانشیز، سقف) فقط بهصورت یک زیرنویس کمرنگ در ستون نام دیده میشود. جزئیات کامل قرارداد جایی نمایش داده نمیشود.
هدف: تجربهی مدیریت بیمه را برای یک مدیر حرفهای مطب/کلینیک سریع و خوانا کنیم — تفکیک پایه/تکمیلی با Tab، حذف انتخاب دستی نوع، نمایش خلاصهی خوانا در ردیف، و ردیفهای Expandable برای جزئیات کامل. همچنین «قیمت ویزیت آزاد» به صفحهی «تنظیمات نوبتدهی» منتقل شود.
## backend — نیازی به تغییر نیست (اول گشتم)
طبق قاعدهی «اول بگرد، بعد بساز» endpointهای موجود کافیاند؛ **هیچ تغییر backend لازم نیست**:
- `GET /api/v1/insurance-pricing` (در [src/Insurance/Controller/InsuranceController.php](src/Insurance/Controller/InsuranceController.php) خط ۲۲۰) هر بیمهی فعال را با فیلد `type` (`'basic'` | `'supplementary'`) و `free_visit_price_rials` برمیگرداند.
- `GET /api/v1/billing/tenant-insurances` (خط ۳۰۶) برای هر قرارداد `insurance_kind` (`kind` قرارداد یا در نبودش `type` کاتالوگ) و همهی فیلدهای پوشش/فرانشیز/سقف/تاریخ را برمیگرداند.
- `POST /api/v1/billing/tenant-insurances` (خط ۳۳۳) فیلد `kind` را در payload میپذیرد و ذخیره میکند.
- `PUT /api/v1/insurance-pricing` (خط ۲۵۸) با `{ free_visit_price_rials }` قیمت ویزیت آزاد را ذخیره میکند.
پس فیلتر بر اساس نوع بیمه کاملاً **سمت frontend** انجام میشود (روی دادههای موجود همین دو endpoint).
## فایلهای مرتبط
| فایل | نقش | تغییر |
|------|-----|-------|
| [assets/admin/pages/InsurancePricingPage.tsx](assets/admin/pages/InsurancePricingPage.tsx) | صفحهی بیمه و قیمتگذاری | حذف `` و توضیح مربوطه |
| [assets/admin/pages/AppointmentSettingsPage.tsx](assets/admin/pages/AppointmentSettingsPage.tsx) | صفحهی تنظیمات نوبتدهی | افزودن `` |
| [assets/admin/components/FreeVisitPrice.tsx](assets/admin/components/FreeVisitPrice.tsx) | کارت قیمت ویزیت آزاد | بدون تغییر (فقط جابهجا میشود) |
| [assets/admin/components/TenantInsuranceContracts.tsx](assets/admin/components/TenantInsuranceContracts.tsx) | جدول مدیریت بیمه | بازنویسی: Tab پایه/تکمیلی + ردیف Expandable + خلاصهی خوانا |
| [assets/admin/components/InsuranceModal.tsx](assets/admin/components/InsuranceModal.tsx) | مودال افزودن/ویرایش بیمه | حذف `select` نوع بیمه؛ `kind` از prop میآید |
## وضعیت فعلی
### `InsurancePricingPage.tsx`
```tsx
```
### `AppointmentSettingsPage.tsx` (بخش render)
```tsx
) : (
)}
```
### `InsuranceModal.tsx` — انتخاب دستی نوع (حذف شود)
```tsx
```
### `TenantInsuranceContracts.tsx` — یک جدول مسطح، خلاصه فقط در زیرنویس نام
```tsx
const contracts: Contract[] = (contractsQuery.data as any)?.data?.data ?? [];
const allInsurances: InsuranceOption[] = (pricingQuery.data as any)?.data?.insurances ?? [];
const activeIds = new Set(contracts.map((c) => c.insurance_id));
const available = allInsurances.filter((i) => !activeIds.has(i.insurance_id));
...
```
## وظایف
### ۱. انتقال «قیمت ویزیت آزاد» به تنظیمات نوبتدهی
**۱.۱ حذف از `InsurancePricingPage.tsx`:** خط `import FreeVisitPrice ...` و `` را بردار. توضیح `PageHeader` را به «قراردادهای بیمه پایه و تکمیلی» تغییر بده (دیگر ویزیت آزاد اینجا نیست).
**۱.۲ افزودن به `AppointmentSettingsPage.tsx`:** `import FreeVisitPrice from '../components/FreeVisitPrice';` و کارت را **بالای** `WeeklyScheduleTab` رندر کن.
نکتهی مهم — گاردِ «فقط پزشک»: `FreeVisitPrice` از `GET/PUT /api/v1/insurance-pricing` استفاده میکند که entity را از روی نقش کاربر (`ROLE_DOCTOR` یا `ROLE_CLINIC`) resolve میکند (خط ۴۸ کنترلر)، پس هم برای پزشک و هم کلینیک کار میکند — اما `AppointmentSettingsPage` وقتی `uuid` پزشک نباشد کل محتوا را با پیام «این بخش فقط برای پزشک در دسترس است» جایگزین میکند. کارت قیمت ویزیت آزاد را **بیرون از** شرط `!uuid` و **قبل از** آن قرار بده تا مستقل از داشتن `doctorUuid` همیشه نمایش داده شود:
```tsx
return (
مدیریت نوبت دهی
{!uuid ? (
این بخش فقط برای پزشک در دسترس است.
) : isLoading ? (
...
) : (
)}
);
```
### ۲. حذف انتخاب دستی نوع بیمه از `InsuranceModal`
نوع بیمه دیگر دستی انتخاب نمیشود؛ از Tab فعال میآید.
**۲.۱** بلوک `