Merged in chore/more-partner-sas-boilerplate (pull request #2756)

chore: Misc for partner-sas

* Add global-error to partner-sas

* Add redirect to lang in partner-sas

* Actually use language from param

* Increase test timeouts and use parsed lang to fix tests

* Remove need to import serverClient to setup trpc


Approved-by: Hrishikesh Vaipurkar
This commit is contained in:
Anton Gunnarsson
2025-09-04 07:45:14 +00:00
parent 36b6685ad5
commit 7e585b2d9a
9 changed files with 162 additions and 26 deletions

View File

@@ -10,8 +10,6 @@ import { NuqsAdapter } from "@scandic-hotels/booking-flow/utils/nuqs"
import { Lang } from "@scandic-hotels/common/constants/language"
import { TrpcProvider } from "@scandic-hotels/trpc/Provider"
import { serverClient } from "@/lib/trpc"
import { getMessages } from "@/i18n"
import ClientIntlProvider from "@/i18n/Provider"
import { setLang } from "@/i18n/serverContext"
@@ -41,17 +39,13 @@ type RootLayoutProps = {
}
export default async function RootLayout(props: RootLayoutProps) {
// const params = await props.params
const lang = Lang.en //params.lang
const params = await props.params
const lang = params.lang
const { children } = props
setLang(lang)
const messages = await getMessages(lang)
// TODO we need this import right now to ensure configureServerClient is called,
// but check where we do this
const _caller = await serverClient()
const parsedLanguage = setLang(lang)
const messages = await getMessages(parsedLanguage)
return (
<html lang="en">
@@ -60,7 +54,7 @@ export default async function RootLayout(props: RootLayoutProps) {
<div className="root">
<ClientIntlProvider
defaultLocale={Lang.en}
locale={lang}
locale={parsedLanguage}
messages={messages}
>
<NuqsAdapter>

View File

@@ -1,4 +1,4 @@
export default function NotFoundPage() {
// eslint-disable-next-line formatjs/no-literal-string-in-jsx
return <div>Not found, forgot lang in url?</div>
return <div>Not Found</div>
}

View File

@@ -0,0 +1,124 @@
"use client"
import * as Sentry from "@sentry/nextjs"
import { useEffect } from "react"
import { logger } from "@scandic-hotels/common/logger"
// TODO verify how this looks with someone
/* eslint-disable formatjs/no-literal-string-in-jsx */
export default function GlobalError({
error,
}: {
error: Error & { digest?: string }
}) {
logger.error("Global Error", { global_error: error })
useEffect(() => {
Sentry.captureException(error)
}, [error])
return (
<html>
<head>
<style>
{`
body {
font-family: Helvetica, Arial, sans-serif;
padding: 32px;
}
a {
color: #4d001b;
}
a:hover {
color: #8f4350;
}
.title {
text-transform: uppercase;
}
.content {
display: flex;
flex-direction: column;
gap: 20px;
max-width: 600px;
margin: 0 auto;
}
.phoneNumbers, .links {
display: flex;
flex-direction: column;
gap: 8px;
padding: 0;
margin: 0;
list-style: none;
}
`}
</style>
</head>
<body>
<div className="content">
<h1 className="title">SORRY, SOMETHING WENT WRONG!</h1>
<p>
<strong>
{
"While we're working hard to fix it, you can always give us a call:"
}
</strong>
</p>
<ul className="phoneNumbers">
<li>
Denmark: <a href="tel:+4533480400">+45 33 48 04 00</a>
</li>
<li>
Finland: <a href="tel:+358020081800">+358 0200 81 800</a>
</li>
<li>
Norway: <a href="tel:+4723155000">+47 23 15 50 00</a>
</li>
<li>
Sweden: <a href="tel:+46851751700">+46 8 517 517 00</a>
</li>
<li>
International: <a href="tel:+46851751720">+46 8 517 517 20</a>
</li>
</ul>
<p>
<strong>
You can also switch languages to try if it works better this way:
</strong>
</p>
<ul className="links">
<li>
<a href="https://sas.scandichotels.com/da">Danish</a>
</li>
<li>
<a href="https://sas.scandichotels.com/en">English</a>
</li>
<li>
<a href="https://sas.scandichotels.com/fi">Finnish</a>
</li>
<li>
<a href="https://sas.scandichotels.com/de">German</a>
</li>
<li>
<a href="https://sas.scandichotels.com/no">Norwegian</a>
</li>
<li>
<a href="https://sas.scandichotels.com/sv">Swedish</a>
</li>
</ul>
<p>
<strong>Thanks for your patience!</strong>
</p>
</div>
</body>
</html>
)
}

View File

@@ -0,0 +1,11 @@
import { configureTrpc } from "@/lib/trpc"
configureTrpc()
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return <>{children}</>
}

View File

@@ -0,0 +1,5 @@
import { redirect } from "next/navigation"
export default function Page() {
redirect("/en")
}

View File

@@ -18,7 +18,11 @@ const getRef = cache(() => ({ current: undefined as Lang | undefined }))
*/
export function setLang(newLang: Lang) {
const parseResult = languageSchema.safeParse(newLang)
getRef().current = parseResult.success ? parseResult.data : Lang.en
const parsedLanguage = parseResult.success ? parseResult.data : Lang.en
getRef().current = parsedLanguage
return parsedLanguage
}
/**

View File

@@ -25,7 +25,9 @@ export async function createAppContext() {
return ctx
}
export function configureTrpc() {
configureServerClient(createAppContext)
}
export async function serverClient() {
const ctx = await createAppContext()

View File

@@ -23,16 +23,11 @@ export const middleware: NextMiddleware = async (request, event) => {
// Default to English if no lang is found.
headers.set("x-lang", Lang.en)
return NextResponse.rewrite(
new URL(`/${Lang.en}/middleware-error/404`, request.nextUrl),
{
return NextResponse.next({
request: {
headers,
},
status: 404,
statusText: "Not found",
}
)
})
}
// Note that the order of middlewares is important since that is the order they are matched by.

View File

@@ -23,19 +23,20 @@ export default defineConfig({
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: "html",
timeout: 120_000,
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL: "http://localhost:3001",
/* How long to wait for actions to complete. */
actionTimeout: 15 * 1000,
actionTimeout: 60_000,
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: process.env.CI ? "on-first-retry" : "retain-on-failure",
},
expect: {
timeout: 10_000,
timeout: 60_000,
},
/* Configure projects for major browsers */