137 lines
3.9 KiB
TypeScript
137 lines
3.9 KiB
TypeScript
import { Edit, Trash2, HardDrive, FileText, Users } from "lucide-react";
|
|
import { Company } from "@/types/company";
|
|
import { Button } from "@/components/ui/button";
|
|
import { ResponsiveDataView, RDVColumn, RDVCardField } from "@/components/common/ResponsiveDataView";
|
|
import { useRouter } from "next/navigation";
|
|
|
|
interface CompanyTableProps {
|
|
companies: Company[];
|
|
isLoading: boolean;
|
|
onEdit: (company: Company) => void;
|
|
onDelete: (company: Company) => void;
|
|
}
|
|
|
|
/**
|
|
* 회사 목록 테이블 컴포넌트
|
|
*/
|
|
export function CompanyTable({ companies, isLoading, onEdit, onDelete }: CompanyTableProps) {
|
|
const router = useRouter();
|
|
|
|
// 부서 관리 페이지로 이동
|
|
const handleManageDepartments = (company: Company) => {
|
|
router.push(`/admin/userMng/companyList/${company.company_code}/departments`);
|
|
};
|
|
|
|
// 디스크 사용량 포맷팅 함수
|
|
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="text-primary h-3 w-3" />
|
|
<span className="text-xs font-medium">{fileCount}개 파일</span>
|
|
</div>
|
|
<div className="flex items-center gap-1">
|
|
<HardDrive className="text-primary h-3 w-3" />
|
|
<span className="text-xs">{totalSizeMB.toFixed(1)} MB</span>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
// 데스크톱 테이블 컬럼 정의
|
|
const columns: RDVColumn<Company>[] = [
|
|
{
|
|
key: "company_code",
|
|
label: "회사코드",
|
|
width: "150px",
|
|
render: (value) => <span className="font-mono">{value}</span>,
|
|
},
|
|
{
|
|
key: "company_name",
|
|
label: "회사명",
|
|
render: (value) => <span className="font-medium">{value}</span>,
|
|
},
|
|
{
|
|
key: "writer",
|
|
label: "등록자",
|
|
width: "200px",
|
|
},
|
|
{
|
|
key: "diskUsage",
|
|
label: "디스크 사용량",
|
|
hideOnMobile: true,
|
|
render: (_value, row) => formatDiskUsage(row),
|
|
},
|
|
];
|
|
|
|
// 모바일 카드 필드 정의
|
|
const cardFields: RDVCardField<Company>[] = [
|
|
{
|
|
label: "작성자",
|
|
render: (company) => <span className="font-medium">{company.writer}</span>,
|
|
},
|
|
{
|
|
label: "디스크 사용량",
|
|
render: (company) => formatDiskUsage(company),
|
|
},
|
|
];
|
|
|
|
return (
|
|
<ResponsiveDataView<Company>
|
|
data={companies}
|
|
columns={columns}
|
|
keyExtractor={(c) => c.regdate + c.company_code}
|
|
isLoading={isLoading}
|
|
emptyMessage="등록된 회사가 없습니다."
|
|
skeletonCount={10}
|
|
cardTitle={(c) => c.company_name}
|
|
cardSubtitle={(c) => <span className="font-mono">{c.company_code}</span>}
|
|
cardFields={cardFields}
|
|
actionsLabel="작업"
|
|
actionsWidth="180px"
|
|
renderActions={(company) => (
|
|
<>
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
onClick={() => handleManageDepartments(company)}
|
|
className="h-8 w-8"
|
|
aria-label="부서관리"
|
|
>
|
|
<Users className="h-4 w-4" />
|
|
</Button>
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
onClick={() => onEdit(company)}
|
|
className="h-8 w-8"
|
|
aria-label="수정"
|
|
>
|
|
<Edit className="h-4 w-4" />
|
|
</Button>
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
onClick={() => onDelete(company)}
|
|
className="text-destructive hover:bg-destructive/10 hover:text-destructive h-8 w-8"
|
|
aria-label="삭제"
|
|
>
|
|
<Trash2 className="h-4 w-4" />
|
|
</Button>
|
|
</>
|
|
)}
|
|
/>
|
|
);
|
|
}
|