diff --git a/.claude/prompt/admin-jalali-date-input.md b/.claude/prompt/admin-jalali-date-input.md
new file mode 100644
index 00000000..4168afe2
--- /dev/null
+++ b/.claude/prompt/admin-jalali-date-input.md
@@ -0,0 +1,156 @@
+# همهی تقویمهای پنل ادمین باید شمسی باشند (رفع تقویم میلادی PersianDateInput)
+
+## پروژه
+
+`clinicpro` (React 19 admin SPA داخل Symfony — `assets/admin/`)
+
+## زمینه
+
+کل محصول فارسی/RTL و تاریخها Jalali (شمسی) است. تقویم شمسی قبلاً نوشته شده:
+`PersianCalendar.tsx` (پیکر ماه/سال/روز شمسی، خروجی `YYYY-MM-DD` میلادی) و روکش آن
+`PersianDatePicker.tsx`. اما یک کامپوننت دیگر بهنام `PersianDateInput.tsx` هنوز از
+`` بومی مرورگر استفاده میکند که **تقویم میلادی** مرورگر را باز میکند.
+هرجای پنل که این کامپوننت استفاده شده، کاربر تقویم میلادی میبیند — خلاف قاعدهی محصول.
+
+## مشکل / هدف
+
+**هدف:** هرجای پنل ادمین که از انتخاب تاریخ (تقویم) استفاده میشود، تقویم شمسی نمایش دهد.
+
+**تنها منبع میلادی در کل ادمین:** `assets/admin/components/ui/PersianDateInput.tsx` خط ۵۶
+(`type="date"`). با اصلاح همین یک فایل، همهی call siteهای زیر یکجا شمسی میشوند
+(بدون تغییر در آنها، چون امضای Props ثابت میماند).
+
+بررسی انجامشده:
+- `PersianCalendar` / `PersianDatePicker` قبلاً شمسیاند — نیازی به بازنویسی ندارند.
+- در کل `assets/admin` فقط **یک** `type="date"` وجود دارد (همین فایل). هیچ
+ `datetime-local` / `month` / `week` بومی دیگری نیست.
+- تقویم ماهانهی درون `DoctorDetailPage.tsx` و `PersianDateInput` محلیِ همان فایل
+ از قبل با `jalaali-js` شمسیاند — دست نزن.
+
+## فایلهای مرتبط
+
+| فایل | نقش |
+|------|-----|
+| `assets/admin/components/ui/PersianDateInput.tsx` | **تنها فایلی که تغییر میکند** — حذف input بومی، استفاده از PersianCalendar |
+| `assets/admin/components/ui/PersianCalendar.tsx` | پیکر شمسی موجود (Props: `value`, `onChange`, `onClose`, `enableYearPicker`) — مرجع |
+| `assets/admin/components/ui/PersianDatePicker.tsx` | الگوی درستِ استفاده از PersianCalendar (کپی همین ساختار) |
+| `assets/admin/lib/utils.ts` → `formatDate()` | نمایش شمسیِ مقدار انتخابشده (از قبل استفاده میشود) |
+
+### call siteهای فعلی PersianDateInput (نباید تغییر کنند — فقط برای اطمینان از سازگاری Props)
+
+```
+components/AppointmentActions.tsx:482,613 value/onChange
+components/InsuranceModal.tsx:153,157 value/onChange/placeholder
+components/NewAppointmentDrawer.tsx:257 value/onChange
+components/PatientsFilterModal.tsx:84,86 value/onChange/placeholder
+pages/AppointmentEditPage.tsx:150 value/onChange
+pages/MyPaymentsPage.tsx:108,111 value/onChange/placeholder
+pages/AppointmentCreatePage.tsx:254 value/onChange
+pages/PatientDetailPage.tsx:373,510 value/onChange
+pages/PatientRecordFormPage.tsx:132 value/onChange ← تاریخ تولد (نیاز به enableYearPicker)
+pages/DoctorDetailPage.tsx:1687,1914,1918 اینها به PersianDateInput محلیِ همان فایل وصلاند، نه فایل مشترک — دست نزن
+```
+
+## وضعیت فعلی (کد مشکلدار)
+
+`assets/admin/components/ui/PersianDateInput.tsx` — لایهی متنی شمسی است ولی پیکر بومی میلادی:
+
+```tsx
+{/* hidden native input — opens picker on click */}
+ onChange(e.target.value)}
+ style={{ position: 'absolute', opacity: 0, pointerEvents: 'none', width: 1, height: 1, top: 0, left: 0 }}
+ tabIndex={-1}
+/>
+```
+
+`Props` فعلی: `value, onChange, placeholder?, min?, max?, style?, className?`.
+نکته: `min`/`max` در هیچ call siteی پاس داده نمیشوند (Prop مردهاند).
+
+## وظایف
+
+### ۱. بازنویسی `PersianDateInput.tsx` روی پیکر شمسی
+
+`` را حذف کن و همان الگوی `PersianDatePicker.tsx` را به کار ببر:
+state باز/بسته + رندر شرطی ``. لایهی متنی visible و `formatDate(value)`
+و دکمهی پاککردن (X) و امضای Props فعلی را **حفظ کن** تا هیچ call siteی نشکند.
+
+```tsx
+import { useState } from 'react';
+import { CalendarDaysIcon, XMarkIcon } from '@heroicons/react/24/outline';
+import { formatDate } from '../../lib/utils';
+import PersianCalendar from './PersianCalendar';
+
+interface Props {
+ value: string; // YYYY-MM-DD میلادی
+ onChange: (v: string) => void;
+ placeholder?: string;
+ enableYearPicker?: boolean; // برای تاریخ تولد
+ style?: React.CSSProperties;
+ className?: string;
+}
+
+export default function PersianDateInput({ value, onChange, placeholder = 'انتخاب تاریخ', enableYearPicker = false, style, className }: Props) {
+ const [open, setOpen] = useState(false);
+ return (
+
+ );
+}
+```
+
+- `min`/`max` را حذف کن (استفادهای ندارند). اگر خواستی امنتر باشی، نگهشان دار ولی
+ بدون اثر — ترجیح: حذف، مطابق قاعدهی «کد مرده ننویس».
+- استایل لایهی visible دقیقاً همان مقادیر فعلی فایل بماند (height 36، `--border`،
+ `--surface`، `minWidth 148`، fontSize 13، رنگ placeholder با `--text-3`).
+
+### ۲. فعالکردن انتخاب سال برای تاریخ تولد
+
+در `pages/PatientRecordFormPage.tsx:132` (فیلد `birth_date`) پراپ `enableYearPicker` را بده
+تا کاربر بتواند سریع سال تولد را انتخاب کند:
+
+```tsx
+ form.setValue('birth_date', v)} enableYearPicker />
+```
+
+(الگوی مشابه از قبل در `PatientRecordInfoForm.tsx:133` با `PersianDatePicker … enableYearPicker` هست.)
+
+### ۳. رفع همپوشانی SOLID (اختیاری ولی توصیهشده)
+
+بعد از این تغییر، `PersianDateInput` و `PersianDatePicker` تقریباً یکی میشوند
+(هر دو = لایهی متنی + PersianCalendar). برای پرهیز از دوگانگی:
+- گزینهی ساده: `PersianDateInput` را یک روکش نازک روی `PersianDatePicker` کن
+ (`return `)، یا
+- در همین تسک فقط رفتار را یکی کن و در کامنت بالای فایل اشاره کن که این دو باید
+ در آینده ادغام شوند. حذف کامل یکی از آنها → نیازمند بهروزرسانی همهی importها است؛
+ اگر انجامش میدهی، همهی call siteها را هم اصلاح کن و tscرا سبز نگه دار.
+
+## نکات مهم
+
+- بعد از تغییر، حتماً تایپچک: `ddev exec npx tsc --noEmit --project tsconfig.json` باید سبز شود.
+- خروجی `PersianCalendar.onChange` همان `YYYY-MM-DD` میلادی است؛ قرارداد دادهی ارسالی
+ به API تغییر نمیکند — فقط UI تقویم شمسی میشود. رفتار submit/فیلترها نباید عوض شود.
+- `DoctorDetailPage.tsx` یک `PersianDateInput` **محلیِ درونفایل** دارد (تعریف حدود خط ۱۷۷)
+ که با `jalaali-js` از قبل شمسی است و پراپ `minDate` دارد؛ به فایل مشترک ربطی ندارد — دست نزن.
+- تستها: اگر تستی برای `PersianDateInput` هست، آپدیت کن؛ در غیر این صورت یک تست کوتاه
+ Vitest اضافه کن که کلیک روی input، پیکر شمسی را باز میکند و انتخاب روز، `onChange`
+ با `YYYY-MM-DD` را صدا میزند (حالت موفق + پاککردن مقدار).
+- تغییرِ فقط-UI است؛ backend و `docs/api/*` نیاز به تغییر ندارند.
diff --git a/assets/admin/components/ui/PersianDateInput.test.tsx b/assets/admin/components/ui/PersianDateInput.test.tsx
new file mode 100644
index 00000000..f9556533
--- /dev/null
+++ b/assets/admin/components/ui/PersianDateInput.test.tsx
@@ -0,0 +1,43 @@
+import { describe, it, expect, vi } from 'vitest';
+import { render, screen, fireEvent } from '@testing-library/react';
+import PersianDateInput from '@/components/ui/PersianDateInput';
+
+describe('PersianDateInput', () => {
+ it('placeholder را وقتی مقدار خالی است نشان میدهد', () => {
+ render();
+ expect(screen.getByText('از تاریخ')).toBeInTheDocument();
+ });
+
+ it('از تقویم شمسی استفاده میکند نه input بومی میلادی', () => {
+ const { container } = render();
+ expect(container.querySelector('input[type="date"]')).toBeNull();
+ });
+
+ it('با کلیک، تقویم شمسی باز میشود (نام ماه فارسی)', () => {
+ const { container } = render();
+ fireEvent.click((container.firstChild as HTMLElement).firstChild as Element);
+ // 2024-03-25 میلادی = ۶ فروردین ۱۴۰۳ شمسی
+ expect(screen.getByText('فروردین')).toBeInTheDocument();
+ });
+
+ it('انتخاب روز، onChange را با YYYY-MM-DD میلادی صدا میزند', () => {
+ const onChange = vi.fn();
+ const { container } = render();
+ fireEvent.click((container.firstChild as HTMLElement).firstChild as Element);
+ const target = Array.from(container.querySelectorAll('button')).find(
+ (b) => b.textContent?.trim() === '۱۵',
+ );
+ expect(target).toBeTruthy();
+ fireEvent.click(target as Element);
+ expect(onChange).toHaveBeenCalledWith(expect.stringMatching(/^\d{4}-\d{2}-\d{2}$/));
+ });
+
+ it('دکمه پاککردن، onChange با رشته خالی میفرستد', () => {
+ const onChange = vi.fn();
+ const { container } = render();
+ const svgs = container.querySelectorAll('svg');
+ const clearIcon = svgs[svgs.length - 1];
+ fireEvent.click(clearIcon.parentElement as Element);
+ expect(onChange).toHaveBeenCalledWith('');
+ });
+});
diff --git a/assets/admin/components/ui/PersianDateInput.tsx b/assets/admin/components/ui/PersianDateInput.tsx
index 10360233..6116745d 100644
--- a/assets/admin/components/ui/PersianDateInput.tsx
+++ b/assets/admin/components/ui/PersianDateInput.tsx
@@ -1,69 +1,17 @@
-import React, { useRef } from 'react';
-import { CalendarDaysIcon, XMarkIcon } from '@heroicons/react/24/outline';
-import { formatDate } from '../../lib/utils';
+import PersianDatePicker from './PersianDatePicker';
interface Props {
- value: string;
+ value: string; // YYYY-MM-DD میلادی
onChange: (v: string) => void;
placeholder?: string;
- min?: string;
- max?: string;
- style?: React.CSSProperties;
- className?: string;
+ /** انتخاب سال→ماه→روز را فعال میکند (مناسب تاریخ تولد). */
+ enableYearPicker?: boolean;
}
-export default function PersianDateInput({ value, onChange, placeholder = 'انتخاب تاریخ', min, max, style, className }: Props) {
- const hiddenRef = useRef(null);
-
- const open = () => {
- const el = hiddenRef.current;
- if (!el) return;
- if (typeof el.showPicker === 'function') {
- try { el.showPicker(); } catch { el.focus(); }
- } else {
- el.focus();
- }
- };
-
- return (
-