diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..67223e8
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "wg-easy-ca-lose"]
+ path = wg-easy-ca-lose
+ url = https://git.the1s.de/theis.gaedigk/wg-easy-ca-lose.git
diff --git a/frontend/src/components/modals/QR-CodeModal.tsx b/frontend/src/components/modals/QR-CodeModal.tsx
new file mode 100644
index 0000000..8c64dcc
--- /dev/null
+++ b/frontend/src/components/modals/QR-CodeModal.tsx
@@ -0,0 +1,31 @@
+import { Modal, ModalDialog, Typography, ModalClose } from "@mui/joy";
+import { useTranslation } from "react-i18next";
+import qrCode from "../../assets/PayPal-QR-Code.png";
+
+interface QRcodeModalProps {
+ QRmodal: boolean;
+ setQRmodal: (value: boolean) => void;
+}
+
+export const QRcodeModal = (props: QRcodeModalProps) => {
+ const { t } = useTranslation();
+
+ return (
+
+
+ props.setQRmodal(false)} />
+ {t("qr-text")}
+
+
+
+ );
+};
diff --git a/frontend/src/components/modals/SelectUserModal.tsx b/frontend/src/components/modals/SelectUserModal.tsx
new file mode 100644
index 0000000..6f6cd42
--- /dev/null
+++ b/frontend/src/components/modals/SelectUserModal.tsx
@@ -0,0 +1,40 @@
+import {
+ Modal,
+ ModalDialog,
+ Typography,
+ ModalClose,
+ Autocomplete,
+} from "@mui/joy";
+import { useTranslation } from "react-i18next";
+
+interface SelectUserModalProps {
+ showSelectUser: boolean;
+ setShowSelectUser: (value: boolean) => void;
+ usernameData: { users: string[] };
+ usernameDataIsLoading: boolean;
+ selectedUser: string | null;
+ handleUserSelection: (value: string | null) => void;
+}
+
+export const SelectUserModal = (props: SelectUserModalProps) => {
+ const { t } = useTranslation();
+ return (
+
+
+ props.setShowSelectUser(false)} />
+ {t("user")}
+ {/* User selection */}
+ props.handleUserSelection(value)}
+ placeholder={t("user")}
+ variant="soft"
+ sx={{ borderRadius: "10px" }}
+ />
+
+
+ );
+};
diff --git a/frontend/src/pages/MainForm.tsx b/frontend/src/pages/MainForm.tsx
index 23cfef6..f6dacba 100644
--- a/frontend/src/pages/MainForm.tsx
+++ b/frontend/src/pages/MainForm.tsx
@@ -13,11 +13,7 @@ import {
Typography,
FormControl,
FormLabel,
- Autocomplete,
ButtonGroup,
- Modal,
- ModalDialog,
- ModalClose,
CircularProgress,
} from "@mui/joy";
import { submitFormData } from "../utils/api/form";
@@ -25,9 +21,10 @@ import type { FormData, Message } from "../config/interfaces.config";
import PersonIcon from "@mui/icons-material/Person";
import QrCodeIcon from "@mui/icons-material/QrCode";
import TranslateIcon from "@mui/icons-material/Translate";
-import qrCode from "../assets/PayPal-QR-Code.png";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { confirmUser, fetchUsers } from "../utils/api/users";
+import { QRcodeModal } from "../components/modals/QR-CodeModal";
+import { SelectUserModal } from "../components/modals/SelectUserModal";
const PAYMENT_METHODS = ["bar", "paypal", "andere"] as const;
const PAYMENT_LABELS: Record = {
@@ -88,8 +85,7 @@ export const MainForm = () => {
const [invoice, setInvoice] = useState(false);
const [msg, setMsg] = useState(null);
- const [nextID, setNextID] = useState(null);
- const [selectedUser, setSelectedUser] = useState("");
+ const [selectedUser, setSelectedUser] = useState(null);
const [formData, setFormData] = useState(DEFAULT_FORM);
const [showSelectUser, setShowSelectUser] = useState(false);
const [QRmodal, setQRmodal] = useState(false);
@@ -102,6 +98,12 @@ export const MainForm = () => {
const savedUser = Cookies.get("selectedUser");
if (savedUser) {
setSelectedUser(savedUser);
+ } else {
+ setMsg({
+ type: "warning",
+ headline: t("set-username-headline"),
+ text: t("set-username-text"),
+ });
}
}, []);
@@ -110,43 +112,30 @@ export const MainForm = () => {
queryFn: fetchUsers,
});
- const { data: userData, isSuccess: userDataIsSuccess } = useQuery({
+ const { data: userData } = useQuery({
queryKey: ["user", selectedUser],
enabled: !!selectedUser,
queryFn: () => confirmUser(selectedUser),
});
- const {
- mutate: mutateForm,
- isSuccess: mutateFormIsSuccess,
- isPending: mutateFormIsPending,
- isError: mutateFormIsError,
- } = useMutation({
+ const { mutate: mutateForm, isPending: mutateFormIsPending } = useMutation({
mutationFn: () => submitFormData(formData, selectedUser),
- });
-
- // Redirecting to success page if mutation was successful
- useEffect(() => {
- if (mutateFormIsSuccess) {
+ onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["user", selectedUser] });
document.location.href = `/success?id=${nextID}&tickets=${formData.tickets}`;
- }
-
- if (mutateFormIsError) {
+ },
+ onError: () => {
queryClient.invalidateQueries({ queryKey: ["user", selectedUser] });
setMsg({
type: "danger",
headline: t("error"),
text: t("form-submission-failed"),
});
- }
- }, [mutateFormIsSuccess, mutateFormIsError]);
+ },
+ });
// Setting the nextID after a user is selected
- useEffect(() => {
- if (!userData) return;
- setNextID(userData.nextID);
- }, [userDataIsSuccess]);
+ const nextID = userData?.nextID ?? "N/A";
const handleUserSelection = (username: string | null) => {
if (username == null || username == "") {
@@ -174,50 +163,21 @@ export const MainForm = () => {
}
};
- useEffect(() => {
- if (formData.paymentMethod === "paypal") {
- setQRmodal(true);
- }
- }, [formData.paymentMethod]);
-
// Shorthand so we don't repeat formData + onChange on every Field usage
const fieldProps = { formData, onChange: handleChange };
return (
<>
-
-
- setShowSelectUser(false)} />
- {t("user")}
- {/* User selection */}
- handleUserSelection(value)}
- placeholder={t("user")}
- variant="soft"
- sx={{ borderRadius: "10px" }}
- />
-
-
-
-
- setQRmodal(false)} />
- {t("qr-text")}
-
-
-
+
+
+
{
formData.paymentMethod === method ? "solid" : "soft"
}
color="primary"
- onClick={() =>
+ onClick={() => {
setFormData((prev) => ({
...prev,
paymentMethod: method,
- }))
- }
+ }));
+ if (method === "paypal") {
+ setQRmodal(true);
+ }
+ }}
sx={{
flex: 1,
minWidth: "90px",
@@ -442,10 +405,16 @@ export const MainForm = () => {
)}
- {/* Alert message */}
+ {/* Message */}
{msg && (
-
- {msg.headline}: {msg.text}
+
+
+ {msg.headline}
+
+ {msg.text}
)}
diff --git a/frontend/src/utils/api/form.ts b/frontend/src/utils/api/form.ts
index 0229d7f..d74138c 100644
--- a/frontend/src/utils/api/form.ts
+++ b/frontend/src/utils/api/form.ts
@@ -1,10 +1,13 @@
import { API_BASE } from "../../config/api.config";
import type { FormData } from "../../config/interfaces.config";
-export const submitFormData = async (data: FormData, username: string) => {
+export const submitFormData = async (
+ data: FormData,
+ username: string | null,
+) => {
console.warn("submitFormData is fetching!");
- await new Promise((resolve) => setTimeout(resolve, 3000)); // Wait 3 seconds
+ // await new Promise((resolve) => setTimeout(resolve, 3000)); // Wait 3 seconds
const response = await fetch(
`${API_BASE}/default/new-entry?username=${username}`,
diff --git a/frontend/src/utils/api/users.ts b/frontend/src/utils/api/users.ts
index 4e0e705..aac1c23 100644
--- a/frontend/src/utils/api/users.ts
+++ b/frontend/src/utils/api/users.ts
@@ -10,7 +10,11 @@ export const fetchUsers = async () => {
return data;
};
-export const confirmUser = async (username: string) => {
+export const confirmUser = async (username: string | null) => {
+ if (!username) {
+ return;
+ }
+
console.warn("confirmUser is fetching!");
const response = await fetch(
`${API_BASE}/default/confirm-user?username=${username}`,
diff --git a/frontend/src/utils/i18n/locales/de/de.json b/frontend/src/utils/i18n/locales/de/de.json
index 0416628..e990b15 100644
--- a/frontend/src/utils/i18n/locales/de/de.json
+++ b/frontend/src/utils/i18n/locales/de/de.json
@@ -28,5 +28,7 @@
"return-to-homepage": "Zurück",
"qr-text": "PayPal QR-Code der Claudius Akademie",
"loading": "Lädt...",
- "greeting": "Hallo,"
+ "greeting": "Hallo,",
+ "set-username-headline": "Keinen Benutzer ausgewählt",
+ "set-username-text": "Um mit dem Losverkauf zu beginnen, musst du einen Benutzer oben links auswählen."
}
\ No newline at end of file
diff --git a/frontend/src/utils/i18n/locales/en/en.json b/frontend/src/utils/i18n/locales/en/en.json
index 5e47dcc..bba6ad1 100644
--- a/frontend/src/utils/i18n/locales/en/en.json
+++ b/frontend/src/utils/i18n/locales/en/en.json
@@ -29,5 +29,7 @@
"return-to-homepage": "Return",
"qr-text": "PayPal QR-Code from the Claudius Akademie",
"loading": "Loading...",
- "greeting": "Hello,"
+ "greeting": "Hello,",
+ "set-username-headline": "No user selected",
+ "set-username-text": "To start the ticket sale, you must select a user first from the top left."
}
\ No newline at end of file
diff --git a/wg-easy-ca-lose b/wg-easy-ca-lose
new file mode 160000
index 0000000..da90d67
--- /dev/null
+++ b/wg-easy-ca-lose
@@ -0,0 +1 @@
+Subproject commit da90d67cc0f3fb3c60d5c2ce0f799dd3c586f1d9