feat(SW-66, SW-348): search functionality and ui

This commit is contained in:
Simon Emanuelsson
2024-08-28 10:47:57 +02:00
parent b9dbcf7d90
commit af850c90e7
437 changed files with 7663 additions and 9881 deletions

View File

@@ -0,0 +1,104 @@
import {
type Action,
ActionType,
type InitState,
type State,
} from "@/types/components/form/bookingwidget"
import type { Location, Locations } from "@/types/trpc/routers/hotel/locations"
export const localStorageKey = "searchHistory"
export function getSearchHistoryFromLocalStorage() {
if (typeof window !== "undefined") {
const storageSearchHistory = window.localStorage.getItem(localStorageKey)
if (storageSearchHistory) {
const parsedStorageSearchHistory: Locations =
JSON.parse(storageSearchHistory)
if (parsedStorageSearchHistory?.length) {
return parsedStorageSearchHistory
}
}
}
return null
}
export const sessionStorageKey = "searchData"
export function getSearchDataFromSessionStorage() {
if (typeof window !== "undefined") {
const storageSearchData = window.sessionStorage.getItem(sessionStorageKey)
if (storageSearchData) {
const parsedStorageSearchData: Location = JSON.parse(storageSearchData)
if (parsedStorageSearchData) {
return parsedStorageSearchData
}
}
}
return undefined
}
export function init(initState: InitState): State {
const searchHistory = getSearchHistoryFromLocalStorage()
const searchData = getSearchDataFromSessionStorage()
return {
defaultLocations: initState.defaultLocations,
locations: [],
search: "",
searchData,
searchHistory,
}
}
export function reducer(state: State, action: Action) {
const type = action.type
switch (type) {
case ActionType.CLEAR_HISTORY_LOCATIONS: {
return {
...state,
locations: [],
search: "",
searchHistory: null,
}
}
case ActionType.CLEAR_SEARCH_LOCATIONS:
return {
...state,
locations: [],
search: "",
}
case ActionType.SEARCH_LOCATIONS: {
const matchesMap = new Map()
const search = action.payload.search.toLowerCase()
state.defaultLocations.forEach((location) => {
const locationName = location.name.toLowerCase()
const keyWords = location.keyWords?.map((l) => l.toLowerCase())
if (locationName.includes(search.trim())) {
matchesMap.set(location.name, location)
}
if (keyWords?.find((keyWord) => keyWord.includes(search.trim()))) {
matchesMap.set(location.name, location)
}
})
const matches: Locations = []
matchesMap.forEach((value) => {
matches.push(value)
})
return {
...state,
locations: matches,
search: action.payload.search,
}
}
case ActionType.SELECT_ITEM: {
return {
...state,
searchData: action.payload.location,
searchHistory: action.payload.searchHistory,
}
}
default:
const unhandledActionType: never = type
console.info(`Unhandled type: ${unhandledActionType}`)
return state
}
}