"use client"; import { useState, useEffect, useCallback } from "react"; import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { Badge } from "@/components/ui/badge"; import { AlertCircle, User } from "lucide-react"; import { UserHistory, UserHistoryResponse } from "@/types/userHistory"; import { userAPI } from "@/lib/api/user"; import { Pagination, PaginationInfo } from "@/components/common/Pagination"; import { USER_HISTORY_TABLE_COLUMNS, STATUS_BADGE_VARIANTS, CHANGE_TYPE_BADGE_VARIANTS } from "@/constants/userHistory"; interface UserHistoryModalProps { isOpen: boolean; onClose: () => void; userId: string; userName: string; } /** * 사용자 변경이력 모달 컴포넌트 (원본 JSP 로직 기반) */ export function UserHistoryModal({ isOpen, onClose, userId, userName }: UserHistoryModalProps) { const [historyList, setHistoryList] = useState([]); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); // 페이지네이션 상태 (원본 JSP와 동일) const [currentPage, setCurrentPage] = useState(1); const [pageSize] = useState(10); // 원본에서 하드코딩된 값 const [totalItems, setTotalItems] = useState(0); const [maxPageSize, setMaxPageSize] = useState(1); // 페이지네이션 정보 계산 const totalPages = Math.ceil(totalItems / pageSize); const paginationInfo: PaginationInfo = { currentPage, totalPages: totalPages || 1, totalItems, itemsPerPage: pageSize, startItem: totalItems > 0 ? (currentPage - 1) * pageSize + 1 : 0, endItem: Math.min(currentPage * pageSize, totalItems), }; // 변경이력 데이터 로드 (원본 JSP 로직 기반) const loadUserHistory = useCallback( async (pageToLoad: number) => { if (!userId) return; setIsLoading(true); setError(null); try { const params = { page: pageToLoad, countPerPage: pageSize, }; console.log("📊 사용자 변경이력 로드:", { userId, params }); const response: UserHistoryResponse = await userAPI.getHistory(userId, params); console.log("📊 백엔드 응답:", response); if (response && response.success && Array.isArray(response.data)) { const responseTotal = response.total || 0; // No 컬럼을 rowNum 값으로 설정 (페이징 고려) const mappedHistoryList = response.data.map((item, index) => ({ ...item, no: item.rowNum || responseTotal - (pageToLoad - 1) * pageSize - index, // rowNum 우선, 없으면 계산 })); setHistoryList(mappedHistoryList); setTotalItems(responseTotal); setMaxPageSize(response.maxPageSize || 1); } else if (response && response.success && (!response.data || response.data.length === 0)) { // 데이터가 비어있는 경우 console.log("📋 변경이력이 없습니다."); setHistoryList([]); setTotalItems(0); setMaxPageSize(1); } else { setHistoryList([]); setTotalItems(0); setMaxPageSize(1); setError(response?.message || "변경이력 조회에 실패했습니다."); } } catch (err) { console.error("사용자 변경이력 로드 오류:", err); setError(err instanceof Error ? err.message : "변경이력 조회 중 오류가 발생했습니다."); setHistoryList([]); setTotalItems(0); setMaxPageSize(1); } finally { setIsLoading(false); } }, [userId, pageSize], ); // 모달이 열릴 때마다 데이터 로드 useEffect(() => { if (isOpen && userId) { setCurrentPage(1); // 페이지 초기화 loadUserHistory(1); // 첫 페이지 로드 } }, [isOpen, userId, loadUserHistory]); // 페이지 변경 핸들러 (원본 JSP의 fnc_goPage와 유사) const handlePageChange = (page: number) => { setCurrentPage(page); loadUserHistory(page); }; // 상태에 따른 배지 색상 (원본 JSP 로직 기반) const getStatusBadgeVariant = (status: string) => { if (status === "active") return "default"; if (status === "inactive") return "secondary"; return STATUS_BADGE_VARIANTS[status as keyof typeof STATUS_BADGE_VARIANTS] || "outline"; }; // 변경 유형에 따른 배지 색상 const getChangeTypeBadgeVariant = (changeType: string) => { return CHANGE_TYPE_BADGE_VARIANTS[changeType as keyof typeof CHANGE_TYPE_BADGE_VARIANTS] || "outline"; }; // 상태 텍스트 변환 (원본 JSP 로직: ${info.STATUS eq 'active' ? '활성화':'비활성화'}) const getStatusText = (status: string) => { return status === "active" ? "활성화" : "비활성화"; }; // 날짜 포맷팅 const formatDate = (dateString: string) => { if (!dateString) return "-"; try { return new Date(dateString).toLocaleString("ko-KR", { year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", }); } catch { return dateString; } }; return ( 사용자 관리 이력
{userName} ({userId})의 변경이력을 조회합니다.
{/* 로딩 상태 */} {isLoading && (
로딩 중...
)} {/* 에러 상태 */} {error && !isLoading && (
{error}
)} {/* 변경이력 테이블 (원본 JSP 구조 기반) */} {!isLoading && !error && ( <>
{USER_HISTORY_TABLE_COLUMNS.map((column) => ( {column.label} ))} {historyList.length === 0 ? ( 조회된 정보가 없습니다. ) : ( historyList.map((history, index) => ( {history.no} {history.sabun || "-"} {history.userId || "-"} {history.userName || "-"} {history.deptName || "-"} {getStatusText(history.status || "")} {history.historyType || "-"} {history.writerName || "-"} {history.regDateTitle || formatDate(history.regDate || "")} )) )}
{/* 페이지네이션 (항상 표시) */}
{}} // 페이지 크기는 고정 (원본과 동일) />
총 {totalItems}건
)}
{/* 하단 버튼 */}
); }