feat(SW-340): Added Hotel Card Listing on map

This commit is contained in:
Pontus Dreij
2024-11-06 15:02:56 +01:00
parent 378225f995
commit 7a49d4a393
11 changed files with 58 additions and 24 deletions

View File

@@ -71,6 +71,7 @@ export default async function SelectHotelMapPage({
hotelPins={hotelPins} hotelPins={hotelPins}
mapId={googleMapId} mapId={googleMapId}
isModal={true} isModal={true}
hotels={hotels}
/> />
</MapModal> </MapModal>
) )

View File

@@ -67,7 +67,7 @@
} }
@media screen and (min-width: 1367px) { @media screen and (min-width: 1367px) {
.card { .card.listing {
grid-template-areas: grid-template-areas:
"image header" "image header"
"image hotel" "image hotel"
@@ -76,30 +76,30 @@
padding: 0; padding: 0;
} }
.imageContainer { .listing .imageContainer {
position: relative; position: relative;
min-height: 200px; min-height: 200px;
width: 518px; width: 518px;
} }
.tripAdvisor { .listing .tripAdvisor {
position: absolute; position: absolute;
display: block; display: block;
left: 7px; left: 7px;
top: 7px; top: 7px;
} }
.hotelInformation { .listing .hotelInformation {
padding-top: var(--Spacing-x2); padding-top: var(--Spacing-x2);
padding-right: var(--Spacing-x2); padding-right: var(--Spacing-x2);
} }
.hotel { .listing .hotel {
gap: var(--Spacing-x2); gap: var(--Spacing-x2);
padding-right: var(--Spacing-x2); padding-right: var(--Spacing-x2);
} }
.prices { .listing .prices {
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
@@ -107,11 +107,11 @@
padding-bottom: var(--Spacing-x2); padding-bottom: var(--Spacing-x2);
} }
.detailsButton { .listing .detailsButton {
border-bottom: none; border-bottom: none;
} }
.button { .listing .button {
width: 160px; width: 160px;
} }
} }

View File

