Spaces:
Running
Running
File size: 6,531 Bytes
9215c5e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | 'use client'
import React from "react"
import { useState } from 'react'
import { ChevronDown, Menu, X } from 'lucide-react'
import Link from 'next/link'
import { ThemeToggle } from '@/components/theme-toggle'
export function Header() {
const [isMenuOpen, setIsMenuOpen] = useState(false)
const [isMoreOpen, setIsMoreOpen] = useState(false)
const handleProjectsClick = (e: React.MouseEvent) => {
e.preventDefault()
const element = document.getElementById('featured-projects')
if (element) {
element.scrollIntoView({ behavior: 'smooth' })
setIsMenuOpen(false)
}
}
const menuItems = [
{ label: 'Home', href: '/' },
{ label: 'Projects', href: '#featured-projects', onClick: handleProjectsClick },
{ label: 'Research', href: '/research' },
{ label: 'Blogs', href: '/blogs' },
{ label: 'Teams', href: '/teams' },
]
const moreItems = [
{ label: 'Events', href: '/events' },
{ label: 'People Review', href: '/reviews' },
{ label: 'Contact Us', href: '/contact' },
{ label: 'Join Community', href: '/join' },
{ label: 'Educational Content', href: '/education' },
]
return (
<header className="fixed top-0 left-0 right-0 z-50 bg-background/95 backdrop-blur-md border-b border-border" role="banner">
<div className="container mx-auto px-3 sm:px-4 lg:px-6">
{/* Top Bar */}
<div className="flex items-center justify-between py-3 sm:py-4">
{/* Logo and Brand */}
<Link href="/" className="flex items-center gap-2 sm:gap-3 hover:opacity-80 transition-opacity" aria-label="Ignite - Home">
<div className="w-8 h-8 sm:w-10 sm:h-10 rounded-lg bg-gradient-to-br from-primary to-secondary flex items-center justify-center text-white font-bold text-sm sm:text-lg">
I
</div>
<div className="hidden xs:block">
<h1 className="text-lg sm:text-xl font-bold text-foreground">Ignite</h1>
<p className="text-[10px] sm:text-xs text-muted-foreground">Open Source Community</p>
</div>
</Link>
{/* Desktop Navigation */}
<nav className="hidden md:flex items-center gap-1">
{menuItems.map((item) => (
<button
key={item.label}
onClick={item.onClick}
as={item.onClick ? 'button' : undefined}
>
<Link
href={item.href}
className="px-4 py-2 text-sm font-medium text-foreground hover:text-primary transition-colors rounded-md hover:bg-muted inline-block"
onClick={(e) => {
if (item.onClick) {
item.onClick(e as any)
}
}}
>
{item.label}
</Link>
</button>
))}
{/* More Dropdown */}
<div className="relative group">
<button className="px-4 py-2 text-sm font-medium text-foreground hover:text-primary transition-colors rounded-md hover:bg-muted flex items-center gap-1">
More
<ChevronDown className="w-4 h-4" />
</button>
<div className="absolute right-0 mt-0 w-48 bg-card border border-border rounded-lg shadow-lg opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200">
{moreItems.map((item) => (
<Link
key={item.label}
href={item.href}
className="block px-4 py-2 text-sm text-foreground hover:bg-primary hover:text-primary-foreground first:rounded-t-lg last:rounded-b-lg transition-colors"
>
{item.label}
</Link>
))}
</div>
</div>
{/* Theme Toggle */}
<ThemeToggle />
</nav>
{/* Mobile Actions */}
<div className="flex items-center gap-1 md:hidden">
<ThemeToggle />
<button
className="p-2"
onClick={() => setIsMenuOpen(!isMenuOpen)}
aria-label={isMenuOpen ? 'Close menu' : 'Open menu'}
>
{isMenuOpen ? (
<X className="w-6 h-6" />
) : (
<Menu className="w-6 h-6" />
)}
</button>
</div>
</div>
{/* Mobile Navigation */}
{isMenuOpen && (
<nav className="md:hidden pb-4 space-y-1 max-h-[70vh] overflow-y-auto" aria-label="Mobile navigation">
{menuItems.map((item) => (
<button
key={item.label}
onClick={() => {
if (item.onClick) {
item.onClick({ preventDefault: () => {} } as any)
}
setIsMenuOpen(false)
}}
className="w-full text-left"
>
<Link
href={item.href}
className="block px-3 py-2.5 text-sm font-medium text-foreground hover:text-primary hover:bg-muted rounded-md transition-colors active:bg-muted/80"
>
{item.label}
</Link>
</button>
))}
{/* Mobile More */}
<button
onClick={() => setIsMoreOpen(!isMoreOpen)}
className="w-full text-left px-3 py-2.5 text-sm font-medium text-foreground hover:text-primary hover:bg-muted rounded-md transition-colors flex items-center gap-1"
aria-expanded={isMoreOpen}
>
More
<ChevronDown className={`w-4 h-4 transition-transform duration-200 ${isMoreOpen ? 'rotate-180' : ''}`} />
</button>
{isMoreOpen && (
<div className="pl-3 space-y-1 border-l-2 border-muted ml-3">
{moreItems.map((item) => (
<Link
key={item.label}
href={item.href}
className="block px-3 py-2 text-sm text-foreground hover:text-primary hover:bg-muted rounded-md transition-colors active:bg-muted/80"
onClick={() => setIsMenuOpen(false)}
>
{item.label}
</Link>
))}
</div>
)}
</nav>
)}
</div>
</header>
)
}
|