dstpabuaran.com/resources/js/components/card/stat-card.tsx
Yoga Pangestu c6a87a64c9 feat: enhance dashboard with detailed statistics and charts
- Refactored the dashboard component to include attendance, revenue, and expense summaries.
- Added donut charts for order statistics by channel, payment type, marketing, and status.
- Implemented a greeting message based on the current time and user information.
- Updated routing to use DashboardController for the dashboard view.
- Introduced a new AnalysisController for future analysis features.
2026-08-07 08:35:01 +07:00

45 lines
1.7 KiB
TypeScript

import type { LucideIcon } from 'lucide-react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { cn } from '@/lib/utils';
type StatItem = {
label: string;
value: string | number;
};
type StatCardProps = {
title: string;
icon: LucideIcon;
mainLabel?: string;
mainValue: string | number;
subLabel?: string;
items?: StatItem[];
cols?: 2 | 3 | 4;
};
export function StatCard({ title, icon: Icon, mainLabel, mainValue, subLabel, items = [], cols = 3 }: StatCardProps) {
return (
<Card>
<CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2">
<CardTitle className="text-sm font-medium">{title}</CardTitle>
<Icon className="size-4 text-muted-foreground" />
</CardHeader>
<CardContent>
{mainLabel && <p className="text-xs text-muted-foreground">{mainLabel}</p>}
<p className="text-2xl font-bold">{mainValue}</p>
{subLabel && <p className="text-xs text-muted-foreground">{subLabel}</p>}
{items.length > 0 && (
<div className={cn('mt-3 grid gap-2', cols === 2 && 'grid-cols-2', cols === 3 && 'grid-cols-3', cols === 4 && 'grid-cols-4')}>
{items.map((item, index) => (
<div key={index}>
<p className="text-xs text-muted-foreground">{item.label}</p>
<p className="text-sm font-medium">{item.value}</p>
</div>
))}
</div>
)}
</CardContent>
</Card>
);
}