177 lines
7.6 KiB
TypeScript
177 lines
7.6 KiB
TypeScript
import { useState, useEffect } from 'react';
|
|
import { Button } from "@/components/ui/button";
|
|
import { Menu, X, Volleyball, ChevronDown, Users } from "lucide-react";
|
|
import { Link, useNavigate } from "react-router-dom";
|
|
import { useAuth } from '@/context/AuthContext';
|
|
import axios from 'axios';
|
|
|
|
|
|
type Team = {
|
|
id: number;
|
|
name: string;
|
|
}
|
|
|
|
const Navbar = () => {
|
|
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
|
const [isTeamsOpen, setIsTeamsOpen] = useState(false);
|
|
const { isAuthenticated, username, logout } = useAuth();
|
|
const [teams, setTeams] = useState<Team[]>([]);
|
|
const navigate = useNavigate();
|
|
|
|
let hoverTimeout: ReturnType<typeof setTimeout>
|
|
|
|
const handleMouseEnter = () => {
|
|
clearTimeout(hoverTimeout);
|
|
setIsTeamsOpen(true);
|
|
}
|
|
|
|
const handleMouseLeave = () => {
|
|
hoverTimeout = setTimeout(() => {
|
|
setIsTeamsOpen(false);
|
|
}, 100);
|
|
};
|
|
|
|
const toggleMenu = () => {
|
|
setIsMenuOpen(!isMenuOpen);
|
|
};
|
|
|
|
const navigateAndScroll = (sectionId: string) => {
|
|
if (window.location.pathname !== "/") {
|
|
navigate("/", { state: { scrollTo: sectionId } });
|
|
} else {
|
|
const el = document.getElementById(sectionId);
|
|
if (el) {
|
|
el.scrollIntoView({ behavior: "smooth" });
|
|
}
|
|
}
|
|
};
|
|
|
|
return (
|
|
<nav className="fixed top-0 left-0 w-full z-50 bg-white/30 backdrop-blur-md border-b border-white/20">
|
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
<div className="flex justify-between h-16 items-center">
|
|
<Link to="/" className="flex items-center">
|
|
<Volleyball className="h-8 w-8 text-frog-500 mr-2" />
|
|
<span className="font-bold text-xl text-frog-800">TG Laudenbach</span>
|
|
</Link>
|
|
|
|
{/* Desktop Navigation */}
|
|
<div className="hidden md:flex items-center space-x-4">
|
|
<button onClick={() => navigateAndScroll("top")} className="text-gray-700 hover:text-frog-600 px-3 py-2 rounded-md font-medium">Startseite</button>
|
|
<button onClick={() => navigateAndScroll("news")} className="text-gray-700 hover:text-frog-600 px-3 py-2 rounded-md font-medium">Aktuelles</button>
|
|
|
|
<div
|
|
className="relative"
|
|
onMouseEnter={handleMouseEnter}
|
|
onMouseLeave={handleMouseLeave}
|
|
>
|
|
<button className="flex items-center text-gray-700 hover:text-frog-600 px-3 py-2 rounded-md font-medium">
|
|
Teams
|
|
<ChevronDown className="ml-1 h-4 w-4" />
|
|
</button>
|
|
|
|
{isTeamsOpen && (
|
|
<div className="absolute left-0 mt-2 w-40 bg-white rounded-md shadow-lg ring-1 ring-black ring-opacity-5 z-10">
|
|
<Link to="/teams/damen1" className="block px-4 py-2 text-gray-700 hover:bg-frog-50 hover:text-frog-600">Damen 1</Link>
|
|
<Link to="/teams/damen2" className="block px-4 py-2 text-gray-700 hover:bg-frog-50 hover:text-frog-600">Damen 2</Link>
|
|
<Link to="/teams/herren1" className="block px-4 py-2 text-gray-700 hover:bg-frog-50 hover:text-frog-600">Herren 1</Link>
|
|
<Link to="/teams/herren2" className="block px-4 py-2 text-gray-700 hover:bg-frog-50 hover:text-frog-600">Herren 2</Link>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
|
|
<button onClick={() => navigateAndScroll("gallery")} className="text-gray-700 hover:text-frog-600 px-3 py-2 rounded-md font-medium">Galerie</button>
|
|
<button onClick={() => navigateAndScroll("about")} className="text-gray-700 hover:text-frog-600 px-3 py-2 rounded-md font-medium">Über uns</button>
|
|
<button onClick={() => navigateAndScroll("contact")} className="text-gray-700 hover:text-frog-600 px-3 py-2 rounded-md font-medium">Kontakt</button>
|
|
|
|
<Link to="/mitglied-werden" className="w-full">
|
|
<Button className="w-full bg-frog-500 hover:bg-frog-600 text-white">
|
|
Mitglied werden
|
|
</Button>
|
|
</Link>
|
|
|
|
<div className="relative group ml-4">
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
onClick={() => {
|
|
if (isAuthenticated) {
|
|
navigate("/admin");
|
|
} else {
|
|
navigate("/admin/login");
|
|
}
|
|
}}
|
|
>
|
|
<Users className="h-6 w-6 text-frog-600 hover:text-frog-800" />
|
|
</Button>
|
|
|
|
{isAuthenticated && (
|
|
<>
|
|
<span className="text-sm text-frog-600 ml-2 hidden md:inline">
|
|
{username}
|
|
</span>
|
|
<div className="absolute right-0 mt-2 hidden group-hover:block bg-white rounded-md shadow-lg z-20 p-2">
|
|
<Button
|
|
variant="ghost"
|
|
className="w-full text-left text-gray-700 hover:bg-frog-50 hover:text-frog-600"
|
|
onClick={() => {
|
|
logout();
|
|
navigate("/admin/login");
|
|
}}
|
|
>
|
|
Logout
|
|
</Button>
|
|
</div>
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Mobile menu button */}
|
|
<div className="md:hidden flex items-center">
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
onClick={toggleMenu}
|
|
aria-expanded={isMenuOpen}
|
|
>
|
|
{isMenuOpen ? <X className="h-6 w-6" /> : <Menu className="h-6 w-6" />}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Mobile Navigation */}
|
|
{isMenuOpen && (
|
|
<div className="md:hidden">
|
|
<div className="px-2 pt-2 pb-3 space-y-1 sm:px-3 bg-white">
|
|
<button onClick={() => navigateAndScroll("top")} className="block px-3 py-2 rounded-md text-base font-medium text-gray-700 hover:text-frog-600 hover:bg-frog-50">Startseite</button>
|
|
<button onClick={() => navigateAndScroll("news")} className="block px-3 py-2 rounded-md text-base font-medium text-gray-700 hover:text-frog-600 hover:bg-frog-50">Aktuelles</button>
|
|
|
|
<div>
|
|
<div className="block px-3 py-2 rounded-md text-base font-medium text-gray-700">Teams</div>
|
|
<div className="pl-6">
|
|
<Link to="/teams/damen1" className="block px-3 py-1 text-gray-700 hover:text-frog-600">Damen 1</Link>
|
|
<Link to="/teams/damen2" className="block px-3 py-1 text-gray-700 hover:text-frog-600">Damen 2</Link>
|
|
<Link to="/teams/herren1" className="block px-3 py-1 text-gray-700 hover:text-frog-600">Herren 1</Link>
|
|
<Link to="/teams/herren2" className="block px-3 py-1 text-gray-700 hover:text-frog-600">Herren 2</Link>
|
|
</div>
|
|
</div>
|
|
|
|
<button onClick={() => navigateAndScroll("gallery")} className="block px-3 py-2 rounded-md text-base font-medium text-gray-700 hover:text-frog-600 hover:bg-frog-50">Galerie</button>
|
|
<button onClick={() => navigateAndScroll("about")} className="block px-3 py-2 rounded-md text-base font-medium text-gray-700 hover:text-frog-600 hover:bg-frog-50">Über uns</button>
|
|
<button onClick={() => navigateAndScroll("contact")} className="block px-3 py-2 rounded-md text-base font-medium text-gray-700 hover:text-frog-600 hover:bg-frog-50">Kontakt</button>
|
|
|
|
<Link to="/mitglied-werden">
|
|
<Button className="w-full bg-frog-500 hover:bg-frog-600 text-white mt-4">Mitglied werden</Button>
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</nav>
|
|
);
|
|
};
|
|
|
|
export default Navbar;
|