360 lines
9.9 KiB
TypeScript
360 lines
9.9 KiB
TypeScript
import {
|
|
TextField,
|
|
FormControlLabel,
|
|
Checkbox,
|
|
Button,
|
|
Alert,
|
|
CircularProgress,
|
|
Autocomplete,
|
|
Chip,
|
|
Box,
|
|
Paper,
|
|
} from "@mui/material";
|
|
import { useTranslation } from "react-i18next";
|
|
import { useState, useEffect } from "react";
|
|
import { submitFormData } from "../utils/sender";
|
|
import Cookies from "js-cookie";
|
|
|
|
interface Message {
|
|
type: "error" | "info" | "success" | "warning";
|
|
headline: string;
|
|
text: string;
|
|
}
|
|
|
|
export const MainForm = () => {
|
|
const { t } = useTranslation();
|
|
const [invoice, setInvoice] = useState(false);
|
|
const [msg, setMsg] = useState<Message | null>(null);
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
const [nextID, setNextID] = useState<number | null>(null);
|
|
const [formData, setFormData] = useState({
|
|
firstName: "",
|
|
lastName: "",
|
|
email: "",
|
|
phoneNumber: "",
|
|
tickets: 1,
|
|
companyName: "",
|
|
cmpFirstName: "",
|
|
cpmLastName: "",
|
|
cpmEmail: "",
|
|
cpmPhoneNumber: "",
|
|
street: "",
|
|
postalCode: "",
|
|
paymentMethod: "",
|
|
});
|
|
const [users, setUsers] = useState<string[]>([]);
|
|
const [selectedUser, setSelectedUser] = useState<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
// 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 data = await response.json();
|
|
setUsers(data.users);
|
|
};
|
|
fetchUsers();
|
|
console.log(users);
|
|
} catch (error) {
|
|
setMsg({
|
|
type: "error",
|
|
headline: t("error"),
|
|
text: t("failed-to-load-users"),
|
|
});
|
|
console.error("Error fetching users:", error);
|
|
}
|
|
|
|
if (Cookies.get("selectedUser")) {
|
|
const cookieUser = Cookies.get("selectedUser")!;
|
|
setSelectedUser(cookieUser);
|
|
confirmUser(cookieUser);
|
|
}
|
|
}, [isLoading]);
|
|
|
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
setFormData({ ...formData, [e.target.name]: e.target.value });
|
|
};
|
|
|
|
const confirmUser = async (selectedUser: string) => {
|
|
try {
|
|
const response = await fetch(
|
|
`http://localhost:8004/default/confirm-user?username=${selectedUser}`,
|
|
);
|
|
const data = await response.json();
|
|
setNextID(data.nextID);
|
|
} catch (error) {
|
|
console.error("Error confirming user:", error);
|
|
}
|
|
};
|
|
|
|
const handleUserSelection = (selectedUser: string | null) => {
|
|
if (!selectedUser) return;
|
|
setSelectedUser(selectedUser);
|
|
confirmUser(selectedUser);
|
|
Cookies.set("selectedUser", selectedUser);
|
|
};
|
|
|
|
const handleSubmit = async () => {
|
|
setIsLoading(true);
|
|
try {
|
|
const result = await submitFormData(formData, selectedUser || "");
|
|
if (result.success) {
|
|
document.location.href = `/success?id=${nextID}&tickets=${formData.tickets}`;
|
|
} else {
|
|
setMsg({
|
|
type: "error",
|
|
headline: t("error"),
|
|
text: result.error || t("form-submission-failed"),
|
|
});
|
|
}
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Box className="min-h-screen bg-gray-800 flex items-center justify-center p-4">
|
|
<Paper
|
|
elevation={3}
|
|
className="w-full max-w-md p-6 rounded-lg"
|
|
sx={{ backgroundColor: "#fff" }}
|
|
>
|
|
<form
|
|
onSubmit={(e) => {
|
|
e.preventDefault();
|
|
handleSubmit();
|
|
}}
|
|
className="flex flex-col gap-4"
|
|
>
|
|
{/* User Selection */}
|
|
<Autocomplete
|
|
disablePortal
|
|
options={users}
|
|
value={selectedUser}
|
|
fullWidth
|
|
renderInput={(params) => (
|
|
<TextField {...params} label={t("user")} variant="filled" />
|
|
)}
|
|
onChange={(_event, value) => handleUserSelection(value)}
|
|
onKeyDown={(event) => {
|
|
if (event.key === "Enter") {
|
|
event.defaultMuiPrevented = true;
|
|
}
|
|
}}
|
|
/>
|
|
|
|
{/* Next ID Chip */}
|
|
<Chip
|
|
label={`#${nextID ?? "N/A"}`}
|
|
color="primary"
|
|
sx={{
|
|
alignSelf: "flex-start",
|
|
fontWeight: "bold",
|
|
fontSize: "1rem",
|
|
py: 2,
|
|
px: 1,
|
|
}}
|
|
/>
|
|
|
|
{/* Name Fields - Two Columns */}
|
|
<Box className="grid grid-cols-2 gap-3">
|
|
<TextField
|
|
required
|
|
id="first-name"
|
|
label={t("first-name")}
|
|
variant="filled"
|
|
value={formData.firstName}
|
|
onChange={handleChange}
|
|
name="firstName"
|
|
fullWidth
|
|
/>
|
|
<TextField
|
|
required
|
|
id="last-name"
|
|
label={t("last-name")}
|
|
variant="filled"
|
|
value={formData.lastName}
|
|
onChange={handleChange}
|
|
name="lastName"
|
|
fullWidth
|
|
/>
|
|
</Box>
|
|
|
|
{/* Email */}
|
|
<TextField
|
|
required
|
|
id="email"
|
|
label={t("email")}
|
|
variant="filled"
|
|
type="email"
|
|
value={formData.email}
|
|
onChange={handleChange}
|
|
name="email"
|
|
fullWidth
|
|
/>
|
|
|
|
{/* Phone Number */}
|
|
<TextField
|
|
required
|
|
id="phone-number"
|
|
label={t("phone-number")}
|
|
variant="filled"
|
|
type="tel"
|
|
value={formData.phoneNumber}
|
|
onChange={handleChange}
|
|
name="phoneNumber"
|
|
fullWidth
|
|
/>
|
|
|
|
{/* Tickets and Invoice Checkbox */}
|
|
<Box className="grid grid-cols-2 gap-3 items-center">
|
|
<TextField
|
|
required
|
|
id="tickets"
|
|
type="number"
|
|
label={t("tickets")}
|
|
variant="filled"
|
|
value={formData.tickets}
|
|
onChange={handleChange}
|
|
name="tickets"
|
|
fullWidth
|
|
inputProps={{ min: 1 }}
|
|
/>
|
|
<FormControlLabel
|
|
control={
|
|
<Checkbox
|
|
checked={invoice}
|
|
onChange={(e) => setInvoice(e.target.checked)}
|
|
/>
|
|
}
|
|
label={t("invoice")}
|
|
className="justify-end"
|
|
/>
|
|
</Box>
|
|
|
|
{/* Invoice Fields */}
|
|
{invoice && (
|
|
<Box className="flex flex-col gap-3 pt-2 border-t border-gray-200">
|
|
<TextField
|
|
required
|
|
id="company-name"
|
|
label={t("company-name")}
|
|
variant="filled"
|
|
value={formData.companyName}
|
|
onChange={handleChange}
|
|
name="companyName"
|
|
fullWidth
|
|
/>
|
|
|
|
{/* Invoice Name Fields - Two Columns */}
|
|
<Box className="grid grid-cols-2 gap-3">
|
|
<TextField
|
|
required
|
|
id="first-name_invoice"
|
|
label={t("first-name")}
|
|
variant="filled"
|
|
value={formData.cmpFirstName}
|
|
onChange={handleChange}
|
|
name="cmpFirstName"
|
|
fullWidth
|
|
/>
|
|
<TextField
|
|
required
|
|
id="last-name_invoice"
|
|
label={t("last-name")}
|
|
variant="filled"
|
|
value={formData.cpmLastName}
|
|
onChange={handleChange}
|
|
name="cpmLastName"
|
|
fullWidth
|
|
/>
|
|
</Box>
|
|
|
|
<TextField
|
|
required
|
|
id="street"
|
|
label={t("street")}
|
|
variant="filled"
|
|
value={formData.street}
|
|
onChange={handleChange}
|
|
name="street"
|
|
fullWidth
|
|
/>
|
|
|
|
<TextField
|
|
required
|
|
id="postal-code"
|
|
label={t("postal-code")}
|
|
variant="filled"
|
|
value={formData.postalCode}
|
|
onChange={handleChange}
|
|
name="postalCode"
|
|
fullWidth
|
|
/>
|
|
|
|
<TextField
|
|
required
|
|
id="phone-number_invoice"
|
|
label={t("phone-number")}
|
|
variant="filled"
|
|
type="tel"
|
|
value={formData.cpmPhoneNumber}
|
|
onChange={handleChange}
|
|
name="cpmPhoneNumber"
|
|
fullWidth
|
|
/>
|
|
|
|
<TextField
|
|
required
|
|
id="email_invoice"
|
|
label={t("email")}
|
|
variant="filled"
|
|
type="email"
|
|
value={formData.cpmEmail}
|
|
onChange={handleChange}
|
|
name="cpmEmail"
|
|
fullWidth
|
|
/>
|
|
</Box>
|
|
)}
|
|
|
|
{/* Payment Methods */}
|
|
<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}
|
|
fullWidth
|
|
size="large"
|
|
sx={{
|
|
mt: 2,
|
|
py: 1.5,
|
|
textTransform: "uppercase",
|
|
fontWeight: "bold",
|
|
}}
|
|
>
|
|
{isLoading ? (
|
|
<CircularProgress size={24} color="inherit" />
|
|
) : (
|
|
t("submit")
|
|
)}
|
|
</Button>
|
|
|
|
{/* Alert Message */}
|
|
{msg && (
|
|
<Alert severity={msg.type} sx={{ mt: 2 }}>
|
|
{msg.headline}: {msg.text}
|
|
</Alert>
|
|
)}
|
|
</form>
|
|
</Paper>
|
|
</Box>
|
|
);
|
|
};
|