feat(SW-713): add rooms sidepeek on hotelpage

This commit is contained in:
Fredrik Thorsson
2024-10-30 09:56:45 +01:00
parent cddbbabe93
commit ddc190e0c8
12 changed files with 35 additions and 85 deletions

View File

@@ -2,9 +2,9 @@
import { useIntl } from "react-intl" import { useIntl } from "react-intl"
import { ChevronRightIcon, ImageIcon } from "@/components/Icons" import { ImageIcon } from "@/components/Icons"
import Image from "@/components/Image" import Image from "@/components/Image"
import Button from "@/components/TempDesignSystem/Button" import RoomSidePeek from "@/components/SidePeeks/RoomSidePeek"
import Body from "@/components/TempDesignSystem/Text/Body" import Body from "@/components/TempDesignSystem/Text/Body"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
@@ -12,26 +12,28 @@ import styles from "./roomCard.module.css"
import type { RoomCardProps } from "@/types/components/hotelPage/room" import type { RoomCardProps } from "@/types/components/hotelPage/room"
export function RoomCard({ export function RoomCard({ room }: RoomCardProps) {
badgeTextTransKey, const { images, name, roomSize, occupancy, id } = room
id,
images,
subtitle,
title,
}: RoomCardProps) {
const intl = useIntl() const intl = useIntl()
const mainImage = images[0] const mainImage = images[0]
const size =
roomSize?.min === roomSize?.max
? `${roomSize.min}`
: `${roomSize.min} - ${roomSize.max}`
const personLabel = intl.formatMessage(
{ id: "hotelPages.rooms.roomCard.persons" },
{ totalOccupancy: occupancy.total }
)
const subtitle = `${size} (${personLabel})`
function handleImageClick() { function handleImageClick() {
// TODO: Implement opening of a model with carousel // TODO: Implement opening of a model with carousel
console.log("Image clicked: ", id) console.log("Image clicked: ", id)
} }
function handleRoomCtaClick() {
// TODO: Implement opening side-peek component with room details
console.log("Room CTA clicked: ", id)
}
return ( return (
<article className={styles.roomCard}> <article className={styles.roomCard}>
<button className={styles.imageWrapper} onClick={handleImageClick}> <button className={styles.imageWrapper} onClick={handleImageClick}>
@@ -64,19 +66,11 @@ export function RoomCard({
color="black" color="black"
className={styles.title} className={styles.title}
> >
{title} {name}
</Subtitle> </Subtitle>
<Body color="grey">{subtitle}</Body> <Body color="grey">{subtitle}</Body>
</div> </div>
<Button <RoomSidePeek selectedRoom={room} buttonSize="medium" />
theme="base"
variant="icon"
intent="text"
onClick={handleRoomCtaClick}
>
{intl.formatMessage({ id: "See room details" })}
<ChevronRightIcon />
</Button>
</div> </div>
</article> </article>
) )

View File

@@ -22,27 +22,6 @@ export function Rooms({ rooms }: RoomsProps) {
const scrollRef = useRef<HTMLDivElement>(null) const scrollRef = useRef<HTMLDivElement>(null)
const mappedRooms = rooms
.map((room) => {
const size = `${room.roomSize.min} - ${room.roomSize.max}`
const personLabel =
room.occupancy.total === 1
? intl.formatMessage({ id: "hotelPages.rooms.roomCard.person" })
: intl.formatMessage({ id: "hotelPages.rooms.roomCard.persons" })
const subtitle = `${size} (${room.occupancy.total} ${personLabel})`
return {
id: room.id,
images: room.images,
title: room.name,
subtitle: subtitle,
sortOrder: room.sortOrder,
popularChoice: null,
}
})
.sort((a, b) => a.sortOrder - b.sortOrder)
function handleShowMore() { function handleShowMore() {
if (scrollRef.current && allRoomsVisible) { if (scrollRef.current && allRoomsVisible) {
scrollRef.current.scrollIntoView({ behavior: "smooth" }) scrollRef.current.scrollIntoView({ behavior: "smooth" })
@@ -64,15 +43,9 @@ export function Rooms({ rooms }: RoomsProps) {
<Grids.Stackable <Grids.Stackable
className={`${styles.grid} ${allRoomsVisible ? styles.allVisible : ""}`} className={`${styles.grid} ${allRoomsVisible ? styles.allVisible : ""}`}
> >
{mappedRooms.map(({ id, images, title, subtitle, popularChoice }) => ( {rooms.map((room) => (
<div key={id}> <div key={room.id}>
<RoomCard <RoomCard room={room} />
id={id}
images={images}
title={title}
subtitle={subtitle}
badgeTextTransKey={popularChoice ? "Popular choice" : null}
/>
</div> </div>
))} ))}
</Grids.Stackable> </Grids.Stackable>

View File

@@ -78,10 +78,7 @@ export default function RoomCard({
: `${roomSize?.min}-${roomSize?.max}`} : `${roomSize?.min}-${roomSize?.max}`}
m² m²
</Caption> </Caption>
<RoomSidePeek <RoomSidePeek selectedRoom={selectedRoom} buttonSize="small" />
selectedRoom={selectedRoom}
roomConfiguration={roomConfiguration}
/>
</div> </div>
<div className={styles.container}> <div className={styles.container}>
<div className={styles.roomDetails}> <div className={styles.roomDetails}>

View File

@@ -16,7 +16,7 @@ import type { RoomSidePeekProps } from "@/types/components/hotelReservation/sele
export default function RoomSidePeek({ export default function RoomSidePeek({
selectedRoom, selectedRoom,
roomConfiguration, buttonSize,
}: RoomSidePeekProps) { }: RoomSidePeekProps) {
const [isSidePeekOpen, setIsSidePeekOpen] = useState(false) const [isSidePeekOpen, setIsSidePeekOpen] = useState(false)
const intl = useIntl() const intl = useIntl()
@@ -31,7 +31,7 @@ export default function RoomSidePeek({
<Button <Button
intent="text" intent="text"
type="button" type="button"
size="small" size={buttonSize}
theme="base" theme="base"
className={styles.button} className={styles.button}
onClick={() => setIsSidePeekOpen(true)} onClick={() => setIsSidePeekOpen(true)}
@@ -41,7 +41,7 @@ export default function RoomSidePeek({
</Button> </Button>
<SidePeek <SidePeek
title={roomConfiguration.roomType} title={selectedRoom?.name ?? ""}
isOpen={isSidePeekOpen} isOpen={isSidePeekOpen}
handleClose={() => setIsSidePeekOpen(false)} handleClose={() => setIsSidePeekOpen(false)}
> >
@@ -51,16 +51,14 @@ export default function RoomSidePeek({
: `${roomSize?.min} - ${roomSize?.max}`} : `${roomSize?.min} - ${roomSize?.max}`}
m².{" "} m².{" "}
{intl.formatMessage( {intl.formatMessage(
{ { id: "booking.accommodatesUpTo" },
id: "booking.accommodatesUpTo",
},
{ nrOfGuests: occupancy } { nrOfGuests: occupancy }
)} )}
</Body> </Body>
{images && ( {images && (
<div className={styles.imageContainer}> <div className={styles.imageContainer}>
<ImageGallery images={images} title={roomConfiguration.roomType} /> <ImageGallery images={images} title={selectedRoom.name} />
</div> </div>
)} )}

View File

@@ -397,8 +397,7 @@
"guaranteeing": "garanti", "guaranteeing": "garanti",
"guest": "gæst", "guest": "gæst",
"guests": "gæster", "guests": "gæster",
"hotelPages.rooms.roomCard.person": "person", "hotelPages.rooms.roomCard.persons": "{totalOccupancy, plural, one {# person} other {# personer}}",
"hotelPages.rooms.roomCard.persons": "personer",
"hotelPages.rooms.roomCard.seeRoomDetails": "Se værelsesdetaljer", "hotelPages.rooms.roomCard.seeRoomDetails": "Se værelsesdetaljer",
"km to city center": "km til byens centrum", "km to city center": "km til byens centrum",
"lowercase letter": "lille bogstav", "lowercase letter": "lille bogstav",

View File

@@ -396,8 +396,7 @@
"guaranteeing": "garantiert", "guaranteeing": "garantiert",
"guest": "gast", "guest": "gast",
"guests": "gäste", "guests": "gäste",
"hotelPages.rooms.roomCard.person": "person", "hotelPages.rooms.roomCard.persons": "{totalOccupancy, plural, one {# person} other {# personen}}",
"hotelPages.rooms.roomCard.persons": "personen",
"hotelPages.rooms.roomCard.seeRoomDetails": "Zimmerdetails ansehen", "hotelPages.rooms.roomCard.seeRoomDetails": "Zimmerdetails ansehen",
"km to city center": "km bis zum Stadtzentrum", "km to city center": "km bis zum Stadtzentrum",
"lowercase letter": "Kleinbuchstabe", "lowercase letter": "Kleinbuchstabe",

View File

@@ -416,8 +416,7 @@
"guaranteeing": "guaranteeing", "guaranteeing": "guaranteeing",
"guest": "guest", "guest": "guest",
"guests": "guests", "guests": "guests",
"hotelPages.rooms.roomCard.person": "person", "hotelPages.rooms.roomCard.persons": "{totalOccupancy, plural, one {# person} other {# persons}}",
"hotelPages.rooms.roomCard.persons": "persons",
"hotelPages.rooms.roomCard.seeRoomDetails": "See room details", "hotelPages.rooms.roomCard.seeRoomDetails": "See room details",
"km to city center": "km to city center", "km to city center": "km to city center",
"lowercase letter": "lowercase letter", "lowercase letter": "lowercase letter",

View File

@@ -396,8 +396,7 @@
"guaranteeing": "varmistetaan", "guaranteeing": "varmistetaan",
"guest": "Vieras", "guest": "Vieras",
"guests": "Vieraita", "guests": "Vieraita",
"hotelPages.rooms.roomCard.person": "henkilö", "hotelPages.rooms.roomCard.persons": "{totalOccupancy, plural, one {# henkilö} other {# Henkilöä}}",
"hotelPages.rooms.roomCard.persons": "Henkilöä",
"hotelPages.rooms.roomCard.seeRoomDetails": "Katso huoneen tiedot", "hotelPages.rooms.roomCard.seeRoomDetails": "Katso huoneen tiedot",
"km to city center": "km keskustaan", "km to city center": "km keskustaan",
"lowercase letter": "pien kirjain", "lowercase letter": "pien kirjain",

View File

@@ -394,8 +394,7 @@
"guaranteeing": "garantiert", "guaranteeing": "garantiert",
"guest": "gjest", "guest": "gjest",
"guests": "gjester", "guests": "gjester",
"hotelPages.rooms.roomCard.person": "person", "hotelPages.rooms.roomCard.persons": "{totalOccupancy, plural, one {# person} other {# personer}}",
"hotelPages.rooms.roomCard.persons": "personer",
"hotelPages.rooms.roomCard.seeRoomDetails": "Se detaljer om rommet", "hotelPages.rooms.roomCard.seeRoomDetails": "Se detaljer om rommet",
"km to city center": "km til sentrum", "km to city center": "km til sentrum",
"lowercase letter": "liten bokstav", "lowercase letter": "liten bokstav",

View File

@@ -395,8 +395,7 @@
"guaranteeing": "garanterar", "guaranteeing": "garanterar",
"guest": "gäst", "guest": "gäst",
"guests": "gäster", "guests": "gäster",
"hotelPages.rooms.roomCard.person": "person", "hotelPages.rooms.roomCard.persons": "{totalOccupancy, plural, one {# person} other {# personer}}",
"hotelPages.rooms.roomCard.persons": "personer",
"hotelPages.rooms.roomCard.seeRoomDetails": "Se information om rummet", "hotelPages.rooms.roomCard.seeRoomDetails": "Se information om rummet",
"km to city center": "km till stadens centrum", "km to city center": "km till stadens centrum",
"lowercase letter": "liten bokstav", "lowercase letter": "liten bokstav",

View File

@@ -1,11 +1,7 @@
import type { RoomData } from "@/types/hotel" import type { RoomData } from "@/types/hotel"
export interface RoomCardProps { export interface RoomCardProps {
id: string room: RoomData
images: RoomData["images"]
title: string
subtitle: string
badgeTextTransKey: string | null
} }
export type RoomsProps = { export type RoomsProps = {

View File

@@ -1,8 +1,6 @@
import { RoomConfiguration } from "@/server/routers/hotels/output"
import { RoomData } from "@/types/hotel" import { RoomData } from "@/types/hotel"
export type RoomSidePeekProps = { export type RoomSidePeekProps = {
roomConfiguration: RoomConfiguration
selectedRoom?: RoomData selectedRoom?: RoomData
buttonSize: "small" | "medium"
} }