Files
sam-react-prod/src/components/organisms/StatCards.tsx
byeongcheolryu a938da9e22 feat(WEB): 회계/HR/주문관리 모듈 개선 및 알림설정 리팩토링
- 회계: 거래처, 매입/매출, 입출금 상세 페이지 개선
- HR: 직원 관리 및 출퇴근 설정 기능 수정
- 주문관리: 상세폼 구조 분리 (cards, dialogs, hooks, tables)
- 알림설정: 컴포넌트 구조 단순화 및 리팩토링
- 캘린더: 헤더 및 일정 타입 개선
- 출고관리: 액션 및 타입 정의 추가

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-06 09:58:10 +09:00

67 lines
2.0 KiB
TypeScript

"use client";
import { Card, CardContent } from "@/components/ui/card";
import { LucideIcon } from "lucide-react";
interface StatCardData {
label: string;
value: string | number;
icon?: LucideIcon;
iconColor?: string;
trend?: {
value: string;
isPositive: boolean;
};
onClick?: () => void;
isActive?: boolean;
}
interface StatCardsProps {
stats: StatCardData[];
}
export function StatCards({ stats }: StatCardsProps) {
return (
<div className="grid grid-cols-2 sm:grid-cols-3 gap-3 md:gap-4">
{stats.map((stat, index) => {
const Icon = stat.icon;
const isClickable = !!stat.onClick;
return (
<Card
key={index}
className={`flex-1 min-w-0 transition-colors ${
isClickable ? 'cursor-pointer hover:border-primary/50' : ''
} ${
stat.isActive ? 'border-primary bg-primary/5' : ''
}`}
onClick={stat.onClick}
>
<CardContent className="p-3 md:p-4 lg:p-6">
<div className="flex items-center justify-between">
<div className="flex-1">
<p className="sm:text-xs md:text-sm text-muted-foreground mb-1 md:mb-2 uppercase tracking-wide text-[12px]">
{stat.label}
</p>
<p className="font-bold text-[24px]">
{stat.value}
</p>
{stat.trend && (
<p className={`text-[10px] sm:text-xs md:text-sm mt-1 md:mt-2 font-medium ${stat.trend.isPositive ? 'text-green-600' : 'text-red-600'}`}>
{stat.trend.value}
</p>
)}
</div>
{Icon && (
<Icon
className={`w-8 h-8 sm:w-9 sm:h-9 md:w-10 md:h-10 lg:w-12 lg:h-12 opacity-15 ${stat.iconColor || 'text-blue-600'}`}
/>
)}
</div>
</CardContent>
</Card>
);
})}
</div>
);
}