Merged in fix/sw-3551-rsc-bookingflowconfig (pull request #2988)

fix(SW-3551): Fix issue with BookingConfigProvider in RSC

* wip move config to pages

* Move config providing to pages
This commit is contained in:
Anton Gunnarsson
2025-10-22 07:04:21 +00:00
parent 2a28681259
commit c435cdba68
44 changed files with 398 additions and 237 deletions

View File

@@ -1,6 +1,8 @@
import { BookingWidget } from "@scandic-hotels/booking-flow/BookingWidget" import { BookingWidget } from "@scandic-hotels/booking-flow/BookingWidget"
import { parseBookingWidgetSearchParams } from "@scandic-hotels/booking-flow/utils/url" import { parseBookingWidgetSearchParams } from "@scandic-hotels/booking-flow/utils/url"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import { getLang } from "@/i18n/serverContext" import { getLang } from "@/i18n/serverContext"
import type { LangParams, PageArgs } from "@/types/params" import type { LangParams, PageArgs } from "@/types/params"
@@ -12,5 +14,7 @@ export default async function BookingWidgetPage(props: PageArgs<LangParams>) {
const lang = await getLang() const lang = await getLang()
return <BookingWidget booking={booking} lang={lang} /> return (
<BookingWidget booking={booking} lang={lang} config={bookingFlowConfig} />
)
} }

View File

@@ -1,5 +1,7 @@
import { BookingWidgetSkeleton } from "@scandic-hotels/booking-flow/BookingWidget" import { BookingWidgetSkeleton } from "@scandic-hotels/booking-flow/BookingWidget"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
// This file is crucial for displaying a loading // This file is crucial for displaying a loading
// state immediately in the booking flow. // state immediately in the booking flow.
// Next doesn't recognize manually added Suspense // Next doesn't recognize manually added Suspense
@@ -7,5 +9,5 @@ import { BookingWidgetSkeleton } from "@scandic-hotels/booking-flow/BookingWidge
// thus making it seem as the page is frozen during // thus making it seem as the page is frozen during
// the time it takes for `BookingWidget` to resolve. // the time it takes for `BookingWidget` to resolve.
export default function BookingWidgetLoading() { export default function BookingWidgetLoading() {
return <BookingWidgetSkeleton /> return <BookingWidgetSkeleton config={bookingFlowConfig} />
} }

View File

@@ -2,6 +2,7 @@ import { BookingWidget } from "@scandic-hotels/booking-flow/BookingWidget"
import { parseBookingWidgetSearchParams } from "@scandic-hotels/booking-flow/utils/url" import { parseBookingWidgetSearchParams } from "@scandic-hotels/booking-flow/utils/url"
import { Typography } from "@scandic-hotels/design-system/Typography" import { Typography } from "@scandic-hotels/design-system/Typography"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import { serverClient } from "@/lib/trpc" import { serverClient } from "@/lib/trpc"
import { getIntl } from "@/i18n" import { getIntl } from "@/i18n"
@@ -33,7 +34,7 @@ export default async function Debug(props: SearchParams) {
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<p>from booking-flow package:</p> <p>from booking-flow package:</p>
</Typography> </Typography>
<BookingWidget booking={booking} lang={lang} /> <BookingWidget booking={booking} lang={lang} config={bookingFlowConfig} />
<hr /> <hr />
<Typography variant="Title/Decorative/lg"> <Typography variant="Title/Decorative/lg">
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}

View File

@@ -1,5 +1,7 @@
import { BookingConfirmationPage as BookingConfirmationPagePrimitive } from "@scandic-hotels/booking-flow/pages/BookingConfirmationPage" import { BookingConfirmationPage as BookingConfirmationPagePrimitive } from "@scandic-hotels/booking-flow/pages/BookingConfirmationPage"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import { getIntl } from "@/i18n" import { getIntl } from "@/i18n"
import { getLang } from "@/i18n/serverContext" import { getLang } from "@/i18n/serverContext"
@@ -17,6 +19,7 @@ export default async function BookingConfirmationPage(
intl={intl} intl={intl}
lang={lang} lang={lang}
searchParams={searchParams} searchParams={searchParams}
config={bookingFlowConfig}
/> />
) )
} }

View File

@@ -1,6 +1,8 @@
import { PaymentCallbackPage as PaymentCallbackPagePrimitive } from "@scandic-hotels/booking-flow/pages/PaymentCallbackPage" import { PaymentCallbackPage as PaymentCallbackPagePrimitive } from "@scandic-hotels/booking-flow/pages/PaymentCallbackPage"
import { logger } from "@scandic-hotels/common/logger" import { logger } from "@scandic-hotels/common/logger"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import type { PaymentCallbackStatusEnum } from "@scandic-hotels/common/constants/paymentCallbackStatusEnum" import type { PaymentCallbackStatusEnum } from "@scandic-hotels/common/constants/paymentCallbackStatusEnum"
import type { LangParams, PageArgs } from "@/types/params" import type { LangParams, PageArgs } from "@/types/params"
@@ -26,6 +28,7 @@ export default async function PaymentCallbackPage(
userAccessToken={userAccessToken} userAccessToken={userAccessToken}
searchParams={searchParams} searchParams={searchParams}
status={params.status as PaymentCallbackStatusEnum} status={params.status as PaymentCallbackStatusEnum}
config={bookingFlowConfig}
/> />
) )
} }

View File

@@ -1,5 +1,6 @@
import { AlternativeHotelsMapPage as AlternativeHotelsMapPagePrimitive } from "@scandic-hotels/booking-flow/pages/AlternativeHotelsMapPage" import { AlternativeHotelsMapPage as AlternativeHotelsMapPagePrimitive } from "@scandic-hotels/booking-flow/pages/AlternativeHotelsMapPage"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import { getHotel } from "@/lib/trpc/memoizedRequests/getHotel" import { getHotel } from "@/lib/trpc/memoizedRequests/getHotel"
import { getIntl } from "@/i18n" import { getIntl } from "@/i18n"
@@ -56,6 +57,7 @@ export default async function AlternativeHotelsMapPage(
<AlternativeHotelsMapPagePrimitive <AlternativeHotelsMapPagePrimitive
lang={lang} lang={lang}
searchParams={searchParams} searchParams={searchParams}
config={bookingFlowConfig}
/> />
</div> </div>
) )

View File

@@ -1,5 +1,6 @@
import { AlternativeHotelsPage as AlternativeHotelsPagePrimitive } from "@scandic-hotels/booking-flow/pages/AlternativeHotelsPage" import { AlternativeHotelsPage as AlternativeHotelsPagePrimitive } from "@scandic-hotels/booking-flow/pages/AlternativeHotelsPage"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import { getHotel } from "@/lib/trpc/memoizedRequests/getHotel" import { getHotel } from "@/lib/trpc/memoizedRequests/getHotel"
import { getIntl } from "@/i18n" import { getIntl } from "@/i18n"
@@ -52,6 +53,10 @@ export default async function AlternativeHotelsPage(
const lang = await getLang() const lang = await getLang()
return ( return (
<AlternativeHotelsPagePrimitive lang={lang} searchParams={searchParams} /> <AlternativeHotelsPagePrimitive
lang={lang}
searchParams={searchParams}
config={bookingFlowConfig}
/>
) )
} }

View File

@@ -1,10 +1,18 @@
import { EnterDetailsPage as EnterDetailsPagePrimitive } from "@scandic-hotels/booking-flow/pages/EnterDetailsPage" import { EnterDetailsPage as EnterDetailsPagePrimitive } from "@scandic-hotels/booking-flow/pages/EnterDetailsPage"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import type { LangParams, PageArgs } from "@/types/params" import type { LangParams, PageArgs } from "@/types/params"
export default async function DetailsPage(props: PageArgs<LangParams>) { export default async function DetailsPage(props: PageArgs<LangParams>) {
const { lang } = await props.params const { lang } = await props.params
const searchParams = await props.searchParams const searchParams = await props.searchParams
return <EnterDetailsPagePrimitive lang={lang} searchParams={searchParams} /> return (
<EnterDetailsPagePrimitive
lang={lang}
searchParams={searchParams}
config={bookingFlowConfig}
/>
)
} }

