diff --git a/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/Room/RoomTypes/index.tsx b/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/Room/RoomTypes/index.tsx new file mode 100644 index 000000000..9450e3889 --- /dev/null +++ b/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/Room/RoomTypes/index.tsx @@ -0,0 +1,62 @@ +import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" +import { Typography } from "@scandic-hotels/design-system/Typography" + +import { getBedIconName } from "@/components/SidePeeks/RoomSidePeek/bedIcon" +import { getIntl } from "@/i18n" + +import { getBedDescriptionText } from "../utils" +import getFilteredRoomTypes from "./utils" + +import styles from "./roomTypes.module.css" + +import type { Room } from "@/types/hotel" + +interface RoomFacilitiesProps { + roomTypes: Room["roomTypes"] +} + +export default async function RoomTypes({ roomTypes }: RoomFacilitiesProps) { + const intl = await getIntl() + + const filteredRoomTypes = getFilteredRoomTypes(roomTypes) + + return ( + <> +
+ +

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

+
+ +

+ {intl.formatMessage({ + defaultMessage: "Based on availability", + })} +

+
+
+ + + ) +} diff --git a/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/Room/RoomTypes/roomTypes.module.css b/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/Room/RoomTypes/roomTypes.module.css new file mode 100644 index 000000000..1d0266830 --- /dev/null +++ b/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/Room/RoomTypes/roomTypes.module.css @@ -0,0 +1,20 @@ +.intro { + display: grid; + gap: var(--Space-x05); +} + +.list { + list-style: none; + display: grid; + gap: var(--Space-x05); +} + +.listItem { + display: flex; + gap: var(--Space-x1); + color: var(--Text-Secondary); +} + +.icon { + flex-shrink: 0; +} diff --git a/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/Room/RoomTypes/utils.ts b/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/Room/RoomTypes/utils.ts new file mode 100644 index 000000000..6c26d7078 --- /dev/null +++ b/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/Room/RoomTypes/utils.ts @@ -0,0 +1,49 @@ +import type { Room } from "@/types/hotel" + +type RoomType = Room["roomTypes"][number] + +// This util function filters room types to show only unique bed configurations +export default function getFilteredRoomTypes(roomTypes: RoomType[]) { + const customOccupancyRoomTypes = roomTypes.filter( + (roomType) => roomType.mainBed.type === "CustomOccupancy" + ) + const otherRoomTypes = roomTypes.filter( + (roomType) => roomType.mainBed.type !== "CustomOccupancy" + ) + + const filteredOtherRoomTypes = filterDuplicatesByDescription(otherRoomTypes) + + // If there are no CustomOccupancy room types, return just the filtered other types + if (customOccupancyRoomTypes.length === 0) { + return filteredOtherRoomTypes + } + + // If there is only one CustomOccupancy room type, no need to find the best one + if (customOccupancyRoomTypes.length === 1) { + return [...filteredOtherRoomTypes, customOccupancyRoomTypes[0]] + } + + // Find the CustomOccupancy room type with highest occupancy + const bestCustomOccupancyRoomType = customOccupancyRoomTypes.reduce( + (best, current) => { + return current.occupancy.total > best.occupancy.total ? current : best + }, + customOccupancyRoomTypes[0] + ) + + return [...filteredOtherRoomTypes, bestCustomOccupancyRoomType] +} + +// Helper function to just filter duplicates by description +function filterDuplicatesByDescription(roomTypes: RoomType[]): RoomType[] { + const uniqueRoomsByDescription: Record = {} + + roomTypes.forEach((roomType) => { + const description = roomType.mainBed.description + if (!uniqueRoomsByDescription[description]) { + uniqueRoomsByDescription[description] = roomType + } + }) + + return Object.values(uniqueRoomsByDescription) +} diff --git a/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/Room/index.tsx b/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/Room/index.tsx index 92d3f33e1..2905aa19c 100644 --- a/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/Room/index.tsx +++ b/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/Room/index.tsx @@ -1,13 +1,11 @@ import Link from "next/link" -import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { Typography } from "@scandic-hotels/design-system/Typography" import { selectRateWithParams } from "@/constants/routes/hotelReservation" import { dt } from "@/lib/dt" import ImageGallery from "@/components/ImageGallery" -import { getBedIconName } from "@/components/SidePeeks/RoomSidePeek/bedIcon" import Button from "@/components/TempDesignSystem/Button" import SidePeek from "@/components/TempDesignSystem/SidePeek" import { getIntl } from "@/i18n" @@ -16,7 +14,7 @@ import { mapApiImagesToGalleryImages } from "@/utils/imageGallery" import { getRoomNameAsParam } from "../../utils" import RoomFacilities from "./RoomFacilities" -import { getBedDescriptionText } from "./utils" +import RoomTypes from "./RoomTypes" import styles from "./room.module.css" @@ -28,7 +26,15 @@ export default async function RoomSidePeek({ }: RoomSidePeekProps) { const lang = await getLang() const intl = await getIntl() - const { roomSize, totalOccupancy, descriptions, images } = room + const { + roomSize, + roomTypes, + roomFacilities, + name, + totalOccupancy, + descriptions, + images, + } = room const roomDescription = descriptions.medium const galleryImages = mapApiImagesToGalleryImages(images) @@ -36,18 +42,13 @@ export default async function RoomSidePeek({ const fromdate = dt().format("YYYY-MM-DD") const todate = dt().add(1, "day").format("YYYY-MM-DD") const selectRateURL = selectRateWithParams(lang, hotelId, fromdate, todate) + return ( - +
- -

+ +

{intl.formatMessage( { defaultMessage: @@ -83,7 +84,7 @@ export default async function RoomSidePeek({

@@ -94,48 +95,11 @@ export default async function RoomSidePeek({
- +
-
- -

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

-
- -

- {intl.formatMessage({ - defaultMessage: "Based on availability", - })} -

-
-
-
    - {room.roomTypes.map((roomType) => { - const iconName = getBedIconName(roomType.mainBed.type) - const descriptionText = getBedDescriptionText( - intl, - roomType.mainBed - ) - - return ( -
  • - - - {descriptionText} - -
  • - ) - })} -
+
diff --git a/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/Room/room.module.css b/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/Room/room.module.css index 5dd1a12d3..c0bb59213 100644 --- a/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/Room/room.module.css +++ b/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/Room/room.module.css @@ -12,39 +12,16 @@ gap: var(--Spacing-x-one-and-half); } -.innerContent .guests { +.guests { color: var(--Text-Accent-Secondary); } -.bedOptions { - gap: var(--Spacing-x-half); -} - .imageContainer { position: relative; border-radius: var(--Corner-radius-md); overflow: hidden; } -.bedOptions { - display: flex; - flex-direction: column; -} - -.listItem { - display: grid; - grid-auto-flow: column; - gap: var(--Spacing-x1); - margin-bottom: var(--Spacing-x-half); - align-items: self-start; - justify-content: flex-start; - color: var(--Text-Secondary); -} - -.icon { - flex-shrink: 0; -} - .buttonContainer { background-color: var(--Base-Background-Primary-Normal); border-top: 1px solid var(--Base-Border-Subtle);