Merged in feat/BOOK-479-scandic-go-hotels-rm-brf- (pull request #3143)

feat(BOOK-479): Updated breakfast UI for ScandicGo hotels

Approved-by: Erik Tiekstra
This commit is contained in:
Hrishikesh Vaipurkar
2025-11-18 13:03:46 +00:00
parent 93c481fea8
commit 4c0daf8062
23 changed files with 144 additions and 213 deletions

View File

@@ -1,6 +1,7 @@
"use client" "use client"
import PriceDetailsModal from "@scandic-hotels/booking-flow/components/PriceDetailsModal" import PriceDetailsModal from "@scandic-hotels/booking-flow/components/PriceDetailsModal"
import { dt } from "@scandic-hotels/common/dt" import { dt } from "@scandic-hotels/common/dt"
import { HotelTypeEnum } from "@scandic-hotels/trpc/enums/hotelType"
import { useMyStayStore } from "@/stores/my-stay" import { useMyStayStore } from "@/stores/my-stay"
@@ -9,17 +10,20 @@ import { calculateTotalPrice, mapToPrice } from "./mapToPrice"
import styles from "./priceDetails.module.css" import styles from "./priceDetails.module.css"
export default function PriceDetails() { export default function PriceDetails() {
const { bookedRoom, rooms } = useMyStayStore((state) => ({ const { bookedRoom, rooms, hotelOffersBreakfast } = useMyStayStore(
bookedRoom: state.bookedRoom, (state) => ({
rooms: state.rooms bookedRoom: state.bookedRoom,
.filter((room) => !room.isCancelled) rooms: state.rooms
.map((room) => ({ .filter((room) => !room.isCancelled)
...room, .map((room) => ({
breakfastIncluded: room.rateDefinition.breakfastIncluded, ...room,
price: mapToPrice(room), breakfastIncluded: room.rateDefinition.breakfastIncluded,
roomType: room.roomName, price: mapToPrice(room),
})), roomType: room.roomName,
})) })),
hotelOffersBreakfast: state.hotel.hotelType !== HotelTypeEnum.ScandicGo,
})
)
const bookingCode = const bookingCode =
rooms.find((room) => room.bookingCode)?.bookingCode ?? undefined rooms.find((room) => room.bookingCode)?.bookingCode ?? undefined
@@ -38,6 +42,7 @@ export default function PriceDetails() {
vat={bookedRoom.vatPercentage} vat={bookedRoom.vatPercentage}
defaultCurrency={bookedRoom.currencyCode} defaultCurrency={bookedRoom.currencyCode}
isCampaignRate={bookedRoom.isCampaignRate} isCampaignRate={bookedRoom.isCampaignRate}
hotelOffersBreakfast={hotelOffersBreakfast}
/> />
</div> </div>
) )

View File

@@ -9,15 +9,23 @@ import { mapToPrice } from "./mapToPrice"
import type { Price } from "../../../types/price" import type { Price } from "../../../types/price"
export default function PriceDetails() { export default function PriceDetails() {
const { bookingCode, currency, fromDate, rooms, vat, toDate } = const {
useBookingConfirmationStore((state) => ({ bookingCode,
bookingCode: state.bookingCode ?? undefined, currency,
currency: state.currencyCode, hotelOffersBreakfast,
fromDate: state.fromDate, fromDate,
rooms: state.rooms, rooms,
toDate: state.toDate, vat,
vat: state.vat, toDate,
})) } = useBookingConfirmationStore((state) => ({
bookingCode: state.bookingCode ?? undefined,
currency: state.currencyCode,
hotelOffersBreakfast: state.hotelOffersBreakfast,
fromDate: state.fromDate,
rooms: state.rooms,
toDate: state.toDate,
vat: state.vat,
}))
if (!rooms[0]) { if (!rooms[0]) {
return null return null
@@ -135,6 +143,7 @@ export default function PriceDetails() {
vat={vat} vat={vat}
defaultCurrency={currency} defaultCurrency={currency}
isCampaignRate={isCampaignRate} isCampaignRate={isCampaignRate}
hotelOffersBreakfast={hotelOffersBreakfast}
/> />
) )
} }

View File

@@ -15,7 +15,7 @@ import { ChildBedTypeEnum } from "@scandic-hotels/trpc/enums/childBedTypeEnum"
import { useBookingConfirmationStore } from "../../../../stores/booking-confirmation" import { useBookingConfirmationStore } from "../../../../stores/booking-confirmation"
import { getRoomFeatureDescription } from "../../../../utils/getRoomFeatureDescription" import { getRoomFeatureDescription } from "../../../../utils/getRoomFeatureDescription"
import Breakfast from "./Breakfast" import { SummaryBreakfast } from "../../../SummaryBreakfast"
import RoomSkeletonLoader from "./RoomSkeletonLoader" import RoomSkeletonLoader from "./RoomSkeletonLoader"
import styles from "./room.module.css" import styles from "./room.module.css"
@@ -36,11 +36,12 @@ export function ReceiptRoom({
showBookingCodeChip = false, showBookingCodeChip = false,
}: BookingConfirmationReceiptRoomProps) { }: BookingConfirmationReceiptRoomProps) {
const intl = useIntl() const intl = useIntl()
const { currencyCode, isVatCurrency, bookingCode } = const { currencyCode, isVatCurrency, bookingCode, hotelOffersBreakfast } =
useBookingConfirmationStore((state) => ({ useBookingConfirmationStore((state) => ({
currencyCode: state.currencyCode, currencyCode: state.currencyCode,
isVatCurrency: state.isVatCurrency, isVatCurrency: state.isVatCurrency,
bookingCode: state.bookingCode, bookingCode: state.bookingCode,
hotelOffersBreakfast: state.hotelOffersBreakfast,
})) }))
if (!room) { if (!room) {
@@ -80,6 +81,11 @@ export function ReceiptRoom({
const showDiscounted = const showDiscounted =
room.rateDefinition.isMemberRate || room.rateDefinition.isCampaignRate room.rateDefinition.isMemberRate || room.rateDefinition.isCampaignRate
const breakfastPrice = room.breakfast
? room.breakfast?.totalPrice
: room.breakfast
const breakfastCurrency = room.breakfast ? room.breakfast?.currency : null
return ( return (
<> <>
<div className={styles.room}> <div className={styles.room}>
@@ -275,10 +281,12 @@ export function ReceiptRoom({
</div> </div>
</Typography> </Typography>
) : null} ) : null}
<Breakfast <SummaryBreakfast
breakfast={room.breakfast} breakfastPrice={breakfastPrice}
breakfastCurrency={breakfastCurrency}
breakfastIncluded={room.breakfastIncluded} breakfastIncluded={room.breakfastIncluded}
guests={guests} guests={guests}
hotelOffersBreakfast={hotelOffersBreakfast}
/> />
{showBookingCodeChip && ( {showBookingCodeChip && (

View File

@@ -4,6 +4,7 @@ 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 { HotelTypeEnum } from "@scandic-hotels/trpc/enums/hotelType"
import { BookingConfirmationProvider } from "../../providers/BookingConfirmationProvider" import { BookingConfirmationProvider } from "../../providers/BookingConfirmationProvider"
import { getBookingConfirmation } from "../../trpc/memoizedRequests/getBookingConfirmation" import { getBookingConfirmation } from "../../trpc/memoizedRequests/getBookingConfirmation"
@@ -51,6 +52,7 @@ export async function BookingConfirmation({
bookingCode={booking.bookingCode} bookingCode={booking.bookingCode}
currencyCode={booking.currencyCode} currencyCode={booking.currencyCode}
fromDate={booking.checkInDate} fromDate={booking.checkInDate}
hotelOffersBreakfast={hotel.hotelType !== HotelTypeEnum.ScandicGo}
toDate={booking.checkOutDate} toDate={booking.checkOutDate}
roomCategories={roomCategories} roomCategories={roomCategories}
rooms={[ rooms={[

View File

@@ -1,6 +1,5 @@
"use client" "use client"
import { useEnterDetailsStore } from "../../../stores/enter-details"
import { SidePanel } from "../../SidePanel" import { SidePanel } from "../../SidePanel"
import SummaryUI from "./UI" import SummaryUI from "./UI"
@@ -9,30 +8,9 @@ type Props = {
} }
export default function DesktopSummary({ isUserLoggedIn }: Props) { export default function DesktopSummary({ isUserLoggedIn }: Props) {
const toggleSummaryOpen = useEnterDetailsStore(
(state) => state.actions.toggleSummaryOpen
)
const { booking, rooms, totalPrice, vat, defaultCurrency } =
useEnterDetailsStore((state) => ({
booking: state.booking,
rooms: state.rooms,
totalPrice: state.totalPrice,
vat: state.vat,
defaultCurrency: state.defaultCurrency,
}))
return ( return (
<SidePanel variant="summary"> <SidePanel variant="summary">
<SummaryUI <SummaryUI isUserLoggedIn={isUserLoggedIn} />
booking={booking}
rooms={rooms}
isUserLoggedIn={isUserLoggedIn}
totalPrice={totalPrice}
vat={vat}
toggleSummaryOpen={toggleSummaryOpen}
defaultCurrency={defaultCurrency}
/>
</SidePanel> </SidePanel>
) )
} }

View File

@@ -11,22 +11,14 @@ type Props = {
isUserLoggedIn: boolean isUserLoggedIn: boolean
} }
export default function MobileSummary({ isUserLoggedIn }: Props) { export default function MobileSummary({ isUserLoggedIn }: Props) {
const { isSummaryOpen, toggleSummaryOpen } = useEnterDetailsStore( const { rooms, isSummaryOpen, toggleSummaryOpen } = useEnterDetailsStore(
(state) => ({ (state) => ({
rooms: state.rooms,
isSummaryOpen: state.isSummaryOpen, isSummaryOpen: state.isSummaryOpen,
toggleSummaryOpen: state.actions.toggleSummaryOpen, toggleSummaryOpen: state.actions.toggleSummaryOpen,
}) })
) )
const { booking, rooms, totalPrice, vat, defaultCurrency } =
useEnterDetailsStore((state) => ({
booking: state.booking,
rooms: state.rooms,
totalPrice: state.totalPrice,
vat: state.vat,
defaultCurrency: state.defaultCurrency,
}))
const showPromo = const showPromo =
!isUserLoggedIn && !isUserLoggedIn &&
rooms.length === 1 && rooms.length === 1 &&
@@ -52,15 +44,7 @@ export default function MobileSummary({ isUserLoggedIn }: Props) {
<SummaryBottomSheet isUserLoggedIn={isUserLoggedIn}> <SummaryBottomSheet isUserLoggedIn={isUserLoggedIn}>
<div className={styles.wrapper}> <div className={styles.wrapper}>
<SummaryUI <SummaryUI isUserLoggedIn={isUserLoggedIn} />
booking={booking}
rooms={rooms}
isUserLoggedIn={isUserLoggedIn}
totalPrice={totalPrice}
vat={vat}
toggleSummaryOpen={toggleSummaryOpen}
defaultCurrency={defaultCurrency}
/>
</div> </div>
</SummaryBottomSheet> </SummaryBottomSheet>
</div> </div>

View File

@@ -1,13 +0,0 @@
.entry {
display: flex;
gap: var(--Space-x05);
justify-content: space-between;
}
.textDefault {
color: var(--Text-Default);
}
.uiTextMediumContrast {
color: var(--UI-Text-Medium-contrast);
}

View File

@@ -1,79 +0,0 @@
"use client"
import { useIntl } from "react-intl"
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
import { Typography } from "@scandic-hotels/design-system/Typography"
import styles from "./breakfast.module.css"
import type { BreakfastPackage } from "@scandic-hotels/trpc/routers/hotels/schemas/packages"
interface BreakfastProps {
adults: number
breakfast: BreakfastPackage | false | undefined
breakfastIncluded: boolean
guests: string
nights: number
}
export default function Breakfast({
adults,
breakfast,
breakfastIncluded,
guests,
nights,
}: BreakfastProps) {
const intl = useIntl()
const breakfastBuffet = intl.formatMessage({
id: "common.breakfastBuffet",
defaultMessage: "Breakfast buffet",
})
if (breakfastIncluded || breakfast) {
const price = breakfast
? formatPrice(
intl,
breakfast.localPrice.price * adults * nights,
breakfast.localPrice.currency
)
: intl.formatMessage({
id: "common.included",
defaultMessage: "Included",
})
return (
<div className={styles.entry}>
<div>
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.textDefault}>{breakfastBuffet}</p>
</Typography>
<Typography variant="Body/Supporting text (caption)/smRegular">
<p className={styles.uiTextMediumContrast}>{guests}</p>
</Typography>
</div>
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.textDefault}>{price}</p>
</Typography>
</div>
)
}
if (breakfast === false) {
const noBreakfast = intl.formatMessage({
id: "common.noBreakfast",
defaultMessage: "No breakfast",
})
return (
<div className={styles.entry}>
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.textDefault}>{breakfastBuffet}</p>
</Typography>
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.textDefault}>{noBreakfast}</p>
</Typography>
</div>
)
}
return null
}

View File

@@ -12,7 +12,7 @@ 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 { getRoomFeatureDescription } from "../../../../../utils/getRoomFeatureDescription" import { getRoomFeatureDescription } from "../../../../../utils/getRoomFeatureDescription"
import Breakfast from "./Breakfast" import { SummaryBreakfast } from "../../../../SummaryBreakfast"
import styles from "./room.module.css" import styles from "./room.module.css"
@@ -26,6 +26,7 @@ interface RoomProps {
nightsCount: number nightsCount: number
defaultCurrency: CurrencyEnum defaultCurrency: CurrencyEnum
showBookingCodeChip?: boolean showBookingCodeChip?: boolean
hotelOffersBreakfast?: boolean
} }
export default function Room({ export default function Room({
@@ -36,6 +37,7 @@ export default function Room({
nightsCount, nightsCount,
defaultCurrency, defaultCurrency,
showBookingCodeChip = false, showBookingCodeChip = false,
hotelOffersBreakfast = true,
}: RoomProps) { }: RoomProps) {
const intl = useIntl() const intl = useIntl()
const adults = room.adults const adults = room.adults
@@ -132,6 +134,13 @@ export default function Room({
) )
} }
const breakfastPrice = room.breakfast
? room.breakfast?.localPrice.price * adults * nightsCount
: room.breakfast
const breakfastCurrency = room.breakfast
? room.breakfast?.localPrice.currency
: null
return ( return (
<> <>
<div className={styles.room} data-testid={`summary-room-${roomNumber}`}> <div className={styles.room} data-testid={`summary-room-${roomNumber}`}>
@@ -340,12 +349,12 @@ export default function Room({
</Typography> </Typography>
) : null} ) : null}
<Breakfast <SummaryBreakfast
adults={room.adults}
breakfast={room.breakfast}
breakfastIncluded={room.breakfastIncluded} breakfastIncluded={room.breakfastIncluded}
breakfastPrice={breakfastPrice}
breakfastCurrency={breakfastCurrency}
guests={guests} guests={guests}
nights={nightsCount} hotelOffersBreakfast={hotelOffersBreakfast}
/> />
</div> </div>
{showBookingCodeChip && ( {showBookingCodeChip && (

View File

@@ -16,6 +16,7 @@ import Subtitle from "@scandic-hotels/design-system/Subtitle"
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 { useEnterDetailsStore } from "../../../../stores/enter-details"
import PriceDetailsModal from "../../../PriceDetailsModal" import PriceDetailsModal from "../../../PriceDetailsModal"
import { isBookingCodeRate } from "../../../SelectRate/RoomsContainer/RateSummary/utils" import { isBookingCodeRate } from "../../../SelectRate/RoomsContainer/RateSummary/utils"
import SignupPromoDesktop from "../../../SignupPromo/Desktop" import SignupPromoDesktop from "../../../SignupPromo/Desktop"
@@ -25,33 +26,33 @@ import { getMemberPrice } from "./utils"
import styles from "./ui.module.css" import styles from "./ui.module.css"
import type { RoomState } from "../../../../stores/enter-details/types"
import type { Price } from "../../../../types/price"
import type { DetailsBooking } from "../../../../utils/url"
type EnterDetailsSummaryProps = {
booking: DetailsBooking
isUserLoggedIn: boolean
totalPrice: Price
vat: number
rooms: RoomState[]
toggleSummaryOpen: () => void
defaultCurrency: CurrencyEnum
}
export default function SummaryUI({ export default function SummaryUI({
booking,
rooms,
totalPrice,
isUserLoggedIn, isUserLoggedIn,
vat, }: {
toggleSummaryOpen, isUserLoggedIn: boolean
defaultCurrency, }) {
}: EnterDetailsSummaryProps) {
const intl = useIntl() const intl = useIntl()
const lang = useLang() const lang = useLang()
const isDesktop = useMediaQuery("(min-width: 1367px)") const isDesktop = useMediaQuery("(min-width: 1367px)")
const {
booking,
defaultCurrency,
hotelOffersBreakfast,
rooms,
totalPrice,
vat,
toggleSummaryOpen,
} = useEnterDetailsStore((state) => ({
booking: state.booking,
defaultCurrency: state.defaultCurrency,
hotelOffersBreakfast: state.hotelOffersBreakfast,
rooms: state.rooms,
totalPrice: state.totalPrice,
vat: state.vat,
toggleSummaryOpen: state.actions.toggleSummaryOpen,
}))
const nights = dt(booking.toDate).diff(booking.fromDate, "days") const nights = dt(booking.toDate).diff(booking.fromDate, "days")
const nightsMsg = intl.formatMessage( const nightsMsg = intl.formatMessage(
@@ -143,6 +144,7 @@ export default function SummaryUI({
(room.roomRate.rateDefinition.isCampaignRate || (room.roomRate.rateDefinition.isCampaignRate ||
!!room.roomRate.bookingCode) !!room.roomRate.bookingCode)
} }
hotelOffersBreakfast={hotelOffersBreakfast}
/> />
))} ))}
@@ -231,6 +233,7 @@ export default function SummaryUI({
totalPrice={totalPrice} totalPrice={totalPrice}
vat={vat} vat={vat}
isCampaignRate={!!containsCampaignRate} isCampaignRate={!!containsCampaignRate}
hotelOffersBreakfast={hotelOffersBreakfast}
/> />
</div> </div>
</div> </div>

View File

@@ -18,6 +18,7 @@ interface BreakfastProps {
childrenInRoom: Child[] | undefined childrenInRoom: Child[] | undefined
currency: string currency: string
nights: number nights: number
hotelOffersBreakfast?: boolean
} }
export default function Breakfast({ export default function Breakfast({
@@ -28,6 +29,7 @@ export default function Breakfast({
childrenInRoom = [], childrenInRoom = [],
currency, currency,
nights, nights,
hotelOffersBreakfast = true,
}: BreakfastProps) { }: BreakfastProps) {
const intl = useIntl() const intl = useIntl()
@@ -194,7 +196,10 @@ export default function Breakfast({
}) })
return ( return (
<Tbody> <Tbody>
<BoldRow label={breakfastBuffet} value={noBreakfast} /> <BoldRow
label={hotelOffersBreakfast ? breakfastBuffet : undefined}
value={noBreakfast}
/>
</Tbody> </Tbody>
) )
} }

View File

@@ -5,7 +5,7 @@ import { Typography } from "@scandic-hotels/design-system/Typography"
import styles from "./row.module.css" import styles from "./row.module.css"
interface RowProps { interface RowProps {
label: string label?: string
value: string value: string
regularValue?: string regularValue?: string
isDiscounted?: boolean isDiscounted?: boolean
@@ -19,11 +19,13 @@ export default function BoldRow({
}: RowProps) { }: RowProps) {
return ( return (
<tr className={styles.row}> <tr className={styles.row}>
<td> {label ? (
<Typography variant="Body/Supporting text (caption)/smBold"> <td>
<span>{label}</span> <Typography variant="Body/Supporting text (caption)/smBold">
</Typography> <span>{label}</span>
</td> </Typography>
</td>
) : null}
<td className={styles.price}> <td className={styles.price}>
{isDiscounted && regularValue ? ( {isDiscounted && regularValue ? (
<Typography variant="Body/Supporting text (caption)/smRegular"> <Typography variant="Body/Supporting text (caption)/smRegular">

View File

@@ -66,6 +66,7 @@ export interface PriceDetailsTableProps {
totalPrice: Price totalPrice: Price
vat: number vat: number
defaultCurrency: CurrencyEnum defaultCurrency: CurrencyEnum
hotelOffersBreakfast?: boolean
} }
export default function PriceDetailsTable({ export default function PriceDetailsTable({
@@ -77,6 +78,7 @@ export default function PriceDetailsTable({
totalPrice, totalPrice,
vat, vat,
defaultCurrency, defaultCurrency,
hotelOffersBreakfast,
}: PriceDetailsTableProps) { }: PriceDetailsTableProps) {
const intl = useIntl() const intl = useIntl()
const lang = useLang() const lang = useLang()
@@ -217,6 +219,7 @@ export default function PriceDetailsTable({
childrenInRoom={room.childrenInRoom} childrenInRoom={room.childrenInRoom}
currency={currency} currency={currency}
nights={nights} nights={nights}
hotelOffersBreakfast={hotelOffersBreakfast}
/> />
{rooms.length !== 1 && {rooms.length !== 1 &&
(room.rateDefinition.isCampaignRate || !!bookingCode) && ( (room.rateDefinition.isCampaignRate || !!bookingCode) && (

View File

@@ -4,20 +4,22 @@ import { useIntl } from "react-intl"
import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting" import { formatPrice } from "@scandic-hotels/common/utils/numberFormatting"
import { Typography } from "@scandic-hotels/design-system/Typography" import { Typography } from "@scandic-hotels/design-system/Typography"
import styles from "./breakfast.module.css" import styles from "./summaryBreakfast.module.css"
import type { PackageSchema } from "@scandic-hotels/trpc/types/bookingConfirmation"
interface BreakfastProps { interface BreakfastProps {
breakfast: PackageSchema | false | undefined breakfastPrice: number | false | undefined
breakfastCurrency?: string | null
breakfastIncluded: boolean breakfastIncluded: boolean
guests: string guests: string
hotelOffersBreakfast: boolean
} }
export default function Breakfast({ export function SummaryBreakfast({
breakfast, breakfastPrice,
breakfastCurrency,
breakfastIncluded, breakfastIncluded,
guests, guests,
hotelOffersBreakfast = true,
}: BreakfastProps) { }: BreakfastProps) {
const intl = useIntl() const intl = useIntl()
@@ -26,13 +28,14 @@ export default function Breakfast({
defaultMessage: "Breakfast buffet", defaultMessage: "Breakfast buffet",
}) })
if (breakfastIncluded || breakfast) { if (breakfastIncluded || (breakfastPrice && breakfastCurrency)) {
const price = breakfast const price =
? formatPrice(intl, breakfast.totalPrice, breakfast.currency) breakfastPrice && breakfastCurrency
: intl.formatMessage({ ? formatPrice(intl, breakfastPrice, breakfastCurrency)
id: "common.included", : intl.formatMessage({
defaultMessage: "Included", id: "common.included",
}) defaultMessage: "Included",
})
return ( return (
<div className={styles.entry}> <div className={styles.entry}>
<div> <div>
@@ -50,20 +53,18 @@ export default function Breakfast({
) )
} }
if (breakfast === false) { if (breakfastPrice === false) {
const noBreakfast = intl.formatMessage({ const noBreakfast = intl.formatMessage({
id: "common.noBreakfast", id: "common.noBreakfast",
defaultMessage: "No breakfast", defaultMessage: "No breakfast",
}) })
return ( return (
<div className={styles.entry}> <Typography variant="Body/Paragraph/mdRegular">
<Typography variant="Body/Paragraph/mdRegular"> <div className={`${styles.entry} ${styles.textDefault}`}>
<p className={styles.textDefault}>{breakfastBuffet}</p> {hotelOffersBreakfast ? <p>{breakfastBuffet}</p> : null}
</Typography> <p>{noBreakfast}</p>
<Typography variant="Body/Paragraph/mdRegular"> </div>
<p className={styles.textDefault}>{noBreakfast}</p> </Typography>
</Typography>
</div>
) )
} }

View File

@@ -1,5 +1,6 @@
.entry { .entry {
display: flex; display: flex;
gap: var(--Space-x05);
justify-content: space-between; justify-content: space-between;
} }

View File

@@ -36,6 +36,7 @@ export const EnterDetailsContext = createContext<EnterDetailsStore | null>(null)
type DetailsProviderProps = React.PropsWithChildren & { type DetailsProviderProps = React.PropsWithChildren & {
booking: DetailsBooking booking: DetailsBooking
breakfastPackages: BreakfastPackages breakfastPackages: BreakfastPackages
hotelOffersBreakfast: boolean
lang: Lang lang: Lang
rooms: Room[] rooms: Room[]
searchParamsStr: string searchParamsStr: string
@@ -49,6 +50,7 @@ export default function EnterDetailsProvider({
booking, booking,
breakfastPackages, breakfastPackages,
children, children,
hotelOffersBreakfast,
lang, lang,
rooms, rooms,
searchParamsStr, searchParamsStr,
@@ -67,6 +69,7 @@ export default function EnterDetailsProvider({
if (!storeRef.current) { if (!storeRef.current) {
const initialData: InitialState = { const initialData: InitialState = {
booking, booking,
hotelOffersBreakfast,
rooms: rooms rooms: rooms
.filter((r) => r.bedTypes?.length) // TODO: how to handle room without bedtypes? .filter((r) => r.bedTypes?.length) // TODO: how to handle room without bedtypes?
.map((room) => ({ .map((room) => ({

View File

@@ -4,6 +4,7 @@ import { Suspense } from "react"
import { FamilyAndFriendsCodes } from "@scandic-hotels/common/constants/familyAndFriends" import { FamilyAndFriendsCodes } from "@scandic-hotels/common/constants/familyAndFriends"
import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking" import { SEARCH_TYPE_REDEMPTION } from "@scandic-hotels/trpc/constants/booking"
import { HotelTypeEnum } from "@scandic-hotels/trpc/enums/hotelType"
import { BookingFlowConfig } from "../bookingFlowConfig/bookingFlowConfig" import { BookingFlowConfig } from "../bookingFlowConfig/bookingFlowConfig"
import HotelHeader from "../components/EnterDetails/Header" import HotelHeader from "../components/EnterDetails/Header"
@@ -137,6 +138,7 @@ export async function EnterDetailsPage({
rooms={rooms} rooms={rooms}
searchParamsStr={selectRoomParams.toString()} searchParamsStr={selectRoomParams.toString()}
user={user} user={user}
hotelOffersBreakfast={hotel.hotelType !== HotelTypeEnum.ScandicGo}
hotelName={hotel.name} hotelName={hotel.name}
vat={hotel.vat} vat={hotel.vat}
roomCategories={hotelData.roomCategories} roomCategories={hotelData.roomCategories}

View File

@@ -17,6 +17,7 @@ export function BookingConfirmationProvider({
children, children,
currencyCode, currencyCode,
fromDate, fromDate,
hotelOffersBreakfast,
toDate, toDate,
roomCategories, roomCategories,
rooms, rooms,
@@ -94,6 +95,7 @@ export function BookingConfirmationProvider({
rooms, rooms,
vat, vat,
isVatCurrency, isVatCurrency,
hotelOffersBreakfast,
formattedTotalCost, formattedTotalCost,
totalBookingPrice, totalBookingPrice,
totalBookingCheques, totalBookingCheques,

View File

@@ -18,6 +18,7 @@ export function createBookingConfirmationStore(initialState: InitialState) {
roomCategories: initialState.roomCategories, roomCategories: initialState.roomCategories,
vat: initialState.vat, vat: initialState.vat,
formattedTotalCost: initialState.formattedTotalCost, formattedTotalCost: initialState.formattedTotalCost,
hotelOffersBreakfast: initialState.hotelOffersBreakfast,
isVatCurrency: initialState.isVatCurrency, isVatCurrency: initialState.isVatCurrency,
totalBookingPrice: initialState.totalBookingPrice, totalBookingPrice: initialState.totalBookingPrice,
totalBookingCheques: initialState.totalBookingCheques, totalBookingCheques: initialState.totalBookingCheques,

View File

@@ -107,6 +107,7 @@ export function createDetailsStore(
canProceedToPayment: false, canProceedToPayment: false,
isSubmitting: false, isSubmitting: false,
isSummaryOpen: false, isSummaryOpen: false,
hotelOffersBreakfast: initialState.hotelOffersBreakfast,
lastRoom: initialState.booking.rooms.length - 1, lastRoom: initialState.booking.rooms.length - 1,
rooms: initialRooms.map((room, idx) => { rooms: initialRooms.map((room, idx) => {
const steps: RoomState["steps"] = { const steps: RoomState["steps"] = {

View File

@@ -85,6 +85,7 @@ export interface RoomState {
export type InitialState = { export type InitialState = {
booking: DetailsBooking booking: DetailsBooking
hotelOffersBreakfast: boolean
rooms: InitialRoomData[] rooms: InitialRoomData[]
vat: number vat: number
hotelName: string hotelName: string
@@ -106,6 +107,7 @@ export interface DetailsState {
booking: DetailsBooking booking: DetailsBooking
breakfastPackages: BreakfastPackages breakfastPackages: BreakfastPackages
canProceedToPayment: boolean canProceedToPayment: boolean
hotelOffersBreakfast: boolean
isSubmitting: boolean isSubmitting: boolean
isSummaryOpen: boolean isSummaryOpen: boolean
lastRoom: number lastRoom: number

View File

@@ -8,6 +8,7 @@ export interface BookingConfirmationProviderProps
bookingCode: string | null bookingCode: string | null
currencyCode: CurrencyEnum currencyCode: CurrencyEnum
fromDate: string fromDate: string
hotelOffersBreakfast: boolean
roomCategories: RoomCategories roomCategories: RoomCategories
rooms: (Room | null)[] rooms: (Room | null)[]
toDate: string toDate: string

View File

@@ -50,6 +50,7 @@ export interface InitialState {
roomCategories: RoomCategories roomCategories: RoomCategories
vat: number vat: number
isVatCurrency: boolean isVatCurrency: boolean
hotelOffersBreakfast: boolean
formattedTotalCost: string formattedTotalCost: string
totalBookingPrice: number totalBookingPrice: number
totalBookingCheques: number totalBookingCheques: number