Files
road-monitoring-ui/components/navigation-menu.tsx

151 lines
5.5 KiB
TypeScript

"use client"
import { useState } from "react"
import { useRouter, usePathname } from "next/navigation"
import {
Sheet,
SheetContent,
SheetHeader,
SheetTitle,
SheetTrigger,
} from "@/components/ui/sheet"
import { Button } from "@/components/ui/button"
import {
Menu,
LayoutDashboard,
ChevronRight,
PlusCircle,
FolderPlus,
Package,
MapPin,
Map
} from "lucide-react"
import { PoweredBy } from "@/components/powered-by"
interface NavItem {
title: string
description: string
href: string
icon: React.ElementType
}
const navItems: NavItem[] = [
{
title: "Dashboard",
description: "View analytics, statistics, and recent analyses",
href: "/dashboard",
icon: LayoutDashboard
},
{
title: "New Analysis",
description: "Start a new road analysis project",
href: "/new-analysis",
icon: PlusCircle
},
{
title: "Create Project",
description: "Create a new infrastructure project",
href: "/create-project",
icon: FolderPlus
},
{
title: "Create Package",
description: "Add a package under an existing project",
href: "/create-package",
icon: Package
},
{
title: "Create Location",
description: "Add a location under a project & package",
href: "/create-location",
icon: MapPin
},
{
title: "Show Map",
description: "View all detections on an interactive map",
href: "/map",
icon: Map
}
]
export function NavigationMenu() {
const [isOpen, setIsOpen] = useState(false)
const router = useRouter()
const pathname = usePathname()
const handleNavigation = (href: string) => {
setIsOpen(false)
router.push(href)
}
return (
<Sheet open={isOpen} onOpenChange={setIsOpen}>
<SheetTrigger asChild>
<Button
variant="ghost"
size="icon"
className="fixed top-4 left-4 z-50 h-11 w-11 rounded-xl glass-card border border-white/20 shadow-lg hover:bg-white/20 hover:scale-105 transition-all duration-300"
aria-label="Open navigation menu"
>
<Menu className="h-5 w-5 text-foreground" />
</Button>
</SheetTrigger>
<SheetContent side="left" className="w-[320px] sm:w-[380px] bg-white backdrop-blur-xl border-r border-slate-200">
<SheetHeader className="pb-6 border-b border-slate-100">
<SheetTitle className="text-2xl font-bold text-[#3b82f6]">
VisionRoad
</SheetTitle>
<p className="text-sm text-gray-500">
AI-Powered Road Detection System
</p>
</SheetHeader>
{/* Navigation Items */}
<nav className="mt-6 space-y-2">
{navItems.map((item) => {
const isActive = pathname === item.href
const Icon = item.icon
return (
<button
key={item.href}
onClick={() => handleNavigation(item.href)}
className={`w-full flex items-center gap-4 p-4 rounded-xl text-left transition-all duration-300 group ${isActive
? "bg-slate-50 border border-slate-200"
: "hover:bg-slate-50 border border-transparent hover:border-slate-100"
}`}
>
<div className={`p-2.5 rounded-lg transition-all duration-300 ${isActive
? "bg-linear-to-b from-[#3895FF] to-[#86B8F1] text-white"
: "bg-[#f0fafd] text-slate-900 group-hover:bg-linear-to-b group-hover:from-[#3895FF] group-hover:to-[#86B8F1] group-hover:text-white border border-slate-100 shadow-sm"
}`}>
<Icon
className={`h-5 w-5 ${isActive ? 'stroke-[2.5]' : 'stroke-2'}`}
/>
</div>
<div className="flex-1 min-w-0">
<h3 className={`font-semibold text-sm ${isActive ? "text-[#1e40af]" : "text-gray-700"
}`}>
{item.title}
</h3>
<p className="text-xs text-gray-400 truncate mt-0.5">
{item.description}
</p>
</div>
<ChevronRight className={`h-4 w-4 transition-all duration-300 ${isActive
? "text-[#1e40af] opacity-100"
: "text-gray-300 opacity-0 group-hover:opacity-100"
}`} />
</button>
)
})}
</nav>
<div className="absolute bottom-4 left-4 right-4">
<PoweredBy />
</div>
</SheetContent>
</Sheet>
)
}