import { useEffect, useState } from "react"; import { Link, useLocation } from "react-router-dom"; import { LayoutDashboard, Building2, Users, Package, FileText, Settings, HelpCircle, X, Shield, BadgeCheck, GitBranch, ChevronDown, ChevronRight, Bell, Paperclip, Bot, } from "lucide-react"; import { cn } from "@/lib/utils"; import { useAppSelector } from "@/hooks/redux-hooks"; import { useAppTheme } from "@/hooks/useAppTheme"; import { AuthenticatedImage } from "@/components/shared"; interface MenuItem { icon: React.ComponentType<{ className?: string; strokeWidth?: number }>; label: string; path?: string; isGroup?: boolean; children?: Array<{ label: string; path: string; requiredPermission?: { resource: string; action?: string; }; }>; requiredPermission?: { resource: string; action?: string; // If not provided, checks for '*' or 'read' }; } interface SidebarProps { isOpen: boolean; onClose: () => void; } // Super Admin menu items 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: Package, label: "Modules", path: "/modules" }, ]; const superAdminSystemMenu: MenuItem[] = [ { icon: Bell, label: "Notifications", isGroup: true, children: [ { label: "Notifications List", path: "/notifications" }, { label: "Master Management", path: "/notification-master" }, { label: "Global Templates", path: "/notification-templates" }, ], }, { icon: FileText, label: "Audit Logs", path: "/audit-logs" }, { icon: Shield, label: "Audit Resources", path: "/audit-resource-types" }, { icon: Settings, label: "Settings", isGroup: true, children: [ { label: "SMTP Config", path: "/settings/smtp" }, { label: "Failed Emails", path: "/settings/failed-emails" }, ], }, ]; // Tenant Admin menu items const tenantAdminPlatformMenu: MenuItem[] = [ { icon: LayoutDashboard, label: "Dashboard", path: "/tenant" }, { icon: Shield, label: "Roles", path: "/tenant/roles", requiredPermission: { resource: "roles" }, }, { icon: Building2, label: "Departments", path: "/tenant/departments", requiredPermission: { resource: "departments" }, }, { icon: BadgeCheck, label: "Designations", path: "/tenant/designations", requiredPermission: { resource: "designations" }, }, { icon: Users, label: "Suppliers", path: "/tenant/suppliers", requiredPermission: { resource: "supplier" }, }, { icon: Users, label: "Users", path: "/tenant/users", requiredPermission: { resource: "users" }, }, ]; const tenantAdminPlatformServiceMenu: MenuItem[] = [ { icon: Paperclip, label: "File Attachments", isGroup: true, children: [ { label: "Files List", path: "/tenant/files", requiredPermission: { resource: "files" }, }, { label: "Storage Dashboard", path: "/tenant/files/storage-dashboard", requiredPermission: { resource: "files" }, }, ], requiredPermission: { resource: "files" }, }, { icon: GitBranch, label: "Workflows", isGroup: true, children: [ { label: "Definitions", path: "/tenant/workflows/definitions", requiredPermission: { resource: "workflow" }, }, { label: "Tasks", path: "/tenant/workflows/tasks", requiredPermission: { resource: "workflow" }, }, ], requiredPermission: { resource: "workflow" }, }, { icon: FileText, label: "Documents", isGroup: true, children: [ { label: "Document Lists", path: "/tenant/documents", requiredPermission: { resource: "document" }, }, { label: "Create Document", path: "/tenant/documents/create", requiredPermission: { resource: "document", action: "create" }, }, { label: "Categories", path: "/tenant/documents/categories", requiredPermission: { resource: "document" }, }, { label: "Due for Review", path: "/tenant/documents/due-for-review", requiredPermission: { resource: "document" }, }, ], requiredPermission: { resource: "document" }, }, { icon: Bot, label: "AI Services", isGroup: true, children: [ { label: "Completion History", path: "/tenant/ai/completions", requiredPermission: { resource: "ai" }, }, { label: "Prompt Management", path: "/tenant/ai/prompts", requiredPermission: { resource: "ai" }, }, { label: "Tenant AI Providers", path: "/tenant/ai/providers", requiredPermission: { resource: "ai" }, }, { label: "AI Usage & Cost Dashboard", path: "/tenant/ai/dashboard", requiredPermission: { resource: "ai" }, }, // { // label: "Tenant Config", // path: "/tenant/ai/config", // requiredPermission: { resource: "ai" }, // }, // { // label: "Knowledge (RAG)", // path: "/tenant/ai/knowledge", // requiredPermission: { resource: "ai" }, // }, ], requiredPermission: { resource: "ai" }, }, { icon: Package, label: "Modules", path: "/tenant/modules" }, ]; const tenantAdminSystemMenu: MenuItem[] = [ { icon: Bell, label: "Notifications", path: "/tenant/notifications", requiredPermission: { resource: "notifications" }, }, { icon: FileText, label: "Audit Logs", path: "/tenant/audit-logs", }, { icon: Settings, label: "Settings", isGroup: true, children: [ { label: "General Settings", path: "/tenant/settings", }, { label: "Notification Settings", path: "/tenant/settings/notifications", }, { label: "Notification Templates", path: "/tenant/settings/notification-templates", }, { label: "SMTP Settings", path: "/tenant/settings/smtp", }, { label: "Failed Emails", path: "/tenant/settings/failed-emails", }, ], requiredPermission: { resource: "tenants" }, }, ]; const GroupMenuItem = ({ item, childrenItems, location, primaryColor, secondaryColor, onClose, }: { item: MenuItem; childrenItems: any[]; location: any; primaryColor: string; secondaryColor: string; onClose: () => void; }) => { const isChildActive = (path: string) => { // Basic exact match check if (location.pathname === path) return true; // Special handling for paths that are prefixes of other siblings // Example: /tenant/settings is a prefix of /tenant/settings/notifications if (location.pathname.startsWith(`${path}/`)) { // If there's another sibling that is a more specific match for the current path, // then this prefix path should not be considered "active" const hasMoreSpecificSibling = childrenItems.some( (sibling) => sibling.path !== path && sibling.path.startsWith(path) && (location.pathname === sibling.path || location.pathname.startsWith(`${sibling.path}/`)), ); if (hasMoreSpecificSibling) return false; // Also keep existing special cases if they don't fit the generic rule above // (Though the generic rule above should cover most of these) // Special handling for Document Lists to NOT show as active when sub-actions are active if (path === "/tenant/documents") { const subActions = [ "/create", "/categories", "/due-for-review", "/edit", ]; const isSubActionActive = subActions.some((sub) => location.pathname.startsWith(path + sub), ); if (isSubActionActive) return false; } // Special handling for Files List to NOT show as active when Storage Dashboard is active if (path === "/tenant/files") { if (location.pathname.startsWith("/tenant/files/storage-dashboard")) { return false; } } return true; } return false; }; const isAnyChildActive = childrenItems.some((child) => isChildActive(child.path), ); const [isExpanded, setIsExpanded] = useState(isAnyChildActive); useEffect(() => { if (isAnyChildActive) setIsExpanded(true); }, [isAnyChildActive]); const Icon = item.icon; return (