Merged in feat/book-425-optimize-campaign-rate-card (pull request #3015)

Feat/book 425 optimize campaign rate card

* feat(BOOK-425): design updates to RateCard

* feat(BOOK-425): design updates to campaign BookingCodeChip

* feat(BOOK-425): fixed breakfast message & booking code chips on select rate and enter detailss

* feat(BOOK-425): fixed booking code chip on Booking Confirmation page

* fixed draft comments

* fixed more comments

* feat(BOOK-425): removed fixed height from RateCard banner

* fixed another variable comment

* fixed more pr comments

* fixed more pr comments

* updated ratecard campaign standard rate title color

* removed deconstructed props


Approved-by: Bianca Widstam
Approved-by: Erik Tiekstra
This commit is contained in:
Matilda Haneling
2025-10-29 13:54:29 +00:00
parent 56b44c16d4
commit 2c6d9860e1
28 changed files with 272 additions and 83 deletions

View File

@@ -120,8 +120,10 @@ export default function PriceDetails() {
requested: undefined,
}
)
const mappedRooms = mapToPrice(rooms, nights)
const isCampaignRate = rooms.every(
(room) => room?.rateDefinition.isCampaignRate
)
return (
<PriceDetailsModal
@@ -132,6 +134,7 @@ export default function PriceDetails() {
totalPrice={totalPrice}
vat={vat}
defaultCurrency={currency}
isCampaignRate={isCampaignRate}
/>
)
}

View File

@@ -5,6 +5,7 @@ import { useIntl } from "react-intl"
import { CancellationRuleEnum } from "@scandic-hotels/common/constants/booking"
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
import { BookingCodeChip } from "@scandic-hotels/design-system/BookingCodeChip"
import { Button } from "@scandic-hotels/design-system/Button"
import { Divider } from "@scandic-hotels/design-system/Divider"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
@@ -25,20 +26,22 @@ type BookingConfirmationReceiptRoomProps = {
room: Room
roomNumber: number
roomCount: number
showBookingCodeChip?: boolean
}
export function ReceiptRoom({
room,
roomNumber,
roomCount,
showBookingCodeChip = false,
}: BookingConfirmationReceiptRoomProps) {
const intl = useIntl()
const { currencyCode, isVatCurrency } = useBookingConfirmationStore(
(state) => ({
const { currencyCode, isVatCurrency, bookingCode } =
useBookingConfirmationStore((state) => ({
currencyCode: state.currencyCode,
isVatCurrency: state.isVatCurrency,
})
)
bookingCode: state.bookingCode,
}))
if (!room) {
return <RoomSkeletonLoader />
@@ -74,7 +77,8 @@ export function ReceiptRoom({
}
const guests = guestsParts.join(", ")
const showDiscounted = room.rateDefinition.isMemberRate
const showDiscounted =
room.rateDefinition.isMemberRate || room.rateDefinition.isCampaignRate
return (
<>
@@ -276,6 +280,14 @@ export function ReceiptRoom({
breakfastIncluded={room.breakfastIncluded}
guests={guests}
/>
{showBookingCodeChip && (
<BookingCodeChip
isCampaign={room.rateDefinition.isCampaignRate}
bookingCode={bookingCode}
alignCenter
/>
)}
</div>
<Divider color="Border/Divider/Subtle" />
</>

View File

@@ -3,8 +3,6 @@
import { cx } from "class-variance-authority"
import { useIntl } from "react-intl"
import { BookingCodeChip } from "@scandic-hotels/design-system/BookingCodeChip"
import { Divider } from "@scandic-hotels/design-system/Divider"
import SkeletonShimmer from "@scandic-hotels/design-system/SkeletonShimmer"
import { Typography } from "@scandic-hotels/design-system/Typography"
@@ -30,7 +28,6 @@ export default function TotalPrice() {
return (
<>
<Divider color="Border/Divider/Subtle" />
<div className={styles.price}>
<div className={styles.entry}>
<div>
@@ -70,15 +67,13 @@ export default function TotalPrice() {
</div>
</div>
</div>
<div className={styles.ctaWrapper}>
<div>
{hasAllRoomsLoaded ? (
<PriceDetails />
) : (
<SkeletonShimmer width={"100%"} />
)}
</div>
{bookingCode && <BookingCodeChip bookingCode={bookingCode} alignCenter />}
</>
)
}

View File

@@ -2,7 +2,6 @@
display: flex;
gap: var(--Space-x05);
justify-content: space-between;
margin-bottom: var(--Space-x15);
}
.prices {
@@ -27,7 +26,3 @@
.approxPrice {
color: var(--Text-Secondary);
}
.ctaWrapper {
margin-top: var(--Space-x15);
}

View File

@@ -4,6 +4,7 @@ import { useIntl } from "react-intl"
import { longDateFormat } from "@scandic-hotels/common/constants/dateFormats"
import { dt } from "@scandic-hotels/common/dt"
import { BookingCodeChip } from "@scandic-hotels/design-system/BookingCodeChip"
import { Divider } from "@scandic-hotels/design-system/Divider"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import { Typography } from "@scandic-hotels/design-system/Typography"
@@ -18,13 +19,19 @@ import styles from "./receipt.module.css"
export function Receipt() {
const lang = useLang()
const intl = useIntl()
const { rooms, fromDate, toDate } = useBookingConfirmationStore((state) => ({
rooms: state.rooms,
fromDate: state.fromDate,
toDate: state.toDate,
}))
const { rooms, fromDate, toDate, bookingCode } = useBookingConfirmationStore(
(state) => ({
rooms: state.rooms,
fromDate: state.fromDate,
toDate: state.toDate,
bookingCode: state.bookingCode,
})
)
const totalNights = dt(toDate).diff(fromDate, "days")
const isCampaignRate = rooms.every(
(room) => room?.rateDefinition.isCampaignRate
)
const nights = intl.formatMessage(
{
@@ -67,10 +74,21 @@ export function Receipt() {
room={room}
roomNumber={idx + 1}
roomCount={rooms.length}
showBookingCodeChip={
rooms.length !== 1 &&
(room.rateDefinition.isCampaignRate || !!bookingCode)
}
/>
))}
<TotalPrice />
{rooms.length === 1 && (isCampaignRate || !!bookingCode) && (
<BookingCodeChip
isCampaign={isCampaignRate}
bookingCode={bookingCode}
alignCenter
/>
)}
</section>
)
}