110 lines
3.9 KiB
TypeScript
110 lines
3.9 KiB
TypeScript
import { useIntl } from "react-intl"
|
|
|
|
import Contact from "@/components/HotelReservation/Contact"
|
|
import Accordion from "@/components/TempDesignSystem/Accordion"
|
|
import AccordionItem from "@/components/TempDesignSystem/Accordion/AccordionItem"
|
|
import Button from "@/components/TempDesignSystem/Button"
|
|
import SidePeek from "@/components/TempDesignSystem/SidePeek"
|
|
import Body from "@/components/TempDesignSystem/Text/Body"
|
|
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
|
|
|
import { getFacilityIcon } from "../RoomSidePeek/facilityIcon"
|
|
|
|
import styles from "./hotelSidePeek.module.css"
|
|
|
|
import type { HotelSidePeekProps } from "@/types/components/hotelReservation/hotelSidePeek"
|
|
import type { ParkingProps } from "@/types/components/hotelReservation/selectHotel/selectHotel"
|
|
import { SidePeekEnum } from "@/types/components/hotelReservation/sidePeek"
|
|
import { IconName } from "@/types/components/icon"
|
|
import type { Amenities, Hotel } from "@/types/hotel"
|
|
|
|
function getAmenitiesList(hotel: Hotel) {
|
|
const detailedAmenities: Amenities = hotel.detailedFacilities.filter(
|
|
// Remove Parking facilities since parking accordion is based on hotel.parking
|
|
(facility) => !facility.name.startsWith("Parking") && facility.public
|
|
)
|
|
return detailedAmenities
|
|
}
|
|
|
|
export default function HotelSidePeek({
|
|
hotel,
|
|
activeSidePeek,
|
|
close,
|
|
showCTA,
|
|
}: HotelSidePeekProps) {
|
|
const intl = useIntl()
|
|
const amenitiesList = getAmenitiesList(hotel)
|
|
|
|
return (
|
|
<SidePeek
|
|
title={hotel.name}
|
|
isOpen={activeSidePeek === SidePeekEnum.hotelDetails}
|
|
handleClose={close}
|
|
>
|
|
<div className={styles.content}>
|
|
<Subtitle>
|
|
{intl.formatMessage({ id: "Practical information" })}
|
|
</Subtitle>
|
|
<Contact hotel={hotel} />
|
|
<Accordion>
|
|
{/* parking */}
|
|
{hotel.parking.length ? (
|
|
<AccordionItem
|
|
title={intl.formatMessage({ id: "Parking" })}
|
|
icon={IconName.Parking}
|
|
>
|
|
{hotel.parking.map((p) => (
|
|
<Parking key={p.name} parking={p} />
|
|
))}
|
|
</AccordionItem>
|
|
) : null}
|
|
<div className={styles.amenity}>
|
|
{intl.formatMessage({ id: "Accessibility" })}
|
|
</div>
|
|
{amenitiesList.map((amenity) => {
|
|
const Icon = getFacilityIcon(amenity.icon)
|
|
return (
|
|
<div key={amenity.id} className={styles.amenity}>
|
|
{Icon && (
|
|
<Icon width={24} height={24} color="uiTextMediumContrast" />
|
|
)}
|
|
<Body
|
|
asChild
|
|
className={!Icon ? styles.noIcon : undefined}
|
|
color="uiTextMediumContrast"
|
|
>
|
|
<span>{amenity.name}</span>
|
|
</Body>
|
|
</div>
|
|
)
|
|
})}
|
|
</Accordion>
|
|
{showCTA && (
|
|
/* TODO: handle linking to Hotel Page */
|
|
<Button theme={"base"}>To the hotel</Button>
|
|
)}
|
|
</div>
|
|
</SidePeek>
|
|
)
|
|
}
|
|
|
|
function Parking({ parking }: ParkingProps) {
|
|
const intl = useIntl()
|
|
return (
|
|
<div>
|
|
<Body>{`${intl.formatMessage({ id: parking.type })} (${parking.name})`}</Body>
|
|
<ul className={styles.list}>
|
|
<li>
|
|
{`${intl.formatMessage({
|
|
id: "Number of charging points for electric cars",
|
|
})}: ${parking.numberOfChargingSpaces}`}
|
|
</li>
|
|
<li>{`${intl.formatMessage({ id: "Parking can be reserved in advance" })}: ${parking.canMakeReservation ? intl.formatMessage({ id: "Yes" }) : intl.formatMessage({ id: "No" })}`}</li>
|
|
<li>{`${intl.formatMessage({ id: "Number of parking spots" })}: ${parking.numberOfParkingSpots}`}</li>
|
|
<li>{`${intl.formatMessage({ id: "Distance to hotel" })}: ${parking.distanceToHotel} m`}</li>
|
|
<li>{`${intl.formatMessage({ id: "Address" })}: ${parking.address}`}</li>
|
|
</ul>
|
|
</div>
|
|
)
|
|
}
|