474 lines
18 KiB
TypeScript
474 lines
18 KiB
TypeScript
import { SidebarMenuTask } from "@/types/globals";
|
|
import { Tooltip } from '@nextui-org/react';
|
|
import Link from 'next/link';
|
|
import { usePathname } from 'next/navigation';
|
|
import React, { useEffect, useState } from 'react';
|
|
import { ChevronLeftIcon, ChevronRightIcon, FormCustomIcon, FormHorizontalIcon, FormLayoutIcon, FormValidationIcon, FormVerticalIcon } from '../icons';
|
|
import { DashboardIcon, HomeIcon, InfoCircleIcon, MinusCircleIcon, TableIcon } from '../icons/sidebar-icon';
|
|
import { ThemeSwitch } from '../theme-switch';
|
|
import { SidebarCollapseItems } from "./sidebar-collapse-items";
|
|
import { SidebarCollapseSubItems } from "./sidebar-collapse-sub-items";
|
|
import { useSidebar } from './sidebar-context';
|
|
import { SidebarMenu } from "./sidebar-menu";
|
|
|
|
interface SubMenuItems {
|
|
id: number;
|
|
name: string;
|
|
modulePathUrl: string;
|
|
isSubActive: boolean;
|
|
}
|
|
|
|
interface MenuItems {
|
|
id: number;
|
|
name: string;
|
|
modulePathUrl: string;
|
|
isSubActive: boolean;
|
|
childMenu?: SubMenuItems[];
|
|
icon?: string
|
|
|
|
}
|
|
|
|
interface SidebarProps {
|
|
sidebarData: boolean;
|
|
updateSidebarData: (newData: boolean) => void;
|
|
}
|
|
|
|
const sideBarDummyData = [
|
|
{
|
|
id: 1,
|
|
name: "Dashboard",
|
|
moduleId: 652,
|
|
moduleName: "Dashboard",
|
|
modulePathUrl: "/admin/dashboard",
|
|
isGroup: true,
|
|
parentId: -1,
|
|
icon: "dashboard",
|
|
position: 1,
|
|
statusId: 1,
|
|
childMenu: [],
|
|
statusName: "Active",
|
|
childModule: null,
|
|
},
|
|
{
|
|
id: 2,
|
|
name: "Dashboard",
|
|
moduleId: 652,
|
|
moduleName: "Dashboard",
|
|
modulePathUrl: "/admin/dashboard",
|
|
parentId: -1,
|
|
icon: <DashboardIcon />,
|
|
position: 1,
|
|
statusId: 1,
|
|
childMenu: [],
|
|
statusName: "Active",
|
|
childModule: null,
|
|
},
|
|
{
|
|
id: 3,
|
|
name: "Apps",
|
|
moduleId: 652,
|
|
moduleName: "Dashboard",
|
|
modulePathUrl: "/admin/basic",
|
|
isGroup: true,
|
|
parentId: -1,
|
|
icon: "table",
|
|
position: 1,
|
|
statusId: 1,
|
|
childMenu: [],
|
|
statusName: "Active",
|
|
childModule: null,
|
|
},
|
|
{
|
|
id: 4,
|
|
name: "Artikel",
|
|
moduleId: 652,
|
|
moduleName: "Dashboard",
|
|
modulePathUrl: "/admin/article",
|
|
parentId: -1,
|
|
icon: <TableIcon />,
|
|
position: 1,
|
|
statusId: 1,
|
|
childMenu: [],
|
|
statusName: "Active",
|
|
childModule: null,
|
|
},
|
|
{
|
|
id: 4,
|
|
name: "E-Magazine",
|
|
moduleId: 652,
|
|
moduleName: "Dashboard",
|
|
modulePathUrl: "/admin/e-magazine",
|
|
parentId: -1,
|
|
icon: <TableIcon />,
|
|
position: 1,
|
|
statusId: 1,
|
|
childMenu: [],
|
|
statusName: "Active",
|
|
childModule: null,
|
|
},
|
|
{
|
|
id: 5,
|
|
name: "Master",
|
|
moduleId: 652,
|
|
moduleName: "Dashboard",
|
|
isGroup: true,
|
|
modulePathUrl: "/admin/basic",
|
|
parentId: -1,
|
|
icon: "table",
|
|
position: 1,
|
|
statusId: 1,
|
|
childMenu: [],
|
|
statusName: "Active",
|
|
childModule: null,
|
|
},
|
|
{
|
|
id: 6,
|
|
name: "Master Menu",
|
|
moduleId: 652,
|
|
moduleName: "Form Custom",
|
|
modulePathUrl: "/admin/master-menu",
|
|
parentId: -1,
|
|
icon: <FormCustomIcon />,
|
|
position: 1,
|
|
statusId: 1,
|
|
childMenu: [],
|
|
statusName: "Active",
|
|
childModule: null,
|
|
},
|
|
{
|
|
id: 7,
|
|
name: "Master Module",
|
|
moduleId: 653,
|
|
moduleName: "Form Horizontal",
|
|
modulePathUrl: "/admin/master-module",
|
|
parentId: -1,
|
|
icon: <FormHorizontalIcon />,
|
|
position: 1,
|
|
statusId: 1,
|
|
childMenu: [],
|
|
statusName: "Active",
|
|
childModule: null,
|
|
},
|
|
{
|
|
id: 8,
|
|
name: "Master User",
|
|
moduleId: 654,
|
|
moduleName: "Form Vertical",
|
|
modulePathUrl: "/admin/master-user",
|
|
parentId: -1,
|
|
icon: <FormVerticalIcon />,
|
|
position: 1,
|
|
statusId: 1,
|
|
childMenu: [],
|
|
statusName: "Active",
|
|
childModule: null,
|
|
},
|
|
{
|
|
id: 9,
|
|
name: "Master User Levels",
|
|
moduleId: 655,
|
|
moduleName: "Form Layout",
|
|
modulePathUrl: "/admin/master-user-level",
|
|
parentId: -1,
|
|
icon: <FormLayoutIcon />,
|
|
position: 1,
|
|
statusId: 1,
|
|
childMenu: [],
|
|
statusName: "Active",
|
|
childModule: null,
|
|
},
|
|
{
|
|
id: 10,
|
|
name: "Master User Role",
|
|
moduleId: 656,
|
|
moduleName: "Form Validation",
|
|
modulePathUrl: "/admin/master-role",
|
|
parentId: -1,
|
|
icon: <FormValidationIcon />,
|
|
position: 1,
|
|
statusId: 1,
|
|
childMenu: [],
|
|
statusName: "Active",
|
|
childModule: null,
|
|
},
|
|
// {
|
|
// id: 11,
|
|
// name: "Form Wizard",
|
|
// moduleId: 657,
|
|
// moduleName: "Form Wizard",
|
|
// modulePathUrl: "/admin/form-wizard",
|
|
// parentId: -1,
|
|
// icon: <FormWizardIcon />,
|
|
// position: 1,
|
|
// statusId: 1,
|
|
// childMenu: [],
|
|
// statusName: "Active",
|
|
// childModule: null,
|
|
// },
|
|
// {
|
|
// id: 13,
|
|
// name: "Others",
|
|
// moduleId: 658,
|
|
// moduleName: "Others",
|
|
// modulePathUrl: "/admin/basic",
|
|
// isGroup: true,
|
|
// parentId: -1,
|
|
// icon: "table",
|
|
// position: 1,
|
|
// statusId: 1,
|
|
// childMenu: [],
|
|
// statusName: "Active",
|
|
// childModule: null,
|
|
// },
|
|
// {
|
|
// id: 13,
|
|
// name: "Menu 1",
|
|
// moduleId: 652,
|
|
// moduleName: "Menu 1",
|
|
// modulePathUrl: "/admin/menu1",
|
|
// parentId: -1,
|
|
// icon: <HomeIcon />,
|
|
// position: 1,
|
|
// statusId: 1,
|
|
// statusName: "Active",
|
|
// childMenu: [
|
|
// {
|
|
// id: 3,
|
|
// name: "SubMenu 1",
|
|
// moduleId: 653,
|
|
// moduleName: "SubMenu 1",
|
|
// modulePathUrl: "/admin/menu1/submenu1",
|
|
// parentId: 702,
|
|
// icon: <Submenu1Icon size={16} />,
|
|
// position: 2,
|
|
// statusId: 1,
|
|
// statusName: "Active",
|
|
// childMenu: [],
|
|
// childModule: null,
|
|
// },
|
|
// {
|
|
// id: 4,
|
|
// name: "SubMenu 2",
|
|
// moduleId: 653,
|
|
// moduleName: "SubMenu 2",
|
|
// modulePathUrl: "/admin/menu1/submenu2",
|
|
// parentId: 702,
|
|
// icon: <Submenu2Icon size={16} />,
|
|
// position: 2,
|
|
// statusId: 1,
|
|
// statusName: "Active",
|
|
// childMenu: [],
|
|
// childModule: null,
|
|
// }
|
|
// ],
|
|
// childModule: null,
|
|
// },
|
|
]
|
|
|
|
const Sidebar: React.FC<SidebarProps> = ({ updateSidebarData }) => {
|
|
const pathname = usePathname();
|
|
const [sidebarMenu, setSidebarMenu] = useState<SidebarMenuTask[]>();
|
|
const { isOpen, toggleSidebar } = useSidebar();
|
|
|
|
const closeSidebar = () => {
|
|
if (isOpen) {
|
|
toggleSidebar();
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
updateSidebarData(isOpen)
|
|
}, [isOpen])
|
|
|
|
const renderIcon = (icon: string) => {
|
|
switch (icon) {
|
|
case 'dashboard':
|
|
return <DashboardIcon />;
|
|
case 'menu1':
|
|
return <HomeIcon />;
|
|
case 'table':
|
|
return <TableIcon />;
|
|
default:
|
|
return null;
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className={`flex h-full ${isOpen ? 'min-w-[290px]' : 'min-w-[80px]'}`}>
|
|
<div className={`will-change relative flex h-full flex-col rounded-lg p-4 mb-0 bg-gray-100 dark:bg-stone-950 z-40 transition-width !ease-in-out ${isOpen ? 'w-[288px]' : 'w-[80px]'
|
|
}`}
|
|
>
|
|
|
|
{!isOpen &&
|
|
<div className='w-full flex justify-center items-center'>
|
|
<button
|
|
className="w-5 h-5 mb-3 text-zinc-400 dark:text-zinc-400 z-50 border-1 border-zinc-400 rounded-full flex justify-center items-center"
|
|
onClick={toggleSidebar}
|
|
>
|
|
<ChevronRightIcon />
|
|
</button>
|
|
</div>
|
|
}
|
|
<div className={`flex ${isOpen ? "justify-between" : "justify-center"} w-full items-center px-2`}>
|
|
<div className='flex flex-row items-center gap-3 font-bold'>
|
|
<img src="/logohumas.png" className='w-20' />
|
|
{/* {isOpen && <span>ACME</span>} */}
|
|
</div>
|
|
{isOpen &&
|
|
<button
|
|
className="w-5 h-5 text-zinc-400 dark:text-zinc-400 z-50 border-1 border-zinc-400 rounded-full flex justify-center items-center"
|
|
onClick={toggleSidebar}
|
|
>
|
|
<ChevronLeftIcon />
|
|
</button>
|
|
}
|
|
</div>
|
|
{/* <div className={`flex ${isOpen ? "justify-between" : "justify-center"} w-full items-center px-2 mt-4 mb-4`}>
|
|
<div className='flex flex-row items-center gap-3 font-bold'>
|
|
<Dropdown placement="bottom-start">
|
|
<DropdownTrigger>
|
|
<User
|
|
as="button"
|
|
avatarProps={{
|
|
isBordered: true,
|
|
src: "https://i.pravatar.cc/150?u=a042581f4e29026024d",
|
|
}}
|
|
classNames={{
|
|
base: `transition-transform gap-0`,
|
|
wrapper: `${isOpen && "pl-3"}`
|
|
}}
|
|
description={isOpen && "@tonyreichert"}
|
|
name={isOpen && "Tony Reichert"}
|
|
/>
|
|
</DropdownTrigger>
|
|
<DropdownMenu aria-label="User Actions" variant="flat">
|
|
<DropdownItem key="profile" className="h-14 gap-2">
|
|
<p className="font-bold">Signed in as</p>
|
|
<p className="font-bold">@tonyreichert</p>
|
|
</DropdownItem>
|
|
<DropdownItem key="team_settings">Profile Settings</DropdownItem>
|
|
<DropdownItem key="analytics">
|
|
Analytics
|
|
</DropdownItem>
|
|
<DropdownItem key="help_and_feedback">
|
|
Help & Feedback
|
|
</DropdownItem>
|
|
<DropdownItem key="logout" color="danger">
|
|
Log Out
|
|
</DropdownItem>
|
|
</DropdownMenu>
|
|
</Dropdown>
|
|
</div>
|
|
</div> */}
|
|
<SidebarMenu>
|
|
{sideBarDummyData
|
|
? sideBarDummyData?.map((list: any, index: number) => (
|
|
list.isGroup ?
|
|
<p className={`font-bold mr-4 ${!isOpen ? 'text-center' : ''}`}>{isOpen ? list.name : "..."}</p>
|
|
:
|
|
list.childMenu?.length < 1 ?
|
|
<>
|
|
{isOpen ?
|
|
<Link key={list.id} href={list.modulePathUrl}>
|
|
<div className={`px-3.5 py-2 mr-4 rounded-lg hover:bg-zinc-400 dark:hover:text-zinc-600 flex flex-row gap-2 ${pathname.includes(list.modulePathUrl) ? "bg-zinc-600 dark:bg-zinc-300 text-zinc-300 dark:text-zinc-500 font-bold" : "text-zinc-600 dark:text-zinc-400"}`}>
|
|
{list.icon} {isOpen && list.name}
|
|
</div>
|
|
</Link> :
|
|
<Tooltip content={list.name} placement="right" delay={0} closeDelay={0}>
|
|
<Link key={list.id} href={list.modulePathUrl}>
|
|
<div className={`py-2 mr-4 rounded-lg hover:bg-zinc-400 dark:hover:text-zinc-600 flex flex-row justify-center gap-1 ${pathname.includes(list.modulePathUrl) ? "bg-zinc-600 dark:bg-zinc-300 text-zinc-300 dark:text-zinc-500 font-bold" : "text-zinc-600 dark:text-zinc-400"}`}>
|
|
{list.icon} {isOpen && list.name}
|
|
</div>
|
|
</Link>
|
|
</Tooltip>
|
|
}
|
|
</>
|
|
:
|
|
<SidebarCollapseItems
|
|
key={list.id}
|
|
title={list.name}
|
|
isActive={pathname.includes(list.modulePathUrl)}
|
|
icon={list.icon}
|
|
items={[
|
|
list?.childMenu?.map((item: any) => (
|
|
<SidebarCollapseSubItems
|
|
key={item.id}
|
|
title={item?.name}
|
|
isActive={pathname.includes(item.modulePathUrl)}
|
|
isParentActive={pathname.includes(list.modulePathUrl)}
|
|
path={item.modulePathUrl}
|
|
icon={item.icon}
|
|
|
|
/>
|
|
)),
|
|
]}
|
|
/>
|
|
))
|
|
: ""}
|
|
</SidebarMenu>
|
|
<div className={`mt-12 p-2 flex ${isOpen ? "justify-start ml-2" : "justify-center"} mt-auto flex flex-col items-between`}>
|
|
<div className='flex flex-col gap-4'>
|
|
<div className={`cursor-pointer flex flex-row ${isOpen ? "justify-start" : "justify-center"} gap-2 items-center text-zinc-600 dark:text-zinc-400 hover:font-semibold hover:text-zinc-700 dark:hover:text-zinc-300`}>
|
|
<ThemeSwitch />
|
|
{isOpen && "Theme"}
|
|
</div>
|
|
{isOpen ?
|
|
<a className={`cursor-pointer flex flex-row ${isOpen ? "justify-start" : "justify-center"} gap-2 items-center text-zinc-600 dark:text-zinc-400 hover:font-semibold hover:text-zinc-700 dark:hover:text-zinc-300`}>
|
|
<InfoCircleIcon size={24} />
|
|
{isOpen && "Support"}
|
|
</a>
|
|
:
|
|
<Tooltip content="Support" delay={0} closeDelay={0} placement='right'>
|
|
<a className={`cursor-pointer flex flex-row ${isOpen ? "justify-start" : "justify-center"} gap-2 items-center text-zinc-600 dark:text-zinc-400 hover:font-semibold hover:text-zinc-700 dark:hover:text-zinc-300`}>
|
|
<InfoCircleIcon size={24} />
|
|
{isOpen && "Support"}
|
|
</a>
|
|
</Tooltip>
|
|
}
|
|
{isOpen ?
|
|
<a className={`ml-[1px] cursor-pointer flex flex-row ${isOpen ? "justify-start" : "justify-center"} gap-2 items-center text-zinc-600 dark:text-zinc-400 hover:font-semibold hover:text-zinc-700 dark:hover:text-zinc-300`}>
|
|
<MinusCircleIcon size={21} />
|
|
{isOpen && "Log Out"}
|
|
</a>
|
|
:
|
|
<Tooltip content="Log Out" delay={0} closeDelay={0} placement='right'>
|
|
<a className={`cursor-pointer flex flex-row ${isOpen ? "justify-start" : "justify-center"} gap-2 items-center text-zinc-600 dark:text-zinc-400 hover:font-semibold hover:text-zinc-700 dark:hover:text-zinc-300`}>
|
|
<MinusCircleIcon size={21} />
|
|
{isOpen && "Log Out"}
|
|
</a>
|
|
</Tooltip>
|
|
|
|
}
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* <div className="hidden md:block w-20 bg-gray-100 dark:bg-stone-950 h-full text-black dark:text-white">
|
|
<div className={`mt-4 flex justify-center w-full ${isOpen ? "hidden" : ""}`}>
|
|
<button
|
|
className="w-6 h-6 z-40"
|
|
onClick={toggleSidebar}
|
|
>
|
|
<MenuBurgerIcon />
|
|
|
|
</button>
|
|
</div>
|
|
{sideBarDummyData.map((list) => (
|
|
<div key={list.id} className='w-full flex justify-center my-2'>
|
|
<ClosedSidebarIcon icon={list.icon} isActive={pathname.includes(list.modulePathUrl)} childMenu={list.childMenu} path={list.modulePathUrl} title={list.name} />
|
|
</div>
|
|
))}
|
|
|
|
</div>
|
|
{isOpen && (
|
|
<div
|
|
className="block md:hidden fixed top-0 left-0 h-full w-full bg-black opacity-50 z-30"
|
|
onClick={toggleSidebar}
|
|
></div>
|
|
)} */}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Sidebar; |