From 55b0d9c8c1b9adf19c603f6819db7e05e663aaae Mon Sep 17 00:00:00 2001 From: Yashwin Date: Fri, 30 Jan 2026 18:16:19 +0530 Subject: [PATCH] Refactor Layout and Sidebar components for improved responsiveness and permission handling. Update layout styles for better spacing and adjust Sidebar menu items to include permission checks for tenant users. Remove unused EditTenantModal and NewModuleModal components to streamline shared components. --- src/components/layout/Layout.tsx | 6 +- src/components/layout/Sidebar.tsx | 88 +- src/components/shared/EditRoleModal.tsx | 170 ++- src/components/shared/EditTenantModal.tsx | 1117 ---------------- src/components/shared/FormSelect.tsx | 4 +- src/components/shared/NewRoleModal.tsx | 79 +- src/components/shared/PaginatedSelect.tsx | 4 +- src/components/shared/index.ts | 9 +- src/components/superadmin/EditTenantModal.tsx | 1155 +++++++++++++++++ .../{shared => superadmin}/NewModuleModal.tsx | 0 .../{shared => superadmin}/NewTenantModal.tsx | 0 .../{shared => superadmin}/RolesTable.tsx | 0 .../{shared => superadmin}/UsersTable.tsx | 0 .../ViewModuleModal.tsx | 0 .../ViewTenantModal.tsx | 0 src/components/superadmin/index.ts | 7 + src/hooks/usePermissions.ts | 91 ++ src/pages/Roles.tsx | 443 ------- src/pages/Users.tsx | 476 ------- src/pages/{ => superadmin}/AuditLogs.tsx | 0 .../{ => superadmin}/CreateTenantWizard.tsx | 203 ++- src/pages/{ => superadmin}/Dashboard.tsx | 0 src/pages/{ => superadmin}/EditTenant.tsx | 221 ++-- src/pages/{ => superadmin}/Modules.tsx | 3 +- src/pages/superadmin/Roles.tsx | 443 +++++++ src/pages/{ => superadmin}/TenantDetails.tsx | 3 +- src/pages/{ => superadmin}/Tenants.tsx | 4 +- src/pages/superadmin/Users.tsx | 476 +++++++ src/pages/tenant/Modules.tsx | 158 ++- src/pages/tenant/Roles.tsx | 28 +- src/pages/tenant/Settings.tsx | 128 +- src/pages/tenant/Users.tsx | 28 +- src/routes/super-admin-routes.tsx | 34 +- src/services/module-service.ts | 14 + src/types/role.ts | 3 + 35 files changed, 2990 insertions(+), 2405 deletions(-) delete mode 100644 src/components/shared/EditTenantModal.tsx create mode 100644 src/components/superadmin/EditTenantModal.tsx rename src/components/{shared => superadmin}/NewModuleModal.tsx (100%) rename src/components/{shared => superadmin}/NewTenantModal.tsx (100%) rename src/components/{shared => superadmin}/RolesTable.tsx (100%) rename src/components/{shared => superadmin}/UsersTable.tsx (100%) rename src/components/{shared => superadmin}/ViewModuleModal.tsx (100%) rename src/components/{shared => superadmin}/ViewTenantModal.tsx (100%) create mode 100644 src/components/superadmin/index.ts create mode 100644 src/hooks/usePermissions.ts delete mode 100644 src/pages/Roles.tsx delete mode 100644 src/pages/Users.tsx rename src/pages/{ => superadmin}/AuditLogs.tsx (100%) rename src/pages/{ => superadmin}/CreateTenantWizard.tsx (88%) rename src/pages/{ => superadmin}/Dashboard.tsx (100%) rename src/pages/{ => superadmin}/EditTenant.tsx (88%) rename src/pages/{ => superadmin}/Modules.tsx (99%) create mode 100644 src/pages/superadmin/Roles.tsx rename src/pages/{ => superadmin}/TenantDetails.tsx (99%) rename src/pages/{ => superadmin}/Tenants.tsx (98%) create mode 100644 src/pages/superadmin/Users.tsx diff --git a/src/components/layout/Layout.tsx b/src/components/layout/Layout.tsx index e5620ba..7e9be39 100644 --- a/src/components/layout/Layout.tsx +++ b/src/components/layout/Layout.tsx @@ -32,7 +32,7 @@ export const Layout = ({ children, currentPage, breadcrumbs, pageHeader }: Layou
{/* Content Wrapper */} -
+
{/* Mobile Overlay */} {isSidebarOpen && (
{/* Main Content */} -
+
{/* Top Header */}
{/* Main Content Area */} -
+
{/* Page Header */} {pageHeader && ( ; label: string; path: string; + requiredPermission?: { + resource: string; + action?: string; // If not provided, checks for '*' or 'read' + }; } interface SidebarProps { @@ -29,32 +33,32 @@ interface SidebarProps { const superAdminPlatformMenu: MenuItem[] = [ { icon: LayoutDashboard, label: 'Dashboard', path: '/dashboard' }, { icon: Building2, label: 'Tenants', path: '/tenants' }, - { icon: Users, label: 'User Management', path: '/users' }, - { icon: Shield, label: 'Roles', path: '/roles' }, + // { icon: Users, label: 'User Management', path: '/users' }, + // { icon: Shield, label: 'Roles', path: '/roles' }, { icon: Package, label: 'Modules', path: '/modules' }, ]; const superAdminSystemMenu: MenuItem[] = [ { icon: FileText, label: 'Audit Logs', path: '/audit-logs' }, - { icon: Settings, label: 'Settings', path: '/settings' }, + // { icon: Settings, label: 'Settings', path: '/settings' }, ]; // Tenant Admin menu items const tenantAdminPlatformMenu: MenuItem[] = [ { icon: LayoutDashboard, label: 'Dashboard', path: '/tenant' }, - { icon: Shield, label: 'Roles', path: '/tenant/roles' }, - { icon: Users, label: 'Users', path: '/tenant/users' }, - { icon: Package, label: 'Modules', path: '/tenant/modules' }, + { icon: Shield, label: 'Roles', path: '/tenant/roles', requiredPermission: { resource: 'roles' } }, + { icon: Users, label: 'Users', path: '/tenant/users', requiredPermission: { resource: 'users' } }, + { icon: Package, label: 'TenantModules', path: '/tenant/modules', requiredPermission: { resource: 'tenants' } }, ]; const tenantAdminSystemMenu: MenuItem[] = [ - { icon: FileText, label: 'Audit Logs', path: '/tenant/audit-logs' }, - { icon: Settings, label: 'Settings', path: '/tenant/settings' }, + { icon: FileText, label: 'Audit Logs', path: '/tenant/audit-logs', requiredPermission: { resource: 'audit_logs' } }, + { icon: Settings, label: 'Settings', path: '/tenant/settings', requiredPermission: { resource: 'tenants' } }, ]; export const Sidebar = ({ isOpen, onClose }: SidebarProps) => { const location = useLocation(); - const { roles } = useAppSelector((state) => state.auth); + const { roles, permissions } = useAppSelector((state) => state.auth); const { theme, logoUrl } = useAppSelector((state) => state.theme); // Fetch theme for tenant admin @@ -79,12 +83,56 @@ export const Sidebar = ({ isOpen, onClose }: SidebarProps) => { useTenantTheme(); } - // Select menu items based on role - const platformMenu = isSuperAdmin ? superAdminPlatformMenu : tenantAdminPlatformMenu; - const systemMenu = isSuperAdmin ? superAdminSystemMenu : tenantAdminSystemMenu; + // Helper function to check if user has permission for a resource + const hasPermission = (resource: string, requiredAction?: string): boolean => { + if (isSuperAdmin) { + return true; // Super admin has all permissions + } + + const allowedActions = requiredAction ? [requiredAction] : ['*', 'read']; + + return permissions.some((perm) => { + // Check if resource matches (exact match or wildcard) + const resourceMatches = perm.resource === resource || perm.resource === '*'; + + // Check if action matches (exact match or wildcard) + const actionMatches = allowedActions.some( + (allowedAction) => perm.action === allowedAction || perm.action === '*' + ); + + return resourceMatches && actionMatches; + }); + }; + + // Filter menu items based on permissions for tenant users + const filterMenuItems = (items: MenuItem[]): MenuItem[] => { + if (isSuperAdmin) { + return items; // Show all items for super admin + } + + return items.filter((item) => { + // If no required permission, always show (e.g., Dashboard, Modules, Settings) + if (!item.requiredPermission) { + return true; + } + + return hasPermission( + item.requiredPermission.resource, + item.requiredPermission.action + ); + }); + }; + + // Select and filter menu items based on role and permissions + const platformMenu = filterMenuItems( + isSuperAdmin ? superAdminPlatformMenu : tenantAdminPlatformMenu + ); + const systemMenu = filterMenuItems( + isSuperAdmin ? superAdminSystemMenu : tenantAdminSystemMenu + ); const MenuSection = ({ title, items }: { title: string; items: MenuItem[] }) => ( -
+
@@ -193,9 +241,9 @@ export const Sidebar = ({ isOpen, onClose }: SidebarProps) => { {/* Desktop Sidebar */} -