Merged in feature/refactor-lang (pull request #387)
feat: SW-238 Avoid prop drilling of lang Approved-by: Michael Zetterberg
This commit is contained in:
@@ -5,13 +5,11 @@ import { overview } from "@/constants/routes/myPages"
|
|||||||
import { serverClient } from "@/lib/trpc/server"
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
|
|
||||||
import { auth } from "@/auth"
|
import { auth } from "@/auth"
|
||||||
|
import { getLang } from "@/i18n/serverContext"
|
||||||
import type { LangParams, LayoutArgs } from "@/types/params"
|
|
||||||
|
|
||||||
export default async function ProtectedLayout({
|
export default async function ProtectedLayout({
|
||||||
children,
|
children,
|
||||||
params,
|
}: React.PropsWithChildren) {
|
||||||
}: React.PropsWithChildren<LayoutArgs<LangParams>>) {
|
|
||||||
const session = await auth()
|
const session = await auth()
|
||||||
/**
|
/**
|
||||||
* Fallback to make sure every route nested in the
|
* Fallback to make sure every route nested in the
|
||||||
@@ -19,16 +17,16 @@ export default async function ProtectedLayout({
|
|||||||
*/
|
*/
|
||||||
const h = headers()
|
const h = headers()
|
||||||
const redirectTo = encodeURIComponent(
|
const redirectTo = encodeURIComponent(
|
||||||
h.get("x-url") ?? h.get("x-pathname") ?? overview[params.lang]
|
h.get("x-url") ?? h.get("x-pathname") ?? overview[getLang()]
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!session) {
|
if (!session) {
|
||||||
redirect(`/${params.lang}/login?redirectTo=${redirectTo}`)
|
redirect(`/${getLang()}/login?redirectTo=${redirectTo}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = await serverClient().user.get()
|
const user = await serverClient().user.get()
|
||||||
if (!user || "error" in user) {
|
if (!user || "error" in user) {
|
||||||
redirect(`/${params.lang}/login?redirectTo=${redirectTo}`)
|
redirect(`/${getLang()}/login?redirectTo=${redirectTo}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
return children
|
return children
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
import Breadcrumbs from "@/components/MyPages/Breadcrumbs"
|
import Breadcrumbs from "@/components/MyPages/Breadcrumbs"
|
||||||
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
|
import { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
|
export default function AllBreadcrumbs({ params }: PageArgs<LangParams>) {
|
||||||
|
setLang(params.lang)
|
||||||
|
|
||||||
export default function AllBreadcrumbs() {
|
|
||||||
return <Breadcrumbs />
|
return <Breadcrumbs />
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import Content from "@/components/MyPages/AccountPage/Content"
|
|||||||
import Title from "@/components/TempDesignSystem/Text/Title"
|
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||||
import TrackingSDK from "@/components/TrackingSDK"
|
import TrackingSDK from "@/components/TrackingSDK"
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import styles from "./page.module.css"
|
import styles from "./page.module.css"
|
||||||
|
|
||||||
@@ -12,6 +13,8 @@ import type { LangParams, PageArgs } from "@/types/params"
|
|||||||
export default async function MyPages({
|
export default async function MyPages({
|
||||||
params,
|
params,
|
||||||
}: PageArgs<LangParams & { path: string[] }>) {
|
}: PageArgs<LangParams & { path: string[] }>) {
|
||||||
|
setLang(params.lang)
|
||||||
|
|
||||||
const accountPageRes = await serverClient().contentstack.accountPage.get()
|
const accountPageRes = await serverClient().contentstack.accountPage.get()
|
||||||
const { formatMessage } = await getIntl()
|
const { formatMessage } = await getIntl()
|
||||||
|
|
||||||
@@ -26,7 +29,7 @@ export default async function MyPages({
|
|||||||
<main className={styles.blocks}>
|
<main className={styles.blocks}>
|
||||||
<Title>{accountPage.heading}</Title>
|
<Title>{accountPage.heading}</Title>
|
||||||
{accountPage.content.length ? (
|
{accountPage.content.length ? (
|
||||||
<Content lang={params.lang} content={accountPage.content} />
|
<Content content={accountPage.content} />
|
||||||
) : (
|
) : (
|
||||||
<p>{formatMessage({ id: "No content published" })}</p>
|
<p>{formatMessage({ id: "No content published" })}</p>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -2,20 +2,17 @@ import Sidebar from "@/components/MyPages/Sidebar"
|
|||||||
|
|
||||||
import styles from "./layout.module.css"
|
import styles from "./layout.module.css"
|
||||||
|
|
||||||
import { LangParams, LayoutArgs } from "@/types/params"
|
|
||||||
|
|
||||||
export default async function MyPagesLayout({
|
export default async function MyPagesLayout({
|
||||||
breadcrumbs,
|
breadcrumbs,
|
||||||
children,
|
children,
|
||||||
params,
|
}: React.PropsWithChildren & {
|
||||||
}: React.PropsWithChildren<LayoutArgs<LangParams>> & {
|
|
||||||
breadcrumbs: React.ReactNode
|
breadcrumbs: React.ReactNode
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<section className={styles.layout}>
|
<section className={styles.layout}>
|
||||||
{breadcrumbs}
|
{breadcrumbs}
|
||||||
<section className={styles.content}>
|
<section className={styles.content}>
|
||||||
<Sidebar lang={params.lang} />
|
<Sidebar />
|
||||||
{children}
|
{children}
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -3,10 +3,17 @@ import Link from "@/components/TempDesignSystem/Link"
|
|||||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||||
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import styles from "./page.module.css"
|
import styles from "./page.module.css"
|
||||||
|
|
||||||
export default async function CommunicationSlot() {
|
import { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
|
export default async function CommunicationSlot({
|
||||||
|
params,
|
||||||
|
}: PageArgs<LangParams>) {
|
||||||
|
setLang(params.lang)
|
||||||
|
|
||||||
const { formatMessage } = await getIntl()
|
const { formatMessage } = await getIntl()
|
||||||
return (
|
return (
|
||||||
<section className={styles.container}>
|
<section className={styles.container}>
|
||||||
|
|||||||
@@ -7,10 +7,14 @@ import Body from "@/components/TempDesignSystem/Text/Body"
|
|||||||
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
||||||
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import styles from "./page.module.css"
|
import styles from "./page.module.css"
|
||||||
|
|
||||||
export default async function CreditCardSlot() {
|
import { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
|
export default async function CreditCardSlot({ params }: PageArgs<LangParams>) {
|
||||||
|
setLang(params.lang)
|
||||||
const { formatMessage } = await getIntl()
|
const { formatMessage } = await getIntl()
|
||||||
const creditCards = await serverClient().user.creditCards()
|
const creditCards = await serverClient().user.creditCards()
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,16 @@ import Link from "@/components/TempDesignSystem/Link"
|
|||||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||||
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import styles from "./page.module.css"
|
import styles from "./page.module.css"
|
||||||
|
|
||||||
export default async function MembershipCardSlot() {
|
import { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
|
export default async function MembershipCardSlot({
|
||||||
|
params,
|
||||||
|
}: PageArgs<LangParams>) {
|
||||||
|
setLang(params.lang)
|
||||||
const { formatMessage } = await getIntl()
|
const { formatMessage } = await getIntl()
|
||||||
const membershipCards = await serverClient().user.membershipCards()
|
const membershipCards = await serverClient().user.membershipCards()
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,15 @@
|
|||||||
import { serverClient } from "@/lib/trpc/server"
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
|
|
||||||
import Form from "@/components/Forms/Edit/Profile"
|
import Form from "@/components/Forms/Edit/Profile"
|
||||||
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
|
import { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
|
export default async function EditProfileSlot({
|
||||||
|
params,
|
||||||
|
}: PageArgs<LangParams>) {
|
||||||
|
setLang(params.lang)
|
||||||
|
|
||||||
export default async function EditProfileSlot() {
|
|
||||||
const user = await serverClient().user.get({ mask: false })
|
const user = await serverClient().user.get({ mask: false })
|
||||||
if (!user || "error" in user) {
|
if (!user || "error" in user) {
|
||||||
return null
|
return null
|
||||||
|
|||||||
@@ -16,12 +16,14 @@ import Link from "@/components/TempDesignSystem/Link"
|
|||||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||||
import Title from "@/components/TempDesignSystem/Text/Title"
|
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
|
import { getLang, setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import styles from "./page.module.css"
|
import styles from "./page.module.css"
|
||||||
|
|
||||||
import type { LangParams, PageArgs } from "@/types/params"
|
import { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
export default async function Profile({ params }: PageArgs<LangParams>) {
|
export default async function Profile({ params }: PageArgs<LangParams>) {
|
||||||
|
setLang(params.lang)
|
||||||
const { formatMessage } = await getIntl()
|
const { formatMessage } = await getIntl()
|
||||||
const user = await serverClient().user.get()
|
const user = await serverClient().user.get()
|
||||||
if (!user || "error" in user) {
|
if (!user || "error" in user) {
|
||||||
@@ -40,7 +42,7 @@ export default async function Profile({ params }: PageArgs<LangParams>) {
|
|||||||
</Title>
|
</Title>
|
||||||
</hgroup>
|
</hgroup>
|
||||||
<Button asChild intent="primary" size="small" theme="base">
|
<Button asChild intent="primary" size="small" theme="base">
|
||||||
<Link color="none" href={profileEdit[params.lang]}>
|
<Link color="none" href={profileEdit[getLang()]}>
|
||||||
{formatMessage({ id: "Edit profile" })}
|
{formatMessage({ id: "Edit profile" })}
|
||||||
</Link>
|
</Link>
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -3,8 +3,12 @@ import "./profileLayout.css"
|
|||||||
import { serverClient } from "@/lib/trpc/server"
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
|
|
||||||
import TrackingSDK from "@/components/TrackingSDK"
|
import TrackingSDK from "@/components/TrackingSDK"
|
||||||
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
export default async function ProfilePage() {
|
import { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
|
export default async function ProfilePage({ params }: PageArgs<LangParams>) {
|
||||||
|
setLang(params.lang)
|
||||||
const accountPage = await serverClient().contentstack.accountPage.get()
|
const accountPage = await serverClient().contentstack.accountPage.get()
|
||||||
|
|
||||||
if (!accountPage) {
|
if (!accountPage) {
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
import Breadcrumbs from "@/components/MyPages/Breadcrumbs"
|
import Breadcrumbs from "@/components/MyPages/Breadcrumbs"
|
||||||
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
|
import { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
|
export default function PageBreadcrumbs({ params }: PageArgs<LangParams>) {
|
||||||
|
setLang(params.lang)
|
||||||
|
|
||||||
export default function PageBreadcrumbs() {
|
|
||||||
return <Breadcrumbs />
|
return <Breadcrumbs />
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { notFound } from "next/navigation"
|
|||||||
import ContentPage from "@/components/ContentType/ContentPage"
|
import ContentPage from "@/components/ContentType/ContentPage"
|
||||||
import HotelPage from "@/components/ContentType/HotelPage/HotelPage"
|
import HotelPage from "@/components/ContentType/HotelPage/HotelPage"
|
||||||
import LoyaltyPage from "@/components/ContentType/LoyaltyPage/LoyaltyPage"
|
import LoyaltyPage from "@/components/ContentType/LoyaltyPage/LoyaltyPage"
|
||||||
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ContentTypeParams,
|
ContentTypeParams,
|
||||||
@@ -14,13 +15,15 @@ import {
|
|||||||
export default async function ContentTypePage({
|
export default async function ContentTypePage({
|
||||||
params,
|
params,
|
||||||
}: PageArgs<LangParams & ContentTypeParams & UIDParams, {}>) {
|
}: PageArgs<LangParams & ContentTypeParams & UIDParams, {}>) {
|
||||||
|
setLang(params.lang)
|
||||||
|
|
||||||
switch (params.contentType) {
|
switch (params.contentType) {
|
||||||
case "content-page":
|
case "content-page":
|
||||||
return <ContentPage />
|
return <ContentPage />
|
||||||
case "loyalty-page":
|
case "loyalty-page":
|
||||||
return <LoyaltyPage lang={params.lang} />
|
return <LoyaltyPage />
|
||||||
case "hotel-page":
|
case "hotel-page":
|
||||||
return <HotelPage lang={params.lang} />
|
return <HotelPage />
|
||||||
default:
|
default:
|
||||||
const type: never = params.contentType
|
const type: never = params.contentType
|
||||||
console.error(`Unsupported content type given: ${type}`)
|
console.error(`Unsupported content type given: ${type}`)
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import { LangParams, PageArgs } from "@/types/params"
|
import { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
export default function HotelReservationPage({ params }: PageArgs<LangParams>) {
|
export default function HotelReservationPage({ params }: PageArgs<LangParams>) {
|
||||||
|
setLang(params.lang)
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { ChevronRightIcon } from "@/components/Icons"
|
|||||||
import StaticMap from "@/components/Maps/StaticMap"
|
import StaticMap from "@/components/Maps/StaticMap"
|
||||||
import Link from "@/components/TempDesignSystem/Link"
|
import Link from "@/components/TempDesignSystem/Link"
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
|
import { getLang, setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import styles from "./page.module.css"
|
import styles from "./page.module.css"
|
||||||
|
|
||||||
@@ -15,10 +16,11 @@ export default async function SelectHotelPage({
|
|||||||
params,
|
params,
|
||||||
}: PageArgs<LangParams>) {
|
}: PageArgs<LangParams>) {
|
||||||
const intl = await getIntl()
|
const intl = await getIntl()
|
||||||
|
setLang(params.lang)
|
||||||
|
|
||||||
const { attributes } = await serverClient().hotel.getHotel({
|
const { attributes } = await serverClient().hotel.getHotel({
|
||||||
hotelId: "d98c7ab1-ebaa-4102-b351-758daf1ddf55",
|
hotelId: "d98c7ab1-ebaa-4102-b351-758daf1ddf55",
|
||||||
language: params.lang,
|
language: getLang(),
|
||||||
})
|
})
|
||||||
const hotels = [attributes]
|
const hotels = [attributes]
|
||||||
|
|
||||||
|
|||||||
@@ -5,16 +5,19 @@ import BedSelection from "@/components/HotelReservation/SelectRate/BedSelection"
|
|||||||
import BreakfastSelection from "@/components/HotelReservation/SelectRate/BreakfastSelection"
|
import BreakfastSelection from "@/components/HotelReservation/SelectRate/BreakfastSelection"
|
||||||
import FlexibilitySelection from "@/components/HotelReservation/SelectRate/FlexibilitySelection"
|
import FlexibilitySelection from "@/components/HotelReservation/SelectRate/FlexibilitySelection"
|
||||||
import RoomSelection from "@/components/HotelReservation/SelectRate/RoomSelection"
|
import RoomSelection from "@/components/HotelReservation/SelectRate/RoomSelection"
|
||||||
|
import { getLang, setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import styles from "./page.module.css"
|
import styles from "./page.module.css"
|
||||||
|
|
||||||
import { LangParams, PageArgs } from "@/types/params"
|
import { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
export default async function SelectRate({ params }: PageArgs<LangParams>) {
|
export default async function SelectRate({ params }: PageArgs<LangParams>) {
|
||||||
|
setLang(params.lang)
|
||||||
|
|
||||||
// TODO: pass the correct hotel ID
|
// TODO: pass the correct hotel ID
|
||||||
const { attributes: hotel } = await serverClient().hotel.getHotel({
|
const { attributes: hotel } = await serverClient().hotel.getHotel({
|
||||||
hotelId: "d98c7ab1-ebaa-4102-b351-758daf1ddf55",
|
hotelId: "d98c7ab1-ebaa-4102-b351-758daf1ddf55",
|
||||||
language: params.lang,
|
language: getLang(),
|
||||||
})
|
})
|
||||||
const rooms = await serverClient().hotel.getRates({
|
const rooms = await serverClient().hotel.getRates({
|
||||||
// TODO: pass the correct hotel ID and all other parameters that should be included in the search
|
// TODO: pass the correct hotel ID and all other parameters that should be included in the search
|
||||||
|
|||||||
@@ -1,14 +1,9 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { useParams } from "next/navigation"
|
|
||||||
|
|
||||||
import { baseUrls } from "@/constants/routes/baseUrls"
|
import { baseUrls } from "@/constants/routes/baseUrls"
|
||||||
|
|
||||||
import LanguageSwitcher from "@/components/Current/Header/LanguageSwitcher"
|
import LanguageSwitcher from "@/components/Current/Header/LanguageSwitcher"
|
||||||
|
|
||||||
import { LangParams } from "@/types/params"
|
|
||||||
|
|
||||||
export default function Error() {
|
export default function Error() {
|
||||||
const params = useParams<LangParams>()
|
return <LanguageSwitcher urls={baseUrls} />
|
||||||
return <LanguageSwitcher urls={baseUrls} lang={params.lang} />
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
import { serverClient } from "@/lib/trpc/server"
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
|
|
||||||
import LanguageSwitcher from "@/components/Current/Header/LanguageSwitcher"
|
import LanguageSwitcher from "@/components/Current/Header/LanguageSwitcher"
|
||||||
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
|
import { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
|
export default async function LanguageSwitcherRoute({
|
||||||
|
params,
|
||||||
|
}: PageArgs<LangParams>) {
|
||||||
|
setLang(params.lang)
|
||||||
|
|
||||||
export default async function LanguageSwitcherRoute() {
|
|
||||||
const data = await serverClient().contentstack.languageSwitcher.get()
|
const data = await serverClient().contentstack.languageSwitcher.get()
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
return <LanguageSwitcher urls={data.urls} lang={data.lang} />
|
return <LanguageSwitcher urls={data.urls} />
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
import { serverClient } from "@/lib/trpc/server"
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
|
|
||||||
import MyPagesMobileDropdown from "@/components/Current/Header/MyPagesMobileDropdown"
|
import MyPagesMobileDropdown from "@/components/Current/Header/MyPagesMobileDropdown"
|
||||||
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import { LangParams, PageArgs } from "@/types/params"
|
import { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
export default async function MyPagesMobileDropdownPage({
|
export default async function MyPagesMobileDropdownPage({
|
||||||
params,
|
params,
|
||||||
}: PageArgs<LangParams>) {
|
}: PageArgs<LangParams>) {
|
||||||
|
setLang(params.lang)
|
||||||
const navigation = await serverClient().contentstack.myPages.navigation.get()
|
const navigation = await serverClient().contentstack.myPages.navigation.get()
|
||||||
if (!navigation) return null
|
if (!navigation) return null
|
||||||
return <MyPagesMobileDropdown navigation={navigation} lang={params.lang} />
|
return <MyPagesMobileDropdown navigation={navigation} />
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,13 @@
|
|||||||
import Header from "@/components/Current/Header"
|
import Header from "@/components/Current/Header"
|
||||||
|
|
||||||
import { LangParams, PageArgs } from "@/types/params"
|
|
||||||
|
|
||||||
export default function HeaderLayout({
|
export default function HeaderLayout({
|
||||||
params,
|
|
||||||
languageSwitcher,
|
languageSwitcher,
|
||||||
myPagesMobileDropdown,
|
myPagesMobileDropdown,
|
||||||
}: PageArgs<LangParams> & {
|
}: {
|
||||||
languageSwitcher: React.ReactNode
|
languageSwitcher: React.ReactNode
|
||||||
} & { myPagesMobileDropdown: React.ReactNode }) {
|
} & { myPagesMobileDropdown: React.ReactNode }) {
|
||||||
return (
|
return (
|
||||||
<Header
|
<Header
|
||||||
lang={params.lang}
|
|
||||||
myPagesMobileDropdown={myPagesMobileDropdown}
|
myPagesMobileDropdown={myPagesMobileDropdown}
|
||||||
languageSwitcher={languageSwitcher}
|
languageSwitcher={languageSwitcher}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -4,18 +4,18 @@ import { serverClient } from "@/lib/trpc/server"
|
|||||||
import Header from "@/components/Current/Header"
|
import Header from "@/components/Current/Header"
|
||||||
import LanguageSwitcher from "@/components/Current/Header/LanguageSwitcher"
|
import LanguageSwitcher from "@/components/Current/Header/LanguageSwitcher"
|
||||||
import MyPagesMobileDropdown from "@/components/Current/Header/MyPagesMobileDropdown"
|
import MyPagesMobileDropdown from "@/components/Current/Header/MyPagesMobileDropdown"
|
||||||
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import { LangParams, PageArgs } from "@/types/params"
|
import { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
export default async function HeaderPage({ params }: PageArgs<LangParams>) {
|
export default async function HeaderPage({ params }: PageArgs<LangParams>) {
|
||||||
|
setLang(params.lang)
|
||||||
|
|
||||||
const navigation = await serverClient().contentstack.myPages.navigation.get()
|
const navigation = await serverClient().contentstack.myPages.navigation.get()
|
||||||
return (
|
return (
|
||||||
<Header
|
<Header
|
||||||
lang={params.lang}
|
myPagesMobileDropdown={<MyPagesMobileDropdown navigation={navigation} />}
|
||||||
myPagesMobileDropdown={
|
languageSwitcher={<LanguageSwitcher urls={baseUrls} />}
|
||||||
<MyPagesMobileDropdown navigation={navigation} lang={params.lang} />
|
|
||||||
}
|
|
||||||
languageSwitcher={<LanguageSwitcher urls={baseUrls} lang={params.lang} />}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import VwoScript from "@/components/Current/VwoScript"
|
|||||||
import { preloadUserTracking } from "@/components/TrackingSDK"
|
import { preloadUserTracking } from "@/components/TrackingSDK"
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
import ServerIntlProvider from "@/i18n/Provider"
|
import ServerIntlProvider from "@/i18n/Provider"
|
||||||
|
import { getLang, setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import type { Metadata } from "next"
|
import type { Metadata } from "next"
|
||||||
|
|
||||||
@@ -30,11 +31,12 @@ export default async function RootLayout({
|
|||||||
header: React.ReactNode
|
header: React.ReactNode
|
||||||
}
|
}
|
||||||
>) {
|
>) {
|
||||||
|
setLang(params.lang)
|
||||||
preloadUserTracking()
|
preloadUserTracking()
|
||||||
|
|
||||||
const { defaultLocale, locale, messages } = await getIntl()
|
const { defaultLocale, locale, messages } = await getIntl()
|
||||||
return (
|
return (
|
||||||
<html lang={params.lang}>
|
<html lang={getLang()}>
|
||||||
<head>
|
<head>
|
||||||
<AdobeSDKScript />
|
<AdobeSDKScript />
|
||||||
<Script data-cookieconsent="ignore" src="/_static/js/cookie-bot.js" />
|
<Script data-cookieconsent="ignore" src="/_static/js/cookie-bot.js" />
|
||||||
@@ -53,10 +55,10 @@ export default async function RootLayout({
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<ServerIntlProvider intl={{ defaultLocale, locale, messages }}>
|
<ServerIntlProvider intl={{ defaultLocale, locale, messages }}>
|
||||||
<TrpcProvider lang={params.lang}>
|
<TrpcProvider>
|
||||||
{header}
|
{header}
|
||||||
{children}
|
{children}
|
||||||
<Footer lang={params.lang} />
|
<Footer />
|
||||||
</TrpcProvider>
|
</TrpcProvider>
|
||||||
</ServerIntlProvider>
|
</ServerIntlProvider>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import { Lang } from "@/constants/languages"
|
|
||||||
|
|
||||||
import NotFound from "@/components/Current/NotFound"
|
import NotFound from "@/components/Current/NotFound"
|
||||||
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import { LangParams, PageArgs } from "@/types/params"
|
import { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
export default function NotFoundPage({ params }: PageArgs<LangParams>) {
|
export default function NotFoundPage({ params }: PageArgs<LangParams>) {
|
||||||
const lang = params.lang || Lang.en
|
setLang(params.lang)
|
||||||
|
|
||||||
return <NotFound lang={lang} />
|
return <NotFound />
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { getLang, setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import styles from "./page.module.css"
|
import styles from "./page.module.css"
|
||||||
|
|
||||||
import { LangParams, LayoutArgs, StatusParams } from "@/types/params"
|
import { LangParams, LayoutArgs, StatusParams } from "@/types/params"
|
||||||
@@ -5,9 +7,11 @@ import { LangParams, LayoutArgs, StatusParams } from "@/types/params"
|
|||||||
export default function MiddlewareError({
|
export default function MiddlewareError({
|
||||||
params,
|
params,
|
||||||
}: LayoutArgs<LangParams & StatusParams>) {
|
}: LayoutArgs<LangParams & StatusParams>) {
|
||||||
|
setLang(params.lang)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.layout}>
|
<div className={styles.layout}>
|
||||||
Middleware Error {params.lang}: {params.status}
|
Middleware Error {getLang()}: {params.status}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
export default async function NotFound() {
|
import { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
|
export default async function NotFound({ params }: PageArgs<LangParams>) {
|
||||||
|
setLang(params.lang)
|
||||||
const { formatMessage } = await getIntl()
|
const { formatMessage } = await getIntl()
|
||||||
return (
|
return (
|
||||||
<main>
|
<main>
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
import { serverClient } from "@/lib/trpc/server"
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
|
|
||||||
import LanguageSwitcher from "@/components/Current/Header/LanguageSwitcher"
|
import LanguageSwitcher from "@/components/Current/Header/LanguageSwitcher"
|
||||||
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
|
import { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
|
export default async function LanguageSwitcherRoute({
|
||||||
|
params,
|
||||||
|
}: PageArgs<LangParams>) {
|
||||||
|
setLang(params.lang)
|
||||||
|
|
||||||
export default async function LanguageSwitcherRoute() {
|
|
||||||
const data = await serverClient().contentstack.languageSwitcher.get()
|
const data = await serverClient().contentstack.languageSwitcher.get()
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
return <LanguageSwitcher urls={data.urls} lang={data.lang} />
|
return <LanguageSwitcher urls={data.urls} />
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,9 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { useParams } from "next/navigation"
|
|
||||||
|
|
||||||
import { baseUrls } from "@/constants/routes/baseUrls"
|
import { baseUrls } from "@/constants/routes/baseUrls"
|
||||||
|
|
||||||
import LanguageSwitcher from "@/components/Current/Header/LanguageSwitcher"
|
import LanguageSwitcher from "@/components/Current/Header/LanguageSwitcher"
|
||||||
|
|
||||||
import { LangParams } from "@/types/params"
|
|
||||||
|
|
||||||
export default function Error() {
|
export default function Error() {
|
||||||
const params = useParams<LangParams>()
|
return <LanguageSwitcher urls={baseUrls} />
|
||||||
return <LanguageSwitcher urls={baseUrls} lang={params.lang} />
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
import { serverClient } from "@/lib/trpc/server"
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
|
|
||||||
import MyPagesMobileDropdown from "@/components/Current/Header/MyPagesMobileDropdown"
|
import MyPagesMobileDropdown from "@/components/Current/Header/MyPagesMobileDropdown"
|
||||||
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import { LangParams, PageArgs } from "@/types/params"
|
import { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
export default async function MyPagesMobileDropdownPage({
|
export default async function MyPagesMobileDropdownPage({
|
||||||
params,
|
params,
|
||||||
}: PageArgs<LangParams>) {
|
}: PageArgs<LangParams>) {
|
||||||
|
setLang(params.lang)
|
||||||
|
|
||||||
const navigation = await serverClient().contentstack.myPages.navigation.get()
|
const navigation = await serverClient().contentstack.myPages.navigation.get()
|
||||||
if (!navigation) {
|
if (!navigation) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
return <MyPagesMobileDropdown navigation={navigation} lang={params.lang} />
|
return <MyPagesMobileDropdown navigation={navigation} />
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,7 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { useParams } from "next/navigation"
|
|
||||||
|
|
||||||
import MyPagesMobileDropdown from "@/components/Current/Header/MyPagesMobileDropdown"
|
import MyPagesMobileDropdown from "@/components/Current/Header/MyPagesMobileDropdown"
|
||||||
|
|
||||||
import { LangParams } from "@/types/params"
|
|
||||||
|
|
||||||
export default function Error() {
|
export default function Error() {
|
||||||
const params = useParams<LangParams>()
|
return <MyPagesMobileDropdown navigation={null} />
|
||||||
return <MyPagesMobileDropdown navigation={null} lang={params.lang} />
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { request } from "@/lib/graphql/request"
|
|||||||
|
|
||||||
import ContentPage from "@/components/Current/ContentPage"
|
import ContentPage from "@/components/Current/ContentPage"
|
||||||
import Tracking from "@/components/Current/Tracking"
|
import Tracking from "@/components/Current/Tracking"
|
||||||
|
import { getLang, setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import type { LangParams, PageArgs, UriParams } from "@/types/params"
|
import type { LangParams, PageArgs, UriParams } from "@/types/params"
|
||||||
import type { GetCurrentBlockPageData } from "@/types/requests/currentBlockPage"
|
import type { GetCurrentBlockPageData } from "@/types/requests/currentBlockPage"
|
||||||
@@ -15,6 +16,8 @@ export default async function CurrentContentPage({
|
|||||||
params,
|
params,
|
||||||
searchParams,
|
searchParams,
|
||||||
}: PageArgs<LangParams, UriParams>) {
|
}: PageArgs<LangParams, UriParams>) {
|
||||||
|
setLang(params.lang)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!searchParams.uri) {
|
if (!searchParams.uri) {
|
||||||
throw new Error("Bad URI")
|
throw new Error("Bad URI")
|
||||||
@@ -23,10 +26,10 @@ export default async function CurrentContentPage({
|
|||||||
const response = await request<GetCurrentBlockPageData>(
|
const response = await request<GetCurrentBlockPageData>(
|
||||||
GetCurrentBlockPage,
|
GetCurrentBlockPage,
|
||||||
{
|
{
|
||||||
locale: params.lang,
|
locale: getLang(),
|
||||||
url: searchParams.uri,
|
url: searchParams.uri,
|
||||||
},
|
},
|
||||||
{ tags: [`${searchParams.uri}-${params.lang}`] }
|
{ tags: [`${searchParams.uri}-${getLang()}`] }
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!response.data?.all_current_blocks_page?.total) {
|
if (!response.data?.all_current_blocks_page?.total) {
|
||||||
@@ -46,7 +49,7 @@ export default async function CurrentContentPage({
|
|||||||
const pageData = response.data.all_current_blocks_page.items[0]
|
const pageData = response.data.all_current_blocks_page.items[0]
|
||||||
|
|
||||||
const trackingData = {
|
const trackingData = {
|
||||||
lang: params.lang,
|
lang: getLang(),
|
||||||
publishedDate: pageData.system.updated_at,
|
publishedDate: pageData.system.updated_at,
|
||||||
createdDate: pageData.system.created_at,
|
createdDate: pageData.system.created_at,
|
||||||
pageId: pageData.system.uid,
|
pageId: pageData.system.uid,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import LangPopup from "@/components/Current/LangPopup"
|
|||||||
import SkipToMainContent from "@/components/SkipToMainContent"
|
import SkipToMainContent from "@/components/SkipToMainContent"
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
import ServerIntlProvider from "@/i18n/Provider"
|
import ServerIntlProvider from "@/i18n/Provider"
|
||||||
|
import { getLang, setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import type { Metadata } from "next"
|
import type { Metadata } from "next"
|
||||||
|
|
||||||
@@ -31,9 +32,11 @@ export default async function RootLayout({
|
|||||||
myPagesMobileDropdown: React.ReactNode
|
myPagesMobileDropdown: React.ReactNode
|
||||||
}
|
}
|
||||||
>) {
|
>) {
|
||||||
|
setLang(params.lang)
|
||||||
const { defaultLocale, locale, messages } = await getIntl()
|
const { defaultLocale, locale, messages } = await getIntl()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang={params.lang}>
|
<html lang={getLang()}>
|
||||||
<head>
|
<head>
|
||||||
{/* eslint-disable-next-line @next/next/no-css-tags */}
|
{/* eslint-disable-next-line @next/next/no-css-tags */}
|
||||||
<link rel="stylesheet" href="/_static/css/core.css" />
|
<link rel="stylesheet" href="/_static/css/core.css" />
|
||||||
@@ -44,7 +47,7 @@ export default async function RootLayout({
|
|||||||
strategy="beforeInteractive"
|
strategy="beforeInteractive"
|
||||||
data-blockingmode="auto"
|
data-blockingmode="auto"
|
||||||
data-cbid="6d539de8-3e67-4f0f-a0df-8cef9070f712"
|
data-cbid="6d539de8-3e67-4f0f-a0df-8cef9070f712"
|
||||||
data-culture={params.lang}
|
data-culture={getLang()}
|
||||||
id="Cookiebot"
|
id="Cookiebot"
|
||||||
src="https://consent.cookiebot.com/uc.js"
|
src="https://consent.cookiebot.com/uc.js"
|
||||||
/>
|
/>
|
||||||
@@ -60,16 +63,15 @@ export default async function RootLayout({
|
|||||||
/>
|
/>
|
||||||
</head>
|
</head>
|
||||||
<body className="theme-00Corecolours theme-X0Oldcorecolours">
|
<body className="theme-00Corecolours theme-X0Oldcorecolours">
|
||||||
<LangPopup lang={params.lang} />
|
<LangPopup />
|
||||||
<SkipToMainContent />
|
<SkipToMainContent />
|
||||||
<ServerIntlProvider intl={{ defaultLocale, locale, messages }}>
|
<ServerIntlProvider intl={{ defaultLocale, locale, messages }}>
|
||||||
<Header
|
<Header
|
||||||
lang={params.lang}
|
|
||||||
myPagesMobileDropdown={myPagesMobileDropdown}
|
myPagesMobileDropdown={myPagesMobileDropdown}
|
||||||
languageSwitcher={languageSwitcher}
|
languageSwitcher={languageSwitcher}
|
||||||
/>
|
/>
|
||||||
{children}
|
{children}
|
||||||
<Footer lang={params.lang} />
|
<Footer />
|
||||||
</ServerIntlProvider>
|
</ServerIntlProvider>
|
||||||
<Script id="page-tracking">{`
|
<Script id="page-tracking">{`
|
||||||
typeof _satellite !== "undefined" && _satellite.pageBottom();
|
typeof _satellite !== "undefined" && _satellite.pageBottom();
|
||||||
|
|||||||
@@ -1,13 +1,5 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import { useParams } from "next/navigation"
|
|
||||||
|
|
||||||
import NotFound from "@/components/Current/NotFound"
|
import NotFound from "@/components/Current/NotFound"
|
||||||
|
|
||||||
import { LangParams } from "@/types/params"
|
|
||||||
|
|
||||||
export default function NotFoundPage() {
|
export default function NotFoundPage() {
|
||||||
const { lang } = useParams<LangParams>()
|
return <NotFound />
|
||||||
|
|
||||||
return <NotFound lang={lang} />
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import InitLivePreview from "@/components/Current/LivePreview"
|
import InitLivePreview from "@/components/Current/LivePreview"
|
||||||
|
import { getLang, setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import type { Metadata } from "next"
|
import type { Metadata } from "next"
|
||||||
|
|
||||||
@@ -13,8 +14,10 @@ export default function RootLayout({
|
|||||||
children,
|
children,
|
||||||
params,
|
params,
|
||||||
}: React.PropsWithChildren<LayoutArgs<LangParams>>) {
|
}: React.PropsWithChildren<LayoutArgs<LangParams>>) {
|
||||||
|
setLang(params.lang)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang={params.lang}>
|
<html lang={getLang()}>
|
||||||
<body>
|
<body>
|
||||||
<InitLivePreview />
|
<InitLivePreview />
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { getLang, setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ContentTypeParams,
|
ContentTypeParams,
|
||||||
LangParams,
|
LangParams,
|
||||||
@@ -9,11 +11,13 @@ export default async function PreviewPage({
|
|||||||
params,
|
params,
|
||||||
searchParams,
|
searchParams,
|
||||||
}: PageArgs<LangParams & ContentTypeParams & UIDParams, {}>) {
|
}: PageArgs<LangParams & ContentTypeParams & UIDParams, {}>) {
|
||||||
|
setLang(params.lang)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
Preview for {params.contentType}:{params.uid} in {params.lang} with
|
Preview for {params.contentType}:{params.uid} in {getLang()} with params{" "}
|
||||||
params <pre>{JSON.stringify(searchParams, null, 2)}</pre> goes here
|
<pre>{JSON.stringify(searchParams, null, 2)}</pre> goes here
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import Footer from "@/components/Current/Footer"
|
|||||||
import LangPopup from "@/components/Current/LangPopup"
|
import LangPopup from "@/components/Current/LangPopup"
|
||||||
import InitLivePreview from "@/components/Current/LivePreview"
|
import InitLivePreview from "@/components/Current/LivePreview"
|
||||||
import SkipToMainContent from "@/components/SkipToMainContent"
|
import SkipToMainContent from "@/components/SkipToMainContent"
|
||||||
|
import { getLang, setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import type { Metadata } from "next"
|
import type { Metadata } from "next"
|
||||||
|
|
||||||
@@ -20,8 +21,10 @@ export default function RootLayout({
|
|||||||
children,
|
children,
|
||||||
params,
|
params,
|
||||||
}: React.PropsWithChildren<LayoutArgs<LangParams>>) {
|
}: React.PropsWithChildren<LayoutArgs<LangParams>>) {
|
||||||
|
setLang(params.lang)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang={params.lang}>
|
<html lang={getLang()}>
|
||||||
<head>
|
<head>
|
||||||
{/* eslint-disable-next-line @next/next/no-css-tags */}
|
{/* eslint-disable-next-line @next/next/no-css-tags */}
|
||||||
<link rel="stylesheet" href="/_static/css/core.css" />
|
<link rel="stylesheet" href="/_static/css/core.css" />
|
||||||
@@ -30,10 +33,10 @@ export default function RootLayout({
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<InitLivePreview />
|
<InitLivePreview />
|
||||||
<LangPopup lang={params.lang} />
|
<LangPopup />
|
||||||
<SkipToMainContent />
|
<SkipToMainContent />
|
||||||
{children}
|
{children}
|
||||||
<Footer lang={params.lang} />
|
<Footer />
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,14 +5,18 @@ import { GetCurrentBlockPage } from "@/lib/graphql/Query/CurrentBlockPage.graphq
|
|||||||
|
|
||||||
import ContentPage from "@/components/Current/ContentPage"
|
import ContentPage from "@/components/Current/ContentPage"
|
||||||
import LoadingSpinner from "@/components/Current/LoadingSpinner"
|
import LoadingSpinner from "@/components/Current/LoadingSpinner"
|
||||||
|
import { getLang, setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import type { LangParams, PageArgs, PreviewParams } from "@/types/params"
|
import type { PageArgs, PreviewParams } from "@/types/params"
|
||||||
|
import { LangParams } from "@/types/params"
|
||||||
import type { GetCurrentBlockPageData } from "@/types/requests/currentBlockPage"
|
import type { GetCurrentBlockPageData } from "@/types/requests/currentBlockPage"
|
||||||
|
|
||||||
export default async function CurrentPreviewPage({
|
export default async function CurrentPreviewPage({
|
||||||
params,
|
params,
|
||||||
searchParams,
|
searchParams,
|
||||||
}: PageArgs<LangParams, PreviewParams>) {
|
}: PageArgs<LangParams, PreviewParams>) {
|
||||||
|
setLang(params.lang)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ContentstackLivePreview.setConfigFromParams(searchParams)
|
ContentstackLivePreview.setConfigFromParams(searchParams)
|
||||||
|
|
||||||
@@ -22,7 +26,7 @@ export default async function CurrentPreviewPage({
|
|||||||
|
|
||||||
const response = await previewRequest<GetCurrentBlockPageData>(
|
const response = await previewRequest<GetCurrentBlockPageData>(
|
||||||
GetCurrentBlockPage,
|
GetCurrentBlockPage,
|
||||||
{ locale: params.lang, url: searchParams.uri }
|
{ locale: getLang(), url: searchParams.uri }
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!response.data?.all_current_blocks_page?.total) {
|
if (!response.data?.all_current_blocks_page?.total) {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { serverClient } from "@/lib/trpc/server"
|
|||||||
|
|
||||||
import AccountPage from "@/components/ContentType/Webviews/AccountPage"
|
import AccountPage from "@/components/ContentType/Webviews/AccountPage"
|
||||||
import LoyaltyPage from "@/components/ContentType/Webviews/LoyaltyPage"
|
import LoyaltyPage from "@/components/ContentType/Webviews/LoyaltyPage"
|
||||||
|
import { getLang, setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ContentTypeWebviewParams,
|
ContentTypeWebviewParams,
|
||||||
@@ -15,6 +16,7 @@ import {
|
|||||||
export default async function ContentTypePage({
|
export default async function ContentTypePage({
|
||||||
params,
|
params,
|
||||||
}: PageArgs<LangParams & ContentTypeWebviewParams & UIDParams, {}>) {
|
}: PageArgs<LangParams & ContentTypeWebviewParams & UIDParams, {}>) {
|
||||||
|
setLang(params.lang)
|
||||||
const user = await serverClient().user.get()
|
const user = await serverClient().user.get()
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
@@ -26,15 +28,15 @@ export default async function ContentTypePage({
|
|||||||
case "unauthorized": // fall through
|
case "unauthorized": // fall through
|
||||||
case "forbidden": // fall through
|
case "forbidden": // fall through
|
||||||
case "token_expired":
|
case "token_expired":
|
||||||
redirect(`/${params.lang}/webview/refresh`)
|
redirect(`/${getLang()}/webview/refresh`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (params.contentType) {
|
switch (params.contentType) {
|
||||||
case "loyalty-page":
|
case "loyalty-page":
|
||||||
return <LoyaltyPage lang={params.lang} />
|
return <LoyaltyPage />
|
||||||
case "account-page":
|
case "account-page":
|
||||||
return <AccountPage lang={params.lang} />
|
return <AccountPage />
|
||||||
default:
|
default:
|
||||||
const type: never = params.contentType
|
const type: never = params.contentType
|
||||||
console.error(`Unsupported content type given: ${type}`)
|
console.error(`Unsupported content type given: ${type}`)
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import TrpcProvider from "@/lib/trpc/Provider"
|
|||||||
import AdobeSDKScript from "@/components/Current/AdobeSDKScript"
|
import AdobeSDKScript from "@/components/Current/AdobeSDKScript"
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
import ServerIntlProvider from "@/i18n/Provider"
|
import ServerIntlProvider from "@/i18n/Provider"
|
||||||
|
import { getLang, setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import styles from "./layout.module.css"
|
import styles from "./layout.module.css"
|
||||||
|
|
||||||
@@ -23,9 +24,11 @@ export default async function RootLayout({
|
|||||||
children,
|
children,
|
||||||
params,
|
params,
|
||||||
}: React.PropsWithChildren<LayoutArgs<LangParams>>) {
|
}: React.PropsWithChildren<LayoutArgs<LangParams>>) {
|
||||||
|
setLang(params.lang)
|
||||||
const { defaultLocale, locale, messages } = await getIntl()
|
const { defaultLocale, locale, messages } = await getIntl()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang={params.lang}>
|
<html lang={getLang()}>
|
||||||
<head>
|
<head>
|
||||||
<AdobeSDKScript />
|
<AdobeSDKScript />
|
||||||
<Script id="ensure-adobeDataLayer">{`
|
<Script id="ensure-adobeDataLayer">{`
|
||||||
@@ -34,7 +37,7 @@ export default async function RootLayout({
|
|||||||
</head>
|
</head>
|
||||||
<body className={styles.layout}>
|
<body className={styles.layout}>
|
||||||
<ServerIntlProvider intl={{ defaultLocale, locale, messages }}>
|
<ServerIntlProvider intl={{ defaultLocale, locale, messages }}>
|
||||||
<TrpcProvider lang={params.lang}>{children}</TrpcProvider>
|
<TrpcProvider>{children}</TrpcProvider>
|
||||||
</ServerIntlProvider>
|
</ServerIntlProvider>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
import LoadingSpinner from "@/components/LoadingSpinner"
|
import LoadingSpinner from "@/components/LoadingSpinner"
|
||||||
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import styles from "./page.module.css"
|
import styles from "./page.module.css"
|
||||||
|
|
||||||
export default function Refresh() {
|
import { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
|
export default function Refresh({ params }: PageArgs<LangParams>) {
|
||||||
|
setLang(params.lang)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<LoadingSpinner />
|
<LoadingSpinner />
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import { serverClient } from "@/lib/trpc/server"
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
|
|
||||||
|
import { getLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import AmenitiesList from "./AmenitiesList"
|
import AmenitiesList from "./AmenitiesList"
|
||||||
import IntroSection from "./IntroSection"
|
import IntroSection from "./IntroSection"
|
||||||
import { Rooms } from "./Rooms"
|
import { Rooms } from "./Rooms"
|
||||||
@@ -7,9 +9,7 @@ import TabNavigation from "./TabNavigation"
|
|||||||
|
|
||||||
import styles from "./hotelPage.module.css"
|
import styles from "./hotelPage.module.css"
|
||||||
|
|
||||||
import type { LangParams } from "@/types/params"
|
export default async function HotelPage() {
|
||||||
|
|
||||||
export default async function HotelPage({ lang }: LangParams) {
|
|
||||||
const hotelPageIdentifierData =
|
const hotelPageIdentifierData =
|
||||||
await serverClient().contentstack.hotelPage.get()
|
await serverClient().contentstack.hotelPage.get()
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ export default async function HotelPage({ lang }: LangParams) {
|
|||||||
|
|
||||||
const { attributes, roomCategories } = await serverClient().hotel.getHotel({
|
const { attributes, roomCategories } = await serverClient().hotel.getHotel({
|
||||||
hotelId: hotelPageIdentifierData.hotel_page_id,
|
hotelId: hotelPageIdentifierData.hotel_page_id,
|
||||||
language: lang,
|
language: getLang(),
|
||||||
include: ["RoomCategories"],
|
include: ["RoomCategories"],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,7 @@ import TrackingSDK from "@/components/TrackingSDK"
|
|||||||
|
|
||||||
import styles from "./loyaltyPage.module.css"
|
import styles from "./loyaltyPage.module.css"
|
||||||
|
|
||||||
import type { LangParams } from "@/types/params"
|
export default async function LoyaltyPage() {
|
||||||
|
|
||||||
export default async function LoyaltyPage({ lang }: LangParams) {
|
|
||||||
const loyaltyPageRes = await serverClient().contentstack.loyaltyPage.get()
|
const loyaltyPageRes = await serverClient().contentstack.loyaltyPage.get()
|
||||||
|
|
||||||
if (!loyaltyPageRes) {
|
if (!loyaltyPageRes) {
|
||||||
@@ -23,14 +21,12 @@ export default async function LoyaltyPage({ lang }: LangParams) {
|
|||||||
<>
|
<>
|
||||||
<section className={styles.content}>
|
<section className={styles.content}>
|
||||||
{loyaltyPage.sidebar.length ? (
|
{loyaltyPage.sidebar.length ? (
|
||||||
<Sidebar blocks={loyaltyPage.sidebar} lang={lang} />
|
<Sidebar blocks={loyaltyPage.sidebar} />
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<MaxWidth className={styles.blocks} tag="main">
|
<MaxWidth className={styles.blocks} tag="main">
|
||||||
<Title>{loyaltyPage.heading}</Title>
|
<Title>{loyaltyPage.heading}</Title>
|
||||||
{loyaltyPage.blocks ? (
|
{loyaltyPage.blocks ? <Blocks blocks={loyaltyPage.blocks} /> : null}
|
||||||
<Blocks blocks={loyaltyPage.blocks} lang={lang} />
|
|
||||||
) : null}
|
|
||||||
</MaxWidth>
|
</MaxWidth>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
@@ -8,12 +8,11 @@ import MaxWidth from "@/components/MaxWidth"
|
|||||||
import Content from "@/components/MyPages/AccountPage/Webview/Content"
|
import Content from "@/components/MyPages/AccountPage/Webview/Content"
|
||||||
import TrackingSDK from "@/components/TrackingSDK"
|
import TrackingSDK from "@/components/TrackingSDK"
|
||||||
import LinkToOverview from "@/components/Webviews/LinkToOverview"
|
import LinkToOverview from "@/components/Webviews/LinkToOverview"
|
||||||
|
import { getLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import styles from "./accountPage.module.css"
|
import styles from "./accountPage.module.css"
|
||||||
|
|
||||||
import { LangParams } from "@/types/params"
|
export default async function MyPages() {
|
||||||
|
|
||||||
export default async function MyPages({ lang }: LangParams) {
|
|
||||||
const accountPageRes = await serverClient().contentstack.accountPage.get()
|
const accountPageRes = await serverClient().contentstack.accountPage.get()
|
||||||
|
|
||||||
if (!accountPageRes) {
|
if (!accountPageRes) {
|
||||||
@@ -22,13 +21,14 @@ export default async function MyPages({ lang }: LangParams) {
|
|||||||
|
|
||||||
const { tracking, accountPage } = accountPageRes
|
const { tracking, accountPage } = accountPageRes
|
||||||
|
|
||||||
const linkToOverview = `/${lang}/webview${accountPage.url}` !== overview[lang]
|
const linkToOverview =
|
||||||
|
`/${getLang()}/webview${accountPage.url}` !== overview[getLang()]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<MaxWidth className={styles.blocks} tag="main">
|
<MaxWidth className={styles.blocks} tag="main">
|
||||||
{linkToOverview ? <LinkToOverview lang={lang} /> : null}
|
{linkToOverview ? <LinkToOverview /> : null}
|
||||||
<Content lang={lang} content={accountPage.content} />
|
<Content content={accountPage.content} />
|
||||||
</MaxWidth>
|
</MaxWidth>
|
||||||
|
|
||||||
<TrackingSDK pageData={tracking} />
|
<TrackingSDK pageData={tracking} />
|
||||||
|
|||||||
@@ -8,9 +8,7 @@ import LinkToOverview from "@/components/Webviews/LinkToOverview"
|
|||||||
|
|
||||||
import styles from "./loyaltyPage.module.css"
|
import styles from "./loyaltyPage.module.css"
|
||||||
|
|
||||||
import { LangParams } from "@/types/params"
|
export default async function AboutScandicFriends() {
|
||||||
|
|
||||||
export default async function AboutScandicFriends({ lang }: LangParams) {
|
|
||||||
const loyaltyPageRes = await serverClient().contentstack.loyaltyPage.get()
|
const loyaltyPageRes = await serverClient().contentstack.loyaltyPage.get()
|
||||||
|
|
||||||
if (!loyaltyPageRes) {
|
if (!loyaltyPageRes) {
|
||||||
@@ -21,10 +19,10 @@ export default async function AboutScandicFriends({ lang }: LangParams) {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<section className={styles.content}>
|
<section className={styles.content}>
|
||||||
<LinkToOverview lang={lang} />
|
<LinkToOverview />
|
||||||
<MaxWidth tag="main" className={styles.blocks}>
|
<MaxWidth tag="main" className={styles.blocks}>
|
||||||
<Title>{loyaltyPage.heading}</Title>
|
<Title>{loyaltyPage.heading}</Title>
|
||||||
<Blocks blocks={loyaltyPage.blocks} lang={lang} />
|
<Blocks blocks={loyaltyPage.blocks} />
|
||||||
</MaxWidth>
|
</MaxWidth>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
import { serverClient } from "@/lib/trpc/server"
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
|
|
||||||
import Image from "@/components/Image"
|
import Image from "@/components/Image"
|
||||||
|
import { getLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import Navigation from "./Navigation"
|
import Navigation from "./Navigation"
|
||||||
|
|
||||||
import styles from "./footer.module.css"
|
import styles from "./footer.module.css"
|
||||||
|
|
||||||
import { LangParams } from "@/types/params"
|
export default async function Footer() {
|
||||||
|
const footerData = await serverClient().contentstack.base.footer({
|
||||||
export default async function Footer({ lang }: LangParams) {
|
lang: getLang(),
|
||||||
const footerData = await serverClient().contentstack.base.footer({ lang })
|
})
|
||||||
if (!footerData) {
|
if (!footerData) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,15 +4,14 @@ import { useCallback, useEffect, useRef, useState } from "react"
|
|||||||
import { Lang, languages } from "@/constants/languages"
|
import { Lang, languages } from "@/constants/languages"
|
||||||
|
|
||||||
import Link from "@/components/TempDesignSystem/Link"
|
import Link from "@/components/TempDesignSystem/Link"
|
||||||
|
import useLang from "@/hooks/useLang"
|
||||||
|
|
||||||
import styles from "./desktop.module.css"
|
import styles from "./desktop.module.css"
|
||||||
|
|
||||||
import type { LanguageSwitcherProps } from "@/types/components/current/languageSwitcher"
|
import type { LanguageSwitcherProps } from "@/types/components/current/languageSwitcher"
|
||||||
|
|
||||||
export default function Desktop({
|
export default function Desktop({ urls }: LanguageSwitcherProps) {
|
||||||
currentLanguage,
|
const currentLanguage = useLang()
|
||||||
urls,
|
|
||||||
}: LanguageSwitcherProps) {
|
|
||||||
const [isOpen, setIsOpen] = useState(false)
|
const [isOpen, setIsOpen] = useState(false)
|
||||||
const divRef = useRef<HTMLDivElement>(null)
|
const divRef = useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ import { useState } from "react"
|
|||||||
|
|
||||||
import { Lang, languages } from "@/constants/languages"
|
import { Lang, languages } from "@/constants/languages"
|
||||||
|
|
||||||
|
import useLang from "@/hooks/useLang"
|
||||||
|
|
||||||
import styles from "./mobile.module.css"
|
import styles from "./mobile.module.css"
|
||||||
|
|
||||||
import type { LanguageSwitcherProps } from "@/types/components/current/languageSwitcher"
|
import type { LanguageSwitcherProps } from "@/types/components/current/languageSwitcher"
|
||||||
|
|
||||||
export default function Mobile({
|
export default function Mobile({ urls }: LanguageSwitcherProps) {
|
||||||
currentLanguage,
|
const currentLanguage = useLang()
|
||||||
urls,
|
|
||||||
}: LanguageSwitcherProps) {
|
|
||||||
const [isOpen, setIsOpen] = useState(false)
|
const [isOpen, setIsOpen] = useState(false)
|
||||||
|
|
||||||
function toggleOpen() {
|
function toggleOpen() {
|
||||||
|
|||||||
@@ -1,19 +1,15 @@
|
|||||||
import Desktop from "./Desktop"
|
import Desktop from "./Desktop"
|
||||||
import Mobile from "./Mobile"
|
import Mobile from "./Mobile"
|
||||||
|
|
||||||
import { LangParams } from "@/types/params"
|
|
||||||
import { LanguageSwitcherData } from "@/types/requests/languageSwitcher"
|
import { LanguageSwitcherData } from "@/types/requests/languageSwitcher"
|
||||||
|
|
||||||
type LanguageSwitcherProps = LangParams & { urls: LanguageSwitcherData }
|
type LanguageSwitcherProps = { urls: LanguageSwitcherData }
|
||||||
|
|
||||||
export default function LanguageSwitcher({
|
export default function LanguageSwitcher({ urls }: LanguageSwitcherProps) {
|
||||||
urls,
|
|
||||||
lang,
|
|
||||||
}: LanguageSwitcherProps) {
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Desktop currentLanguage={lang} urls={urls} />
|
<Desktop urls={urls} />
|
||||||
<Mobile currentLanguage={lang} urls={urls} />
|
<Mobile urls={urls} />
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,26 +7,24 @@ import { login } from "@/constants/routes/handleAuth"
|
|||||||
|
|
||||||
import Link from "@/components/TempDesignSystem/Link"
|
import Link from "@/components/TempDesignSystem/Link"
|
||||||
import { LinkProps } from "@/components/TempDesignSystem/Link/link"
|
import { LinkProps } from "@/components/TempDesignSystem/Link/link"
|
||||||
|
import useLang from "@/hooks/useLang"
|
||||||
import { trackLoginClick } from "@/utils/tracking"
|
import { trackLoginClick } from "@/utils/tracking"
|
||||||
|
|
||||||
import { TrackingPosition } from "@/types/components/tracking"
|
import { TrackingPosition } from "@/types/components/tracking"
|
||||||
import { LangParams } from "@/types/params"
|
|
||||||
|
|
||||||
export default function LoginButton({
|
export default function LoginButton({
|
||||||
className,
|
className,
|
||||||
position,
|
position,
|
||||||
trackingId,
|
trackingId,
|
||||||
lang,
|
|
||||||
children,
|
children,
|
||||||
color = "black",
|
color = "black",
|
||||||
}: PropsWithChildren<
|
}: PropsWithChildren<{
|
||||||
LangParams & {
|
className: string
|
||||||
className: string
|
trackingId: string
|
||||||
trackingId: string
|
position: TrackingPosition
|
||||||
position: TrackingPosition
|
color?: LinkProps["color"]
|
||||||
color?: LinkProps["color"]
|
}>) {
|
||||||
}
|
const lang = useLang()
|
||||||
>) {
|
|
||||||
const pathName = usePathname()
|
const pathName = usePathname()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import useDropdownStore from "@/stores/main-menu"
|
|||||||
import Image from "@/components/Image"
|
import Image from "@/components/Image"
|
||||||
import Avatar from "@/components/MyPages/Avatar"
|
import Avatar from "@/components/MyPages/Avatar"
|
||||||
import Link from "@/components/TempDesignSystem/Link"
|
import Link from "@/components/TempDesignSystem/Link"
|
||||||
|
import useLang from "@/hooks/useLang"
|
||||||
import { trackClick } from "@/utils/tracking"
|
import { trackClick } from "@/utils/tracking"
|
||||||
|
|
||||||
import BookingButton from "../BookingButton"
|
import BookingButton from "../BookingButton"
|
||||||
@@ -27,9 +28,9 @@ export function MainMenu({
|
|||||||
myPagesMobileDropdown,
|
myPagesMobileDropdown,
|
||||||
bookingHref,
|
bookingHref,
|
||||||
user,
|
user,
|
||||||
lang,
|
|
||||||
}: MainMenuProps) {
|
}: MainMenuProps) {
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
|
const lang = useLang()
|
||||||
|
|
||||||
const {
|
const {
|
||||||
isHamburgerMenuOpen,
|
isHamburgerMenuOpen,
|
||||||
@@ -111,7 +112,6 @@ export function MainMenu({
|
|||||||
position="hamburger menu"
|
position="hamburger menu"
|
||||||
trackingId="loginStartHamburgerMenu"
|
trackingId="loginStartHamburgerMenu"
|
||||||
className={styles.mobileLinkButton}
|
className={styles.mobileLinkButton}
|
||||||
lang={lang}
|
|
||||||
>
|
>
|
||||||
{intl.formatMessage({ id: "Log in" })}
|
{intl.formatMessage({ id: "Log in" })}
|
||||||
</LoginButton>
|
</LoginButton>
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
import { Fragment } from "react"
|
import { Fragment } from "react"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { Lang } from "@/constants/languages"
|
|
||||||
import { logout } from "@/constants/routes/handleAuth"
|
import { logout } from "@/constants/routes/handleAuth"
|
||||||
import { navigationQueryRouter } from "@/server/routers/contentstack/myPages/navigation/query"
|
import { navigationQueryRouter } from "@/server/routers/contentstack/myPages/navigation/query"
|
||||||
import useDropdownStore from "@/stores/main-menu"
|
import useDropdownStore from "@/stores/main-menu"
|
||||||
@@ -10,6 +9,7 @@ import useDropdownStore from "@/stores/main-menu"
|
|||||||
import Divider from "@/components/TempDesignSystem/Divider"
|
import Divider from "@/components/TempDesignSystem/Divider"
|
||||||
import Link from "@/components/TempDesignSystem/Link"
|
import Link from "@/components/TempDesignSystem/Link"
|
||||||
import Title from "@/components/TempDesignSystem/Text/Title"
|
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||||
|
import useLang from "@/hooks/useLang"
|
||||||
|
|
||||||
import styles from "./my-pages-mobile-dropdown.module.css"
|
import styles from "./my-pages-mobile-dropdown.module.css"
|
||||||
|
|
||||||
@@ -17,12 +17,11 @@ type Navigation = Awaited<ReturnType<(typeof navigationQueryRouter)["get"]>>
|
|||||||
|
|
||||||
export default function MyPagesMobileDropdown({
|
export default function MyPagesMobileDropdown({
|
||||||
navigation,
|
navigation,
|
||||||
lang,
|
|
||||||
}: {
|
}: {
|
||||||
navigation: Navigation
|
navigation: Navigation
|
||||||
lang: Lang | null
|
|
||||||
}) {
|
}) {
|
||||||
const { formatMessage } = useIntl()
|
const { formatMessage } = useIntl()
|
||||||
|
const lang = useLang()
|
||||||
const { toggleMyPagesMobileMenu, isMyPagesMobileMenuOpen } =
|
const { toggleMyPagesMobileMenu, isMyPagesMobileMenuOpen } =
|
||||||
useDropdownStore()
|
useDropdownStore()
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { serverClient } from "@/lib/trpc/server"
|
|||||||
|
|
||||||
import Link from "@/components/TempDesignSystem/Link"
|
import Link from "@/components/TempDesignSystem/Link"
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
|
import { getLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import LoginButton from "../LoginButton"
|
import LoginButton from "../LoginButton"
|
||||||
|
|
||||||
@@ -19,7 +20,6 @@ export default async function TopMenu({
|
|||||||
homeHref,
|
homeHref,
|
||||||
links,
|
links,
|
||||||
languageSwitcher,
|
languageSwitcher,
|
||||||
lang,
|
|
||||||
}: TopMenuProps) {
|
}: TopMenuProps) {
|
||||||
const { formatMessage } = await getIntl()
|
const { formatMessage } = await getIntl()
|
||||||
const user = await serverClient().user.name()
|
const user = await serverClient().user.name()
|
||||||
@@ -47,7 +47,7 @@ export default async function TopMenu({
|
|||||||
<>
|
<>
|
||||||
{user ? (
|
{user ? (
|
||||||
<Link
|
<Link
|
||||||
href={logout[lang]}
|
href={logout[getLang()]}
|
||||||
className={styles.sessionLink}
|
className={styles.sessionLink}
|
||||||
prefetch={false}
|
prefetch={false}
|
||||||
>
|
>
|
||||||
@@ -56,7 +56,7 @@ export default async function TopMenu({
|
|||||||
) : null}
|
) : null}
|
||||||
<div className={styles.loginSeparator} />
|
<div className={styles.loginSeparator} />
|
||||||
<Link
|
<Link
|
||||||
href={logout[lang]}
|
href={logout[getLang()]}
|
||||||
className={styles.sessionLink}
|
className={styles.sessionLink}
|
||||||
prefetch={false}
|
prefetch={false}
|
||||||
>
|
>
|
||||||
@@ -68,7 +68,6 @@ export default async function TopMenu({
|
|||||||
position="hamburger menu"
|
position="hamburger menu"
|
||||||
trackingId="loginStartTopMeny"
|
trackingId="loginStartTopMeny"
|
||||||
className={`${styles.sessionLink} ${styles.loginLink}`}
|
className={`${styles.sessionLink} ${styles.loginLink}`}
|
||||||
lang={lang}
|
|
||||||
>
|
>
|
||||||
{formatMessage({ id: "Log in" })}
|
{formatMessage({ id: "Log in" })}
|
||||||
</LoginButton>
|
</LoginButton>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { serverClient } from "@/lib/trpc/server"
|
|||||||
|
|
||||||
import { auth } from "@/auth"
|
import { auth } from "@/auth"
|
||||||
import { BookingWidget } from "@/components/BookingWidget"
|
import { BookingWidget } from "@/components/BookingWidget"
|
||||||
|
import { getLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import { MainMenu } from "./MainMenu"
|
import { MainMenu } from "./MainMenu"
|
||||||
import OfflineBanner from "./OfflineBanner"
|
import OfflineBanner from "./OfflineBanner"
|
||||||
@@ -11,17 +12,15 @@ import TopMenu from "./TopMenu"
|
|||||||
|
|
||||||
import styles from "./header.module.css"
|
import styles from "./header.module.css"
|
||||||
|
|
||||||
import { LangParams } from "@/types/params"
|
|
||||||
|
|
||||||
export default async function Header({
|
export default async function Header({
|
||||||
lang,
|
|
||||||
languageSwitcher,
|
languageSwitcher,
|
||||||
myPagesMobileDropdown,
|
myPagesMobileDropdown,
|
||||||
}: LangParams & { languageSwitcher: React.ReactNode } & {
|
}: {
|
||||||
|
languageSwitcher: React.ReactNode
|
||||||
myPagesMobileDropdown: React.ReactNode
|
myPagesMobileDropdown: React.ReactNode
|
||||||
}) {
|
}) {
|
||||||
const data = await serverClient().contentstack.base.header({
|
const data = await serverClient().contentstack.base.header({
|
||||||
lang,
|
lang: getLang(),
|
||||||
})
|
})
|
||||||
|
|
||||||
const user = await serverClient().user.name()
|
const user = await serverClient().user.name()
|
||||||
@@ -35,7 +34,7 @@ export default async function Header({
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const homeHref = homeHrefs[env.NODE_ENV][lang]
|
const homeHref = homeHrefs[env.NODE_ENV][getLang()]
|
||||||
const { frontpage_link_text, logo, menu, top_menu } = data
|
const { frontpage_link_text, logo, menu, top_menu } = data
|
||||||
|
|
||||||
const topMenuMobileLinks = top_menu.links
|
const topMenuMobileLinks = top_menu.links
|
||||||
@@ -50,7 +49,6 @@ export default async function Header({
|
|||||||
homeHref={homeHref}
|
homeHref={homeHref}
|
||||||
links={top_menu.links}
|
links={top_menu.links}
|
||||||
languageSwitcher={languageSwitcher}
|
languageSwitcher={languageSwitcher}
|
||||||
lang={lang}
|
|
||||||
/>
|
/>
|
||||||
<MainMenu
|
<MainMenu
|
||||||
frontpageLinkText={frontpage_link_text}
|
frontpageLinkText={frontpage_link_text}
|
||||||
@@ -62,7 +60,6 @@ export default async function Header({
|
|||||||
myPagesMobileDropdown={myPagesMobileDropdown}
|
myPagesMobileDropdown={myPagesMobileDropdown}
|
||||||
bookingHref={homeHref}
|
bookingHref={homeHref}
|
||||||
user={user}
|
user={user}
|
||||||
lang={lang}
|
|
||||||
/>
|
/>
|
||||||
{hideBookingWidget ? null : <BookingWidget />}
|
{hideBookingWidget ? null : <BookingWidget />}
|
||||||
</header>
|
</header>
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ import { headers } from "next/headers"
|
|||||||
|
|
||||||
import { Lang, localeToLang } from "@/constants/languages"
|
import { Lang, localeToLang } from "@/constants/languages"
|
||||||
|
|
||||||
export default function LangPopup({ lang }: { lang: Lang }) {
|
import { getLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
|
export default function LangPopup() {
|
||||||
const headersList = headers()
|
const headersList = headers()
|
||||||
const preferedLang = headersList.get("Accept-Language") ?? ""
|
const preferedLang = headersList.get("Accept-Language") ?? ""
|
||||||
|
|
||||||
@@ -14,7 +16,7 @@ export default function LangPopup({ lang }: { lang: Lang }) {
|
|||||||
|
|
||||||
const langOfChoice: Lang = localeToLang[preferedLang as Lang]
|
const langOfChoice: Lang = localeToLang[preferedLang as Lang]
|
||||||
|
|
||||||
if (langOfChoice === lang) {
|
if (langOfChoice === getLang()) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
|
import { getLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import { texts } from "./Texts"
|
import { texts } from "./Texts"
|
||||||
|
|
||||||
import styles from "./notFound.module.css"
|
import styles from "./notFound.module.css"
|
||||||
|
|
||||||
import { LangParams } from "@/types/params"
|
export default function NotFound() {
|
||||||
|
const infoTexts = texts[getLang()]
|
||||||
export default function NotFound({ lang }: LangParams) {
|
|
||||||
const infoTexts = texts[lang]
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<div className={styles.content}>
|
<div className={styles.content}>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { membershipLevels } from "@/constants/membershipLevels"
|
|||||||
|
|
||||||
import Image from "@/components/Image"
|
import Image from "@/components/Image"
|
||||||
import Select from "@/components/TempDesignSystem/Select"
|
import Select from "@/components/TempDesignSystem/Select"
|
||||||
|
import useLang from "@/hooks/useLang"
|
||||||
import { getMembership } from "@/utils/user"
|
import { getMembership } from "@/utils/user"
|
||||||
|
|
||||||
import DA from "./data/DA.json"
|
import DA from "./data/DA.json"
|
||||||
@@ -33,7 +34,6 @@ import {
|
|||||||
OverviewTableProps,
|
OverviewTableProps,
|
||||||
OverviewTableReducerAction,
|
OverviewTableReducerAction,
|
||||||
} from "@/types/components/loyalty/blocks"
|
} from "@/types/components/loyalty/blocks"
|
||||||
import { LangParams } from "@/types/params"
|
|
||||||
import type { User } from "@/types/user"
|
import type { User } from "@/types/user"
|
||||||
|
|
||||||
const levelsTranslations = {
|
const levelsTranslations = {
|
||||||
@@ -127,9 +127,9 @@ function reducer(state: any, action: OverviewTableReducerAction) {
|
|||||||
|
|
||||||
export default function OverviewTable({
|
export default function OverviewTable({
|
||||||
activeMembership,
|
activeMembership,
|
||||||
lang,
|
}: OverviewTableProps) {
|
||||||
}: OverviewTableProps & LangParams) {
|
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
|
const lang = useLang()
|
||||||
const levelsData = levelsTranslations[lang]
|
const levelsData = levelsTranslations[lang]
|
||||||
const [selectionState, dispatch] = useReducer(
|
const [selectionState, dispatch] = useReducer(
|
||||||
reducer,
|
reducer,
|
||||||
|
|||||||
@@ -17,12 +17,8 @@ import type {
|
|||||||
DynamicContentProps,
|
DynamicContentProps,
|
||||||
} from "@/types/components/loyalty/blocks"
|
} from "@/types/components/loyalty/blocks"
|
||||||
import { LoyaltyComponentEnum } from "@/types/components/loyalty/enums"
|
import { LoyaltyComponentEnum } from "@/types/components/loyalty/enums"
|
||||||
import { LangParams } from "@/types/params"
|
|
||||||
|
|
||||||
async function DynamicComponentBlock({
|
async function DynamicComponentBlock({ component }: DynamicComponentProps) {
|
||||||
component,
|
|
||||||
lang,
|
|
||||||
}: DynamicComponentProps & LangParams) {
|
|
||||||
const membershipLevel = await serverClient().user.membershipLevel()
|
const membershipLevel = await serverClient().user.membershipLevel()
|
||||||
switch (component) {
|
switch (component) {
|
||||||
case LoyaltyComponentEnum.how_it_works:
|
case LoyaltyComponentEnum.how_it_works:
|
||||||
@@ -30,7 +26,7 @@ async function DynamicComponentBlock({
|
|||||||
case LoyaltyComponentEnum.loyalty_levels:
|
case LoyaltyComponentEnum.loyalty_levels:
|
||||||
return <LoyaltyLevels />
|
return <LoyaltyLevels />
|
||||||
case LoyaltyComponentEnum.overview_table:
|
case LoyaltyComponentEnum.overview_table:
|
||||||
return <OverviewTable activeMembership={membershipLevel} lang={lang} />
|
return <OverviewTable activeMembership={membershipLevel} />
|
||||||
default:
|
default:
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -39,8 +35,7 @@ async function DynamicComponentBlock({
|
|||||||
export default function DynamicContent({
|
export default function DynamicContent({
|
||||||
dynamicContent,
|
dynamicContent,
|
||||||
firstItem,
|
firstItem,
|
||||||
lang,
|
}: DynamicContentProps) {
|
||||||
}: DynamicContentProps & LangParams) {
|
|
||||||
const displayHeader = !!(
|
const displayHeader = !!(
|
||||||
dynamicContent.link ||
|
dynamicContent.link ||
|
||||||
dynamicContent.subtitle ||
|
dynamicContent.subtitle ||
|
||||||
@@ -63,7 +58,7 @@ export default function DynamicContent({
|
|||||||
topTitle={firstItem}
|
topTitle={firstItem}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
<DynamicComponentBlock component={dynamicContent.component} lang={lang} />
|
<DynamicComponentBlock component={dynamicContent.component} />
|
||||||
{displayHeader && (
|
{displayHeader && (
|
||||||
<SectionLink link={dynamicContent.link} variant="mobile" />
|
<SectionLink link={dynamicContent.link} variant="mobile" />
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import JsonToHtml from "@/components/JsonToHtml"
|
import JsonToHtml from "@/components/JsonToHtml"
|
||||||
import DynamicContentBlock from "@/components/Loyalty/Blocks/DynamicContent"
|
import DynamicContentBlock from "@/components/Loyalty/Blocks/DynamicContent"
|
||||||
import Shortcuts from "@/components/MyPages/Blocks/Shortcuts"
|
import Shortcuts from "@/components/MyPages/Blocks/Shortcuts"
|
||||||
|
import { getLang } from "@/i18n/serverContext"
|
||||||
import { modWebviewLink } from "@/utils/webviews"
|
import { modWebviewLink } from "@/utils/webviews"
|
||||||
|
|
||||||
import CardsGrid from "../CardsGrid"
|
import CardsGrid from "../CardsGrid"
|
||||||
|
|
||||||
import type { BlocksProps } from "@/types/components/loyalty/blocks"
|
import type { BlocksProps } from "@/types/components/loyalty/blocks"
|
||||||
import { LoyaltyBlocksTypenameEnum } from "@/types/components/loyalty/enums"
|
import { LoyaltyBlocksTypenameEnum } from "@/types/components/loyalty/enums"
|
||||||
import { LangParams } from "@/types/params"
|
|
||||||
|
|
||||||
export function Blocks({ lang, blocks }: BlocksProps & LangParams) {
|
export function Blocks({ blocks }: BlocksProps) {
|
||||||
return blocks.map((block, idx) => {
|
return blocks.map((block, idx) => {
|
||||||
const firstItem = idx === 0
|
const firstItem = idx === 0
|
||||||
switch (block.__typename) {
|
switch (block.__typename) {
|
||||||
@@ -35,7 +35,10 @@ export function Blocks({ lang, blocks }: BlocksProps & LangParams) {
|
|||||||
link: block.dynamic_content.link
|
link: block.dynamic_content.link
|
||||||
? {
|
? {
|
||||||
...block.dynamic_content.link,
|
...block.dynamic_content.link,
|
||||||
href: modWebviewLink(block.dynamic_content.link.href, lang),
|
href: modWebviewLink(
|
||||||
|
block.dynamic_content.link.href,
|
||||||
|
getLang()
|
||||||
|
),
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
}
|
}
|
||||||
@@ -45,13 +48,12 @@ export function Blocks({ lang, blocks }: BlocksProps & LangParams) {
|
|||||||
dynamicContent={dynamicContent}
|
dynamicContent={dynamicContent}
|
||||||
firstItem={firstItem}
|
firstItem={firstItem}
|
||||||
key={`${block.dynamic_content.title}-${idx}`}
|
key={`${block.dynamic_content.title}-${idx}`}
|
||||||
lang={lang}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksShortcuts:
|
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksShortcuts:
|
||||||
const shortcuts = block.shortcuts.shortcuts.map((shortcut) => ({
|
const shortcuts = block.shortcuts.shortcuts.map((shortcut) => ({
|
||||||
...shortcut,
|
...shortcut,
|
||||||
url: modWebviewLink(shortcut.url, lang),
|
url: modWebviewLink(shortcut.url, getLang()),
|
||||||
}))
|
}))
|
||||||
return (
|
return (
|
||||||
<Shortcuts
|
<Shortcuts
|
||||||
|
|||||||
@@ -6,9 +6,8 @@ import CardsGrid from "./CardsGrid"
|
|||||||
|
|
||||||
import type { BlocksProps } from "@/types/components/loyalty/blocks"
|
import type { BlocksProps } from "@/types/components/loyalty/blocks"
|
||||||
import { LoyaltyBlocksTypenameEnum } from "@/types/components/loyalty/enums"
|
import { LoyaltyBlocksTypenameEnum } from "@/types/components/loyalty/enums"
|
||||||
import { LangParams } from "@/types/params"
|
|
||||||
|
|
||||||
export function Blocks({ blocks, lang }: BlocksProps & LangParams) {
|
export function Blocks({ blocks }: BlocksProps) {
|
||||||
return blocks.map((block, idx) => {
|
return blocks.map((block, idx) => {
|
||||||
const firstItem = idx === 0
|
const firstItem = idx === 0
|
||||||
switch (block.__typename) {
|
switch (block.__typename) {
|
||||||
@@ -27,7 +26,6 @@ export function Blocks({ blocks, lang }: BlocksProps & LangParams) {
|
|||||||
dynamicContent={block.dynamic_content}
|
dynamicContent={block.dynamic_content}
|
||||||
firstItem={firstItem}
|
firstItem={firstItem}
|
||||||
key={`${block.dynamic_content.title}-${idx}`}
|
key={`${block.dynamic_content.title}-${idx}`}
|
||||||
lang={lang}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksShortcuts:
|
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksShortcuts:
|
||||||
|
|||||||
@@ -14,12 +14,10 @@ import Contact from "./Contact"
|
|||||||
import styles from "./joinLoyalty.module.css"
|
import styles from "./joinLoyalty.module.css"
|
||||||
|
|
||||||
import type { JoinLoyaltyContactProps } from "@/types/components/loyalty/sidebar"
|
import type { JoinLoyaltyContactProps } from "@/types/components/loyalty/sidebar"
|
||||||
import { LangParams } from "@/types/params"
|
|
||||||
|
|
||||||
export default async function JoinLoyaltyContact({
|
export default async function JoinLoyaltyContact({
|
||||||
block,
|
block,
|
||||||
lang,
|
}: JoinLoyaltyContactProps) {
|
||||||
}: JoinLoyaltyContactProps & LangParams) {
|
|
||||||
const { formatMessage } = await getIntl()
|
const { formatMessage } = await getIntl()
|
||||||
const user = await serverClient().user.name()
|
const user = await serverClient().user.name()
|
||||||
|
|
||||||
@@ -55,7 +53,6 @@ export default async function JoinLoyaltyContact({
|
|||||||
<Body>{formatMessage({ id: "Already a friend?" })}</Body>
|
<Body>{formatMessage({ id: "Already a friend?" })}</Body>
|
||||||
<LoginButton
|
<LoginButton
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
lang={lang}
|
|
||||||
trackingId="loginJoinLoyalty"
|
trackingId="loginJoinLoyalty"
|
||||||
position="join scandic friends sidebar"
|
position="join scandic friends sidebar"
|
||||||
color="burgundy"
|
color="burgundy"
|
||||||
|
|||||||
@@ -10,12 +10,8 @@ import {
|
|||||||
SidebarTypenameEnum,
|
SidebarTypenameEnum,
|
||||||
} from "@/types/components/loyalty/enums"
|
} from "@/types/components/loyalty/enums"
|
||||||
import { SidebarProps } from "@/types/components/loyalty/sidebar"
|
import { SidebarProps } from "@/types/components/loyalty/sidebar"
|
||||||
import { LangParams } from "@/types/params"
|
|
||||||
|
|
||||||
export default function SidebarLoyalty({
|
export default function SidebarLoyalty({ blocks }: SidebarProps) {
|
||||||
blocks,
|
|
||||||
lang,
|
|
||||||
}: SidebarProps & LangParams) {
|
|
||||||
return (
|
return (
|
||||||
<aside className={styles.aside}>
|
<aside className={styles.aside}>
|
||||||
{blocks.map((block, idx) => {
|
{blocks.map((block, idx) => {
|
||||||
@@ -37,18 +33,12 @@ export default function SidebarLoyalty({
|
|||||||
<JoinLoyaltyContact
|
<JoinLoyaltyContact
|
||||||
block={block.join_loyalty_contact}
|
block={block.join_loyalty_contact}
|
||||||
key={`${block.__typename}-${idx}`}
|
key={`${block.__typename}-${idx}`}
|
||||||
lang={lang}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
case SidebarTypenameEnum.LoyaltyPageSidebarDynamicContent:
|
case SidebarTypenameEnum.LoyaltyPageSidebarDynamicContent:
|
||||||
switch (block.dynamic_content.component) {
|
switch (block.dynamic_content.component) {
|
||||||
case LoyaltySidebarDynamicComponentEnum.my_pages_navigation:
|
case LoyaltySidebarDynamicComponentEnum.my_pages_navigation:
|
||||||
return (
|
return <SidebarMyPages key={`${block.__typename}-${idx}`} />
|
||||||
<SidebarMyPages
|
|
||||||
key={`${block.__typename}-${idx}`}
|
|
||||||
lang={lang}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
default:
|
default:
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import Shortcuts from "@/components/MyPages/Blocks/Shortcuts"
|
|||||||
import PreviousStays from "@/components/MyPages/Blocks/Stays/Previous"
|
import PreviousStays from "@/components/MyPages/Blocks/Stays/Previous"
|
||||||
import SoonestStays from "@/components/MyPages/Blocks/Stays/Soonest"
|
import SoonestStays from "@/components/MyPages/Blocks/Stays/Soonest"
|
||||||
import UpcomingStays from "@/components/MyPages/Blocks/Stays/Upcoming"
|
import UpcomingStays from "@/components/MyPages/Blocks/Stays/Upcoming"
|
||||||
|
import { getLang } from "@/i18n/serverContext"
|
||||||
import { removeMultipleSlashes } from "@/utils/url"
|
import { removeMultipleSlashes } from "@/utils/url"
|
||||||
|
|
||||||
import PointsOverview from "../Blocks/Points/Overview"
|
import PointsOverview from "../Blocks/Points/Overview"
|
||||||
@@ -47,7 +48,7 @@ function DynamicComponent({ component, props }: AccountPageContentProps) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Content({ lang, content }: ContentProps) {
|
export default function Content({ content }: ContentProps) {
|
||||||
return content.map((item, idx) => {
|
return content.map((item, idx) => {
|
||||||
switch (item.__typename) {
|
switch (item.__typename) {
|
||||||
case ContentEntries.AccountPageContentDynamicContent:
|
case ContentEntries.AccountPageContentDynamicContent:
|
||||||
@@ -57,14 +58,13 @@ export default function Content({ lang, content }: ContentProps) {
|
|||||||
item.dynamic_content.link.linkConnection.edges[0].node
|
item.dynamic_content.link.linkConnection.edges[0].node
|
||||||
.original_url ||
|
.original_url ||
|
||||||
removeMultipleSlashes(
|
removeMultipleSlashes(
|
||||||
`/${lang}/${item.dynamic_content.link.linkConnection.edges[0].node.url}`
|
`/${getLang()}/${item.dynamic_content.link.linkConnection.edges[0].node.url}`
|
||||||
),
|
),
|
||||||
text: item.dynamic_content.link.link_text,
|
text: item.dynamic_content.link.link_text,
|
||||||
}
|
}
|
||||||
: null
|
: null
|
||||||
|
|
||||||
const componentProps = {
|
const componentProps = {
|
||||||
lang,
|
|
||||||
title: item.dynamic_content.title,
|
title: item.dynamic_content.title,
|
||||||
// TODO: rename preamble to subtitle in Contentstack?
|
// TODO: rename preamble to subtitle in Contentstack?
|
||||||
subtitle: item.dynamic_content.preamble,
|
subtitle: item.dynamic_content.preamble,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import JsonToHtml from "@/components/JsonToHtml"
|
import JsonToHtml from "@/components/JsonToHtml"
|
||||||
import Overview from "@/components/MyPages/Blocks/Overview"
|
import Overview from "@/components/MyPages/Blocks/Overview"
|
||||||
import Shortcuts from "@/components/MyPages/Blocks/Shortcuts"
|
import Shortcuts from "@/components/MyPages/Blocks/Shortcuts"
|
||||||
|
import { getLang } from "@/i18n/serverContext"
|
||||||
import { removeMultipleSlashes } from "@/utils/url"
|
import { removeMultipleSlashes } from "@/utils/url"
|
||||||
import { modWebviewLink } from "@/utils/webviews"
|
import { modWebviewLink } from "@/utils/webviews"
|
||||||
|
|
||||||
@@ -39,7 +40,7 @@ function DynamicComponent({ component, props }: AccountPageContentProps) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Content({ lang, content }: ContentProps) {
|
export default function Content({ content }: ContentProps) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{content.map((item, idx) => {
|
{content.map((item, idx) => {
|
||||||
@@ -62,7 +63,6 @@ export default function Content({ lang, content }: ContentProps) {
|
|||||||
: null
|
: null
|
||||||
|
|
||||||
const componentProps = {
|
const componentProps = {
|
||||||
lang,
|
|
||||||
title: item.dynamic_content.title,
|
title: item.dynamic_content.title,
|
||||||
// TODO: rename preamble to subtitle in Contentstack?
|
// TODO: rename preamble to subtitle in Contentstack?
|
||||||
subtitle: item.dynamic_content.preamble,
|
subtitle: item.dynamic_content.preamble,
|
||||||
@@ -79,7 +79,7 @@ export default function Content({ lang, content }: ContentProps) {
|
|||||||
const shortcuts = item.shortcuts.shortcuts.map((shortcut) => {
|
const shortcuts = item.shortcuts.shortcuts.map((shortcut) => {
|
||||||
return {
|
return {
|
||||||
...shortcut,
|
...shortcut,
|
||||||
url: modWebviewLink(shortcut.url, lang),
|
url: modWebviewLink(shortcut.url, getLang()),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -6,20 +6,19 @@ import SectionHeader from "@/components/Section/Header"
|
|||||||
import SectionLink from "@/components/Section/Link"
|
import SectionLink from "@/components/Section/Link"
|
||||||
import Grids from "@/components/TempDesignSystem/Grids"
|
import Grids from "@/components/TempDesignSystem/Grids"
|
||||||
import Title from "@/components/TempDesignSystem/Text/Title"
|
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||||
|
import { getLang } from "@/i18n/serverContext"
|
||||||
import { getMembershipLevelObject } from "@/utils/membershipLevel"
|
import { getMembershipLevelObject } from "@/utils/membershipLevel"
|
||||||
import { getMembership } from "@/utils/user"
|
import { getMembership } from "@/utils/user"
|
||||||
|
|
||||||
import styles from "./current.module.css"
|
import styles from "./current.module.css"
|
||||||
|
|
||||||
import type { AccountPageComponentProps } from "@/types/components/myPages/myPage/accountPage"
|
import type { AccountPageComponentProps } from "@/types/components/myPages/myPage/accountPage"
|
||||||
import type { LangParams } from "@/types/params"
|
|
||||||
|
|
||||||
export default async function CurrentBenefitsBlock({
|
export default async function CurrentBenefitsBlock({
|
||||||
title,
|
title,
|
||||||
subtitle,
|
subtitle,
|
||||||
link,
|
link,
|
||||||
lang,
|
}: AccountPageComponentProps) {
|
||||||
}: AccountPageComponentProps & LangParams) {
|
|
||||||
const user = await serverClient().user.get()
|
const user = await serverClient().user.get()
|
||||||
// TAKE NOTE: we need clarification on how benefits stack from different levels
|
// TAKE NOTE: we need clarification on how benefits stack from different levels
|
||||||
// in order to determine if a benefit is specific to a level or if it is a cumulative benefit
|
// in order to determine if a benefit is specific to a level or if it is a cumulative benefit
|
||||||
@@ -35,7 +34,7 @@ export default async function CurrentBenefitsBlock({
|
|||||||
|
|
||||||
const currentLevel = getMembershipLevelObject(
|
const currentLevel = getMembershipLevelObject(
|
||||||
user.memberships[0].membershipLevel as MembershipLevelEnum,
|
user.memberships[0].membershipLevel as MembershipLevelEnum,
|
||||||
lang
|
getLang()
|
||||||
)
|
)
|
||||||
if (!currentLevel) {
|
if (!currentLevel) {
|
||||||
// TODO: handle this case?
|
// TODO: handle this case?
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import Grids from "@/components/TempDesignSystem/Grids"
|
|||||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||||
import Title from "@/components/TempDesignSystem/Text/Title"
|
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
|
import { getLang } from "@/i18n/serverContext"
|
||||||
import { getMembershipLevelObject } from "@/utils/membershipLevel"
|
import { getMembershipLevelObject } from "@/utils/membershipLevel"
|
||||||
|
|
||||||
import styles from "./next.module.css"
|
import styles from "./next.module.css"
|
||||||
@@ -20,7 +21,6 @@ import { AccountPageComponentProps } from "@/types/components/myPages/myPage/acc
|
|||||||
export default async function NextLevelBenefitsBlock({
|
export default async function NextLevelBenefitsBlock({
|
||||||
title,
|
title,
|
||||||
subtitle,
|
subtitle,
|
||||||
lang,
|
|
||||||
link,
|
link,
|
||||||
}: AccountPageComponentProps) {
|
}: AccountPageComponentProps) {
|
||||||
const { formatMessage } = await getIntl()
|
const { formatMessage } = await getIntl()
|
||||||
@@ -30,7 +30,7 @@ export default async function NextLevelBenefitsBlock({
|
|||||||
}
|
}
|
||||||
const nextLevel = getMembershipLevelObject(
|
const nextLevel = getMembershipLevelObject(
|
||||||
user.memberships[0].nextLevel as MembershipLevelEnum,
|
user.memberships[0].nextLevel as MembershipLevelEnum,
|
||||||
lang
|
getLang()
|
||||||
)
|
)
|
||||||
if (!nextLevel) {
|
if (!nextLevel) {
|
||||||
// TODO: handle this case, when missing or when user is top level?
|
// TODO: handle this case, when missing or when user is top level?
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { MembershipLevelEnum } from "@/constants/membershipLevels"
|
import { MembershipLevelEnum } from "@/constants/membershipLevels"
|
||||||
|
|
||||||
|
import { getLang } from "@/i18n/serverContext"
|
||||||
import { getMembershipLevelObject } from "@/utils/membershipLevel"
|
import { getMembershipLevelObject } from "@/utils/membershipLevel"
|
||||||
import { getMembership } from "@/utils/user"
|
import { getMembership } from "@/utils/user"
|
||||||
|
|
||||||
@@ -7,13 +8,12 @@ import PointsContainer from "./Container"
|
|||||||
import { NextLevelPointsColumn, YourPointsColumn } from "./PointsColumn"
|
import { NextLevelPointsColumn, YourPointsColumn } from "./PointsColumn"
|
||||||
|
|
||||||
import { UserProps } from "@/types/components/myPages/user"
|
import { UserProps } from "@/types/components/myPages/user"
|
||||||
import { LangParams } from "@/types/params"
|
|
||||||
|
|
||||||
export default async function Points({ user, lang }: UserProps & LangParams) {
|
export default async function Points({ user }: UserProps) {
|
||||||
const membership = getMembership(user.memberships)
|
const membership = getMembership(user.memberships)
|
||||||
const nextLevel = getMembershipLevelObject(
|
const nextLevel = getMembershipLevelObject(
|
||||||
membership?.nextLevel as MembershipLevelEnum,
|
membership?.nextLevel as MembershipLevelEnum,
|
||||||
lang
|
getLang()
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -6,12 +6,11 @@ import Points from "./Points"
|
|||||||
import styles from "./stats.module.css"
|
import styles from "./stats.module.css"
|
||||||
|
|
||||||
import type { UserProps } from "@/types/components/myPages/user"
|
import type { UserProps } from "@/types/components/myPages/user"
|
||||||
import type { LangParams } from "@/types/params"
|
|
||||||
|
|
||||||
export default function Stats({ user, lang }: UserProps & LangParams) {
|
export default function Stats({ user }: UserProps) {
|
||||||
return (
|
return (
|
||||||
<section className={styles.stats}>
|
<section className={styles.stats}>
|
||||||
<Points user={user} lang={lang} />
|
<Points user={user} />
|
||||||
<Divider variant="default" color="pale" />
|
<Divider variant="default" color="pale" />
|
||||||
<ExpiringPoints user={user} />
|
<ExpiringPoints user={user} />
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import SectionContainer from "@/components/Section/Container"
|
|||||||
import SectionHeader from "@/components/Section/Header"
|
import SectionHeader from "@/components/Section/Header"
|
||||||
import SectionLink from "@/components/Section/Link"
|
import SectionLink from "@/components/Section/Link"
|
||||||
import Divider from "@/components/TempDesignSystem/Divider"
|
import Divider from "@/components/TempDesignSystem/Divider"
|
||||||
|
import { getLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import Hero from "./Friend/Hero"
|
import Hero from "./Friend/Hero"
|
||||||
import Friend from "./Friend"
|
import Friend from "./Friend"
|
||||||
@@ -12,14 +13,12 @@ import Stats from "./Stats"
|
|||||||
import styles from "./overview.module.css"
|
import styles from "./overview.module.css"
|
||||||
|
|
||||||
import type { AccountPageComponentProps } from "@/types/components/myPages/myPage/accountPage"
|
import type { AccountPageComponentProps } from "@/types/components/myPages/myPage/accountPage"
|
||||||
import type { LangParams } from "@/types/params"
|
|
||||||
|
|
||||||
export default async function Overview({
|
export default async function Overview({
|
||||||
link,
|
link,
|
||||||
subtitle,
|
subtitle,
|
||||||
title,
|
title,
|
||||||
lang,
|
}: AccountPageComponentProps) {
|
||||||
}: AccountPageComponentProps & LangParams) {
|
|
||||||
const user = await serverClient().user.get()
|
const user = await serverClient().user.get()
|
||||||
if (!user || "error" in user) {
|
if (!user || "error" in user) {
|
||||||
return null
|
return null
|
||||||
@@ -31,7 +30,7 @@ export default async function Overview({
|
|||||||
<Hero color="red">
|
<Hero color="red">
|
||||||
<Friend user={user} color="burgundy" />
|
<Friend user={user} color="burgundy" />
|
||||||
<Divider className={styles.divider} color="peach" />
|
<Divider className={styles.divider} color="peach" />
|
||||||
<Stats user={user} lang={lang} />
|
<Stats user={user} />
|
||||||
</Hero>
|
</Hero>
|
||||||
<SectionLink link={link} variant="mobile" />
|
<SectionLink link={link} variant="mobile" />
|
||||||
</SectionContainer>
|
</SectionContainer>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { dt } from "@/lib/dt"
|
import { dt } from "@/lib/dt"
|
||||||
|
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
|
import { getLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import AwardPoints from "./AwardPoints"
|
import AwardPoints from "./AwardPoints"
|
||||||
|
|
||||||
@@ -8,15 +9,17 @@ import styles from "./row.module.css"
|
|||||||
|
|
||||||
import type { RowProps } from "@/types/components/myPages/myPage/earnAndBurn"
|
import type { RowProps } from "@/types/components/myPages/myPage/earnAndBurn"
|
||||||
|
|
||||||
export default async function Row({ transaction, lang }: RowProps) {
|
export default async function Row({ transaction }: RowProps) {
|
||||||
const { formatMessage } = await getIntl()
|
const { formatMessage } = await getIntl()
|
||||||
const description =
|
const description =
|
||||||
transaction.hotelName && transaction.city
|
transaction.hotelName && transaction.city
|
||||||
? `${transaction.hotelName}, ${transaction.city} ${transaction.nights} ${formatMessage({ id: "nights" })}`
|
? `${transaction.hotelName}, ${transaction.city} ${transaction.nights} ${formatMessage({ id: "nights" })}`
|
||||||
: `${transaction.nights} ${formatMessage({ id: "nights" })}`
|
: `${transaction.nights} ${formatMessage({ id: "nights" })}`
|
||||||
const arrival = dt(transaction.checkinDate).locale(lang).format("DD MMM YYYY")
|
const arrival = dt(transaction.checkinDate)
|
||||||
|
.locale(getLang())
|
||||||
|
.format("DD MMM YYYY")
|
||||||
const departure = dt(transaction.checkoutDate)
|
const departure = dt(transaction.checkoutDate)
|
||||||
.locale(lang)
|
.locale(getLang())
|
||||||
.format("DD MMM YYYY")
|
.format("DD MMM YYYY")
|
||||||
return (
|
return (
|
||||||
<tr className={styles.tr}>
|
<tr className={styles.tr}>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const tableHeadings = [
|
|||||||
"Points",
|
"Points",
|
||||||
]
|
]
|
||||||
|
|
||||||
export default async function DesktopTable({ lang, transactions }: TableProps) {
|
export default async function DesktopTable({ transactions }: TableProps) {
|
||||||
const { formatMessage } = await getIntl()
|
const { formatMessage } = await getIntl()
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
@@ -35,7 +35,6 @@ export default async function DesktopTable({ lang, transactions }: TableProps) {
|
|||||||
<tbody>
|
<tbody>
|
||||||
{transactions.map((transaction) => (
|
{transactions.map((transaction) => (
|
||||||
<Row
|
<Row
|
||||||
lang={lang}
|
|
||||||
key={transaction.confirmationNumber}
|
key={transaction.confirmationNumber}
|
||||||
transaction={transaction}
|
transaction={transaction}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -3,12 +3,13 @@ import { dt } from "@/lib/dt"
|
|||||||
import AwardPoints from "@/components/MyPages/Blocks/Points/EarnAndBurn/Desktop/Row/AwardPoints"
|
import AwardPoints from "@/components/MyPages/Blocks/Points/EarnAndBurn/Desktop/Row/AwardPoints"
|
||||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
|
import { getLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import styles from "./mobile.module.css"
|
import styles from "./mobile.module.css"
|
||||||
|
|
||||||
import type { TableProps } from "@/types/components/myPages/myPage/earnAndBurn"
|
import type { TableProps } from "@/types/components/myPages/myPage/earnAndBurn"
|
||||||
|
|
||||||
export default async function MobileTable({ lang, transactions }: TableProps) {
|
export default async function MobileTable({ transactions }: TableProps) {
|
||||||
const { formatMessage } = await getIntl()
|
const { formatMessage } = await getIntl()
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
@@ -32,7 +33,7 @@ export default async function MobileTable({ lang, transactions }: TableProps) {
|
|||||||
<td className={`${styles.td} ${styles.transactionDetails}`}>
|
<td className={`${styles.td} ${styles.transactionDetails}`}>
|
||||||
<span className={styles.transactionDate}>
|
<span className={styles.transactionDate}>
|
||||||
{dt(transaction.checkinDate)
|
{dt(transaction.checkinDate)
|
||||||
.locale(lang)
|
.locale(getLang())
|
||||||
.format("DD MMM YYYY")}
|
.format("DD MMM YYYY")}
|
||||||
</span>
|
</span>
|
||||||
{transaction.hotelName && transaction.city ? (
|
{transaction.hotelName && transaction.city ? (
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import MobileTable from "./Mobile"
|
|||||||
import type { AccountPageComponentProps } from "@/types/components/myPages/myPage/accountPage"
|
import type { AccountPageComponentProps } from "@/types/components/myPages/myPage/accountPage"
|
||||||
|
|
||||||
export default async function EarnAndBurn({
|
export default async function EarnAndBurn({
|
||||||
lang,
|
|
||||||
link,
|
link,
|
||||||
subtitle,
|
subtitle,
|
||||||
title,
|
title,
|
||||||
@@ -23,8 +22,8 @@ export default async function EarnAndBurn({
|
|||||||
return (
|
return (
|
||||||
<SectionContainer>
|
<SectionContainer>
|
||||||
<SectionHeader title={title} link={link} subtitle={subtitle} />
|
<SectionHeader title={title} link={link} subtitle={subtitle} />
|
||||||
<MobileTable lang={lang} transactions={transactions.data} />
|
<MobileTable transactions={transactions.data} />
|
||||||
<DesktopTable lang={lang} transactions={transactions.data} />
|
<DesktopTable transactions={transactions.data} />
|
||||||
<SectionLink link={link} variant="mobile" />
|
<SectionLink link={link} variant="mobile" />
|
||||||
</SectionContainer>
|
</SectionContainer>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -12,14 +12,12 @@ import Stats from "../../Overview/Stats"
|
|||||||
import styles from "./overview.module.css"
|
import styles from "./overview.module.css"
|
||||||
|
|
||||||
import type { AccountPageComponentProps } from "@/types/components/myPages/myPage/accountPage"
|
import type { AccountPageComponentProps } from "@/types/components/myPages/myPage/accountPage"
|
||||||
import type { LangParams } from "@/types/params"
|
|
||||||
|
|
||||||
export default async function PointsOverview({
|
export default async function PointsOverview({
|
||||||
link,
|
link,
|
||||||
subtitle,
|
subtitle,
|
||||||
title,
|
title,
|
||||||
lang,
|
}: AccountPageComponentProps) {
|
||||||
}: AccountPageComponentProps & LangParams) {
|
|
||||||
const user = await serverClient().user.get()
|
const user = await serverClient().user.get()
|
||||||
if (!user || "error" in user) {
|
if (!user || "error" in user) {
|
||||||
return null
|
return null
|
||||||
@@ -31,7 +29,7 @@ export default async function PointsOverview({
|
|||||||
<Hero color="burgundy">
|
<Hero color="burgundy">
|
||||||
<Friend user={user} color="red" />
|
<Friend user={user} color="red" />
|
||||||
<Divider className={styles.divider} color="peach" />
|
<Divider className={styles.divider} color="peach" />
|
||||||
<Stats user={user} lang={lang} />
|
<Stats user={user} />
|
||||||
</Hero>
|
</Hero>
|
||||||
<SectionLink link={link} variant="mobile" />
|
<SectionLink link={link} variant="mobile" />
|
||||||
</SectionContainer>
|
</SectionContainer>
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import type {
|
|||||||
|
|
||||||
export default function ClientPreviousStays({
|
export default function ClientPreviousStays({
|
||||||
initialPreviousStays,
|
initialPreviousStays,
|
||||||
lang,
|
|
||||||
}: PreviousStaysClientProps) {
|
}: PreviousStaysClientProps) {
|
||||||
const { data, isFetching, fetchNextPage, hasNextPage, isLoading } =
|
const { data, isFetching, fetchNextPage, hasNextPage, isLoading } =
|
||||||
trpc.user.stays.previous.useInfiniteQuery(
|
trpc.user.stays.previous.useInfiniteQuery(
|
||||||
@@ -49,11 +48,7 @@ export default function ClientPreviousStays({
|
|||||||
<ListContainer>
|
<ListContainer>
|
||||||
<Grids.Stackable>
|
<Grids.Stackable>
|
||||||
{stays.map((stay) => (
|
{stays.map((stay) => (
|
||||||
<StayCard
|
<StayCard key={stay.attributes.confirmationNumber} stay={stay} />
|
||||||
key={stay.attributes.confirmationNumber}
|
|
||||||
lang={lang}
|
|
||||||
stay={stay}
|
|
||||||
/>
|
|
||||||
))}
|
))}
|
||||||
</Grids.Stackable>
|
</Grids.Stackable>
|
||||||
{hasNextPage ? (
|
{hasNextPage ? (
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import EmptyPreviousStaysBlock from "./EmptyPreviousStays"
|
|||||||
import type { AccountPageComponentProps } from "@/types/components/myPages/myPage/accountPage"
|
import type { AccountPageComponentProps } from "@/types/components/myPages/myPage/accountPage"
|
||||||
|
|
||||||
export default async function PreviousStays({
|
export default async function PreviousStays({
|
||||||
lang,
|
|
||||||
title,
|
title,
|
||||||
subtitle,
|
subtitle,
|
||||||
link,
|
link,
|
||||||
@@ -23,10 +22,7 @@ export default async function PreviousStays({
|
|||||||
<SectionContainer>
|
<SectionContainer>
|
||||||
<SectionHeader title={title} subtitle={subtitle} link={link} />
|
<SectionHeader title={title} subtitle={subtitle} link={link} />
|
||||||
{initialPreviousStays.data.length ? (
|
{initialPreviousStays.data.length ? (
|
||||||
<ClientPreviousStays
|
<ClientPreviousStays initialPreviousStays={initialPreviousStays} />
|
||||||
initialPreviousStays={initialPreviousStays}
|
|
||||||
lang={lang}
|
|
||||||
/>
|
|
||||||
) : (
|
) : (
|
||||||
<EmptyPreviousStaysBlock />
|
<EmptyPreviousStaysBlock />
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -5,12 +5,11 @@ import { ArrowRightIcon } from "@/components/Icons"
|
|||||||
import Link from "@/components/TempDesignSystem/Link"
|
import Link from "@/components/TempDesignSystem/Link"
|
||||||
import Title from "@/components/TempDesignSystem/Text/Title"
|
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
|
import { getLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import styles from "./emptyUpcomingStays.module.css"
|
import styles from "./emptyUpcomingStays.module.css"
|
||||||
|
|
||||||
import { LangParams } from "@/types/params"
|
export default async function EmptyUpcomingStaysBlock() {
|
||||||
|
|
||||||
export default async function EmptyUpcomingStaysBlock({ lang }: LangParams) {
|
|
||||||
const { formatMessage } = await getIntl()
|
const { formatMessage } = await getIntl()
|
||||||
return (
|
return (
|
||||||
<section className={styles.container}>
|
<section className={styles.container}>
|
||||||
@@ -23,7 +22,7 @@ export default async function EmptyUpcomingStaysBlock({ lang }: LangParams) {
|
|||||||
</Title>
|
</Title>
|
||||||
</div>
|
</div>
|
||||||
<Link
|
<Link
|
||||||
href={homeHrefs[env.NODE_ENV][lang]}
|
href={homeHrefs[env.NODE_ENV][getLang()]}
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
color="peach80"
|
color="peach80"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import EmptyUpcomingStaysBlock from "./EmptyUpcomingStays"
|
|||||||
import { AccountPageComponentProps } from "@/types/components/myPages/myPage/accountPage"
|
import { AccountPageComponentProps } from "@/types/components/myPages/myPage/accountPage"
|
||||||
|
|
||||||
export default async function SoonestStays({
|
export default async function SoonestStays({
|
||||||
lang,
|
|
||||||
title,
|
title,
|
||||||
subtitle,
|
subtitle,
|
||||||
link,
|
link,
|
||||||
@@ -27,15 +26,11 @@ export default async function SoonestStays({
|
|||||||
{response.data.length ? (
|
{response.data.length ? (
|
||||||
<Grids.Stackable>
|
<Grids.Stackable>
|
||||||
{response.data.map((stay) => (
|
{response.data.map((stay) => (
|
||||||
<StayCard
|
<StayCard key={stay.attributes.confirmationNumber} stay={stay} />
|
||||||
key={stay.attributes.confirmationNumber}
|
|
||||||
lang={lang}
|
|
||||||
stay={stay}
|
|
||||||
/>
|
|
||||||
))}
|
))}
|
||||||
</Grids.Stackable>
|
</Grids.Stackable>
|
||||||
) : (
|
) : (
|
||||||
<EmptyUpcomingStaysBlock lang={lang} />
|
<EmptyUpcomingStaysBlock />
|
||||||
)}
|
)}
|
||||||
<SectionLink link={link} variant="mobile" />
|
<SectionLink link={link} variant="mobile" />
|
||||||
</SectionContainer>
|
</SectionContainer>
|
||||||
|
|||||||
@@ -5,12 +5,14 @@ import Image from "@/components/Image"
|
|||||||
import Link from "@/components/TempDesignSystem/Link"
|
import Link from "@/components/TempDesignSystem/Link"
|
||||||
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
||||||
import Title from "@/components/TempDesignSystem/Text/Title"
|
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||||
|
import useLang from "@/hooks/useLang"
|
||||||
|
|
||||||
import styles from "./stay.module.css"
|
import styles from "./stay.module.css"
|
||||||
|
|
||||||
import type { StayCardProps } from "@/types/components/myPages/stays/stayCard"
|
import type { StayCardProps } from "@/types/components/myPages/stays/stayCard"
|
||||||
|
|
||||||
export default function StayCard({ stay, lang }: StayCardProps) {
|
export default function StayCard({ stay }: StayCardProps) {
|
||||||
|
const lang = useLang()
|
||||||
const { checkinDate, checkoutDate, hotelInformation, bookingUrl } =
|
const { checkinDate, checkoutDate, hotelInformation, bookingUrl } =
|
||||||
stay.attributes
|
stay.attributes
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import type {
|
|||||||
|
|
||||||
export default function ClientUpcomingStays({
|
export default function ClientUpcomingStays({
|
||||||
initialUpcomingStays,
|
initialUpcomingStays,
|
||||||
lang,
|
|
||||||
}: UpcomingStaysClientProps) {
|
}: UpcomingStaysClientProps) {
|
||||||
const { data, isFetching, fetchNextPage, hasNextPage, isLoading } =
|
const { data, isFetching, fetchNextPage, hasNextPage, isLoading } =
|
||||||
trpc.user.stays.upcoming.useInfiniteQuery(
|
trpc.user.stays.upcoming.useInfiniteQuery(
|
||||||
@@ -49,11 +48,7 @@ export default function ClientUpcomingStays({
|
|||||||
<ListContainer>
|
<ListContainer>
|
||||||
<Grids.Stackable>
|
<Grids.Stackable>
|
||||||
{stays.map((stay) => (
|
{stays.map((stay) => (
|
||||||
<StayCard
|
<StayCard key={stay.attributes.confirmationNumber} stay={stay} />
|
||||||
key={stay.attributes.confirmationNumber}
|
|
||||||
lang={lang}
|
|
||||||
stay={stay}
|
|
||||||
/>
|
|
||||||
))}
|
))}
|
||||||
</Grids.Stackable>
|
</Grids.Stackable>
|
||||||
{hasNextPage ? (
|
{hasNextPage ? (
|
||||||
|
|||||||
@@ -5,12 +5,11 @@ import { ArrowRightIcon } from "@/components/Icons"
|
|||||||
import Link from "@/components/TempDesignSystem/Link"
|
import Link from "@/components/TempDesignSystem/Link"
|
||||||
import Title from "@/components/TempDesignSystem/Text/Title"
|
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
|
import { getLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import styles from "./emptyUpcomingStays.module.css"
|
import styles from "./emptyUpcomingStays.module.css"
|
||||||
|
|
||||||
import { LangParams } from "@/types/params"
|
export default async function EmptyUpcomingStaysBlock() {
|
||||||
|
|
||||||
export default async function EmptyUpcomingStaysBlock({ lang }: LangParams) {
|
|
||||||
const { formatMessage } = await getIntl()
|
const { formatMessage } = await getIntl()
|
||||||
return (
|
return (
|
||||||
<section className={styles.container}>
|
<section className={styles.container}>
|
||||||
@@ -23,7 +22,7 @@ export default async function EmptyUpcomingStaysBlock({ lang }: LangParams) {
|
|||||||
</Title>
|
</Title>
|
||||||
</div>
|
</div>
|
||||||
<Link
|
<Link
|
||||||
href={homeHrefs[env.NODE_ENV][lang]}
|
href={homeHrefs[env.NODE_ENV][getLang()]}
|
||||||
className={styles.link}
|
className={styles.link}
|
||||||
color="peach80"
|
color="peach80"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import EmptyUpcomingStaysBlock from "./EmptyUpcomingStays"
|
|||||||
import type { AccountPageComponentProps } from "@/types/components/myPages/myPage/accountPage"
|
import type { AccountPageComponentProps } from "@/types/components/myPages/myPage/accountPage"
|
||||||
|
|
||||||
export default async function UpcomingStays({
|
export default async function UpcomingStays({
|
||||||
lang,
|
|
||||||
title,
|
title,
|
||||||
subtitle,
|
subtitle,
|
||||||
link,
|
link,
|
||||||
@@ -23,12 +22,9 @@ export default async function UpcomingStays({
|
|||||||
<SectionContainer>
|
<SectionContainer>
|
||||||
<SectionHeader title={title} subtitle={subtitle} link={link} />
|
<SectionHeader title={title} subtitle={subtitle} link={link} />
|
||||||
{initialUpcomingStays.data.length ? (
|
{initialUpcomingStays.data.length ? (
|
||||||
<ClientUpcomingStays
|
<ClientUpcomingStays initialUpcomingStays={initialUpcomingStays} />
|
||||||
initialUpcomingStays={initialUpcomingStays}
|
|
||||||
lang={lang}
|
|
||||||
/>
|
|
||||||
) : (
|
) : (
|
||||||
<EmptyUpcomingStaysBlock lang={lang} />
|
<EmptyUpcomingStaysBlock />
|
||||||
)}
|
)}
|
||||||
<SectionLink link={link} variant="mobile" />
|
<SectionLink link={link} variant="mobile" />
|
||||||
</SectionContainer>
|
</SectionContainer>
|
||||||
|
|||||||
@@ -7,12 +7,11 @@ import Divider from "@/components/TempDesignSystem/Divider"
|
|||||||
import Link from "@/components/TempDesignSystem/Link"
|
import Link from "@/components/TempDesignSystem/Link"
|
||||||
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
|
import { getLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import styles from "./sidebar.module.css"
|
import styles from "./sidebar.module.css"
|
||||||
|
|
||||||
import type { LangParams } from "@/types/params"
|
export default async function SidebarMyPages() {
|
||||||
|
|
||||||
export default async function SidebarMyPages({ lang }: LangParams) {
|
|
||||||
const navigation = await serverClient().contentstack.myPages.navigation.get()
|
const navigation = await serverClient().contentstack.myPages.navigation.get()
|
||||||
const { formatMessage } = await getIntl()
|
const { formatMessage } = await getIntl()
|
||||||
if (!navigation) {
|
if (!navigation) {
|
||||||
@@ -43,7 +42,7 @@ export default async function SidebarMyPages({ lang }: LangParams) {
|
|||||||
<li>
|
<li>
|
||||||
<Link
|
<Link
|
||||||
color="burgundy"
|
color="burgundy"
|
||||||
href={logout[lang]}
|
href={logout[getLang()]}
|
||||||
prefetch={false}
|
prefetch={false}
|
||||||
size="small"
|
size="small"
|
||||||
variant="sidebar"
|
variant="sidebar"
|
||||||
|
|||||||
@@ -4,15 +4,14 @@ import { overview } from "@/constants/routes/webviews"
|
|||||||
|
|
||||||
import Link from "@/components/TempDesignSystem/Link"
|
import Link from "@/components/TempDesignSystem/Link"
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
|
import { getLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import styles from "./linkToOverview.module.css"
|
import styles from "./linkToOverview.module.css"
|
||||||
|
|
||||||
import type { LangParams } from "@/types/params"
|
export default async function LinkToOverview() {
|
||||||
|
|
||||||
export default async function LinkToOverview({ lang }: LangParams) {
|
|
||||||
const { formatMessage } = await getIntl()
|
const { formatMessage } = await getIntl()
|
||||||
return (
|
return (
|
||||||
<Link className={styles.overviewLink} href={overview[lang]}>
|
<Link className={styles.overviewLink} href={overview[getLang()]}>
|
||||||
<ArrowLeft height={20} width={20} />{" "}
|
<ArrowLeft height={20} width={20} />{" "}
|
||||||
{formatMessage({ id: "Go back to overview" })}
|
{formatMessage({ id: "Go back to overview" })}
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
12
hooks/useLang.ts
Normal file
12
hooks/useLang.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
"use client"
|
||||||
|
import { useParams } from "next/navigation"
|
||||||
|
|
||||||
|
import { LangParams } from "@/types/params"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A hook to get the current lang from the URL
|
||||||
|
*/
|
||||||
|
export default function useLang() {
|
||||||
|
const { lang } = useParams<LangParams>()
|
||||||
|
return lang
|
||||||
|
}
|
||||||
17
i18n/i18n.md
Normal file
17
i18n/i18n.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Internationalization
|
||||||
|
|
||||||
|
## The `lang` route parameter
|
||||||
|
|
||||||
|
All page paths starts with a language parameter, e.g. `/sv/utforska-scandic/wi-fi`.
|
||||||
|
|
||||||
|
### Get the language in a client component
|
||||||
|
|
||||||
|
We have a hook called `useLang` that directly returns the `lang` parameter from the path.
|
||||||
|
|
||||||
|
### Get the language in a server component
|
||||||
|
|
||||||
|
In order to not prop drill that all the way from a page we use React's `cache` in a way that resembles React`s context, but on the server side.
|
||||||
|
|
||||||
|
For this to work we must set the language with `setLang` on all root layouts and pages, including pages in parallel routes. Then we can use `getLang` in the components where we need the language.
|
||||||
|
|
||||||
|
This was inspired by [server-only-context](https://github.com/manvalls/server-only-context)
|
||||||
22
i18n/serverContext.ts
Normal file
22
i18n/serverContext.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { cache } from "react"
|
||||||
|
|
||||||
|
import { Lang } from "@/constants/languages"
|
||||||
|
|
||||||
|
const getRef = cache(() => ({ current: Lang.en }))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the language for the current request
|
||||||
|
*
|
||||||
|
* It works kind of like React's context,
|
||||||
|
* but on the server side, per request.
|
||||||
|
*
|
||||||
|
* @param newLang
|
||||||
|
*/
|
||||||
|
export const setLang = (newLang: Lang) => {
|
||||||
|
getRef().current = newLang
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the global language set for the current request
|
||||||
|
*/
|
||||||
|
export const getLang = () => getRef().current
|
||||||
@@ -14,9 +14,9 @@ import { env } from "@/env/client"
|
|||||||
import { SessionExpiredError } from "@/server/errors/trpc"
|
import { SessionExpiredError } from "@/server/errors/trpc"
|
||||||
import { transformer } from "@/server/transformer"
|
import { transformer } from "@/server/transformer"
|
||||||
|
|
||||||
import { trpc } from "./client"
|
import useLang from "@/hooks/useLang"
|
||||||
|
|
||||||
import { LangParams } from "@/types/params"
|
import { trpc } from "./client"
|
||||||
|
|
||||||
function initializeTrpcClient() {
|
function initializeTrpcClient() {
|
||||||
// Locally we set nextjs to run on port to 3000 so that we always guarantee
|
// Locally we set nextjs to run on port to 3000 so that we always guarantee
|
||||||
@@ -41,10 +41,8 @@ function initializeTrpcClient() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function TrpcProvider({
|
export default function TrpcProvider({ children }: React.PropsWithChildren) {
|
||||||
children,
|
const lang = useLang()
|
||||||
lang,
|
|
||||||
}: React.PropsWithChildren<LangParams>) {
|
|
||||||
const [queryClient] = useState(
|
const [queryClient] = useState(
|
||||||
() =>
|
() =>
|
||||||
new QueryClient({
|
new QueryClient({
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import { Lang } from "@/constants/languages"
|
|
||||||
|
|
||||||
import type { Image } from "@/types/image"
|
import type { Image } from "@/types/image"
|
||||||
import type {
|
import type {
|
||||||
CurrentHeaderLink,
|
CurrentHeaderLink,
|
||||||
@@ -17,5 +15,4 @@ export type MainMenuProps = {
|
|||||||
myPagesMobileDropdown: React.ReactNode | null
|
myPagesMobileDropdown: React.ReactNode | null
|
||||||
bookingHref: string
|
bookingHref: string
|
||||||
user: Pick<User, "firstName" | "lastName"> | null
|
user: Pick<User, "firstName" | "lastName"> | null
|
||||||
lang: Lang
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import { Lang } from "@/constants/languages"
|
|
||||||
|
|
||||||
import type { TopMenuHeaderLink } from "@/types/requests/currentHeader"
|
import type { TopMenuHeaderLink } from "@/types/requests/currentHeader"
|
||||||
|
|
||||||
export type TopMenuProps = {
|
export type TopMenuProps = {
|
||||||
@@ -7,5 +5,4 @@ export type TopMenuProps = {
|
|||||||
homeHref: string
|
homeHref: string
|
||||||
links: TopMenuHeaderLink[]
|
links: TopMenuHeaderLink[]
|
||||||
languageSwitcher: React.ReactNode | null
|
languageSwitcher: React.ReactNode | null
|
||||||
lang: Lang
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,5 @@ export type LanguageSwitcherLink = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type LanguageSwitcherProps = {
|
export type LanguageSwitcherProps = {
|
||||||
currentLanguage: Lang
|
|
||||||
urls: LanguageSwitcherData
|
urls: LanguageSwitcherData
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ import {
|
|||||||
|
|
||||||
import { LangParams } from "@/types/params"
|
import { LangParams } from "@/types/params"
|
||||||
|
|
||||||
export type SidebarProps = LangParams & {
|
export type SidebarProps = {
|
||||||
blocks: Sidebar[]
|
blocks: Sidebar[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export type JoinLoyaltyContactProps = LangParams & {
|
export type JoinLoyaltyContactProps = {
|
||||||
block: JoinLoyaltyContact["join_loyalty_contact"]
|
block: JoinLoyaltyContact["join_loyalty_contact"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,18 +9,15 @@ export type AccountPageContentProps = {
|
|||||||
title: string | null
|
title: string | null
|
||||||
subtitle: string | null
|
subtitle: string | null
|
||||||
link?: { href: string; text: string }
|
link?: { href: string; text: string }
|
||||||
lang: Lang
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AccountPageComponentProps = {
|
export type AccountPageComponentProps = {
|
||||||
lang: Lang
|
|
||||||
title: string | null
|
title: string | null
|
||||||
subtitle: string | null
|
subtitle: string | null
|
||||||
link?: { href: string; text: string }
|
link?: { href: string; text: string }
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ContentProps = {
|
export type ContentProps = {
|
||||||
lang: Lang
|
|
||||||
content: AccountPageContentItem[]
|
content: AccountPageContentItem[]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,12 +24,10 @@ export type EarnAndBurnProps = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface TableProps {
|
export interface TableProps {
|
||||||
lang: Lang
|
|
||||||
transactions: Transactions
|
transactions: Transactions
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RowProps {
|
export interface RowProps {
|
||||||
lang: Lang
|
|
||||||
transaction: Transaction
|
transaction: Transaction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,11 @@ export type PreviousStaysResponse = Awaited<
|
|||||||
>
|
>
|
||||||
export type PreviousStaysNonNullResponseObject =
|
export type PreviousStaysNonNullResponseObject =
|
||||||
NonNullable<PreviousStaysResponse>
|
NonNullable<PreviousStaysResponse>
|
||||||
export type PreviousStays = NonNullable<PreviousStaysNonNullResponseObject>["data"]
|
export type PreviousStays =
|
||||||
export type PreviousStay = NonNullable<PreviousStaysNonNullResponseObject>["data"][number]
|
NonNullable<PreviousStaysNonNullResponseObject>["data"]
|
||||||
|
export type PreviousStay =
|
||||||
|
NonNullable<PreviousStaysNonNullResponseObject>["data"][number]
|
||||||
|
|
||||||
export interface PreviousStaysClientProps {
|
export interface PreviousStaysClientProps {
|
||||||
lang: Lang
|
|
||||||
initialPreviousStays: PreviousStaysNonNullResponseObject
|
initialPreviousStays: PreviousStaysNonNullResponseObject
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import type { Lang } from "@/constants/languages"
|
|
||||||
import type { Stay } from "@/server/routers/user/output"
|
import type { Stay } from "@/server/routers/user/output"
|
||||||
|
|
||||||
export type StayCardProps = {
|
export type StayCardProps = {
|
||||||
lang: Lang
|
|
||||||
stay: Stay
|
stay: Stay
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,11 @@ export type UpcomingStaysResponse = Awaited<
|
|||||||
>
|
>
|
||||||
export type UpcomingStaysNonNullResponseObject =
|
export type UpcomingStaysNonNullResponseObject =
|
||||||
NonNullable<UpcomingStaysResponse>
|
NonNullable<UpcomingStaysResponse>
|
||||||
export type UpcomingStays = NonNullable<UpcomingStaysNonNullResponseObject>["data"]
|
export type UpcomingStays =
|
||||||
export type UpcomingStay = NonNullable<UpcomingStaysNonNullResponseObject>["data"][number]
|
NonNullable<UpcomingStaysNonNullResponseObject>["data"]
|
||||||
|
export type UpcomingStay =
|
||||||
|
NonNullable<UpcomingStaysNonNullResponseObject>["data"][number]
|
||||||
|
|
||||||
export interface UpcomingStaysClientProps {
|
export interface UpcomingStaysClientProps {
|
||||||
lang: Lang
|
|
||||||
initialUpcomingStays: UpcomingStaysNonNullResponseObject
|
initialUpcomingStays: UpcomingStaysNonNullResponseObject
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user