import { useState, useEffect } from 'react'; import type { UserDetail, CreateUserRequest, UpdateUserRequest } from '../../types/user'; import type { Tenant } from '../../types/tenant'; import { getUsers, createUser, updateUser, deactivateUser } from '../../services/userService'; import { getTenants } from '../../services/tenantService'; const ROLE_BADGE: Record = { ADMIN: 'bg-red-100 text-red-800', MANAGER: 'bg-orange-100 text-orange-800', USER: 'bg-blue-100 text-blue-800', VIEWER: 'bg-gray-100 text-gray-800', }; const UsersPage = () => { const [users, setUsers] = useState([]); const [tenants, setTenants] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); const [editingUser, setEditingUser] = useState(null); const [loginId, setLoginId] = useState(''); const [password, setPassword] = useState(''); const [userName, setUserName] = useState(''); const [email, setEmail] = useState(''); const [tenantId, setTenantId] = useState(''); const [role, setRole] = useState('USER'); const [isActive, setIsActive] = useState(true); const fetchData = async () => { try { setLoading(true); const [usersRes, tenantsRes] = await Promise.all([getUsers(), getTenants()]); if (usersRes.success && usersRes.data) { setUsers(usersRes.data); } if (tenantsRes.success && tenantsRes.data) { setTenants(tenantsRes.data); } } catch { setError('데이터를 불러오는데 실패했습니다.'); } finally { setLoading(false); } }; useEffect(() => { fetchData(); }, []); const handleOpenCreate = () => { setEditingUser(null); setLoginId(''); setPassword(''); setUserName(''); setEmail(''); setTenantId(''); setRole('USER'); setIsActive(true); setIsModalOpen(true); }; const handleOpenEdit = (user: UserDetail) => { setEditingUser(user); setLoginId(user.loginId); setPassword(''); setUserName(user.userName); setEmail(user.email || ''); setTenantId(user.tenantId ? String(user.tenantId) : ''); setRole(user.role); setIsActive(user.isActive); setIsModalOpen(true); }; const handleCloseModal = () => { setIsModalOpen(false); setEditingUser(null); setError(null); }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(null); try { if (editingUser) { const req: UpdateUserRequest = { tenantId: tenantId ? Number(tenantId) : undefined, userName, email: email || undefined, role, password: password || undefined, isActive, }; const res = await updateUser(editingUser.userId, req); if (!res.success) { setError(res.message || '사용자 수정에 실패했습니다.'); return; } } else { const req: CreateUserRequest = { tenantId: tenantId ? Number(tenantId) : undefined, loginId, password, userName, email: email || undefined, role, }; const res = await createUser(req); if (!res.success) { setError(res.message || '사용자 생성에 실패했습니다.'); return; } } handleCloseModal(); await fetchData(); } catch { setError(editingUser ? '사용자 수정에 실패했습니다.' : '사용자 생성에 실패했습니다.'); } }; const handleDeactivate = async (user: UserDetail) => { if (!confirm(`'${user.userName}' 사용자를 비활성화하시겠습니까?`)) return; try { const res = await deactivateUser(user.userId); if (!res.success) { setError(res.message || '사용자 비활성화에 실패했습니다.'); return; } await fetchData(); } catch { setError('사용자 비활성화에 실패했습니다.'); } }; if (loading) { return
로딩 중...
; } return (

Users

{error && !isModalOpen && (
{error}
)}
{users.map((user) => ( ))} {users.length === 0 && ( )}
Login ID Name Email Tenant Role Active Last Login Actions
{user.loginId} {user.userName} {user.email || '-'} {user.tenantName || '-'} {user.role} {user.isActive ? 'Active' : 'Inactive'} {user.lastLoginAt ? new Date(user.lastLoginAt).toLocaleString() : '-'} {user.isActive && ( )}
등록된 사용자가 없습니다.
{isModalOpen && (

{editingUser ? '사용자 수정' : '사용자 생성'}

{error && (
{error}
)}
setLoginId(e.target.value)} disabled={!!editingUser} required className="w-full border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 rounded-lg px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:outline-none disabled:bg-gray-100 disabled:text-gray-500 dark:disabled:bg-gray-600 dark:disabled:text-gray-400" />
setPassword(e.target.value)} required={!editingUser} placeholder={editingUser ? '변경 시 입력' : ''} className="w-full border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 rounded-lg px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:outline-none" />
setUserName(e.target.value)} required className="w-full border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 rounded-lg px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:outline-none" />
setEmail(e.target.value)} className="w-full border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 rounded-lg px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:outline-none" />
{editingUser && (
setIsActive(e.target.checked)} className="rounded" />
)}
)}
); }; export default UsersPage;