feat: add multiroom signup

This commit is contained in:
Simon Emanuelsson
2025-02-17 15:10:48 +01:00
parent 95917e5e4f
commit 92c5566c59
78 changed files with 2035 additions and 1545 deletions

View File

@@ -8,7 +8,7 @@ import SummaryUI from "./UI"
import type { SummaryProps } from "@/types/components/hotelReservation/summary"
export default function DesktopSummary(props: SummaryProps) {
export default function DesktopSummary({ isMember }: SummaryProps) {
const {
booking,
actions: { toggleSummaryOpen },
@@ -23,8 +23,7 @@ export default function DesktopSummary(props: SummaryProps) {
<SummaryUI
booking={booking}
rooms={rooms}
isMember={props.isMember}
breakfastIncluded={props.breakfastIncluded}
isMember={isMember}
totalPrice={totalPrice}
vat={vat}
toggleSummaryOpen={toggleSummaryOpen}

View File

@@ -11,7 +11,7 @@ import styles from "./mobile.module.css"
import type { SummaryProps } from "@/types/components/hotelReservation/summary"
export default function MobileSummary(props: SummaryProps) {
export default function MobileSummary({ isMember }: SummaryProps) {
const {
booking,
actions: { toggleSummaryOpen },
@@ -22,10 +22,10 @@ export default function MobileSummary(props: SummaryProps) {
const rooms = useEnterDetailsStore((state) => state.rooms)
const showPromo =
!props.isMember &&
!isMember &&
rooms.length === 1 &&
!rooms[0].guest.join &&
!rooms[0].guest.membershipNo
!rooms[0].room.guest.join &&
!rooms[0].room.guest.membershipNo
return (
<div className={styles.mobileSummary}>
@@ -35,8 +35,7 @@ export default function MobileSummary(props: SummaryProps) {
<SummaryUI
booking={booking}
rooms={rooms}
isMember={props.isMember}
breakfastIncluded={props.breakfastIncluded}
isMember={isMember}
totalPrice={totalPrice}
vat={vat}
toggleSummaryOpen={toggleSummaryOpen}

View File

@@ -1,6 +1,6 @@
"use client"
import React from "react"
import { Fragment } from "react"
import { useIntl } from "react-intl"
import { dt } from "@/lib/dt"
@@ -32,7 +32,6 @@ export default function SummaryUI({
rooms,
totalPrice,
isMember,
breakfastIncluded,
vat,
toggleSummaryOpen,
}: EnterDetailsSummaryProps) {
@@ -66,9 +65,11 @@ export default function SummaryUI({
rooms.length === 1 &&
rooms
.slice(0, 1)
.some((r) => !isMember || !r.guest.join || !r.guest.membershipNo)
.some(
(r) => !isMember || !r.room.guest.join || !r.room.guest.membershipNo
)
const memberPrice = getMemberPrice(rooms[0].roomRate)
const memberPrice = getMemberPrice(rooms[0].room.roomRate)
return (
<section className={styles.summary}>
@@ -91,7 +92,7 @@ export default function SummaryUI({
</Button>
</header>
<Divider color="primaryLightSubtle" />
{rooms.map((room, idx) => {
{rooms.map(({ room }, idx) => {
const roomNumber = idx + 1
const adults = room.adults
const childrenInRoom = room.childrenInRoom
@@ -139,7 +140,7 @@ export default function SummaryUI({
}
return (
<React.Fragment key={idx}>
<Fragment key={idx}>
<div
className={styles.addOns}
data-testid={`summary-room-${roomNumber}`}
@@ -272,7 +273,7 @@ export default function SummaryUI({
</Body>
</div>
) : null}
{breakfastIncluded ? (
{room.breakfastIncluded ? (
<div className={styles.entry}>
<Body color="uiTextHighContrast">
{intl.formatMessage({ id: "Breakfast included" })}
@@ -309,7 +310,9 @@ export default function SummaryUI({
<Body color="uiTextHighContrast">
{formatPrice(
intl,
parseInt(room.breakfast.localPrice.totalPrice),
parseInt(room.breakfast.localPrice.price) *
adults *
diff,
room.breakfast.localPrice.currency
)}
</Body>
@@ -337,7 +340,7 @@ export default function SummaryUI({
) : null}
</div>
<Divider color="primaryLightSubtle" />
</React.Fragment>
</Fragment>
)
})}
<div className={styles.total}>
@@ -353,13 +356,13 @@ export default function SummaryUI({
fromDate={booking.fromDate}
toDate={booking.toDate}
rooms={rooms.map((r) => ({
adults: r.adults,
childrenInRoom: r.childrenInRoom,
roomPrice: r.roomPrice,
roomType: r.roomType,
bedType: r.bedType,
breakfast: r.breakfast,
roomFeatures: r.roomFeatures,
adults: r.room.adults,
bedType: r.room.bedType,
breakfast: r.room.breakfast,
childrenInRoom: r.room.childrenInRoom,
roomFeatures: r.room.roomFeatures,
roomPrice: r.room.roomPrice,
roomType: r.room.roomType,
}))}
totalPrice={totalPrice}
vat={vat}

View File

@@ -20,6 +20,7 @@ import SummaryUI from "./UI"
import type { PropsWithChildren } from "react"
import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums"
import { StepEnum } from "@/types/enums/step"
import type { RoomState } from "@/types/stores/enter-details"
jest.mock("@/lib/api", () => ({
@@ -42,36 +43,78 @@ function createWrapper(intlConfig: IntlConfig) {
const rooms: RoomState[] = [
{
adults: 2,
childrenInRoom: [{ bed: ChildBedMapEnum.IN_EXTRA_BED, age: 5 }],
bedType: {
description: bedType.queen.description,
roomTypeCode: bedType.queen.value,
currentStep: StepEnum.selectBed,
isComplete: false,
room: {
adults: 2,
bedType: {
description: bedType.queen.description,
roomTypeCode: bedType.queen.value,
},
bedTypes: [],
breakfast: breakfastPackage,
breakfastIncluded: false,
cancellationText: "Non-refundable",
childrenInRoom: [{ bed: ChildBedMapEnum.IN_EXTRA_BED, age: 5 }],
guest: guestDetailsNonMember,
rateDetails: [],
roomFeatures: [],
roomPrice: roomPrice,
roomRate: roomRate,
roomType: "Standard",
roomTypeCode: "QS",
},
steps: {
[StepEnum.selectBed]: {
step: StepEnum.selectBed,
isValid: false,
},
[StepEnum.breakfast]: {
step: StepEnum.breakfast,
isValid: false,
},
[StepEnum.details]: {
step: StepEnum.details,
isValid: false,
},
},
breakfast: breakfastPackage,
guest: guestDetailsNonMember,
roomRate: roomRate,
roomPrice: roomPrice,
roomType: "Standard",
rateDetails: [],
cancellationText: "Non-refundable",
roomFeatures: [],
},
{
adults: 1,
childrenInRoom: [],
bedType: {
description: bedType.king.description,
roomTypeCode: bedType.king.value,
currentStep: StepEnum.selectBed,
isComplete: false,
room: {
adults: 1,
bedType: {
description: bedType.king.description,
roomTypeCode: bedType.king.value,
},
bedTypes: [],
breakfast: undefined,
breakfastIncluded: false,
cancellationText: "Non-refundable",
childrenInRoom: [],
guest: guestDetailsMember,
rateDetails: [],
roomFeatures: [],
roomPrice: roomPrice,
roomRate: roomRate,
roomType: "Standard",
roomTypeCode: "QS",
},
steps: {
[StepEnum.selectBed]: {
step: StepEnum.selectBed,
isValid: false,
},
[StepEnum.breakfast]: {
step: StepEnum.breakfast,
isValid: false,
},
[StepEnum.details]: {
step: StepEnum.details,
isValid: false,
},
},
breakfast: undefined,
guest: guestDetailsMember,
roomRate: roomRate,
roomPrice: roomPrice,
roomType: "Standard",
rateDetails: [],
cancellationText: "Non-refundable",
roomFeatures: [],
},
]
@@ -89,7 +132,6 @@ describe("EnterDetails Summary", () => {
booking={booking}
rooms={rooms.slice(0, 1)}
isMember={false}
breakfastIncluded={false}
totalPrice={{
requested: {
currency: "EUR",
@@ -127,7 +169,6 @@ describe("EnterDetails Summary", () => {
booking={booking}
rooms={rooms}
isMember={false}
breakfastIncluded={false}
totalPrice={{
requested: {
currency: "EUR",