SiteFrontend/src/components/contact_form/contact.tsx

161 lines
5.1 KiB
TypeScript
Raw Normal View History

import React, {ChangeEvent, useState} from "react";
import './Contact.css';
import { useNavigate } from 'react-router-dom'
type InputNames = "username" | "email" | "question";
interface Step {
label: string;
name: InputNames;
type: "text" | "email" | "textarea";
min_length: number;
max_length: number;
required: boolean;
pattern: string;
}
type FormDataType = Record<InputNames, string>;
const ContactForm = () => {
const navigate = useNavigate()
const [formData, setFormData] = useState<FormDataType>({
username: "",
email: "",
question: ""
});
const [currentStep, setCurrentStep] = useState<number>(0);
const [errorMessage, setErrorMessage] = useState<string>("");
function handleChange(e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) {
const { name, value } = e.target;
setErrorMessage("");
switch (name) {
case 'username':
if (/^[a-zA-Z0-9_]*$/.test(value)) {
setFormData(prevState => ({ ...prevState, [name]: value }));
} else {
setErrorMessage('Invalid character entered. Please use only alphanumeric characters and underscores.');
}
break;
default:
setFormData(prevState => ({ ...prevState, [name]: value }));
}
}
const steps: Step[] = [
{
label: "Username",
name: "username",
type: "text",
min_length: 3,
max_length: 16,
required: true,
pattern: ""
},
{
label: "Email",
name: "email",
type: "email",
min_length: 3,
max_length: 254,
required: false,
pattern: ""
},
{
label: "Question",
name: "question",
type: "textarea",
min_length: 10,
max_length: 2000,
required: true,
pattern: ""
},
]
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
try {
const response = await fetch('http://localhost:8080/api/contact/submitContactForm', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData)
})
if (!response.ok) {
alert("Your form submission was denied by the server, or the server was unable to process it, if you didn't mess with the data please contact the administrator at admin@alttd.com");
} else {
navigate('/verify-email', {
state: {
email: formData.email
}
});
}
} catch (e) {
alert("Your form submission was denied by the server, if you didn't mess with the data please contact the administrator at admin@alttd.com")
}
};
const next = () => {
setCurrentStep(current => current + 1)
}
const prev = () => {
setCurrentStep(current => Math.max(current - 1, 0))
setErrorMessage('');
}
function isNextDisabled(): boolean {
let step: Step = steps[currentStep];
if (!step)
return true;
if (!step.required)
return false;
return formData[step.name].length === 0
}
function getInputField(step: Step): JSX.Element {
switch (step.type) {
case "text":
case "email":
return <input pattern={step.pattern} type={step.type} name={step.name} minLength={step.min_length}
maxLength={step.max_length} onChange={handleChange} value={formData[step.name]} required/>
case "textarea":
return <textarea name={step.name} minLength={step.min_length} maxLength={step.max_length}
onChange={handleChange} value={formData.question} required/>
}
}
return (
<div className="container">
<div>
<h1>Contact Form</h1>
</div>
{errorMessage && <p>{errorMessage}</p>}
<div>
<form onSubmit={handleSubmit}>
<div>
<label>
{steps[currentStep].label}
{getInputField(steps[currentStep])}
</label>
</div>
<button type="button" onClick={prev} disabled={currentStep === 0}>
Previous
</button>
<button type="button" onClick={next} disabled={currentStep === steps.length - 1 || isNextDisabled()}>
Next
</button>
<input type="submit" value="Submit" disabled={currentStep !== steps.length - 1}
hidden={currentStep !== steps.length - 1}/>
</form>
</div>
</div>
);
};
export default ContactForm;