import { useTranslation } from "react-i18next"; import { useState, useEffect } from "react"; import * as React from "react"; import Cookies from "js-cookie"; import { Sheet, Input, Button, Checkbox, Chip, IconButton, Alert, Typography, FormControl, FormLabel, Autocomplete, ButtonGroup, Modal, ModalDialog, ModalClose, } from "@mui/joy"; import { submitFormData } from "../utils/sender"; 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 } from "@tanstack/react-query"; import { confirmUser, fetchUsers } from "../utils/api/users"; const PAYMENT_METHODS = ["bar", "paypal", "andere"] as const; const PAYMENT_LABELS: Record = { bar: "Cash", paypal: "PayPal", andere: "Transfer", }; const DEFAULT_FORM: FormData = { firstName: "", lastName: "", email: "", phoneNumber: "", tickets: 1, companyName: "", cmpFirstName: "", cpmLastName: "", cpmEmail: "", cpmPhoneNumber: "", street: "", postalCode: "", paymentMethod: "", }; // ─── Field component lives OUTSIDE MainForm so React doesn't treat it as a // new component type on every render, which would cause inputs to lose focus. const Field = ({ label, name, type = "text", required = true, formData, onChange, }: { label: string; name: keyof FormData; type?: string; required?: boolean; formData: FormData; onChange: (e: React.ChangeEvent) => void; }) => ( {label} ); export const MainForm = () => { const { t, i18n } = useTranslation(); const [invoice, setInvoice] = useState(false); const [msg, setMsg] = useState(null); const [nextID, setNextID] = useState(null); const [selectedUser, setSelectedUser] = useState(""); const [formData, setFormData] = useState(DEFAULT_FORM); const [showSelectUser, setShowSelectUser] = useState(false); const [QRmodal, setQRmodal] = useState(false); const handleChange = (e: React.ChangeEvent) => { setFormData({ ...formData, [e.target.name]: e.target.value }); }; useEffect(() => { const savedUser = Cookies.get("selectedUser"); if (savedUser) { setSelectedUser(savedUser); } }, []); const { data: usernameData, isLoading: usernameDataIsLoading } = useQuery({ queryKey: ["users"], queryFn: fetchUsers, }); const { data: userData, isSuccess: userDataIsSuccess } = useQuery({ queryKey: ["user", selectedUser], enabled: !!selectedUser, queryFn: () => confirmUser(selectedUser), }); // Setting the nextID after a user is selected useEffect(() => { if (!userData) return; setNextID(userData.nextID); }, [userDataIsSuccess]); const handleUserSelection = (username: string | null) => { if (username == null || username == "") { return; } setSelectedUser(username); }; const changeTranslation = () => { const clientLng = i18n.language; if (clientLng === "en") { i18n.changeLanguage("de"); Cookies.set("language", "de"); } else if (clientLng === "de") { i18n.changeLanguage("en"); Cookies.set("language", "en"); } else { setMsg({ type: "danger", headline: "Error", text: "Cannot change langugage.", }); } }; useEffect(() => { if (formData.paymentMethod === "paypal") { setQRmodal(true); } }, [formData.paymentMethod]); const handleSubmit = async () => { try { const result = await submitFormData(formData, selectedUser || ""); if (result.success) { document.location.href = `/success?id=${nextID}&tickets=${formData.tickets}`; } else { setMsg({ type: "danger", headline: t("form-submission-failed"), text: result.error || t("form-submission-failed"), }); } } catch (error) { setMsg({ type: "danger", headline: t("error"), text: t("form-submission-failed"), }); } }; // 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
setShowSelectUser(true)}> setQRmodal(true)}> {/* Language toggle */} {`${t("greeting")} ${userData?.fullname ?? t("loading")}`}
{ e.preventDefault(); handleSubmit(); }} className="flex flex-col gap-4" > {/* Next ID badge */} #{nextID ?? "N/A"} {/* Name row */}
{/* Tickets + Invoice toggle */}
{t("tickets")}
setInvoice(e.target.checked)} label={t("invoice")} variant="outlined" />
{/* Invoice details (conditional) */} {invoice && (
{t("invoice-details")}
)} {/* Payment method selection */} {t("select-payment-method")}
{PAYMENT_METHODS.map((method) => ( ))}
{/* Hidden required input to enforce payment selection on submit */} {!formData.paymentMethod && ( {}} style={{ opacity: 0, width: 0, height: 0, position: "absolute", }} /> )}
{/* Submit button */} {/* Alert message */} {msg && ( {msg.headline}: {msg.text} )}
); };