feat(SW-203): added show more functionality to rooms inside the hotel page
This commit is contained in:
@@ -14,6 +14,7 @@ import { RoomCardProps } from "@/types/components/hotelPage/roomCard"
|
|||||||
|
|
||||||
export function RoomCard({
|
export function RoomCard({
|
||||||
badgeTextTransKey,
|
badgeTextTransKey,
|
||||||
|
hidden,
|
||||||
id,
|
id,
|
||||||
images,
|
images,
|
||||||
subtitle,
|
subtitle,
|
||||||
@@ -33,7 +34,7 @@ export function RoomCard({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<article className={styles.roomCard}>
|
<article className={`${styles.roomCard} ${hidden ? styles.hidden : ""}`}>
|
||||||
<button className={styles.imageWrapper} onClick={handleImageClick}>
|
<button className={styles.imageWrapper} onClick={handleImageClick}>
|
||||||
{badgeTextTransKey && (
|
{badgeTextTransKey && (
|
||||||
<span className={styles.badge}>
|
<span className={styles.badge}>
|
||||||
|
|||||||
@@ -5,6 +5,10 @@
|
|||||||
display: grid;
|
display: grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
/*TODO: Build Chip/Badge component. */
|
/*TODO: Build Chip/Badge component. */
|
||||||
.badge {
|
.badge {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
@@ -1,13 +1,24 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { useRef, useState } from "react"
|
||||||
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
|
import { ChevronDownIcon } from "@/components/Icons"
|
||||||
import SectionContainer from "@/components/Section/Container"
|
import SectionContainer from "@/components/Section/Container"
|
||||||
import SectionHeader from "@/components/Section/Header"
|
import SectionHeader from "@/components/Section/Header"
|
||||||
|
import Button from "@/components/TempDesignSystem/Button"
|
||||||
import Grids from "@/components/TempDesignSystem/Grids"
|
import Grids from "@/components/TempDesignSystem/Grids"
|
||||||
import { getIntl } from "@/i18n"
|
|
||||||
|
|
||||||
import { RoomCard } from "./RoomCard"
|
import { RoomCard } from "./RoomCard"
|
||||||
import { RoomsProps } from "./types"
|
import { RoomsProps } from "./types"
|
||||||
|
|
||||||
export async function Rooms({ rooms }: RoomsProps) {
|
import styles from "./rooms.module.css"
|
||||||
const { formatMessage } = await getIntl()
|
|
||||||
|
export function Rooms({ rooms }: RoomsProps) {
|
||||||
|
const { formatMessage } = useIntl()
|
||||||
|
const [allRoomsVisible, setAllRoomsVisible] = useState(false)
|
||||||
|
const scrollRef = useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
const mappedRooms = rooms
|
const mappedRooms = rooms
|
||||||
.map((room) => {
|
.map((room) => {
|
||||||
const size = `${room.attributes.roomSize.min} - ${room.attributes.roomSize.max} m²`
|
const size = `${room.attributes.roomSize.min} - ${room.attributes.roomSize.max} m²`
|
||||||
@@ -28,26 +39,48 @@ export async function Rooms({ rooms }: RoomsProps) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.sort((a, b) => a.sortOrder - b.sortOrder)
|
.sort((a, b) => a.sortOrder - b.sortOrder)
|
||||||
.slice(0, 3) //TODO: Remove this and render all rooms once we've implemented "show more" logic in SW-203.
|
|
||||||
|
function handleToggleShowMore() {
|
||||||
|
setAllRoomsVisible(!allRoomsVisible)
|
||||||
|
if (scrollRef.current) {
|
||||||
|
scrollRef.current.scrollIntoView({ behavior: "smooth" })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SectionContainer id="rooms-section">
|
<SectionContainer id="rooms-section">
|
||||||
|
<div ref={scrollRef}></div>
|
||||||
<SectionHeader
|
<SectionHeader
|
||||||
textTransform="uppercase"
|
textTransform="uppercase"
|
||||||
title={formatMessage({ id: "Rooms" })}
|
title={formatMessage({ id: "Rooms" })}
|
||||||
subtitle={null}
|
subtitle={null}
|
||||||
/>
|
/>
|
||||||
<Grids.Stackable>
|
<Grids.Stackable>
|
||||||
{mappedRooms.map(({ id, images, title, subtitle, popularChoice }) => (
|
{mappedRooms.map(
|
||||||
<RoomCard
|
({ id, images, title, subtitle, popularChoice }, index) => (
|
||||||
key={id}
|
<RoomCard
|
||||||
id={id}
|
key={id}
|
||||||
images={images}
|
id={id}
|
||||||
title={title}
|
hidden={!allRoomsVisible && index > 2}
|
||||||
subtitle={subtitle}
|
images={images}
|
||||||
badgeTextTransKey={popularChoice ? "Popular choice" : null}
|
title={title}
|
||||||
/>
|
subtitle={subtitle}
|
||||||
))}
|
badgeTextTransKey={popularChoice ? "Popular choice" : null}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
)}
|
||||||
</Grids.Stackable>
|
</Grids.Stackable>
|
||||||
|
|
||||||
|
<div className={styles.ctaContainer}>
|
||||||
|
<Button
|
||||||
|
onClick={handleToggleShowMore}
|
||||||
|
variant="icon"
|
||||||
|
className={`${styles.showMoreButton} ${allRoomsVisible ? styles.showLess : ""}`}
|
||||||
|
>
|
||||||
|
<ChevronDownIcon className={styles.chevron} />
|
||||||
|
{formatMessage({ id: allRoomsVisible ? "Show less" : "Show more" })}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</SectionContainer>
|
</SectionContainer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
8
components/ContentType/HotelPage/Rooms/rooms.module.css
Normal file
8
components/ContentType/HotelPage/Rooms/rooms.module.css
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
.ctaContainer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.showMoreButton.showLess .chevron {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
@@ -109,6 +109,7 @@
|
|||||||
"Select country of residence": "Select country of residence",
|
"Select country of residence": "Select country of residence",
|
||||||
"Select date of birth": "Select date of birth",
|
"Select date of birth": "Select date of birth",
|
||||||
"Select language": "Select language",
|
"Select language": "Select language",
|
||||||
|
"Show less": "Show less",
|
||||||
"Show more": "Show more",
|
"Show more": "Show more",
|
||||||
"Show all amenities": "Show all amenities",
|
"Show all amenities": "Show all amenities",
|
||||||
"Skip to main content": "Skip to main content",
|
"Skip to main content": "Skip to main content",
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { RoomData } from "@/types/hotel"
|
|||||||
export interface RoomCardProps {
|
export interface RoomCardProps {
|
||||||
id: string
|
id: string
|
||||||
images: RoomData["attributes"]["content"]["images"]
|
images: RoomData["attributes"]["content"]["images"]
|
||||||
|
hidden?: boolean
|
||||||
title: string
|
title: string
|
||||||
subtitle: string
|
subtitle: string
|
||||||
badgeTextTransKey: string | null
|
badgeTextTransKey: string | null
|
||||||
|
|||||||
Reference in New Issue
Block a user