import { Key, History, Edit } from "lucide-react"; import { useState } from "react"; import { User } from "@/types/user"; import { Button } from "@/components/ui/button"; import { Switch } from "@/components/ui/switch"; import { PaginationInfo } from "@/components/common/Pagination"; import { ResponsiveDataView, RDVColumn, RDVCardField } from "@/components/common/ResponsiveDataView"; import { UserStatusConfirmDialog } from "./UserStatusConfirmDialog"; import { UserHistoryModal } from "./UserHistoryModal"; interface UserTableProps { users: User[]; isLoading: boolean; paginationInfo: PaginationInfo; onStatusToggle: (user: User, newStatus: string) => void; onPasswordReset: (userId: string, userName: string) => void; onEdit: (user: User) => void; } /** * 사용자 목록 테이블 컴포넌트 */ export function UserTable({ users, isLoading, paginationInfo, onStatusToggle, onPasswordReset, onEdit, }: UserTableProps) { // 확인 모달 상태 관리 const [confirmDialog, setConfirmDialog] = useState<{ isOpen: boolean; user: User | null; newStatus: string; }>({ isOpen: false, user: null, newStatus: "", }); // 히스토리 모달 상태 관리 const [historyModal, setHistoryModal] = useState<{ isOpen: boolean; userId: string; userName: string; }>({ isOpen: false, userId: "", userName: "", }); // NO 컬럼 계산 함수 (페이지네이션 고려) const getRowNumber = (index: number) => { return paginationInfo.startItem + index; }; // 날짜 포맷팅 함수 const formatDate = (dateString: string) => { if (!dateString) return "-"; return dateString.split(" ")[0]; }; // 상태 토글 핸들러 (확인 모달 표시) const handleStatusToggle = (user: User, checked: boolean) => { const newStatus = checked ? "active" : "inactive"; setConfirmDialog({ isOpen: true, user, newStatus, }); }; // 상태 변경 확인 const handleConfirmStatusChange = () => { if (confirmDialog.user) { onStatusToggle(confirmDialog.user, confirmDialog.newStatus); } setConfirmDialog({ isOpen: false, user: null, newStatus: "" }); }; // 상태 변경 취소 const handleCancelStatusChange = () => { setConfirmDialog({ isOpen: false, user: null, newStatus: "" }); }; // 변경이력 모달 열기 const handleOpenHistoryModal = (user: User) => { setHistoryModal({ isOpen: true, userId: user.userId, userName: user.userName || user.userId, }); }; // 변경이력 모달 닫기 const handleCloseHistoryModal = () => { setHistoryModal({ isOpen: false, userId: "", userName: "", }); }; // 데스크톱 테이블 컬럼 정의 const columns: RDVColumn[] = [ { key: "no", label: "No", width: "60px", render: (_value, _row, index) => ( {getRowNumber(index)} ), }, { key: "sabun", label: "사번", width: "80px", hideOnMobile: true, render: (value) => {value || "-"}, }, { key: "companyCode", label: "회사", width: "120px", hideOnMobile: true, render: (value) => {value || "-"}, }, { key: "deptName", label: "부서명", width: "120px", hideOnMobile: true, render: (value) => {value || "-"}, }, { key: "positionName", label: "직책", width: "100px", hideOnMobile: true, render: (value) => {value || "-"}, }, { key: "userId", label: "사용자 ID", width: "120px", hideOnMobile: true, render: (value) => {value}, }, { key: "userName", label: "사용자명", width: "100px", hideOnMobile: true, render: (value) => {value}, }, { key: "tel", label: "전화번호", width: "120px", hideOnMobile: true, render: (_value, row) => {row.tel || row.cellPhone || "-"}, }, { key: "email", label: "이메일", width: "200px", hideOnMobile: true, className: "max-w-[200px] truncate", render: (value, row) => ( {value || "-"} ), }, { key: "regDate", label: "등록일", width: "100px", hideOnMobile: true, render: (value) => {formatDate(value || "")}, }, { key: "status", label: "상태", width: "120px", hideOnMobile: true, render: (_value, row) => (
handleStatusToggle(row, checked)} aria-label={`${row.userName} 상태 토글`} />
), }, ]; // 모바일 카드 필드 정의 const cardFields: RDVCardField[] = [ { label: "사번", render: (user) => {user.sabun || "-"}, hideEmpty: true, }, { label: "회사", render: (user) => {user.companyCode || ""}, hideEmpty: true, }, { label: "부서", render: (user) => {user.deptName || ""}, hideEmpty: true, }, { label: "직책", render: (user) => {user.positionName || ""}, hideEmpty: true, }, { label: "연락처", render: (user) => {user.tel || user.cellPhone || ""}, hideEmpty: true, }, { label: "이메일", render: (user) => {user.email || ""}, hideEmpty: true, }, { label: "등록일", render: (user) => {formatDate(user.regDate || "")}, }, ]; return ( <> data={users} columns={columns} keyExtractor={(u) => u.userId} isLoading={isLoading} emptyMessage="등록된 사용자가 없습니다." skeletonCount={10} cardTitle={(u) => u.userName || ""} cardSubtitle={(u) => {u.userId}} cardHeaderRight={(u) => ( handleStatusToggle(u, checked)} aria-label={`${u.userName} 상태 토글`} /> )} cardFields={cardFields} actionsLabel="작업" actionsWidth="200px" renderActions={(user) => ( <> )} /> {/* 상태 변경 확인 모달 */} {/* 사용자 변경이력 모달 */} ); }