Merged in chore/SW-2878-extract-booking-confirmation-pag (pull request #2779)
Chore/SW-2878 extract booking confirmation pag * chore(SW-2878): Moved booking confirmation page to booking-flow package * chore(SW-2878): Fixed promo styles as per design * chore(SW-2878): Kept tiny duplicate function to avoid export from booking-flow package Approved-by: Anton Gunnarsson
This commit is contained in:
@@ -1,12 +1,8 @@
|
|||||||
import { cookies } from "next/headers"
|
import { BookingConfirmationPage as BookingConfirmationPagePrimitive } from "@scandic-hotels/booking-flow/pages/BookingConfirmationPage"
|
||||||
import { notFound, redirect } from "next/navigation"
|
|
||||||
|
|
||||||
import { decrypt } from "@scandic-hotels/trpc/utils/encryption"
|
import Tracking from "@/components/HotelReservation/BookingConfirmation/Tracking"
|
||||||
|
import { getIntl } from "@/i18n"
|
||||||
import { MEMBERSHIP_FAILED_ERROR } from "@/constants/booking"
|
import { getLang } from "@/i18n/serverContext"
|
||||||
import { getBookingConfirmation } from "@/lib/trpc/memoizedRequests"
|
|
||||||
|
|
||||||
import BookingConfirmation from "@/components/HotelReservation/BookingConfirmation"
|
|
||||||
|
|
||||||
import type { LangParams, PageArgs } from "@/types/params"
|
import type { LangParams, PageArgs } from "@/types/params"
|
||||||
|
|
||||||
@@ -14,35 +10,20 @@ export default async function BookingConfirmationPage(
|
|||||||
props: PageArgs<LangParams, { RefId?: string }>
|
props: PageArgs<LangParams, { RefId?: string }>
|
||||||
) {
|
) {
|
||||||
const searchParams = await props.searchParams
|
const searchParams = await props.searchParams
|
||||||
const params = await props.params
|
const lang = await getLang()
|
||||||
const refId = searchParams.RefId
|
const intl = await getIntl()
|
||||||
|
|
||||||
if (!refId) {
|
|
||||||
notFound()
|
|
||||||
}
|
|
||||||
|
|
||||||
const cookieStore = await cookies()
|
|
||||||
const sig = cookieStore.get("bcsig")?.value
|
|
||||||
|
|
||||||
if (!sig) {
|
|
||||||
redirect(`/${params.lang}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
const expire = Number(decrypt(sig))
|
|
||||||
const now = Math.floor(Date.now() / 1000)
|
|
||||||
if (typeof expire === "number" && !isNaN(expire) && now > expire) {
|
|
||||||
redirect(`/${params.lang}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
void getBookingConfirmation(refId)
|
|
||||||
|
|
||||||
const membershipFailedError =
|
|
||||||
searchParams.errorCode === MEMBERSHIP_FAILED_ERROR
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BookingConfirmation
|
<BookingConfirmationPagePrimitive
|
||||||
refId={refId}
|
intl={intl}
|
||||||
membershipFailedError={membershipFailedError}
|
lang={lang}
|
||||||
|
searchParams={searchParams}
|
||||||
|
renderTracking={(props) => (
|
||||||
|
<Tracking
|
||||||
|
bookingConfirmation={props.bookingConfirmation}
|
||||||
|
refId={props.refId}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { notFound } from "next/navigation"
|
import { notFound } from "next/navigation"
|
||||||
|
|
||||||
|
import { PaymentCallbackStatusEnum } from "@scandic-hotels/common/constants/booking"
|
||||||
import { myStay } from "@scandic-hotels/common/constants/routes/myStay"
|
import { myStay } from "@scandic-hotels/common/constants/routes/myStay"
|
||||||
import { logger } from "@scandic-hotels/common/logger"
|
import { logger } from "@scandic-hotels/common/logger"
|
||||||
import { LoadingSpinner } from "@scandic-hotels/design-system/LoadingSpinner"
|
import { LoadingSpinner } from "@scandic-hotels/design-system/LoadingSpinner"
|
||||||
import { BookingErrorCodeEnum } from "@scandic-hotels/trpc/enums/bookingErrorCode"
|
import { BookingErrorCodeEnum } from "@scandic-hotels/trpc/enums/bookingErrorCode"
|
||||||
|
|
||||||
import { PaymentCallbackStatusEnum } from "@/constants/booking"
|
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
|
|
||||||
import GuaranteeCallback from "@/components/HotelReservation/MyStay/Ancillaries/GuaranteeCallback"
|
import GuaranteeCallback from "@/components/HotelReservation/MyStay/Ancillaries/GuaranteeCallback"
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { notFound } from "next/navigation"
|
import { notFound } from "next/navigation"
|
||||||
|
|
||||||
|
import { PaymentCallbackStatusEnum } from "@scandic-hotels/common/constants/booking"
|
||||||
import {
|
import {
|
||||||
bookingConfirmation,
|
bookingConfirmation,
|
||||||
details,
|
details,
|
||||||
@@ -11,7 +12,6 @@ import { getBooking } from "@scandic-hotels/trpc/routers/booking/utils"
|
|||||||
import { encrypt } from "@scandic-hotels/trpc/utils/encryption"
|
import { encrypt } from "@scandic-hotels/trpc/utils/encryption"
|
||||||
import { isValidSession } from "@scandic-hotels/trpc/utils/session"
|
import { isValidSession } from "@scandic-hotels/trpc/utils/session"
|
||||||
|
|
||||||
import { PaymentCallbackStatusEnum } from "@/constants/booking"
|
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
|
|
||||||
import { auth } from "@/auth"
|
import { auth } from "@/auth"
|
||||||
|
|||||||
@@ -1,67 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import { useIntl } from "react-intl"
|
|
||||||
|
|
||||||
import Body from "@scandic-hotels/design-system/Body"
|
|
||||||
import Link from "@scandic-hotels/design-system/Link"
|
|
||||||
import Subtitle from "@scandic-hotels/design-system/Subtitle"
|
|
||||||
|
|
||||||
import styles from "./hotelDetails.module.css"
|
|
||||||
|
|
||||||
import type { BookingConfirmationHotelDetailsProps } from "@/types/components/hotelReservation/bookingConfirmation/hotelDetails"
|
|
||||||
|
|
||||||
export default function HotelDetails({
|
|
||||||
hotel,
|
|
||||||
}: BookingConfirmationHotelDetailsProps) {
|
|
||||||
const intl = useIntl()
|
|
||||||
return (
|
|
||||||
<div className={styles.container}>
|
|
||||||
<div className={styles.details}>
|
|
||||||
<Subtitle color="uiTextHighContrast" type="two">
|
|
||||||
{intl.formatMessage({
|
|
||||||
defaultMessage: "Hotel details",
|
|
||||||
})}
|
|
||||||
</Subtitle>
|
|
||||||
<div className={styles.hotel}>
|
|
||||||
<Body color="uiTextHighContrast">{hotel.name}</Body>
|
|
||||||
<Body color="uiTextHighContrast">
|
|
||||||
{intl.formatMessage(
|
|
||||||
{
|
|
||||||
defaultMessage: "{streetAddress}, {zipCode} {city}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
streetAddress: hotel.address.streetAddress,
|
|
||||||
zipCode: hotel.address.zipCode,
|
|
||||||
city: hotel.address.city,
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
</Body>
|
|
||||||
<Body asChild color="uiTextHighContrast">
|
|
||||||
<Link
|
|
||||||
className={styles.link}
|
|
||||||
href={`tel:${hotel.contactInformation.phoneNumber}`}
|
|
||||||
>
|
|
||||||
{hotel.contactInformation.phoneNumber}
|
|
||||||
</Link>
|
|
||||||
</Body>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className={styles.contact}>
|
|
||||||
<Link
|
|
||||||
className={styles.link}
|
|
||||||
color="Text/Interactive/Secondary"
|
|
||||||
href={`mailto:${hotel.contactInformation.email}`}
|
|
||||||
>
|
|
||||||
{hotel.contactInformation.email}
|
|
||||||
</Link>
|
|
||||||
<Link
|
|
||||||
className={styles.link}
|
|
||||||
color="Text/Interactive/Secondary"
|
|
||||||
href={hotel.contactInformation.websiteUrl}
|
|
||||||
>
|
|
||||||
{hotel.contactInformation.websiteUrl}
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import { useIntl } from "react-intl"
|
|
||||||
|
|
||||||
import { useBookingConfirmationStore } from "@scandic-hotels/booking-flow/stores/booking-confirmation"
|
|
||||||
import Body from "@scandic-hotels/design-system/Body"
|
|
||||||
import SkeletonShimmer from "@scandic-hotels/design-system/SkeletonShimmer"
|
|
||||||
import Subtitle from "@scandic-hotels/design-system/Subtitle"
|
|
||||||
|
|
||||||
import styles from "./paymentDetails.module.css"
|
|
||||||
|
|
||||||
export default function PaymentDetails() {
|
|
||||||
const intl = useIntl()
|
|
||||||
|
|
||||||
const { rooms, formattedTotalCost } = useBookingConfirmationStore(
|
|
||||||
(state) => ({
|
|
||||||
rooms: state.rooms,
|
|
||||||
formattedTotalCost: state.formattedTotalCost,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
const hasAllRoomsLoaded = rooms.every((room) => room)
|
|
||||||
return (
|
|
||||||
<div className={styles.details}>
|
|
||||||
<Subtitle color="uiTextHighContrast" type="two">
|
|
||||||
{intl.formatMessage({
|
|
||||||
defaultMessage: "Payment details",
|
|
||||||
})}
|
|
||||||
</Subtitle>
|
|
||||||
<div className={styles.payment}>
|
|
||||||
{hasAllRoomsLoaded ? (
|
|
||||||
<Body color="uiTextHighContrast">
|
|
||||||
{intl.formatMessage(
|
|
||||||
{
|
|
||||||
defaultMessage: "Total cost: {amount}",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
amount: formattedTotalCost,
|
|
||||||
}
|
|
||||||
)}
|
|
||||||
</Body>
|
|
||||||
) : (
|
|
||||||
<SkeletonShimmer width={"100%"} />
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
import Body from "@scandic-hotels/design-system/Body"
|
|
||||||
import Link from "@scandic-hotels/design-system/Link"
|
|
||||||
import { OldDSButton as Button } from "@scandic-hotels/design-system/OldDSButton"
|
|
||||||
import Title from "@scandic-hotels/design-system/Title"
|
|
||||||
|
|
||||||
import styles from "./promo.module.css"
|
|
||||||
|
|
||||||
import type { PromoProps } from "@/types/components/hotelReservation/bookingConfirmation/promo"
|
|
||||||
|
|
||||||
export default function Promo({ buttonText, href, text, title }: PromoProps) {
|
|
||||||
return (
|
|
||||||
<Link className={styles.link} color="none" href={href}>
|
|
||||||
<article className={styles.promo}>
|
|
||||||
<Title color="white" level="h4">
|
|
||||||
{title}
|
|
||||||
</Title>
|
|
||||||
<Body className={styles.text} color="white" textAlign="center">
|
|
||||||
{text}
|
|
||||||
</Body>
|
|
||||||
<Button asChild intent="primary" size="small" theme="primaryStrong">
|
|
||||||
<div>{buttonText}</div>
|
|
||||||
</Button>
|
|
||||||
</article>
|
|
||||||
</Link>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import { useIntl } from "react-intl"
|
|
||||||
|
|
||||||
import Body from "@scandic-hotels/design-system/Body"
|
|
||||||
import { OldDSButton as Button } from "@scandic-hotels/design-system/OldDSButton"
|
|
||||||
|
|
||||||
import styles from "./retry.module.css"
|
|
||||||
|
|
||||||
import type { RetryProps } from "@/types/components/hotelReservation/bookingConfirmation/rooms/linkedReservation"
|
|
||||||
|
|
||||||
export default function Retry({ handleRefetch }: RetryProps) {
|
|
||||||
const intl = useIntl()
|
|
||||||
return (
|
|
||||||
<div className={styles.retry}>
|
|
||||||
<Body>
|
|
||||||
{intl.formatMessage({
|
|
||||||
defaultMessage: "Something went wrong!",
|
|
||||||
})}
|
|
||||||
</Body>
|
|
||||||
|
|
||||||
<Button size={"small"} onPress={handleRefetch}>
|
|
||||||
{intl.formatMessage({
|
|
||||||
defaultMessage: "Try again",
|
|
||||||
})}
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -2,6 +2,7 @@ import { createHash } from "crypto"
|
|||||||
import { differenceInCalendarDays, format, isWeekend } from "date-fns"
|
import { differenceInCalendarDays, format, isWeekend } from "date-fns"
|
||||||
|
|
||||||
import { invertedBedTypeMap } from "@scandic-hotels/booking-flow/utils/SelectRate"
|
import { invertedBedTypeMap } from "@scandic-hotels/booking-flow/utils/SelectRate"
|
||||||
|
import { CancellationRuleEnum } from "@scandic-hotels/common/constants/booking"
|
||||||
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
||||||
import { RateEnum } from "@scandic-hotels/common/constants/rate"
|
import { RateEnum } from "@scandic-hotels/common/constants/rate"
|
||||||
import {
|
import {
|
||||||
@@ -14,8 +15,6 @@ import {
|
|||||||
import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast"
|
import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast"
|
||||||
import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter"
|
import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter"
|
||||||
|
|
||||||
import { CancellationRuleEnum } from "@/constants/booking"
|
|
||||||
|
|
||||||
import { readPaymentInfoFromSessionStorage } from "@/components/HotelReservation/EnterDetails/Payment/helpers"
|
import { readPaymentInfoFromSessionStorage } from "@/components/HotelReservation/EnterDetails/Payment/helpers"
|
||||||
import { getSpecialRoomType } from "@/utils/specialRoomType"
|
import { getSpecialRoomType } from "@/utils/specialRoomType"
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import { useRouter } from "next/navigation"
|
|||||||
import { useEffect } from "react"
|
import { useEffect } from "react"
|
||||||
|
|
||||||
import { serializeBookingSearchParams } from "@scandic-hotels/booking-flow/utils/url"
|
import { serializeBookingSearchParams } from "@scandic-hotels/booking-flow/utils/url"
|
||||||
|
import { PaymentCallbackStatusEnum } from "@scandic-hotels/common/constants/booking"
|
||||||
import { trackEvent } from "@scandic-hotels/common/tracking/base"
|
import { trackEvent } from "@scandic-hotels/common/tracking/base"
|
||||||
import { LoadingSpinner } from "@scandic-hotels/design-system/LoadingSpinner"
|
import { LoadingSpinner } from "@scandic-hotels/design-system/LoadingSpinner"
|
||||||
|
|
||||||
import { PaymentCallbackStatusEnum } from "@/constants/booking"
|
|
||||||
import { detailsStorageName } from "@/stores/enter-details"
|
import { detailsStorageName } from "@/stores/enter-details"
|
||||||
|
|
||||||
import { trackPaymentEvent } from "@/utils/tracking"
|
import { trackPaymentEvent } from "@/utils/tracking"
|
||||||
|
|||||||
@@ -3,11 +3,10 @@
|
|||||||
import { useRouter } from "next/navigation"
|
import { useRouter } from "next/navigation"
|
||||||
import { useEffect } from "react"
|
import { useEffect } from "react"
|
||||||
|
|
||||||
|
import { MEMBERSHIP_FAILED_ERROR } from "@scandic-hotels/common/constants/booking"
|
||||||
import { LoadingSpinner } from "@scandic-hotels/design-system/LoadingSpinner"
|
import { LoadingSpinner } from "@scandic-hotels/design-system/LoadingSpinner"
|
||||||
import { BookingStatusEnum } from "@scandic-hotels/trpc/enums/bookingStatus"
|
import { BookingStatusEnum } from "@scandic-hotels/trpc/enums/bookingStatus"
|
||||||
|
|
||||||
import { MEMBERSHIP_FAILED_ERROR } from "@/constants/booking"
|
|
||||||
|
|
||||||
import { useHandleBookingStatus } from "@/hooks/booking/useHandleBookingStatus"
|
import { useHandleBookingStatus } from "@/hooks/booking/useHandleBookingStatus"
|
||||||
|
|
||||||
import TimeoutSpinner from "./TimeoutSpinner"
|
import TimeoutSpinner from "./TimeoutSpinner"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
} from "react-aria-components"
|
} from "react-aria-components"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
|
import { getFeatureDescription } from "@scandic-hotels/booking-flow/utils/getRoomFeatureDescription"
|
||||||
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
|
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
|
||||||
import Body from "@scandic-hotels/design-system/Body"
|
import Body from "@scandic-hotels/design-system/Body"
|
||||||
import Caption from "@scandic-hotels/design-system/Caption"
|
import Caption from "@scandic-hotels/design-system/Caption"
|
||||||
@@ -17,8 +18,6 @@ import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
|||||||
import { OldDSButton as Button } from "@scandic-hotels/design-system/OldDSButton"
|
import { OldDSButton as Button } from "@scandic-hotels/design-system/OldDSButton"
|
||||||
import Subtitle from "@scandic-hotels/design-system/Subtitle"
|
import Subtitle from "@scandic-hotels/design-system/Subtitle"
|
||||||
|
|
||||||
import { getFeatureDescription } from "@/components/HotelReservation/utils/getRoomFeatureDescription"
|
|
||||||
|
|
||||||
import styles from "./priceChangeSummary.module.css"
|
import styles from "./priceChangeSummary.module.css"
|
||||||
|
|
||||||
import type { RoomState } from "@/types/stores/enter-details"
|
import type { RoomState } from "@/types/stores/enter-details"
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { useEnterDetailsStore } from "@/stores/enter-details"
|
import { SidePanel } from "@scandic-hotels/booking-flow/components/SidePanel"
|
||||||
|
|
||||||
import SidePanel from "@/components/HotelReservation/SidePanel"
|
import { useEnterDetailsStore } from "@/stores/enter-details"
|
||||||
|
|
||||||
import SummaryUI from "./UI"
|
import SummaryUI from "./UI"
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { cx } from "class-variance-authority"
|
import { cx } from "class-variance-authority"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
|
import { getFeatureDescription } from "@scandic-hotels/booking-flow/utils/getRoomFeatureDescription"
|
||||||
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
||||||
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
|
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
|
||||||
import { Button } from "@scandic-hotels/design-system/Button"
|
import { Button } from "@scandic-hotels/design-system/Button"
|
||||||
@@ -10,8 +11,6 @@ import Modal from "@scandic-hotels/design-system/Modal"
|
|||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
import { ChildBedMapEnum } from "@scandic-hotels/trpc/enums/childBedMapEnum"
|
import { ChildBedMapEnum } from "@scandic-hotels/trpc/enums/childBedMapEnum"
|
||||||
|
|
||||||
import { getFeatureDescription } from "@/components/HotelReservation/utils/getRoomFeatureDescription"
|
|
||||||
|
|
||||||
import Breakfast from "./Breakfast"
|
import Breakfast from "./Breakfast"
|
||||||
|
|
||||||
import styles from "./room.module.css"
|
import styles from "./room.module.css"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { Typography } from "@scandic-hotels/design-system/Typography"
|
|||||||
|
|
||||||
import styles from "./promo.module.css"
|
import styles from "./promo.module.css"
|
||||||
|
|
||||||
import type { PromoProps } from "@/types/components/hotelReservation/bookingConfirmation/promo"
|
import type { PromoProps } from "@scandic-hotels/booking-flow/types/components/promo/promoProps"
|
||||||
|
|
||||||
export default function Promo({
|
export default function Promo({
|
||||||
buttonText,
|
buttonText,
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
"use client"
|
"use client"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
|
import { CancellationRuleEnum } from "@scandic-hotels/common/constants/booking"
|
||||||
import { preliminaryReceipt } from "@scandic-hotels/common/constants/routes/myStay"
|
import { preliminaryReceipt } from "@scandic-hotels/common/constants/routes/myStay"
|
||||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||||
import Link from "@scandic-hotels/design-system/Link"
|
import Link from "@scandic-hotels/design-system/Link"
|
||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
|
|
||||||
import { CancellationRuleEnum } from "@/constants/booking"
|
|
||||||
import { useMyStayStore } from "@/stores/my-stay"
|
import { useMyStayStore } from "@/stores/my-stay"
|
||||||
|
|
||||||
import useLang from "@/hooks/useLang"
|
import useLang from "@/hooks/useLang"
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { IconForFeatureCode } from "@scandic-hotels/booking-flow/utils/SelectRate"
|
import { IconForFeatureCode } from "@scandic-hotels/booking-flow/utils/SelectRate"
|
||||||
|
import { CancellationRuleEnum } from "@scandic-hotels/common/constants/booking"
|
||||||
import { changeOrCancelDateFormat } from "@scandic-hotels/common/constants/dateFormats"
|
import { changeOrCancelDateFormat } from "@scandic-hotels/common/constants/dateFormats"
|
||||||
import { RateEnum } from "@scandic-hotels/common/constants/rate"
|
import { RateEnum } from "@scandic-hotels/common/constants/rate"
|
||||||
import { dt } from "@scandic-hotels/common/dt"
|
import { dt } from "@scandic-hotels/common/dt"
|
||||||
@@ -15,8 +16,6 @@ import Modal from "@scandic-hotels/design-system/Modal"
|
|||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter"
|
import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter"
|
||||||
|
|
||||||
import { CancellationRuleEnum } from "@/constants/booking"
|
|
||||||
|
|
||||||
import useRateTitles from "@/hooks/booking/useRateTitles"
|
import useRateTitles from "@/hooks/booking/useRateTitles"
|
||||||
import useLang from "@/hooks/useLang"
|
import useLang from "@/hooks/useLang"
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
|
import { getFeatureDescription } from "@scandic-hotels/booking-flow/utils/getRoomFeatureDescription"
|
||||||
import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter"
|
import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter"
|
||||||
|
|
||||||
import { useMyStayStore } from "@/stores/my-stay"
|
import { useMyStayStore } from "@/stores/my-stay"
|
||||||
|
|
||||||
import { getFeatureDescription } from "@/components/HotelReservation/utils/getRoomFeatureDescription"
|
|
||||||
|
|
||||||
import Row from "./Row"
|
import Row from "./Row"
|
||||||
|
|
||||||
export default function Packages() {
|
export default function Packages() {
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
|
import { CancellationRuleEnum } from "@scandic-hotels/common/constants/booking"
|
||||||
import { RateEnum } from "@scandic-hotels/common/constants/rate"
|
import { RateEnum } from "@scandic-hotels/common/constants/rate"
|
||||||
import { IconButton } from "@scandic-hotels/design-system/IconButton"
|
import { IconButton } from "@scandic-hotels/design-system/IconButton"
|
||||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||||
import Modal from "@scandic-hotels/design-system/Modal"
|
import Modal from "@scandic-hotels/design-system/Modal"
|
||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
|
|
||||||
import { CancellationRuleEnum } from "@/constants/booking"
|
|
||||||
import { useMyStayStore } from "@/stores/my-stay"
|
import { useMyStayStore } from "@/stores/my-stay"
|
||||||
|
|
||||||
import useRateTitles from "@/hooks/booking/useRateTitles"
|
import useRateTitles from "@/hooks/booking/useRateTitles"
|
||||||
|
|||||||
@@ -3,11 +3,10 @@
|
|||||||
import { useRouter } from "next/navigation"
|
import { useRouter } from "next/navigation"
|
||||||
import { useEffect } from "react"
|
import { useEffect } from "react"
|
||||||
|
|
||||||
|
import { PaymentCallbackStatusEnum } from "@scandic-hotels/common/constants/booking"
|
||||||
import { trackEvent } from "@scandic-hotels/common/tracking/base"
|
import { trackEvent } from "@scandic-hotels/common/tracking/base"
|
||||||
import { LoadingSpinner } from "@scandic-hotels/design-system/LoadingSpinner"
|
import { LoadingSpinner } from "@scandic-hotels/design-system/LoadingSpinner"
|
||||||
|
|
||||||
import { PaymentCallbackStatusEnum } from "@/constants/booking"
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
clearGlaSessionStorage,
|
clearGlaSessionStorage,
|
||||||
readGlaFromSessionStorage,
|
readGlaFromSessionStorage,
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
|
import { CancellationRuleEnum } from "@scandic-hotels/common/constants/booking"
|
||||||
import { ChildBedTypeEnum } from "@scandic-hotels/trpc/enums/childBedTypeEnum"
|
import { ChildBedTypeEnum } from "@scandic-hotels/trpc/enums/childBedTypeEnum"
|
||||||
|
|
||||||
import { CancellationRuleEnum } from "@/constants/booking"
|
|
||||||
|
|
||||||
export function formatChildBedPreferences({
|
export function formatChildBedPreferences({
|
||||||
childrenAges,
|
childrenAges,
|
||||||
childBedPreferences,
|
childBedPreferences,
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
|
import { CancellationRuleEnum } from "@scandic-hotels/common/constants/booking"
|
||||||
import { dt } from "@scandic-hotels/common/dt"
|
import { dt } from "@scandic-hotels/common/dt"
|
||||||
import { BookingStatusEnum } from "@scandic-hotels/trpc/enums/bookingStatus"
|
import { BookingStatusEnum } from "@scandic-hotels/trpc/enums/bookingStatus"
|
||||||
import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast"
|
import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast"
|
||||||
import { PackageTypeEnum } from "@scandic-hotels/trpc/enums/packages"
|
import { PackageTypeEnum } from "@scandic-hotels/trpc/enums/packages"
|
||||||
import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter"
|
import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter"
|
||||||
|
|
||||||
import { CancellationRuleEnum } from "@/constants/booking"
|
|
||||||
|
|
||||||
import { convertToChildType } from "../../utils/convertToChildType"
|
import { convertToChildType } from "../../utils/convertToChildType"
|
||||||
import { getPriceType } from "../../utils/getPriceType"
|
import { getPriceType } from "../../utils/getPriceType"
|
||||||
import { formatChildBedPreferences } from "../utils"
|
import { formatChildBedPreferences } from "../utils"
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
|
import { getFeatureDescription } from "@scandic-hotels/booking-flow/utils/getRoomFeatureDescription"
|
||||||
import { sumPackages } from "@scandic-hotels/booking-flow/utils/SelectRate"
|
import { sumPackages } from "@scandic-hotels/booking-flow/utils/SelectRate"
|
||||||
import { changeOrCancelDateFormat } from "@scandic-hotels/common/constants/dateFormats"
|
import { changeOrCancelDateFormat } from "@scandic-hotels/common/constants/dateFormats"
|
||||||
import { dt } from "@scandic-hotels/common/dt"
|
import { dt } from "@scandic-hotels/common/dt"
|
||||||
@@ -17,7 +18,6 @@ import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter"
|
|||||||
import GuestDetails from "@/components/HotelReservation/MyStay/GuestDetails"
|
import GuestDetails from "@/components/HotelReservation/MyStay/GuestDetails"
|
||||||
import PriceType from "@/components/HotelReservation/MyStay/PriceType"
|
import PriceType from "@/components/HotelReservation/MyStay/PriceType"
|
||||||
import { hasModifiableRate } from "@/components/HotelReservation/MyStay/utils"
|
import { hasModifiableRate } from "@/components/HotelReservation/MyStay/utils"
|
||||||
import { getFeatureDescription } from "@/components/HotelReservation/utils/getRoomFeatureDescription"
|
|
||||||
import useLang from "@/hooks/useLang"
|
import useLang from "@/hooks/useLang"
|
||||||
import { mapApiImagesToGalleryImages } from "@/utils/imageGallery"
|
import { mapApiImagesToGalleryImages } from "@/utils/imageGallery"
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { type NextMiddleware, NextResponse } from "next/server"
|
import { type NextMiddleware, NextResponse } from "next/server"
|
||||||
|
|
||||||
|
import { SEARCHTYPE } from "@scandic-hotels/common/constants/booking"
|
||||||
import { login } from "@scandic-hotels/common/constants/routes/handleAuth"
|
import { login } from "@scandic-hotels/common/constants/routes/handleAuth"
|
||||||
import { findLang } from "@scandic-hotels/common/utils/languages"
|
import { findLang } from "@scandic-hotels/common/utils/languages"
|
||||||
import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking"
|
import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking"
|
||||||
import { isValidSession } from "@scandic-hotels/trpc/utils/session"
|
import { isValidSession } from "@scandic-hotels/trpc/utils/session"
|
||||||
|
|
||||||
import { SEARCHTYPE } from "@/constants/booking"
|
|
||||||
import { getPublicNextURL } from "@/server/utils"
|
import { getPublicNextURL } from "@/server/utils"
|
||||||
|
|
||||||
import { auth } from "@/auth"
|
import { auth } from "@/auth"
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConfirmation"
|
|
||||||
|
|
||||||
export interface BookingConfirmationHotelDetailsProps {
|
|
||||||
hotel: BookingConfirmation["hotel"]
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConfirmation"
|
|
||||||
|
|
||||||
export interface PromosProps extends Pick<BookingConfirmation, "booking"> {}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import type { Room } from "@scandic-hotels/booking-flow/types/stores/booking-confirmation"
|
|
||||||
|
|
||||||
export interface BookingConfirmationReceiptRoomProps {
|
|
||||||
room: Room
|
|
||||||
roomNumber: number
|
|
||||||
roomCount: number
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConfirmation"
|
|
||||||
import type { Room } from "@scandic-hotels/trpc/types/hotel"
|
|
||||||
|
|
||||||
export interface BookingConfirmationRoomsProps
|
|
||||||
extends Pick<BookingConfirmation, "booking"> {
|
|
||||||
mainRoom: Room & {
|
|
||||||
bedType: Room["roomTypes"][number]
|
|
||||||
}
|
|
||||||
checkInTime: string
|
|
||||||
checkOutTime: string
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
export interface LinkedReservationProps {
|
|
||||||
checkInTime: string
|
|
||||||
checkOutTime: string
|
|
||||||
refId: string
|
|
||||||
roomIndex: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RetryProps {
|
|
||||||
handleRefetch: () => void
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConfirmation"
|
|
||||||
|
|
||||||
export interface RoomProps {
|
|
||||||
booking: BookingConfirmation["booking"]
|
|
||||||
checkInTime: string
|
|
||||||
checkOutTime: string
|
|
||||||
img?: NonNullable<BookingConfirmation["room"]>["images"][number]
|
|
||||||
roomName: NonNullable<BookingConfirmation["room"]>["name"]
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
import type { VariantProps } from "class-variance-authority"
|
|
||||||
|
|
||||||
import type { sidePanelVariants } from "@/components/HotelReservation/SidePanel/variants"
|
|
||||||
|
|
||||||
export interface SidePanelProps
|
|
||||||
extends VariantProps<typeof sidePanelVariants> {}
|
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
|
import Link from "@scandic-hotels/design-system/Link"
|
||||||
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
|
|
||||||
|
import styles from "./hotelDetails.module.css"
|
||||||
|
|
||||||
|
import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConfirmation"
|
||||||
|
|
||||||
|
export function HotelDetails({
|
||||||
|
hotel,
|
||||||
|
}: {
|
||||||
|
hotel: BookingConfirmation["hotel"]
|
||||||
|
}) {
|
||||||
|
const intl = useIntl()
|
||||||
|
return (
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.details}>
|
||||||
|
<Typography variant={"Title/Subtitle/md"}>
|
||||||
|
<h3>
|
||||||
|
{intl.formatMessage({
|
||||||
|
defaultMessage: "Hotel details",
|
||||||
|
})}
|
||||||
|
</h3>
|
||||||
|
</Typography>
|
||||||
|
<Typography variant={"Body/Paragraph/mdRegular"}>
|
||||||
|
<div className={styles.hotel}>
|
||||||
|
<p>{hotel.name}</p>
|
||||||
|
<p>
|
||||||
|
{intl.formatMessage(
|
||||||
|
{
|
||||||
|
defaultMessage: "{streetAddress}, {zipCode} {city}",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
streetAddress: hotel.address.streetAddress,
|
||||||
|
zipCode: hotel.address.zipCode,
|
||||||
|
city: hotel.address.city,
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<Link
|
||||||
|
className={styles.link}
|
||||||
|
href={`tel:${hotel.contactInformation.phoneNumber}`}
|
||||||
|
>
|
||||||
|
{hotel.contactInformation.phoneNumber}
|
||||||
|
</Link>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
<div className={styles.contact}>
|
||||||
|
<Link
|
||||||
|
className={styles.link}
|
||||||
|
color="Text/Interactive/Secondary"
|
||||||
|
href={`mailto:${hotel.contactInformation.email}`}
|
||||||
|
textDecoration={"underline"}
|
||||||
|
>
|
||||||
|
{hotel.contactInformation.email}
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
className={styles.link}
|
||||||
|
color="Text/Interactive/Secondary"
|
||||||
|
href={hotel.contactInformation.websiteUrl}
|
||||||
|
textDecoration={"underline"}
|
||||||
|
>
|
||||||
|
{hotel.contactInformation.websiteUrl}
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
|
import SkeletonShimmer from "@scandic-hotels/design-system/SkeletonShimmer"
|
||||||
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
|
|
||||||
|
import { useBookingConfirmationStore } from "../../../stores/booking-confirmation"
|
||||||
|
|
||||||
|
import styles from "./paymentDetails.module.css"
|
||||||
|
|
||||||
|
export function PaymentDetails() {
|
||||||
|
const intl = useIntl()
|
||||||
|
|
||||||
|
const { rooms, formattedTotalCost } = useBookingConfirmationStore(
|
||||||
|
(state) => ({
|
||||||
|
rooms: state.rooms,
|
||||||
|
formattedTotalCost: state.formattedTotalCost,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
const hasAllRoomsLoaded = rooms.every((room) => room)
|
||||||
|
return (
|
||||||
|
<div className={styles.details}>
|
||||||
|
<Typography variant={"Title/Subtitle/md"}>
|
||||||
|
<h2>
|
||||||
|
{intl.formatMessage({
|
||||||
|
defaultMessage: "Payment details",
|
||||||
|
})}
|
||||||
|
</h2>
|
||||||
|
</Typography>
|
||||||
|
<div className={styles.payment}>
|
||||||
|
{hasAllRoomsLoaded ? (
|
||||||
|
<Typography variant={"Body/Paragraph/mdRegular"}>
|
||||||
|
<p>
|
||||||
|
{intl.formatMessage(
|
||||||
|
{
|
||||||
|
defaultMessage: "Total cost: {amount}",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
amount: formattedTotalCost,
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</Typography>
|
||||||
|
) : (
|
||||||
|
<SkeletonShimmer width={"100%"} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
"use client"
|
"use client"
|
||||||
import PriceDetailsModal from "@scandic-hotels/booking-flow/components/PriceDetailsModal"
|
|
||||||
import { useBookingConfirmationStore } from "@scandic-hotels/booking-flow/stores/booking-confirmation"
|
|
||||||
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
||||||
import { dt } from "@scandic-hotels/common/dt"
|
import { dt } from "@scandic-hotels/common/dt"
|
||||||
|
|
||||||
|
import PriceDetailsModal from "../../../components/PriceDetailsModal"
|
||||||
|
import { useBookingConfirmationStore } from "../../../stores/booking-confirmation"
|
||||||
import { mapToPrice } from "./mapToPrice"
|
import { mapToPrice } from "./mapToPrice"
|
||||||
|
|
||||||
import type { Price } from "@/types/components/hotelReservation/price"
|
import type { Price } from "../../../types/price"
|
||||||
|
|
||||||
export default function PriceDetails() {
|
export default function PriceDetails() {
|
||||||
const { bookingCode, currency, fromDate, rooms, vat, toDate } =
|
const { bookingCode, currency, fromDate, rooms, vat, toDate } =
|
||||||
@@ -7,9 +7,10 @@ import {
|
|||||||
packageSchema,
|
packageSchema,
|
||||||
} from "@scandic-hotels/trpc/routers/hotels/schemas/packages"
|
} from "@scandic-hotels/trpc/routers/hotels/schemas/packages"
|
||||||
|
|
||||||
import type { Room } from "@scandic-hotels/booking-flow/types/stores/booking-confirmation"
|
|
||||||
import type { Package } from "@scandic-hotels/trpc/types/packages"
|
import type { Package } from "@scandic-hotels/trpc/types/packages"
|
||||||
|
|
||||||
|
import type { Room } from "../../../types/stores/booking-confirmation"
|
||||||
|
|
||||||
export function mapToPrice(rooms: (Room | null)[], nights: number) {
|
export function mapToPrice(rooms: (Room | null)[], nights: number) {
|
||||||
return rooms
|
return rooms
|
||||||
.filter((room): room is Room => !!room)
|
.filter((room): room is Room => !!room)
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { Button } from "@scandic-hotels/design-system/Button"
|
||||||
|
import Link from "@scandic-hotels/design-system/Link"
|
||||||
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
|
|
||||||
|
import styles from "./promo.module.css"
|
||||||
|
|
||||||
|
import type { PromoProps } from "../../../../types/components/promo/promoProps"
|
||||||
|
|
||||||
|
export function Promo({ buttonText, href, text, title }: PromoProps) {
|
||||||
|
return (
|
||||||
|
<Link className={styles.link} color="none" href={href}>
|
||||||
|
<article className={styles.promo}>
|
||||||
|
<Typography variant={"Title/smLowCase"}>
|
||||||
|
<h4>{title}</h4>
|
||||||
|
</Typography>
|
||||||
|
<Typography variant={"Body/Paragraph/mdRegular"}>
|
||||||
|
<p className={styles.text}>{text}</p>
|
||||||
|
</Typography>
|
||||||
|
<Button size="Small" variant={"Secondary"} color={"Inverted"} wrapping>
|
||||||
|
<div>{buttonText}</div>
|
||||||
|
</Button>
|
||||||
|
</article>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
border-radius: var(--Medium, 8px);
|
border-radius: var(--Medium, 8px);
|
||||||
|
color: var(--Text-Brand-OnPrimary-2-Heading);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1 0 320px;
|
flex: 1 0 320px;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -37,4 +38,5 @@
|
|||||||
|
|
||||||
.text {
|
.text {
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
@@ -4,17 +4,18 @@ import { useIntl } from "react-intl"
|
|||||||
|
|
||||||
import { myStay } from "@scandic-hotels/common/constants/routes/myStay"
|
import { myStay } from "@scandic-hotels/common/constants/routes/myStay"
|
||||||
|
|
||||||
import useLang from "@/hooks/useLang"
|
import useLang from "../../../hooks/useLang"
|
||||||
|
import { Promo } from "./Promo"
|
||||||
import Promo from "./Promo"
|
|
||||||
|
|
||||||
import styles from "./promos.module.css"
|
import styles from "./promos.module.css"
|
||||||
|
|
||||||
import type { AdditionalInfoCookieValue } from "@scandic-hotels/booking-flow/types/components/findMyBooking/additionalInfoCookieValue"
|
import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConfirmation"
|
||||||
|
|
||||||
import type { PromosProps } from "@/types/components/hotelReservation/bookingConfirmation/promos"
|
import type { AdditionalInfoCookieValue } from "../../../types/components/findMyBooking/additionalInfoCookieValue"
|
||||||
|
|
||||||
export default function Promos({ booking }: PromosProps) {
|
export interface PromosProps extends Pick<BookingConfirmation, "booking"> {}
|
||||||
|
|
||||||
|
export function Promos({ booking }: PromosProps) {
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
const lang = useLang()
|
const lang = useLang()
|
||||||
const { refId, confirmationNumber, hotelId } = booking
|
const { refId, confirmationNumber, hotelId } = booking
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
import { cx } from "class-variance-authority"
|
import { cx } from "class-variance-authority"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { useBookingConfirmationStore } from "@scandic-hotels/booking-flow/stores/booking-confirmation"
|
import { CancellationRuleEnum } from "@scandic-hotels/common/constants/booking"
|
||||||
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
|
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
|
||||||
import { Button } from "@scandic-hotels/design-system/Button"
|
import { Button } from "@scandic-hotels/design-system/Button"
|
||||||
import { Divider } from "@scandic-hotels/design-system/Divider"
|
import { Divider } from "@scandic-hotels/design-system/Divider"
|
||||||
@@ -12,18 +12,22 @@ import Modal from "@scandic-hotels/design-system/Modal"
|
|||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
import { ChildBedTypeEnum } from "@scandic-hotels/trpc/enums/childBedTypeEnum"
|
import { ChildBedTypeEnum } from "@scandic-hotels/trpc/enums/childBedTypeEnum"
|
||||||
|
|
||||||
import { CancellationRuleEnum } from "@/constants/booking"
|
import { useBookingConfirmationStore } from "../../../../stores/booking-confirmation"
|
||||||
|
import { getFeatureDescription } from "../../../../utils/getRoomFeatureDescription"
|
||||||
import { getFeatureDescription } from "@/components/HotelReservation/utils/getRoomFeatureDescription"
|
|
||||||
|
|
||||||
import Breakfast from "./Breakfast"
|
import Breakfast from "./Breakfast"
|
||||||
import RoomSkeletonLoader from "./RoomSkeletonLoader"
|
import RoomSkeletonLoader from "./RoomSkeletonLoader"
|
||||||
|
|
||||||
import styles from "./room.module.css"
|
import styles from "./room.module.css"
|
||||||
|
|
||||||
import type { BookingConfirmationReceiptRoomProps } from "@/types/components/hotelReservation/bookingConfirmation/receipt"
|
import type { Room } from "../../../../types/stores/booking-confirmation"
|
||||||
|
|
||||||
export default function ReceiptRoom({
|
type BookingConfirmationReceiptRoomProps = {
|
||||||
|
room: Room
|
||||||
|
roomNumber: number
|
||||||
|
roomCount: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ReceiptRoom({
|
||||||
room,
|
room,
|
||||||
roomNumber,
|
roomNumber,
|
||||||
roomCount,
|
roomCount,
|
||||||
@@ -3,12 +3,12 @@
|
|||||||
import { cx } from "class-variance-authority"
|
import { cx } from "class-variance-authority"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { useBookingConfirmationStore } from "@scandic-hotels/booking-flow/stores/booking-confirmation"
|
|
||||||
import { BookingCodeChip } from "@scandic-hotels/design-system/BookingCodeChip"
|
import { BookingCodeChip } from "@scandic-hotels/design-system/BookingCodeChip"
|
||||||
import { Divider } from "@scandic-hotels/design-system/Divider"
|
import { Divider } from "@scandic-hotels/design-system/Divider"
|
||||||
import SkeletonShimmer from "@scandic-hotels/design-system/SkeletonShimmer"
|
import SkeletonShimmer from "@scandic-hotels/design-system/SkeletonShimmer"
|
||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
|
|
||||||
|
import { useBookingConfirmationStore } from "../../../../stores/booking-confirmation"
|
||||||
import PriceDetails from "../../PriceDetails"
|
import PriceDetails from "../../PriceDetails"
|
||||||
|
|
||||||
import styles from "./totalPrice.module.css"
|
import styles from "./totalPrice.module.css"
|
||||||
@@ -2,21 +2,20 @@
|
|||||||
|
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { useBookingConfirmationStore } from "@scandic-hotels/booking-flow/stores/booking-confirmation"
|
|
||||||
import { longDateFormat } from "@scandic-hotels/common/constants/dateFormats"
|
import { longDateFormat } from "@scandic-hotels/common/constants/dateFormats"
|
||||||
import { dt } from "@scandic-hotels/common/dt"
|
import { dt } from "@scandic-hotels/common/dt"
|
||||||
import { Divider } from "@scandic-hotels/design-system/Divider"
|
import { Divider } from "@scandic-hotels/design-system/Divider"
|
||||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
|
|
||||||
import useLang from "@/hooks/useLang"
|
import useLang from "../../../hooks/useLang"
|
||||||
|
import { useBookingConfirmationStore } from "../../../stores/booking-confirmation"
|
||||||
import Room from "./Room"
|
import { ReceiptRoom as Room } from "./Room"
|
||||||
import TotalPrice from "./TotalPrice"
|
import TotalPrice from "./TotalPrice"
|
||||||
|
|
||||||
import styles from "./receipt.module.css"
|
import styles from "./receipt.module.css"
|
||||||
|
|
||||||
export default function Receipt() {
|
export function Receipt() {
|
||||||
const lang = useLang()
|
const lang = useLang()
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
const { rooms, fromDate, toDate } = useBookingConfirmationStore((state) => ({
|
const { rooms, fromDate, toDate } = useBookingConfirmationStore((state) => ({
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
|
import { Button } from "@scandic-hotels/design-system/Button"
|
||||||
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
|
|
||||||
|
import styles from "./retry.module.css"
|
||||||
|
|
||||||
|
export interface RetryProps {
|
||||||
|
handleRefetch: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Retry({ handleRefetch }: RetryProps) {
|
||||||
|
const intl = useIntl()
|
||||||
|
return (
|
||||||
|
<div className={styles.retry}>
|
||||||
|
<Typography variant={"Body/Paragraph/mdRegular"}>
|
||||||
|
<p>
|
||||||
|
{intl.formatMessage({
|
||||||
|
defaultMessage: "Something went wrong!",
|
||||||
|
})}
|
||||||
|
</p>
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
<Button size={"Small"} onPress={handleRefetch}>
|
||||||
|
{intl.formatMessage({
|
||||||
|
defaultMessage: "Try again",
|
||||||
|
})}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -3,19 +3,23 @@
|
|||||||
import { useEffect } from "react"
|
import { useEffect } from "react"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { useBookingConfirmationStore } from "@scandic-hotels/booking-flow/stores/booking-confirmation"
|
|
||||||
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
||||||
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
|
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
|
||||||
import { trpc } from "@scandic-hotels/trpc/client"
|
import { trpc } from "@scandic-hotels/trpc/client"
|
||||||
|
|
||||||
import useLang from "@/hooks/useLang"
|
import useLang from "../../../../hooks/useLang"
|
||||||
|
import { useBookingConfirmationStore } from "../../../../stores/booking-confirmation"
|
||||||
import { mapRoomState } from "../../utils"
|
import { mapRoomState } from "../../utils"
|
||||||
import Room from "../Room"
|
import { Room } from "../Room"
|
||||||
import { LinkedReservationCardSkeleton } from "./LinkedReservationCardSkeleton"
|
import { LinkedReservationCardSkeleton } from "./LinkedReservationCardSkeleton"
|
||||||
import Retry from "./Retry"
|
import Retry from "./Retry"
|
||||||
|
|
||||||
import type { LinkedReservationProps } from "@/types/components/hotelReservation/bookingConfirmation/rooms/linkedReservation"
|
export interface LinkedReservationProps {
|
||||||
|
checkInTime: string
|
||||||
|
checkOutTime: string
|
||||||
|
refId: string
|
||||||
|
roomIndex: number
|
||||||
|
}
|
||||||
|
|
||||||
export function LinkedReservation({
|
export function LinkedReservation({
|
||||||
checkInTime,
|
checkInTime,
|
||||||
@@ -2,28 +2,34 @@
|
|||||||
|
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { RoomDetailsSidePeek } from "@scandic-hotels/booking-flow/components/RoomDetailsSidePeek"
|
import { CancellationRuleEnum } from "@scandic-hotels/common/constants/booking"
|
||||||
import { useBookingConfirmationStore } from "@scandic-hotels/booking-flow/stores/booking-confirmation"
|
|
||||||
import {
|
import {
|
||||||
changeOrCancelDateFormat,
|
changeOrCancelDateFormat,
|
||||||
longDateFormat,
|
longDateFormat,
|
||||||
} from "@scandic-hotels/common/constants/dateFormats"
|
} from "@scandic-hotels/common/constants/dateFormats"
|
||||||
import { dt } from "@scandic-hotels/common/dt"
|
import { dt } from "@scandic-hotels/common/dt"
|
||||||
import Caption from "@scandic-hotels/design-system/Caption"
|
|
||||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||||
import Image from "@scandic-hotels/design-system/Image"
|
import Image from "@scandic-hotels/design-system/Image"
|
||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
import { getHotelRoom } from "@scandic-hotels/trpc/routers/booking/helpers"
|
import { getHotelRoom } from "@scandic-hotels/trpc/routers/booking/helpers"
|
||||||
|
|
||||||
import { CancellationRuleEnum } from "@/constants/booking"
|
import { RoomDetailsSidePeek } from "../../../../components/RoomDetailsSidePeek"
|
||||||
|
import useLang from "../../../../hooks/useLang"
|
||||||
import useLang from "@/hooks/useLang"
|
import { useBookingConfirmationStore } from "../../../../stores/booking-confirmation"
|
||||||
|
|
||||||
import styles from "./room.module.css"
|
import styles from "./room.module.css"
|
||||||
|
|
||||||
import type { RoomProps } from "@/types/components/hotelReservation/bookingConfirmation/rooms/room"
|
import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConfirmation"
|
||||||
|
|
||||||
export default function Room({
|
export interface RoomProps {
|
||||||
|
booking: BookingConfirmation["booking"]
|
||||||
|
checkInTime: string
|
||||||
|
checkOutTime: string
|
||||||
|
img?: NonNullable<BookingConfirmation["room"]>["images"][number]
|
||||||
|
roomName: NonNullable<BookingConfirmation["room"]>["name"]
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Room({
|
||||||
booking,
|
booking,
|
||||||
checkInTime,
|
checkInTime,
|
||||||
checkOutTime,
|
checkOutTime,
|
||||||
@@ -67,11 +73,13 @@ export default function Room({
|
|||||||
icon="check_circle"
|
icon="check_circle"
|
||||||
size={20}
|
size={20}
|
||||||
/>
|
/>
|
||||||
<Caption>
|
<Typography variant="Body/Supporting text (caption)/smRegular">
|
||||||
{intl.formatMessage({
|
<p>
|
||||||
defaultMessage: "Membership benefits applied",
|
{intl.formatMessage({
|
||||||
})}
|
defaultMessage: "Membership benefits applied",
|
||||||
</Caption>
|
})}
|
||||||
|
</p>
|
||||||
|
</Typography>
|
||||||
</>
|
</>
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
@@ -1,21 +1,33 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
|
|
||||||
import { getIntl } from "@/i18n"
|
|
||||||
|
|
||||||
import { LinkedReservation } from "./LinkedReservation"
|
import { LinkedReservation } from "./LinkedReservation"
|
||||||
import Room from "./Room"
|
import { Room } from "./Room"
|
||||||
|
|
||||||
import styles from "./rooms.module.css"
|
import styles from "./rooms.module.css"
|
||||||
|
|
||||||
import type { BookingConfirmationRoomsProps } from "@/types/components/hotelReservation/bookingConfirmation/rooms"
|
import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConfirmation"
|
||||||
|
import type { Room as RoomProp } from "@scandic-hotels/trpc/types/hotel"
|
||||||
|
|
||||||
export default async function Rooms({
|
export interface BookingConfirmationRoomsProps
|
||||||
|
extends Pick<BookingConfirmation, "booking"> {
|
||||||
|
mainRoom: RoomProp & {
|
||||||
|
bedType: RoomProp["roomTypes"][number]
|
||||||
|
}
|
||||||
|
checkInTime: string
|
||||||
|
checkOutTime: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Rooms({
|
||||||
booking,
|
booking,
|
||||||
checkInTime,
|
checkInTime,
|
||||||
checkOutTime,
|
checkOutTime,
|
||||||
mainRoom,
|
mainRoom,
|
||||||
}: BookingConfirmationRoomsProps) {
|
}: BookingConfirmationRoomsProps) {
|
||||||
const intl = await getIntl()
|
const intl = useIntl()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={styles.rooms}>
|
<section className={styles.rooms}>
|
||||||
@@ -1,36 +1,42 @@
|
|||||||
import { notFound } from "next/navigation"
|
import { notFound } from "next/navigation"
|
||||||
|
|
||||||
import { Confirmation } from "@scandic-hotels/booking-flow/components/BookingConfirmation/Confirmation"
|
|
||||||
import BookingConfirmationProvider from "@scandic-hotels/booking-flow/providers/BookingConfirmationProvider"
|
|
||||||
import { filterOverlappingDates } from "@scandic-hotels/booking-flow/utils/SelectRate"
|
|
||||||
import { AlertTypeEnum } from "@scandic-hotels/common/constants/alert"
|
import { AlertTypeEnum } from "@scandic-hotels/common/constants/alert"
|
||||||
import { dt } from "@scandic-hotels/common/dt"
|
import { dt } from "@scandic-hotels/common/dt"
|
||||||
import { Alert } from "@scandic-hotels/design-system/Alert"
|
import { Alert } from "@scandic-hotels/design-system/Alert"
|
||||||
import { Divider } from "@scandic-hotels/design-system/Divider"
|
import { Divider } from "@scandic-hotels/design-system/Divider"
|
||||||
|
|
||||||
import { getBookingConfirmation } from "@/lib/trpc/memoizedRequests"
|
import { BookingConfirmationProvider } from "../../providers/BookingConfirmationProvider"
|
||||||
|
import { getBookingConfirmation } from "../../trpc/memoizedRequests/getBookingConfirmation"
|
||||||
import HotelDetails from "@/components/HotelReservation/BookingConfirmation/HotelDetails"
|
import { filterOverlappingDates } from "../../utils/SelectRate"
|
||||||
import PaymentDetails from "@/components/HotelReservation/BookingConfirmation/PaymentDetails"
|
import { SidePanel } from "../SidePanel"
|
||||||
import Promos from "@/components/HotelReservation/BookingConfirmation/Promos"
|
import { Confirmation } from "./Confirmation"
|
||||||
import Receipt from "@/components/HotelReservation/BookingConfirmation/Receipt"
|
import { HotelDetails } from "./HotelDetails"
|
||||||
import Rooms from "@/components/HotelReservation/BookingConfirmation/Rooms"
|
import { PaymentDetails } from "./PaymentDetails"
|
||||||
import SidePanel from "@/components/HotelReservation/SidePanel"
|
import { Promos } from "./Promos"
|
||||||
import { getIntl } from "@/i18n"
|
import { Receipt } from "./Receipt"
|
||||||
|
import { Rooms } from "./Rooms"
|
||||||
import Tracking from "./Tracking"
|
|
||||||
import { mapRoomState } from "./utils"
|
import { mapRoomState } from "./utils"
|
||||||
|
|
||||||
import styles from "./bookingConfirmation.module.css"
|
import styles from "./bookingConfirmation.module.css"
|
||||||
|
|
||||||
|
import type { BookingConfirmation } from "@scandic-hotels/trpc/types/bookingConfirmation"
|
||||||
|
import type { IntlShape } from "react-intl"
|
||||||
|
|
||||||
type BookingConfirmationProps = {
|
type BookingConfirmationProps = {
|
||||||
|
intl: IntlShape
|
||||||
refId: string
|
refId: string
|
||||||
membershipFailedError: boolean
|
membershipFailedError: boolean
|
||||||
|
renderTracking: (trackingProps: {
|
||||||
|
bookingConfirmation: BookingConfirmation
|
||||||
|
refId: string
|
||||||
|
}) => React.ReactNode
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function BookingConfirmation({
|
export async function BookingConfirmation({
|
||||||
|
intl,
|
||||||
refId,
|
refId,
|
||||||
membershipFailedError,
|
membershipFailedError,
|
||||||
|
renderTracking,
|
||||||
}: BookingConfirmationProps) {
|
}: BookingConfirmationProps) {
|
||||||
const bookingConfirmation = await getBookingConfirmation(refId)
|
const bookingConfirmation = await getBookingConfirmation(refId)
|
||||||
|
|
||||||
@@ -44,7 +50,6 @@ export default async function BookingConfirmation({
|
|||||||
return notFound()
|
return notFound()
|
||||||
}
|
}
|
||||||
|
|
||||||
const intl = await getIntl()
|
|
||||||
return (
|
return (
|
||||||
<BookingConfirmationProvider
|
<BookingConfirmationProvider
|
||||||
bookingCode={booking.bookingCode}
|
bookingCode={booking.bookingCode}
|
||||||
@@ -106,7 +111,8 @@ export default async function BookingConfirmation({
|
|||||||
</SidePanel>
|
</SidePanel>
|
||||||
</aside>
|
</aside>
|
||||||
</Confirmation>
|
</Confirmation>
|
||||||
<Tracking bookingConfirmation={bookingConfirmation} refId={refId} />
|
|
||||||
|
{renderTracking({ bookingConfirmation, refId })}
|
||||||
</BookingConfirmationProvider>
|
</BookingConfirmationProvider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -4,12 +4,13 @@ import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
|
|||||||
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
|
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
|
||||||
import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast"
|
import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast"
|
||||||
|
|
||||||
import type { BookingConfirmationRoom } from "@scandic-hotels/booking-flow/types/components/bookingConfirmation/bookingConfirmation"
|
|
||||||
import type {
|
import type {
|
||||||
BookingConfirmationSchema,
|
BookingConfirmationSchema,
|
||||||
PackageSchema,
|
PackageSchema,
|
||||||
} from "@scandic-hotels/trpc/types/bookingConfirmation"
|
} from "@scandic-hotels/trpc/types/bookingConfirmation"
|
||||||
|
|
||||||
|
import type { BookingConfirmationRoom } from "../../types/components/bookingConfirmation/bookingConfirmation"
|
||||||
|
|
||||||
export function mapRoomState(
|
export function mapRoomState(
|
||||||
booking: BookingConfirmationSchema,
|
booking: BookingConfirmationSchema,
|
||||||
room: BookingConfirmationRoom,
|
room: BookingConfirmationRoom,
|
||||||
@@ -21,7 +21,7 @@ import Room from "../Room"
|
|||||||
|
|
||||||
import styles from "./summaryContent.module.css"
|
import styles from "./summaryContent.module.css"
|
||||||
|
|
||||||
import type { Price } from "../../../../../../contexts/SelectRate/getTotalPrice"
|
import type { Price } from "../../../../../../types/price"
|
||||||
|
|
||||||
export type SelectRateSummaryProps = {
|
export type SelectRateSummaryProps = {
|
||||||
isUserLoggedIn: boolean
|
isUserLoggedIn: boolean
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ import { sidePanelVariants } from "./variants"
|
|||||||
|
|
||||||
import styles from "./sidePanel.module.css"
|
import styles from "./sidePanel.module.css"
|
||||||
|
|
||||||
import type { SidePanelProps } from "@/types/components/hotelReservation/sidePanel"
|
import type { VariantProps } from "class-variance-authority"
|
||||||
|
|
||||||
export default function SidePanel({
|
interface SidePanelProps extends VariantProps<typeof sidePanelVariants> {}
|
||||||
|
|
||||||
|
export function SidePanel({
|
||||||
children,
|
children,
|
||||||
variant,
|
variant,
|
||||||
}: React.PropsWithChildren<SidePanelProps>) {
|
}: React.PropsWithChildren<SidePanelProps>) {
|
||||||
@@ -31,13 +31,14 @@ import { clearRooms } from "./clearRooms"
|
|||||||
import { DebugButton } from "./DebugButton"
|
import { DebugButton } from "./DebugButton"
|
||||||
import { findUnavailableSelectedRooms } from "./findUnavailableSelectedRooms"
|
import { findUnavailableSelectedRooms } from "./findUnavailableSelectedRooms"
|
||||||
import { getSelectedPackages } from "./getSelectedPackages"
|
import { getSelectedPackages } from "./getSelectedPackages"
|
||||||
import { getTotalPrice, type Price } from "./getTotalPrice"
|
import { getTotalPrice } from "./getTotalPrice"
|
||||||
import { includeRoomInfo } from "./includeRoomInfo"
|
import { includeRoomInfo } from "./includeRoomInfo"
|
||||||
import { isRateSelected as isRateSelected_Inner } from "./isRateSelected"
|
import { isRateSelected as isRateSelected_Inner } from "./isRateSelected"
|
||||||
|
|
||||||
import type { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast"
|
import type { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast"
|
||||||
|
|
||||||
import type { SelectRateBooking } from "../../types/components/selectRate/selectRate"
|
import type { SelectRateBooking } from "../../types/components/selectRate/selectRate"
|
||||||
|
import type { Price } from "../../types/price"
|
||||||
import type {
|
import type {
|
||||||
AvailabilityWithRoomInfo,
|
AvailabilityWithRoomInfo,
|
||||||
DefaultRoomPackage,
|
DefaultRoomPackage,
|
||||||
|
|||||||
@@ -5,21 +5,9 @@ import { sumPackages, sumPackagesRequestedPrice } from "../../utils/SelectRate"
|
|||||||
|
|
||||||
import type { RedemptionProduct } from "@scandic-hotels/trpc/types/roomAvailability"
|
import type { RedemptionProduct } from "@scandic-hotels/trpc/types/roomAvailability"
|
||||||
|
|
||||||
|
import type { Price } from "../../types/price"
|
||||||
import type { AvailabilityWithRoomInfo, Rate, RoomPackage } from "./types"
|
import type { AvailabilityWithRoomInfo, Rate, RoomPackage } from "./types"
|
||||||
|
|
||||||
type TPrice = {
|
|
||||||
additionalPrice?: number
|
|
||||||
additionalPriceCurrency?: CurrencyEnum
|
|
||||||
currency: CurrencyEnum
|
|
||||||
price: number
|
|
||||||
regularPrice?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Price = {
|
|
||||||
requested?: TPrice
|
|
||||||
local: TPrice
|
|
||||||
}
|
|
||||||
|
|
||||||
type SelectedRate = {
|
type SelectedRate = {
|
||||||
roomConfiguration: AvailabilityWithRoomInfo | null
|
roomConfiguration: AvailabilityWithRoomInfo | null
|
||||||
rate: Rate | undefined
|
rate: Rate | undefined
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
import { type RouterOutput } from "@scandic-hotels/trpc/client"
|
import { type RouterOutput } from "@scandic-hotels/trpc/client"
|
||||||
|
|
||||||
import { type Price } from "./getTotalPrice"
|
|
||||||
|
|
||||||
import type { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter"
|
import type { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter"
|
||||||
import type { RoomsAvailabilityOutputSchema } from "@scandic-hotels/trpc/types/availability"
|
import type { RoomsAvailabilityOutputSchema } from "@scandic-hotels/trpc/types/availability"
|
||||||
import type { PackageEnum } from "@scandic-hotels/trpc/types/packages"
|
import type { PackageEnum } from "@scandic-hotels/trpc/types/packages"
|
||||||
import type { RoomConfiguration } from "@scandic-hotels/trpc/types/roomAvailability"
|
import type { RoomConfiguration } from "@scandic-hotels/trpc/types/roomAvailability"
|
||||||
|
|
||||||
import type { BookingCodeFilterEnum } from "../../stores/bookingCode-filter"
|
import type { BookingCodeFilterEnum } from "../../stores/bookingCode-filter"
|
||||||
|
import type { Price } from "../../types/price"
|
||||||
|
|
||||||
export type SelectRateContext = {
|
export type SelectRateContext = {
|
||||||
hotel: QueryData<RouterOutput["hotel"]["get"]>
|
hotel: QueryData<RouterOutput["hotel"]["get"]>
|
||||||
|
|||||||
62
packages/booking-flow/lib/pages/BookingConfirmationPage.tsx
Normal file
62
packages/booking-flow/lib/pages/BookingConfirmationPage.tsx
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
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 type { Lang } from "@scandic-hotels/common/constants/language"
|
||||||
|
import type { BookingConfirmation as BookingConfirmationType } from "@scandic-hotels/trpc/types/bookingConfirmation"
|
||||||
|
import type { IntlShape } from "react-intl"
|
||||||
|
|
||||||
|
import type { NextSearchParams } from "../types"
|
||||||
|
|
||||||
|
export async function BookingConfirmationPage({
|
||||||
|
intl,
|
||||||
|
lang,
|
||||||
|
searchParams,
|
||||||
|
renderTracking,
|
||||||
|
}: {
|
||||||
|
intl: IntlShape
|
||||||
|
lang: Lang
|
||||||
|
searchParams: NextSearchParams
|
||||||
|
renderTracking: (trackingProps: {
|
||||||
|
bookingConfirmation: BookingConfirmationType
|
||||||
|
refId: string
|
||||||
|
}) => React.ReactNode
|
||||||
|
}) {
|
||||||
|
const refId = searchParams.RefId?.toString()
|
||||||
|
|
||||||
|
if (!refId) {
|
||||||
|
notFound()
|
||||||
|
}
|
||||||
|
|
||||||
|
const cookieStore = await cookies()
|
||||||
|
const sig = cookieStore.get("bcsig")?.value
|
||||||
|
|
||||||
|
if (!sig) {
|
||||||
|
redirect(`/${lang}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const expire = Number(decrypt(sig))
|
||||||
|
const now = Math.floor(Date.now() / 1000)
|
||||||
|
if (typeof expire === "number" && !isNaN(expire) && now > expire) {
|
||||||
|
redirect(`/${lang}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
void getBookingConfirmation(refId)
|
||||||
|
|
||||||
|
const membershipFailedError =
|
||||||
|
searchParams.errorCode === MEMBERSHIP_FAILED_ERROR
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BookingConfirmation
|
||||||
|
intl={intl}
|
||||||
|
refId={refId}
|
||||||
|
membershipFailedError={membershipFailedError}
|
||||||
|
renderTracking={renderTracking}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -12,7 +12,7 @@ import { createBookingConfirmationStore } from "../stores/booking-confirmation"
|
|||||||
import type { BookingConfirmationStore } from "../types/contexts/booking-confirmation"
|
import type { BookingConfirmationStore } from "../types/contexts/booking-confirmation"
|
||||||
import type { BookingConfirmationProviderProps } from "../types/providers/booking-confirmation"
|
import type { BookingConfirmationProviderProps } from "../types/providers/booking-confirmation"
|
||||||
|
|
||||||
export default function BookingConfirmationProvider({
|
export function BookingConfirmationProvider({
|
||||||
bookingCode,
|
bookingCode,
|
||||||
children,
|
children,
|
||||||
currencyCode,
|
currencyCode,
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { cache } from "react"
|
||||||
|
|
||||||
|
import { serverClient } from "../../trpc"
|
||||||
|
|
||||||
|
export const getBookingConfirmation = cache(
|
||||||
|
async function getMemoizedBookingConfirmation(refId: string) {
|
||||||
|
const caller = await serverClient()
|
||||||
|
return caller.booking.get({ refId })
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
export interface PromoProps {
|
export type PromoProps = {
|
||||||
buttonText: string
|
buttonText: string
|
||||||
href: string
|
href: string
|
||||||
text: string
|
text: string
|
||||||
@@ -37,6 +37,7 @@
|
|||||||
"./components/SelectHotelMap": "./lib/components/SelectHotel/SelectHotelMap/index.tsx",
|
"./components/SelectHotelMap": "./lib/components/SelectHotel/SelectHotelMap/index.tsx",
|
||||||
"./components/SelectRate": "./lib/components/SelectRate/index.tsx",
|
"./components/SelectRate": "./lib/components/SelectRate/index.tsx",
|
||||||
"./components/SelectRate/RoomsContainer/RateSummary/utils": "./lib/components/SelectRate/RoomsContainer/RateSummary/utils.ts",
|
"./components/SelectRate/RoomsContainer/RateSummary/utils": "./lib/components/SelectRate/RoomsContainer/RateSummary/utils.ts",
|
||||||
|
"./components/SidePanel": "./lib/components/SidePanel/index.tsx",
|
||||||
"./components/SidePeekAccordions/BreakfastAccordionItem": "./lib/components/SidePeekAccordions/BreakfastAccordionItem.tsx",
|
"./components/SidePeekAccordions/BreakfastAccordionItem": "./lib/components/SidePeekAccordions/BreakfastAccordionItem.tsx",
|
||||||
"./components/SidePeekAccordions/CheckInCheckOutAccordionItem": "./lib/components/SidePeekAccordions/CheckInCheckOutAccordionItem.tsx",
|
"./components/SidePeekAccordions/CheckInCheckOutAccordionItem": "./lib/components/SidePeekAccordions/CheckInCheckOutAccordionItem.tsx",
|
||||||
"./components/SidePeekAccordions/ParkingAccordionItem": "./lib/components/SidePeekAccordions/ParkingAccordionItem.tsx",
|
"./components/SidePeekAccordions/ParkingAccordionItem": "./lib/components/SidePeekAccordions/ParkingAccordionItem.tsx",
|
||||||
@@ -54,11 +55,13 @@
|
|||||||
"./stores/bookingCode-filter": "./lib/stores/bookingCode-filter.ts",
|
"./stores/bookingCode-filter": "./lib/stores/bookingCode-filter.ts",
|
||||||
"./stores/hotels-map": "./lib/stores/hotels-map.ts",
|
"./stores/hotels-map": "./lib/stores/hotels-map.ts",
|
||||||
"./stores/booking-confirmation": "./lib/stores/booking-confirmation/index.ts",
|
"./stores/booking-confirmation": "./lib/stores/booking-confirmation/index.ts",
|
||||||
"./types/components/selectRate/selectRate": "./lib/types/components/selectRate/selectRate.ts",
|
|
||||||
"./types/components/bookingConfirmation/bookingConfirmation": "./lib/types/components/bookingConfirmation/bookingConfirmation.ts",
|
"./types/components/bookingConfirmation/bookingConfirmation": "./lib/types/components/bookingConfirmation/bookingConfirmation.ts",
|
||||||
"./types/components/findMyBooking/additionalInfoCookieValue": "./lib/types/components/findMyBooking/additionalInfoCookieValue.ts",
|
"./types/components/findMyBooking/additionalInfoCookieValue": "./lib/types/components/findMyBooking/additionalInfoCookieValue.ts",
|
||||||
|
"./types/components/promo/promoProps": "./lib/types/components/promo/promoProps.ts",
|
||||||
|
"./types/components/selectRate/selectRate": "./lib/types/components/selectRate/selectRate.ts",
|
||||||
"./types/stores/rates": "./lib/types/stores/rates.ts",
|
"./types/stores/rates": "./lib/types/stores/rates.ts",
|
||||||
"./types/stores/booking-confirmation": "./lib/types/stores/booking-confirmation.ts",
|
"./types/stores/booking-confirmation": "./lib/types/stores/booking-confirmation.ts",
|
||||||
|
"./utils/getRoomFeatureDescription": "./lib/utils/getRoomFeatureDescription.ts",
|
||||||
"./utils/isSameBooking": "./lib/utils/isSameBooking.ts",
|
"./utils/isSameBooking": "./lib/utils/isSameBooking.ts",
|
||||||
"./utils/url": "./lib/utils/url.ts",
|
"./utils/url": "./lib/utils/url.ts",
|
||||||
"./utils/SelectRate": "./lib/utils/SelectRate/index.tsx",
|
"./utils/SelectRate": "./lib/utils/SelectRate/index.tsx",
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
},
|
},
|
||||||
"exports": {
|
"exports": {
|
||||||
"./constants/alert": "./constants/alert.ts",
|
"./constants/alert": "./constants/alert.ts",
|
||||||
|
"./constants/booking": "./constants/booking.ts",
|
||||||
"./constants/currency": "./constants/currency.ts",
|
"./constants/currency": "./constants/currency.ts",
|
||||||
"./constants/dateFormats": "./constants/dateFormats.ts",
|
"./constants/dateFormats": "./constants/dateFormats.ts",
|
||||||
"./constants/facilities": "./constants/facilities.ts",
|
"./constants/facilities": "./constants/facilities.ts",
|
||||||
|
|||||||
Reference in New Issue
Block a user