"use client"; import { Activity, AudioWaveform, BarChartHorizontalBigIcon, Bell, BlocksIcon, BookIcon, Boxes, ChevronRight, Command, CreditCard, Database, Folder, Forward, GalleryVerticalEnd, GitBranch, Heart, KeyRound, type LucideIcon, Package, PieChart, Server, ShieldCheck, User, Users, } from "lucide-react"; import { usePathname } from "next/navigation"; import type * as React from "react"; import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, } from "@/components/ui/breadcrumb"; import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "@/components/ui/collapsible"; import { Separator } from "@/components/ui/separator"; import { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarTrigger, useSidebar, } from "@/components/ui/sidebar"; import { cn } from "@/lib/utils"; import { api } from "@/utils/api"; import Link from "next/link"; import { useRouter } from "next/router"; import { Logo } from "../shared/logo"; import { UpdateServerButton } from "./update-server"; import { UserNav } from "./user-nav"; // This is sample data. interface NavItem { title: string; url: string; icon: LucideIcon; isSingle: boolean; isActive: boolean; items?: { title: string; url: string; icon?: LucideIcon; }[]; } interface ExternalLink { name: string; url: string; icon: LucideIcon; } const data = { user: { name: "shadcn", email: "m@example.com", avatar: "/avatars/shadcn.jpg", }, teams: [ { name: "Dokploy", logo: Logo, plan: "Enterprise", }, { name: "Acme Corp.", logo: AudioWaveform, plan: "Startup", }, { name: "Evil Corp.", logo: Command, plan: "Free", }, ], home: [ { title: "Projects", url: "/dashboard/projects", icon: Folder, isSingle: true, isActive: false, }, { title: "Monitoring", url: "/dashboard/monitoring", icon: BarChartHorizontalBigIcon, isSingle: true, isActive: false, }, { title: "File System", url: "/dashboard/traefik", icon: GalleryVerticalEnd, isSingle: true, isActive: false, }, { title: "Docker", url: "/dashboard/docker", icon: BlocksIcon, isSingle: true, isActive: false, }, { title: "Swarm", url: "/dashboard/swarm", icon: PieChart, isSingle: true, isActive: false, }, { title: "Requests", url: "/dashboard/requests", icon: Forward, isSingle: true, isActive: false, }, // { // title: "Projects", // url: "/dashboard/projects", // icon: Folder, // isSingle: true, // }, // { // title: "Monitoring", // icon: BarChartHorizontalBigIcon, // url: "/dashboard/settings/monitoring", // isSingle: true, // }, // { // title: "Settings", // url: "#", // icon: Settings2, // isActive: true, // items: [ // { // title: "Profile", // url: "/dashboard/settings/profile", // }, // { // title: "Users", // url: "/dashboard/settings/users", // }, // { // title: "SSH Key", // url: "/dashboard/settings/ssh-keys", // }, // { // title: "Git", // url: "/dashboard/settings/git-providers", // }, // ], // }, // { // title: "Integrations", // icon: BlocksIcon, // items: [ // { // title: "S3 Destinations", // url: "/dashboard/settings/destinations", // }, // { // title: "Registry", // url: "/dashboard/settings/registry", // }, // { // title: "Notifications", // url: "/dashboard/settings/notifications", // }, // ], // }, // { // title: "Appearance", // icon: Frame, // items: [ // { // title: "Theme", // url: "/dashboard/settings/appearance", // }, // ], // }, ] as NavItem[], settings: [ { title: "Server", url: "/dashboard/settings/server", icon: Activity, isSingle: true, isActive: false, }, { title: "Profile", url: "/dashboard/settings/profile", icon: User, isSingle: true, isActive: false, }, { title: "Servers", url: "/dashboard/settings/servers", icon: Server, isSingle: true, isActive: false, }, { title: "Users", icon: Users, url: "/dashboard/settings/users", isSingle: true, isActive: false, }, { title: "SSH Keys", icon: KeyRound, url: "/dashboard/settings/ssh-keys", isSingle: true, isActive: false, }, { title: "Git", url: "/dashboard/settings/git-providers", icon: GitBranch, isSingle: true, isActive: false, }, { title: "Registry", url: "/dashboard/settings/registry", icon: Package, isSingle: true, isActive: false, }, { title: "S3 Destinations", url: "/dashboard/settings/destinations", icon: Database, isSingle: true, isActive: false, }, { title: "Certificates", url: "/dashboard/settings/certificates", icon: ShieldCheck, isSingle: true, isActive: false, }, { title: "Cluster", url: "/dashboard/settings/cluster", icon: Boxes, isSingle: true, isActive: false, }, { title: "Notifications", url: "/dashboard/settings/notifications", icon: Bell, isSingle: true, isActive: false, }, { title: "Billing", url: "/dashboard/settings/billing", icon: CreditCard, isSingle: true, isActive: false, }, // { // title: "Appearance", // url: "/dashboard/settings/appearance", // icon: Frame, // }, ] as NavItem[], projects: [ { name: "Documentation", url: "https://docs.dokploy.com/docs/core", icon: BookIcon, }, { name: "Support", url: "https://opencollective.com/dokploy", icon: Heart, }, // { // name: "Sales & Marketing", // url: "#", // icon: PieChart, // }, // { // name: "Travel", // url: "#", // icon: Map, // }, ] as ExternalLink[], }; interface Props { children: React.ReactNode; } function LogoWrapper() { return ; } function SidebarLogo() { const { state } = useSidebar(); const { data: dokployVersion } = api.settings.getDokployVersion.useQuery(); return (
{state === "expanded" && (
Dokploy {dokployVersion}
)} ); } export default function Page({ children }: Props) { const router = useRouter(); const pathname = usePathname(); const currentPath = router.pathname; const { data: auth } = api.auth.get.useQuery(); const { data: user } = api.user.byAuthId.useQuery( { authId: auth?.id || "", }, { enabled: !!auth?.id && auth?.rol === "user", }, ); const includesProjects = pathname?.includes("/dashboard/project"); const { data: isCloud, isLoading } = api.settings.isCloud.useQuery(); const isActiveRoute = (itemUrl: string) => { const normalizedItemUrl = itemUrl?.replace("/projects", "/project"); const normalizedPathname = pathname?.replace("/projects", "/project"); if (!normalizedPathname) return false; if (normalizedPathname === normalizedItemUrl) return true; if (normalizedPathname.startsWith(normalizedItemUrl)) { const nextChar = normalizedPathname.charAt(normalizedItemUrl.length); return nextChar === "/"; } return false; }; let filteredHome = isCloud ? data.home.filter( (item) => ![ "/dashboard/monitoring", "/dashboard/traefik", "/dashboard/docker", "/dashboard/swarm", "/dashboard/requests", ].includes(item.url), ) : data.home; let filteredSettings = isCloud ? data.settings.filter( (item) => !["/dashboard/settings/server"].includes(item.url), ) : data.settings.filter( (item) => !["/dashboard/settings/billing"].includes(item.url), ); filteredHome = filteredHome.map((item) => ({ ...item, isActive: isActiveRoute(item.url), })); filteredSettings = filteredSettings.map((item) => ({ ...item, isActive: isActiveRoute(item.url), })); const activeItem = filteredHome.find((item) => item.isActive) || filteredSettings.find((item) => item.isActive); const showProjectsButton = currentPath === "/dashboard/projects" && (auth?.rol === "admin" || user?.canCreateProjects); return ( Home {filteredHome.map((item) => ( {item.isSingle ? ( {item.title} ) : ( <> {item.icon && } {item.title} {item.items?.length && ( )} {item.items?.map((subItem) => ( {subItem.icon && ( )} {subItem.title} ))} )} ))} Settings {filteredSettings.map((item) => ( {item.isSingle ? ( {item.title} ) : ( <> {item.icon && } {item.title} {item.items?.length && ( )} {item.items?.map((subItem) => ( {subItem.icon && ( )} {subItem.title} ))} )} ))} Extra {data.projects.map((item) => ( {item.name} ))} {!isCloud && ( )} {!includesProjects && (
{activeItem?.title} {activeItem?.title}
)}
{children}
); }