Compare commits

..

17 Commits

Author SHA1 Message Date
7cf1245ef6 Merge branch 'dev' into prod 2026-01-21 14:27:37 +01:00
2adbfa75a5 Merge branch 'dev' into prod 2026-01-21 14:07:26 +01:00
216a1cb1d4 Merge branch 'dev' into prod 2026-01-20 20:43:59 +01:00
7fc98d6c9f Merge branch 'dev' into prod 2026-01-20 20:34:52 +01:00
e346cf9445 e 2026-01-20 20:33:41 +01:00
c030b6dbe6 Merge branch 'dev' into prod 2026-01-20 20:33:31 +01:00
6f26b9bbc3 e 2026-01-20 20:22:59 +01:00
a34a70572f edited 2026-01-20 20:19:12 +01:00
4b3c8a2424 edited compose file 2026-01-20 20:17:53 +01:00
568b3bf495 edited 2026-01-20 20:08:14 +01:00
5653d32857 fix: update WireGuard PASSWORD_HASH to a static value 2026-01-20 20:06:44 +01:00
7cf5b8df48 Merge branch 'dev' into prod 2026-01-20 20:03:51 +01:00
65c5fc0f8f Merge branch 'dev' into prod 2026-01-20 19:59:27 +01:00
b626a67907 Merge branch 'dev' into prod 2026-01-20 19:46:56 +01:00
6643a176a6 Merge branch 'dev' into prod 2026-01-20 19:43:53 +01:00
89803754a7 Merge branch 'dev' into prod 2026-01-20 19:38:27 +01:00
5052b3e83a changed fetch urls 2026-01-20 19:23:53 +01:00
7 changed files with 36 additions and 210 deletions

View File

@@ -6,8 +6,6 @@ services:
networks:
ca-lose-internal:
ipv4_address: 172.25.0.2
proxynet:
ipv4_address: 172.20.0.61
restart: unless-stopped
backend:

View File

@@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Lose verkaufen</title>
<title>frontend</title>
</head>
<body>
<div id="root"></div>

View File

