feat(web): migrate CRM screens to Ant Design Vue with central theme
Adopt ant-design-vue and a shared antdTheme for leads, pipeline, invoices, and shared form controls under strict single-page governance. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
# وضعیت دیزاینسیستم منتکت (Montact CRM)
|
||||
|
||||
سند audit وضعیت واقعی لایهٔ UI در `apps/web` — نه آرزو، نه Figma.
|
||||
آخرین بهروزرسانی: ۲۶ مهر ۱۴۰۵
|
||||
|
||||
**راهنما:**
|
||||
- **آماده** = در کد وجود دارد و بهطور منسجم قابل اتکا است
|
||||
- **نیمهآماده** = وجود دارد ولی پوشش/انضباط ناقص است
|
||||
- **نیست** = در کدبیس پیاده نشده
|
||||
|
||||
---
|
||||
|
||||
## خلاصهٔ اجرایی
|
||||
|
||||
دیزاینسیستم منتکت **نیمهآماده / در حال رشد** است: توکنهای CSS، کلاسهای الگوی `crm-*`، و یک کیت داخلی ۱۸تایی `Ui*` وجود دارد؛ اما API دوگانهٔ لگسی (`.btn` / `.field`)، hardcode گستردهٔ رنگ و فاصله در scoped CSS، نبود Storybook، و نبود چند primitive پرکاربرد مانع «سیستم واقعی» است.
|
||||
|
||||
| معیار | مقدار |
|
||||
|---|---|
|
||||
| امتیاز کلی آمادگی | **حدود ۵۰٪** (بازهٔ واقعبینانه ۴۵–۵۵٪) |
|
||||
| استک UI | Vue 3 SFC + Composition API — بدون Tailwind / UI kit شخصثالث |
|
||||
| primitives `Ui*` | ۱۸ کامپوننت + barrel |
|
||||
| adoption مستقیم در views | **۵۲ از ۷۶** (~۶۸٪) |
|
||||
| تم تاریک / چندتم | نیست |
|
||||
| کاتالوگ زنده (Storybook و مشابه) | نیست |
|
||||
|
||||
**حکم یکخطی:** زبان بصری teal + RTL برای CRM شکل گرفته؛ انضباط و پوشش کامپوننت هنوز به سطح design system کامل نرسیده.
|
||||
|
||||
---
|
||||
|
||||
## استک و مرز سیستم
|
||||
|
||||
```
|
||||
tokens (main.css :root)
|
||||
↓
|
||||
utilities / patterns (tokens.css → .crm-*)
|
||||
↓
|
||||
primitives (components/ui/Ui*)
|
||||
↓
|
||||
domain composites (pipeline/, gamification/, nav/, …)
|
||||
↓
|
||||
views + layouts
|
||||
```
|
||||
|
||||
| لایه | مسیر | نقش |
|
||||
|---|---|---|
|
||||
| تعریف توکنها | [`apps/web/src/styles/main.css`](../apps/web/src/styles/main.css) | `:root` — رنگ، تایپو، فاصله، سایه، z-index، کنترلها؛ همچنین استایل لگسی `.btn` / `.field` |
|
||||
| الگوهای CRM | [`apps/web/src/styles/tokens.css`](../apps/web/src/styles/tokens.css) | utilityهای `.crm-page`, `.crm-card`, `.crm-toolbar`, … (نام فایل «tokens» است؛ تعریف توکن اینجا نیست) |
|
||||
| فونت | [`apps/web/src/styles/fonts.css`](../apps/web/src/styles/fonts.css) | IRANSans FaNum خودمیزبان |
|
||||
| کیت UI | [`apps/web/src/components/ui/`](../apps/web/src/components/ui/) | ۱۸ SFC + [`index.ts`](../apps/web/src/components/ui/index.ts) |
|
||||
| آیکن | [`apps/web/src/components/UiIcon.vue`](../apps/web/src/components/UiIcon.vue) | بیرون از barrel `ui/` |
|
||||
| شِل اپ | [`layouts/AppLayout.vue`](../apps/web/src/layouts/AppLayout.vue)، [`layouts/AdmLayout.vue`](../apps/web/src/layouts/AdmLayout.vue) | سایدبار + workspace / ادمین پلتفرم |
|
||||
|
||||
**وابستگیهای UI در `package.json` وب:** فقط Vue، Vue Router، Pinia، Axios، ECharts / vue-echarts، xlsx. هیچ Element Plus / Vuetify / Naive / Headless / Tailwind نیست.
|
||||
|
||||
---
|
||||
|
||||
## ماتریس آمادگی
|
||||
|
||||
| لایه | وضعیت | توضیح کوتاه |
|
||||
|---|---|---|
|
||||
| توکن رنگ / تایپو / فاصله / سایه | **آماده** | پالت teal روی slate؛ scale فونت و spacing و shadow تعریف شده |
|
||||
| مقیاس radius | **نیمهآماده** | همهٔ `--radius-*` (جز full) روی ۱۰px قفلاند — سلسلهمراتب واقعی نیست |
|
||||
| spacing کامل | **نیمهآماده** | `--sp-1`…`6` و `8` و `10`؛ `--sp-7` / `--sp-9` نیست |
|
||||
| الگوی صفحه `crm-*` | **نیمهآماده** | مجموعهٔ خوب برای page/header/card/table/form؛ adoption ناقص |
|
||||
| primitives `Ui*` | **نیمهآماده** | ۱۸ قطعهٔ کاربردی؛ چند کنترل پایهٔ فرم/فیدبک غایب |
|
||||
| آیکن `UiIcon` | **آماده** | ~۷۰ آیکن stroke، `currentColor`، بدون پکیج خارجی |
|
||||
| Layout اپ / ادمین | **آماده** | شِل دسکتاپ + موبایل tabbar؛ ادم جدا |
|
||||
| RTL + IRANSans + جلالی | **آماده** | `dir="rtl"`، فونت فارسی، `lib/jalali.ts`، ارقام فارسی |
|
||||
| Dark mode / multi-theme | **نیست** | فقط تم روشن |
|
||||
| Storybook / Histoire / playground | **نیست** | اسکریپت lint وب هم placeholder است |
|
||||
| Checkbox / Switch / Tabs / Toast / Tooltip / Table / DatePicker بهعنوان `Ui*` | **نیست** | معادلها اغلب ad-hoc یا دامنهٔ خاص (`JalaliDateInput` و …) |
|
||||
| vue-i18n | **نیست** | متنها فارسی hardcode در template |
|
||||
| lint / اجبار توکن (منع hex خام) | **نیست** | رنگ و rem زیاد در scoped CSS تکرار شده |
|
||||
|
||||
---
|
||||
|
||||
## توکنها (آنچه واقعاً هست)
|
||||
|
||||
تعریف در `:root` داخل `main.css`:
|
||||
|
||||
| دسته | نمونه |
|
||||
|---|---|
|
||||
| سطح | `--bg`, `--surface`, `--surface-subtle`, `--surface-hover` |
|
||||
| متن / خط | `--ink`, `--ink-secondary`, `--muted`, `--line`, … |
|
||||
| accent | `--accent` (#14b8a6) و hover/deep/soft/subtle/contrast |
|
||||
| معنایی | `--danger`, `--success`, `--warning`, `--info` (+ soft/deep) |
|
||||
| تایپو | `--fs-xs`…`--fs-3xl`, `--fw-*`, `--lh-*`, `--font` |
|
||||
| فاصله | `--sp-1`…`--sp-6`, `--sp-8`, `--sp-10` |
|
||||
| کنترل | `--control-h-sm/h/md/lg`, `--pad-modal` |
|
||||
| سایه / حرکت / z | `--shadow-*`, `--transition-*`, `--z-dropdown`…`--z-toast` |
|
||||
| alias لگسی | `--color-primary`, `--color-text`, `--color-border`, … |
|
||||
|
||||
**ضعفها:** radius تخت؛ `--fw-extrabold` برابر bold؛ توکنهای محلی در `AppLayout` (مثل `--sidebar-card`) بیرون از `:root` سراسری؛ `CHART_PALETTE` در `UiChart` تا حدی جدا از توکنها.
|
||||
|
||||
---
|
||||
|
||||
## کاتالوگ کامپوننتهای `Ui*`
|
||||
|
||||
منبع: barrel [`components/ui/index.ts`](../apps/web/src/components/ui/index.ts).
|
||||
|
||||
| کامپوننت | نقش |
|
||||
|---|---|
|
||||
| `UiButton` | دکمه — variant / size / loading / block |
|
||||
| `UiInput` | ورودی متن — `defineModel`، prefix/suffix |
|
||||
| `UiTextarea` | متن چندخطی |
|
||||
| `UiSelect` | select بومی با slot برای `<option>` |
|
||||
| `UiField` | برچسب + hint + error دور کنترل |
|
||||
| `UiCard` | کارت با header / actions / footer |
|
||||
| `UiModal` | مودال + قفل اسکرول body |
|
||||
| `UiDrawer` | کشو از کنار |
|
||||
| `UiBusyOverlay` | پوشش busy / progress |
|
||||
| `UiPageHeader` | عنوان صفحه + lead + actions + back |
|
||||
| `UiBadge` | نشان وضعیت |
|
||||
| `UiPagination` | صفحهبندی + page size |
|
||||
| `UiEmptyState` | حالت خالی |
|
||||
| `UiSearch` | جستجوی ساده |
|
||||
| `UiFilterBar` | نوار جستجو + پنل فیلتر |
|
||||
| `UiSegmented` | کنترل segmented |
|
||||
| `UiChart` | ECharts + `CHART_PALETTE` |
|
||||
| `UiDropdownMenu` | منوی کشویی با trigger slot |
|
||||
|
||||
**مرتبط ولی خارج از barrel:** `UiIcon.vue`.
|
||||
|
||||
**domain composites (دیزاینسیستم نیستند):** پوشههایی مثل `pipeline/`, `gamification/`, `dashboard/`, `routines/`, `nav/`, `person-profile/` — ترکیب ویژگیمحور روی primitives یا استایل محلی.
|
||||
|
||||
---
|
||||
|
||||
## پترنهای UI واقعی در پروژه
|
||||
|
||||
### ۱) الگوی ترجیحی (هدف فعلی)
|
||||
|
||||
```ts
|
||||
import { UiButton, UiModal, UiPageHeader } from '@/components/ui';
|
||||
```
|
||||
|
||||
صفحه با `.crm-page` + `UiPageHeader` / `UiFilterBar` / `UiCard` / جدول `.crm-table*`.
|
||||
|
||||
### ۲) الگوی موازی / لگسی
|
||||
|
||||
- کلاسهای سراسری `.btn`, `.btn-ghost`, `.field` در `main.css`
|
||||
- `<button>` / `<input>` خام + scoped CSS در viewهای قدیمیتر یا خاص (Login، Notes، adm، …)
|
||||
- import مستقیم فایل بهجای barrel در بعضی viewها (`import UiButton from '@/components/ui/UiButton.vue'`)
|
||||
|
||||
### ۳) الگوی غیرمستقیم
|
||||
|
||||
بعضی viewها خودشان `ui/` را import نمیکنند ولی childها میکنند (مثلاً `HomeView` → `components/dashboard/*` → `UiChart` / `UiButton`).
|
||||
|
||||
### لایهبندی مفهومی
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
tokens[CSS_tokens_main_css]
|
||||
utils[crm_utilities_tokens_css]
|
||||
ui[Ui_primitives]
|
||||
domain[Domain_composites]
|
||||
views[Views_and_Layouts]
|
||||
legacy[Legacy_btn_field]
|
||||
tokens --> utils
|
||||
tokens --> ui
|
||||
utils --> views
|
||||
ui --> domain
|
||||
ui --> views
|
||||
domain --> views
|
||||
legacy --> views
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Adoption کمی (views)
|
||||
|
||||
| متریک | عدد |
|
||||
|---|---:|
|
||||
| کل viewهای `apps/web/src/views` | ۷۶ |
|
||||
| view با import مستقیم از `components/ui` | ۵۲ (~۶۸٪) |
|
||||
| view بدون import مستقیم | ۲۴ (~۳۲٪) |
|
||||
|
||||
### بدون import مستقیم `ui/` (ممکن است از child یا لگسی استفاده کنند)
|
||||
|
||||
- `ActivitiesCalendarView`, `ActivityDetailView`
|
||||
- `adm/AdmAdminsView`, `AdmBillingPanel`, `AdmDashboardView`, `AdmLoginView`, `AdmOrganizationsView`, `AdmUsersView`
|
||||
- `AttachmentsView`, `ConversationsView`
|
||||
- `gamification/GamificationView`, `GamificationAdminView`
|
||||
- `HomeView`, `InvoiceFormView`, `LeadFormPublicView`
|
||||
- `LoginView`, `NotesView`, `PersonProfileView`, `PortalView`, `ProfileView`
|
||||
- `ProjectCardFormView`, `QuoteFormView`, `QuotesView`, `RegisterView`
|
||||
|
||||
**نکتهٔ کیفیت:** حتی viewهایی که `Ui*` دارند اغلب هنوز hex/`rem` محلی در `<style scoped>` دارند؛ adoption کامپوننت ≠ انضباط توکن.
|
||||
|
||||
---
|
||||
|
||||
## ساختار پوشهٔ `components/` (خلاصه)
|
||||
|
||||
```
|
||||
components/
|
||||
├── ui/ ← primitives + index.ts (تنها barrel)
|
||||
├── UiIcon.vue ← آیکن مشترک
|
||||
├── activities|auth|automations|brand|dashboard|
|
||||
│ gamification|nav|person-*|pipeline|routines|…
|
||||
└── *.vue ← ورودیهای متقاطع (JalaliDateInput, MoneyInput, …)
|
||||
```
|
||||
|
||||
الگوی غالب: **Composition API** با `<script setup lang="ts">`؛ استایل scoped روی کامپوننت + مصرف `var(--…)`.
|
||||
|
||||
---
|
||||
|
||||
## شکافها و اولویت پیشنهادی
|
||||
|
||||
ترتیب پیشنهادی برای نزدیکشدن به design system واقعی (فقط نقشه — خارج از scope این سند):
|
||||
|
||||
1. **یک API برای دکمه/فرم** — مهاجرت تدریجی از `.btn` / `.field` به `UiButton` / `UiField` + حذف یا thin-wrapper کردن لگسی
|
||||
2. **تکمیل primitives پرکاربرد** — حداقل Toast، Tabs، Checkbox/Switch، Table (یا wrapper روی الگوی `.crm-table`)
|
||||
3. **اجبار توکن** — جایگزینی تدریجی hex تکراری با `var(--…)`؛ در حد ممکن rule/lint
|
||||
4. **کاتالوگ زنده** — Storybook / Histoire یا یک صفحهٔ داخلی فقط برای `Ui*`
|
||||
5. **تم** — فقط اگر محصول dark/multi-brand میخواهد؛ فعلاً پیشنیاز انضباط توکن است
|
||||
|
||||
---
|
||||
|
||||
## چکلیست «آیا design system هستیم؟»
|
||||
|
||||
| قابلیت | وضعیت |
|
||||
|---|---|
|
||||
| توکنهای مشترک | بله |
|
||||
| لایهٔ الگوی صفحه | بله (ناقص) |
|
||||
| کیت primitive داخلی | بله (ناقص) |
|
||||
| آیکن یکپارچه | بله |
|
||||
| شِل و RTL فارسی | بله |
|
||||
| پوشش اکثر صفحات | نسبتاً بله (~۶۸٪ مستقیم) |
|
||||
| یک منبع حقیقت بدون لگسی موازی | خیر |
|
||||
| مستند/کاتالوگ زنده | خیر |
|
||||
| تم / i18n / lint توکن | خیر |
|
||||
|
||||
**جمعبندی:** پروژه یک **design language + UI kit در حال رشد** دارد، نه یک design system کامل و منضبط. برای کار روزمرهٔ فیچر کافی است؛ برای اسکیل بدون drift بصری، اولویتهای ۱–۴ بالا ضروریاند.
|
||||
)
|
||||
Reference in New Issue
Block a user