View File

@@ -1,6 +1,8 @@
import { SelectHotelMapPage as SelectHotelMapPagePrimitive } from "@scandic-hotels/booking-flow/pages/SelectHotelMapPage" import { SelectHotelMapPage as SelectHotelMapPagePrimitive } from "@scandic-hotels/booking-flow/pages/SelectHotelMapPage"
import { toCapitalCase } from "@scandic-hotels/common/utils/toCapitalCase" import { toCapitalCase } from "@scandic-hotels/common/utils/toCapitalCase"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import { getLang } from "@/i18n/serverContext" import { getLang } from "@/i18n/serverContext"
import type { Metadata } from "next" import type { Metadata } from "next"
@@ -25,5 +27,11 @@ export default async function SelectHotelMapPage(props: PageArgs<LangParams>) {
const searchParams = await props.searchParams const searchParams = await props.searchParams
const lang = await getLang() const lang = await getLang()
return <SelectHotelMapPagePrimitive lang={lang} searchParams={searchParams} /> return (
<SelectHotelMapPagePrimitive
lang={lang}
searchParams={searchParams}
config={bookingFlowConfig}
/>
)
} }

View File

@@ -1,6 +1,8 @@
import { SelectHotelPage as SelectHotelPagePrimitive } from "@scandic-hotels/booking-flow/pages/SelectHotelPage" import { SelectHotelPage as SelectHotelPagePrimitive } from "@scandic-hotels/booking-flow/pages/SelectHotelPage"
import { toCapitalCase } from "@scandic-hotels/common/utils/toCapitalCase" import { toCapitalCase } from "@scandic-hotels/common/utils/toCapitalCase"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import { getLang } from "@/i18n/serverContext" import { getLang } from "@/i18n/serverContext"
import type { Metadata } from "next" import type { Metadata } from "next"
@@ -25,5 +27,11 @@ export default async function SelectHotelPage(props: PageArgs<LangParams>) {
const searchParams = await props.searchParams const searchParams = await props.searchParams
const lang = await getLang() const lang = await getLang()
return <SelectHotelPagePrimitive lang={lang} searchParams={searchParams} /> return (
<SelectHotelPagePrimitive
lang={lang}
searchParams={searchParams}
config={bookingFlowConfig}
/>
)
} }

View File

@@ -1,5 +1,6 @@
import { SelectRatePage as SelectRatePagePrimitive } from "@scandic-hotels/booking-flow/pages/SelectRatePage" import { SelectRatePage as SelectRatePagePrimitive } from "@scandic-hotels/booking-flow/pages/SelectRatePage"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import { getHotel } from "@/lib/trpc/memoizedRequests/getHotel" import { getHotel } from "@/lib/trpc/memoizedRequests/getHotel"
import { getLang } from "@/i18n/serverContext" import { getLang } from "@/i18n/serverContext"
@@ -38,5 +39,11 @@ export default async function SelectRatePage(props: PageArgs<LangParams>) {
const searchParams = await props.searchParams const searchParams = await props.searchParams
const lang = await getLang() const lang = await getLang()
return <SelectRatePagePrimitive lang={lang} searchParams={searchParams} /> return (
<SelectRatePagePrimitive
lang={lang}
searchParams={searchParams}
config={bookingFlowConfig}
/>
)
} }

View File

@@ -8,13 +8,8 @@ import { ReactQueryDevtools } from "@tanstack/react-query-devtools"
import Script from "next/script" import Script from "next/script"
import { SessionProvider } from "next-auth/react" import { SessionProvider } from "next-auth/react"
import { BookingFlowConfig } from "@scandic-hotels/booking-flow/BookingFlowConfig"
import { NuqsAdapter } from "@scandic-hotels/booking-flow/utils/nuqs" import { NuqsAdapter } from "@scandic-hotels/booking-flow/utils/nuqs"
import { Lang } from "@scandic-hotels/common/constants/language" import { Lang } from "@scandic-hotels/common/constants/language"
import { bookingTermsAndConditionsRoutes } from "@scandic-hotels/common/constants/routes/bookingTermsAndConditionsRoutes"
import { customerService } from "@scandic-hotels/common/constants/routes/customerService"
import { myStay } from "@scandic-hotels/common/constants/routes/myStay"
import { privacyPolicyRoutes } from "@scandic-hotels/common/constants/routes/privacyPolicyRoutes"
import { ToastHandler } from "@scandic-hotels/design-system/ToastHandler" import { ToastHandler } from "@scandic-hotels/design-system/ToastHandler"
import AdobeSDKScript from "@/components/AdobeSDKScript" import AdobeSDKScript from "@/components/AdobeSDKScript"
@@ -34,8 +29,6 @@ import { Footer } from "../../components/Footer/Footer"
import { Header } from "../../components/Header/Header" import { Header } from "../../components/Header/Header"
import { SocialLoginProvider } from "./(auth)/SocialLogin" import { SocialLoginProvider } from "./(auth)/SocialLogin"
import type { LangRoute } from "@scandic-hotels/common/constants/routes/langRoute"
type LangParams = { type LangParams = {
lang: Lang lang: Lang
} }
@@ -55,20 +48,6 @@ export default async function RootLayout(props: RootLayoutProps) {
const parsedLanguage = setLang(lang) const parsedLanguage = setLang(lang)
const messages = await getMessages(parsedLanguage) const messages = await getMessages(parsedLanguage)
const bookingFlowConfig: BookingFlowConfig = {
bookingCodeEnabled: false,
enterDetailsMembershipIdInputLocation: "join-card",
variant: "partner-sas",
routes: {
myStay: routeToScandicWeb(myStay),
bookingTermsAndConditions: routeToScandicWeb(
bookingTermsAndConditionsRoutes
),
customerService: routeToScandicWeb(customerService),
privacyPolicy: routeToScandicWeb(privacyPolicyRoutes),
},
}
return ( return (
<html lang={lang}> <html lang={lang}>
<head> <head>
@@ -93,7 +72,6 @@ export default async function RootLayout(props: RootLayoutProps) {
<TrpcProvider> <TrpcProvider>
<SocialLoginProvider> <SocialLoginProvider>
<RACRouterProvider> <RACRouterProvider>
<BookingFlowConfig config={bookingFlowConfig}>
<BookingFlowProviders> <BookingFlowProviders>
<RouteChange /> <RouteChange />
<SiteWideAlert /> <SiteWideAlert />
@@ -105,7 +83,6 @@ export default async function RootLayout(props: RootLayoutProps) {
<CookieBotConsent /> <CookieBotConsent />
<ReactQueryDevtools initialIsOpen={false} /> <ReactQueryDevtools initialIsOpen={false} />
</BookingFlowProviders> </BookingFlowProviders>
</BookingFlowConfig>
</RACRouterProvider> </RACRouterProvider>
</SocialLoginProvider> </SocialLoginProvider>
</TrpcProvider> </TrpcProvider>
@@ -127,11 +104,3 @@ export default async function RootLayout(props: RootLayoutProps) {
</html> </html>
) )
} }
function routeToScandicWeb(route: LangRoute) {
const url = `https://www.scandichotels.com`
return Object.entries(route).reduce((acc, [key, value]) => {
acc[key as Lang] = `${url}${value}`
return acc
}, {} as LangRoute)
}

View File

@@ -3,6 +3,8 @@ import { parseBookingWidgetSearchParams } from "@scandic-hotels/booking-flow/uti
import Image from "@scandic-hotels/design-system/Image" import Image from "@scandic-hotels/design-system/Image"
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK" import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import { getLang } from "@/i18n/serverContext" import { getLang } from "@/i18n/serverContext"
import LandingPageHeroImage from "@/public/_static/img/landing-page-hero.png" import LandingPageHeroImage from "@/public/_static/img/landing-page-hero.png"
@@ -30,7 +32,11 @@ export default async function Home(props: PageArgs<LangParams>) {
<> <>
<section className={styles.mainContent}> <section className={styles.mainContent}>
<div className={styles.bookingWidgetWrapper}> <div className={styles.bookingWidgetWrapper}>
<FloatingBookingWidget booking={booking} lang={lang} /> <FloatingBookingWidget
booking={booking}
lang={lang}
config={bookingFlowConfig}
/>
</div> </div>
<Image <Image
alt="Hero Image" alt="Hero Image"

View File

@@ -0,0 +1,30 @@
import { bookingTermsAndConditionsRoutes } from "@scandic-hotels/common/constants/routes/bookingTermsAndConditionsRoutes"
import { customerService } from "@scandic-hotels/common/constants/routes/customerService"
import { myStay } from "@scandic-hotels/common/constants/routes/myStay"
import { privacyPolicyRoutes } from "@scandic-hotels/common/constants/routes/privacyPolicyRoutes"
import type { BookingFlowConfig } from "@scandic-hotels/booking-flow/BookingFlowConfig"
import type { Lang } from "@scandic-hotels/common/constants/language"
import type { LangRoute } from "@scandic-hotels/common/constants/routes/langRoute"
export const bookingFlowConfig: BookingFlowConfig = {
bookingCodeEnabled: false,
enterDetailsMembershipIdInputLocation: "join-card",
variant: "partner-sas",
routes: {
myStay: routeToScandicWeb(myStay),
bookingTermsAndConditions: routeToScandicWeb(
bookingTermsAndConditionsRoutes
),
customerService: routeToScandicWeb(customerService),
privacyPolicy: routeToScandicWeb(privacyPolicyRoutes),
},
}
function routeToScandicWeb(route: LangRoute) {
const url = `https://www.scandichotels.com`
return Object.entries(route).reduce((acc, [key, value]) => {
acc[key as Lang] = `${url}${value}`
return acc
}, {} as LangRoute)
}

View File

@@ -1,5 +1,7 @@
import { BookingConfirmationPage as BookingConfirmationPagePrimitive } from "@scandic-hotels/booking-flow/pages/BookingConfirmationPage" import { BookingConfirmationPage as BookingConfirmationPagePrimitive } from "@scandic-hotels/booking-flow/pages/BookingConfirmationPage"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import { getIntl } from "@/i18n" import { getIntl } from "@/i18n"
import { getLang } from "@/i18n/serverContext" import { getLang } from "@/i18n/serverContext"
@@ -17,6 +19,7 @@ export default async function BookingConfirmationPage(
intl={intl} intl={intl}
lang={lang} lang={lang}
searchParams={searchParams} searchParams={searchParams}
config={bookingFlowConfig}
/> />
) )
} }

