- Refactored role metadata styles in UserDetailPage for consistency with design tokens. - Replaced hardcoded avatar colors with a utility function to generate gradients based on user ID. - Improved InfoCard component styles for better hover effects and accessibility. - Removed deprecated color classes and adjusted background gradients for various components. - Updated theme token tests to reflect the removal of deferred files and ensure compliance with design standards. - Added new avatarColors utility file to manage avatar gradient definitions.
515 lines
24 KiB
Markdown
515 lines
24 KiB
Markdown
# ClinicPro Admin — UI Design Specification
|
||
> سبک بصری: Panelix Premium React Admin Dashboard
|
||
|
||
---
|
||
|
||
## 1. Design System پایه
|
||
|
||
### رنگبندی (Color Palette)
|
||
|
||
> **منبع حقیقت `assets/admin/styles.css` است.** توکنها در `:root` تعریف و در
|
||
> `[data-theme="dark"]` بازتعریف میشوند؛ نسخهٔ oklch/color-mix زیر `@supports` میآید و
|
||
> مرورگر قدیمی روی همان مقادیر sRGB میماند. هیچ توکنی نباید فقط داخل `@supports` تعریف شود.
|
||
|
||
```css
|
||
/* Brand — indigo (نه بنفشِ این سند در نسخههای قدیمی) */
|
||
--primary --primary-600 --primary-700 --primary-soft --primary-soft2 --on-primary
|
||
/* Accent — نارنجی همخانواده با clinic-pro-tauri */
|
||
--accent --accent-600 --accent-bg
|
||
/* سطوح و متن */
|
||
--bg --bg-2 --surface --surface-2 --surface-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}
|
||
```
|
||
|
||
**قاعدهٔ الزامی:** در `assets/admin` رنگ ثابت ممنوع است — نه hex، نه کلاس پالت Tailwind
|
||
(`bg-white`, `text-gray-800`, `border-slate-200`, …). بهجایش:
|
||
|
||
| بهجای | بنویس |
|
||
|---|---|
|
||
| `style={{ color: '#525252' }}` | `style={{ color: 'var(--text)' }}` |
|
||
| `className="text-[#525252] dark:text-[#D7D8ED]"` | `className="text-[var(--text)]"` |
|
||
| `className="bg-white border border-gray-100"` | `className="bg-[var(--surface)] border border-[var(--border)]"` |
|
||
| `stroke="#616161"` روی SVG | `style={{ stroke: 'var(--text-2)' }}` یا `stroke="currentColor"` |
|
||
|
||
نگاشت hexهای قدیمی به توکن (از آدیت ۱۴۰۵/۰۵):
|
||
|
||
| hex | توکن |
|
||
|---|---|
|
||
| `#525252` `#3b3b3b` `#2f2f2f` `#111827` `#374151` · دارک: `#d7d8ed` | `--text` |
|
||
| `#616161` `#6b7280` `#7e7e7e` `#858d9d` · دارک: `#a1a1a1` | `--text-2` |
|
||
| `#9ca3af` `#94a3b8` `#9b9b9b` | `--text-3` |
|
||
| `#5559ce` | `--primary` · `#494cb3` → `--primary-600` · `#3b3f9f` → `--primary-700` |
|
||
| `#f17732` `#f0682a` `#f97316` | `--accent` |
|
||
| `#ffffff` (سطح کارت) · دارک: `#222433` | `--surface` |
|
||
| `#efefef` `#ededed` `#e7e7e7` · دارک: `#35343d` `#343645` | `--border` |
|
||
| `#e0e0e0` `#e1e1e1` `#dbdbdb` `#d7d7d7` · دارک: `#404040` | `--border-2` |
|
||
| `#ef4444` `#d32f2f` `#e53935` | `--danger` (پسزمینه: `--danger-bg`) |
|
||
| `#2e7d32` `#3c9a4f` `#22c55e` | `--success` (پسزمینه: `--success-bg`) |
|
||
| `#f59e0b` `#fdd835` `#ffc051` | `--warning` (پسزمینه: `--warning-bg`) |
|
||
| `#f4f5fd` `#f7f8ff` `#eef0ff` | `--primary-soft` · `#e8ebff` `#c7cef4` → `--primary-soft2` |
|
||
|
||
استثناهای پذیرفتهشده (در تست گارد ثبت شدهاند): پالت انتخابی برچسبها
|
||
(`TagsSettingsPage`)، اسکریم مودال (`bg-black/50`، مثل `.overlay`)، و `BrandFixed`
|
||
هیوی نارنجی در `stores/uiStore.ts`.
|
||
|
||
### تایپوگرافی
|
||
|
||
```
|
||
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 | 768px–1024px | Sidebar collapsed (72px) |
|
||
| desktop | > 1024px | Sidebar باز (260px) |
|
||
|
||
---
|
||
|
||
## 16. Dark Mode (پیادهشده)
|
||
|
||
دارکمود کامل شیپ شده است. `stores/uiStore.ts` → `applyTheme()` روی `<html>` همزمان
|
||
کلاس `dark` (برای واریانت Tailwind) و `data-theme="dark"` (برای توکنهای CSS) را ست
|
||
میکند و مقدارش در `localStorage['clinicpro-ui']` میماند. `applyBrand()` هم
|
||
`--brand-h/--brand-c` و در صورت وجود `BrandFixed` مقادیر `--primary*` را inline میگذارد.
|
||
|
||
```css
|
||
/* styles.css */
|
||
@custom-variant dark (&:where(.dark, .dark *));
|
||
:root { --surface: #ffffff; --text: #3b3b3b; /* … */ }
|
||
[data-theme="dark"] { --surface: #222433; --text: #D7D8ED; /* … */ }
|
||
```
|
||
|
||
قواعد:
|
||
|
||
- رنگ از توکن بیاید؛ آنوقت دارکمود **خودکار** درست است و `dark:` لازم نیست.
|
||
- `dark:` فقط وقتی که واقعاً توکنِ متفاوتی در دو تم لازم است — نه برای جبران hex ثابت.
|
||
- **inline style همیشه بر کلاس غالب است.** `style={{ color: '#525252' }}` کنار
|
||
`className="dark:text-[#D7D8ED]"` یعنی کلاس هیچوقت اعمال نمیشود؛ این الگو در
|
||
تست گارد `assets/admin/test/theme-tokens.test.ts` fail میدهد.
|
||
- `var(--token)` داخل `style` کار میکند؛ برای SVG یا `stroke="currentColor"` بگذار و
|
||
رنگ را از والد بگیر، یا `style={{ stroke: 'var(--…)' }}`.
|
||
- الفای هگزی (`${color}30`) روی توکن بیمعنی است — `color-mix(in srgb, var(--x) 19%, transparent)`.
|
||
|
||
کل `assets/admin` مهاجرت کرده است؛ تست گارد `DEFERRED` ندارد و فقط سه استثنای عمدی
|
||
دارد: پالت برچسبها، `BrandFixed` در `uiStore`، و گرادیان تزئینی آواتار
|
||
(`lib/avatarColors.ts`). اسکریم `bg-black/NN` هم مجاز است.
|
||
|
||
> نکتهٔ تاریخی: کلاسهایی مثل `text-primary-600` / `bg-primary-100` هیچوقت رنگی تولید
|
||
> نمیکردند — بلوک `@theme` فقط `--font-sans` را تعریف میکند و مقیاس `primary-*` در
|
||
> Tailwind وجود ندارد. ۴۳ نمونه از این کلاسهای مرده در آدیت به توکن تبدیل شدند.
|
||
|
||
---
|
||
|
||
## 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)
|