diff --git a/components/ProfileTasks.tsx b/components/ProfileTasks.tsx index b10c79983..83f4e1d28 100644 --- a/components/ProfileTasks.tsx +++ b/components/ProfileTasks.tsx @@ -1,6 +1,6 @@ import Link from 'next/link' -interface Task { +export interface Task { title: string areaLabel: string link: string diff --git a/graphql/mappers/auth-modals.ts b/graphql/mappers/auth-modals.ts index c3d167c4c..81f10b808 100644 --- a/graphql/mappers/auth-modals.ts +++ b/graphql/mappers/auth-modals.ts @@ -82,7 +82,7 @@ const getCachedContent = () => { cache, getFreshValue: async () => { const response = await fetch( - `${process.env.AEM_GRAPHQL_ENDPOINT}getSchAuthModalsV1` + `${process.env.AEM_GRAPHQL_ENDPOINT}getSchAuthModalsV1`, ) if (!response.ok) return null return (await response.json()) as GetSchAuthModalsV1 @@ -91,7 +91,7 @@ const getCachedContent = () => { }) } -export async function getAuthModalsContent() { +export async function getAuthModalsContent(): Promise { const response = await getCachedContent() const resSignedOutContent = response?.data.youHaveBeenSignedOut.item const resStaySignedIn = response?.data.staySignedIn.item @@ -125,13 +125,13 @@ export async function getAuthModalsContent() { en: { bannerHeading: resStaySignedIn?.scHeadingEn, signOutLinkText: resStaySignedIn?.scFragments.filter( - (fragment) => fragment.scId === 'sign-out' + (fragment) => fragment.scId === 'sign-out', )[0].scLinkTextEn, staySignedInLinktext: resStaySignedIn?.scFragments.filter( - (fragment) => fragment.scId === 'stay-signed-in' + (fragment) => fragment.scId === 'stay-signed-in', )[0].scLinkTextEn, bannerContent: resStaySignedIn?.scContentEn.json.map((data) => - data.content.map((paragraph) => paragraph.value) + data.content.map((paragraph) => paragraph.value), ), bannerMinutesAnd: 'minutes and', bannerSeconds: 'seconds', @@ -139,13 +139,13 @@ export async function getAuthModalsContent() { fr: { bannerHeading: resStaySignedIn?.scHeadingFr, signOutLinkText: resStaySignedIn?.scFragments.filter( - (fragment) => fragment.scId === 'sign-out' + (fragment) => fragment.scId === 'sign-out', )[0].scLinkTextFr, staySignedInLinktext: resStaySignedIn?.scFragments.filter( - (fragment) => fragment.scId === 'stay-signed-in' + (fragment) => fragment.scId === 'stay-signed-in', )[0].scLinkTextFr, bannerContent: resStaySignedIn?.scContentFr.json.map((data) => - data.content.map((paragraph) => paragraph.value) + data.content.map((paragraph) => paragraph.value), ), bannerMinutesAnd: 'minutes et', bannerSeconds: 'secondes', @@ -154,3 +154,48 @@ export async function getAuthModalsContent() { return { mappedPopupStaySignedIn, mappedPopupSignedOut } } + +// TODO: Check which of these properties should actually be optional and switch to using a question mark instead +export interface AuthModalsContent { + err?: string + mappedPopupStaySignedIn?: { + en: { + bannerHeading: string | undefined + signOutLinkText: string | undefined + staySignedInLinktext: string | undefined + bannerContent: string[][] | undefined + bannerMinutesAnd: string + bannerSeconds: string + } + fr: { + bannerHeading: string | undefined + signOutLinkText: string | undefined + staySignedInLinktext: string | undefined + bannerContent: string[][] | undefined + bannerMinutesAnd: string + bannerSeconds: string + } + } + mappedPopupSignedOut?: { + en: { + bannerBoldText: string | undefined + bannerText: string | undefined + bannerLink: string | undefined + bannerLinkHref: string | undefined + bannerButtonText: string | undefined + bannerButtonLink: string + icon: string | undefined + bannerHeading: string | undefined + } + fr: { + bannerBoldText: string | undefined + bannerText: string | undefined + bannerLink: string | undefined + bannerLinkHref: string | undefined + bannerButtonText: string | undefined + bannerButtonLink: string + icon: string | undefined + bannerHeading: string | undefined + } + } +} diff --git a/graphql/mappers/profile.ts b/graphql/mappers/profile.ts index f473cf9a1..5a31e1ddd 100644 --- a/graphql/mappers/profile.ts +++ b/graphql/mappers/profile.ts @@ -72,7 +72,7 @@ const getCachedContent = () => { cache, getFreshValue: async () => { const response = await fetch( - `${process.env.AEM_GRAPHQL_ENDPOINT}getSchProfileV1` + `${process.env.AEM_GRAPHQL_ENDPOINT}getSchProfileV1`, ) if (!response.ok) return null return (await response.json()) as GetSchProfileV1 @@ -81,7 +81,7 @@ const getCachedContent = () => { }) } -export async function getProfileContent() { +export async function getProfileContent(): Promise { const response = await getCachedContent() // LookingFor Fragment @@ -95,7 +95,7 @@ export async function getProfileContent() { // BackToDashboard Fragment const backToDashboardFragment = findFragmentByScId( response, - 'back-to-my-dashboard' + 'back-to-my-dashboard', ) // ProfileIntro Fragment @@ -110,7 +110,7 @@ export async function getProfileContent() { link: level.scPageNameEn, text: level.scTitleEn, } - } + }, ), pageName: response?.data.schPageV1ByPath.item.scTitleEn, heading: profileIntroFragment?.scContentEn?.json[0].content[0].value, @@ -162,7 +162,7 @@ export async function getProfileContent() { link: level.scPageNameFr, text: level.scTitleFr, } - } + }, ), pageName: response?.data.schPageV1ByPath.item.scTitleFr, heading: profileIntroFragment?.scContentFr?.json[0].content[0].value, @@ -213,7 +213,97 @@ export async function getProfileContent() { const findFragmentByScId = (res: GetSchProfileV1 | null, id: string) => { return ( res?.data.schPageV1ByPath.item.scFragments.find( - ({ scId }) => scId === id + ({ scId }) => scId === id, ) ?? null ) } + +// TODO: Check which of these properties should actually be optional and switch to using a question mark instead +export interface ProfileContent { + err?: string + en?: + | { + breadcrumb: + | { + link: string + text: string + }[] + | undefined + pageName: string | undefined + heading: string | undefined + list: + | ( + | { + id: string + title: string | undefined + tasks: + | { + id: string + title: string + areaLabel: string + link: string + icon: string + betaPopUp: boolean + }[] + | undefined + } + | undefined + )[] + | undefined + lookingFor: { + title: string | undefined + subText: (string | undefined)[] + link: string + id: string + } + backToDashboard: { + id: string | undefined + btnText: string | undefined + btnLink: string | undefined + } + title?: string | undefined + } + | undefined + fr?: { + breadcrumb: + | { + link: string + text: string + }[] + | undefined + pageName: string | undefined + heading: string | undefined + list: + | ( + | { + id: string + title: string | undefined + tasks: + | { + id: string + title: string + areaLabel: string + link: string + icon: string + betaPopUp: boolean + }[] + | undefined + } + | undefined + )[] + | undefined + lookingFor: { + title: string | undefined + subText: (string | undefined)[] + link: string + id: string + } + backToDashboard: + | { + id: string | undefined + btnText: string | undefined + btnLink: string | undefined + } + | undefined + } +} diff --git a/pages/contact-us/[id].tsx b/pages/contact-us/[id].tsx index 3cf6d9782..cad3ff46b 100644 --- a/pages/contact-us/[id].tsx +++ b/pages/contact-us/[id].tsx @@ -196,12 +196,12 @@ export const getServerSideProps = (async ({ req, res, locale, params }) => { aaMenuPrefix: `ESDC-EDSC_MSCA-MSDC-SCH:Nav Menu`, popupStaySignedIn: locale === 'en' - ? authModals.mappedPopupStaySignedIn.en - : authModals.mappedPopupStaySignedIn.fr, + ? authModals.mappedPopupStaySignedIn?.en + : authModals.mappedPopupStaySignedIn?.fr, popupYouHaveBeenSignedout: locale === 'en' - ? authModals.mappedPopupSignedOut.en - : authModals.mappedPopupSignedOut.fr, + ? authModals.mappedPopupSignedOut?.en + : authModals.mappedPopupSignedOut?.fr, }, } }) satisfies GetServerSideProps diff --git a/pages/contact-us/index.tsx b/pages/contact-us/index.tsx index 44810efed..61b8b3b07 100644 --- a/pages/contact-us/index.tsx +++ b/pages/contact-us/index.tsx @@ -207,12 +207,12 @@ export const getServerSideProps = (async ({ req, res, locale }) => { aaMenuPrefix: `ESDC-EDSC_MSCA-MSDC-SCH:Nav Menu`, popupStaySignedIn: locale === 'en' - ? authModals.mappedPopupStaySignedIn.en - : authModals.mappedPopupStaySignedIn.fr, + ? authModals.mappedPopupStaySignedIn?.en + : authModals.mappedPopupStaySignedIn?.fr, popupYouHaveBeenSignedout: locale === 'en' - ? authModals.mappedPopupSignedOut.en - : authModals.mappedPopupSignedOut.fr, + ? authModals.mappedPopupSignedOut?.en + : authModals.mappedPopupSignedOut?.fr, }, } }) satisfies GetServerSideProps diff --git a/pages/profile.js b/pages/profile.tsx similarity index 68% rename from pages/profile.js rename to pages/profile.tsx index 711df7af2..74c28d61e 100644 --- a/pages/profile.js +++ b/pages/profile.tsx @@ -3,8 +3,11 @@ import Heading from '../components/Heading' import PageLink from '../components/PageLink' import en from '../locales/en' import fr from '../locales/fr' -import { getProfileContent } from '../graphql/mappers/profile' -import { getAuthModalsContent } from '../graphql/mappers/auth-modals' +import { getProfileContent, ProfileContent } from '../graphql/mappers/profile' +import { + AuthModalsContent, + getAuthModalsContent, +} from '../graphql/mappers/auth-modals' import { getLogger } from '../logging/log-util' import { AuthIsDisabled, @@ -13,19 +16,61 @@ import { Redirect, getIdToken, } from '../lib/auth' -import { authOptions } from '../pages/api/auth/[...nextauth]' +import { authOptions } from './api/auth/[...nextauth]' import { getServerSession } from 'next-auth/next' -import ProfileTasks from './../components/ProfileTasks' -import React from 'react' +import ProfileTasks, { Task } from '../components/ProfileTasks' +import React, { ReactNode } from 'react' import { acronym } from '../lib/acronym' import ErrorPage from '../components/ErrorPage' +import { GetServerSidePropsContext } from 'next' + +interface ProfilePageProps { + locale: string | undefined + content: { + err?: '500' | '404' | '503' + pageName: string + heading: string + list: { + // TODO: Figure out what this return value is + map: ( + arg0: ( + program: { + title: string + tasks: Task[] + }, + index: string, + ) => React.JSX.Element, + ) => ReactNode + } + lookingFor: { + title: string + subText: string[] + link: string + } + backToDashboard: { btnLink: string; btnText: string } + } + bannerContent?: { + err?: '500' | '404' | '503' + } + popupContent?: { + err?: '500' | '404' | '503' + } + popupContentNA?: { + err?: '500' | '404' | '503' + } + // TODO: Is this actually being used? + authModals?: { + err?: '500' | '404' | '503' + } + aaPrefix: string +} -export default function Profile(props) { +export default function Profile(props: ProfilePageProps) { /* istanbul ignore next */ const t = props.locale === 'en' ? en : fr const errorCode = - props.content?.err || + props.content.err || props.bannerContent?.err || props.popupContent?.err || props.popupContentNA?.err || @@ -40,7 +85,7 @@ export default function Profile(props) { props.locale === 'en' ? 'en/my-dashboard' : 'fr/mon-tableau-de-bord' } accountPageLink={ - props?.locale === 'en' + props.locale === 'en' ? 'https://srv136.services.gc.ca/sc/msca-mdsc/portal-portail/pro/home-accueil?Lang=eng' : 'https://srv136.services.gc.ca/sc/msca-mdsc/portal-portail/pro/home-accueil?Lang=fra' } @@ -84,7 +129,15 @@ export default function Profile(props) { ) } -export async function getServerSideProps({ req, res, locale }) { +export async function getServerSideProps({ + req, + res, + locale, +}: { + req: GetServerSidePropsContext['req'] + res: GetServerSidePropsContext['res'] + locale: string +}) { const session = await getServerSession(req, res, authOptions) if (!AuthIsDisabled() && !(await AuthIsValid(req, session))) @@ -126,27 +179,30 @@ export async function getServerSideProps({ req, res, locale }) { const content = await getProfileContent().catch((error) => { logger.error(error) - return { err: '500' } + return { err: '500' } as ProfileContent }) const authModals = await getAuthModalsContent().catch((error) => { logger.error(error) - return { err: '500' } + return { err: '500' } as AuthModalsContent }) /* istanbul ignore next */ const langToggleLink = locale === 'en' ? '/fr/profil' : '/en/profile' - - const t = locale === 'en' ? en : fr - const breadCrumbItems = - locale === 'en' - ? content.en.breadcrumb?.map(({ link, text }) => { - return { text, link: '/' + locale + '/' + link } - }) - : content.fr.breadcrumb?.map(({ link, text }) => { - return { text, link: '/' + locale + '/' + link } - }) + content.err !== undefined + ? [] + : locale === 'en' + ? content.en?.breadcrumb?.map( + ({ link, text }: { link: string; text: string }) => { + return { text, link: '/' + locale + '/' + link } + }, + ) + : content.fr?.breadcrumb?.map( + ({ link, text }: { link: string; text: string }) => { + return { text, link: '/' + locale + '/' + link } + }, + ) /* Place-holder Meta Data Props */ const meta = { @@ -175,7 +231,7 @@ export async function getServerSideProps({ req, res, locale }) { locale, langToggleLink, content: - content?.err !== undefined + content.err !== undefined ? content : locale === 'en' ? content.en @@ -183,23 +239,23 @@ export async function getServerSideProps({ req, res, locale }) { meta, breadCrumbItems, aaPrefix: - content?.err !== undefined + content.err !== undefined ? '' : `ESDC-EDSC_MSCA-MSDC-SCH:${content.en?.pageName || content.en?.title}`, aaMenuPrefix: - content?.err !== undefined ? '' : `ESDC-EDSC_MSCA-MSDC-SCH:Nav Menu`, + content.err !== undefined ? '' : `ESDC-EDSC_MSCA-MSDC-SCH:Nav Menu`, popupStaySignedIn: - authModals?.err !== undefined + authModals.err !== undefined ? authModals : locale === 'en' - ? authModals.mappedPopupStaySignedIn.en - : authModals.mappedPopupStaySignedIn.fr, + ? authModals.mappedPopupStaySignedIn?.en + : authModals.mappedPopupStaySignedIn?.fr, popupYouHaveBeenSignedout: - authModals?.err !== undefined + authModals.err !== undefined ? authModals : locale === 'en' - ? authModals.mappedPopupSignedOut.en - : authModals.mappedPopupSignedOut.fr, + ? authModals.mappedPopupSignedOut?.en + : authModals.mappedPopupSignedOut?.fr, }, } }