From c26531e97e4f4511dfe1ef83c7c6ad827cb04703 Mon Sep 17 00:00:00 2001 From: Marc Itzenthaler Date: Mon, 15 Jan 2024 22:57:52 +0100 Subject: [PATCH] feat: added specific agency provider to provide agency specific links --- src/components/appointment/Appointments.tsx | 16 ++++-- .../formAccordion/FormAccordion.tsx | 21 +++++--- src/components/profile/Profile.tsx | 14 ++++-- .../registration/RegistrationForm.tsx | 1 + src/components/sessionMenu/SessionMenu.tsx | 8 ++- src/components/stageLayout/StageLayout.tsx | 20 ++++++-- .../videoConference/WaitingRoom.tsx | 8 +-- src/components/waitingRoom/WaitingRoom.tsx | 6 +-- src/globalState/index.ts | 1 + src/globalState/provider/AgencyProvider.tsx | 39 +++++++++++++++ .../provider/LegalLinksProvider.tsx | 49 ++++++++++++++++--- src/globalState/state.tsx | 4 +- 12 files changed, 155 insertions(+), 32 deletions(-) create mode 100644 src/globalState/provider/AgencyProvider.tsx diff --git a/src/components/appointment/Appointments.tsx b/src/components/appointment/Appointments.tsx index 0ee4f9f1e..ba8223a73 100644 --- a/src/components/appointment/Appointments.tsx +++ b/src/components/appointment/Appointments.tsx @@ -4,6 +4,7 @@ import { Overlay, OVERLAY_FUNCTIONS, OverlayItem } from '../overlay/Overlay'; import { Button, BUTTON_TYPES, ButtonItem } from '../button/Button'; import './appointments.styles.scss'; import { + AgencySpecificContext, NOTIFICATION_TYPE_SUCCESS, NotificationsContext } from '../../globalState'; @@ -31,6 +32,7 @@ import { ListInfo } from '../listInfo/ListInfo'; export const Appointments = () => { const { t: translate } = useTranslation(); const legalLinks = useContext(LegalLinksContext); + const { specificAgency } = useContext(AgencySpecificContext); const { addNotification } = useContext(NotificationsContext); const [loading, setLoading] = useState(true); @@ -310,7 +312,11 @@ export const Appointments = () => {
{legalLinks.map((legalLink, index) => ( - + {index > 0 && ( { /> )} diff --git a/src/components/formAccordion/FormAccordion.tsx b/src/components/formAccordion/FormAccordion.tsx index 510181cda..b9e35bd34 100644 --- a/src/components/formAccordion/FormAccordion.tsx +++ b/src/components/formAccordion/FormAccordion.tsx @@ -13,7 +13,7 @@ import { RequiredComponentsInterface, RegistrationNotesInterface, useTenant, - LegalLinkInterface + AgencySpecificContext } from '../../globalState'; import { FormAccordionItem } from '../formAccordion/FormAccordionItem'; import { RegistrationUsername } from '../registration/RegistrationUsername'; @@ -35,6 +35,7 @@ import { ProposedAgencies } from '../../containers/registration/components/Propo import { useConsultantAgenciesAndConsultingTypes } from '../../containers/registration/hooks/useConsultantAgenciesAndConsultingTypes'; import { FormAccordionData } from '../registration/RegistrationForm'; import { UrlParamsContext } from '../../globalState/provider/UrlParamsProvider'; +import { TProvidedLegalLink } from '../../globalState/provider/LegalLinksProvider'; interface FormAccordionProps { formAccordionData: FormAccordionData; @@ -43,7 +44,7 @@ interface FormAccordionProps { onValidation: Dispatch>; additionalStepsData?: RequiredComponentsInterface; registrationNotes?: RegistrationNotesInterface; - legalLinks: Array; + legalLinks: TProvidedLegalLink[]; handleSubmitButtonClick: Function; isSubmitButtonDisabled: boolean; setIsDataProtectionSelected: Dispatch>; @@ -67,6 +68,9 @@ export const FormAccordion = ({ const tenantData = useTenant(); const { consultingType, consultant } = useContext(UrlParamsContext); + const { setSpecificAgency, specificAgency } = useContext( + AgencySpecificContext + ); const { consultingTypes } = useConsultantAgenciesAndConsultingTypes(); const [activeItem, setActiveItem] = useState(1); @@ -108,7 +112,12 @@ export const FormAccordion = ({ ); formAccordionData.agency?.tenantId && setIsDataProtectionSelected(false); - }, [formAccordionData.agency, setIsDataProtectionSelected]); + setSpecificAgency(formAccordionData.agency); + }, [ + formAccordionData.agency, + setSpecificAgency, + setIsDataProtectionSelected + ]); useEffect(() => { onValidation( @@ -205,9 +214,9 @@ export const FormAccordion = ({ 'registration.dataProtection.label.and' ) : '') + - `` + `` ) .join(''), translate('registration.dataProtection.label.suffix') diff --git a/src/components/profile/Profile.tsx b/src/components/profile/Profile.tsx index c27896454..87e271302 100644 --- a/src/components/profile/Profile.tsx +++ b/src/components/profile/Profile.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import { useState, useRef, useContext, useEffect, Fragment } from 'react'; import { logout } from '../logout/logout'; import { + AgencySpecificContext, AUTHORITIES, ConsultingTypesContext, hasUserAuthority, @@ -60,6 +61,7 @@ export const Profile = () => { const legalLinks = useContext(LegalLinksContext); const { userData } = useContext(UserDataContext); + const { specificAgency } = useContext(AgencySpecificContext); const { consultingTypes } = useContext(ConsultingTypesContext); const [mobileMenu, setMobileMenu] = useState< @@ -467,7 +469,9 @@ export const Profile = () => {
{legalLinks.map((legalLink, index) => ( - + {index > 0 && ( { /> )} diff --git a/src/components/registration/RegistrationForm.tsx b/src/components/registration/RegistrationForm.tsx index 46175568e..17e36b61b 100644 --- a/src/components/registration/RegistrationForm.tsx +++ b/src/components/registration/RegistrationForm.tsx @@ -6,6 +6,7 @@ import { endpoints } from '../../resources/scripts/endpoints'; import { Overlay, OVERLAY_FUNCTIONS, OverlayItem } from '../overlay/Overlay'; import { redirectToApp } from './autoLogin'; import { + AgencySpecificContext, AgencyDataInterface, ConsultingTypeInterface, NOTIFICATION_TYPE_ERROR, diff --git a/src/components/sessionMenu/SessionMenu.tsx b/src/components/sessionMenu/SessionMenu.tsx index c1e6d37c2..2e57e131c 100644 --- a/src/components/sessionMenu/SessionMenu.tsx +++ b/src/components/sessionMenu/SessionMenu.tsx @@ -596,8 +596,12 @@ export const SessionMenu = (props: SessionMenuProps) => {
{legalLinks.map((legalLink) => ( diff --git a/src/components/stageLayout/StageLayout.tsx b/src/components/stageLayout/StageLayout.tsx index 3748c80c8..5928af323 100644 --- a/src/components/stageLayout/StageLayout.tsx +++ b/src/components/stageLayout/StageLayout.tsx @@ -4,7 +4,7 @@ import { Button } from '../button/Button'; import { Text } from '../text/Text'; import './StageLayout.styles.scss'; import clsx from 'clsx'; -import { LocaleContext } from '../../globalState'; +import { AgencySpecificContext, LocaleContext } from '../../globalState'; import { useTranslation } from 'react-i18next'; import { LocaleSwitch } from '../localeSwitch/LocaleSwitch'; import { LegalLinksContext } from '../../globalState/provider/LegalLinksProvider'; @@ -33,6 +33,7 @@ export const StageLayout = ({ const { t: translate } = useTranslation(); const legalLinks = useContext(LegalLinksContext); const { selectableLocales } = useContext(LocaleContext); + const { specificAgency } = useContext(AgencySpecificContext); const settings = useAppConfig(); const { fromL } = useResponsive(); @@ -102,7 +103,11 @@ export const StageLayout = ({ {showLegalLinks && (
{legalLinks.map((legalLink, index) => ( - + {index > 0 && ( - window.open(legalLink.url, '_blank') + window.open( + legalLink.getUrl({ + aid: specificAgency?.id + }), + '_blank' + ) } > ${translate( - legalLink.label + `${translate( + legalLink.getUrl({ aid: null }) )}` ) .join('') diff --git a/src/components/waitingRoom/WaitingRoom.tsx b/src/components/waitingRoom/WaitingRoom.tsx index 78c03fe50..1d9005896 100644 --- a/src/components/waitingRoom/WaitingRoom.tsx +++ b/src/components/waitingRoom/WaitingRoom.tsx @@ -301,9 +301,9 @@ export const WaitingRoom = (props: WaitingRoomProps) => { 'registration.dataProtection.label.and' ) : '') + - `${translate(legalLink.label)}` + `${translate(legalLink.label)}` ) .join(''), translate( diff --git a/src/globalState/index.ts b/src/globalState/index.ts index b127a6723..ef72c8f94 100644 --- a/src/globalState/index.ts +++ b/src/globalState/index.ts @@ -9,6 +9,7 @@ export * from './interfaces/LegalLinkInterface'; export * from './interfaces/ServerAppConfigInterface'; export * from './interfaces/AppConfig'; +export * from './provider/AgencyProvider'; export * from './provider/AnonymousConversationFinishedProvider'; export * from './provider/AnonymousEnquiryAcceptedProvider'; export * from './provider/AnonymousConversationStartedProvider'; diff --git a/src/globalState/provider/AgencyProvider.tsx b/src/globalState/provider/AgencyProvider.tsx new file mode 100644 index 000000000..dba1c9469 --- /dev/null +++ b/src/globalState/provider/AgencyProvider.tsx @@ -0,0 +1,39 @@ +import * as React from 'react'; +import { + createContext, + useState, + useContext, + Dispatch, + SetStateAction, + useEffect +} from 'react'; +import { UserDataContext } from './UserDataProvider'; +import { AgencyDataInterface } from '../interfaces/UserDataInterface'; +import useUrlParamsLoader from '../../utils/useUrlParamsLoader'; + +export const AgencySpecificContext = createContext<{ + specificAgency: AgencyDataInterface; + setSpecificAgency: Dispatch>; +}>(null); + +export function AgencyProvider(props) { + const { userData } = useContext(UserDataContext); + const { agency: urlAgency } = useUrlParamsLoader(); + const [agency, setAgency] = useState(); + + useEffect(() => { + if (userData?.agencies?.length > 0) { + setAgency(userData.agencies[0]); + } else if (urlAgency) { + setAgency(urlAgency); + } + }, [urlAgency, userData]); + + return ( + + {props.children} + + ); +} diff --git a/src/globalState/provider/LegalLinksProvider.tsx b/src/globalState/provider/LegalLinksProvider.tsx index ddddf111a..2352891cc 100644 --- a/src/globalState/provider/LegalLinksProvider.tsx +++ b/src/globalState/provider/LegalLinksProvider.tsx @@ -1,9 +1,15 @@ -import { createContext, ReactNode } from 'react'; +import { createContext, ReactNode, useCallback, useMemo } from 'react'; import { LegalLinkInterface } from '../interfaces/LegalLinkInterface'; import * as React from 'react'; import { useAppConfig } from '../../hooks/useAppConfig'; -export const LegalLinksContext = createContext([]); +export type TProvidedLegalLink = Omit & { + getUrl: (params?: { + [key: string]: string | number | null | undefined; + }) => string; +}; + +export const LegalLinksContext = createContext([]); type TLegalLinksProvider = { legalLinks?: LegalLinkInterface[]; @@ -11,15 +17,46 @@ type TLegalLinksProvider = { }; export function LegalLinksProvider({ - legalLinks, + legalLinks: externalLegalLinks, children }: TLegalLinksProvider) { const settings = useAppConfig(); + const getUrl = useCallback( + ( + url: string, + params: { [key: string]: string | number | null | undefined } + ) => { + const urlObject = Object.entries(params || {}) + .filter(([, value]) => !!value) + .map(([key, value]) => [ + key, + typeof value === 'number' ? value.toString() : value + ]) + .reduce((acc, [key, value]) => { + acc.searchParams.append(key, value); + return acc; + }, new URL(url)); + return urlObject.toString(); + }, + [] + ); + + const legalLinks = useMemo( + () => + (externalLegalLinks ?? settings.legalLinks ?? []).map( + ({ url, ...legalLink }) => ({ + ...legalLink, + getUrl: (params: { + [key: string]: string | number | null | undefined; + }) => getUrl(url, params) + }) + ), + [externalLegalLinks, settings.legalLinks, getUrl] + ); + return ( - + {children} ); diff --git a/src/globalState/state.tsx b/src/globalState/state.tsx index da9c28625..f1c828243 100644 --- a/src/globalState/state.tsx +++ b/src/globalState/state.tsx @@ -11,7 +11,8 @@ import { RocketChatGlobalSettingsProvider, AnonymousConversationStartedProvider, SessionsDataProvider, - ModalProvider + ModalProvider, + AgencyProvider } from '.'; function ProviderComposer({ contexts, children }) { @@ -35,6 +36,7 @@ function ContextProvider({ children }) { , , , + , , , ,