From 22453db22027de565471ccbc028aa21dbe0576d6 Mon Sep 17 00:00:00 2001 From: Vitalii Kiiko Date: Mon, 10 Feb 2025 17:16:34 +0100 Subject: [PATCH] - added beneficiary stats page; --- src/components/ChartDomandePerStato/index.js | 15 +- .../ChartRichiesteVsApprovate/index.js | 56 ++++++ src/pages/Dashboard/index.js | 2 +- src/pages/DomandeInstructorManager/index.js | 2 +- .../BeneficiarioUltimeDomandeTable/index.js | 146 ++++++++++++++ .../PreInstructorSoccorsiTable/index.js | 178 ------------------ src/pages/StatsBeneficiary/index.js | 25 ++- src/service/application-service.js | 4 + 8 files changed, 230 insertions(+), 198 deletions(-) create mode 100644 src/components/ChartRichiesteVsApprovate/index.js create mode 100644 src/pages/StatsBeneficiary/components/BeneficiarioUltimeDomandeTable/index.js delete mode 100644 src/pages/StatsBeneficiary/components/PreInstructorSoccorsiTable/index.js diff --git a/src/components/ChartDomandePerStato/index.js b/src/components/ChartDomandePerStato/index.js index efbc744..a27c0e5 100644 --- a/src/components/ChartDomandePerStato/index.js +++ b/src/components/ChartDomandePerStato/index.js @@ -1,10 +1,10 @@ import React, { useEffect, useState } from 'react'; import { __ } from '@wordpress/i18n'; -import { Tooltip, ResponsiveContainer, Cell, Pie, PieChart } from 'recharts'; +import { Tooltip, ResponsiveContainer, Cell, Pie, PieChart, Legend } from 'recharts'; import { isEmpty } from 'ramda'; -import getBandoLabel from '../../helpers/getBandoLabel'; -// components +// tools +import getBandoLabel from '../../helpers/getBandoLabel'; const ChartDomandePerStato = ({ title, data = [] }) => { @@ -36,15 +36,13 @@ const ChartDomandePerStato = ({ title, data = [] }) => { } return acc; }, { - inProgress: {value: 0, label: 'In corso'}, - approved: {value: 0, label: 'Approvato'}, - rejected: {value: 0, label: 'Respinto'} + inProgress: {value: 0, label: __('In corso', 'gepafin')}, + approved: {value: 0, label: __('Approvato', 'gepafin')}, + rejected: {value: 0, label: __('Respinto', 'gepafin')} }); setChartData(grouped) }, [data]); - console.log('chartData', chartData) - return (
{title ? {title} : null} {chartData && !isEmpty(chartData) @@ -70,6 +68,7 @@ const ChartDomandePerStato = ({ title, data = [] }) => { ))} } /> +
: null} diff --git a/src/components/ChartRichiesteVsApprovate/index.js b/src/components/ChartRichiesteVsApprovate/index.js new file mode 100644 index 0000000..e693b45 --- /dev/null +++ b/src/components/ChartRichiesteVsApprovate/index.js @@ -0,0 +1,56 @@ +import React from 'react'; +import { __ } from '@wordpress/i18n'; +import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts'; +import { isEmpty } from 'ramda'; + +// components + + +const ChartRichiesteVsApprovate = ({ title, data = [] }) => { + + // Custom tooltip + const CustomTooltip = ({ active, payload, label }) => { + if (active && payload && payload.length) { + return ( +
+

{label}

+

+ {__('In bozza', 'gepafin')}: {payload[0].value} +

+

+ {__('Inviate', 'gepafin')}: {payload[1].value} +

