Merged in fix/SW-2553-sidepeeks (pull request #1919)

Fix/SW-2553 sidepeeks

* fix(SW-2553): apply sidepeek display logic

* chore: move convertToChildType and getPriceType utils

* fix: apply PR requested changes

* fix(SW-2553): fix roomNumber for multiroom

* fix(SW-2553): fix sidepeek for my-stay page


Approved-by: Michael Zetterberg
Approved-by: Bianca Widstam
Approved-by: Matilda Landström
This commit is contained in:
Arvid Norlin
2025-05-02 15:10:34 +00:00
committed by Bianca Widstam
parent f5f9aba2e5
commit 0c7836fa59
33 changed files with 881 additions and 510 deletions

View File

@@ -86,6 +86,7 @@ export function LinkedReservation({
checkOutTime={checkOutTime}
img={data.room.images[0]}
roomName={data.room.name}
roomNumber={roomIndex + 1}
/>
)
}

View File

@@ -0,0 +1,10 @@
.trigger {
align-items: center;
background: none;
border: none;
color: var(--Component-Button-Brand-Secondary-On-fill-Default);
cursor: pointer;
display: flex;
gap: var(--Space-x1);
padding: var(--Space-x025) 0;
}

View File

@@ -0,0 +1,118 @@
"use client"
import { Button as ButtonRAC, DialogTrigger } from "react-aria-components"
import { useIntl } from "react-intl"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { BookingStatusEnum } from "@/constants/booking"
import { trpc } from "@/lib/trpc/client"
import { getBookedHotelRoom } from "@/server/routers/booking/utils"
import { useBookingConfirmationStore } from "@/stores/booking-confirmation"
import { convertToChildType } from "@/components/HotelReservation/utils/convertToChildType"
import { getPriceType } from "@/components/HotelReservation/utils/getPriceType"
import BookedRoomSidePeek from "@/components/SidePeeks/BookedRoomSidePeek"
import styles from "./RoomDetailsSidePeek.module.css"
import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast"
import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter"
import { BreakfastPackageEnum } from "@/types/enums/breakfast"
import { PackageTypeEnum } from "@/types/enums/packages"
import type { BookingConfirmationSchema } from "@/types/trpc/routers/booking/confirmation"
interface RoomDetailsSidePeekProps {
booking: BookingConfirmationSchema
roomNumber?: number
}
export default function RoomDetailsSidePeek({
booking,
roomNumber = 1,
}: RoomDetailsSidePeekProps) {
const intl = useIntl()
const user = trpc.user.getSafely.useQuery()
const roomCategories = useBookingConfirmationStore(
(state) => state.roomCategories
)
const hotelRoom = getBookedHotelRoom(roomCategories, booking.roomTypeCode)
const breakfastPackage = booking.packages.find(
(pkg) => pkg.code === BreakfastPackageEnum.REGULAR_BREAKFAST
)
const breakfast: Omit<BreakfastPackage, "requestedPrice"> | null =
breakfastPackage
? {
code: breakfastPackage.code,
description: breakfastPackage.description,
localPrice: {
currency: breakfastPackage.currency,
price: breakfastPackage.unitPrice,
totalPrice: breakfastPackage.totalPrice,
},
packageType: PackageTypeEnum.BreakfastAdult,
}
: null
const childrenInRoom = convertToChildType(
booking.childrenAges,
booking.childBedPreferences
)
const priceType = getPriceType(
booking.cheques,
booking.roomPoints,
booking.vouchers
)
const featuresPackages = booking.packages.filter(
(pkg) =>
pkg.code === RoomPackageCodeEnum.PET_ROOM ||
pkg.code === RoomPackageCodeEnum.ALLERGY_ROOM ||
pkg.code === RoomPackageCodeEnum.ACCESSIBILITY_ROOM
)
const packages = featuresPackages.map((pkg) => ({
code: pkg.code as RoomPackageCodeEnum,
description: pkg.description,
inventories: [],
itemCode: "",
localPrice: {
currency: pkg.currency,
price: pkg.unitPrice,
totalPrice: pkg.totalPrice,
},
requestedPrice: {
currency: pkg.currency,
price: pkg.unitPrice,
totalPrice: pkg.totalPrice,
},
}))
const room = {
...booking,
bedType: {
description: hotelRoom?.bedType.mainBed.description ?? "",
roomTypeCode: hotelRoom?.bedType.code ?? "",
},
breakfast,
childrenInRoom,
isCancelled: booking.reservationStatus === BookingStatusEnum.Cancelled,
packages,
priceType,
roomName: hotelRoom?.name ?? "",
roomNumber,
terms: booking.rateDefinition.cancellationText,
}
return (
<DialogTrigger>
<Typography variant="Body/Supporting text (caption)/smBold">
<ButtonRAC className={styles.trigger}>
<span>
{intl.formatMessage({ defaultMessage: "View room details" })}
</span>
<MaterialIcon color="CurrentColor" icon="chevron_right" size={20} />
</ButtonRAC>
</Typography>
<BookedRoomSidePeek
hotelRoom={hotelRoom}
room={room}
user={user.data ?? null}
/>
</DialogTrigger>
)
}

View File

@@ -9,12 +9,13 @@ import { CancellationRuleEnum } from "@/constants/booking"
import { dt } from "@/lib/dt"
import Image from "@/components/Image"
import Link from "@/components/TempDesignSystem/Link"
import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import useLang from "@/hooks/useLang"
import RoomDetailsSidePeek from "./RoomDetailsSidePeek"
import styles from "./room.module.css"
import type { RoomProps } from "@/types/components/hotelReservation/bookingConfirmation/rooms/room"
@@ -25,6 +26,7 @@ export default function Room({
checkOutTime,
img,
roomName,
roomNumber = 1,
}: RoomProps) {
const intl = useIntl()
const lang = useLang()
@@ -113,16 +115,7 @@ export default function Room({
<Subtitle color="uiTextHighContrast" type="two">
{roomName}
</Subtitle>
<Link color="burgundy" href="" variant="icon">
{intl.formatMessage({
defaultMessage: "View room details",
})}
<MaterialIcon
icon="chevron_right"
size={20}
color="CurrentColor"
/>
</Link>
<RoomDetailsSidePeek booking={booking} roomNumber={roomNumber} />
</div>
<ul className={styles.details}>
<li className={styles.listItem}>

View File

@@ -30,7 +30,7 @@ export default async function BookingConfirmation({
if (!bookingConfirmation) {
return notFound()
}
const { booking, hotel, room } = bookingConfirmation
const { booking, hotel, room, roomCategories } = bookingConfirmation
if (!room) {
return notFound()
}
@@ -46,6 +46,7 @@ export default async function BookingConfirmation({
currencyCode={booking.currencyCode}
fromDate={booking.checkInDate}
toDate={booking.checkOutDate}
roomCategories={roomCategories}
rooms={[
mapRoomState(booking, room, intl),
// null represents "known but not yet fetched rooms" and is used to render placeholders correctly