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.
139 lines
5.8 KiB
TypeScript
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; |