View File

@@ -2,6 +2,8 @@ import { PaymentCallbackPage as PaymentCallbackPagePrimitive } from "@scandic-ho
import { logger } from "@scandic-hotels/common/logger" import { logger } from "@scandic-hotels/common/logger"
import { isValidSession } from "@scandic-hotels/trpc/utils/session" import { isValidSession } from "@scandic-hotels/trpc/utils/session"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import { auth } from "@/auth" import { auth } from "@/auth"
import type { PaymentCallbackStatusEnum } from "@scandic-hotels/common/constants/paymentCallbackStatusEnum" import type { PaymentCallbackStatusEnum } from "@scandic-hotels/common/constants/paymentCallbackStatusEnum"
@@ -35,6 +37,7 @@ export default async function PaymentCallbackPage(
searchParams={searchParams} searchParams={searchParams}
// TODO refactor this route to get this from params instead of rewriting in next.config // TODO refactor this route to get this from params instead of rewriting in next.config
status={searchParams.status as PaymentCallbackStatusEnum} status={searchParams.status as PaymentCallbackStatusEnum}
config={bookingFlowConfig}
/> />
) )
} }

View File

@@ -1,5 +1,6 @@
import { AlternativeHotelsMapPage as AlternativeHotelsMapPagePrimitive } from "@scandic-hotels/booking-flow/pages/AlternativeHotelsMapPage" import { AlternativeHotelsMapPage as AlternativeHotelsMapPagePrimitive } from "@scandic-hotels/booking-flow/pages/AlternativeHotelsMapPage"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import { getHotel } from "@/lib/trpc/memoizedRequests" import { getHotel } from "@/lib/trpc/memoizedRequests"
import { getIntl } from "@/i18n" import { getIntl } from "@/i18n"
@@ -58,6 +59,7 @@ export default async function AlternativeHotelsMapPage(
<AlternativeHotelsMapPagePrimitive <AlternativeHotelsMapPagePrimitive
lang={lang} lang={lang}
searchParams={searchParams} searchParams={searchParams}
config={bookingFlowConfig}
/> />
</div> </div>
) )

View File

@@ -1,5 +1,6 @@
import { AlternativeHotelsPage as AlternativeHotelsPagePrimitive } from "@scandic-hotels/booking-flow/pages/AlternativeHotelsPage" import { AlternativeHotelsPage as AlternativeHotelsPagePrimitive } from "@scandic-hotels/booking-flow/pages/AlternativeHotelsPage"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import { getHotel } from "@/lib/trpc/memoizedRequests" import { getHotel } from "@/lib/trpc/memoizedRequests"
import { getIntl } from "@/i18n" import { getIntl } from "@/i18n"
@@ -55,6 +56,10 @@ export default async function AlternativeHotelsPage(
const searchParams = await props.searchParams const searchParams = await props.searchParams
const lang = await getLang() const lang = await getLang()
return ( return (
<AlternativeHotelsPagePrimitive lang={lang} searchParams={searchParams} /> <AlternativeHotelsPagePrimitive
lang={lang}
searchParams={searchParams}
config={bookingFlowConfig}
/>
) )
} }

View File

@@ -1,5 +1,7 @@
import { EnterDetailsPage as EnterDetailsPagePrimitive } from "@scandic-hotels/booking-flow/pages/EnterDetailsPage" import { EnterDetailsPage as EnterDetailsPagePrimitive } from "@scandic-hotels/booking-flow/pages/EnterDetailsPage"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import type { LangParams, NextSearchParams, PageArgs } from "@/types/params" import type { LangParams, NextSearchParams, PageArgs } from "@/types/params"
export default async function DetailsPage( export default async function DetailsPage(
@@ -8,5 +10,11 @@ export default async function DetailsPage(
const { lang } = await props.params const { lang } = await props.params
const searchParams = await props.searchParams const searchParams = await props.searchParams
return <EnterDetailsPagePrimitive lang={lang} searchParams={searchParams} /> return (
<EnterDetailsPagePrimitive
lang={lang}
searchParams={searchParams}
config={bookingFlowConfig}
/>
)
} }

View File

@@ -1,6 +1,8 @@
import { SelectHotelMapPage as SelectHotelMapPagePrimitive } from "@scandic-hotels/booking-flow/pages/SelectHotelMapPage" import { SelectHotelMapPage as SelectHotelMapPagePrimitive } from "@scandic-hotels/booking-flow/pages/SelectHotelMapPage"
import { toCapitalCase } from "@scandic-hotels/common/utils/toCapitalCase" import { toCapitalCase } from "@scandic-hotels/common/utils/toCapitalCase"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import { getLang } from "@/i18n/serverContext" import { getLang } from "@/i18n/serverContext"
import styles from "./page.module.css" import styles from "./page.module.css"
@@ -27,7 +29,11 @@ export default async function SelectHotelMapPage(
return ( return (
<div className={styles.main}> <div className={styles.main}>
<SelectHotelMapPagePrimitive lang={lang} searchParams={searchParams} /> <SelectHotelMapPagePrimitive
lang={lang}
searchParams={searchParams}
config={bookingFlowConfig}
/>
</div> </div>
) )
} }

View File

