UNPKG

@restnfeel/agentc-starter-kit

Version:

한국어 기업용 CMS 모듈 - Task Master AI와 함께 빠르게 웹사이트를 구현할 수 있는 재사용 가능한 컴포넌트 시스템

344 lines (290 loc) 8.48 kB
"use client"; import { useSession } from "next-auth/react"; import { useMemo } from "react"; import { UserRole } from "./middleware"; import { Permission, hasPermission, hasAllPermissions, hasAnyPermission, hasResourcePermission, canManageUser, isHigherRole, shouldShowComponent, filterMenuItems, type MenuItem, } from "./rbac"; /** * 현재 사용자의 인증 상태와 권한 정보를 제공하는 훅 */ export function useAuth() { const { data: session, status } = useSession(); const user = useMemo(() => { if (!session?.user) return null; return { id: session.user.id, email: session.user.email, name: session.user.name, image: session.user.image, role: session.user.role as UserRole, }; }, [session]); const isAuthenticated = status === "authenticated" && !!user; const isLoading = status === "loading"; return { user, isAuthenticated, isLoading, session, status, }; } /** * 권한 확인을 위한 훅 */ export function usePermissions() { const { user } = useAuth(); const checkPermission = useMemo(() => { if (!user) return () => false; return (permission: Permission) => hasPermission(user.role, permission); }, [user]); const checkAllPermissions = useMemo(() => { if (!user) return () => false; return (permissions: Permission[]) => hasAllPermissions(user.role, permissions); }, [user]); const checkAnyPermission = useMemo(() => { if (!user) return () => false; return (permissions: Permission[]) => hasAnyPermission(user.role, permissions); }, [user]); const checkResourcePermission = useMemo(() => { if (!user) return () => false; return ( resource: | "USER" | "SITE" | "SECTION" | "TEMPLATE" | "FILE" | "SYSTEM" | "TENANT", action: | "create" | "read" | "update" | "delete" | "publish" | "manage_roles" | "upload" ) => hasResourcePermission(user.role, resource, action); }, [user]); const checkCanManageUser = useMemo(() => { if (!user) return () => false; return (targetRole: UserRole) => canManageUser(user.role, targetRole); }, [user]); const checkIsHigherRole = useMemo(() => { if (!user) return () => false; return (targetRole: UserRole) => isHigherRole(user.role, targetRole); }, [user]); return { hasPermission: checkPermission, hasAllPermissions: checkAllPermissions, hasAnyPermission: checkAnyPermission, hasResourcePermission: checkResourcePermission, canManageUser: checkCanManageUser, isHigherRole: checkIsHigherRole, userRole: user?.role, }; } /** * 관리자 권한 확인 훅 */ export function useIsAdmin() { const { user } = useAuth(); return user?.role === UserRole.ADMIN; } /** * 편집자 이상 권한 확인 훅 */ export function useIsEditor() { const { user } = useAuth(); return user?.role === UserRole.ADMIN || user?.role === UserRole.EDITOR; } /** * 인증된 사용자 확인 훅 */ export function useIsAuthenticated() { const { user } = useAuth(); return ( user?.role === UserRole.ADMIN || user?.role === UserRole.EDITOR || user?.role === UserRole.VIEWER ); } /** * 특정 권한이 있는 경우에만 컴포넌트를 렌더링하는 훅 */ export function usePermissionGuard(requiredPermissions: Permission[]) { const { user } = useAuth(); const canRender = useMemo(() => { if (!user) return false; return shouldShowComponent(user.role, requiredPermissions); }, [user, requiredPermissions]); return canRender; } /** * 권한 기반 메뉴 필터링 훅 */ export function useFilteredMenu(menuItems: MenuItem[]) { const { user } = useAuth(); const filteredMenu = useMemo(() => { if (!user) return []; return filterMenuItems(menuItems, user.role); }, [menuItems, user]); return filteredMenu; } /** * 사용자 역할별 대시보드 설정 훅 */ export function useDashboardConfig() { const { user } = useAuth(); const dashboardConfig = useMemo(() => { if (!user) return null; switch (user.role) { case UserRole.ADMIN: return { title: "관리자 대시보드", sections: ["users", "sites", "templates", "system", "analytics"], quickActions: [ "create-user", "create-site", "system-settings", "backup", ], widgets: [ "user-stats", "site-stats", "system-health", "recent-activity", ], }; case UserRole.EDITOR: return { title: "편집자 대시보드", sections: ["sites", "sections", "templates", "files"], quickActions: ["create-site", "create-section", "upload-file"], widgets: [ "my-sites", "recent-edits", "draft-content", "published-content", ], }; case UserRole.VIEWER: return { title: "뷰어 대시보드", sections: ["sites", "sections", "templates"], quickActions: ["view-sites", "search-content"], widgets: ["favorite-sites", "recent-views", "bookmarks"], }; case UserRole.GUEST: return { title: "게스트 대시보드", sections: ["public-sites"], quickActions: ["browse-sites"], widgets: ["featured-sites", "popular-content"], }; default: return null; } }, [user]); return dashboardConfig; } /** * 권한 기반 폼 필드 표시 훅 */ export function useFormPermissions() { const { hasPermission } = usePermissions(); const getFieldPermissions = useMemo(() => { return (fieldPermissions: Record<string, Permission[]>) => { const allowedFields: Record<string, boolean> = {}; Object.entries(fieldPermissions).forEach(([field, permissions]) => { allowedFields[field] = permissions.some((permission) => hasPermission(permission) ); }); return allowedFields; }; }, [hasPermission]); return { getFieldPermissions }; } /** * 권한 기반 액션 버튼 표시 훅 */ export function useActionPermissions() { const { hasPermission } = usePermissions(); const getActionPermissions = useMemo(() => { return (actions: Record<string, Permission>) => { const allowedActions: Record<string, boolean> = {}; Object.entries(actions).forEach(([action, permission]) => { allowedActions[action] = hasPermission(permission); }); return allowedActions; }; }, [hasPermission]); return { getActionPermissions }; } /** * 리소스별 CRUD 권한 확인 훅 */ export function useResourcePermissions( resource: | "USER" | "SITE" | "SECTION" | "TEMPLATE" | "FILE" | "SYSTEM" | "TENANT" ) { const { hasResourcePermission } = usePermissions(); const permissions = useMemo( () => ({ canCreate: hasResourcePermission(resource, "create"), canRead: hasResourcePermission(resource, "read"), canUpdate: hasResourcePermission(resource, "update"), canDelete: hasResourcePermission(resource, "delete"), canPublish: hasResourcePermission(resource, "publish"), canUpload: resource === "FILE" ? hasResourcePermission(resource, "upload") : false, canManageRoles: resource === "USER" ? hasResourcePermission(resource, "manage_roles") : false, }), [hasResourcePermission, resource] ); return permissions; } /** * 조건부 렌더링을 위한 권한 체크 훅 */ export function useConditionalRender() { const { user } = useAuth(); const { hasPermission, hasAnyPermission } = usePermissions(); const renderIf = useMemo(() => { return { isAuthenticated: () => !!user, isAdmin: () => user?.role === UserRole.ADMIN, isEditor: () => user?.role === UserRole.ADMIN || user?.role === UserRole.EDITOR, hasRole: (role: UserRole) => user?.role === role, hasPermission: (permission: Permission) => hasPermission(permission), hasAnyPermission: (permissions: Permission[]) => hasAnyPermission(permissions), isOwner: (ownerId: string) => user?.id === ownerId, }; }, [user, hasPermission, hasAnyPermission]); return renderIf; }