177 lines
4.7 KiB
TypeScript
177 lines
4.7 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import { useUserManagement } from "@/hooks/useUserManagement";
|
|
import { UserToolbar } from "./UserToolbar";
|
|
import { UserTable } from "./UserTable";
|
|
import { Pagination } from "@/components/common/Pagination";
|
|
import { UserPasswordResetModal } from "./UserPasswordResetModal";
|
|
import { UserFormModal } from "./UserFormModal";
|
|
|
|
/**
|
|
* 사용자 관리 메인 컴포넌트
|
|
* - 원본 Spring + JSP 코드 패턴 기반 REST API 연동
|
|
* - 실제 데이터베이스와 연동되어 작동
|
|
*/
|
|
export function UserManagement() {
|
|
const {
|
|
// 데이터
|
|
users,
|
|
searchFilter,
|
|
isLoading,
|
|
isSearching,
|
|
error,
|
|
paginationInfo,
|
|
|
|
// 검색 기능
|
|
updateSearchFilter,
|
|
|
|
// 페이지네이션
|
|
handlePageChange,
|
|
handlePageSizeChange,
|
|
|
|
// 액션 핸들러
|
|
handleStatusToggle,
|
|
|
|
// 유틸리티
|
|
clearError,
|
|
refreshData,
|
|
} = useUserManagement();
|
|
|
|
// 비밀번호 초기화 모달 상태
|
|
const [passwordResetModal, setPasswordResetModal] = useState({
|
|
isOpen: false,
|
|
userId: null as string | null,
|
|
userName: null as string | null,
|
|
});
|
|
|
|
// 사용자 등록/수정 모달 상태
|
|
const [userFormModal, setUserFormModal] = useState({
|
|
isOpen: false,
|
|
editingUser: null as any | null,
|
|
});
|
|
|
|
// 사용자 등록 핸들러
|
|
const handleCreateUser = () => {
|
|
setUserFormModal({
|
|
isOpen: true,
|
|
editingUser: null,
|
|
});
|
|
};
|
|
|
|
// 사용자 수정 핸들러
|
|
const handleEditUser = (user: any) => {
|
|
setUserFormModal({
|
|
isOpen: true,
|
|
editingUser: user,
|
|
});
|
|
};
|
|
|
|
// 사용자 등록/수정 모달 닫기
|
|
const handleUserFormClose = () => {
|
|
setUserFormModal({
|
|
isOpen: false,
|
|
editingUser: null,
|
|
});
|
|
};
|
|
|
|
// 사용자 등록/수정 성공 핸들러
|
|
const handleUserFormSuccess = () => {
|
|
refreshData(); // 목록 새로고침
|
|
handleUserFormClose();
|
|
};
|
|
|
|
// 비밀번호 초기화 핸들러
|
|
const handlePasswordReset = (userId: string, userName: string) => {
|
|
setPasswordResetModal({
|
|
isOpen: true,
|
|
userId,
|
|
userName,
|
|
});
|
|
};
|
|
|
|
// 비밀번호 초기화 모달 닫기
|
|
const handlePasswordResetClose = () => {
|
|
setPasswordResetModal({
|
|
isOpen: false,
|
|
userId: null,
|
|
userName: null,
|
|
});
|
|
};
|
|
|
|
// 비밀번호 초기화 성공 핸들러
|
|
const handlePasswordResetSuccess = () => {
|
|
// refreshData(); // 비밀번호 변경은 목록에 영향을 주지 않으므로 새로고침 불필요
|
|
handlePasswordResetClose();
|
|
};
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
{/* 툴바 - 검색, 필터, 등록 버튼 */}
|
|
<UserToolbar
|
|
searchFilter={searchFilter}
|
|
totalCount={paginationInfo.totalItems} // 전체 총 개수
|
|
isSearching={isSearching}
|
|
onSearchChange={updateSearchFilter}
|
|
onCreateClick={handleCreateUser}
|
|
/>
|
|
|
|
{/* 에러 메시지 */}
|
|
{error && (
|
|
<div className="border-destructive/50 bg-destructive/10 rounded-lg border p-4">
|
|
<div className="flex items-center justify-between">
|
|
<p className="text-destructive text-sm font-semibold">오류가 발생했습니다</p>
|
|
<button
|
|
onClick={clearError}
|
|
className="text-destructive hover:text-destructive/80 transition-colors"
|
|
aria-label="에러 메시지 닫기"
|
|
>
|
|
✕
|
|
</button>
|
|
</div>
|
|
<p className="text-destructive/80 mt-1.5 text-sm">{error}</p>
|
|
</div>
|
|
)}
|
|
|
|
{/* 사용자 목록 테이블 */}
|
|
<UserTable
|
|
users={users}
|
|
isLoading={isLoading}
|
|
paginationInfo={paginationInfo}
|
|
onStatusToggle={handleStatusToggle}
|
|
onPasswordReset={handlePasswordReset}
|
|
onEdit={handleEditUser}
|
|
/>
|
|
|
|
{/* 페이지네이션 */}
|
|
{!isLoading && users.length > 0 && (
|
|
<Pagination
|
|
paginationInfo={paginationInfo}
|
|
onPageChange={handlePageChange}
|
|
onPageSizeChange={handlePageSizeChange}
|
|
showPageSizeSelector={true}
|
|
pageSizeOptions={[10, 20, 50, 100]}
|
|
className="mt-6"
|
|
/>
|
|
)}
|
|
|
|
{/* 사용자 등록/수정 모달 */}
|
|
<UserFormModal
|
|
isOpen={userFormModal.isOpen}
|
|
onClose={handleUserFormClose}
|
|
onSuccess={handleUserFormSuccess}
|
|
editingUser={userFormModal.editingUser}
|
|
/>
|
|
|
|
{/* 비밀번호 초기화 모달 */}
|
|
<UserPasswordResetModal
|
|
isOpen={passwordResetModal.isOpen}
|
|
onClose={handlePasswordResetClose}
|
|
userId={passwordResetModal.userId}
|
|
userName={passwordResetModal.userName}
|
|
onSuccess={handlePasswordResetSuccess}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|