Merge branch 'master' into feature/tracking
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
import LoadingSpinner from "@/components/LoadingSpinner"
|
||||
|
||||
export default function LoadingModal() {
|
||||
return <LoadingSpinner />
|
||||
}
|
||||
@@ -15,7 +15,7 @@ import { MapModal } from "@/components/MapModal"
|
||||
import TrackingSDK from "@/components/TrackingSDK"
|
||||
import { setLang } from "@/i18n/serverContext"
|
||||
|
||||
import { fetchAvailableHotels } from "../../utils"
|
||||
import { fetchAvailableHotels, getFiltersFromHotels } from "../../utils"
|
||||
|
||||
import type { SelectHotelSearchParams } from "@/types/components/hotelReservation/selectHotel/selectHotelSearchParams"
|
||||
import {
|
||||
@@ -92,6 +92,7 @@ export default async function SelectHotelMapPage({
|
||||
}
|
||||
|
||||
const hotelPins = getHotelPins(hotels)
|
||||
const filterList = getFiltersFromHotels(hotels)
|
||||
|
||||
return (
|
||||
<MapModal>
|
||||
@@ -100,6 +101,7 @@ export default async function SelectHotelMapPage({
|
||||
hotelPins={hotelPins}
|
||||
mapId={googleMapId}
|
||||
hotels={hotels}
|
||||
filterList={filterList}
|
||||
/>
|
||||
<TrackingSDK pageData={pageTrackingData} hotelInfo={hotelsTrackingData} />
|
||||
</MapModal>
|
||||
|
||||
@@ -20,10 +20,13 @@
|
||||
gap: var(--Spacing-x1);
|
||||
}
|
||||
|
||||
.sorter {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sideBar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 340px;
|
||||
}
|
||||
|
||||
.link {
|
||||
@@ -47,6 +50,10 @@
|
||||
gap: var(--Spacing-x3);
|
||||
}
|
||||
|
||||
.filter {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.main {
|
||||
padding: var(--Spacing-x5);
|
||||
@@ -58,6 +65,11 @@
|
||||
var(--Spacing-x5);
|
||||
}
|
||||
|
||||
.sorter {
|
||||
display: block;
|
||||
width: 339px;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
@@ -65,6 +77,14 @@
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.sideBar {
|
||||
max-width: 340px;
|
||||
}
|
||||
.filter {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.link {
|
||||
display: flex;
|
||||
padding-bottom: var(--Spacing-x6);
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
getFiltersFromHotels,
|
||||
} from "@/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/utils"
|
||||
import HotelCardListing from "@/components/HotelReservation/HotelCardListing"
|
||||
import HotelCount from "@/components/HotelReservation/SelectHotel/HotelCount"
|
||||
import HotelFilter from "@/components/HotelReservation/SelectHotel/HotelFilter"
|
||||
import HotelSorter from "@/components/HotelReservation/SelectHotel/HotelSorter"
|
||||
import MobileMapButtonContainer from "@/components/HotelReservation/SelectHotel/MobileMapButtonContainer"
|
||||
@@ -22,7 +23,6 @@ import StaticMap from "@/components/Maps/StaticMap"
|
||||
import Alert from "@/components/TempDesignSystem/Alert"
|
||||
import Button from "@/components/TempDesignSystem/Button"
|
||||
import Link from "@/components/TempDesignSystem/Link"
|
||||
import Preamble from "@/components/TempDesignSystem/Text/Preamble"
|
||||
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
||||
import TrackingSDK from "@/components/TrackingSDK"
|
||||
import { getIntl } from "@/i18n"
|
||||
@@ -76,6 +76,8 @@ export default async function SelectHotelPage({
|
||||
|
||||
const filterList = getFiltersFromHotels(hotels)
|
||||
|
||||
const isAllUnavailable = hotels.every((hotel) => hotel.price === undefined)
|
||||
|
||||
const pageTrackingData: TrackingSDKPageData = {
|
||||
pageId: "select-hotel",
|
||||
domainLanguage: params.lang as Lang,
|
||||
@@ -107,11 +109,13 @@ export default async function SelectHotelPage({
|
||||
<div className={styles.title}>
|
||||
<div className={styles.cityInformation}>
|
||||
<Subtitle>{city.name}</Subtitle>
|
||||
<Preamble>{hotels.length} hotels</Preamble>
|
||||
<HotelCount />
|
||||
</div>
|
||||
<div className={styles.sorter}>
|
||||
<HotelSorter discreet />
|
||||
</div>
|
||||
<HotelSorter />
|
||||
</div>
|
||||
<MobileMapButtonContainer city={searchParams.city} />
|
||||
<MobileMapButtonContainer filters={filterList} />
|
||||
</header>
|
||||
<main className={styles.main}>
|
||||
<div className={styles.sideBar}>
|
||||
@@ -119,7 +123,7 @@ export default async function SelectHotelPage({
|
||||
<Link
|
||||
className={styles.link}
|
||||
color="burgundy"
|
||||
href={selectHotelMap[params.lang]}
|
||||
href={selectHotelMap(params.lang)}
|
||||
keepSearchParams
|
||||
>
|
||||
<div className={styles.mapContainer}>
|
||||
@@ -153,10 +157,10 @@ export default async function SelectHotelPage({
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<HotelFilter filters={filterList} />
|
||||
<HotelFilter filters={filterList} className={styles.filter} />
|
||||
</div>
|
||||
<div className={styles.hotelList}>
|
||||
{!hotels.length && (
|
||||
{isAllUnavailable && (
|
||||
<Alert
|
||||
type={AlertTypeEnum.Info}
|
||||
heading={intl.formatMessage({ id: "No availability" })}
|
||||
|
||||
@@ -9,8 +9,6 @@ import type {
|
||||
CategorizedFilters,
|
||||
Filter,
|
||||
} from "@/types/components/hotelReservation/selectHotel/hotelFilters"
|
||||
import type { HotelPin } from "@/types/components/hotelReservation/selectHotel/map"
|
||||
import { HotelListingEnum } from "@/types/enums/hotelListing"
|
||||
|
||||
const hotelSurroundingsFilterNames = [
|
||||
"Hotel surroundings",
|
||||
@@ -21,6 +19,15 @@ const hotelSurroundingsFilterNames = [
|
||||
"Omgivningar",
|
||||
]
|
||||
|
||||
const hotelFacilitiesFilterNames = [
|
||||
"Hotel facilities",
|
||||
"Hotellfaciliteter",
|
||||
"Hotelfaciliteter",
|
||||
"Hotel faciliteter",
|
||||
"Hotel-Infos",
|
||||
"Hotellin palvelut",
|
||||
]
|
||||
|
||||
export async function fetchAvailableHotels(
|
||||
input: AvailabilityInput
|
||||
): Promise<HotelData[]> {
|
||||
@@ -29,24 +36,8 @@ export async function fetchAvailableHotels(
|
||||
if (!availableHotels) throw new Error()
|
||||
|
||||
const language = getLang()
|
||||
const hotelMap = new Map<number, any>()
|
||||
|
||||
availableHotels.availability.forEach((hotel) => {
|
||||
const existingHotel = hotelMap.get(hotel.hotelId)
|
||||
if (existingHotel) {
|
||||
if (hotel.ratePlanSet === HotelListingEnum.RatePlanSet.PUBLIC) {
|
||||
existingHotel.bestPricePerNight.regularAmount =
|
||||
hotel.bestPricePerNight?.regularAmount
|
||||
} else if (hotel.ratePlanSet === HotelListingEnum.RatePlanSet.MEMBER) {
|
||||
existingHotel.bestPricePerNight.memberAmount =
|
||||
hotel.bestPricePerNight?.memberAmount
|
||||
}
|
||||
} else {
|
||||
hotelMap.set(hotel.hotelId, { ...hotel })
|
||||
}
|
||||
})
|
||||
|
||||
const hotels = Array.from(hotelMap.values()).map(async (hotel) => {
|
||||
const hotels = availableHotels.availability.map(async (hotel) => {
|
||||
const hotelData = await getHotelData({
|
||||
hotelId: hotel.hotelId.toString(),
|
||||
language,
|
||||
@@ -56,7 +47,7 @@ export async function fetchAvailableHotels(
|
||||
|
||||
return {
|
||||
hotelData: hotelData.data.attributes,
|
||||
price: hotel.bestPricePerNight,
|
||||
price: hotel.productType,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -70,6 +61,7 @@ export function getFiltersFromHotels(hotels: HotelData[]): CategorizedFilters {
|
||||
const filterList: Filter[] = uniqueFilterIds
|
||||
.map((filterId) => filters.find((filter) => filter.id === filterId))
|
||||
.filter((filter): filter is Filter => filter !== undefined)
|
||||
.sort((a, b) => b.sortOrder - a.sortOrder)
|
||||
|
||||
return filterList.reduce<CategorizedFilters>(
|
||||
(acc, filter) => {
|
||||
@@ -79,10 +71,13 @@ export function getFiltersFromHotels(hotels: HotelData[]): CategorizedFilters {
|
||||
surroundingsFilters: [...acc.surroundingsFilters, filter],
|
||||
}
|
||||
|
||||
return {
|
||||
facilityFilters: [...acc.facilityFilters, filter],
|
||||
surroundingsFilters: acc.surroundingsFilters,
|
||||
}
|
||||
if (filter.filter && hotelFacilitiesFilterNames.includes(filter.filter))
|
||||
return {
|
||||
facilityFilters: [...acc.facilityFilters, filter],
|
||||
surroundingsFilters: acc.surroundingsFilters,
|
||||
}
|
||||
|
||||
return acc
|
||||
},
|
||||
{ facilityFilters: [], surroundingsFilters: [] }
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user