@@ -1,6 +1,8 @@
import { SelectHotelPage as SelectHotelPagePrimitive } from "@scandic-hotels/booking-flow/pages/SelectHotelPage" import { SelectHotelPage as SelectHotelPagePrimitive } from "@scandic-hotels/booking-flow/pages/SelectHotelPage"
import { toCapitalCase } from "@scandic-hotels/common/utils/toCapitalCase" import { toCapitalCase } from "@scandic-hotels/common/utils/toCapitalCase"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import { getLang } from "@/i18n/serverContext" import { getLang } from "@/i18n/serverContext"
import type { Metadata } from "next" import type { Metadata } from "next"
@@ -23,5 +25,11 @@ export default async function SelectHotelPage(
const searchParams = await props.searchParams const searchParams = await props.searchParams
const lang = await getLang() const lang = await getLang()
return <SelectHotelPagePrimitive lang={lang} searchParams={searchParams} /> return (
<SelectHotelPagePrimitive
lang={lang}
searchParams={searchParams}
config={bookingFlowConfig}
/>
)
} }

View File

@@ -1,5 +1,6 @@
import { SelectRatePage as SelectRatePagePrimitive } from "@scandic-hotels/booking-flow/pages/SelectRatePage" import { SelectRatePage as SelectRatePagePrimitive } from "@scandic-hotels/booking-flow/pages/SelectRatePage"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import { getHotel } from "@/lib/trpc/memoizedRequests" import { getHotel } from "@/lib/trpc/memoizedRequests"
import { getLang } from "@/i18n/serverContext" import { getLang } from "@/i18n/serverContext"
@@ -40,5 +41,11 @@ export default async function SelectRatePage(
const searchParams = await props.searchParams const searchParams = await props.searchParams
const lang = await getLang() const lang = await getLang()
return <SelectRatePagePrimitive lang={lang} searchParams={searchParams} /> return (
<SelectRatePagePrimitive
lang={lang}
searchParams={searchParams}
config={bookingFlowConfig}
/>
)
} }

View File

@@ -1,6 +1,7 @@
import { BookingWidget } from "@scandic-hotels/booking-flow/BookingWidget" import { BookingWidget } from "@scandic-hotels/booking-flow/BookingWidget"
import { parseBookingWidgetSearchParams } from "@scandic-hotels/booking-flow/utils/url" import { parseBookingWidgetSearchParams } from "@scandic-hotels/booking-flow/utils/url"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import { getDestinationCityPage } from "@/lib/trpc/memoizedRequests" import { getDestinationCityPage } from "@/lib/trpc/memoizedRequests"
import { getLang } from "@/i18n/serverContext" import { getLang } from "@/i18n/serverContext"
@@ -24,5 +25,7 @@ export default async function BookingWidgetDestinationCityPage(
const lang = await getLang() const lang = await getLang()
return <BookingWidget booking={booking} lang={lang} /> return (
<BookingWidget booking={booking} lang={lang} config={bookingFlowConfig} />
)
} }

View File

@@ -1,6 +1,7 @@
import { BookingWidget } from "@scandic-hotels/booking-flow/BookingWidget" import { BookingWidget } from "@scandic-hotels/booking-flow/BookingWidget"
import { parseBookingWidgetSearchParams } from "@scandic-hotels/booking-flow/utils/url" import { parseBookingWidgetSearchParams } from "@scandic-hotels/booking-flow/utils/url"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import { getHotel, getHotelPage } from "@/lib/trpc/memoizedRequests" import { getHotel, getHotelPage } from "@/lib/trpc/memoizedRequests"
import { getLang } from "@/i18n/serverContext" import { getLang } from "@/i18n/serverContext"
@@ -36,5 +37,7 @@ export default async function BookingWidgetHotelPage(
const booking = parseBookingWidgetSearchParams(bookingWidgetSearchParams) const booking = parseBookingWidgetSearchParams(bookingWidgetSearchParams)
return <BookingWidget booking={booking} lang={lang} /> return (
<BookingWidget booking={booking} lang={lang} config={bookingFlowConfig} />
)
} }

View File

@@ -1,5 +1,7 @@
import { BookingWidgetSkeleton } from "@scandic-hotels/booking-flow/BookingWidget" import { BookingWidgetSkeleton } from "@scandic-hotels/booking-flow/BookingWidget"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
// This file is crucial for displaying a loading // This file is crucial for displaying a loading
// state immediately in the booking flow. // state immediately in the booking flow.
// Next doesn't recognize manually added Suspense // Next doesn't recognize manually added Suspense
@@ -7,5 +9,5 @@ import { BookingWidgetSkeleton } from "@scandic-hotels/booking-flow/BookingWidge
// thus making it seem as the page is frozen during // thus making it seem as the page is frozen during
// the time it takes for `BookingWidget` to resolve. // the time it takes for `BookingWidget` to resolve.
export default function BookingWidgetLoading() { export default function BookingWidgetLoading() {
return <BookingWidgetSkeleton /> return <BookingWidgetSkeleton config={bookingFlowConfig} />
} }

View File

@@ -1,6 +1,8 @@
import { BookingWidget } from "@scandic-hotels/booking-flow/BookingWidget" import { BookingWidget } from "@scandic-hotels/booking-flow/BookingWidget"
import { parseBookingWidgetSearchParams } from "@scandic-hotels/booking-flow/utils/url" import { parseBookingWidgetSearchParams } from "@scandic-hotels/booking-flow/utils/url"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import { getLang } from "@/i18n/serverContext" import { getLang } from "@/i18n/serverContext"
import type { LangParams, NextSearchParams, PageArgs } from "@/types/params" import type { LangParams, NextSearchParams, PageArgs } from "@/types/params"
@@ -14,5 +16,7 @@ export default async function BookingWidgetPage(
const lang = await getLang() const lang = await getLang()
return <BookingWidget booking={booking} lang={lang} /> return (
<BookingWidget booking={booking} lang={lang} config={bookingFlowConfig} />
)
} }

View File

@@ -1,6 +1,8 @@
import { BookingWidget } from "@scandic-hotels/booking-flow/BookingWidget" import { BookingWidget } from "@scandic-hotels/booking-flow/BookingWidget"
import { parseBookingWidgetSearchParams } from "@scandic-hotels/booking-flow/utils/url" import { parseBookingWidgetSearchParams } from "@scandic-hotels/booking-flow/utils/url"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import { getLang } from "@/i18n/serverContext" import { getLang } from "@/i18n/serverContext"
import type { LangParams, NextSearchParams, PageArgs } from "@/types/params" import type { LangParams, NextSearchParams, PageArgs } from "@/types/params"
@@ -14,5 +16,7 @@ export default async function BookingWidgetPage(
const lang = await getLang() const lang = await getLang()
return <BookingWidget booking={booking} lang={lang} /> return (
<BookingWidget booking={booking} lang={lang} config={bookingFlowConfig} />
)
} }

View File

