Merged in chore/move-enter-details (pull request #2778)
Chore/move enter details Approved-by: Anton Gunnarsson
This commit is contained in:
@@ -2,6 +2,7 @@ import { notFound } from "next/navigation"
|
||||
import { Suspense } from "react"
|
||||
|
||||
import { safeTry } from "@scandic-hotels/common/utils/safeTry"
|
||||
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
|
||||
|
||||
import { env } from "../../env/server"
|
||||
import { MapContainer } from "../components/MapContainer"
|
||||
@@ -19,24 +20,15 @@ import { getCityCoordinates } from "../trpc/memoizedRequests/getCityCoordinates"
|
||||
import { parseSelectHotelSearchParams } from "../utils/url"
|
||||
|
||||
import type { Lang } from "@scandic-hotels/common/constants/language"
|
||||
import type {
|
||||
TrackingSDKHotelInfo,
|
||||
TrackingSDKPageData,
|
||||
} from "@scandic-hotels/common/tracking/types"
|
||||
|
||||
import type { NextSearchParams } from "../types"
|
||||
|
||||
export async function AlternativeHotelsMapPage({
|
||||
lang,
|
||||
searchParams,
|
||||
renderTracking,
|
||||
}: {
|
||||
lang: Lang
|
||||
searchParams: NextSearchParams
|
||||
renderTracking: (trackingProps: {
|
||||
hotelsTrackingData: TrackingSDKHotelInfo
|
||||
pageTrackingData: TrackingSDKPageData
|
||||
}) => React.ReactNode
|
||||
}) {
|
||||
const googleMapId = env.GOOGLE_DYNAMIC_MAP_ID
|
||||
const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY
|
||||
@@ -127,7 +119,10 @@ export async function AlternativeHotelsMapPage({
|
||||
isAlternativeHotels={true}
|
||||
filterList={filterList}
|
||||
/>
|
||||
{renderTracking({ hotelsTrackingData, pageTrackingData })}
|
||||
<TrackingSDK
|
||||
hotelInfo={hotelsTrackingData}
|
||||
pageData={pageTrackingData}
|
||||
/>
|
||||
</Suspense>
|
||||
</MapContainer>
|
||||
)
|
||||
|
||||
@@ -4,6 +4,7 @@ import { notFound } from "next/navigation"
|
||||
import { Suspense } from "react"
|
||||
|
||||
import { FamilyAndFriendsCodes } from "@scandic-hotels/common/constants/familyAndFriends"
|
||||
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
|
||||
|
||||
import { AlternativeHotelsPageTitle } from "../components/AlternativeHotelsPageTitle"
|
||||
import FnFNotAllowedAlert from "../components/FnFNotAllowedAlert"
|
||||
@@ -14,24 +15,15 @@ import { getSelectHotelTracking } from "../misc/selectHotelTracking"
|
||||
import { parseSelectHotelSearchParams } from "../utils/url"
|
||||
|
||||
import type { Lang } from "@scandic-hotels/common/constants/language"
|
||||
import type {
|
||||
TrackingSDKHotelInfo,
|
||||
TrackingSDKPageData,
|
||||
} from "@scandic-hotels/common/tracking/types"
|
||||
|
||||
import type { NextSearchParams } from "../types"
|
||||
|
||||
export async function AlternativeHotelsPage({
|
||||
lang,
|
||||
searchParams,
|
||||
renderTracking,
|
||||
}: {
|
||||
lang: Lang
|
||||
searchParams: NextSearchParams
|
||||
renderTracking: (trackingProps: {
|
||||
hotelsTrackingData: TrackingSDKHotelInfo
|
||||
pageTrackingData: TrackingSDKPageData
|
||||
}) => React.ReactNode
|
||||
}) {
|
||||
const booking = parseSelectHotelSearchParams(searchParams)
|
||||
|
||||
@@ -130,7 +122,10 @@ export async function AlternativeHotelsPage({
|
||||
lang={lang}
|
||||
/>
|
||||
<Suspense key={`${suspenseKey}-tracking`} fallback={null}>
|
||||
{renderTracking({ hotelsTrackingData, pageTrackingData })}
|
||||
<TrackingSDK
|
||||
hotelInfo={hotelsTrackingData}
|
||||
pageData={pageTrackingData}
|
||||
/>
|
||||
</Suspense>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { cookies } from "next/headers"
|
||||
import { notFound, redirect } from "next/navigation"
|
||||
|
||||
import { MEMBERSHIP_FAILED_ERROR } from "@scandic-hotels/common/constants/booking"
|
||||
import { decrypt } from "@scandic-hotels/trpc/utils/encryption"
|
||||
|
||||
import { BookingConfirmation } from "../components/BookingConfirmation"
|
||||
import { getBookingConfirmation } from "../trpc/memoizedRequests/getBookingConfirmation"
|
||||
import { MEMBERSHIP_FAILED_ERROR } from "../types/membershipFailedError"
|
||||
|
||||
import type { Lang } from "@scandic-hotels/common/constants/language"
|
||||
import type { BookingConfirmation as BookingConfirmationType } from "@scandic-hotels/trpc/types/bookingConfirmation"
|
||||
|
||||
46
packages/booking-flow/lib/pages/EnterDetailsPage.module.css
Normal file
46
packages/booking-flow/lib/pages/EnterDetailsPage.module.css
Normal file
@@ -0,0 +1,46 @@
|
||||
.container {
|
||||
display: grid;
|
||||
gap: var(--Spacing-x3) var(--Spacing-x9);
|
||||
}
|
||||
|
||||
.content {
|
||||
width: var(--max-width-page);
|
||||
margin: var(--Spacing-x3) auto 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--Spacing-x4);
|
||||
}
|
||||
|
||||
.header {
|
||||
padding-bottom: var(--Spacing-x3);
|
||||
}
|
||||
|
||||
.summary {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1367px) {
|
||||
.container {
|
||||
grid-template-columns: 1fr 340px;
|
||||
grid-template-rows: auto 1fr;
|
||||
width: var(--max-width-page);
|
||||
margin: var(--Spacing-x5) auto 0;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
margin: var(--Spacing-x3) 0 0;
|
||||
}
|
||||
|
||||
.summary {
|
||||
position: static;
|
||||
display: grid;
|
||||
grid-column: 2/3;
|
||||
grid-row: 1/-1;
|
||||
z-index: unset;
|
||||
}
|
||||
}
|
||||
168
packages/booking-flow/lib/pages/EnterDetailsPage.tsx
Normal file
168
packages/booking-flow/lib/pages/EnterDetailsPage.tsx
Normal file
@@ -0,0 +1,168 @@
|
||||
import { cookies } from "next/headers"
|
||||
import { notFound } from "next/navigation"
|
||||
import { Suspense } from "react"
|
||||
|
||||
import { FamilyAndFriendsCodes } from "@scandic-hotels/common/constants/familyAndFriends"
|
||||
|
||||
import HotelHeader from "../components/EnterDetails/Header"
|
||||
import Payment from "../components/EnterDetails/Payment"
|
||||
import Multiroom from "../components/EnterDetails/Room/Multiroom"
|
||||
import RoomOne from "../components/EnterDetails/Room/One"
|
||||
import DesktopSummary from "../components/EnterDetails/Summary/Desktop"
|
||||
import MobileSummary from "../components/EnterDetails/Summary/Mobile"
|
||||
import EnterDetailsTrackingWrapper from "../components/EnterDetails/Tracking"
|
||||
import FnFNotAllowedAlert from "../components/FnFNotAllowedAlert"
|
||||
import EnterDetailsProvider from "../contexts/EnterDetails/EnterDetailsContext"
|
||||
import { RoomProvider } from "../contexts/EnterDetails/RoomContext"
|
||||
import { getBreakfastPackages } from "../trpc/memoizedRequests/getBreakfastPackages"
|
||||
import { getHotel } from "../trpc/memoizedRequests/getHotel"
|
||||
import { getProfileSafely } from "../trpc/memoizedRequests/getProfile"
|
||||
import { getSelectedRoomsAvailabilityEnterDetails } from "../trpc/memoizedRequests/getSelectedRoomsAvailabilityEnterDetails"
|
||||
import { parseDetailsSearchParams } from "../utils/url"
|
||||
|
||||
import styles from "./EnterDetailsPage.module.css"
|
||||
|
||||
import type { Lang } from "@scandic-hotels/common/constants/language"
|
||||
|
||||
import type { NextSearchParams } from "../types"
|
||||
|
||||
export async function EnterDetailsPage({
|
||||
lang,
|
||||
searchParams,
|
||||
}: {
|
||||
lang: Lang
|
||||
searchParams: NextSearchParams
|
||||
}) {
|
||||
const selectRoomParams = new URLSearchParams(
|
||||
searchParams as Record<string, string>
|
||||
)
|
||||
|
||||
const booking = parseDetailsSearchParams(searchParams)
|
||||
|
||||
if (!booking) return notFound()
|
||||
|
||||
if (selectRoomParams.has("activeRoomIndex")) {
|
||||
selectRoomParams.delete("activeRoomIndex")
|
||||
}
|
||||
|
||||
if (
|
||||
booking.bookingCode &&
|
||||
FamilyAndFriendsCodes.includes(booking.bookingCode)
|
||||
) {
|
||||
const cookieStore = await cookies()
|
||||
const isInValidFNF = cookieStore.get("sc")?.value !== "1"
|
||||
|
||||
if (isInValidFNF) {
|
||||
return <FnFNotAllowedAlert />
|
||||
}
|
||||
}
|
||||
|
||||
const breakfastInput = {
|
||||
adults: 1,
|
||||
fromDate: booking.fromDate,
|
||||
hotelId: booking.hotelId,
|
||||
toDate: booking.toDate,
|
||||
}
|
||||
const hotelInput = {
|
||||
hotelId: booking.hotelId,
|
||||
// TODO: Remove this from input since it forces
|
||||
// waterfalls for no other reason than to
|
||||
// set merchantInformationData.alternatePaymentOptions
|
||||
// to an empty array
|
||||
isCardOnlyPayment: false,
|
||||
language: lang,
|
||||
}
|
||||
const getHotelPromise = getHotel(hotelInput)
|
||||
const getBreakfastPackagesPromise = getBreakfastPackages(breakfastInput)
|
||||
const getProfilePromise = getProfileSafely()
|
||||
|
||||
const rooms = await getSelectedRoomsAvailabilityEnterDetails({
|
||||
booking,
|
||||
lang,
|
||||
})
|
||||
|
||||
const hotelData = await getHotelPromise
|
||||
|
||||
if (!hotelData || !rooms.length) {
|
||||
return notFound()
|
||||
}
|
||||
|
||||
const breakfastPackages = await getBreakfastPackagesPromise
|
||||
const user = await getProfilePromise
|
||||
|
||||
const isCardOnlyPayment = rooms.some((room) => room.mustBeGuaranteed)
|
||||
const { hotel } = hotelData
|
||||
// TODO: Temp fix to avoid waterfall fetch and moving this
|
||||
// logic from the route here for now
|
||||
if (isCardOnlyPayment) {
|
||||
hotel.merchantInformationData.alternatePaymentOptions = []
|
||||
}
|
||||
|
||||
const firstRoom = rooms[0]
|
||||
const multirooms = rooms.slice(1)
|
||||
|
||||
const { rateDefinition, rateDefinitionMember } = firstRoom.roomRate
|
||||
if (user && rateDefinitionMember) {
|
||||
const rateCode = selectRoomParams.get("room[0].ratecode")
|
||||
if (rateDefinitionMember.rateCode !== rateCode) {
|
||||
booking.rooms[0].rateCode = rateDefinitionMember.rateCode
|
||||
selectRoomParams.set("room[0].ratecode", rateDefinitionMember.rateCode)
|
||||
booking.rooms[0].counterRateCode = rateDefinition.rateCode
|
||||
selectRoomParams.set("room[0].counterratecode", rateDefinition.rateCode)
|
||||
}
|
||||
}
|
||||
|
||||
// attribute data-footer-spacing used to add spacing
|
||||
// beneath footer to be able to show entire footer upon
|
||||
// scrolling down to the bottom of the page
|
||||
return (
|
||||
<main data-footer-spacing>
|
||||
<EnterDetailsProvider
|
||||
booking={booking}
|
||||
breakfastPackages={breakfastPackages}
|
||||
lang={lang}
|
||||
rooms={rooms}
|
||||
searchParamsStr={selectRoomParams.toString()}
|
||||
user={user}
|
||||
vat={hotel.vat}
|
||||
roomCategories={hotelData.roomCategories}
|
||||
>
|
||||
<HotelHeader hotelData={hotelData} />
|
||||
<div className={styles.container}>
|
||||
<div className={styles.content}>
|
||||
<RoomProvider idx={0} room={firstRoom}>
|
||||
<RoomOne user={user} />
|
||||
</RoomProvider>
|
||||
{multirooms.map((room, idx) => (
|
||||
// Need to start idx from 1 since first room is
|
||||
// rendered above
|
||||
<RoomProvider key={idx + 1} idx={idx + 1} room={room}>
|
||||
<Multiroom />
|
||||
</RoomProvider>
|
||||
))}
|
||||
<Suspense>
|
||||
<Payment
|
||||
otherPaymentOptions={
|
||||
hotel.merchantInformationData.alternatePaymentOptions
|
||||
}
|
||||
supportedCards={hotel.merchantInformationData.cards}
|
||||
/>
|
||||
</Suspense>
|
||||
</div>
|
||||
<aside className={styles.summary}>
|
||||
<MobileSummary isUserLoggedIn={!!user} />
|
||||
<DesktopSummary isUserLoggedIn={!!user} />
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
<EnterDetailsTrackingWrapper
|
||||
booking={booking}
|
||||
hotel={hotel}
|
||||
isMember={!!user}
|
||||
lang={lang}
|
||||
rooms={rooms}
|
||||
/>
|
||||
</EnterDetailsProvider>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import { notFound } from "next/navigation"
|
||||
import { Suspense } from "react"
|
||||
|
||||
import { safeTry } from "@scandic-hotels/common/utils/safeTry"
|
||||
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
|
||||
|
||||
import { env } from "../../env/server"
|
||||
import { MapContainer } from "../components/MapContainer"
|
||||
@@ -20,24 +21,15 @@ import { getCityCoordinates } from "../trpc/memoizedRequests/getCityCoordinates"
|
||||
import { parseSelectHotelSearchParams } from "../utils/url"
|
||||
|
||||
import type { Lang } from "@scandic-hotels/common/constants/language"
|
||||
import type {
|
||||
TrackingSDKHotelInfo,
|
||||
TrackingSDKPageData,
|
||||
} from "@scandic-hotels/common/tracking/types"
|
||||
|
||||
import type { NextSearchParams } from "../types"
|
||||
|
||||
export async function SelectHotelMapPage({
|
||||
lang,
|
||||
searchParams,
|
||||
renderTracking,
|
||||
}: {
|
||||
lang: Lang
|
||||
searchParams: NextSearchParams
|
||||
renderTracking: (trackingProps: {
|
||||
hotelsTrackingData: TrackingSDKHotelInfo
|
||||
pageTrackingData: TrackingSDKPageData
|
||||
}) => React.ReactNode
|
||||
}) {
|
||||
const googleMapId = env.GOOGLE_DYNAMIC_MAP_ID
|
||||
const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY
|
||||
@@ -129,7 +121,10 @@ export async function SelectHotelMapPage({
|
||||
isBookingCodeRateAvailable={isBookingCodeRateAvailable}
|
||||
filterList={filterList}
|
||||
/>
|
||||
{renderTracking({ hotelsTrackingData, pageTrackingData })}
|
||||
<TrackingSDK
|
||||
hotelInfo={hotelsTrackingData}
|
||||
pageData={pageTrackingData}
|
||||
/>
|
||||
</Suspense>
|
||||
</MapContainer>
|
||||
)
|
||||
|
||||
@@ -4,6 +4,7 @@ import { notFound } from "next/navigation"
|
||||
import { Suspense } from "react"
|
||||
|
||||
import { FamilyAndFriendsCodes } from "@scandic-hotels/common/constants/familyAndFriends"
|
||||
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
|
||||
|
||||
import FnFNotAllowedAlert from "../components/FnFNotAllowedAlert"
|
||||
import { SelectHotel } from "../components/SelectHotel"
|
||||
@@ -13,24 +14,15 @@ import { getSelectHotelTracking } from "../misc/selectHotelTracking"
|
||||
import { parseSelectHotelSearchParams } from "../utils/url"
|
||||
|
||||
import type { Lang } from "@scandic-hotels/common/constants/language"
|
||||
import type {
|
||||
TrackingSDKHotelInfo,
|
||||
TrackingSDKPageData,
|
||||
} from "@scandic-hotels/common/tracking/types"
|
||||
|
||||
import type { NextSearchParams } from "../types"
|
||||
|
||||
export async function SelectHotelPage({
|
||||
lang,
|
||||
searchParams,
|
||||
renderTracking,
|
||||
}: {
|
||||
lang: Lang
|
||||
searchParams: NextSearchParams
|
||||
renderTracking: (trackingProps: {
|
||||
hotelsTrackingData: TrackingSDKHotelInfo
|
||||
pageTrackingData: TrackingSDKPageData
|
||||
}) => React.ReactNode
|
||||
}) {
|
||||
const booking = parseSelectHotelSearchParams(searchParams)
|
||||
|
||||
@@ -113,7 +105,10 @@ export async function SelectHotelPage({
|
||||
lang={lang}
|
||||
/>
|
||||
<Suspense key={`${suspenseKey}-tracking`} fallback={null}>
|
||||
{renderTracking({ hotelsTrackingData, pageTrackingData })}
|
||||
<TrackingSDK
|
||||
hotelInfo={hotelsTrackingData}
|
||||
pageData={pageTrackingData}
|
||||
/>
|
||||
</Suspense>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { notFound } from "next/navigation"
|
||||
|
||||
import { logger } from "@scandic-hotels/common/logger"
|
||||
import { TrackingSDK } from "@scandic-hotels/tracking/TrackingSDK"
|
||||
import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking"
|
||||
|
||||
import { SelectRate } from "../components/SelectRate"
|
||||
@@ -11,10 +12,6 @@ import { getHotel } from "../trpc/memoizedRequests"
|
||||
import { parseSelectRateSearchParams } from "../utils/url"
|
||||
|
||||
import type { Lang } from "@scandic-hotels/common/constants/language"
|
||||
import type {
|
||||
TrackingSDKHotelInfo,
|
||||
TrackingSDKPageData,
|
||||
} from "@scandic-hotels/common/tracking/types"
|
||||
|
||||
import type { NextSearchParams } from "../types"
|
||||
|
||||
@@ -31,14 +28,9 @@ const singleRoomRateTypes = combineRegExps(
|
||||
export async function SelectRatePage({
|
||||
lang,
|
||||
searchParams,
|
||||
renderTracking,
|
||||
}: {
|
||||
lang: Lang
|
||||
searchParams: NextSearchParams
|
||||
renderTracking: (trackingProps: {
|
||||
hotelsTrackingData: TrackingSDKHotelInfo
|
||||
pageTrackingData: TrackingSDKPageData
|
||||
}) => React.ReactNode
|
||||
}) {
|
||||
const booking = parseSelectRateSearchParams(searchParams)
|
||||
|
||||
@@ -104,7 +96,7 @@ export async function SelectRatePage({
|
||||
<SelectRateProvider hotelData={hotelData}>
|
||||
<SelectRate hotelData={hotelData} booking={booking} />
|
||||
</SelectRateProvider>
|
||||
{renderTracking({ hotelsTrackingData, pageTrackingData })}
|
||||
<TrackingSDK hotelInfo={hotelsTrackingData} pageData={pageTrackingData} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user