"use client"; import React, { useState, useEffect } from "react"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Badge } from "@/components/ui/badge"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Plus, Search, MoreHorizontal, Edit, Trash2, Play, History, RefreshCw } from "lucide-react"; import { toast } from "sonner"; import { CollectionAPI, DataCollectionConfig } from "@/lib/api/collection"; import CollectionConfigModal from "@/components/admin/CollectionConfigModal"; export default function CollectionManagementPage() { const [configs, setConfigs] = useState([]); const [filteredConfigs, setFilteredConfigs] = useState([]); const [isLoading, setIsLoading] = useState(false); const [searchTerm, setSearchTerm] = useState(""); const [statusFilter, setStatusFilter] = useState("all"); const [typeFilter, setTypeFilter] = useState("all"); // 모달 상태 const [isModalOpen, setIsModalOpen] = useState(false); const [selectedConfig, setSelectedConfig] = useState(null); const collectionTypeOptions = CollectionAPI.getCollectionTypeOptions(); useEffect(() => { loadConfigs(); }, []); useEffect(() => { filterConfigs(); }, [configs, searchTerm, statusFilter, typeFilter]); const loadConfigs = async () => { setIsLoading(true); try { const data = await CollectionAPI.getCollectionConfigs(); setConfigs(data); } catch (error) { console.error("수집 설정 목록 조회 오류:", error); toast.error("수집 설정 목록을 불러오는데 실패했습니다."); } finally { setIsLoading(false); } }; const filterConfigs = () => { let filtered = configs; // 검색어 필터 if (searchTerm) { filtered = filtered.filter(config => config.config_name.toLowerCase().includes(searchTerm.toLowerCase()) || config.source_table.toLowerCase().includes(searchTerm.toLowerCase()) || config.description?.toLowerCase().includes(searchTerm.toLowerCase()) ); } // 상태 필터 if (statusFilter !== "all") { filtered = filtered.filter(config => config.is_active === statusFilter); } // 타입 필터 if (typeFilter !== "all") { filtered = filtered.filter(config => config.collection_type === typeFilter); } setFilteredConfigs(filtered); }; const handleCreate = () => { setSelectedConfig(null); setIsModalOpen(true); }; const handleEdit = (config: DataCollectionConfig) => { setSelectedConfig(config); setIsModalOpen(true); }; const handleDelete = async (config: DataCollectionConfig) => { if (!confirm(`"${config.config_name}" 수집 설정을 삭제하시겠습니까?`)) { return; } try { await CollectionAPI.deleteCollectionConfig(config.id!); toast.success("수집 설정이 삭제되었습니다."); loadConfigs(); } catch (error) { console.error("수집 설정 삭제 오류:", error); toast.error("수집 설정 삭제에 실패했습니다."); } }; const handleExecute = async (config: DataCollectionConfig) => { try { await CollectionAPI.executeCollection(config.id!); toast.success(`"${config.config_name}" 수집 작업을 시작했습니다.`); } catch (error) { console.error("수집 작업 실행 오류:", error); toast.error("수집 작업 실행에 실패했습니다."); } }; const handleModalSave = () => { loadConfigs(); }; const getStatusBadge = (isActive: string) => { return isActive === "Y" ? ( 활성 ) : ( 비활성 ); }; const getTypeBadge = (type: string) => { const option = collectionTypeOptions.find(opt => opt.value === type); const colors = { full: "bg-blue-100 text-blue-800", incremental: "bg-purple-100 text-purple-800", delta: "bg-orange-100 text-orange-800", }; return ( {option?.label || type} ); }; return (
{/* 헤더 */}

수집 관리

외부 데이터베이스에서 데이터를 수집하는 설정을 관리합니다.

{/* 필터 및 검색 */} 필터 및 검색
setSearchTerm(e.target.value)} className="pl-10" />
{/* 수집 설정 목록 */} 수집 설정 목록 ({filteredConfigs.length}개) {isLoading ? (

수집 설정을 불러오는 중...

) : filteredConfigs.length === 0 ? (
{configs.length === 0 ? "수집 설정이 없습니다." : "검색 결과가 없습니다."}
) : ( 설정명 수집 타입 소스 테이블 대상 테이블 스케줄 상태 마지막 수집 작업 {filteredConfigs.map((config) => (
{config.config_name}
{config.description && (
{config.description}
)}
{getTypeBadge(config.collection_type)} {config.source_table} {config.target_table || "-"} {config.schedule_cron || "-"} {getStatusBadge(config.is_active)} {config.last_collected_at ? new Date(config.last_collected_at).toLocaleString() : "-"} handleEdit(config)}> 수정 handleExecute(config)} disabled={config.is_active !== "Y"} > 실행 handleDelete(config)}> 삭제
))}
)}
{/* 수집 설정 모달 */} setIsModalOpen(false)} onSave={handleModalSave} config={selectedConfig} />
); }