diff --git a/app/[lang]/(live-current)/@languageSwitcher/page.tsx b/app/[lang]/(live-current)/@languageSwitcher/page.tsx index 18783cdd0..24881aa47 100644 --- a/app/[lang]/(live-current)/@languageSwitcher/page.tsx +++ b/app/[lang]/(live-current)/@languageSwitcher/page.tsx @@ -9,19 +9,13 @@ import Mobile from "@/components/Current/Header/LanguageSwitcher/Mobile" import styles from "./page.module.css" -import { LangParams, PageArgs } from "@/types/params" +import { LangParams, PageArgs, UIDParams, UriParams } from "@/types/params" import { LanguageSwitcherData } from "@/types/requests/languageSwitcher" export default async function LanguageSwitcher({ params, searchParams, -}: PageArgs< - LangParams, - { - uid: string - uri: string - } ->) { +}: PageArgs) { if (!searchParams.uid) { return null } diff --git a/components/Current/Header/BookingButton/index.tsx b/components/Current/Header/BookingButton/index.tsx index 095120ae4..fba9ee4c2 100644 --- a/components/Current/Header/BookingButton/index.tsx +++ b/components/Current/Header/BookingButton/index.tsx @@ -1,11 +1,13 @@ import "@scandic-hotels/design-system/current/style.css" +import { _ } from "@/lib/translation" + import styles from "./bookingButton.module.css" export default function BookingButton({ href }: { href: string }) { return ( - Book + {_("Book")} ) } diff --git a/components/Current/Header/MainMenu/index.tsx b/components/Current/Header/MainMenu/index.tsx index af241f7f7..67d7d17bb 100644 --- a/components/Current/Header/MainMenu/index.tsx +++ b/components/Current/Header/MainMenu/index.tsx @@ -25,11 +25,10 @@ export function MainMenu({ languageSwitcher, bookingHref, isLoggedIn, + lang, }: MainMenuProps) { const [isOpen, setIsOpen] = useState(false) - const lang = useParams().lang as Lang - function toogleIsOpen() { setIsOpen((prevIsOpen) => !prevIsOpen) } diff --git a/components/Current/Header/index.tsx b/components/Current/Header/index.tsx index 449333111..457dbad09 100644 --- a/components/Current/Header/index.tsx +++ b/components/Current/Header/index.tsx @@ -45,6 +45,7 @@ export default async function Header({ languageSwitcher={languageSwitcher} bookingHref={homeHref} isLoggedIn={!!session} + lang={lang} /> ) diff --git a/server/routers/contentstack/header/index.ts b/server/routers/contentstack/header/index.ts deleted file mode 100644 index 53b998e7f..000000000 --- a/server/routers/contentstack/header/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { mergeRouters } from "@/server/trpc" - -import { accountPageQueryRouter } from "./query" - -export const accountPageRouter = mergeRouters(accountPageQueryRouter) diff --git a/server/routers/contentstack/header/output.ts b/server/routers/contentstack/header/output.ts deleted file mode 100644 index e78b0951e..000000000 --- a/server/routers/contentstack/header/output.ts +++ /dev/null @@ -1,190 +0,0 @@ -import { z } from "zod" - -import { Lang } from "@/constants/languages" - -import { - ContentEntries, - DynamicContentComponents, -} from "@/types/components/myPages/myPage/enums" -import { Embeds } from "@/types/requests/embeds" -import { PageLinkEnum } from "@/types/requests/pageLinks" -import { Edges } from "@/types/requests/utils/edges" -import { RTEDocument } from "@/types/rte/node" - -const accountPageShortcuts = z.object({ - __typename: z.literal(ContentEntries.AccountPageContentShortcuts), - shortcuts: z.object({ - title: z.string().nullable(), - preamble: z.string().nullable(), - shortcuts: z.array( - z.object({ - linkConnection: z.object({ - edges: z.array( - z.object({ - node: z.object({ - system: z.object({ - uid: z.string(), - locale: z.nativeEnum(Lang), - }), - original_url: z.string().nullable().optional(), - url: z.string(), - title: z.string(), - }), - }) - ), - totalCount: z.number(), - }), - text: z.string().nullable(), - open_in_new_tab: z.boolean(), - }) - ), - }), -}) - -const accountPageDynamicContent = z.object({ - __typename: z.literal(ContentEntries.AccountPageContentDynamicContent), - dynamic_content: z.object({ - title: z.string().nullable(), - preamble: z.string().nullable(), - component: z.nativeEnum(DynamicContentComponents), - link: z.object({ - linkConnection: z.object({ - edges: z.array( - z.object({ - node: z.object({ - system: z.object({ - uid: z.string(), - locale: z.nativeEnum(Lang), - }), - url: z.string(), - original_url: z.string().nullable().optional(), - title: z.string(), - }), - }) - ), - totalCount: z.number(), - }), - link_text: z.string(), - }), - }), -}) - -const accountPageTextContent = z.object({ - __typename: z.literal(ContentEntries.AccountPageContentTextContent), - text_content: z.object({ - content: z.object({ - json: z.any(), - embedded_itemsConnection: z.object({ - edges: z.array(z.any()), - totalCount: z.number(), - }), - }), - }), -}) - -type TextContentRaw = z.infer - -type DynamicContentRaw = z.infer - -type ShortcutsRaw = z.infer - -export type Shortcuts = Omit & { - shortcuts: Omit & { - shortcuts: { - text?: string - openInNewTab: boolean - url: string - title: string - }[] - } -} - -export type RteTextContent = Omit & { - text_content: { - content: { - json: RTEDocument - embedded_itemsConnection: Edges - } - } -} - -export type AccountPageContentItem = - | DynamicContentRaw - | Shortcuts - | RteTextContent - -const accountPageContentItem = z.discriminatedUnion("__typename", [ - accountPageShortcuts, - accountPageDynamicContent, - accountPageTextContent, -]) - -export const validateAccountPageSchema = z.object({ - account_page: z.object({ - url: z.string(), - title: z.string(), - content: z.array(accountPageContentItem), - }), -}) - -export type AccountPageDataRaw = z.infer - -type AccountPageRaw = AccountPageDataRaw["account_page"] - -export type AccountPage = Omit & { - content: AccountPageContentItem[] -} - -// Refs types -const pageConnectionRefs = z.object({ - edges: z.array( - z.object({ - node: z.object({ - __typename: z.nativeEnum(PageLinkEnum), - system: z.object({ - content_type_uid: z.string(), - uid: z.string(), - }), - }), - }) - ), -}) - -const accountPageShortcutsRefs = z.object({ - __typename: z.literal(ContentEntries.AccountPageContentShortcuts), - shortcuts: z.object({ - shortcuts: z.array( - z.object({ - linkConnection: pageConnectionRefs, - }) - ), - }), -}) - -const accountPageDynamicContentRefs = z.object({ - __typename: z.literal(ContentEntries.AccountPageContentDynamicContent), - dynamic_content: z.object({ - link: z.object({ - linkConnection: pageConnectionRefs, - }), - }), -}) - -const accountPageContentItemRefs = z.discriminatedUnion("__typename", [ - accountPageDynamicContentRefs, - accountPageShortcutsRefs, -]) - -export const validateAccountPageRefsSchema = z.object({ - account_page: z.object({ - content: z.array(accountPageContentItemRefs), - system: z.object({ - content_type_uid: z.string(), - uid: z.string(), - }), - }), -}) - -export type AccountPageRefsDataRaw = z.infer< - typeof validateAccountPageRefsSchema -> diff --git a/server/routers/contentstack/header/query.ts b/server/routers/contentstack/header/query.ts deleted file mode 100644 index 17375efa6..000000000 --- a/server/routers/contentstack/header/query.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { - GetAccountPage, - GetAccountPageRefs, -} from "@/lib/graphql/Query/AccountPage.graphql" -import { request } from "@/lib/graphql/request" -import { internalServerError, notFound } from "@/server/errors/trpc" -import { contentstackProcedure, router } from "@/server/trpc" - -import { - generateRefsResponseTag, - generateTag, - generateTags, -} from "@/utils/generateTag" - -import { removeEmptyObjects } from "../../utils" -import { - type AccountPage, - AccountPageRefsDataRaw, - validateAccountPageRefsSchema, - validateAccountPageSchema, -} from "./output" -import { getConnections } from "./utils" - -import { ContentEntries } from "@/types/components/myPages/myPage/enums" -import { Embeds } from "@/types/requests/embeds" -import { Edges } from "@/types/requests/utils/edges" -import { RTEDocument } from "@/types/rte/node" - -export const accountPageQueryRouter = router({ - get: contentstackProcedure.query(async ({ ctx }) => { - const { lang, uid } = ctx - - const refsResponse = await request( - GetAccountPageRefs, - { - locale: lang, - uid, - }, - { - next: { - tags: [generateRefsResponseTag(lang, uid)], - }, - } - ) - - if (!refsResponse.data) { - throw notFound(refsResponse) - } - - // Remove empty objects from a fetched content type. Needed since - // Contentstack returns empty objects for all non queried blocks in modular blocks. - // This is an ongoing support case in Contentstack, ticker number #00031579 - const cleanedData = removeEmptyObjects(refsResponse.data) - - const validatedAccountPageRefs = - validateAccountPageRefsSchema.safeParse(cleanedData) - if (!validatedAccountPageRefs.success) { - throw internalServerError(validatedAccountPageRefs.error) - } - - const connections = getConnections(validatedAccountPageRefs.data) - - const tags = [ - generateTags(lang, connections), - generateTag(lang, validatedAccountPageRefs.data.account_page.system.uid), - ].flat() - - const response = await request( - GetAccountPage, - { - locale: lang, - uid, - }, - { next: { tags } } - ) - - if (!response.data) { - throw notFound(response) - } - - const validatedAccountPage = validateAccountPageSchema.safeParse( - response.data - ) - - if (!validatedAccountPage.success) { - throw internalServerError(validatedAccountPage.error) - } - - // TODO: Make returned data nicer - const content = validatedAccountPage.data.account_page.content.map( - (block) => { - switch (block.__typename) { - case ContentEntries.AccountPageContentDynamicContent: - return block - case ContentEntries.AccountPageContentShortcuts: - return { - ...block, - shortcuts: { - ...block.shortcuts, - shortcuts: block.shortcuts.shortcuts.map((shortcut) => ({ - text: shortcut.text, - openInNewTab: shortcut.open_in_new_tab, - ...shortcut.linkConnection.edges[0].node, - url: - shortcut.linkConnection.edges[0].node.original_url || - `/${shortcut.linkConnection.edges[0].node.system.locale}${shortcut.linkConnection.edges[0].node.url}`, - })), - }, - } - case ContentEntries.AccountPageContentTextContent: - return { - ...block, - text_content: { - content: { - json: block.text_content.content.json as RTEDocument, - embedded_itemsConnection: block.text_content.content - .embedded_itemsConnection as Edges, - }, - }, - } - default: - return null - } - } - ) - - const accountPage = { - ...validatedAccountPage.data.account_page, - content, - } as AccountPage - - return accountPage - }), -}) diff --git a/server/routers/contentstack/header/utils.ts b/server/routers/contentstack/header/utils.ts deleted file mode 100644 index 8b1e73d7d..000000000 --- a/server/routers/contentstack/header/utils.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { AccountPageRefsDataRaw } from "./output" - -import { ContentEntries } from "@/types/components/myPages/myPage/enums" -import type { Edges } from "@/types/requests/utils/edges" -import type { NodeRefs } from "@/types/requests/utils/refs" - -export function getConnections(refs: AccountPageRefsDataRaw) { - const connections: Edges[] = [] - if (refs.account_page.content) { - refs.account_page.content.forEach((item) => { - switch (item.__typename) { - case ContentEntries.AccountPageContentShortcuts: { - item.shortcuts.shortcuts.forEach((shortcut) => { - if (shortcut.linkConnection.edges.length) { - connections.push(shortcut.linkConnection) - } - }) - break - } - case ContentEntries.AccountPageContentDynamicContent: { - if (item.dynamic_content.link.linkConnection.edges.length) { - connections.push(item.dynamic_content.link.linkConnection) - } - break - } - } - }) - } - - return connections -} diff --git a/types/components/current/header/mainMenu.ts b/types/components/current/header/mainMenu.ts index 6873a3ed9..229c590b2 100644 --- a/types/components/current/header/mainMenu.ts +++ b/types/components/current/header/mainMenu.ts @@ -1,3 +1,5 @@ +import { Lang } from "@/constants/languages" + import type { Image } from "@/types/image" import type { CurrentHeaderLink, @@ -13,4 +15,5 @@ export type MainMenuProps = { languageSwitcher: React.ReactNode bookingHref: string isLoggedIn: boolean + lang: Lang }