354 lines
14 KiB
JavaScript
354 lines
14 KiB
JavaScript
import React, { useState, useEffect, useRef, useMemo } from 'react';
|
||
import { __, sprintf } from '@wordpress/i18n';
|
||
import { useNavigate, useParams } from 'react-router-dom';
|
||
import { is, isEmpty } from 'ramda';
|
||
import { useForm } from 'react-hook-form';
|
||
import { klona } from 'klona';
|
||
|
||
// store
|
||
import { storeSet, useStore } from '../../store';
|
||
|
||
// api
|
||
import AmendmentsService from '../../service/amendments-service';
|
||
import ApplicationService from '../../service/application-service';
|
||
|
||
// tools
|
||
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||
import getBandoLabel from '../../helpers/getBandoLabel';
|
||
import getDateFromISOstring from '../../helpers/getDateFromISOstring';
|
||
import renderHtmlContent from '../../helpers/renderHtmlContent';
|
||
|
||
// components
|
||
import { Button } from 'primereact/button';
|
||
import BlockingOverlay from '../../components/BlockingOverlay';
|
||
import { Toast } from 'primereact/toast';
|
||
import { Dialog } from 'primereact/dialog';
|
||
import FormField from '../../components/FormField';
|
||
import SoccorsoComunications from '../SoccorsoEditPreInstructor/components/SoccorsoComunications';
|
||
|
||
const DomandaBeneficiario = () => {
|
||
const isAsyncRequest = useStore().main.isAsyncRequest();
|
||
const { id } = useParams();
|
||
const navigate = useNavigate();
|
||
const [data, setData] = useState({});
|
||
const [dataAppl, setDataAppl] = useState({});
|
||
const [isVisibleEmailDialog, setIsVisibleEmailDialog] = useState(false);
|
||
const toast = useRef(null);
|
||
const [formInitialData, setFormInitialData] = useState({});
|
||
const {
|
||
control,
|
||
handleSubmit,
|
||
formState: { errors },
|
||
setValue,
|
||
register,
|
||
trigger,
|
||
getValues
|
||
} = useForm({
|
||
defaultValues: useMemo(() => {
|
||
return formInitialData;
|
||
}, [formInitialData]), mode: 'onChange'
|
||
});
|
||
|
||
const goToArchivePage = () => {
|
||
navigate(`/domande`);
|
||
}
|
||
|
||
useEffect(() => {
|
||
const parsedId = parseInt(id);
|
||
const entityId = !isNaN(parsedId) ? parsedId : 0;
|
||
|
||
AmendmentsService.getSoccorsoByApplId(entityId, getCallback, errGetCallback, [
|
||
['statuses', 'AWAITING']
|
||
]);
|
||
}, [id]);
|
||
|
||
const getCallback = (data) => {
|
||
if (data.status === 'SUCCESS') {
|
||
if (data.data.length) {
|
||
const amendmentObj = data.data[0];
|
||
setData(getFormattedData(amendmentObj));
|
||
const formDataInitial = amendmentObj.applicationFormFields.reduce((acc, cur) => {
|
||
if (cur.fieldValue) {
|
||
acc[cur.fieldId] = cur.fieldValue;
|
||
}
|
||
return acc;
|
||
}, {});
|
||
setFormInitialData(formDataInitial);
|
||
storeSet.main.unsetAsyncRequest();
|
||
} else {
|
||
ApplicationService.getApplication(id, getApplCallback, errGetCallback)
|
||
}
|
||
}
|
||
}
|
||
|
||
const errGetCallback = (data) => {
|
||
if (toast.current && data.message) {
|
||
toast.current.show({
|
||
severity: 'error',
|
||
summary: '',
|
||
detail: data.message
|
||
});
|
||
}
|
||
set404FromErrorResponse(data);
|
||
storeSet.main.unsetAsyncRequest();
|
||
}
|
||
|
||
const getApplCallback = (data) => {
|
||
if (data.status === 'SUCCESS') {
|
||
setDataAppl(getFormattedData(data.data));
|
||
}
|
||
storeSet.main.unsetAsyncRequest();
|
||
}
|
||
|
||
const getFormattedData = (data) => {
|
||
data.submissionDate = is(String, data.submissionDate) ? new Date(data.submissionDate) : (data.submissionDate ? data.submissionDate : '');
|
||
data.startDate = is(String, data.startDate) ? new Date(data.startDate) : (data.startDate ? data.startDate : '');
|
||
data.expirationDate = is(String, data.expirationDate) ? new Date(data.expirationDate) : (data.expirationDate ? data.expirationDate : '');
|
||
return data;
|
||
};
|
||
|
||
const onSubmit = () => {
|
||
};
|
||
|
||
const doUpdateAmendment = () => {
|
||
trigger();
|
||
let formValues = klona(getValues());
|
||
const newFormValues = Object.keys(formValues)
|
||
.reduce((acc, cur) => {
|
||
let fieldVal = formValues[cur];
|
||
|
||
fieldVal = isEmpty(fieldVal) ? null : fieldVal;
|
||
fieldVal = is(Array, fieldVal) ? fieldVal.map(o => o.id).join(',') : null;
|
||
|
||
acc.push({
|
||
'fieldId': cur,
|
||
'fieldValue': fieldVal
|
||
});
|
||
return acc;
|
||
}, []);
|
||
|
||
const submitData = {
|
||
applicationFormFields: newFormValues,
|
||
}
|
||
const amendmentId = data.id;
|
||
|
||
storeSet.main.setAsyncRequest();
|
||
AmendmentsService.updateSoccorso(amendmentId, submitData, updateAmendmentCallback, errUpdateAmendmentCallback);
|
||
}
|
||
|
||
const updateAmendmentCallback = (data) => {
|
||
if (data.status === 'SUCCESS') {
|
||
if (toast.current) {
|
||
toast.current.show({
|
||
severity: 'success',
|
||
summary: '',
|
||
detail: data.message
|
||
});
|
||
}
|
||
const newFormDataInitial = data.data.applicationFormFields.reduce((acc, cur) => {
|
||
if (cur.fieldValue) {
|
||
acc[cur.fieldId] = cur.fieldValue;
|
||
}
|
||
return acc;
|
||
}, formInitialData);
|
||
setFormInitialData(newFormDataInitial);
|
||
}
|
||
storeSet.main.unsetAsyncRequest();
|
||
}
|
||
|
||
const errUpdateAmendmentCallback = (data) => {
|
||
if (toast.current && data.message) {
|
||
toast.current.show({
|
||
severity: 'error',
|
||
summary: '',
|
||
detail: data.message
|
||
});
|
||
}
|
||
//set404FromErrorResponse(data);
|
||
storeSet.main.unsetAsyncRequest();
|
||
}
|
||
|
||
useEffect(() => {
|
||
if (formInitialData) {
|
||
//reset();
|
||
Object.keys(formInitialData).map(k => setValue(k, formInitialData[k]));
|
||
trigger();
|
||
}
|
||
}, [formInitialData]);
|
||
|
||
return (
|
||
<div className="appPage">
|
||
<div className="appPage__pageHeader">
|
||
{data.id
|
||
? <h1>
|
||
{sprintf(__('Soccorso Istruttorio: richiesta integrazione documenti per domanda #%s', 'gepafin'), id)}
|
||
</h1> : null}
|
||
{dataAppl.id
|
||
? <h1>
|
||
{sprintf(__('Dettagli: domanda #%s', 'gepafin'), dataAppl.id)}
|
||
</h1> : null}
|
||
</div>
|
||
|
||
<div className="appPage__spacer"></div>
|
||
<Toast ref={toast}/>
|
||
<BlockingOverlay shouldDisplay={isAsyncRequest}/>
|
||
|
||
<div className="appPageSection__row">
|
||
<Button
|
||
type="button"
|
||
outlined
|
||
onClick={goToArchivePage}
|
||
label={__('Indietro', 'gepafin')}
|
||
icon="pi pi-arrow-left" iconPos="left"/>
|
||
</div>
|
||
|
||
<div className="appPage__spacer"></div>
|
||
|
||
<div className="appPage__content">
|
||
{data.id
|
||
? <div className="appPageSection__withBorder columns">
|
||
<p className="appPageSection__pMeta">
|
||
<span>{__('ID domanda', 'gepafin')}</span>
|
||
<span>{data.applicationId}</span>
|
||
</p>
|
||
<p className="appPageSection__pMeta">
|
||
<span>{__('Bando', 'gepafin')}</span>
|
||
<span>{data.callName}</span>
|
||
</p>
|
||
<p className="appPageSection__pMeta">
|
||
<span>{__('Beneficiario', 'gepafin')}</span>
|
||
<span>{data.beneficiaryName}</span>
|
||
</p>
|
||
<p className="appPageSection__pMeta">
|
||
<span>{__('Inizio', 'gepafin')}</span>
|
||
<span>{getDateFromISOstring(data.startDate)}</span>
|
||
</p>
|
||
<p className="appPageSection__pMeta">
|
||
<span>{__('Scadenza', 'gepafin')}</span>
|
||
<span>{getDateFromISOstring(data.expirationDate)}</span>
|
||
</p>
|
||
<p className="appPageSection__pMeta">
|
||
<span>{__('Stato', 'gepafin')}</span>
|
||
<span>{getBandoLabel(data.status)}</span>
|
||
</p>
|
||
</div> : null}
|
||
{dataAppl.id
|
||
? <div className="appPageSection__withBorder columns">
|
||
<p className="appPageSection__pMeta">
|
||
<span>{__('ID domanda', 'gepafin')}</span>
|
||
<span>{dataAppl.id}</span>
|
||
</p>
|
||
<p className="appPageSection__pMeta">
|
||
<span>{__('Bando', 'gepafin')}</span>
|
||
<span>{dataAppl.callTitle}</span>
|
||
</p>
|
||
<p className="appPageSection__pMeta">
|
||
<span>{__('Azienda', 'gepafin')}</span>
|
||
<span>{dataAppl.companyName}</span>
|
||
</p>
|
||
<p className="appPageSection__pMeta">
|
||
<span>{__('Inviato', 'gepafin')}</span>
|
||
<span>{getDateFromISOstring(dataAppl.submissionDate)}</span>
|
||
</p>
|
||
<p className="appPageSection__pMeta">
|
||
<span>{__('Protocolo', 'gepafin')}</span>
|
||
<span>{dataAppl.protocolNumber}</span>
|
||
</p>
|
||
<p className="appPageSection__pMeta">
|
||
<span>{__('Stato', 'gepafin')}</span>
|
||
<span>{getBandoLabel(dataAppl.status)}</span>
|
||
</p>
|
||
</div> : null}
|
||
|
||
{data.id
|
||
? <div className="appPageSection">
|
||
<h2>{__('Dettagli Richiesta', 'gepafin')}</h2>
|
||
<h3>{__('Note e spiegazioni', 'gepafin')}</h3>
|
||
<div className="appPageSection__withBorder grey ql-editor"
|
||
style={{ minHeight: '100px' }}>
|
||
{renderHtmlContent(data.note)}
|
||
</div>
|
||
</div> : null}
|
||
|
||
{data.id
|
||
? <div className="appPageSection">
|
||
<h3>{__('Documenti Richiesti', 'gepafin')}</h3>
|
||
<form className="appForm" onSubmit={handleSubmit(onSubmit)}>
|
||
{data.formFields
|
||
? data.formFields.map((o, i) => {
|
||
return <FormField
|
||
key={o.fieldId}
|
||
disabled={data.status === 'CLOSE'}
|
||
type="fileupload"
|
||
setDataFn={setValue}
|
||
saveFormCallback={doUpdateAmendment}
|
||
fieldName={o.fieldId}
|
||
label={o.label}
|
||
control={control}
|
||
register={register}
|
||
errors={errors}
|
||
defaultValue={formInitialData[o.fieldId] ? formInitialData[o.fieldId] : []}
|
||
accept={[]}
|
||
source="AMENDMENT"
|
||
sourceId={data.applicationId}
|
||
multiple={true}
|
||
/>
|
||
}) : null}
|
||
</form>
|
||
{/*<ol className="appPageSection__list">
|
||
{data.formFields
|
||
? data.formFields.map((o, i) => <li key={o.fieldId}
|
||
style={{ flexDirection: 'row' }}>
|
||
<span>{o.label}</span>
|
||
</li>) : null}
|
||
</ol>*/}
|
||
</div> : null}
|
||
|
||
{data.id
|
||
? <div className="appPageSection">
|
||
<h2>{__('Comunicazioni', 'gepafin')}</h2>
|
||
<SoccorsoComunications amendmentId={data.id} soccorsoStatus={data.status}/>
|
||
</div> : null}
|
||
|
||
{data.id
|
||
? <div className="appPageSection__message warning">
|
||
<i className="pi pi-exclamation-triangle"></i>
|
||
<span className="summary">{__('Attenzione', 'gepafin')}</span>
|
||
<span>{__('Inviare la documentazione richiesta completa delle integrazioni esclusivamente via PEC. In caso contarrio l’integrazione non può essere ritenuta valida.', 'gepafin')}</span>
|
||
</div> : null}
|
||
|
||
<div className="appPageSection">
|
||
<div className="appPageSection__actions">
|
||
{data.id
|
||
? <Button
|
||
type="button"
|
||
disabled={isAsyncRequest}
|
||
onClick={() => setIsVisibleEmailDialog(true)}
|
||
label={__('Invia documenti via PEC', 'gepafin')}
|
||
icon="pi pi-envelope" iconPos="right"/> : null}
|
||
<Button
|
||
type="button"
|
||
outlined
|
||
onClick={goToArchivePage}
|
||
disabled={isAsyncRequest}
|
||
label={__('Chiudi', 'gepafin')}
|
||
icon="pi pi-times" iconPos="right"/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<Dialog
|
||
header={__('Invia documenti via PEC', 'gepafin')}
|
||
visible={isVisibleEmailDialog}
|
||
style={{ width: '50vw' }}
|
||
onHide={() => {if (!isVisibleEmailDialog) return; setIsVisibleEmailDialog(false); }}>
|
||
<p className="m-0">
|
||
{data.callEmail}
|
||
</p>
|
||
</Dialog>
|
||
</div>
|
||
)
|
||
|
||
}
|
||
|
||
export default DomandaBeneficiario; |