diff --git a/src/assets/fonts/montserrat-v26-latin-600.woff2 b/src/assets/fonts/montserrat-v26-latin-600.woff2
new file mode 100644
index 0000000..a0bfc7b
Binary files /dev/null and b/src/assets/fonts/montserrat-v26-latin-600.woff2 differ
diff --git a/src/assets/fonts/montserrat-v26-latin-700.woff2 b/src/assets/fonts/montserrat-v26-latin-700.woff2
new file mode 100644
index 0000000..cf273a0
Binary files /dev/null and b/src/assets/fonts/montserrat-v26-latin-700.woff2 differ
diff --git a/src/assets/fonts/montserrat-v26-latin-800.woff2 b/src/assets/fonts/montserrat-v26-latin-800.woff2
new file mode 100644
index 0000000..d69d4a1
Binary files /dev/null and b/src/assets/fonts/montserrat-v26-latin-800.woff2 differ
diff --git a/src/assets/fonts/montserrat-v26-latin-italic.woff2 b/src/assets/fonts/montserrat-v26-latin-italic.woff2
new file mode 100644
index 0000000..17a8120
Binary files /dev/null and b/src/assets/fonts/montserrat-v26-latin-italic.woff2 differ
diff --git a/src/assets/fonts/montserrat-v26-latin-regular.woff2 b/src/assets/fonts/montserrat-v26-latin-regular.woff2
new file mode 100644
index 0000000..f4b26df
Binary files /dev/null and b/src/assets/fonts/montserrat-v26-latin-regular.woff2 differ
diff --git a/src/assets/scss/components/appForm.scss b/src/assets/scss/components/appForm.scss
new file mode 100644
index 0000000..63ffb5f
--- /dev/null
+++ b/src/assets/scss/components/appForm.scss
@@ -0,0 +1,10 @@
+.appForm {
+ display: flex;
+ flex-direction: column;
+ gap: 24px;
+}
+.appForm__field {
+ display: flex;
+ flex-direction: column;
+ gap: 14px;
+}
\ No newline at end of file
diff --git a/src/assets/scss/components/appPage.css b/src/assets/scss/components/appPage.css
deleted file mode 100644
index 6b3d2e8..0000000
--- a/src/assets/scss/components/appPage.css
+++ /dev/null
@@ -1,22 +0,0 @@
-.appPage {
- display: flex;
- flex-direction: column;
-
- h1 {
- color: var(--primary-color);
- font-size: 28px;
- font-style: normal;
- font-weight: 600;
- line-height: normal;
- margin: 28px 0;
- }
-
- h2 {
- color: var(--Black);
- font-size: 21px;
- font-style: normal;
- font-weight: 600;
- line-height: normal;
- margin: 24px 0;
- }
-}
\ No newline at end of file
diff --git a/src/assets/scss/components/appPage.scss b/src/assets/scss/components/appPage.scss
new file mode 100644
index 0000000..59a9994
--- /dev/null
+++ b/src/assets/scss/components/appPage.scss
@@ -0,0 +1,67 @@
+.appPage {
+ display: flex;
+ flex-direction: column;
+
+ h1 {
+ color: var(--primary-color);
+ font-size: 28px;
+ font-style: normal;
+ font-weight: 600;
+ line-height: normal;
+ }
+}
+
+.appPageSection {
+ display: flex;
+ flex-direction: column;
+
+ h2 {
+ color: var(--Black);
+ font-size: 21px;
+ font-style: normal;
+ font-weight: 600;
+ line-height: normal;
+ margin: 0 0 24px;
+ }
+}
+
+.appTableHeader {
+ display: flex;
+ justify-content: space-between;
+}
+
+.appPage__pageHeader {
+ display: flex;
+ flex-direction: column;
+ gap: 14px;
+ padding: 28px;
+
+ h1, h2, h3 {
+ margin: 0;
+ }
+
+ p, span {
+ color: var(--text-color-secondary);
+ font-size: 17.5px;
+ font-style: normal;
+ font-weight: 400;
+ line-height: 120%;
+ margin: 0;
+ }
+
+ span {
+ margin-left: 10px;
+ text-transform: uppercase;
+ }
+}
+
+.appPage__spacer {
+ width: 100%;
+ padding: 24px 0;
+}
+
+.appPageSection__actions {
+ display: flex;
+ gap: 24px;
+ margin-bottom: 24px;
+}
\ No newline at end of file
diff --git a/src/assets/scss/components/bandoStatusTag.scss b/src/assets/scss/components/bandoStatusTag.scss
new file mode 100644
index 0000000..bc428a8
--- /dev/null
+++ b/src/assets/scss/components/bandoStatusTag.scss
@@ -0,0 +1,7 @@
+.bandoStatusTag {
+ text-transform: uppercase;
+ font-size: 10.5px;
+ font-style: normal;
+ font-weight: 600;
+ line-height: 150%;
+}
\ No newline at end of file
diff --git a/src/assets/scss/components/statsBigBadges.css b/src/assets/scss/components/statsBigBadges.scss
similarity index 93%
rename from src/assets/scss/components/statsBigBadges.css
rename to src/assets/scss/components/statsBigBadges.scss
index 8a60fd9..70c01ea 100644
--- a/src/assets/scss/components/statsBigBadges.css
+++ b/src/assets/scss/components/statsBigBadges.scss
@@ -1,7 +1,4 @@
.statsBigBadges {
- display: flex;
- flex-direction: column;
- padding: 24px 0;
}
.statsBigBadges__grid {
display: grid;
diff --git a/src/assets/scss/components/topBar.css b/src/assets/scss/components/topBar.scss
similarity index 100%
rename from src/assets/scss/components/topBar.css
rename to src/assets/scss/components/topBar.scss
diff --git a/src/assets/scss/gepafin/_fonts.scss b/src/assets/scss/gepafin/_fonts.scss
index e69de29..341a320 100644
--- a/src/assets/scss/gepafin/_fonts.scss
+++ b/src/assets/scss/gepafin/_fonts.scss
@@ -0,0 +1,44 @@
+/* montserrat-regular - latin */
+@font-face {
+ font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
+ font-family: 'Montserrat';
+ font-style: normal;
+ font-weight: 400;
+ src: url('../../fonts/montserrat-v26-latin-regular.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
+}
+
+/* montserrat-italic - latin */
+@font-face {
+ font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
+ font-family: 'Montserrat';
+ font-style: italic;
+ font-weight: 400;
+ src: url('../../fonts/montserrat-v26-latin-italic.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
+}
+
+/* montserrat-600 - latin */
+@font-face {
+ font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
+ font-family: 'Montserrat';
+ font-style: normal;
+ font-weight: 600;
+ src: url('../../fonts/montserrat-v26-latin-600.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
+}
+
+/* montserrat-700 - latin */
+@font-face {
+ font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
+ font-family: 'Montserrat';
+ font-style: normal;
+ font-weight: 700;
+ src: url('../../fonts/montserrat-v26-latin-700.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
+}
+
+/* montserrat-800 - latin */
+@font-face {
+ font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
+ font-family: 'Montserrat';
+ font-style: normal;
+ font-weight: 800;
+ src: url('../../fonts/montserrat-v26-latin-800.woff2') format('woff2'); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
+}
diff --git a/src/assets/scss/gepafin/_variables.scss b/src/assets/scss/gepafin/_variables.scss
index 7fe6834..8d8e1ca 100644
--- a/src/assets/scss/gepafin/_variables.scss
+++ b/src/assets/scss/gepafin/_variables.scss
@@ -1,6 +1,6 @@
-$primaryColor: #4A644E;
-$primaryDarkColor: #4A644E;
-$primaryDarkerColor: #4A644E;
+$primaryColor: #3B7C43;
+$primaryDarkColor: #3B7C43;
+$primaryDarkerColor: #3B7C43;
$primaryTextColor: #ffffff;
$chipBg: $primaryColor;
@@ -10,6 +10,7 @@ $chipFocusBg: $primaryColor;
$chipFocusTextColor: $primaryTextColor;
$colors: (
+ "grey": #6B7280,
"blue": #2196F3,
"green": #4caf50,
"yellow": #FBC02D,
diff --git a/src/assets/scss/gepafin/variables/_button.scss b/src/assets/scss/gepafin/variables/_button.scss
index fbe6feb..a2b9743 100644
--- a/src/assets/scss/gepafin/variables/_button.scss
+++ b/src/assets/scss/gepafin/variables/_button.scss
@@ -147,13 +147,16 @@ $successButtonActiveBorderColor: #388E3C;
$successButtonFocusShadow: 0 0 0 0.2rem lighten($successButtonBg, 35%);
-$warningButtonBg: #FFC107;
+$warningButtonBg: #F97316;
+
+
+$closedButtonBg: #6B7280;
$warningButtonTextColor: $textColor;
-$warningButtonBorder: 1px solid #FFC107;
+$warningButtonBorder: 1px solid #F97316;
$warningButtonHoverBg: #FFB300;
diff --git a/src/assets/scss/theme-base/components/misc/_badge.scss b/src/assets/scss/theme-base/components/misc/_badge.scss
index cb73e69..450d7dc 100644
--- a/src/assets/scss/theme-base/components/misc/_badge.scss
+++ b/src/assets/scss/theme-base/components/misc/_badge.scss
@@ -67,7 +67,7 @@
&.p-tag-warning {
background-color: $warningButtonBg;
- color: $warningButtonTextColor;
+ color: $dangerButtonTextColor;
}
&.p-tag-danger {
diff --git a/src/assets/scss/theme-base/components/misc/_tag.scss b/src/assets/scss/theme-base/components/misc/_tag.scss
index 2a2453d..edb8235 100644
--- a/src/assets/scss/theme-base/components/misc/_tag.scss
+++ b/src/assets/scss/theme-base/components/misc/_tag.scss
@@ -20,7 +20,7 @@
&.p-tag-warning {
background-color: $warningButtonBg;
- color: $warningButtonTextColor;
+ color: $dangerButtonTextColor;
}
&.p-tag-danger {
@@ -28,6 +28,11 @@
color: $dangerButtonTextColor;
}
+ &.p-tag-closed {
+ background-color: $closedButtonBg;
+ color: $dangerButtonTextColor;
+ }
+
.p-tag-icon {
margin-right: math.div($inlineSpacing, 2);
font-size: $badgeFontSize;
diff --git a/src/assets/scss/theme.scss b/src/assets/scss/theme.scss
index 5ba4b2c..bff55e7 100644
--- a/src/assets/scss/theme.scss
+++ b/src/assets/scss/theme.scss
@@ -16,22 +16,38 @@
--card-full-background-color-1: #3B7C43;
}
-body {
- margin: 0;
-}
-
-.wrapper {
+html {
+ min-height: 100%;
display: flex;
flex-direction: column;
- height: 100vh;
- min-height: 0;
+}
+
+body {
+ min-height: 100%;
+ display: flex;
+ flex-direction: column;
+ flex-grow: 1;
+ margin: 0;
+ font-family: 'Montserrat';
+
+ p, span, input, label, textarea, a, li, h1, h2, h3, h4, h5, h6, div, th, td, button {
+ font-family: 'Montserrat';
+ }
+}
+
+#root, .wrapper {
+ min-height: 100%;
+ display: flex;
+ flex-direction: column;
+ flex-grow: 1;
}
.inner {
display: flex;
height: 100%;
min-height: 0;
+ flex-grow: 1;
- > sidebar {
+ > aside {
flex: 0 0 320px;
border-right: 1px solid var(--menu-borderColor);
@@ -42,11 +58,13 @@ body {
margin: 0;
padding: 0;
- li a {
+ li a, li button {
display: flex;
padding: 10.5px 17.5px;
align-items: center;
gap: 7px;
+ width: 100%;
+ border: 0;
border-bottom: 1px solid var(--menu-borderColor);
color: var(--menuitem-color);
background-color: transparent;
@@ -56,6 +74,10 @@ body {
line-height: 100%;
text-decoration: none;
+ &:hover {
+ cursor: pointer;
+ }
+
i {
color: var(--text-color-secondary);
}
@@ -75,10 +97,12 @@ body {
> main {
flex: 1 1 auto;
box-sizing: border-box;
- padding: 0 24px;
+ padding: 0 24px 50px;
}
}
-@import "./components/topBar.css";
-@import "./components/appPage.css";
-@import "./components/statsBigBadges.css";
\ No newline at end of file
+@import "./components/topBar.scss";
+@import "./components/appPage.scss";
+@import "./components/statsBigBadges.scss";
+@import "./components/bandoStatusTag.scss";
+@import "./components/appForm.scss";
\ No newline at end of file
diff --git a/src/components/ProperBandoLabel/index.js b/src/components/ProperBandoLabel/index.js
new file mode 100644
index 0000000..e8bee90
--- /dev/null
+++ b/src/components/ProperBandoLabel/index.js
@@ -0,0 +1,16 @@
+import React from 'react';
+
+// tools
+import getBandoLabel from '../../helpers/getBandoLabel';
+import getBandoSeverity from '../../helpers/getBandoSeverity';
+
+// components
+import { Tag } from 'primereact/tag';
+
+const ProperBandoLabel = ({ status }) => {
+ return(
+
+ )
+}
+
+export default ProperBandoLabel;
\ No newline at end of file
diff --git a/src/helpers/getBandoLabel.js b/src/helpers/getBandoLabel.js
new file mode 100644
index 0000000..2802fd0
--- /dev/null
+++ b/src/helpers/getBandoLabel.js
@@ -0,0 +1,19 @@
+import { __ } from '@wordpress/i18n';
+
+const getBandoLabel = (status) => {
+ switch (status) {
+ case 'publish':
+ return __('Pubblicato', 'gepafin');
+
+ case 'draft':
+ return __('Bozza', 'gepafin');
+
+ case 'closed':
+ return __('Chiuso', 'gepafin');
+
+ default:
+ return '';
+ }
+};
+
+export default getBandoLabel;
\ No newline at end of file
diff --git a/src/helpers/getBandoSeverity.js b/src/helpers/getBandoSeverity.js
new file mode 100644
index 0000000..f60c933
--- /dev/null
+++ b/src/helpers/getBandoSeverity.js
@@ -0,0 +1,17 @@
+const getBandoSeverity = (status) => {
+ switch (status) {
+ case 'publish':
+ return 'success';
+
+ case 'draft':
+ return 'warning';
+
+ case 'closed':
+ return 'closed';
+
+ default:
+ return 'info';
+ }
+};
+
+export default getBandoSeverity;
\ 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 c2865a8..504073a 100644
--- a/src/layouts/DefaultLayout/components/AppSidebar/index.js
+++ b/src/layouts/DefaultLayout/components/AppSidebar/index.js
@@ -2,37 +2,38 @@ import React from 'react';
import { __ } from '@wordpress/i18n';
// components
+import { NavLink } from 'react-router-dom';
const AppSidebar = () => {
const items = [
{
label: __('Riepilogo', 'gepafin'),
icon: 'pi pi-objects-column',
- clickFn: () => {},
+ href: '/',
id: 1
},
{
label: __('Gestione Bandi', 'gepafin'),
icon: 'pi pi-file',
- clickFn: () => {},
+ href: '/bandi',
id: 2
},
{
label: __('Gestione Utenti', 'gepafin'),
icon: 'pi pi-users',
- clickFn: () => {},
+ href: '/utenti',
id: 3
},
{
label: __('Configurazione', 'gepafin'),
icon: 'pi pi-cog',
- clickFn: () => {},
+ href: '/configurazione',
id: 4
},
{
label: __('Report e Analisi', 'gepafin'),
icon: 'pi pi-chart-bar',
- clickFn: () => {},
+ href: '/stats',
id: 5
},
{
@@ -43,16 +44,21 @@ const AppSidebar = () => {
}
]
- return
+ return
+
}
export default AppSidebar;
\ No newline at end of file
diff --git a/src/pages/Bandi/components/AllBandiTable/index.js b/src/pages/Bandi/components/AllBandiTable/index.js
new file mode 100644
index 0000000..f93d20c
--- /dev/null
+++ b/src/pages/Bandi/components/AllBandiTable/index.js
@@ -0,0 +1,175 @@
+import React, { useState, useEffect} from 'react';
+import { __ } from '@wordpress/i18n';
+import { uniq } from 'ramda';
+
+// tools
+import getBandoSeverity from '../../../../helpers/getBandoSeverity';
+import getBandoLabel from '../../../../helpers/getBandoLabel';
+
+// 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 { 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 AllBandiTable = () => {
+ const [items, setItems] = useState(null);
+ const [filters, setFilters] = useState(null);
+ const [loading, setLoading] = 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: 'draft',
+ 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: 'closed',
+ id: 2
+ }
+ ]
+ setItems(getFormattedBandiData(items));
+ setStatuses(uniq(items.map(o => o.status)))
+ setLoading(false);
+ initFilters();
+ }, []);
+
+ const getFormattedBandiData = (data) => {
+ return [...(data || [])].map((d) => {
+ d.start_date = new Date(d.start_date);
+ d.end_date = new Date(d.end_date);
+
+ 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 },
+ name: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] },
+ start_date: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] },
+ end_date: { 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 dateStartBodyTemplate = (rowData) => {
+ return formatDate(rowData.start_date);
+ };
+
+ const dateEndBodyTemplate = (rowData) => {
+ return formatDate(rowData.end_date);
+ };
+
+ 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 statusItemTemplate = (option) => {
+ return ;
+ };
+
+ const actionsBodyTemplate = (rowData) => {
+ return
+
+
+ }
+
+ const header = renderHeader();
+
+ return(
+
+ setFilters(e.filters)}>
+
+
+
+
+
+
+
+ )
+}
+
+export default AllBandiTable;
\ No newline at end of file
diff --git a/src/pages/Bandi/index.js b/src/pages/Bandi/index.js
new file mode 100644
index 0000000..dee6056
--- /dev/null
+++ b/src/pages/Bandi/index.js
@@ -0,0 +1,37 @@
+import React from 'react';
+import { __ } from '@wordpress/i18n';
+import { useNavigate } from 'react-router-dom';
+
+// components
+import AllBandiTable from './components/AllBandiTable';
+import { Button } from 'primereact/button';
+
+const Bandi = () => {
+ const navigate = useNavigate();
+
+ const onGoToCreateNewBando = () => {
+ navigate('/bandi/new');
+ }
+
+ return(
+
+
+
{__('Gestione Bandi', 'gepafin')}
+
+
+
+
+
+
+ )
+}
+
+export default Bandi;
\ No newline at end of file
diff --git a/src/pages/Bando/index.js b/src/pages/Bando/index.js
new file mode 100644
index 0000000..ccfe821
--- /dev/null
+++ b/src/pages/Bando/index.js
@@ -0,0 +1,115 @@
+import React, { useState, useEffect } from 'react';
+import { __ } from '@wordpress/i18n';
+import { useParams } from 'react-router-dom';
+import { useForm, Controller } from 'react-hook-form';
+import { classNames } from 'primereact/utils';
+
+// components
+import { InputText } from 'primereact/inputtext';
+import { InputTextarea } from 'primereact/inputtextarea';
+import getBandoLabel from '../../helpers/getBandoLabel';
+import { Button } from 'primereact/button';
+
+const Bando = () => {
+ const { id } = useParams();
+ const [data, setData] = useState({});
+ const {
+ control,
+ reset,
+ handleSubmit,
+ formState: { errors },
+ getValues
+ } = useForm(data);
+ const onSubmit = data => console.log(data);
+ console.log(errors, getValues());
+
+ const onPublish = () => {
+ console.log('click onPublish');
+ }
+
+ useEffect(() => {
+ const parsed = parseInt(id)
+ const bandoId = !isNaN(parsed) ? parsed : 0;
+
+ const data = 0 === bandoId
+ ? {
+ status: 'draft',
+ name: null,
+ description: null
+ }
+ : {
+ name: 'Bando Innovazione 2024',
+ description: '',
+ start_date: '2024-08-08T00:00:00+00:00',
+ end_date: '2024-08-30T00:00:00+00:00',
+ submissions: 24,
+ status: 'publish',
+ id: 11
+ }
+ setData(data);
+ reset();
+ }, [id]);
+
+ return (
+
+
+
{__('Creazione/Modifica Bando', 'gepafin')}
+
+ {__('Stato:', 'gepafin')}
+ {getBandoLabel(data.status)}
+
+
+
+
+
+ {data
+ ?
: null}
+
+ )
+}
+
+export default Bando;
\ No newline at end of file
diff --git a/src/pages/Dashboard/components/LatestBandiTable/index.js b/src/pages/Dashboard/components/LatestBandiTable/index.js
new file mode 100644
index 0000000..00e92c3
--- /dev/null
+++ b/src/pages/Dashboard/components/LatestBandiTable/index.js
@@ -0,0 +1,176 @@
+import React, { useState, useEffect} from 'react';
+import { __ } from '@wordpress/i18n';
+import { uniq } from 'ramda';
+
+// tools
+import getBandoLabel from '../../../../helpers/getBandoLabel';
+import getBandoSeverity from '../../../../helpers/getBandoSeverity';
+
+// 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 { InputNumber } from 'primereact/inputnumber';
+import { Button } from 'primereact/button';
+import { Calendar } from 'primereact/calendar';
+import { Tag } from 'primereact/tag';
+import ProperBandoLabel from '../../../../components/ProperBandoLabel';
+
+
+const LatestBandiTable = () => {
+ const [items, setItems] = useState(null);
+ const [filters, setFilters] = useState(null);
+ const [loading, setLoading] = 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: 'closed',
+ id: 2
+ }
+ ]
+ setItems(getFormattedBandiData(items));
+ setStatuses(uniq(items.map(o => o.status)))
+ setLoading(false);
+ initFilters();
+ }, []);
+
+ const getFormattedBandiData = (data) => {
+ return [...(data || [])].map((d) => {
+ d.start_date = new Date(d.start_date);
+ d.end_date = new Date(d.end_date);
+
+ 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 },
+ name: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] },
+ start_date: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] },
+ end_date: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] },
+ submissions: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.EQUALS }] },
+ status: { operator: FilterOperator.OR, constraints: [{ value: null, matchMode: FilterMatchMode.EQUALS }] },
+ });
+ setGlobalFilterValue('');
+ };
+
+ const renderHeader = () => {
+ return (
+
+
+
+
+
+
+
+ );
+ };
+
+ const dateStartBodyTemplate = (rowData) => {
+ return formatDate(rowData.start_date);
+ };
+
+ const dateEndBodyTemplate = (rowData) => {
+ return formatDate(rowData.end_date);
+ };
+
+ const dateFilterTemplate = (options) => {
+ return options.filterCallback(e.value, options.index)} dateFormat="mm/dd/yy" placeholder="mm/dd/yyyy" mask="99/99/9999" />;
+ };
+
+ const balanceFilterTemplate = (options) => {
+ return options.filterCallback(e.value, options.index)} />;
+ };
+
+ 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 statusItemTemplate = (option) => {
+ return ;
+ };
+
+ const header = renderHeader();
+
+ return(
+
+ setFilters(e.filters)}>
+
+
+
+
+
+
+
+ )
+}
+
+export default LatestBandiTable;
\ No newline at end of file
diff --git a/src/pages/Dashboard/components/LatestUsersActivityTable/index.js b/src/pages/Dashboard/components/LatestUsersActivityTable/index.js
new file mode 100644
index 0000000..9aa34f1
--- /dev/null
+++ b/src/pages/Dashboard/components/LatestUsersActivityTable/index.js
@@ -0,0 +1,123 @@
+import React, { useState, useEffect} from 'react';
+import { __ } from '@wordpress/i18n';
+
+// 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 LatestUsersActivityTable = () => {
+ const [items, setItems] = useState(null);
+ const [filters, setFilters] = useState(null);
+ const [loading, setLoading] = useState(false);
+ const [globalFilterValue, setGlobalFilterValue] = useState('');
+
+ useEffect(() => {
+ // TODO
+ const bandi = [
+ {
+ date: '2024-08-02T00:00:00+14:32',
+ email: 'mario.rossi@gepafin.it',
+ action: 'Valutazione Domanda',
+ details: 'Bando Innovazione 2024 - Domanda #123',
+ id: 11
+ },
+ {
+ date: '2024-08-01T00:00:00+08:23',
+ email: 'laura.bianchi@gepafin.it',
+ action: 'Creazione Bando',
+ details: 'Nuovo bando "Formazione 2025" in bozza',
+ id: 9
+ }
+ ]
+ setItems(getFormattedBandiData(bandi));
+ setLoading(false);
+ initFilters();
+ }, []);
+
+ const getFormattedBandiData = (data) => {
+ return [...(data || [])].map((d) => {
+ d.date = new Date(d.date);
+
+ 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 },
+ email: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] },
+ date: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] },
+ });
+ setGlobalFilterValue('');
+ };
+
+ const renderHeader = () => {
+ return (
+
+
+
+
+
+
+
+ );
+ };
+
+ const dateBodyTemplate = (rowData) => {
+ return formatDate(rowData.date);
+ };
+
+ const dateFilterTemplate = (options) => {
+ return options.filterCallback(e.value, options.index)} dateFormat="mm/dd/yy" placeholder="mm/dd/yyyy" mask="99/99/9999" />;
+ };
+
+ const header = renderHeader();
+
+ return(
+
+ setFilters(e.filters)}>
+
+
+
+
+
+
+ )
+}
+
+export default LatestUsersActivityTable;
\ No newline at end of file
diff --git a/src/pages/Dashboard/index.js b/src/pages/Dashboard/index.js
index 319d996..dec0e5e 100644
--- a/src/pages/Dashboard/index.js
+++ b/src/pages/Dashboard/index.js
@@ -1,12 +1,40 @@
import React from 'react';
import { __ } from '@wordpress/i18n';
+import { useNavigate } from 'react-router-dom';
+
+// components
+import LatestBandiTable from './components/LatestBandiTable';
+import LatestUsersActivityTable from './components/LatestUsersActivityTable';
+import { Button } from 'primereact/button';
const Dashboard = () => {
+ const navigate = useNavigate();
+
+ const onGoToCreateNewBando = () => {
+ navigate('/bandi/new');
+ }
+
+ const onGoToUsers = () => {
+ console.log('onGoToUsers')
+ }
+
+ const onGoToStats = () => {
+ console.log('onGoToStats')
+ }
+
+ const onGoToSettings = () => {
+ console.log('onGoToSettings')
+ }
+
return(
-
{__('Dashboard', 'gepafin')}
+
+
{__('Dashboard', 'gepafin')}
+
-
+
+
+
{__('Panoramica di Sistema', 'gepafin')}
@@ -27,6 +55,43 @@ const Dashboard = () => {
+
+
+
+
+
{__('Ultimi Bandi Pubblicati', 'gepafin')}
+
+
+
+
+
+
+
{__('Attività Recenti Utenti', 'gepafin')}
+
+
+
+
+
+
+
{__('Collegamenti rapidi', 'gepafin')}
+
+
+
+
+
+
+
)
}
diff --git a/src/routes.js b/src/routes.js
index ebf1987..132b75e 100644
--- a/src/routes.js
+++ b/src/routes.js
@@ -6,11 +6,15 @@ import Login from './pages/Login';
import ProtectedRoute from './components/ProtectedRoute';
import Dashboard from './pages/Dashboard';
import DefaultLayout from './layouts/DefaultLayout';
+import Bandi from './pages/Bandi';
+import Bando from './pages/Bando';
const routes = () => (
}>
}/>
+ }/>
+ }/>
}/>
{/*}/>*/}