feat: added Rooms component to Hotelpage with some dummy rooms typing
This commit is contained in:
committed by
Chuma McPhoy
parent
68f40a144e
commit
7eea7aa400
@@ -1,15 +0,0 @@
|
||||
.cardContainer {
|
||||
display: grid;
|
||||
gap: var(--Spacing-x3);
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
}
|
||||
|
||||
.cardContainer.twoColumns {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
.cardContainer.threeColumns {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
.cardContainer.fourColumns {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import { VariantProps } from "class-variance-authority"
|
||||
|
||||
import { cardContainerVariants } from "./variants"
|
||||
|
||||
export interface CardContainerProps
|
||||
extends React.PropsWithChildren<React.HTMLAttributes<HTMLElement>>,
|
||||
VariantProps<typeof cardContainerVariants> {}
|
||||
@@ -1,18 +0,0 @@
|
||||
import { CardContainerProps } from "./cardContainer"
|
||||
import { cardContainerVariants } from "./variants"
|
||||
|
||||
export function CardContainer({
|
||||
children,
|
||||
className,
|
||||
columns,
|
||||
...props
|
||||
}: CardContainerProps) {
|
||||
return (
|
||||
<section
|
||||
className={cardContainerVariants({ className, columns })}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import { cva } from "class-variance-authority"
|
||||
|
||||
import styles from "./cardContainer.module.css"
|
||||
|
||||
export const cardContainerVariants = cva(styles.cardContainer, {
|
||||
variants: {
|
||||
columns: {
|
||||
2: styles.twoColumns,
|
||||
3: styles.threeColumns,
|
||||
4: styles.fourColumns,
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
columns: 3,
|
||||
},
|
||||
})
|
||||
@@ -3,6 +3,9 @@ import { serverClient } from "@/lib/trpc/server"
|
||||
import AmenitiesList from "./AmenitiesList"
|
||||
import IntroSection from "./IntroSection"
|
||||
|
||||
import { Rooms } from "./Rooms"
|
||||
import { MOCK_ROOMS } from "./tempHotelPageData"
|
||||
|
||||
import styles from "./hotelPage.module.css"
|
||||
|
||||
import type { LangParams } from "@/types/params"
|
||||
@@ -19,6 +22,7 @@ export default async function HotelPage({ lang }: LangParams) {
|
||||
hotelId: hotelPageIdentifierData.hotel_page_id,
|
||||
language: lang,
|
||||
})
|
||||
const rooms = MOCK_ROOMS
|
||||
|
||||
return (
|
||||
<main className={styles.pageContainer}>
|
||||
@@ -32,6 +36,7 @@ export default async function HotelPage({ lang }: LangParams) {
|
||||
/>
|
||||
<AmenitiesList detailedFacilities={attributes.detailedFacilities} />
|
||||
</div>
|
||||
<Rooms rooms={rooms} />
|
||||
</main>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -12,5 +12,5 @@ export interface RoomCardProps {
|
||||
title: string
|
||||
subtitle: string
|
||||
cta: RoomCardCtaProps
|
||||
badgeText?: string
|
||||
badgeText?: string | null
|
||||
}
|
||||
56
components/ContentType/HotelPage/Rooms/index.tsx
Normal file
56
components/ContentType/HotelPage/Rooms/index.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
"use client"
|
||||
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { RoomCard } from "./RoomCard"
|
||||
import { RoomsProps } from "./rooms"
|
||||
|
||||
import styles from "./rooms.module.css"
|
||||
|
||||
export function Rooms({ rooms }: RoomsProps) {
|
||||
const { formatMessage } = useIntl()
|
||||
|
||||
// TODO: Typings should be adjusted to match the actual data structure
|
||||
const mappedRooms = rooms.map((room) => ({
|
||||
id: room.id,
|
||||
image: room.images[0],
|
||||
imageCount: room.images.length,
|
||||
title: room.title,
|
||||
subtitle: room.subtitle,
|
||||
popularChoice: room.popularChoice,
|
||||
}))
|
||||
|
||||
function handleImageClick(id: string) {
|
||||
// TODO: Implement opening of a model with carousel
|
||||
console.log("Image clicked: ", id)
|
||||
}
|
||||
|
||||
function handleRoomCtaClick(id: string) {
|
||||
// TODO: Implement opening side-peek component with room details
|
||||
console.log("Room CTA clicked: ", id)
|
||||
}
|
||||
|
||||
return (
|
||||
<section className={styles.cardContainer}>
|
||||
{mappedRooms.map(
|
||||
({ id, image, imageCount, title, subtitle, popularChoice }) => (
|
||||
<RoomCard
|
||||
key={id}
|
||||
image={image}
|
||||
imageCount={imageCount}
|
||||
title={title}
|
||||
subtitle={subtitle}
|
||||
badgeText={
|
||||
popularChoice ? formatMessage({ id: "Popular choice" }) : null
|
||||
}
|
||||
imageClick={() => handleImageClick(id)}
|
||||
cta={{
|
||||
text: formatMessage({ id: "See room details" }),
|
||||
callback: () => handleRoomCtaClick(id),
|
||||
}}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
10
components/ContentType/HotelPage/Rooms/rooms.module.css
Normal file
10
components/ContentType/HotelPage/Rooms/rooms.module.css
Normal file
@@ -0,0 +1,10 @@
|
||||
.cardContainer {
|
||||
display: grid;
|
||||
gap: var(--Spacing-x3);
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
.cardContainer {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
}
|
||||
12
components/ContentType/HotelPage/Rooms/rooms.ts
Normal file
12
components/ContentType/HotelPage/Rooms/rooms.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { ImageProps } from "next/image"
|
||||
|
||||
// TODO: Typings should be adjusted to match the actual data structure
|
||||
export interface RoomsProps {
|
||||
rooms: {
|
||||
id: string
|
||||
title: string
|
||||
subtitle: string
|
||||
popularChoice: boolean
|
||||
images: ImageProps[]
|
||||
}[]
|
||||
}
|
||||
82
components/ContentType/HotelPage/tempHotelPageData.ts
Normal file
82
components/ContentType/HotelPage/tempHotelPageData.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { RoomsProps } from "./Rooms/rooms"
|
||||
|
||||
export const MOCK_ROOMS: RoomsProps["rooms"] = [
|
||||
{
|
||||
id: "1",
|
||||
title: "Cabin",
|
||||
subtitle: "15 - 20 m² (2 personer)",
|
||||
images: [
|
||||
{
|
||||
src: "https://placehold.co/300x200",
|
||||
alt: "Placeholder image",
|
||||
width: 300,
|
||||
height: 200,
|
||||
},
|
||||
{
|
||||
src: "https://placehold.co/300x200",
|
||||
alt: "Placeholder image",
|
||||
width: 300,
|
||||
height: 200,
|
||||
},
|
||||
],
|
||||
popularChoice: false,
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
title: "Standard",
|
||||
subtitle: "15 - 20 m² (2 personer)",
|
||||
images: [
|
||||
{
|
||||
src: "https://placehold.co/300x200",
|
||||
alt: "Placeholder image",
|
||||
width: 300,
|
||||
height: 200,
|
||||
},
|
||||
{
|
||||
src: "https://placehold.co/300x200",
|
||||
alt: "Placeholder image",
|
||||
width: 300,
|
||||
height: 200,
|
||||
},
|
||||
{
|
||||
src: "https://placehold.co/300x200",
|
||||
alt: "Placeholder image",
|
||||
width: 300,
|
||||
height: 200,
|
||||
},
|
||||
],
|
||||
popularChoice: true,
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
title: "Superior",
|
||||
subtitle: "15 m² (2 personer)",
|
||||
images: [
|
||||
{
|
||||
src: "https://placehold.co/300x200",
|
||||
alt: "Placeholder image",
|
||||
width: 300,
|
||||
height: 200,
|
||||
},
|
||||
{
|
||||
src: "https://placehold.co/300x200",
|
||||
alt: "Placeholder image",
|
||||
width: 300,
|
||||
height: 200,
|
||||
},
|
||||
{
|
||||
src: "https://placehold.co/300x200",
|
||||
alt: "Placeholder image",
|
||||
width: 300,
|
||||
height: 200,
|
||||
},
|
||||
{
|
||||
src: "https://placehold.co/300x200",
|
||||
alt: "Placeholder image",
|
||||
width: 300,
|
||||
height: 200,
|
||||
},
|
||||
],
|
||||
popularChoice: false,
|
||||
},
|
||||
]
|
||||
Reference in New Issue
Block a user