+ ?
+
{renderHtmlContent(text.value)}
diff --git a/src/pages/BandoApplicationPreview/index.js b/src/pages/BandoApplicationPreview/index.js
new file mode 100644
index 0000000..74b79d4
--- /dev/null
+++ b/src/pages/BandoApplicationPreview/index.js
@@ -0,0 +1,412 @@
+import React, { useState, useEffect, useRef, useMemo } from 'react';
+import { __, sprintf } from '@wordpress/i18n';
+import { useParams } from 'react-router-dom';
+import { head, isEmpty, pathOr } from 'ramda';
+import { useForm } from 'react-hook-form';
+import 'quill/dist/quill.core.css';
+
+// store
+import { storeSet, useStore } from '../../store';
+
+// api
+import ApplicationService from '../../service/application-service';
+
+// tools
+import {
+ isPIVA,
+ isCodiceFiscale,
+ isCAP,
+ isIBAN,
+ isEmail,
+ isEmailPEC,
+ isUrl,
+ isMarcaDaBollo, minChecks, maxChecks, nonEmptyTables
+} from '../../helpers/validators';
+import renderHtmlContent from '../../helpers/renderHtmlContent';
+import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
+
+// components
+import { Skeleton } from 'primereact/skeleton';
+import { Button } from 'primereact/button';
+import FormField from '../../components/FormField';
+import { Toast } from 'primereact/toast';
+import { Messages } from 'primereact/messages';
+import ApplicationSteps from '../BandoApplication/ApplicationSteps';
+import BlockingOverlay from '../../components/BlockingOverlay';
+
+const BandoApplicationPreview = () => {
+ const { id } = useParams();
+ const [formData, setFormData] = useState([]);
+ const [formInitialData, setFormInitialData] = useState(null);
+ const [bandoTitle, setBandoTitle] = useState('');
+ const [bandoId, setBandoId] = useState(0);
+ const [formId, setFormId] = useState('');
+ const [totalSteps, setTotalSteps] = useState(0);
+ const [applicationStatus, setApplicationStatus] = useState('');
+ const [activeStep, setActiveStep] = useState(1);
+ const isAsyncRequest = useStore().main.isAsyncRequest();
+ const toast = useRef(null);
+ const formMsgs = useRef(null);
+ const {
+ control,
+ handleSubmit,
+ formState: { errors },
+ setValue,
+ trigger,
+ register,
+ getValues,
+ reset
+ } = useForm({
+ defaultValues: useMemo(() => {
+ return formInitialData ? formInitialData : {}
+ }, [formInitialData]),
+ mode: 'onChange'
+ });
+ const validationFns = {
+ isPIVA,
+ isCodiceFiscale,
+ isCAP,
+ isIBAN,
+ isEmail,
+ isEmailPEC,
+ isUrl,
+ isMarcaDaBollo,
+ minChecks,
+ maxChecks,
+ nonEmptyTables
+ }
+ const activeStepIndex = activeStep - 1;
+ const values = getValues();
+
+ const onValidate = () => {
+ const applId = getApplicationId();
+ storeSet.main.setAsyncRequest();
+ formMsgs.current.clear();
+
+ ApplicationService.validateApplication(applId, {}, validateApplicationCallback, errValidateApplicationCallback);
+ };
+
+ const onSubmit = () => {
+ };
+
+ const validateApplicationCallback = (data) => {
+ if (data.status === 'SUCCESS') {
+ toast.current.show({
+ severity: 'success',
+ summary: '',
+ detail: data.message
+ });
+ }
+ storeSet.main.unsetAsyncRequest();
+ }
+
+ const errValidateApplicationCallback = (data) => {
+ if (toast.current) {
+ toast.current.show({
+ severity: 'error',
+ summary: '',
+ detail: data.message
+ });
+ }
+ storeSet.main.unsetAsyncRequest();
+ }
+
+ const saveDraft = (saveAndMove = '') => {
+ trigger();
+ }
+
+ const getApplicationId = () => {
+ const parsed = parseInt(id)
+ return !isNaN(parsed) ? parsed : 0;
+ }
+
+ const goBackward = () => {
+ storeSet.main.setAsyncRequest();
+ ApplicationService.getApplicationForm(id, getApplFormCallback, errGetApplFormCallbacks, [
+ ['formId', formId],
+ ['action', 'PREVIOUS']
+ ]);
+ }
+
+ const goForward = () => {
+ storeSet.main.setAsyncRequest();
+ ApplicationService.getApplicationForm(id, getApplFormCallback, errGetApplFormCallbacks, [
+ ['formId', formId],
+ ['action', 'NEXT']
+ ]);
+ }
+
+ const getApplFormCallback = (data) => {
+ if (data.status === 'SUCCESS') {
+ setBandoTitle(data.data.callTitle);
+ setBandoId(data.data.callId);
+ setFormData(data.data.applicationFormResponse.content);
+ setFormId(data.data.formId);
+ setTotalSteps(data.data.totalFormSteps);
+ setApplicationStatus(data.data.applicationStatus)
+ setActiveStep(data.data.currentStep);
+
+ /*const chosenCompanyId = storeGet.main.chosenCompanyId();
+ const companies = storeGet.main.companies();
+ const company = head(companies.filter(o => o.id === chosenCompanyId));*/
+ let formDataInitial = {};
+ let dynamicData = {
+ company: {},
+ user: {}
+ };
+
+ /*if (company) {
+ dynamicData = Object.keys(company).reduce((acc, cur) => {
+ if ([
+ 'companyName', 'vatNumber', 'codiceFiscale', 'address', 'phoneNumber',
+ 'city', 'province', 'cap', 'country', 'pec', 'email', 'contactName', 'contactEmail'
+ ].includes(cur)) {
+ acc.company[cur] = company[cur];
+ }
+ return acc;
+ }, dynamicData);
+ }
+
+ const userData = storeGet.main.userData();
+ Object.keys(userData).reduce((acc, cur) => {
+ if ([
+ 'email', 'firstName', 'lastName', 'phoneNumber', 'codiceFiscale'
+ ].includes(cur)) {
+ acc.user[cur] = userData[cur];
+ }
+ if (['dateOfBirth'].includes(cur)) {
+ acc.user[cur] = new Date(userData[cur]);
+ }
+ return acc;
+ }, dynamicData);*/
+
+ if (data.data.applicationFormResponse.content) {
+ // eslint-disable-next-line array-callback-return
+ data.data.applicationFormResponse.content.map((o) => {
+ if (o.dynamicData && !isEmpty(o.dynamicData)) {
+ formDataInitial[o.id] = pathOr('', o.dynamicData.split('.'), dynamicData);
+ }
+ })
+ }
+
+ if (data.data.applicationFormResponse.formFields) {
+ const submitData = data.data.applicationFormResponse.formFields.map((o) => ({
+ fieldId: o.fieldId,
+ fieldValue: o.fieldValue
+ }));
+ formDataInitial = submitData.reduce((acc, cur) => {
+ if (cur.fieldValue) {
+ acc[cur.fieldId] = cur.fieldValue;
+ }
+ return acc;
+ }, formDataInitial);
+ }
+
+ reset();
+ setFormInitialData(formDataInitial);
+ }
+ storeSet.main.unsetAsyncRequest();
+ }
+
+ const errGetApplFormCallbacks = (data) => {
+ storeSet.main.unsetAsyncRequest();
+ if (data.status === 'VALIDATION_ERROR') {
+ if (toast.current) {
+ toast.current.show({
+ severity: 'error',
+ summary: '',
+ detail: data.message
+ });
+ }
+ } else {
+ set404FromErrorResponse(data);
+ }
+ }
+
+ const onDownloadApplicationPdf = () => {
+ const applId = getApplicationId();
+ storeSet.main.setAsyncRequest();
+
+ ApplicationService.downloadApplicationPdf(applId, {}, getPdfCallback, errPdfCallback);
+ }
+
+ const getPdfCallback = (data) => {
+ const applId = getApplicationId();
+ const pdfFile = new Blob([data], { type: 'application/octet-stream' })
+ const url = window.URL.createObjectURL(pdfFile);
+ const link = document.createElement('a');
+ link.href = url;
+ link.setAttribute('download', `application-${applId}.pdf`);
+ document.body.appendChild(link);
+ link.click();
+ link.remove();
+ storeSet.main.unsetAsyncRequest();
+ }
+
+ const errPdfCallback = (data) => {
+ set404FromErrorResponse(data);
+ storeSet.main.unsetAsyncRequest();
+ }
+
+ const actionBtns =
+ {activeStep > 1 && activeStep <= totalSteps
+ ? : null}
+
+ {activeStep < totalSteps
+ ? : null}
+ {/* */}
+
+
+
+ useEffect(() => {
+ if (formInitialData) {
+ //reset();
+ Object.keys(formInitialData).map(k => setValue(k, formInitialData[k]));
+ trigger();
+ }
+ }, [formInitialData]);
+
+ useEffect(() => {
+ const applId = getApplicationId();
+
+ if (applId) {
+ storeSet.main.setAsyncRequest();
+ ApplicationService.getApplicationForm(applId, getApplFormCallback, errGetApplFormCallbacks);
+ }
+ }, [id]);
+
+ return (
+
+ {!isAsyncRequest
+ ?
+
{sprintf(__('Domanda per il Bando: %s', 'gepafin'), bandoTitle)}
+
+ : <>
+
+
+ >}
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+
+}
+
+export default BandoApplicationPreview;
\ No newline at end of file
diff --git a/src/pages/Dashboard/components/DraftApplicationsTable/index.js b/src/pages/Dashboard/components/DraftApplicationsTable/index.js
new file mode 100644
index 0000000..63518ff
--- /dev/null
+++ b/src/pages/Dashboard/components/DraftApplicationsTable/index.js
@@ -0,0 +1,199 @@
+import React, { useState, useEffect } from 'react';
+import { __ } from '@wordpress/i18n';
+import { uniq, is } from 'ramda';
+
+// tools
+import getBandoLabel from '../../../../helpers/getBandoLabel';
+import getBandoSeverity from '../../../../helpers/getBandoSeverity';
+
+// store
+import { useStore } from '../../../../store';
+
+// api
+import ApplicationService from '../../../../service/application-service';
+
+// components
+import { FilterMatchMode, FilterOperator } from 'primereact/api';
+import { DataTable } from 'primereact/datatable';
+import { Column } from 'primereact/column';
+import { InputText } from 'primereact/inputtext';
+import { IconField } from 'primereact/iconfield';
+import { InputIcon } from 'primereact/inputicon';
+import { Dropdown } from 'primereact/dropdown';
+import { ProgressBar } from 'primereact/progressbar';
+import { Button } from 'primereact/button';
+//import { Calendar } from 'primereact/calendar';
+import { Tag } from 'primereact/tag';
+import ProperBandoLabel from '../../../../components/ProperBandoLabel';
+import { Link } from 'react-router-dom';
+
+const DraftApplicationsTable = () => {
+ const chosenCompanyId = useStore().main.chosenCompanyId();
+ const [localAsyncRequest, setLocalAsyncRequest] = useState(false);
+ const [items, setItems] = useState(null);
+ const [filters, setFilters] = useState(null);
+ const [globalFilterValue, setGlobalFilterValue] = useState('');
+ const [statuses, setStatuses] = useState([]);
+
+ useEffect(() => {
+ setLocalAsyncRequest(true);
+ ApplicationService.getApplications(getApplCallback, errGetApplCallback, [
+ ['statuses', ['DRAFT', 'AWAITING', 'READY']]
+ ])
+ }, [chosenCompanyId]);
+
+ const getApplCallback = (data) => {
+ if (data.status === 'SUCCESS') {
+ if (is(Array, data.data)) {
+ setItems(getFormattedBandiData(data.data));
+ setStatuses(uniq(items.map(o => o.status)))
+ initFilters();
+ }
+ }
+ setLocalAsyncRequest(false);
+ }
+
+ const errGetApplCallback = (data) => {
+ setLocalAsyncRequest(false);
+ }
+
+ const getFormattedBandiData = (data) => {
+ return [...(data || [])].map((d) => {
+ d.callEndDate = new Date(d.callEndDate);
+ d.modifiedDate = new Date(d.modifiedDate);
+
+ return d;
+ });
+ };
+
+ /*const formatDate = (value) => {
+ return value.toLocaleDateString('it-IT', {
+ day: '2-digit',
+ month: '2-digit',
+ year: 'numeric'
+ });
+ };*/
+
+ const clearFilter = () => {
+ initFilters();
+ };
+
+ const onGlobalFilterChange = (e) => {
+ const value = e.target.value;
+ let _filters = { ...filters };
+
+ _filters['global'].value = value;
+
+ setFilters(_filters);
+ setGlobalFilterValue(value);
+ };
+
+ const initFilters = () => {
+ setFilters({
+ global: { value: null, matchMode: FilterMatchMode.CONTAINS },
+ callTitle: {
+ operator: FilterOperator.AND,
+ constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }]
+ },
+ modifiedDate: {
+ operator: FilterOperator.AND,
+ constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }]
+ },
+ callEndDate: {
+ operator: FilterOperator.AND,
+ constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }]
+ },
+ status: { operator: FilterOperator.OR, constraints: [{ value: null, matchMode: FilterMatchMode.EQUALS }] },
+ });
+ setGlobalFilterValue('');
+ };
+
+ const renderHeader = () => {
+ return (
+
+
+
+
+
+
+
+ );
+ };
+
+ /*const dateModifyBodyTemplate = (rowData) => {
+ return formatDate(rowData.modifiedDate);
+ };
+
+ const dateEndBodyTemplate = (rowData) => {
+ return formatDate(rowData.callEndDate);
+ };
+
+ const dateFilterTemplate = (options) => {
+ return
options.filterCallback(e.value, options.index)}
+ dateFormat="mm/dd/yy" placeholder="mm/dd/yyyy" mask="99/99/9999"/>;
+ };*/
+
+ const statusBodyTemplate = (rowData) => {
+ return ;
+ };
+
+ const statusFilterTemplate = (options) => {
+ return options.filterCallback(e.value, options.index)}
+ itemTemplate={statusItemTemplate} placeholder="Select One" className="p-column-filter"
+ showClear/>;
+ };
+
+ const progressBodyTemplate = (options) => {
+ return ;
+ };
+
+ const statusItemTemplate = (option) => {
+ return ;
+ };
+
+ const actionsBodyTemplate = (rowData) => {
+ return
+
+
+ }
+
+ const header = renderHeader();
+
+ return (
+
+ setFilters(e.filters)}>
+
+
+ {/*
+ */}
+
+
+
+
+
+ )
+}
+
+export default DraftApplicationsTable;
\ No newline at end of file
diff --git a/src/pages/Dashboard/index.js b/src/pages/Dashboard/index.js
index da701f6..71334b0 100644
--- a/src/pages/Dashboard/index.js
+++ b/src/pages/Dashboard/index.js
@@ -16,6 +16,7 @@ import LatestBandiTable from './components/LatestBandiTable';
import { Button } from 'primereact/button';
//import MyEvaluationsTable from '../DashboardPreInstructor/components/PreInstructorDomandeTable';
import AllDomandeTable from '../Domande/components/AllDomandeTable';
+import DraftApplicationsTable from './components/DraftApplicationsTable';
const Dashboard = () => {
const navigate = useNavigate();
@@ -69,35 +70,35 @@ const Dashboard = () => {
+ locales="it-IT"/>