Files
web/apps/scandic-web/components/HotelReservation/SelectHotel/index.tsx
Anton Gunnarsson 002d093af4 Merged in feat/sw-2863-move-contentstack-router-to-trpc-package (pull request #2389)
feat(SW-2863): Move contentstack router to trpc package

* Add exports to packages and lint rule to prevent relative imports

* Add env to trpc package

* Add eslint to trpc package

* Apply lint rules

* Use direct imports from trpc package

* Add lint-staged config to trpc

* Move lang enum to common

* Restructure trpc package folder structure

* WIP first step

* update internal imports in trpc

* Fix most errors in scandic-web

Just 100 left...

* Move Props type out of trpc

* Fix CategorizedFilters types

* Move more schemas in hotel router

* Fix deps

* fix getNonContentstackUrls

* Fix import error

* Fix entry error handling

* Fix generateMetadata metrics

* Fix alertType enum

* Fix duplicated types

* lint:fix

* Merge branch 'master' into feat/sw-2863-move-contentstack-router-to-trpc-package

* Fix broken imports

* Merge branch 'master' into feat/sw-2863-move-contentstack-router-to-trpc-package


Approved-by: Linus Flood
2025-06-26 07:53:01 +00:00

131 lines
4.4 KiB
TypeScript

import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import HotelCardListing from "@/components/HotelReservation/HotelCardListing"
import BookingCodeFilter from "@/components/HotelReservation/SelectHotel/BookingCodeFilter"
import HotelFilter from "@/components/HotelReservation/SelectHotel/Filters/HotelFilter"
import HotelCount from "@/components/HotelReservation/SelectHotel/HotelCount"
import HotelSorter from "@/components/HotelReservation/SelectHotel/HotelSorter"
import MobileMapButtonContainer from "@/components/HotelReservation/SelectHotel/MobileMapButtonContainer"
import NoAvailabilityAlert from "@/components/HotelReservation/SelectHotel/NoAvailabilityAlert"
import StaticMap from "@/components/Maps/StaticMap"
import Link from "@/components/TempDesignSystem/Link"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import { getIntl } from "@/i18n"
import { getFiltersFromHotels, type HotelResponse } from "./helpers"
import styles from "./selectHotel.module.css"
import type { Location } from "@scandic-hotels/trpc/types/locations"
interface SelectHotelProps {
isAlternative?: boolean
bookingCode?: string
city: Location
hotels: HotelResponse[]
isBookingCodeRateAvailable?: boolean
mapHref: string
title: string
}
export default async function SelectHotel({
bookingCode,
city,
hotels,
isAlternative = false,
isBookingCodeRateAvailable = false,
mapHref,
title,
}: SelectHotelProps) {
const intl = await getIntl()
const isAllUnavailable = hotels.every(
(hotel) => hotel.availability.status !== "Available"
)
const isCityWithCountry = (city: any): city is { country: string } =>
"country" in city
// Special rates (corporate cheque, voucher) will not have regular rate hotels availability
const isSpecialRate = hotels.some(
(hotel) =>
hotel.availability.productType?.bonusCheque ||
hotel.availability.productType?.voucher
)
const filterList = getFiltersFromHotels(hotels)
const showBookingCodeFilter = isBookingCodeRateAvailable && !isSpecialRate
return (
<>
<header className={styles.header}>
<div className={styles.headerContent}>
<div className={styles.title}>
<div className={styles.cityInformation}>
<Subtitle>{title}</Subtitle>
<HotelCount />
</div>
<div className={styles.sorter}>
<HotelSorter discreet />
</div>
</div>
<MobileMapButtonContainer filters={filterList} />
</div>
</header>
<main className={styles.main}>
{showBookingCodeFilter ? <BookingCodeFilter /> : null}
<div className={styles.sideBar}>
{hotels.length ? (
<Link className={styles.link} href={mapHref} keepSearchParams>
<div className={styles.mapContainer}>
<StaticMap
city={city.name}
country={isCityWithCountry(city) ? city.country : undefined}
width={340}
height={180}
zoomLevel={11}
mapType="roadmap"
altText={`Map of ${city.name} city center`}
/>
<div className={styles.linkText}>
{intl.formatMessage({
defaultMessage: "See map",
})}
<MaterialIcon
icon="chevron_right"
size={20}
color="CurrentColor"
/>
</div>
</div>
</Link>
) : (
<div className={styles.mapContainer}>
<StaticMap
city={city.name}
width={340}
height={180}
zoomLevel={11}
mapType="roadmap"
altText={`Map of ${city.name} city center`}
/>
</div>
)}
<HotelFilter filters={filterList} className={styles.filter} />
</div>
<div className={styles.hotelList}>
<NoAvailabilityAlert
hotelsLength={hotels.length}
isAlternative={isAlternative}
isAllUnavailable={isAllUnavailable}
operaId={hotels?.[0]?.hotel.operaId}
bookingCode={bookingCode}
isBookingCodeRateNotAvailable={!isBookingCodeRateAvailable}
/>
<HotelCardListing hotelData={hotels} />
</div>
</main>
</>
)
}