Feat/SW-2271 hotel list filtering

* feat(SW-2271): Changes to hotel data types in preperation for filtering
* feat(SW-2271): Added filter and sort functionality

Approved-by: Matilda Landström
This commit is contained in:
Erik Tiekstra
2025-07-04 09:27:20 +00:00
parent 82e21af0d4
commit fa7214cb58
58 changed files with 1572 additions and 450 deletions

View File

@@ -1,67 +0,0 @@
import type {
CategorizedFilters,
Filter,
} from "../../../types/destinationFilterAndSort"
import type { DestinationPagesHotelData } from "../../../types/hotel"
const HOTEL_SURROUNDINGS_FILTER_TYPE_NAMES = [
"Hotel surroundings",
"Hotel omgivelser",
"Hotelumgebung",
"Hotellia lähellä",
"Hotellomgivelser",
"Omgivningar",
]
const HOTEL_FACILITIES_FILTER_TYPE_NAMES = [
"Hotel facilities",
"Hotellfaciliteter",
"Hotelfaciliteter",
"Hotel faciliteter",
"Hotel-Infos",
"Hotellin palvelut",
]
export function getFiltersFromHotels(
hotels: DestinationPagesHotelData[]
): CategorizedFilters {
if (hotels.length === 0) {
return { facilityFilters: [], surroundingsFilters: [] }
}
const filters = hotels.flatMap(({ hotel }) => hotel.detailedFacilities)
const uniqueFilterNames = [...new Set(filters.map((filter) => filter.name))]
const filterList = uniqueFilterNames
.map((filterName) => {
const filter = filters.find((filter) => filter.name === filterName)
return filter
? {
name: filter.name,
slug: filter.slug,
filterType: filter.filter,
sortOrder: filter.sortOrder,
}
: null
})
.filter((filter): filter is Filter => !!filter)
const facilityFilters = filterList.filter((filter) =>
HOTEL_FACILITIES_FILTER_TYPE_NAMES.includes(filter.filterType)
)
const surroundingsFilters = filterList.filter((filter) =>
HOTEL_SURROUNDINGS_FILTER_TYPE_NAMES.includes(filter.filterType)
)
return {
facilityFilters: sortFilters(facilityFilters),
surroundingsFilters: sortFilters(surroundingsFilters),
}
}
function sortFilters(filters: Filter[]): Filter[] {
return [...filters].sort((a, b) => {
// First sort by sortOrder
const orderDiff = a.sortOrder - b.sortOrder
// If sortOrder is the same, sort by name as secondary criterion
return orderDiff === 0 ? a.name.localeCompare(b.name) : orderDiff
})
}

View File

@@ -1,5 +1,6 @@
import { SortOption } from "../../../enums/destinationFilterAndSort"
import { ApiCountry } from "../../../types/country"
import { HotelSortOption } from "../../../types/hotel"
import { getFiltersFromHotels } from "../../../utils/getFiltersFromHotels"
import { getSortedCities } from "../../../utils/getSortedCities"
import {
getCityByCityIdentifier,
@@ -8,7 +9,6 @@ import {
getHotelsByHotelIds,
} from "../../hotels/utils"
import { getCityPages } from "../destinationCountryPage/utils"
import { getFiltersFromHotels } from "./helpers"
import type { Lang } from "@scandic-hotels/common/constants/language"
@@ -61,7 +61,7 @@ export async function getCityData(
let filterType
if (filter) {
const allFilters = getFiltersFromHotels(hotels)
const allFilters = getFiltersFromHotels(hotels, lang)
const facilityFilter = allFilters.facilityFilters.find(
(f) => f.slug === filter
)
@@ -101,7 +101,7 @@ export async function getCountryData(
let filterType
const cities = await getCityPages(lang, serviceToken, country)
const sortedCities = getSortedCities(cities, SortOption.Recommended)
const sortedCities = getSortedCities(cities, HotelSortOption.Recommended)
const hotelIds = await getHotelIdsByCountry({
country,
serviceToken,
@@ -110,7 +110,7 @@ export async function getCountryData(
const hotels = await getHotelsByHotelIds({ hotelIds, lang, serviceToken })
if (filter) {
const allFilters = getFiltersFromHotels(hotels)
const allFilters = getFiltersFromHotels(hotels, lang)
const facilityFilter = allFilters.facilityFilters.find(
(f) => f.slug === filter
)