Merged in feat/sw-2873-move-selecthotel-to-booking-flow (pull request #2727)

feat(SW-2873): Move select-hotel to booking flow

* crude setup of select-hotel in partner-sas

* wip

* Fix linting

* restructure tracking files

* Remove dependency on trpc in tracking hooks

* Move pageview tracking to common

* Fix some lint and import issues

* Add AlternativeHotelsPage

* Add SelectHotelMapPage

* Add AlternativeHotelsMapPage

* remove next dependency in tracking store

* Remove dependency on react in tracking hooks

* move isSameBooking to booking-flow

* Inject searchParamsComparator into tracking store

* Move useTrackHardNavigation to common

* Move useTrackSoftNavigation to common

* Add TrackingSDK to partner-sas

* call serverclient in layout

* Remove unused css

* Update types

* Move HotelPin type

* Fix todos

* Merge branch 'master' into feat/sw-2873-move-selecthotel-to-booking-flow

* Merge branch 'master' into feat/sw-2873-move-selecthotel-to-booking-flow

* Fix component


Approved-by: Joakim Jäderberg
This commit is contained in:
Anton Gunnarsson
2025-09-01 08:37:00 +00:00
parent 93a90bef9d
commit 87402a2092
157 changed files with 2026 additions and 1376 deletions

View File

@@ -0,0 +1,29 @@
import { create } from "zustand"
interface HotelFilterState {
activeFilters: string[]
toggleFilter: (filterId: string) => void
setFilters: (filters: string[]) => void
resultCount: number
unfilteredResultCount: number
setResultCount: (count: number, unfilteredCount: number) => void
}
export const useHotelFilterStore = create<HotelFilterState>((set) => ({
activeFilters: [],
setFilters: (filters) => set({ activeFilters: filters }),
toggleFilter: (filterId: string) =>
set((state) => {
const isActive = state.activeFilters.includes(filterId)
const newFilters = isActive
? state.activeFilters.filter((id) => id !== filterId)
: [...state.activeFilters, filterId]
return { activeFilters: newFilters }
}),
resultCount: 0,
unfilteredResultCount: 0,
setResultCount: (count, unfilteredCount) =>
set({ resultCount: count, unfilteredResultCount: unfilteredCount }),
}))

View File

@@ -0,0 +1,43 @@
import { create } from "zustand"
interface HotelsMapState {
activeHotel: string | null
hoveredHotel: string | null
hoverTimeout: number | null
activate: (hotel: string | null) => void
deactivate: () => void
engage: (hotel: string | null) => void
disengage: () => void
disengageAfterDelay: () => void
}
export const useHotelsMapStore = create<HotelsMapState>((set, get) => ({
activeHotel: null,
hoveredHotel: null,
hoverTimeout: null,
activate: (hotel) => set({ activeHotel: hotel }),
deactivate: () => set({ activeHotel: null }),
engage: (hotel) => {
const state = get()
if (state.hoverTimeout) {
window.clearTimeout(state.hoverTimeout)
}
if (hotel && state.activeHotel) {
set({ activeHotel: null })
}
set({ hoveredHotel: hotel })
},
disengage: () => {
set({ hoveredHotel: null })
},
disengageAfterDelay: () => {
const timeoutId = window.setTimeout(() => {
set({ hoveredHotel: null, activeHotel: null, hoverTimeout: null })
}, 3000)
set({ hoverTimeout: timeoutId })
},
}))