Files
clinicpro/assets/admin/components/dashboard/TauriStatCards.tsx
T

104 lines
3.6 KiB
TypeScript

/**
* Stat cards row — ported pixel-for-pixel from clinic-pro-tauri
* `src/components/dashboard/cards/` (index + Card). Exact Tailwind arbitrary
* classes / colors kept; icons are the ported SVGs in `dashboardIcons`.
*/
import React from 'react';
import { UserAddIcon, CardIcon, CardTickIcon, CalendarIcon } from './dashboardIcons';
export interface StatCardModel {
/** background tint of the whole card (source `card_color`) */
cardColor: string;
/** solid background of the round icon bubble (source `icon_color`) */
iconColor: string;
icon: React.ReactNode;
value: React.ReactNode;
label: string;
}
function TauriStatCard({ data }: { data: StatCardModel }) {
return (
<li
className={`px-[8px] md:px-[16px] lg:px-[24px] py-[18px] sm:py-[20px] md:py-[22px] lg:py-[24px] rounded-[8px] flex items-center justify-start gap-[4px] md:gap-[8px] lg:gap-[12px] ${data.cardColor} dark:bg-[#222433]`}
>
<div
className={`p-[8px] w-[calc(18px+8px)] sm:w-[calc(20px+8px)] md:w-[calc(22px+8px)] lg:w-[calc(24px+8px)] min-w-[calc(18px+8px)] sm:min-w-[calc(20px+8px)] md:min-w-[calc(22px+8px)] lg:min-w-[calc(24px+8px)] h-[calc(18px+8px)] sm:h-[calc(20px+8px)] md:h-[calc(22px+8px)] lg:h-[calc(24px+8px)] grid place-items-center rounded-full ${data.iconColor}`}
>
{data.icon}
</div>
<div className="flex flex-col w-full items-start justify-center gap-[8px]">
<p className="text-[#3B3B3B] text-wrap dark:text-[#D7D8ED] text-[14px] sm:text-[16px] md:text-[18px] lg:text-[20px] font-medium">
{data.value}
</p>
<p className="text-[#616161] dark:text-[#A1A1A1] text-[12px] md:text-[14px] lg:text-[16px] font-normal">
{data.label}
</p>
</div>
</li>
);
}
export interface DashboardStats {
/** تعداد کل مراجعین */
totalPatients: number;
/** کل پرداختی‌ها (ریال) */
totalPaymentsRials: number;
/** پرداختی‌های امروز (ریال) */
todayPaymentsRials: number;
/** تعداد نوبت‌های امروز */
todayAppointments: number;
}
/**
* 4-card grid. `formatNumber`/`formatRial` are passed in so this stays a pure
* presentational component (SRP) — no coupling to the app's utils.
*/
export function TauriStatCards({
stats,
formatNumber,
formatRial,
}: {
stats: DashboardStats;
formatNumber: (n: number) => string;
formatRial: (rial: number) => string;
}) {
const cards: StatCardModel[] = [
{
cardColor: 'bg-[rgba(241,119,50,0.10)]',
iconColor: 'bg-[#F17732]',
icon: <UserAddIcon />,
value: `${formatNumber(stats.totalPatients)}+`,
label: 'تعداد کل مراجعین',
},
{
cardColor: 'bg-[rgba(0,157,121,0.10)]',
iconColor: 'bg-[#009D79]',
icon: <CardIcon />,
value: formatRial(stats.totalPaymentsRials),
label: 'کل پرداختی‌ها',
},
{
cardColor: 'bg-[rgba(85,89,206,0.08)]',
iconColor: 'bg-[#5559CE]',
icon: <CardTickIcon />,
value: formatRial(stats.todayPaymentsRials),
label: 'پرداختی‌های امروز',
},
{
cardColor: 'bg-[rgba(255,192,81,0.11)]',
iconColor: 'bg-[#FFC051]',
icon: <CalendarIcon />,
value: `${formatNumber(stats.todayAppointments)}+`,
label: 'تعداد نوبت‌های امروز',
},
];
return (
<ul className="grid w-full grid-cols-1 sm:grid-cols-2 xl:grid-cols-4 gap-[16px] sm:gap-[23px] md:gap-[30px] lg:gap-[36px]">
{cards.map((c) => (
<TauriStatCard key={c.label} data={c} />
))}
</ul>
);
}