feat: Add mobile hamburger menu and Videos link to Browse dropdown
Some checks are pending
Deploy Elmeg / deploy (push) Waiting to run
Some checks are pending
Deploy Elmeg / deploy (push) Waiting to run
This commit is contained in:
parent
735fd1a6ea
commit
1b11ad8b52
1 changed files with 154 additions and 55 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
"use client"
|
"use client"
|
||||||
|
import { useState } from "react"
|
||||||
import Link from "next/link"
|
import Link from "next/link"
|
||||||
import { Music, User, ChevronDown } from "lucide-react"
|
import { Music, User, ChevronDown, Menu, X } from "lucide-react"
|
||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button"
|
||||||
import { SearchDialog } from "@/components/ui/search-dialog"
|
import { SearchDialog } from "@/components/ui/search-dialog"
|
||||||
import { NotificationBell } from "@/components/notifications/notification-bell"
|
import { NotificationBell } from "@/components/notifications/notification-bell"
|
||||||
|
|
@ -14,19 +15,30 @@ import {
|
||||||
} from "@/components/ui/dropdown-menu"
|
} from "@/components/ui/dropdown-menu"
|
||||||
import { useAuth } from "@/contexts/auth-context"
|
import { useAuth } from "@/contexts/auth-context"
|
||||||
|
|
||||||
|
const browseLinks = [
|
||||||
|
{ href: "/shows", label: "Shows" },
|
||||||
|
{ href: "/venues", label: "Venues" },
|
||||||
|
{ href: "/songs", label: "Songs" },
|
||||||
|
{ href: "/performances", label: "Top Performances" },
|
||||||
|
{ href: "/tours", label: "Tours" },
|
||||||
|
{ href: "/videos", label: "Videos" },
|
||||||
|
]
|
||||||
|
|
||||||
export function Navbar() {
|
export function Navbar() {
|
||||||
const { user, logout } = useAuth()
|
const { user, logout } = useAuth()
|
||||||
|
const [mobileMenuOpen, setMobileMenuOpen] = useState(false)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<header className="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
|
<header className="sticky top-0 z-50 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
|
||||||
<div className="container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 flex h-14 items-center">
|
<div className="container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 flex h-14 items-center justify-between">
|
||||||
<div className="mr-4 hidden md:flex">
|
{/* Logo - always visible */}
|
||||||
<Link href="/" className="mr-6 flex items-center space-x-2">
|
<Link href="/" className="flex items-center space-x-2">
|
||||||
<Music className="h-6 w-6" />
|
<Music className="h-6 w-6" />
|
||||||
<span className="hidden font-bold sm:inline-block">
|
<span className="font-bold">Elmeg</span>
|
||||||
Elmeg
|
|
||||||
</span>
|
|
||||||
</Link>
|
</Link>
|
||||||
<nav className="flex items-center space-x-6 text-sm font-medium">
|
|
||||||
|
{/* Desktop Navigation */}
|
||||||
|
<nav className="hidden md:flex items-center space-x-6 text-sm font-medium">
|
||||||
<Link href="/archive" className="transition-colors hover:text-foreground/80 text-foreground/60">
|
<Link href="/archive" className="transition-colors hover:text-foreground/80 text-foreground/60">
|
||||||
Archive
|
Archive
|
||||||
</Link>
|
</Link>
|
||||||
|
|
@ -37,22 +49,11 @@ export function Navbar() {
|
||||||
<ChevronDown className="h-4 w-4" />
|
<ChevronDown className="h-4 w-4" />
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent align="start">
|
<DropdownMenuContent align="start">
|
||||||
<Link href="/shows">
|
{browseLinks.map((link) => (
|
||||||
<DropdownMenuItem>Shows</DropdownMenuItem>
|
<Link key={link.href} href={link.href}>
|
||||||
|
<DropdownMenuItem>{link.label}</DropdownMenuItem>
|
||||||
</Link>
|
</Link>
|
||||||
<Link href="/venues">
|
))}
|
||||||
<DropdownMenuItem>Venues</DropdownMenuItem>
|
|
||||||
</Link>
|
|
||||||
<Link href="/songs">
|
|
||||||
<DropdownMenuItem>Songs</DropdownMenuItem>
|
|
||||||
</Link>
|
|
||||||
<Link href="/performances">
|
|
||||||
<DropdownMenuItem>Top Performances</DropdownMenuItem>
|
|
||||||
</Link>
|
|
||||||
<Link href="/tours">
|
|
||||||
<DropdownMenuItem>Tours</DropdownMenuItem>
|
|
||||||
</Link>
|
|
||||||
{/* Leaderboards hidden until community activity grows */}
|
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
|
|
||||||
|
|
@ -60,20 +61,21 @@ export function Navbar() {
|
||||||
About
|
About
|
||||||
</Link>
|
</Link>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
|
||||||
<div className="flex flex-1 items-center justify-between space-x-2 md:justify-end">
|
{/* Right side - search, theme, auth */}
|
||||||
<div className="w-full flex-1 md:w-auto md:flex-none">
|
<div className="flex items-center gap-2">
|
||||||
|
<div className="hidden sm:block">
|
||||||
<SearchDialog />
|
<SearchDialog />
|
||||||
</div>
|
</div>
|
||||||
<ThemeToggle />
|
<ThemeToggle />
|
||||||
<nav className="flex items-center gap-2">
|
|
||||||
|
{/* Desktop auth */}
|
||||||
|
<div className="hidden md:flex items-center gap-2">
|
||||||
{user ? (
|
{user ? (
|
||||||
<>
|
<>
|
||||||
{(user.role === 'admin' || user.role === 'moderator') && (
|
{(user.role === 'admin' || user.role === 'moderator') && (
|
||||||
<Link href="/mod">
|
<Link href="/mod">
|
||||||
<Button variant="ghost" size="sm">
|
<Button variant="ghost" size="sm">Mod</Button>
|
||||||
Mod
|
|
||||||
</Button>
|
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
<NotificationBell />
|
<NotificationBell />
|
||||||
|
|
@ -103,22 +105,119 @@ export function Navbar() {
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex items-center gap-2">
|
<>
|
||||||
<Link href="/login">
|
<Link href="/login">
|
||||||
<Button variant="ghost" size="sm">
|
<Button variant="ghost" size="sm">Sign In</Button>
|
||||||
Sign In
|
|
||||||
</Button>
|
|
||||||
</Link>
|
</Link>
|
||||||
<Link href="/register">
|
<Link href="/register">
|
||||||
<Button size="sm">
|
<Button size="sm">Sign Up</Button>
|
||||||
Sign Up
|
</Link>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Mobile menu button */}
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="icon"
|
||||||
|
className="md:hidden"
|
||||||
|
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
|
||||||
|
>
|
||||||
|
{mobileMenuOpen ? <X className="h-5 w-5" /> : <Menu className="h-5 w-5" />}
|
||||||
|
<span className="sr-only">Toggle menu</span>
|
||||||
</Button>
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Mobile Menu */}
|
||||||
|
{mobileMenuOpen && (
|
||||||
|
<div className="md:hidden border-t bg-background">
|
||||||
|
<div className="container mx-auto max-w-7xl px-4 py-4 space-y-4">
|
||||||
|
{/* Mobile search */}
|
||||||
|
<div className="sm:hidden">
|
||||||
|
<SearchDialog />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Mobile nav links */}
|
||||||
|
<nav className="flex flex-col space-y-2">
|
||||||
|
<Link
|
||||||
|
href="/archive"
|
||||||
|
className="px-3 py-2 rounded-md hover:bg-muted transition-colors"
|
||||||
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
|
>
|
||||||
|
Archive
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<div className="px-3 py-2 text-sm font-medium text-muted-foreground">Browse</div>
|
||||||
|
{browseLinks.map((link) => (
|
||||||
|
<Link
|
||||||
|
key={link.href}
|
||||||
|
href={link.href}
|
||||||
|
className="px-6 py-2 rounded-md hover:bg-muted transition-colors"
|
||||||
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
|
>
|
||||||
|
{link.label}
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
|
||||||
|
<Link
|
||||||
|
href="/about"
|
||||||
|
className="px-3 py-2 rounded-md hover:bg-muted transition-colors"
|
||||||
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
|
>
|
||||||
|
About
|
||||||
|
</Link>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
{/* Mobile auth */}
|
||||||
|
<div className="border-t pt-4">
|
||||||
|
{user ? (
|
||||||
|
<div className="flex flex-col space-y-2">
|
||||||
|
<div className="px-3 py-2 text-sm text-muted-foreground">{user.email}</div>
|
||||||
|
{(user.role === 'admin' || user.role === 'moderator') && (
|
||||||
|
<Link
|
||||||
|
href="/mod"
|
||||||
|
className="px-3 py-2 rounded-md hover:bg-muted transition-colors"
|
||||||
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
|
>
|
||||||
|
Moderation
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
<Link
|
||||||
|
href="/profile"
|
||||||
|
className="px-3 py-2 rounded-md hover:bg-muted transition-colors"
|
||||||
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
|
>
|
||||||
|
Profile
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="/settings"
|
||||||
|
className="px-3 py-2 rounded-md hover:bg-muted transition-colors"
|
||||||
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
|
>
|
||||||
|
Settings
|
||||||
|
</Link>
|
||||||
|
<button
|
||||||
|
onClick={() => { logout(); setMobileMenuOpen(false); }}
|
||||||
|
className="px-3 py-2 text-left rounded-md text-red-500 hover:bg-muted transition-colors"
|
||||||
|
>
|
||||||
|
Sign Out
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<Link href="/login" className="flex-1" onClick={() => setMobileMenuOpen(false)}>
|
||||||
|
<Button variant="outline" className="w-full">Sign In</Button>
|
||||||
|
</Link>
|
||||||
|
<Link href="/register" className="flex-1" onClick={() => setMobileMenuOpen(false)}>
|
||||||
|
<Button className="w-full">Sign Up</Button>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</nav>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</header>
|
</header>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue