Qassure-frontend/src/pages/tenant/Dashboard.tsx

130 lines
3.5 KiB
TypeScript

import { Layout } from '@/components/layout/Layout';
import type { ReactElement } from 'react';
import { Info, FileCheck, Briefcase, FileText, GraduationCap } from 'lucide-react';
interface StatCardProps {
icon: React.ComponentType<{ className?: string }>;
value: string | number;
label: string;
status: 'success' | 'process' | 'warning' | 'disabled';
statusLabel: string;
}
const StatCard = ({ icon: Icon, value, label, status, statusLabel }: StatCardProps): ReactElement => {
const statusConfig = {
success: {
bg: 'bg-[#f1fffb]',
dot: 'bg-[#16c784]',
text: 'text-[#16c784]',
},
process: {
bg: 'bg-[#fff5e5]',
dot: 'bg-[#fca004]',
text: 'text-[#fca004]',
},
warning: {
bg: 'bg-[#fdf5f4]',
dot: 'bg-[#e0352a]',
text: 'text-[#e0352a]',
},
disabled: {
bg: 'bg-[#e5e7eb]',
dot: 'bg-[#9ca3af]',
text: 'text-[#9ca3af]',
},
};
const config = statusConfig[status];
const valueColor = status === 'warning' && label === 'Overdue Tasks' ? 'text-[#e0352a]' : 'text-[#0f1724]';
return (
<div className="relative p-[1px] rounded-lg" style={{ backgroundImage: 'linear-gradient(172.99deg, rgb(8, 76, 200) 1.15%, rgb(117, 192, 68) 44.3%, rgb(254, 211, 20) 89.74%)' }}>
<div className="bg-white border border-[#d1d5db] rounded-lg p-[17px] flex flex-col gap-3">
{/* Header with icon and status */}
<div className="flex items-start justify-between">
<Icon className="w-5 h-5 text-[#0f1724] shrink-0" />
<div className={`${config.bg} flex gap-1 items-center px-3 py-1 rounded-full`}>
<div className={`${config.dot} rounded-sm w-1.5 h-1.5`} />
<span className={`${config.text} text-xs font-medium capitalize`}>{statusLabel}</span>
</div>
</div>
{/* Value and Label */}
<div className="flex flex-col gap-0">
<div className={`text-2xl font-bold tracking-[-0.48px] ${valueColor}`}>
{value}
</div>
<div className="text-xs font-medium text-[#6b7280]">
{label}
</div>
</div>
</div>
</div>
);
};
const Dashboard = (): ReactElement => {
const statCards: StatCardProps[] = [
{
icon: Info,
value: '18',
label: 'Open CAPAs',
status: 'success',
statusLabel: 'Success',
},
{
icon: FileCheck,
value: '7',
label: 'Pending Approvals',
status: 'process',
statusLabel: 'Process',
},
{
icon: Briefcase,
value: '9',
label: 'Active Projects',
status: 'warning',
statusLabel: 'Warning',
},
{
icon: Info,
value: '3',
label: 'Overdue Tasks',
status: 'warning',
statusLabel: 'Warning',
},
{
icon: FileText,
value: '14',
label: 'Docs Pending Review',
status: 'disabled',
statusLabel: 'Disabled',
},
{
icon: GraduationCap,
value: '94%',
label: 'Training Compliance',
status: 'success',
statusLabel: 'Success',
},
];
return (
<Layout
currentPage="Dashboard Overview"
pageHeader={{
title: 'Tenant Overview',
description: 'Key quality metrics and performance indicators.',
}}
>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{statCards.map((card, index) => (
<StatCard key={index} {...card} />
))}
</div>
</Layout>
);
};
export default Dashboard;