feat/sw-251 Filter hotels on select hotel page

This commit is contained in:
Niclas Edenvin
2024-11-06 15:22:02 +01:00
parent 560fb25aee
commit a8558eb499
5 changed files with 124 additions and 20 deletions

View File

@@ -1,3 +1,6 @@
"use client"
import { useIntl } from "react-intl"
import { mapFacilityToIcon } from "@/components/ContentType/HotelPage/data"
import { PriceTagIcon, ScandicLogoIcon } from "@/components/Icons"
import TripAdvisorIcon from "@/components/Icons/TripAdvisor"
@@ -17,8 +20,8 @@ import styles from "./hotelCard.module.css"
import type { HotelCardProps } from "@/types/components/hotelReservation/selectHotel/hotelCardProps"
export default async function HotelCard({ hotel }: HotelCardProps) {
const intl = await getIntl()
export default function HotelCard({ hotel }: HotelCardProps) {
const intl = useIntl()
const { hotelData } = hotel
const { price } = hotel

View File

@@ -1,3 +1,7 @@
"use client"
import { useSearchParams } from "next/navigation"
import { useMemo } from "react"
import Title from "@/components/TempDesignSystem/Text/Title"
import HotelCard from "../HotelCard"
@@ -7,12 +11,25 @@ import styles from "./hotelCardListing.module.css"
import { HotelCardListingProps } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps"
export default function HotelCardListing({ hotelData }: HotelCardListingProps) {
// TODO: filter with url params
const searchParams = useSearchParams()
const hotels = useMemo(() => {
const appliedFilters = searchParams.get("filters")?.split(",")
if (!appliedFilters || appliedFilters.length === 0) return hotelData
return hotelData.filter((hotel) =>
appliedFilters.every((appliedFilterId) =>
hotel.hotelData.detailedFacilities.some(
(facility) => facility.id.toString() === appliedFilterId
)
)
)
}, [searchParams, hotelData])
return (
<section className={styles.hotelCards}>
{hotelData && hotelData.length ? (
hotelData.map((hotel) => (
{hotels.length ? (
hotels.map((hotel) => (
<HotelCard key={hotel.hotelData.name} hotel={hotel} />
))
) : (

View File

@@ -1,5 +1,8 @@
"use client"
import { usePathname, useSearchParams } from "next/navigation"
import { useCallback, useEffect } from "react"
import { useForm } from "react-hook-form"
import { useIntl } from "react-intl"
import styles from "./hotelFilter.module.css"
@@ -8,26 +11,77 @@ import { HotelFiltersProps } from "@/types/components/hotelReservation/selectHot
export default function HotelFilter({ filters }: HotelFiltersProps) {
const intl = useIntl()
const searchParams = useSearchParams()
const pathname = usePathname()
function handleOnChange() {
// TODO: Update URL with selected values
}
const { watch, handleSubmit, getValues, register } = useForm<
Record<string, boolean | undefined>
>({
defaultValues: searchParams
?.get("filters")
?.split(",")
.reduce((acc, curr) => ({ ...acc, [curr]: true }), {}),
})
const submitFilter = useCallback(() => {
const newSearchParams = new URLSearchParams(searchParams)
const values = Object.entries(getValues())
.filter(([_, value]) => !!value)
.map(([key, _]) => key)
.join(",")
if (values === "") {
newSearchParams.delete("filters")
} else {
newSearchParams.set("filters", values)
}
if (values !== searchParams.values.toString()) {
window.history.replaceState(
null,
"",
`${pathname}?${newSearchParams.toString()}`
)
}
}, [getValues, pathname, searchParams])
useEffect(() => {
const subscription = watch(() => handleSubmit(submitFilter)())
return () => subscription.unsubscribe()
}, [handleSubmit, watch, submitFilter])
return (
<aside className={styles.container}>
<div className={styles.facilities}>
{intl.formatMessage({ id: "Hotel facilities" })}
<form>
<form onSubmit={handleSubmit(submitFilter)}>
{intl.formatMessage({ id: "Hotel facilities" })}
<ul>
{filters.map((data) => (
<li key={data.id} className={styles.filter}>
{filters.facilityFilters.map((filter) => (
<li key={`li-${filter.id}`} className={styles.filter}>
<input
id={`${data.id}`}
name={data.name}
type="checkbox"
onChange={handleOnChange}
id={`checkbox-${filter.id.toString()}`}
{...register(filter.id.toString())}
/>
<label htmlFor={`${data?.id}`}>{data?.name}</label>
<label htmlFor={`checkbox-${filter.id.toString()}`}>
{filter.name}
</label>
</li>
))}
</ul>
{intl.formatMessage({ id: "Hotel surroundings" })}
<ul>
{filters.surroundingsFilters.map((filter) => (
<li key={`li-${filter.id}`} className={styles.filter}>
<input
type="checkbox"
id={`checkbox-${filter.id.toString()}`}
{...register(filter.id.toString())}
/>
<label htmlFor={`checkbox-${filter.id.toString()}`}>
{filter.name}
</label>
</li>
))}
</ul>