// components/permissions/permission-assignment-manager.tsx (업데이트) "use client"; import { useState, useEffect } from "react"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Users, User, Plus, X, Search, Shield, Loader2 } from "lucide-react"; import { toast } from "sonner"; import { getPermissionAssignments, assignPermissionToRoles, assignPermissionToUsers, removePermissionFromRole, removePermissionFromUser, } from "@/lib/permissions/permission-assignment-actions"; import { cn } from "@/lib/utils"; interface Permission { id: number; permissionKey: string; name: string; description?: string; permissionType: string; resource: string; action: string; scope: string; menuPath?: string; } interface AssignedRole { id: number; name: string; domain: string; userCount: number; } interface AssignedUser { id: number; name: string; email: string; imageUrl?: string; domain: string; isGrant: boolean; reason?: string; } export function PermissionAssignmentManager() { const [permissions, setPermissions] = useState([]); const [selectedPermission, setSelectedPermission] = useState(null); const [assignedRoles, setAssignedRoles] = useState([]); const [assignedUsers, setAssignedUsers] = useState([]); const [searchQuery, setSearchQuery] = useState(""); const [loading, setLoading] = useState(false); useEffect(() => { loadPermissions(); }, []); useEffect(() => { if (selectedPermission) { loadAssignments(selectedPermission.id); } }, [selectedPermission]); const loadPermissions = async () => { setLoading(true); try { const data = await getPermissionAssignments(); setPermissions(data.permissions); } catch (error) { toast.error("권한 목록을 불러오는데 실패했습니다."); } finally { setLoading(false); } }; const loadAssignments = async (permissionId: number) => { try { const data = await getPermissionAssignments(permissionId); setAssignedRoles(data.roles); setAssignedUsers(data.users); } catch (error) { toast.error("할당 정보를 불러오는데 실패했습니다."); } }; const handleRemoveRole = async (roleId: number) => { if (!selectedPermission) return; try { await removePermissionFromRole(selectedPermission.id, roleId); toast.success("역할에서 권한이 제거되었습니다."); loadAssignments(selectedPermission.id); } catch (error) { toast.error("권한 제거에 실패했습니다."); } }; const handleRemoveUser = async (userId: number) => { if (!selectedPermission) return; try { await removePermissionFromUser(selectedPermission.id, userId); toast.success("사용자에서 권한이 제거되었습니다."); loadAssignments(selectedPermission.id); } catch (error) { toast.error("권한 제거에 실패했습니다."); } }; // 권한 필터링 const filteredPermissions = permissions.filter(p => p.name.toLowerCase().includes(searchQuery.toLowerCase()) || p.permissionKey.toLowerCase().includes(searchQuery.toLowerCase()) || p.resource.toLowerCase().includes(searchQuery.toLowerCase()) ); // 리소스별 권한 그룹화 const groupedPermissions = filteredPermissions.reduce((acc, perm) => { const group = perm.resource; if (!acc[group]) acc[group] = []; acc[group].push(perm); return acc; }, {} as Record); return (
{/* 권한 목록 */} 권한 목록 권한을 선택하여 할당을 관리하세요.
{/* 검색 */}
setSearchQuery(e.target.value)} className="pl-8" />
{/* 권한 목록 */} {loading ? (
) : (
{Object.entries(groupedPermissions).map(([resource, perms]) => (

{resource}

{perms.map(permission => ( ))}
))}
)}
{/* 할당 관리 */} {selectedPermission ? ( {selectedPermission.name}
{selectedPermission.permissionKey} {selectedPermission.permissionType} {selectedPermission.scope}
역할 ({assignedRoles.length}) 사용자 ({assignedUsers.length})
{assignedRoles.map((role) => (
{role.name}
{role.domain} • {role.userCount}명 사용자
))}
{assignedUsers.map((user) => (
{user.name[0]}
{user.name}
{user.email}
{user.isGrant ? ( 부여 ) : ( 제한 )}
))}
) : (

권한을 선택하면 할당 정보가 표시됩니다.

)}
); }