import { useCallback, useEffect, useState } from 'react'; import type { Role, User } from '../../types'; import { api } from '../../utils/api'; type FilterStatus = 'ALL' | 'PENDING' | 'ACTIVE' | 'REJECTED' | 'DISABLED'; export function UserManagement() { const [users, setUsers] = useState([]); const [roles, setRoles] = useState([]); const [filter, setFilter] = useState('ALL'); const [loading, setLoading] = useState(true); const [roleModalUser, setRoleModalUser] = useState(null); const [selectedRoleIds, setSelectedRoleIds] = useState([]); const fetchData = useCallback(async () => { try { const [usersData, rolesData] = await Promise.all([ api.get('/admin/users'), api.get('/admin/roles'), ]); setUsers(usersData); setRoles(rolesData); } catch { // API 미연동 시 빈 배열 유지 } finally { setLoading(false); } }, []); useEffect(() => { fetchData(); }, [fetchData]); const handleAction = async (userId: number, action: 'approve' | 'reject' | 'disable') => { try { await api.put(`/admin/users/${userId}/${action}`, {}); fetchData(); } catch { // 에러 처리 } }; const handleToggleAdmin = async (userId: number, isAdmin: boolean) => { try { if (isAdmin) { await api.delete(`/admin/users/${userId}/admin`); } else { await api.post(`/admin/users/${userId}/admin`); } fetchData(); } catch { // 에러 처리 } }; const handleRoleSave = async () => { if (!roleModalUser) return; try { await api.put(`/admin/users/${roleModalUser.id}/roles`, { roleIds: selectedRoleIds }); setRoleModalUser(null); fetchData(); } catch { // 에러 처리 } }; const filteredUsers = filter === 'ALL' ? users : users.filter((u) => u.status === filter); const statusBadge = (status: User['status']) => { const styles: Record = { ACTIVE: 'bg-success/10 text-success', PENDING: 'bg-warning/10 text-warning', REJECTED: 'bg-danger/10 text-danger', DISABLED: 'bg-bg-tertiary text-text-muted', }; const labels: Record = { ACTIVE: '활성', PENDING: '대기', REJECTED: '거절', DISABLED: '비활성', }; return ( {labels[status]} ); }; if (loading) { return (
); } return (

사용자 관리

{/* 필터 */}
{(['ALL', 'PENDING', 'ACTIVE', 'REJECTED', 'DISABLED'] as FilterStatus[]).map((s) => ( ))}
{/* 테이블 */}
{filteredUsers.length === 0 ? ( ) : ( filteredUsers.map((user) => ( )) )}
사용자 상태 가입일 작업
{users.length === 0 ? '등록된 사용자가 없습니다.' : '해당 상태의 사용자가 없습니다.'}
{user.avatarUrl ? ( ) : (
{user.name[0]}
)}

{user.name} {user.isAdmin && ( ADMIN )}

{user.email}

{statusBadge(user.status)} {user.roles.length > 0 ? user.roles.map((r) => r.name).join(', ') : 미배정} {new Date(user.createdAt).toLocaleDateString('ko-KR')}
{user.status === 'PENDING' && ( <> )} {user.status === 'ACTIVE' && ( )} {user.status === 'ACTIVE' && ( )}
{/* 롤 배정 모달 */} {roleModalUser && (

롤 배정 — {roleModalUser.name}

{roles.map((role) => ( ))} {roles.length === 0 && (

등록된 롤이 없습니다.

)}
)}
); }