From 0f97757e31f28ad8f481ddc8816ce9f5a4976b16 Mon Sep 17 00:00:00 2001 From: Niclas Edenvin Date: Mon, 11 Nov 2024 08:55:49 +0000 Subject: [PATCH] Merged in feat/sw-620-sort-hotels (pull request #868) Feat/sw-620 sort hotels * SW-620 Add radio button to select box * feat(SW-620): Implement sorting on select hotel * Fix casing * Shallow copy hoteldata * Use translations * Remove unnecessary style * Import order * Type Approved-by: Pontus Dreij --- .../(standard)/select-hotel/page.module.css | 9 +++ .../(standard)/select-hotel/page.tsx | 61 +++++++++++-------- .../HotelCardListing/index.tsx | 43 +++++++++++-- .../SelectHotel/HotelSorter/index.tsx | 56 +++++++++++++++++ components/TempDesignSystem/Select/index.tsx | 3 +- .../TempDesignSystem/Select/select.module.css | 22 ++++++- components/TempDesignSystem/Select/select.ts | 1 + i18n/dictionaries/da.json | 1 + i18n/dictionaries/de.json | 1 + i18n/dictionaries/en.json | 1 + i18n/dictionaries/fi.json | 1 + i18n/dictionaries/no.json | 1 + i18n/dictionaries/sv.json | 1 + .../selectHotel/hotelSorter.ts | 11 ++++ 14 files changed, 179 insertions(+), 33 deletions(-) create mode 100644 components/HotelReservation/SelectHotel/HotelSorter/index.tsx create mode 100644 types/components/hotelReservation/selectHotel/hotelSorter.ts diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/page.module.css b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/page.module.css index 9f8df3025..d8e3db57e 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/page.module.css +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/page.module.css @@ -9,6 +9,15 @@ margin: 0 auto; } +.header { + display: flex; + margin: 0 auto; + padding: var(--Spacing-x4) var(--Spacing-x5) var(--Spacing-x3) + var(--Spacing-x5); + justify-content: space-between; + max-width: var(--max-width); +} + .sideBar { display: flex; flex-direction: column; diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/page.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/page.tsx index e6e4c9757..7ddffacae 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/page.tsx +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/page.tsx @@ -9,6 +9,7 @@ import { } from "@/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/utils" import HotelCardListing from "@/components/HotelReservation/HotelCardListing" import HotelFilter from "@/components/HotelReservation/SelectHotel/HotelFilter" +import HotelSorter from "@/components/HotelReservation/SelectHotel/HotelSorter" import MobileMapButtonContainer from "@/components/HotelReservation/SelectHotel/MobileMapButtonContainer" import { generateChildrenString, @@ -61,33 +62,39 @@ export default async function SelectHotelPage({ const filterList = getFiltersFromHotels(hotels) return ( -
-
- -
- -
- {intl.formatMessage({ id: "Show map" })} - + <> +
+
{city.name}
+ +
+
+
+ +
+ +
+ {intl.formatMessage({ id: "Show map" })} + +
-
- - - -
- -
+ + + + + + + ) } diff --git a/components/HotelReservation/HotelCardListing/index.tsx b/components/HotelReservation/HotelCardListing/index.tsx index e49e6ee09..18b491a45 100644 --- a/components/HotelReservation/HotelCardListing/index.tsx +++ b/components/HotelReservation/HotelCardListing/index.tsx @@ -5,6 +5,7 @@ import { useMemo } from "react" import Title from "@/components/TempDesignSystem/Text/Title" import HotelCard from "../HotelCard" +import { DEFAULT_SORT } from "../SelectHotel/HotelSorter" import styles from "./hotelCardListing.module.css" @@ -12,6 +13,7 @@ import { type HotelCardListingProps, HotelCardListingTypeEnum, } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps" +import { SortOrder } from "@/types/components/hotelReservation/selectHotel/hotelSorter" export default function HotelCardListing({ hotelData, @@ -21,25 +23,58 @@ export default function HotelCardListing({ }: HotelCardListingProps) { const searchParams = useSearchParams() + const sortBy = useMemo( + () => searchParams.get("sort") ?? DEFAULT_SORT, + [searchParams] + ) + + const sortedHotels = useMemo(() => { + switch (sortBy) { + case SortOrder.Name: + return [...hotelData].sort((a, b) => + a.hotelData.name.localeCompare(b.hotelData.name) + ) + case SortOrder.TripAdvisorRating: + return [...hotelData].sort( + (a, b) => + (b.hotelData.ratings?.tripAdvisor.rating ?? 0) - + (a.hotelData.ratings?.tripAdvisor.rating ?? 0) + ) + case SortOrder.Price: + return [...hotelData].sort( + (a, b) => + parseInt(a.price?.memberAmount ?? "0", 10) - + parseInt(b.price?.memberAmount ?? "0", 10) + ) + case SortOrder.Distance: + default: + return [...hotelData].sort( + (a, b) => + a.hotelData.location.distanceToCentre - + b.hotelData.location.distanceToCentre + ) + } + }, [hotelData, sortBy]) + const hotels = useMemo(() => { const appliedFilters = searchParams.get("filters")?.split(",") - if (!appliedFilters || appliedFilters.length === 0) return hotelData + if (!appliedFilters || appliedFilters.length === 0) return sortedHotels - return hotelData.filter((hotel) => + return sortedHotels.filter((hotel) => appliedFilters.every((appliedFilterId) => hotel.hotelData.detailedFacilities.some( (facility) => facility.id.toString() === appliedFilterId ) ) ) - }, [searchParams, hotelData]) + }, [searchParams, sortedHotels]) return (
{hotels?.length ? ( hotels.map((hotel) => ( { + const newSort = value.toString() + if (newSort === searchParams.get("sort")) { + return + } + + const newSearchParams = new URLSearchParams(searchParams) + newSearchParams.set("sort", newSort) + + window.history.replaceState( + null, + "", + `${pathname}?${newSearchParams.toString()}` + ) + }, + [pathname, searchParams] + ) + + return ( +