fix: refactor language switcher

This commit is contained in:
Christel Westerberg
2024-06-03 09:38:17 +02:00
parent 2c102c62e0
commit 095edcce8c
14 changed files with 196 additions and 230 deletions

View File

@@ -5,16 +5,20 @@ import Mobile from "@/components/Current/Header/LanguageSwitcher/Mobile"
import styles from "./page.module.css"
export default async function LanguageSwitcher() {
const data = await serverClient().contentstack.accountPage.languageSwitcher()
import { LangParams, PageArgs, UriParams } from "@/types/params"
export default async function LanguageSwitcher({
params,
}: PageArgs<LangParams & UriParams>) {
const { urls } = await serverClient().contentstack.config.languageSwitcher()
return (
<>
<section className={styles.desktop}>
<Desktop currentLanguage={data.lang} urls={data.urls} />
<Desktop currentLanguage={params.lang} urls={urls} />
</section>
<section className={styles.mobile}>
<Mobile currentLanguage={data.lang} urls={data.urls} />
<Mobile currentLanguage={params.lang} urls={urls} />
</section>
</>
)

View File

@@ -1,50 +0,0 @@
import { notFound } from "next/navigation"
import { Lang } from "@/constants/languages"
import { serverClient } from "@/lib/trpc/server"
import Desktop from "@/components/Current/Header/LanguageSwitcher/Desktop"
import Mobile from "@/components/Current/Header/LanguageSwitcher/Mobile"
import styles from "./page.module.css"
import {
ContentTypeParams,
LangParams,
PageArgs,
UIDParams,
} from "@/types/params"
import { LanguageSwitcherData } from "@/types/requests/languageSwitcher"
export default async function LanguageSwitcher({
params,
}: PageArgs<LangParams & ContentTypeParams & UIDParams, {}>) {
let urls: LanguageSwitcherData
let lang: Lang
switch (params.contentType) {
case "loyalty-page":
const data =
await serverClient().contentstack.loyaltyPage.languageSwitcher()
urls = data.urls
lang = data.lang
break
case "content-page":
// TODO: Implement this
return null
default:
const type: never = params.contentType
console.error(`Unsupported content type given: ${type}`)
notFound()
}
return (
<>
<section className={styles.desktop}>
<Desktop currentLanguage={params.lang} urls={urls} />
</section>
<section className={styles.mobile}>
<Mobile currentLanguage={params.lang} urls={urls} />
</section>
</>
)
}

View File

@@ -1,17 +0,0 @@
.desktop {
display: none;
}
.mobile {
display: block;
}
@media (min-width: 950px) {
.desktop {
display: block;
}
.mobile {
display: none;
}
}

View File

@@ -1,8 +1,4 @@
import { batchRequest } from "@/lib/graphql/batchRequest"
import {
GetDaDeEnUrlsCurrentBlocksPage,
GetFiNoSvUrlsCurrentBlocksPage,
} from "@/lib/graphql/Query/LanguageSwitcherCurrent.graphql"
import { serverClient } from "@/lib/trpc/server"
import Desktop from "@/components/Current/Header/LanguageSwitcher/Desktop"
import Mobile from "@/components/Current/Header/LanguageSwitcher/Mobile"
@@ -10,7 +6,6 @@ import Mobile from "@/components/Current/Header/LanguageSwitcher/Mobile"
import styles from "./page.module.css"
import { LangParams, PageArgs, UIDParams, UriParams } from "@/types/params"
import { LanguageSwitcherData } from "@/types/requests/languageSwitcher"
export default async function LanguageSwitcher({
params,
@@ -20,20 +15,7 @@ export default async function LanguageSwitcher({
return null
}
const variables = {
uid: searchParams.uid,
}
const { data: urls } = await batchRequest<LanguageSwitcherData>([
{
document: GetDaDeEnUrlsCurrentBlocksPage,
variables,
},
{
document: GetFiNoSvUrlsCurrentBlocksPage,
variables,
},
])
const { urls } = await serverClient().contentstack.config.languageSwitcher()
return (
<>

View File

@@ -64,35 +64,29 @@ query GetAccountPageRefs($locale: String!, $uid: String!) {
}
query GetDaDeEnUrlsAccountPage($uid: String!) {
de: all_account_page(where: { uid: $uid }, locale: "de") {
items {
url
}
de: account_page(uid: $uid, locale: "de") {
url
}
en: all_account_page(where: { uid: $uid }, locale: "en") {
items {
url
}
en: account_page(uid: $uid, locale: "en") {
url
}
da: all_account_page(where: { uid: $uid }, locale: "da") {
items {
url
}
da: account_page(uid: $uid, locale: "da") {
url
}
}
query GetFiNoSvUrlsAccountPage($uid: String!) {
fi: all_account_page(where: { uid: $uid }, locale: "fi") {
fi: account_page(uid: $uid, locale: "fi") {
items {
url
}
}
no: all_account_page(where: { uid: $uid }, locale: "no") {
no: account_page(uid: $uid, locale: "no") {
items {
url
}
}
sv: all_account_page(where: { uid: $uid }, locale: "sv") {
sv: account_page(uid: $uid, locale: "sv") {
items {
url
}

View File

@@ -3,6 +3,7 @@
#import "../Fragments/Footer/Navigation.graphql"
#import "../Fragments/Footer/SocialMedia.graphql"
#import "../Fragments/Footer/TripAdvisor.graphql"
#import "../Fragments/Refs/System.graphql"
query GetCurrentFooter($locale: String!) {
all_current_footer(limit: 1, locale: $locale) {
@@ -24,3 +25,13 @@ query GetCurrentFooter($locale: String!) {
}
}
}
query GetCurrentFooterRef($locale: String!) {
all_current_footer(limit: 1, locale: $locale) {
items {
system {
...System
}
}
}
}

View File

@@ -1,10 +1,6 @@
import { Lang } from "@/constants/languages"
import { batchRequest } from "@/lib/graphql/batchRequest"
import {
GetAccountPage,
GetAccountPageRefs,
GetDaDeEnUrlsAccountPage,
GetFiNoSvUrlsAccountPage,
} from "@/lib/graphql/Query/AccountPage.graphql"
import { request } from "@/lib/graphql/request"
import { internalServerError, notFound } from "@/server/errors/trpc"
@@ -22,16 +18,11 @@ import {
AccountPageRefsDataRaw,
validateAccountPageRefsSchema,
validateAccountPageSchema,
validateLanguageSwitcherData,
} from "./output"
import { getConnections } from "./utils"
import { ContentEntries } from "@/types/components/myPages/myPage/enums"
import { Embeds } from "@/types/requests/embeds"
import {
LanguageSwitcherData,
LanguageSwitcherQueryDataRaw,
} from "@/types/requests/languageSwitcher"
import { Edges } from "@/types/requests/utils/edges"
import { RTEDocument } from "@/types/rte/node"
@@ -140,38 +131,4 @@ export const accountPageQueryRouter = router({
return accountPage
}),
languageSwitcher: contentstackProcedure.query(async ({ ctx }) => {
const variables = {
uid: ctx.uid,
}
const res = await batchRequest<LanguageSwitcherQueryDataRaw>([
{
document: GetDaDeEnUrlsAccountPage,
variables,
},
{
document: GetFiNoSvUrlsAccountPage,
variables,
},
])
const urls = Object.keys(res.data).reduce<LanguageSwitcherData>(
(acc, key) => {
const item = res.data[key as Lang]?.items[0]
const url = item ? `/${key}${item.url}` : undefined
return { ...acc, [key]: { url, isExternal: false } }
},
{} as LanguageSwitcherData
)
const validatedLanguageSwitcherData =
validateLanguageSwitcherData.safeParse(urls)
if (!validatedLanguageSwitcherData.success) {
throw internalServerError(validatedLanguageSwitcherData.error)
}
return { lang: ctx.lang, urls }
}),
})

View File

@@ -132,6 +132,8 @@ const validateHeaderRefConfigSchema = z.object({
}),
})
export type HeaderRefDataRaw = z.infer<typeof validateHeaderRefConfigSchema>
const validateAppDownload = z.object({
href: z.string(),
imageConnection: z.object({
@@ -155,9 +157,6 @@ const validateAppDownload = z.object({
}),
})
export type HeaderRefDataRaw = z.infer<typeof validateHeaderRefConfigSchema>
const validateNavigationItem = z.object({
links: z.array(z.object({ href: z.string(), title: z.string() })),
title: z.string(),
@@ -240,3 +239,27 @@ export type FooterData = Omit<
> & {
logo: Image
}
const validateFooterRefConfigSchema = z.object({
all_current_footer: z.object({
items: z.array(
z.object({
system: z.object({
content_type_uid: z.string(),
uid: z.string(),
}),
})
),
}),
})
export type FooterRefDataRaw = z.infer<typeof validateFooterRefConfigSchema>
export const validateLanguageSwitcherData = z.object({
en: z.object({ url: z.string(), isExternal: z.boolean() }).optional(),
da: z.object({ url: z.string(), isExternal: z.boolean() }).optional(),
de: z.object({ url: z.string(), isExternal: z.boolean() }).optional(),
fi: z.object({ url: z.string(), isExternal: z.boolean() }).optional(),
sv: z.object({ url: z.string(), isExternal: z.boolean() }).optional(),
no: z.object({ url: z.string(), isExternal: z.boolean() }).optional(),
})

View File

@@ -1,9 +1,26 @@
import { Lang } from "@/constants/languages"
import { batchRequest } from "@/lib/graphql/batchRequest"
import {
GetDaDeEnUrlsAccountPage,
GetFiNoSvUrlsAccountPage,
} from "@/lib/graphql/Query/AccountPage.graphql"
import { GetContactConfig } from "@/lib/graphql/Query/ContactConfig.graphql"
import { GetCurrentFooter } from "@/lib/graphql/Query/CurrentFooter.graphql"
import {
GetCurrentFooter,
GetCurrentFooterRef,
} from "@/lib/graphql/Query/CurrentFooter.graphql"
import {
GetCurrentHeader,
GetCurrentHeaderRef,
} from "@/lib/graphql/Query/CurrentHeader.graphql"
import {
GetDaDeEnUrlsCurrentBlocksPage,
GetFiNoSvUrlsCurrentBlocksPage,
} from "@/lib/graphql/Query/LanguageSwitcherCurrent.graphql"
import {
GetDaDeEnUrlsLoyaltyPage,
GetFiNoSvUrlsLoyaltyPage,
} from "@/lib/graphql/Query/LoyaltyPage.graphql"
import { request } from "@/lib/graphql/request"
import { internalServerError, notFound } from "@/server/errors/trpc"
import { contentstackProcedure, publicProcedure, router } from "@/server/trpc"
@@ -13,14 +30,22 @@ import { generateTag } from "@/utils/generateTag"
import {
type ContactConfigData,
FooterDataRaw,
FooterRefDataRaw,
HeaderData,
HeaderDataRaw,
HeaderRefDataRaw,
validateContactConfigSchema,
validateFooterConfigSchema,
validateHeaderConfigSchema,
validateLanguageSwitcherData,
} from "./output"
import {
LanguageSwitcherData,
LanguageSwitcherQueryDataRaw,
} from "@/types/requests/languageSwitcher"
import { PageTypeEnum } from "@/types/requests/pageType"
export const configQueryRouter = router({
contact: contentstackProcedure.query(async ({ ctx }) => {
const { lang } = ctx
@@ -85,13 +110,24 @@ export const configQueryRouter = router({
} as HeaderData
}),
footer: contentstackProcedure.query(async ({ ctx }) => {
const responseRef = await request<FooterRefDataRaw>(GetCurrentFooterRef, {
locale: ctx.lang,
})
const response = await request<FooterDataRaw>(
GetCurrentFooter,
{
locale: ctx.lang,
},
{
next: { tags: [`footer-${ctx.lang}`] },
next: {
tags: [
generateTag(
ctx.lang,
responseRef.data.all_current_footer.items[0].system.uid
),
],
},
}
)
@@ -105,4 +141,99 @@ export const configQueryRouter = router({
return validatedFooterConfig.data.all_current_footer.items[0]
}),
languageSwitcher: contentstackProcedure.query(async ({ ctx }) => {
const variables = { uid: ctx.uid, locale: ctx.lang }
let urls: LanguageSwitcherData
switch (ctx.contentType) {
case PageTypeEnum.accountPage:
const accountPageRes = await batchRequest<LanguageSwitcherQueryDataRaw>(
[
{
document: GetDaDeEnUrlsAccountPage,
variables,
},
{
document: GetFiNoSvUrlsAccountPage,
variables,
},
]
)
const accountPageUrls = Object.keys(
accountPageRes.data
).reduce<LanguageSwitcherData>((acc, key) => {
const item = accountPageRes.data[key as Lang]?.items?.[0]
const url = item
? { url: `/${key}${item.url}`, isExternal: false }
: undefined
return { ...acc, [key]: url }
}, {} as LanguageSwitcherData)
const validatedAccountLanguageSwitcherData =
validateLanguageSwitcherData.safeParse(accountPageUrls)
if (!validatedAccountLanguageSwitcherData.success) {
throw internalServerError(validatedAccountLanguageSwitcherData.error)
}
urls = validatedAccountLanguageSwitcherData.data
break
case PageTypeEnum.loyaltyPage:
const loyaltyPageRes = await batchRequest<LanguageSwitcherQueryDataRaw>(
[
{
document: GetDaDeEnUrlsLoyaltyPage,
variables,
},
{
document: GetFiNoSvUrlsLoyaltyPage,
variables,
},
]
)
const loyaltyPageUrls = Object.keys(
loyaltyPageRes.data
).reduce<LanguageSwitcherData>((acc, key) => {
const item = loyaltyPageRes.data[key as Lang]?.items?.[0]
const url = item
? {
url: item.web?.original_url || `/${key}${item.url}`,
isExternal: !!item?.web?.original_url,
}
: undefined
return {
...acc,
[key]: url,
}
}, {} as LanguageSwitcherData)
const validatedLoyaltyLanguageSwitcherData =
validateLanguageSwitcherData.safeParse(loyaltyPageUrls)
if (!validatedLoyaltyLanguageSwitcherData.success) {
throw internalServerError(validatedLoyaltyLanguageSwitcherData.error)
}
urls = validatedLoyaltyLanguageSwitcherData.data
break
case PageTypeEnum.currentBlocksPage:
const { data } = await batchRequest<LanguageSwitcherData>([
{
document: GetDaDeEnUrlsCurrentBlocksPage,
variables,
},
{
document: GetFiNoSvUrlsCurrentBlocksPage,
variables,
},
])
urls = data
break
default:
urls = [] as unknown as LanguageSwitcherData
}
return { urls, lang: ctx.lang }
}),
})

View File

@@ -306,24 +306,3 @@ export const validateLoyaltyPageRefsSchema = z.object({
export type LoyaltyPageRefsDataRaw = z.infer<
typeof validateLoyaltyPageRefsSchema
>
export const validateLanguageSwitcherData = z.object({
en: z
.object({ url: z.string().optional(), isExternal: z.boolean() })
.nullable(),
da: z
.object({ url: z.string().optional(), isExternal: z.boolean() })
.nullable(),
de: z
.object({ url: z.string().optional(), isExternal: z.boolean() })
.nullable(),
fi: z
.object({ url: z.string().optional(), isExternal: z.boolean() })
.nullable(),
sv: z
.object({ url: z.string().optional(), isExternal: z.boolean() })
.nullable(),
no: z
.object({ url: z.string().optional(), isExternal: z.boolean() })
.nullable(),
})

View File

@@ -1,8 +1,4 @@
import { Lang } from "@/constants/languages"
import { batchRequest } from "@/lib/graphql/batchRequest"
import {
GetDaDeEnUrlsLoyaltyPage,
GetFiNoSvUrlsLoyaltyPage,
GetLoyaltyPage,
GetLoyaltyPageRefs,
} from "@/lib/graphql/Query/LoyaltyPage.graphql"
@@ -21,17 +17,12 @@ import { removeEmptyObjects } from "../../utils"
import {
LoyaltyPage,
type LoyaltyPageRefsDataRaw,
validateLanguageSwitcherData,
validateLoyaltyPageRefsSchema,
validateLoyaltyPageSchema,
} from "./output"
import { getConnections } from "./utils"
import { LoyaltyBlocksTypenameEnum } from "@/types/components/loyalty/enums"
import {
LanguageSwitcherData,
LanguageSwitcherQueryDataRaw,
} from "@/types/requests/languageSwitcher"
function makeButtonObject(button: any) {
return {
@@ -181,44 +172,4 @@ export const loyaltyPageQueryRouter = router({
// Assert LoyaltyPage type to get correct typings for RTE fields
return validatedLoyaltyPage.data as LoyaltyPage
}),
languageSwitcher: contentstackProcedure.query(async ({ ctx }) => {
const variables = {
uid: ctx.uid,
}
const res = await batchRequest<LanguageSwitcherQueryDataRaw>([
{
document: GetDaDeEnUrlsLoyaltyPage,
variables,
},
{
document: GetFiNoSvUrlsLoyaltyPage,
variables,
},
])
const urls = Object.keys(res.data).reduce<LanguageSwitcherData>(
(acc, key) => {
const item = res.data[key as Lang]?.items[0]
const url = item
? item.web?.original_url || `/${key}${item.url}`
: undefined
return {
...acc,
[key]: { url, isExternal: !!item?.web?.original_url },
}
},
{} as LanguageSwitcherData
)
const validatedLanguageSwitcherData =
validateLanguageSwitcherData.safeParse(urls)
if (!validatedLanguageSwitcherData.success) {
throw internalServerError(validatedLanguageSwitcherData.error)
}
return { lang: ctx.lang, urls }
}),
})

View File

@@ -4,12 +4,12 @@ type CurrentLanguageResult = {
}
export type LanguageSwitcherData = {
da: CurrentLanguageResult | undefined
de: CurrentLanguageResult | undefined
en: CurrentLanguageResult | undefined
fi: CurrentLanguageResult | undefined
no: CurrentLanguageResult | undefined
sv: CurrentLanguageResult | undefined
da?: CurrentLanguageResult
de?: CurrentLanguageResult
en?: CurrentLanguageResult
fi?: CurrentLanguageResult
no?: CurrentLanguageResult
sv?: CurrentLanguageResult
}
type LanguageResult = {

View File

@@ -1,4 +1,5 @@
export enum PageTypeEnum {
accountPage = "account-page",
loyaltyPage = "loyalty-page",
currentBlocksPage = "current-blocks-page",
}