1const e=`import { useNavigate, useLocation } from "react-router-dom"; 2import { useState, useRef } from "react"; 3import { Button } from "@/components/ui/button"; 4 5export default function NavBar({ user }) { 6 const navigate = useNavigate(); 7 const location = useLocation(); 8 const [mobileOpen, setMobileOpen] = useState(false); 9 const [openDropdown, setOpenDropdown] = useState(null); 10 const hoverTimeout = useRef(null); 11 12 const handleMouseEnter = (label) => { 13 clearTimeout(hoverTimeout.current); 14 setOpenDropdown(label); 15 }; 16 17 const handleMouseLeave = () => { 18 hoverTimeout.current = setTimeout(() => { 19 setOpenDropdown(null); 20 }, 150); 21 }; 22 23 const path = location.pathname; 24 25 const isActive = (routes) => 26 routes.some(r => path === r || path.startsWith(r)); 27 28 const navItems = [ 29 { 30 label: "Library", 31 routes: ["/Library", "/SongPreview"], 32 children: [ 33 { label: "ðµ Song Library", route: "/Library" }, 34 { label: "ð¼ Song Sets", route: "/Library?tab=sets" }, 35 ], 36 }, 37 { 38 label: "Catalog", 39 routes: ["/Catalog", "/CatalogWorkspace"], 40 children: [ 41 { label: "ð Browse Catalog", route: "/Catalog" }, 42 { label: "âï¸ Catalog Workspace", route: "/CatalogWorkspace" }, 43 ], 44 }, 45 { 46 label: "Backgrounds", 47 routes: ["/BackgroundDesigner", "/Favorites"], 48 children: [ 49 { label: "ð¨ Background Designer", route: "/BackgroundDesigner" }, 50 { label: "â My Favorites", route: "/Favorites" }, 51 ], 52 }, 53 { label: "Team", route: "/Team", routes: ["/Team"] }, 54 { label: "Settings", route: "/Settings", routes: ["/Settings"] }, 55 { label: "Guide", route: "/UserGuide", routes: ["/UserGuide"] }, 56 ]; 57 58 const handleNav = (route) => { 59 navigate(route); 60 setMobileOpen(false); 61 setOpenDropdown(null); 62 }; 63 64 const handleLogout = async () => { 65 await import("@/api/base44Client").then(m => m.base44.auth.logout()); 66 }; 67 68 const toggleTheme = () => { 69 const current = localStorage.getItem("theme"); 70 const next = current === "dark" ? "light" : "dark"; 71 localStorage.setItem("theme", next); 72 document.documentElement.classList.toggle("dark", next === "dark"); 73 }; 74 75 return ( 76 <header className="sticky top-0 z-50 w-full bg-slate-950 border-b border-slate-800 h-14 flex items-center px-4"> 77 78 {/* Logo */} 79 <div className="flex items-center gap-3 cursor-pointer flex-shrink-0" onClick={() => handleNav("/")}> 80 <img src="https://qtrypzzcjebvfcihiynt.supabase.co/storage/v1/object/public/base44-prod/public/6960417100e858f30f2881b6/488a27e39_Untitled-20260108-232326-4413-2x.png" 81 alt="SongSlide" className="h-8 w-auto" /> 82 </div> 83 84 {/* Org name */} 85 {user?.tenantName && ( 86 <span className="ml-3 text-xs text-slate-500 hidden md:block border border-slate-700 rounded px-2 py-0.5"> 87 ð¢ {user.tenantName} 88 </span> 89 )} 90 91 {/* Desktop Nav */} 92 <nav className="hidden md:flex items-center gap-1 ml-6 flex-1"> 93 {navItems.map((item) => ( 94 <div key={item.label} className="relative" 95 onMouseEnter={() => item.children && handleMouseEnter(item.label)} 96 onMouseLeave={handleMouseLeave}> 97 98 {item.children ? ( 99 <> 100 <button 101 onClick={() => setOpenDropdown(openDropdown === item.label ? null : item.label)} 102 className={\`flex items-center gap-1 px-3 pt-2 pb-3 rounded-md text-sm font-medium transition-colors 103 \${isActive(item.routes) 104 ? "text-sky-400 bg-slate-800" 105 : "text-slate-300 hover:text-white hover:bg-slate-800"}\`}> 106 {item.label} 107 <span className={\`text-xs transition-transform \${openDropdown === item.label ? "rotate-180" : ""}\`}>â¾</span> 108 </button> 109 110 {openDropdown === item.label && ( 111 <div 112 className="absolute top-full left-0 w-52 z-50" 113 onMouseEnter={() => clearTimeout(hoverTimeout.current)} 114 onMouseLeave={handleMouseLeave} 115 > 116 <div className="h-1 w-full" /> 117 <div className="w-full bg-slate-800 border border-slate-700 rounded-lg shadow-xl py-1"> 118 {item.children.map((child) => ( 119 <button key={child.route} 120 onClick={() => handleNav(child.route)} 121 className="w-full text-left px-4 py-2 text-sm text-slate-300 hover:text-white hover:bg-slate-700 flex items-center gap-2"> 122 {child.label} 123 </button> 124 ))} 125 </div> 126 </div> 127 )} 128 </> 129 ) : ( 130 <button 131 onClick={() => handleNav(item.route)} 132 className={\`px-3 py-2 rounded-md text-sm font-medium transition-colors 133 \${isActive(item.routes) 134 ? "text-sky-400 bg-slate-800" 135 : "text-slate-300 hover:text-white hover:bg-slate-800"}\`}> 136 {item.label} 137 </button> 138 )} 139 </div> 140 ))} 141 </nav> 142 143 {/* Right side â desktop */} 144 <div className="hidden md:flex items-center gap-2 ml-auto"> 145 <button onClick={toggleTheme} 146 className="p-2 rounded-md text-slate-400 hover:text-white hover:bg-slate-800 transition-colors text-lg"> 147 âï¸ 148 </button> 149 <button onClick={handleLogout} 150 className="px-3 py-1.5 text-sm text-slate-300 hover:text-white hover:bg-slate-800 rounded-md transition-colors"> 151 Logout 152 </button> 153 </div> 154 155 {/* Mobile hamburger */} 156 <button className="md:hidden ml-auto p-2 text-slate-300 hover:text-white" 157 onClick={() => setMobileOpen(!mobileOpen)}> 158 {mobileOpen ? "â" : "â°"} 159 </button> 160 161 {/* Mobile drawer */} 162 {mobileOpen && ( 163 <div className="absolute top-14 left-0 right-0 bg-slate-900 border-b border-slate-700 z-50 md:hidden"> 164 {navItems.map((item) => ( 165 <div key={item.label}> 166 {item.children ? ( 167 <> 168 <button 169 onClick={() => setOpenDropdown(openDropdown === item.label ? null : item.label)} 170 className="w-full text-left px-4 py-3 text-sm font-medium text-slate-300 hover:text-white hover:bg-slate-800 flex justify-between items-center border-b border-slate-800"> 171 {item.label} <span>{openDropdown === item.label ? "â´" : "â¾"}</span> 172 </button> 173 {openDropdown === item.label && item.children.map((child) => ( 174 <button key={child.route} 175 onClick={() => handleNav(child.route)} 176 className="w-full text-left px-8 py-2.5 text-sm text-slate-400 hover:text-white hover:bg-slate-800 border-b border-slate-800"> 177 {child.label} 178 </button> 179 ))} 180 </> 181 ) : ( 182 <button 183 onClick={() => handleNav(item.route)} 184 className="w-full text-left px-4 py-3 text-sm font-medium text-slate-300 hover:text-white hover:bg-slate-800 border-b border-slate-800"> 185 {item.label} 186 </button> 187 )} 188 </div> 189 ))} 190 <div className="flex items-center justify-between px-4 py-3"> 191 <button onClick={toggleTheme} className="text-slate-400 hover:text-white text-lg">
191âï¸</button> 192 <button onClick={handleLogout} className="text-sm text-slate-300 hover:text-white">Logout</button> 193 </div> 194 </div> 195 )} 196 </header> 197 ); 198}`;export{e as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.