From 0c7836fa59a843b964698600c40fe7a5db56fd75 Mon Sep 17 00:00:00 2001 From: Arvid Norlin Date: Fri, 2 May 2025 15:10:34 +0000 Subject: [PATCH] Merged in fix/SW-2553-sidepeeks (pull request #1919) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../Rooms/LinkedReservation/index.tsx | 1 + .../Rooms/Room/RoomDetailsSidePeek.module.css | 10 + .../Rooms/Room/RoomDetailsSidePeek.tsx | 118 +++++++ .../BookingConfirmation/Rooms/Room/index.tsx | 15 +- .../BookingConfirmation/index.tsx | 3 +- .../MyStay/GuestDetails/Details.tsx | 315 ----------------- .../MyStay/GuestDetails/index.tsx | 316 +++++++++++++++++- .../MyStay/Rooms/MultiRoom/ToggleSidePeek.tsx | 43 --- .../MyStay/Rooms/MultiRoom/index.tsx | 36 +- .../Rooms/MultiRoom/multiRoom.module.css | 7 + .../Rooms/MultiRoom/toggleSidePeek.module.css | 6 - .../MyStay/Rooms/SingleRoom/index.tsx | 62 +++- .../MyStay/Rooms/SingleRoom/room.module.css | 11 + .../HotelReservation/MyStay/Rooms/index.tsx | 23 +- .../MyStay/utils/mapRoomDetails.ts | 5 +- .../RoomListItem/Details/ToggleSidePeek.tsx | 18 +- .../RoomsList/RoomListItem/Details/index.tsx | 9 +- .../HotelReservation/SidePeek/index.tsx | 33 +- .../{MyStay => }/utils/convertToChildType.ts | 0 .../{MyStay => }/utils/getPriceType.ts | 0 .../SidePeeks/BookedRoomSidePeek/index.tsx | 152 ++++++--- .../SidePeekSelfControlled/SidePeekSEO.tsx | 15 + .../SidePeekSelfControlled/index.tsx | 68 ++++ .../SidePeekSelfControlled/sidePeek.ts | 3 + .../sidePeekSelfControlled.module.css | 102 ++++++ .../SidePeekSelfControlled/types.ts | 10 + .../providers/BookingConfirmationProvider.tsx | 2 + .../stores/booking-confirmation/index.ts | 1 + apps/scandic-web/stores/my-stay/index.ts | 1 + .../bookingConfirmation/rooms/room.ts | 1 + .../types/providers/booking-confirmation.ts | 2 + .../types/stores/booking-confirmation.ts | 2 + apps/scandic-web/types/stores/my-stay.ts | 1 + 33 files changed, 881 insertions(+), 510 deletions(-) create mode 100644 apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/Room/RoomDetailsSidePeek.module.css create mode 100644 apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/Room/RoomDetailsSidePeek.tsx delete mode 100644 apps/scandic-web/components/HotelReservation/MyStay/GuestDetails/Details.tsx delete mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/ToggleSidePeek.tsx delete mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/toggleSidePeek.module.css rename apps/scandic-web/components/HotelReservation/{MyStay => }/utils/convertToChildType.ts (100%) rename apps/scandic-web/components/HotelReservation/{MyStay => }/utils/getPriceType.ts (100%) create mode 100644 apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/SidePeekSEO.tsx create mode 100644 apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/index.tsx create mode 100644 apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/sidePeek.ts create mode 100644 apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/sidePeekSelfControlled.module.css create mode 100644 apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/types.ts diff --git a/apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/LinkedReservation/index.tsx b/apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/LinkedReservation/index.tsx index 1b76ff457..3338fd1b4 100644 --- a/apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/LinkedReservation/index.tsx +++ b/apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/LinkedReservation/index.tsx @@ -86,6 +86,7 @@ export function LinkedReservation({ checkOutTime={checkOutTime} img={data.room.images[0]} roomName={data.room.name} + roomNumber={roomIndex + 1} /> ) } diff --git a/apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/Room/RoomDetailsSidePeek.module.css b/apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/Room/RoomDetailsSidePeek.module.css new file mode 100644 index 000000000..c02928dc1 --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/Room/RoomDetailsSidePeek.module.css @@ -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; +} diff --git a/apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/Room/RoomDetailsSidePeek.tsx b/apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/Room/RoomDetailsSidePeek.tsx new file mode 100644 index 000000000..35de1787a --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/Room/RoomDetailsSidePeek.tsx @@ -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 | 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 ( + + + + + {intl.formatMessage({ defaultMessage: "View room details" })} + + + + + + + ) +} diff --git a/apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/Room/index.tsx b/apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/Room/index.tsx index 33d20db5e..c5839a707 100644 --- a/apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/Room/index.tsx +++ b/apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/Room/index.tsx @@ -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({ {roomName} - - {intl.formatMessage({ - defaultMessage: "View room details", - })} - - +
  • diff --git a/apps/scandic-web/components/HotelReservation/BookingConfirmation/index.tsx b/apps/scandic-web/components/HotelReservation/BookingConfirmation/index.tsx index 91f39fb4f..8a8b32614 100644 --- a/apps/scandic-web/components/HotelReservation/BookingConfirmation/index.tsx +++ b/apps/scandic-web/components/HotelReservation/BookingConfirmation/index.tsx @@ -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 diff --git a/apps/scandic-web/components/HotelReservation/MyStay/GuestDetails/Details.tsx b/apps/scandic-web/components/HotelReservation/MyStay/GuestDetails/Details.tsx deleted file mode 100644 index 51da312d3..000000000 --- a/apps/scandic-web/components/HotelReservation/MyStay/GuestDetails/Details.tsx +++ /dev/null @@ -1,315 +0,0 @@ -"use client" -import { zodResolver } from "@hookform/resolvers/zod" -import { useRouter } from "next/navigation" -import { useState } from "react" -import { Dialog } from "react-aria-components" -import { FormProvider, useForm } from "react-hook-form" -import { useIntl } from "react-intl" - -import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" -import { Typography } from "@scandic-hotels/design-system/Typography" - -import { trpc } from "@/lib/trpc/client" - -import MembershipLevelIcon from "@/components/Levels/Icon" -import Modal from "@/components/Modal" -import { ModalContentWithActions } from "@/components/Modal/ModalContentWithActions" -import Button from "@/components/TempDesignSystem/Button" -import { toast } from "@/components/TempDesignSystem/Toasts" -import useLang from "@/hooks/useLang" - -import ModifyContact from "../ModifyContact" - -import styles from "./guestDetails.module.css" - -import { - type ModifyContactSchema, - modifyContactSchema, -} from "@/types/components/hotelReservation/myStay/modifyContact" -import { MODAL_STEPS } from "@/types/components/hotelReservation/myStay/myStay" -import type { Room } from "@/types/stores/my-stay" -import type { SafeUser } from "@/types/user" - -interface DetailsProps { - booking: Room - user: SafeUser -} - -export default function Details({ booking, user }: DetailsProps) { - const intl = useIntl() - const lang = useLang() - const router = useRouter() - const utils = trpc.useUtils() - const [currentStep, setCurrentStep] = useState(MODAL_STEPS.INITIAL) - const [isLoading, setIsLoading] = useState(false) - - const [isModifyGuestDetailsOpen, setIsModifyGuestDetailsOpen] = - useState(false) - - const form = useForm({ - resolver: zodResolver(modifyContactSchema), - defaultValues: { - firstName: booking.guest.firstName, - lastName: booking.guest.lastName, - email: booking.guest.email, - phoneNumber: booking.guest.phoneNumber, - countryCode: booking.guest.countryCode, - }, - }) - - const isFirstStep = currentStep === MODAL_STEPS.INITIAL - - const isMemberBooking = - booking.guest.membershipNumber === user?.membership?.membershipNumber - - const updateGuest = trpc.booking.update.useMutation({ - onMutate: () => setIsLoading(true), - onSuccess: (data) => { - if (data) { - utils.booking.get.invalidate({ - confirmationNumber: data.confirmationNumber, - }) - - toast.success( - intl.formatMessage({ - defaultMessage: "Guest details updated", - }) - ) - setIsModifyGuestDetailsOpen(false) - setCurrentStep(MODAL_STEPS.INITIAL) - } else { - toast.error( - intl.formatMessage({ - defaultMessage: "Failed to update guest details", - }) - ) - } - }, - onError: () => { - toast.error( - intl.formatMessage({ - defaultMessage: "Failed to update guest details", - }) - ) - }, - onSettled: () => { - setIsLoading(false) - }, - }) - - async function onSubmit(data: ModifyContactSchema) { - updateGuest.mutate({ - confirmationNumber: booking.confirmationNumber, - guest: { - email: data.email, - phoneNumber: data.phoneNumber, - countryCode: data.countryCode, - }, - }) - } - - function handleModifyMemberDetails() { - const expirationTime = Date.now() + 10 * 60 * 1000 - sessionStorage.setItem( - "myStayReturnRoute", - JSON.stringify({ - path: window.location.href, - expiry: expirationTime, - }) - ) - router.push(`/${lang}/scandic-friends/my-pages/profile/edit`) - } - - return ( -
    - {isMemberBooking && user.membership && ( -
    -
    - -

    - {intl.formatMessage({ - defaultMessage: "Your member tier", - })} -

    -
    -
    -
    - -
    -
    -
    - - - -

    - {intl.formatMessage({ - defaultMessage: "My total points", - })} -

    -
    -
    - - -

    {user.membership.currentPoints}

    -
    -
    -
    - )} -
    - -

    - {booking.guest.firstName} {booking.guest.lastName} -

    -
    - {isMemberBooking && user.membership && ( - -

    - {intl.formatMessage( - { - defaultMessage: "Member no. {nr}", - }, - { - nr: user.membership.membershipNumber, - } - )} -

    -
    - )} -
    - -

    {booking.guest.email}

    -
    - -

    {booking.guest.phoneNumber}

    -
    -
    -
    - -

    {booking.guest.email}

    -
    - -

    {booking.guest.phoneNumber}

    -
    -
    -
    - {isMemberBooking ? ( - - ) : ( - <> - - {isModifyGuestDetailsOpen && ( - - - {({ close }) => ( - - setIsModifyGuestDetailsOpen(false)} - content={ - booking.guest && ( - - ) - } - primaryAction={{ - label: isFirstStep - ? intl.formatMessage({ - defaultMessage: "Save updates", - }) - : intl.formatMessage({ - defaultMessage: "Confirm", - }), - onClick: isFirstStep - ? () => setCurrentStep(MODAL_STEPS.CONFIRMATION) - : () => form.handleSubmit(onSubmit)(), - disabled: !form.formState.isValid || isLoading, - intent: isFirstStep ? "secondary" : "primary", - }} - secondaryAction={{ - label: isFirstStep - ? intl.formatMessage({ - defaultMessage: "Back", - }) - : intl.formatMessage({ - defaultMessage: "Cancel", - }), - onClick: () => { - close() - setCurrentStep(MODAL_STEPS.INITIAL) - }, - }} - /> - - )} - - - )} - - )} -
    - ) -} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/GuestDetails/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/GuestDetails/index.tsx index 7f786c59f..741abcac1 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/GuestDetails/index.tsx +++ b/apps/scandic-web/components/HotelReservation/MyStay/GuestDetails/index.tsx @@ -1,22 +1,322 @@ "use client" -import { useMyStayStore } from "@/stores/my-stay" +import { zodResolver } from "@hookform/resolvers/zod" +import { useRouter } from "next/navigation" +import { useState } from "react" +import { Dialog } from "react-aria-components" +import { FormProvider, useForm } from "react-hook-form" +import { useIntl } from "react-intl" -import Details from "./Details" +import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" +import { Typography } from "@scandic-hotels/design-system/Typography" -import type { Room } from "@/types/stores/my-stay" +import { trpc } from "@/lib/trpc/client" + +import MembershipLevelIcon from "@/components/Levels/Icon" +import Modal from "@/components/Modal" +import { ModalContentWithActions } from "@/components/Modal/ModalContentWithActions" +import Button from "@/components/TempDesignSystem/Button" +import { toast } from "@/components/TempDesignSystem/Toasts" +import useLang from "@/hooks/useLang" + +import ModifyContact from "../ModifyContact" + +import styles from "./guestDetails.module.css" + +import { + type ModifyContactSchema, + modifyContactSchema, +} from "@/types/components/hotelReservation/myStay/modifyContact" +import { MODAL_STEPS } from "@/types/components/hotelReservation/myStay/myStay" import type { SafeUser } from "@/types/user" +import type { Guest } from "@/server/routers/booking/output" interface GuestDetailsProps { - selectedRoom?: Room + confirmationNumber: string + guest: Guest + isCancelled: boolean user: SafeUser } export default function GuestDetails({ - selectedRoom, + confirmationNumber, + guest, + isCancelled, user, }: GuestDetailsProps) { - const booking = useMyStayStore((state) => state.bookedRoom) - const room = selectedRoom ? selectedRoom : booking + const intl = useIntl() + const lang = useLang() + const router = useRouter() + const utils = trpc.useUtils() + const [currentStep, setCurrentStep] = useState(MODAL_STEPS.INITIAL) + const [isLoading, setIsLoading] = useState(false) - return
    + const [isModifyGuestDetailsOpen, setIsModifyGuestDetailsOpen] = + useState(false) + + const form = useForm({ + resolver: zodResolver(modifyContactSchema), + defaultValues: { + firstName: guest.firstName, + lastName: guest.lastName, + email: guest.email, + phoneNumber: guest.phoneNumber, + countryCode: guest.countryCode, + }, + }) + + const isFirstStep = currentStep === MODAL_STEPS.INITIAL + + const isMemberBooking = + guest.membershipNumber === user?.membership?.membershipNumber + + const updateGuest = trpc.booking.update.useMutation({ + onMutate: () => setIsLoading(true), + onSuccess: (data) => { + if (data) { + utils.booking.get.invalidate({ + confirmationNumber: data.confirmationNumber, + }) + + toast.success( + intl.formatMessage({ + defaultMessage: "Guest details updated", + }) + ) + setIsModifyGuestDetailsOpen(false) + setCurrentStep(MODAL_STEPS.INITIAL) + } else { + toast.error( + intl.formatMessage({ + defaultMessage: "Failed to update guest details", + }) + ) + } + }, + onError: () => { + toast.error( + intl.formatMessage({ + defaultMessage: "Failed to update guest details", + }) + ) + }, + onSettled: () => { + setIsLoading(false) + }, + }) + + async function onSubmit(data: ModifyContactSchema) { + updateGuest.mutate({ + confirmationNumber, + guest: { + email: data.email, + phoneNumber: data.phoneNumber, + countryCode: data.countryCode, + }, + }) + } + + function handleModifyMemberDetails() { + const expirationTime = Date.now() + 10 * 60 * 1000 + sessionStorage.setItem( + "myStayReturnRoute", + JSON.stringify({ + path: window.location.href, + expiry: expirationTime, + }) + ) + router.push(`/${lang}/scandic-friends/my-pages/profile/edit`) + } + + return ( +
    + {isMemberBooking && user.membership && ( +
    +
    + +

    + {intl.formatMessage({ + defaultMessage: "Your member tier", + })} +

    +
    +
    +
    + +
    +
    +
    + + + +

    + {intl.formatMessage({ + defaultMessage: "My total points", + })} +

    +
    +
    + + +

    {user.membership.currentPoints}

    +
    +
    +
    + )} +
    + +

    + {guest.firstName} {guest.lastName} +

    +
    + {isMemberBooking && user.membership && ( + +

    + {intl.formatMessage( + { + defaultMessage: "Member no. {nr}", + }, + { + nr: user.membership.membershipNumber, + } + )} +

    +
    + )} +
    + +

    {guest.email}

    +
    + +

    {guest.phoneNumber}

    +
    +
    +
    + +

    {guest.email}

    +
    + +

    {guest.phoneNumber}

    +
    +
    +
    + {isMemberBooking ? ( + + ) : ( + <> + + {isModifyGuestDetailsOpen && ( + + + {({ close }) => ( + + setIsModifyGuestDetailsOpen(false)} + content={ + guest && ( + + ) + } + primaryAction={{ + label: isFirstStep + ? intl.formatMessage({ + defaultMessage: "Save updates", + }) + : intl.formatMessage({ + defaultMessage: "Confirm", + }), + onClick: isFirstStep + ? () => setCurrentStep(MODAL_STEPS.CONFIRMATION) + : form.handleSubmit(onSubmit), + disabled: !form.formState.isValid || isLoading, + intent: isFirstStep ? "secondary" : "primary", + }} + secondaryAction={{ + label: isFirstStep + ? intl.formatMessage({ + defaultMessage: "Back", + }) + : intl.formatMessage({ + defaultMessage: "Cancel", + }), + onClick: () => { + close() + setCurrentStep(MODAL_STEPS.INITIAL) + }, + }} + /> + + )} + + + )} + + )} +
    + ) } diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/ToggleSidePeek.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/ToggleSidePeek.tsx deleted file mode 100644 index ea4591696..000000000 --- a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/ToggleSidePeek.tsx +++ /dev/null @@ -1,43 +0,0 @@ -"use client" - -import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" - -import useSidePeekStore from "@/stores/sidepeek" - -import Button from "@/components/TempDesignSystem/Button" - -import styles from "./toggleSidePeek.module.css" - -import { SidePeekEnum } from "@/types/components/hotelReservation/sidePeek" -import type { ToggleSidePeekProps } from "@/types/components/hotelReservation/toggleSidePeekProps" - -export default function ToggleSidePeek({ - hotelId, - roomTypeCode, - user, - confirmationNumber, -}: ToggleSidePeekProps) { - const openSidePeek = useSidePeekStore((state) => state.openSidePeek) - - return ( - - ) -} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/index.tsx index 75cabc5f3..051763713 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/index.tsx +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/index.tsx @@ -1,13 +1,16 @@ "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 { dt } from "@/lib/dt" +import { getBookedHotelRoom } from "@/server/routers/booking/utils" import { IconForFeatureCode } from "@/components/HotelReservation/utils" import Image from "@/components/Image" +import BookedRoomSidePeek from "@/components/SidePeeks/BookedRoomSidePeek" import Divider from "@/components/TempDesignSystem/Divider" import IconChip from "@/components/TempDesignSystem/IconChip" import useLang from "@/hooks/useLang" @@ -15,11 +18,11 @@ import { formatPrice } from "@/utils/numberFormatting" import PriceType from "../../PriceType" import { hasModifiableRate } from "../../utils" -import ToggleSidePeek from "./ToggleSidePeek" import styles from "./multiRoom.module.css" import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter" +import type { RoomCategories } from "@/types/hotel" import type { Room } from "@/types/stores/my-stay" import type { SafeUser } from "@/types/user" @@ -27,9 +30,15 @@ interface MultiRoomProps { booking: Room roomNr: number user: SafeUser + roomCategories: RoomCategories } -export default function MultiRoom({ booking, roomNr, user }: MultiRoomProps) { +export default function MultiRoom({ + booking, + roomNr, + user, + roomCategories, +}: MultiRoomProps) { const intl = useIntl() const lang = useLang() @@ -42,7 +51,6 @@ export default function MultiRoom({ booking, roomNr, user }: MultiRoomProps) { childrenAges, confirmationNumber, currencyCode, - hotelId, packages, rateDefinition, room, @@ -94,6 +102,7 @@ export default function MultiRoom({ booking, roomNr, user }: MultiRoomProps) { breakfast.localPrice.currency ) } + const hotelRoom = getBookedHotelRoom(roomCategories, roomTypeCode) return (
    @@ -167,12 +176,21 @@ export default function MultiRoom({ booking, roomNr, user }: MultiRoomProps) {
    - + + + + + +
    ({ adults: state.bookedRoom.adults, bookingCode: state.bookedRoom.bookingCode, breakfast: state.bookedRoom.breakfast, + guest: state.bookedRoom.guest, checkInDate: state.bookedRoom.checkInDate, cheques: state.bookedRoom.cheques, childrenAges: state.bookedRoom.childrenAges, @@ -77,6 +86,7 @@ export default function SingleRoom({ bedType, image, user }: RoomProps) { roomTypeCode: state.bookedRoom.roomTypeCode, totalPrice: state.bookedRoom.totalPrice, vouchers: state.bookedRoom.vouchers, + bookedRoom: state.bookedRoom, })) if (!roomNumber) { @@ -149,6 +159,8 @@ export default function SingleRoom({ bedType, image, user }: RoomProps) { ) } + const hotelRoom = getBookedHotelRoom(roomCategories, roomTypeCode) + return (
    @@ -187,11 +199,27 @@ export default function SingleRoom({ bedType, image, user }: RoomProps) {
    - + + + + + {intl.formatMessage({ + defaultMessage: "View room details", + })} + + + + + +
    @@ -401,7 +429,12 @@ export default function SingleRoom({ bedType, image, user }: RoomProps) {
    - +
    @@ -454,7 +487,12 @@ export default function SingleRoom({ bedType, image, user }: RoomProps) {
    - +
    diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/room.module.css b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/room.module.css index ee54a0f64..b9a96e503 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/room.module.css +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/room.module.css @@ -6,6 +6,17 @@ padding: var(--Spacing-x3) 0; } +.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; +} + .roomName { color: var(--Scandic-Brand-Burgundy); padding: 0 var(--Spacing-x2); diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/index.tsx index e895f3e81..5376ecf01 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/index.tsx +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/index.tsx @@ -20,12 +20,15 @@ interface RoomsProps { export default function Rooms({ user }: RoomsProps) { const intl = useIntl() - const { allRoomsAreCancelled, room, rooms } = useMyStayStore((state) => ({ - allRoomsAreCancelled: state.allRoomsAreCancelled, - hotel: state.hotel, - room: state.bookedRoom.room, - rooms: state.rooms, - })) + const { allRoomsAreCancelled, room, rooms, roomCategories } = useMyStayStore( + (state) => ({ + allRoomsAreCancelled: state.allRoomsAreCancelled, + hotel: state.hotel, + room: state.bookedRoom.room, + rooms: state.rooms, + roomCategories: state.roomCategories, + }) + ) if (!room) { return null @@ -50,6 +53,7 @@ export default function Rooms({ user }: RoomsProps) { bedType={room.bedType} image={room.images[0]} user={user} + roomCategories={roomCategories} /> ) : (
    @@ -58,7 +62,12 @@ export default function Rooms({ user }: RoomsProps) { key={booking.confirmationNumber} className={styles.roomWrapper} > - +
    ))} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/utils/mapRoomDetails.ts b/apps/scandic-web/components/HotelReservation/MyStay/utils/mapRoomDetails.ts index 185075a63..a4a168062 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/utils/mapRoomDetails.ts +++ b/apps/scandic-web/components/HotelReservation/MyStay/utils/mapRoomDetails.ts @@ -1,9 +1,10 @@ import { BookingStatusEnum, CancellationRuleEnum } from "@/constants/booking" import { dt } from "@/lib/dt" +import { convertToChildType } from "@/components/HotelReservation/utils/convertToChildType" +import { getPriceType } from "@/components/HotelReservation/utils/getPriceType" + import { formatChildBedPreferences } from "../utils" -import { convertToChildType } from "./convertToChildType" -import { getPriceType } from "./getPriceType" import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast" import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter" diff --git a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Details/ToggleSidePeek.tsx b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Details/ToggleSidePeek.tsx index dab08d819..608fcb3f1 100644 --- a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Details/ToggleSidePeek.tsx +++ b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Details/ToggleSidePeek.tsx @@ -13,8 +13,6 @@ import type { ToggleSidePeekProps } from "@/types/components/hotelReservation/to export default function ToggleSidePeek({ hotelId, roomTypeCode, - intent = "textInverted", - title, }: ToggleSidePeekProps) { const intl = useIntl() const openSidePeek = useSidePeekStore((state) => state.openSidePeek) @@ -22,19 +20,19 @@ export default function ToggleSidePeek({ return ( ) diff --git a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Details/index.tsx b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Details/index.tsx index 96c8fd4c3..8aa62180b 100644 --- a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Details/index.tsx +++ b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Details/index.tsx @@ -51,14 +51,7 @@ export default function Details({ roomTypeCode }: { roomTypeCode: string }) {
    {roomTypeCode && ( - + )}
    diff --git a/apps/scandic-web/components/HotelReservation/SidePeek/index.tsx b/apps/scandic-web/components/HotelReservation/SidePeek/index.tsx index 177abf728..de9166049 100644 --- a/apps/scandic-web/components/HotelReservation/SidePeek/index.tsx +++ b/apps/scandic-web/components/HotelReservation/SidePeek/index.tsx @@ -4,27 +4,19 @@ import { trpc } from "@/lib/trpc/client" import useSidePeekStore from "@/stores/sidepeek" import AmenitiesSidePeek from "@/components/SidePeeks/AmenitiesSidePeek" -import BookedRoomSidePeek from "@/components/SidePeeks/BookedRoomSidePeek" import HotelSidePeek from "@/components/SidePeeks/HotelSidePeek" import RoomSidePeek from "@/components/SidePeeks/RoomSidePeek" import useLang from "@/hooks/useLang" export default function HotelReservationSidePeek() { - const { - activeSidePeek, - confirmationNumber, - hotelId, - roomTypeCode, - showCTA, - user, - } = useSidePeekStore((state) => ({ - activeSidePeek: state.activeSidePeek, - confirmationNumber: state.confirmationNumber, - hotelId: state.hotelId, - roomTypeCode: state.roomTypeCode, - showCTA: state.showCTA, - user: state.user, - })) + const { activeSidePeek, hotelId, roomTypeCode, showCTA } = useSidePeekStore( + (state) => ({ + activeSidePeek: state.activeSidePeek, + hotelId: state.hotelId, + roomTypeCode: state.roomTypeCode, + showCTA: state.showCTA, + }) + ) const close = useSidePeekStore((state) => state.closeSidePeek) const lang = useLang() @@ -72,15 +64,6 @@ export default function HotelReservationSidePeek() { close={close} /> )} - {selectedRoom && ( - - )} ) } diff --git a/apps/scandic-web/components/HotelReservation/MyStay/utils/convertToChildType.ts b/apps/scandic-web/components/HotelReservation/utils/convertToChildType.ts similarity index 100% rename from apps/scandic-web/components/HotelReservation/MyStay/utils/convertToChildType.ts rename to apps/scandic-web/components/HotelReservation/utils/convertToChildType.ts diff --git a/apps/scandic-web/components/HotelReservation/MyStay/utils/getPriceType.ts b/apps/scandic-web/components/HotelReservation/utils/getPriceType.ts similarity index 100% rename from apps/scandic-web/components/HotelReservation/MyStay/utils/getPriceType.ts rename to apps/scandic-web/components/HotelReservation/utils/getPriceType.ts diff --git a/apps/scandic-web/components/SidePeeks/BookedRoomSidePeek/index.tsx b/apps/scandic-web/components/SidePeeks/BookedRoomSidePeek/index.tsx index 7718708ca..b6a07c169 100644 --- a/apps/scandic-web/components/SidePeeks/BookedRoomSidePeek/index.tsx +++ b/apps/scandic-web/components/SidePeeks/BookedRoomSidePeek/index.tsx @@ -5,7 +5,6 @@ import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { Typography } from "@scandic-hotels/design-system/Typography" import { dt } from "@/lib/dt" -import { useMyStayStore } from "@/stores/my-stay" import GuestDetails from "@/components/HotelReservation/MyStay/GuestDetails" import PriceType from "@/components/HotelReservation/MyStay/PriceType" @@ -14,7 +13,7 @@ import ImageGallery from "@/components/ImageGallery" import Accordion from "@/components/TempDesignSystem/Accordion" import AccordionItem from "@/components/TempDesignSystem/Accordion/AccordionItem" import IconChip from "@/components/TempDesignSystem/IconChip" -import SidePeek from "@/components/TempDesignSystem/SidePeek" +import SidePeekSelfControlled from "@/components/TempDesignSystem/SidePeekSelfControlled" import useLang from "@/hooks/useLang" import { mapApiImagesToGalleryImages } from "@/utils/imageGallery" import { formatPrice } from "@/utils/numberFormatting" @@ -23,28 +22,60 @@ import RoomDetails from "./RoomDetails" import styles from "./bookedRoomSidePeek.module.css" +import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast" +import type { BedTypeSchema } from "@/types/components/hotelReservation/enterDetails/bedType" +import type { PriceTypeEnum } from "@/types/components/hotelReservation/myStay/myStay" import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter" -import { SidePeekEnum } from "@/types/components/hotelReservation/sidePeek" -import type { BookedRoomSidePeekProps } from "@/types/components/sidePeeks/bookedRoomSidePeek" +import type { Child } from "@/types/components/hotelReservation/selectRate/selectRate" +import type { Room as HotelRoom } from "@/types/hotel" +import type { Packages } from "@/types/requests/packages" +import type { BookingConfirmationSchema } from "@/types/trpc/routers/booking/confirmation" +import type { SafeUser } from "@/types/user" + +export type PartialHotelRoom = Pick< + HotelRoom, + "descriptions" | "images" | "name" | "roomFacilities" | "roomTypes" +> + +export type Room = Pick< + BookingConfirmationSchema, + | "adults" + | "bookingCode" + | "cancellationNumber" + | "checkInDate" + | "cheques" + | "confirmationNumber" + | "currencyCode" + | "guest" + | "rateDefinition" + | "roomPoints" + | "totalPrice" + | "vouchers" +> & { + bedType: BedTypeSchema + breakfast: Omit | null + childrenInRoom: Child[] + isCancelled: boolean + packages: Packages | null + priceType: PriceTypeEnum + roomName: string + roomNumber: number + terms: string | null +} + +interface RoomDetailsSidePeekProps { + hotelRoom: PartialHotelRoom | null + room: Room + user: SafeUser +} export default function BookedRoomSidePeek({ + hotelRoom, room, - activeSidePeek, user, - confirmationNumber, - close, -}: BookedRoomSidePeekProps) { +}: RoomDetailsSidePeekProps) { const intl = useIntl() const lang = useLang() - const rooms = useMyStayStore((state) => state.rooms) - - const bookingRoom = rooms.find( - (r) => r.confirmationNumber === confirmationNumber - ) - - if (!bookingRoom) { - return null - } const { adults, @@ -53,20 +84,28 @@ export default function BookedRoomSidePeek({ breakfast, cancellationNumber, checkInDate, + cheques, childrenInRoom, + confirmationNumber, currencyCode, + guest, isCancelled, + roomName, packages, + priceType, rateDefinition, roomNumber, + roomPoints, terms, totalPrice, - } = bookingRoom + vouchers, + } = room const fromDate = dt(checkInDate).locale(lang) - const roomDescription = room.descriptions.medium - const galleryImages = mapApiImagesToGalleryImages(room.images) + const galleryImages = hotelRoom + ? mapApiImagesToGalleryImages(hotelRoom.images) + : null const adultsMsg = intl.formatMessage( { @@ -106,12 +145,10 @@ export default function BookedRoomSidePeek({ ) } + const hotelRoomName = hotelRoom?.name || roomName + return ( - +
    {isCancelled ? ( @@ -180,11 +217,13 @@ export default function BookedRoomSidePeek({
    - + {galleryImages ? ( + + ) : null}
    @@ -334,14 +373,14 @@ export default function BookedRoomSidePeek({
    @@ -369,23 +408,30 @@ export default function BookedRoomSidePeek({ )} - +
    - - - - - + {hotelRoom ? ( + + + + + + ) : null}
    -
    + ) } diff --git a/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/SidePeekSEO.tsx b/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/SidePeekSEO.tsx new file mode 100644 index 000000000..1fd88c067 --- /dev/null +++ b/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/SidePeekSEO.tsx @@ -0,0 +1,15 @@ +import type { SidePeekSelfControlledProps } from "./sidePeek" +// Sidepeeks generally have important content that should be indexed by search engines. +// The content is hidden behind a modal, but it is still important for SEO. +// This component is used to provide SEO information for the sidepeek content. +export default function SidePeekSEO({ + title, + children, +}: React.PropsWithChildren>) { + return ( +
    +

    {title}

    + {children} +
    + ) +} diff --git a/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/index.tsx b/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/index.tsx new file mode 100644 index 000000000..3521fabe9 --- /dev/null +++ b/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/index.tsx @@ -0,0 +1,68 @@ +"use client" +import { useEffect } from "react" +import { Dialog, Modal, ModalOverlay } 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 useSetOverflowVisibleOnRA from "@/hooks/useSetOverflowVisibleOnRA" + +import Button from "../Button" +import SidePeekSEO from "./SidePeekSEO" + +import styles from "./sidePeekSelfControlled.module.css" + +import type { SidePeekSelfControlledProps } from "./sidePeek" + +export default function SidePeekSelfControlled({ + children, + title, +}: React.PropsWithChildren) { + const intl = useIntl() + return ( + <> + + + + {({ close }) => ( + + )} + + + + {children} + + ) +} +function KeepBodyVisible() { + const toggle = useSetOverflowVisibleOnRA() + useEffect(() => { + toggle(true) + return () => toggle(false) + }, [toggle]) + return null +} diff --git a/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/sidePeek.ts b/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/sidePeek.ts new file mode 100644 index 000000000..068a2df83 --- /dev/null +++ b/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/sidePeek.ts @@ -0,0 +1,3 @@ +export interface SidePeekSelfControlledProps { + title: string +} diff --git a/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/sidePeekSelfControlled.module.css b/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/sidePeekSelfControlled.module.css new file mode 100644 index 000000000..e40066fc9 --- /dev/null +++ b/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/sidePeekSelfControlled.module.css @@ -0,0 +1,102 @@ +.modal { + --sidepeek-desktop-width: 560px; +} + +@keyframes slide-in { + from { + right: calc(-1 * var(--sidepeek-desktop-width)); + } + + to { + right: 0; + } +} + +@keyframes slide-up { + from { + top: 100vh; + } + + to { + top: 0; + } +} + +.overlay { + position: fixed; + inset: 0; + z-index: var(--sidepeek-z-index); + background-color: var(--UI-Opacity-Almost-Black-30); +} + +.modal { + position: fixed; + top: 0; + right: auto; + bottom: 0; + width: 100%; + height: 100vh; + background-color: var(--Base-Background-Primary-Normal); + z-index: var(--sidepeek-z-index); +} + +.modal[data-entering] { + animation: slide-up 300ms; +} + +.modal[data-exiting] { + animation: slide-up 300ms reverse; +} + +.dialog { + height: 100%; + outline: none; +} + +.sidePeek { + display: grid; + grid-template-rows: min-content auto; + height: 100%; +} + +.header { + display: flex; + justify-content: flex-end; + border-bottom: 1px solid var(--Base-Border-Subtle); + align-items: center; + padding: var(--Spacing-x4); +} + +.header:has(> h2) { + justify-content: space-between; +} + +.closeButton { + padding: 0; +} + +.heading { + color: var(--Text-Heading); +} + +.sidePeekContent { + padding: var(--Spacing-x4); + overflow-y: auto; +} + +@media screen and (min-width: 1367px) { + .modal { + top: 0; + right: 0px; + width: var(--sidepeek-desktop-width); + height: 100vh; + } + + .modal[data-entering] { + animation: slide-in 250ms; + } + + .modal[data-exiting] { + animation: slide-in 250ms reverse; + } +} diff --git a/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/types.ts b/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/types.ts new file mode 100644 index 000000000..b724b305f --- /dev/null +++ b/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/types.ts @@ -0,0 +1,10 @@ +export type SidePeekProps = { + activeContent: string | null + onClose: (isOpen: boolean) => void +} +export type SidePeekContentProps = { + title?: string + contentKey: string + isActive?: boolean + onClose?: () => void +} diff --git a/apps/scandic-web/providers/BookingConfirmationProvider.tsx b/apps/scandic-web/providers/BookingConfirmationProvider.tsx index 00d6ff368..0494ac1c1 100644 --- a/apps/scandic-web/providers/BookingConfirmationProvider.tsx +++ b/apps/scandic-web/providers/BookingConfirmationProvider.tsx @@ -18,6 +18,7 @@ export default function BookingConfirmationProvider({ currencyCode, fromDate, toDate, + roomCategories, rooms, vat, }: BookingConfirmationProviderProps) { @@ -73,6 +74,7 @@ export default function BookingConfirmationProvider({ fromDate, toDate, rooms, + roomCategories, vat, isVatCurrency, formattedTotalCost, diff --git a/apps/scandic-web/stores/booking-confirmation/index.ts b/apps/scandic-web/stores/booking-confirmation/index.ts index 99c2aa39f..ec954f648 100644 --- a/apps/scandic-web/stores/booking-confirmation/index.ts +++ b/apps/scandic-web/stores/booking-confirmation/index.ts @@ -15,6 +15,7 @@ export function createBookingConfirmationStore(initialState: InitialState) { currencyCode: initialState.currencyCode, fromDate: initialState.fromDate, toDate: initialState.toDate, + roomCategories: initialState.roomCategories, vat: initialState.vat, formattedTotalCost: initialState.formattedTotalCost, isVatCurrency: initialState.isVatCurrency, diff --git a/apps/scandic-web/stores/my-stay/index.ts b/apps/scandic-web/stores/my-stay/index.ts index fd6544ebc..e2af9e0fd 100644 --- a/apps/scandic-web/stores/my-stay/index.ts +++ b/apps/scandic-web/stores/my-stay/index.ts @@ -74,6 +74,7 @@ export function createMyStayStore({ savedCreditCards, totalPoints, totalPrice, + roomCategories, actions: { closeManageStay() { diff --git a/apps/scandic-web/types/components/hotelReservation/bookingConfirmation/rooms/room.ts b/apps/scandic-web/types/components/hotelReservation/bookingConfirmation/rooms/room.ts index bc2ce6b9a..3f5ba8c03 100644 --- a/apps/scandic-web/types/components/hotelReservation/bookingConfirmation/rooms/room.ts +++ b/apps/scandic-web/types/components/hotelReservation/bookingConfirmation/rooms/room.ts @@ -6,4 +6,5 @@ export interface RoomProps { checkOutTime: string img: NonNullable["images"][number] roomName: NonNullable["name"] + roomNumber?: number } diff --git a/apps/scandic-web/types/providers/booking-confirmation.ts b/apps/scandic-web/types/providers/booking-confirmation.ts index 5a75f52d7..0cf4df972 100644 --- a/apps/scandic-web/types/providers/booking-confirmation.ts +++ b/apps/scandic-web/types/providers/booking-confirmation.ts @@ -1,4 +1,5 @@ import type { CurrencyEnum } from "../enums/currency" +import type { RoomCategories } from "../hotel" import type { Room } from "../stores/booking-confirmation" export interface BookingConfirmationProviderProps @@ -7,6 +8,7 @@ export interface BookingConfirmationProviderProps currencyCode: CurrencyEnum fromDate: Date rooms: (Room | null)[] + roomCategories: RoomCategories toDate: Date vat: number } diff --git a/apps/scandic-web/types/stores/booking-confirmation.ts b/apps/scandic-web/types/stores/booking-confirmation.ts index 314882049..28cbfa7c7 100644 --- a/apps/scandic-web/types/stores/booking-confirmation.ts +++ b/apps/scandic-web/types/stores/booking-confirmation.ts @@ -1,5 +1,6 @@ import type { ChildBedTypeEnum } from "@/constants/booking" import type { CurrencyEnum } from "../enums/currency" +import type { RoomCategories } from "../hotel" import type { BookingConfirmation, PackageSchema, @@ -43,6 +44,7 @@ export interface InitialState { rooms: (Room | null)[] toDate: Date currencyCode: CurrencyEnum + roomCategories: RoomCategories vat: number isVatCurrency: boolean formattedTotalCost: string diff --git a/apps/scandic-web/types/stores/my-stay.ts b/apps/scandic-web/types/stores/my-stay.ts index a9492ec2b..c9898806c 100644 --- a/apps/scandic-web/types/stores/my-stay.ts +++ b/apps/scandic-web/types/stores/my-stay.ts @@ -76,6 +76,7 @@ export interface MyStayState { savedCreditCards: CreditCard[] | null totalPoints: number totalPrice: string + roomCategories: RoomCategories } export interface InitialState