From 11c2372cae35887bd755555308661b6f7abf13af Mon Sep 17 00:00:00 2001 From: Theis Date: Tue, 19 May 2026 21:54:02 +0200 Subject: [PATCH] outsourced modals --- .../src/components/modals/QR-CodeModal.tsx | 31 ++++++ .../src/components/modals/SelectUserModal.tsx | 40 +++++++ frontend/src/pages/MainForm.tsx | 101 +++++------------- frontend/src/utils/api/form.ts | 5 +- frontend/src/utils/api/users.ts | 6 +- 5 files changed, 109 insertions(+), 74 deletions(-) create mode 100644 frontend/src/components/modals/QR-CodeModal.tsx create mode 100644 frontend/src/components/modals/SelectUserModal.tsx 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")} + PayPal QR Code + + + ); +}; 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 d17c43a..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); @@ -106,8 +102,8 @@ export const MainForm = () => { setMsg({ type: "warning", headline: t("set-username-headline"), - text: t("set-username-text") - }) + text: t("set-username-text"), + }); } }, []); @@ -116,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 == "") { @@ -180,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")} - PayPal QR Code - - + + +
{ formData.paymentMethod === method ? "solid" : "soft" } color="primary" - onClick={() => + onClick={() => { setFormData((prev) => ({ ...prev, paymentMethod: method, - })) - } + })); + if (method === "paypal") { + setQRmodal(true); + } + }} sx={{ flex: 1, minWidth: "90px", diff --git a/frontend/src/utils/api/form.ts b/frontend/src/utils/api/form.ts index 5c9f095..d74138c 100644 --- a/frontend/src/utils/api/form.ts +++ b/frontend/src/utils/api/form.ts @@ -1,7 +1,10 @@ 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 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}`,