Merged in feat/sw-2874-move-select-rate (pull request #2750)
Approved-by: Joakim Jäderberg
This commit is contained in:
@@ -1,4 +1,24 @@
|
||||
export default async function SelectRatePage() {
|
||||
// eslint-disable-next-line formatjs/no-literal-string-in-jsx
|
||||
return <div>select-rate</div>
|
||||
import { SelectRatePage as SelectRatePagePrimitive } from "@scandic-hotels/booking-flow/pages/SelectRatePage"
|
||||
|
||||
import TrackingSDK from "@/components/TrackingSDK"
|
||||
import { getLang } from "@/i18n/serverContext"
|
||||
|
||||
import { type LangParams, type PageArgs } from "@/types/params"
|
||||
|
||||
export default async function SelectRatePage(props: PageArgs<LangParams>) {
|
||||
const searchParams = await props.searchParams
|
||||
const lang = await getLang()
|
||||
|
||||
return (
|
||||
<SelectRatePagePrimitive
|
||||
lang={lang}
|
||||
searchParams={searchParams}
|
||||
renderTracking={(props) => (
|
||||
<TrackingSDK
|
||||
hotelInfo={props.hotelsTrackingData}
|
||||
pageData={props.pageTrackingData}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import "../../globals.css"
|
||||
|
||||
import { BookingFlowContextProvider } from "@scandic-hotels/booking-flow/BookingFlowContextProvider"
|
||||
import { BookingFlowTrackingProvider } from "@scandic-hotels/booking-flow/BookingFlowTrackingProvider"
|
||||
import { NuqsAdapter } from "@scandic-hotels/booking-flow/utils/nuqs"
|
||||
import { Lang } from "@scandic-hotels/common/constants/language"
|
||||
import { TrpcProvider } from "@scandic-hotels/trpc/Provider"
|
||||
|
||||
@@ -62,6 +63,7 @@ export default async function RootLayout(props: RootLayoutProps) {
|
||||
locale={lang}
|
||||
messages={messages}
|
||||
>
|
||||
<NuqsAdapter>
|
||||
{/* TODO handle onError */}
|
||||
<TrpcProvider>
|
||||
<BookingFlowContextProvider
|
||||
@@ -96,6 +98,7 @@ export default async function RootLayout(props: RootLayoutProps) {
|
||||
</BookingFlowTrackingProvider>
|
||||
</BookingFlowContextProvider>
|
||||
</TrpcProvider>
|
||||
</NuqsAdapter>
|
||||
</ClientIntlProvider>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// import { BedTypeEnum } from "@/constants/booking"
|
||||
|
||||
// import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums"
|
||||
// import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast"
|
||||
// import type { BreakfastPackage } from "@scandic-hotels/trpc/routers/hotels/schemas/packages"
|
||||
// import type { BedTypeSelection } from "@/types/components/hotelReservation/enterDetails/bedType"
|
||||
// import type {
|
||||
// DetailsSchema,
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
import { HotelInfoCardSkeleton } from "@scandic-hotels/design-system/HotelInfoCard"
|
||||
|
||||
import { RoomsContainerSkeleton } from "@/components/HotelReservation/SelectRate/RoomsContainer/RoomsContainerSkeleton"
|
||||
import { SelectRateSkeleton } from "@scandic-hotels/booking-flow/components/SelectRate"
|
||||
|
||||
export default function LoadingSelectRate() {
|
||||
return (
|
||||
<>
|
||||
<HotelInfoCardSkeleton />
|
||||
<RoomsContainerSkeleton />
|
||||
</>
|
||||
)
|
||||
return <SelectRateSkeleton />
|
||||
}
|
||||
|
||||
@@ -1,68 +1,30 @@
|
||||
import { notFound } from "next/navigation"
|
||||
import { SelectRatePage as SelectRatePagePrimitive } from "@scandic-hotels/booking-flow/pages/SelectRatePage"
|
||||
|
||||
import { SelectRateProvider } from "@scandic-hotels/booking-flow/contexts/SelectRate/SelectRateContext"
|
||||
import { parseSelectRateSearchParams } from "@scandic-hotels/booking-flow/utils/url"
|
||||
import { logger } from "@scandic-hotels/common/logger"
|
||||
import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking"
|
||||
import TrackingSDK from "@/components/TrackingSDK"
|
||||
import { getLang } from "@/i18n/serverContext"
|
||||
|
||||
import { combineRegExps, rateTypeRegex } from "@/constants/booking"
|
||||
import { getHotel } from "@/lib/trpc/memoizedRequests"
|
||||
|
||||
import SelectRate from "@/components/HotelReservation/SelectRate"
|
||||
|
||||
import type { LangParams, NextSearchParams, PageArgs } from "@/types/params"
|
||||
|
||||
const singleRoomRateTypes = combineRegExps(
|
||||
[rateTypeRegex.ARB, rateTypeRegex.VOUCHER],
|
||||
"i"
|
||||
)
|
||||
import {
|
||||
type LangParams,
|
||||
type NextSearchParams,
|
||||
type PageArgs,
|
||||
} from "@/types/params"
|
||||
|
||||
export default async function SelectRatePage(
|
||||
props: PageArgs<LangParams & { section: string }, NextSearchParams>
|
||||
props: PageArgs<LangParams, NextSearchParams>
|
||||
) {
|
||||
const params = await props.params
|
||||
const searchParams = await props.searchParams
|
||||
const booking = parseSelectRateSearchParams(searchParams)
|
||||
|
||||
if (!booking) {
|
||||
logger.debug("Invalid search params", searchParams)
|
||||
notFound()
|
||||
}
|
||||
|
||||
const isMultiRoom = booking.rooms.length > 1
|
||||
const isRedemption = booking.searchType === SEARCH_TYPE_REDEMPTION
|
||||
const isArbOrVoucher = booking.bookingCode
|
||||
? singleRoomRateTypes.test(booking.bookingCode)
|
||||
: false
|
||||
|
||||
if ((isMultiRoom && isRedemption) || (isMultiRoom && isArbOrVoucher)) {
|
||||
logger.debug(
|
||||
"Invalid search params, can't have multiroom and redemption/voucher",
|
||||
{ isMultiRoom, isRedemption, isArbOrVoucher }
|
||||
)
|
||||
notFound()
|
||||
}
|
||||
|
||||
// If someone tries to update the url with
|
||||
// a bookingCode also, then we need to remove it
|
||||
if (isRedemption && searchParams.bookingCode) {
|
||||
delete searchParams.bookingCode
|
||||
}
|
||||
|
||||
const hotelData = await getHotel({
|
||||
hotelId: booking.hotelId,
|
||||
isCardOnlyPayment: false,
|
||||
language: params.lang,
|
||||
})
|
||||
|
||||
if (!hotelData) {
|
||||
logger.debug("Unable to find hotel data")
|
||||
notFound()
|
||||
}
|
||||
const lang = await getLang()
|
||||
|
||||
return (
|
||||
<SelectRateProvider hotelData={hotelData}>
|
||||
<SelectRate hotelData={hotelData} booking={booking} />
|
||||
</SelectRateProvider>
|
||||
<SelectRatePagePrimitive
|
||||
lang={lang}
|
||||
searchParams={searchParams}
|
||||
renderTracking={(props) => (
|
||||
<TrackingSDK
|
||||
hotelInfo={props.hotelsTrackingData}
|
||||
pageData={props.pageTrackingData}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ import "@scandic-hotels/design-system/style.css"
|
||||
import { ReactQueryDevtools } from "@tanstack/react-query-devtools"
|
||||
import Script from "next/script"
|
||||
import { SessionProvider } from "next-auth/react"
|
||||
import { NuqsAdapter } from "nuqs/adapters/next/app"
|
||||
|
||||
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"
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@ import "@scandic-hotels/design-system/style.css"
|
||||
import { ReactQueryDevtools } from "@tanstack/react-query-devtools"
|
||||
import Script from "next/script"
|
||||
import { SessionProvider } from "next-auth/react"
|
||||
import { NuqsAdapter } from "nuqs/adapters/next/app"
|
||||
|
||||
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"
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ import "@scandic-hotels/design-system/style.css"
|
||||
|
||||
import { ReactQueryDevtools } from "@tanstack/react-query-devtools"
|
||||
import Script from "next/script"
|
||||
import { NuqsAdapter } from "nuqs/adapters/next/app"
|
||||
|
||||
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"
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@ import "@scandic-hotels/design-system/style.css"
|
||||
import "@scandic-hotels/design-system/design-system-new-deprecated.css"
|
||||
|
||||
import Script from "next/script"
|
||||
import { NuqsAdapter } from "nuqs/adapters/next/app"
|
||||
|
||||
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"
|
||||
|
||||
|
||||
@@ -46,8 +46,6 @@ export class ErrorBoundary extends React.Component<
|
||||
)}
|
||||
</>
|
||||
)
|
||||
|
||||
return this.props.fallback
|
||||
}
|
||||
|
||||
return this.props.children
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
"use client"
|
||||
import PriceDetailsModal from "@scandic-hotels/booking-flow/components/PriceDetailsModal"
|
||||
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
||||
import { dt } from "@scandic-hotels/common/dt"
|
||||
|
||||
import { useBookingConfirmationStore } from "@/stores/booking-confirmation"
|
||||
|
||||
import PriceDetailsModal from "@/components/HotelReservation/PriceDetailsModal"
|
||||
|
||||
import { mapToPrice } from "./mapToPrice"
|
||||
|
||||
import type { Price } from "@/types/components/hotelReservation/price"
|
||||
|
||||
@@ -2,13 +2,13 @@ import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast"
|
||||
import { ChildBedMapEnum } from "@scandic-hotels/trpc/enums/childBedMapEnum"
|
||||
import { PackageTypeEnum } from "@scandic-hotels/trpc/enums/packages"
|
||||
import {
|
||||
type BreakfastPackage,
|
||||
breakfastPackageSchema,
|
||||
packageSchema,
|
||||
} from "@scandic-hotels/trpc/routers/hotels/schemas/packages"
|
||||
|
||||
import type { Package } from "@scandic-hotels/trpc/types/packages"
|
||||
|
||||
import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast"
|
||||
import type { Room } from "@/types/stores/booking-confirmation"
|
||||
|
||||
export function mapToPrice(rooms: (Room | null)[], nights: number) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { RoomDetailsSidePeek } from "@scandic-hotels/booking-flow/components/RoomDetailsSidePeek"
|
||||
import {
|
||||
changeOrCancelDateFormat,
|
||||
longDateFormat,
|
||||
@@ -16,7 +17,6 @@ import { getHotelRoom } from "@scandic-hotels/trpc/routers/booking/helpers"
|
||||
import { CancellationRuleEnum } from "@/constants/booking"
|
||||
import { useBookingConfirmationStore } from "@/stores/booking-confirmation"
|
||||
|
||||
import RoomDetailsSidePeek from "@/components/SidePeeks/RoomDetailsSidePeek"
|
||||
import useLang from "@/hooks/useLang"
|
||||
|
||||
import styles from "./room.module.css"
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
import { z } from "zod"
|
||||
|
||||
export const bedTypeSchema = z.object({
|
||||
bedType: z.object({
|
||||
description: z.string(),
|
||||
roomTypeCode: z.string(),
|
||||
type: z.string(),
|
||||
}),
|
||||
})
|
||||
export const bedTypeFormSchema = z.object({
|
||||
bedType: z.string(),
|
||||
})
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useRouter } from "next/navigation"
|
||||
import { useTransition } from "react"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { RoomDetailsSidePeek } from "@scandic-hotels/booking-flow/components/RoomDetailsSidePeek"
|
||||
import { selectRate } from "@scandic-hotels/common/constants/routes/hotelReservation"
|
||||
import { Button } from "@scandic-hotels/design-system/Button"
|
||||
import Footnote from "@scandic-hotels/design-system/Footnote"
|
||||
@@ -13,7 +14,6 @@ import { getHotelRoom } from "@scandic-hotels/trpc/routers/booking/helpers"
|
||||
|
||||
import { useEnterDetailsStore } from "@/stores/enter-details"
|
||||
|
||||
import RoomDetailsSidePeek from "@/components/SidePeeks/RoomDetailsSidePeek"
|
||||
import { useRoomContext } from "@/contexts/Details/Room"
|
||||
import useLang from "@/hooks/useLang"
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import { type PropsWithChildren, useEffect, useRef } from "react"
|
||||
import { Button as ButtonRAC } from "react-aria-components"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { isBookingCodeRate } from "@scandic-hotels/booking-flow/components/SelectRate/RoomsContainer/RateSummary/utils"
|
||||
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
|
||||
import { Button } from "@scandic-hotels/design-system/Button"
|
||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||
@@ -14,7 +15,6 @@ import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||
import { useEnterDetailsStore } from "@/stores/enter-details"
|
||||
|
||||
import { formId } from "@/components/HotelReservation/EnterDetails/Payment/PaymentClient"
|
||||
import { isBookingCodeRate } from "@/components/HotelReservation/SelectRate/RoomsContainer/RateSummary/utils"
|
||||
|
||||
import styles from "./bottomSheet.module.css"
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
"use client"
|
||||
|
||||
import { useEnterDetailsStore } from "@/stores/enter-details"
|
||||
import SignupPromoMobile from "@scandic-hotels/booking-flow/components/SignupPromoMobile"
|
||||
|
||||
import SignupPromoMobile from "@/components/HotelReservation/SignupPromo/Mobile"
|
||||
import { useEnterDetailsStore } from "@/stores/enter-details"
|
||||
|
||||
import SummaryUI from "../UI"
|
||||
import SummaryBottomSheet from "./BottomSheet"
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||
|
||||
import styles from "./breakfast.module.css"
|
||||
|
||||
import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast"
|
||||
import type { BreakfastPackage } from "@scandic-hotels/trpc/routers/hotels/schemas/packages"
|
||||
|
||||
interface BreakfastProps {
|
||||
adults: number
|
||||
|
||||
@@ -4,6 +4,9 @@ import { cx } from "class-variance-authority"
|
||||
import { useIntl } from "react-intl"
|
||||
import { useMediaQuery } from "usehooks-ts"
|
||||
|
||||
import PriceDetailsModal from "@scandic-hotels/booking-flow/components/PriceDetailsModal"
|
||||
import { isBookingCodeRate } from "@scandic-hotels/booking-flow/components/SelectRate/RoomsContainer/RateSummary/utils"
|
||||
import SignupPromoDesktop from "@scandic-hotels/booking-flow/components/SignupPromoDesktop"
|
||||
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
||||
import { longDateFormat } from "@scandic-hotels/common/constants/dateFormats"
|
||||
import { dt } from "@scandic-hotels/common/dt"
|
||||
@@ -15,9 +18,6 @@ import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||
import Subtitle from "@scandic-hotels/design-system/Subtitle"
|
||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||
|
||||
import PriceDetailsModal from "@/components/HotelReservation/PriceDetailsModal"
|
||||
import { isBookingCodeRate } from "@/components/HotelReservation/SelectRate/RoomsContainer/RateSummary/utils"
|
||||
import SignupPromoDesktop from "@/components/HotelReservation/SignupPromo/Desktop"
|
||||
import useLang from "@/hooks/useLang"
|
||||
|
||||
import { mapToPrice } from "./mapToPrice"
|
||||
|
||||
@@ -16,6 +16,7 @@ import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter"
|
||||
import { getSpecialRoomType } from "@/utils/specialRoomType"
|
||||
|
||||
import type { Lang } from "@scandic-hotels/common/constants/language"
|
||||
import type { BreakfastPackages } from "@scandic-hotels/trpc/routers/hotels/output"
|
||||
import type { Hotel } from "@scandic-hotels/trpc/types/hotel"
|
||||
import type { Room } from "@scandic-hotels/trpc/types/room"
|
||||
import type {
|
||||
@@ -23,7 +24,6 @@ import type {
|
||||
Product,
|
||||
} from "@scandic-hotels/trpc/types/roomAvailability"
|
||||
|
||||
import type { BreakfastPackages } from "@/types/components/hotelReservation/breakfast"
|
||||
import type {
|
||||
DetailsBooking,
|
||||
RoomRate,
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
"use client"
|
||||
import PriceDetailsModal from "@scandic-hotels/booking-flow/components/PriceDetailsModal"
|
||||
import { dt } from "@scandic-hotels/common/dt"
|
||||
|
||||
import { useMyStayStore } from "@/stores/my-stay"
|
||||
|
||||
import PriceDetailsModal from "@/components/HotelReservation/PriceDetailsModal"
|
||||
|
||||
import { calculateTotalPrice, mapToPrice } from "./mapToPrice"
|
||||
|
||||
import styles from "./priceDetails.module.css"
|
||||
|
||||
@@ -11,10 +11,10 @@ import { getPriceType } from "../../utils/getPriceType"
|
||||
import { formatChildBedPreferences } from "../utils"
|
||||
|
||||
import type { RateEnum } from "@scandic-hotels/common/constants/rate"
|
||||
import type { BreakfastPackage } from "@scandic-hotels/trpc/routers/hotels/schemas/packages"
|
||||
import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConfirmation"
|
||||
import type { Room } from "@scandic-hotels/trpc/types/hotel"
|
||||
|
||||
import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast"
|
||||
import type { Room as MyStayRoom } from "@/types/stores/my-stay"
|
||||
|
||||
interface MapRoomDetailsParams {
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
"use client"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
|
||||
|
||||
import { getFeatureDescription } from "@/components/HotelReservation/utils/getRoomFeatureDescription"
|
||||
|
||||
import RegularRow from "../Regular"
|
||||
|
||||
import type { Packages as PackagesType } from "@scandic-hotels/trpc/types/packages"
|
||||
|
||||
interface PackagesProps {
|
||||
packages: PackagesType | null
|
||||
}
|
||||
|
||||
export default function PackagesRow({ packages }: PackagesProps) {
|
||||
const intl = useIntl()
|
||||
|
||||
if (!packages || !packages.length) {
|
||||
return null
|
||||
}
|
||||
|
||||
return packages?.map((pkg) => (
|
||||
<RegularRow
|
||||
key={pkg.code}
|
||||
label={getFeatureDescription(pkg.code, pkg.description, intl)}
|
||||
value={formatPrice(
|
||||
intl,
|
||||
+pkg.localPrice.totalPrice,
|
||||
pkg.localPrice.currency
|
||||
)}
|
||||
/>
|
||||
))
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
import type {
|
||||
Rate,
|
||||
Room as SelectRateRoom,
|
||||
} from "@scandic-hotels/booking-flow/types/components/selectRate/selectRate"
|
||||
|
||||
import type { Room } from "@/components/HotelReservation/PriceDetailsModal/PriceDetailsTable"
|
||||
|
||||
export function mapToPrice(
|
||||
rooms: (Rate | null)[],
|
||||
bookingRooms: SelectRateRoom[],
|
||||
isUserLoggedIn: boolean
|
||||
) {
|
||||
return rooms
|
||||
.map((room, idx) => {
|
||||
if (!room) {
|
||||
return null
|
||||
}
|
||||
|
||||
let price = null
|
||||
if ("corporateCheque" in room.product) {
|
||||
price = {
|
||||
corporateCheque: room.product.corporateCheque.localPrice,
|
||||
}
|
||||
} else if ("redemption" in room.product) {
|
||||
price = {
|
||||
redemption: room.product.redemption.localPrice,
|
||||
}
|
||||
} else if ("voucher" in room.product) {
|
||||
price = {
|
||||
voucher: room.product.voucher,
|
||||
}
|
||||
} else {
|
||||
const isMainRoom = idx === 0
|
||||
const memberRate = room.product.member
|
||||
const onlyMemberRate = !room.product.public && memberRate
|
||||
if ((isUserLoggedIn && isMainRoom && memberRate) || onlyMemberRate) {
|
||||
price = {
|
||||
regular: {
|
||||
...memberRate.localPrice,
|
||||
regularPricePerStay:
|
||||
room.product.public?.localPrice.pricePerStay ||
|
||||
memberRate.localPrice.pricePerStay,
|
||||
},
|
||||
}
|
||||
} else if (room.product.public) {
|
||||
price = {
|
||||
regular: room.product.public.localPrice,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bookingRoom = bookingRooms[idx]
|
||||
return {
|
||||
adults: bookingRoom.adults,
|
||||
bedType: undefined,
|
||||
breakfast: undefined,
|
||||
breakfastIncluded: room.product.rateDefinition.breakfastIncluded,
|
||||
childrenInRoom: bookingRoom.childrenInRoom,
|
||||
packages: room.packages,
|
||||
price,
|
||||
roomType: room.roomType,
|
||||
rateDefinition: room.product.rateDefinition,
|
||||
}
|
||||
})
|
||||
.filter((r) => !!(r && r.price)) as Room[]
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
"use client"
|
||||
|
||||
import { useSearchParams } from "next/navigation"
|
||||
import React from "react"
|
||||
|
||||
import {
|
||||
parseSelectRateSearchParams,
|
||||
searchParamsToRecord,
|
||||
} from "@scandic-hotels/booking-flow/utils/url"
|
||||
import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking"
|
||||
|
||||
import TrackingSDK from "@/components/TrackingSDK"
|
||||
import useLang from "@/hooks/useLang"
|
||||
|
||||
import { getValidDates } from "../getValidDates"
|
||||
import { getSelectRateTracking } from "./tracking"
|
||||
|
||||
export default function Tracking({
|
||||
hotelId,
|
||||
hotelName,
|
||||
country,
|
||||
city,
|
||||
}: {
|
||||
hotelId: string
|
||||
hotelName: string
|
||||
country: string
|
||||
city: string
|
||||
}) {
|
||||
const lang = useLang()
|
||||
const params = useSearchParams()
|
||||
const booking = parseSelectRateSearchParams(searchParamsToRecord(params))
|
||||
|
||||
if (!booking) return null
|
||||
|
||||
const { fromDate, toDate } = getValidDates(booking.fromDate, booking.toDate)
|
||||
|
||||
const { rooms, searchType, bookingCode, city: paramCity } = booking
|
||||
|
||||
const arrivalDate = fromDate.toDate()
|
||||
const departureDate = toDate.toDate()
|
||||
|
||||
const { hotelsTrackingData, pageTrackingData } = getSelectRateTracking({
|
||||
lang,
|
||||
arrivalDate,
|
||||
departureDate,
|
||||
hotelId,
|
||||
hotelName,
|
||||
country,
|
||||
hotelCity: city,
|
||||
paramCity,
|
||||
bookingCode,
|
||||
isRedemption: searchType === SEARCH_TYPE_REDEMPTION,
|
||||
rooms,
|
||||
})
|
||||
|
||||
return (
|
||||
<TrackingSDK pageData={pageTrackingData} hotelInfo={hotelsTrackingData} />
|
||||
)
|
||||
}
|
||||
@@ -25,12 +25,12 @@ import RoomDetails from "./RoomDetails"
|
||||
|
||||
import styles from "./bookedRoomSidePeek.module.css"
|
||||
|
||||
import type { BreakfastPackage } from "@scandic-hotels/trpc/routers/hotels/schemas/packages"
|
||||
import type { BookingConfirmationSchema } from "@scandic-hotels/trpc/types/bookingConfirmation"
|
||||
import type { Child } from "@scandic-hotels/trpc/types/child"
|
||||
import type { Room as HotelRoom } from "@scandic-hotels/trpc/types/hotel"
|
||||
import type { Packages } from "@scandic-hotels/trpc/types/packages"
|
||||
|
||||
import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast"
|
||||
import type { BedTypeSchema } from "@/types/components/hotelReservation/enterDetails/bedType"
|
||||
import type { PriceTypeEnum } from "@/types/components/hotelReservation/myStay/myStay"
|
||||
import type { SafeUser } from "@/types/user"
|
||||
|
||||
@@ -65,12 +65,3 @@ export enum PaymentCallbackStatusEnum {
|
||||
Error = "error",
|
||||
Cancel = "cancel",
|
||||
}
|
||||
|
||||
export function combineRegExps(regexps: RegExp[], flags = "") {
|
||||
return new RegExp(regexps.map((r) => r.source).join("|"), flags)
|
||||
}
|
||||
|
||||
export const rateTypeRegex = {
|
||||
ARB: /(^B[a-z]{3}\d{6}$)/,
|
||||
VOUCHER: /(^VO[0-9a-z]*$)/,
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ const nextConfig = {
|
||||
"@scandic-hotels/common",
|
||||
"@scandic-hotels/trpc",
|
||||
"@scandic-hotels/booking-flow",
|
||||
"@scandic-hotels/design-system",
|
||||
],
|
||||
experimental: {
|
||||
serverActions: {
|
||||
|
||||
@@ -40,7 +40,10 @@
|
||||
"@opentelemetry/sdk-trace-base": "^1.29.0",
|
||||
"@radix-ui/react-slot": "^1.2.2",
|
||||
"@react-aria/ssr": "^3.9.8",
|
||||
"@scandic-hotels/booking-flow": "workspace:*",
|
||||
"@scandic-hotels/common": "workspace:*",
|
||||
"@scandic-hotels/design-system": "workspace:*",
|
||||
"@scandic-hotels/trpc": "workspace:*",
|
||||
"@sentry/nextjs": "^8.41.0",
|
||||
"@swc/plugin-formatjs": "^3.2.2",
|
||||
"@t3-oss/env-nextjs": "^0.13.4",
|
||||
@@ -79,9 +82,8 @@
|
||||
"md5": "^2.3.0",
|
||||
"motion": "^12.10.0",
|
||||
"nanoid": "^5.1.5",
|
||||
"next": "15.3.3",
|
||||
"next": "15.3.4",
|
||||
"next-auth": "5.0.0-beta.27",
|
||||
"nuqs": "^2.4.3",
|
||||
"react": "19.1.0",
|
||||
"react-aria-components": "^1.8.0",
|
||||
"react-day-picker": "^9.6.7",
|
||||
@@ -105,7 +107,6 @@
|
||||
"@formatjs/cli": "^6.7.1",
|
||||
"@lokalise/node-api": "^14.0.0",
|
||||
"@react-aria/test-utils": "1.0.0-alpha.8",
|
||||
"@scandic-hotels/common": "workspace:*",
|
||||
"@scandic-hotels/typescript-config": "workspace:*",
|
||||
"@svgr/webpack": "^8.1.0",
|
||||
"@testing-library/react": "^16.3.0",
|
||||
|
||||
@@ -10,6 +10,7 @@ import { logger } from "@scandic-hotels/common/logger"
|
||||
|
||||
import { detailsStorageName } from "."
|
||||
|
||||
import type { BreakfastPackage } from "@scandic-hotels/trpc/routers/hotels/schemas/packages"
|
||||
import type { Packages } from "@scandic-hotels/trpc/types/packages"
|
||||
import type {
|
||||
CorporateChequeProduct,
|
||||
@@ -18,7 +19,6 @@ import type {
|
||||
VoucherProduct,
|
||||
} from "@scandic-hotels/trpc/types/roomAvailability"
|
||||
|
||||
import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast"
|
||||
import { type RoomRate } from "@/types/components/hotelReservation/enterDetails/details"
|
||||
import type { Price } from "@/types/components/hotelReservation/price"
|
||||
import type { PersistedState, RoomState } from "@/types/stores/enter-details"
|
||||
|
||||
@@ -17,8 +17,8 @@ import {
|
||||
} from "./helpers"
|
||||
|
||||
import type { Lang } from "@scandic-hotels/common/constants/language"
|
||||
import type { BreakfastPackages } from "@scandic-hotels/trpc/routers/hotels/output"
|
||||
|
||||
import type { BreakfastPackages } from "@/types/components/hotelReservation/breakfast"
|
||||
import type { Price } from "@/types/components/hotelReservation/price"
|
||||
import { StepEnum } from "@/types/enums/step"
|
||||
import type {
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
import type { breakfastPackagesSchema } from "@scandic-hotels/trpc/routers/hotels/output"
|
||||
import type { breakfastPackageSchema } from "@scandic-hotels/trpc/routers/hotels/schemas/packages"
|
||||
import type { z } from "zod"
|
||||
|
||||
import type { breakfastFormSchema } from "@/components/HotelReservation/EnterDetails/Breakfast/schema"
|
||||
|
||||
export interface BreakfastFormSchema
|
||||
extends z.output<typeof breakfastFormSchema> {}
|
||||
|
||||
export interface BreakfastPackages
|
||||
extends z.output<typeof breakfastPackagesSchema> {}
|
||||
|
||||
export interface BreakfastPackage
|
||||
extends z.output<typeof breakfastPackageSchema> {}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import type { z } from "zod"
|
||||
|
||||
import type {
|
||||
bedTypeFormSchema,
|
||||
bedTypeSchema,
|
||||
} from "@/components/HotelReservation/EnterDetails/BedType/schema"
|
||||
import type { bedTypeFormSchema } from "@/components/HotelReservation/EnterDetails/BedType/schema"
|
||||
|
||||
export interface BedTypeFormSchema extends z.output<typeof bedTypeFormSchema> {}
|
||||
|
||||
export type BedTypeSchema = z.output<typeof bedTypeSchema>["bedType"]
|
||||
|
||||
export type BedTypeSchema = {
|
||||
description: string
|
||||
type: string
|
||||
roomTypeCode: string
|
||||
}
|
||||
export type BedTypeInfoProps = {
|
||||
hasMultipleBedTypes: boolean
|
||||
}
|
||||
|
||||
@@ -11,12 +11,3 @@ export type RoomListItemImageProps = Pick<
|
||||
> & {
|
||||
roomPackages: Package[]
|
||||
}
|
||||
|
||||
export interface RoomSizeProps {
|
||||
roomSize:
|
||||
| {
|
||||
max: number
|
||||
min: number
|
||||
}
|
||||
| undefined
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
import type { HotelData } from "@scandic-hotels/trpc/types/hotel"
|
||||
|
||||
export interface RoomsContainerProps
|
||||
extends Pick<HotelData, "roomCategories">,
|
||||
Pick<HotelData["hotel"], "hotelType" | "vat"> {}
|
||||
@@ -1,8 +0,0 @@
|
||||
export interface SignupPromoProps {
|
||||
memberPrice: {
|
||||
amount: number
|
||||
currency: string
|
||||
}
|
||||
badgeContent?: string
|
||||
isEnterDetailsPage?: boolean
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { Lang } from "@scandic-hotels/common/constants/language"
|
||||
import type { BreakfastPackages } from "@scandic-hotels/trpc/routers/hotels/output"
|
||||
import type { RoomCategories } from "@scandic-hotels/trpc/types/hotel"
|
||||
import type { Room } from "@scandic-hotels/trpc/types/room"
|
||||
|
||||
import type { SafeUser } from "@/types/user"
|
||||
import type { BreakfastPackages } from "../components/hotelReservation/breakfast"
|
||||
import type { DetailsBooking } from "../components/hotelReservation/enterDetails/details"
|
||||
|
||||
export interface DetailsProviderProps extends React.PropsWithChildren {
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import type { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
||||
import type { BreakfastPackages } from "@scandic-hotels/trpc/routers/hotels/output"
|
||||
import type { BreakfastPackage } from "@scandic-hotels/trpc/routers/hotels/schemas/packages"
|
||||
import type { BedTypeSelection } from "@scandic-hotels/trpc/types/bedTypeSelection"
|
||||
import type { Child } from "@scandic-hotels/trpc/types/child"
|
||||
import type { RoomCategories } from "@scandic-hotels/trpc/types/hotel"
|
||||
import type { Packages } from "@scandic-hotels/trpc/types/packages"
|
||||
|
||||
import type {
|
||||
BreakfastPackage,
|
||||
BreakfastPackages,
|
||||
} from "@/types/components/hotelReservation/breakfast"
|
||||
import type { BedTypeSchema } from "@/types/components/hotelReservation/enterDetails/bedType"
|
||||
import type {
|
||||
DetailsBooking,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { BreakfastPackage } from "@scandic-hotels/trpc/routers/hotels/schemas/packages"
|
||||
import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConfirmation"
|
||||
import type { Child } from "@scandic-hotels/trpc/types/child"
|
||||
import type {
|
||||
@@ -8,7 +9,6 @@ import type {
|
||||
import type { CreditCard } from "@scandic-hotels/trpc/types/user"
|
||||
import type { IntlShape } from "react-intl"
|
||||
|
||||
import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast"
|
||||
import type { BedTypeSchema } from "@/types/components/hotelReservation/enterDetails/bedType"
|
||||
import type { RoomPrice } from "@/types/components/hotelReservation/enterDetails/details"
|
||||
import type { PriceTypeEnum } from "@/types/components/hotelReservation/myStay/myStay"
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
import { trackEvent } from "@scandic-hotels/common/tracking/base"
|
||||
|
||||
import type { BreakfastPackages } from "@/types/components/hotelReservation/breakfast"
|
||||
import type { LowestRoomPriceEvent } from "@scandic-hotels/common/tracking/types"
|
||||
import type { BreakfastPackages } from "@scandic-hotels/trpc/routers/hotels/output"
|
||||
|
||||
export function trackLowestRoomPrice(event: LowestRoomPriceEvent) {
|
||||
trackEvent({
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import * as Sentry from "@sentry/nextjs"
|
||||
import React from "react"
|
||||
|
||||
import { logger } from "@scandic-hotels/common/logger"
|
||||
|
||||
type ErrorBoundaryProps = {
|
||||
children: React.ReactNode
|
||||
fallback?: React.ReactNode
|
||||
}
|
||||
type ErrorBoundaryState = { hasError: boolean; error?: Error }
|
||||
|
||||
export class ErrorBoundary extends React.Component<
|
||||
ErrorBoundaryProps,
|
||||
ErrorBoundaryState
|
||||
> {
|
||||
constructor(props: ErrorBoundaryProps) {
|
||||
super(props)
|
||||
this.state = { hasError: false }
|
||||
}
|
||||
|
||||
static getDerivedStateFromError(error: Error) {
|
||||
return { hasError: true, error }
|
||||
}
|
||||
|
||||
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
|
||||
logger.error("ErrorBoundary caught an error:", error, errorInfo)
|
||||
Sentry.captureException(error, { extra: { errorInfo } })
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.hasError) {
|
||||
const hasFallback = !!this.props.fallback
|
||||
|
||||
return (
|
||||
<>
|
||||
{hasFallback && this.props.fallback}
|
||||
{!hasFallback && <h2>Something went wrong.</h2>}
|
||||
{process.env.NODE_ENV === "development" && (
|
||||
<button onClick={() => this.setState({ hasError: false })}>
|
||||
Reset
|
||||
</button>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
return this.props.children
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import type {
|
||||
Hotel,
|
||||
Restaurant,
|
||||
} from "@scandic-hotels/trpc/types/hotel"
|
||||
import type { ReactNode } from "react"
|
||||
|
||||
enum SidePeekEnum {
|
||||
hotelDetails = "hotel-detail-side-peek",
|
||||
@@ -23,7 +24,7 @@ interface HotelDetailsSidePeekProps {
|
||||
hotel: Hotel & { url: string | null }
|
||||
restaurants: Restaurant[]
|
||||
additionalHotelData: AdditionalData | undefined
|
||||
triggerLabel: string
|
||||
triggerLabel: ReactNode
|
||||
buttonVariant: "primary" | "secondary"
|
||||
wrapping?: boolean
|
||||
}
|
||||
|
||||
@@ -7,10 +7,9 @@ import BoldRow from "./Row/Bold"
|
||||
import RegularRow from "./Row/Regular"
|
||||
import Tbody from "./Tbody"
|
||||
|
||||
import type { BreakfastPackage } from "@scandic-hotels/trpc/routers/hotels/schemas/packages"
|
||||
import type { Child } from "@scandic-hotels/trpc/types/child"
|
||||
|
||||
import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast"
|
||||
|
||||
interface BreakfastProps {
|
||||
adults: number
|
||||
breakfast: Omit<BreakfastPackage, "requestedPrice"> | false | undefined | null
|
||||
@@ -6,7 +6,7 @@ import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||
|
||||
import styles from "./row.module.css"
|
||||
|
||||
import type { Price } from "@/types/components/hotelReservation/price"
|
||||
import type { Price } from "../../../../types/price"
|
||||
|
||||
interface RowProps {
|
||||
allPricesIsDiscounted: boolean
|
||||
@@ -5,10 +5,12 @@ import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
|
||||
|
||||
import RegularRow from "../Regular"
|
||||
|
||||
import type { BedTypeSchema } from "@/types/components/hotelReservation/enterDetails/bedType"
|
||||
|
||||
interface BedTypeRowProps {
|
||||
bedType: BedTypeSchema | undefined
|
||||
bedType:
|
||||
| {
|
||||
description: string
|
||||
}
|
||||
| undefined
|
||||
currency?: string
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
"use client"
|
||||
import { type IntlShape, useIntl } from "react-intl"
|
||||
|
||||
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
|
||||
import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter"
|
||||
|
||||
import RegularRow from "../Regular"
|
||||
|
||||
import type { Packages as PackagesType } from "@scandic-hotels/trpc/types/packages"
|
||||
|
||||
interface PackagesProps {
|
||||
packages: PackagesType | null
|
||||
}
|
||||
|
||||
export default function PackagesRow({ packages }: PackagesProps) {
|
||||
const intl = useIntl()
|
||||
|
||||
if (!packages || !packages.length) {
|
||||
return null
|
||||
}
|
||||
|
||||
return packages?.map((pkg) => (
|
||||
<RegularRow
|
||||
key={pkg.code}
|
||||
label={getFeatureDescription(pkg.code, pkg.description, intl)}
|
||||
value={formatPrice(
|
||||
intl,
|
||||
+pkg.localPrice.totalPrice,
|
||||
pkg.localPrice.currency
|
||||
)}
|
||||
/>
|
||||
))
|
||||
}
|
||||
|
||||
// TODO this might be duplicated, check if we can reuse
|
||||
function getFeatureDescription(
|
||||
code: string,
|
||||
description: string,
|
||||
intl: IntlShape
|
||||
): string {
|
||||
const roomFeatureDescriptions: Record<string, string> = {
|
||||
[RoomPackageCodeEnum.ACCESSIBILITY_ROOM]: intl.formatMessage({
|
||||
defaultMessage: "Accessible room",
|
||||
}),
|
||||
[RoomPackageCodeEnum.ALLERGY_ROOM]: intl.formatMessage({
|
||||
defaultMessage: "Allergy-friendly room",
|
||||
}),
|
||||
[RoomPackageCodeEnum.PET_ROOM]: intl.formatMessage({
|
||||
defaultMessage: "Pet-friendly room",
|
||||
}),
|
||||
}
|
||||
|
||||
return roomFeatureDescriptions[code] ?? description
|
||||
}
|
||||
@@ -1,9 +1,13 @@
|
||||
import type { Packages } from "@scandic-hotels/trpc/types/packages"
|
||||
|
||||
import type { BedTypeSchema } from "@/types/components/hotelReservation/enterDetails/bedType"
|
||||
|
||||
export interface SharedPriceRowProps {
|
||||
bedType: BedTypeSchema | undefined
|
||||
bedType:
|
||||
| {
|
||||
description: string
|
||||
type: string
|
||||
roomTypeCode: string
|
||||
}
|
||||
| undefined
|
||||
nights: number
|
||||
packages: Packages | null
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
"use client"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { calculateVat } from "@scandic-hotels/booking-flow/utils/SelectRate"
|
||||
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
||||
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
|
||||
|
||||
import { calculateVat } from "../../../../utils/SelectRate"
|
||||
import RegularRow from "./Regular"
|
||||
|
||||
import type { Price } from "@/types/components/hotelReservation/price"
|
||||
import type { Price } from "../../../../types/price"
|
||||
|
||||
interface VatProps {
|
||||
totalPrice: Price
|
||||
@@ -6,8 +6,7 @@ import { longDateFormat } from "@scandic-hotels/common/constants/dateFormats"
|
||||
import { dt } from "@scandic-hotels/common/dt"
|
||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||
|
||||
import useLang from "@/hooks/useLang"
|
||||
|
||||
import useLang from "../../../hooks/useLang"
|
||||
import BookingCodeRow from "./Row/BookingCode"
|
||||
import HeaderRow from "./Row/Header"
|
||||
import LargeRow from "./Row/Large"
|
||||
@@ -26,13 +25,12 @@ import Tbody from "./Tbody"
|
||||
import styles from "./priceDetailsTable.module.css"
|
||||
|
||||
import type { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
||||
import type { BreakfastPackage } from "@scandic-hotels/trpc/routers/hotels/schemas/packages"
|
||||
import type { Child } from "@scandic-hotels/trpc/types/child"
|
||||
import type { Packages } from "@scandic-hotels/trpc/types/packages"
|
||||
import type { RateDefinition } from "@scandic-hotels/trpc/types/roomAvailability"
|
||||
|
||||
import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast"
|
||||
import type { BedTypeSchema } from "@/types/components/hotelReservation/enterDetails/bedType"
|
||||
import type { Price } from "@/types/components/hotelReservation/price"
|
||||
import type { Price } from "../../../types/price"
|
||||
|
||||
type RoomPrice =
|
||||
| CorporateChequePriceType
|
||||
@@ -42,7 +40,13 @@ type RoomPrice =
|
||||
|
||||
export interface Room {
|
||||
adults: number
|
||||
bedType: BedTypeSchema | undefined
|
||||
bedType:
|
||||
| {
|
||||
description: string
|
||||
type: string
|
||||
roomTypeCode: string
|
||||
}
|
||||
| undefined
|
||||
breakfast: Omit<BreakfastPackage, "requestedPrice"> | false | undefined | null
|
||||
breakfastChildren?: Omit<BreakfastPackage, "requestedPrice"> | null
|
||||
breakfastIncluded: boolean
|
||||
@@ -1,13 +1,11 @@
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import {
|
||||
BED_TYPE_ICONS,
|
||||
type BedTypes,
|
||||
} from "@scandic-hotels/booking-flow/bedTypeIcons"
|
||||
import { FacilityIcon } from "@scandic-hotels/design-system/Icons/FacilityIcon"
|
||||
import ImageGallery from "@scandic-hotels/design-system/ImageGallery"
|
||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||
|
||||
import { BED_TYPE_ICONS, type BedTypes } from "../../../misc/bedTypeIcons"
|
||||
|
||||
import styles from "./roomSidePeekContent.module.css"
|
||||
|
||||
import type { ApiImage, Room } from "@scandic-hotels/trpc/types/hotel"
|
||||
@@ -6,13 +6,14 @@ import { Button } from "@scandic-hotels/design-system/Button"
|
||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||
import SidePeekSelfControlled from "@scandic-hotels/design-system/SidePeekSelfControlled"
|
||||
|
||||
import { trackOpenSidePeekEvent } from "@/utils/tracking"
|
||||
|
||||
import { useTrackingContext } from "../../trackingContext"
|
||||
import { RoomSidePeekContent } from "./RoomSidePeekContent"
|
||||
|
||||
import type { Room } from "@scandic-hotels/trpc/types/hotel"
|
||||
|
||||
import { SidePeekEnum } from "@/types/sidepeek"
|
||||
enum SidePeekEnum {
|
||||
roomDetails = "room-detail-side-peek",
|
||||
}
|
||||
|
||||
interface RoomDetailsSidePeekProps {
|
||||
hotelId: string
|
||||
@@ -44,7 +45,7 @@ const buttonPropsMap: Record<
|
||||
},
|
||||
}
|
||||
|
||||
export default function RoomDetailsSidePeek({
|
||||
export function RoomDetailsSidePeek({
|
||||
hotelId,
|
||||
room,
|
||||
roomTypeCode,
|
||||
@@ -52,6 +53,7 @@ export default function RoomDetailsSidePeek({
|
||||
wrapping = true,
|
||||
buttonVariant: variant = "primary",
|
||||
}: RoomDetailsSidePeekProps) {
|
||||
const tracking = useTrackingContext()
|
||||
const buttonProps = buttonPropsMap[variant]
|
||||
|
||||
return (
|
||||
@@ -60,7 +62,7 @@ export default function RoomDetailsSidePeek({
|
||||
{...buttonProps}
|
||||
wrapping={wrapping}
|
||||
onPress={() =>
|
||||
trackOpenSidePeekEvent({
|
||||
tracking.trackOpenSidePeek({
|
||||
name: SidePeekEnum.roomDetails,
|
||||
hotelId,
|
||||
roomTypeCode,
|
||||
@@ -0,0 +1,13 @@
|
||||
"use client"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
export function AmenitiesSidePeekLabel() {
|
||||
const intl = useIntl()
|
||||
return (
|
||||
<>
|
||||
{intl.formatMessage({
|
||||
defaultMessage: "See all amenities",
|
||||
})}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -8,15 +8,14 @@ import Footnote from "@scandic-hotels/design-system/Footnote"
|
||||
import { OldDSButton as Button } from "@scandic-hotels/design-system/OldDSButton"
|
||||
import Subtitle from "@scandic-hotels/design-system/Subtitle"
|
||||
|
||||
import SignupPromoDesktop from "@/components/HotelReservation/SignupPromo/Desktop"
|
||||
import { useIsUserLoggedIn } from "@/hooks/useIsUserLoggedIn"
|
||||
|
||||
import { useIsLoggedIn } from "../../../../hooks/useIsLoggedIn"
|
||||
import SignupPromoDesktop from "../../../SignupPromo/Desktop"
|
||||
import { isBookingCodeRate } from "./utils"
|
||||
|
||||
import styles from "./rateSummary.module.css"
|
||||
|
||||
import type { useSelectRateContext } from "@scandic-hotels/booking-flow/contexts/SelectRate/SelectRateContext"
|
||||
import type { SelectedRate } from "@scandic-hotels/booking-flow/contexts/SelectRate/types"
|
||||
import type { useSelectRateContext } from "../../../../contexts/SelectRate/SelectRateContext"
|
||||
import type { SelectedRate } from "../../../../contexts/SelectRate/types"
|
||||
|
||||
export function DesktopSummary({
|
||||
input,
|
||||
@@ -30,7 +29,7 @@ export function DesktopSummary({
|
||||
bookingCode: string
|
||||
}) {
|
||||
const intl = useIntl()
|
||||
const isUserLoggedIn = useIsUserLoggedIn()
|
||||
const isUserLoggedIn = useIsLoggedIn()
|
||||
|
||||
if (!selectedRates.totalPrice) {
|
||||
return null
|
||||
@@ -2,7 +2,6 @@
|
||||
import { cx } from "class-variance-authority"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { useSelectRateContext } from "@scandic-hotels/booking-flow/contexts/SelectRate/SelectRateContext"
|
||||
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
||||
import { longDateFormat } from "@scandic-hotels/common/constants/dateFormats"
|
||||
import { dt } from "@scandic-hotels/common/dt"
|
||||
@@ -12,17 +11,17 @@ import { IconButton } from "@scandic-hotels/design-system/IconButton"
|
||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||
|
||||
import PriceDetailsModal from "@/components/HotelReservation/PriceDetailsModal"
|
||||
import SignupPromoDesktop from "@/components/HotelReservation/SignupPromo/Desktop"
|
||||
import useRateTitles from "@/hooks/booking/useRateTitles"
|
||||
import useLang from "@/hooks/useLang"
|
||||
|
||||
import { useSelectRateContext } from "../../../../../../contexts/SelectRate/SelectRateContext"
|
||||
import useLang from "../../../../../../hooks/useLang"
|
||||
import PriceDetailsModal from "../../../../../PriceDetailsModal"
|
||||
import SignupPromoDesktop from "../../../../../SignupPromo/Desktop"
|
||||
import { useRateTitles } from "../../../Rooms/RoomsList/RoomListItem/Rates/useRateTitles"
|
||||
import { isBookingCodeRate } from "../../utils"
|
||||
import Room from "../Room"
|
||||
|
||||
import styles from "./summaryContent.module.css"
|
||||
|
||||
import type { Price } from "@scandic-hotels/booking-flow/contexts/SelectRate/getTotalPrice"
|
||||
import type { Price } from "../../../../../../contexts/SelectRate/getTotalPrice"
|
||||
|
||||
export type SelectRateSummaryProps = {
|
||||
isMember: boolean
|
||||
@@ -100,12 +99,10 @@ export default function SummaryContent({
|
||||
.locale(lang)
|
||||
.format(longDateFormat[lang])}
|
||||
<MaterialIcon icon="arrow_forward" size={15} color="CurrentColor" />
|
||||
{/* eslint-disable formatjs/no-literal-string-in-jsx */}
|
||||
{dt(input.data?.booking.toDate)
|
||||
.locale(lang)
|
||||
.format(longDateFormat[lang])}{" "}
|
||||
({nightsLabel})
|
||||
{/* eslint-enable formatjs/no-literal-string-in-jsx */}
|
||||
</p>
|
||||
</Typography>
|
||||
</header>
|
||||
@@ -16,19 +16,20 @@ import styles from "./room.module.css"
|
||||
|
||||
import type { Child } from "@scandic-hotels/trpc/types/child"
|
||||
import type { Packages } from "@scandic-hotels/trpc/types/packages"
|
||||
import type { Product } from "@scandic-hotels/trpc/types/roomAvailability"
|
||||
|
||||
import type {
|
||||
RoomPrice,
|
||||
RoomRate,
|
||||
} from "@/types/components/hotelReservation/enterDetails/details"
|
||||
import type { Price } from "../../../../../../types/price"
|
||||
|
||||
interface RoomProps {
|
||||
room: {
|
||||
adults: number
|
||||
childrenInRoom: Child[] | undefined
|
||||
roomType: string
|
||||
roomPrice: RoomPrice
|
||||
roomRate: RoomRate
|
||||
roomPrice: {
|
||||
perNight: Price
|
||||
perStay: Price
|
||||
}
|
||||
roomRate: Product
|
||||
rateDetails: string[] | undefined
|
||||
cancellationText: string
|
||||
packages?: Packages
|
||||
@@ -4,14 +4,13 @@ import { useEffect, useRef, useState } from "react"
|
||||
import { Button as ButtonRAC } from "react-aria-components"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { useSelectRateContext } from "@scandic-hotels/booking-flow/contexts/SelectRate/SelectRateContext"
|
||||
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
|
||||
import { Button } from "@scandic-hotels/design-system/Button"
|
||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||
|
||||
import { useIsUserLoggedIn } from "@/hooks/useIsUserLoggedIn"
|
||||
|
||||
import { useSelectRateContext } from "../../../../../contexts/SelectRate/SelectRateContext"
|
||||
import { useIsLoggedIn } from "../../../../../hooks/useIsLoggedIn"
|
||||
import { isBookingCodeRate } from "../utils"
|
||||
import SummaryContent from "./Content"
|
||||
|
||||
@@ -21,7 +20,7 @@ export function MobileSummary() {
|
||||
const intl = useIntl()
|
||||
const scrollY = useRef(0)
|
||||
const [isSummaryOpen, setIsSummaryOpen] = useState(false)
|
||||
const isUserLoggedIn = useIsUserLoggedIn()
|
||||
const isUserLoggedIn = useIsLoggedIn()
|
||||
|
||||
const { selectedRates } = useSelectRateContext()
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
||||
|
||||
import type { Packages } from "@scandic-hotels/trpc/types/packages"
|
||||
|
||||
import type {
|
||||
Rate,
|
||||
Room,
|
||||
} from "@scandic-hotels/booking-flow/types/components/selectRate/selectRate"
|
||||
import type { Packages } from "@scandic-hotels/trpc/types/packages"
|
||||
|
||||
import type { Price } from "@/types/components/hotelReservation/price"
|
||||
} from "../../../../../types/components/selectRate/selectRate"
|
||||
import type { Price } from "../../../../../types/price"
|
||||
|
||||
export function mapRate(
|
||||
room: Rate,
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { RoomRate } from "@/types/components/hotelReservation/enterDetails/details"
|
||||
import type { Product } from "@scandic-hotels/trpc/types/roomAvailability"
|
||||
|
||||
export function getMemberPrice(roomRate: RoomRate) {
|
||||
export function getMemberPrice(roomRate: Product) {
|
||||
if ("member" in roomRate && roomRate.member) {
|
||||
return {
|
||||
amount: roomRate.member.localPrice.pricePerStay,
|
||||
@@ -3,10 +3,8 @@
|
||||
import { useRouter, useSearchParams } from "next/navigation"
|
||||
import { useState, useTransition } from "react"
|
||||
|
||||
import { useSelectRateContext } from "@scandic-hotels/booking-flow/contexts/SelectRate/SelectRateContext"
|
||||
|
||||
import { ErrorBoundary } from "@/components/ErrorBoundary/ErrorBoundary"
|
||||
|
||||
import { useSelectRateContext } from "../../../../contexts/SelectRate/SelectRateContext"
|
||||
import { ErrorBoundary } from "../../../ErrorBoundary/ErrorBoundary"
|
||||
import { DesktopSummary } from "./DesktopSummary"
|
||||
import { MobileSummary } from "./MobileSummary"
|
||||
|
||||
@@ -14,7 +12,6 @@ import styles from "./rateSummary.module.css"
|
||||
|
||||
export function RateSummary() {
|
||||
return (
|
||||
// eslint-disable-next-line formatjs/no-literal-string-in-jsx
|
||||
<ErrorBoundary fallback={<div>Unable to render summary</div>}>
|
||||
<InnerRateSummary />
|
||||
</ErrorBoundary>
|
||||
@@ -62,7 +59,6 @@ function InnerRateSummary() {
|
||||
>
|
||||
<div className={styles.summary}>
|
||||
<div className={styles.content}>
|
||||
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
|
||||
<ErrorBoundary fallback={<div>Unable to render desktop summary</div>}>
|
||||
<DesktopSummary
|
||||
isSubmitting={isSubmitting}
|
||||
@@ -73,7 +69,6 @@ function InnerRateSummary() {
|
||||
</ErrorBoundary>
|
||||
</div>
|
||||
<div className={styles.mobileSummary}>
|
||||
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
|
||||
<ErrorBoundary fallback={<div>Unable to render mobile summary</div>}>
|
||||
<MobileSummary />
|
||||
</ErrorBoundary>
|
||||
@@ -1,15 +1,16 @@
|
||||
import { sumPackages } from "@scandic-hotels/booking-flow/utils/SelectRate"
|
||||
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
||||
import { RateTypeEnum } from "@scandic-hotels/common/constants/rateType"
|
||||
|
||||
import type { Rate } from "@scandic-hotels/booking-flow/types/components/selectRate/selectRate"
|
||||
import { sumPackages } from "../../../../utils/SelectRate"
|
||||
|
||||
import type { Packages } from "@scandic-hotels/trpc/types/packages"
|
||||
import type {
|
||||
Product,
|
||||
RedemptionProduct,
|
||||
} from "@scandic-hotels/trpc/types/roomAvailability"
|
||||
|
||||
import type { Price } from "@/types/components/hotelReservation/price"
|
||||
import type { Rate } from "../../../../types/components/selectRate/selectRate"
|
||||
import type { Price } from "../../../../types/price"
|
||||
|
||||
export function calculateTotalPrice(
|
||||
selectedRateSummary: Rate[],
|
||||
@@ -1,7 +1,6 @@
|
||||
"use client"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { useSelectRateContext } from "@scandic-hotels/booking-flow/contexts/SelectRate/SelectRateContext"
|
||||
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
||||
import { RateEnum } from "@scandic-hotels/common/constants/rate"
|
||||
import { logger } from "@scandic-hotels/common/logger"
|
||||
@@ -13,7 +12,8 @@ import Image from "@scandic-hotels/design-system/Image"
|
||||
import { OldDSButton as Button } from "@scandic-hotels/design-system/OldDSButton"
|
||||
import Subtitle from "@scandic-hotels/design-system/Subtitle"
|
||||
|
||||
import { useIsUserLoggedIn } from "@/hooks/useIsUserLoggedIn"
|
||||
import { useSelectRateContext } from "../../../../../../contexts/SelectRate/SelectRateContext"
|
||||
import { useIsLoggedIn } from "../../../../../../hooks/useIsLoggedIn"
|
||||
|
||||
import styles from "./selectedRoomPanel.module.css"
|
||||
|
||||
@@ -100,7 +100,7 @@ export function SelectedRoomPanel({ roomIndex }: { roomIndex: number }) {
|
||||
|
||||
function useSelectedProductTitle({ roomIndex }: { roomIndex: number }) {
|
||||
const intl = useIntl()
|
||||
const isUserLoggedIn = useIsUserLoggedIn()
|
||||
const isUserLoggedIn = useIsLoggedIn()
|
||||
const {
|
||||
selectedRates,
|
||||
input: { nights },
|
||||
@@ -1,12 +1,12 @@
|
||||
import { useEffect } from "react"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { useSelectRateContext } from "@scandic-hotels/booking-flow/contexts/SelectRate/SelectRateContext"
|
||||
import useStickyPosition from "@scandic-hotels/common/hooks/useStickyPosition"
|
||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||
import { OldDSButton as Button } from "@scandic-hotels/design-system/OldDSButton"
|
||||
import Subtitle from "@scandic-hotels/design-system/Subtitle"
|
||||
|
||||
import { useSelectRateContext } from "../../../../../contexts/SelectRate/SelectRateContext"
|
||||
import { SelectedRoomPanel } from "./SelectedRoomPanel"
|
||||
import { roomSelectionPanelVariants } from "./variants"
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
"use client"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { useSelectRateContext } from "@scandic-hotels/booking-flow/contexts/SelectRate/SelectRateContext"
|
||||
import { AlertTypeEnum } from "@scandic-hotels/common/constants/alert"
|
||||
import { alternativeHotels } from "@scandic-hotels/common/constants/routes/hotelReservation"
|
||||
import { Alert } from "@scandic-hotels/design-system/Alert"
|
||||
import { AvailabilityEnum } from "@scandic-hotels/trpc/enums/selectHotel"
|
||||
|
||||
import useLang from "@/hooks/useLang"
|
||||
import { useSelectRateContext } from "../../../../../contexts/SelectRate/SelectRateContext"
|
||||
import useLang from "../../../../../hooks/useLang"
|
||||
|
||||
import styles from "./alert.module.css"
|
||||
|
||||
@@ -12,15 +12,15 @@ import {
|
||||
} from "react-aria-components"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { useSelectRateContext } from "@scandic-hotels/booking-flow/contexts/SelectRate/SelectRateContext"
|
||||
import { BookingCodeFilterEnum } from "@scandic-hotels/booking-flow/stores/bookingCode-filter"
|
||||
import { RateTypeEnum } from "@scandic-hotels/common/constants/rateType"
|
||||
import { ChipButton } from "@scandic-hotels/design-system/ChipButton"
|
||||
import { IconButton } from "@scandic-hotels/design-system/IconButton"
|
||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||
|
||||
import { useBreakpoint } from "@/hooks/useBreakpoint"
|
||||
import { useSelectRateContext } from "../../../../../../contexts/SelectRate/SelectRateContext"
|
||||
import { useBreakpoint } from "../../../../../../hooks/useBreakpoint"
|
||||
import { BookingCodeFilterEnum } from "../../../../../../stores/bookingCode-filter"
|
||||
|
||||
import styles from "./bookingCodeFilter.module.css"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useSelectRateContext } from "@scandic-hotels/booking-flow/contexts/SelectRate/SelectRateContext"
|
||||
import { BookingCodeChip } from "@scandic-hotels/design-system/BookingCodeChip"
|
||||
|
||||
import { useSelectRateContext } from "../../../../../../contexts/SelectRate/SelectRateContext"
|
||||
|
||||
export function RemoveBookingCodeButton() {
|
||||
const {
|
||||
input: { bookingCode },
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user