SiteFrontend/src/components/form/genericForm.tsx
Teriuihi 75559af7c8 Add form active status check and redirection
Introduced `FormActiveRedirect` component to check if forms are active before rendering. Updated form data to include `backendFormName` and adjusted routes in `App.tsx` to use the new component. This ensures that inactive forms redirect users with a relevant message.
2024-08-10 03:10:25 +02:00

139 lines
5.8 KiB
TypeScript

import React, {useState} from "react";
import './GenericForm.css';
import {useNavigate} from 'react-router-dom'
import {ErrorMessage, Form, FormikProvider, FormikValues, useFormik} from "formik";
import {Step, UserInput, FormData} from './formInterfaces';
import * as Yup from "yup";
import FormHTML from "./formHTML";
const GenericForm = (formData: FormData) => {
const steps: Step[] = formData.steps;
const backend: string = formData.backend;
const userInput: UserInput = formData.userInput;
const spec: Yup.Schema<any> = formData.spec;
const backendFormname = formData.backendFormName
const navigate = useNavigate();
const [currentStep, setCurrentStep] = useState<number>(0);
const handleSubmit = async (formikValues: FormikValues) => {
console.log(JSON.stringify(formikValues))
try {
const response = await fetch(backend, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formikValues)
})
if (!response.ok) {
let json: string = JSON.stringify(formikValues);
const blob = new Blob([json], {type: "application/json"});
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = 'your_form_data.json';
link.click();
URL.revokeObjectURL(url);
//TODO clean up
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: formikValues['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))
}
const formik = useFormik({
initialValues: userInput,
validationSchema: spec,
onSubmit: (values) => {
handleSubmit(values);
},
});
const {
touched,
errors,
isValid,
handleChange,
values,
setFieldTouched,
setFieldValue,
} = formik;
const [prevLength, setPrevLength] = useState(0);
return (
<div>
<div>
<h1>{formData.title}</h1>
</div>
<div>
<FormikProvider value={formik}>
<Form>
<div>
<div>
<label>
<label className="headline">
{steps[currentStep].label}
</label>
<label className="description">
{
steps[currentStep].additional_info ?
steps[currentStep].additional_info?.split('\n').map((line, i) => (
<React.Fragment key={i}>{line}<br/></React.Fragment>
))
: null
}
</label>
</label>
<label>
<FormHTML steps={steps} currentStep={currentStep} handleChange={handleChange}
setFieldTouched={setFieldTouched} setFieldValue={setFieldValue} values={values}
prevLength={prevLength} setPrevLength={setPrevLength}>
</FormHTML>
</label>
</div>
<div>
<label className="error-message">
<ErrorMessage name={steps[currentStep].name} component="div"/>
</label>
</div>
<div>
<button style={{marginLeft: 0}} className="button-outer" type="button" onClick={prev} disabled={currentStep === 0}>
Previous
</button>
<button className={currentStep === (steps.length - 1) ? "" : "button-outer"} type="button" onClick={next}
hidden={currentStep === (steps.length - 1)}
disabled={(!touched[steps[currentStep].name] || !!errors[steps[currentStep].name]) || currentStep === (steps.length - 1)}>
Next
</button>
<input className={currentStep !== (steps.length - 1) ? "" : "button-outer"} type="submit" value="Submit"
hidden={currentStep !== (steps.length - 1)}
disabled={!isValid || currentStep !== (steps.length - 1)}
/>
</div>
</div>
</Form>
</FormikProvider>
</div>
</div>
);
};
export default GenericForm;