Navbar gefixt
Some checks are pending
Deploy Volleyball Dev / deploy (push) Waiting to run

This commit is contained in:
Marc Wieland 2025-04-30 00:06:28 +02:00
parent 6af5da0a90
commit 5cd544147a
4 changed files with 88 additions and 32 deletions

10
package-lock.json generated
View File

@ -52,6 +52,7 @@
"react-day-picker": "^8.10.1",
"react-dom": "^18.3.1",
"react-hook-form": "^7.53.0",
"react-loading-skeleton": "^3.5.0",
"react-markdown": "^10.1.0",
"react-quill": "^2.0.0",
"react-resizable-panels": "^2.1.3",
@ -7438,6 +7439,15 @@
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
"license": "MIT"
},
"node_modules/react-loading-skeleton": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/react-loading-skeleton/-/react-loading-skeleton-3.5.0.tgz",
"integrity": "sha512-gxxSyLbrEAdXTKgfbpBEFZCO/P153DnqSCQau2+o6lNy1jgMRr2MmRmOzMmyrwSaSYLRB8g7b0waYPmUjz7IhQ==",
"license": "MIT",
"peerDependencies": {
"react": ">=16.8.0"
}
},
"node_modules/react-markdown": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz",

View File

@ -55,6 +55,7 @@
"react-day-picker": "^8.10.1",
"react-dom": "^18.3.1",
"react-hook-form": "^7.53.0",
"react-loading-skeleton": "^3.5.0",
"react-markdown": "^10.1.0",
"react-quill": "^2.0.0",
"react-resizable-panels": "^2.1.3",

View File

@ -14,6 +14,17 @@ const Navbar = () => {
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">
@ -25,22 +36,19 @@ const Navbar = () => {
{/* Desktop Navigation */}
<div className="hidden md:flex items-center space-x-4">
<a href="#" className="text-gray-700 hover:text-frog-600 px-3 py-2 rounded-md font-medium">Startseite</a>
<a href="#news" className="text-gray-700 hover:text-frog-600 px-3 py-2 rounded-md font-medium">Aktuelles</a>
<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={() => setIsTeamsOpen(true)}
<div
className="relative"
onMouseEnter={() => setIsTeamsOpen(true)}
onMouseLeave={() => setIsTeamsOpen(false)}
>
<button
className="flex items-center text-gray-700 hover:text-frog-600 px-3 py-2 rounded-md font-medium focus:outline-none"
>
<button className="flex items-center text-gray-700 hover:text-frog-600 px-3 py-2 rounded-md font-medium focus:outline-none">
Teams
<ChevronDown className="ml-1 h-4 w-4" />
</button>
{/* Dropdown */}
{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>
@ -51,21 +59,20 @@ const Navbar = () => {
)}
</div>
<a href="#gallery" className="text-gray-700 hover:text-frog-600 px-3 py-2 rounded-md font-medium">Galerie</a>
<a href="#about" className="text-gray-700 hover:text-frog-600 px-3 py-2 rounded-md font-medium">Über uns</a>
<a href="#contact" className="text-gray-700 hover:text-frog-600 px-3 py-2 rounded-md font-medium">Kontakt</a>
<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>
{/* USER ICON + DROPDOWN */}
<div className="relative group ml-4">
<Button
variant="ghost"
size="icon"
<Button
variant="ghost"
size="icon"
onClick={() => {
if (isAuthenticated) {
navigate("/admin");
@ -82,8 +89,6 @@ const Navbar = () => {
<span className="text-sm text-frog-600 ml-2 hidden md:inline">
{username}
</span>
{/* Dropdown */}
<div className="absolute right-0 mt-2 hidden group-hover:block bg-white rounded-md shadow-lg z-20 p-2">
<Button
variant="ghost"
@ -99,14 +104,13 @@ const Navbar = () => {
</>
)}
</div>
</div>
{/* Mobile menu button */}
<div className="md:hidden flex items-center">
<Button
variant="ghost"
size="icon"
<Button
variant="ghost"
size="icon"
onClick={toggleMenu}
aria-expanded={isMenuOpen}
>
@ -120,10 +124,9 @@ const Navbar = () => {
{isMenuOpen && (
<div className="md:hidden">
<div className="px-2 pt-2 pb-3 space-y-1 sm:px-3 bg-white">
<a href="#" className="block px-3 py-2 rounded-md text-base font-medium text-gray-700 hover:text-frog-600 hover:bg-frog-50">Startseite</a>
<a href="#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</a>
<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>
{/* Mobile Teams Submenu */}
<div>
<div className="block px-3 py-2 rounded-md text-base font-medium text-gray-700">Teams</div>
<div className="pl-6">
@ -134,9 +137,10 @@ const Navbar = () => {
</div>
</div>
<a href="#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</a>
<a href="#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</a>
<a href="#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</a>
<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>

View File

@ -2,6 +2,8 @@ import { useParams } from "react-router-dom";
import { useEffect, useState } from "react";
import { Carousel } from "react-responsive-carousel";
import "react-responsive-carousel/lib/styles/carousel.min.css";
import Skeleton from "react-loading-skeleton";
import "react-loading-skeleton/dist/skeleton.css";
const apiBase = import.meta.env.VITE_API_URL;
@ -51,7 +53,42 @@ const TeamDetailPage = () => {
fetchTeam();
}, [id]);
if (loading) return <p className="text-center py-12">Lade Teamdaten...</p>;
if (loading) {
return (
<div className="max-w-7xl mx-auto py-8 px-4">
<div className="mb-8">
<Skeleton height={400} borderRadius={12} />
</div>
<div className="text-center mb-12">
<h1 className="text-4xl font-bold text-frog-600">
<Skeleton width={220} />
</h1>
<p className="text-lg text-gray-700 mt-2">
<Skeleton width={160} />
</p>
<p className="mt-4 text-gray-600">
<Skeleton count={2} />
</p>
<p className="text-sm text-frog-700 font-medium mt-2">
<Skeleton width={180} />
</p>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6">
{[...Array(3)].map((_, i) => (
<div key={i} className="bg-white rounded-lg shadow-md p-4">
<Skeleton height={200} className="mb-4" />
<Skeleton width={`60%`} height={24} />
<Skeleton width={`40%`} height={18} />
<Skeleton width={`50%`} height={14} />
</div>
))}
</div>
</div>
);
}
if (!team) return <p className="text-center py-12">Team nicht gefunden 🐸</p>;
return (
@ -89,7 +126,9 @@ const TeamDetailPage = () => {
Training: {team.trainingszeiten || "Nicht angegeben"}
</p>
{team.trainingsort && (
<p className="text-sm text-gray-500 mt-1">Ort: {team.trainingsort}</p>
<p className="text-sm text-gray-500 mt-1">
Ort: {team.trainingsort}
</p>
)}
</div>
@ -118,7 +157,9 @@ const TeamDetailPage = () => {
alt={player.name}
className="w-full h-108 object-cover rounded-lg mb-4"
/>
<h3 className="text-xl font-semibold text-frog-700">{player.name}</h3>
<h3 className="text-xl font-semibold text-frog-700">
{player.name}
</h3>
<p className="text-gray-500">{player.position}</p>
{player.nickname && (
<p className="text-sm text-frog-500 mt-1">{player.nickname}</p>