feat(BOOK-54): Adjusted filter functionality to save filters as query parameters instead of paths

* feat(BOOK-54): Destination filters now matching on id instead of slug in preparation for filters from Contentstack

Approved-by: Chuma Mcphoy (We Ahead)
This commit is contained in:
Erik Tiekstra
2025-09-18 13:03:01 +00:00
parent 32a817fa72
commit 948c86479a
18 changed files with 136 additions and 102 deletions

View File

@@ -1,4 +1,5 @@
import {
type HotelFilter,
type HotelListingHotelData,
type HotelSortItem,
HotelSortOption,
@@ -25,12 +26,12 @@ const HOTEL_SORTING_STRATEGIES: Partial<
export function getFilteredHotels(
hotels: HotelListingHotelData[],
filters: string[]
filters: HotelFilter[]
) {
if (filters.length) {
return hotels.filter(({ hotel }) =>
filters.every((filter) =>
hotel.detailedFacilities.some((facility) => facility.slug === filter)
hotel.detailedFacilities.some((facility) => facility.id === filter.id)
)
)
}

View File

@@ -29,26 +29,30 @@ export function createDestinationDataStore({
allCities,
allHotels,
allFilters,
filterFromUrl,
pathname,
sortItems,
searchParams,
}: InitialState) {
const defaultSort =
sortItems.find((s) => s.isDefault)?.value ?? sortItems[0].value
const allFilterSlugs = Object.values(allFilters).flatMap(
(filter: HotelFilter[]) => filter.map((f) => f.slug)
)
const flattenedFilters = Object.values(allFilters).flat<HotelFilter[]>()
const allFilterSlugs = flattenedFilters.map((filter) => filter.slug)
const activeFilters: HotelFilter[] = []
let filterFromUrl: HotelFilter | null = null
const activeFilters: string[] = filterFromUrl ? [filterFromUrl] : []
const basePathnameWithoutFilters = getBasePathNameWithoutFilters(
pathname,
allFilterSlugs
)
if (basePathnameWithoutFilters !== pathname) {
const pathParts = pathname.split("/")
const lastPathPart = pathParts[pathParts.length - 1]
activeFilters.push(lastPathPart)
filterFromUrl =
flattenedFilters.find(
(filter) => filter.slug === pathParts[pathParts.length - 1]
) ?? null
if (filterFromUrl) {
activeFilters.push(filterFromUrl)
}
}
let activeSort = defaultSort
@@ -65,13 +69,16 @@ export function createDestinationDataStore({
return create<DestinationDataState>((set) => ({
actions: {
updateActiveFiltersAndSort(filters, sort) {
updateActiveFiltersAndSort(filterSlugs, sort) {
return set(
produce((state: DestinationDataState) => {
const newSort =
sort && isValidSortOption(sort, state.sortItems)
? sort
: state.defaultSort
const filters = flattenedFilters.filter((filter) =>
filterSlugs.includes(filter.slug)
)
const filteredHotels = getFilteredHotels(state.allHotels, filters)
const sortedHotels = getSortedHotels(filteredHotels, newSort)
const filteredCities = state.allHotels.length
@@ -86,16 +93,22 @@ export function createDestinationDataStore({
if (
JSON.stringify(filters) !== JSON.stringify(state.activeFilters)
) {
const facilityFiltersUsed = filters.filter((f) =>
state.allFilters.facilityFilters
.map((ff) => ff.slug)
.includes(f)
)
const surroundingsFiltersUsed = filters.filter((f) =>
state.allFilters.surroundingsFilters
.map((sf) => sf.slug)
.includes(f)
)
const facilityFiltersUsed = filters
.filter(
(f) =>
!!state.allFilters.facilityFilters.find(
(ff) => ff.id === f.id
)
)
.map((f) => f.slug)
const surroundingsFiltersUsed = filters
.filter(
(f) =>
!!state.allFilters.surroundingsFilters.find(
(sf) => sf.id === f.id
)
)
.map((f) => f.slug)
trackFilterChangeEvent(
facilityFiltersUsed,
@@ -133,9 +146,12 @@ export function createDestinationDataStore({
togglePendingFilter(filter) {
return set(
produce((state: DestinationDataState) => {
const isActive = state.pendingFilters.includes(filter)
const filterId = filter.id
const isActive = !!state.pendingFilters.find(
(pf) => pf.id === filterId
)
const filters = isActive
? state.pendingFilters.filter((f) => f !== filter)
? state.pendingFilters.filter((f) => f.id !== filterId)
: [...state.pendingFilters, filter]
const pendingHotels = getFilteredHotels(state.allHotels, filters)
const pendingCities = state.allHotels.length
@@ -180,7 +196,7 @@ export function createDestinationDataStore({
activeFilters,
pendingFilters: activeFilters,
allFilters,
allFilterSlugs,
filterFromUrl,
basePathnameWithoutFilters,
sortItems,
isLoading: false,