From 984805ea8dd196590d6c596dfb1779624415569f Mon Sep 17 00:00:00 2001 From: Bianca Widstam Date: Tue, 3 Jun 2025 12:51:33 +0000 Subject: [PATCH] Merged in feat/SW-1936-ui-room-card (pull request #2268) feat(SW-1936): update room card ui * feat(SW-1936): update room card ui Approved-by: Linus Flood --- .../RoomListItem/Details/RoomSize.tsx | 56 +++++++++------- .../RoomListItem/Details/ToggleSidePeek.tsx | 6 +- .../RoomListItem/Details/details.module.css | 23 ++----- .../RoomsList/RoomListItem/Details/index.tsx | 65 ++++++++----------- .../breakfastMessage.module.css | 7 ++ .../Rates/BreakfastMessage/index.tsx | 16 +++-- .../RoomListItem/RoomImage/image.module.css | 16 +++++ .../RoomListItem/RoomImage/index.tsx | 40 ++++++++---- .../ImageGallery/imageGallery.module.css | 10 +++ .../components/ImageGallery/index.tsx | 9 ++- .../types/components/imageGallery.ts | 1 + 11 files changed, 154 insertions(+), 95 deletions(-) create mode 100644 apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Rates/BreakfastMessage/breakfastMessage.module.css diff --git a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Details/RoomSize.tsx b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Details/RoomSize.tsx index c25c95b62..351469f11 100644 --- a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Details/RoomSize.tsx +++ b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Details/RoomSize.tsx @@ -1,7 +1,7 @@ "use client" import { useIntl } from "react-intl" -import Caption from "@/components/TempDesignSystem/Text/Caption" +import { Typography } from "@scandic-hotels/design-system/Typography" import type { RoomSizeProps } from "@/types/components/hotelReservation/selectRate/roomListItem" @@ -15,34 +15,42 @@ export default function RoomSize({ roomSize }: RoomSizeProps) { if (roomSize.min === roomSize.max) { return ( <> - {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} - ∙ - - {intl.formatMessage( - { - defaultMessage: "{roomSize} m²", - }, - { roomSize: roomSize.min } - )} - + + {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} +

+
+ +

+ {intl.formatMessage( + { + defaultMessage: "{roomSize} m²", + }, + { roomSize: roomSize.min } + )} +

+
) } return ( <> - {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} - ∙ - - {intl.formatMessage( - { - defaultMessage: "{roomSizeMin} - {roomSizeMax} m²", - }, - { - roomSizeMin: roomSize.min, - roomSizeMax: roomSize.max, - } - )} - + + {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */} +

+
+ +

+ {intl.formatMessage( + { + defaultMessage: "{roomSizeMin} - {roomSizeMax} m²", + }, + { + roomSizeMin: roomSize.min, + roomSizeMax: roomSize.max, + } + )} +

+
) } diff --git a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Details/ToggleSidePeek.tsx b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Details/ToggleSidePeek.tsx index 5ca3b0c52..c72977480 100644 --- a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Details/ToggleSidePeek.tsx +++ b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Details/ToggleSidePeek.tsx @@ -7,6 +7,8 @@ import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import useSidePeekStore from "@/stores/sidepeek" +import styles from "./details.module.css" + import { SidePeekEnum } from "@/types/components/hotelReservation/sidePeek" import type { ToggleSidePeekProps } from "@/types/components/hotelReservation/toggleSidePeekProps" @@ -30,8 +32,10 @@ export default function ToggleSidePeek({ variant="Text" wrapping typography="Body/Supporting text (caption)/smBold" + color="Inverted" + className={styles.sidePeekButton} > - {intl.formatMessage({ defaultMessage: "Room details" })} + {intl.formatMessage({ defaultMessage: "View room details" })} ) diff --git a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Details/details.module.css b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Details/details.module.css index b6d0d0080..93429b6d0 100644 --- a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Details/details.module.css +++ b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Details/details.module.css @@ -1,27 +1,18 @@ .specification { align-items: center; display: flex; - flex-direction: row; - gap: var(--Spacing-x1); - justify-content: space-between; -} - -.toggleSidePeek { - margin-left: auto; -} - -.specification .toggleSidePeek button { - padding: 0; - text-align: start; + justify-content: center; + gap: var(--Space-x1); } .roomDetails { display: flex; flex-direction: column; - gap: var(--Spacing-x1); - padding-bottom: var(--Spacing-x-half); + text-align: center; + gap: var(--Space-x1); + padding-bottom: var(--Space-x05); } -.name { - display: inline-block; +.sidePeekButton { + width: 100%; } diff --git a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Details/index.tsx b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Details/index.tsx index 8aa62180b..b96454a77 100644 --- a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Details/index.tsx +++ b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Details/index.tsx @@ -1,22 +1,17 @@ "use client" import { useIntl } from "react-intl" +import { Typography } from "@scandic-hotels/design-system/Typography" + import { useRatesStore } from "@/stores/select-rate" -import Caption from "@/components/TempDesignSystem/Text/Caption" -import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" - import RoomSize from "./RoomSize" -import ToggleSidePeek from "./ToggleSidePeek" import styles from "./details.module.css" export default function Details({ roomTypeCode }: { roomTypeCode: string }) { const intl = useIntl() - const { hotelId, roomCategories } = useRatesStore((state) => ({ - hotelId: state.booking.hotelId, - roomCategories: state.roomCategories, - })) + const roomCategories = useRatesStore((state) => state.roomCategories) const selectedRoom = roomCategories.find((roomCategory) => roomCategory.roomTypes.find((roomType) => roomType.code === roomTypeCode) @@ -28,40 +23,34 @@ export default function Details({ roomTypeCode }: { roomTypeCode: string }) { <>
{occupancy && ( - - {occupancy.max === occupancy.min - ? intl.formatMessage( - { - defaultMessage: - "{guests, plural, one {# guest} other {# guests}}", - }, - { guests: occupancy.max } - ) - : intl.formatMessage( - { - defaultMessage: "{min}-{max} guests", - }, - { - min: occupancy.min, - max: occupancy.max, - } - )} - + +

+ {occupancy.max === occupancy.min + ? intl.formatMessage( + { + defaultMessage: + "{guests, plural, one {# guest} other {# guests}}", + }, + { guests: occupancy.max } + ) + : intl.formatMessage( + { + defaultMessage: "{min}-{max} guests", + }, + { + min: occupancy.min, + max: occupancy.max, + } + )} +

+
)} -
- {roomTypeCode && ( - - )} -
- - {name} - - {/* Out of scope for now - {descriptions?.short} - */} + +

{name}

+
) diff --git a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Rates/BreakfastMessage/breakfastMessage.module.css b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Rates/BreakfastMessage/breakfastMessage.module.css new file mode 100644 index 000000000..71316289a --- /dev/null +++ b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Rates/BreakfastMessage/breakfastMessage.module.css @@ -0,0 +1,7 @@ +.message { + display: flex; + align-items: center; + text-align: center; + gap: var(--Space-x1); + white-space: nowrap; +} diff --git a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Rates/BreakfastMessage/index.tsx b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Rates/BreakfastMessage/index.tsx index bd0e2825b..f96ff1e99 100644 --- a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Rates/BreakfastMessage/index.tsx +++ b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/Rates/BreakfastMessage/index.tsx @@ -2,14 +2,18 @@ import { useSession } from "next-auth/react" import { useIntl } from "react-intl" +import { Typography } from "@scandic-hotels/design-system/Typography" + import { useRatesStore } from "@/stores/select-rate" -import Caption from "@/components/TempDesignSystem/Text/Caption" +import Divider from "@/components/TempDesignSystem/Divider" import { useRoomContext } from "@/contexts/SelectRate/Room" import { isValidClientSession } from "@/utils/clientSession" import { getBreakfastMessage } from "./getBreakfastMessage" +import styles from "./breakfastMessage.module.css" + import { BookingCodeFilterEnum } from "@/types/enums/bookingCodeFilter" export default function BreakfastMessage({ @@ -61,8 +65,12 @@ export default function BreakfastMessage({ } return ( - - {breakfastMessage} - +
+ + +

{breakfastMessage}

+
+ +
) } diff --git a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/RoomImage/image.module.css b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/RoomImage/image.module.css index ffea6a031..7ee68ca47 100644 --- a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/RoomImage/image.module.css +++ b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/RoomImage/image.module.css @@ -30,3 +30,19 @@ div[data-multiroom="true"] .imageContainer { max-width: 100%; object-fit: cover; } + +.toggleSidePeek { + display: flex; + align-items: center; + justify-content: center; + position: absolute; + bottom: 0; + color: var(--Component-Button-Brand-Secondary-On-fill-Inverted); + background-color: var(--Surface-Brand-Primary-1-OnSurface-Default); + height: 40px; + width: 100%; +} + +.inventory { + color: var(--Text-Interactive-Default); +} diff --git a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/RoomImage/index.tsx b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/RoomImage/index.tsx index c9bd471d3..d1906a12b 100644 --- a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/RoomImage/index.tsx +++ b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsList/RoomListItem/RoomImage/index.tsx @@ -1,14 +1,17 @@ "use client" import { useIntl } from "react-intl" +import { Typography } from "@scandic-hotels/design-system/Typography" + import { useRatesStore } from "@/stores/select-rate" import { IconForFeatureCode } from "@/components/HotelReservation/utils" import ImageGallery from "@/components/ImageGallery" -import Footnote from "@/components/TempDesignSystem/Text/Footnote" import { useRoomContext } from "@/contexts/SelectRate/Room" import { mapApiImagesToGalleryImages } from "@/utils/imageGallery" +import ToggleSidePeek from "../Details/ToggleSidePeek" + import styles from "./image.module.css" import type { RoomListItemImageProps } from "@/types/components/hotelReservation/selectRate/roomListItem" @@ -21,7 +24,10 @@ export default function RoomImage({ }: RoomListItemImageProps) { const intl = useIntl() const { selectedPackages } = useRoomContext() - const roomCategories = useRatesStore((state) => state.roomCategories) + const { roomCategories, hotelId } = useRatesStore((state) => ({ + roomCategories: state.roomCategories, + hotelId: state.booking.hotelId, + })) const showLowInventory = roomsLeft > 0 && roomsLeft < 5 @@ -36,14 +42,16 @@ export default function RoomImage({
{showLowInventory ? ( - - {intl.formatMessage( - { - defaultMessage: "{amount, number} left", - }, - { amount: roomsLeft } - )} - + +

+ {intl.formatMessage( + { + defaultMessage: "{amount, number} left", + }, + { amount: roomsLeft } + )} +

+
) : null} {roomPackages @@ -56,7 +64,17 @@ export default function RoomImage({ ))}
- + +
+ {roomTypeCode && ( + + )} +
) } diff --git a/apps/scandic-web/components/ImageGallery/imageGallery.module.css b/apps/scandic-web/components/ImageGallery/imageGallery.module.css index bf81d022c..ee8fa6013 100644 --- a/apps/scandic-web/components/ImageGallery/imageGallery.module.css +++ b/apps/scandic-web/components/ImageGallery/imageGallery.module.css @@ -19,6 +19,16 @@ color: var(--Text-Inverted); } +.imageCountBottom { + bottom: var(--Space-x2); + top: auto; +} + +.imageCountTop { + top: var(--Space-x2); + bottom: auto; +} + .triggerArea { background-color: transparent; border-width: 0; diff --git a/apps/scandic-web/components/ImageGallery/index.tsx b/apps/scandic-web/components/ImageGallery/index.tsx index 3643abdf6..94eb74ad9 100644 --- a/apps/scandic-web/components/ImageGallery/index.tsx +++ b/apps/scandic-web/components/ImageGallery/index.tsx @@ -21,6 +21,7 @@ function ImageGallery({ height = 280, sizes, hideLabel, + imageCountPosition = "bottom", }: ImageGalleryProps) { const intl = useIntl() const [isOpen, setIsOpen] = useState(false) @@ -44,7 +45,13 @@ function ImageGallery({ {...imageProps} /> - + {images.length} diff --git a/apps/scandic-web/types/components/imageGallery.ts b/apps/scandic-web/types/components/imageGallery.ts index fce3b9e4c..2769ebae5 100644 --- a/apps/scandic-web/types/components/imageGallery.ts +++ b/apps/scandic-web/types/components/imageGallery.ts @@ -13,4 +13,5 @@ export type ImageGalleryProps = { height?: number sizes?: string hideLabel?: boolean + imageCountPosition?: "top" | "bottom" }