QoL Updates

This commit is contained in:
Marc Wieland
2025-04-20 20:32:34 +02:00
parent d085a26416
commit 8f9cd73e50
10 changed files with 282 additions and 31 deletions

View File

@@ -1,50 +1,101 @@
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { useState } from "react";
import { Button } from "@/components/ui/button";
import { Select, SelectItem } from "@/components/ui/select"; // Falls du ein Select UI-Element hast
const news = [
{
id: 1,
title: "Saisonstart 2023/24",
date: "15. September 2023",
date: "2023-09-15",
description: "Die neue Saison beginnt mit einem Heimspiel gegen VfB Mosbach. Kommt vorbei und unterstützt unser Team!",
image: "https://images.unsplash.com/photo-1612872087720-bb876e2e67d1?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80"
image: "https://images.unsplash.com/photo-1612872087720-bb876e2e67d1?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80",
team: "Herren I"
},
{
id: 2,
title: "Beachvolleyball-Turnier",
date: "3. Juli 2023",
date: "2023-07-03",
description: "Unser jährliches Beachvolleyball-Turnier war ein voller Erfolg! 24 Teams kämpften um den Sieg.",
image: "https://images.unsplash.com/photo-1583514555852-6f77e7c9e081?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80"
image: "https://images.unsplash.com/photo-1583514555852-6f77e7c9e081?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80",
team: "Mixed-Team"
},
{
id: 3,
title: "Neuer Trainer für die Jugendmannschaft",
date: "21. Mai 2023",
date: "2023-05-21",
description: "Wir freuen uns, Marc Schneider als neuen Trainer für unsere U16-Mannschaft begrüßen zu dürfen.",
image: "https://images.unsplash.com/photo-1547347298-4074fc3086f0?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80"
image: "https://images.unsplash.com/photo-1547347298-4074fc3086f0?ixlib=rb-4.0.3&auto=format&fit=crop&w=500&q=80",
team: "Jugend U16"
},
// 🔜 später kannst du hier easy mehr News reinladen oder aus ner API holen
];
const AlleNeuigkeitenPage = () => {
const [selectedTeam, setSelectedTeam] = useState("Alle");
// Teams dynamisch auslesen
const teams = ["Alle", ...Array.from(new Set(news.map((item) => item.team)))];
// Nach Datum absteigend sortieren
const sortedNews = [...news].sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
// Nach Team filtern
const filteredNews = sortedNews.filter((item) =>
selectedTeam === "Alle" ? true : item.team === selectedTeam
);
// Gruppieren nach Jahren
const groupedNews = filteredNews.reduce((acc: any, item) => {
const year = new Date(item.date).getFullYear();
if (!acc[year]) acc[year] = [];
acc[year].push(item);
return acc;
}, {});
return (
<div className="max-w-5xl mx-auto px-4 py-12">
<h1 className="text-3xl font-bold text-center mb-8 text-frog-600">Alle Neuigkeiten</h1>
<div className="grid md:grid-cols-2 gap-6">
{news.map((item) => (
<Card key={item.id} className="overflow-hidden">
<div className="h-48 overflow-hidden">
<img src={item.image} alt={item.title} className="w-full h-full object-cover" />
</div>
<CardHeader>
<CardTitle>{item.title}</CardTitle>
<CardDescription>{item.date}</CardDescription>
</CardHeader>
<CardContent>
<p>{item.description}</p>
</CardContent>
</Card>
))}
{/* Team-Filter */}
<div className="flex justify-center mb-8">
<select
value={selectedTeam}
onChange={(e) => setSelectedTeam(e.target.value)}
className="border border-gray-300 rounded-md p-2"
>
{teams.map((team) => (
<option key={team} value={team}>
{team}
</option>
))}
</select>
</div>
{/* News nach Jahren gruppiert */}
{Object.entries(groupedNews).map(([year, items]) => (
<div key={year} className="mb-12">
<h2 className="text-2xl font-bold text-frog-500 mb-4">{year}</h2>
<div className="grid md:grid-cols-2 gap-6">
{(items as typeof news).map((item) => (
<Card key={item.id} className="overflow-hidden">
<div className="h-48 overflow-hidden">
<img src={item.image} alt={item.title} className="w-full h-full object-cover" />
</div>
<CardHeader>
<CardTitle>{item.title}</CardTitle>
<CardDescription>{new Date(item.date).toLocaleDateString("de-DE")}</CardDescription>
</CardHeader>
<CardContent>
<p>{item.description}</p>
</CardContent>
</Card>
))}
</div>
</div>
))}
</div>
);
};

