feat: update user roles and passwords in QA driver, enhance documentation with error codes, and improve trial activation error handling

This commit is contained in:
hamed
2026-07-19 15:19:03 +03:30
parent 3e841b5e57
commit 7761c37a3e
10 changed files with 326 additions and 109 deletions
+12 -13
View File
@@ -20,6 +20,7 @@ const jalaali = require('jalaali-js') as {
import { NewAppointmentsTable } from '../components/dashboard/NewAppointmentsTable';
import DoctorAppointmentsPanel from '../components/dashboard/DoctorAppointmentsPanel';
import { usePermissions } from '../hooks/usePermissions';
import { STATUS_META } from '../components/ui/AppointmentStatusDropdown';
// ── Chart period (Jalali) ─────────────────────────────────────────────────
@@ -47,18 +48,15 @@ function useJalaliChartPeriod() {
// ── Shared Status Maps ────────────────────────────────────────────────────
const APPT_LABEL: Record<string, string> = {
waiting_for_payment: 'انتظار پرداخت', reserved: 'رزرو شده', checked_in: 'ورود به مطب',
waiting: 'صف انتظار', in_progress: 'در حال ویزیت', visited: 'ویزیت شده',
completed: 'تکمیل شده', cancelled_by_doctor: 'لغو پزشک', cancelled_by_user: 'لغو بیمار',
auto_cancel_unpaid: 'لغو خودکار', no_show: 'غیبت',
};
const APPT_COLOR: Record<string, string> = {
waiting_for_payment: '#f59e0b', reserved: '#3b82f6', checked_in: '#6366f1',
waiting: '#f97316', in_progress: '#8b5cf6', visited: '#10b981',
completed: '#22c55e', cancelled_by_doctor: '#ef4444', cancelled_by_user: '#f43f5e',
auto_cancel_unpaid: '#94a3b8', no_show: '#64748b',
};
// Derived from the canonical STATUS_META rather than kept as a second copy —
// the local map had drifted off the backend's Appointment::STATUS_* set, so
// `confirmed` and `expired` rendered as raw English on the dashboard.
const APPT_LABEL: Record<string, string> = Object.fromEntries(
Object.entries(STATUS_META).map(([k, v]) => [k, v.label]),
);
const APPT_COLOR: Record<string, string> = Object.fromEntries(
Object.entries(STATUS_META).map(([k, v]) => [k, v.color]),
);
const APPT_CLS: Record<string, string> = {
waiting_for_payment: 'amber', reserved: 'blue', checked_in: 'violet',
waiting: 'amber', in_progress: 'violet', visited: 'green', completed: 'green',
@@ -384,7 +382,8 @@ function AdminDashboard() {
{ label: 'پزشکان فعال', value: fn(stats?.active_doctors), hint: stats ? `از ${fn(stats.total_doctors)} پزشک` : '', icon: HeartIcon, color: 'var(--success)', bg: 'var(--success-bg)' },
{ label: 'کلینیک‌ها', value: fn(stats?.total_clinics), hint: '', icon: BuildingOffice2Icon, color: 'var(--info)', bg: 'var(--info-bg)' },
{ label: 'نوبت‌های امروز', value: fn(stats?.today_appointments), hint: stats ? `ماه جاری: ${fn(stats.this_month_appointments)}` : '', icon: CalendarDaysIcon, color: 'var(--warning)', bg: 'var(--warning-bg)' },
{ label: 'درآمد این ماه', value: fr(stats?.this_month_revenue), hint: 'تومان', icon: CreditCardIcon, color: 'var(--primary)', bg: 'var(--primary-soft)' },
// formatRial already suffixes « تومان» — a 'تومان' hint here renders it twice.
{ label: 'درآمد این ماه', value: fr(stats?.this_month_revenue), hint: '', icon: CreditCardIcon, color: 'var(--primary)', bg: 'var(--primary-soft)' },
{ label: 'در انتظار بررسی', value: fn(stats ? stats.pending_comments + stats.pending_settlements : undefined), hint: stats ? `${fn(stats.pending_comments)} نظر · ${fn(stats.pending_settlements)} تسویه` : '', icon: BellAlertIcon, color: 'var(--danger)', bg: 'var(--danger-bg)' },
];