Files
bflows-bandi-fe/src/pages/BandoFormsPreview/index.js
2024-10-03 09:17:04 +02:00

199 lines
8.0 KiB
JavaScript

import React, { useState, useEffect } from 'react';
import { __ } from '@wordpress/i18n';
import { useNavigate, useParams } from 'react-router-dom';
import { klona } from 'klona';
import { head } from 'ramda';
import { useForm } from 'react-hook-form';
// store
import { storeSet, useStore } from '../../store';
// api
import FormsService from '../../service/forms-service';
// components
import { Skeleton } from 'primereact/skeleton';
import { Button } from 'primereact/button';
import FormField from '../../components/FormField';
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
// tools
import {
isCAP,
isCodiceFiscale,
isEmail,
isEmailPEC,
isIBAN,
isMarcaDaBollo,
isPIVA,
isUrl
} from '../../helpers/validators';
import renderHtmlContent from '../../helpers/renderHtmlContent';
const BandoFormsPreview = () => {
const { id, formId } = useParams();
const navigate = useNavigate();
const [formData, setFormData] = useState([]);
const [formName, setFormName] = useState('');
const isAsyncRequest = useStore().main.isAsyncRequest();
const {
control,
handleSubmit,
formState: { errors },
getValues,
register,
setValue
} = useForm({ defaultValues: {}, mode: 'onChange' });
const values = getValues();
const validationFns = {
isPIVA,
isCodiceFiscale,
isCAP,
isIBAN,
isEmail,
isEmailPEC,
isUrl,
isMarcaDaBollo
}
const onSubmit = () => {
}
const closePreview = () => {
const parsedId = parseInt(id)
const bandoId = !isNaN(parsedId) ? parsedId : 0;
const parsedFormId = parseInt(formId)
const bandoFormId = !isNaN(parsedFormId) ? parsedFormId : 0;
navigate(`/bandi/${bandoId}/forms/${bandoFormId}`);
}
const getFormCallback = (data) => {
if (data.status === 'SUCCESS') {
setFormName(data.data.label);
const elements = klona(data.data.content);
setFormData(elements);
}
storeSet.main.unsetAsyncRequest();
}
const errGetFormCallbacks = (data) => {
set404FromErrorResponse(data);
storeSet.main.unsetAsyncRequest();
}
useEffect(() => {
const parsedFormId = parseInt(formId)
const bandoFormId = !isNaN(parsedFormId) ? parsedFormId : 0;
if (bandoFormId) {
storeSet.main.setAsyncRequest();
FormsService.getFormById(bandoFormId, getFormCallback, errGetFormCallbacks);
}
}, [id, formId]);
return (
<div className="appPage">
{!isAsyncRequest
? <div className="appPage__pageHeader">
<h1>{formName}</h1>
</div>
: <>
<Skeleton width="20%" height="1rem" className="mb-2"></Skeleton>
<Skeleton width="100%" height="2rem" className="mb-8"></Skeleton>
</>}
<div className="appPage__spacer"></div>
{!isAsyncRequest
? <div className="appPage__content">
<div className="appPageSection__preview">
<Button
type="button"
outlined
onClick={closePreview}
label={__('Chiudi Anteprima', 'gepafin')}
icon="pi pi-arrow-left" iconPos="left"/>
</div>
<form className="appForm" onSubmit={handleSubmit(onSubmit)}>
{formData.map(o => {
const label = head(o.settings.filter(o => o.name === 'label'));
const text = head(o.settings.filter(o => o.name === 'text'));
const placeholder = head(o.settings.filter(o => o.name === 'placeholder'));
const options = head(o.settings.filter(o => o.name === 'options'));
const tableColumns = head(o.settings.filter(o => o.name === 'table_columns'));
const step = head(o.settings.filter(o => o.name === 'step'));
const mime = head(o.settings.filter(o => o.name === 'mime'));
let mimeValue = '';
if (mime) {
mimeValue = mime.value.map(o => o.code).join(',');
}
const validations = Object.keys(o.validators).reduce((acc, cur) => {
if (o.validators[cur]) {
if (['min', 'max', 'minLength', 'maxLength', 'maxSize'].includes(cur)) {
acc[cur] = parseInt(o.validators[cur]);
} else if ('pattern' === cur) {
acc[cur] = new RegExp(o.validators[cur])
} else if ('isRequired' === cur) {
acc[cur] = o.validators[cur]
} else if ('custom' === cur && validationFns[o.validators[cur]]) {
if (!acc.validate) {
acc.validate = {}
}
acc.validate[cur] = validationFns[o.validators[cur]]
}
}
return acc;
}, {});
return ['paragraph'].includes(o.name) && text
? <div className="appForm__content">{renderHtmlContent(text.value)}</div>
: <FormField
key={o.id}
type={o.name}
fieldName={o.id}
label={label ? label.value : ''}
placeholder={placeholder ? placeholder.value : ''}
control={control}
register={register}
errors={errors}
defaultValue={values[o.id]}
maxFractionDigits={step ? step.value : 0}
accept={mimeValue}
config={validations}
options={options ? options.value : []}
setDataFn={setValue}
sourceId={0}
tableColumns={tableColumns ? tableColumns.value : {}}
/>
})}
</form>
<div className="appPageSection__preview">
<Button
type="button"
outlined
onClick={closePreview}
label={__('Chiudi Anteprima', 'gepafin')}
icon="pi pi-arrow-left" iconPos="left"/>
</div>
</div>
: <>
<Skeleton width="20%" height="1rem" className="mb-2"></Skeleton>
<Skeleton width="100%" height="2rem" className="mb-8"></Skeleton>
<Skeleton width="20%" height="1rem" className="mb-2"></Skeleton>
<Skeleton width="100%" height="4rem" className="mb-8"></Skeleton>
<Skeleton width="20%" height="1rem" className="mb-2"></Skeleton>
<Skeleton width="100%" height="2rem" className="mb-8"></Skeleton>
<Skeleton width="20%" height="1rem" className="mb-2"></Skeleton>
<Skeleton width="100%" height="4rem"></Skeleton>
</>}
</div>
)
}
export default BandoFormsPreview;