diff --git a/package.json b/package.json
index b1eef76..c998aa0 100644
--- a/package.json
+++ b/package.json
@@ -8,7 +8,8 @@
"@date-fns/tz": "1.1.2",
"@emailjs/browser": "^4.4.1",
"@emotion/styled": "11.13.0",
- "@tanstack/react-table": "8.20.5",
+ "@number-flow/react": "0.2.0",
+ "@tanstack/react-table": "^8.20.5",
"@wordpress/i18n": "5.8.0",
"@wordpress/react-i18n": "4.8.0",
"@xyflow/react": "12.3.1",
diff --git a/src/assets/scss/components/appForm.scss b/src/assets/scss/components/appForm.scss
index db6b970..bb2c482 100644
--- a/src/assets/scss/components/appForm.scss
+++ b/src/assets/scss/components/appForm.scss
@@ -2,6 +2,7 @@
display: flex;
flex-direction: column;
gap: 24px;
+ width: 100%;
}
.appForm__field {
position: relative;
@@ -10,6 +11,11 @@
gap: 14px;
padding: 5px 0;
width: 100%;
+
+ &.row {
+ flex-direction: row;
+ align-items: center;
+ }
label {
font-size: 14px;
diff --git a/src/assets/scss/components/appPage.scss b/src/assets/scss/components/appPage.scss
index 522398d..fab7e1e 100644
--- a/src/assets/scss/components/appPage.scss
+++ b/src/assets/scss/components/appPage.scss
@@ -88,6 +88,18 @@
display: flex;
flex-direction: column;
align-items: flex-start;
+ width: 100%;
+
+ &.columns {
+ display: grid;
+ gap: 1rem;
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+ width: 100%;
+
+ /*> div {
+ max-width: 50%;
+ }*/
+ }
h2 {
color: var(--global-textColor);
@@ -98,11 +110,27 @@
margin: 0 0 24px;
}
+ h3 {
+ color: var(--global-textColor);
+ font-size: 16px;
+ font-style: normal;
+ font-weight: 600;
+ line-height: normal;
+ margin: 0 0 16px;
+ }
+
.row {
display: flex;
gap: 1rem;
align-items: center;
padding: 5px 0;
+ width: 100%;
+ }
+
+ .col {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
}
}
@@ -117,6 +145,10 @@
container-name: section_with_border;
container-type: inline-size;
+ &.grey {
+ border-color: var(--table-border-color)
+ }
+
&.disabled {
filter: grayscale(1);
opacity: 0.8;
@@ -149,14 +181,101 @@
flex: 1 1 100%;
}
- ul {
+ ul, ol {
padding-left: 1rem;
+
+ li {
+ color: var(--global-textColor);
+ }
+ }
+
+ a {
+ color: var(--global-textColor);
+ text-decoration: underline;
+
+ &:hover {
+ text-decoration: none;
+ }
}
button {
flex: 0 0 auto;
}
}
+
+ &.columns {
+ gap: 2em;
+ column-count: 2;
+ column-width: 4em;
+ display: block;
+ padding-bottom: 0;
+
+ .appPageSection__pMeta {
+ margin-bottom: 1em;
+ }
+ }
+}
+
+.appPageSection__list {
+ display: flex;
+ flex-direction: column;
+ padding: 0;
+ width: 100%;
+
+ > li {
+ padding: 15px;
+ border-bottom: 1px solid var(--button-secondary-borderColor);
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ flex-direction: column;
+ gap: 1rem;
+
+ &.row {
+ flex-direction: row;
+ }
+ }
+}
+
+.appPageSection__checklist {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+
+ div {
+ display: flex;
+ gap: 0.5rem;
+ }
+}
+
+.appPageSection__iconActions {
+ display: flex;
+ gap: 0.5em;
+}
+
+.appPageSection__message {
+ display: flex;
+ align-items: center;
+ gap: 20px;
+ background: rgba(255, 242, 226, 0.7);
+ border-style: solid;
+ border-width: 0 0 0 6px;
+ padding: 1.25rem 1.75rem;
+ border-radius: 6px;
+
+ &.warning {
+ color: var(--message-warning-color);
+ border-color: var(--message-warning-color);
+ }
+
+ &.info {
+ color: var(--message-info-color);
+ border-color: var(--message-info-color);
+ }
+
+ .summary {
+ font-weight: bold;
+ }
}
@container section_with_border (max-width: 600px) {
@@ -215,6 +334,10 @@
font-weight: 600;
line-height: normal;
}
+
+ span:nth-of-type(2) {
+ font-weight: 400;
+ }
}
.appPageSection__table {
@@ -269,4 +392,12 @@
&[disabled] {
background-color: var(--message-info-background);
}
+}
+
+@media (max-width: 700px) {
+ .appPageSection {
+ &.columns {
+ grid-template-columns: 1fr;
+ }
+ }
}
\ No newline at end of file
diff --git a/src/assets/scss/components/evaluation.scss b/src/assets/scss/components/evaluation.scss
new file mode 100644
index 0000000..1498d2f
--- /dev/null
+++ b/src/assets/scss/components/evaluation.scss
@@ -0,0 +1,41 @@
+.criterionRelatedData {
+ display: flex;
+ flex-direction: column;
+ gap: 15px;
+ max-height: 400px;
+ overflow-y: auto;
+ padding: 0 0 10px 0;
+
+ > h3 {
+ margin: 0;
+ }
+}
+
+.criterionRelatedData__item {
+ display: flex;
+ flex-direction: column;
+ gap: 7px;
+ padding: 10px;
+ background-color: #f5f5f5;
+ font-size: 14px;
+
+ ul {
+ margin: 0;
+ padding-left: 15px;
+
+ li a {
+ text-decoration: underline;
+ color: var(--global-textColor);
+ }
+ }
+
+ table, th, td {
+ border: 1px solid var(--table-border-color);
+ border-collapse: collapse;
+ text-align: left;
+ }
+
+ th, td {
+ padding: 3px;
+ }
+}
\ No newline at end of file
diff --git a/src/assets/scss/components/layout.scss b/src/assets/scss/components/layout.scss
index 1792b9d..d4e3572 100644
--- a/src/assets/scss/components/layout.scss
+++ b/src/assets/scss/components/layout.scss
@@ -12,9 +12,19 @@ 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),
- input, label:not(.p-error), textarea, a, li, h1, h2, h3, h4, h5, h6, div:not(.p-inline-message, .p-toast-detail), th, td {
+ /*p, span:not(.p-button-label, .p-button-icon, .p-badge, .p-message-detail, .p-message-summary, .p-highlight, .p-inline-message-text, .p-tag, .p-tag-icon),
+ input:not(.p-checkbox-input),
+ label:not(.p-error), textarea, a, li, h1, h2, h3, h4, h5, h6, div:not(.p-inline-message, .p-toast-detail, .p-checkbox-box), th, td,
+ :not(svg, path, .p-button, .p-button > span, .statsBigBadges__gridItem > span, number-flow, .p-paginator-page, .p-badge) {
color: var(--global-textColor);
+ }*/
+
+ h2, h3, p, label, .appPageSection__hr, li {
+ color: var(--global-textColor);
+ }
+
+ textarea {
+ max-width: 100%;
}
}
@@ -87,6 +97,12 @@ img {
color: white;
}
+ svg {
+ path {
+ fill: white;
+ }
+ }
+
span {
color: var(--menuitem-active-color);
}
diff --git a/src/assets/scss/components/misc.scss b/src/assets/scss/components/misc.scss
index b2c5847..8d5a701 100644
--- a/src/assets/scss/components/misc.scss
+++ b/src/assets/scss/components/misc.scss
@@ -113,16 +113,15 @@
background-color: rgba(255,255,255,0.3)
}
-.p-inputgroup {
- align-items: center;
-}
-
.p-accordion-header-text, .p-accordion-content {
p {
margin: 0;
}
}
+.p-inputgroup.flex-1 {
+ align-items: center;
+}
.flex-1 {
display: flex;
align-items: center;
diff --git a/src/assets/scss/components/myTable.scss b/src/assets/scss/components/myTable.scss
new file mode 100644
index 0000000..bbfbb2a
--- /dev/null
+++ b/src/assets/scss/components/myTable.scss
@@ -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;
+ }
+}
\ No newline at end of file
diff --git a/src/assets/scss/theme.scss b/src/assets/scss/theme.scss
index 08279a3..2bd1bad 100644
--- a/src/assets/scss/theme.scss
+++ b/src/assets/scss/theme.scss
@@ -18,6 +18,7 @@
--table-border-color: #B7B7B7B2;
--message-error-background: #ffdbdb;
--message-error-color: #C2504D;
+ --message-warning-color: #cc8925;
--message-info-background: rgba(183, 183, 183, 0.7);
--message-info-color: #3B82F6;
@@ -40,4 +41,6 @@
@import "./components/misc.scss";
@import "./components/login.scss";
@import "./components/flowBuilder.scss";
-@import "./components/error404.scss";
\ No newline at end of file
+@import "./components/error404.scss";
+@import "./components/myTable.scss";
+@import "./components/evaluation.scss";
\ No newline at end of file
diff --git a/src/components/TopBarProfileMenu/index.js b/src/components/TopBarProfileMenu/index.js
index 32bfac6..4288572 100644
--- a/src/components/TopBarProfileMenu/index.js
+++ b/src/components/TopBarProfileMenu/index.js
@@ -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,
@@ -86,7 +86,7 @@ const TopBarProfileMenu = ({ menuLeftRef }) => {
const switchCompany = (id) => {
if (chosenCompanyId !== id) {
storeSet.main.chosenCompanyId(id);
- console.log('set company 2', id)
+
if (toast.current) {
toast.current.show({
severity: 'success',
diff --git a/src/components/UnsavedChangesDetector/index.js b/src/components/UnsavedChangesDetector/index.js
index 71c967e..86c21fd 100644
--- a/src/components/UnsavedChangesDetector/index.js
+++ b/src/components/UnsavedChangesDetector/index.js
@@ -2,17 +2,62 @@ import { useEffect } from 'react';
import { __ } from '@wordpress/i18n';
import equal from 'fast-deep-equal';
//import { diff } from 'deep-object-diff';
+import { klona } from 'klona';
+import { TZDate } from '@date-fns/tz';
+import { wrap } from 'object-path-immutable';
+import { is, isNil } from 'ramda';
// store
import { storeGet } from '../../store';
const UnsavedChangesDetector = ({ getValuesFn }) => {
const warnIfUnsavedChanges = (event) => {
- const formData = getValuesFn();
+ let formData = klona(getValuesFn());
+ formData.dates = [];
+
+ if (formData.startDate) {
+ let starDate;
+
+ if (is(String, formData.startDate)) {
+ starDate = formData.startDate;
+ } else {
+ const tzAwareDate = new TZDate(formData.startDate, 'Europe/Berlin');
+ starDate = tzAwareDate.toISOString().substring(0, 19);
+ }
+
+ formData = wrap(formData).insert(['dates'], starDate, 0).value();
+ }
+ if (formData.endDate) {
+ let endDate;
+
+ if (is(String, formData.endDate)) {
+ endDate = formData.endDate;
+ } else {
+ const tzAwareDate = new TZDate(formData.endDate, 'Europe/Berlin');
+ endDate = tzAwareDate.toISOString().substring(0, 19);
+ }
+
+ formData = wrap(formData).insert(['dates'], endDate, 1).value();
+ }
+ if (!isNil(formData.startTime)) {
+ if (!is(String, formData.startTime)) {
+ const tzAwareDate = new TZDate(formData.startTime, 'Europe/Berlin');
+ formData.startTime = tzAwareDate.toISOString().substring(11, 16);
+ }
+ }
+ if (!isNil(formData.endTime)) {
+ if (!is(String, formData.endTime)) {
+ const tzAwareDate = new TZDate(formData.endTime, 'Europe/Berlin');
+ formData.endTime = tzAwareDate.toISOString().substring(11, 16);
+ }
+ }
const initial = storeGet.main.formInitialData();
+
const isEqual = equal(initial, formData);
// TODO
- //console.log('isEqual', isEqual, initial, formData, diff(initial, formData))
+ /*console.log('isEqual', isEqual,
+ initial, formData,
+ diff(initial, formData))*/
if (!isEqual) {
event.returnValue = __('You have unsaved changes. If you proceed, they will be lost.', 'gepafin');
}
diff --git a/src/helpers/getBandoLabel.js b/src/helpers/getBandoLabel.js
index 35a850e..43abcd3 100644
--- a/src/helpers/getBandoLabel.js
+++ b/src/helpers/getBandoLabel.js
@@ -17,6 +17,9 @@ const getBandoLabel = (status) => {
case 'READY':
return __('Pronto', 'gepafin');
+ case 'SOCCORSO':
+ return __('Soccorso', 'gepafin');
+
case 'DRAFT':
return __('Bozza', 'gepafin');
@@ -38,6 +41,9 @@ const getBandoLabel = (status) => {
case 'EXPIRED':
return __('Scaduto', 'gepafin');
+ case 'CLOSE':
+ return __('Chiuso', 'gepafin');
+
default:
return '';
}
diff --git a/src/helpers/getBandoSeverity.js b/src/helpers/getBandoSeverity.js
index d090c80..631cfe6 100644
--- a/src/helpers/getBandoSeverity.js
+++ b/src/helpers/getBandoSeverity.js
@@ -15,6 +15,9 @@ const getBandoSeverity = (status) => {
case 'READY':
return 'info';
+ case 'SOCCORSO':
+ return 'warning';
+
case 'DRAFT':
return 'warning';
@@ -36,6 +39,9 @@ const getBandoSeverity = (status) => {
case 'EXPIRED':
return 'closed';
+ case 'CLOSE':
+ return 'closed';
+
default:
return 'info';
}
diff --git a/src/helpers/renderHtmlContent.js b/src/helpers/renderHtmlContent.js
index 672546a..2da65aa 100644
--- a/src/helpers/renderHtmlContent.js
+++ b/src/helpers/renderHtmlContent.js
@@ -1,6 +1,10 @@
import parse from 'html-react-parser';
import { isNil } from 'ramda';
+import DOMPurify from 'dompurify';
-const renderHtmlContent = (content = '') => !isNil(content) ? parse(content) : '';
+const renderHtmlContent = (content = '') => {
+ const clean = DOMPurify.sanitize(content);
+ return !isNil(clean) ? parse(clean) : '';
+}
export default renderHtmlContent;
\ No newline at end of file
diff --git a/src/icons/HelpIcon/index.js b/src/icons/HelpIcon/index.js
new file mode 100644
index 0000000..26dfcd7
--- /dev/null
+++ b/src/icons/HelpIcon/index.js
@@ -0,0 +1,20 @@
+import React from 'react';
+
+const HelpIcon = () => {
+ return
+}
+
+export default HelpIcon;
\ No newline at end of file
diff --git a/src/layouts/DefaultLayout/components/AppSidebar/index.js b/src/layouts/DefaultLayout/components/AppSidebar/index.js
index 61a4484..5155f78 100644
--- a/src/layouts/DefaultLayout/components/AppSidebar/index.js
+++ b/src/layouts/DefaultLayout/components/AppSidebar/index.js
@@ -1,12 +1,13 @@
import React from 'react';
import { __ } from '@wordpress/i18n';
-import { intersection } from 'ramda';
+import { intersection, is } from 'ramda';
// store
import { useStore } from '../../../../store';
// components
import { NavLink } from 'react-router-dom';
+import HelpIcon from '../../../../icons/HelpIcon';
const AppSidebar = () => {
const permissions = useStore().main.getPermissions();
@@ -41,32 +42,59 @@ const AppSidebar = () => {
enable: intersection(permissions, ['VIEW_CALLS']).length
},
{
- label: __('Gestione Utenti', 'gepafin'),
+ label: __('Gestione domande', 'gepafin'),
+ icon: 'pi pi-file',
+ href: '/domande',
+ id: 5,
+ enable: intersection(permissions, ['VIEW_USERS', 'MANAGE_USERS']).length
+ },
+ {
+ label: __('Domande da valutare', 'gepafin'),
+ icon: 'pi pi-calendar-clock',
+ href: '/domande',
+ id: 6,
+ enable: intersection(permissions, ['EVALUATE_APPLICATIONS']).length
+ },
+ {
+ label: __('Archivio domande', 'gepafin'),
+ icon: 'pi pi-file',
+ href: '/domande',
+ id: 7,
+ enable: intersection(permissions, ['APPLY_CALLS']).length
+ },
+ {
+ label: __('Soccorso istruttorio', 'gepafin'),
+ icon: ,
+ href: '/soccorso-istruttorio',
+ id: 8,
+ enable: intersection(permissions, ['EVALUATE_APPLICATIONS']).length
+ },
+ {
+ label: __('Gestione utenti', 'gepafin'),
icon: 'pi pi-users',
href: '/utenti',
- id: 5,
- enable: false
- //enable: intersection(permissions, ['VIEW_USERS', 'MANAGE_USERS']).length
+ id: 9,
+ enable: intersection(permissions, ['VIEW_USERS', 'MANAGE_USERS']).length
},
{
label: __('Configurazione', 'gepafin'),
icon: 'pi pi-cog',
//href: '/configurazione',
- id: 6,
+ id: 10,
enable: false
},
{
label: __('Report e Analisi', 'gepafin'),
icon: 'pi pi-chart-bar',
//href: '/stats',
- id: 7,
+ id: 11,
enable: false
},
{
label: __('Log di Sistema', 'gepafin'),
icon: 'pi pi-receipt',
clickFn: () => {},
- id: 8,
+ id: 12,
enable: false
}
]
@@ -78,11 +106,15 @@ const AppSidebar = () => {
.map(o =>
{o.href
?
-
+ {is(String, o.icon)
+ ?
+ : o.icon}
{o.label}
: }
)}
diff --git a/src/layouts/DefaultLayout/components/AppTopbar/index.js b/src/layouts/DefaultLayout/components/AppTopbar/index.js
index 3627539..af1e9a8 100644
--- a/src/layouts/DefaultLayout/components/AppTopbar/index.js
+++ b/src/layouts/DefaultLayout/components/AppTopbar/index.js
@@ -27,9 +27,10 @@ const AppTopbar = () => {
-
+
+ {/*
-
+ */}