This commit is contained in:
parent
6af5da0a90
commit
5cd544147a
10
package-lock.json
generated
10
package-lock.json
generated
@ -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",
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user