@@ -9,13 +9,11 @@ import {
Chip,
Box,
Paper,
Typography,
} from "@mui/material";
import { useTranslation } from "react-i18next";
import { useState, useEffect } from "react";
import { submitFormData } from "../utils/sender";
import Cookies from "js-cookie";
import * as React from "react";
interface Message {
type: "error" | "info" | "success" | "warning";
@@ -51,7 +49,7 @@ export const MainForm = () => {
// Fetch user data or any other data needed for the form
try {
const fetchUsers = async () => {
const response = await fetch("http://localhost:8004/default/users");
const response = await fetch("/backend/default/users");
const data = await response.json();
setUsers(data.users);
};
@@ -80,7 +78,7 @@ export const MainForm = () => {
const confirmUser = async (selectedUser: string) => {
try {
const response = await fetch(
`http://localhost:8004/default/confirm-user?username=${selectedUser}`,
`/backend/default/confirm-user?username=${selectedUser}`
);
const data = await response.json();
setNextID(data.nextID);
@@ -115,33 +113,11 @@ export const MainForm = () => {
};
return (
<Box
className="bg-gray-100 py-10 px-4"
sx={{
minHeight: "100vh",
width: "100%",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<Box className="min-h-screen bg-gray-800 flex items-center justify-center p-4">
<Paper
elevation={6}
className="w-full rounded-2xl"
sx={{
backgroundColor: "#fff",
boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.25)",
width: "100%",
maxWidth: {
xs: 360, // kompakte Handy-Ansicht
sm: 420, // kleine Tablets / große Phones
md: 480, // Desktop, bleibt angenehm schmal
},
padding: {
xs: "1.5rem",
sm: "2rem",
},
}}
elevation={3}
className="w-full max-w-md p-6 rounded-lg"
sx={{ backgroundColor: "#fff" }}
>
<form
onSubmit={(e) => {
@@ -173,14 +149,10 @@ export const MainForm = () => {
color="primary"
sx={{
alignSelf: "flex-start",
fontWeight: 500,
fontSize: "0.9rem",
mt: 0.5,
mb: 0.5,
py: 0.5,
px: 1.25,
borderRadius: "999px",
background: "linear-gradient(135deg, #1976d2 0%, #1565c0 100%)",
fontWeight: "bold",
fontSize: "1rem",
py: 2,
px: 1,
}}
/>
@@ -262,14 +234,7 @@ export const MainForm = () => {
{/* Invoice Fields */}
{invoice && (
<Box
className="flex flex-col gap-2 pt-3 mt-2"
sx={{
borderTop: "2px solid",
borderColor: "primary.light",
borderRadius: "0",
}}
>
<Box className="flex flex-col gap-3 pt-2 border-t border-gray-200">
<TextField
required
id="company-name"
@@ -352,118 +317,26 @@ export const MainForm = () => {
/>
</Box>
)}
{/* Payment Methods */}
<Box className="flex flex-col gap-2 mt-2">
<Typography
component="label"
sx={{
fontSize: "0.875rem",
fontWeight: 500,
color: "text.secondary",
display: "flex",
alignItems: "center",
gap: 0.5,
}}
>
{t("select-payment-method")} *
</Typography>
<Box className="flex gap-2 flex-wrap">
<Button
variant={
formData.paymentMethod === "bar" ? "contained" : "outlined"
}
onClick={() =>
setFormData({ ...formData, paymentMethod: "bar" })
}
sx={{
flex: 1,
minWidth: "100px",
py: 1.5,
borderRadius: "12px",
textTransform: "none",
fontWeight: formData.paymentMethod === "bar" ? 600 : 400,
}}
>
{t("cash")}
</Button>
<Button
variant={
formData.paymentMethod === "paypal" ? "contained" : "outlined"
}
onClick={() =>
setFormData({ ...formData, paymentMethod: "paypal" })
}
sx={{
flex: 1,
minWidth: "100px",
py: 1.5,
borderRadius: "12px",
textTransform: "none",
fontWeight: formData.paymentMethod === "paypal" ? 600 : 400,
}}
>
{t("paypal")}
</Button>
<Button
variant={
formData.paymentMethod === "andere" ? "contained" : "outlined"
}
onClick={() =>
setFormData({ ...formData, paymentMethod: "andere" })
}
sx={{
flex: 1,
minWidth: "100px",
py: 1.5,
borderRadius: "12px",
textTransform: "none",
fontWeight: formData.paymentMethod === "andere" ? 600 : 400,
}}
>
{t("transfer")}
</Button>
</Box>
{!formData.paymentMethod && (
<input
tabIndex={-1}
autoComplete="off"
style={{
opacity: 0,
width: 0,
height: 0,
position: "absolute",
}}
required
value={formData.paymentMethod}
onChange={() => {}}
/>
)}
<Box className="flex justify-center gap-4 pt-2">
<FormControlLabel control={<Checkbox />} label={t("cash")} />
<FormControlLabel control={<Checkbox />} label={t("paypal")} />
<FormControlLabel control={<Checkbox />} label={t("transfer")} />
</Box>
{/* Submit Button */}
<Button
type="submit"
variant="contained"
disabled={isLoading || !formData.paymentMethod}
disabled={isLoading}
fullWidth
size="large"
sx={{
mt: 3,
py: 2,
mt: 2,
py: 1.5,
textTransform: "uppercase",
fontWeight: "bold",
borderRadius: "12px",
fontSize: "1rem",
background: "linear-gradient(135deg, #1976d2 0%, #1565c0 100%)",
boxShadow: "0 4px 14px 0 rgba(25, 118, 210, 0.39)",
"&:hover": {
background: "linear-gradient(135deg, #1565c0 0%, #0d47a1 100%)",
boxShadow: "0 6px 20px 0 rgba(25, 118, 210, 0.5)",
},
"&:disabled": {
background: "#e0e0e0",
boxShadow: "none",
},
}}
>
{isLoading ? (

View File

@@ -1,4 +1,4 @@
import { Box, Paper, Typography, Chip, Button } from "@mui/material";
import { Box, Paper, Typography, Chip } from "@mui/material";
import { useEffect, useState } from "react";
import { CircleCheck } from "lucide-react";
import { useTranslation } from "react-i18next";
@@ -8,7 +8,6 @@ export const SuccessPage = () => {
const [tickets, setNumberOfTickets] = useState<number>(0);
const [animate, setAnimate] = useState(false);
const { t } = useTranslation();
const [seconds, setSeconds] = useState(30);
useEffect(() => {
const params = new URLSearchParams(window.location.search);
@@ -21,17 +20,6 @@ export const SuccessPage = () => {
setTimeout(() => setAnimate(true), 100);
}, []);
useEffect(() => {
if (seconds === 0) {
window.location.href = "/";
return;
}
const timer = setTimeout(() => setSeconds(seconds - 1), 1000);
return () => clearTimeout(timer);
}, [seconds]);
return (
<Box className="min-h-screen bg-gray-800 flex items-center justify-center p-4">
<Paper
@@ -144,30 +132,6 @@ export const SuccessPage = () => {
</Box>
)}
{/* Return button */}
<Box
sx={{
mb: 3,
transition: "all 0.5s ease-in-out 0.4s",
transform: animate ? "translateY(0)" : "translateY(20px)",
opacity: animate ? 1 : 0,
}}
>
<Button
href="/"
variant="contained"
color="primary"
sx={{
fontWeight: "bold",
fontSize: "1.25rem",
py: 3,
px: 2,
}}
>
{seconds + " " + t("return-to-homepage")}
</Button>
</Box>
{/* Additional Info */}
<Box
sx={{

View File

@@ -8,7 +8,7 @@
"street": "Straße + Haus Nr.",
"postal-code": "Plz + Stadt",
"email": "E-Mail",
"submit": "Abschicken",
"submit": "Kaufen",
"failed-to-load-users": "Das Laden der Benutzer ist fehlgeschlagen.",
"user": "Benutzer",
"next-id": "Nächste Eintragsnummer: ",
@@ -18,11 +18,8 @@
"error": "Fehler",
"cash": "Bar",
"paypal": "PayPal",
"transfer": "Andere (notieren)",
"ticket-payment_one": "Sie haben erfolgreich {{count}} Los gekauft.",
"ticket-payment_other": "Sie haben erfolgreich {{count}} Lose gekauft.",
"transfer": "Überweisung",
"ticket-payment": "Sie haben erflogreich {count} {count, plural, one {Los} other {Lose}} gekauft.",
"entry-id": "Eintrags-ID",
"thank-you": "Vielen Dank für Ihre Unterstützung der Claudius Akademie! Wir wünschen Ihnen viel Glück mit dem Los.",
"select-payment-method": "Zahlungsmethode auswählen",
"return-to-homepage": "Zurück"
"thank-you": "Vielen Dank für Ihre Unterstützung der Claudius Akademie! Wir wünschen Ihnen viel Glück mit dem Los."
}

View File

@@ -7,7 +7,7 @@
"street": "Street + House No.",
"postal-code": "Postal Code + City",
"email": "Email",
"submit": "Submit Form",
"submit": "Buy",
"failed-to-load-users": "Failed to load users.",
"user": "User",
"next-id": "Next Entry Number: ",
@@ -17,13 +17,11 @@
"error": "Error",
"cash": "Cash",
"paypal": "PayPal",
"transfer": "Other (note down)",
"transfer": "Bank Transfer",
"ticket-payment_one": "You have successfully purchased {{count}} ticket.",
"ticket-payment_other": "You have successfully purchased {{count}} tickets.",
"ticket": "Ticket",
"tickets": "Tickets",
"ticket": "ticket",
"tickets": "tickets",
"entry-id": "Entry ID",
"thank-you": "Thank you for supporting the Claudius Akademie! We wish you the best of luck with your ticket.",
"select-payment-method": "Select Payment Method",
"return-to-homepage": "Return"
"thank-you": "Thank you for supporting the Claudius Akademie! We wish you the best of luck with your ticket."
}

View File

@@ -15,18 +15,14 @@ interface FormData {
}
export const submitFormData = async (data: FormData, username: string) => {
console.log(data);
try {
const response = await fetch(
`http://localhost:8004/default/new-entry?username=${username}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
const response = await fetch(`/backend/default/new-entry?username=${username}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
);
body: JSON.stringify(data),
});
if (!response.ok) {
const errorText = await response.text();