@@ -9,13 +9,11 @@ import { ReactQueryDevtools } from "@tanstack/react-query-devtools"
import Script from "next/script" import Script from "next/script"
import { SessionProvider } from "next-auth/react" import { SessionProvider } from "next-auth/react"
import { BookingFlowConfig } from "@scandic-hotels/booking-flow/BookingFlowConfig"
import StorageCleaner from "@scandic-hotels/booking-flow/components/EnterDetails/StorageCleaner" import StorageCleaner from "@scandic-hotels/booking-flow/components/EnterDetails/StorageCleaner"
import { NuqsAdapter } from "@scandic-hotels/booking-flow/utils/nuqs" import { NuqsAdapter } from "@scandic-hotels/booking-flow/utils/nuqs"
import { Lang } from "@scandic-hotels/common/constants/language" import { Lang } from "@scandic-hotels/common/constants/language"
import { ToastHandler } from "@scandic-hotels/design-system/ToastHandler" import { ToastHandler } from "@scandic-hotels/design-system/ToastHandler"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import TrpcProvider from "@/lib/trpc/Provider" import TrpcProvider from "@/lib/trpc/Provider"
import { SessionRefresher } from "@/components/Auth/TokenRefresher" import { SessionRefresher } from "@/components/Auth/TokenRefresher"
@@ -75,7 +73,6 @@ export default async function RootLayout(
<NuqsAdapter> <NuqsAdapter>
<TrpcProvider> <TrpcProvider>
<RACRouterProvider> <RACRouterProvider>
<BookingFlowConfig config={bookingFlowConfig}>
<BookingFlowProviders> <BookingFlowProviders>
<RouteChange /> <RouteChange />
<SitewideAlert /> <SitewideAlert />
@@ -90,7 +87,6 @@ export default async function RootLayout(
<UserExists /> <UserExists />
<ReactQueryDevtools initialIsOpen={false} /> <ReactQueryDevtools initialIsOpen={false} />
</BookingFlowProviders> </BookingFlowProviders>
</BookingFlowConfig>
</RACRouterProvider> </RACRouterProvider>
</TrpcProvider> </TrpcProvider>
</NuqsAdapter> </NuqsAdapter>

View File

@@ -9,13 +9,11 @@ import { ReactQueryDevtools } from "@tanstack/react-query-devtools"
import Script from "next/script" import Script from "next/script"
import { SessionProvider } from "next-auth/react" import { SessionProvider } from "next-auth/react"
import { BookingFlowConfig } from "@scandic-hotels/booking-flow/BookingFlowConfig"
import StorageCleaner from "@scandic-hotels/booking-flow/components/EnterDetails/StorageCleaner" import StorageCleaner from "@scandic-hotels/booking-flow/components/EnterDetails/StorageCleaner"
import { NuqsAdapter } from "@scandic-hotels/booking-flow/utils/nuqs" import { NuqsAdapter } from "@scandic-hotels/booking-flow/utils/nuqs"
import { Lang } from "@scandic-hotels/common/constants/language" import { Lang } from "@scandic-hotels/common/constants/language"
import { ToastHandler } from "@scandic-hotels/design-system/ToastHandler" import { ToastHandler } from "@scandic-hotels/design-system/ToastHandler"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import TrpcProvider from "@/lib/trpc/Provider" import TrpcProvider from "@/lib/trpc/Provider"
import { SessionRefresher } from "@/components/Auth/TokenRefresher" import { SessionRefresher } from "@/components/Auth/TokenRefresher"
@@ -59,7 +57,6 @@ export default async function RootLayout(
> >
<NuqsAdapter> <NuqsAdapter>
<TrpcProvider> <TrpcProvider>
<BookingFlowConfig config={bookingFlowConfig}>
<RouteChange /> <RouteChange />
{children} {children}
<ToastHandler /> <ToastHandler />
@@ -67,7 +64,6 @@ export default async function RootLayout(
<StorageCleaner /> <StorageCleaner />
<CookieBotConsent /> <CookieBotConsent />
<ReactQueryDevtools initialIsOpen={false} /> <ReactQueryDevtools initialIsOpen={false} />
</BookingFlowConfig>
</TrpcProvider> </TrpcProvider>
</NuqsAdapter> </NuqsAdapter>
</ClientIntlProvider> </ClientIntlProvider>

View File

@@ -8,13 +8,11 @@ import "@scandic-hotels/common/polyfills"
import { ReactQueryDevtools } from "@tanstack/react-query-devtools" import { ReactQueryDevtools } from "@tanstack/react-query-devtools"
import Script from "next/script" import Script from "next/script"
import { BookingFlowConfig } from "@scandic-hotels/booking-flow/BookingFlowConfig"
import StorageCleaner from "@scandic-hotels/booking-flow/components/EnterDetails/StorageCleaner" import StorageCleaner from "@scandic-hotels/booking-flow/components/EnterDetails/StorageCleaner"
import { NuqsAdapter } from "@scandic-hotels/booking-flow/utils/nuqs" import { NuqsAdapter } from "@scandic-hotels/booking-flow/utils/nuqs"
import { Lang } from "@scandic-hotels/common/constants/language" import { Lang } from "@scandic-hotels/common/constants/language"
import { ToastHandler } from "@scandic-hotels/design-system/ToastHandler" import { ToastHandler } from "@scandic-hotels/design-system/ToastHandler"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import TrpcProvider from "@/lib/trpc/Provider" import TrpcProvider from "@/lib/trpc/Provider"
import TokenRefresher from "@/components/Auth/TokenRefresher" import TokenRefresher from "@/components/Auth/TokenRefresher"
@@ -59,7 +57,6 @@ export default async function RootLayout(
> >
<NuqsAdapter> <NuqsAdapter>
<TrpcProvider> <TrpcProvider>
<BookingFlowConfig config={bookingFlowConfig}>
<RouteChange /> <RouteChange />
{children} {children}
<ToastHandler /> <ToastHandler />
@@ -67,7 +64,6 @@ export default async function RootLayout(
<StorageCleaner /> <StorageCleaner />
<CookieBotConsent /> <CookieBotConsent />
<ReactQueryDevtools initialIsOpen={false} /> <ReactQueryDevtools initialIsOpen={false} />
</BookingFlowConfig>
</TrpcProvider> </TrpcProvider>
</NuqsAdapter> </NuqsAdapter>
</ClientIntlProvider> </ClientIntlProvider>

View File

@@ -4,6 +4,7 @@ import { Typography } from "@scandic-hotels/design-system/Typography"
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK" import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
import { BlocksEnums } from "@scandic-hotels/trpc/types/blocksEnum" import { BlocksEnums } from "@scandic-hotels/trpc/types/blocksEnum"
import { bookingFlowConfig } from "@/constants/bookingFlowConfig"
import { getStartPage } from "@/lib/trpc/memoizedRequests" import { getStartPage } from "@/lib/trpc/memoizedRequests"
import Blocks from "@/components/Blocks" import Blocks from "@/components/Blocks"
@@ -36,7 +37,11 @@ export default async function StartPage({
<h1>{header.heading}</h1> <h1>{header.heading}</h1>
</Typography> </Typography>
) : null} ) : null}
<FloatingBookingWidget booking={booking} lang={lang} /> <FloatingBookingWidget
booking={booking}
lang={lang}
config={bookingFlowConfig}
/>
</div> </div>
{header.hero_image ? ( {header.hero_image ? (
<Image <Image

View File

@@ -54,7 +54,7 @@ export default function BookingWidgetClient({
const [originalOverflowY, setOriginalOverflowY] = useState<string | null>( const [originalOverflowY, setOriginalOverflowY] = useState<string | null>(
null null
) )
const { bookingCodeEnabled } = useBookingFlowConfig() const bookingFlowConfig = useBookingFlowConfig()
const storedBookingWidgetState = useBookingWidgetState() const storedBookingWidgetState = useBookingWidgetState()
const shouldFetchAutoComplete = !!data.hotelId || !!data.city const shouldFetchAutoComplete = !!data.hotelId || !!data.city
@@ -128,7 +128,7 @@ export default function BookingWidgetClient({
toDate: toDate.format("YYYY-MM-DD"), toDate: toDate.format("YYYY-MM-DD"),
}, },
bookingCode: { bookingCode: {
value: bookingCodeEnabled ? selectedBookingCode : "", value: bookingFlowConfig.bookingCodeEnabled ? selectedBookingCode : "",
remember: false, remember: false,
}, },
redemption: data.searchType === SEARCH_TYPE_REDEMPTION, redemption: data.searchType === SEARCH_TYPE_REDEMPTION,
@@ -228,7 +228,7 @@ export default function BookingWidgetClient({
}, [data, methods, storedBookingWidgetState]) }, [data, methods, storedBookingWidgetState])
if (shouldShowSkeleton) { if (shouldShowSkeleton) {
return <BookingWidgetSkeleton type={type} /> return <BookingWidgetSkeleton type={type} config={bookingFlowConfig} />
} }
const classNames = bookingWidgetContainerVariants({ const classNames = bookingWidgetContainerVariants({

View File

@@ -1,3 +1,4 @@
import { BookingFlowConfig } from "../../../bookingFlowConfig/bookingFlowConfig"
import { import {
getPageSettingsBookingCode, getPageSettingsBookingCode,
isBookingWidgetHidden, isBookingWidgetHidden,
@@ -9,6 +10,7 @@ import type { BookingWidgetProps } from ".."
export async function FloatingBookingWidget({ export async function FloatingBookingWidget({
booking, booking,
lang, lang,
config,
}: Omit<BookingWidgetProps, "type">) { }: Omit<BookingWidgetProps, "type">) {
const isHidden = await isBookingWidgetHidden(lang) const isHidden = await isBookingWidgetHidden(lang)
@@ -22,9 +24,11 @@ export async function FloatingBookingWidget({
} }
return ( return (
<BookingFlowConfig config={config}>
<FloatingBookingWidgetClient <FloatingBookingWidgetClient
data={booking} data={booking}
pageSettingsBookingCodePromise={pageSettingsBookingCodePromise} pageSettingsBookingCodePromise={pageSettingsBookingCodePromise}
/> />
</BookingFlowConfig>
) )
} }

View File

@@ -1,30 +1,34 @@
"use client" "use client"
import { BookingFlowConfigContextProvider } from "../../bookingFlowConfig/bookingFlowConfigContext"
import { BookingWidgetFormSkeleton } from "./BookingWidgetForm" import { BookingWidgetFormSkeleton } from "./BookingWidgetForm"
import { MobileToggleButtonSkeleton } from "./MobileToggleButton" import { MobileToggleButtonSkeleton } from "./MobileToggleButton"
import { bookingWidgetContainerVariants } from "./variant" import { bookingWidgetContainerVariants } from "./variant"
import styles from "./bookingWidget.module.css" import styles from "./bookingWidget.module.css"
import type { BookingFlowConfig } from "../../bookingFlowConfig/bookingFlowConfig"
import type { BookingWidgetClientProps } from "./Client" import type { BookingWidgetClientProps } from "./Client"
export function BookingWidgetSkeleton({ export function BookingWidgetSkeleton({
type = "full", type = "full",
config,
}: { }: {
type?: BookingWidgetClientProps["type"] type?: BookingWidgetClientProps["type"]
config: BookingFlowConfig
}) { }) {
const classNames = bookingWidgetContainerVariants({ const classNames = bookingWidgetContainerVariants({
type, type,
}) })
return ( return (
<> <BookingFlowConfigContextProvider config={config}>
<section className={classNames} style={{ top: 0 }}> <section className={classNames} style={{ top: 0 }}>
<MobileToggleButtonSkeleton /> <MobileToggleButtonSkeleton />
<div className={styles.formContainer}> <div className={styles.formContainer}>
<BookingWidgetFormSkeleton type={type} /> <BookingWidgetFormSkeleton type={type} />
</div> </div>
</section> </section>
</> </BookingFlowConfigContextProvider>
) )
} }

View File

@@ -1,5 +1,6 @@
import { Suspense } from "react" import { Suspense } from "react"
import { BookingFlowConfig } from "../../bookingFlowConfig/bookingFlowConfig"
import { import {
getPageSettingsBookingCode, getPageSettingsBookingCode,
isBookingWidgetHidden, isBookingWidgetHidden,
@@ -39,13 +40,16 @@ export type BookingWidgetProps = {
type?: BookingWidgetType type?: BookingWidgetType
booking: BookingWidgetSearchData booking: BookingWidgetSearchData
lang: Lang lang: Lang
config: BookingFlowConfig
} }
export async function BookingWidget(props: BookingWidgetProps) { export async function BookingWidget({ config, ...props }: BookingWidgetProps) {
return ( return (
<Suspense fallback={<BookingWidgetSkeleton />}> <BookingFlowConfig config={config}>
<Suspense fallback={<BookingWidgetSkeleton config={config} />}>
<InternalBookingWidget {...props} /> <InternalBookingWidget {...props} />
</Suspense> </Suspense>
</BookingFlowConfig>
) )
} }
@@ -53,7 +57,7 @@ async function InternalBookingWidget({
lang, lang,
type, type,
booking, booking,
}: BookingWidgetProps) { }: Omit<BookingWidgetProps, "config">) {
const isHidden = await isBookingWidgetHidden(lang) const isHidden = await isBookingWidgetHidden(lang)
if (isHidden) { if (isHidden) {

View File

@@ -5,7 +5,7 @@ import { safeTry } from "@scandic-hotels/common/utils/safeTry"
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK" import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
import { env } from "../../env/server" import { env } from "../../env/server"
import { getBookingFlowConfig } from "../bookingFlowConfig/bookingFlowConfig" import { BookingFlowConfig } from "../bookingFlowConfig/bookingFlowConfig"
import { MapContainer } from "../components/MapContainer" import { MapContainer } from "../components/MapContainer"
import { import {
getFiltersFromHotels, getFiltersFromHotels,
@@ -27,9 +27,11 @@ import type { NextSearchParams } from "../types"
export async function AlternativeHotelsMapPage({ export async function AlternativeHotelsMapPage({
lang, lang,
searchParams, searchParams,
config,
}: { }: {
lang: Lang lang: Lang
searchParams: NextSearchParams searchParams: NextSearchParams
config: BookingFlowConfig
}) { }) {
const googleMapId = env.GOOGLE_DYNAMIC_MAP_ID const googleMapId = env.GOOGLE_DYNAMIC_MAP_ID
const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY
@@ -103,12 +105,13 @@ export async function AlternativeHotelsMapPage({
isBookingCodeRateAvailable, isBookingCodeRateAvailable,
isRedemption: redemption, isRedemption: redemption,
isRedemptionAvailable: isRedemptionAvailability, isRedemptionAvailable: isRedemptionAvailability,
config: getBookingFlowConfig(), config,
}) })
const filterList = getFiltersFromHotels(hotels, isBookingCodeRateAvailable) const filterList = getFiltersFromHotels(hotels, isBookingCodeRateAvailable)
return ( return (
<BookingFlowConfig config={config}>
<MapContainer> <MapContainer>
<Suspense key={booking.hotelId} fallback={<SelectHotelMapSkeleton />}> <Suspense key={booking.hotelId} fallback={<SelectHotelMapSkeleton />}>
<SelectHotelMap <SelectHotelMap
@@ -127,5 +130,6 @@ export async function AlternativeHotelsMapPage({
/> />
</Suspense> </Suspense>
</MapContainer> </MapContainer>
</BookingFlowConfig>
) )
} }

View File

@@ -7,7 +7,7 @@ import { FamilyAndFriendsCodes } from "@scandic-hotels/common/constants/familyAn
import { NoAvailabilityTracking } from "@scandic-hotels/tracking/NoAvailabilityTracking" import { NoAvailabilityTracking } from "@scandic-hotels/tracking/NoAvailabilityTracking"
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK" import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
import { getBookingFlowConfig } from "../bookingFlowConfig/bookingFlowConfig" import { BookingFlowConfig } from "../bookingFlowConfig/bookingFlowConfig"
import { AlternativeHotelsPageTitle } from "../components/AlternativeHotelsPageTitle" import { AlternativeHotelsPageTitle } from "../components/AlternativeHotelsPageTitle"
import FnFNotAllowedAlert from "../components/FnFNotAllowedAlert" import FnFNotAllowedAlert from "../components/FnFNotAllowedAlert"
import { SelectHotel } from "../components/SelectHotel" import { SelectHotel } from "../components/SelectHotel"
@@ -25,9 +25,11 @@ export { SelectHotelSkeleton as AlternativeHotelsPageSkeleton } from "../compone
export async function AlternativeHotelsPage({ export async function AlternativeHotelsPage({
lang, lang,
searchParams, searchParams,
config,
}: { }: {
lang: Lang lang: Lang
searchParams: NextSearchParams searchParams: NextSearchParams
config: BookingFlowConfig
}) { }) {
const booking = parseSelectHotelSearchParams(searchParams) const booking = parseSelectHotelSearchParams(searchParams)
@@ -108,7 +110,7 @@ export async function AlternativeHotelsPage({
isBookingCodeRateAvailable, isBookingCodeRateAvailable,
isRedemption: searchDetails.redemption, isRedemption: searchDetails.redemption,
isRedemptionAvailable: isRedemptionAvailability, isRedemptionAvailable: isRedemptionAvailability,
config: getBookingFlowConfig(), config,
}) })
const suspenseKey = stringify(searchParams) const suspenseKey = stringify(searchParams)
@@ -118,7 +120,7 @@ export async function AlternativeHotelsPage({
(booking.bookingCode && hotels.length > 0 && !isBookingCodeRateAvailable) (booking.bookingCode && hotels.length > 0 && !isBookingCodeRateAvailable)
) )
return ( return (
<> <BookingFlowConfig config={config}>
<SelectHotel <SelectHotel
bookingCode={booking.bookingCode} bookingCode={booking.bookingCode}
city={searchDetails.city} city={searchDetails.city}
@@ -142,6 +144,6 @@ export async function AlternativeHotelsPage({
shouldTrackNoAvailability={shouldTrackNoAvailability} shouldTrackNoAvailability={shouldTrackNoAvailability}
/> />
</Suspense> </Suspense>
</> </BookingFlowConfig>
) )
} }

View File

@@ -3,6 +3,7 @@ import { notFound, redirect } from "next/navigation"
import { decrypt } from "@scandic-hotels/trpc/utils/encryption" import { decrypt } from "@scandic-hotels/trpc/utils/encryption"
import { BookingFlowConfig } from "../bookingFlowConfig/bookingFlowConfig"
import { BookingConfirmation } from "../components/BookingConfirmation" import { BookingConfirmation } from "../components/BookingConfirmation"
import { getBookingConfirmation } from "../trpc/memoizedRequests/getBookingConfirmation" import { getBookingConfirmation } from "../trpc/memoizedRequests/getBookingConfirmation"
import { MEMBERSHIP_FAILED_ERROR } from "../types/membershipFailedError" import { MEMBERSHIP_FAILED_ERROR } from "../types/membershipFailedError"
@@ -16,10 +17,12 @@ export async function BookingConfirmationPage({
intl, intl,
lang, lang,
searchParams, searchParams,
config,
}: { }: {
intl: IntlShape intl: IntlShape
lang: Lang lang: Lang
searchParams: NextSearchParams searchParams: NextSearchParams
config: BookingFlowConfig
}) { }) {
const refId = searchParams.RefId?.toString() const refId = searchParams.RefId?.toString()
@@ -46,10 +49,12 @@ export async function BookingConfirmationPage({
searchParams.errorCode === MEMBERSHIP_FAILED_ERROR searchParams.errorCode === MEMBERSHIP_FAILED_ERROR
return ( return (
<BookingFlowConfig config={config}>
<BookingConfirmation <BookingConfirmation
intl={intl} intl={intl}
refId={refId} refId={refId}
membershipFailedError={membershipFailedError} membershipFailedError={membershipFailedError}
/> />
</BookingFlowConfig>
) )
} }

View File

@@ -4,6 +4,7 @@ import { Suspense } from "react"
import { FamilyAndFriendsCodes } from "@scandic-hotels/common/constants/familyAndFriends" import { FamilyAndFriendsCodes } from "@scandic-hotels/common/constants/familyAndFriends"
import { BookingFlowConfig } from "../bookingFlowConfig/bookingFlowConfig"
import HotelHeader from "../components/EnterDetails/Header" import HotelHeader from "../components/EnterDetails/Header"
import Payment from "../components/EnterDetails/Payment" import Payment from "../components/EnterDetails/Payment"
import Multiroom from "../components/EnterDetails/Room/Multiroom" import Multiroom from "../components/EnterDetails/Room/Multiroom"
@@ -29,9 +30,11 @@ import type { NextSearchParams } from "../types"
export async function EnterDetailsPage({ export async function EnterDetailsPage({
lang, lang,
searchParams, searchParams,
config,
}: { }: {
lang: Lang lang: Lang
searchParams: NextSearchParams searchParams: NextSearchParams
config: BookingFlowConfig
}) { }) {
const selectRoomParams = new URLSearchParams( const selectRoomParams = new URLSearchParams(
searchParams as Record<string, string> searchParams as Record<string, string>
@@ -116,6 +119,7 @@ export async function EnterDetailsPage({
// beneath footer to be able to show entire footer upon // beneath footer to be able to show entire footer upon
// scrolling down to the bottom of the page // scrolling down to the bottom of the page
return ( return (
<BookingFlowConfig config={config}>
<main data-footer-spacing> <main data-footer-spacing>
<EnterDetailsProvider <EnterDetailsProvider
booking={booking} booking={booking}
@@ -164,5 +168,6 @@ export async function EnterDetailsPage({
/> />
</EnterDetailsProvider> </EnterDetailsProvider>
</main> </main>
</BookingFlowConfig>
) )
} }

View File

@@ -11,6 +11,7 @@ import { BookingErrorCodeEnum } from "@scandic-hotels/trpc/enums/bookingErrorCod
import { getBooking } from "@scandic-hotels/trpc/routers/booking/utils" import { getBooking } from "@scandic-hotels/trpc/routers/booking/utils"
import { encrypt } from "@scandic-hotels/trpc/utils/encryption" import { encrypt } from "@scandic-hotels/trpc/utils/encryption"
import { BookingFlowConfig } from "../bookingFlowConfig/bookingFlowConfig"
import { HandleErrorCallback } from "../components/EnterDetails/Payment/PaymentCallback/HandleErrorCallback" import { HandleErrorCallback } from "../components/EnterDetails/Payment/PaymentCallback/HandleErrorCallback"
import { HandleSuccessCallback } from "../components/EnterDetails/Payment/PaymentCallback/HandleSuccessCallback" import { HandleSuccessCallback } from "../components/EnterDetails/Payment/PaymentCallback/HandleSuccessCallback"
import { serverClient } from "../trpc" import { serverClient } from "../trpc"
@@ -24,12 +25,14 @@ type PaymentCallbackPageProps = {
searchParams: NextSearchParams searchParams: NextSearchParams
userAccessToken: string | null userAccessToken: string | null
status: PaymentCallbackStatusEnum status: PaymentCallbackStatusEnum
config: BookingFlowConfig
} }
export async function PaymentCallbackPage({ export async function PaymentCallbackPage({
lang, lang,
userAccessToken, userAccessToken,
searchParams, searchParams,
status, status,
config,
}: PaymentCallbackPageProps) { }: PaymentCallbackPageProps) {
const { confirmationNumber } = searchParams const { confirmationNumber } = searchParams
@@ -51,12 +54,14 @@ export async function PaymentCallbackPage({
if (status === PaymentCallbackStatusEnum.Cancel) { if (status === PaymentCallbackStatusEnum.Cancel) {
searchObject.set("errorCode", BookingErrorCodeEnum.TransactionCancelled) searchObject.set("errorCode", BookingErrorCodeEnum.TransactionCancelled)
return ( return (
<BookingFlowConfig config={config}>
<HandleErrorCallback <HandleErrorCallback
returnUrl={returnUrl.toString()} returnUrl={returnUrl.toString()}
searchObject={searchObject} searchObject={searchObject}
status={status} status={status}
errorMessage={errorMessage} errorMessage={errorMessage}
/> />
</BookingFlowConfig>
) )
} }
@@ -92,12 +97,14 @@ export async function PaymentCallbackPage({
) )
return ( return (
<BookingFlowConfig config={config}>
<HandleSuccessCallback <HandleSuccessCallback
refId={refId} refId={refId}
sig={sig} sig={sig}
successRedirectUrl={confirmationUrl} successRedirectUrl={confirmationUrl}
cardType={booking.guaranteeInfo?.cardType} cardType={booking.guaranteeInfo?.cardType}
/> />
</BookingFlowConfig>
) )
} }
@@ -141,11 +148,13 @@ export async function PaymentCallbackPage({
} }
return ( return (
<BookingFlowConfig config={config}>
<HandleErrorCallback <HandleErrorCallback
returnUrl={returnUrl.toString()} returnUrl={returnUrl.toString()}
searchObject={searchObject} searchObject={searchObject}
status={status} status={status}
errorMessage={errorMessage} errorMessage={errorMessage}
/> />
</BookingFlowConfig>
) )
} }

View File

@@ -6,7 +6,7 @@ import { safeTry } from "@scandic-hotels/common/utils/safeTry"
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK" import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
import { env } from "../../env/server" import { env } from "../../env/server"
import { getBookingFlowConfig } from "../bookingFlowConfig/bookingFlowConfig" import { BookingFlowConfig } from "../bookingFlowConfig/bookingFlowConfig"
import { MapContainer } from "../components/MapContainer" import { MapContainer } from "../components/MapContainer"
import { import {
getFiltersFromHotels, getFiltersFromHotels,
@@ -28,9 +28,11 @@ import type { NextSearchParams } from "../types"
export async function SelectHotelMapPage({ export async function SelectHotelMapPage({
lang, lang,
searchParams, searchParams,
config,
}: { }: {
lang: Lang lang: Lang
searchParams: NextSearchParams searchParams: NextSearchParams
config: BookingFlowConfig
}) { }) {
const googleMapId = env.GOOGLE_DYNAMIC_MAP_ID const googleMapId = env.GOOGLE_DYNAMIC_MAP_ID
const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY
@@ -104,7 +106,7 @@ export async function SelectHotelMapPage({
isBookingCodeRateAvailable, isBookingCodeRateAvailable,
isRedemption: redemption, isRedemption: redemption,
isRedemptionAvailable: isRedemptionAvailability, isRedemptionAvailable: isRedemptionAvailability,
config: getBookingFlowConfig(), config,
}) })
const filterList = getFiltersFromHotels(hotels, isBookingCodeRateAvailable) const filterList = getFiltersFromHotels(hotels, isBookingCodeRateAvailable)
@@ -112,6 +114,7 @@ export async function SelectHotelMapPage({
const suspenseKey = stringify(searchParams) const suspenseKey = stringify(searchParams)
return ( return (
<BookingFlowConfig config={config}>
<MapContainer> <MapContainer>
<Suspense key={suspenseKey} fallback={<SelectHotelMapSkeleton />}> <Suspense key={suspenseKey} fallback={<SelectHotelMapSkeleton />}>
<SelectHotelMap <SelectHotelMap
@@ -129,5 +132,6 @@ export async function SelectHotelMapPage({
/> />
</Suspense> </Suspense>
</MapContainer> </MapContainer>
</BookingFlowConfig>
) )
} }

View File

@@ -7,7 +7,7 @@ import { FamilyAndFriendsCodes } from "@scandic-hotels/common/constants/familyAn
import { NoAvailabilityTracking } from "@scandic-hotels/tracking/NoAvailabilityTracking" import { NoAvailabilityTracking } from "@scandic-hotels/tracking/NoAvailabilityTracking"
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK" import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
import { getBookingFlowConfig } from "../bookingFlowConfig/bookingFlowConfig" import { BookingFlowConfig } from "../bookingFlowConfig/bookingFlowConfig"
import FnFNotAllowedAlert from "../components/FnFNotAllowedAlert" import FnFNotAllowedAlert from "../components/FnFNotAllowedAlert"
import { SelectHotel } from "../components/SelectHotel" import { SelectHotel } from "../components/SelectHotel"
import { getHotels } from "../components/SelectHotel/helpers" import { getHotels } from "../components/SelectHotel/helpers"
@@ -24,9 +24,11 @@ export { SelectHotelSkeleton as SelectHotelPageSkeleton } from "../components/Se
export async function SelectHotelPage({ export async function SelectHotelPage({
lang, lang,
searchParams, searchParams,
config,
}: { }: {
lang: Lang lang: Lang
searchParams: NextSearchParams searchParams: NextSearchParams
config: BookingFlowConfig
}) { }) {
const booking = parseSelectHotelSearchParams(searchParams) const booking = parseSelectHotelSearchParams(searchParams)
@@ -94,7 +96,7 @@ export async function SelectHotelPage({
isBookingCodeRateAvailable, isBookingCodeRateAvailable,
isRedemption: redemption, isRedemption: redemption,
isRedemptionAvailable: isRedemptionAvailability, isRedemptionAvailable: isRedemptionAvailability,
config: getBookingFlowConfig(), config,
}) })
const suspenseKey = stringify(searchParams) const suspenseKey = stringify(searchParams)
@@ -105,7 +107,7 @@ export async function SelectHotelPage({
) )
return ( return (
<> <BookingFlowConfig config={config}>
<SelectHotel <SelectHotel
bookingCode={booking.bookingCode} bookingCode={booking.bookingCode}
isBookingCodeRateAvailable={isBookingCodeRateAvailable} isBookingCodeRateAvailable={isBookingCodeRateAvailable}
@@ -126,6 +128,6 @@ export async function SelectHotelPage({
shouldTrackNoAvailability={shouldTrackNoAvailability} shouldTrackNoAvailability={shouldTrackNoAvailability}
/> />
</Suspense> </Suspense>
</> </BookingFlowConfig>
) )
} }

View File

@@ -3,6 +3,7 @@ import { notFound } from "next/navigation"
import { logger } from "@scandic-hotels/common/logger" import { logger } from "@scandic-hotels/common/logger"
import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking" import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking"
import { BookingFlowConfig } from "../bookingFlowConfig/bookingFlowConfig"
import { SelectRate } from "../components/SelectRate" import { SelectRate } from "../components/SelectRate"
import { SelectRateTracking } from "../components/SelectRate/Tracking/SelectRateTracking" import { SelectRateTracking } from "../components/SelectRate/Tracking/SelectRateTracking"
import { SelectRateProvider } from "../contexts/SelectRate/SelectRateContext" import { SelectRateProvider } from "../contexts/SelectRate/SelectRateContext"
@@ -28,9 +29,11 @@ const singleRoomRateTypes = combineRegExps(
export async function SelectRatePage({ export async function SelectRatePage({
lang, lang,
searchParams, searchParams,
config,
}: { }: {
lang: Lang lang: Lang
searchParams: NextSearchParams searchParams: NextSearchParams
config: BookingFlowConfig
}) { }) {
const booking = parseSelectRateSearchParams(searchParams) const booking = parseSelectRateSearchParams(searchParams)
@@ -71,12 +74,12 @@ export async function SelectRatePage({
} }
return ( return (
<> <BookingFlowConfig config={config}>
<SelectRateProvider hotelData={hotelData}> <SelectRateProvider hotelData={hotelData}>
<SelectRate hotelData={hotelData} booking={booking} /> <SelectRate hotelData={hotelData} booking={booking} />
<SelectRateTracking hotelData={hotelData} booking={booking} /> <SelectRateTracking hotelData={hotelData} booking={booking} />
</SelectRateProvider> </SelectRateProvider>
</> </BookingFlowConfig>
) )
} }

View File

@@ -11,10 +11,7 @@ export async function getUserPointsBalance(
const verifiedUser = const verifiedUser =
session.token.loginType === "eurobonus" session.token.loginType === "eurobonus"
? await getEuroBonusProfileData({ ? await getEuroBonusProfileSafely(session)
accessToken: session.token.access_token,
loginType: session.token.loginType,
})
: await getVerifiedUser({ session }) : await getVerifiedUser({ session })
if (!verifiedUser || "error" in verifiedUser) { if (!verifiedUser || "error" in verifiedUser) {
@@ -28,3 +25,14 @@ export async function getUserPointsBalance(
return points ?? 0 return points ?? 0
} }
async function getEuroBonusProfileSafely(session: Session) {
try {
return await getEuroBonusProfileData({
accessToken: session.token.access_token,
loginType: session.token.loginType,
})
} catch (_error) {
return undefined
}
}