mirror of
https://github.com/freedbygrace/DynamoDNS.git
synced 2026-08-13 11:36:53 +00:00
8bddf00ef4
Replit-Commit-Author: Agent Replit-Commit-Session-Id: 9111ef36-26c8-4085-84ca-a35dc1fec1b5 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/7083d608-d6d3-4a6a-9a27-6286c5109627/e33594f7-ad24-43f5-a4e1-0d9d2f261947.jpg
171 lines
4.7 KiB
TypeScript
171 lines
4.7 KiB
TypeScript
import { Link, useLocation } from "wouter";
|
|
import { cn } from "@/lib/utils";
|
|
import { ThemeToggle } from "@/components/shared/theme-toggle";
|
|
import { OrganizationSelector } from "@/components/shared/organization-selector";
|
|
import { useAuth } from "@/hooks/use-auth";
|
|
import {
|
|
LayoutDashboard,
|
|
Home,
|
|
Globe,
|
|
BarChart2,
|
|
FileEdit,
|
|
Key,
|
|
Users,
|
|
Settings,
|
|
CreditCard,
|
|
LogOut,
|
|
} from "lucide-react";
|
|
import { Button } from "@/components/ui/button";
|
|
|
|
export function Sidebar() {
|
|
const [location] = useLocation();
|
|
const { user, logoutMutation } = useAuth();
|
|
|
|
// Define navigation items
|
|
const navItems = [
|
|
{
|
|
title: "Dashboard",
|
|
href: "/",
|
|
icon: <LayoutDashboard className="w-5 h-5 mr-3" />,
|
|
},
|
|
{
|
|
title: "Organizations",
|
|
href: "/organizations",
|
|
icon: <Users className="w-5 h-5 mr-3" />,
|
|
},
|
|
{
|
|
title: "Domains",
|
|
href: "/domains",
|
|
icon: <Home className="w-5 h-5 mr-3" />,
|
|
},
|
|
{
|
|
title: "DNS Records",
|
|
href: "/dns-records",
|
|
icon: <Globe className="w-5 h-5 mr-3" />,
|
|
},
|
|
{
|
|
title: "Metrics",
|
|
href: "/metrics",
|
|
icon: <BarChart2 className="w-5 h-5 mr-3" />,
|
|
},
|
|
{
|
|
title: "History",
|
|
href: "/history",
|
|
icon: <FileEdit className="w-5 h-5 mr-3" />,
|
|
},
|
|
{
|
|
title: "API Tokens",
|
|
href: "/api-tokens",
|
|
icon: <Key className="w-5 h-5 mr-3" />,
|
|
},
|
|
];
|
|
|
|
// Define admin navigation items
|
|
const adminNavItems = [
|
|
{
|
|
title: "Users & Roles",
|
|
href: "/users-roles",
|
|
icon: <Users className="w-5 h-5 mr-3" />,
|
|
roles: ["admin"],
|
|
},
|
|
{
|
|
title: "Providers",
|
|
href: "/providers",
|
|
icon: <CreditCard className="w-5 h-5 mr-3" />,
|
|
roles: ["admin", "manager"],
|
|
},
|
|
{
|
|
title: "Settings",
|
|
href: "/settings",
|
|
icon: <Settings className="w-5 h-5 mr-3" />,
|
|
roles: ["admin", "manager"],
|
|
},
|
|
];
|
|
|
|
// Filter admin items based on user role
|
|
const filteredAdminItems = adminNavItems.filter(
|
|
item => !item.roles || (user && item.roles.includes(user.role))
|
|
);
|
|
|
|
return (
|
|
<aside className="hidden lg:flex lg:flex-col w-64 border-r border-border bg-card">
|
|
<div className="p-4 flex items-center justify-between">
|
|
<div className="flex items-center">
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
strokeWidth="2"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
className="w-6 h-6 text-primary mr-2"
|
|
>
|
|
<path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"></path>
|
|
</svg>
|
|
<span className="font-semibold text-xl">DynamiDNS</span>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Organization Selector */}
|
|
<div className="px-4 py-2">
|
|
<OrganizationSelector />
|
|
</div>
|
|
|
|
<nav className="flex-1 py-4 px-2 space-y-1 overflow-y-auto">
|
|
{navItems.map((item) => (
|
|
<Link key={item.href} href={item.href}>
|
|
<a
|
|
className={cn(
|
|
"flex items-center px-3 py-2 text-sm font-medium rounded-md",
|
|
location === item.href
|
|
? "bg-primary text-primary-foreground"
|
|
: "hover:bg-accent hover:text-accent-foreground"
|
|
)}
|
|
>
|
|
{item.icon}
|
|
{item.title}
|
|
</a>
|
|
</Link>
|
|
))}
|
|
|
|
{filteredAdminItems.length > 0 && (
|
|
<div className="pt-4">
|
|
<div className="px-3 text-xs font-semibold text-muted-foreground uppercase tracking-wider">
|
|
Administration
|
|
</div>
|
|
{filteredAdminItems.map((item) => (
|
|
<Link key={item.href} href={item.href}>
|
|
<a
|
|
className={cn(
|
|
"mt-1 flex items-center px-3 py-2 text-sm font-medium rounded-md",
|
|
location === item.href
|
|
? "bg-primary text-primary-foreground"
|
|
: "hover:bg-accent hover:text-accent-foreground"
|
|
)}
|
|
>
|
|
{item.icon}
|
|
{item.title}
|
|
</a>
|
|
</Link>
|
|
))}
|
|
</div>
|
|
)}
|
|
</nav>
|
|
|
|
<div className="p-4 border-t border-border flex flex-col gap-2">
|
|
<ThemeToggle />
|
|
<Button
|
|
variant="outline"
|
|
className="w-full justify-start"
|
|
onClick={() => logoutMutation.mutate()}
|
|
disabled={logoutMutation.isPending}
|
|
>
|
|
<LogOut className="mr-2 h-4 w-4" />
|
|
Log out
|
|
</Button>
|
|
</div>
|
|
</aside>
|
|
);
|
|
}
|