@@ -4,23 +4,22 @@ import { useIntl } from "react-intl"
import { mapFacilityToIcon } from "@/components/ContentType/HotelPage/data" import { mapFacilityToIcon } from "@/components/ContentType/HotelPage/data"
import { PriceTagIcon, ScandicLogoIcon } from "@/components/Icons" import { PriceTagIcon, ScandicLogoIcon } from "@/components/Icons"
import TripAdvisorIcon from "@/components/Icons/TripAdvisor" import TripAdvisorIcon from "@/components/Icons/TripAdvisor"
import Image from "@/components/Image"
import Button from "@/components/TempDesignSystem/Button" import Button from "@/components/TempDesignSystem/Button"
import Chip from "@/components/TempDesignSystem/Chip" import Chip from "@/components/TempDesignSystem/Chip"
import Link from "@/components/TempDesignSystem/Link" import Link from "@/components/TempDesignSystem/Link"
import Caption from "@/components/TempDesignSystem/Text/Caption" import Caption from "@/components/TempDesignSystem/Text/Caption"
import Footnote from "@/components/TempDesignSystem/Text/Footnote" import Footnote from "@/components/TempDesignSystem/Text/Footnote"
import Title from "@/components/TempDesignSystem/Text/Title" import Title from "@/components/TempDesignSystem/Text/Title"
import { getIntl } from "@/i18n"
import ReadMore from "../ReadMore" import ReadMore from "../ReadMore"
import ImageGallery from "../SelectRate/ImageGallery" import ImageGallery from "../SelectRate/ImageGallery"
import { hotelCardVariants } from "./variants"
import styles from "./hotelCard.module.css" import styles from "./hotelCard.module.css"
import type { HotelCardProps } from "@/types/components/hotelReservation/selectHotel/hotelCardProps" import type { HotelCardProps } from "@/types/components/hotelReservation/selectHotel/hotelCardProps"
export default function HotelCard({ hotel }: HotelCardProps) { export default function HotelCard({ hotel, type = "listing" }: HotelCardProps) {
const intl = useIntl() const intl = useIntl()
const { hotelData } = hotel const { hotelData } = hotel
@@ -28,8 +27,12 @@ export default function HotelCard({ hotel }: HotelCardProps) {
const amenities = hotelData.detailedFacilities.slice(0, 5) const amenities = hotelData.detailedFacilities.slice(0, 5)
const classNames = hotelCardVariants({
type,
})
return ( return (
<article className={styles.card}> <article className={classNames}>
<section className={styles.imageContainer}> <section className={styles.imageContainer}>
{hotelData.gallery && ( {hotelData.gallery && (
<ImageGallery <ImageGallery

View File

@@ -0,0 +1,15 @@
import { cva } from "class-variance-authority"
import styles from "./hotelCard.module.css"
export const hotelCardVariants = cva(styles.card, {
variants: {
type: {
listing: styles.listing,
map: styles.map,
},
},
defaultVariants: {
type: "listing",
},
})

View File

@@ -10,7 +10,10 @@ import styles from "./hotelCardListing.module.css"
import { HotelCardListingProps } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps" import { HotelCardListingProps } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps"
export default function HotelCardListing({ hotelData }: HotelCardListingProps) { export default function HotelCardListing({
hotelData,
type = "listing",
}: HotelCardListingProps) {
const searchParams = useSearchParams() const searchParams = useSearchParams()
const hotels = useMemo(() => { const hotels = useMemo(() => {
@@ -28,9 +31,9 @@ export default function HotelCardListing({ hotelData }: HotelCardListingProps) {
return ( return (
<section className={styles.hotelCards}> <section className={styles.hotelCards}>
{hotels.length ? ( {hotels?.length ? (
hotels.map((hotel) => ( hotels.map((hotel) => (
<HotelCard key={hotel.hotelData.name} hotel={hotel} /> <HotelCard key={hotel.hotelData.name} hotel={hotel} type={type} />
)) ))
) : ( ) : (
<Title>No hotels found</Title> <Title>No hotels found</Title>

View File

@@ -5,5 +5,8 @@
@media (min-width: 768px) { @media (min-width: 768px) {
.hotelListing { .hotelListing {
display: block; display: block;
width: 420px;
padding: var(--Spacing-x3) var(--Spacing-x4);
overflow-y: auto;
} }
} }

View File

@@ -1,13 +1,15 @@
"use client" "use client"
import HotelCardListing from "@/components/HotelReservation/HotelCardListing"
import styles from "./hotelListing.module.css" import styles from "./hotelListing.module.css"
import { HotelListingProps } from "@/types/components/hotelReservation/selectHotel/map" import type { HotelListingProps } from "@/types/components/hotelReservation/selectHotel/map"
// TODO: This component is copied from export default function HotelListing({ hotels }: HotelListingProps) {
// components/ContentType/HotelPage/Map/DynamicMap/Sidebar. return (
// Look at that for inspiration on how to do the interaction with the map. <div className={styles.hotelListing}>
<HotelCardListing hotelData={hotels} type="map" />
export default function HotelListing({}: HotelListingProps) { </div>
return <section className={styles.hotelListing}>Hotel listing TBI</section> )
} }

View File

@@ -23,6 +23,7 @@ export default function SelectHotelMap({
hotelPins, hotelPins,
mapId, mapId,
isModal, isModal,
hotels,
}: SelectHotelMapProps) { }: SelectHotelMapProps) {
const searchParams = useSearchParams() const searchParams = useSearchParams()
const router = useRouter() const router = useRouter()
@@ -66,7 +67,7 @@ export default function SelectHotelMap({
<span>Filter and sort</span> <span>Filter and sort</span>
{/* TODO: Add filter and sort button */} {/* TODO: Add filter and sort button */}
</div> </div>
<HotelListing /> <HotelListing hotels={hotels} />
<InteractiveMap <InteractiveMap
closeButton={closeButton} closeButton={closeButton}
coordinates={coordinates} coordinates={coordinates}

View File

@@ -4,6 +4,7 @@ import { Hotel } from "@/types/hotel"
export type HotelCardListingProps = { export type HotelCardListingProps = {
hotelData: HotelData[] hotelData: HotelData[]
type?: "map" | "listing"
} }
export type HotelData = { export type HotelData = {

View File

@@ -2,4 +2,5 @@ import { HotelData } from "./hotelCardListingProps"
export type HotelCardProps = { export type HotelCardProps = {
hotel: HotelData hotel: HotelData
type?: "map" | "listing"
} }

View File

@@ -1,6 +1,9 @@
import { Coordinates } from "@/types/components/maps/coordinates" import { HotelData } from "./hotelCardListingProps"
import type { Coordinates } from "@/types/components/maps/coordinates"
export interface HotelListingProps { export interface HotelListingProps {
hotels: HotelData[]
// pointsOfInterest: PointOfInterest[] // pointsOfInterest: PointOfInterest[]
// activePoi: PointOfInterest["name"] | null // activePoi: PointOfInterest["name"] | null
// onActivePoiChange: (poi: PointOfInterest["name"] | null) => void // onActivePoiChange: (poi: PointOfInterest["name"] | null) => void
@@ -12,6 +15,7 @@ export interface SelectHotelMapProps {
hotelPins: HotelPin[] hotelPins: HotelPin[]
mapId: string mapId: string
isModal: boolean isModal: boolean
hotels: HotelData[]
} }
export type HotelPin = { export type HotelPin = {