import { useEffect, useState } from 'react'; import { PATHS } from '@/shared/constants/paths'; import { useNavigate } from '@/shared/lib/hooks/use-navigate'; import { HeaderType } from '@/entities/common/model/types'; import { useSetHeaderTitle, useSetHeaderType, useSetFooterMode, useSetOnBack } from '@/widgets/sub-layout/use-sub-layout'; import { useLocation } from 'react-router'; import { useUserMenuPermissionsSaveMutation } from '@/entities/user/api/use-user-menu-permission-save-mutation'; // import { useUserMenuPermissionsMutation } from '@/entities/user/api/use-user-menu-permission-mutation'; import { UserMenuPermissionData } from '@/entities/user/model/types'; import { snackBar } from '@/shared/lib/toast'; // 권한 비트 플래그 (실제 API 데이터 기준) const PERMISSION = { READ: 1, // 조회 SAVE: 2, // 저장 EXECUTE: 4, // 실행 DOWNLOAD: 8 // 다운로드 }; export const UserMenuAuthPage = () => { const { navigate } = useNavigate(); const location = useLocation(); const { mid, usrid, menuName, subMenu, menuGrants } = location.state || {}; // 메뉴별 권한 상태 관리 const [permissions, setPermissions] = useState>({}); const [initialPermissions, setInitialPermissions] = useState>({}); const [defaultPermissions, setDefaultPermissions] = useState>({}); const [hasChanges, setHasChanges] = useState(false); const [isInitialLoad, setIsInitialLoad] = useState(true); const savePermissionsMutation = useUserMenuPermissionsSaveMutation({ onSuccess: () => { snackBar('권한이 성공적으로 저장되었습니다.'); navigate(PATHS.account.user.accountAuth, { state: { mid, usrid, idCl: location.state?.idCl, status: location.state?.status } }); }, onError: (error) => { snackBar(error?.response?.data?.message || '권한 저장에 실패했습니다.'); } }); useSetHeaderTitle(menuName); useSetHeaderType(HeaderType.LeftArrow); useSetFooterMode(false); useSetOnBack(() => { navigate(PATHS.account.user.accountAuth, { state: { mid, usrid, idCl: location.state?.idCl, status: location.state?.status } }); }); useEffect(() => { console.log('menuGrants : ', menuGrants); }, [menuGrants]); // // 메뉴 권한 조회 함수 // const loadPermissions = useCallback(() => { // if (mid && usrid) { // getPermissionsMutation.mutate( // { mid, usrid }, // { // onSuccess: (response) => { // if (response.data) { // const perms: Record = {}; // response.data.forEach((item: UserMenuPermissionData) => { // perms[item.menuId] = item.grant; // }); // setPermissions(perms); // } // } // } // ); // } // // eslint-disable-next-line react-hooks/exhaustive-deps // }, [mid, usrid]); // menuGrants를 권한 상태로 초기화 또는 API에서 권한 조회 useEffect(() => { if (menuGrants && Array.isArray(menuGrants) && menuGrants.length > 0) { // menuGrants 데이터가 있으면 사용 const grants: Record = {}; const defaultGrants: Record = {}; menuGrants.forEach((grant: { menuId: number; grant: number; defaultGrant: number }) => { grants[grant.menuId] = grant.grant || 0; defaultGrants[grant.menuId] = grant.defaultGrant || 0; }); setPermissions(grants); setInitialPermissions(grants); // 초기값은 현재 grant 값으로 설정 setDefaultPermissions(defaultGrants); // defaultGrant는 별도로 관리 // 초기 로드 완료 후 애니메이션 활성화 setTimeout(() => setIsInitialLoad(false), 100); } else { // menuGrants가 없거나 빈 배열이면 API에서 권한 조회 // loadPermissions(); } }, [menuGrants]); // 권한 변경 감지 useEffect(() => { const hasAnyChange = Object.keys(permissions).some(key => { const menuId = Number(key); return permissions[menuId] !== (initialPermissions[menuId] || 0); }) || Object.keys(initialPermissions).some(key => { const menuId = Number(key); return (permissions[menuId] || 0) !== initialPermissions[menuId]; }); setHasChanges(hasAnyChange); }, [permissions, initialPermissions]); // 특정 메뉴의 권한 체크 const hasPermission = (menuId: number, flag: number): boolean => { const grant = permissions[menuId] || 0; return (grant & flag) === flag; }; const hasDefaultPermission = (menuId: number, flag: number): boolean => { const grant = defaultPermissions[menuId] || 0; return (grant & flag) === flag; }; // 권한 토글 처리 const togglePermission = (menuId: number, flag: number) => { setPermissions(prev => { const currentGrant = prev[menuId] || 0; const newGrant = currentGrant ^ flag; return { ...prev, [menuId]: newGrant }; }); }; // 메인 토글 처리 (VIEW 권한) const toggleMainPermission = (menuId: number) => { setPermissions(prev => { const currentGrant = prev[menuId] || 0; if (currentGrant > 0) { // 권한이 있으면 모두 제거 return { ...prev, [menuId]: 0 }; } else { // 권한이 없으면 VIEW 권한만 부여 return { ...prev, [menuId]: PERMISSION.READ }; } }); }; // 권한 저장 const handleSave = () => { const namsUserMenuAccess: UserMenuPermissionData[] = Object.entries(permissions).map( ([menuId, grant]) => ({ menuId: Number(menuId), usrid: usrid, grant: grant, defaultGrant: defaultPermissions[Number(menuId)] || 0 }) ); savePermissionsMutation.mutate( { mid, namsUserMenuAccess }, { onSuccess: () => { snackBar('권한이 저장되었습니다.'); // 저장 성공 후 초기값 업데이트 setInitialPermissions({...permissions}); setHasChanges(false); }, onError: (error) => { alert('권한 저장에 실패했습니다.'); console.error(error); } } ); }; return ( <>
메뉴별 사용 권한을 설정해 주세요.
선택한 권한에 따라 기능 이용이 제한됩니다.
{subMenu && subMenu.map((menu: { menuId: number; menuName: string }) => { const menuGrant = permissions[menu.menuId] || 0; const hasAccess = menuGrant > 0; return (
{menu.menuName}
{(hasDefaultPermission(menu.menuId, PERMISSION.SAVE) || hasDefaultPermission(menu.menuId, PERMISSION.EXECUTE) || hasDefaultPermission(menu.menuId, PERMISSION.DOWNLOAD)) && (
)} {hasDefaultPermission(menu.menuId, PERMISSION.SAVE) && (
저장
)} {hasDefaultPermission(menu.menuId, PERMISSION.EXECUTE) && (
실행
)} {hasDefaultPermission(menu.menuId, PERMISSION.DOWNLOAD) && (
다운로드
)}
); })}
); };