This commit is contained in:
@@ -1,95 +1,97 @@
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Carousel } from "react-responsive-carousel"; // Neue Library!
|
||||
import "react-responsive-carousel/lib/styles/carousel.min.css"; // Wichtig!
|
||||
import { Carousel } from "react-responsive-carousel";
|
||||
import "react-responsive-carousel/lib/styles/carousel.min.css";
|
||||
|
||||
const teamData = [
|
||||
{
|
||||
id: "1",
|
||||
name: "Damen I",
|
||||
league: "Landesliga Nord",
|
||||
description: "Unsere erste Damenmannschaft spielt auf hohem Niveau und liebt den Volleyballsport.",
|
||||
trainingTimes: "Dienstag & Donnerstag 19:00 - 21:00 Uhr",
|
||||
images: [
|
||||
"/images/damen1-1.jpg",
|
||||
"/images/damen1-2.jpg",
|
||||
"/images/damen1-3.jpg",
|
||||
],
|
||||
canJoin: false,
|
||||
players: [
|
||||
{ name: "Anna", position: "Außenangriff", nickname: "Speedy", image: "/images/anna.jpg" },
|
||||
{ name: "Lea", position: "Libera", nickname: "Wall-E", image: "/images/lea.jpg" },
|
||||
{ name: "Sophie", position: "Zuspiel", nickname: "Magic", image: "/images/sophie.jpg" },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
name: "Herren I",
|
||||
league: "Landesliga",
|
||||
description: "Das Team der Herren 1 ist tritt in der Saison 25/26 in der Landesliga beim NVV an.",
|
||||
trainingTimes: "Montag & Freitag 20:00 - 22:00 Uhr",
|
||||
images: [
|
||||
"/images/players/herren1/carousel/carousel2.jpg",
|
||||
"/images/players/herren1/carousel/carousel2.jpg",
|
||||
"/images/players/herren1/carousel/carousel2.jpg",
|
||||
],
|
||||
canJoin: true,
|
||||
players: [
|
||||
{ name: "Samuel", position: "Mittelblock", nickname: "BeSamu", image: "/images/players/herren1/samuel.jpg" },
|
||||
{ name: "Sten", position: "Außen/Annahme", nickname: "Stenislav", image: "/images/players/herren1/sten.jpg" },
|
||||
{ name: "David", position: "Mittelblock", nickname: "Blocki", image: "/images/players/herren1/david.jpg" },
|
||||
{ name: "Erik", position: "Libero", nickname: "Erika", image: "/images/players/herren1/erik.jpg" },
|
||||
{ name: "Lasse", position: "Außen/Annahme", nickname: "Lass es!", image: "/images/players/herren1/lasse.jpg" },
|
||||
{ name: "Peter", position: "Zuspieler", nickname: "-", image: "/images/players/herren1/peter.jpg" },
|
||||
{ name: "Tony", position: "Zuspieler", nickname: "Tony Mahony", image: "/images/players/herren1/tony.jpg" },
|
||||
{ name: "Marc", position: "Diagonal", nickname: "Marci", image: "/images/players/herren1/marc.jpg" },
|
||||
{ name: "Phillip", position: "Libero", nickname: "Hifi", image: "/images/players/herren1/phillip.jpg" },
|
||||
{ name: "Kathrin", position: "Trainerin", nickname: "Mutti", image: "/images/players/herren1/phillip.jpg" },
|
||||
{ name: "DU?", position: "Alles", },
|
||||
],
|
||||
},
|
||||
];
|
||||
const apiBase = import.meta.env.VITE_API_URL;
|
||||
|
||||
type Player = {
|
||||
id: number;
|
||||
name: string;
|
||||
position: string;
|
||||
nickname?: string;
|
||||
image_url?: string;
|
||||
};
|
||||
|
||||
type Team = {
|
||||
id: number;
|
||||
name: string;
|
||||
liga?: string;
|
||||
beschreibung?: string;
|
||||
trainingszeiten?: string;
|
||||
sucht_spieler?: boolean;
|
||||
karussell_bilder?: string[]; // Wichtig: als Array erwartet!
|
||||
players: Player[];
|
||||
};
|
||||
|
||||
const TeamDetailPage = () => {
|
||||
const { id } = useParams();
|
||||
const team = teamData.find((t) => t.id === id);
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const [team, setTeam] = useState<Team | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
if (!team) return <p>Team nicht gefunden 🐸</p>;
|
||||
useEffect(() => {
|
||||
const fetchTeam = async () => {
|
||||
try {
|
||||
const res = await fetch(`${apiBase}/api/teams/${id}`);
|
||||
const data = await res.json();
|
||||
|
||||
// Falls karussell_bilder als String (JSON) kommt → parsen
|
||||
if (typeof data.karussell_bilder === "string") {
|
||||
data.karussell_bilder = JSON.parse(data.karussell_bilder);
|
||||
}
|
||||
|
||||
setTeam(data);
|
||||
} catch (err) {
|
||||
console.error("Fehler beim Laden des Teams:", err);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchTeam();
|
||||
}, [id]);
|
||||
|
||||
if (loading) return <p className="text-center py-12">Lade Teamdaten...</p>;
|
||||
if (!team) return <p className="text-center py-12">Team nicht gefunden 🐸</p>;
|
||||
|
||||
return (
|
||||
<div className="max-w-7xl mx-auto py-8 px-4">
|
||||
{/* Karussell */}
|
||||
<div className="mb-8">
|
||||
<Carousel
|
||||
showThumbs={false}
|
||||
showStatus={false}
|
||||
infiniteLoop
|
||||
autoPlay
|
||||
interval={4000}
|
||||
dynamicHeight={false}
|
||||
className="rounded-lg overflow-hidden"
|
||||
>
|
||||
{team.images.map((src, index) => (
|
||||
<div key={index} className="h-96">
|
||||
<img
|
||||
src={src}
|
||||
alt={`Team ${team.name} Bild ${index + 1}`}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</Carousel>
|
||||
</div>
|
||||
{team.karussell_bilder && team.karussell_bilder.length > 0 && (
|
||||
<div className="mb-8">
|
||||
<Carousel
|
||||
showThumbs={false}
|
||||
showStatus={false}
|
||||
infiniteLoop
|
||||
autoPlay
|
||||
interval={4000}
|
||||
className="rounded-lg overflow-hidden"
|
||||
>
|
||||
{team.karussell_bilder.map((src, index) => (
|
||||
<div key={index} className="h-96">
|
||||
<img
|
||||
src={`${apiBase}${src}`}
|
||||
alt={`Bild ${index + 1}`}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</Carousel>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Team Info */}
|
||||
<div className="text-center mb-12">
|
||||
<h1 className="text-4xl font-bold text-frog-600">{team.name}</h1>
|
||||
<p className="text-lg text-gray-700 mt-2">{team.league}</p>
|
||||
<p className="text-gray-600 mt-4">{team.description}</p>
|
||||
<p className="text-sm text-frog-700 font-medium mt-2">Training: {team.trainingTimes}</p>
|
||||
<p className="text-lg text-gray-700 mt-2">{team.liga}</p>
|
||||
<p className="text-gray-600 mt-4">{team.beschreibung}</p>
|
||||
<p className="text-sm text-frog-700 font-medium mt-2">
|
||||
Training: {team.trainingszeiten || "Nicht angegeben"}
|
||||
</p>
|
||||
</div>
|
||||
{/*Join Button */}
|
||||
{team.canJoin && (
|
||||
|
||||
{/* Join Button */}
|
||||
{team.sucht_spieler && (
|
||||
<div className="mt-6 mb-6 flex justify-center">
|
||||
<button className="bg-frog-500 hover:bg-frog-600 text-white font-semibold py-2 px-6 rounded-full shadow-lg transition">
|
||||
Mitmachen
|
||||
@@ -99,16 +101,25 @@ const TeamDetailPage = () => {
|
||||
|
||||
{/* Spielerübersicht */}
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6">
|
||||
{team.players.map((player, idx) => (
|
||||
<div key={idx} className="bg-white rounded-lg shadow-md p-4 flex flex-col items-center text-center hover:shadow-lg transition">
|
||||
{team.players.map((player) => (
|
||||
<div
|
||||
key={player.id}
|
||||
className="bg-white rounded-lg shadow-md p-4 flex flex-col items-center text-center hover:shadow-lg transition"
|
||||
>
|
||||
<img
|
||||
src={player.image}
|
||||
src={
|
||||
player.image_url
|
||||
? `${apiBase}${player.image_url}`
|
||||
: "/images/default-player.png"
|
||||
}
|
||||
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>
|
||||
<p className="text-gray-500">{player.position}</p>
|
||||
<p className="text-sm text-frog-500 mt-1">„{player.nickname}“</p>
|
||||
{player.nickname && (
|
||||
<p className="text-sm text-frog-500 mt-1">„{player.nickname}“</p>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user