"use client"; import React, { useState, useEffect } from "react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Plus, Search, RefreshCw, Database } from "lucide-react"; import { toast } from "sonner"; import { useRouter } from "next/navigation"; import { BatchAPI, BatchConfig, BatchMapping, } from "@/lib/api/batch"; import BatchCard from "@/components/admin/BatchCard"; import { ScrollToTop } from "@/components/common/ScrollToTop"; export default function BatchManagementPage() { const router = useRouter(); // 상태 관리 const [batchConfigs, setBatchConfigs] = useState([]); const [loading, setLoading] = useState(false); const [searchTerm, setSearchTerm] = useState(""); const [currentPage, setCurrentPage] = useState(1); const [totalPages, setTotalPages] = useState(1); const [executingBatch, setExecutingBatch] = useState(null); const [isBatchTypeModalOpen, setIsBatchTypeModalOpen] = useState(false); // 페이지 로드 시 배치 목록 조회 useEffect(() => { loadBatchConfigs(); }, [currentPage, searchTerm]); // 배치 설정 목록 조회 const loadBatchConfigs = async () => { setLoading(true); try { const response = await BatchAPI.getBatchConfigs({ page: currentPage, limit: 10, search: searchTerm || undefined, }); if (response.success && response.data) { setBatchConfigs(response.data); if (response.pagination) { setTotalPages(response.pagination.totalPages); } } else { setBatchConfigs([]); } } catch (error) { console.error("배치 목록 조회 실패:", error); toast.error("배치 목록을 불러오는데 실패했습니다."); setBatchConfigs([]); } finally { setLoading(false); } }; // 배치 수동 실행 const executeBatch = async (batchId: number) => { setExecutingBatch(batchId); try { const response = await BatchAPI.executeBatchConfig(batchId); if (response.success) { toast.success(`배치가 성공적으로 실행되었습니다! (처리: ${response.data?.totalRecords}개, 성공: ${response.data?.successRecords}개)`); } else { toast.error("배치 실행에 실패했습니다."); } } catch (error) { console.error("배치 실행 실패:", error); toast.error("배치 실행 중 오류가 발생했습니다."); } finally { setExecutingBatch(null); } }; // 배치 활성화/비활성화 토글 const toggleBatchStatus = async (batchId: number, currentStatus: string) => { console.log("🔄 배치 상태 변경 시작:", { batchId, currentStatus }); try { const newStatus = currentStatus === 'Y' ? 'N' : 'Y'; console.log("📝 새로운 상태:", newStatus); const result = await BatchAPI.updateBatchConfig(batchId, { isActive: newStatus }); console.log("✅ API 호출 성공:", result); toast.success(`배치가 ${newStatus === 'Y' ? '활성화' : '비활성화'}되었습니다.`); loadBatchConfigs(); // 목록 새로고침 } catch (error) { console.error("❌ 배치 상태 변경 실패:", error); toast.error("배치 상태 변경에 실패했습니다."); } }; // 배치 삭제 const deleteBatch = async (batchId: number, batchName: string) => { if (!confirm(`'${batchName}' 배치를 삭제하시겠습니까?`)) { return; } try { await BatchAPI.deleteBatchConfig(batchId); toast.success("배치가 삭제되었습니다."); loadBatchConfigs(); // 목록 새로고침 } catch (error) { console.error("배치 삭제 실패:", error); toast.error("배치 삭제에 실패했습니다."); } }; // 검색 처리 const handleSearch = (value: string) => { setSearchTerm(value); setCurrentPage(1); // 검색 시 첫 페이지로 이동 }; // 매핑 정보 요약 생성 const getMappingSummary = (mappings: BatchMapping[]) => { if (!mappings || mappings.length === 0) { return "매핑 없음"; } const tableGroups = new Map(); mappings.forEach(mapping => { const key = `${mapping.from_table_name} → ${mapping.to_table_name}`; tableGroups.set(key, (tableGroups.get(key) || 0) + 1); }); const summaries = Array.from(tableGroups.entries()).map(([key, count]) => `${key} (${count}개 컬럼)` ); return summaries.join(", "); }; // 배치 추가 버튼 클릭 핸들러 const handleCreateBatch = () => { setIsBatchTypeModalOpen(true); }; // 배치 타입 선택 핸들러 const handleBatchTypeSelect = (type: 'db-to-db' | 'restapi-to-db') => { console.log("배치 타입 선택:", type); setIsBatchTypeModalOpen(false); if (type === 'db-to-db') { // 기존 DB → DB 배치 생성 페이지로 이동 console.log("DB → DB 페이지로 이동:", '/admin/batchmng/create'); router.push('/admin/batchmng/create'); } else if (type === 'restapi-to-db') { // 새로운 REST API 배치 페이지로 이동 console.log("REST API → DB 페이지로 이동:", '/admin/batch-management-new'); try { router.push('/admin/batch-management-new'); console.log("라우터 push 실행 완료"); } catch (error) { console.error("라우터 push 오류:", error); // 대안: window.location 사용 window.location.href = '/admin/batch-management-new'; } } }; return (
{/* 페이지 헤더 */}

배치 관리

데이터베이스 간 배치 작업을 관리합니다.

{/* 검색 및 액션 영역 */}
{/* 검색 영역 */}
handleSearch(e.target.value)} className="h-10 pl-10 text-sm" />
{/* 액션 버튼 영역 */}
총{" "} {batchConfigs.length.toLocaleString()} {" "} 건
{/* 배치 목록 */} {batchConfigs.length === 0 ? (

배치가 없습니다

{searchTerm ? "검색 결과가 없습니다." : "새로운 배치를 추가해보세요."}

{!searchTerm && ( )}
) : (
{batchConfigs.map((batch) => ( { toggleBatchStatus(batchId, currentStatus); }} onEdit={(batchId) => router.push(`/admin/batchmng/edit/${batchId}`)} onDelete={deleteBatch} getMappingSummary={getMappingSummary} /> ))}
)} {/* 페이지네이션 */} {totalPages > 1 && (
{Array.from({ length: Math.min(5, totalPages) }, (_, i) => { const pageNum = i + 1; return ( ); })}
)} {/* 배치 타입 선택 모달 */} {isBatchTypeModalOpen && (

배치 타입 선택

{/* DB → DB */} {/* REST API → DB */}
)}
{/* Scroll to Top 버튼 */}
); }