ERP-node/frontend/components/admin/CompanyTable.tsx

164 lines
5.6 KiB
TypeScript

import { Edit, Trash2, HardDrive, FileText } from "lucide-react";
import { Company } from "@/types/company";
import { COMPANY_TABLE_COLUMNS } from "@/constants/company";
import { Button } from "@/components/ui/button";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Badge } from "@/components/ui/badge";
interface CompanyTableProps {
companies: Company[];
isLoading: boolean;
onEdit: (company: Company) => void;
onDelete: (company: Company) => void;
}
/**
* 회사 목록 테이블 컴포넌트
*/
export function CompanyTable({ companies, isLoading, onEdit, onDelete }: CompanyTableProps) {
// 디스크 사용량 포맷팅 함수
const formatDiskUsage = (company: Company) => {
if (!company.diskUsage) {
return (
<div className="text-muted-foreground flex items-center gap-1">
<HardDrive className="h-3 w-3" />
<span className="text-xs"> </span>
</div>
);
}
const { fileCount, totalSizeMB } = company.diskUsage;
return (
<div className="flex flex-col gap-1">
<div className="flex items-center gap-1">
<FileText className="h-3 w-3 text-blue-500" />
<span className="text-xs font-medium">{fileCount} </span>
</div>
<div className="flex items-center gap-1">
<HardDrive className="h-3 w-3 text-green-500" />
<span className="text-xs">{totalSizeMB.toFixed(1)} MB</span>
</div>
</div>
);
};
// 상태에 따른 Badge 색상 결정
console.log(companies);
// 로딩 상태 렌더링
if (isLoading) {
return (
<div className="rounded-md border">
<Table>
<TableHeader>
<TableRow>
{COMPANY_TABLE_COLUMNS.map((column) => (
<TableHead key={column.key} style={{ width: column.width }}>
{column.label}
</TableHead>
))}
<TableHead className="w-[140px]"></TableHead>
</TableRow>
</TableHeader>
<TableBody>
{Array.from({ length: 5 }).map((_, index) => (
<TableRow key={index}>
{COMPANY_TABLE_COLUMNS.map((column) => (
<TableCell key={column.key}>
<div className="bg-muted h-4 animate-pulse rounded"></div>
</TableCell>
))}
<TableCell>
<div className="flex gap-2">
<div className="bg-muted h-8 w-8 animate-pulse rounded"></div>
<div className="bg-muted h-8 w-8 animate-pulse rounded"></div>
</div>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
);
}
// 데이터가 없을 때
if (companies.length === 0) {
return (
<div className="rounded-md border">
<Table>
<TableHeader>
<TableRow>
{COMPANY_TABLE_COLUMNS.map((column) => (
<TableHead key={column.key} style={{ width: column.width }}>
{column.label}
</TableHead>
))}
<TableHead className="w-[140px]"></TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell colSpan={COMPANY_TABLE_COLUMNS.length + 1} className="h-24 text-center">
<div className="text-muted-foreground flex flex-col items-center justify-center">
<p> .</p>
</div>
</TableCell>
</TableRow>
</TableBody>
</Table>
</div>
);
}
// 실제 데이터 렌더링
return (
<div className="rounded-md border">
<Table>
<TableHeader className="bg-muted">
<TableRow>
{COMPANY_TABLE_COLUMNS.map((column) => (
<TableHead key={column.key} style={{ width: column.width }}>
{column.label}
</TableHead>
))}
<TableHead className="w-[140px]"> </TableHead>
<TableHead className="w-[120px]"></TableHead>
</TableRow>
</TableHeader>
<TableBody>
{companies.map((company) => (
<TableRow key={company.regdate + company.company_code} className="hover:bg-muted/50">
<TableCell className="font-mono text-sm">{company.company_code}</TableCell>
<TableCell className="font-medium">{company.company_name}</TableCell>
<TableCell>{company.writer}</TableCell>
<TableCell className="py-2">{formatDiskUsage(company)}</TableCell>
<TableCell>
<div className="flex gap-2">
<Button
variant="ghost"
size="sm"
onClick={() => onEdit(company)}
className="h-8 w-8 p-0"
title="수정"
>
<Edit className="h-4 w-4" />
</Button>
<Button
variant="ghost"
size="sm"
onClick={() => onDelete(company)}
className="text-destructive hover:text-destructive h-8 w-8 p-0 hover:font-bold"
title="삭제"
>
<Trash2 className="h-4 w-4" />
</Button>
</div>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
);
}