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

@@ -6,6 +6,7 @@ import { CurrencyEnum } from "@scandic-hotels/common/constants/currency"
import { longDateFormat } from "@scandic-hotels/common/constants/dateFormats"
import { dt } from "@scandic-hotels/common/dt"
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
import { BookingCodeChip } from "@scandic-hotels/design-system/BookingCodeChip"
import { Divider } from "@scandic-hotels/design-system/Divider"
import { IconButton } from "@scandic-hotels/design-system/IconButton"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
@@ -58,6 +59,11 @@ export default function SummaryContent({
(r) => r && isBookingCodeRate(r)
)
const cointainsCode = selectedRates.rates.find((r) => r?.type === "code")
const containsCampaignRate = selectedRates.rates.some(
(r) => r?.type === "campaign"
)
if (!selectedRates?.totalPrice) {
return null
}
@@ -129,6 +135,10 @@ export default function SummaryContent({
roomNumber={idx + 1}
roomCount={selectedRates.rates.length}
isMember={isUserLoggedIn && idx === 0}
showBookingCodeChip={
selectedRates.rates.length !== 1 &&
(room.rateDefinition.isCampaignRate || isBookingCodeRate(room))
}
/>
)
})}
@@ -216,6 +226,9 @@ export default function SummaryContent({
selectedRates.totalPrice.requested?.currency ??
selectedRates.totalPrice.local.currency
}
isCampaignRate={selectedRates?.rates?.some(
(room) => room != null && room.type === "campaign"
)}
rooms={selectedRates.rates
.map((room, idx) => {
if (!room) {
@@ -308,6 +321,7 @@ export default function SummaryContent({
breakfastIncluded:
room?.rateDefinition.breakfastIncluded ?? false,
rateDefinition: room.rateDefinition,
bookingCode: room.bookingCode,
}
})
.filter((x) => !!x)}
@@ -317,6 +331,17 @@ export default function SummaryContent({
vat={selectedRates.vat}
/>
</div>
{selectedRates.rates.length === 1 &&
(containsBookingCodeRate || cointainsCode) && (
<div>
<BookingCodeChip
alignCenter
bookingCode={input.bookingCode}
isCampaign={containsCampaignRate}
/>
</div>
)}
{!isUserLoggedIn && memberPrice ? (
<SignupPromoDesktop
memberPrice={{

View File

@@ -2,6 +2,7 @@ import { cx } from "class-variance-authority"
import { useIntl } from "react-intl"
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"
@@ -33,6 +34,7 @@ interface RoomProps {
cancellationText: string
packages?: Packages
}
showBookingCodeChip: boolean
roomNumber: number
roomCount: number
isMember: boolean
@@ -43,6 +45,7 @@ export default function Room({
roomNumber,
roomCount,
isMember,
showBookingCodeChip,
}: RoomProps) {
const intl = useIntl()
const adults = room.adults
@@ -271,6 +274,13 @@ export default function Room({
</Typography>
))}
</div>
{showBookingCodeChip && (
<BookingCodeChip
isCampaign={room.roomRate.rateDefinition.isCampaignRate}
bookingCode={room.roomRate.bookingCode}
alignCenter
/>
)}
<Divider color="Border/Divider/Subtle" />
</>
)

View File

@@ -6,6 +6,7 @@ export function RemoveBookingCodeButton() {
const {
input: { bookingCode },
actions: { removeBookingCode },
hasCampaignRates,
} = useSelectRateContext()
if (!bookingCode) {
@@ -16,6 +17,7 @@ export function RemoveBookingCodeButton() {
<BookingCodeChip
bookingCode={bookingCode}
filledIcon
isCampaign={hasCampaignRates}
withCloseButton={true}
withText={false}
onClose={() => {

View File

@@ -148,8 +148,9 @@ function Inner({
id: "booking.campaign",
defaultMessage: "Campaign",
})
if (product.bookingCode) {
bannerText = product.bookingCode
bannerText = `${bannerText}${product.bookingCode.trim()}`
}
if (product.rateDefinition.breakfastIncluded) {
@@ -157,11 +158,6 @@ function Inner({
id: "booking.breakfastIncluded",
defaultMessage: "Breakfast included",
})}`
} else {
bannerText = `${bannerText}${intl.formatMessage({
id: "booking.breakfastExcluded",
defaultMessage: "Breakfast excluded",
})}`
}
const pkgsSum = sumPackages(selectedPackages)

View File

@@ -1,7 +1,5 @@
"use client"
import { Divider } from "@scandic-hotels/design-system/Divider"
import { useSelectRateContext } from "../../../../../../../contexts/SelectRate/SelectRateContext"
import { BookingCodeFilterEnum } from "../../../../../../../stores/bookingCode-filter"
import { BreakfastMessage } from "./BreakfastMessage"
@@ -44,22 +42,38 @@ export function Rates({
selectedPackages,
}
const showAllRates = bookingCodeFilter === BookingCodeFilterEnum.All
const hasBookingCodeRates = !!(campaign.length || code.length)
const hasRegularRates = !!regular.length
const showDivider = showAllRates && hasBookingCodeRates && hasRegularRates
const showSeparateCampaignBreakfastMessage = campaign.some((camp) => {
return (
camp.rateDefinition.breakfastIncluded ||
camp.rateDefinitionMember?.breakfastIncluded
)
})
return (
<>
<Code {...sharedProps} code={code} />
{!showSeparateCampaignBreakfastMessage && showAllRates && (
<BreakfastMessage
breakfastIncludedMember={breakfastIncludedInAllRatesMember}
breakfastIncludedStandard={breakfastIncludedInAllRates}
hasRegularRates={hasRegularRates && showAllRates}
roomIndex={roomIndex}
/>
)}
<Campaign {...sharedProps} campaign={campaign} />
<Redemptions {...sharedProps} redemptions={redemptions} />
{showDivider ? <Divider color="Border/Divider/Subtle" /> : null}
<BreakfastMessage
breakfastIncludedMember={breakfastIncludedInAllRatesMember}
breakfastIncludedStandard={breakfastIncludedInAllRates}
hasRegularRates={hasRegularRates && showAllRates}
roomIndex={roomIndex}
/>
{showSeparateCampaignBreakfastMessage && showAllRates && (
<BreakfastMessage
breakfastIncludedMember={breakfastIncludedInAllRatesMember}
breakfastIncludedStandard={breakfastIncludedInAllRates}
hasRegularRates={hasRegularRates && showAllRates}
roomIndex={roomIndex}
/>
)}
<RegularRate {...sharedProps} regular={regular} />
</>
)