mirror of
https://github.com/i701/sarlink-portal.git
synced 2025-10-06 16:45:24 +00:00
refactor(sidebar): re arrange sidebar links 🔨
This commit is contained in:
@@ -1,224 +1,226 @@
|
|||||||
import {
|
import {
|
||||||
BadgePlus,
|
BadgePlus,
|
||||||
Calculator,
|
Calculator,
|
||||||
ChevronRight,
|
ChevronRight,
|
||||||
Coins,
|
Coins,
|
||||||
CreditCard,
|
CreditCard,
|
||||||
Handshake,
|
Handshake,
|
||||||
MonitorSpeaker,
|
MonitorSpeaker,
|
||||||
Smartphone,
|
Smartphone,
|
||||||
UsersRound,
|
UsersRound,
|
||||||
Wallet2Icon,
|
Wallet2Icon,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { getServerSession } from "next-auth";
|
import { getServerSession } from "next-auth";
|
||||||
import { authOptions } from "@/app/auth";
|
import { authOptions } from "@/app/auth";
|
||||||
import {
|
import {
|
||||||
Collapsible,
|
Collapsible,
|
||||||
CollapsibleContent,
|
CollapsibleContent,
|
||||||
CollapsibleTrigger,
|
CollapsibleTrigger,
|
||||||
} from "@/components/ui/collapsible";
|
} from "@/components/ui/collapsible";
|
||||||
import {
|
import {
|
||||||
Sidebar,
|
Sidebar,
|
||||||
SidebarContent,
|
SidebarContent,
|
||||||
SidebarGroup,
|
SidebarGroup,
|
||||||
SidebarGroupContent,
|
SidebarGroupContent,
|
||||||
SidebarGroupLabel,
|
SidebarGroupLabel,
|
||||||
SidebarHeader,
|
SidebarHeader,
|
||||||
SidebarMenu,
|
SidebarMenu,
|
||||||
SidebarMenuButton,
|
SidebarMenuButton,
|
||||||
SidebarMenuItem,
|
SidebarMenuItem,
|
||||||
SidebarRail,
|
SidebarRail,
|
||||||
} from "@/components/ui/sidebar";
|
} from "@/components/ui/sidebar";
|
||||||
|
|
||||||
type Permission = {
|
type Permission = {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type Categories = {
|
type Categories = {
|
||||||
id: string;
|
id: string;
|
||||||
children: (
|
children: (
|
||||||
| {
|
| {
|
||||||
title: string;
|
title: string;
|
||||||
link: string;
|
link: string;
|
||||||
perm_identifier: string;
|
perm_identifier: string;
|
||||||
icon: React.JSX.Element;
|
icon: React.JSX.Element;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
title: string;
|
title: string;
|
||||||
link: string;
|
link: string;
|
||||||
icon: React.JSX.Element;
|
icon: React.JSX.Element;
|
||||||
perm_identifier?: undefined;
|
perm_identifier?: undefined;
|
||||||
}
|
}
|
||||||
)[];
|
)[];
|
||||||
}[];
|
}[];
|
||||||
|
|
||||||
export async function AppSidebar({
|
export async function AppSidebar({
|
||||||
...props
|
...props
|
||||||
}: React.ComponentProps<typeof Sidebar>) {
|
}: React.ComponentProps<typeof Sidebar>) {
|
||||||
const categories = [
|
const categories = [
|
||||||
{
|
{
|
||||||
id: "MENU",
|
id: "MENU",
|
||||||
url: "#",
|
url: "#",
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
title: "Devices",
|
title: "Devices",
|
||||||
link: "/devices?page=1",
|
link: "/devices?page=1",
|
||||||
perm_identifier: "device",
|
perm_identifier: "device",
|
||||||
icon: <Smartphone size={16} />,
|
icon: <Smartphone size={16} />,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Payments",
|
title: "Parental Control",
|
||||||
link: "/payments?page=1",
|
link: "/parental-control?page=1",
|
||||||
icon: <CreditCard size={16} />,
|
icon: <CreditCard size={16} />,
|
||||||
perm_identifier: "payment",
|
perm_identifier: "device",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Top Ups",
|
title: "Subscriptions",
|
||||||
link: "/top-ups?page=1",
|
link: "/payments?page=1",
|
||||||
icon: <BadgePlus size={16} />,
|
icon: <CreditCard size={16} />,
|
||||||
perm_identifier: "topup",
|
perm_identifier: "payment",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Parental Control",
|
title: "Top Ups",
|
||||||
link: "/parental-control?page=1",
|
link: "/top-ups?page=1",
|
||||||
icon: <CreditCard size={16} />,
|
icon: <BadgePlus size={16} />,
|
||||||
perm_identifier: "device",
|
perm_identifier: "topup",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Agreements",
|
title: "Transaction History",
|
||||||
link: "/agreements",
|
link: "/wallet",
|
||||||
icon: <Handshake size={16} />,
|
icon: <Wallet2Icon size={16} />,
|
||||||
perm_identifier: "device",
|
perm_identifier: "wallet transaction",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Wallet",
|
title: "Agreements",
|
||||||
link: "/wallet",
|
link: "/agreements",
|
||||||
icon: <Wallet2Icon size={16} />,
|
icon: <Handshake size={16} />,
|
||||||
perm_identifier: "wallet transaction",
|
perm_identifier: "device",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "ADMIN CONTROL",
|
id: "ADMIN CONTROL",
|
||||||
url: "#",
|
url: "#",
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
title: "Users",
|
title: "Users",
|
||||||
link: "/users",
|
link: "/users",
|
||||||
icon: <UsersRound size={16} />,
|
icon: <UsersRound size={16} />,
|
||||||
perm_identifier: "device",
|
perm_identifier: "device",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "User Devices",
|
title: "User Devices",
|
||||||
link: "/user-devices",
|
link: "/user-devices",
|
||||||
icon: <MonitorSpeaker size={16} />,
|
icon: <MonitorSpeaker size={16} />,
|
||||||
perm_identifier: "device",
|
perm_identifier: "device",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "User Payments",
|
title: "User Payments",
|
||||||
link: "/user-payments",
|
link: "/user-payments",
|
||||||
icon: <Coins size={16} />,
|
icon: <Coins size={16} />,
|
||||||
perm_identifier: "payment",
|
perm_identifier: "payment",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "User Topups",
|
title: "User Topups",
|
||||||
link: "/user-topups",
|
link: "/user-topups",
|
||||||
icon: <Coins size={16} />,
|
icon: <Coins size={16} />,
|
||||||
perm_identifier: "topup",
|
perm_identifier: "topup",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Price Calculator",
|
title: "Price Calculator",
|
||||||
link: "/price-calculator",
|
link: "/price-calculator",
|
||||||
icon: <Calculator size={16} />,
|
icon: <Calculator size={16} />,
|
||||||
perm_identifier: "device",
|
perm_identifier: "device",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const session = await getServerSession(authOptions);
|
const session = await getServerSession(authOptions);
|
||||||
|
|
||||||
let CATEGORIES: Categories;
|
let CATEGORIES: Categories;
|
||||||
if (session?.user?.is_admin) {
|
if (session?.user?.is_admin) {
|
||||||
CATEGORIES = categories;
|
CATEGORIES = categories;
|
||||||
} else {
|
} else {
|
||||||
// Filter out ADMIN CONTROL category for non-admin users
|
// Filter out ADMIN CONTROL category for non-admin users
|
||||||
const nonAdminCategories = categories.filter(
|
const nonAdminCategories = categories.filter(
|
||||||
(category) => category.id !== "ADMIN CONTROL",
|
(category) => category.id !== "ADMIN CONTROL",
|
||||||
);
|
);
|
||||||
|
|
||||||
const filteredCategories = nonAdminCategories.map((category) => {
|
const filteredCategories = nonAdminCategories.map((category) => {
|
||||||
const filteredChildren = category.children.filter((child) => {
|
const filteredChildren = category.children.filter((child) => {
|
||||||
const permIdentifier = child.perm_identifier;
|
const permIdentifier = child.perm_identifier;
|
||||||
return session?.user?.user_permissions?.some(
|
return session?.user?.user_permissions?.some(
|
||||||
(permission: Permission) => {
|
(permission: Permission) => {
|
||||||
const permissionParts = permission.name.split(" ");
|
const permissionParts = permission.name.split(" ");
|
||||||
const modelNameFromPermission = permissionParts.slice(2).join(" ");
|
const modelNameFromPermission = permissionParts.slice(2).join(" ");
|
||||||
return modelNameFromPermission === permIdentifier;
|
return modelNameFromPermission === permIdentifier;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
return { ...category, children: filteredChildren };
|
return { ...category, children: filteredChildren };
|
||||||
});
|
});
|
||||||
|
|
||||||
CATEGORIES = filteredCategories.filter(
|
CATEGORIES = filteredCategories.filter(
|
||||||
(category) => category.children.length > 0,
|
(category) => category.children.length > 0,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Sidebar {...props} className="z-50">
|
<Sidebar {...props} className="z-50">
|
||||||
<SidebarHeader>
|
<SidebarHeader>
|
||||||
<h4 className="p-2 rounded title-bg border text-center uppercase ">
|
<h4 className="p-2 rounded title-bg border text-center uppercase ">
|
||||||
Sar Link Portal
|
Sar Link Portal
|
||||||
</h4>
|
</h4>
|
||||||
</SidebarHeader>
|
</SidebarHeader>
|
||||||
<SidebarContent className="gap-0">
|
<SidebarContent className="gap-0">
|
||||||
{CATEGORIES.map((item) => {
|
{CATEGORIES.map((item) => {
|
||||||
return (
|
return (
|
||||||
<Collapsible
|
<Collapsible
|
||||||
key={item.id}
|
key={item.id}
|
||||||
title={item.id}
|
title={item.id}
|
||||||
defaultOpen
|
defaultOpen
|
||||||
className="group/collapsible"
|
className="group/collapsible"
|
||||||
>
|
>
|
||||||
<SidebarGroup>
|
<SidebarGroup>
|
||||||
<SidebarGroupLabel
|
<SidebarGroupLabel
|
||||||
asChild
|
asChild
|
||||||
className="group/label text-sm text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground"
|
className="group/label text-sm text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground"
|
||||||
>
|
>
|
||||||
<CollapsibleTrigger>
|
<CollapsibleTrigger>
|
||||||
{item.id}{" "}
|
{item.id}{" "}
|
||||||
<ChevronRight className="ml-auto transition-transform group-data-[state=open]/collapsible:rotate-90" />
|
<ChevronRight className="ml-auto transition-transform group-data-[state=open]/collapsible:rotate-90" />
|
||||||
</CollapsibleTrigger>
|
</CollapsibleTrigger>
|
||||||
</SidebarGroupLabel>
|
</SidebarGroupLabel>
|
||||||
<CollapsibleContent>
|
<CollapsibleContent>
|
||||||
<SidebarGroupContent>
|
<SidebarGroupContent>
|
||||||
<SidebarMenu>
|
<SidebarMenu>
|
||||||
{item.children.map((item) => (
|
{item.children.map((item) => (
|
||||||
<SidebarMenuItem key={item.title}>
|
<SidebarMenuItem key={item.title}>
|
||||||
<SidebarMenuButton className="py-6" asChild>
|
<SidebarMenuButton className="py-6" asChild>
|
||||||
<Link className="text-md" href={item.link}>
|
<Link className="text-md" href={item.link}>
|
||||||
{item.icon}
|
{item.icon}
|
||||||
<span className="opacity-70 ml-2">
|
<span
|
||||||
{item.title}
|
className={`opacity-70 motion-preset-slide-left-md ml-2`}
|
||||||
</span>
|
>
|
||||||
</Link>
|
{item.title}
|
||||||
</SidebarMenuButton>
|
</span>
|
||||||
</SidebarMenuItem>
|
</Link>
|
||||||
))}
|
</SidebarMenuButton>
|
||||||
</SidebarMenu>
|
</SidebarMenuItem>
|
||||||
</SidebarGroupContent>
|
))}
|
||||||
</CollapsibleContent>
|
</SidebarMenu>
|
||||||
</SidebarGroup>
|
</SidebarGroupContent>
|
||||||
</Collapsible>
|
</CollapsibleContent>
|
||||||
);
|
</SidebarGroup>
|
||||||
})}
|
</Collapsible>
|
||||||
</SidebarContent>
|
);
|
||||||
<SidebarRail />
|
})}
|
||||||
</Sidebar>
|
</SidebarContent>
|
||||||
);
|
<SidebarRail />
|
||||||
|
</Sidebar>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user