- updated users table;
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
"@babel/preset-react": "7.24.7",
|
||||
"@date-fns/tz": "1.1.2",
|
||||
"@emotion/styled": "11.13.0",
|
||||
"@number-flow/react": "^0.2.0",
|
||||
"@tanstack/react-table": "^8.20.5",
|
||||
"@wordpress/i18n": "5.8.0",
|
||||
"@wordpress/react-i18n": "4.8.0",
|
||||
|
||||
@@ -157,6 +157,18 @@
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
&.columns {
|
||||
gap: 2em;
|
||||
column-count: 2;
|
||||
column-width: 4em;
|
||||
display: block;
|
||||
padding-bottom: 0;
|
||||
|
||||
.appPageSection__pMeta {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@container section_with_border (max-width: 600px) {
|
||||
@@ -212,6 +224,10 @@
|
||||
font-weight: 600;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
span:nth-of-type(2) {
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
|
||||
.appPageSection__table {
|
||||
|
||||
@@ -12,7 +12,7 @@ body {
|
||||
margin: 0;
|
||||
font-family: "Montserrat", sans-serif;
|
||||
|
||||
p, span:not(.p-button-label, .p-button-icon, .p-badge, .p-message-detail, .p-highlight, .p-inline-message-text),
|
||||
p, span:not(.p-button-label, .p-button-icon, .p-badge, .p-message-detail, .p-highlight, .p-inline-message-text, .p-tag, .p-tag-icon),
|
||||
input, label:not(.p-error), textarea, a, li, h1, h2, h3, h4, h5, h6, div:not(.p-inline-message, .p-toast-detail), th, td {
|
||||
color: var(--global-textColor);
|
||||
}
|
||||
|
||||
39
src/assets/scss/components/myTable.scss
Normal file
39
src/assets/scss/components/myTable.scss
Normal file
@@ -0,0 +1,39 @@
|
||||
.myTable {
|
||||
border-spacing: 0px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.myThead {
|
||||
th {
|
||||
text-align: left;
|
||||
padding: 1rem 1rem;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-width: 0 0 1px 0;
|
||||
font-weight: 700;
|
||||
color: #374151;
|
||||
background: #f9fafb;
|
||||
transition: box-shadow 0.2s;
|
||||
}
|
||||
}
|
||||
|
||||
.myTbody {
|
||||
td {
|
||||
text-align: left;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-width: 0 0 1px 0;
|
||||
padding: 1rem 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.myTfoot {
|
||||
td {
|
||||
text-align: left;
|
||||
padding: 1rem 1rem;
|
||||
border: 1px solid #e5e7eb;
|
||||
border-width: 0 0 1px 0;
|
||||
font-weight: 700;
|
||||
color: #374151;
|
||||
background: #f9fafb;
|
||||
transition: box-shadow 0.2s;
|
||||
}
|
||||
}
|
||||
@@ -41,3 +41,4 @@
|
||||
@import "./components/login.scss";
|
||||
@import "./components/flowBuilder.scss";
|
||||
@import "./components/error404.scss";
|
||||
@import "./components/myTable.scss";
|
||||
@@ -55,7 +55,7 @@ const TopBarProfileMenu = ({ menuLeftRef }) => {
|
||||
command: () => {
|
||||
navigate('/profilo-aziendale')
|
||||
},
|
||||
enable: !intersection(permissions, ['MANAGE_TENDERS']).length && companies.length > 0
|
||||
enable: intersection(permissions, ['APPLY_CALLS']).length && companies.length > 0
|
||||
},
|
||||
{
|
||||
label: __('Seleziona azienda', 'gepafin'),
|
||||
@@ -67,7 +67,7 @@ const TopBarProfileMenu = ({ menuLeftRef }) => {
|
||||
command: () => {
|
||||
navigate('/agguingi-azienda')
|
||||
},
|
||||
enable: !intersection(permissions, ['MANAGE_TENDERS']).length
|
||||
enable: intersection(permissions, ['APPLY_CALLS']).length
|
||||
},
|
||||
{
|
||||
separator: true,
|
||||
|
||||
@@ -2,6 +2,9 @@ import { __ } from '@wordpress/i18n';
|
||||
|
||||
const getBandoLabel = (status) => {
|
||||
switch (status) {
|
||||
case 'ACTIVE':
|
||||
return __('Attivo', 'gepafin');
|
||||
|
||||
case 'SUBMIT':
|
||||
return __('Inviato', 'gepafin');
|
||||
|
||||
@@ -17,6 +20,9 @@ const getBandoLabel = (status) => {
|
||||
case 'DRAFT':
|
||||
return __('Bozza', 'gepafin');
|
||||
|
||||
case 'AWAITING':
|
||||
return __('In attesa', 'gepafin');
|
||||
|
||||
case 'EXPIRED':
|
||||
return __('Scaduto', 'gepafin');
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@ import { __ } from '@wordpress/i18n';
|
||||
|
||||
const getBandoSeverity = (status) => {
|
||||
switch (status) {
|
||||
case 'ACTIVE':
|
||||
return 'success';
|
||||
|
||||
case 'SUBMIT':
|
||||
return 'success';
|
||||
|
||||
@@ -17,6 +20,9 @@ const getBandoSeverity = (status) => {
|
||||
case 'DRAFT':
|
||||
return 'warning';
|
||||
|
||||
case 'AWAITING':
|
||||
return 'warning';
|
||||
|
||||
case 'EXPIRED':
|
||||
return 'closed';
|
||||
|
||||
|
||||
@@ -40,6 +40,13 @@ const AppSidebar = () => {
|
||||
id: 4,
|
||||
enable: intersection(permissions, ['VIEW_CALLS']).length
|
||||
},
|
||||
{
|
||||
label: __('Domande da valutare', 'gepafin'),
|
||||
icon: 'pi pi-calendar-clock',
|
||||
href: '/valutazioni',
|
||||
id: 4,
|
||||
enable: intersection(permissions, ['EVALUATE_APPLICATIONS']).length
|
||||
},
|
||||
{
|
||||
label: __('Gestione Utenti', 'gepafin'),
|
||||
icon: 'pi pi-users',
|
||||
|
||||
@@ -27,9 +27,10 @@ const AppTopbar = () => {
|
||||
<i className="pi pi-bell p-overlay-badge topBar__icon">
|
||||
<Badge value="0"></Badge>
|
||||
</i>
|
||||
<i className="pi pi-envelope p-overlay-badge topBar__icon">
|
||||
<i className="pi pi-envelope topBar__icon"></i>
|
||||
{/*<i className="pi pi-envelope p-overlay-badge topBar__icon">
|
||||
<Badge severity="danger"></Badge>
|
||||
</i>
|
||||
</i>*/}
|
||||
<Button
|
||||
className="topBar__profileBtn"
|
||||
outlined
|
||||
|
||||
@@ -31,12 +31,12 @@ import { Link } from 'react-router-dom';
|
||||
const AllBandiTable = () => {
|
||||
const [items, setItems] = useState(null);
|
||||
const [filters, setFilters] = useState(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [localAsyncRequest, setLocalAsyncRequest] = useState(false);
|
||||
const [globalFilterValue, setGlobalFilterValue] = useState('');
|
||||
const [statuses, setStatuses] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
storeSet.main.setAsyncRequest();
|
||||
setLocalAsyncRequest(true);
|
||||
BandoService.getBandi(getCallback, errGetCallbacks);
|
||||
}, []);
|
||||
|
||||
@@ -46,12 +46,11 @@ const AllBandiTable = () => {
|
||||
setStatuses(uniq(data.data.map(o => o.status)))
|
||||
initFilters();
|
||||
}
|
||||
storeSet.main.unsetAsyncRequest();
|
||||
setLocalAsyncRequest(false);
|
||||
}
|
||||
|
||||
const errGetCallbacks = (data) => {
|
||||
console.log('errGetCallbacks', data)
|
||||
storeSet.main.unsetAsyncRequest();
|
||||
setLocalAsyncRequest(false);
|
||||
}
|
||||
|
||||
const getFormattedBandiData = (data) => {
|
||||
@@ -136,7 +135,7 @@ const AllBandiTable = () => {
|
||||
|
||||
return(
|
||||
<div className="appPageSection__table">
|
||||
<DataTable value={items} paginator showGridlines rows={10} loading={loading} dataKey="id"
|
||||
<DataTable value={items} paginator showGridlines rows={10} loading={localAsyncRequest} dataKey="id"
|
||||
filters={filters}
|
||||
globalFilterFields={['name', 'status']}
|
||||
header={header}
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react';
|
||||
import { head, isEmpty, isNil } from 'ramda';
|
||||
import { __, sprintf } from '@wordpress/i18n';
|
||||
import { klona } from 'klona';
|
||||
import { wrap } from 'object-path-immutable';
|
||||
|
||||
// store
|
||||
import { storeSet, useStore } from '../../../../store';
|
||||
@@ -14,13 +15,17 @@ import { TabView, TabPanel } from 'primereact/tabview';
|
||||
import { InputSwitch } from 'primereact/inputswitch';
|
||||
import ElementSetting from './components/ElementSetting';
|
||||
import { Dropdown } from 'primereact/dropdown';
|
||||
import { MultiSelect } from 'primereact/multiselect';
|
||||
|
||||
const BuilderElementSettings = ({ closeSettings }) => {
|
||||
const BuilderElementSettings = ({ closeSettingsFn }) => {
|
||||
const elements = useStore().main.formElements();
|
||||
const activeElement = useStore().main.activeElement();
|
||||
const criteriaOptions = useStore().main.bandoCriteria();
|
||||
const [activeElementData, setActiveElementData] = useState({});
|
||||
const [settings, setSettings] = useState([]);
|
||||
const [validators, setValidators] = useState({});
|
||||
const [dynamicData, setDynamicData] = useState('');
|
||||
const [criteria, setCriteria] = useState([]);
|
||||
const textBasedValidatorFields = ['min', 'max', 'minLength', 'maxLength', 'pattern'];
|
||||
const customValidationOptions = [
|
||||
{ value: 'isPIVA', label: 'isPIVA' },
|
||||
@@ -63,11 +68,14 @@ const BuilderElementSettings = ({ closeSettings }) => {
|
||||
}
|
||||
|
||||
const saveSettings = () => {
|
||||
activeElementData.settings = settings;
|
||||
activeElementData.validators = validators;
|
||||
const newElements = elements.map(o => o.id === activeElementData.id ? activeElementData : o);
|
||||
let newActiveElementData = klona(activeElementData);
|
||||
newActiveElementData = wrap(newActiveElementData).set(['settings'], settings).value();
|
||||
newActiveElementData = wrap(newActiveElementData).set(['validators'], validators).value();
|
||||
newActiveElementData = wrap(newActiveElementData).set(['dynamicData'], dynamicData).value();
|
||||
newActiveElementData = wrap(newActiveElementData).set(['criteria'], criteria).value();
|
||||
const newElements = elements.map(o => o.id === newActiveElementData.id ? newActiveElementData : o);
|
||||
storeSet.main.formElements(newElements);
|
||||
closeSettings();
|
||||
closeSettingsFn();
|
||||
}
|
||||
|
||||
const showField = (value, key) => {
|
||||
@@ -92,17 +100,56 @@ const BuilderElementSettings = ({ closeSettings }) => {
|
||||
setValidators(newValidators);
|
||||
}
|
||||
|
||||
const onChangeCriteriaData = (value) => {
|
||||
setCriteria(value);
|
||||
}
|
||||
|
||||
|
||||
const getDynamicDataOptions = (type) => {
|
||||
switch (type) {
|
||||
case 'datepicker' :
|
||||
return [
|
||||
{ label: 'user dateOfBirth', value: 'user.dateOfBirth' }
|
||||
]
|
||||
default :
|
||||
return [
|
||||
{ label: 'company name', value: 'company.companyName' },
|
||||
{ label: 'company piva', value: 'company.vatNumber' },
|
||||
{ label: 'company codiceFiscale', value: 'company.codiceFiscale' },
|
||||
{ label: 'company address', value: 'company.address' },
|
||||
{ label: 'company phoneNumber', value: 'company.phoneNumber' },
|
||||
{ label: 'company city', value: 'company.city' },
|
||||
{ label: 'company province', value: 'company.province' },
|
||||
{ label: 'company cap', value: 'company.cap' },
|
||||
{ label: 'company country', value: 'company.country' },
|
||||
{ label: 'company pec', value: 'company.pec' },
|
||||
{ label: 'company email', value: 'company.email' },
|
||||
{ label: 'company contactName', value: 'company.contactName' },
|
||||
{ label: 'company contactEmail', value: 'company.contactEmail' },
|
||||
{ label: 'user email', value: 'user.email' },
|
||||
{ label: 'user firstName', value: 'user.firstName' },
|
||||
{ label: 'user lastName', value: 'user.lastName' },
|
||||
{ label: 'user phoneNumber', value: 'user.phoneNumber' },
|
||||
{ label: 'user codiceFiscale', value: 'user.codiceFiscale' }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const chosen = head(elements.filter(o => o.id === activeElement));
|
||||
|
||||
if (chosen) {
|
||||
setActiveElementData(klona(chosen));
|
||||
setSettings(klona(chosen.settings));
|
||||
setValidators(klona(chosen.validators))
|
||||
setValidators(klona(chosen.validators));
|
||||
setDynamicData(chosen.dynamicData ? chosen.dynamicData : '');
|
||||
setCriteria(chosen.criteria ? chosen.criteria : []);
|
||||
} else {
|
||||
setActiveElementData({});
|
||||
setSettings([]);
|
||||
setValidators({})
|
||||
setValidators({});
|
||||
setDynamicData('');
|
||||
setCriteria([]);
|
||||
}
|
||||
}, [activeElement]);
|
||||
|
||||
@@ -118,6 +165,18 @@ const BuilderElementSettings = ({ closeSettings }) => {
|
||||
changeFn={onChange}
|
||||
updateDataFn={onUpdateOptions}/>)
|
||||
: null}
|
||||
{['textinput', 'datepicker'].includes(activeElementData.name)
|
||||
? <div className="formElementSettings__field">
|
||||
<label htmlFor="dynamicData">{__('Dati dinamici', 'gepafin')}</label>
|
||||
<Dropdown
|
||||
id="dynamicData"
|
||||
value={dynamicData}
|
||||
onChange={(e) => setDynamicData(e.value)}
|
||||
options={getDynamicDataOptions(activeElementData.name)}
|
||||
optionLabel="label"
|
||||
optionValue="value"
|
||||
placeholder={__('Scegli', 'gepafin')}/>
|
||||
</div> : null}
|
||||
</TabPanel>
|
||||
{!isEmpty(validators)
|
||||
? <TabPanel header={__('Validation', 'gepafin')}>
|
||||
@@ -162,6 +221,20 @@ const BuilderElementSettings = ({ closeSettings }) => {
|
||||
</div> : null}
|
||||
</div>) : null}
|
||||
</TabPanel> : null}
|
||||
<TabPanel header={__('Criteri', 'gepafin')}>
|
||||
<div className="formElementSettings__field">
|
||||
<label htmlFor="criteria">{__('Criteri di valutazione', 'gepafin')}</label>
|
||||
<MultiSelect
|
||||
id="criteria"
|
||||
value={criteria}
|
||||
onChange={(e) => onChangeCriteriaData(e.value)}
|
||||
options={criteriaOptions}
|
||||
optionLabel="label"
|
||||
optionValue="value"
|
||||
display="chip"
|
||||
placeholder={__('Scegli', 'gepafin')}/>
|
||||
</div>
|
||||
</TabPanel>
|
||||
</TabView>
|
||||
|
||||
<Button label={__('Salva', 'gepafin')} onClick={saveSettings}/>
|
||||
|
||||
@@ -57,7 +57,7 @@ const FormBuilder = () => {
|
||||
<>
|
||||
<Sidebar visible={!isEmpty(activeElement)} onHide={closeSettings} className="formBuilder__elementSettings">
|
||||
<h2>{__('Impostazioni del campo modulo', 'gepafin')}</h2>
|
||||
{!isEmpty(activeElement) ? <BuilderElementSettings closeSettings={closeSettings}/> : null}
|
||||
{!isEmpty(activeElement) ? <BuilderElementSettings closeSettingsFn={closeSettings}/> : null}
|
||||
</Sidebar>
|
||||
<div className="formBuilder">
|
||||
<div className="formBuilder__main">
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { DndProvider } from 'react-dnd';
|
||||
import { HTML5Backend } from 'react-dnd-html5-backend';
|
||||
import { klona } from 'klona';
|
||||
import { isEmpty } from 'ramda';
|
||||
import { isEmpty, pathOr } from 'ramda';
|
||||
|
||||
// store
|
||||
import { storeSet, storeGet, useStore } from '../../store';
|
||||
@@ -21,6 +21,7 @@ import { Messages } from 'primereact/messages';
|
||||
// api
|
||||
import FormsService from '../../service/forms-service';
|
||||
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||
import BandoService from '../../service/bando-service';
|
||||
|
||||
// TODO temp data
|
||||
//import { elementItems } from '../../tempData';
|
||||
@@ -243,7 +244,20 @@ const BandoFormsEdit = () => {
|
||||
storeSet.main.unsetAsyncRequest();
|
||||
}
|
||||
|
||||
const getBandoCallback = (data) => {
|
||||
if (data.status === 'SUCCESS') {
|
||||
const criteria = pathOr([], ['data', 'criteria'], data);
|
||||
const criteriaOptions = criteria.map(o => ({value: o.id, label: o.value}));
|
||||
storeSet.main.bandoCriteria(criteriaOptions);
|
||||
}
|
||||
}
|
||||
|
||||
const errGetBandoCallback = (data) => {
|
||||
set404FromErrorResponse(data);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const bandoId = getBandoId();
|
||||
const parsedFormId = parseInt(formId)
|
||||
const bandoFormId = !isNaN(parsedFormId) ? parsedFormId : 0;
|
||||
|
||||
@@ -253,12 +267,14 @@ const BandoFormsEdit = () => {
|
||||
if (bandoFormId) {
|
||||
storeSet.main.setAsyncRequest();
|
||||
FormsService.getFormById(bandoFormId, getFormCallback, errGetFormCallbacks);
|
||||
BandoService.getBando(bandoId, getBandoCallback, errGetBandoCallback);
|
||||
}
|
||||
|
||||
return () => {
|
||||
storeSet.main.formId(0);
|
||||
storeSet.main.formLabel('');
|
||||
storeSet.main.formElements([]);
|
||||
storeSet.main.bandoCriteria([]);
|
||||
}
|
||||
}, [id, formId]);
|
||||
|
||||
|
||||
@@ -31,44 +31,12 @@ import { Link } from 'react-router-dom';
|
||||
const LatestBandiTable = () => {
|
||||
const [items, setItems] = useState(null);
|
||||
const [filters, setFilters] = useState(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [localAsyncRequest, setLocalAsyncRequest] = useState(false);
|
||||
const [globalFilterValue, setGlobalFilterValue] = useState('');
|
||||
const [statuses, setStatuses] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
// TODO
|
||||
/*const items = [
|
||||
{
|
||||
name: 'Bando Innovazione 2024',
|
||||
start_date: '2024-08-08T00:00:00+00:00',
|
||||
end_date: '2024-08-30T00:00:00+00:00',
|
||||
submissions: 24,
|
||||
status: 'PUBLISH',
|
||||
id: 11
|
||||
},
|
||||
{
|
||||
name: 'Bando Sostenibilità 2024',
|
||||
start_date: '2024-07-28T00:00:00+00:00',
|
||||
end_date: '2024-08-15T00:00:00+00:00',
|
||||
submissions: 35,
|
||||
status: 'PUBLISH',
|
||||
id: 9
|
||||
},
|
||||
{
|
||||
name: 'Bando A',
|
||||
start_date: '2024-06-28T00:00:00+00:00',
|
||||
end_date: '2024-06-15T00:00:00+00:00',
|
||||
submissions: 2,
|
||||
status: 'EXPIRED',
|
||||
id: 2
|
||||
}
|
||||
]
|
||||
setItems(getFormattedBandiData(items));
|
||||
setStatuses(uniq(items.map(o => o.status)))
|
||||
setLoading(false);
|
||||
initFilters();*/
|
||||
|
||||
storeSet.main.setAsyncRequest();
|
||||
setLocalAsyncRequest(true);
|
||||
BandoService.getBandi(getCallback, errGetCallbacks);
|
||||
}, []);
|
||||
|
||||
@@ -79,12 +47,11 @@ const LatestBandiTable = () => {
|
||||
setStatuses(uniq(data.data.map(o => o.status)))
|
||||
initFilters();
|
||||
}
|
||||
storeSet.main.unsetAsyncRequest();
|
||||
setLocalAsyncRequest(false);
|
||||
}
|
||||
|
||||
const errGetCallbacks = (data) => {
|
||||
console.log('errGetCallbacks', data)
|
||||
storeSet.main.unsetAsyncRequest();
|
||||
setLocalAsyncRequest(false);
|
||||
}
|
||||
|
||||
const getFormattedBandiData = (data) => {
|
||||
@@ -179,13 +146,13 @@ const LatestBandiTable = () => {
|
||||
|
||||
return(
|
||||
<div className="appPageSection__table">
|
||||
<DataTable value={items} paginator showGridlines rows={10} loading={loading} dataKey="id"
|
||||
<DataTable value={items} paginator showGridlines rows={10} loading={localAsyncRequest} dataKey="id"
|
||||
filters={filters}
|
||||
globalFilterFields={['name', 'status']}
|
||||
header={header}
|
||||
emptyMessage={__('Nessun dato disponibile', 'gepafin')}
|
||||
onFilter={(e) => setFilters(e.filters)}>
|
||||
<Column field="name" header={__('Nome Bando', 'gepafin')} filter filterPlaceholder="Search by name"
|
||||
<Column field="name" header={__('Nome Bando', 'gepafin')} filter filterPlaceholder={__('Cerca il nome', 'gepafin')}
|
||||
style={{ minWidth: '12rem' }}/>
|
||||
<Column header={__('Data Pubblicazione', 'gepafin')} filterField="start_date" dataType="date"
|
||||
style={{ minWidth: '10rem' }}
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { pathOr } from 'ramda';
|
||||
import NumberFlow from '@number-flow/react';
|
||||
|
||||
// store
|
||||
//import { storeSet } from '../../store';
|
||||
@@ -13,6 +14,7 @@ import DashboardService from '../../service/dashboard-service';
|
||||
import LatestBandiTable from './components/LatestBandiTable';
|
||||
//import LatestUsersActivityTable from './components/LatestUsersActivityTable';
|
||||
import { Button } from 'primereact/button';
|
||||
import MyEvaluationsTable from '../DashboardInstructor/components/MyEvaluationsTable';
|
||||
|
||||
const Dashboard = () => {
|
||||
const navigate = useNavigate();
|
||||
@@ -67,27 +69,52 @@ const Dashboard = () => {
|
||||
<div className="statsBigBadges__grid">
|
||||
<div className="statsBigBadges__gridItem">
|
||||
<span>{__('Bandi attivi', 'gepafin')}</span>
|
||||
<span>{getStatValue('numberOfActiveCalls', 0)}</span>
|
||||
<span><NumberFlow
|
||||
value={getStatValue('numberOfActiveCalls', 0)}
|
||||
format={{ notation: 'compact' }}
|
||||
locales="it-IT" /></span>
|
||||
</div>
|
||||
<div className="statsBigBadges__gridItem">
|
||||
<span>{__('Utenti registrati', 'gepafin')}</span>
|
||||
<span>{getStatValue('numberOfResgisteredUsers', 0)}</span>
|
||||
<span><NumberFlow
|
||||
value={getStatValue('numberOfResgisteredUsers', 0)}
|
||||
format={{ notation: 'compact' }}
|
||||
locales="it-IT" /></span>
|
||||
</div>
|
||||
<div className="statsBigBadges__gridItem">
|
||||
<span>{__('Domande in pre-istruttoria', 'gepafin')}</span>
|
||||
<span>{getStatValue('numberOfSubmittedApplications', 0)}</span>
|
||||
<span><NumberFlow
|
||||
value={getStatValue('numberOfSubmittedApplications', 0)}
|
||||
format={{ notation: 'compact' }}
|
||||
locales="it-IT" /></span>
|
||||
</div>
|
||||
<div className="statsBigBadges__gridItem">
|
||||
<span>{__('Domande in bozza', 'gepafin')}</span>
|
||||
<span>{getStatValue('numberOfDraftApplications', 0)}</span>
|
||||
<span><NumberFlow
|
||||
value={getStatValue('numberOfDraftApplications', 0)}
|
||||
format={{ notation: 'compact' }}
|
||||
locales="it-IT" /></span>
|
||||
</div>
|
||||
<div className="statsBigBadges__gridItem">
|
||||
<span>{__('Aziende', 'gepafin')}</span>
|
||||
<span>{getStatValue('numberOfCompany', 0)}</span>
|
||||
<span><NumberFlow
|
||||
value={getStatValue('numberOfCompany', 0)}
|
||||
format={{ notation: 'compact' }}
|
||||
locales="it-IT" /></span>
|
||||
</div>
|
||||
<div className="statsBigBadges__gridItem">
|
||||
<span>{__('Totale finanziamenti attivi', 'gepafin')}</span>
|
||||
<span>€{formatToMillions(getStatValue('totalActiveFinancing', 0))}</span>
|
||||
<span><NumberFlow
|
||||
value={getStatValue('totalActiveFinancing', 0)}
|
||||
format={{
|
||||
notation: 'compact',
|
||||
compactDisplay: 'short',
|
||||
roundingMode: 'trunc',
|
||||
style: 'currency',
|
||||
currency: 'EUR',
|
||||
currencyDisplay: 'symbol'
|
||||
}}
|
||||
locales="en-US" /></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -95,10 +122,17 @@ const Dashboard = () => {
|
||||
<div className="appPage__spacer"></div>
|
||||
|
||||
<div className="appPageSection">
|
||||
<h2>{__('Ultimi Bandi Pubblicati', 'gepafin')}</h2>
|
||||
<h2>{__('Ultimi bandi pubblicati', 'gepafin')}</h2>
|
||||
<LatestBandiTable/>
|
||||
</div>
|
||||
|
||||
<div className="appPage__spacer"></div>
|
||||
|
||||
<div className="appPageSection">
|
||||
<h2>{__('Ultime domande pubblicate', 'gepafin')}</h2>
|
||||
<MyEvaluationsTable/>
|
||||
</div>
|
||||
|
||||
{/*<div className="appPage__spacer"></div>
|
||||
|
||||
<div className="appPageSection">
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useState, useEffect} from 'react';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { uniq } from 'ramda';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
// tools
|
||||
import getBandoLabel from '../../../../helpers/getBandoLabel';
|
||||
@@ -25,7 +26,6 @@ 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 LatestBandiTable = () => {
|
||||
@@ -43,7 +43,7 @@ const LatestBandiTable = () => {
|
||||
const getCallback = (data) => {
|
||||
if (data.status === 'SUCCESS') {
|
||||
const newItems = data.data.filter(o => o.status === 'PUBLISH');
|
||||
setItems(getFormattedBandiData(newItems));
|
||||
setItems(getFormattedData(newItems));
|
||||
setStatuses(uniq(data.data.map(o => o.status)))
|
||||
initFilters();
|
||||
}
|
||||
@@ -55,7 +55,7 @@ const LatestBandiTable = () => {
|
||||
storeSet.main.unsetAsyncRequest();
|
||||
}
|
||||
|
||||
const getFormattedBandiData = (data) => {
|
||||
const getFormattedData = (data) => {
|
||||
return [...(data || [])].map((d) => {
|
||||
d.start_date = new Date(d.dates[0]);
|
||||
d.end_date = new Date(d.dates[1]);
|
||||
@@ -121,18 +121,10 @@ const LatestBandiTable = () => {
|
||||
return <Calendar value={options.value} onChange={(e) => options.filterCallback(e.value, options.index)} dateFormat="mm/dd/yy" placeholder="mm/dd/yyyy" mask="99/99/9999" />;
|
||||
};
|
||||
|
||||
const balanceFilterTemplate = (options) => {
|
||||
return <InputNumber value={options.value} onChange={(e) => options.filterCallback(e.value, options.index)} />;
|
||||
};
|
||||
|
||||
const statusBodyTemplate = (rowData) => {
|
||||
return <ProperBandoLabel status={rowData.status}/>;
|
||||
};
|
||||
|
||||
const statusFilterTemplate = (options) => {
|
||||
return <Dropdown value={options.value} options={statuses} onChange={(e) => options.filterCallback(e.value, options.index)} itemTemplate={statusItemTemplate} placeholder="Select One" className="p-column-filter" showClear />;
|
||||
};
|
||||
|
||||
const statusItemTemplate = (option) => {
|
||||
return <Tag value={getBandoLabel(option)} severity={getBandoSeverity(option)} />;
|
||||
};
|
||||
@@ -153,7 +145,7 @@ const LatestBandiTable = () => {
|
||||
header={header}
|
||||
emptyMessage={__('Nessun dato disponibile', 'gepafin')}
|
||||
onFilter={(e) => setFilters(e.filters)}>
|
||||
<Column field="name" header={__('Nome Bando', 'gepafin')} filter filterPlaceholder="Search by name"
|
||||
<Column field="name" header={__('Nome Bando', 'gepafin')} filter filterPlaceholder={__('Cerca il nome', 'gepafin')}
|
||||
style={{ minWidth: '12rem' }}/>
|
||||
<Column header={__('Data Pubblicazione', 'gepafin')} filterField="start_date" dataType="date"
|
||||
style={{ minWidth: '10rem' }}
|
||||
|
||||
@@ -26,14 +26,14 @@ import set404FromErrorResponse from '../../../../helpers/set404FromErrorResponse
|
||||
|
||||
|
||||
const MyLatestSubmissionsTable = () => {
|
||||
const isAsyncRequest = useStore().main.isAsyncRequest();
|
||||
const [localAsyncRequest, setLocalAsyncRequest] = useState(false);
|
||||
const [items, setItems] = useState(null);
|
||||
const [filters, setFilters] = useState(null);
|
||||
const [globalFilterValue, setGlobalFilterValue] = useState('');
|
||||
const [statuses, setStatuses] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
storeSet.main.setAsyncRequest();
|
||||
setLocalAsyncRequest(true);
|
||||
ApplicationService.getApplications(getApplCallback, errGetApplCallback)
|
||||
}, []);
|
||||
|
||||
@@ -45,12 +45,11 @@ const MyLatestSubmissionsTable = () => {
|
||||
initFilters();
|
||||
}
|
||||
}
|
||||
storeSet.main.unsetAsyncRequest();
|
||||
setLocalAsyncRequest(false);
|
||||
}
|
||||
|
||||
const errGetApplCallback = (data) => {
|
||||
set404FromErrorResponse(data);
|
||||
storeSet.main.unsetAsyncRequest();
|
||||
setLocalAsyncRequest(false);
|
||||
}
|
||||
|
||||
const getFormattedBandiData = (data) => {
|
||||
@@ -164,13 +163,13 @@ const MyLatestSubmissionsTable = () => {
|
||||
|
||||
return (
|
||||
<div className="appPageSection__table">
|
||||
<DataTable value={items} paginator showGridlines rows={10} loading={isAsyncRequest} dataKey="id"
|
||||
<DataTable value={items} paginator showGridlines rows={10} loading={localAsyncRequest} dataKey="id"
|
||||
filters={filters}
|
||||
globalFilterFields={['name', 'status']}
|
||||
header={header}
|
||||
emptyMessage={__('Nessun dato disponibile', 'gepafin')}
|
||||
onFilter={(e) => setFilters(e.filters)}>
|
||||
<Column field="callTitle" header={__('Bando', 'gepafin')} filter filterPlaceholder="Search by name"
|
||||
<Column field="callTitle" header={__('Bando', 'gepafin')} filter filterPlaceholder={__('Cerca il nome', 'gepafin')}
|
||||
style={{ minWidth: '12rem' }}/>
|
||||
<Column header={__('Scadenza', 'gepafin')} filterField="callEndDate" dataType="date"
|
||||
style={{ minWidth: '10rem' }}
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { head, pathOr } from 'ramda';
|
||||
import NumberFlow from '@number-flow/react';
|
||||
|
||||
// store
|
||||
import { useStore } from '../../store';
|
||||
@@ -57,15 +58,24 @@ const DashboardBeneficiario = () => {
|
||||
<div className="statsBigBadges__grid">
|
||||
<div className="statsBigBadges__gridItem">
|
||||
<span>{__('Domande attive', 'gepafin')}</span>
|
||||
<span>{getStatValue('numberOfApplications', 0)}</span>
|
||||
<span><NumberFlow
|
||||
value={getStatValue('numberOfApplications', 0)}
|
||||
format={{ notation: 'compact' }}
|
||||
locales="it-IT" /></span>
|
||||
</div>
|
||||
<div className="statsBigBadges__gridItem">
|
||||
<span>{__('Bandi osservati', 'gepafin')}</span>
|
||||
<span>{getStatValue('numberOfCalls', 0)}</span>
|
||||
<span><NumberFlow
|
||||
value={getStatValue('numberOfCalls', 0)}
|
||||
format={{ notation: 'compact' }}
|
||||
locales="it-IT" /></span>
|
||||
</div>
|
||||
<div className="statsBigBadges__gridItem">
|
||||
<span>{__('Documenti da integrare', 'gepafin')}</span>
|
||||
<span>{getStatValue('numberOfIntegratedDocuments', 0)}</span>
|
||||
<span><NumberFlow
|
||||
value={getStatValue('numberOfIntegratedDocuments', 0)}
|
||||
format={{ notation: 'compact' }}
|
||||
locales="it-IT" /></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
// store
|
||||
import { useStore } from '../../../../store';
|
||||
|
||||
// tools
|
||||
//import set404FromErrorResponse from '../../../../helpers/set404FromErrorResponse';
|
||||
import ProperBandoLabel from '../../../../components/ProperBandoLabel';
|
||||
|
||||
// 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 { Button } from 'primereact/button';
|
||||
import { Calendar } from 'primereact/calendar';
|
||||
|
||||
|
||||
const MyEvaluationsTable = () => {
|
||||
const isAsyncRequest = useStore().main.isAsyncRequest();
|
||||
const [items, setItems] = useState(null);
|
||||
const [filters, setFilters] = useState(null);
|
||||
const [globalFilterValue, setGlobalFilterValue] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
const demoItems = [
|
||||
{
|
||||
id: 1,
|
||||
callTitle: 'Bando 1',
|
||||
appliedDate: '2024-10-01',
|
||||
callEndDate: '2025-11-25',
|
||||
status: 'AWAITING'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
callTitle: 'Bando 2',
|
||||
appliedDate: '2024-08-11',
|
||||
callEndDate: '2027-09-23',
|
||||
status: 'AWAITING'
|
||||
}
|
||||
];
|
||||
setItems(getFormattedData(demoItems));
|
||||
/*storeSet.main.setAsyncRequest();
|
||||
ApplicationService.getApplications(getApplCallback, errGetApplCallback)*/
|
||||
}, []);
|
||||
|
||||
/*const getApplCallback = (data) => {
|
||||
if (data.status === 'SUCCESS') {
|
||||
if (data.data.length) {
|
||||
setItems(getFormattedBandiData(data.data));
|
||||
setStatuses(uniq(items.map(o => o.status)))
|
||||
initFilters();
|
||||
}
|
||||
}
|
||||
storeSet.main.unsetAsyncRequest();
|
||||
}
|
||||
|
||||
const errGetApplCallback = (data) => {
|
||||
set404FromErrorResponse(data);
|
||||
storeSet.main.unsetAsyncRequest();
|
||||
}*/
|
||||
|
||||
const getFormattedData = (data) => {
|
||||
return [...(data || [])].map((d) => {
|
||||
d.appliedDate = new Date(d.appliedDate);
|
||||
d.callEndDate = new Date(d.callEndDate);
|
||||
|
||||
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 }]
|
||||
},
|
||||
appliedDate: {
|
||||
operator: FilterOperator.AND,
|
||||
constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }]
|
||||
},
|
||||
callEndDate: {
|
||||
operator: FilterOperator.AND,
|
||||
constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }]
|
||||
}
|
||||
});
|
||||
setGlobalFilterValue('');
|
||||
};
|
||||
|
||||
const renderHeader = () => {
|
||||
return (
|
||||
<div className="appTableHeader">
|
||||
<Button type="button" icon="pi pi-filter-slash" label={__('Pulisci', 'gepafin')} outlined
|
||||
onClick={clearFilter}/>
|
||||
<IconField iconPosition="left">
|
||||
<InputIcon className="pi pi-search"/>
|
||||
<InputText value={globalFilterValue} onChange={onGlobalFilterChange}
|
||||
placeholder={__('Cerca', 'gepafin')}/>
|
||||
</IconField>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const dateAppliedBodyTemplate = (rowData) => {
|
||||
return formatDate(rowData.appliedDate);
|
||||
};
|
||||
|
||||
const dateEndBodyTemplate = (rowData) => {
|
||||
return formatDate(rowData.callEndDate);
|
||||
};
|
||||
|
||||
const dateFilterTemplate = (options) => {
|
||||
return <Calendar value={options.value} onChange={(e) => options.filterCallback(e.value, options.index)}
|
||||
dateFormat="mm/dd/yy" placeholder="mm/dd/yyyy" mask="99/99/9999"/>;
|
||||
};
|
||||
|
||||
const statusBodyTemplate = (rowData) => {
|
||||
return <ProperBandoLabel status={rowData.status}/>;
|
||||
};
|
||||
|
||||
const actionsBodyTemplate = (rowData) => {
|
||||
return <Link to={`/valutazioni/${rowData.id}`}>
|
||||
<Button type="button"
|
||||
severity="info"
|
||||
label={__('Valuta', 'gepafin')}
|
||||
size="small"/>
|
||||
</Link>
|
||||
}
|
||||
|
||||
const header = renderHeader();
|
||||
|
||||
return (
|
||||
<div className="appPageSection__table">
|
||||
<DataTable value={items} paginator showGridlines rows={10} loading={isAsyncRequest} dataKey="id"
|
||||
filters={filters}
|
||||
globalFilterFields={['name', 'status']}
|
||||
header={header}
|
||||
emptyMessage={__('Nessun dato disponibile', 'gepafin')}
|
||||
onFilter={(e) => setFilters(e.filters)}>
|
||||
<Column field="id" header={__('ID domanda', 'gepafin')}
|
||||
style={{ minWidth: '2rem' }}/>
|
||||
<Column field="callTitle" header={__('Bando', 'gepafin')} filter filterPlaceholder={__('Cerca il nome', 'gepafin')}
|
||||
style={{ minWidth: '12rem' }}/>
|
||||
<Column header={__('Data Ricezione', 'gepafin')} filterField="modifiedDate" dataType="date"
|
||||
style={{ minWidth: '10rem' }}
|
||||
body={dateAppliedBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
||||
<Column header={__('Scadenza', 'gepafin')} filterField="callEndDate" dataType="date"
|
||||
style={{ minWidth: '10rem' }}
|
||||
body={dateEndBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
||||
<Column field="status" header={__('Stato', 'gepafin')}
|
||||
style={{ width: '120px' }} body={statusBodyTemplate} />
|
||||
<Column header={__('Azioni', 'gepafin')}
|
||||
body={actionsBodyTemplate}/>
|
||||
</DataTable>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default MyEvaluationsTable;
|
||||
76
src/pages/DashboardInstructor/index.js
Normal file
76
src/pages/DashboardInstructor/index.js
Normal file
@@ -0,0 +1,76 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { head, pathOr } from 'ramda';
|
||||
|
||||
// store
|
||||
import { useStore } from '../../store';
|
||||
|
||||
// api
|
||||
//import DashboardService from '../../service/dashboard-service';
|
||||
|
||||
// components
|
||||
//import LatestBandiTable from './components/LatestBandiTable';
|
||||
//import MyLatestSubmissionsTable from './components/MyLatestSubmissionsTable';
|
||||
import { Button } from 'primereact/button';
|
||||
import MyEvaluationsTable from './components/MyEvaluationsTable';
|
||||
|
||||
const DashboardInstructor = () => {
|
||||
const navigate = useNavigate();
|
||||
//const [mainStats, setMainStats] = useState({});
|
||||
|
||||
const goToAllEvaluations = () => {
|
||||
navigate('/valutazioni');
|
||||
}
|
||||
|
||||
return(
|
||||
<div className="appPage">
|
||||
<div className="appPage__pageHeader">
|
||||
<h1>{__('Dashboard', 'gepafin')}</h1>
|
||||
</div>
|
||||
|
||||
{/*<div className="appPage__spacer"></div>
|
||||
|
||||
<div className="appPageSection statsBigBadges">
|
||||
<h2>{__('Panoramica di Sistema', 'gepafin')}</h2>
|
||||
<div className="statsBigBadges__grid">
|
||||
<div className="statsBigBadges__gridItem">
|
||||
<span>{__('Domande attive', 'gepafin')}</span>
|
||||
<span>{getStatValue('numberOfApplications', 0)}</span>
|
||||
</div>
|
||||
<div className="statsBigBadges__gridItem">
|
||||
<span>{__('Bandi osservati', 'gepafin')}</span>
|
||||
<span>{getStatValue('numberOfCalls', 0)}</span>
|
||||
</div>
|
||||
<div className="statsBigBadges__gridItem">
|
||||
<span>{__('Documenti da integrare', 'gepafin')}</span>
|
||||
<span>{getStatValue('numberOfIntegratedDocuments', 0)}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>*/}
|
||||
|
||||
<div className="appPage__spacer"></div>
|
||||
|
||||
<div className="appPageSection">
|
||||
<h2>{__('Coda di lavoro', 'gepafin')}</h2>
|
||||
<MyEvaluationsTable/>
|
||||
</div>
|
||||
|
||||
<div className="appPage__spacer"></div>
|
||||
|
||||
<div className="appPageSection__hr">
|
||||
<span>{__('Azioni rapide', 'gepafin')}</span>
|
||||
</div>
|
||||
|
||||
<div className="appPageSection">
|
||||
<div className="appPageSection__actions">
|
||||
<Button
|
||||
onClick={goToAllEvaluations}
|
||||
label={__('Tutti valutazioni', 'gepafin')} icon="pi pi-arrow-right" iconPos="right"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default DashboardInstructor;
|
||||
227
src/pages/EvaluationEdit/index.js
Normal file
227
src/pages/EvaluationEdit/index.js
Normal file
@@ -0,0 +1,227 @@
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import { __, sprintf } from '@wordpress/i18n';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { is, isEmpty, isNil } from 'ramda';
|
||||
|
||||
// store
|
||||
import { storeSet, useStore } from '../../store';
|
||||
|
||||
// tools
|
||||
import getNumberWithCurrency from '../../helpers/getNumberWithCurrency';
|
||||
//import getDateFromISOstring from '../../helpers/getDateFromISOstring';
|
||||
|
||||
// components
|
||||
import { Skeleton } from 'primereact/skeleton';
|
||||
import { Button } from 'primereact/button';
|
||||
import { Messages } from 'primereact/messages';
|
||||
import { Tag } from 'primereact/tag';
|
||||
|
||||
const EvaluationEdit = () => {
|
||||
const isAsyncRequest = useStore().main.isAsyncRequest();
|
||||
const { id } = useParams();
|
||||
const navigate = useNavigate();
|
||||
const [data, setData] = useState({});
|
||||
const pageMsgs = useRef(null);
|
||||
|
||||
const goToEvaluationsPage = () => {
|
||||
navigate('/valutazioni');
|
||||
}
|
||||
|
||||
/*const getCallback = (data) => {
|
||||
if (data.status === 'SUCCESS') {
|
||||
setData(getFormattedBandiData(data.data));
|
||||
}
|
||||
storeSet.main.unsetAsyncRequest();
|
||||
}
|
||||
|
||||
const errGetCallback = (data) => {
|
||||
if (pageMsgs.current && data.message) {
|
||||
pageMsgs.current.show([
|
||||
{
|
||||
sticky: true, severity: 'error', summary: '',
|
||||
detail: data.message,
|
||||
closable: true
|
||||
}
|
||||
]);
|
||||
}
|
||||
set404FromErrorResponse(data);
|
||||
storeSet.main.unsetAsyncRequest();
|
||||
}*/
|
||||
|
||||
/*const getFormattedBandiData = (data) => {
|
||||
data.dates = data.dates.map(v => is(String, v) ? new Date(v) : (v ? v : ''));
|
||||
return data;
|
||||
};*/
|
||||
|
||||
useEffect(() => {
|
||||
const parsed = parseInt(id)
|
||||
const entityId = !isNaN(parsed) ? parsed : 0;
|
||||
|
||||
setData({
|
||||
id: 'DOM_2024_001',
|
||||
callTitle: 'Innovazione 2024',
|
||||
beneficiario: 'Azienda Alpha SRL',
|
||||
createdAt: '2024-08-01',
|
||||
scadenzaAt: '2024-08-05',
|
||||
status: 'In Valutazione',
|
||||
criteria: [
|
||||
{ title: 'Innovatività del progetto', score: 25, id: 12 },
|
||||
{ title: 'Innovatività del progetto2', score: 35, id: 13 },
|
||||
{ title: 'Innovatività del progetto3', score: 15, id: 14 }
|
||||
],
|
||||
minScore: 60
|
||||
});
|
||||
|
||||
//BandoService.getBando(entityId, getCallback, errGetCallback);
|
||||
}, [id]);
|
||||
|
||||
return (
|
||||
<div className="appPage">
|
||||
<div className="appPage__pageHeader">
|
||||
<h1>{__('Valuta domanda', 'gepafin')}</h1>
|
||||
</div>
|
||||
|
||||
<div className="appPage__spacer"></div>
|
||||
<Messages ref={pageMsgs}/>
|
||||
|
||||
<div className="appPageSection__row">
|
||||
<Button
|
||||
type="button"
|
||||
outlined
|
||||
onClick={goToEvaluationsPage}
|
||||
label={__('Indietro', 'gepafin')}
|
||||
icon="pi pi-arrow-left" iconPos="left"/>
|
||||
</div>
|
||||
|
||||
<div className="appPage__spacer"></div>
|
||||
|
||||
{!isAsyncRequest && !isEmpty(data)
|
||||
? <div className="appPage__content">
|
||||
<div className="appPageSection__withBorder columns">
|
||||
<p className="appPageSection__pMeta">
|
||||
<span>{__('ID domanda', 'gepafin')}</span>
|
||||
<span>{data.id}</span>
|
||||
</p>
|
||||
<p className="appPageSection__pMeta">
|
||||
<span>{__('Bando', 'gepafin')}</span>
|
||||
<span>{data.callTitle}</span>
|
||||
</p>
|
||||
<p className="appPageSection__pMeta">
|
||||
<span>{__('Beneficiario', 'gepafin')}</span>
|
||||
<span>{data.beneficiario}</span>
|
||||
</p>
|
||||
<p className="appPageSection__pMeta">
|
||||
<span>{__('Data ricezione', 'gepafin')}</span>
|
||||
<span>{data.createdAt}</span>
|
||||
</p>
|
||||
<p className="appPageSection__pMeta">
|
||||
<span>{__('Scadenza Valutazione', 'gepafin')}</span>
|
||||
<span>{data.scadenzaAt}</span>
|
||||
</p>
|
||||
<p className="appPageSection__pMeta">
|
||||
<span>{__('Stato', 'gepafin')}</span>
|
||||
<span>{data.status}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="appPageSection">
|
||||
<h2>{__('Punteggi di valutazione', 'gepafin')}</h2>
|
||||
{data.criteria
|
||||
? <table className="myTable">
|
||||
<thead className="myThead">
|
||||
<tr>
|
||||
<th>{__('Parametro', 'gepafin')}</th>
|
||||
<th>{__('Punteggio', 'gepafin')}</th>
|
||||
<th>{__('Stato', 'gepafin')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="myTbody">
|
||||
{data.criteria.map(o => <tr key={o.id}>
|
||||
<td>{o.title}</td>
|
||||
<td>{o.score}</td>
|
||||
<td></td>
|
||||
</tr>)}
|
||||
<tr>
|
||||
<td>{__('Punteggio:', 'gepafin')}</td>
|
||||
<td>{68}</td>
|
||||
<td><Tag icon="pi pi-check" severity="success" value={__('Ammissibile')}></Tag></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot className="myTfoot">
|
||||
<tr>
|
||||
<td colSpan="3">{sprintf(__('Punteggio minimo per l\'ammissione: %d'), data.minScore)}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table> : null}
|
||||
</div>
|
||||
|
||||
<div className="appPageSection">
|
||||
<h2>{__('Checklist Valutazione', 'gepafin')}</h2>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div className="appPage__spacer"></div>
|
||||
|
||||
<div className="appPageSection__hr">
|
||||
<span>{__('Azioni rapide', 'gepafin')}</span>
|
||||
</div>
|
||||
|
||||
<div className="appPageSection">
|
||||
<div className="appPageSection__actions">
|
||||
<Button
|
||||
type="button"
|
||||
outlined
|
||||
label={<>
|
||||
{__('Richiedi Soccorso Istruttorio', 'gepafin')}
|
||||
<i style={{marginLeft: 7}}>
|
||||
<svg width="15" height="14" viewBox="0 0 15 14" fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<g clipPath="url(#clip0_1665_1656)">
|
||||
<path
|
||||
d="M7.50129 14C6.53308 14 5.62302 13.8163 4.7711 13.4488C3.91919 13.0814 3.17818 12.5827 2.54805 11.9529C1.91793 11.323 1.41903 10.5823 1.05134 9.73074C0.683781 8.87919 0.5 7.96938 0.5 7.00129C0.5 6.03308 0.683719 5.12302 1.05116 4.2711C1.4186 3.41919 1.91725 2.67818 2.54713 2.04805C3.17701 1.41793 3.91772 0.919026 4.76926 0.551342C5.62081 0.183781 6.53062 0 7.49871 0C8.46692 0 9.37698 0.183719 10.2289 0.551158C11.0808 0.918596 11.8218 1.41725 12.4519 2.04713C13.0821 2.67701 13.581 3.41772 13.9487 4.26926C14.3162 5.12081 14.5 6.03062 14.5 6.99871C14.5 7.96692 14.3163 8.87698 13.9488 9.72889C13.5814 10.5808 13.0827 11.3218 12.4529 11.9519C11.823 12.5821 11.0823 13.081 10.2307 13.4487C9.37919 13.8162 8.46938 14 7.50129 14ZM5.36316 12.4895L6.44576 10.0238C5.98585 9.86147 5.58888 9.60977 5.25484 9.26874C4.92081 8.92758 4.66598 8.52747 4.49037 8.06842L1.99634 9.1C2.28359 9.88596 2.72195 10.5737 3.31142 11.1632C3.90089 11.7526 4.58481 12.1947 5.36316 12.4895ZM4.49037 5.93158C4.65665 5.47253 4.90816 5.07555 5.24489 4.74066C5.58163 4.40576 5.97719 4.15567 6.43158 3.99037L5.4 1.49634C4.60937 1.79587 3.91932 2.24037 3.32984 2.82984C2.74037 3.41932 2.29587 4.10937 1.99634 4.9L4.49037 5.93158ZM7.49834 9.09724C8.08045 9.09724 8.57579 8.8935 8.98437 8.48603C9.39295 8.07855 9.59724 7.58376 9.59724 7.00166C9.59724 6.41955 9.3935 5.92421 8.98603 5.51563C8.57855 5.10705 8.08376 4.90276 7.50166 4.90276C6.91955 4.90276 6.42421 5.1065 6.01563 5.51397C5.60705 5.92145 5.40276 6.41624 5.40276 6.99834C5.40276 7.58045 5.6065 8.07579 6.01397 8.48437C6.42145 8.89295 6.91624 9.09724 7.49834 9.09724ZM9.63684 12.4895C10.4105 12.1947 11.089 11.7557 11.6724 11.1724C12.2557 10.589 12.6947 9.91053 12.9895 9.13684L10.5238 8.05424C10.368 8.50862 10.1209 8.90302 9.78274 9.23742C9.44453 9.57182 9.05203 9.82923 8.60526 10.0096L9.63684 12.4895ZM10.5096 5.89474L12.9895 4.86316C12.6947 4.08947 12.2557 3.41096 11.6724 2.82763C11.089 2.2443 10.4105 1.80526 9.63684 1.51053L8.60526 4.01303C9.04258 4.18299 9.4242 4.43051 9.75013 4.75558C10.0761 5.08053 10.3292 5.46025 10.5096 5.89474Z"
|
||||
fill="#3B7C43"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_1665_1656">
|
||||
<rect width="14" height="14" fill="white"
|
||||
transform="translate(0.5)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
</i>
|
||||
</>}
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
outlined
|
||||
label={__('Salva Bozza Valutazione', 'gepafin')}
|
||||
icon="pi pi-save" iconPos="right"/>
|
||||
<Button
|
||||
type="button"
|
||||
label={__('Richiedi Soccorso Istruttorio', 'gepafin')}
|
||||
icon="pi pi-check" iconPos="right"/>
|
||||
<Button
|
||||
type="button"
|
||||
label={__('Richiedi Soccorso Istruttorio', 'gepafin')}
|
||||
icon="pi pi-times" iconPos="right"/>
|
||||
</div>
|
||||
</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 EvaluationEdit;
|
||||
23
src/pages/Evaluations/index.js
Normal file
23
src/pages/Evaluations/index.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
|
||||
// components
|
||||
import MyEvaluationsTable from '../DashboardInstructor/components/MyEvaluationsTable';
|
||||
|
||||
const Bandi = () => {
|
||||
return(
|
||||
<div className="appPage">
|
||||
<div className="appPage__pageHeader">
|
||||
<h1>{__('Domande da valutare', 'gepafin')}</h1>
|
||||
</div>
|
||||
|
||||
<div className="appPage__spacer"></div>
|
||||
|
||||
<div className="appPageSection">
|
||||
<MyEvaluationsTable/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Bandi;
|
||||
@@ -114,9 +114,9 @@ const LoginAdmin = () => {
|
||||
label={__('Accedi', 'gepafin')}
|
||||
disabled={loading}/>
|
||||
|
||||
<Button
|
||||
{/*<Button
|
||||
label={__('Password dimenticata?', 'gepafin')}
|
||||
link onClick={gotToResetPassword}/>
|
||||
link onClick={gotToResetPassword}/>*/}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -129,88 +129,7 @@ const Profile = () => {
|
||||
</div>
|
||||
|
||||
<div className="appPageSection">
|
||||
<h2>{__('Consensi', 'gepafin')}</h2>
|
||||
|
||||
<div className="appForm__switchFieldWrapper">
|
||||
<FormField
|
||||
type="switch"
|
||||
disabled={true}
|
||||
fieldName="privacy"
|
||||
label={''}
|
||||
control={control}
|
||||
errors={errors}
|
||||
onLabel={''}
|
||||
offLabel={''}
|
||||
/>
|
||||
<div>
|
||||
{__('Dichiaro di aver preso visione, prima dell\'accesso al portale https://bandi.gepafin.it, dell\' "Informativa Privacy" all\'interno dell\'Appendice 10 dell\'Avviso secondo il Regolamento UE 2016/679 relativo alla protezione delle persone fisiche con riguardo al trattamento dei dati personale, nonché alla libera circolazione di tali dati e che abroga la Direttiva 95/46 CE.', 'gepafin')}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="appForm__switchFieldWrapper">
|
||||
<FormField
|
||||
type="switch"
|
||||
disabled={true}
|
||||
fieldName="terms"
|
||||
label={''}
|
||||
control={control}
|
||||
errors={errors}
|
||||
onLabel={''}
|
||||
offLabel={''}
|
||||
/>
|
||||
<div>
|
||||
{__('Termini e condizioni', 'gepafin')}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="appForm__switchFieldWrapper">
|
||||
<FormField
|
||||
type="switch"
|
||||
fieldName="marketing"
|
||||
label={''}
|
||||
control={control}
|
||||
errors={errors}
|
||||
onLabel={''}
|
||||
offLabel={''}
|
||||
/>
|
||||
<div>
|
||||
{__('Invio di materiale pubblicitario, vendita diretta, compimento di ricerche di mercato o comunicazione commerciale riguardanti promozione e vendita di prodotti e servizi della Gepafin, mediante modalità di contatto automatizzate (posta elettronica, PEC, messaggi tramite canali informatici, network ed applicazioni web) e tradizionali (come posta cartacea e chiamate telefoniche con operatore)', 'gepafin')}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="appForm__switchFieldWrapper">
|
||||
<FormField
|
||||
type="switch"
|
||||
fieldName="offers"
|
||||
label={''}
|
||||
control={control}
|
||||
errors={errors}
|
||||
onLabel={''}
|
||||
offLabel={''}
|
||||
/>
|
||||
<div>
|
||||
{__('Elaborazione, in forma elettronica, dei dati relativi ai rapporti e servizi forniti, per l’analisi di comportamenti e preferenze della clientela, da utilizzare a scopo commerciale, per la individuazione ed offerta di prodotti e servizi di suo interesse', 'gepafin')}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="appForm__switchFieldWrapper">
|
||||
<FormField
|
||||
type="switch"
|
||||
fieldName="thirdParty"
|
||||
label={''}
|
||||
control={control}
|
||||
errors={errors}
|
||||
onLabel={''}
|
||||
offLabel={''}
|
||||
/>
|
||||
<div>
|
||||
{__('Comunicazione dei miei dati ad altre società in ambito bancario, finanziario od assicurativo e enti pubblici che li tratteranno per invio di materiale pubblicitario, vendita diretta, compimento di ricerche di mercato o comunicazione commerciale riguardanti loro prodotti o servizi, mediante le modalità automatizzate e tradizionali di comunicazione sopra indicate', 'gepafin')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="appPageSection">
|
||||
<h2>{__('Utenti Associati', 'gepafin')}</h2>
|
||||
<h2>{__('Impostazioni', 'gepafin')}</h2>
|
||||
<div className="appForm__cols">
|
||||
<FormField
|
||||
type="select"
|
||||
|
||||
288
src/pages/ProfileBeneficiario/index.js
Normal file
288
src/pages/ProfileBeneficiario/index.js
Normal file
@@ -0,0 +1,288 @@
|
||||
import React, { useMemo, useRef } from 'react';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { useForm } from 'react-hook-form';
|
||||
|
||||
// store
|
||||
import { storeSet, useStore } from '../../store';
|
||||
|
||||
// components
|
||||
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||
import FormField from '../../components/FormField';
|
||||
import { Button } from 'primereact/button';
|
||||
import { Toast } from 'primereact/toast';
|
||||
|
||||
// api
|
||||
import UserService from '../../service/user-service';
|
||||
|
||||
// tools
|
||||
import getDateFromISOstring from '../../helpers/getDateFromISOstring';
|
||||
|
||||
const ProfileBeneficiario = () => {
|
||||
const isAsyncRequest = useStore().main.isAsyncRequest();
|
||||
const userData = useStore().main.userData();
|
||||
const toast = useRef(null);
|
||||
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
formState: { errors }
|
||||
} = useForm({
|
||||
defaultValues: useMemo(() => {
|
||||
return userData;
|
||||
}, [userData]),
|
||||
mode: 'onChange'
|
||||
});
|
||||
|
||||
const onSubmit = (formData) => {
|
||||
storeSet.main.setAsyncRequest();
|
||||
|
||||
UserService.updateUser(userData.id, formData, updateCallback, updateError);
|
||||
};
|
||||
|
||||
const updateCallback = (data) => {
|
||||
if (data.status === 'SUCCESS') {
|
||||
storeSet.main.userData(data.data);
|
||||
if (toast.current) {
|
||||
toast.current.show({
|
||||
severity: 'success',
|
||||
summary: '',
|
||||
detail: __('L\'utente è stato aggiornato!', 'gepafin')
|
||||
});
|
||||
}
|
||||
}
|
||||
storeSet.main.unsetAsyncRequest();
|
||||
}
|
||||
|
||||
const updateError = (data) => {
|
||||
set404FromErrorResponse(data);
|
||||
storeSet.main.unsetAsyncRequest();
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="appPage">
|
||||
<div className="appPage__pageHeader">
|
||||
<h1>{__('Profilo utente', 'gepafin')}</h1>
|
||||
</div>
|
||||
|
||||
<div className="appPage__spacer"></div>
|
||||
<Toast ref={toast}/>
|
||||
|
||||
<form className="appForm" onSubmit={handleSubmit(onSubmit)}>
|
||||
|
||||
<div className="appPageSection">
|
||||
<h2>{__('Informazioni personali', 'gepafin')}</h2>
|
||||
<div className="appForm__cols">
|
||||
<FormField
|
||||
type="textinput"
|
||||
disabled={true}
|
||||
fieldName="firstName"
|
||||
label={__('Nome', 'gepafin')}
|
||||
control={control}
|
||||
errors={errors}
|
||||
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||||
placeholder="Francesco"
|
||||
/>
|
||||
|
||||
<FormField
|
||||
type="textinput"
|
||||
disabled={true}
|
||||
fieldName="lastName"
|
||||
label={__('Cognome', 'gepafin')}
|
||||
control={control}
|
||||
errors={errors}
|
||||
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||||
placeholder="Moli"
|
||||
/>
|
||||
|
||||
<FormField
|
||||
type="textinput"
|
||||
disabled={true}
|
||||
fieldName="codiceFiscale"
|
||||
label={__('Codice fiscale', 'gepafin')}
|
||||
control={control}
|
||||
errors={errors}
|
||||
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||||
placeholder="XXXXXXXX"
|
||||
/>
|
||||
</div>
|
||||
<div className="appForm__cols">
|
||||
<FormField
|
||||
type="textinput"
|
||||
fieldName="email"
|
||||
label={__('Email', 'gepafin')}
|
||||
control={control}
|
||||
errors={errors}
|
||||
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||||
placeholder="user@example.com"
|
||||
/>
|
||||
|
||||
<FormField
|
||||
type="textinput"
|
||||
fieldName="phoneNumber"
|
||||
label={__('Telefono', 'gepafin')}
|
||||
control={control}
|
||||
errors={errors}
|
||||
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||||
placeholder="1234567"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="appPageSection">
|
||||
<h2>{__('Consensi', 'gepafin')}</h2>
|
||||
|
||||
<div className="appForm__switchFieldWrapper">
|
||||
<FormField
|
||||
type="switch"
|
||||
disabled={true}
|
||||
fieldName="privacy"
|
||||
label={''}
|
||||
control={control}
|
||||
errors={errors}
|
||||
onLabel={''}
|
||||
offLabel={''}
|
||||
/>
|
||||
<div>
|
||||
{__('Dichiaro di aver preso visione, prima dell\'accesso al portale https://bandi.gepafin.it, dell\' "Informativa Privacy" all\'interno dell\'Appendice 10 dell\'Avviso secondo il Regolamento UE 2016/679 relativo alla protezione delle persone fisiche con riguardo al trattamento dei dati personale, nonché alla libera circolazione di tali dati e che abroga la Direttiva 95/46 CE.', 'gepafin')}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="appForm__switchFieldWrapper">
|
||||
<FormField
|
||||
type="switch"
|
||||
disabled={true}
|
||||
fieldName="terms"
|
||||
label={''}
|
||||
control={control}
|
||||
errors={errors}
|
||||
onLabel={''}
|
||||
offLabel={''}
|
||||
/>
|
||||
<div>
|
||||
{__('Termini e condizioni', 'gepafin')}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="appForm__switchFieldWrapper">
|
||||
<FormField
|
||||
type="switch"
|
||||
fieldName="marketing"
|
||||
label={''}
|
||||
control={control}
|
||||
errors={errors}
|
||||
onLabel={''}
|
||||
offLabel={''}
|
||||
/>
|
||||
<div>
|
||||
{__('Invio di materiale pubblicitario, vendita diretta, compimento di ricerche di mercato o comunicazione commerciale riguardanti promozione e vendita di prodotti e servizi della Gepafin, mediante modalità di contatto automatizzate (posta elettronica, PEC, messaggi tramite canali informatici, network ed applicazioni web) e tradizionali (come posta cartacea e chiamate telefoniche con operatore)', 'gepafin')}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="appForm__switchFieldWrapper">
|
||||
<FormField
|
||||
type="switch"
|
||||
fieldName="offers"
|
||||
label={''}
|
||||
control={control}
|
||||
errors={errors}
|
||||
onLabel={''}
|
||||
offLabel={''}
|
||||
/>
|
||||
<div>
|
||||
{__('Elaborazione, in forma elettronica, dei dati relativi ai rapporti e servizi forniti, per l’analisi di comportamenti e preferenze della clientela, da utilizzare a scopo commerciale, per la individuazione ed offerta di prodotti e servizi di suo interesse', 'gepafin')}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="appForm__switchFieldWrapper">
|
||||
<FormField
|
||||
type="switch"
|
||||
fieldName="thirdParty"
|
||||
label={''}
|
||||
control={control}
|
||||
errors={errors}
|
||||
onLabel={''}
|
||||
offLabel={''}
|
||||
/>
|
||||
<div>
|
||||
{__('Comunicazione dei miei dati ad altre società in ambito bancario, finanziario od assicurativo e enti pubblici che li tratteranno per invio di materiale pubblicitario, vendita diretta, compimento di ricerche di mercato o comunicazione commerciale riguardanti loro prodotti o servizi, mediante le modalità automatizzate e tradizionali di comunicazione sopra indicate', 'gepafin')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="appPageSection">
|
||||
<h2>{__('Impostazioni', 'gepafin')}</h2>
|
||||
<div className="appForm__cols">
|
||||
<FormField
|
||||
type="select"
|
||||
disabled={true}
|
||||
fieldName="language"
|
||||
defaultValue={'it'}
|
||||
label={__('Lingua predefinita', 'gepafin')}
|
||||
control={control}
|
||||
errors={errors}
|
||||
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||||
options={[
|
||||
{ label: __('Italiano', 'gepafin'), name: 'it' }
|
||||
]}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
type="select"
|
||||
disabled={true}
|
||||
fieldName="timezone"
|
||||
defaultValue={'Europe/Rome'}
|
||||
label={__('Fuso Orario', 'gepafin')}
|
||||
control={control}
|
||||
errors={errors}
|
||||
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||||
options={[
|
||||
{ label: __('Europe/Rome', 'gepafin'), name: 'Europe/Rome' }
|
||||
]}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
type="select"
|
||||
disabled={true}
|
||||
fieldName="dateformat"
|
||||
defaultValue={'DD/MM/YY'}
|
||||
label={__('Formato Data', 'gepafin')}
|
||||
control={control}
|
||||
errors={errors}
|
||||
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||||
options={[
|
||||
{ label: __('DD/MM/YY', 'gepafin'), name: 'DD/MM/YY' }
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="appPageSection">
|
||||
<h2>{__('Sicurezza', 'gepafin')}</h2>
|
||||
<div className="appForm__row">
|
||||
<label>{__('Ultimo accesso', 'gepafin')}</label>
|
||||
<span>{getDateFromISOstring(userData.lastLogin)}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="appPage__spacer"></div>
|
||||
|
||||
<div className="appPageSection__hr">
|
||||
<span>{__('Azioni rapide', 'gepafin')}</span>
|
||||
</div>
|
||||
|
||||
<div className="appPageSection">
|
||||
<div className="appPageSection__actions">
|
||||
<Button
|
||||
disabled={isAsyncRequest}
|
||||
label={__('Salva modifiche', 'gepafin')}
|
||||
icon="pi pi-check" iconPos="right"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
export default ProfileBeneficiario;
|
||||
@@ -143,7 +143,7 @@ const ResetPassword = () => {
|
||||
type="textinput"
|
||||
inputtype="password"
|
||||
fieldName="confirmPassword"
|
||||
label={__('Conferma Password', 'gepafin')}
|
||||
label={__('Conferma password', 'gepafin')}
|
||||
control={control}
|
||||
errors={errors}
|
||||
config={{
|
||||
|
||||
@@ -11,6 +11,7 @@ import UserService from '../../service/user-service';
|
||||
|
||||
// tools
|
||||
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||
import { isEmail } from '../../helpers/validators';
|
||||
|
||||
// components
|
||||
import AllUsersTable from './components/AllUsersTable';
|
||||
@@ -31,7 +32,9 @@ const Users = () => {
|
||||
lastName: '',
|
||||
email: '',
|
||||
phoneNumber: '',
|
||||
role: ''
|
||||
password: '',
|
||||
confPassword: '',
|
||||
roleId: 0
|
||||
});
|
||||
const [roles, setRoles] = useState([]);
|
||||
const toast = useRef(null);
|
||||
@@ -51,11 +54,16 @@ const Users = () => {
|
||||
lastName: '',
|
||||
email: '',
|
||||
phoneNumber: '',
|
||||
role: ''
|
||||
password: '',
|
||||
confPassword: '',
|
||||
roleId: 0
|
||||
});
|
||||
}
|
||||
|
||||
const saveEditDialog = () => {
|
||||
const emptyValues = Object.values(newUserData).filter(v => isEmpty(v));
|
||||
|
||||
if (isEmpty(emptyValues) && newUserData.password === newUserData.confPassword && !loading) {
|
||||
setLoading(true);
|
||||
const body = {
|
||||
...newUserData,
|
||||
@@ -64,6 +72,7 @@ const Users = () => {
|
||||
|
||||
UserService.createUser(body, createUserCallback, errCreateUserCallback);
|
||||
}
|
||||
}
|
||||
|
||||
const createUserCallback = (data) => {
|
||||
if (data.status === 'SUCCESS') {
|
||||
@@ -118,6 +127,8 @@ const Users = () => {
|
||||
storeSet.main.unsetAsyncRequest();
|
||||
}
|
||||
|
||||
const isInvalidField = (data, key) => isEmpty(data[key]) || isNil(data[key])
|
||||
|
||||
useEffect(() => {
|
||||
if (isVisibleEditDialog) {
|
||||
UserService.getRoles(getRolesCallback, errGetRolesCallback)
|
||||
@@ -153,42 +164,73 @@ const Users = () => {
|
||||
<div className="appForm__cols">
|
||||
<div className="appForm__field">
|
||||
<label
|
||||
className={classNames({ 'p-error': isEmpty(newUserData.firstName) || isNil(newUserData.firstName) })}>{__('Nome', 'gepafin')}*</label>
|
||||
className={classNames({ 'p-error': isInvalidField(newUserData, 'firstName') })}>
|
||||
{__('Nome', 'gepafin')}*
|
||||
</label>
|
||||
<InputText value={newUserData.firstName}
|
||||
invalid={isEmpty(newUserData.firstName) || isNil(newUserData.firstName)}
|
||||
invalid={isInvalidField(newUserData, 'firstName')}
|
||||
onChange={(e) => onChangeEditItem(e.target.value, 'firstName')}/>
|
||||
</div>
|
||||
<div className="appForm__field">
|
||||
<label
|
||||
className={classNames({ 'p-error': isEmpty(newUserData.lastName) || isNil(newUserData.lastName) })}>{__('Cognome', 'gepafin')}*</label>
|
||||
className={classNames({ 'p-error': isInvalidField(newUserData, 'lastName') })}>
|
||||
{__('Cognome', 'gepafin')}*
|
||||
</label>
|
||||
<InputText value={newUserData.lastName}
|
||||
invalid={isEmpty(newUserData.lastName) || isNil(newUserData.lastName)}
|
||||
invalid={isInvalidField(newUserData, 'lastName')}
|
||||
onChange={(e) => onChangeEditItem(e.target.value, 'lastName')}/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="appForm__cols">
|
||||
<div className="appForm__field">
|
||||
<label
|
||||
className={classNames({ 'p-error': isEmpty(newUserData.email) || isNil(newUserData.email) })}>{__('Email', 'gepafin')}*</label>
|
||||
className={classNames({ 'p-error': isEmpty(newUserData.email) || isNil(newUserData.email) || !isEmail(newUserData.email) })}>
|
||||
{__('Email', 'gepafin')}*
|
||||
</label>
|
||||
<InputText value={newUserData.email}
|
||||
invalid={isEmpty(newUserData.email) || isNil(newUserData.email)}
|
||||
invalid={isEmpty(newUserData.email) || isNil(newUserData.email) || !isEmail(newUserData.email)}
|
||||
onChange={(e) => onChangeEditItem(e.target.value, 'email')}/>
|
||||
</div>
|
||||
<div className="appForm__field">
|
||||
<label
|
||||
className={classNames({ 'p-error': isEmpty(newUserData.phoneNumber) || isNil(newUserData.phoneNumber) })}>{__('Telefono', 'gepafin')}</label>
|
||||
className={classNames({ 'p-error': isInvalidField(newUserData, 'phoneNumber') })}>
|
||||
{__('Telefono', 'gepafin')}
|
||||
</label>
|
||||
<InputText value={newUserData.phoneNumber}
|
||||
invalid={isEmpty(newUserData.phoneNumber) || isNil(newUserData.phoneNumber)}
|
||||
keyfilter="int"
|
||||
invalid={isInvalidField(newUserData, 'phoneNumber')}
|
||||
onChange={(e) => onChangeEditItem(e.target.value, 'phoneNumber')}/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="appForm__cols">
|
||||
<div className="appForm__field">
|
||||
<label
|
||||
className={classNames({ 'p-error': isEmpty(newUserData.password) || isNil(newUserData.password) || newUserData.password !== newUserData.confPassword })}>
|
||||
{__('Password', 'gepafin')}*
|
||||
</label>
|
||||
<InputText value={newUserData.password}
|
||||
invalid={isEmpty(newUserData.password) || isNil(newUserData.password) || newUserData.password !== newUserData.confPassword}
|
||||
onChange={(e) => onChangeEditItem(e.target.value, 'password')}/>
|
||||
</div>
|
||||
<div className="appForm__field">
|
||||
<label
|
||||
className={classNames({ 'p-error': isEmpty(newUserData.confPassword) || isNil(newUserData.confPassword) || newUserData.password !== newUserData.confPassword })}>
|
||||
{__('Conferma password', 'gepafin')}*
|
||||
</label>
|
||||
<InputText value={newUserData.confPassword}
|
||||
invalid={isEmpty(newUserData.confPassword) || isNil(newUserData.confPassword) || newUserData.password !== newUserData.confPassword}
|
||||
onChange={(e) => onChangeEditItem(e.target.value, 'confPassword')}/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="appForm__field">
|
||||
<label
|
||||
className={classNames({ 'p-error': isEmpty(newUserData.role) || isNil(newUserData.role) })}>{__('Ruolo', 'gepafin')}</label>
|
||||
className={classNames({ 'p-error': isEmpty(newUserData.roleId) || isNil(newUserData.roleId) || newUserData.roleId === 0 })}>
|
||||
{__('Ruolo', 'gepafin')}*
|
||||
</label>
|
||||
<Dropdown
|
||||
value={newUserData.role}
|
||||
invalid={isEmpty(newUserData.role) || isNil(newUserData.role)}
|
||||
onChange={(e) => onChangeEditItem(e.value, 'role')}
|
||||
value={newUserData.roleId}
|
||||
invalid={isEmpty(newUserData.roleId) || isNil(newUserData.roleId) || newUserData.roleId === 0}
|
||||
onChange={(e) => onChangeEditItem(e.value, 'roleId')}
|
||||
options={roles}
|
||||
optionLabel="name"
|
||||
optionValue="value"/>
|
||||
|
||||
@@ -25,6 +25,10 @@ import ProfileCompany from './pages/ProfileCompany';
|
||||
import Users from './pages/Users';
|
||||
import AddCompany from './pages/AddCompany';
|
||||
import ResetPassword from './pages/ResetPassword';
|
||||
import DashboardInstructor from './pages/DashboardInstructor';
|
||||
import ProfileBeneficiario from './pages/ProfileBeneficiario';
|
||||
import Evaluations from './pages/Evaluations';
|
||||
import EvaluationEdit from './pages/EvaluationEdit';
|
||||
|
||||
const routes = ({ role, chosenCompanyId }) => {
|
||||
|
||||
@@ -34,62 +38,87 @@ const routes = ({ role, chosenCompanyId }) => {
|
||||
<Route path="/" element={<DefaultLayout>
|
||||
{'ROLE_SUPER_ADMIN' === role ? <Dashboard/> : null}
|
||||
{'ROLE_BENEFICIARY' === role ? <DashboardBeneficiario/> : null}
|
||||
{'ROLE_PRE_INSTRUCTOR' === role ? <DashboardInstructor/> : null}
|
||||
</DefaultLayout>}/>
|
||||
<Route path="/bandi" element={<DefaultLayout>
|
||||
{'ROLE_SUPER_ADMIN' === role ? <Bandi/> : null}
|
||||
{'ROLE_BENEFICIARY' === role ? <BandiBeneficiario/> : null}
|
||||
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||
</DefaultLayout>}/>
|
||||
<Route path="/bandi/:id" element={<DefaultLayout>
|
||||
{'ROLE_SUPER_ADMIN' === role ? <BandoEdit/> : null}
|
||||
{'ROLE_BENEFICIARY' === role ? <BandoViewBeneficiario/> : null}
|
||||
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||
</DefaultLayout>}/>
|
||||
<Route path="/bandi/:id/preview" element={<DefaultLayout>
|
||||
{'ROLE_SUPER_ADMIN' === role ? <BandoView/> : null}
|
||||
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
||||
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||
</DefaultLayout>}/>
|
||||
<Route path="/bandi/:id/preview-evaluation" element={<DefaultLayout>
|
||||
{'ROLE_SUPER_ADMIN' === role ? <BandoView/> : null}
|
||||
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
||||
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||
</DefaultLayout>}/>
|
||||
<Route path="/bandi/:id/forms" element={<DefaultLayout>
|
||||
{'ROLE_SUPER_ADMIN' === role ? <BandoForms/> : null}
|
||||
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
||||
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||
</DefaultLayout>}/>
|
||||
<Route path="/bandi/:id/forms/:formId" element={<DefaultLayout>
|
||||
{'ROLE_SUPER_ADMIN' === role ? <BandoFormsEdit/> : null}
|
||||
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
||||
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||
</DefaultLayout>}/>
|
||||
<Route path="/bandi/:id/forms/:formId/preview" element={<DefaultLayout>
|
||||
{'ROLE_SUPER_ADMIN' === role ? <BandoFormsPreview/> : null}
|
||||
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
||||
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||
</DefaultLayout>}/>
|
||||
<Route path="/bandi/:id/flow" element={<DefaultLayout>
|
||||
{'ROLE_SUPER_ADMIN' === role ? <BandoFlowEdit/> : null}
|
||||
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
||||
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||
</DefaultLayout>}/>
|
||||
<Route path="/imieibandi" element={<DefaultLayout>
|
||||
{'ROLE_SUPER_ADMIN' === role ? <PageNotFound/> : null}
|
||||
{'ROLE_BENEFICIARY' === role ? <Applications/> : null}
|
||||
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||
</DefaultLayout>}/>
|
||||
<Route path="/imieibandi/:id/" element={<DefaultLayout>
|
||||
{'ROLE_SUPER_ADMIN' === role ? <PageNotFound/> : null}
|
||||
{'ROLE_BENEFICIARY' === role ? <BandoApplication/> : null}
|
||||
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||
</DefaultLayout>}/>
|
||||
<Route path="/valutazioni" element={<DefaultLayout>
|
||||
{'ROLE_SUPER_ADMIN' === role ? <PageNotFound/> : null}
|
||||
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
||||
{'ROLE_PRE_INSTRUCTOR' === role ? <Evaluations/> : null}
|
||||
</DefaultLayout>}/>
|
||||
<Route path="/valutazioni/:id/" element={<DefaultLayout>
|
||||
{'ROLE_SUPER_ADMIN' === role ? <PageNotFound/> : null}
|
||||
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
||||
{'ROLE_PRE_INSTRUCTOR' === role ? <EvaluationEdit/> : null}
|
||||
</DefaultLayout>}/>
|
||||
<Route path="/profilo" element={<DefaultLayout>
|
||||
{'ROLE_SUPER_ADMIN' === role ? <Profile/> : null}
|
||||
{'ROLE_BENEFICIARY' === role ? <Profile/> : null}
|
||||
{'ROLE_BENEFICIARY' === role ? <ProfileBeneficiario/> : null}
|
||||
{'ROLE_PRE_INSTRUCTOR' === role ? <Profile/> : null}
|
||||
</DefaultLayout>}/>
|
||||
<Route path="/profilo-aziendale" element={<DefaultLayout>
|
||||
{'ROLE_SUPER_ADMIN' === role ? <PageNotFound/> : null}
|
||||
{'ROLE_BENEFICIARY' === role && chosenCompanyId > 0 ? <ProfileCompany/> : <PageNotFound/>}
|
||||
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||
</DefaultLayout>}/>
|
||||
<Route path="/agguingi-azienda" element={<DefaultLayout>
|
||||
{'ROLE_SUPER_ADMIN' === role ? <PageNotFound/> : null}
|
||||
{'ROLE_BENEFICIARY' === role ? <AddCompany/> : null}
|
||||
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||
</DefaultLayout>}/>
|
||||
<Route path="/utenti" element={<DefaultLayout>
|
||||
{'ROLE_SUPER_ADMIN' === role ? <Users/> : null}
|
||||
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
||||
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||
</DefaultLayout>}/>
|
||||
</Route>
|
||||
<Route exact path="/reset-password" element={<ResetPassword/>}/>
|
||||
|
||||
@@ -17,6 +17,7 @@ const initialStore = {
|
||||
elementItems: [],
|
||||
activeElement: '',
|
||||
draggingElementId: 0,
|
||||
bandoCriteria: [],
|
||||
// flow
|
||||
flowData: [],
|
||||
flowForms: [],
|
||||
|
||||
Reference in New Issue
Block a user