- 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.
6.9 KiB
6.9 KiB
قواعد UI — هر صفحه و بخش جدید عیناً مطابق سیستم موجود
الزامی برای همهٔ تسکها. هیچ طراحی جدید، هیچ تم جدید، هیچ کامپوننت موازی.
منبع حقیقت: کدِ موجود، نه سلیقه و نه docs/admin-ui/ui-design-spec.md (که draft قدیمی
با پالت بنفش است و با کد شیپشده نمیخواند).
پنل ادمین clinicpro — React 19 + Webpack Encore + Tailwind v4
توکنها — هرگز مقدار hard-code
منبع: assets/admin/styles.css، بلوک :root.
// ❌
<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
پنج قاعدهٔ غیرقابلمذاکره
SearchableSelect، هرگز<select>بومی. بیاستثنا.- دکمهٔ بازگشت در هر زیرصفحه. صفحهای که از دل صفحهٔ دیگر باز میشود:
- با
PageHeader→ فقطbackTo="/admin/…"بده - بی
PageHeader→<BackButton fallback="/admin/…" />بالای هدر - دکمهٔ دستساز نساز. رفتار در
hooks/useGoBack.tsمتمرکز است.
- با
- وضعیت لیست در URL، نه در
useState. جستجو، فیلتر، شمارهٔ صفحه، نما — همه باhooks/useUrlState.ts:دلیلش «بازگشت» است:const [urlState, setUrlState] = useUrlState({ page: '1', search: '', status: '' }); const setSearch = (v: string) => setUrlState({ search: v, page: '1' });navigate(-1)همان URL را برمیگرداند. فیلد جستجوی debounceشده local میماند، فقط مقدار نهایی به URL میرود. - داده فقط با TanStack Query.
useQuery/useMutation، کلید['resource', page, filters]، همهٔ HTTP ازlib/api.ts. استخراج: paginated →data?.data+data?.meta?.totalRecords؛ single →data?.data؛ Category →data?.data?.data ?? []. - فرم با 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-sideuseProvince() - فراخوانی 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 نمایش داده میشوند