Spaces:
Sleeping
Sleeping
| '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> | |
| ) | |
| } | |