ERP-node/frontend/lib/meta-components/DataView/views/CardView.tsx

97 lines
2.7 KiB
TypeScript
Raw Normal View History

2026-03-01 03:39:00 +09:00
/**
* CardView - DataView의
* -
* - Phase A: 기본
*/
"use client";
import React from "react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Skeleton } from "@/components/ui/skeleton";
import { cn } from "@/lib/utils";
interface CardViewProps {
data: any[];
columns: string[];
tableName: string;
loading?: boolean;
onCardClick?: (row: any) => void;
}
export function CardView({ data, columns, tableName, loading = false, onCardClick }: CardViewProps) {
// 로딩 스켈레톤
if (loading) {
return (
<div className="grid grid-cols-1 gap-4 p-4 md:grid-cols-2 lg:grid-cols-3">
{Array.from({ length: 6 }).map((_, i) => (
<Skeleton key={i} className="h-32 w-full" />
))}
</div>
);
}
// 데이터 없음
if (data.length === 0) {
return (
<div className="flex flex-col items-center justify-center py-12 text-center">
<div className="mb-2 text-sm font-semibold"> </div>
<p className="text-xs text-muted-foreground"> </p>
</div>
);
}
return (
<div className="grid grid-cols-1 gap-4 p-4 md:grid-cols-2 lg:grid-cols-3">
{data.map((row, index) => {
const rowId = row.id || String(index);
const titleColumn = columns[0]; // 첫 번째 컬럼을 제목으로 사용
return (
<Card
key={rowId}
className={cn(
"cursor-pointer transition-all hover:shadow-md",
onCardClick && "hover:border-primary"
)}
onClick={() => onCardClick?.(row)}
>
<CardHeader className="p-4">
<CardTitle className="text-sm font-semibold">{row[titleColumn] || "(제목 없음)"}</CardTitle>
</CardHeader>
<CardContent className="space-y-1 p-4 pt-0">
{columns.slice(1).map((column) => (
<div key={column} className="flex justify-between text-xs">
<span className="text-muted-foreground">{column}:</span>
<span className="font-medium">{formatValue(row[column])}</span>
</div>
))}
</CardContent>
</Card>
);
})}
</div>
);
}
// 값 포맷팅
function formatValue(value: any): string {
if (value === null || value === undefined) {
return "-";
}
if (typeof value === "boolean") {
return value ? "O" : "X";
}
if (value instanceof Date) {
return value.toLocaleDateString("ko-KR");
}
if (typeof value === "object") {
return JSON.stringify(value);
}
return String(value);
}