feat: SW-601 Implement filters and sort in map view

This commit is contained in:
Hrishikesh Vaipurkar
2024-11-19 14:54:11 +01:00
parent ccf332490f
commit bc344e64cf
9 changed files with 120 additions and 8 deletions

View File

@@ -12,7 +12,7 @@ import {
import { MapModal } from "@/components/MapModal"
import { setLang } from "@/i18n/serverContext"
import { fetchAvailableHotels } from "../../utils"
import { fetchAvailableHotels, getFiltersFromHotels } from "../../utils"
import type { SelectHotelSearchParams } from "@/types/components/hotelReservation/selectHotel/selectHotelSearchParams"
import type { LangParams, PageArgs } from "@/types/params"
@@ -57,6 +57,7 @@ export default async function SelectHotelMapPage({
})
const hotelPins = getHotelPins(hotels)
const filterList = getFiltersFromHotels(hotels)
return (
<MapModal>
@@ -65,6 +66,7 @@ export default async function SelectHotelMapPage({
hotelPins={hotelPins}
mapId={googleMapId}
hotels={hotels}
filterList={filterList}
/>
</MapModal>
)

View File

@@ -81,6 +81,10 @@
flex: 0 0 auto;
}
.title {
display: none;
}
.close {
background: none;
border: none;
@@ -97,3 +101,69 @@
flex: 0 0 auto;
border-top: 1px solid var(--Base-Border-Subtle);
}
@media screen and (min-width: 768px) {
.modal {
left: 50%;
bottom: 50%;
height: min(80dvh, 680px);
width: min(80dvw, 960px);
translate: -50% 50%;
overflow-y: auto;
}
.header {
display: grid;
grid-template-columns: auto 1fr;
padding: var(--Spacing-x2) var(--Spacing-x3);
align-items: center;
border-bottom: 1px solid var(--Base-Border-Subtle);
position: sticky;
top: 0;
background: var(--Base-Surface-Primary-light-Normal);
z-index: 1;
border-top-left-radius: var(--Corner-radius-large);
border-top-right-radius: var(--Corner-radius-large);
}
.title {
display: block;
}
.content {
gap: var(--Spacing-x4);
height: auto;
}
.filters {
overflow-y: unset;
}
.sorter,
.filters,
.footer,
.divider {
padding: 0 var(--Spacing-x3);
}
.footer {
flex-direction: row-reverse;
justify-content: space-between;
position: sticky;
bottom: 0;
background: var(--Base-Surface-Primary-light-Normal);
z-index: 1;
border-bottom-left-radius: var(--Corner-radius-large);
border-bottom-right-radius: var(--Corner-radius-large);
padding: var(--Spacing-x2) var(--Spacing-x3);
}
.filters aside h1 {
margin-bottom: var(--Spacing-x2);
}
.filters aside > div:last-child {
margin-top: var(--Spacing-x4);
padding-bottom: 0;
}
}

View File

@@ -12,6 +12,8 @@ import { useHotelFilterStore } from "@/stores/hotel-filters"
import { CloseLargeIcon, FilterIcon } from "@/components/Icons"
import Button from "@/components/TempDesignSystem/Button"
import Divider from "@/components/TempDesignSystem/Divider"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import HotelFilter from "../HotelFilter"
import HotelSorter from "../HotelSorter"
@@ -47,12 +49,20 @@ export default function FilterAndSortModal({
>
<CloseLargeIcon />
</button>
<Subtitle
type="two"
textAlign="center"
className={styles.title}
>
{intl.formatMessage({ id: "Filter and sort" })}
</Subtitle>
</header>
<div className={styles.sorter}>
<HotelSorter />
</div>
<Divider color="subtle" className="divider" />
<div className={styles.filters}>
<HotelFilter filters={filters} />
<HotelFilter filters={filters} type="modal" />
</div>
<footer className={styles.footer}>
<Button

View File

@@ -38,3 +38,17 @@
height: 1.25rem;
margin: 0;
}
@media screen and (min-width: 768px) {
.facilities ul.modal {
display: grid;
grid-template-columns: auto auto auto;
margin-top: var(--Spacing-x3);
}
}
@media screen and (min-width: 768px) and (max-width: 1023) {
.facilities ul.modal {
grid-template-columns: auto auto;
}
}

View File

@@ -15,7 +15,11 @@ import styles from "./hotelFilter.module.css"
import type { HotelFiltersProps } from "@/types/components/hotelReservation/selectHotel/hotelFilters"
export default function HotelFilter({ className, filters }: HotelFiltersProps) {
export default function HotelFilter({
className,
filters,
type,
}: HotelFiltersProps) {
const intl = useIntl()
const searchParams = useSearchParams()
const pathname = usePathname()
@@ -63,7 +67,7 @@ export default function HotelFilter({ className, filters }: HotelFiltersProps) {
<Title as="h4">{intl.formatMessage({ id: "Filter by" })}</Title>
<div className={styles.facilities}>
<Subtitle>{intl.formatMessage({ id: "Hotel facilities" })}</Subtitle>
<ul>
<ul className={type ? styles.modal : ""}>
{filters.facilityFilters.map((filter) => (
<li key={`li-${filter.id}`} className={styles.filter}>
<FilterCheckbox
@@ -81,7 +85,7 @@ export default function HotelFilter({ className, filters }: HotelFiltersProps) {
<div className={styles.facilities}>
<Subtitle>{intl.formatMessage({ id: "Hotel surroundings" })}</Subtitle>
<ul>
<ul className={type ? styles.modal : ""}>
{filters.surroundingsFilters.map((filter) => (
<li key={`li-${filter.id}`} className={styles.filter}>
<FilterCheckbox

View File

@@ -13,6 +13,7 @@ import { BackToTopButton } from "@/components/TempDesignSystem/BackToTopButton"
import Button from "@/components/TempDesignSystem/Button"
import useLang from "@/hooks/useLang"
import FilterAndSortModal from "../FilterAndSortModal"
import HotelListing from "./HotelListing"
import { getCentralCoordinates } from "./utils"
@@ -25,6 +26,7 @@ export default function SelectHotelMap({
hotelPins,
mapId,
hotels,
filterList,
}: SelectHotelMapProps) {
const searchParams = useSearchParams()
const router = useRouter()
@@ -102,8 +104,7 @@ export default function SelectHotelMap({
>
<CloseLargeIcon />
</Button>
<span>Filter and sort</span>
{/* TODO: Add filter and sort button */}
<FilterAndSortModal filters={filterList} />
</div>
<HotelListing
hotels={hotels}

View File

@@ -41,4 +41,9 @@
.container {
display: flex;
}
.filterContainer {
justify-content: flex-end;
padding: 0 0 var(--Spacing-x1);
}
}

View File

@@ -7,6 +7,7 @@ export type CategorizedFilters = {
export type HotelFiltersProps = {
filters: CategorizedFilters
className?: string
type?: "modal"
}
export type Filter = {
@@ -16,3 +17,7 @@ export type Filter = {
sortOrder: number
filter?: string
}
export type HotelFilterModalProps = {
filters: CategorizedFilters
}

View File

@@ -6,7 +6,7 @@ import {
} from "@/server/routers/hotels/schemas/image"
import { HotelData } from "./hotelCardListingProps"
import { Filter } from "./hotelFilters"
import { CategorizedFilters, Filter } from "./hotelFilters"
import type { Coordinates } from "@/types/components/maps/coordinates"
@@ -21,6 +21,7 @@ export interface SelectHotelMapProps {
hotelPins: HotelPin[]
mapId: string
hotels: HotelData[]
filterList: CategorizedFilters
}
type ImageSizes = z.infer<typeof imageSizesSchema>