"use client"; import * as React from "react"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { RefreshCw } from "lucide-react"; import { type ColumnDef } from "@tanstack/react-table"; import { ClientDataTableColumnHeaderSimple } from "@/components/client-data-table/data-table-column-simple-header"; import { ClientDataTable } from "@/components/client-data-table/data-table"; import { cn } from "@/lib/utils"; import { toast } from "sonner"; import type { DataTableAdvancedFilterField } from "@/types/table"; import { Progress } from "@/components/ui/progress"; import { getVendorFormStatus } from "@/lib/forms/stat"; // 타입 정의 interface VendorFormStatus { vendorId: number; vendorName: string; formCount: number; // 벤더가 가진 form 개수 tagCount: number; // 벤더가 가진 tag 개수 totalFields: number; // 입력해야 하는 총 필드 개수 completedFields: number; // 입력 완료된 필드 개수 completionRate: number; // 완료율 (%) } interface VendorFormStatusTableProps { initialData?: VendorFormStatus[]; } // 완료율에 따른 색상 반환 const getCompletionColor = (rate: number) => { if (rate >= 80) return "text-green-600"; if (rate >= 50) return "text-yellow-600"; if (rate >= 20) return "text-orange-600"; return "text-red-600"; }; // 완료율에 따른 Badge variant 반환 const getCompletionBadgeVariant = (rate: number): "default" | "secondary" | "destructive" | "outline" => { if (rate >= 80) return "default"; if (rate >= 50) return "secondary"; if (rate >= 20) return "outline"; return "destructive"; }; export function VendorFormStatusTable({ initialData = [], }: VendorFormStatusTableProps) { const [data, setData] = React.useState(initialData); const [isRefreshing, setIsRefreshing] = React.useState(false); // 데이터 새로고침 const handleRefresh = React.useCallback(async () => { setIsRefreshing(true); try { const result = await getVendorFormStatus(); setData(result); toast.success("데이터를 새로고침했습니다."); } catch (error) { console.error("Refresh error:", error); toast.error("새로고침 중 오류가 발생했습니다."); } finally { setIsRefreshing(false); } }, []); // 초기 데이터 로드 React.useEffect(() => { if (initialData.length === 0) { handleRefresh(); } }, []); // 컬럼 정의 const columns: ColumnDef[] = React.useMemo(() => [ { accessorKey: "vendorName", header: ({ column }) => , cell: ({ row }) => (
{row.original.vendorName}
), size: 200, enablePinning: true, }, { accessorKey: "formCount", header: ({ column }) => , cell: ({ row }) => (
{row.original.formCount}
), size: 100, }, { accessorKey: "tagCount", header: ({ column }) => , cell: ({ row }) => (
{row.original.tagCount}
), size: 100, }, { accessorKey: "totalFields", header: ({ column }) => , cell: ({ row }) => (
{row.original.totalFields.toLocaleString()}
), size: 100, }, { accessorKey: "completedFields", header: ({ column }) => , cell: ({ row }) => (
{row.original.completedFields.toLocaleString()}
), size: 100, }, { accessorKey: "completionRate", header: ({ column }) => , cell: ({ row }) => { const rate = row.original.completionRate; return (
{rate.toFixed(1)}%
); }, size: 180, }, { id: "progress", header: "진행 상태", cell: ({ row }) => { const { completedFields, totalFields } = row.original; return (
{completedFields} / {totalFields}
); }, size: 120, }, ], []); // 필터 필드 정의 const advancedFilterFields: DataTableAdvancedFilterField[] = [ { id: "vendorName", label: "벤더명", type: "text" }, { id: "formCount", label: "Form 개수", type: "number" }, { id: "tagCount", label: "Tag 개수", type: "number" }, { id: "completionRate", label: "완료율", type: "number" }, ]; // 요약 통계 const summaryStats = React.useMemo(() => { const totalVendors = data.length; const totalForms = data.reduce((sum, v) => sum + v.formCount, 0); const totalTags = data.reduce((sum, v) => sum + v.tagCount, 0); const avgCompletionRate = data.length > 0 ? data.reduce((sum, v) => sum + v.completionRate, 0) / data.length : 0; const fullCompletedVendors = data.filter(v => v.completionRate === 100).length; return { totalVendors, totalForms, totalTags, avgCompletionRate, fullCompletedVendors, }; }, [data]); return (
{/* 요약 카드 */}
전체 벤더
{summaryStats.totalVendors}
전체 Form
{summaryStats.totalForms.toLocaleString()}
전체 Tag
{summaryStats.totalTags.toLocaleString()}
평균 완료율
{summaryStats.avgCompletionRate.toFixed(1)}%
완료 벤더
{summaryStats.fullCompletedVendors} / {summaryStats.totalVendors}
{/* 데이터 테이블 */}
벤더별 Form 입력 현황
); }