Skip to content

Commit

Permalink
refactor: rework on 'Digital Domicile' and 'Validating Pec' Banners (…
Browse files Browse the repository at this point in the history
…pf and pg)
  • Loading branch information
mflauti committed Feb 18, 2025
1 parent 2fc0d69 commit 89d87ff
Show file tree
Hide file tree
Showing 19 changed files with 203 additions and 123 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"pec-validation-banner": {
"title": "La PEC è in validazione",
"dod-enabled-message": "Fino al termine del processo, la Piattaforma SEND rimane attiva come domicilio digitale.",
"dod-disabled-message": "Fino al termine del processo non sarà possibile modificare i recapiti a valore legale."
"dod-disabled-message": "Fino al termine del processo non sarà possibile modificare i recapiti a valore legale.",
"parties-list": "La piattaforma SEND resterà il tuo domicilio digitale per {{list}} fino al completamento della validazione."
},
"pec-description": "Quando un ente ti invia una notifica SEND, ricevi l’avviso a valore legale sulla PEC che hai scelto.",
"link-pec-placeholder": "La tua PEC",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ const EmailContactItem: React.FC = () => {
actions={getActions()}
expanded={isEmailActive}
data-testid="emailContact"
slotProps={{ Card: { id: 'emailContactSection' } }}
>
{!isEmailActive && (
<Typography variant="body1" fontSize={{ xs: '14px', lg: '16px' }} mb={3}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ const IOContact: React.FC = () => {
color="primary"
fullWidth={isMobile}
sx={{ mt: 3 }}
id="ioContactButton"
>
{t('io-contact.enable', { ns: 'recapiti' })}
</Button>
Expand Down Expand Up @@ -208,6 +209,7 @@ const IOContact: React.FC = () => {
: undefined
}
expanded={isAppIOEnabled}
slotProps={{ Card: { id: 'ioContactSection' } }}
>
<Stack direction="row" alignItems="center" data-testid="ioContact">
<Avatar variant="rounded" sx={{ bgcolor: '#0B3EE3', width: '36px', height: '36px' }}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ const LegalContacts = () => {
)
.unwrap()
.then(() => {
if (channelType === ChannelType.SERCQ_SEND) {
sessionStorage.removeItem('domicileBannerClosed');
}
PFEventStrategyFactory.triggerEvent(
PFEventsType[`SEND_REMOVE_${channelType}_SUCCESS`],
'default'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ const SercqSendContactWizard: React.FC<Props> = ({ goToNextStep, setShowPecWizar
dispatch(createOrUpdateAddress(digitalAddressParams))
.unwrap()
.then(() => {
sessionStorage.removeItem('domicileBannerClosed');
PFEventStrategyFactory.triggerEvent(PFEventsType.SEND_ADD_SERCQ_SEND_UX_SUCCESS, 'default');
// show success message
dispatch(
Expand All @@ -150,7 +151,6 @@ const SercqSendContactWizard: React.FC<Props> = ({ goToNextStep, setShowPecWizar
message: t(`legal-contacts.sercq_send-added-successfully`, { ns: 'recapiti' }),
})
);

goToNextStep && goToNextStep();
})
.catch(() => {});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ import { ButtonNaked } from '@pagopa/mui-italia';

import { PFEventsType } from '../../models/PFEventsType';
import {
AddressType,
ChannelType,
ContactOperation,
ContactSource,
IOAllowedValues,
} from '../../models/contacts';
import * as routes from '../../navigation/routes.const';
import { setExternalEvent } from '../../redux/contact/reducers';
import { contactsSelectors, setExternalEvent } from '../../redux/contact/reducers';
import { useAppDispatch, useAppSelector } from '../../redux/hooks';
import { closeDomicileBanner } from '../../redux/sidemenu/reducers';
import { RootState } from '../../redux/store';
Expand Down Expand Up @@ -108,43 +107,47 @@ const DomicileBanner: React.FC<Props> = ({ source }) => {
const dispatch = useAppDispatch();
const open = useAppSelector((state: RootState) => state.generalInfoState.domicileBannerOpened);
const { IS_DOD_ENABLED } = getConfiguration();
const {
defaultPECAddress,
defaultSERCQ_SENDAddress,
defaultAPPIOAddress,
defaultEMAILAddress,
defaultSMSAddress,
} = useAppSelector(contactsSelectors.selectAddresses);

const digitalAddresses = useAppSelector(
(state: RootState) => state.contactsState.digitalAddresses
);

const hasSercqSend = digitalAddresses.find((addr) => addr.channelType === ChannelType.SERCQ_SEND);
const hasAppIODisabled = digitalAddresses.find(
(addr) => addr.channelType === ChannelType.IOMSG && addr.value === IOAllowedValues.DISABLED
);
const hasAppIODisabled = defaultAPPIOAddress?.value === IOAllowedValues.DISABLED;

const hasCourtesyAddresses =
digitalAddresses.filter(
(addr) => addr.addressType === AddressType.COURTESY && addr.value !== IOAllowedValues.DISABLED
).length > 0;
const domicileBannerData: DomicileBannerData | null = getDomicileData(
source,
!!hasSercqSend,
hasCourtesyAddresses,
!!hasAppIODisabled,
IS_DOD_ENABLED
);
const hasCourtesyAddresses = !!(defaultEMAILAddress || defaultSMSAddress);
const domicileBannerData: DomicileBannerData | null = defaultPECAddress
? null
: getDomicileData(
source,
!!defaultSERCQ_SENDAddress,
hasCourtesyAddresses,
hasAppIODisabled,
IS_DOD_ENABLED
);

const handleClose = () => {
dispatch(closeDomicileBanner());
// sessionStorage.setItem('domicileBannerClosed', 'true');
sessionStorage.setItem('domicileBannerClosed', 'true');
};

const handleClick = (destination?: ChannelType, operation?: ContactOperation) => {
if (destination && operation) {
dispatch(setExternalEvent({ destination, source, operation }));
if (destination === ChannelType.SERCQ_SEND && operation === ContactOperation.ADD) {
navigate(routes.DIGITAL_DOMICILE_ACTIVATION);
return;
} else {
dispatch(setExternalEvent({ destination, source, operation }));
}
}
PFEventStrategyFactory.triggerEvent(PFEventsType.SEND_VIEW_CONTACT_DETAILS, { source });
navigate(routes.RECAPITI);
};

return open && domicileBannerData ? (
<Box mb={5}>
<Box my={4}>
<Alert
severity={domicileBannerData.severity}
variant="outlined"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,7 @@ describe('DomicileBanner component', () => {
const button = getByText('domicile-banner.no-sercq-cta');
fireEvent.click(button);
expect(mockNavigateFn).toHaveBeenCalledTimes(1);
expect(mockNavigateFn).toHaveBeenCalledWith(routes.RECAPITI);
expect(testStore.getState().contactsState.event).toStrictEqual({
destination: ChannelType.SERCQ_SEND,
source: ContactSource.HOME_NOTIFICHE,
operation: ContactOperation.ADD,
});
expect(mockNavigateFn).toHaveBeenCalledWith(routes.DIGITAL_DOMICILE_ACTIVATION);
});

it('renders the component - no SERCQ SEND enabled - banner closed', () => {
Expand Down
99 changes: 68 additions & 31 deletions packages/pn-personafisica-webapp/src/pages/Contacts.page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback, useMemo } from 'react';
import { useCallback, useEffect, useMemo } from 'react';
import { Trans, useTranslation } from 'react-i18next';

import { Alert, Box, Link, Stack, Typography } from '@mui/material';
Expand All @@ -9,27 +9,73 @@ import LegalContacts from '../components/Contacts/LegalContacts';
import DomicileBanner from '../components/DomicileBanner/DomicileBanner';
import LoadingPageWrapper from '../components/LoadingPageWrapper/LoadingPageWrapper';
import { PFEventsType } from '../models/PFEventsType';
import { ContactSource } from '../models/contacts';
import { ChannelType, ContactOperation, ContactSource } from '../models/contacts';
import { FAQ_WHAT_IS_AAR, FAQ_WHAT_IS_COURTESY_MESSAGE } from '../navigation/externalRoutes.const';
import { CONTACT_ACTIONS, getDigitalAddresses } from '../redux/contact/actions';
import { contactsSelectors } from '../redux/contact/reducers';
import { contactsSelectors, resetExternalEvent } from '../redux/contact/reducers';
import { useAppDispatch, useAppSelector } from '../redux/hooks';
import { RootState } from '../redux/store';
import { getConfiguration } from '../services/configuration.service';
import PFEventStrategyFactory from '../utility/MixpanelUtils/PFEventStrategyFactory';

const Contacts = () => {
const ValidatingPecBanner: React.FC = () => {
const { t } = useTranslation(['recapiti']);
const dispatch = useAppDispatch();
const {
defaultPECAddress,
defaultAPPIOAddress,
defaultSERCQ_SENDAddress,
specialPECAddresses,
specialSERCQ_SENDAddresses,
addresses,
} = useAppSelector(contactsSelectors.selectAddresses);

const isValidatingDefaultPec = defaultPECAddress?.pecValid === false;

const isDefaultSercqSendActive = !!defaultSERCQ_SENDAddress;

const validatingSpecialPecList: Array<string> = specialPECAddresses
.filter(
(pecAddr) =>
pecAddr.pecValid === false &&
(isDefaultSercqSendActive ||
specialSERCQ_SENDAddresses.some((sercqAddr) => sercqAddr.senderId === pecAddr.senderId))
)
.map((addr) => addr.senderName ?? addr.senderId);

// eslint-disable-next-line functional/no-let
let bannerMessage = '';
if (!isValidatingDefaultPec && validatingSpecialPecList.length === 0) {
return;
}
if (isValidatingDefaultPec) {
if (isDefaultSercqSendActive) {
bannerMessage = 'dod-enabled-message';
} else {
bannerMessage = 'dod-disabled-message';
}
} else {
bannerMessage = 'parties-list';
}
return (
<Alert data-testid="PecVerificationAlert" severity="warning" sx={{ my: { xs: 2, lg: 4 } }}>
<Typography variant="inherit" sx={{ fontWeight: '600' }}>
{t('legal-contacts.pec-validation-banner.title')}
</Typography>
<Typography variant="inherit">
{t(`legal-contacts.pec-validation-banner.${bannerMessage}`, {
list: validatingSpecialPecList.join(', '),
})}
</Typography>
</Alert>
);
};

const Contacts = () => {
const { t } = useTranslation(['recapiti']);
const dispatch = useAppDispatch();
const { defaultAPPIOAddress, addresses } = useAppSelector(contactsSelectors.selectAddresses);
const { LANDING_SITE_URL } = getConfiguration();

const externalEvent = useAppSelector((state: RootState) => state.contactsState.event);

const fetchAddresses = useCallback(() => {
void dispatch(getDigitalAddresses())
.unwrap()
Expand All @@ -41,19 +87,6 @@ const Contacts = () => {
});
}, []);

const hasDodEnabledAndValidatingPec =
(!defaultPECAddress?.pecValid && defaultSERCQ_SENDAddress) ||
specialSERCQ_SENDAddresses.some((sercqAddr) =>
specialPECAddresses.some(
(pecAddr) => !pecAddr.pecValid && pecAddr.senderId === sercqAddr.senderId
)
);

const hasValidatingPecSpecialContact = specialPECAddresses.some((address) => !address.pecValid);

const verifyingPecAddress =
(defaultPECAddress && !defaultPECAddress.pecValid) || hasValidatingPecSpecialContact;

const faqWhatIsAarCompleteLink = useMemo(
() =>
LANDING_SITE_URL && FAQ_WHAT_IS_AAR ? `${LANDING_SITE_URL}${FAQ_WHAT_IS_AAR}` : undefined,
Expand Down Expand Up @@ -91,9 +124,20 @@ const Contacts = () => {
/>
);

const bannerMessage = hasDodEnabledAndValidatingPec
? 'legal-contacts.pec-validation-banner.dod-enabled-message'
: 'legal-contacts.pec-validation-banner.dod-disabled-message';
const goToSection = (section: ChannelType) => {
const sectionId = section === ChannelType.EMAIL ? 'emailContactSection' : 'ioContactSection';
const titleId = section === ChannelType.EMAIL ? 'default_email' : 'ioContactButton';

document.getElementById(sectionId)?.scrollIntoView({ behavior: 'smooth' });
document.getElementById(titleId)?.focus({ preventScroll: true });
};

useEffect(() => {
if (externalEvent && externalEvent.operation === ContactOperation.SCROLL) {
goToSection(externalEvent.destination);
dispatch(resetExternalEvent());
}
}, [externalEvent]);

return (
<LoadingPageWrapper isInitialized={true}>
Expand All @@ -109,14 +153,7 @@ const Contacts = () => {
reloadAction={fetchAddresses}
>
<DomicileBanner source={ContactSource.RECAPITI} />
{verifyingPecAddress && (
<Alert data-testid="PecVerificationAlert" severity="info" sx={{ my: { xs: 2, lg: 4 } }}>
<Typography variant="inherit" sx={{ fontWeight: '600' }}>
{t('legal-contacts.pec-validation-banner.title', { ns: 'recapiti' })}
</Typography>
<Typography variant="inherit">{t(bannerMessage, { ns: 'recapiti' })}</Typography>
</Alert>
)}
<ValidatingPecBanner />
<Stack direction="column" spacing={2} mt={2}>
<LegalContacts />
<CourtesyContacts />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -340,9 +340,9 @@ const NotificationDetail: React.FC = () => {

const visibleDomicileBanner = () =>
!mandateId &&
notification.notificationStatusHistory.findIndex(
notification.notificationStatusHistory.some(
(history) => history.status === NotificationStatus.VIEWED
) > -1;
);

useEffect(() => {
if (checkIfUserHasPayments && !(isCancelled.cancelled || isCancelled.cancellationInProgress)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,10 @@ describe('Contacts page', async () => {

const banner = result.getByTestId('PecVerificationAlert');
expect(banner).toBeInTheDocument();
const alertIcon = within(banner).getByTestId('InfoOutlinedIcon');
const alertIcon = within(banner).getByTestId('ReportProblemOutlinedIcon');
expect(alertIcon).toBeInTheDocument();
expect(banner).toHaveTextContent('legal-contacts.pec-validation-banner.title');
expect(banner).toHaveTextContent('legal-contacts.pec-validation-banner.dod-enabled-message');
expect(banner).toHaveTextContent('legal-contacts.pec-validation-banner.parties-list');

const specialContacts = result.getByTestId('specialContacts');
expect(specialContacts).toBeInTheDocument();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"pec-validation-banner": {
"title": "La PEC è in validazione",
"dod-enabled-message": "Fino al termine del processo, la Piattaforma SEND rimane attiva come domicilio digitale.",
"dod-disabled-message": "Fino al termine del processo non sarà possibile modificare i recapiti a valore legale."
"dod-disabled-message": "Fino al termine del processo non sarà possibile modificare i recapiti a valore legale.",
"parties-list": "La piattaforma SEND resterà il tuo domicilio digitale per {{list}} fino al completamento della validazione."
},
"pec-description": "Quando un ente invia alla tua impresa una notifica SEND, viene recapitata in modo sicuro e con valore legale sulla PEC che hai scelto.",
"link-pec-placeholder": "Indirizzo PEC",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ const EmailContactItem: React.FC = () => {
actions={getActions()}
expanded={isEmailActive}
data-testid="emailContact"
slotProps={{ Card: { id: 'emailContactSection' } }}
>
{!isEmailActive && (
<Typography variant="body1" fontSize={{ xs: '14px', lg: '16px' }} mb={3}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ const LegalContacts = () => {
)
.unwrap()
.then(() => {
if (channelType === ChannelType.SERCQ_SEND) {
sessionStorage.removeItem('domicileBannerClosed');
}
dispatch(
appStateActions.addSuccess({
title: '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ const SercqSendContactWizard: React.FC<Props> = ({ goToNextStep, setShowPecWizar
dispatch(createOrUpdateAddress(digitalAddressParams))
.unwrap()
.then(() => {
sessionStorage.removeItem('domicileBannerClosed');
// show success message
dispatch(
appStateActions.addSuccess({
Expand Down
Loading

0 comments on commit 89d87ff

Please sign in to comment.