Files
clinicpro/assets/admin/components/appointments/TurnsStatInfo.tsx
T
hamed 55ab2f5dfc Implement comprehensive dark/light mode overhaul for admin panel
- Refactor color palette in `ui-design-spec.md` to utilize CSS variables exclusively, eliminating fixed hex values and Tailwind utility classes.
- Complete dark mode implementation in `uiStore.ts`, ensuring proper theme application via `applyTheme()` and `applyBrand()`.
- Create `admin-theme-dark-light-audit.md` to document the transition process, outlining issues with inline styles and fixed colors.
- Introduce `theme-tokens.test.ts` to enforce rules against fixed hex colors and ensure compliance with the design system.
- Update various components and styles to replace inline styles and fixed colors with CSS variables, ensuring consistent theming across light and dark modes.
- Ensure all changes maintain visual integrity in both light and dark modes, with a focus on accessibility and contrast standards.
2026-07-27 16:41:52 +03:30

62 lines
2.5 KiB
TypeScript

import { UsersIcon, UserPlusIcon, ClockIcon, XCircleIcon } from '@heroicons/react/24/outline';
/**
* نوار آمار نوبت‌ها — بازسازیِ `TurnsStatInfo.jsx` طرح tauri (کارت سفید با
* جداکننده‌های عمودی و چهار آمار). رنگ‌ها از `data/turnsHeaderStats.json` مبدأ.
*/
export interface TurnsStats {
total: number;
completed: number;
waiting: number;
cancelled: number;
}
interface StatDef {
title: string;
value: number;
Icon: React.ElementType;
iconColor: string;
iconBg: string;
}
function BadgeIcon({ Icon, color, bg }: { Icon: React.ElementType; color: string; bg: string }) {
return (
<div style={{
width: 44, height: 44, borderRadius: 10, background: bg,
display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
}}>
<Icon style={{ width: 22, height: 22, color }} />
</div>
);
}
export default function TurnsStatInfo({ stats }: { stats: TurnsStats }) {
const items: StatDef[] = [
{ title: 'کل نوبت های امروز', value: stats.total, Icon: UsersIcon, iconColor: 'var(--primary-600)', iconBg: 'var(--primary-soft)' },
{ title: 'نوبت های انجام شده', value: stats.completed, Icon: UserPlusIcon, iconColor: 'var(--success)', iconBg: 'var(--success-bg)' },
{ title: 'بیماران در انتظار', value: stats.waiting, Icon: ClockIcon, iconColor: 'var(--warning)', iconBg: 'var(--warning-bg)' },
{ title: 'نوبت های لغو شده', value: stats.cancelled, Icon: XCircleIcon, iconColor: 'var(--danger)', iconBg: 'var(--danger-bg)' },
];
return (
<div style={{
display: 'flex', alignItems: 'center', background: 'var(--surface)',
border: '1px solid var(--border)', borderRadius: 'var(--r)',
padding: '14px 20px', marginBottom: 16, gap: 4,
}}>
{items.map((it, i) => (
<div key={it.title} style={{ display: 'flex', alignItems: 'center', flex: 1, gap: 10 }}>
{i > 0 && <div style={{ width: 1, height: 48, background: 'var(--border)', marginInlineEnd: 8 }} />}
<BadgeIcon Icon={it.Icon} color={it.iconColor} bg={it.iconBg} />
<div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
<span style={{ fontSize: 12, color: 'var(--text-2)', whiteSpace: 'nowrap' }}>{it.title}</span>
<span style={{ fontSize: 18, fontWeight: 700, color: 'var(--text)' }}>
{it.value.toLocaleString('fa-IR')}
</span>
</div>
</div>
))}
</div>
);
}