26
src/pages/LoginPage.tsx Normal file
View File

@@ -0,0 +1,26 @@
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
const LoginPage = () => {
return (
<div className="flex justify-center items-center min-h-screen bg-gray-50">
<Card className="w-full max-w-md">
<CardHeader>
<CardTitle className="text-center text-frog-600">Login</CardTitle>
</CardHeader>
<CardContent>
<form className="space-y-4">
<Input placeholder="E-Mail-Adresse" type="email" required />
<Input placeholder="Passwort" type="password" required />
<Button type="submit" className="w-full bg-frog-500 hover:bg-frog-600 text-white">
Einloggen
</Button>
</form>
</CardContent>
</Card>
</div>
);
};
export default LoginPage;

View File

@@ -1,19 +1,51 @@
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import IbanInput from "@/components/IbanInput";
import AdresseInput from "@/components/AdresseInput";
const MitgliedWerdenPage = () => {
return (
<div className="flex justify-center mt-10">
<Card className="w-full max-w-md">
<Card className="w-full max-w-2xl">
<CardContent className="p-6">
<h1 className="text-2xl font-bold mb-4 text-center">Mitglied werden</h1>
<form className="space-y-4">
<Input placeholder="Vorname" />
<Input placeholder="Nachname" />
<Input placeholder="E-Mail" type="email" />
<Input placeholder="Geburtsdatum" type="date" />
<Button type="submit" className="w-full bg-frog-500 hover:bg-frog-600 text-white">
{/* Mitgliedsdaten */}
<h2 className="text-lg font-semibold">Persönliche Daten</h2>
<Input placeholder="Vorname" required />
<Input placeholder="Nachname" required />
{/*<AdresseInput /> -> Für die spätere Verwendung zum AutoComplete*/}
<Input placeholder="Straße und Hausnummer" required />
<Input placeholder="PLZ und Wohnort" required />
<Input placeholder="Telefonnummer" required />
<Input placeholder="E-Mail-Adresse" type="email" required />
<div className="flex flex-col space-y-1">
<label htmlFor="birthdate" className="text-sm font-medium text-gray-700">
Geburtsdatum*
</label>
<Input id="birthdate" type="date" required />
</div>
<div className="flex flex-col space-y-1">
<label htmlFor="entrydate" className="text-sm font-medium text-gray-700">
Eintrittsdatum*
</label>
<Input id="entrydate" type="date" required />
</div>
{/* Bankverbindung */}
<h2 className="text-lg font-semibold mt-6">Bankverbindung</h2>
<Input placeholder="Kontoinhaber (Name, Vorname)" required />
<Input placeholder="Straße und Hausnummer (falls abweichend)" />
<Input placeholder="PLZ und Wohnort (falls abweichend)" />
<IbanInput />
<Input placeholder="BIC" required />
{/* Submit Button */}
<Button type="submit" className="w-full bg-frog-500 hover:bg-frog-600 text-white mt-6">
Absenden
</Button>
</form>

View File

@@ -15,6 +15,7 @@ const teamData = [
"/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" },
@@ -32,6 +33,7 @@ const teamData = [
"/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" },
@@ -43,6 +45,7 @@ const teamData = [
{ 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", },
],
},
];
@@ -85,6 +88,14 @@ const TeamDetailPage = () => {
<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>
</div>
{/*Join Button */}
{team.canJoin && (
<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
</button>
</div>
)}
{/* Spielerübersicht */}
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6">