"use client"; import { useState } from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from "@/components/ui/alert-dialog"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Label } from "@/components/ui/label"; import { Search, MoreVertical, Loader2 } from "lucide-react"; interface YardLayout { id: number; name: string; description: string; placement_count: number; updated_at: string; } interface YardLayoutListProps { layouts: YardLayout[]; isLoading: boolean; onSelect: (layout: YardLayout) => void; onDelete: (id: number) => Promise; onDuplicate: (id: number, newName: string) => Promise; } export default function YardLayoutList({ layouts, isLoading, onSelect, onDelete, onDuplicate }: YardLayoutListProps) { const [searchText, setSearchText] = useState(""); const [sortOrder, setSortOrder] = useState<"recent" | "name">("recent"); const [deleteTarget, setDeleteTarget] = useState(null); const [duplicateTarget, setDuplicateTarget] = useState(null); const [duplicateName, setDuplicateName] = useState(""); const [isDeleting, setIsDeleting] = useState(false); const [isDuplicating, setIsDuplicating] = useState(false); // 검색 필터링 const filteredLayouts = layouts.filter((layout) => { if (!searchText) return true; return ( layout.name.toLowerCase().includes(searchText.toLowerCase()) || layout.description?.toLowerCase().includes(searchText.toLowerCase()) ); }); // 정렬 const sortedLayouts = [...filteredLayouts].sort((a, b) => { if (sortOrder === "recent") { return new Date(b.updated_at).getTime() - new Date(a.updated_at).getTime(); } else { return a.name.localeCompare(b.name); } }); // 날짜 포맷팅 const formatDate = (dateString: string) => { const date = new Date(dateString); return date.toLocaleString("ko-KR", { year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", }); }; // 삭제 확인 const handleDeleteConfirm = async () => { if (!deleteTarget) return; setIsDeleting(true); try { await onDelete(deleteTarget.id); setDeleteTarget(null); } catch (error) { console.error("삭제 실패:", error); } finally { setIsDeleting(false); } }; // 복제 실행 const handleDuplicateConfirm = async () => { if (!duplicateTarget || !duplicateName.trim()) return; setIsDuplicating(true); try { await onDuplicate(duplicateTarget.id, duplicateName); setDuplicateTarget(null); setDuplicateName(""); } catch (error) { console.error("복제 실패:", error); } finally { setIsDuplicating(false); } }; // 복제 모달 열기 const handleDuplicateClick = (layout: YardLayout) => { setDuplicateTarget(layout); setDuplicateName(`${layout.name} (복사본)`); }; if (isLoading) { return (
); } return (
{/* 검색 및 정렬 */}
setSearchText(e.target.value)} className="pl-9" />
{/* 테이블 */} {sortedLayouts.length === 0 ? (
{searchText ? "검색 결과가 없습니다" : "등록된 야드가 없습니다"}
) : (
야드명 설명 배치 자재 최종 수정 작업 {sortedLayouts.map((layout) => ( onSelect(layout)}> {layout.name} {layout.description || "-"} {layout.placement_count}개 {formatDate(layout.updated_at)} e.stopPropagation()}> onSelect(layout)}>편집 handleDuplicateClick(layout)}>복제 setDeleteTarget(layout)} className="text-destructive"> 삭제 ))}
)} {/* 총 개수 */}
총 {sortedLayouts.length}개
{/* 삭제 확인 모달 */} setDeleteTarget(null)}> 야드 삭제 정말로 "{deleteTarget?.name}" 야드를 삭제하시겠습니까?
배치된 자재 정보도 함께 삭제됩니다.
취소 {isDeleting ? ( <> 삭제 중... ) : ( "삭제" )}
{/* 복제 모달 */} setDuplicateTarget(null)}> 야드 복제 새로운 야드의 이름을 입력하세요
setDuplicateName(e.target.value)} placeholder="야드 이름을 입력하세요" />
); }