Merged in feat/SW-1451-country-page-sorting (pull request #1426)
Feat/SW-1451 country page filtering and sorting * feat(SW-1451): implemented sorting and filtering on country pages * feat(SW-1451): Renamed hotel-data to destination-data because of its multi-purpose use * feat(SW-1451): Now filtering after change of url instead of inside the store after submit Approved-by: Fredrik Thorsson
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
import { useParams } from "next/navigation"
|
||||
import { useEffect } from "react"
|
||||
|
||||
import { useDestinationDataStore } from "@/stores/destination-data"
|
||||
|
||||
export default function DestinationDataProviderContent({
|
||||
children,
|
||||
}: React.PropsWithChildren) {
|
||||
const params = useParams()
|
||||
const { basePath, updateActiveFiltersAndSort } = useDestinationDataStore(
|
||||
(state) => ({
|
||||
basePath: state.basePathnameWithoutFilters,
|
||||
updateActiveFiltersAndSort: state.actions.updateActiveFiltersAndSort,
|
||||
})
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
const currentUrl = new URL(window.location.href)
|
||||
const searchParams = currentUrl.searchParams
|
||||
const currentPathname = currentUrl.pathname
|
||||
const currentHash = currentUrl.hash
|
||||
const sort = searchParams.get("sort")
|
||||
const filters = []
|
||||
const pathParts = currentPathname.split("/")
|
||||
const lastPathPart = pathParts[pathParts.length - 1]
|
||||
|
||||
if (basePath !== currentPathname) {
|
||||
filters.push(lastPathPart)
|
||||
}
|
||||
if (currentHash) {
|
||||
const hashValue = currentHash.substring(1)
|
||||
filters.push(...hashValue.split("&"))
|
||||
}
|
||||
|
||||
updateActiveFiltersAndSort(filters, sort)
|
||||
}, [params, updateActiveFiltersAndSort, basePath])
|
||||
|
||||
return <>{children}</>
|
||||
}
|
||||
39
apps/scandic-web/providers/DestinationDataProvider/index.tsx
Normal file
39
apps/scandic-web/providers/DestinationDataProvider/index.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
"use client"
|
||||
import { usePathname } from "next/navigation"
|
||||
import { useRef } from "react"
|
||||
|
||||
import { createDestinationDataStore } from "@/stores/destination-data"
|
||||
|
||||
import { DestinationDataContext } from "@/contexts/DestinationData"
|
||||
|
||||
import DestinationDataProviderContent from "./Content"
|
||||
|
||||
import type { DestinationDataStore } from "@/types/contexts/destination-data"
|
||||
import type { DestinationDataProviderProps } from "@/types/providers/destination-data"
|
||||
|
||||
export default function DestinationDataProvider({
|
||||
allCities = [],
|
||||
allHotels,
|
||||
sortItems,
|
||||
children,
|
||||
}: DestinationDataProviderProps) {
|
||||
const storeRef = useRef<DestinationDataStore>()
|
||||
const pathname = usePathname()
|
||||
|
||||
if (!storeRef.current) {
|
||||
storeRef.current = createDestinationDataStore({
|
||||
allCities,
|
||||
allHotels,
|
||||
pathname,
|
||||
sortItems,
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<DestinationDataContext.Provider value={storeRef.current}>
|
||||
<DestinationDataProviderContent>
|
||||
{children}
|
||||
</DestinationDataProviderContent>
|
||||
</DestinationDataContext.Provider>
|
||||
)
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
"use client"
|
||||
import { usePathname, useRouter, useSearchParams } from "next/navigation"
|
||||
import { useRef } from "react"
|
||||
|
||||
import { createHotelDataStore } from "@/stores/hotel-data"
|
||||
import { DEFAULT_SORT } from "@/stores/hotel-data/helper"
|
||||
|
||||
import { HotelDataContext } from "@/contexts/HotelData"
|
||||
|
||||
import type { HotelDataStore } from "@/types/contexts/hotel-data"
|
||||
import type { HotelDataProviderProps } from "@/types/providers/hotel-data"
|
||||
import type { SubmitCallbackData } from "@/types/stores/hotel-data"
|
||||
|
||||
export default function HotelDataProvider({
|
||||
allHotels,
|
||||
filterFromUrl,
|
||||
sortItems,
|
||||
children,
|
||||
}: HotelDataProviderProps) {
|
||||
const storeRef = useRef<HotelDataStore>()
|
||||
const searchParams = useSearchParams()
|
||||
const pathname = usePathname()
|
||||
const router = useRouter()
|
||||
|
||||
function submitCallbackFn({ sort, filters, basePath }: SubmitCallbackData) {
|
||||
const parsedUrl = new URL(window.location.href)
|
||||
const searchParams = parsedUrl.searchParams
|
||||
if (sort === DEFAULT_SORT && searchParams.has("sort")) {
|
||||
searchParams.delete("sort")
|
||||
} else if (sort !== DEFAULT_SORT) {
|
||||
searchParams.set("sort", sort)
|
||||
}
|
||||
|
||||
const [firstFilter, ...remainingFilters] = filters
|
||||
|
||||
parsedUrl.pathname = basePath
|
||||
if (firstFilter) {
|
||||
parsedUrl.pathname += `/${firstFilter}`
|
||||
}
|
||||
if (remainingFilters.length > 0) {
|
||||
parsedUrl.hash = `#${remainingFilters.join("&")}`
|
||||
} else {
|
||||
parsedUrl.hash = ""
|
||||
}
|
||||
|
||||
router.push(parsedUrl.toString(), { scroll: false })
|
||||
}
|
||||
|
||||
if (!storeRef.current) {
|
||||
storeRef.current = createHotelDataStore({
|
||||
allHotels,
|
||||
pathname,
|
||||
searchParams,
|
||||
filterFromUrl,
|
||||
sortItems,
|
||||
submitCallbackFn,
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<HotelDataContext.Provider value={storeRef.current}>
|
||||
{children}
|
||||
</HotelDataContext.Provider>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user