import React from "react"; type NavItemProps = { to?: string; children?: React.ReactNode; [key: string]: any; }; /** * Filters navigation items based on user's roles & dynamic permission config. */ export const filterNavLinksByRole = ( navItems: React.ReactNode, userRoles?: string[], permissions?: Record ): React.ReactNode => { if (!userRoles || userRoles.length === 0) return null; if (userRoles.includes("super_admin")) return navItems; const filteredItems = React.Children.map(navItems, (item) => { if (!React.isValidElement(item)) return null; const props = item.props as NavItemProps; const path = props.to; const children = props.children; if (children) { const filteredChildren = React.Children.map(children, (child) => { if (!React.isValidElement(child)) return null; const childProps = child.props as NavItemProps; const childPath = childProps.to; return childPath && shouldShowItem(childPath, userRoles, permissions) ? child : null; })?.filter(Boolean); if (filteredChildren?.length) { // Cast item as ReactElement to allow children return React.cloneElement(item, { ...props, children: filteredChildren, }); } return path && shouldShowItem(path, userRoles, permissions) ? item : null; } return path && shouldShowItem(path, userRoles, permissions) ? item : null; })?.filter(Boolean); return filteredItems ?? null; }; const shouldShowItem = ( path: string, userRoles?: string[], permissions?: Record ): boolean => { if (!userRoles || userRoles.length === 0) return false; if (!permissions) return false; const cleanPath = path.startsWith("/") ? path.slice(1) : path; if (!permissions[cleanPath]) return false; return userRoles.some((role) => permissions[cleanPath].includes(role)); };