- added cache faq items;

- added terms pdf;
- added redirect to 'add company' for new users;
This commit is contained in:
Vitalii Kiiko
2024-10-11 12:51:15 +02:00
parent 8fb1551880
commit bd64a34347
26 changed files with 168 additions and 36 deletions

View File

@@ -2,10 +2,10 @@
<html lang="en">
<head>
<meta charset="utf-8"/>
<link rel="icon" href="%PUBLIC_URL%/favicon.ico"/>
<link rel="icon" href="%PUBLIC_URL%/loaded-files/favicon.ico"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="description" content="Gepafin"/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png"/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/loaded-files/logo.svg"/>
<link rel="manifest" href="%PUBLIC_URL%/manifest.json"/>
<title>%REACT_APP_TAB_TITLE%</title>
</head>

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

View File

@@ -8,13 +8,13 @@
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"src": "logo.svg",
"type": "image/svg+xml",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"src": "logo.svg",
"type": "image/svg+xml",
"sizes": "512x512"
}
],

View File

@@ -4,7 +4,7 @@ import Routes from './routes';
import { createI18n, setLocaleData } from '@wordpress/i18n';
import { I18nProvider } from '@wordpress/react-i18n';
import './assets/scss/theme.scss';
import { isEmpty } from 'ramda'
import { isEmpty, head } from 'ramda'
// store
import { useStore, storeSet, storeGet } from './store';
@@ -17,6 +17,7 @@ const i18n = createI18n({}, 'gepafin');
function App() {
const role = useStore().main.getRole();
const chosenCompanyId = useStore().main.chosenCompanyId();
const isRedirectedOnceNoCompany = useStore().main.isRedirectedOnceNoCompany();
const callback = (data) => {
if (data.status === 'SUCCESS') {
@@ -36,9 +37,23 @@ function App() {
const userData = storeGet.main.userData();
if (userData.companies && !isEmpty(userData.companies)) {
storeSet.main.companies(userData.companies);
const company = head(userData.companies.filter(o => o.id === chosenCompanyId));
if (!company) {
storeSet.main.chosenCompanyId(userData.companies[0].id);
}
} else {
storeSet.main.chosenCompanyId(0);
const { origin, href } = window.location;
const url = `${origin}/agguingi-azienda`;
if (!isRedirectedOnceNoCompany && url !== href) {
storeSet.main.isRedirectedOnceNoCompany(true);
window.location.replace('/agguingi-azienda')
}
}
}
}, [role])
}, [role]);
useEffect(() => {
storeSet.main.setAsyncRequest();

View File

@@ -25,6 +25,15 @@ body {
flex-grow: 1;
}
iframe {
width: 100%;
height: 100%;
}
img {
max-width: 100%;
}
.inner {
display: flex;
height: 100%;

View File

@@ -27,6 +27,7 @@ const Switch = ({
rules={config}
render={({ field, fieldState }) => (
<InputSwitch
inputId={fieldName}
checked={field.value}
disabled={disabled}
onChange={(e) => field.onChange(e.value)}

View File

@@ -86,6 +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',

View File

@@ -5,7 +5,10 @@ export const mimeTypes = [
{ name: 'Immagine', code: 'image/*' },
{
name: 'Word',
code: 'application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document'
code: '.doc,.docx,.odt,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.oasis.opendocument.text'
},
{ name: 'Excel doc', code: 'application/vnd.ms-excel' }
{
name: 'Excel',
code: '.xls,.xlsx,.ods,application/vnd.ms-excel,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.oasis.opendocument.spreadsheet'
}
];

View File

@@ -75,6 +75,7 @@ const AddCompany = () => {
} else {
newCompanies = [...companies, company];
storeSet.main.chosenCompanyId(company.id);
console.log('set company 1', company.id)
}
storeSet.main.companies(newCompanies);

View File

@@ -140,7 +140,8 @@ const AllBandiTable = () => {
filters={filters}
globalFilterFields={['name', 'status']}
header={header}
emptyMessage="Nothing found." onFilter={(e) => setFilters(e.filters)}>
emptyMessage={__('Nessun dato disponibile', 'gepafin')}
onFilter={(e) => setFilters(e.filters)}>
<Column field="name" header={__('Nome Bando', 'gepafin')}
filter filterPlaceholder={__('Cerca', 'gepafin')}
style={{ minWidth: '12rem' }}/>

View File

@@ -126,8 +126,13 @@ const AllBandiAccordion = () => {
return(
<div className="appPageSection__table">
<DataTable value={items} paginator rows={10} loading={isAsyncRequest} dataKey="id"
filters={filters} emptyMessage="Nothing found."
<DataTable value={items}
paginator
rows={10}
loading={isAsyncRequest}
dataKey="id"
filters={filters}
emptyMessage={__('Nessun dato disponibile', 'gepafin')}
expandedRows={expandedRows}
onRowToggle={(e) => setExpandedRows(e.data)}
rowExpansionTemplate={rowExpansionTemplate}

View File

@@ -42,7 +42,7 @@ const ElementSetting = ({ setting, changeFn, updateDataFn }) => {
};
const header = renderHeader();
console.log('setting', setting)
const getProperField = (setting) => {
if (setting.name === 'options') {
return <ElementSettingRepeater

View File

@@ -112,19 +112,6 @@ const BandoViewBeneficiario = () => {
const createCallBack = (data) => {
if (data.status === 'SUCCESS') {
setNewQuestion('');
/*if (bandoMsgs.current && data.message) {
bandoMsgs.current.show([
{
sticky: true, severity: 'success', summary: '',
detail: data.message,
closable: true
}
]);
setTimeout(() => {
bandoMsgs.current.clear();
}, 5000);
}*/
if (toast.current) {
toast.current.show({
severity: 'success',
@@ -355,7 +342,7 @@ const BandoViewBeneficiario = () => {
label={__('Salva', 'gepafin')}/>
</div>
{chosenCompanyId === 0
{!chosenCompanyId || chosenCompanyId === 0
? <>
<Message severity="error"
text={__('Devi creare un\'azienda prima di partecipare nei bandi. Vai nel profilo aziendale.', 'gepafin')}/>

View File

@@ -183,7 +183,8 @@ const LatestBandiTable = () => {
filters={filters}
globalFilterFields={['name', 'status']}
header={header}
emptyMessage="Nothing found." onFilter={(e) => setFilters(e.filters)}>
emptyMessage={__('Nessun dato disponibile', 'gepafin')}
onFilter={(e) => setFilters(e.filters)}>
<Column field="name" header={__('Nome Bando', 'gepafin')} filter filterPlaceholder="Search by name"
style={{ minWidth: '12rem' }}/>
<Column header={__('Data Pubblicazione', 'gepafin')} filterField="start_date" dataType="date"

View File

@@ -107,7 +107,8 @@ const LatestUsersActivityTable = () => {
filters={filters}
globalFilterFields={['name', 'status']}
header={header}
emptyMessage="Nothing found." onFilter={(e) => setFilters(e.filters)}>
emptyMessage={__('Nessun dato disponibile', 'gepafin')}
onFilter={(e) => setFilters(e.filters)}>
<Column header={__('Timestamp', 'gepafin')} filterField="date" dataType="date"
style={{ minWidth: '10rem' }}
body={dateBodyTemplate} filter filterElement={dateFilterTemplate}/>

View File

@@ -151,7 +151,8 @@ const LatestBandiTable = () => {
filters={filters}
globalFilterFields={['name', 'status']}
header={header}
emptyMessage="Nothing found." onFilter={(e) => setFilters(e.filters)}>
emptyMessage={__('Nessun dato disponibile', 'gepafin')}
onFilter={(e) => setFilters(e.filters)}>
<Column field="name" header={__('Nome Bando', 'gepafin')} filter filterPlaceholder="Search by name"
style={{ minWidth: '12rem' }}/>
<Column header={__('Data Pubblicazione', 'gepafin')} filterField="start_date" dataType="date"

View File

@@ -166,7 +166,8 @@ const MyLatestSubmissionsTable = () => {
filters={filters}
globalFilterFields={['name', 'status']}
header={header}
emptyMessage="Nothing found." onFilter={(e) => setFilters(e.filters)}>
emptyMessage={__('Nessun dato disponibile', 'gepafin')}
onFilter={(e) => setFilters(e.filters)}>
<Column field="callTitle" header={__('Bando', 'gepafin')} filter filterPlaceholder="Search by name"
style={{ minWidth: '12rem' }}/>
<Column header={__('Scadenza', 'gepafin')} filterField="callEndDate" dataType="date"

View File

@@ -6,11 +6,16 @@ import { isEmpty, isNil } from 'ramda';
// store
import { storeSet, useStore } from '../../store';
// api
import AuthenticationService from '../../service/authentication-service';
// components
import LogoIcon from '../../icons/LogoIcon';
import { Messages } from 'primereact/messages';
import { useSearchParams } from 'react-router-dom';
import AuthenticationService from '../../service/authentication-service';
import { Dialog } from 'primereact/dialog';
import { Accordion } from 'primereact/accordion';
import { AccordionTab } from 'primereact/accordion';
const API_BASE_URL = process.env.REACT_APP_API_ADDRESS;
@@ -18,7 +23,9 @@ const Login = () => {
const token = useStore().main.token();
const errorMsgs = useRef(null);
const [loading, setLoading] = useState(false);
const [visibleCacheFaq, setVisibleCacheFaq] = useState(false);
let [searchParams] = useSearchParams();
const { origin } = window.location;
const loginWithSpid = () => {
if (!loading) {
@@ -56,6 +63,15 @@ const Login = () => {
setLoading(false);
}
const openCacheFaq = (e) => {
e.preventDefault();
setVisibleCacheFaq(true);
}
const hideCacheFaq = () => {
setVisibleCacheFaq(false);
}
useEffect(() => {
if (!isEmpty(token)) {
window.location.replace('/')
@@ -104,6 +120,72 @@ const Login = () => {
<span>{__('Entra con SPID', 'gepafin')}</span>
</button>
<div className="appPage__spacer"></div>
<p><a href={origin} onClick={openCacheFaq}>{__('Hai problemi di accesso con SPID?', 'gepafin')}</a></p>
<Dialog header={__('Termini e condizioni', 'gepafin')} visible={visibleCacheFaq} style={{
width: '70vw',
minHeight: 500
}} onHide={hideCacheFaq}>
<p>
{__('Se rilevi problemi di accesso allo sportello telematico utilizzando le tue credenziali SPID, solitamente si tratta di un esaurimento dello spazio dedicato alla cache, cioè linsieme dei dati che i software salvano sul browser per rendere il caricamento di determinate pagine internet più rapido.', 'gepafin')}
</p>
<Accordion>
<AccordionTab header={__('Come svuotare la cache su Google Chrome', 'gepafin')}>
<p>Se solitamente navighi in internet utilizzando Google Chrome, per svuotare la cache
devi:</p>
<ul>
<li>cliccare sui tre puntini verticali in alto a destra
</li>
<li>selezionare la voce Impostazioni</li>
<li>accedere al menu Privacy e sicurezza > Cancella dati di navigazione</li>
<li>selezionare la voce Immagini e file memorizzati nella cache e poi premere sul
pulsante Cancella dati.
</li>
</ul>
<img src={`${origin}/loaded-files/empty-cache-chrome.png`}
alt={__('Come svuotare la cache su Google Chrome', 'gepafin')}/>
</AccordionTab>
<AccordionTab header={__('Come svuotare la cache su Mozilla Firefox', 'gepafin')}>
<p>Se solitamente navighi in internet utilizzando Mozilla Firefox, per svuotare la cache
devi:</p>
<ul>
<li>cliccare sulle tre linee orizzontali in alto a destra</li>
<li>selezionare la voce Impostazioni</li>
<li>accedere al menu Privacy e sicurezza > Cookie e dati dei siti web > Elimina
dati...
</li>
<li>selezionare la voce Contenuti web in cache e poi premere sul pulsante Elimina.</li>
</ul>
<img src={`${origin}/loaded-files/empty-cache-firefox.png`}
alt={__('Come svuotare la cache su Mozilla Firefox', 'gepafin')}/>
</AccordionTab>
<AccordionTab header={__('Come svuotare la cache su Microsoft Edge', 'gepafin')}>
<p>Se solitamente navighi in internet utilizzando Microsoft Edge, per svuotare la cache
devi:</p>
<ul>
<li>cliccare sui tre puntini orizzontali in alto a destra</li>
<li>selezionare la voce Impostazioni</li>
<li>accedere al menu Privacy, ricerca e servizi > Cancella i dati di navigazione >
Scegli cosa cancellare
</li>
<li>selezionare la voce Immagini e file memorizzati nella cache e poi premere sul
pulsante Cancella ora.
</li>
</ul>
<img src={`${origin}/loaded-files/empty-cache-edge.png`}
alt={__('Come svuotare la cache su Microsoft Edge', 'gepafin')}/>
</AccordionTab>
</Accordion>
</Dialog>
</div>
</div>
)

View File

@@ -82,6 +82,7 @@ const ProfileCompany = () => {
} else {
newCompanies = [...companies, company];
storeSet.main.chosenCompanyId(company.id);
console.log('set company 3', company.id)
}
storeSet.main.companies(newCompanies);

View File

@@ -20,10 +20,12 @@ import LogoIcon from '../../icons/LogoIcon';
import { Button } from 'primereact/button';
import { Messages } from 'primereact/messages';
import { Panel } from 'primereact/panel';
import { Dialog } from 'primereact/dialog';
const Registration = () => {
const token = useStore().main.token();
const [loading, setLoading] = useState(false);
const [visibleTerms, setVisibleTerms] = useState(false);
const errorMsgs = useRef(null);
let [searchParams] = useSearchParams();
const {
@@ -34,6 +36,8 @@ const Registration = () => {
getValues
} = useForm({ mode: 'onChange' });
const values = getValues();
const { origin } = window.location;
const urlTermsPdf = `${origin}/loaded-files/termini-e-condizioni.pdf`;
const onSubmit = (formData) => {
errorMsgs.current.clear();
@@ -117,6 +121,15 @@ const Registration = () => {
setValue('thirdParty', true);
}
const openTermsDoc = (e) => {
e.preventDefault();
setVisibleTerms(true);
}
const hideTerms = () => {
setVisibleTerms(false);
}
useEffect(() => {
if (!isEmpty(token)) {
setLoading(true);
@@ -279,7 +292,7 @@ const Registration = () => {
}}
toggleable>
<p className="m-0">
{__('Termini e condizioni', 'gepafin')}
<a href={urlTermsPdf} onClick={openTermsDoc}>{__('Termini e condizioni', 'gepafin')}</a>
</p>
</Panel>
@@ -350,9 +363,16 @@ const Registration = () => {
</Panel>
<Button
label={__('Accedi', 'gepafin')}
label={__('Invia', 'gepafin')}
disabled={loading}/>
</form>
<Dialog header={__('Termini e condizioni', 'gepafin')} visible={visibleTerms} style={{
width: '70vw',
minHeight: 500
}} onHide={hideTerms}>
<iframe src={urlTermsPdf} title={__('Termini e condizioni', 'gepafin')}></iframe>
</Dialog>
</div>
</div>
)

View File

@@ -150,7 +150,8 @@ const AllUsersTable = () => {
filters={filters}
globalFilterFields={['name', 'status']}
header={header}
emptyMessage="Nothing found." onFilter={(e) => setFilters(e.filters)}>
emptyMessage={__('Nessun dato disponibile', 'gepafin')}
onFilter={(e) => setFilters(e.filters)}>
<Column field="name" header={__('Nome utente', 'gepafin')} filter filterPlaceholder="Search by name"
style={{ minWidth: '12rem' }}/>
<Column field="email" header={__('Email', 'gepafin')} filter filterPlaceholder="Search by email"

View File

@@ -2,6 +2,7 @@ const initialStore = {
// ui related
isAsyncRequest: 0, // number
isError404: false,
isRedirectedOnceNoCompany: false,
// user
userData: {},
token: '',