From 0cef1518d7d29c201c8786fc3a8816c0aaefc2ec Mon Sep 17 00:00:00 2001 From: hamed <15238-genius.ha@users.noreply.drupalcode.org> Date: Tue, 23 Jun 2026 17:41:18 +0330 Subject: [PATCH] feat(ui-kit): tauri pastel stat cards on doctor/clinic dashboards Exact tauri stat-card palette tokens; doctor and clinic dashboards now render 4 pastel StatCards (amber/violet/green/pink) matching the clinic-pro-tauri reference. Co-Authored-By: Claude Opus 4.8 --- assets/admin/pages/DashboardPage.tsx | 60 +++++++++++----------------- assets/admin/styles.css | 10 ++--- 2 files changed, 29 insertions(+), 41 deletions(-) diff --git a/assets/admin/pages/DashboardPage.tsx b/assets/admin/pages/DashboardPage.tsx index 3fe7cf66..6bc250c5 100644 --- a/assets/admin/pages/DashboardPage.tsx +++ b/assets/admin/pages/DashboardPage.tsx @@ -12,6 +12,7 @@ import type { ApiResponse } from '../lib/api'; import { formatNumber, formatRial, formatDateTime } from '../lib/utils'; import { useAuthStore } from '../stores/authStore'; import InviteDoctorModal from '../components/ui/InviteDoctorModal'; +import StatCard from '../components/ui/StatCard'; // ── Shared Status Maps ──────────────────────────────────────────────────── @@ -593,14 +594,15 @@ function ClinicDashboard() { if (q.isLoading) return ; - const kpiCards = [ - { label: 'پزشکان', value: formatNumber(d?.stats.total_doctors ?? 0), icon: HeartIcon, color: 'var(--success)', bg: 'var(--success-bg)' }, - { label: 'نوبت‌های امروز', value: formatNumber(d?.stats.today_appointments ?? 0), icon: CalendarDaysIcon, color: 'var(--warning)', bg: 'var(--warning-bg)' }, - { label: 'نوبت‌های این ماه', value: formatNumber(d?.stats.this_month_appointments ?? 0), icon: ClockIcon, color: 'var(--info)', bg: 'var(--info-bg)' }, - { label: 'دعوتنامه در انتظار', value: formatNumber(d?.stats.pending_invitations ?? 0), icon: BellAlertIcon, color: 'var(--danger)', bg: 'var(--danger-bg)' }, - ...(d?.stats.sms_wallet_balance != null ? [{ label: 'موجودی پیامک', value: formatRial(d.stats.sms_wallet_balance), icon: CreditCardIcon, color: 'var(--primary)', bg: 'var(--primary-soft)' }] : []), - ...(d?.stats.unique_patients_count != null ? [{ label: 'بیماران یکتا', value: formatNumber(d.stats.unique_patients_count), icon: UserGroupIcon, color: 'var(--violet)', bg: 'var(--violet-bg)' }] : []), - ...(d?.stats.revenue_period_rials != null ? [{ label: 'درآمد دوره', value: formatRial(d.stats.revenue_period_rials), icon: CreditCardIcon, color: 'var(--success)', bg: 'var(--success-bg)' }] : []), + const statCards: { tone: 'amber' | 'violet' | 'green' | 'pink'; label: string; value: React.ReactNode; icon: React.ReactNode }[] = [ + { tone: 'amber', label: 'تعداد نوبت‌های امروز', value: `${formatNumber(d?.stats.today_appointments ?? 0)}+`, icon: }, + { tone: 'violet', label: 'نوبت‌های این ماه', value: formatNumber(d?.stats.this_month_appointments ?? 0), icon: }, + { tone: 'green', label: d?.stats.revenue_period_rials != null ? 'درآمد دوره' : 'پزشکان', + value: d?.stats.revenue_period_rials != null ? formatRial(d.stats.revenue_period_rials) : formatNumber(d?.stats.total_doctors ?? 0), + icon: d?.stats.revenue_period_rials != null ? : }, + { tone: 'pink', label: d?.stats.unique_patients_count != null ? 'بیماران یکتا' : 'دعوتنامه در انتظار', + value: d?.stats.unique_patients_count != null ? formatNumber(d.stats.unique_patients_count) : formatNumber(d?.stats.pending_invitations ?? 0), + icon: }, ]; return ( @@ -627,15 +629,9 @@ function ClinicDashboard() { -
- {kpiCards.map(c => ( -
-
- -
-
{c.label}
-
{c.value}
-
+
+ {statCards.map(c => ( + ))}
@@ -823,13 +819,13 @@ function DoctorDashboard() { if (q.isLoading) return ; - const kpiCards = [ - { label: 'نوبت‌های امروز', value: formatNumber(d?.stats.today_appointments ?? 0), icon: CalendarDaysIcon, color: 'var(--warning)', bg: 'var(--warning-bg)' }, - { label: 'نوبت‌های فردا', value: formatNumber(d?.stats.tomorrow_appointments ?? 0), icon: ClockIcon, color: 'var(--info)', bg: 'var(--info-bg)' }, - { label: 'نوبت‌های این ماه', value: formatNumber(d?.stats.this_month_appointments ?? 0), icon: CalendarDaysIcon, color: 'var(--success)', bg: 'var(--success-bg)' }, - { label: 'میانگین امتیاز', value: d?.stats.avg_rating != null ? String(d.stats.avg_rating) : '—', icon: StarIcon, color: 'var(--primary)', bg: 'var(--primary-soft)' }, - ...(d?.stats.unique_patients_count != null ? [{ label: 'بیماران یکتا', value: formatNumber(d.stats.unique_patients_count), icon: UserGroupIcon, color: 'var(--violet)', bg: 'var(--violet-bg)' }] : []), - ...(d?.stats.revenue_period_rials != null ? [{ label: 'درآمد دوره', value: formatRial(d.stats.revenue_period_rials), icon: CreditCardIcon, color: 'var(--success)', bg: 'var(--success-bg)' }] : []), + const statCards: { tone: 'amber' | 'violet' | 'green' | 'pink'; label: string; value: React.ReactNode; icon: React.ReactNode }[] = [ + { tone: 'amber', label: 'تعداد نوبت‌های امروز', value: `${formatNumber(d?.stats.today_appointments ?? 0)}+`, icon: }, + { tone: 'violet', label: 'نوبت‌های فردا', value: `${formatNumber(d?.stats.tomorrow_appointments ?? 0)}+`, icon: }, + { tone: 'green', label: 'نوبت‌های این ماه', value: formatNumber(d?.stats.this_month_appointments ?? 0), icon: }, + { tone: 'pink', label: d?.stats.revenue_period_rials != null ? 'درآمد دوره' : 'میانگین امتیاز', + value: d?.stats.revenue_period_rials != null ? formatRial(d.stats.revenue_period_rials) : (d?.stats.avg_rating != null ? String(d.stats.avg_rating) : '—'), + icon: d?.stats.revenue_period_rials != null ? : }, ]; return ( @@ -852,21 +848,13 @@ function DoctorDashboard() {
-
- {kpiCards.map(c => ( -
-
- -
-
{c.label}
-
{c.value}
- {c.label === 'میانگین امتیاز' && d?.stats.total_ratings ? ( -
{formatNumber(d.stats.total_ratings)} نظر
- ) : null} -
+
+ {statCards.map(c => ( + ))}
+
diff --git a/assets/admin/styles.css b/assets/admin/styles.css index f6bb27c5..16e66c54 100644 --- a/assets/admin/styles.css +++ b/assets/admin/styles.css @@ -47,11 +47,11 @@ --accent: #f0682a; --accent-600: #db5a1f; --accent-bg: #fdeee4; - /* رنگ‌های پاستلی stat-cards داشبورد (هم‌خوان با tauri) */ - --stat-amber-bg: #fdf0e3; --stat-amber-fg: #e08a1e; - --stat-violet-bg: #efeefb; --stat-violet-fg: #6d5cf0; - --stat-green-bg: #e7f6ef; --stat-green-fg: #16a35a; - --stat-pink-bg: #fdeee9; --stat-pink-fg: #f0682a; + /* رنگ‌های پاستلی stat-cards داشبورد (دقیقاً مطابق clinic-pro-tauri) */ + --stat-amber-bg: rgba(255,192,81,0.11); --stat-amber-fg: #FFC051; + --stat-violet-bg: rgba(85,89,206,0.08); --stat-violet-fg: #5559CE; + --stat-green-bg: rgba(0,157,121,0.10); --stat-green-fg: #009D79; + --stat-pink-bg: rgba(241,119,50,0.10); --stat-pink-fg: #F17732; --ring: color-mix(in oklch, var(--primary) 32%, transparent); --shadow-sm: 0 1px 2px rgba(15,27,46,.06), 0 1px 3px rgba(15,27,46,.05); --shadow: 0 2px 6px rgba(15,27,46,.06), 0 8px 24px rgba(15,27,46,.06);