This commit is contained in:
71
src/pages/EventsPage.tsx
Normal file
71
src/pages/EventsPage.tsx
Normal file
@@ -0,0 +1,71 @@
|
||||
import { Calendar, dateFnsLocalizer } 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 "d:/Projects/web/tg/volleyball-dev-frontend/node_modules/date-fns/locale/de";
|
||||
import { useMemo } from "react";
|
||||
|
||||
const locales = {
|
||||
de: de,
|
||||
};
|
||||
|
||||
const localizer = dateFnsLocalizer({
|
||||
format,
|
||||
parse,
|
||||
startOfWeek: () => startOfWeek(new Date(), { locale: de }),
|
||||
getDay,
|
||||
locales,
|
||||
});
|
||||
|
||||
const events = [
|
||||
{
|
||||
title: "Heimspiel Herren 1",
|
||||
start: new Date("2025-06-08T15:00:00"),
|
||||
end: new Date("2025-06-08T17:00:00"),
|
||||
allDay: false,
|
||||
},
|
||||
{
|
||||
title: "Sommerfest",
|
||||
start: new Date("2025-06-15"),
|
||||
end: new Date("2025-06-15"),
|
||||
allDay: true,
|
||||
},
|
||||
{
|
||||
title: "Training Jugend U16",
|
||||
start: new Date("2025-06-17T18:00:00"),
|
||||
end: new Date("2025-06-17T19:30:00"),
|
||||
allDay: false,
|
||||
},
|
||||
];
|
||||
|
||||
const EventsPage = () => {
|
||||
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={{
|
||||
today: "Heute",
|
||||
previous: "Zurück",
|
||||
next: "Weiter",
|
||||
month: "Monat",
|
||||
week: "Woche",
|
||||
day: "Tag",
|
||||
agenda: "Liste",
|
||||
date: "Datum",
|
||||
time: "Uhrzeit",
|
||||
event: "Event",
|
||||
noEventsInRange: "Keine Events im gewählten Zeitraum",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default EventsPage;
|
||||
@@ -7,6 +7,7 @@ import TeamSection from "@/components/TeamSection";
|
||||
import GallerySection from "@/components/GallerySection";
|
||||
import AboutSection from "@/components/AboutSection";
|
||||
import ContactSection from "@/components/ContactSection";
|
||||
import EventsSection from "../components/EventsSection";
|
||||
|
||||
const Index = () => {
|
||||
const location = useLocation();
|
||||
@@ -27,6 +28,8 @@ const Index = () => {
|
||||
<Hero />
|
||||
<div id="news" />
|
||||
<NewsSection />
|
||||
<div id="events" />
|
||||
<EventsSection/>
|
||||
<div id="team" />
|
||||
<TeamSection />
|
||||
<div id="gallery" />
|
||||
|
||||
@@ -3,26 +3,29 @@ import { useNavigate } from "react-router-dom";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { useAuth } from "@/context/AuthContext";
|
||||
|
||||
|
||||
const apiBase = import.meta.env.VITE_API_URL;
|
||||
|
||||
const LoginPage = () => {
|
||||
const [email, setEmail] = useState(""); // Wird eigentlich Username sein!
|
||||
const [email, setEmail] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [error, setError] = useState("");
|
||||
const navigate = useNavigate();
|
||||
const [loginAttempts, setLoginAttempts] = useState(0);
|
||||
|
||||
const [captcha, setCaptcha] = useState("");
|
||||
const [showCaptcha, setShowCaptcha] = useState(false);
|
||||
|
||||
const navigate = useNavigate();
|
||||
const { login } = useAuth(); // <-- Context-Funktion holen
|
||||
|
||||
const handleLogin = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
setError("");
|
||||
|
||||
try {
|
||||
|
||||
if(showCaptcha && captcha.toLowerCase() !== "laudenbach") {
|
||||
// Captcha check
|
||||
if (showCaptcha && captcha.toLowerCase() !== "laudenbach") {
|
||||
setError("Captcha falsch. Bitte versuche es erneut.");
|
||||
return;
|
||||
}
|
||||
@@ -32,17 +35,18 @@ const LoginPage = () => {
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ username: email, password }),
|
||||
});
|
||||
|
||||
|
||||
if (!res.ok) {
|
||||
if (res.status === 429) {
|
||||
throw new Error("rate_limit");
|
||||
}
|
||||
throw new Error("login_failed");
|
||||
}
|
||||
|
||||
|
||||
const data = await res.json();
|
||||
localStorage.setItem("token", data.token);
|
||||
navigate("/admin");
|
||||
localStorage.setItem("token", data.token);
|
||||
login(data.token);
|
||||
navigate("/admin");
|
||||
} catch (err: any) {
|
||||
console.error(err);
|
||||
if (err.message === "rate_limit") {
|
||||
@@ -51,13 +55,11 @@ const LoginPage = () => {
|
||||
setError("Login fehlgeschlagen. Bitte prüfe Benutzername und Passwort.");
|
||||
const newAttempts = loginAttempts + 1;
|
||||
setLoginAttempts(newAttempts);
|
||||
|
||||
if(newAttempts >= 3) {
|
||||
if (newAttempts >= 5) {
|
||||
setShowCaptcha(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user