feat(SW-340): Added HotelCardDialog component
This commit is contained in:
@@ -67,7 +67,7 @@
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1367px) {
|
||||
.card.listing {
|
||||
.card.pageListing {
|
||||
grid-template-areas:
|
||||
"image header"
|
||||
"image hotel"
|
||||
@@ -76,30 +76,30 @@
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.listing .imageContainer {
|
||||
.pageListing .imageContainer {
|
||||
position: relative;
|
||||
min-height: 200px;
|
||||
width: 518px;
|
||||
}
|
||||
|
||||
.listing .tripAdvisor {
|
||||
.pageListing .tripAdvisor {
|
||||
position: absolute;
|
||||
display: block;
|
||||
left: 7px;
|
||||
top: 7px;
|
||||
}
|
||||
|
||||
.listing .hotelInformation {
|
||||
.pageListing .hotelInformation {
|
||||
padding-top: var(--Spacing-x2);
|
||||
padding-right: var(--Spacing-x2);
|
||||
}
|
||||
|
||||
.listing .hotel {
|
||||
.pageListing .hotel {
|
||||
gap: var(--Spacing-x2);
|
||||
padding-right: var(--Spacing-x2);
|
||||
}
|
||||
|
||||
.listing .prices {
|
||||
.pageListing .prices {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
@@ -107,11 +107,11 @@
|
||||
padding-bottom: var(--Spacing-x2);
|
||||
}
|
||||
|
||||
.listing .detailsButton {
|
||||
.pageListing .detailsButton {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.listing .button {
|
||||
.pageListing .button {
|
||||
width: 160px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,13 @@ import { hotelCardVariants } from "./variants"
|
||||
|
||||
import styles from "./hotelCard.module.css"
|
||||
|
||||
import { HotelCardListingType } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps"
|
||||
import type { HotelCardProps } from "@/types/components/hotelReservation/selectHotel/hotelCardProps"
|
||||
|
||||
export default function HotelCard({ hotel, type = "listing" }: HotelCardProps) {
|
||||
export default function HotelCard({
|
||||
hotel,
|
||||
type = HotelCardListingType.PageListing,
|
||||
}: HotelCardProps) {
|
||||
const intl = useIntl()
|
||||
|
||||
const { hotelData } = hotel
|
||||
|
||||
@@ -5,11 +5,11 @@ import styles from "./hotelCard.module.css"
|
||||
export const hotelCardVariants = cva(styles.card, {
|
||||
variants: {
|
||||
type: {
|
||||
listing: styles.listing,
|
||||
map: styles.map,
|
||||
pageListing: styles.pageListing,
|
||||
mapListing: styles.mapListing,
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
type: "listing",
|
||||
type: "pageListing",
|
||||
},
|
||||
})
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
.dialog {
|
||||
padding-bottom: var(--Spacing-x1);
|
||||
bottom: 32px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
border: none;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.dialogContainer {
|
||||
border: 1px solid var(--Base-Border-Subtle);
|
||||
border-radius: var(--Corner-radius-Medium);
|
||||
width: 402px;
|
||||
min-height: 227px;
|
||||
background: var(--Base-Surface-Primary-light-Normal);
|
||||
box-shadow: 0px 0px 8px 3px rgba(0, 0, 0, 0.1);
|
||||
flex-direction: row;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.imageContainer {
|
||||
position: relative;
|
||||
min-height: 227px;
|
||||
width: 177px;
|
||||
}
|
||||
|
||||
.tripAdvisor {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.imageContainer img {
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
padding: var(--Spacing-x-one-and-half);
|
||||
gap: var(--Spacing-x1);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.facilities {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--Spacing-x1);
|
||||
}
|
||||
|
||||
.facilitiesItem {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--Spacing-x-half);
|
||||
}
|
||||
|
||||
.prices {
|
||||
border-radius: var(--Corner-radius-Medium);
|
||||
padding: var(--Spacing-x-half) var(--Spacing-x1);
|
||||
background: var(--Base-Surface-Secondary-light-Normal);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--Spacing-x-half);
|
||||
}
|
||||
|
||||
.perNight {
|
||||
color: var(--Base-Text-Subtle-light-Normal);
|
||||
}
|
||||
|
||||
.button {
|
||||
margin-top: auto;
|
||||
}
|
||||
90
components/HotelReservation/HotelCardDialog/index.tsx
Normal file
90
components/HotelReservation/HotelCardDialog/index.tsx
Normal file
@@ -0,0 +1,90 @@
|
||||
"use client"
|
||||
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import { mapFacilityToIcon } from "@/components/ContentType/HotelPage/data"
|
||||
import TripAdvisorIcon from "@/components/Icons/TripAdvisor"
|
||||
import Image from "@/components/Image"
|
||||
import Button from "@/components/TempDesignSystem/Button"
|
||||
import Chip from "@/components/TempDesignSystem/Chip"
|
||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
||||
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
||||
|
||||
import styles from "./hotelCardDialog.module.css"
|
||||
|
||||
import { HotelPin } from "@/types/components/hotelReservation/selectHotel/map"
|
||||
|
||||
export default function HotelCardDialog({
|
||||
pin,
|
||||
isOpen,
|
||||
}: {
|
||||
isOpen: boolean
|
||||
pin: HotelPin
|
||||
}) {
|
||||
const intl = useIntl()
|
||||
|
||||
const {
|
||||
name,
|
||||
publicPrice,
|
||||
memberPrice,
|
||||
currency,
|
||||
amenities,
|
||||
images,
|
||||
ratings,
|
||||
} = pin
|
||||
|
||||
return (
|
||||
<dialog open={isOpen} className={styles.dialog}>
|
||||
<div className={styles.dialogContainer}>
|
||||
<div className={styles.imageContainer}>
|
||||
<Image
|
||||
src={images[0].imageSizes.small}
|
||||
alt={images[0].metaData.altText}
|
||||
fill
|
||||
/>
|
||||
<div className={styles.tripAdvisor}>
|
||||
<Chip intent="primary" className={styles.tripAdvisor}>
|
||||
<TripAdvisorIcon color="white" />
|
||||
{ratings}
|
||||
</Chip>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.content}>
|
||||
<Body textTransform="bold">{name}</Body>
|
||||
<div className={styles.facilities}>
|
||||
{amenities.map((facility) => {
|
||||
const IconComponent = mapFacilityToIcon(facility.id)
|
||||
return (
|
||||
<div className={styles.facilitiesItem} key={facility.id}>
|
||||
{IconComponent && <IconComponent color="grey80" />}
|
||||
<Caption color="textMediumContrast">{facility.name}</Caption>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
<div className={styles.prices}>
|
||||
<Caption type="bold">{intl.formatMessage({ id: "From" })}</Caption>
|
||||
<Subtitle type="two">
|
||||
{publicPrice} {currency}
|
||||
<Body asChild>
|
||||
<span>/{intl.formatMessage({ id: "night" })}</span>
|
||||
</Body>
|
||||
</Subtitle>
|
||||
{memberPrice && (
|
||||
<Subtitle type="two" color="red">
|
||||
{memberPrice} {currency}
|
||||
<Body asChild color="red">
|
||||
<span>/{intl.formatMessage({ id: "night" })}</span>
|
||||
</Body>
|
||||
</Subtitle>
|
||||
)}
|
||||
</div>
|
||||
<Button size="small" theme="base" className={styles.button}>
|
||||
{intl.formatMessage({ id: "See rooms" })}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</dialog>
|
||||
)
|
||||
}
|
||||
@@ -8,11 +8,14 @@ import HotelCard from "../HotelCard"
|
||||
|
||||
import styles from "./hotelCardListing.module.css"
|
||||
|
||||
import { HotelCardListingProps } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps"
|
||||
import {
|
||||
HotelCardListingProps,
|
||||
HotelCardListingType,
|
||||
} from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps"
|
||||
|
||||
export default function HotelCardListing({
|
||||
hotelData,
|
||||
type = "listing",
|
||||
type = HotelCardListingType.PageListing,
|
||||
}: HotelCardListingProps) {
|
||||
const searchParams = useSearchParams()
|
||||
|
||||
|
||||
@@ -4,12 +4,16 @@ import HotelCardListing from "@/components/HotelReservation/HotelCardListing"
|
||||
|
||||
import styles from "./hotelListing.module.css"
|
||||
|
||||
import { HotelCardListingType } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps"
|
||||
import type { HotelListingProps } from "@/types/components/hotelReservation/selectHotel/map"
|
||||
|
||||
export default function HotelListing({ hotels }: HotelListingProps) {
|
||||
return (
|
||||
<div className={styles.hotelListing}>
|
||||
<HotelCardListing hotelData={hotels} type="map" />
|
||||
<HotelCardListing
|
||||
hotelData={hotels}
|
||||
type={HotelCardListingType.MapListing}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ export default function SelectHotelMap({
|
||||
closeButton={closeButton}
|
||||
coordinates={coordinates}
|
||||
hotelPins={hotelPins}
|
||||
hotels={hotels}
|
||||
activeHotelPin={activeHotelPin}
|
||||
onActiveHotelPinChange={setActiveHotelPin}
|
||||
mapId={mapId}
|
||||
|
||||
Reference in New Issue
Block a user