"use client"; import { useState, useTransition, useMemo } from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; import { Label } from "@/components/ui/label"; import { RefreshCw, Download, Search, X, Check, ChevronsUpDown } from "lucide-react"; import { syncSwpProjectAction, type SwpTableFilters } from "../actions"; import { useToast } from "@/hooks/use-toast"; import { useRouter } from "next/navigation"; import { cn } from "@/lib/utils"; interface SwpTableToolbarProps { filters: SwpTableFilters; onFiltersChange: (filters: SwpTableFilters) => void; projects?: Array<{ PROJ_NO: string; PROJ_NM: string }>; } export function SwpTableToolbar({ filters, onFiltersChange, projects = [], }: SwpTableToolbarProps) { const [isSyncing, startSync] = useTransition(); const [localFilters, setLocalFilters] = useState(filters); const { toast } = useToast(); const router = useRouter(); const [projectSearchOpen, setProjectSearchOpen] = useState(false); const [projectSearch, setProjectSearch] = useState(""); // 동기화 핸들러 const handleSync = () => { const projectNo = localFilters.projNo; if (!projectNo) { toast({ variant: "destructive", title: "프로젝트 선택 필요", description: "동기화할 프로젝트를 먼저 선택해주세요.", }); return; } startSync(async () => { try { toast({ title: "동기화 시작", description: `프로젝트 ${projectNo} 동기화를 시작합니다...`, }); const result = await syncSwpProjectAction(projectNo, "V"); if (result.success) { toast({ title: "동기화 완료", description: `문서 ${result.stats.documents.total}개, 파일 ${result.stats.files.total}개 동기화 완료`, }); // 페이지 새로고침 router.refresh(); } else { throw new Error(result.errors.join(", ")); } } catch (error) { console.error("동기화 실패:", error); toast({ variant: "destructive", title: "동기화 실패", description: error instanceof Error ? error.message : "알 수 없는 오류", }); } }); }; /** * 파일 업로드 핸들러 * 1) 네트워크 드라이브에 정해진 규칙대로, 파일이름 기반으로 파일 업로드하기 (단, cpyCd는 어떻게 해결할지 고민해봐야 함...) * 2) 1~N개 파일 받아서, 파일 이름 기준으로 파싱해서 SaveInBoxList API를 통해 업로드 처리 * * 개발중인 동안은 토스트 반환하도록 처리 */ const handleUploadFiles = () => { toast({ title: "파일 업로드", description: "현재 개발중입니다.", }); } // 검색 적용 const handleSearch = () => { onFiltersChange(localFilters); }; // 검색 초기화 const handleReset = () => { const resetFilters: SwpTableFilters = {}; setLocalFilters(resetFilters); onFiltersChange(resetFilters); }; // 프로젝트 필터링 const filteredProjects = useMemo(() => { if (!projectSearch) return projects; const search = projectSearch.toLowerCase(); return projects.filter( (proj) => proj.PROJ_NO.toLowerCase().includes(search) || proj.PROJ_NM.toLowerCase().includes(search) ); }, [projects, projectSearch]); return (
{/* 상단 액션 바 */}
SWP 문서 관리 시스템
{/* 검색 필터 */}

검색 필터

{/* 프로젝트 번호 */}
{projects.length > 0 ? (
setProjectSearch(e.target.value)} className="border-0 focus-visible:ring-0 focus-visible:ring-offset-0" />
{filteredProjects.map((proj) => ( ))} {filteredProjects.length === 0 && (
검색 결과가 없습니다.
)}
) : ( setLocalFilters({ ...localFilters, projNo: e.target.value }) } disabled className="bg-muted" /> )}
{/* 문서 번호 */}
setLocalFilters({ ...localFilters, docNo: e.target.value }) } />
{/* 문서 제목 */}
setLocalFilters({ ...localFilters, docTitle: e.target.value }) } />
{/* 패키지 번호 */}
setLocalFilters({ ...localFilters, pkgNo: e.target.value }) } />
{/* 업체 코드 */}
setLocalFilters({ ...localFilters, vndrCd: e.target.value }) } />
{/* 스테이지 */}
); }