| // frontend/src/components/admin/OverviewCard.jsx | |
| import React from "react"; | |
| const colorMap = { | |
| blue: "bg-blue-50 text-blue-700", | |
| amber: "bg-amber-50 text-amber-700", | |
| red: "bg-rose-50 text-rose-700", | |
| green: "bg-emerald-50 text-emerald-700", | |
| }; | |
| export default function OverviewCard({ title, value, icon: Icon, color, trend, onClick }) { | |
| const badgeClasses = colorMap[color] || "bg-slate-50 text-slate-700"; | |
| const clickable = !!onClick; | |
| return ( | |
| <div | |
| onClick={onClick} | |
| className={ | |
| "bg-white border border-stone-200 rounded-2xl p-4 shadow-sm flex flex-col justify-between transition-shadow " + | |
| (clickable ? "cursor-pointer hover:shadow-md" : "") | |
| } | |
| > | |
| <div className="flex items-start justify-between gap-3"> | |
| <div> | |
| <div className="text-xs font-medium text-stone-500 uppercase tracking-wide mb-1"> | |
| {title} | |
| </div> | |
| <div className="text-2xl font-semibold text-stone-900"> | |
| {value ?? 0} | |
| </div> | |
| </div> | |
| {Icon && ( | |
| <div | |
| className={`inline-flex items-center justify-center w-9 h-9 rounded-full text-xs font-medium ${badgeClasses}`} | |
| > | |
| <Icon className="w-4 h-4" /> | |
| </div> | |
| )} | |
| </div> | |
| {trend && ( | |
| <div className="mt-3 text-xs text-stone-500"> | |
| {trend} | |
| </div> | |
| )} | |
| </div> | |
| ); | |
| } | |