diff --git a/components/HotelReservation/SelectRate/RoomSelection/FlexibilityOption/index.tsx b/components/HotelReservation/SelectRate/RoomSelection/FlexibilityOption/index.tsx index e44c3312e..01e4890a5 100644 --- a/components/HotelReservation/SelectRate/RoomSelection/FlexibilityOption/index.tsx +++ b/components/HotelReservation/SelectRate/RoomSelection/FlexibilityOption/index.tsx @@ -18,9 +18,7 @@ export default function FlexibilityOption({ name, paymentTerm, priceInformation, - roomType, roomTypeCode, - features, petRoomPackage, handleSelectRate, }: FlexibilityOptionProps) { @@ -45,10 +43,22 @@ export default function FlexibilityOption({ const { public: publicPrice, member: memberPrice } = product.productType - function onChange() { - handleSelectRate({ - publicRateCode: publicPrice.rateCode, - roomTypeCode: roomTypeCode, + const onClick: React.MouseEventHandler = (e) => { + handleSelectRate((prev) => { + if ( + prev && + prev.publicRateCode === publicPrice.rateCode && + prev.roomTypeCode === roomTypeCode + ) { + if (e.currentTarget?.checked) e.currentTarget.checked = false + return undefined + } else + return { + publicRateCode: publicPrice.rateCode, + roomTypeCode: roomTypeCode, + name: name, + paymentTerm: paymentTerm, + } }) } @@ -58,7 +68,7 @@ export default function FlexibilityOption({ type="radio" name="rateCode" value={publicPrice?.rateCode} - onChange={onChange} + onClick={onClick} />
diff --git a/components/HotelReservation/SelectRate/RoomSelection/RateSummary/index.tsx b/components/HotelReservation/SelectRate/RoomSelection/RateSummary/index.tsx index 222acef51..4322872dc 100644 --- a/components/HotelReservation/SelectRate/RoomSelection/RateSummary/index.tsx +++ b/components/HotelReservation/SelectRate/RoomSelection/RateSummary/index.tsx @@ -34,6 +34,7 @@ export default function RateSummary({ features, roomType, priceName, + priceTerm, } = rateSummary const priceToShow = isUserLoggedIn && member ? member : publicRate @@ -80,87 +81,93 @@ export default function RateSummary({
)} -
- {roomType} - {priceName} -
-
- {showMemberDiscountBanner && ( -
- - {intl.formatMessage( - { - id: "To get the member price {amount} {currency}, log in or join when completing the booking.", - }, - { - span: (str) => ( - - {str} - - ), - amount: member.localPrice.pricePerStay, - currency: member.localPrice.currency, - } - )} - -
- )} -
- - {intl.formatMessage( - { id: "Total price (incl VAT)" }, - { b: (str) => {str} } - )} - - {summaryPriceTex} +
+
+ {roomType} + {`${priceName}, ${priceTerm}`}
-
-
- - {priceToShow?.localPrice.pricePerStay}{" "} - {priceToShow?.localPrice.currency} - - - {intl.formatMessage({ id: "Approx." })}{" "} - {priceToShow?.requestedPrice?.pricePerStay}{" "} - {priceToShow?.requestedPrice?.currency} - -
-
- - {intl.formatMessage({ id: "Total price" })} - - - {priceToShow?.localPrice.pricePerStay}{" "} - {priceToShow?.localPrice.currency} - - - {summaryPriceTex} - -
- {isPetRoomSelected && ( -
- - + {petRoomPrice} {petRoomCurrency} - - - {intl.formatMessage({ id: "Pet charge" })} - +
+ {showMemberDiscountBanner && ( +
+ + {intl.formatMessage( + { + id: "To get the member price {amount} {currency}, log in or join when completing the booking.", + }, + { + span: (str) => ( + + {str} + + ), + amount: member.localPrice.pricePerStay, + currency: member.localPrice.currency, + } + )} +
)} - +
+ + {intl.formatMessage( + { id: "Total price (incl VAT)" }, + { b: (str) => {str} } + )} + + {summaryPriceTex} +
+
+
+ + {priceToShow?.localPrice.pricePerStay}{" "} + {priceToShow?.localPrice.currency} + + + {intl.formatMessage({ id: "Approx." })}{" "} + {priceToShow?.requestedPrice?.pricePerStay}{" "} + {priceToShow?.requestedPrice?.currency} + +
+
+ + {intl.formatMessage({ id: "Total price" })} + + + {priceToShow?.localPrice.pricePerStay}{" "} + {priceToShow?.localPrice.currency} + + + {summaryPriceTex} + +
+ {isPetRoomSelected && ( +
+ + + {petRoomPrice} {petRoomCurrency} + + + {intl.formatMessage({ id: "Pet charge" })} + +
+ )} + +
diff --git a/components/HotelReservation/SelectRate/RoomSelection/RateSummary/rateSummary.module.css b/components/HotelReservation/SelectRate/RoomSelection/RateSummary/rateSummary.module.css index 4c49741c5..3271969ae 100644 --- a/components/HotelReservation/SelectRate/RoomSelection/RateSummary/rateSummary.module.css +++ b/components/HotelReservation/SelectRate/RoomSelection/RateSummary/rateSummary.module.css @@ -6,12 +6,19 @@ right: 0; background-color: var(--Base-Surface-Primary-light-Normal); padding: 0 0 var(--Spacing-x5); + align-items: center; + border-top: 1px solid var(--Base-Border-Subtle); + transition: bottom 300ms ease-in-out; +} + +.content { + width: 100%; + max-width: var(--max-width-navigation); + margin: 0 auto; display: flex; flex-direction: column; justify-content: space-between; align-items: center; - border-top: 1px solid var(--Base-Border-Subtle); - transition: bottom 300ms ease-in-out; } .summary[data-visible="true"] { @@ -80,7 +87,9 @@ @media (min-width: 768px) { .summary { - padding: var(--Spacing-x3) var(--Spacing-x2) var(--Spacing-x5); + padding: var(--Spacing-x3) var(--Spacing-x7) var(--Spacing-x5); + } + .content { flex-direction: row; } .petInfo, @@ -102,5 +111,6 @@ .summaryPriceContainer { width: auto; padding: 0; + align-items: center; } } diff --git a/components/HotelReservation/SelectRate/Rooms/index.tsx b/components/HotelReservation/SelectRate/Rooms/index.tsx index 857256e28..ee1758b47 100644 --- a/components/HotelReservation/SelectRate/Rooms/index.tsx +++ b/components/HotelReservation/SelectRate/Rooms/index.tsx @@ -26,7 +26,13 @@ export default function Rooms({ const visibleRooms: RoomConfiguration[] = filterDuplicateRoomTypesByLowestPrice(roomsAvailability.roomConfigurations) const [selectedRate, setSelectedRate] = useState< - { publicRateCode: string; roomTypeCode: string } | undefined + | { + publicRateCode: string + roomTypeCode: string + name: string + paymentTerm: string + } + | undefined >(undefined) const [selectedPackages, setSelectedPackages] = useState( [] @@ -115,17 +121,30 @@ export default function Rooms({ ) )?.features + const roomType = roomCategories.find((roomCategory) => + roomCategory.roomTypes.some( + (roomType) => roomType.code === room.roomTypeCode + ) + ) + const rateSummary: Rate = { features: petRoomPackage && features ? features : [], - priceName: room.roomType, + priceName: selectedRate?.name, + priceTerm: selectedRate?.paymentTerm, public: product.productType.public, member: product.productType.member, - roomType: room.roomType, + roomType: roomType?.name || room.roomType, roomTypeCode: room.roomTypeCode, } return rateSummary - }, [filteredRooms, availablePackages, selectedPackages, selectedRate]) + }, [ + filteredRooms, + availablePackages, + selectedPackages, + selectedRate, + roomCategories, + ]) useEffect(() => { if (rateSummary) return diff --git a/types/components/hotelReservation/selectRate/flexibilityOption.ts b/types/components/hotelReservation/selectRate/flexibilityOption.ts index 5baef06a4..b7e5a0232 100644 --- a/types/components/hotelReservation/selectRate/flexibilityOption.ts +++ b/types/components/hotelReservation/selectRate/flexibilityOption.ts @@ -8,7 +8,6 @@ import { } from "@/server/routers/hotels/output" import { RoomPackage } from "./roomFilter" -import { Rate } from "./selectRate" type ProductPrice = z.output export type RoomPriceSchema = z.output @@ -23,10 +22,17 @@ export type FlexibilityOptionProps = { roomTypeCode: RoomConfiguration["roomTypeCode"] features: RoomConfiguration["features"] petRoomPackage: RoomPackage | undefined - handleSelectRate: (rateCode: { - publicRateCode: string - roomTypeCode: string - }) => void + handleSelectRate: React.Dispatch< + React.SetStateAction< + | { + publicRateCode: string + roomTypeCode: string + name: string + paymentTerm: string + } + | undefined + > + > } export interface PriceListProps { diff --git a/types/components/hotelReservation/selectRate/roomCard.ts b/types/components/hotelReservation/selectRate/roomCard.ts index cc7836a62..27cdf67ec 100644 --- a/types/components/hotelReservation/selectRate/roomCard.ts +++ b/types/components/hotelReservation/selectRate/roomCard.ts @@ -19,10 +19,17 @@ export type RoomCardProps = { roomCategories: RoomData[] selectedPackages: RoomPackageCodes[] packages: RoomPackageData | undefined - handleSelectRate: (rateCode: { - publicRateCode: string - roomTypeCode: string - }) => void + handleSelectRate: React.Dispatch< + React.SetStateAction< + | { + publicRateCode: string + roomTypeCode: string + name: string + paymentTerm: string + } + | undefined + > + > } type RoomPackagePriceSchema = z.output diff --git a/types/components/hotelReservation/selectRate/roomSelection.ts b/types/components/hotelReservation/selectRate/roomSelection.ts index abc07cf6a..c91fe6725 100644 --- a/types/components/hotelReservation/selectRate/roomSelection.ts +++ b/types/components/hotelReservation/selectRate/roomSelection.ts @@ -10,10 +10,17 @@ export interface RoomSelectionProps { user: SafeUser availablePackages: RoomPackageData | undefined selectedPackages: RoomPackageCodes[] - setRateCode: (rateCode: { - publicRateCode: string - roomTypeCode: string - }) => void + setRateCode: React.Dispatch< + React.SetStateAction< + | { + publicRateCode: string + roomTypeCode: string + name: string + paymentTerm: string + } + | undefined + > + > rateSummary: Rate | null } diff --git a/types/components/hotelReservation/selectRate/selectRate.ts b/types/components/hotelReservation/selectRate/selectRate.ts index 12eb83eb1..7a1fb89bb 100644 --- a/types/components/hotelReservation/selectRate/selectRate.ts +++ b/types/components/hotelReservation/selectRate/selectRate.ts @@ -27,7 +27,8 @@ export interface SelectRateSearchParams { export interface Rate { roomType: RoomConfiguration["roomType"] roomTypeCode: RoomConfiguration["roomTypeCode"] - priceName: string + priceName?: string + priceTerm?: string public: Product["productType"]["public"] member?: Product["productType"]["member"] features: RoomConfiguration["features"]