From db289b80b19724c377a52d5fc43dc52a2b097c3e Mon Sep 17 00:00:00 2001 From: Simon Emanuelsson Date: Sat, 3 May 2025 19:33:04 +0200 Subject: [PATCH] feat: refactor NewDates, clean up legacy code This reverts commit 0c7836fa59a843b964698600c40fe7a5db56fd75. --- .../hotelreservation/my-stay/page.tsx | 41 +- .../webview/hotelreservation/my-stay/page.tsx | 47 +- .../Rooms/LinkedReservation/index.tsx | 3 +- .../Rooms/Room/RoomDetailsSidePeek.tsx | 11 +- ...idePeek.module.css => sidePeek.module.css} | 0 .../BookingConfirmation/Rooms/index.tsx | 1 + .../MyStay/Ancillaries/index.tsx | 5 +- .../Modal/Button/button.module.css | 1 + .../Modal/Button/index.tsx | 0 .../Modal/ModalContent/Body/body.module.css | 0 .../Modal/ModalContent/Body/index.tsx | 0 .../ModalContent/Footer/footer.module.css | 0 .../Modal/ModalContent/Footer/index.tsx | 0 .../ModalContent/Header/header.module.css | 0 .../Modal/ModalContent/Header/index.tsx | 0 .../Modal/ModalContent/index.tsx | 0 .../ModalContent/modalContent.module.css | 2 + .../{ReferenceCard => }/Modal/index.tsx | 0 .../Modal/modal.module.css | 11 +- .../customerSupport.module.css | 4 + .../Actions/CustomerSupportModal/index.tsx | 4 +- .../Actions/AddToCalendar/button.module.css | 1 + .../ManageStay/Actions/CancelStay/Alerts.tsx | 2 +- .../CancelStay/Steps/Confirmation/index.tsx | 2 +- .../Steps/FinalConfirmation/index.tsx | 2 +- .../Actions/CancelStay/cancelStay.module.css | 4 + .../ManageStay/Actions/CancelStay/index.tsx | 6 +- .../ChangeDates/Alerts/CannotChangeDate.tsx | 2 +- .../ChangeDates/Alerts/MultiRoomBooking.tsx | 2 +- .../ChangeDates/Alerts/NotMainRoom.tsx | 2 +- .../ChangeDates/Steps/Confirmation/index.tsx | 2 +- .../CalendarButton/calendarButton.module.css | 14 - .../Form/NewDates/CalendarButton/index.tsx | 24 - .../ChangeDates/Steps/Form/NewDates/index.tsx | 248 ++++----- .../Steps/Form/NewDates/newDates.module.css | 20 + .../Actions/ChangeDates/Steps/Form/index.tsx | 4 +- .../ManageStay/Actions/ChangeDates/index.tsx | 2 +- .../Actions/CustomerSupport/index.tsx | 2 +- .../GuaranteeLateArrival/Form/form.module.css | 8 +- .../GuaranteeLateArrival/guarantee.module.css | 3 + .../Actions/GuaranteeLateArrival/index.tsx | 6 +- .../ManageStay/Info/info.module.css | 7 +- .../Actions/NotCancelled/ManageStay/index.tsx | 2 +- .../ManageStay/manageStay.module.css | 17 +- .../NotCancelled/notCancelled.module.css | 1 + .../ReferenceCard/PriceContainer/index.tsx | 4 +- .../PriceContainer/priceContainer.module.css | 6 +- .../MyStay/Rooms/MultiRoom/Room.tsx | 292 +++++++++++ .../Rooms/MultiRoom/RoomDetailsSidePeek.tsx | 30 ++ .../MyStay/Rooms/MultiRoom/index.tsx | 327 ++---------- .../Rooms/MultiRoom/multiRoom.module.css | 118 ++--- .../MyStay/Rooms/MultiRoom/room.module.css | 94 ++++ .../Rooms/MultiRoom/sidePeek.module.css | 8 + .../BookingInformation/BookingCode.tsx | 42 ++ .../PriceDetails/details.module.css | 30 ++ .../BookingInformation/PriceDetails/index.tsx | 40 ++ .../SingleRoom/BookingInformation/index.tsx | 13 + .../BookingInformation/information.module.css | 22 + .../SingleRoom/Details/BedPreference.tsx | 49 ++ .../Rooms/SingleRoom/Details/Breakfast.tsx | 35 ++ .../Rooms/SingleRoom/Details/Guests.tsx | 45 ++ .../Rooms/SingleRoom/Details/ModifyBy.tsx | 47 ++ .../Rooms/SingleRoom/Details/Packages.tsx | 36 ++ .../Rooms/SingleRoom/Details/Row/index.tsx | 32 ++ .../SingleRoom/Details/Row/row.module.css | 38 ++ .../MyStay/Rooms/SingleRoom/Details/Terms.tsx | 27 + .../SingleRoom/Details/details.module.css | 10 + .../MyStay/Rooms/SingleRoom/Details/index.tsx | 21 + .../Rooms/SingleRoom/Header/header.module.css | 39 ++ .../MyStay/Rooms/SingleRoom/Header/index.tsx | 59 +++ .../Rooms/SingleRoom/Img/img.module.css | 22 + .../MyStay/Rooms/SingleRoom/Img/index.tsx | 31 ++ .../Rooms/SingleRoom/Packages/index.tsx | 38 ++ .../SingleRoom/Packages/packages.module.css | 22 + .../Rooms/SingleRoom/RoomDetailsSidePeek.tsx | 37 ++ .../Rooms/SingleRoom/ToggleSidePeek.tsx | 46 -- .../MyStay/Rooms/SingleRoom/index.tsx | 496 ++---------------- .../MyStay/Rooms/SingleRoom/room.module.css | 225 +------- .../HotelReservation/MyStay/Rooms/index.tsx | 96 ---- .../MyStay/Rooms/rooms.module.css | 63 --- .../MyStay/utils/mapRoomDetails.ts | 5 +- .../{utils.tsx => utils/index.tsx} | 0 .../SidePeeks/BookedRoomSidePeek/index.tsx | 2 +- .../TempDesignSystem/AncillaryCard/index.tsx | 16 +- .../SidePeekSelfControlled/SidePeekSEO.tsx | 1 + .../SidePeekSelfControlled/index.tsx | 3 + .../sidePeekSelfControlled.module.css | 1 + .../SidePeekSelfControlled/types.ts | 1 + .../providers/BookingConfirmationProvider.tsx | 2 +- .../server/routers/booking/utils.ts | 6 +- apps/scandic-web/stores/my-stay/index.ts | 1 - .../rooms/linkedReservation.ts | 1 + .../components/myPages/myStay/ancillaries.ts | 2 +- .../sidePeeks/bookedRoomSidePeek.ts | 6 +- .../types/providers/booking-confirmation.ts | 2 +- apps/scandic-web/types/stores/my-stay.ts | 1 - 96 files changed, 1603 insertions(+), 1500 deletions(-) rename apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/Room/{RoomDetailsSidePeek.module.css => sidePeek.module.css} (100%) rename apps/scandic-web/components/HotelReservation/MyStay/{ReferenceCard => }/Modal/Button/button.module.css (91%) rename apps/scandic-web/components/HotelReservation/MyStay/{ReferenceCard => }/Modal/Button/index.tsx (100%) rename apps/scandic-web/components/HotelReservation/MyStay/{ReferenceCard => }/Modal/ModalContent/Body/body.module.css (100%) rename apps/scandic-web/components/HotelReservation/MyStay/{ReferenceCard => }/Modal/ModalContent/Body/index.tsx (100%) rename apps/scandic-web/components/HotelReservation/MyStay/{ReferenceCard => }/Modal/ModalContent/Footer/footer.module.css (100%) rename apps/scandic-web/components/HotelReservation/MyStay/{ReferenceCard => }/Modal/ModalContent/Footer/index.tsx (100%) rename apps/scandic-web/components/HotelReservation/MyStay/{ReferenceCard => }/Modal/ModalContent/Header/header.module.css (100%) rename apps/scandic-web/components/HotelReservation/MyStay/{ReferenceCard => }/Modal/ModalContent/Header/index.tsx (100%) rename apps/scandic-web/components/HotelReservation/MyStay/{ReferenceCard => }/Modal/ModalContent/index.tsx (100%) rename apps/scandic-web/components/HotelReservation/MyStay/{ReferenceCard => }/Modal/ModalContent/modalContent.module.css (51%) rename apps/scandic-web/components/HotelReservation/MyStay/{ReferenceCard => }/Modal/index.tsx (100%) rename apps/scandic-web/components/HotelReservation/MyStay/{ReferenceCard => }/Modal/modal.module.css (88%) delete mode 100644 apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Steps/Form/NewDates/CalendarButton/calendarButton.module.css delete mode 100644 apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Steps/Form/NewDates/CalendarButton/index.tsx create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/GuaranteeLateArrival/guarantee.module.css create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/Room.tsx create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/RoomDetailsSidePeek.tsx create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/room.module.css create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/sidePeek.module.css create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/BookingInformation/BookingCode.tsx create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/BookingInformation/PriceDetails/details.module.css create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/BookingInformation/PriceDetails/index.tsx create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/BookingInformation/index.tsx create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/BookingInformation/information.module.css create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/BedPreference.tsx create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/Breakfast.tsx create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/Guests.tsx create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/ModifyBy.tsx create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/Packages.tsx create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/Row/index.tsx create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/Row/row.module.css create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/Terms.tsx create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/details.module.css create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/index.tsx create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Header/header.module.css create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Header/index.tsx create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Img/img.module.css create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Img/index.tsx create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Packages/index.tsx create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Packages/packages.module.css create mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/RoomDetailsSidePeek.tsx delete mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/ToggleSidePeek.tsx delete mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/index.tsx delete mode 100644 apps/scandic-web/components/HotelReservation/MyStay/Rooms/rooms.module.css rename apps/scandic-web/components/HotelReservation/{utils.tsx => utils/index.tsx} (100%) diff --git a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/my-stay/page.tsx b/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/my-stay/page.tsx index 17be92f63..f7c28468f 100644 --- a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/my-stay/page.tsx +++ b/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/my-stay/page.tsx @@ -28,7 +28,8 @@ import BookingSummary from "@/components/HotelReservation/MyStay/BookingSummary" import { Header } from "@/components/HotelReservation/MyStay/Header" import Promo from "@/components/HotelReservation/MyStay/Promo" import { ReferenceCard } from "@/components/HotelReservation/MyStay/ReferenceCard" -import Rooms from "@/components/HotelReservation/MyStay/Rooms" +import MultiRoom from "@/components/HotelReservation/MyStay/Rooms/MultiRoom" +import SingleRoom from "@/components/HotelReservation/MyStay/Rooms/SingleRoom" import SidePeek from "@/components/HotelReservation/SidePeek" import Image from "@/components/Image" import { getIntl } from "@/i18n" @@ -116,6 +117,11 @@ export default async function MyStay({ rooms: booking.linkedReservations, }) + const ancillariesInput = { + fromDate, + hotelId: hotel.operaId, + toDate, + } const packagesInput = { adults: booking.adults, children: booking.childrenAges.length, @@ -141,21 +147,27 @@ export default async function MyStay({ if (shouldFetchBreakfastPackages) { void getPackages(packagesInput) } - void getSavedPaymentCardsSafely(savedPaymentCardsInput) - - const ancillaryPackages = await getAncillaryPackages({ - fromDate, - hotelId: hotel.operaId, - toDate, - }) + if (user) { + void getSavedPaymentCardsSafely(savedPaymentCardsInput) + } + if (booking.showAncillaries) { + void getAncillaryPackages(ancillariesInput) + } let breakfastPackages = null if (shouldFetchBreakfastPackages) { breakfastPackages = await getPackages(packagesInput) } - const savedCreditCards = await getSavedPaymentCardsSafely( - savedPaymentCardsInput - ) + let savedCreditCards = null + if (user) { + savedCreditCards = await getSavedPaymentCardsSafely( + savedPaymentCardsInput + ) + } + let ancillaryPackagesPromise = null + if (booking.showAncillaries) { + ancillaryPackagesPromise = getAncillaryPackages(ancillariesInput) + } const imageSrc = hotel.hotelContent.images.imageSizes.large ?? @@ -196,9 +208,9 @@ export default async function MyStay({
- {booking.showAncillaries && ( + {booking.showAncillaries && ancillaryPackagesPromise && ( )} - + + pkg.code === BreakfastPackageEnum.REGULAR_BREAKFAST ) const breakfastIncluded = booking.rateDefinition.breakfastIncluded - const alreadyHasABreakfastSelection = + const shouldFetchBreakfastPackages = !hasBreakfastPackage && !breakfastIncluded - if (alreadyHasABreakfastSelection) { + if (shouldFetchBreakfastPackages) { void getPackages(packagesInput) } - void getSavedPaymentCardsSafely(savedPaymentCardsInput) - - const ancillaryPackages = await getAncillaryPackages({ - fromDate, - hotelId: hotel.operaId, - toDate, - }) + if (user) { + void getSavedPaymentCardsSafely(savedPaymentCardsInput) + } + if (booking.showAncillaries) { + void getAncillaryPackages(ancillariesInput) + } let breakfastPackages = null - if (alreadyHasABreakfastSelection) { + if (shouldFetchBreakfastPackages) { breakfastPackages = await getPackages(packagesInput) } - const savedCreditCards = await getSavedPaymentCardsSafely( - savedPaymentCardsInput - ) + let savedCreditCards = null + if (user) { + savedCreditCards = await getSavedPaymentCardsSafely( + savedPaymentCardsInput + ) + } + let ancillaryPackagesPromise = null + if (booking.showAncillaries) { + ancillaryPackagesPromise = getAncillaryPackages(ancillariesInput) + } const imageSrc = hotel.hotelContent.images.imageSizes.large ?? @@ -193,9 +205,9 @@ export default async function MyStay({
- {booking.showAncillaries && ( + {booking.showAncillaries && ancillaryPackagesPromise && ( )} - + + ) } diff --git a/apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/Room/RoomDetailsSidePeek.tsx b/apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/Room/RoomDetailsSidePeek.tsx index 35de1787a..32a8c7df4 100644 --- a/apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/Room/RoomDetailsSidePeek.tsx +++ b/apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/Room/RoomDetailsSidePeek.tsx @@ -1,4 +1,5 @@ "use client" + import { Button as ButtonRAC, DialogTrigger } from "react-aria-components" import { useIntl } from "react-intl" @@ -14,7 +15,7 @@ import { convertToChildType } from "@/components/HotelReservation/utils/convertT import { getPriceType } from "@/components/HotelReservation/utils/getPriceType" import BookedRoomSidePeek from "@/components/SidePeeks/BookedRoomSidePeek" -import styles from "./RoomDetailsSidePeek.module.css" +import styles from "./sidePeek.module.css" import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast" import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter" @@ -26,6 +27,7 @@ interface RoomDetailsSidePeekProps { booking: BookingConfirmationSchema roomNumber?: number } + export default function RoomDetailsSidePeek({ booking, roomNumber = 1, @@ -36,9 +38,11 @@ export default function RoomDetailsSidePeek({ (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 ? { @@ -52,21 +56,25 @@ export default function RoomDetailsSidePeek({ 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, @@ -83,6 +91,7 @@ export default function RoomDetailsSidePeek({ totalPrice: pkg.totalPrice, }, })) + const room = { ...booking, bedType: { diff --git a/apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/Room/RoomDetailsSidePeek.module.css b/apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/Room/sidePeek.module.css similarity index 100% rename from apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/Room/RoomDetailsSidePeek.module.css rename to apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/Room/sidePeek.module.css diff --git a/apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/index.tsx b/apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/index.tsx index 32dec7c98..8ae1bb9b1 100644 --- a/apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/index.tsx +++ b/apps/scandic-web/components/HotelReservation/BookingConfirmation/Rooms/index.tsx @@ -59,6 +59,7 @@ export default async function Rooms({ checkOutTime={checkOutTime} confirmationNumber={reservation.confirmationNumber} roomIndex={idx + 1} + roomNumber={idx + 2} /> ))} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/index.tsx index a35fa8514..2ce63ec90 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/index.tsx +++ b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/index.tsx @@ -1,5 +1,5 @@ "use client" -import { useMemo } from "react" +import { use, useMemo } from "react" import { useIntl } from "react-intl" import { Carousel } from "@/components/Carousel" @@ -78,7 +78,7 @@ function addBreakfastPackage( } export function Ancillaries({ - ancillaries, + ancillariesPromise, booking, packages, user, @@ -86,6 +86,7 @@ export function Ancillaries({ refId, }: AncillariesProps) { const intl = useIntl() + const ancillaries = use(ancillariesPromise) /** * A constructed ancillary for breakfast diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/Button/button.module.css b/apps/scandic-web/components/HotelReservation/MyStay/Modal/Button/button.module.css similarity index 91% rename from apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/Button/button.module.css rename to apps/scandic-web/components/HotelReservation/MyStay/Modal/Button/button.module.css index a88172b13..fa1f1e05d 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/Button/button.module.css +++ b/apps/scandic-web/components/HotelReservation/MyStay/Modal/Button/button.module.css @@ -6,6 +6,7 @@ display: flex; gap: var(--Space-x1); padding: var(--Space-x1) 0; + text-align: left; width: 100%; } diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/Button/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Modal/Button/index.tsx similarity index 100% rename from apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/Button/index.tsx rename to apps/scandic-web/components/HotelReservation/MyStay/Modal/Button/index.tsx diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/ModalContent/Body/body.module.css b/apps/scandic-web/components/HotelReservation/MyStay/Modal/ModalContent/Body/body.module.css similarity index 100% rename from apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/ModalContent/Body/body.module.css rename to apps/scandic-web/components/HotelReservation/MyStay/Modal/ModalContent/Body/body.module.css diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/ModalContent/Body/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Modal/ModalContent/Body/index.tsx similarity index 100% rename from apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/ModalContent/Body/index.tsx rename to apps/scandic-web/components/HotelReservation/MyStay/Modal/ModalContent/Body/index.tsx diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/ModalContent/Footer/footer.module.css b/apps/scandic-web/components/HotelReservation/MyStay/Modal/ModalContent/Footer/footer.module.css similarity index 100% rename from apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/ModalContent/Footer/footer.module.css rename to apps/scandic-web/components/HotelReservation/MyStay/Modal/ModalContent/Footer/footer.module.css diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/ModalContent/Footer/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Modal/ModalContent/Footer/index.tsx similarity index 100% rename from apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/ModalContent/Footer/index.tsx rename to apps/scandic-web/components/HotelReservation/MyStay/Modal/ModalContent/Footer/index.tsx diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/ModalContent/Header/header.module.css b/apps/scandic-web/components/HotelReservation/MyStay/Modal/ModalContent/Header/header.module.css similarity index 100% rename from apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/ModalContent/Header/header.module.css rename to apps/scandic-web/components/HotelReservation/MyStay/Modal/ModalContent/Header/header.module.css diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/ModalContent/Header/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Modal/ModalContent/Header/index.tsx similarity index 100% rename from apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/ModalContent/Header/index.tsx rename to apps/scandic-web/components/HotelReservation/MyStay/Modal/ModalContent/Header/index.tsx diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/ModalContent/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Modal/ModalContent/index.tsx similarity index 100% rename from apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/ModalContent/index.tsx rename to apps/scandic-web/components/HotelReservation/MyStay/Modal/ModalContent/index.tsx diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/ModalContent/modalContent.module.css b/apps/scandic-web/components/HotelReservation/MyStay/Modal/ModalContent/modalContent.module.css similarity index 51% rename from apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/ModalContent/modalContent.module.css rename to apps/scandic-web/components/HotelReservation/MyStay/Modal/ModalContent/modalContent.module.css index 37a8f2d91..3fb9cf987 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/ModalContent/modalContent.module.css +++ b/apps/scandic-web/components/HotelReservation/MyStay/Modal/ModalContent/modalContent.module.css @@ -1,4 +1,6 @@ .container { display: grid; gap: var(--Space-x3); + grid-template-rows: auto 1fr auto; + height: 100%; } diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Modal/index.tsx similarity index 100% rename from apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/index.tsx rename to apps/scandic-web/components/HotelReservation/MyStay/Modal/index.tsx diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/modal.module.css b/apps/scandic-web/components/HotelReservation/MyStay/Modal/modal.module.css similarity index 88% rename from apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/modal.module.css rename to apps/scandic-web/components/HotelReservation/MyStay/Modal/modal.module.css index f796f38c9..2faa3b81b 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Modal/modal.module.css +++ b/apps/scandic-web/components/HotelReservation/MyStay/Modal/modal.module.css @@ -56,6 +56,13 @@ } } +@media screen and (max-width: 767px) { + .modal { + bottom: 0; + width: 100%; + } +} + @media screen and (min-width: 768px) { .overlay { align-items: center; @@ -65,6 +72,8 @@ .modal { border-radius: var(--Corner-radius-Large); - width: min(690px, 100dvw); + display: flex; + min-height: 300px; + min-width: 690px; } } diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/CustomerSupportModal/customerSupport.module.css b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/CustomerSupportModal/customerSupport.module.css index c0b9a6d5f..70132740a 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/CustomerSupportModal/customerSupport.module.css +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/CustomerSupportModal/customerSupport.module.css @@ -1,3 +1,7 @@ +.dialog { + max-width: 690px; +} + .links { display: grid; gap: var(--Space-x05); diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/CustomerSupportModal/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/CustomerSupportModal/index.tsx index ba4e86abd..0dcb60627 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/CustomerSupportModal/index.tsx +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/CustomerSupportModal/index.tsx @@ -8,7 +8,7 @@ import { Typography } from "@scandic-hotels/design-system/Typography" import { useMyStayStore } from "@/stores/my-stay" -import Modal from "@/components/HotelReservation/MyStay/ReferenceCard/Modal" +import Modal from "@/components/HotelReservation/MyStay/Modal" import styles from "./customerSupport.module.css" @@ -30,7 +30,7 @@ export default function CustomerSupportModal() { return ( - + {({ close }) => ( diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/AddToCalendar/button.module.css b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/AddToCalendar/button.module.css index e6b2fafcf..3715e6b97 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/AddToCalendar/button.module.css +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/AddToCalendar/button.module.css @@ -15,4 +15,5 @@ .text { color: var(--Text-Interactive-Default); + text-align: left; } diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/CancelStay/Alerts.tsx b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/CancelStay/Alerts.tsx index 8afe7f741..dce1610f7 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/CancelStay/Alerts.tsx +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/CancelStay/Alerts.tsx @@ -3,7 +3,7 @@ import { useIntl } from "react-intl" import { useMyStayStore } from "@/stores/my-stay" -import Modal from "@/components/HotelReservation/MyStay/ReferenceCard/Modal" +import Modal from "@/components/HotelReservation/MyStay/Modal" import Alert from "@/components/TempDesignSystem/Alert" import { AlertTypeEnum } from "@/types/enums/alert" diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/CancelStay/Steps/Confirmation/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/CancelStay/Steps/Confirmation/index.tsx index 2b1894a18..d5ae7a9c3 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/CancelStay/Steps/Confirmation/index.tsx +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/CancelStay/Steps/Confirmation/index.tsx @@ -7,7 +7,7 @@ import { Typography } from "@scandic-hotels/design-system/Typography" import { dt } from "@/lib/dt" import { useMyStayStore } from "@/stores/my-stay" -import Modal from "@/components/HotelReservation/MyStay/ReferenceCard/Modal" +import Modal from "@/components/HotelReservation/MyStay/Modal" import useLang from "@/hooks/useLang" import CancelStayPriceContainer from "../CancelStayPriceContainer" diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/CancelStay/Steps/FinalConfirmation/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/CancelStay/Steps/FinalConfirmation/index.tsx index 8bd45aadf..9b441100c 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/CancelStay/Steps/FinalConfirmation/index.tsx +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/CancelStay/Steps/FinalConfirmation/index.tsx @@ -7,7 +7,7 @@ import { Typography } from "@scandic-hotels/design-system/Typography" import { trpc } from "@/lib/trpc/client" import { useMyStayStore } from "@/stores/my-stay" -import Modal from "@/components/HotelReservation/MyStay/ReferenceCard/Modal" +import Modal from "@/components/HotelReservation/MyStay/Modal" import { toast } from "@/components/TempDesignSystem/Toasts" import useLang from "@/hooks/useLang" diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/CancelStay/cancelStay.module.css b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/CancelStay/cancelStay.module.css index 73d64df70..9b6862580 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/CancelStay/cancelStay.module.css +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/CancelStay/cancelStay.module.css @@ -1,3 +1,7 @@ +.dialog { + max-width: 690px; +} + .modalText { display: flex; flex-direction: column; diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/CancelStay/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/CancelStay/index.tsx index 339a34efe..697944dd9 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/CancelStay/index.tsx +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/CancelStay/index.tsx @@ -2,11 +2,13 @@ import { Dialog, DialogTrigger } from "react-aria-components" import { useIntl } from "react-intl" -import Modal from "@/components/HotelReservation/MyStay/ReferenceCard/Modal" +import Modal from "@/components/HotelReservation/MyStay/Modal" import Alerts from "./Alerts" import Steps from "./Steps" +import styles from "./cancelStay.module.css" + export default function CancelStay() { const intl = useIntl() return ( @@ -15,7 +17,7 @@ export default function CancelStay() { {intl.formatMessage({ defaultMessage: "Cancel stay" })} - + {({ close }) => ( diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Alerts/CannotChangeDate.tsx b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Alerts/CannotChangeDate.tsx index 1482b6014..217cb8202 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Alerts/CannotChangeDate.tsx +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Alerts/CannotChangeDate.tsx @@ -1,7 +1,7 @@ "use client" import { useIntl } from "react-intl" -import Modal from "@/components/HotelReservation/MyStay/ReferenceCard/Modal" +import Modal from "@/components/HotelReservation/MyStay/Modal" import Alert from "@/components/TempDesignSystem/Alert" import { AlertTypeEnum } from "@/types/enums/alert" diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Alerts/MultiRoomBooking.tsx b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Alerts/MultiRoomBooking.tsx index b9aa33069..33dd52785 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Alerts/MultiRoomBooking.tsx +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Alerts/MultiRoomBooking.tsx @@ -1,7 +1,7 @@ "use client" import { useIntl } from "react-intl" -import Modal from "@/components/HotelReservation/MyStay/ReferenceCard/Modal" +import Modal from "@/components/HotelReservation/MyStay/Modal" import Alert from "@/components/TempDesignSystem/Alert" import { AlertTypeEnum } from "@/types/enums/alert" diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Alerts/NotMainRoom.tsx b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Alerts/NotMainRoom.tsx index 153722593..a52521c99 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Alerts/NotMainRoom.tsx +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Alerts/NotMainRoom.tsx @@ -1,7 +1,7 @@ "use client" import { useIntl } from "react-intl" -import Modal from "@/components/HotelReservation/MyStay/ReferenceCard/Modal" +import Modal from "@/components/HotelReservation/MyStay/Modal" import Alert from "@/components/TempDesignSystem/Alert" import { AlertTypeEnum } from "@/types/enums/alert" diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Steps/Confirmation/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Steps/Confirmation/index.tsx index 9c75710fc..b59a02140 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Steps/Confirmation/index.tsx +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Steps/Confirmation/index.tsx @@ -5,7 +5,7 @@ import { dt } from "@/lib/dt" import { trpc } from "@/lib/trpc/client" import { useMyStayStore } from "@/stores/my-stay" -import Modal from "@/components/HotelReservation/MyStay/ReferenceCard/Modal" +import Modal from "@/components/HotelReservation/MyStay/Modal" import PriceContainer from "@/components/HotelReservation/MyStay/ReferenceCard/PriceContainer" import Divider from "@/components/TempDesignSystem/Divider" import { toast } from "@/components/TempDesignSystem/Toasts" diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Steps/Form/NewDates/CalendarButton/calendarButton.module.css b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Steps/Form/NewDates/CalendarButton/calendarButton.module.css deleted file mode 100644 index 6078b24b8..000000000 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Steps/Form/NewDates/CalendarButton/calendarButton.module.css +++ /dev/null @@ -1,14 +0,0 @@ -.button { - background-color: var(--Main-Grey-White); - border-color: var(--Scandic-Beige-40); - border-style: solid; - border-width: 1px; - border-radius: var(--Corner-radius-Medium); - display: flex; - align-items: center; - justify-content: space-between; - min-width: 0; /* allow shrinkage */ - height: 60px; - padding: var(--Spacing-x1) var(--Spacing-x2); - transition: border-color 200ms ease; -} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Steps/Form/NewDates/CalendarButton/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Steps/Form/NewDates/CalendarButton/index.tsx deleted file mode 100644 index 81b19f19c..000000000 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Steps/Form/NewDates/CalendarButton/index.tsx +++ /dev/null @@ -1,24 +0,0 @@ -"use client" - -import { Button as ButtonRAC } from "react-aria-components" - -import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" -import { Typography } from "@scandic-hotels/design-system/Typography" - -import styles from "./calendarButton.module.css" - -interface CalendarButtonProps { - text: string - onClick: () => void -} - -export default function CalendarButton({ text, onClick }: CalendarButtonProps) { - return ( - - - {text} - - - - ) -} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Steps/Form/NewDates/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Steps/Form/NewDates/index.tsx index b0040e5bf..b2152a0d9 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Steps/Form/NewDates/index.tsx +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Steps/Form/NewDates/index.tsx @@ -1,39 +1,33 @@ "use client" -import { useState } from "react" -import { createPortal } from "react-dom" -import { useFormContext } from "react-hook-form" +import { + Button as ButtonRAC, + Dialog, + DialogTrigger, +} from "react-aria-components" +import { useFormContext, useWatch } 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 { dt } from "@/lib/dt" -import { useMyStayStore } from "@/stores/my-stay" import DatePickerSingleDesktop from "@/components/DatePicker/Single/Desktop" import DatePickerSingleMobile from "@/components/DatePicker/Single/Mobile" -import Modal from "@/components/Modal" -import Caption from "@/components/TempDesignSystem/Text/Caption" +import Modal from "@/components/HotelReservation/MyStay/Modal" import useLang from "@/hooks/useLang" -import CalendarButton from "./CalendarButton" - import styles from "./newDates.module.css" -import type { DateRange } from "react-day-picker" - -export default function NewDates() { - const { checkInDate, checkOutDate } = useMyStayStore((state) => ({ - checkInDate: state.mainRoom.checkInDate, - checkOutDate: state.mainRoom.checkOutDate, - })) - - const [showCheckInDatePicker, setShowCheckInDatePicker] = useState(false) - const [showCheckOutDatePicker, setShowCheckOutDatePicker] = useState(false) - const [selectedDates, setSelectedDates] = useState(() => ({ - from: dt(checkInDate).startOf("day").toDate(), - to: dt(checkOutDate).startOf("day").toDate(), - })) +interface NewDatesProps { + checkInDate: Date + checkOutDate: Date +} +export default function NewDates({ checkInDate, checkOutDate }: NewDatesProps) { const intl = useIntl() const lang = useLang() + const { setValue } = useFormContext() // Calculate default number of days between check-in and check-out @@ -41,147 +35,111 @@ export default function NewDates() { .startOf("day") .diff(dt(checkInDate).startOf("day"), "days") - function showCheckInPicker() { - // Update selected dates before showing picker - setSelectedDates((prev) => ({ - from: prev.from ?? dt(checkInDate).startOf("day").toDate(), - to: prev.to ?? dt(checkOutDate).startOf("day").toDate(), - })) - setShowCheckInDatePicker(true) - setShowCheckOutDatePicker(false) + const fromDate = useWatch({ name: "checkInDate" }) + const toDate = useWatch({ name: "checkOutDate" }) + + function handleSelectDate(date: Date, name: "checkInDate" | "checkOutDate") { + setValue(name, dt(date).format("YYYY-MM-DD")) } - function showCheckOutPicker() { - // Update selected dates before showing picker - setSelectedDates((prev) => ({ - from: prev.from ?? dt(checkInDate).startOf("day").toDate(), - to: prev.to ?? dt(checkOutDate).startOf("day").toDate(), - })) - setShowCheckOutDatePicker(true) - setShowCheckInDatePicker(false) - } - - function handleCheckInDateSelect(date: Date) { - const newCheckIn = dt(date).startOf("day") - const currentCheckOut = dt(selectedDates.to).startOf("day") - - // Calculate new check-out date based on defaultDaysBetween, only if new check-in is after current check-out - const newCheckOut = newCheckIn.isSameOrAfter(currentCheckOut) - ? newCheckIn.add(defaultDaysBetween, "days") - : currentCheckOut - - // Update selected dates state first - const newDates = { - from: newCheckIn.toDate(), - to: newCheckOut.toDate(), + function handleSelectCheckInDate(checkIn: Date) { + handleSelectDate(checkIn, "checkInDate") + if (dt(checkIn).isSameOrAfter(toDate)) { + handleSelectDate( + dt(checkIn).add(defaultDaysBetween, "days").toDate(), + "checkOutDate" + ) } - setSelectedDates(newDates) - - // Then update form values - setValue("checkInDate", newCheckIn.format("YYYY-MM-DD")) - setValue("checkOutDate", newCheckOut.format("YYYY-MM-DD")) } - function handleCheckOutDateSelect(date: Date) { - const newCheckOut = dt(date).startOf("day") - const currentCheckIn = dt(selectedDates.from).startOf("day") - - // Only adjust check-in if new check-out is before current check-in - const newCheckIn = newCheckOut.isBefore(currentCheckIn) - ? newCheckOut.subtract(defaultDaysBetween, "days") - : currentCheckIn - - // Update selected dates state - const newDates = { - from: newCheckIn.toDate(), - to: newCheckOut.toDate(), + function handleSelectCheckOutDate(checkOut: Date) { + handleSelectDate(checkOut, "checkOutDate") + if (dt(checkOut).isSameOrBefore(fromDate)) { + handleSelectDate( + dt(checkOut).subtract(defaultDaysBetween, "days").toDate(), + "checkInDate" + ) } - setSelectedDates(newDates) - - // Then update form values - setValue("checkInDate", newCheckIn.format("YYYY-MM-DD")) - setValue("checkOutDate", newCheckOut.format("YYYY-MM-DD")) } - const fromDate = selectedDates.from ?? dt(checkInDate).toDate() - const toDate = selectedDates.to ?? dt(checkOutDate).toDate() + const checkInLabel = intl.formatMessage({ defaultMessage: "Check-in" }) + const checkOutLabel = intl.formatMessage({ defaultMessage: "Check-out" }) + const checkInText = dt(fromDate).locale(lang).format("dddd, DD MMM, YYYY") + const checkOutText = dt(toDate).locale(lang).format("dddd, DD MMM, YYYY") return ( <>
- - {intl.formatMessage({ - defaultMessage: "Check-in", - })} - + + {checkInLabel} + - + + + + {checkInText} + + + + + + {({ close }) => ( + <> + + + + )} + + +
-
- - {intl.formatMessage({ - defaultMessage: "Check-out", - })} - - +
+ + {checkOutLabel} + + + + + + {checkOutText} + + + + + + {({ close }) => ( + <> + + + + )} + + +
- - {showCheckInDatePicker && - createPortal( - setShowCheckInDatePicker(!showCheckInDatePicker)} - > - setShowCheckInDatePicker(false)} - handleOnSelect={handleCheckInDateSelect} - selectedDate={fromDate} - startMonth={fromDate} - /> - setShowCheckInDatePicker(false)} - handleOnSelect={handleCheckInDateSelect} - selectedDate={fromDate} - hideHeader - /> - , - document.body - )} - - {showCheckOutDatePicker && - createPortal( - setShowCheckOutDatePicker(!showCheckOutDatePicker)} - > - setShowCheckOutDatePicker(false)} - handleOnSelect={handleCheckOutDateSelect} - selectedDate={toDate} - startMonth={toDate} - /> - setShowCheckOutDatePicker(false)} - handleOnSelect={handleCheckOutDateSelect} - selectedDate={toDate} - hideHeader - /> - , - document.body - )} ) } diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Steps/Form/NewDates/newDates.module.css b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Steps/Form/NewDates/newDates.module.css index 299ac912d..429528aa4 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Steps/Form/NewDates/newDates.module.css +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Steps/Form/NewDates/newDates.module.css @@ -13,3 +13,23 @@ flex-direction: column; gap: var(--Spacing-x1); } + +.trigger { + align-items: center; + background-color: var(--Main-Grey-White); + border-color: var(--Scandic-Beige-40); + border-radius: var(--Corner-radius-Medium); + border-style: solid; + border-width: 1px; + display: flex; + height: 60px; + justify-content: space-between; + min-width: 0; + /* allow shrinkage */ + padding: var(--Spacing-x1) var(--Spacing-x2); + transition: border-color 200ms ease; +} + +.textDefault { + color: var(--Text-Default); +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Steps/Form/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Steps/Form/index.tsx index c65908fcd..8c7c5cffe 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Steps/Form/index.tsx +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/Steps/Form/index.tsx @@ -6,7 +6,7 @@ import { useIntl } from "react-intl" import { dt } from "@/lib/dt" import { useMyStayStore } from "@/stores/my-stay" -import Modal from "@/components/HotelReservation/MyStay/ReferenceCard/Modal" +import Modal from "@/components/HotelReservation/MyStay/Modal" import { toast } from "@/components/TempDesignSystem/Toasts" import NoAvailability from "./Alerts/NoAvailability" @@ -62,7 +62,7 @@ export default function Form({ /> {noAvailability && } - + diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/index.tsx index 064f45ecf..6a66d954d 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/index.tsx +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/ChangeDates/index.tsx @@ -4,7 +4,7 @@ import { useIntl } from "react-intl" import { useMyStayStore } from "@/stores/my-stay" -import Modal from "@/components/HotelReservation/MyStay/ReferenceCard/Modal" +import Modal from "@/components/HotelReservation/MyStay/Modal" import { dateHasPassed } from "../utils" import Alerts from "./Alerts" diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/CustomerSupport/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/CustomerSupport/index.tsx index 1a3798eef..c5a11af1f 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/CustomerSupport/index.tsx +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/CustomerSupport/index.tsx @@ -2,8 +2,8 @@ import { DialogTrigger } from "react-aria-components" import { useIntl } from "react-intl" +import Modal from "@/components/HotelReservation/MyStay/Modal" import CustomerSupportModal from "@/components/HotelReservation/MyStay/ReferenceCard/Actions/CustomerSupportModal" -import Modal from "@/components/HotelReservation/MyStay/ReferenceCard/Modal" export default function CustomerSupport() { const intl = useIntl() diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/GuaranteeLateArrival/Form/form.module.css b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/GuaranteeLateArrival/Form/form.module.css index 94d862acd..e6b9d692b 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/GuaranteeLateArrival/Form/form.module.css +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/GuaranteeLateArrival/Form/form.module.css @@ -34,15 +34,21 @@ } .guaranteeCostText { - align-items: flex-end; display: flex; flex-direction: column; } .baseTextHighContrast { color: var(--Base-Text-High-contrast); + white-space: nowrap; } .textDefault { color: var(--Text-Default); } + +@media screen and (min-width: 768px) { + .guaranteeCostText { + align-items: flex-end; + } +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/GuaranteeLateArrival/guarantee.module.css b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/GuaranteeLateArrival/guarantee.module.css new file mode 100644 index 000000000..4b01c9a1e --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/GuaranteeLateArrival/guarantee.module.css @@ -0,0 +1,3 @@ +.dialog { + max-width: 690px; +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/GuaranteeLateArrival/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/GuaranteeLateArrival/index.tsx index 9f24f003a..011585fe2 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/GuaranteeLateArrival/index.tsx +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Actions/GuaranteeLateArrival/index.tsx @@ -6,11 +6,13 @@ import { Typography } from "@scandic-hotels/design-system/Typography" import { useMyStayStore } from "@/stores/my-stay" -import Modal from "@/components/HotelReservation/MyStay/ReferenceCard/Modal" +import Modal from "@/components/HotelReservation/MyStay/Modal" import { dateHasPassed } from "../utils" import Form from "./Form" +import styles from "./guarantee.module.css" + export default function GuaranteeLateArrival() { const intl = useIntl() @@ -41,7 +43,7 @@ export default function GuaranteeLateArrival() { {text} - + {({ close }) => ( diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Info/info.module.css b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Info/info.module.css index 911d67310..0ac314802 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Info/info.module.css +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/Info/info.module.css @@ -3,7 +3,6 @@ background-color: var(--Surface-Primary-OnSurface-Default); border-radius: var(--Corner-radius-md); display: flex; - flex-direction: column; gap: var(--Space-x2); justify-content: center; padding: var(--Space-x15) var(--Space-x3); @@ -27,3 +26,9 @@ display: flex; flex-direction: column; } + +@media screen and (min-width: 768px) { + .container { + flex-direction: column; + } +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/index.tsx index b4471d3fc..9d5a22f9d 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/index.tsx +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/index.tsx @@ -11,7 +11,7 @@ import { Typography } from "@scandic-hotels/design-system/Typography" import { useMyStayStore } from "@/stores/my-stay" -import Modal from "@/components/HotelReservation/MyStay/ReferenceCard/Modal" +import Modal from "@/components/HotelReservation/MyStay/Modal" import Actions from "./Actions" import Info from "./Info" diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/manageStay.module.css b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/manageStay.module.css index eb1c294cb..ccc30714c 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/manageStay.module.css +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/ManageStay/manageStay.module.css @@ -24,7 +24,8 @@ .dialog { display: grid; - gap: var(--Space-x3); + flex: 1; + gap: var(--Space-x2); } .header { @@ -47,6 +48,16 @@ .content { display: grid; - gap: var(--Space-x3); - grid-template-columns: 1fr 1fr; + gap: var(--Space-x2); +} + +@media screen and (min-width: 768px) { + .dialog { + gap: var(--Space-x3); + } + + .content { + gap: var(--Space-x3); + grid-template-columns: 1fr 1fr; + } } diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/notCancelled.module.css b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/notCancelled.module.css index 279f6bc24..b73bcdb3c 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/notCancelled.module.css +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/Actions/NotCancelled/notCancelled.module.css @@ -4,6 +4,7 @@ border-radius: var(--Corner-radius-rounded); color: var(--Text-Interactive-Default); display: flex; + height: 48px; justify-content: center; text-decoration: none; } diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/PriceContainer/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/PriceContainer/index.tsx index f4e2ea81e..60623c97e 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/PriceContainer/index.tsx +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/PriceContainer/index.tsx @@ -33,8 +33,8 @@ export default function PriceContainer({ {totalChildren > 0 ? `, ${childrenText}` : ""}
-
- +
+ {price}
diff --git a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/PriceContainer/priceContainer.module.css b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/PriceContainer/priceContainer.module.css index 803f044cb..af098b749 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/PriceContainer/priceContainer.module.css +++ b/apps/scandic-web/components/HotelReservation/MyStay/ReferenceCard/PriceContainer/priceContainer.module.css @@ -15,8 +15,12 @@ flex-direction: column; } -.price { +.wrapper { padding-left: var(--Spacing-x2); display: flex; align-items: center; } + +.price { + white-space: nowrap; +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/Room.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/Room.tsx new file mode 100644 index 000000000..92f3d6c0b --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/Room.tsx @@ -0,0 +1,292 @@ +"use client" +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 { IconForFeatureCode } from "@/components/HotelReservation/utils" +import Image from "@/components/Image" +import Divider from "@/components/TempDesignSystem/Divider" +import IconChip from "@/components/TempDesignSystem/IconChip" +import useLang from "@/hooks/useLang" +import { formatPrice } from "@/utils/numberFormatting" + +import PriceType from "../../PriceType" +import { hasModifiableRate } from "../../utils" +import RoomDetailsSidePeek from "./RoomDetailsSidePeek" + +import styles from "./room.module.css" + +import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter" +import type { Room } from "@/types/stores/my-stay" +import type { SafeUser } from "@/types/user" + +interface RoomProps { + booking: Room + roomNr: number + user: SafeUser +} + +export default function Room({ booking, roomNr, user }: RoomProps) { + const intl = useIntl() + const lang = useLang() + + const { + adults, + breakfast, + cancellationNumber, + checkInDate, + cheques, + childrenAges, + confirmationNumber, + currencyCode, + packages, + rateDefinition, + room, + roomName, + roomPoints, + isCancelled, + priceType, + vouchers, + totalPrice, + } = booking + + const fromDate = dt(checkInDate).locale(lang) + + const adultsMsg = intl.formatMessage( + { + defaultMessage: "{adults, plural, one {# adult} other {# adults}}", + }, + { + adults: adults, + } + ) + + const childrenMsg = intl.formatMessage( + { + defaultMessage: "{children, plural, one {# child} other {# children}}", + }, + { + children: childrenAges.length, + } + ) + + const adultsOnlyMsg = adultsMsg + const adultsAndChildrenMsg = [adultsMsg, childrenMsg].join(", ") + + const formattedTotalPrice = formatPrice(intl, totalPrice, currencyCode) + + let breakfastPrice = intl.formatMessage({ + defaultMessage: "No breakfast", + }) + if (rateDefinition.breakfastIncluded) { + breakfastPrice = intl.formatMessage({ + defaultMessage: "Included", + }) + } else if (breakfast) { + breakfastPrice = formatPrice( + intl, + breakfast.localPrice.totalPrice, + breakfast.localPrice.currency + ) + } + + return ( +
+ +

{roomName}

+
+
+ {isCancelled ? ( + + } + > + + + {intl.formatMessage({ + defaultMessage: "Cancelled", + })} + + + + ) : ( +
+ + + {intl.formatMessage( + { + defaultMessage: "Room {roomIndex}", + }, + { + roomIndex: roomNr, + } + )} + + +
+ )} +
+ + {isCancelled ? ( + + {intl.formatMessage({ + defaultMessage: "Cancellation no", + })} + {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} + {":"} + + ) : ( + + {intl.formatMessage({ + defaultMessage: "Booking number", + })} + {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} + {":"} + + )} + + + {isCancelled ? ( + + {cancellationNumber} + + ) : ( + {confirmationNumber} + )} + +
+
+ +
+
+
+ {packages?.some((item) => + Object.values(RoomPackageCodeEnum).includes( + item.code as RoomPackageCodeEnum + ) + ) && ( +
+ {packages + .filter((item) => + Object.values(RoomPackageCodeEnum).includes( + item.code as RoomPackageCodeEnum + ) + ) + .map((item) => { + return ( + + + + ) + })} +
+ )} +
+ {roomName} +
+
+
+ +

+ {intl.formatMessage({ + defaultMessage: "Guests", + })} +

+
+ +

+ {childrenAges.length > 0 ? adultsAndChildrenMsg : adultsOnlyMsg} +

+
+
+ {rateDefinition.cancellationText ? ( +
+ +

+ {intl.formatMessage({ + defaultMessage: "Terms", + })} +

+
+ +

{rateDefinition.cancellationText}

+
+
+ ) : null} + {hasModifiableRate(rateDefinition.cancellationRule) && ( +
+ +

+ {intl.formatMessage({ + defaultMessage: "Modify By", + })} +

+
+ + + {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} +

+ 18:00, {fromDate.format("dddd D MMM")} +

+
+
+ )} + {breakfastPrice !== null && ( +
+ +

+ {intl.formatMessage({ + defaultMessage: "Breakfast", + })} +

+
+ + +

{breakfastPrice}

+
+
+ )} + +
+ +

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

+
+ +
+
+
+
+ ) +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/RoomDetailsSidePeek.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/RoomDetailsSidePeek.tsx new file mode 100644 index 000000000..243e174f4 --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/RoomDetailsSidePeek.tsx @@ -0,0 +1,30 @@ +"use client" +import { Button as ButtonRAC, DialogTrigger } from "react-aria-components" + +import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" + +import BookedRoomSidePeek from "@/components/SidePeeks/BookedRoomSidePeek" + +import styles from "./sidePeek.module.css" + +import type { Room as MyStayRoom } from "@/types/stores/my-stay" +import type { SafeUser } from "@/types/user" + +interface RoomDetailsSidePeekProps { + booking: MyStayRoom + user: SafeUser +} + +export default function RoomDetailsSidePeek({ + booking, + user, +}: RoomDetailsSidePeekProps) { + 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 051763713..821ce78b6 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/index.tsx +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/index.tsx @@ -1,317 +1,70 @@ "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 { useMyStayStore } from "@/stores/my-stay" -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" -import { formatPrice } from "@/utils/numberFormatting" - -import PriceType from "../../PriceType" -import { hasModifiableRate } from "../../utils" +import PriceDetails from "../../PriceDetails" +import TotalPrice from "../TotalPrice" +import Room from "./Room" 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" interface MultiRoomProps { - booking: Room - roomNr: number user: SafeUser - roomCategories: RoomCategories } -export default function MultiRoom({ - booking, - roomNr, - user, - roomCategories, -}: MultiRoomProps) { +export default function MultiRoom(props: MultiRoomProps) { const intl = useIntl() - const lang = useLang() + const { allRoomsAreCancelled, rooms } = useMyStayStore((state) => ({ + allRoomsAreCancelled: state.allRoomsAreCancelled, + rooms: state.rooms, + })) - const { - adults, - breakfast, - cancellationNumber, - checkInDate, - cheques, - childrenAges, - confirmationNumber, - currencyCode, - packages, - rateDefinition, - room, - roomName, - roomPoints, - isCancelled, - priceType, - roomTypeCode, - vouchers, - totalPrice, - } = booking - - const fromDate = dt(checkInDate).locale(lang) - - const adultsMsg = intl.formatMessage( - { - defaultMessage: "{adults, plural, one {# adult} other {# adults}}", - }, - { - adults: adults, - } - ) - - const childrenMsg = intl.formatMessage( - { - defaultMessage: "{children, plural, one {# child} other {# children}}", - }, - { - children: childrenAges.length, - } - ) - - const adultsOnlyMsg = adultsMsg - const adultsAndChildrenMsg = [adultsMsg, childrenMsg].join(", ") - - const formattedTotalPrice = formatPrice(intl, totalPrice, currencyCode) - - let breakfastPrice = intl.formatMessage({ - defaultMessage: "No breakfast", - }) - if (rateDefinition.breakfastIncluded) { - breakfastPrice = intl.formatMessage({ - defaultMessage: "Included", - }) - } else if (breakfast) { - breakfastPrice = formatPrice( - intl, - breakfast.localPrice.totalPrice, - breakfast.localPrice.currency - ) + if (rooms.length <= 1) { + return null } - const hotelRoom = getBookedHotelRoom(roomCategories, roomTypeCode) return ( -
- -

{roomName}

+
+ +

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

-
- {isCancelled ? ( - - } - > - - - {intl.formatMessage({ - defaultMessage: "Cancelled", - })} - - - - ) : ( -
- - - {intl.formatMessage( - { - defaultMessage: "Room {roomIndex}", - }, - { - roomIndex: roomNr, - } - )} - - -
- )} -
- - {isCancelled ? ( - - {intl.formatMessage({ - defaultMessage: "Cancellation no", - })} - {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} - {":"} - - ) : ( - - {intl.formatMessage({ - defaultMessage: "Booking number", - })} - {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} - {":"} - - )} - - - {isCancelled ? ( - - {cancellationNumber} - - ) : ( - {confirmationNumber} - )} - -
-
- - +
+ {rooms.map((booking, index) => ( +
- - - - + +
+ ))}
-
- {packages?.some((item) => - Object.values(RoomPackageCodeEnum).includes( - item.code as RoomPackageCodeEnum - ) - ) && ( -
- {packages - .filter((item) => - Object.values(RoomPackageCodeEnum).includes( - item.code as RoomPackageCodeEnum - ) - ) - .map((item) => { - return ( - - - - ) +
+
+ +

+ {intl.formatMessage({ + defaultMessage: "Booking total", })} -

- )} -
- {roomName} + {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} + {":"} +

+ +
-
-
- -

- {intl.formatMessage({ - defaultMessage: "Guests", - })} -

-
- -

- {childrenAges.length > 0 ? adultsAndChildrenMsg : adultsOnlyMsg} -

-
-
- {rateDefinition.cancellationText ? ( -
- -

- {intl.formatMessage({ - defaultMessage: "Terms", - })} -

-
- -

{rateDefinition.cancellationText}

-
-
- ) : null} - {hasModifiableRate(rateDefinition.cancellationRule) && ( -
- -

- {intl.formatMessage({ - defaultMessage: "Modify By", - })} -

-
- - {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} -

- 18:00, {fromDate.format("dddd D MMM")} -

-
-
- )} - {breakfastPrice !== null && ( -
- -

- {intl.formatMessage({ - defaultMessage: "Breakfast", - })} -

-
- - -

{breakfastPrice}

-
-
- )} - -
- -

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

-
- -
-
+ {allRoomsAreCancelled ? null : }
-
+
) } diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/multiRoom.module.css b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/multiRoom.module.css index 7a50b6668..973b4489c 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/multiRoom.module.css +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/multiRoom.module.css @@ -1,101 +1,63 @@ -.multiRoom { +.wrapper { display: flex; flex-direction: column; - gap: var(--Spacing-x2); + gap: var(--Spacing-x3); +} + +.title { + color: var(--Scandic-Brand-Burgundy); padding: 0 var(--Spacing-x2); } -.cancelled { - opacity: 0.5; -} - -.cancellationNumber { - text-decoration: line-through; -} - -.multiRoomCard { +.container { display: flex; flex-direction: column; - gap: var(--Spacing-x2); - background-color: var(--Base-Background-Primary-Normal); - border-radius: var(--Corner-radius-Large); - border: 1px solid var(--Base-Border-Subtle); - overflow: hidden; - padding-bottom: var(--Spacing-x3); - position: relative; + gap: var(--Spacing-x5); } -.imageContainer { +.roomsContainer { + display: grid; + gap: var(--Spacing-x3); + grid-template-columns: 1fr; width: 100%; - height: 342px; - position: relative; } -.iconContainer { +.roomWrapper { + min-width: 0; + width: 100%; +} + +.roomWrapper > * { + width: 100%; +} + +.totalContainer { display: flex; - border: 1px solid var(--Base-Border-Subtle); - border-radius: var(--Corner-radius-Small); - padding: var(--Spacing-x-half); -} - -.roomName { - color: var(--Scandic-Brand-Burgundy); -} - -.roomHeader { - display: flex; - align-items: center; - gap: var(--Spacing-x-one-and-half); -} - -.chip { - background-color: var(--Scandic-Peach-30); - color: var(--Scandic-Red-100); - border-radius: var(--Corner-radius-Small); - padding: var(--Spacing-x-half) var(--Spacing-x1); - height: fit-content; -} - -.toggleSidePeek { - margin-left: auto; -} - -.reference { - display: flex; - gap: var(--Spacing-x-half); -} - -.details { - display: flex; - padding: var(--Spacing-x-one-and-half) var(--Spacing-x2) 0; - gap: var(--Spacing-x2); flex-direction: column; -} - -.row { - display: flex; - flex-direction: row; - justify-content: space-between; -} - -.packages { - position: absolute; - top: 304px; - left: 10px; - display: flex; - flex-direction: row; gap: var(--Spacing-x1); - z-index: 100; + padding: 0 var(--Spacing-x2); } -.package { - background-color: var(--Main-Grey-White); - padding: var(--Spacing-x-half) var(--Spacing-x1); - border-radius: var(--Corner-radius-Small); +.total { + display: flex; + justify-content: flex-end; + gap: var(--Spacing-x1); } @media (min-width: 768px) { - .multiRoom { + .roomsContainer { + grid-template-columns: repeat(2, 1fr); + } + + .roomsContainer:has(> *:nth-child(3):last-child) { + grid-template-columns: repeat(3, 1fr); + } + + .title { + padding: 0; + } + + .totalContainer { padding: 0; } } diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/room.module.css b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/room.module.css new file mode 100644 index 000000000..4090a3acd --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/room.module.css @@ -0,0 +1,94 @@ +.multiRoom { + display: flex; + flex-direction: column; + gap: var(--Spacing-x2); + padding: 0 var(--Spacing-x2); +} + +.cancelled { + opacity: 0.5; +} + +.cancellationNumber { + text-decoration: line-through; +} + +.multiRoomCard { + display: flex; + flex-direction: column; + gap: var(--Spacing-x2); + background-color: var(--Base-Background-Primary-Normal); + border-radius: var(--Corner-radius-Large); + border: 1px solid var(--Base-Border-Subtle); + overflow: hidden; + padding-bottom: var(--Spacing-x3); + position: relative; +} + +.imageContainer { + width: 100%; + height: 342px; + position: relative; +} + +.roomName { + color: var(--Scandic-Brand-Burgundy); +} + +.roomHeader { + display: flex; + align-items: center; + gap: var(--Spacing-x-one-and-half); +} + +.chip { + background-color: var(--Scandic-Peach-30); + color: var(--Scandic-Red-100); + border-radius: var(--Corner-radius-Small); + padding: var(--Spacing-x-half) var(--Spacing-x1); + height: fit-content; +} + +.toggleSidePeek { + margin-left: auto; +} + +.reference { + display: flex; + gap: var(--Spacing-x-half); +} + +.details { + display: flex; + padding: var(--Spacing-x-one-and-half) var(--Spacing-x2) 0; + gap: var(--Spacing-x2); + flex-direction: column; +} + +.row { + display: flex; + flex-direction: row; + justify-content: space-between; +} + +.packages { + position: absolute; + top: 304px; + left: 10px; + display: flex; + flex-direction: row; + gap: var(--Spacing-x1); + z-index: 100; +} + +.package { + background-color: var(--Main-Grey-White); + padding: var(--Spacing-x-half) var(--Spacing-x1); + border-radius: var(--Corner-radius-Small); +} + +@media (min-width: 768px) { + .multiRoom { + padding: 0; + } +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/sidePeek.module.css b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/sidePeek.module.css new file mode 100644 index 000000000..1d326e34c --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/MultiRoom/sidePeek.module.css @@ -0,0 +1,8 @@ +.trigger { + background: none; + border: 1px solid var(--Base-Border-Subtle); + border-radius: var(--Corner-radius-Small); + cursor: pointer; + display: flex; + padding: var(--Spacing-x-half); +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/BookingInformation/BookingCode.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/BookingInformation/BookingCode.tsx new file mode 100644 index 000000000..747ccb723 --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/BookingInformation/BookingCode.tsx @@ -0,0 +1,42 @@ +"use client" +import { useIntl } from "react-intl" + +import DiscountIcon from "@scandic-hotels/design-system/Icons/DiscountIcon" +import { Typography } from "@scandic-hotels/design-system/Typography" + +import { useMyStayStore } from "@/stores/my-stay" + +import IconChip from "@/components/TempDesignSystem/IconChip" + +export default function BookingCode() { + const intl = useIntl() + + const bookingCode = useMyStayStore((state) => state.bookedRoom.bookingCode) + + if (!bookingCode) { + return null + } + + return ( + + } + > + {intl.formatMessage( + { + defaultMessage: "Booking code: {value}", + }, + { + value: bookingCode, + strong: (text) => ( + + {text} + + ), + } + )} + + + ) +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/BookingInformation/PriceDetails/details.module.css b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/BookingInformation/PriceDetails/details.module.css new file mode 100644 index 000000000..2f6d2dbfd --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/BookingInformation/PriceDetails/details.module.css @@ -0,0 +1,30 @@ +.priceDetails { + display: flex; + flex-direction: column; + align-items: center; + gap: var(--Spacing-x1); + padding: var(--Spacing-x-one-and-half) 0; + width: calc(100% - var(--Spacing-x4)); + justify-content: center; + margin: 0 auto; +} + +.price { + align-items: center; + display: flex; + gap: var(--Spacing-x1); + justify-content: space-between; + width: 100%; +} + +@media (min-width: 768px) { + .priceDetails { + align-items: flex-end; + margin: 0 0 0 auto; + width: auto; + } + + .price { + justify-content: flex-end; + } +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/BookingInformation/PriceDetails/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/BookingInformation/PriceDetails/index.tsx new file mode 100644 index 000000000..dbe52fb52 --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/BookingInformation/PriceDetails/index.tsx @@ -0,0 +1,40 @@ +"use client" +import { useIntl } from "react-intl" + +import { Typography } from "@scandic-hotels/design-system/Typography" + +import { useMyStayStore } from "@/stores/my-stay" + +import PriceType from "@/components/HotelReservation/MyStay/PriceType" + +import styles from "./details.module.css" + +export default function PriceDetails() { + const intl = useIntl() + + const pricing = useMyStayStore((state) => ({ + cheques: state.bookedRoom.cheques, + formattedTotalPrice: state.totalPrice, + isCancelled: state.bookedRoom.isCancelled, + priceType: state.bookedRoom.priceType, + rateDefinition: state.bookedRoom.rateDefinition, + roomPoints: state.bookedRoom.roomPoints, + totalPrice: state.bookedRoom.totalPrice, + vouchers: state.bookedRoom.vouchers, + })) + + return ( +
+
+ +

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

+
+ +
+
+ ) +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/BookingInformation/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/BookingInformation/index.tsx new file mode 100644 index 000000000..25e562db5 --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/BookingInformation/index.tsx @@ -0,0 +1,13 @@ +import BookingCode from "./BookingCode" +import PriceDetails from "./PriceDetails" + +import styles from "./information.module.css" + +export default function BookingInformation() { + return ( +
+ + +
+ ) +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/BookingInformation/information.module.css b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/BookingInformation/information.module.css new file mode 100644 index 000000000..66681dad0 --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/BookingInformation/information.module.css @@ -0,0 +1,22 @@ +.bookingInformation { + align-items: center; + background-color: var(--Scandic-Beige-10); + border: 1px solid var(--Base-Border-Subtle); + border-radius: var(--Corner-radius-Medium); + display: flex; + flex-direction: column-reverse; + gap: var(--Spacing-x2); + margin: 0 var(--Spacing-x2); +} + +@media (min-width: 768px) { + .bookingInformation { + align-items: flex-start; + border: none; + border-radius: 0; + flex-direction: row; + justify-content: space-between; + margin: 0; + padding: var(--Spacing-x-one-and-half); + } +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/BedPreference.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/BedPreference.tsx new file mode 100644 index 000000000..d8244b42f --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/BedPreference.tsx @@ -0,0 +1,49 @@ +import { useIntl } from "react-intl" + +import { useMyStayStore } from "@/stores/my-stay" + +import Row from "./Row" + +export default function BedPreference() { + const intl = useIntl() + + const bedType = useMyStayStore((state) => state.bookedRoom.room?.bedType) + + if (!bedType) { + return null + } + + const mainBedWidthValueMsg = intl.formatMessage( + { + defaultMessage: "{value} cm", + }, + { + value: bedType.mainBed.widthRange.min, + } + ) + + const mainBedWidthRangeMsg = intl.formatMessage( + { + defaultMessage: "{min}–{max} cm", + }, + { + min: bedType.mainBed.widthRange.min, + max: bedType.mainBed.widthRange.max, + } + ) + + const sameWidth = + bedType.mainBed.widthRange.min === bedType.mainBed.widthRange.max + const widthMsg = sameWidth ? mainBedWidthValueMsg : mainBedWidthRangeMsg + const text = `${bedType.mainBed.description} (${widthMsg})` + + return ( + + ) +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/Breakfast.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/Breakfast.tsx new file mode 100644 index 000000000..ca34e8e2d --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/Breakfast.tsx @@ -0,0 +1,35 @@ +"use client" +import { useIntl } from "react-intl" + +import { useMyStayStore } from "@/stores/my-stay" + +import { formatPrice } from "@/utils/numberFormatting" + +import Row from "./Row" + +export default function Breakfast() { + const intl = useIntl() + + const { breakfast, rateDefinition } = useMyStayStore((state) => ({ + breakfast: state.bookedRoom.breakfast, + rateDefinition: state.bookedRoom.rateDefinition, + })) + + let breakfastPrice = intl.formatMessage({ + defaultMessage: "No breakfast", + }) + if (rateDefinition.breakfastIncluded) { + breakfastPrice = intl.formatMessage({ + defaultMessage: "Included", + }) + } else if (breakfast) { + breakfastPrice = formatPrice( + intl, + breakfast.localPrice.totalPrice, + breakfast.localPrice.currency + ) + } + + const title = intl.formatMessage({ defaultMessage: "Breakfast" }) + return +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/Guests.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/Guests.tsx new file mode 100644 index 000000000..b7aa92078 --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/Guests.tsx @@ -0,0 +1,45 @@ +import { useIntl } from "react-intl" + +import { useMyStayStore } from "@/stores/my-stay" + +import Row from "./Row" + +export default function Guests() { + const intl = useIntl() + + const { adults, childrenAges } = useMyStayStore((state) => ({ + adults: state.bookedRoom.adults, + childrenAges: state.bookedRoom.childrenAges, + })) + + const adultsMsg = intl.formatMessage( + { + defaultMessage: "{adults, plural, one {# adult} other {# adults}}", + }, + { + adults, + } + ) + + const childrenMsg = intl.formatMessage( + { + defaultMessage: "{children, plural, one {# child} other {# children}}", + }, + { + children: childrenAges.length, + } + ) + + const adultsOnlyMsg = adultsMsg + const adultsAndChildrenMsg = [adultsMsg, childrenMsg].join(", ") + + return ( + 0 ? adultsAndChildrenMsg : adultsOnlyMsg} + title={intl.formatMessage({ + defaultMessage: "Guests", + })} + /> + ) +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/ModifyBy.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/ModifyBy.tsx new file mode 100644 index 000000000..2dcdafa59 --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/ModifyBy.tsx @@ -0,0 +1,47 @@ +import { useIntl } from "react-intl" + +import { dt } from "@/lib/dt" +import { useMyStayStore } from "@/stores/my-stay" + +import { hasModifiableRate } from "@/components/HotelReservation/MyStay/utils" +import useLang from "@/hooks/useLang" + +import Row from "./Row" + +export default function ModifyBy() { + const intl = useIntl() + const lang = useLang() + + const { checkInDate, isModifyable } = useMyStayStore((state) => ({ + checkInDate: state.bookedRoom.checkInDate, + isModifyable: hasModifiableRate( + state.bookedRoom.rateDefinition.cancellationRule + ), + })) + + if (!isModifyable) { + return null + } + + const fromDate = dt(checkInDate).locale(lang) + + const text = intl.formatMessage( + { + defaultMessage: "Until {time}, {date}", + }, + { + time: "18:00", + date: fromDate.format("dddd D MMM"), + } + ) + + return ( + + ) +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/Packages.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/Packages.tsx new file mode 100644 index 000000000..7e2b4a1e0 --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/Packages.tsx @@ -0,0 +1,36 @@ +import { useIntl } from "react-intl" + +import { useMyStayStore } from "@/stores/my-stay" + +import Row from "./Row" + +import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter" + +export default function Packages() { + const intl = useIntl() + + const packages = useMyStayStore( + (state) => + state.bookedRoom.packages + ?.filter((item) => + Object.values(RoomPackageCodeEnum).includes( + item.code as RoomPackageCodeEnum + ) + ) + .map((item) => item.description) || [] + ) + + if (!packages.length) { + return null + } + + return ( + + ) +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/Row/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/Row/index.tsx new file mode 100644 index 000000000..71bd9e58f --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/Row/index.tsx @@ -0,0 +1,32 @@ +"use client" +import { + MaterialIcon, + type MaterialIconProps, +} from "@scandic-hotels/design-system/Icons/MaterialIcon" +import { Typography } from "@scandic-hotels/design-system/Typography" + +import styles from "./row.module.css" + +interface RowProps { + icon: MaterialIconProps["icon"] + text: string + title: string +} + +export default function Row({ icon, text, title }: RowProps) { + return ( +
+ + + +

{title}

+
+
+
+ +

{text}

+
+
+
+ ) +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/Row/row.module.css b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/Row/row.module.css new file mode 100644 index 000000000..6de33979c --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/Row/row.module.css @@ -0,0 +1,38 @@ +.row { + display: flex; + flex-direction: column; + padding: var(--Spacing-x-one-and-half) 0; +} + +.row:last-child { + border-bottom: none; +} + +.title { + display: flex; + flex-direction: row; + gap: var(--Spacing-x1); +} + +.title svg { + height: 24px; + width: 24px; +} + +.content { + padding-left: var(--Spacing-x4); +} + +@media (min-width: 768px) { + .row { + align-items: center; + border-bottom: 1px solid var(--Base-Border-Subtle); + flex-direction: row; + justify-content: space-between; + } + + .title svg { + height: 20px; + width: 20px; + } +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/Terms.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/Terms.tsx new file mode 100644 index 000000000..7c12584b0 --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/Terms.tsx @@ -0,0 +1,27 @@ +import { useIntl } from "react-intl" + +import { useMyStayStore } from "@/stores/my-stay" + +import Row from "./Row" + +export default function Terms() { + const intl = useIntl() + + const cancellationText = useMyStayStore( + (state) => state.bookedRoom.rateDefinition.cancellationText + ) + + if (!cancellationText) { + return null + } + + return ( + + ) +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/details.module.css b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/details.module.css new file mode 100644 index 000000000..0fa25f1d6 --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/details.module.css @@ -0,0 +1,10 @@ +.details { + max-width: 100%; + padding: 0 var(--Spacing-x2); +} + +@media (min-width: 768px) { + .details { + padding: 0; + } +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/index.tsx new file mode 100644 index 000000000..19643e4b5 --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Details/index.tsx @@ -0,0 +1,21 @@ +import BedPreference from "./BedPreference" +import Breakfast from "./Breakfast" +import Guests from "./Guests" +import ModifyBy from "./ModifyBy" +import Packages from "./Packages" +import Terms from "./Terms" + +import styles from "./details.module.css" + +export default function Details() { + return ( +
+ + + + + + +
+ ) +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Header/header.module.css b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Header/header.module.css new file mode 100644 index 000000000..7377cae77 --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Header/header.module.css @@ -0,0 +1,39 @@ +.header { + display: flex; + gap: var(--Spacing-x-one-and-half); + padding: 0 var(--Spacing-x2); +} + +.container { + display: flex; + gap: var(--Spacing-x-one-and-half); +} + +.chip { + background-color: var(--Scandic-Peach-30); + color: var(--Scandic-Red-100); + border-radius: var(--Corner-radius-Small); + padding: var(--Spacing-x-half) var(--Spacing-x1); +} + +.reference { + display: flex; + gap: var(--Spacing-x-half); +} + +.sidePeek { + display: none; +} + +@media (min-width: 768px) { + .header { + justify-content: space-between; + align-items: center; + flex-direction: row; + padding: 0; + } + + .sidePeek { + display: block; + } +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Header/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Header/index.tsx new file mode 100644 index 000000000..8e844cf99 --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Header/index.tsx @@ -0,0 +1,59 @@ +"use client" +import { useIntl } from "react-intl" + +import { Typography } from "@scandic-hotels/design-system/Typography" + +import { useMyStayStore } from "@/stores/my-stay" + +import RoomDetailsSidePeek from "../RoomDetailsSidePeek" + +import styles from "./header.module.css" + +import type { SafeUser } from "@/types/user" + +export default function Header({ user }: { user: SafeUser }) { + const intl = useIntl() + + const { confirmationNumber, roomNumber } = useMyStayStore((state) => ({ + confirmationNumber: state.bookedRoom.confirmationNumber, + roomNumber: state.bookedRoom.roomNumber, + })) + + return ( +
+
+
+ + + {intl.formatMessage( + { + defaultMessage: "Room {roomIndex}", + }, + { + roomIndex: roomNumber, + } + )} + + +
+
+ + + {intl.formatMessage({ + defaultMessage: "Booking number", + })} + {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} + {":"} + + + + {confirmationNumber} + +
+
+
+ +
+
+ ) +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Img/img.module.css b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Img/img.module.css new file mode 100644 index 000000000..bfae8b25f --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Img/img.module.css @@ -0,0 +1,22 @@ +.imageContainer { + height: 220px; + overflow: hidden; +} + +.image { + aspect-ratio: 16/9; + height: 220px; + object-fit: cover; + width: 100%; +} + +@media (min-width: 768px) { + .imageContainer { + height: 640px; + } + + .image { + border-radius: var(--Corner-radius-Medium); + height: 100%; + } +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Img/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Img/index.tsx new file mode 100644 index 000000000..91b209ca2 --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Img/index.tsx @@ -0,0 +1,31 @@ +"use client" +import { useMyStayStore } from "@/stores/my-stay" + +import Image from "@/components/Image" + +import styles from "./img.module.css" + +export default function Img() { + const { room, roomName } = useMyStayStore((state) => ({ + room: state.bookedRoom.room, + roomName: state.bookedRoom.roomName, + })) + + if (!room) { + return null + } + + const image = room.images?.[0] + + return ( +
+ {roomName} +
+ ) +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Packages/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Packages/index.tsx new file mode 100644 index 000000000..521dbbb68 --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Packages/index.tsx @@ -0,0 +1,38 @@ +"use client" + +import { useMyStayStore } from "@/stores/my-stay" + +import { IconForFeatureCode } from "@/components/HotelReservation/utils" + +import styles from "./packages.module.css" + +import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter" + +export default function Packages() { + const packages = useMyStayStore( + (state) => + state.bookedRoom.packages?.filter((item) => + Object.values(RoomPackageCodeEnum).includes( + item.code as RoomPackageCodeEnum + ) + ) || [] + ) + + if (!packages.length) { + return null + } + + return ( +
+ {packages.map((item) => ( + + + + ))} +
+ ) +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Packages/packages.module.css b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Packages/packages.module.css new file mode 100644 index 000000000..09e80b94f --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/Packages/packages.module.css @@ -0,0 +1,22 @@ +.packages { + display: flex; + flex-direction: row; + gap: var(--Spacing-x1); + left: 15px; + position: absolute; + top: 180px; + z-index: 1; +} + +.package { + background-color: var(--Main-Grey-White); + border-radius: var(--Corner-radius-Small); + padding: var(--Spacing-x-half) var(--Spacing-x1); +} + +@media (min-width: 768px) { + .packages { + left: 25px; + top: 620px; + } +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/RoomDetailsSidePeek.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/RoomDetailsSidePeek.tsx new file mode 100644 index 000000000..ef6ec9d42 --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/RoomDetailsSidePeek.tsx @@ -0,0 +1,37 @@ +"use client" + +import { DialogTrigger } from "react-aria-components" +import { useIntl } from "react-intl" + +import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" + +import { useMyStayStore } from "@/stores/my-stay" + +import BookedRoomSidePeek from "@/components/SidePeeks/BookedRoomSidePeek" +import Button from "@/components/TempDesignSystem/Button" + +import type { SafeUser } from "@/types/user" + +interface RoomDetailsSidePeekProps { + user: SafeUser +} + +export default function RoomDetailsSidePeek({ + user, +}: RoomDetailsSidePeekProps) { + const intl = useIntl() + const bookedRoom = useMyStayStore((state) => state.bookedRoom) + return ( + + + + + ) +} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/ToggleSidePeek.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/ToggleSidePeek.tsx deleted file mode 100644 index c9ecaa921..000000000 --- a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/ToggleSidePeek.tsx +++ /dev/null @@ -1,46 +0,0 @@ -"use client" - -import { useIntl } from "react-intl" - -import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" - -import useSidePeekStore from "@/stores/sidepeek" - -import Button from "@/components/TempDesignSystem/Button" - -import { SidePeekEnum } from "@/types/components/hotelReservation/sidePeek" -import type { ToggleSidePeekProps } from "@/types/components/hotelReservation/toggleSidePeekProps" - -export default function ToggleSidePeek({ - hotelId, - roomTypeCode, - intent = "textInverted", - title, -}: ToggleSidePeekProps) { - const intl = useIntl() - const openSidePeek = useSidePeekStore((state) => state.openSidePeek) - - return ( - - ) -} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/index.tsx index e7315c6ed..459bf2e02 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/index.tsx +++ b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/SingleRoom/index.tsx @@ -1,94 +1,48 @@ "use client" -import { Button as ButtonRAC, DialogTrigger } from "react-aria-components" -import { useIntl } from "react-intl" -import DiscountIcon from "@scandic-hotels/design-system/Icons/DiscountIcon" -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 { useMyStayStore } from "@/stores/my-stay" import GuestDetails from "@/components/HotelReservation/MyStay/GuestDetails" import PriceDetails from "@/components/HotelReservation/MyStay/PriceDetails" -import PriceType from "@/components/HotelReservation/MyStay/PriceType" -import { hasModifiableRate } from "@/components/HotelReservation/MyStay/utils" -import { IconForFeatureCode } from "@/components/HotelReservation/utils" -import Image from "@/components/Image" -import BookedRoomSidePeek from "@/components/SidePeeks/BookedRoomSidePeek" import SkeletonShimmer from "@/components/SkeletonShimmer" -import IconChip from "@/components/TempDesignSystem/IconChip" -import useLang from "@/hooks/useLang" -import { formatPrice } from "@/utils/numberFormatting" + +import BookingInformation from "./BookingInformation" +import Details from "./Details" +import Header from "./Header" +import Img from "./Img" +import Packages from "./Packages" import styles from "./room.module.css" -import { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter" -import type { Room, RoomCategories } from "@/types/hotel" import type { SafeUser } from "@/types/user" interface RoomProps { - bedType: Room["roomTypes"][number] - image: Room["images"][number] user: SafeUser - roomCategories: RoomCategories } -export default function SingleRoom({ - bedType, - image, - user, - roomCategories, -}: RoomProps) { - const intl = useIntl() - const lang = useLang() - +export default function SingleRoom({ user }: RoomProps) { const { - adults, - bookingCode, - breakfast, - checkInDate, - cheques, - childrenAges, confirmationNumber, - formattedTotalPrice, guest, isCancelled, - packages, - priceType, - rateDefinition, + isMultiRoom, roomName, roomNumber, - roomPoints, - roomTypeCode, - totalPrice, - vouchers, - bookedRoom, } = useMyStayStore((state) => ({ - 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, confirmationNumber: state.bookedRoom.confirmationNumber, - formattedTotalPrice: state.totalPrice, - hotel: state.hotel, + guest: state.bookedRoom.guest, isCancelled: state.bookedRoom.isCancelled, - packages: state.bookedRoom.packages, - priceType: state.bookedRoom.priceType, - rateDefinition: state.bookedRoom.rateDefinition, + isMultiRoom: state.rooms.length > 1, roomName: state.bookedRoom.roomName, roomNumber: state.bookedRoom.roomNumber, - roomPoints: state.bookedRoom.roomPoints, - roomTypeCode: state.bookedRoom.roomTypeCode, - totalPrice: state.bookedRoom.totalPrice, - vouchers: state.bookedRoom.vouchers, - bookedRoom: state.bookedRoom, })) + if (isMultiRoom) { + return null + } + if (!roomNumber) { return (
@@ -98,403 +52,45 @@ export default function SingleRoom({ ) } - const fromDate = dt(checkInDate).locale(lang) - - const mainBedWidthValueMsg = intl.formatMessage( - { - defaultMessage: "{value} cm", - }, - { - value: bedType.mainBed.widthRange.min, - } - ) - - const mainBedWidthRangeMsg = intl.formatMessage( - { - defaultMessage: "{min}–{max} cm", - }, - { - min: bedType.mainBed.widthRange.min, - max: bedType.mainBed.widthRange.max, - } - ) - - const adultsMsg = intl.formatMessage( - { - defaultMessage: "{adults, plural, one {# adult} other {# adults}}", - }, - { - adults, - } - ) - - const childrenMsg = intl.formatMessage( - { - defaultMessage: "{children, plural, one {# child} other {# children}}", - }, - { - children: childrenAges.length, - } - ) - - const adultsOnlyMsg = adultsMsg - const adultsAndChildrenMsg = [adultsMsg, childrenMsg].join(", ") - - const hasPackages = packages?.some((item) => - Object.values(RoomPackageCodeEnum).includes( - item.code as RoomPackageCodeEnum - ) - ) - - let breakfastPrice = null - if (rateDefinition.breakfastIncluded) { - breakfastPrice = intl.formatMessage({ - defaultMessage: "Included", - }) - } else if (breakfast) { - breakfastPrice = formatPrice( - intl, - breakfast.localPrice.totalPrice, - breakfast.localPrice.currency - ) - } - - const hotelRoom = getBookedHotelRoom(roomCategories, roomTypeCode) - return ( -
-
- -

{roomName}

-
-
-
-
- - - {intl.formatMessage( - { - defaultMessage: "Room {roomIndex}", - }, - { - roomIndex: roomNumber, - } - )} - - -
-
- - - {intl.formatMessage({ - defaultMessage: "Booking number", - })} - {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} - {":"} - - - - {confirmationNumber} - -
-
-
- - - - - {intl.formatMessage({ - defaultMessage: "View room details", - })} - - +
+
+ +

{roomName}

+
+
+
+
+ + +
+
+
+ - - - - -
-
-
-
- {packages?.some((item) => - Object.values(RoomPackageCodeEnum).includes( - item.code as RoomPackageCodeEnum - ) - ) && ( -
- {packages - .filter((item) => - Object.values(RoomPackageCodeEnum).includes( - item.code as RoomPackageCodeEnum - ) - ) - .map((item) => { - return ( - - - - ) - })} -
- )} -
- {roomName} -
-
-
-
- - - -

- {intl.formatMessage({ - defaultMessage: "Guests", - })} -

-
-
-
- -

- {childrenAges.length > 0 - ? adultsAndChildrenMsg - : adultsOnlyMsg} -

-
-
-
- {rateDefinition.cancellationText ? ( -
- - - -

- {intl.formatMessage({ - defaultMessage: "Terms", - })} -

-
-
-
- -

- {rateDefinition.cancellationText} -

-
-
-
- ) : null} - {hasModifiableRate(rateDefinition.cancellationRule) && ( -
- - - -

- {intl.formatMessage({ - defaultMessage: "Modify By", - })} -

-
-
-
- -

- {intl.formatMessage( - { - defaultMessage: "Until {time}, {date}", - }, - { - time: "18:00", - date: fromDate.format("dddd D MMM"), - } - )} -

-
-
-
- )} - {breakfastPrice !== null && ( -
- - - -

- {intl.formatMessage({ - defaultMessage: "Breakfast", - })} -

-
-
-
- -

{breakfastPrice}

-
-
-
- )} - {hasPackages && ( -
- - - -

- {intl.formatMessage({ - defaultMessage: "Room classification", - })} -

-
-
-
- -

- {packages! - .filter((item) => - Object.values(RoomPackageCodeEnum).includes( - item.code as RoomPackageCodeEnum - ) - ) - .map((item) => item.description) - .join(", ")} -

-
-
-
- )} - -
- - - -

- {intl.formatMessage({ - defaultMessage: "Bed preference", - })} -

-
-
-
- -

- {bedType.mainBed.description} - {bedType.mainBed.widthRange.min === - bedType.mainBed.widthRange.max - ? // eslint-disable-next-line formatjs/no-literal-string-in-jsx - ` (${mainBedWidthValueMsg})` - : // eslint-disable-next-line formatjs/no-literal-string-in-jsx - ` (${mainBedWidthRangeMsg})`} -

-
-
-
- -
+
-
- {bookingCode && ( - - } - > - {intl.formatMessage( - { - defaultMessage: "Booking code: {value}", - }, - { - value: bookingCode, - strong: (text) => ( - - {text} - - ), - } - )} - - - )} -
-
- -

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

-
- -
-
+ +
+
-
- - -
- -
-
+
+
) } 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 b9a96e503..53e896926 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 @@ -1,42 +1,28 @@ +.wrapper { + display: flex; + flex-direction: column; + gap: var(--Spacing-x3); +} + +.container { + display: flex; + flex-direction: column; + gap: var(--Spacing-x5); +} + .room { + background-color: var(--Base-Background-Primary-Normal); display: flex; flex-direction: column; gap: var(--Spacing-x2); - background-color: var(--Base-Background-Primary-Normal); 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); } -.roomHeader { - display: flex; - gap: var(--Spacing-x-one-and-half); - padding: 0 var(--Spacing-x2); -} - -.roomHeaderContent { - display: flex; - gap: var(--Spacing-x-one-and-half); -} - -.sidePeek { - display: none; -} - .booking { display: flex; flex-direction: column; @@ -56,136 +42,12 @@ opacity: 0.5; } -.chip { - background-color: var(--Scandic-Peach-30); - color: var(--Scandic-Red-100); - border-radius: var(--Corner-radius-Small); - padding: var(--Spacing-x-half) var(--Spacing-x1); -} - -.reference { - display: flex; - gap: var(--Spacing-x-half); -} - -.packages { - position: absolute; - top: 180px; - left: 15px; - display: flex; - flex-direction: row; - gap: var(--Spacing-x1); - z-index: 1; -} - -.package { - background-color: var(--Main-Grey-White); - padding: var(--Spacing-x-half) var(--Spacing-x1); - border-radius: var(--Corner-radius-Small); -} - -.imageContainer { - height: 220px; - overflow: hidden; -} - -.image { - width: 100%; - height: 220px; - aspect-ratio: 16/9; - object-fit: cover; -} - -.imagePlaceholder { - height: 100%; - width: 100%; - background-color: #fff; - background-image: - linear-gradient(45deg, #000000 25%, transparent 25%), - linear-gradient(-45deg, #000000 25%, transparent 25%), - linear-gradient(45deg, transparent 75%, #000000 75%), - linear-gradient(-45deg, transparent 75%, #000000 75%); - background-size: 120px 120px; - background-position: - 0 0, - 0 60px, - 60px -60px, - -60px 0; -} - .roomDetails { display: flex; flex-direction: column; gap: var(--Spacing-x5); } -.bookingDetails { - max-width: 100%; - padding: 0 var(--Spacing-x2); -} - -.row { - display: flex; - flex-direction: column; - padding: var(--Spacing-x-one-and-half) 0; -} - -.row:last-child { - border-bottom: none; -} - -.rowTitle { - display: flex; - flex-direction: row; - gap: var(--Spacing-x1); -} - -.rowTitle svg { - width: 24px; - height: 24px; -} - -.rowContent { - padding-left: var(--Spacing-x4); -} - -.bookingInformation { - display: flex; - flex-direction: column-reverse; - align-items: center; - gap: var(--Spacing-x2); - background-color: var(--Scandic-Beige-10); - margin: 0 var(--Spacing-x2); - border: 1px solid var(--Base-Border-Subtle); - border-radius: var(--Corner-radius-Medium); -} - -.priceDetails { - display: flex; - flex-direction: column; - align-items: center; - gap: var(--Spacing-x1); - padding: var(--Spacing-x-one-and-half) 0; - width: calc(100% - var(--Spacing-x4)); - justify-content: center; - margin: 0 auto; -} - -.price { - align-items: center; - display: flex; - gap: var(--Spacing-x1); - justify-content: space-between; - width: 100%; -} - -.userDetails { - width: 100%; - border-bottom: 1px solid var(--Base-Border-Subtle); - margin-bottom: var(--Spacing-x1); - color: var(--Scandic-Brand-Burgundy); -} - .guestDetailsMobileWrapper { display: block; padding: 0 var(--Spacing-x2); @@ -205,17 +67,6 @@ padding: 0; } - .roomHeader { - justify-content: space-between; - align-items: center; - flex-direction: row; - padding: 0; - } - - .sidePeek { - display: block; - } - .booking { border-radius: var(--Corner-radius-Large); background-color: var(--Base-Background-Primary-Normal); @@ -227,56 +78,6 @@ width: var(--max-width-content); } - .packages { - top: 620px; - left: 25px; - } - - .imageContainer { - height: 640px; - } - - .image { - height: 100%; - border-radius: var(--Corner-radius-Medium); - } - - .bookingDetails { - padding: 0; - } - - .row { - border-bottom: 1px solid var(--Base-Border-Subtle); - flex-direction: row; - align-items: center; - justify-content: space-between; - } - - .rowTitle svg { - width: 20px; - height: 20px; - } - - .bookingInformation { - flex-direction: row; - justify-content: space-between; - align-items: flex-start; - padding: var(--Spacing-x-one-and-half); - margin: 0; - border-radius: 0; - border: none; - } - - .priceDetails { - margin: 0 0 0 auto; - width: auto; - align-items: flex-end; - } - - .price { - justify-content: flex-end; - } - .guestDetailsMobileWrapper { display: none; } diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/index.tsx b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/index.tsx deleted file mode 100644 index 5376ecf01..000000000 --- a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/index.tsx +++ /dev/null @@ -1,96 +0,0 @@ -"use client" -import { useIntl } from "react-intl" - -import { Typography } from "@scandic-hotels/design-system/Typography" - -import { useMyStayStore } from "@/stores/my-stay" - -import PriceDetails from "../PriceDetails" -import MultiRoom from "./MultiRoom" -import SingleRoom from "./SingleRoom" -import TotalPrice from "./TotalPrice" - -import styles from "./rooms.module.css" - -import type { SafeUser } from "@/types/user" - -interface RoomsProps { - user: SafeUser -} - -export default function Rooms({ user }: RoomsProps) { - const intl = useIntl() - 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 - } - - const isMultiRoom = rooms.length > 1 - - return ( -
- {isMultiRoom && ( - -

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

-
- )} -
- {!isMultiRoom ? ( - - ) : ( -
- {rooms.map((booking, index) => ( -
- -
- ))} -
- )} -
- {isMultiRoom && ( -
-
- -

- {intl.formatMessage({ - defaultMessage: "Booking total", - })} - {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} - {":"} -

-
- -
- - {allRoomsAreCancelled ? null : } -
- )} -
- ) -} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/rooms.module.css b/apps/scandic-web/components/HotelReservation/MyStay/Rooms/rooms.module.css deleted file mode 100644 index bd4bb71ad..000000000 --- a/apps/scandic-web/components/HotelReservation/MyStay/Rooms/rooms.module.css +++ /dev/null @@ -1,63 +0,0 @@ -.wrapper { - display: flex; - flex-direction: column; - gap: var(--Spacing-x3); -} - -.container { - display: flex; - flex-direction: column; - gap: var(--Spacing-x5); -} - -.roomsContainer { - display: grid; - gap: var(--Spacing-x3); - width: 100%; - grid-template-columns: 1fr; -} - -.roomWrapper { - width: 100%; - min-width: 0; -} - -.roomWrapper > * { - width: 100%; -} - -.title { - color: var(--Scandic-Brand-Burgundy); - padding: 0 var(--Spacing-x2); -} - -.totalContainer { - display: flex; - flex-direction: column; - gap: var(--Spacing-x1); - padding: 0 var(--Spacing-x2); -} - -.total { - display: flex; - justify-content: flex-end; - gap: var(--Spacing-x1); -} - -@media (min-width: 768px) { - .roomsContainer { - grid-template-columns: repeat(2, 1fr); - } - - .roomsContainer:has(> *:nth-child(3):last-child) { - grid-template-columns: repeat(3, 1fr); - } - - .title { - padding: 0; - } - - .totalContainer { - padding: 0; - } -} diff --git a/apps/scandic-web/components/HotelReservation/MyStay/utils/mapRoomDetails.ts b/apps/scandic-web/components/HotelReservation/MyStay/utils/mapRoomDetails.ts index a4a168062..7c5097a01 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/utils/mapRoomDetails.ts +++ b/apps/scandic-web/components/HotelReservation/MyStay/utils/mapRoomDetails.ts @@ -1,9 +1,8 @@ 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 { convertToChildType } from "../../utils/convertToChildType" +import { getPriceType } from "../../utils/getPriceType" import { formatChildBedPreferences } from "../utils" import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast" diff --git a/apps/scandic-web/components/HotelReservation/utils.tsx b/apps/scandic-web/components/HotelReservation/utils/index.tsx similarity index 100% rename from apps/scandic-web/components/HotelReservation/utils.tsx rename to apps/scandic-web/components/HotelReservation/utils/index.tsx diff --git a/apps/scandic-web/components/SidePeeks/BookedRoomSidePeek/index.tsx b/apps/scandic-web/components/SidePeeks/BookedRoomSidePeek/index.tsx index b6a07c169..674aa2f45 100644 --- a/apps/scandic-web/components/SidePeeks/BookedRoomSidePeek/index.tsx +++ b/apps/scandic-web/components/SidePeeks/BookedRoomSidePeek/index.tsx @@ -32,7 +32,7 @@ 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< +type PartialHotelRoom = Pick< HotelRoom, "descriptions" | "images" | "name" | "roomFacilities" | "roomTypes" > diff --git a/apps/scandic-web/components/TempDesignSystem/AncillaryCard/index.tsx b/apps/scandic-web/components/TempDesignSystem/AncillaryCard/index.tsx index c6e4f28c9..e54eb0716 100644 --- a/apps/scandic-web/components/TempDesignSystem/AncillaryCard/index.tsx +++ b/apps/scandic-web/components/TempDesignSystem/AncillaryCard/index.tsx @@ -18,13 +18,15 @@ export function AncillaryCard({ ancillary }: AncillaryCardProps) { return (
- {ancillary.title} + {ancillary.imageUrl ? ( + {ancillary.title} + ) : null}
diff --git a/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/SidePeekSEO.tsx b/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/SidePeekSEO.tsx index 1fd88c067..5c64ade27 100644 --- a/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/SidePeekSEO.tsx +++ b/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/SidePeekSEO.tsx @@ -1,4 +1,5 @@ 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. diff --git a/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/index.tsx b/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/index.tsx index 3521fabe9..e827e4b88 100644 --- a/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/index.tsx +++ b/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/index.tsx @@ -1,4 +1,5 @@ "use client" + import { useEffect } from "react" import { Dialog, Modal, ModalOverlay } from "react-aria-components" import { useIntl } from "react-intl" @@ -54,10 +55,12 @@ export default function SidePeekSelfControlled({
+ {children} ) } + function KeepBodyVisible() { const toggle = useSetOverflowVisibleOnRA() useEffect(() => { diff --git a/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/sidePeekSelfControlled.module.css b/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/sidePeekSelfControlled.module.css index e40066fc9..e37dd7b9b 100644 --- a/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/sidePeekSelfControlled.module.css +++ b/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/sidePeekSelfControlled.module.css @@ -38,6 +38,7 @@ height: 100vh; background-color: var(--Base-Background-Primary-Normal); z-index: var(--sidepeek-z-index); + outline: none; } .modal[data-entering] { diff --git a/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/types.ts b/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/types.ts index b724b305f..e37554aff 100644 --- a/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/types.ts +++ b/apps/scandic-web/components/TempDesignSystem/SidePeekSelfControlled/types.ts @@ -2,6 +2,7 @@ export type SidePeekProps = { activeContent: string | null onClose: (isOpen: boolean) => void } + export type SidePeekContentProps = { title?: string contentKey: string diff --git a/apps/scandic-web/providers/BookingConfirmationProvider.tsx b/apps/scandic-web/providers/BookingConfirmationProvider.tsx index 0494ac1c1..1532d459c 100644 --- a/apps/scandic-web/providers/BookingConfirmationProvider.tsx +++ b/apps/scandic-web/providers/BookingConfirmationProvider.tsx @@ -73,8 +73,8 @@ export default function BookingConfirmationProvider({ currencyCode, fromDate, toDate, - rooms, roomCategories, + rooms, vat, isVatCurrency, formattedTotalCost, diff --git a/apps/scandic-web/server/routers/booking/utils.ts b/apps/scandic-web/server/routers/booking/utils.ts index 0941bc76b..2d9e581a0 100644 --- a/apps/scandic-web/server/routers/booking/utils.ts +++ b/apps/scandic-web/server/routers/booking/utils.ts @@ -10,13 +10,13 @@ import type { BookingConfirmation } from "@/types/trpc/routers/booking/confirmat import type { Lang } from "@/constants/languages" export function getBookedHotelRoom( - rooms: Room[] | undefined, + rooms: Room[], roomTypeCode: BookingConfirmation["booking"]["roomTypeCode"] ) { - if (!rooms?.length || !roomTypeCode) { + if (!rooms.length || !roomTypeCode) { return null } - const room = rooms?.find((r) => { + const room = rooms.find((r) => { return r.roomTypes.find((roomType) => roomType.code === roomTypeCode) }) if (!room) { diff --git a/apps/scandic-web/stores/my-stay/index.ts b/apps/scandic-web/stores/my-stay/index.ts index e2af9e0fd..fd6544ebc 100644 --- a/apps/scandic-web/stores/my-stay/index.ts +++ b/apps/scandic-web/stores/my-stay/index.ts @@ -74,7 +74,6 @@ export function createMyStayStore({ savedCreditCards, totalPoints, totalPrice, - roomCategories, actions: { closeManageStay() { diff --git a/apps/scandic-web/types/components/hotelReservation/bookingConfirmation/rooms/linkedReservation.ts b/apps/scandic-web/types/components/hotelReservation/bookingConfirmation/rooms/linkedReservation.ts index a03adeb20..37aff477a 100644 --- a/apps/scandic-web/types/components/hotelReservation/bookingConfirmation/rooms/linkedReservation.ts +++ b/apps/scandic-web/types/components/hotelReservation/bookingConfirmation/rooms/linkedReservation.ts @@ -3,6 +3,7 @@ export interface LinkedReservationProps { checkOutTime: string confirmationNumber: string roomIndex: number + roomNumber: number } export interface RetryProps { diff --git a/apps/scandic-web/types/components/myPages/myStay/ancillaries.ts b/apps/scandic-web/types/components/myPages/myStay/ancillaries.ts index 6e372a5bd..81eb1dfe2 100644 --- a/apps/scandic-web/types/components/myPages/myStay/ancillaries.ts +++ b/apps/scandic-web/types/components/myPages/myStay/ancillaries.ts @@ -13,7 +13,7 @@ export type SelectedAncillary = Ancillary["ancillaryContent"][number] export type Packages = z.output export interface AncillariesProps extends Pick { - ancillaries: Ancillaries | null + ancillariesPromise: Promise packages: Packages | null user: User | null savedCreditCards: CreditCard[] | null diff --git a/apps/scandic-web/types/components/sidePeeks/bookedRoomSidePeek.ts b/apps/scandic-web/types/components/sidePeeks/bookedRoomSidePeek.ts index 69e0d785b..dbcb348ec 100644 --- a/apps/scandic-web/types/components/sidePeeks/bookedRoomSidePeek.ts +++ b/apps/scandic-web/types/components/sidePeeks/bookedRoomSidePeek.ts @@ -1,13 +1,11 @@ import type { Room } from "@/types/hotel" import type { SafeUser } from "@/types/user" -import type { SidePeekEnum } from "../hotelReservation/sidePeek" export type BookedRoomSidePeekProps = { - room: Room - activeSidePeek: SidePeekEnum | null close: () => void - user: SafeUser confirmationNumber: string + room: Room + user: SafeUser } export type RoomDetailsProps = { diff --git a/apps/scandic-web/types/providers/booking-confirmation.ts b/apps/scandic-web/types/providers/booking-confirmation.ts index 0cf4df972..1cfc7ee96 100644 --- a/apps/scandic-web/types/providers/booking-confirmation.ts +++ b/apps/scandic-web/types/providers/booking-confirmation.ts @@ -7,8 +7,8 @@ export interface BookingConfirmationProviderProps bookingCode: string | null currencyCode: CurrencyEnum fromDate: Date - rooms: (Room | null)[] roomCategories: RoomCategories + rooms: (Room | null)[] toDate: Date vat: number } diff --git a/apps/scandic-web/types/stores/my-stay.ts b/apps/scandic-web/types/stores/my-stay.ts index c9898806c..a9492ec2b 100644 --- a/apps/scandic-web/types/stores/my-stay.ts +++ b/apps/scandic-web/types/stores/my-stay.ts @@ -76,7 +76,6 @@ export interface MyStayState { savedCreditCards: CreditCard[] | null totalPoints: number totalPrice: string - roomCategories: RoomCategories } export interface InitialState