+
+ ); + } + return null; + }; + + return (
+ {title ? {title} : null} + {data && !isEmpty(data) + ?
+ + + + + + }/> + + + + + +
: null} +
) +} + +export default ChartRichiesteVsApprovate; \ No newline at end of file diff --git a/src/pages/Dashboard/index.js b/src/pages/Dashboard/index.js index 4bb003e..0126e31 100644 --- a/src/pages/Dashboard/index.js +++ b/src/pages/Dashboard/index.js @@ -112,7 +112,7 @@ const Dashboard = () => { currency: 'EUR', currencyDisplay: 'symbol' }} - locales="en-US"/> + locales="it-IT"/> diff --git a/src/pages/DomandeInstructorManager/index.js b/src/pages/DomandeInstructorManager/index.js index 35957b5..31ee817 100644 --- a/src/pages/DomandeInstructorManager/index.js +++ b/src/pages/DomandeInstructorManager/index.js @@ -1,6 +1,6 @@ import React, { useEffect, useRef, useState } from 'react'; import { __ } from '@wordpress/i18n'; -import { isEmpty, pathOr } from 'ramda'; +import { isEmpty } from 'ramda'; // store import { storeSet } from '../../store'; diff --git a/src/pages/StatsBeneficiary/components/BeneficiarioUltimeDomandeTable/index.js b/src/pages/StatsBeneficiary/components/BeneficiarioUltimeDomandeTable/index.js new file mode 100644 index 0000000..31c7ec9 --- /dev/null +++ b/src/pages/StatsBeneficiary/components/BeneficiarioUltimeDomandeTable/index.js @@ -0,0 +1,146 @@ +import React, { useState, useEffect } from 'react'; +import { __ } from '@wordpress/i18n'; +import { is, isEmpty, uniq } from 'ramda'; + +// store +import { useStore } from '../../../../store'; + +// api +import ApplicationService from '../../../../service/application-service'; + +// tools +import getNumberWithCurrency from '../../../../helpers/getNumberWithCurrency'; + +// components +import { FilterMatchMode, FilterOperator } from 'primereact/api'; +import { DataTable } from 'primereact/datatable'; +import { Column } from 'primereact/column'; +import ProperBandoLabel from '../../../../components/ProperBandoLabel'; +import translationStrings from '../../../../translationStringsForComponents'; + + +const BeneficiarioUltimeDomandeTable = () => { + const chosenCompanyId = useStore().main.chosenCompanyId(); + const [items, setItems] = useState(null); + // eslint-disable-next-line + const [filters, setFilters] = useState(null); + const [localAsyncRequest, setLocalAsyncRequest] = useState(false); + // eslint-disable-next-line + const [statuses, setStatuses] = useState([]); + const perPage = 5; + + const getPaginationQuery = (status = 'DRAFT', curPage = 1) => { + return { + "globalFilters": { + //"year": 0, + "page": curPage, + //"search": "", + "limit": perPage, + }, + //"daysRange": 0, + "status": status + } + } + + useEffect(() => { + if (!isEmpty(chosenCompanyId) && chosenCompanyId !== 0 && !localAsyncRequest) { + const bodyParams = getPaginationQuery( + ['SOCCORSO', 'APPROVED', 'REJECTED', 'EVALUATION', 'SUBMIT'], + 1 + ); + + setLocalAsyncRequest(true); + ApplicationService.getApplicationsPaginated(bodyParams, getApplCallback, errGetApplCallback, [ + ['companyId', chosenCompanyId], + ['statuses', ['SOCCORSO', 'APPROVED', 'REJECTED', 'EVALUATION', 'SUBMIT']] // 'NDG', 'ADMISSIBLE', 'APPOINTMENT' + ]); + } + }, [chosenCompanyId]); + + const getApplCallback = (resp) => { + if (resp.status === 'SUCCESS') { + if (resp.data && is(Array, resp.data.body)) { + setItems(getFormattedBandiData(resp.data.body)); + setStatuses(uniq(items.map(o => o.status))) + initFilters(); + } + } + setLocalAsyncRequest(false); + } + + const errGetApplCallback = () => { + setLocalAsyncRequest(false); + } + + const getFormattedBandiData = (data) => { + return [...(data || [])].map((d) => { + d.callEndDate = new Date(d.callEndDate); + d.modifiedDate = new Date(d.modifiedDate); + d.submissionDate = new Date(d.submissionDate); + + return d; + }); + }; + + const formatDate = (value) => { + return value.toLocaleDateString('it-IT', { + year: 'numeric' + }); + }; + + const initFilters = () => { + setFilters({ + global: { value: null, matchMode: FilterMatchMode.CONTAINS }, + callTitle: { + operator: FilterOperator.AND, + constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] + }, + companyName: { + operator: FilterOperator.AND, + constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] + }, + modifiedDate: { + operator: FilterOperator.AND, + constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] + }, + callEndDate: { + operator: FilterOperator.AND, + constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] + } + }); + }; + + const dateSubmissionBodyTemplate = (rowData) => { + return formatDate(rowData.submissionDate); + }; + + const importoBodyTemplate = (rowData) => { + return getNumberWithCurrency(rowData.amountRequested); + }; + + const statusBodyTemplate = (rowData) => { + return ; + }; + + return ( +
+ + + + + + +
+ ) +} + +export default BeneficiarioUltimeDomandeTable; diff --git a/src/pages/StatsBeneficiary/components/PreInstructorSoccorsiTable/index.js b/src/pages/StatsBeneficiary/components/PreInstructorSoccorsiTable/index.js deleted file mode 100644 index b74acd6..0000000 --- a/src/pages/StatsBeneficiary/components/PreInstructorSoccorsiTable/index.js +++ /dev/null @@ -1,178 +0,0 @@ -import React, { useState, useEffect} from 'react'; -import { __ } from '@wordpress/i18n'; -import { is, isNil, uniq } from 'ramda'; -import { Link } from 'react-router-dom'; - -// api -import AmendmentsService from '../../../../service/amendments-service'; - -// 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 { Button } from 'primereact/button'; -import { Calendar } from 'primereact/calendar'; -import ProperBandoLabel from '../../../../components/ProperBandoLabel'; -import { Dropdown } from 'primereact/dropdown'; -import { Tag } from 'primereact/tag'; - -import translationStrings from '../../../../translationStringsForComponents'; - - -const PreInstructorSoccorsiTable = ({ userId = null }) => { - const [items, setItems] = useState(null); - const [filters, setFilters] = useState(null); - const [localAsyncRequest, setLocalAsyncRequest] = useState(false); - const [statuses, setStatuses] = useState([]); - - useEffect(() => { - if (!isNil(userId)) { - setLocalAsyncRequest(true); - - if (userId === 0) { - AmendmentsService.getSoccorsi(getCallback, errGetCallbacks); - } else { - AmendmentsService.getSoccorsi(getCallback, errGetCallbacks, [ - ['userId', userId] - ]); - } - } - }, [userId]); - - const getCallback = (data) => { - if (data.status === 'SUCCESS') { - setItems(getFormattedData(data.data)); - setStatuses(uniq(data.data.map(o => o.status))) - initFilters(); - } - setLocalAsyncRequest(false); - } - - const errGetCallbacks = (data) => { - setLocalAsyncRequest(false); - } - - const getFormattedData = (data) => { - return data.map((d) => { - d.startDate = is(String, d.startDate) ? new Date(d.startDate) : (d.startDate ? d.startDate : ''); - d.evaluationEndDate = is(String, d.evaluationEndDate) ? new Date(d.evaluationEndDate) : (d.evaluationEndDate ? d.evaluationEndDate : ''); - return d; - }); - }; - - const formatDate = (value) => { - return value.toLocaleDateString('it-IT', { - day: '2-digit', - month: '2-digit', - year: 'numeric' - }); - }; - - const clearFilter = () => { - initFilters(); - }; - - const initFilters = () => { - setFilters({ - global: { value: null, matchMode: FilterMatchMode.CONTAINS }, - callName: { - operator: FilterOperator.AND, - constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] - }, - companyName: { - operator: FilterOperator.AND, - constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] - }, - startDate: { - operator: FilterOperator.AND, - constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] - }, - evaluationEndDate: { - operator: FilterOperator.AND, - constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] - } - }); - }; - - const renderHeader = () => { - return ( -
-
- ); - }; - - const dateStartBodyTemplate = (rowData) => { - return formatDate(rowData.startDate); - }; - - const dateExpirationBodyTemplate = (rowData) => { - return rowData.evaluationEndDate ? formatDate(rowData.evaluationEndDate) : ''; - }; - - 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={translationStrings.selectOneLabel} className="p-column-filter" showClear />; - }; - - const statusItemTemplate = (option) => { - return ; - }; - - const actionsBodyTemplate = (rowData) => { - return -