Merge remote-tracking branch 'origin' into feature/tracking

This commit is contained in:
Linus Flood
2024-12-13 09:02:37 +01:00
329 changed files with 4494 additions and 1910 deletions

View File

@@ -1,4 +1,4 @@
import { NextRequest, NextResponse } from "next/server"
import { type NextRequest, NextResponse } from "next/server"
import { AuthError } from "next-auth"
import { Lang } from "@/constants/languages"

View File

@@ -4,7 +4,7 @@ import Breadcrumbs from "@/components/Breadcrumbs"
import BreadcrumbsSkeleton from "@/components/TempDesignSystem/Breadcrumbs/BreadcrumbsSkeleton"
import { setLang } from "@/i18n/serverContext"
import { LangParams, PageArgs } from "@/types/params"
import type { LangParams, PageArgs } from "@/types/params"
export default function AllBreadcrumbs({ params }: PageArgs<LangParams>) {
setLang(params.lang)

View File

@@ -23,7 +23,7 @@
@media screen and (min-width: 1367px) {
.content {
gap: var(--Spacing-x5);
grid-template-columns: max(360px) 1fr;
grid-template-columns: max(340px) 1fr;
padding-left: var(--Spacing-x5);
padding-right: var(--Spacing-x5);
}

View File

@@ -6,7 +6,7 @@ import { setLang } from "@/i18n/serverContext"
import styles from "./page.module.css"
import { LangParams, PageArgs } from "@/types/params"
import type { LangParams, PageArgs } from "@/types/params"
export default async function CommunicationSlot({
params,

View File

@@ -9,7 +9,7 @@ import { setLang } from "@/i18n/serverContext"
import styles from "./page.module.css"
import { LangParams, PageArgs } from "@/types/params"
import type { LangParams, PageArgs } from "@/types/params"
export default async function CreditCardSlot({ params }: PageArgs<LangParams>) {
setLang(params.lang)

View File

@@ -9,7 +9,7 @@ import { setLang } from "@/i18n/serverContext"
import styles from "./page.module.css"
import { LangParams, PageArgs } from "@/types/params"
import type { LangParams, PageArgs } from "@/types/params"
export default async function MembershipCardSlot({
params,

View File

@@ -3,7 +3,7 @@ import { getProfile } from "@/lib/trpc/memoizedRequests"
import Form from "@/components/Forms/Edit/Profile"
import { setLang } from "@/i18n/serverContext"
import { LangParams, PageArgs } from "@/types/params"
import type { LangParams, PageArgs } from "@/types/params"
export default async function EditProfileSlot({
params,

View File

@@ -20,7 +20,7 @@ import { setLang } from "@/i18n/serverContext"
import styles from "./page.module.css"
import { LangParams, PageArgs } from "@/types/params"
import type { LangParams, PageArgs } from "@/types/params"
export default async function Profile({ params }: PageArgs<LangParams>) {
setLang(params.lang)

View File

@@ -5,7 +5,7 @@ import { serverClient } from "@/lib/trpc/server"
import TrackingSDK from "@/components/TrackingSDK"
import { setLang } from "@/i18n/serverContext"
import { LangParams, PageArgs } from "@/types/params"
import type { LangParams, PageArgs } from "@/types/params"
export { generateMetadata } from "@/utils/generateMetadata"

View File

@@ -4,7 +4,7 @@ import Breadcrumbs from "@/components/Breadcrumbs"
import BreadcrumbsSkeleton from "@/components/TempDesignSystem/Breadcrumbs/BreadcrumbsSkeleton"
import { setLang } from "@/i18n/serverContext"
import { LangParams, PageArgs } from "@/types/params"
import type { LangParams, PageArgs } from "@/types/params"
export default function PageBreadcrumbs({ params }: PageArgs<LangParams>) {
setLang(params.lang)

View File

@@ -2,7 +2,7 @@ import { setPreviewData } from "@/lib/previewContext"
import InitLivePreview from "@/components/LivePreview"
import { PageArgs, UIDParams } from "@/types/params"
import type { PageArgs, UIDParams } from "@/types/params"
export default function PreviewPage({
searchParams,

View File

@@ -1,6 +1,6 @@
import styles from "./layout.module.css"
import {
import type {
ContentTypeParams,
LangParams,
LayoutArgs,

View File

@@ -11,7 +11,7 @@ import CollectionPage from "@/components/ContentType/StaticPages/CollectionPage"
import ContentPage from "@/components/ContentType/StaticPages/ContentPage"
import { setLang } from "@/i18n/serverContext"
import {
import type {
ContentTypeParams,
LangParams,
PageArgs,

View File

@@ -1,6 +1,6 @@
import styles from "./layout.module.css"
import { LangParams, LayoutArgs } from "@/types/params"
import type { LangParams, LayoutArgs } from "@/types/params"
export default function PaymentCallbackLayout({
children,

View File

@@ -12,7 +12,7 @@ import { serverClient } from "@/lib/trpc/server"
import PaymentCallback from "@/components/HotelReservation/EnterDetails/Payment/PaymentCallback"
import { LangParams, PageArgs } from "@/types/params"
import type { LangParams, PageArgs } from "@/types/params"
export default async function PaymentCallbackPage({
params,

View File

@@ -1,6 +1,6 @@
import styles from "./layout.module.css"
import { LangParams, LayoutArgs } from "@/types/params"
import type { LangParams, LayoutArgs } from "@/types/params"
export default function HotelReservationLayout({
children,

View File

@@ -1,5 +0,0 @@
import LoadingSpinner from "@/components/LoadingSpinner"
export default function LoadingModal() {
return <LoadingSpinner />
}

View File

@@ -1,125 +0,0 @@
import { differenceInCalendarDays, format, isWeekend } from "date-fns"
import { notFound } from "next/navigation"
import { Suspense } from "react"
import { Lang } from "@/constants/languages"
import { env } from "@/env/server"
import { getCityCoordinates, getLocations } from "@/lib/trpc/memoizedRequests"
import { getHotelPins } from "@/components/HotelReservation/HotelCardDialogListing/utils"
import SelectHotelMap from "@/components/HotelReservation/SelectHotel/SelectHotelMap"
import {
generateChildrenString,
getHotelReservationQueryParams,
} from "@/components/HotelReservation/SelectRate/RoomSelection/utils"
import { MapModal } from "@/components/MapModal"
import TrackingSDK from "@/components/TrackingSDK"
import { setLang } from "@/i18n/serverContext"
import { fetchAvailableHotels, getFiltersFromHotels } from "../../utils"
import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums"
import type { HotelData } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps"
import type { SelectHotelSearchParams } from "@/types/components/hotelReservation/selectHotel/selectHotelSearchParams"
import {
TrackingChannelEnum,
TrackingSDKHotelInfo,
TrackingSDKPageData,
} from "@/types/components/tracking"
import type { LangParams, PageArgs } from "@/types/params"
export default async function SelectHotelMapPage({
params,
searchParams,
}: PageArgs<LangParams, SelectHotelSearchParams>) {
setLang(params.lang)
const locations = await getLocations()
if (!locations || "error" in locations) {
return null
}
const city = locations.data.find(
(location) =>
location.name.toLowerCase() === searchParams.city.toLowerCase()
)
if (!city) return notFound()
const googleMapId = env.GOOGLE_DYNAMIC_MAP_ID
const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY
const selectHotelParams = new URLSearchParams(searchParams)
const selectHotelParamsObject =
getHotelReservationQueryParams(selectHotelParams)
const adults = selectHotelParamsObject.room[0].adults // TODO: Handle multiple rooms
const child = selectHotelParamsObject.room[0].child // TODO: Handle multiple rooms
const children = child ? generateChildrenString(child) : undefined // TODO: Handle multiple rooms
const hotels = await fetchAvailableHotels({
cityId: city.id,
roomStayStartDate: searchParams.fromDate,
roomStayEndDate: searchParams.toDate,
adults,
children,
})
const validHotels = hotels.filter(
(hotel): hotel is HotelData => hotel !== null
)
const arrivalDate = new Date(searchParams.fromDate)
const departureDate = new Date(searchParams.toDate)
const pageTrackingData: TrackingSDKPageData = {
pageId: "select-hotel",
domainLanguage: params.lang as Lang,
channel: TrackingChannelEnum["hotelreservation"],
pageName: "hotelreservation|select-hotel|mapview",
siteSections: "hotelreservation|select-hotel|mapview",
pageType: "bookinghotelsmapviewpage",
siteVersion: "new-web",
}
const hotelsTrackingData: TrackingSDKHotelInfo = {
availableResults: hotels.length,
searchTerm: searchParams.city,
arrivalDate: format(arrivalDate, "yyyy-MM-dd"),
departureDate: format(departureDate, "yyyy-MM-dd"),
noOfAdults: adults,
noOfChildren: child?.length,
ageOfChildren: child?.map((c) => c.age).join(","),
childBedPreference: child?.map((c) => ChildBedMapEnum[c.bed]).join("|"),
noOfRooms: 1, // // TODO: Handle multiple rooms
duration: differenceInCalendarDays(departureDate, arrivalDate),
leadTime: differenceInCalendarDays(arrivalDate, new Date()),
searchType: "destination",
bookingTypeofDay: isWeekend(arrivalDate) ? "weekend" : "weekday",
country: validHotels?.[0].hotelData.address.country,
region: validHotels?.[0].hotelData.address.city,
}
const hotelPins = getHotelPins(validHotels)
const filterList = getFiltersFromHotels(validHotels)
const cityCoordinates = await getCityCoordinates({
city: city.name,
hotel: { address: hotels?.[0]?.hotelData?.address.streetAddress },
})
return (
<MapModal>
<SelectHotelMap
apiKey={googleMapsApiKey}
hotelPins={hotelPins}
mapId={googleMapId}
hotels={validHotels}
filterList={filterList}
cityCoordinates={cityCoordinates}
/>
<Suspense fallback={null}>
<TrackingSDK
pageData={pageTrackingData}
hotelInfo={hotelsTrackingData}
/>
</Suspense>
</MapModal>
)
}

View File

@@ -1,3 +0,0 @@
export default function Default() {
return null
}

View File

@@ -3,3 +3,9 @@
background-color: var(--Base-Background-Primary-Normal);
position: relative;
}
@media screen and (min-width: 768px) {
.layout {
z-index: 0;
}
}

View File

@@ -1,17 +1,9 @@
import styles from "./layout.module.css"
import { LangParams, LayoutArgs } from "@/types/params"
import type { LangParams, LayoutArgs } from "@/types/params"
export default function HotelReservationLayout({
children,
modal,
}: React.PropsWithChildren<
LayoutArgs<LangParams> & { modal: React.ReactNode }
>) {
return (
<div className={styles.layout}>
{children}
{modal}
</div>
)
}: React.PropsWithChildren<LayoutArgs<LangParams>>) {
return <div className={styles.layout}>{children}</div>
}

View File

@@ -1 +1,63 @@
export { default } from "../@modal/(.)map/page"
import { notFound } from "next/navigation"
import { Suspense } from "react"
import { getLocations } from "@/lib/trpc/memoizedRequests"
import { SelectHotelMapContainer } from "@/components/HotelReservation/SelectHotel/SelectHotelMap/SelectHotelMapContainer"
import { SelectHotelMapContainerSkeleton } from "@/components/HotelReservation/SelectHotel/SelectHotelMap/SelectHotelMapContainerSkeleton"
import {
generateChildrenString,
getHotelReservationQueryParams,
} from "@/components/HotelReservation/SelectRate/RoomSelection/utils"
import { MapContainer } from "@/components/MapContainer"
import { setLang } from "@/i18n/serverContext"
import styles from "./page.module.css"
import type { SelectHotelSearchParams } from "@/types/components/hotelReservation/selectHotel/selectHotelSearchParams"
import type { LangParams, PageArgs } from "@/types/params"
export default async function SelectHotelMapPage({
params,
searchParams,
}: PageArgs<LangParams, SelectHotelSearchParams>) {
setLang(params.lang)
const locations = await getLocations()
if (!locations || "error" in locations) {
return null
}
const city = locations.data.find(
(location) =>
location.name.toLowerCase() === searchParams.city.toLowerCase()
)
if (!city) return notFound()
const selectHotelParams = new URLSearchParams(searchParams)
const selectHotelParamsObject =
getHotelReservationQueryParams(selectHotelParams)
const adultsInRoom = selectHotelParamsObject.room[0].adults // TODO: Handle multiple rooms
const childrenInRoom = selectHotelParamsObject.room[0].child
? generateChildrenString(selectHotelParamsObject.room[0].child)
: undefined // TODO: Handle multiple rooms
const child = selectHotelParamsObject.room[0].child // TODO: Handle multiple rooms
return (
<div className={styles.main}>
<MapContainer>
<Suspense
key={city.name}
fallback={<SelectHotelMapContainerSkeleton />}
>
<SelectHotelMapContainer
city={city}
searchParams={searchParams}
adultsInRoom={adultsInRoom}
childrenInRoom={childrenInRoom}
child={child}
/>
</Suspense>
</MapContainer>
</div>
)
}

View File

@@ -1,116 +0,0 @@
.main {
display: flex;
padding: 0 var(--Spacing-x2) var(--Spacing-x3) var(--Spacing-x2);
background-color: var(--Scandic-Brand-Warm-White);
min-height: 100dvh;
flex-direction: column;
max-width: var(--max-width);
margin: 0 auto;
}
.header {
display: flex;
flex-direction: column;
gap: var(--Spacing-x2);
padding: var(--Spacing-x3) var(--Spacing-x2) 0 var(--Spacing-x2);
}
.header nav {
display: none;
}
.cityInformation {
display: flex;
flex-wrap: wrap;
gap: var(--Spacing-x1);
}
.sorter {
display: none;
}
.sideBar {
display: flex;
flex-direction: column;
}
.link {
display: none;
}
.buttonContainer {
display: flex;
gap: var(--Spacing-x2);
margin-bottom: var(--Spacing-x3);
}
.button {
flex: 1;
}
.hotelList {
flex: 1;
display: flex;
flex-direction: column;
gap: var(--Spacing-x3);
}
.filter {
display: none;
}
@media (min-width: 768px) {
.main {
padding: var(--Spacing-x5);
}
.header {
display: block;
background-color: var(--Base-Surface-Subtle-Normal);
padding: var(--Spacing-x4) var(--Spacing-x5) var(--Spacing-x3)
var(--Spacing-x5);
}
.header nav {
display: block;
max-width: var(--max-width-navigation);
padding: 0;
}
.sorter {
display: block;
width: 339px;
}
.title {
margin: var(--Spacing-x3) auto 0;
display: flex;
max-width: var(--max-width-navigation);
align-items: center;
justify-content: space-between;
}
.sideBar {
max-width: 340px;
}
.filter {
display: block;
}
.link {
display: flex;
padding-bottom: var(--Spacing-x6);
}
.mapContainer {
display: flex;
flex-direction: column;
background: var(--Base-Surface-Primary-light-Normal);
border-radius: var(--Corner-radius-Medium);
border: 1px solid var(--Base-Border-Subtle);
}
.main {
flex-direction: row;
gap: var(--Spacing-x5);
}
.buttonContainer {
display: none;
}
}

View File

@@ -1,51 +1,18 @@
import { differenceInCalendarDays, format, isWeekend } from "date-fns"
import { notFound } from "next/navigation"
import { Suspense } from "react"
import { Lang } from "@/constants/languages"
import {
selectHotel,
selectHotelMap,
} from "@/constants/routes/hotelReservation"
import { getLocations } from "@/lib/trpc/memoizedRequests"
import {
fetchAvailableHotels,
getFiltersFromHotels,
} from "@/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/utils"
import HotelCardListing from "@/components/HotelReservation/HotelCardListing"
import HotelCount from "@/components/HotelReservation/SelectHotel/HotelCount"
import HotelFilter from "@/components/HotelReservation/SelectHotel/HotelFilter"
import HotelSorter from "@/components/HotelReservation/SelectHotel/HotelSorter"
import MobileMapButtonContainer from "@/components/HotelReservation/SelectHotel/MobileMapButtonContainer"
import SelectHotel from "@/components/HotelReservation/SelectHotel"
import { SelectHotelSkeleton } from "@/components/HotelReservation/SelectHotel/SelectHotelSkeleton"
import {
generateChildrenString,
getHotelReservationQueryParams,
} from "@/components/HotelReservation/SelectRate/RoomSelection/utils"
import { ChevronRightIcon } from "@/components/Icons"
import StaticMap from "@/components/Maps/StaticMap"
import Alert from "@/components/TempDesignSystem/Alert"
import Breadcrumbs from "@/components/TempDesignSystem/Breadcrumbs"
import BreadcrumbsSkeleton from "@/components/TempDesignSystem/Breadcrumbs/BreadcrumbsSkeleton"
import Button from "@/components/TempDesignSystem/Button"
import Link from "@/components/TempDesignSystem/Link"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import TrackingSDK from "@/components/TrackingSDK"
import { getIntl } from "@/i18n"
import { setLang } from "@/i18n/serverContext"
import styles from "./page.module.css"
import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums"
import type { HotelData } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps"
import type { SelectHotelSearchParams } from "@/types/components/hotelReservation/selectHotel/selectHotelSearchParams"
import {
TrackingChannelEnum,
TrackingSDKHotelInfo,
TrackingSDKPageData,
} from "@/types/components/tracking"
import { AlertTypeEnum } from "@/types/enums/alert"
import { LangParams, PageArgs } from "@/types/params"
import type { LangParams, PageArgs } from "@/types/params"
export default async function SelectHotelPage({
params,
@@ -64,10 +31,6 @@ export default async function SelectHotelPage({
if (!city) return notFound()
const isCityWithCountry = (city: any): city is { country: string } =>
"country" in city
const intl = await getIntl()
const selectHotelParams = new URLSearchParams(searchParams)
const selectHotelParamsObject =
getHotelReservationQueryParams(selectHotelParams)
@@ -79,157 +42,30 @@ export default async function SelectHotelPage({
return notFound()
}
const adults = selectHotelParamsObject.room[0].adults // TODO: Handle multiple rooms
const adultsParams = selectHotelParamsObject.room[0].adults // TODO: Handle multiple rooms
const childrenParams = selectHotelParamsObject.room[0].child
? generateChildrenString(selectHotelParamsObject.room[0].child)
: undefined // TODO: Handle multiple rooms
const child = selectHotelParamsObject.room[0].child // TODO: Handle multiple rooms
const children = child ? generateChildrenString(child) : undefined
const hotels = await fetchAvailableHotels({
cityId: city.id,
roomStayStartDate: searchParams.fromDate,
roomStayEndDate: searchParams.toDate,
adults,
children,
})
const arrivalDate = new Date(searchParams.fromDate)
const departureDate = new Date(searchParams.toDate)
const validHotels = hotels.filter(
(hotel): hotel is HotelData => hotel !== null
)
const filterList = getFiltersFromHotels(validHotels)
const breadcrumbs = [
{
title: intl.formatMessage({ id: "Home" }),
href: `/${params.lang}`,
uid: "home-page",
},
{
title: intl.formatMessage({ id: "Hotel reservation" }),
href: `/${params.lang}/hotelreservation`,
uid: "hotel-reservation",
},
{
title: intl.formatMessage({ id: "Select hotel" }),
href: `${selectHotel(params.lang)}/?${selectHotelParams}`,
uid: "select-hotel",
},
{
title: city.name,
uid: city.id,
},
]
const isAllUnavailable = hotels.every((hotel) => hotel.price === undefined)
const pageTrackingData: TrackingSDKPageData = {
pageId: "select-hotel",
domainLanguage: params.lang as Lang,
channel: TrackingChannelEnum["hotelreservation"],
pageName: "hotelreservation|select-hotel",
siteSections: "hotelreservation|select-hotel",
pageType: "bookinghotelspage",
siteVersion: "new-web",
}
const hotelsTrackingData: TrackingSDKHotelInfo = {
availableResults: hotels.length,
searchTerm: searchParams.city,
arrivalDate: format(arrivalDate, "yyyy-MM-dd"),
departureDate: format(departureDate, "yyyy-MM-dd"),
noOfAdults: adults,
noOfChildren: child?.length,
ageOfChildren: child?.map((c) => c.age).join(","),
childBedPreference: child?.map((c) => ChildBedMapEnum[c.bed]).join("|"),
noOfRooms: 1, // // TODO: Handle multiple rooms
duration: differenceInCalendarDays(departureDate, arrivalDate),
leadTime: differenceInCalendarDays(arrivalDate, new Date()),
searchType: "destination",
bookingTypeofDay: isWeekend(arrivalDate) ? "weekend" : "weekday",
country: validHotels?.[0].hotelData.address.country,
region: validHotels?.[0].hotelData.address.city,
const reservationParams = {
selectHotelParams,
searchParams,
adultsParams,
childrenParams,
child,
}
return (
<>
<header className={styles.header}>
<Suspense fallback={<BreadcrumbsSkeleton />}>
<Breadcrumbs breadcrumbs={breadcrumbs} />
</Suspense>
<div className={styles.title}>
<div className={styles.cityInformation}>
<Subtitle>{city.name}</Subtitle>
<HotelCount />
</div>
<div className={styles.sorter}>
<HotelSorter discreet />
</div>
</div>
<MobileMapButtonContainer filters={filterList} />
</header>
<main className={styles.main}>
<div className={styles.sideBar}>
{hotels.length > 0 ? ( // TODO: Temp fix until API returns hotels that are not available
<Link
className={styles.link}
color="burgundy"
href={selectHotelMap(params.lang)}
keepSearchParams
>
<div className={styles.mapContainer}>
<StaticMap
city={searchParams.city}
country={isCityWithCountry(city) ? city.country : undefined}
width={340}
height={180}
zoomLevel={11}
mapType="roadmap"
altText={`Map of ${searchParams.city} city center`}
/>
<Button wrapping size="medium" intent="text" theme="base">
{intl.formatMessage({ id: "See map" })}
<ChevronRightIcon
color="baseButtonTextOnFillNormal"
width={20}
height={20}
/>
</Button>
</div>
</Link>
) : (
<div className={styles.mapContainer}>
<StaticMap
city={searchParams.city}
width={340}
height={180}
zoomLevel={11}
mapType="roadmap"
altText={`Map of ${searchParams.city} city center`}
/>
</div>
)}
<HotelFilter filters={filterList} className={styles.filter} />
</div>
<div className={styles.hotelList}>
{isAllUnavailable && (
<Alert
type={AlertTypeEnum.Info}
heading={intl.formatMessage({ id: "No availability" })}
text={intl.formatMessage({
id: "There are no rooms available that match your request.",
})}
/>
)}
<HotelCardListing hotelData={validHotels} />
</div>
<Suspense fallback={null}>
<TrackingSDK
pageData={pageTrackingData}
hotelInfo={hotelsTrackingData}
/>
</Suspense>
</main>
</>
<Suspense
key={`${city.name}-${searchParams.fromDate}-${searchParams.toDate}-${adultsParams}-${childrenParams}`}
fallback={<SelectHotelSkeleton />}
>
<SelectHotel
city={city}
params={params}
reservationParams={reservationParams}
/>
</Suspense>
)
}

View File

@@ -1,7 +1,7 @@
import { Dayjs } from "dayjs"
import { dt } from "@/lib/dt"
import type { Dayjs } from "dayjs"
/**
* Get valid dates from stringFromDate and stringToDate making sure that they are not in the past and chronologically correct
* @example const { fromDate, toDate} = getValidDates("2021-01-01", "2021-01-02")

View File

@@ -17,12 +17,10 @@
@media screen and (min-width: 1367px) {
.container {
width: var(--max-width-page);
grid-template-columns: 1fr 340px;
grid-template-rows: auto 1fr;
width: var(--max-width-page);
margin: var(--Spacing-x5) auto 0;
/* simulates padding on viewport smaller than --max-width-navigation */
}
.content {

View File

@@ -35,12 +35,11 @@ import EnterDetailsTracking from "./enterDetailsTracking"
import styles from "./page.module.css"
import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums"
import { SelectRateSearchParams } from "@/types/components/hotelReservation/selectRate/selectRate"
import {
import type { SelectRateSearchParams } from "@/types/components/hotelReservation/selectRate/selectRate"
import type {
TrackingChannelEnum,
TrackingSDKHotelInfo,
TrackingSDKPageData,
} from "@/types/components/tracking"
TrackingSDKPageData} from "@/types/components/tracking";
import { StepEnum } from "@/types/enums/step"
import type { LangParams, PageArgs } from "@/types/params"

View File

@@ -1,4 +1,4 @@
import { NextRequest, NextResponse } from "next/server"
import { type NextRequest, NextResponse } from "next/server"
import { AuthError } from "next-auth"
import { Lang } from "@/constants/languages"
@@ -117,7 +117,7 @@ export async function GET(
/** Record<string, any> is next-auth typings */
const params: Record<string, any> = {
ui_locales: context.params.lang,
scope: ["openid", "profile"],
scope: ["openid", "profile", "booking"],
/**
* The `acr_values` param is used to make Curity display the proper login
* page for Scandic. Without the parameter Curity presents some choices

View File

@@ -1,14 +1,13 @@
import { NextRequest, NextResponse } from "next/server"
import { type NextRequest, NextResponse } from "next/server"
import { AuthError } from "next-auth"
import { Lang } from "@/constants/languages"
import { login } from "@/constants/routes/handleAuth"
import { env } from "@/env/server"
import { badRequest, internalServerError } from "@/server/errors/next"
import { getPublicURL } from "@/server/utils"
import { signIn } from "@/auth"
import type { Lang } from "@/constants/languages"
export async function GET(
request: NextRequest,
context: { params: { lang: Lang } }

View File

@@ -2,7 +2,7 @@ import { env } from "@/env/server"
import BookingWidget, { preload } from "@/components/BookingWidget"
import { PageArgs } from "@/types/params"
import type { PageArgs } from "@/types/params"
export default async function BookingWidgetPage({
searchParams,

View File

@@ -3,7 +3,7 @@ import { serverClient } from "@/lib/trpc/server"
import BookingWidget, { preload } from "@/components/BookingWidget"
import { PageArgs } from "@/types/params"
import type { PageArgs } from "@/types/params"
export default async function BookingWidgetPage({
searchParams,

View File

@@ -4,7 +4,7 @@ import CurrentFooter from "@/components/Current/Footer"
import Footer, { preload } from "@/components/Footer"
import { setLang } from "@/i18n/serverContext"
import { LangParams, PageArgs } from "@/types/params"
import type { LangParams, PageArgs } from "@/types/params"
export default function FooterSlot({ params }: PageArgs<LangParams>) {
setLang(params.lang)

View File

@@ -7,7 +7,7 @@ import HeaderFallback from "@/components/Current/Header/HeaderFallback"
import Header from "@/components/Header"
import { setLang } from "@/i18n/serverContext"
import { LangParams, PageArgs } from "@/types/params"
import type { LangParams, PageArgs } from "@/types/params"
export default function HeaderPage({ params }: PageArgs<LangParams>) {
setLang(params.lang)

View File

@@ -16,7 +16,7 @@ import { findLang } from "@/utils/languages"
import styles from "./error.module.css"
import { LangParams } from "@/types/params"
import type { LangParams } from "@/types/params"
export default function Error({
error,

View File

@@ -3,7 +3,6 @@ import "@scandic-hotels/design-system/style.css"
import Script from "next/script"
import { env } from "@/env/server"
import TrpcProvider from "@/lib/trpc/Provider"
import TokenRefresher from "@/components/Auth/TokenRefresher"

View File

@@ -1,7 +1,7 @@
import NotFound from "@/components/Current/NotFound"
import { setLang } from "@/i18n/serverContext"
import { LangParams, PageArgs } from "@/types/params"
import type { LangParams, PageArgs } from "@/types/params"
export default function NotFoundPage({ params }: PageArgs<LangParams>) {
setLang(params.lang)

View File

@@ -2,7 +2,7 @@ import { setLang } from "@/i18n/serverContext"
import styles from "./page.module.css"
import { LangParams, LayoutArgs, StatusParams } from "@/types/params"
import type { LangParams, LayoutArgs, StatusParams } from "@/types/params"
export default function MiddlewareError({
params,