This commit is contained in:
@@ -79,6 +79,7 @@ const Navbar = () => {
|
||||
<Link to="/teams/1" className="block px-3 py-1 text-gray-700 hover:text-frog-600">Herren 1</Link>
|
||||
<Link to="/teams/2" className="block px-3 py-1 text-gray-700 hover:text-frog-600">Herren 2</Link>
|
||||
<Link to="/teams/9" className="block px-3 py-1 text-gray-700 hover:text-frog-600">Mixed</Link>
|
||||
<Link to="/teams/9" className="block px-3 py-1 text-gray-700 hover:text-frog-600">TestTeam</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -22,6 +22,11 @@ const Datenschutz = () => {
|
||||
Wir erheben personenbezogene Daten nur, wenn du uns diese im Rahmen einer Anfrage über unser Kontaktformular mitteilst oder dich einloggst.
|
||||
</p>
|
||||
|
||||
<p className="mb-4">
|
||||
Beim Besuch dieser Website werden aus Sicherheitsgründen und zur Analyse der Nutzung automatisch Informationen über die IP-Adresse sowie das zugehörige Land (basierend auf öffentlich zugänglichen Geo-Datenbanken) erfasst. Diese Daten werden ausschließlich anonymisiert ausgewertet und nach spätestens 7 Tagen gelöscht. Eine Weitergabe an Dritte erfolgt nicht.
|
||||
</p>
|
||||
|
||||
|
||||
<h2 className="text-xl font-semibold mt-6 mb-2">3. Kontaktformular</h2>
|
||||
<p className="mb-4">
|
||||
Wenn du uns über das Kontaktformular kontaktierst, werden deine Angaben inklusive der von dir dort angegebenen Kontaktdaten zum Zweck der Bearbeitung der Anfrage und für den Fall von Anschlussfragen bei uns gespeichert.
|
||||
@@ -59,6 +64,12 @@ const Datenschutz = () => {
|
||||
<p className="mb-4">
|
||||
Wir behalten uns vor, diese Datenschutzerklärung bei Bedarf anzupassen, um sie stets aktuell zu halten.
|
||||
</p>
|
||||
|
||||
<h2 className="text-xl font-semibold mt-6 mb-2">9. IP- und Geo-Datenanalyse</h2>
|
||||
<p className="mb-4">
|
||||
Beim Aufruf unserer Website wird die IP-Adresse deines Geräts automatisch durch unseren Server verarbeitet. Zusätzlich wird das Herkunftsland ermittelt (basierend auf öffentlichen Geo-IP-Datenbanken), um potenzielle Angriffe zu erkennen und statistische Auswertungen durchzuführen. Die Daten werden dabei nicht mit anderen personenbezogenen Informationen verknüpft und nach spätestens 7 Tagen automatisch gelöscht.
|
||||
</p>
|
||||
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
import { Calendar, dateFnsLocalizer } from "react-big-calendar";
|
||||
import { useState } from "react";
|
||||
import {
|
||||
Calendar,
|
||||
dateFnsLocalizer,
|
||||
Event as CalendarEvent,
|
||||
} from "react-big-calendar";
|
||||
import "react-big-calendar/lib/css/react-big-calendar.css";
|
||||
import { parse, startOfWeek, format, getDay } from "date-fns";
|
||||
|
||||
import { de } from "date-fns/locale";
|
||||
import { useMemo } from "react";
|
||||
|
||||
import { Dialog } from "@headlessui/react";
|
||||
|
||||
|
||||
// Locale-Konfiguration
|
||||
const locales = {
|
||||
de: de,
|
||||
};
|
||||
@@ -16,40 +26,54 @@ const localizer = dateFnsLocalizer({
|
||||
locales,
|
||||
});
|
||||
|
||||
// Event-Daten
|
||||
const events = [
|
||||
{
|
||||
title: "Heimspiel Herren 1",
|
||||
start: new Date("2025-06-08T15:00:00"),
|
||||
end: new Date("2025-06-08T17:00:00"),
|
||||
allDay: false,
|
||||
location: "Sporthalle TG Laudenbach",
|
||||
description: "Heimspiel gegen TSV XY.",
|
||||
bgColor: "#000000", // Rot
|
||||
},
|
||||
{
|
||||
title: "Sommerfest",
|
||||
start: new Date("2025-06-15"),
|
||||
end: new Date("2025-06-15"),
|
||||
allDay: true,
|
||||
description: "Vereinsfest mit BBQ.",
|
||||
bgColor: "#10b981", // Grün
|
||||
},
|
||||
{
|
||||
title: "Training Jugend U16",
|
||||
start: new Date("2025-06-17T18:00:00"),
|
||||
end: new Date("2025-06-17T19:30:00"),
|
||||
allDay: false,
|
||||
location: "Halle 2",
|
||||
description: "Wöchentliches Training.",
|
||||
bgColor: "#2563eb", // Blau
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
const EventsPage = () => {
|
||||
const [selectedEvent, setSelectedEvent] = useState<any | null>(null);
|
||||
|
||||
const handleSelectEvent = (event: CalendarEvent) => {
|
||||
setSelectedEvent(event);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-white py-12 px-4 md:px-12">
|
||||
<h1 className="text-3xl font-bold mb-6 text-center">Eventkalender</h1>
|
||||
|
||||
<div className="bg-white rounded-xl shadow-md p-4">
|
||||
<Calendar
|
||||
localizer={localizer}
|
||||
events={events}
|
||||
startAccessor="start"
|
||||
endAccessor="end"
|
||||
style={{ height: 600 }}
|
||||
views={["month", "week", "agenda"]}
|
||||
messages={{
|
||||
localizer={localizer}
|
||||
events={events}
|
||||
startAccessor="start"
|
||||
endAccessor="end"
|
||||
style={{ height: 600 }}
|
||||
views={["month", "week", "agenda"]}
|
||||
messages={{
|
||||
today: "Heute",
|
||||
previous: "Zurück",
|
||||
next: "Weiter",
|
||||
@@ -61,9 +85,69 @@ const EventsPage = () => {
|
||||
time: "Uhrzeit",
|
||||
event: "Event",
|
||||
noEventsInRange: "Keine Events im gewählten Zeitraum",
|
||||
}}
|
||||
}}
|
||||
onSelectEvent={handleSelectEvent}
|
||||
eventPropGetter={(event) => {
|
||||
const backgroundColor = event.bgColor || "#3b82f6"; // fallback: blau
|
||||
return {
|
||||
style: {
|
||||
backgroundColor,
|
||||
color: "white",
|
||||
borderRadius: "0.5rem",
|
||||
border: "none",
|
||||
padding: "4px 8px",
|
||||
},
|
||||
};
|
||||
}}
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
{/* Modal bei Event-Auswahl */}
|
||||
<Dialog
|
||||
open={!!selectedEvent}
|
||||
onClose={() => setSelectedEvent(null)}
|
||||
className="fixed inset-0 z-50 flex items-center justify-center p-4"
|
||||
>
|
||||
{/* Hintergrund Overlay */}
|
||||
<div className="fixed inset-0 bg-black bg-opacity-30" aria-hidden="true" />
|
||||
|
||||
{/* Modal-Fenster */}
|
||||
<Dialog.Panel className="bg-white rounded-xl p-6 max-w-md w-full z-10 shadow-lg">
|
||||
<Dialog.Title className="text-xl font-bold mb-2">
|
||||
{selectedEvent?.title}
|
||||
</Dialog.Title>
|
||||
|
||||
<p className="text-sm text-gray-500 mb-1">
|
||||
📅{" "}
|
||||
{selectedEvent?.start &&
|
||||
new Date(selectedEvent.start).toLocaleString("de-DE", {
|
||||
weekday: "long",
|
||||
day: "2-digit",
|
||||
month: "long",
|
||||
year: "numeric",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
})}
|
||||
</p>
|
||||
|
||||
{selectedEvent?.location && (
|
||||
<p className="text-sm mb-2">📍 {selectedEvent.location}</p>
|
||||
)}
|
||||
|
||||
{selectedEvent?.description && (
|
||||
<p className="text-sm text-gray-700">{selectedEvent.description}</p>
|
||||
)}
|
||||
|
||||
<button
|
||||
onClick={() => setSelectedEvent(null)}
|
||||
className="mt-4 bg-primary text-white px-4 py-2 rounded hover:bg-primary/90 transition"
|
||||
>
|
||||
Schließen
|
||||
</button>
|
||||
</Dialog.Panel>
|
||||
</Dialog>
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user