diff --git a/apps/partner-sas/app/[lang]/layout.tsx b/apps/partner-sas/app/[lang]/layout.tsx
index 29c225124..bbf69dd58 100644
--- a/apps/partner-sas/app/[lang]/layout.tsx
+++ b/apps/partner-sas/app/[lang]/layout.tsx
@@ -4,6 +4,7 @@ import "@scandic-hotels/design-system/normalize.css"
import "@scandic-hotels/design-system/design-system-new-deprecated.css"
import "../../globals.css"
+import { ReactQueryDevtools } from "@tanstack/react-query-devtools"
import Script from "next/script"
import { BookingFlowContextProvider } from "@scandic-hotels/booking-flow/BookingFlowContextProvider"
@@ -11,18 +12,20 @@ import { BookingFlowTrackingProvider } from "@scandic-hotels/booking-flow/Bookin
import { NuqsAdapter } from "@scandic-hotels/booking-flow/utils/nuqs"
import { Lang } from "@scandic-hotels/common/constants/language"
import { ToastHandler } from "@scandic-hotels/design-system/ToastHandler"
-import { TrpcProvider } from "@scandic-hotels/trpc/Provider"
+import AdobeSDKScript from "@/components/AdobeSDKScript"
import CookieBotConsent from "@/components/CookieBotConsent"
+import GTMScript from "@/components/GTMScript"
import { RACRouterProvider } from "@/components/RACRouterProvider"
import { SiteWideAlert } from "@/components/SitewideAlert"
+import TrpcProvider from "@/components/TrpcProvider"
import { FontPreload } from "@/fonts/font-preloading"
import { getMessages } from "@/i18n"
import ClientIntlProvider from "@/i18n/Provider"
import { setLang } from "@/i18n/serverContext"
-import { Footer } from "../components/Footer/Footer"
-import { Header } from "../components/Header/Header"
+import { Footer } from "../../components/Footer/Footer"
+import { Header } from "../../components/Header/Header"
import {
trackAccordionItemOpen,
trackBedSelection,
@@ -65,8 +68,14 @@ export default async function RootLayout(props: RootLayoutProps) {
return (
- {/* TODO */}
+
+
+ {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
+
@@ -76,7 +85,6 @@ export default async function RootLayout(props: RootLayoutProps) {
messages={messages}
>
- {/* TODO handle onError */}
+
diff --git a/apps/partner-sas/components/AdobeSDKScript.tsx b/apps/partner-sas/components/AdobeSDKScript.tsx
new file mode 100644
index 000000000..12a13c611
--- /dev/null
+++ b/apps/partner-sas/components/AdobeSDKScript.tsx
@@ -0,0 +1,13 @@
+import Script from "next/script"
+
+import { env } from "@/env/server"
+
+export default function AdobeSDKScript() {
+ return env.ADOBE_SDK_SCRIPT_SRC ? (
+
+ ) : null
+}
diff --git a/apps/partner-sas/app/components/Footer/Footer.tsx b/apps/partner-sas/components/Footer/Footer.tsx
similarity index 100%
rename from apps/partner-sas/app/components/Footer/Footer.tsx
rename to apps/partner-sas/components/Footer/Footer.tsx
diff --git a/apps/partner-sas/app/components/Footer/footer.module.css b/apps/partner-sas/components/Footer/footer.module.css
similarity index 100%
rename from apps/partner-sas/app/components/Footer/footer.module.css
rename to apps/partner-sas/components/Footer/footer.module.css
diff --git a/apps/partner-sas/components/GTMScript.tsx b/apps/partner-sas/components/GTMScript.tsx
new file mode 100644
index 000000000..9dbf47e4a
--- /dev/null
+++ b/apps/partner-sas/components/GTMScript.tsx
@@ -0,0 +1,31 @@
+import Script from "next/script"
+
+import { env } from "@/env/server"
+
+export default function GTMScript() {
+ return env.ENABLE_GTMSCRIPT ? (
+
+ ) : null
+}
diff --git a/apps/partner-sas/app/components/Header/Header.tsx b/apps/partner-sas/components/Header/Header.tsx
similarity index 100%
rename from apps/partner-sas/app/components/Header/Header.tsx
rename to apps/partner-sas/components/Header/Header.tsx
diff --git a/apps/partner-sas/app/components/Header/header.module.css b/apps/partner-sas/components/Header/header.module.css
similarity index 100%
rename from apps/partner-sas/app/components/Header/header.module.css
rename to apps/partner-sas/components/Header/header.module.css
diff --git a/apps/partner-sas/app/components/PoweredByScandic/PoweredByScandic.tsx b/apps/partner-sas/components/PoweredByScandic/PoweredByScandic.tsx
similarity index 100%
rename from apps/partner-sas/app/components/PoweredByScandic/PoweredByScandic.tsx
rename to apps/partner-sas/components/PoweredByScandic/PoweredByScandic.tsx
diff --git a/apps/partner-sas/app/components/PoweredByScandic/poweredByScandic.module.css b/apps/partner-sas/components/PoweredByScandic/poweredByScandic.module.css
similarity index 100%
rename from apps/partner-sas/app/components/PoweredByScandic/poweredByScandic.module.css
rename to apps/partner-sas/components/PoweredByScandic/poweredByScandic.module.css
diff --git a/apps/partner-sas/components/TrpcProvider.tsx b/apps/partner-sas/components/TrpcProvider.tsx
new file mode 100644
index 000000000..9b9c09b68
--- /dev/null
+++ b/apps/partner-sas/components/TrpcProvider.tsx
@@ -0,0 +1,40 @@
+"use client"
+
+import { TRPCClientError } from "@trpc/client"
+
+import { login } from "@scandic-hotels/common/constants/routes/handleAuth"
+import { logger } from "@scandic-hotels/common/logger"
+import { SessionExpiredError } from "@scandic-hotels/trpc/errors"
+import { TrpcProvider as InternalTrpcProvider } from "@scandic-hotels/trpc/Provider"
+
+import useLang from "@/hooks/useLang"
+
+import type { AnyTRPCRouter } from "@trpc/server"
+
+export default function TrpcProvider({
+ children,
+}: {
+ children: React.ReactNode
+}) {
+ const lang = useLang()
+
+ return (
+ {
+ if (error instanceof TRPCClientError) {
+ const appError: TRPCClientError = error
+ logger.error("trpc error", { appError })
+ if (appError.data?.code === "UNAUTHORIZED") {
+ if (appError.data?.cause instanceof SessionExpiredError) {
+ // TODO verify login url
+ const loginUrl = login[lang]
+ window.location.assign(loginUrl)
+ }
+ }
+ }
+ }}
+ >
+ {children}
+
+ )
+}
diff --git a/apps/partner-sas/env/server.ts b/apps/partner-sas/env/server.ts
index 032203dff..c551d7d43 100644
--- a/apps/partner-sas/env/server.ts
+++ b/apps/partner-sas/env/server.ts
@@ -10,9 +10,19 @@ export const env = createEnv({
isServer: typeof window === "undefined" || "Deno" in window,
server: {
PUBLIC_URL: z.string().default(""),
+ ADOBE_SDK_SCRIPT_SRC: z.string().optional(),
+ ENABLE_GTMSCRIPT: z
+ .string()
+ // only allow "true" or "false"
+ .refine((s) => s === "true" || s === "false")
+ // transform to boolean
+ .transform((s) => s === "true")
+ .default("false"),
},
emptyStringAsUndefined: true,
runtimeEnv: {
PUBLIC_URL: process.env.NEXT_PUBLIC_PUBLIC_URL,
+ ADOBE_SDK_SCRIPT_SRC: process.env.ADOBE_SDK_SCRIPT_SRC,
+ ENABLE_GTMSCRIPT: process.env.ENABLE_GTMSCRIPT,
},
})
diff --git a/apps/partner-sas/package.json b/apps/partner-sas/package.json
index 425222016..3acb77d00 100644
--- a/apps/partner-sas/package.json
+++ b/apps/partner-sas/package.json
@@ -26,6 +26,7 @@
"@scandic-hotels/trpc": "workspace:*",
"@sentry/nextjs": "^8.41.0",
"@swc/plugin-formatjs": "^3.2.2",
+ "@tanstack/react-query-devtools": "^5.75.5",
"next": "15.3.4",
"react": "^19.0.0",
"react-dom": "^19.0.0",
diff --git a/yarn.lock b/yarn.lock
index f1559221f..22cd5a8e5 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5835,6 +5835,7 @@ __metadata:
"@scandic-hotels/typescript-config": "workspace:*"
"@sentry/nextjs": "npm:^8.41.0"
"@swc/plugin-formatjs": "npm:^3.2.2"
+ "@tanstack/react-query-devtools": "npm:^5.75.5"
"@types/node": "npm:^20"
"@types/react": "npm:19.1.0"
"@types/react-dom": "npm:19.1.0"