Merge branch 'develop' into feat/sw-386-current-header-fixes
This commit is contained in:
@@ -2,7 +2,7 @@ import { headers } from "next/headers"
|
|||||||
import { redirect } from "next/navigation"
|
import { redirect } from "next/navigation"
|
||||||
|
|
||||||
import { overview } from "@/constants/routes/myPages"
|
import { overview } from "@/constants/routes/myPages"
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
import { getProfile } from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import { auth } from "@/auth"
|
import { auth } from "@/auth"
|
||||||
import { getLang } from "@/i18n/serverContext"
|
import { getLang } from "@/i18n/serverContext"
|
||||||
@@ -27,7 +27,7 @@ export default async function ProtectedLayout({
|
|||||||
redirect(redirectURL)
|
redirect(redirectURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = await serverClient().user.get()
|
const user = await getProfile()
|
||||||
|
|
||||||
if (user && "error" in user) {
|
if (user && "error" in user) {
|
||||||
// redirect(redirectURL)
|
// redirect(redirectURL)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import Breadcrumbs from "@/components/MyPages/Breadcrumbs"
|
import Breadcrumbs from "@/components/Breadcrumbs"
|
||||||
import { setLang } from "@/i18n/serverContext"
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import { LangParams, PageArgs } from "@/types/params"
|
import { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { serverClient } from "@/lib/trpc/server"
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
|
|
||||||
import Content from "@/components/MyPages/AccountPage/Content"
|
import Blocks from "@/components/Blocks"
|
||||||
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"
|
||||||
@@ -10,7 +10,7 @@ import styles from "./page.module.css"
|
|||||||
|
|
||||||
import type { LangParams, PageArgs } from "@/types/params"
|
import type { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
export { generateMetadata } from "@/utils/generateMetadata"
|
export { generateMetadataAccountPage as generateMetadata } from "@/utils/generateMetadata"
|
||||||
|
|
||||||
export default async function MyPages({
|
export default async function MyPages({
|
||||||
params,
|
params,
|
||||||
@@ -30,8 +30,8 @@ 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 content={accountPage.content} />
|
<Blocks blocks={accountPage.content} />
|
||||||
) : (
|
) : (
|
||||||
<p>{formatMessage({ id: "No content published" })}</p>
|
<p>{formatMessage({ id: "No content published" })}</p>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { serverClient } from "@/lib/trpc/server"
|
import { getProfile } from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import Form from "@/components/Forms/Edit/Profile"
|
import Form from "@/components/Forms/Edit/Profile"
|
||||||
import { setLang } from "@/i18n/serverContext"
|
import { setLang } from "@/i18n/serverContext"
|
||||||
@@ -10,7 +10,7 @@ export default async function EditProfileSlot({
|
|||||||
}: PageArgs<LangParams>) {
|
}: PageArgs<LangParams>) {
|
||||||
setLang(params.lang)
|
setLang(params.lang)
|
||||||
|
|
||||||
const user = await serverClient().user.get()
|
const user = await getProfile()
|
||||||
if (!user || "error" in user) {
|
if (!user || "error" in user) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { languages, languageSelect } from "@/constants/languages"
|
import { languages, languageSelect } from "@/constants/languages"
|
||||||
import { profileEdit } from "@/constants/routes/myPages"
|
import { profileEdit } from "@/constants/routes/myPages"
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
import { getProfile } from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CalendarIcon,
|
CalendarIcon,
|
||||||
@@ -16,7 +16,7 @@ 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 { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import styles from "./page.module.css"
|
import styles from "./page.module.css"
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ 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)
|
setLang(params.lang)
|
||||||
const { formatMessage } = await getIntl()
|
const { formatMessage } = await getIntl()
|
||||||
const user = await serverClient().user.get()
|
const user = await getProfile()
|
||||||
if (!user || "error" in user) {
|
if (!user || "error" in user) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,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 prefetch={false} color="none" href={profileEdit[getLang()]}>
|
<Link prefetch={false} color="none" href={profileEdit[params.lang]}>
|
||||||
{formatMessage({ id: "Edit profile" })}
|
{formatMessage({ id: "Edit profile" })}
|
||||||
</Link>
|
</Link>
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import ProfilePage from "../page"
|
import ProfilePage from "../page"
|
||||||
|
|
||||||
export { generateMetadata } from "@/utils/generateMetadata"
|
export { generateMetadataAccountPage as generateMetadata } from "@/utils/generateMetadata"
|
||||||
|
|
||||||
export default ProfilePage
|
export default ProfilePage
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { setLang } from "@/i18n/serverContext"
|
|||||||
|
|
||||||
import { LangParams, PageArgs } from "@/types/params"
|
import { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
export { generateMetadata } from "@/utils/generateMetadata"
|
export { generateMetadataAccountPage as generateMetadata } from "@/utils/generateMetadata"
|
||||||
|
|
||||||
export default async function ProfilePage({ params }: PageArgs<LangParams>) {
|
export default async function ProfilePage({ params }: PageArgs<LangParams>) {
|
||||||
setLang(params.lang)
|
setLang(params.lang)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import Breadcrumbs from "@/components/MyPages/Breadcrumbs"
|
import Breadcrumbs from "@/components/Breadcrumbs"
|
||||||
import { setLang } from "@/i18n/serverContext"
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import { LangParams, PageArgs } from "@/types/params"
|
import { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import { setLang } from "@/i18n/serverContext"
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import { LangParams, PageArgs } from "@/types/params"
|
import type { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
export default function HotelReservationPage({ params }: PageArgs<LangParams>) {
|
export default function HotelReservationPage({ params }: PageArgs<LangParams>) {
|
||||||
setLang(params.lang)
|
setLang(params.lang)
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
import { serverClient } from "@/lib/trpc/server"
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
|
|
||||||
import BookingWidget from "@/components/BookingWidget"
|
import BookingWidget, { preload } from "@/components/BookingWidget"
|
||||||
|
|
||||||
export default async function BookingWidgetPage() {
|
export default async function BookingWidgetPage() {
|
||||||
|
preload()
|
||||||
|
|
||||||
// Get the booking widget show/hide status based on page specific settings
|
// Get the booking widget show/hide status based on page specific settings
|
||||||
const bookingWidgetToggle =
|
const bookingWidgetToggle =
|
||||||
await serverClient().contentstack.bookingwidget.getToggle()
|
await serverClient().contentstack.bookingwidget.toggle.get()
|
||||||
|
|
||||||
return (
|
if (bookingWidgetToggle.hideBookingWidget) {
|
||||||
<>
|
return null
|
||||||
{bookingWidgetToggle && bookingWidgetToggle.hideBookingWidget ? null : (
|
}
|
||||||
<BookingWidget />
|
|
||||||
)}
|
return <BookingWidget />
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import { ToastHandler } from "@/components/TempDesignSystem/Toasts"
|
|||||||
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 { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import type { LangParams, LayoutArgs } from "@/types/params"
|
import type { LangParams, LayoutArgs } from "@/types/params"
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ export default async function RootLayout({
|
|||||||
const { defaultLocale, locale, messages } = await getIntl()
|
const { defaultLocale, locale, messages } = await getIntl()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang={getLang()}>
|
<html lang={params.lang}>
|
||||||
<head>
|
<head>
|
||||||
<AdobeSDKScript />
|
<AdobeSDKScript />
|
||||||
<Script data-cookieconsent="ignore" src="/_static/js/cookie-bot.js" />
|
<Script data-cookieconsent="ignore" src="/_static/js/cookie-bot.js" />
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { getLang, setLang } from "@/i18n/serverContext"
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import styles from "./page.module.css"
|
import styles from "./page.module.css"
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ export default function MiddlewareError({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.layout}>
|
<div className={styles.layout}>
|
||||||
Middleware Error {getLang()}: {params.status}
|
Middleware Error {params.lang}: {params.status}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { notFound } from "next/navigation"
|
import { notFound } from "next/navigation"
|
||||||
|
|
||||||
import { GetCurrentBlockPage } from "@/lib/graphql/Query/CurrentBlockPage.graphql"
|
import { GetCurrentBlockPage } from "@/lib/graphql/Query/Current/CurrentBlockPage.graphql"
|
||||||
import { GetCurrentBlockPageTrackingData } from "@/lib/graphql/Query/CurrentBlockPageTrackingData.graphql"
|
import { GetCurrentBlockPageTrackingData } from "@/lib/graphql/Query/Current/CurrentBlockPageTrackingData.graphql"
|
||||||
import { request } from "@/lib/graphql/request"
|
import { request } from "@/lib/graphql/request"
|
||||||
|
|
||||||
import ContentPage from "@/components/Current/ContentPage"
|
import ContentPage from "@/components/Current/ContentPage"
|
||||||
|
|||||||
@@ -11,7 +11,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 { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import type { Metadata } from "next"
|
import type { Metadata } from "next"
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ export default async function RootLayout({
|
|||||||
const { defaultLocale, locale, messages } = await getIntl()
|
const { defaultLocale, locale, messages } = await getIntl()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang={getLang()}>
|
<html lang={params.lang}>
|
||||||
<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" />
|
||||||
@@ -45,7 +45,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={getLang()}
|
data-culture={params.lang}
|
||||||
id="Cookiebot"
|
id="Cookiebot"
|
||||||
src="https://consent.cookiebot.com/uc.js"
|
src="https://consent.cookiebot.com/uc.js"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import InitLivePreview from "@/components/Current/LivePreview"
|
import InitLivePreview from "@/components/Current/LivePreview"
|
||||||
import { getLang, setLang } from "@/i18n/serverContext"
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import type { Metadata } from "next"
|
import type { Metadata } from "next"
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ export default function RootLayout({
|
|||||||
setLang(params.lang)
|
setLang(params.lang)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang={getLang()}>
|
<html lang={params.lang}>
|
||||||
<body>
|
<body>
|
||||||
<InitLivePreview />
|
<InitLivePreview />
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { getLang, setLang } from "@/i18n/serverContext"
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ContentTypeParams,
|
ContentTypeParams,
|
||||||
@@ -16,8 +16,8 @@ export default async function PreviewPage({
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
Preview for {params.contentType}:{params.uid} in {getLang()} with params{" "}
|
Preview for {params.contentType}:{params.uid} in {params.lang} with
|
||||||
<pre>{JSON.stringify(searchParams, null, 2)}</pre> goes here
|
params <pre>{JSON.stringify(searchParams, null, 2)}</pre> goes here
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
import Script from "next/script"
|
|
||||||
|
|
||||||
import Footer from "@/components/Current/Footer"
|
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 { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import type { Metadata } from "next"
|
import type { Metadata } from "next"
|
||||||
|
|
||||||
@@ -24,7 +22,7 @@ export default function RootLayout({
|
|||||||
setLang(params.lang)
|
setLang(params.lang)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang={getLang()}>
|
<html lang={params.lang}>
|
||||||
<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" />
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import ContentstackLivePreview from "@contentstack/live-preview-utils"
|
import ContentstackLivePreview from "@contentstack/live-preview-utils"
|
||||||
|
|
||||||
import { previewRequest } from "@/lib/graphql/previewRequest"
|
import { previewRequest } from "@/lib/graphql/previewRequest"
|
||||||
import { GetCurrentBlockPage } from "@/lib/graphql/Query/CurrentBlockPage.graphql"
|
import { GetCurrentBlockPage } from "@/lib/graphql/Query/Current/CurrentBlockPage.graphql"
|
||||||
|
|
||||||
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 { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import type { PageArgs, PreviewParams } from "@/types/params"
|
import type { PageArgs, PreviewParams } from "@/types/params"
|
||||||
import { LangParams } from "@/types/params"
|
import { LangParams } from "@/types/params"
|
||||||
@@ -26,7 +26,7 @@ export default async function CurrentPreviewPage({
|
|||||||
|
|
||||||
const response = await previewRequest<GetCurrentBlockPageData>(
|
const response = await previewRequest<GetCurrentBlockPageData>(
|
||||||
GetCurrentBlockPage,
|
GetCurrentBlockPage,
|
||||||
{ locale: getLang(), url: searchParams.uri }
|
{ locale: params.lang, url: searchParams.uri }
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!response.data?.all_current_blocks_page?.total) {
|
if (!response.data?.all_current_blocks_page?.total) {
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { headers } from "next/headers"
|
import { headers } from "next/headers"
|
||||||
import { notFound, redirect } from "next/navigation"
|
import { notFound, redirect } from "next/navigation"
|
||||||
|
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
import { getProfile } from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import AccountPage from "@/components/ContentType/Webviews/AccountPage"
|
import AccountPage from "@/components/Webviews/AccountPage"
|
||||||
import LoyaltyPage from "@/components/ContentType/Webviews/LoyaltyPage"
|
import LoyaltyPage from "@/components/Webviews/LoyaltyPage"
|
||||||
import { getLang, setLang } from "@/i18n/serverContext"
|
import { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ContentTypeWebviewParams,
|
ContentTypeWebviewParams,
|
||||||
@@ -18,7 +18,7 @@ export default async function ContentTypePage({
|
|||||||
params,
|
params,
|
||||||
}: PageArgs<LangParams & ContentTypeWebviewParams & UIDParams, {}>) {
|
}: PageArgs<LangParams & ContentTypeWebviewParams & UIDParams, {}>) {
|
||||||
setLang(params.lang)
|
setLang(params.lang)
|
||||||
const user = await serverClient().user.get()
|
const user = await getProfile()
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
console.log(`[webview:page] unable to load user`)
|
console.log(`[webview:page] unable to load user`)
|
||||||
@@ -31,8 +31,8 @@ export default async function ContentTypePage({
|
|||||||
case "forbidden": // fall through
|
case "forbidden": // fall through
|
||||||
case "token_expired":
|
case "token_expired":
|
||||||
const h = headers()
|
const h = headers()
|
||||||
const returnURL = `/${getLang()}/webview${h.get("x-pathname")!}`
|
const returnURL = `/${params.lang}/webview${h.get("x-pathname")!}`
|
||||||
const redirectURL = `/${getLang()}/webview/refresh?returnUrl=${encodeURIComponent(returnURL)}`
|
const redirectURL = `/${params.lang}/webview/refresh?returnUrl=${encodeURIComponent(returnURL)}`
|
||||||
console.log(`[webview:page] user error, redirecting to: ${redirectURL}`)
|
console.log(`[webview:page] user error, redirecting to: ${redirectURL}`)
|
||||||
redirect(redirectURL)
|
redirect(redirectURL)
|
||||||
case "notfound":
|
case "notfound":
|
||||||
|
|||||||
@@ -8,7 +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 { setLang } from "@/i18n/serverContext"
|
||||||
|
|
||||||
import styles from "./layout.module.css"
|
import styles from "./layout.module.css"
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ export default async function RootLayout({
|
|||||||
const { defaultLocale, locale, messages } = await getIntl()
|
const { defaultLocale, locale, messages } = await getIntl()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang={getLang()}>
|
<html lang={params.lang}>
|
||||||
<head>
|
<head>
|
||||||
<AdobeSDKScript />
|
<AdobeSDKScript />
|
||||||
<Script id="ensure-adobeDataLayer">{`
|
<Script id="ensure-adobeDataLayer">{`
|
||||||
|
|||||||
60
app/api/web/revalidate/manually/route.ts
Normal file
60
app/api/web/revalidate/manually/route.ts
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import { revalidateTag } from "next/cache"
|
||||||
|
import { headers } from "next/headers"
|
||||||
|
|
||||||
|
import { Lang } from "@/constants/languages"
|
||||||
|
import { env } from "@/env/server"
|
||||||
|
import { badRequest, internalServerError } from "@/server/errors/next"
|
||||||
|
|
||||||
|
import { generateTag } from "@/utils/generateTag"
|
||||||
|
|
||||||
|
// This file is primarily to be used locally to test
|
||||||
|
// purging your cache for new (and old) requests
|
||||||
|
export async function POST() {
|
||||||
|
try {
|
||||||
|
const headersList = headers()
|
||||||
|
const secret = headersList.get("x-revalidate-secret")
|
||||||
|
|
||||||
|
if (secret !== env.REVALIDATE_SECRET) {
|
||||||
|
console.error(`Invalid Secret`)
|
||||||
|
console.error({ secret })
|
||||||
|
return badRequest({
|
||||||
|
now: Date.now(),
|
||||||
|
revalidated: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const affix = headersList.get("x-affix")
|
||||||
|
const identifier = headersList.get("x-identifier")
|
||||||
|
const lang = headersList.get("x-lang")
|
||||||
|
if (lang && identifier) {
|
||||||
|
if (affix) {
|
||||||
|
const tag = generateTag(lang as Lang, identifier, affix)
|
||||||
|
console.info(
|
||||||
|
`Revalidated tag for [lang: ${lang}, identifier: ${identifier}, affix: ${affix}]`
|
||||||
|
)
|
||||||
|
console.info(`Tag: ${tag}`)
|
||||||
|
revalidateTag(tag)
|
||||||
|
} else {
|
||||||
|
const tag = generateTag(lang as Lang, identifier)
|
||||||
|
console.info(
|
||||||
|
`Revalidated tag for [lang: ${lang}, identifier: ${identifier}]`
|
||||||
|
)
|
||||||
|
console.info(`Tag: ${tag}`)
|
||||||
|
revalidateTag(tag)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.info(`Missing lang and/or identifier`)
|
||||||
|
console.info(`lang: ${lang}, identifier: ${identifier}`)
|
||||||
|
return badRequest({
|
||||||
|
now: Date.now(),
|
||||||
|
revalidated: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response.json({ revalidated: true, now: Date.now() })
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to revalidate tag(s)")
|
||||||
|
console.error(error)
|
||||||
|
return internalServerError({ revalidated: false, now: Date.now() })
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@ import { z } from "zod"
|
|||||||
|
|
||||||
import { Lang } from "@/constants/languages"
|
import { Lang } from "@/constants/languages"
|
||||||
import { env } from "@/env/server"
|
import { env } from "@/env/server"
|
||||||
import { internalServerError } from "@/server/errors/next"
|
import { badRequest, internalServerError } from "@/server/errors/next"
|
||||||
import { affix as bookingwidgetAffix } from "@/server/routers/contentstack/bookingwidget/utils"
|
import { affix as bookingwidgetAffix } from "@/server/routers/contentstack/bookingwidget/utils"
|
||||||
import { affix as breadcrumbsAffix } from "@/server/routers/contentstack/breadcrumbs/utils"
|
import { affix as breadcrumbsAffix } from "@/server/routers/contentstack/breadcrumbs/utils"
|
||||||
import { languageSwitcherAffix } from "@/server/routers/contentstack/languageSwitcher/utils"
|
import { languageSwitcherAffix } from "@/server/routers/contentstack/languageSwitcher/utils"
|
||||||
@@ -48,15 +48,10 @@ export async function POST(request: NextRequest) {
|
|||||||
if (secret !== env.REVALIDATE_SECRET) {
|
if (secret !== env.REVALIDATE_SECRET) {
|
||||||
console.error(`Invalid Secret`)
|
console.error(`Invalid Secret`)
|
||||||
console.error({ secret })
|
console.error({ secret })
|
||||||
return Response.json(
|
return badRequest({
|
||||||
{
|
now: Date.now(),
|
||||||
now: Date.now(),
|
revalidated: false,
|
||||||
revalidated: false,
|
})
|
||||||
},
|
|
||||||
{
|
|
||||||
status: 400,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await request.json()
|
const data = await request.json()
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import ContentCard from "@/components/TempDesignSystem/ContentCard"
|
|||||||
import Grids from "@/components/TempDesignSystem/Grids"
|
import Grids from "@/components/TempDesignSystem/Grids"
|
||||||
import LoyaltyCard from "@/components/TempDesignSystem/LoyaltyCard"
|
import LoyaltyCard from "@/components/TempDesignSystem/LoyaltyCard"
|
||||||
|
|
||||||
import type { CardsGridProps } from "@/types/components/content/blocks"
|
import type { CardsGridProps } from "@/types/components/blocks/cardsGrid"
|
||||||
import { CardsGridEnum } from "@/types/components/content/enums"
|
import { CardsGridEnum } from "@/types/enums/cardsGrid"
|
||||||
|
|
||||||
export default function CardsGrid({
|
export default function CardsGrid({
|
||||||
cards_grid,
|
cards_grid,
|
||||||
@@ -22,36 +22,37 @@ export default function CardsGrid({
|
|||||||
<Grids.Stackable>
|
<Grids.Stackable>
|
||||||
{cards_grid.cards.map((card) => {
|
{cards_grid.cards.map((card) => {
|
||||||
switch (card.__typename) {
|
switch (card.__typename) {
|
||||||
case CardsGridEnum.Card:
|
case CardsGridEnum.cards.Card: {
|
||||||
return card.isContentCard ? (
|
return card.isContentCard ? (
|
||||||
<ContentCard
|
<ContentCard
|
||||||
key={card.system.uid}
|
key={card.system.uid}
|
||||||
title={card.heading || ""}
|
description={card.body_text}
|
||||||
description={card.body_text || ""}
|
backgroundImage={card.backgroundImage}
|
||||||
primaryButton={card.primaryButton}
|
primaryButton={card.primaryButton}
|
||||||
secondaryButton={card.secondaryButton}
|
secondaryButton={card.secondaryButton}
|
||||||
sidePeekButton={card.sidePeekButton}
|
sidePeekButton={card.sidePeekButton}
|
||||||
backgroundImage={card.background_image}
|
|
||||||
style="default"
|
style="default"
|
||||||
|
title={card.heading}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<Card
|
<Card
|
||||||
theme={cards_grid.theme || "one"}
|
|
||||||
key={card.system.uid}
|
key={card.system.uid}
|
||||||
scriptedTopTitle={card.scripted_top_title}
|
|
||||||
heading={card.heading}
|
|
||||||
bodyText={card.body_text}
|
bodyText={card.body_text}
|
||||||
secondaryButton={card.secondaryButton}
|
heading={card.heading}
|
||||||
primaryButton={card.primaryButton}
|
primaryButton={card.primaryButton}
|
||||||
|
secondaryButton={card.secondaryButton}
|
||||||
|
scriptedTopTitle={card.scripted_top_title}
|
||||||
|
theme={cards_grid.theme || "one"}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
case CardsGridEnum.LoyaltyCard:
|
}
|
||||||
|
case CardsGridEnum.cards.LoyaltyCard:
|
||||||
return (
|
return (
|
||||||
<LoyaltyCard
|
<LoyaltyCard
|
||||||
key={card.system.uid}
|
key={card.system.uid}
|
||||||
image={card.image}
|
|
||||||
heading={card.heading}
|
|
||||||
bodyText={card.body_text}
|
bodyText={card.body_text}
|
||||||
|
heading={card.heading}
|
||||||
|
image={card.image}
|
||||||
link={card.link}
|
link={card.link}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { MembershipLevelEnum } from "@/constants/membershipLevels"
|
import { MembershipLevelEnum } from "@/constants/membershipLevels"
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
import { getProfile } from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import SectionContainer from "@/components/Section/Container"
|
import SectionContainer from "@/components/Section/Container"
|
||||||
import SectionHeader from "@/components/Section/Header"
|
import SectionHeader from "@/components/Section/Header"
|
||||||
@@ -8,7 +8,6 @@ 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 { getLang } from "@/i18n/serverContext"
|
||||||
import { getMembershipLevelObject } from "@/utils/membershipLevel"
|
import { getMembershipLevelObject } from "@/utils/membershipLevel"
|
||||||
import { getMembership } from "@/utils/user"
|
|
||||||
|
|
||||||
import styles from "./current.module.css"
|
import styles from "./current.module.css"
|
||||||
|
|
||||||
@@ -19,21 +18,16 @@ export default async function CurrentBenefitsBlock({
|
|||||||
subtitle,
|
subtitle,
|
||||||
link,
|
link,
|
||||||
}: AccountPageComponentProps) {
|
}: AccountPageComponentProps) {
|
||||||
const user = await serverClient().user.get()
|
const user = await getProfile()
|
||||||
// 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
|
||||||
// we might have to add a new boolean property "exclusive" or similar
|
// we might have to add a new boolean property "exclusive" or similar
|
||||||
if (!user || "error" in user) {
|
if (!user || "error" in user || !user.membership) {
|
||||||
return null
|
|
||||||
}
|
|
||||||
const membership = getMembership(user.memberships)
|
|
||||||
if (!membership) {
|
|
||||||
// TODO: handle this case?
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentLevel = getMembershipLevelObject(
|
const currentLevel = getMembershipLevelObject(
|
||||||
user.memberships[0].membershipLevel as MembershipLevelEnum,
|
user.membership.membershipLevel as MembershipLevelEnum,
|
||||||
getLang()
|
getLang()
|
||||||
)
|
)
|
||||||
if (!currentLevel) {
|
if (!currentLevel) {
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Lock } from "react-feather"
|
import { Lock } from "react-feather"
|
||||||
|
|
||||||
import { MembershipLevelEnum } from "@/constants/membershipLevels"
|
import { MembershipLevelEnum } from "@/constants/membershipLevels"
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
import { getProfile } from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import SectionContainer from "@/components/Section/Container"
|
import SectionContainer from "@/components/Section/Container"
|
||||||
import SectionHeader from "@/components/Section/Header"
|
import SectionHeader from "@/components/Section/Header"
|
||||||
@@ -24,12 +24,12 @@ export default async function NextLevelBenefitsBlock({
|
|||||||
link,
|
link,
|
||||||
}: AccountPageComponentProps) {
|
}: AccountPageComponentProps) {
|
||||||
const intl = await getIntl()
|
const intl = await getIntl()
|
||||||
const user = await serverClient().user.get()
|
const user = await getProfile()
|
||||||
if (!user || "error" in user) {
|
if (!user || "error" in user || !user.membership) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
const nextLevel = getMembershipLevelObject(
|
const nextLevel = getMembershipLevelObject(
|
||||||
user.memberships[0].nextLevel as MembershipLevelEnum,
|
user.membership.nextLevel as MembershipLevelEnum,
|
||||||
getLang()
|
getLang()
|
||||||
)
|
)
|
||||||
if (!nextLevel) {
|
if (!nextLevel) {
|
||||||
27
components/Blocks/DynamicContent/HowItWorks/index.tsx
Normal file
27
components/Blocks/DynamicContent/HowItWorks/index.tsx
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||||
|
import { getIntl } from "@/i18n"
|
||||||
|
|
||||||
|
import SectionWrapper from "../SectionWrapper"
|
||||||
|
|
||||||
|
import styles from "./howItWorks.module.css"
|
||||||
|
|
||||||
|
import type { HowItWorksProps } from "@/types/components/blocks/dynamicContent"
|
||||||
|
|
||||||
|
export default async function HowItWorks({
|
||||||
|
dynamic_content,
|
||||||
|
firstItem,
|
||||||
|
}: HowItWorksProps) {
|
||||||
|
const intl = await getIntl()
|
||||||
|
const displayHeader = !!(
|
||||||
|
dynamic_content.link ||
|
||||||
|
dynamic_content.subtitle ||
|
||||||
|
dynamic_content.title
|
||||||
|
)
|
||||||
|
return (
|
||||||
|
<SectionWrapper dynamic_content={dynamic_content} firstItem={firstItem}>
|
||||||
|
<section className={styles.container}>
|
||||||
|
<Title level="h3">{intl.formatMessage({ id: "How it works" })}</Title>
|
||||||
|
</section>
|
||||||
|
</SectionWrapper>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -20,27 +20,35 @@ import Caption from "@/components/TempDesignSystem/Text/Caption"
|
|||||||
import Title from "@/components/TempDesignSystem/Text/Title"
|
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||||
import levelsData from "@/data/loyaltyLevels"
|
import levelsData from "@/data/loyaltyLevels"
|
||||||
|
|
||||||
|
import SectionWrapper from "../SectionWrapper"
|
||||||
|
|
||||||
import styles from "./loyaltyLevels.module.css"
|
import styles from "./loyaltyLevels.module.css"
|
||||||
|
|
||||||
import type { Level, LevelCardProps } from "@/types/components/content/blocks"
|
import type { LoyaltyLevelsProps } from "@/types/components/blocks/dynamicContent"
|
||||||
|
import type { Level, LevelCardProps } from "@/types/components/overviewTable"
|
||||||
|
|
||||||
export default function LoyaltyLevels() {
|
export default function LoyaltyLevels({
|
||||||
|
dynamic_content,
|
||||||
|
firstItem,
|
||||||
|
}: LoyaltyLevelsProps) {
|
||||||
const params = useParams()
|
const params = useParams()
|
||||||
const lang = params.lang as Lang
|
const lang = params.lang as Lang
|
||||||
const { formatMessage } = useIntl()
|
const { formatMessage } = useIntl()
|
||||||
|
|
||||||
const { levels } = levelsData[lang]
|
const { levels } = levelsData[lang]
|
||||||
return (
|
return (
|
||||||
<section className={styles.cardContainer}>
|
<SectionWrapper dynamic_content={dynamic_content} firstItem={firstItem}>
|
||||||
{levels.map((level: Level) => (
|
<section className={styles.cardContainer}>
|
||||||
<LevelCard
|
{levels.map((level: Level) => (
|
||||||
key={level.level}
|
<LevelCard
|
||||||
formatMessage={formatMessage}
|
key={level.level}
|
||||||
lang={lang}
|
formatMessage={formatMessage}
|
||||||
level={level}
|
lang={lang}
|
||||||
/>
|
level={level}
|
||||||
))}
|
/>
|
||||||
</section>
|
))}
|
||||||
|
</section>
|
||||||
|
</SectionWrapper>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2,11 +2,12 @@ import Caption from "@/components/TempDesignSystem/Text/Caption"
|
|||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
|
|
||||||
import CopyButton from "../../Buttons/CopyButton"
|
import CopyButton from "../../Buttons/CopyButton"
|
||||||
import { MembershipNumberProps } from "./membershipNumber"
|
|
||||||
import { membershipNumberVariants } from "./membershipNumberVariants"
|
import { membershipNumberVariants } from "./membershipNumberVariants"
|
||||||
|
|
||||||
import styles from "./membershipNumber.module.css"
|
import styles from "./membershipNumber.module.css"
|
||||||
|
|
||||||
|
import type { MembershipNumberProps } from "@/types/components/myPages/membershipNumber"
|
||||||
|
|
||||||
export default async function MembershipNumber({
|
export default async function MembershipNumber({
|
||||||
className,
|
className,
|
||||||
color,
|
color,
|
||||||
@@ -23,7 +24,7 @@ export default async function MembershipNumber({
|
|||||||
</Caption>
|
</Caption>
|
||||||
<span className={styles.icon}>
|
<span className={styles.icon}>
|
||||||
<Caption className={styles.icon} color="pale" asChild>
|
<Caption className={styles.icon} color="pale" asChild>
|
||||||
<code>{membership.membershipNumber ?? "N/A"}</code>
|
<code>{membership?.membershipNumber ?? "N/A"}</code>
|
||||||
</Caption>
|
</Caption>
|
||||||
{membership && (
|
{membership && (
|
||||||
<CopyButton membershipNumber={membership.membershipNumber} />
|
<CopyButton membershipNumber={membership.membershipNumber} />
|
||||||
@@ -3,22 +3,20 @@ import { membershipLevels } from "@/constants/membershipLevels"
|
|||||||
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 { getMembership, isHighestMembership } from "@/utils/user"
|
import { isHighestMembership } from "@/utils/user"
|
||||||
|
|
||||||
import { MembershipNumberProps } from "./MemershipNumber/membershipNumber"
|
|
||||||
import MembershipLevel from "./MembershipLevel"
|
import MembershipLevel from "./MembershipLevel"
|
||||||
import MembershipNumber from "./MemershipNumber"
|
|
||||||
|
|
||||||
import styles from "./friend.module.css"
|
import styles from "./friend.module.css"
|
||||||
|
|
||||||
import type { UserProps } from "@/types/components/myPages/user"
|
import type { FriendProps } from "@/types/components/myPages/friend"
|
||||||
|
|
||||||
export default async function Friend({
|
export default async function Friend({
|
||||||
user,
|
children,
|
||||||
color,
|
membership,
|
||||||
}: UserProps & Pick<MembershipNumberProps, "color">) {
|
name,
|
||||||
|
}: FriendProps) {
|
||||||
const { formatMessage } = await getIntl()
|
const { formatMessage } = await getIntl()
|
||||||
const membership = getMembership(user.memberships)
|
|
||||||
if (!membership?.membershipLevel) {
|
if (!membership?.membershipLevel) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -45,9 +43,9 @@ export default async function Friend({
|
|||||||
</header>
|
</header>
|
||||||
<div className={styles.membership}>
|
<div className={styles.membership}>
|
||||||
<Title className={styles.name} color="pale" level="h3">
|
<Title className={styles.name} color="pale" level="h3">
|
||||||
{user.name}
|
{name}
|
||||||
</Title>
|
</Title>
|
||||||
<MembershipNumber membership={membership} color={color} />
|
{children}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
import { serverClient } from "@/lib/trpc/server"
|
import { getProfile } from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import SectionContainer from "@/components/Section/Container"
|
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 MembershipNumber from "./Friend/MembershipNumber"
|
||||||
import Friend from "./Friend"
|
import Friend from "./Friend"
|
||||||
import Stats from "./Stats"
|
import Stats from "./Stats"
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ export default async function Overview({
|
|||||||
subtitle,
|
subtitle,
|
||||||
title,
|
title,
|
||||||
}: AccountPageComponentProps) {
|
}: AccountPageComponentProps) {
|
||||||
const user = await serverClient().user.get()
|
const user = await getProfile()
|
||||||
if (!user || "error" in user) {
|
if (!user || "error" in user) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -28,7 +28,9 @@ export default async function Overview({
|
|||||||
<SectionContainer>
|
<SectionContainer>
|
||||||
<SectionHeader link={link} preamble={subtitle} title={title} topTitle />
|
<SectionHeader link={link} preamble={subtitle} title={title} topTitle />
|
||||||
<Hero color="red">
|
<Hero color="red">
|
||||||
<Friend user={user} color="burgundy" />
|
<Friend membership={user.membership} name={user.name}>
|
||||||
|
<MembershipNumber color="burgundy" membership={user.membership} />
|
||||||
|
</Friend>
|
||||||
<Divider className={styles.divider} color="peach" />
|
<Divider className={styles.divider} color="peach" />
|
||||||
<Stats user={user} />
|
<Stats user={user} />
|
||||||
</Hero>
|
</Hero>
|
||||||
@@ -6,7 +6,7 @@ import BenefitValue from "../BenefitValue"
|
|||||||
|
|
||||||
import styles from "./benefitCard.module.css"
|
import styles from "./benefitCard.module.css"
|
||||||
|
|
||||||
import type { BenefitCardProps } from "@/types/components/loyalty/blocks"
|
import type { BenefitCardProps } from "@/types/components/overviewTable"
|
||||||
|
|
||||||
export default function BenefitCard({
|
export default function BenefitCard({
|
||||||
comparedValues,
|
comparedValues,
|
||||||
@@ -4,7 +4,7 @@ import BenefitCard from "../BenefitCard"
|
|||||||
|
|
||||||
import styles from "./benefitList.module.css"
|
import styles from "./benefitList.module.css"
|
||||||
|
|
||||||
import type { BenefitListProps } from "@/types/components/content/blocks"
|
import type { BenefitListProps } from "@/types/components/overviewTable"
|
||||||
|
|
||||||
export default function BenefitList({ levels }: BenefitListProps) {
|
export default function BenefitList({ levels }: BenefitListProps) {
|
||||||
return getUnlockedBenefits(levels).map((benefit) => {
|
return getUnlockedBenefits(levels).map((benefit) => {
|
||||||
@@ -4,7 +4,7 @@ import CheckCircle from "@/components/Icons/CheckCircle"
|
|||||||
|
|
||||||
import styles from "./benefitValue.module.css"
|
import styles from "./benefitValue.module.css"
|
||||||
|
|
||||||
import type { BenefitValueProps } from "@/types/components/loyalty/blocks"
|
import type { BenefitValueProps } from "@/types/components/overviewTable"
|
||||||
|
|
||||||
export default function BenefitValue({ benefit }: BenefitValueProps) {
|
export default function BenefitValue({ benefit }: BenefitValueProps) {
|
||||||
if (!benefit.unlocked) {
|
if (!benefit.unlocked) {
|
||||||
@@ -31,9 +31,9 @@ import {
|
|||||||
DesktopSelectColumns,
|
DesktopSelectColumns,
|
||||||
type MobileColumnHeaderProps,
|
type MobileColumnHeaderProps,
|
||||||
overviewTableActionsEnum,
|
overviewTableActionsEnum,
|
||||||
type OverviewTableProps,
|
type OverviewTableClientProps,
|
||||||
OverviewTableReducerAction,
|
OverviewTableReducerAction,
|
||||||
} from "@/types/components/loyalty/blocks"
|
} from "@/types/components/overviewTable"
|
||||||
import type { User } from "@/types/user"
|
import type { User } from "@/types/user"
|
||||||
|
|
||||||
const levelsTranslations = {
|
const levelsTranslations = {
|
||||||
@@ -126,9 +126,9 @@ function reducer(state: any, action: OverviewTableReducerAction) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function OverviewTable({
|
export default function OverviewTableClient({
|
||||||
activeMembership,
|
activeMembership,
|
||||||
}: OverviewTableProps) {
|
}: OverviewTableClientProps) {
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
const lang = useLang()
|
const lang = useLang()
|
||||||
const levelsData = levelsTranslations[lang]
|
const levelsData = levelsTranslations[lang]
|
||||||
@@ -241,6 +241,7 @@ export default function OverviewTable({
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className={styles.mobileColumns}>
|
<div className={styles.mobileColumns}>
|
||||||
@@ -8,7 +8,7 @@ import styles from "./desktopHeader.module.css"
|
|||||||
import type {
|
import type {
|
||||||
DesktopSelectColumns,
|
DesktopSelectColumns,
|
||||||
LargeTableProps,
|
LargeTableProps,
|
||||||
} from "@/types/components/loyalty/blocks"
|
} from "@/types/components/overviewTable"
|
||||||
|
|
||||||
export default function DesktopHeader({
|
export default function DesktopHeader({
|
||||||
levels,
|
levels,
|
||||||
@@ -11,7 +11,7 @@ import styles from "./largeTable.module.css"
|
|||||||
import type {
|
import type {
|
||||||
BenefitTableHeaderProps,
|
BenefitTableHeaderProps,
|
||||||
LargeTableProps,
|
LargeTableProps,
|
||||||
} from "@/types/components/content/blocks"
|
} from "@/types/components/overviewTable"
|
||||||
|
|
||||||
export default function LargeTable({
|
export default function LargeTable({
|
||||||
levels,
|
levels,
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import styles from "./levelSummary.module.css"
|
import styles from "./levelSummary.module.css"
|
||||||
|
|
||||||
import type { LevelSummaryProps } from "@/types/components/content/blocks"
|
import type { LevelSummaryProps } from "@/types/components/overviewTable"
|
||||||
|
|
||||||
export default function LevelSummary({
|
export default function LevelSummary({
|
||||||
level,
|
level,
|
||||||
18
components/Blocks/DynamicContent/OverviewTable/index.tsx
Normal file
18
components/Blocks/DynamicContent/OverviewTable/index.tsx
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
|
|
||||||
|
import SectionWrapper from "../SectionWrapper"
|
||||||
|
import OverviewTableClient from "./Client"
|
||||||
|
|
||||||
|
import type { OverviewTableProps } from "@/types/components/blocks/dynamicContent"
|
||||||
|
|
||||||
|
export default async function OverviewTable({
|
||||||
|
dynamic_content,
|
||||||
|
firstItem,
|
||||||
|
}: OverviewTableProps) {
|
||||||
|
const membershipLevel = await serverClient().user.safeMembershipLevel()
|
||||||
|
return (
|
||||||
|
<SectionWrapper dynamic_content={dynamic_content} firstItem={firstItem}>
|
||||||
|
<OverviewTableClient activeMembership={membershipLevel} />
|
||||||
|
</SectionWrapper>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -6,14 +6,15 @@ import { useIntl } from "react-intl"
|
|||||||
import { webviews } from "@/constants/routes/webviews"
|
import { webviews } from "@/constants/routes/webviews"
|
||||||
import { dt } from "@/lib/dt"
|
import { dt } from "@/lib/dt"
|
||||||
|
|
||||||
import AwardPoints from "@/components/MyPages/Blocks/Points/EarnAndBurn/AwardPoints"
|
|
||||||
import Link from "@/components/TempDesignSystem/Link"
|
import Link from "@/components/TempDesignSystem/Link"
|
||||||
import Table from "@/components/TempDesignSystem/Table"
|
import Table from "@/components/TempDesignSystem/Table"
|
||||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||||
import useLang from "@/hooks/useLang"
|
import useLang from "@/hooks/useLang"
|
||||||
|
|
||||||
|
import AwardPoints from "../../../AwardPoints"
|
||||||
|
|
||||||
import type { RowProps } from "@/types/components/myPages/myPage/earnAndBurn"
|
import type { RowProps } from "@/types/components/myPages/myPage/earnAndBurn"
|
||||||
import { RewardTransactionTypes } from "@/types/components/myPages/myPage/enums"
|
import { Transactions } from "@/types/enums/transactions"
|
||||||
|
|
||||||
export default function Row({ transaction }: RowProps) {
|
export default function Row({ transaction }: RowProps) {
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
@@ -29,8 +30,8 @@ export default function Row({ transaction }: RowProps) {
|
|||||||
: `${nightString}`
|
: `${nightString}`
|
||||||
|
|
||||||
switch (transaction.type) {
|
switch (transaction.type) {
|
||||||
case RewardTransactionTypes.stay:
|
case Transactions.rewardType.stay:
|
||||||
case RewardTransactionTypes.stayAdj:
|
case Transactions.rewardType.stayAdj:
|
||||||
if (transaction.hotelId === "ORS") {
|
if (transaction.hotelId === "ORS") {
|
||||||
description = intl.formatMessage({ id: "Former Scandic Hotel" })
|
description = intl.formatMessage({ id: "Former Scandic Hotel" })
|
||||||
}
|
}
|
||||||
@@ -40,19 +41,19 @@ export default function Row({ transaction }: RowProps) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case RewardTransactionTypes.ancillary:
|
case Transactions.rewardType.ancillary:
|
||||||
description = intl.formatMessage({ id: "Extras to your booking" })
|
description = intl.formatMessage({ id: "Extras to your booking" })
|
||||||
break
|
break
|
||||||
case RewardTransactionTypes.enrollment:
|
case Transactions.rewardType.enrollment:
|
||||||
description = intl.formatMessage({ id: "Sign up bonus" })
|
description = intl.formatMessage({ id: "Sign up bonus" })
|
||||||
break
|
break
|
||||||
case RewardTransactionTypes.mastercard_points:
|
case Transactions.rewardType.mastercard_points:
|
||||||
description = intl.formatMessage({ id: "Scandic Friends Mastercard" })
|
description = intl.formatMessage({ id: "Scandic Friends Mastercard" })
|
||||||
break
|
break
|
||||||
case RewardTransactionTypes.tui_points:
|
case Transactions.rewardType.tui_points:
|
||||||
description = intl.formatMessage({ id: "TUI Points" })
|
description = intl.formatMessage({ id: "TUI Points" })
|
||||||
|
|
||||||
case RewardTransactionTypes.pointShop:
|
case Transactions.rewardType.pointShop:
|
||||||
description = intl.formatMessage({ id: "Scandic Friends Point Shop" })
|
description = intl.formatMessage({ id: "Scandic Friends Point Shop" })
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -65,8 +66,8 @@ export default function Row({ transaction }: RowProps) {
|
|||||||
if (
|
if (
|
||||||
!isWebview &&
|
!isWebview &&
|
||||||
transaction.bookingUrl &&
|
transaction.bookingUrl &&
|
||||||
(transaction.type === RewardTransactionTypes.stay ||
|
(transaction.type === Transactions.rewardType.stay ||
|
||||||
transaction.type === RewardTransactionTypes.rewardNight)
|
transaction.type === Transactions.rewardType.rewardNight)
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
<Link variant="underscored" href={transaction.bookingUrl}>
|
<Link variant="underscored" href={transaction.bookingUrl}>
|
||||||
@@ -6,7 +6,7 @@ import JourneyTable from "./JourneyTable"
|
|||||||
|
|
||||||
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 function EarnAndBurn({
|
||||||
link,
|
link,
|
||||||
subtitle,
|
subtitle,
|
||||||
title,
|
title,
|
||||||
@@ -4,11 +4,12 @@ import { useIntl } from "react-intl"
|
|||||||
|
|
||||||
import { dt } from "@/lib/dt"
|
import { dt } from "@/lib/dt"
|
||||||
|
|
||||||
import AwardPoints from "@/components/MyPages/Blocks/Points/EarnAndBurn/AwardPoints"
|
|
||||||
import Table from "@/components/TempDesignSystem/Table"
|
import Table from "@/components/TempDesignSystem/Table"
|
||||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||||
import useLang from "@/hooks/useLang"
|
import useLang from "@/hooks/useLang"
|
||||||
|
|
||||||
|
import AwardPoints from "../../EarnAndBurn/AwardPoints"
|
||||||
|
|
||||||
const tableHeadings = ["Points", "Expiration Date"]
|
const tableHeadings = ["Points", "Expiration Date"]
|
||||||
|
|
||||||
export default function ExpiringPointsTable({
|
export default function ExpiringPointsTable({
|
||||||
@@ -1,18 +1,16 @@
|
|||||||
import {
|
import { MembershipLevelEnum } from "@/constants/membershipLevels"
|
||||||
MembershipLevelEnum,
|
|
||||||
membershipLevels,
|
|
||||||
} from "@/constants/membershipLevels"
|
|
||||||
|
|
||||||
import PointsContainer from "@/components/MyPages/Blocks/Overview/Stats/Points/Container"
|
import { getIntl } from "@/i18n"
|
||||||
|
import { getMembershipLevelObject } from "@/utils/membershipLevel"
|
||||||
|
import { getMembership } from "@/utils/user"
|
||||||
|
|
||||||
|
import PointsContainer from "../../../Overview/Stats/Points/Container"
|
||||||
import {
|
import {
|
||||||
NextLevelNightsColumn,
|
NextLevelNightsColumn,
|
||||||
NextLevelPointsColumn,
|
NextLevelPointsColumn,
|
||||||
StayOnLevelColumn,
|
StayOnLevelColumn,
|
||||||
YourPointsColumn,
|
YourPointsColumn,
|
||||||
} from "@/components/MyPages/Blocks/Overview/Stats/Points/PointsColumn"
|
} from "../../../Overview/Stats/Points/PointsColumn"
|
||||||
import { getIntl } from "@/i18n"
|
|
||||||
import { getMembershipLevelObject } from "@/utils/membershipLevel"
|
|
||||||
import { getMembership } from "@/utils/user"
|
|
||||||
|
|
||||||
import { UserProps } from "@/types/components/myPages/user"
|
import { UserProps } from "@/types/components/myPages/user"
|
||||||
import { LangParams } from "@/types/params"
|
import { LangParams } from "@/types/params"
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { serverClient } from "@/lib/trpc/server"
|
import { getProfile } from "@/lib/trpc/memoizedRequests"
|
||||||
|
|
||||||
import SectionContainer from "@/components/Section/Container"
|
import SectionContainer from "@/components/Section/Container"
|
||||||
import SectionHeader from "@/components/Section/Header"
|
import SectionHeader from "@/components/Section/Header"
|
||||||
@@ -7,6 +7,7 @@ import Divider from "@/components/TempDesignSystem/Divider"
|
|||||||
|
|
||||||
import Friend from "../../Overview/Friend"
|
import Friend from "../../Overview/Friend"
|
||||||
import Hero from "../../Overview/Friend/Hero"
|
import Hero from "../../Overview/Friend/Hero"
|
||||||
|
import MembershipNumber from "../../Overview/Friend/MembershipNumber"
|
||||||
import Stats from "../../Overview/Stats"
|
import Stats from "../../Overview/Stats"
|
||||||
|
|
||||||
import styles from "./overview.module.css"
|
import styles from "./overview.module.css"
|
||||||
@@ -18,7 +19,7 @@ export default async function PointsOverview({
|
|||||||
subtitle,
|
subtitle,
|
||||||
title,
|
title,
|
||||||
}: AccountPageComponentProps) {
|
}: AccountPageComponentProps) {
|
||||||
const user = await serverClient().user.get()
|
const user = await getProfile()
|
||||||
if (!user || "error" in user) {
|
if (!user || "error" in user) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -27,7 +28,9 @@ export default async function PointsOverview({
|
|||||||
<SectionContainer>
|
<SectionContainer>
|
||||||
<SectionHeader link={link} preamble={subtitle} title={title} topTitle />
|
<SectionHeader link={link} preamble={subtitle} title={title} topTitle />
|
||||||
<Hero color="burgundy">
|
<Hero color="burgundy">
|
||||||
<Friend user={user} color="red" />
|
<Friend membership={user.membership} name={user.name}>
|
||||||
|
<MembershipNumber color="red" membership={user.membership} />
|
||||||
|
</Friend>
|
||||||
<Divider className={styles.divider} color="peach" />
|
<Divider className={styles.divider} color="peach" />
|
||||||
<Stats user={user} />
|
<Stats user={user} />
|
||||||
</Hero>
|
</Hero>
|
||||||
46
components/Blocks/DynamicContent/SectionWrapper/index.tsx
Normal file
46
components/Blocks/DynamicContent/SectionWrapper/index.tsx
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import SectionContainer from "@/components/Section/Container"
|
||||||
|
import SectionHeader from "@/components/Section/Header"
|
||||||
|
import SectionLink from "@/components/Section/Link"
|
||||||
|
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
||||||
|
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||||
|
|
||||||
|
import styles from "./sectionWrapper.module.css"
|
||||||
|
|
||||||
|
import type { DynamicContentProps } from "@/types/components/blocks/dynamicContent"
|
||||||
|
import { DynamicContentEnum } from "@/types/enums/dynamicContent"
|
||||||
|
|
||||||
|
export default function SectionWrapper({
|
||||||
|
children,
|
||||||
|
dynamic_content,
|
||||||
|
firstItem,
|
||||||
|
}: React.PropsWithChildren<DynamicContentProps>) {
|
||||||
|
const displayHeader = !!(
|
||||||
|
dynamic_content.link ||
|
||||||
|
dynamic_content.subtitle ||
|
||||||
|
dynamic_content.title
|
||||||
|
)
|
||||||
|
const isOverviewTable =
|
||||||
|
dynamic_content.component ===
|
||||||
|
DynamicContentEnum.Blocks.components.overview_table
|
||||||
|
return (
|
||||||
|
<SectionContainer className={styles.container}>
|
||||||
|
{isOverviewTable ? (
|
||||||
|
<div className={styles.header}>
|
||||||
|
<Title className={styles.tableTitle}> {dynamic_content.title}</Title>
|
||||||
|
<Subtitle>{dynamic_content.subtitle}</Subtitle>
|
||||||
|
</div>
|
||||||
|
) : displayHeader ? (
|
||||||
|
<SectionHeader
|
||||||
|
link={dynamic_content.link}
|
||||||
|
preamble={dynamic_content.subtitle}
|
||||||
|
title={dynamic_content.title}
|
||||||
|
topTitle={firstItem}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
{children}
|
||||||
|
{displayHeader ? (
|
||||||
|
<SectionLink link={dynamic_content.link} variant="mobile" />
|
||||||
|
) : null}
|
||||||
|
</SectionContainer>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -42,7 +42,7 @@ export default function ClientPreviousStays({
|
|||||||
// TS having a hard time with the filtered type.
|
// TS having a hard time with the filtered type.
|
||||||
// This is only temporary as we will not return null
|
// This is only temporary as we will not return null
|
||||||
// later on when we handle errors appropriately.
|
// later on when we handle errors appropriately.
|
||||||
const filteredStays = (data?.pages.filter((page) => page && page.data) ??
|
const filteredStays = (data?.pages.filter((page) => page?.data) ??
|
||||||
[]) as unknown as PreviousStaysNonNullResponseObject[]
|
[]) as unknown as PreviousStaysNonNullResponseObject[]
|
||||||
const stays = filteredStays.flatMap((page) => page.data)
|
const stays = filteredStays.flatMap((page) => page.data)
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user