- Add task for completing service mode in clinicpro with detailed objectives and acceptance criteria. - Create architecture documentation for task 00b, outlining involved components and necessary changes. - Develop checklist for task 00b to ensure all requirements are met. - Document implementation notes for task 00b, emphasizing API contract checks and design system adherence. - Update task documentation for task 00b, specifying goals and current issues with service mode.
127 lines
6.9 KiB
Markdown
127 lines
6.9 KiB
Markdown
# قواعد UI — هر صفحه و بخش جدید عیناً مطابق سیستم موجود
|
|
|
|
**الزامی برای همهٔ تسکها.** هیچ طراحی جدید، هیچ تم جدید، هیچ کامپوننت موازی.
|
|
منبع حقیقت: کدِ موجود، نه سلیقه و نه `docs/admin-ui/ui-design-spec.md` (که draft قدیمی
|
|
با پالت بنفش است و با کد شیپشده نمیخواند).
|
|
|
|
---
|
|
|
|
## پنل ادمین `clinicpro` — React 19 + Webpack Encore + Tailwind v4
|
|
|
|
### توکنها — هرگز مقدار hard-code
|
|
|
|
منبع: `assets/admin/styles.css`، بلوک `:root`.
|
|
|
|
```tsx
|
|
// ❌
|
|
<div style={{ background: '#5559CE', borderRadius: 14 }}>
|
|
|
|
// ✅
|
|
<div className="bg-[var(--primary)] rounded-[var(--r)]">
|
|
```
|
|
|
|
| گروه | توکن |
|
|
|---|---|
|
|
| برند | `--primary` `#5559CE` · `--primary-600/700` · `--primary-soft/soft2` · `--on-primary` |
|
|
| اکسنت | `--accent` `#f0682a` · `--accent-600` · `--accent-bg` |
|
|
| سطوح | `--bg` `--bg-2` `--surface` `--surface-2/3` `--border` `--border-2` |
|
|
| متن | `--text` `--text-2` `--text-3` |
|
|
| وضعیت | `--success/-bg` `--warning/-bg` `--danger/-bg` `--info/-bg` `--violet/-bg` |
|
|
| کارت آمار | `--stat-{amber,violet,green,pink}-{bg,fg}` |
|
|
| شعاع | `--r-xs:7` `--r-sm:8` `--r:14` `--r-lg:18` `--r-xl:24` `--r-pill:999` |
|
|
| سایه | `--shadow-sm` `--shadow` `--shadow-lg` |
|
|
| چیدمان | `--sidebar-w:243` `--collapsed-w:90` `--topbar-h:64` `--gap:20` `--card-pad:22` `--row-h:56` |
|
|
| حرکت | `--ease: cubic-bezier(.22,.61,.36,1)` |
|
|
|
|
دارکمود با `[data-theme="dark"]` و حالت فشرده با `[data-density="compact"]` خودکار
|
|
اعمال میشوند — **اگر** از توکن استفاده کرده باشی. مقدار hard-code در دارکمود میشکند.
|
|
|
|
### کامپوننتها — اول جستوجو، بعد ساخت
|
|
|
|
`assets/admin/components/ui/` اینها را دارد. ساختن نسخهٔ موازی از هر کدام **رد** میشود:
|
|
|
|
```
|
|
DataTable (مرتبسازی، جستجو، skeleton، empty state، bulk) · Modal · ConfirmDialog
|
|
PageHeader (عنوان + breadcrumb + action + backTo) · BackButton · StatCard · StatusBadge
|
|
Pagination · SearchableSelect · AppointmentStatusDropdown
|
|
PersianDateInput / PersianDatePicker / PersianCalendar
|
|
MobileInput · PriceInput · Portal · FeatureGate · Altcha
|
|
```
|
|
|
|
### پنج قاعدهٔ غیرقابلمذاکره
|
|
|
|
1. **`SearchableSelect`، هرگز `<select>` بومی.** بیاستثنا.
|
|
2. **دکمهٔ بازگشت در هر زیرصفحه.** صفحهای که از دل صفحهٔ دیگر باز میشود:
|
|
- با `PageHeader` → فقط `backTo="/admin/…"` بده
|
|
- بی `PageHeader` → `<BackButton fallback="/admin/…" />` بالای هدر
|
|
- دکمهٔ دستساز نساز. رفتار در `hooks/useGoBack.ts` متمرکز است.
|
|
3. **وضعیت لیست در URL، نه در `useState`.** جستجو، فیلتر، شمارهٔ صفحه، نما — همه با
|
|
`hooks/useUrlState.ts`:
|
|
```tsx
|
|
const [urlState, setUrlState] = useUrlState({ page: '1', search: '', status: '' });
|
|
const setSearch = (v: string) => setUrlState({ search: v, page: '1' });
|
|
```
|
|
دلیلش «بازگشت» است: `navigate(-1)` همان URL را برمیگرداند. فیلد جستجوی debounceشده
|
|
local میماند، فقط مقدار نهایی به URL میرود.
|
|
4. **داده فقط با TanStack Query.** `useQuery`/`useMutation`، کلید `['resource', page, filters]`،
|
|
همهٔ HTTP از `lib/api.ts`. استخراج: paginated → `data?.data` + `data?.meta?.totalRecords`؛
|
|
single → `data?.data`؛ Category → `data?.data?.data ?? []`.
|
|
5. **فرم با React Hook Form + Zod.** `z.object({...})` و تایپ با `z.infer`.
|
|
|
|
### فارسی، RTL، شمسی
|
|
|
|
- همهٔ رشتههای UI فارسی — از فایل i18n، نه inline
|
|
- تاریخها شمسی با `formatDate`/`formatDateTime` از `lib/utils.ts` (پشتصحنه `jalaali-js`)
|
|
- مبالغ با `formatRial`/`formatNumber`
|
|
- جهت RTL — `ms-*`/`me-*` بهجای `ml-*`/`mr-*`
|
|
- فونت `Vazirmatn` از `@fontsource/vazirmatn`
|
|
- آیکنها Heroicons v2 · نمودار Recharts · تُست `sonner`
|
|
|
|
### نامگذاری و مسیر
|
|
|
|
- صفحه: `assets/admin/pages/XxxPage.tsx` · کامپوننت PascalCase · هوک `useXxx.ts`
|
|
- کامپوننت عمومی → `components/ui/` · کامپوزیت مخصوص فیچر → `components/*.tsx`
|
|
- تایپهای مشترک → `types/index.ts`
|
|
- مسیر در `App.tsx` (React Router v7)، زیر `/admin/*`
|
|
|
|
---
|
|
|
|
## سایت عمومی `nobat724_front` — Next.js 15 App Router + MUI v5 + Tailwind
|
|
|
|
- تم MUI در `mui/index.js` با `direction: rtl` و فونت Vazir — تم جدید نساز
|
|
- Tailwind با `darkMode: "class"`؛ صفحات عمومی `data-theme`، پنل `class`
|
|
(`next-themes` در `app/Providers.js`)
|
|
- **فونت فقط Vazir** — در `app/globals.css` با `@font-face`. فونت دیگر اضافه نکن.
|
|
- هر صفحه باید `generateMetadata` صادر کند · همیشه `await params`
|
|
- شهر از subdomain: server-side `lib/getStateInfo.js` · client-side `useProvince()`
|
|
- فراخوانی API: `services/response.js` → `request.*`؛ برای auth `{ requireAuth: true }`
|
|
- داده server-side: `lib/req.js` → `fetchReq(url)`
|
|
- slug پزشک/کلینیک = `uuid`
|
|
- JSON-LD مستقیم در JSX صفحات doctor/clinic/blog
|
|
- تاریخ شمسی با `jalali-moment` / `dayjs`
|
|
- کامپوننتهای موجود `components/appointment/*` را توسعه بده، مسیر موازی نساز
|
|
|
|
---
|
|
|
|
## چکلیست UI — در `checklist.md` هر تسکی که صفحه یا کامپوننت میسازد
|
|
|
|
هر ردیف باید یکی از ✅ / 🔄 / ⏳ / ⚠️ بگیرد:
|
|
|
|
```
|
|
□ هیچ رنگ/شعاع/سایهٔ hard-code نیست — همه از توکنهای styles.css
|
|
□ دارکمود بررسی شد (data-theme="dark") و چیزی نمیشکند
|
|
□ حالت فشرده بررسی شد (data-density="compact")
|
|
□ همهٔ select ها SearchableSelect اند، هیچ <select> بومی نیست
|
|
□ زیرصفحهها backTo یا <BackButton /> دارند
|
|
□ وضعیت لیست (جستجو/فیلتر/صفحه) در URL است با useUrlState
|
|
□ لیستها از DataTable استفاده میکنند با skeleton و empty state فارسی
|
|
□ هیچ کامپوننت موازیِ چیزی که در components/ui/ هست ساخته نشد
|
|
□ همهٔ رشتهها فارسی و از i18n
|
|
□ تاریخها شمسی با formatDate · مبالغ با formatRial
|
|
□ RTL بررسی شد (ms/me نه ml/mr)
|
|
□ موبایل بررسی شد (بدون اسکرول افقی)
|
|
□ فرمها با React Hook Form + Zod
|
|
□ داده با TanStack Query و استخراج envelope درست
|
|
□ خطاها با پیام فارسی از ErrorCodes نمایش داده میشوند
|
|
```
|