"use client"; import { useState, useEffect } from "react"; import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { Badge } from "@/components/ui/badge"; import { LoadingSpinner } from "@/components/common/LoadingSpinner"; import { toast } from "sonner"; import { tableManagementApi } from "@/lib/api/tableManagement"; import { History, RefreshCw, Filter, X } from "lucide-react"; interface TableLogViewerProps { tableName: string; open: boolean; onOpenChange: (open: boolean) => void; } interface LogData { log_id: number; operation_type: string; original_id: string; changed_column?: string; old_value?: string; new_value?: string; changed_by?: string; changed_at: string; ip_address?: string; } export function TableLogViewer({ tableName, open, onOpenChange }: TableLogViewerProps) { const [logs, setLogs] = useState([]); const [loading, setLoading] = useState(false); const [total, setTotal] = useState(0); const [page, setPage] = useState(1); const [pageSize] = useState(20); const [totalPages, setTotalPages] = useState(0); // 필터 상태 const [operationType, setOperationType] = useState(""); const [startDate, setStartDate] = useState(""); const [endDate, setEndDate] = useState(""); const [changedBy, setChangedBy] = useState(""); const [originalId, setOriginalId] = useState(""); // 로그 데이터 로드 const loadLogs = async () => { if (!tableName) return; setLoading(true); try { const response = await tableManagementApi.getLogData(tableName, { page, size: pageSize, operationType: operationType || undefined, startDate: startDate || undefined, endDate: endDate || undefined, changedBy: changedBy || undefined, originalId: originalId || undefined, }); if (response.success && response.data) { setLogs(response.data.data); setTotal(response.data.total); setTotalPages(response.data.totalPages); } else { toast.error(response.message || "로그 데이터를 불러올 수 없습니다."); } } catch (error) { toast.error("로그 데이터 조회 중 오류가 발생했습니다."); } finally { setLoading(false); } }; // 다이얼로그가 열릴 때 로그 로드 useEffect(() => { if (open && tableName) { loadLogs(); } }, [open, tableName, page]); // 필터 초기화 const resetFilters = () => { setOperationType(""); setStartDate(""); setEndDate(""); setChangedBy(""); setOriginalId(""); setPage(1); }; // 작업 타입에 따른 뱃지 색상 const getOperationBadge = (type: string) => { switch (type) { case "INSERT": return 추가; case "UPDATE": return 수정; case "DELETE": return 삭제; default: return {type}; } }; // 날짜 포맷팅 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", second: "2-digit", }); }; return ( {tableName} - 변경 이력 {/* 필터 영역 */}

필터

setStartDate(e.target.value)} />
setEndDate(e.target.value)} />
setChangedBy(e.target.value)} />
setOriginalId(e.target.value)} />
{/* 로그 테이블 */}
{loading ? (
) : logs.length === 0 ? (
변경 이력이 없습니다.
) : ( 작업 원본 ID 변경 컬럼 변경 전 변경 후 변경자 변경 시각 IP {logs.map((log) => ( {getOperationBadge(log.operation_type)} {log.original_id} {log.changed_column || "-"} {log.old_value || "-"} {log.new_value || "-"} {log.changed_by || "system"} {formatDate(log.changed_at)} {log.ip_address || "-"} ))}
)}
{/* 페이지네이션 */}
전체 {total}건 (페이지 {page} / {totalPages})
); }