Files
clinicpro/docs/admin-ui/ui-design-spec.md
T
hamed de1a78a235 feat: Implement SMS sending functionality with KavehNegar and Rangineh providers
- Add SendSmsMessage class for encapsulating SMS message data.
- Create KavehNegarProvider and RanginehProvider classes implementing SmsProviderInterface for sending SMS.
- Implement SmsLogRepository and SmsTemplateRepository for managing SMS logs and templates.
- Develop SendSmsHandler for handling SMS sending messages.
- Create SmsService to manage SMS dispatching and logging.
- Add UserProfileController for managing user profiles with CRUD operations.
- Implement UserProfile entity and repository for user profile data management.
- Update symfony.lock and bootstrap.php for project dependencies and environment setup.
2026-06-09 22:00:34 +03:30

483 lines
20 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ClinicPro Admin — UI Design Specification
> سبک بصری: Panelix Premium React Admin Dashboard
---
## 1. Design System پایه
### رنگ‌بندی (Color Palette)
```css
/* Primary — Purple (Panelix style) */
--color-primary-50: #f5f3ff;
--color-primary-100: #ede9fe;
--color-primary-200: #ddd6fe;
--color-primary-300: #c4b5fd;
--color-primary-400: #a78bfa;
--color-primary-500: #8b5cf6; /* main */
--color-primary-600: #7c3aed;
--color-primary-700: #6d28d9;
--color-primary-800: #5b21b6;
--color-primary-900: #4c1d95;
/* Neutrals */
--color-gray-50: #f9fafb;
--color-gray-100: #f3f4f6;
--color-gray-200: #e5e7eb;
--color-gray-300: #d1d5db;
--color-gray-400: #9ca3af;
--color-gray-500: #6b7280;
--color-gray-600: #4b5563;
--color-gray-700: #374151;
--color-gray-800: #1f2937;
--color-gray-900: #111827;
/* Status Colors */
--color-success: #10b981;
--color-warning: #f59e0b;
--color-danger: #ef4444;
--color-info: #3b82f6;
/* Background */
--color-bg-body: #f1f5f9; /* light gray page bg */
--color-bg-card: #ffffff;
--color-bg-sidebar: #0f172a; /* dark navy sidebar */
--color-bg-sidebar-active: rgba(139, 92, 246, 0.15);
```
### تایپوگرافی
```
Font Family: "Vazirmatn", "Inter", sans-serif ← فارسی + لاتین
Direction: RTL
Heading 1: 28px / font-bold / gray-900
Heading 2: 22px / font-bold / gray-900
Heading 3: 18px / font-semibold / gray-800
Heading 4: 16px / font-semibold / gray-700
Body: 14px / font-normal / gray-600
Caption: 12px / font-normal / gray-500
Label: 12px / font-medium / gray-700 / uppercase + tracking-wide
```
### Spacing & Border Radius
```
Spacing scale: 4px base (4, 8, 12, 16, 20, 24, 32, 40, 48, 64)
Border radius:
sm: 6px (badges, chips)
md: 10px (inputs, buttons)
lg: 16px (cards)
xl: 24px (modals)
full: 9999px (avatars, toggles)
Box shadow:
card: 0 1px 3px rgba(0,0,0,.08), 0 1px 2px rgba(0,0,0,.06)
modal: 0 20px 60px rgba(0,0,0,.15)
dropdown: 0 4px 20px rgba(0,0,0,.10)
```
---
## 2. Layout Structure
```
┌─────────────────────────────────────────────────────────┐
│ TOPBAR (64px) │
├────────────┬────────────────────────────────────────────┤
│ │ │
│ SIDEBAR │ MAIN CONTENT │
│ (260px) │ │
│ │ ┌──────────────────────────────────────┐ │
│ collapsed │ │ Page Header (title + breadcrumb) │ │
│ → 72px │ ├──────────────────────────────────────┤ │
│ │ │ │ │
│ │ │ Content Area (padding 24px) │ │
│ │ │ │ │
│ │ └──────────────────────────────────────┘ │
└────────────┴────────────────────────────────────────────┘
```
---
## 3. Sidebar
### حالت باز (260px)
```
┌──────────────────────────────┐
│ ◉ ClinicPro [← collapse] │ ← logo + toggle button
├──────────────────────────────┤
│ 🔍 جستجوی سریع... │ ← search input
├──────────────────────────────┤
│ GENERAL │ ← section label (gray-500, 11px, uppercase)
│ ◉ داشبورد │ ← active item (purple bg + purple text + bold)
│ ○ کاربران │
│ ○ پزشکان │
│ ○ کلینیک‌ها │
├──────────────────────────────┤
│ MANAGEMENT │
│ ○ نوبت‌ها [3] │ ← badge count
│ ○ پرداخت‌ها │
│ ○ تسویه‌حساب [5] │
├──────────────────────────────┤
│ CONTENT │
│ ○ نظرات [12] │
│ ○ امتیازها │
│ ○ بلاگ │
│ ○ پیامک │
├──────────────────────────────┤
│ SYSTEM │
│ ○ دسته‌بندی‌ها │
│ ○ نمایندگان │
│ ○ منشی‌ها │
├──────────────────────────────┤
│ ┌────────────────────────┐ │
│ │ 👤 Admin │ ← admin profile card at bottom
│ │ admin@clinicpro.ir │
│ │ [تنظیمات] [خروج] │
│ └────────────────────────┘ │
└──────────────────────────────┘
```
### حالت جمع‌شده (72px) — Flyout on hover
```
┌──────┐
│ ◉ │ ← logo icon
├──────┤
│ 🔍 │ ← hover → flyout search
├──────┤
│ ⊞ │ ← icon only, hover → flyout label + submenu
│ 👥 │
│ 🩺 │
│ 🏥 │
│ 📅 │
│ 💳 │
│ 🏦 │ ← badge dot (نه عدد)
│ 💬 │ ← badge dot
│ ⭐ │
│ 📝 │
│ 📱 │
│ 🗂 │
│ 🤝 │
│ 🔐 │
└──────┘
```
**رفتار sidebar:**
- `transition: width 300ms cubic-bezier(0.4, 0, 0.2, 1)`
- Overlay در موبایل (< 768px)
- Active item: `bg-primary-500/15` + right border `4px solid #8b5cf6`
- Hover item: `bg-gray-700/40`
---
## 4. Topbar
```
┌─────────────────────────────────────────────────────────────┐
│ ≡ [Breadcrumb: داشبورد / پزشکان] 🔔 5 👤 Admin ▾ │
└─────────────────────────────────────────────────────────────┘
```
- ارتفاع: 64px
- پس‌زمینه: سفید + `box-shadow: 0 1px 0 #e5e7eb`
- **Notification Bell:** dropdown با لیست آخرین رویدادها
- **User Menu:** تصویر آواتار + نام + dropdown (پروفایل / تنظیمات / خروج)
---
## 5. Cards
### Stat Card (آمار خلاصه)
```
┌──────────────────────────────────┐
│ ┌────┐ │
│ │ 🩺 │ کل پزشکان │ ← icon در مربع رنگی (purple-100)
│ └────┘ 1,284 │ ← عدد بزرگ (28px bold)
│ ↑ 12% نسبت به ماه قبل │ ← trend badge (سبز/قرمز)
└──────────────────────────────────┘
bg: white, radius: 16px, shadow: card, padding: 24px
```
### Data Card (محتوا / جداول)
```
┌────────────────────────────────────────────┐
│ عنوان کارت [اقدام ▾] │ ← header
├────────────────────────────────────────────┤
│ │
│ محتوا (جدول / نمودار / فرم) │
│ │
└────────────────────────────────────────────┘
```
---
## 6. DataTable (جدول داده)
```
┌─────────────────────────────────────────────────────────────────┐
│ [🔍 جستجو...] [فیلتر ▾] [ستون‌ها ▾] [صادرکردن ↓] │
├──────────┬────────────┬──────────┬────────┬─────────────────────┤
│ ☐ نام │ موبایل │ نقش │ وضعیت │ اقدامات │
├──────────┼────────────┼──────────┼────────┼─────────────────────┤
│ ☐ علی م. │ 0912*** │ پزشک │ ● فعال │ 👁 ✏️ 🗑 │
│ ☐ سارا ح │ 0935*** │ کلینیک │ ○ غیر │ 👁 ✏️ 🗑 │
├──────────┴────────────┴──────────┴────────┴─────────────────────┤
│ نمایش 1-10 از 284 [← قبلی] 1 2 3 ... 29 [بعدی →] │
└─────────────────────────────────────────────────────────────────┘
```
**ویژگی‌ها:**
- Sortable columns (کلیک روی header → ↑↓)
- Row hover: `bg-gray-50`
- Sticky header هنگام scroll
- Loading state: skeleton rows (shimmer animation)
- Empty state: آیکون + پیام توصیفی + دکمه اقدام
- Bulk actions: با انتخاب checkbox ها → نوار بالا ظاهر می‌شود
---
## 7. Status Badges
```jsx
// وضعیت نوبت
<Badge variant="yellow">در انتظار پرداخت</Badge> /* waiting_for_payment */
<Badge variant="blue">رزرو شده</Badge> /* reserved */
<Badge variant="purple">ورود به مطب</Badge> /* checked_in */
<Badge variant="orange">در صف انتظار</Badge> /* waiting */
<Badge variant="indigo">در حال ویزیت</Badge> /* in_progress */
<Badge variant="green">ویزیت شده</Badge> /* visited / completed */
<Badge variant="red">لغو شده</Badge> /* cancelled_* */
<Badge variant="gray">لغو خودکار</Badge> /* auto_cancel_unpaid */
<Badge variant="rose">غیبت</Badge> /* no_show */
// وضعیت پرداخت
<Badge variant="yellow">در انتظار</Badge> /* pending */
<Badge variant="green">موفق</Badge> /* received */
<Badge variant="red">لغو شده</Badge> /* canceled */
<Badge variant="blue">استرداد</Badge> /* refund */
// وضعیت SMS Template
<Badge variant="gray">پیشنویس</Badge> /* draft */
<Badge variant="yellow">در انتظار تأیید</Badge> /* pending_approval */
<Badge variant="green">تأیید شده</Badge> /* approved */
<Badge variant="red">رد شده</Badge> /* rejected */
```
**ساختار badge:**
```
padding: 2px 10px
border-radius: 9999px
font-size: 12px / font-medium
با dot رنگی (●) در ابتدا
```
---
## 8. فرم‌ها (Forms)
### Input
```
┌─────────────────────────────────┐
│ برچسب │
│ ┌─────────────────────────────┐ │
│ │ 🔍 placeholder... │ │ ← icon اختیاری
│ └─────────────────────────────┘ │
│ پیام خطا (قرمز، 12px) │
└─────────────────────────────────┘
```
- Border: `1px solid #d1d5db` → focus: `2px solid #8b5cf6`
- Height input: 44px
- Border-radius: 10px
- Error state: border قرمز + shake animation
- Disabled: opacity 50%
### Select / Dropdown
- کتابخانه: `react-select` با استایل custom (RTL support)
- Multi-select برای تخصص‌ها، بیمه‌ها، تگ‌ها
### Permission Matrix (منشی)
```
مشاهده ایجاد ویرایش حذف
نوبت‌ها ☑ ☑ ☐ ☐
آدرس‌ها ☑ ☐ ☐ ☐
اطلاعات کلینیک ☑ — ☐ —
بیمه‌ها ☑ ☐ ☐ ☐
```
---
## 9. نمودارها (Charts)
### داشبورد اصلی
```
Row 1: [Stat Card x4] ← کاربران / پزشکان / نوبت امروز / درآمد امروز
Row 2: [Area Chart — درآمد ماهانه (60%)] | [Donut Chart — نوبت‌ها بر اساس وضعیت (40%)]
Row 3: [Bar Chart — آمار ماهانه نمایندگان (60%)] | [لیست آخرین نوبت‌ها (40%)]
```
**کتابخانه:** `Recharts` یا `ApexCharts`
- رنگ اصلی نمودارها: shades of purple + secondary colors
- Tooltip: سفید با سایه، اعداد فارسی
- X-axis: نام ماه‌های شمسی (فروردین ... اسفند)
- Responsive: `<ResponsiveContainer width="100%" height={300}>`
---
## 10. Modal / Dialog
```
┌──────────────────────────────────────────────────┐
│ │ ← backdrop: rgba(0,0,0,.4)
│ ┌────────────────────────────────────────────┐ │
│ │ عنوان Modal ✕ │ │ ← header: border-bottom
│ ├────────────────────────────────────────────┤ │
│ │ │ │
│ │ محتوا │ │
│ │ │ │
│ ├────────────────────────────────────────────┤ │
│ │ [لغو] [تأیید / ذخیره] │ │ ← footer: border-top
│ └────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────┘
```
- انیمیشن ورود: `scale(0.95) → scale(1)` + `opacity 0 → 1` (200ms)
- Confirm Dialog برای حذف: دکمه «حذف» قرمز + آیکون هشدار
- Width: sm=400px / md=600px / lg=800px / xl=1000px
---
## 11. Toast Notifications
```
موقعیت: top-left (RTL)
┌─────────────────────────────────┐
│ ✓ پزشک با موفقیت ویرایش شد. │ ← success (سبز)
└─────────────────────────────────┘
┌─────────────────────────────────┐
│ ✕ خطا در ذخیره اطلاعات. │ ← error (قرمز)
└─────────────────────────────────┘
```
- Auto dismiss: 4 ثانیه
- Stack: حداکثر 3 نوتیفیکیشن همزمان
- کتابخانه: `react-hot-toast` یا `sonner`
---
## 12. Empty States & Loading
### Loading (Skeleton)
```
┌──────────────────────────────┐
│ ▓▓▓▓▓▓▓▓▓ ░░░░░░░░░░░ │ ← shimmer animation
│ ░░░░░░░░░░░░░░░░░░░░░░░░ │
│ ░░░░░░░░░░░ ▓▓▓▓▓▓▓▓▓▓ │
└──────────────────────────────┘
```
- `animate-pulse` با رنگ `gray-200`
### Empty State
```
┌──────────────────────────────────┐
│ │
│ [SVG Illustration] │
│ │
│ هیچ موردی یافت نشد │
│ توضیح کوتاه... │
│ │
│ [افزودن اولین مورد] │
│ │
└──────────────────────────────────┘
```
---
## 13. Page Header (هر صفحه)
```
┌─────────────────────────────────────────────────────────┐
│ پزشکان [+ افزودن پزشک] │
│ داشبورد / پزشکان │ ← breadcrumb
└─────────────────────────────────────────────────────────┘
```
---
## 14. تکنولوژی Stack
| لایه | کتابخانه |
|------|----------|
| Framework | React 19 + TypeScript |
| Routing | React Router v7 |
| Styling | Tailwind CSS v4 |
| State (server) | TanStack Query v5 |
| State (client) | Zustand |
| Forms | React Hook Form + Zod |
| Charts | Recharts |
| Table | TanStack Table v8 |
| Icons | Heroicons v2 |
| Date (Jalali) | `@date-io/date-fns-jalali` + `react-datepicker` |
| Numbers | `react-number-format` |
| Toast | `sonner` |
| Select | `react-select` |
| Rich Text | `@tiptap/react` |
| File Upload | `react-dropzone` |
| RTL | `dir="rtl"` + Tailwind `rtl:` variants |
| Font | Vazirmatn (از Google Fonts یا CDN) |
---
## 15. Responsive Breakpoints
| نام | عرض | رفتار |
|-----|-----|--------|
| mobile | < 768px | Sidebar → Drawer overlay |
| tablet | 768px1024px | Sidebar collapsed (72px) |
| desktop | > 1024px | Sidebar باز (260px) |
---
## 16. Dark Mode (اختیاری — فاز دوم)
```css
/* با Tailwind dark: variant */
.dark {
--color-bg-body: #0f172a;
--color-bg-card: #1e293b;
--color-bg-sidebar: #0a0f1e;
}
```
Toggle در topbar ← ذخیره در `localStorage`
---
## 17. نمونه رنگ‌بندی صفحه داشبورد
```
[صفحه] bg: #f1f5f9
├── Sidebar (bg: #0f172a, text: gray-400, active: purple-500)
└── Main
├── Topbar (bg: white, border-bottom: gray-200)
└── Content (padding: 24px)
├── [Stat Card] bg:white, icon-box: purple-100
├── [Stat Card] bg:white, icon-box: green-100
├── [Stat Card] bg:white, icon-box: blue-100
└── [Stat Card] bg:white, icon-box: orange-100
```
---
## منابع
- طراحی مرجع: [Panelix Premium React Admin Dashboard](https://themeforest.net/item/panelix-premium-react-admin-dashboard-template/63163276)
- فونت: [Vazirmatn](https://rastikerdar.github.io/vazirmatn/)
- آیکون: [Heroicons](https://heroicons.com/)
- رنگ‌بندی: [Tailwind CSS Colors](https://tailwindcss.com/docs/customizing-colors)