From 3ad8bf0197fce7b5ef9aacdffb642e8dad2f6d21 Mon Sep 17 00:00:00 2001 From: Pontus Dreij Date: Tue, 29 Oct 2024 12:07:20 +0100 Subject: [PATCH 01/11] Added See on map button --- .../(standard)/select-hotel/page.module.css | 13 +++++ .../(standard)/select-hotel/page.tsx | 55 ++++++++++++------- 2 files changed, 48 insertions(+), 20 deletions(-) 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 acc942e21..dfb4c68bd 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 @@ -19,7 +19,20 @@ padding: var(--Spacing-x2) var(--Spacing-x0); } +.mapContainer { + display: none; +} + +.buttonContainer { + display: flex; + gap: var(--Spacing-x2); + margin-bottom: var(--Spacing-x3); +} + @media (min-width: 768px) { + .mapContainer { + display: block; + } .main { flex-direction: row; } 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 3ebe54958..cec055445 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/page.tsx +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/page.tsx @@ -13,8 +13,9 @@ import { generateChildrenString, getHotelReservationQueryParams, } from "@/components/HotelReservation/SelectRate/RoomSelection/utils" -import { ChevronRightIcon } from "@/components/Icons" +import { ChevronRightIcon, MapIcon } from "@/components/Icons" import StaticMap from "@/components/Maps/StaticMap" +import Button from "@/components/TempDesignSystem/Button" import Link from "@/components/TempDesignSystem/Link" import { getIntl } from "@/i18n" import { setLang } from "@/i18n/serverContext" @@ -62,25 +63,39 @@ export default async function SelectHotelPage({ return (
- - - - - {intl.formatMessage({ id: "Show map" })} - - +
+ + + + + {intl.formatMessage({ id: "Show map" })} + + +
+
+ +
From 6debd2d89856f8f2140985d99dbc647697359146 Mon Sep 17 00:00:00 2001 From: Pontus Dreij Date: Tue, 29 Oct 2024 12:12:14 +0100 Subject: [PATCH 02/11] feat(sw-343): Added "See on map" translations --- 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 + 6 files changed, 6 insertions(+) diff --git a/i18n/dictionaries/da.json b/i18n/dictionaries/da.json index 8bc08cc13..6a253deb6 100644 --- a/i18n/dictionaries/da.json +++ b/i18n/dictionaries/da.json @@ -286,6 +286,7 @@ "See all photos": "Se alle billeder", "See hotel details": "Se hoteloplysninger", "See less FAQ": "Se mindre FAQ", + "See on map": "Se på kort", "See room details": "Se værelsesdetaljer", "See rooms": "Se værelser", "Select a country": "Vælg et land", diff --git a/i18n/dictionaries/de.json b/i18n/dictionaries/de.json index e72d5bffc..a26b4b751 100644 --- a/i18n/dictionaries/de.json +++ b/i18n/dictionaries/de.json @@ -285,6 +285,7 @@ "See all photos": "Alle Fotos ansehen", "See hotel details": "Hotelinformationen ansehen", "See less FAQ": "Weniger anzeigen FAQ", + "See on map": "Karte ansehen", "See room details": "Zimmerdetails ansehen", "See rooms": "Zimmer ansehen", "Select a country": "Wähle ein Land", diff --git a/i18n/dictionaries/en.json b/i18n/dictionaries/en.json index 177c4a803..d1cd64e00 100644 --- a/i18n/dictionaries/en.json +++ b/i18n/dictionaries/en.json @@ -299,6 +299,7 @@ "See all photos": "See all photos", "See hotel details": "See hotel details", "See less FAQ": "See less FAQ", + "See on map": "See on map", "See room details": "See room details", "See rooms": "See rooms", "Select a country": "Select a country", diff --git a/i18n/dictionaries/fi.json b/i18n/dictionaries/fi.json index 28703bc14..8abb46922 100644 --- a/i18n/dictionaries/fi.json +++ b/i18n/dictionaries/fi.json @@ -287,6 +287,7 @@ "See all photos": "Katso kaikki kuvat", "See hotel details": "Katso hotellin tiedot", "See less FAQ": "Katso vähemmän UKK", + "See on map": "Näytä kartalla", "See room details": "Katso huoneen tiedot", "See rooms": "Katso huoneet", "Select a country": "Valitse maa", diff --git a/i18n/dictionaries/no.json b/i18n/dictionaries/no.json index f1f0a38ac..fcbe82391 100644 --- a/i18n/dictionaries/no.json +++ b/i18n/dictionaries/no.json @@ -284,6 +284,7 @@ "See all photos": "Se alle bilder", "See hotel details": "Se hotellinformasjon", "See less FAQ": "Se mindre FAQ", + "See on map": "Se på kart", "See room details": "Se detaljer om rommet", "See rooms": "Se rom", "Select a country": "Velg et land", diff --git a/i18n/dictionaries/sv.json b/i18n/dictionaries/sv.json index 0aeb71644..6d22fdea0 100644 --- a/i18n/dictionaries/sv.json +++ b/i18n/dictionaries/sv.json @@ -284,6 +284,7 @@ "See all photos": "Se alla foton", "See hotel details": "Se hotellinformation", "See less FAQ": "See färre FAQ", + "See on map": "Se på karta", "See room details": "Se rumsdetaljer", "See rooms": "Se rum", "Select a country": "Välj ett land", From 0aed1d9d575c2447f065ef87bb52be91515bc51b Mon Sep 17 00:00:00 2001 From: Pontus Dreij Date: Wed, 30 Oct 2024 10:37:43 +0100 Subject: [PATCH 03/11] feat(sw-343) added buttons to open map in mobile --- .../select-hotel/map/page.module.css | 8 +++- .../(standard)/select-hotel/page.module.css | 9 +++- .../(standard)/select-hotel/page.tsx | 17 ++----- .../HotelFilter/hotelFilter.module.css | 7 +++ .../MobileButtonContainer/index.tsx | 48 +++++++++++++++++++ .../mobileButtonContainer.module.css | 0 .../HotelListing/hotelListing.module.css | 9 ++++ .../SelectHotelMap/HotelListing/index.tsx | 4 +- .../SelectHotel/SelectHotelMap/index.tsx | 16 +++++++ .../SelectHotelMap/selectHotelMap.module.css | 23 +++++++++ components/Icons/Filter.tsx | 23 +++++++++ components/Icons/index.tsx | 1 + 12 files changed, 148 insertions(+), 17 deletions(-) create mode 100644 components/HotelReservation/SelectHotel/MobileButtonContainer/index.tsx create mode 100644 components/HotelReservation/SelectHotel/MobileButtonContainer/mobileButtonContainer.module.css create mode 100644 components/HotelReservation/SelectHotel/SelectHotelMap/HotelListing/hotelListing.module.css create mode 100644 components/Icons/Filter.tsx diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/page.module.css b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/page.module.css index ec9b9ce4f..3fdff19f7 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/page.module.css +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/page.module.css @@ -2,5 +2,11 @@ display: grid; background-color: var(--Scandic-Brand-Warm-White); min-height: 100dvh; - grid-template-columns: 420px 1fr; + position: relative; +} + +@media (min-width: 768px) { + .main { + grid-template-columns: 420px 1fr; + } } 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 dfb4c68bd..800ffe8f9 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 @@ -1,6 +1,6 @@ .main { display: flex; - gap: var(--Spacing-x4); + gap: var(--Spacing-x3); padding: var(--Spacing-x4) var(--Spacing-x4) 0 var(--Spacing-x4); background-color: var(--Scandic-Brand-Warm-White); min-height: 100dvh; @@ -29,6 +29,10 @@ margin-bottom: var(--Spacing-x3); } +.button { + flex: 1; +} + @media (min-width: 768px) { .mapContainer { display: block; @@ -36,4 +40,7 @@ .main { flex-direction: row; } + .buttonContainer { + display: none; + } } 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 cec055445..7977ff63b 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/page.tsx +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/page.tsx @@ -9,13 +9,13 @@ 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 MobileButtonContainer from "@/components/HotelReservation/SelectHotel/MobileButtonContainer" import { generateChildrenString, getHotelReservationQueryParams, } from "@/components/HotelReservation/SelectRate/RoomSelection/utils" -import { ChevronRightIcon, MapIcon } from "@/components/Icons" +import { ChevronRightIcon } from "@/components/Icons" import StaticMap from "@/components/Maps/StaticMap" -import Button from "@/components/TempDesignSystem/Button" import Link from "@/components/TempDesignSystem/Link" import { getIntl } from "@/i18n" import { setLang } from "@/i18n/serverContext" @@ -84,18 +84,7 @@ export default async function SelectHotelPage({ -
- -
+ diff --git a/components/HotelReservation/SelectHotel/HotelFilter/hotelFilter.module.css b/components/HotelReservation/SelectHotel/HotelFilter/hotelFilter.module.css index 737eca4d9..156874b54 100644 --- a/components/HotelReservation/SelectHotel/HotelFilter/hotelFilter.module.css +++ b/components/HotelReservation/SelectHotel/HotelFilter/hotelFilter.module.css @@ -1,5 +1,6 @@ .container { min-width: 272px; + display: none; } .facilities { @@ -24,3 +25,9 @@ height: 1.25rem; margin: 0; } + +@media (min-width: 768px) { + .container { + display: block; + } +} diff --git a/components/HotelReservation/SelectHotel/MobileButtonContainer/index.tsx b/components/HotelReservation/SelectHotel/MobileButtonContainer/index.tsx new file mode 100644 index 000000000..1df90483f --- /dev/null +++ b/components/HotelReservation/SelectHotel/MobileButtonContainer/index.tsx @@ -0,0 +1,48 @@ +"use client" + +import { useIntl } from "react-intl" + +import { selectHotelMap } from "@/constants/routes/hotelReservation" + +import { FilterIcon, MapIcon } from "@/components/Icons" +import Button from "@/components/TempDesignSystem/Button" +import Link from "@/components/TempDesignSystem/Link" +import useLang from "@/hooks/useLang" + +import styles from "./mobileButtonContainer.module.css" + +export default function MobileButtonContainer({ city }: { city: string }) { + const intl = useIntl() + const lang = useLang() + + return ( +
+ + {/* TODO: Add filter toggle */} + +
+ ) +} diff --git a/components/HotelReservation/SelectHotel/MobileButtonContainer/mobileButtonContainer.module.css b/components/HotelReservation/SelectHotel/MobileButtonContainer/mobileButtonContainer.module.css new file mode 100644 index 000000000..e69de29bb diff --git a/components/HotelReservation/SelectHotel/SelectHotelMap/HotelListing/hotelListing.module.css b/components/HotelReservation/SelectHotel/SelectHotelMap/HotelListing/hotelListing.module.css new file mode 100644 index 000000000..9ebb0678e --- /dev/null +++ b/components/HotelReservation/SelectHotel/SelectHotelMap/HotelListing/hotelListing.module.css @@ -0,0 +1,9 @@ +.hotelListing { + display: none; +} + +@media (min-width: 768px) { + .hotelListing { + display: block; + } +} diff --git a/components/HotelReservation/SelectHotel/SelectHotelMap/HotelListing/index.tsx b/components/HotelReservation/SelectHotel/SelectHotelMap/HotelListing/index.tsx index 4bcdb2d68..ecb639250 100644 --- a/components/HotelReservation/SelectHotel/SelectHotelMap/HotelListing/index.tsx +++ b/components/HotelReservation/SelectHotel/SelectHotelMap/HotelListing/index.tsx @@ -1,5 +1,7 @@ "use client" +import styles from "./hotelListing.module.css" + import { HotelListingProps } from "@/types/components/hotelReservation/selectHotel/map" // TODO: This component is copied from @@ -7,5 +9,5 @@ import { HotelListingProps } from "@/types/components/hotelReservation/selectHot // Look at that for inspiration on how to do the interaction with the map. export default function HotelListing({}: HotelListingProps) { - return
Hotel listing TBI
+ return
Hotel listing TBI
} diff --git a/components/HotelReservation/SelectHotel/SelectHotelMap/index.tsx b/components/HotelReservation/SelectHotel/SelectHotelMap/index.tsx index b14538812..cd63a00bf 100644 --- a/components/HotelReservation/SelectHotel/SelectHotelMap/index.tsx +++ b/components/HotelReservation/SelectHotel/SelectHotelMap/index.tsx @@ -43,6 +43,22 @@ export default function SelectHotelMap({ ) return ( +
+ + Filter and sort + {/* TODO: Add filter and sort button */} +
+ + + ) +} diff --git a/components/Icons/index.tsx b/components/Icons/index.tsx index ce23296fe..a8be6f48f 100644 --- a/components/Icons/index.tsx +++ b/components/Icons/index.tsx @@ -45,6 +45,7 @@ export { default as ErrorCircleIcon } from "./ErrorCircle" export { default as EyeHideIcon } from "./EyeHide" export { default as EyeShowIcon } from "./EyeShow" export { default as FanIcon } from "./Fan" +export { default as FilterIcon } from "./Filter" export { default as FitnessIcon } from "./Fitness" export { default as FootstoolIcon } from "./Footstool" export { default as GalleryIcon } from "./Gallery" From efad3381b6c8ecd7ce1303108f6e2ce080604ac4 Mon Sep 17 00:00:00 2001 From: Pontus Dreij Date: Thu, 31 Oct 2024 09:09:22 +0100 Subject: [PATCH 04/11] feat(sw-343) set up intercepted routes for map modal --- .../select-hotel/@modal/(.)map/modal.tsx | 30 +++++++ .../select-hotel/@modal/(.)map/page.tsx | 79 +++++++++++++++++++ .../select-hotel/@modal/default.tsx | 3 + .../(standard)/select-hotel/layout.module.css | 4 + .../(standard)/select-hotel/layout.tsx | 24 ++++++ .../(standard)/select-hotel/map/page.tsx | 56 +++++++------ .../(standard)/select-hotel/utils.ts | 43 +++++++++- .../MobileButtonContainer/index.tsx | 2 +- .../mobileButtonContainer.module.css | 15 ++++ components/MapModal/index.tsx | 43 ++++++++++ components/MapModal/mapModal.module.css | 18 +++++ 11 files changed, 291 insertions(+), 26 deletions(-) create mode 100644 app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/modal.tsx create mode 100644 app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/page.tsx create mode 100644 app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/default.tsx create mode 100644 app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/layout.module.css create mode 100644 app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/layout.tsx create mode 100644 components/MapModal/index.tsx create mode 100644 components/MapModal/mapModal.module.css diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/modal.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/modal.tsx new file mode 100644 index 000000000..ab8e0a451 --- /dev/null +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/modal.tsx @@ -0,0 +1,30 @@ +"use client" + +import { useRouter } from "next/navigation" +import { type ElementRef, useEffect, useRef } from "react" + +export function Modal({ children }: { children: React.ReactNode }) { + const router = useRouter() + const dialogRef = useRef>(null) + + console.log("modal is open") + + useEffect(() => { + if (!dialogRef.current?.open) { + dialogRef.current?.showModal() + } + }, []) + + function onDismiss() { + router.back() + } + + return ( +
+ + {children} + +
+ ) +} diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/page.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/page.tsx new file mode 100644 index 000000000..6df8e0fec --- /dev/null +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/page.tsx @@ -0,0 +1,79 @@ +import { notFound } from "next/navigation" + +import { env } from "@/env/server" +import { getLocations } from "@/lib/trpc/memoizedRequests" + +import SelectHotelMap from "@/components/HotelReservation/SelectHotel/SelectHotelMap" +import getHotelReservationQueryParams from "@/components/HotelReservation/SelectRate/RoomSelection/utils" +import { MapModal } from "@/components/MapModal" +import { setLang } from "@/i18n/serverContext" + +import { + fetchAvailableHotels, + generateChildrenString, + getPointOfInterests, +} from "../../utils" + +import type { SelectHotelSearchParams } from "@/types/components/hotelReservation/selectHotel/selectHotelSearchParams" +import type { LangParams, PageArgs } from "@/types/params" + +export default async function SelectHotelMapPage({ + params, + searchParams, +}: PageArgs) { + setLang(params.lang) + const locations = await getLocations() + + if (!locations || "error" in locations) { + return null + } + const city = locations.data.find( + (location) => + location.name.toLowerCase() === searchParams.city.toLowerCase() + ) + if (!city) return notFound() + + const googleMapId = env.GOOGLE_DYNAMIC_MAP_ID + const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY + + const selectHotelParams = new URLSearchParams(searchParams) + const selectHotelParamsObject = + getHotelReservationQueryParams(selectHotelParams) + const adults = selectHotelParamsObject.room[0].adults // TODO: Handle multiple rooms + const children = selectHotelParamsObject.room[0].child + ? generateChildrenString(selectHotelParamsObject.room[0].child) + : undefined // TODO: Handle multiple rooms + + const hotels = await fetchAvailableHotels({ + cityId: city.id, + roomStayStartDate: searchParams.fromDate, + roomStayEndDate: searchParams.toDate, + adults, + children, + }) + + const pointOfInterests = getPointOfInterests(hotels) + + const centralCoordinates = pointOfInterests.reduce( + (acc, poi) => { + acc.lat += poi.coordinates.lat + acc.lng += poi.coordinates.lng + return acc + }, + { lat: 0, lng: 0 } + ) + + centralCoordinates.lat /= pointOfInterests.length + centralCoordinates.lng /= pointOfInterests.length + + return ( + + + + ) +} diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/default.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/default.tsx new file mode 100644 index 000000000..86b9e9a38 --- /dev/null +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/default.tsx @@ -0,0 +1,3 @@ +export default function Default() { + return null +} diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/layout.module.css b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/layout.module.css new file mode 100644 index 000000000..0969a7151 --- /dev/null +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/layout.module.css @@ -0,0 +1,4 @@ +.layout { + min-height: 100dvh; + background-color: var(--Base-Background-Primary-Normal); +} diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/layout.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/layout.tsx new file mode 100644 index 000000000..ab5f62674 --- /dev/null +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/layout.tsx @@ -0,0 +1,24 @@ +import { notFound } from "next/navigation" + +import { env } from "@/env/server" + +import styles from "./layout.module.css" + +import { LangParams, LayoutArgs } from "@/types/params" + +export default function HotelReservationLayout({ + children, + modal, +}: React.PropsWithChildren< + LayoutArgs & { modal: React.ReactNode } +>) { + if (env.HIDE_FOR_NEXT_RELEASE) { + return notFound() + } + return ( +
+ {children} + {modal} +
+ ) +} diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/page.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/page.tsx index 8dca8f4c7..4c09e3bd8 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/page.tsx +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/page.tsx @@ -1,48 +1,60 @@ +import { notFound } from "next/navigation" + import { env } from "@/env/server" +import { getLocations } from "@/lib/trpc/memoizedRequests" import { fetchAvailableHotels, + generateChildrenString, getFiltersFromHotels, + getPointOfInterests, } from "@/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/utils" import SelectHotelMap from "@/components/HotelReservation/SelectHotel/SelectHotelMap" +import getHotelReservationQueryParams from "@/components/HotelReservation/SelectRate/RoomSelection/utils" import { setLang } from "@/i18n/serverContext" import styles from "./page.module.css" -import { - PointOfInterest, - PointOfInterestCategoryNameEnum, - PointOfInterestGroupEnum, -} from "@/types/hotel" -import { LangParams, PageArgs } from "@/types/params" +import { type SelectHotelSearchParams } from "@/types/components/hotelReservation/selectHotel/selectHotelSearchParams" +import type { LangParams, PageArgs } from "@/types/params" export default async function SelectHotelMapPage({ params, -}: PageArgs) { + searchParams, +}: PageArgs) { const googleMapId = env.GOOGLE_DYNAMIC_MAP_ID const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY setLang(params.lang) + const locations = await getLocations() + + if (!locations || "error" in locations) { + return null + } + const city = locations.data.find( + (location) => + location.name.toLowerCase() === searchParams.city.toLowerCase() + ) + if (!city) return notFound() + + const selectHotelParams = new URLSearchParams(searchParams) + const selectHotelParamsObject = + getHotelReservationQueryParams(selectHotelParams) + const adults = selectHotelParamsObject.room[0].adults // TODO: Handle multiple rooms + const children = selectHotelParamsObject.room[0].child + ? generateChildrenString(selectHotelParamsObject.room[0].child) + : undefined // TODO: Handle multiple rooms const hotels = await fetchAvailableHotels({ - cityId: "8ec4bba3-1c38-4606-82d1-bbe3f6738e54", - roomStayStartDate: "2024-11-02", - roomStayEndDate: "2024-11-03", - adults: 1, + cityId: city.id, + roomStayStartDate: searchParams.fromDate, + roomStayEndDate: searchParams.toDate, + adults, + children, }) const filters = getFiltersFromHotels(hotels) - // TODO: this is just a quick transformation to get something there. May need rework - const pointOfInterests: PointOfInterest[] = hotels.map((hotel) => ({ - coordinates: { - lat: hotel.hotelData.location.latitude, - lng: hotel.hotelData.location.longitude, - }, - name: hotel.hotelData.name, - distance: hotel.hotelData.location.distanceToCentre, - categoryName: PointOfInterestCategoryNameEnum.HOTEL, - group: PointOfInterestGroupEnum.LOCATION, - })) + const pointOfInterests = getPointOfInterests(hotels) return (
diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/utils.ts b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/utils.ts index 8dfc76a1d..b14268126 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/utils.ts +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/utils.ts @@ -2,9 +2,16 @@ import { serverClient } from "@/lib/trpc/server" import { getLang } from "@/i18n/serverContext" -import { AvailabilityInput } from "@/types/components/hotelReservation/selectHotel/availabilityInput" -import { HotelData } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps" -import { Filter } from "@/types/components/hotelReservation/selectHotel/hotelFilters" +import { BedTypeEnum } from "@/types/components/bookingWidget/enums" +import type { AvailabilityInput } from "@/types/components/hotelReservation/selectHotel/availabilityInput" +import type { HotelData } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps" +import type { Filter } from "@/types/components/hotelReservation/selectHotel/hotelFilters" +import type { Child } from "@/types/components/hotelReservation/selectRate/selectRate" +import { + type PointOfInterest, + PointOfInterestCategoryNameEnum, + PointOfInterestGroupEnum, +} from "@/types/hotel" export async function fetchAvailableHotels( input: AvailabilityInput @@ -41,3 +48,33 @@ export function getFiltersFromHotels(hotels: HotelData[]) { return filterList } + +const bedTypeMap: Record = { + [BedTypeEnum.IN_ADULTS_BED]: "ParentsBed", + [BedTypeEnum.IN_CRIB]: "Crib", + [BedTypeEnum.IN_EXTRA_BED]: "ExtraBed", +} + +export function generateChildrenString(children: Child[]): string { + return `[${children + ?.map((child) => { + const age = child.age + const bedType = bedTypeMap[+child.bed] + return `${age}:${bedType}` + }) + .join(",")}]` +} + +export function getPointOfInterests(hotels: HotelData[]): PointOfInterest[] { + // TODO: this is just a quick transformation to get something there. May need rework + return hotels.map((hotel) => ({ + coordinates: { + lat: hotel.hotelData.location.latitude, + lng: hotel.hotelData.location.longitude, + }, + name: hotel.hotelData.name, + distance: hotel.hotelData.location.distanceToCentre, + categoryName: PointOfInterestCategoryNameEnum.HOTEL, + group: PointOfInterestGroupEnum.LOCATION, + })) +} diff --git a/components/HotelReservation/SelectHotel/MobileButtonContainer/index.tsx b/components/HotelReservation/SelectHotel/MobileButtonContainer/index.tsx index 1df90483f..730cd780b 100644 --- a/components/HotelReservation/SelectHotel/MobileButtonContainer/index.tsx +++ b/components/HotelReservation/SelectHotel/MobileButtonContainer/index.tsx @@ -25,7 +25,7 @@ export default function MobileButtonContainer({ city }: { city: string }) { className={styles.button} > diff --git a/components/HotelReservation/SelectHotel/MobileButtonContainer/mobileButtonContainer.module.css b/components/HotelReservation/SelectHotel/MobileButtonContainer/mobileButtonContainer.module.css index e69de29bb..5d0610d8f 100644 --- a/components/HotelReservation/SelectHotel/MobileButtonContainer/mobileButtonContainer.module.css +++ b/components/HotelReservation/SelectHotel/MobileButtonContainer/mobileButtonContainer.module.css @@ -0,0 +1,15 @@ +.buttonContainer { + display: flex; + gap: var(--Spacing-x2); + margin-bottom: var(--Spacing-x3); +} + +.button { + flex: 1; +} + +@media (min-width: 768px) { + .buttonContainer { + display: none; + } +} diff --git a/components/MapModal/index.tsx b/components/MapModal/index.tsx new file mode 100644 index 000000000..8064355cb --- /dev/null +++ b/components/MapModal/index.tsx @@ -0,0 +1,43 @@ +"use client" + +import { useRouter } from "next/navigation" +import { useEffect, useRef, useState } from "react" +import { Dialog, Modal } from "react-aria-components" + +import styles from "./mapModal.module.css" + +export function MapModal({ children }: { children: React.ReactNode }) { + const router = useRouter() + const [scrollHeightWhenOpened, setScrollHeightWhenOpened] = useState(0) + const hasMounted = useRef(false) + + function onDismiss() { + router.back() + } + + // Making sure the map is always opened at the top of the page, just below the header. + // When closing, the page should scroll back to the position it was before opening the map. + useEffect(() => { + // Skip the first render + if (!hasMounted.current) { + hasMounted.current = true + return + } + + if (scrollHeightWhenOpened === 0) { + setScrollHeightWhenOpened(window.scrollY) + window.scrollTo({ top: 0, behavior: "instant" }) + } + }, [scrollHeightWhenOpened]) + + return ( + + + {children} + + + + ) +} diff --git a/components/MapModal/mapModal.module.css b/components/MapModal/mapModal.module.css new file mode 100644 index 000000000..31029868e --- /dev/null +++ b/components/MapModal/mapModal.module.css @@ -0,0 +1,18 @@ +.dynamicMap { + position: fixed; + top: calc( + var(--main-menu-mobile-height) + var(--booking-widget-mobile-height) - 4px + ); + right: 0; + bottom: 0; + left: 0; + z-index: var(--dialog-z-index); + display: flex; + background-color: var(--Base-Surface-Primary-light-Normal); +} + +@media screen and (min-width: 768px) { + .dynamicMap { + top: var(--main-menu-desktop-height); + } +} From 3a5ec28dc19e7532c5ffb8a984c8fc668c738482 Mon Sep 17 00:00:00 2001 From: Pontus Dreij Date: Fri, 1 Nov 2024 09:39:34 +0100 Subject: [PATCH 05/11] feat(343): Style fixes on map --- .../select-hotel/@modal/(.)map/modal.tsx | 30 -------- .../select-hotel/@modal/(.)map/page.tsx | 2 +- .../(standard)/select-hotel/layout.module.css | 1 + .../(standard)/select-hotel/map/page.tsx | 2 +- .../SelectHotel/SelectHotelMap/index.tsx | 23 +++--- .../SelectHotelMap/selectHotelMap.module.css | 6 +- components/MapModal/index.tsx | 75 +++++++++++++++---- components/MapModal/mapModal.module.css | 20 +++-- .../InteractiveMap/interactiveMap.module.css | 1 + 9 files changed, 94 insertions(+), 66 deletions(-) delete mode 100644 app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/modal.tsx diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/modal.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/modal.tsx deleted file mode 100644 index ab8e0a451..000000000 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/modal.tsx +++ /dev/null @@ -1,30 +0,0 @@ -"use client" - -import { useRouter } from "next/navigation" -import { type ElementRef, useEffect, useRef } from "react" - -export function Modal({ children }: { children: React.ReactNode }) { - const router = useRouter() - const dialogRef = useRef>(null) - - console.log("modal is open") - - useEffect(() => { - if (!dialogRef.current?.open) { - dialogRef.current?.showModal() - } - }, []) - - function onDismiss() { - router.back() - } - - return ( -
- - {children} - -
- ) -} diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/page.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/page.tsx index 6df8e0fec..f2c2ab55f 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/page.tsx +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/page.tsx @@ -4,7 +4,7 @@ import { env } from "@/env/server" import { getLocations } from "@/lib/trpc/memoizedRequests" import SelectHotelMap from "@/components/HotelReservation/SelectHotel/SelectHotelMap" -import getHotelReservationQueryParams from "@/components/HotelReservation/SelectRate/RoomSelection/utils" +import { getHotelReservationQueryParams } from "@/components/HotelReservation/SelectRate/RoomSelection/utils" import { MapModal } from "@/components/MapModal" import { setLang } from "@/i18n/serverContext" diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/layout.module.css b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/layout.module.css index 0969a7151..b86e58a72 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/layout.module.css +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/layout.module.css @@ -1,4 +1,5 @@ .layout { min-height: 100dvh; background-color: var(--Base-Background-Primary-Normal); + position: relative; } diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/page.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/page.tsx index 4c09e3bd8..5d0d9e5c4 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/page.tsx +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/page.tsx @@ -10,7 +10,7 @@ import { getPointOfInterests, } from "@/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/utils" import SelectHotelMap from "@/components/HotelReservation/SelectHotel/SelectHotelMap" -import getHotelReservationQueryParams from "@/components/HotelReservation/SelectRate/RoomSelection/utils" +import { getHotelReservationQueryParams } from "@/components/HotelReservation/SelectRate/RoomSelection/utils" import { setLang } from "@/i18n/serverContext" import styles from "./page.module.css" diff --git a/components/HotelReservation/SelectHotel/SelectHotelMap/index.tsx b/components/HotelReservation/SelectHotel/SelectHotelMap/index.tsx index cd63a00bf..3109d5cc3 100644 --- a/components/HotelReservation/SelectHotel/SelectHotelMap/index.tsx +++ b/components/HotelReservation/SelectHotel/SelectHotelMap/index.tsx @@ -1,11 +1,12 @@ "use client" import { APIProvider } from "@vis.gl/react-google-maps" +import { useRouter } from "next/navigation" import { useState } from "react" import { useIntl } from "react-intl" import { selectHotel } from "@/constants/routes/hotelReservation" -import { CloseIcon } from "@/components/Icons" +import { CloseIcon, CloseLargeIcon } from "@/components/Icons" import InteractiveMap from "@/components/Maps/InteractiveMap" import Button from "@/components/TempDesignSystem/Button" import Link from "@/components/TempDesignSystem/Link" @@ -23,38 +24,38 @@ export default function SelectHotelMap({ pointsOfInterest, mapId, }: SelectHotelMapProps) { + const router = useRouter() const lang = useLang() const intl = useIntl() const [activePoi, setActivePoi] = useState(null) + function onDismiss() { + router.back() + } + const closeButton = ( ) return (
Filter and sort {/* TODO: Add filter and sort button */} diff --git a/components/HotelReservation/SelectHotel/SelectHotelMap/selectHotelMap.module.css b/components/HotelReservation/SelectHotel/SelectHotelMap/selectHotelMap.module.css index 7892f77bd..adb35a386 100644 --- a/components/HotelReservation/SelectHotel/SelectHotelMap/selectHotelMap.module.css +++ b/components/HotelReservation/SelectHotel/SelectHotelMap/selectHotelMap.module.css @@ -9,7 +9,7 @@ display: flex; justify-content: space-between; align-items: center; - position: absolute; + position: relative; top: 0; left: 0; right: 0; @@ -18,6 +18,10 @@ padding: 0 var(--Spacing-x2); } +.filterContainer .closeButton { + color: var(--UI-Text-High-Contrast); +} + @media (min-width: 768px) { .closeButton { display: flex !important; diff --git a/components/MapModal/index.tsx b/components/MapModal/index.tsx index 8064355cb..ddedd622f 100644 --- a/components/MapModal/index.tsx +++ b/components/MapModal/index.tsx @@ -1,43 +1,88 @@ "use client" import { useRouter } from "next/navigation" -import { useEffect, useRef, useState } from "react" +import { useCallback, useEffect, useRef, useState } from "react" import { Dialog, Modal } from "react-aria-components" +import { useHandleKeyUp } from "@/hooks/useHandleKeyUp" +import { debounce } from "@/utils/debounce" + import styles from "./mapModal.module.css" export function MapModal({ children }: { children: React.ReactNode }) { const router = useRouter() + const [mapHeight, setMapHeight] = useState("0px") + const [mapTop, setMapTop] = useState("0px") + const [scrollHeightWhenOpened, setScrollHeightWhenOpened] = useState(0) - const hasMounted = useRef(false) + + const rootDiv = useRef(null) function onDismiss() { router.back() } - // Making sure the map is always opened at the top of the page, just below the header. + useHandleKeyUp((event: KeyboardEvent) => { + if (event.key === "Escape") { + onDismiss() + } + }) + + // Calculate the height of the map based on the viewport height from the start-point (below the header and booking widget) + const handleMapHeight = useCallback(() => { + const topPosition = rootDiv.current?.getBoundingClientRect().top ?? 0 + const scrollY = window.scrollY + setMapHeight(`calc(100dvh - ${topPosition + scrollY}px)`) + setMapTop(`${topPosition + scrollY}px`) + }, []) + + // Making sure the map is always opened at the top of the page, + // just below the header and booking widget as these should stay visible. // When closing, the page should scroll back to the position it was before opening the map. useEffect(() => { // Skip the first render - if (!hasMounted.current) { - hasMounted.current = true + if (!rootDiv.current) { return } if (scrollHeightWhenOpened === 0) { - setScrollHeightWhenOpened(window.scrollY) + const scrollY = window.scrollY + setScrollHeightWhenOpened(scrollY) window.scrollTo({ top: 0, behavior: "instant" }) } - }, [scrollHeightWhenOpened]) + }, [scrollHeightWhenOpened, rootDiv]) + + useEffect(() => { + const debouncedResizeHandler = debounce(function () { + handleMapHeight() + }) + + const observer = new ResizeObserver(debouncedResizeHandler) + + observer.observe(document.documentElement) + + return () => { + if (observer) { + observer.unobserve(document.documentElement) + } + } + }, [rootDiv, handleMapHeight]) return ( - - - {children} - - - +
+ + + {children} + + +
) } diff --git a/components/MapModal/mapModal.module.css b/components/MapModal/mapModal.module.css index 31029868e..3000d4673 100644 --- a/components/MapModal/mapModal.module.css +++ b/components/MapModal/mapModal.module.css @@ -1,15 +1,21 @@ .dynamicMap { - position: fixed; - top: calc( - var(--main-menu-mobile-height) + var(--booking-widget-mobile-height) - 4px - ); - right: 0; - bottom: 0; + --hotel-map-height: 100dvh; + --hotel-map-top: 0px; + position: absolute; + top: var(--hotel-map-top); left: 0; - z-index: var(--dialog-z-index); + height: var(--hotel-map-height); + width: 100dvw; + z-index: var(--hotel-dynamic-map-z-index); display: flex; + flex-direction: column; background-color: var(--Base-Surface-Primary-light-Normal); } +.wrapper { + position: absolute; + top: 0; + left: 0; +} @media screen and (min-width: 768px) { .dynamicMap { diff --git a/components/Maps/InteractiveMap/interactiveMap.module.css b/components/Maps/InteractiveMap/interactiveMap.module.css index 557730bfe..471409188 100644 --- a/components/Maps/InteractiveMap/interactiveMap.module.css +++ b/components/Maps/InteractiveMap/interactiveMap.module.css @@ -1,6 +1,7 @@ .mapContainer { --button-box-shadow: 0 0 8px 1px rgba(0, 0, 0, 0.1); width: 100%; + height: 100%; position: relative; z-index: 0; } From 1b008422d3def4f5c6c7ac19f432116f06ff12b2 Mon Sep 17 00:00:00 2001 From: Pontus Dreij Date: Fri, 1 Nov 2024 10:11:27 +0100 Subject: [PATCH 06/11] feat(sw-343): fixed map page (without modal) --- .../select-hotel/@modal/(.)map/page.tsx | 14 +---- .../(standard)/select-hotel/map/page.tsx | 6 +- .../(standard)/select-hotel/utils.ts | 16 ++++++ .../SelectHotel/SelectHotelMap/index.tsx | 56 +++++++++++-------- .../SelectHotelMap/selectHotelMap.module.css | 5 ++ .../hotelReservation/selectHotel/map.ts | 1 + 6 files changed, 61 insertions(+), 37 deletions(-) diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/page.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/page.tsx index f2c2ab55f..eadd81bbb 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/page.tsx +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/page.tsx @@ -11,6 +11,7 @@ import { setLang } from "@/i18n/serverContext" import { fetchAvailableHotels, generateChildrenString, + getCentralCoordinates, getPointOfInterests, } from "../../utils" @@ -54,17 +55,7 @@ export default async function SelectHotelMapPage({ const pointOfInterests = getPointOfInterests(hotels) - const centralCoordinates = pointOfInterests.reduce( - (acc, poi) => { - acc.lat += poi.coordinates.lat - acc.lng += poi.coordinates.lng - return acc - }, - { lat: 0, lng: 0 } - ) - - centralCoordinates.lat /= pointOfInterests.length - centralCoordinates.lng /= pointOfInterests.length + const centralCoordinates = getCentralCoordinates(pointOfInterests) return ( @@ -73,6 +64,7 @@ export default async function SelectHotelMapPage({ coordinates={centralCoordinates} pointsOfInterest={pointOfInterests} mapId={googleMapId} + isModal={true} /> ) diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/page.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/page.tsx index 5d0d9e5c4..97d4ec815 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/page.tsx +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/page.tsx @@ -6,6 +6,7 @@ import { getLocations } from "@/lib/trpc/memoizedRequests" import { fetchAvailableHotels, generateChildrenString, + getCentralCoordinates, getFiltersFromHotels, getPointOfInterests, } from "@/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/utils" @@ -55,15 +56,16 @@ export default async function SelectHotelMapPage({ const filters = getFiltersFromHotels(hotels) const pointOfInterests = getPointOfInterests(hotels) + const centralCoordinates = getCentralCoordinates(pointOfInterests) return (
) diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/utils.ts b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/utils.ts index b14268126..d33c995fe 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/utils.ts +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/utils.ts @@ -78,3 +78,19 @@ export function getPointOfInterests(hotels: HotelData[]): PointOfInterest[] { group: PointOfInterestGroupEnum.LOCATION, })) } + +export function getCentralCoordinates(pointOfInterests: PointOfInterest[]) { + const centralCoordinates = pointOfInterests.reduce( + (acc, poi) => { + acc.lat += poi.coordinates.lat + acc.lng += poi.coordinates.lng + return acc + }, + { lat: 0, lng: 0 } + ) + + centralCoordinates.lat /= pointOfInterests.length + centralCoordinates.lng /= pointOfInterests.length + + return centralCoordinates +} diff --git a/components/HotelReservation/SelectHotel/SelectHotelMap/index.tsx b/components/HotelReservation/SelectHotel/SelectHotelMap/index.tsx index 3109d5cc3..c25bc4f15 100644 --- a/components/HotelReservation/SelectHotel/SelectHotelMap/index.tsx +++ b/components/HotelReservation/SelectHotel/SelectHotelMap/index.tsx @@ -9,7 +9,6 @@ import { selectHotel } from "@/constants/routes/hotelReservation" import { CloseIcon, CloseLargeIcon } from "@/components/Icons" import InteractiveMap from "@/components/Maps/InteractiveMap" import Button from "@/components/TempDesignSystem/Button" -import Link from "@/components/TempDesignSystem/Link" import useLang from "@/hooks/useLang" import HotelListing from "./HotelListing" @@ -23,23 +22,30 @@ export default function SelectHotelMap({ coordinates, pointsOfInterest, mapId, + isModal, }: SelectHotelMapProps) { const router = useRouter() const lang = useLang() const intl = useIntl() const [activePoi, setActivePoi] = useState(null) - function onDismiss() { + function handleModalDismiss() { router.back() } + function handlePageRedirect() { + router.push( + `${selectHotel[lang]}?${new URLSearchParams(window.location.search)}` + ) + } + const closeButton = ( - Filter and sort - {/* TODO: Add filter and sort button */} +
+
+ + Filter and sort + {/* TODO: Add filter and sort button */} +
+ +
- - ) } diff --git a/components/HotelReservation/SelectHotel/SelectHotelMap/selectHotelMap.module.css b/components/HotelReservation/SelectHotel/SelectHotelMap/selectHotelMap.module.css index adb35a386..17bf1b39e 100644 --- a/components/HotelReservation/SelectHotel/SelectHotelMap/selectHotelMap.module.css +++ b/components/HotelReservation/SelectHotel/SelectHotelMap/selectHotelMap.module.css @@ -5,6 +5,10 @@ display: none !important; } +.container { + height: 100%; +} + .filterContainer { display: flex; justify-content: space-between; @@ -16,6 +20,7 @@ z-index: 10; background-color: var(--Base-Surface-Secondary-light-Normal); padding: 0 var(--Spacing-x2); + height: 44px; } .filterContainer .closeButton { diff --git a/types/components/hotelReservation/selectHotel/map.ts b/types/components/hotelReservation/selectHotel/map.ts index 9d223d24d..0dfbe98a7 100644 --- a/types/components/hotelReservation/selectHotel/map.ts +++ b/types/components/hotelReservation/selectHotel/map.ts @@ -12,4 +12,5 @@ export interface SelectHotelMapProps { coordinates: Coordinates pointsOfInterest: PointOfInterest[] mapId: string + isModal: boolean } From 399c23ea0201570c3d2c030fb048b31dca63a44b Mon Sep 17 00:00:00 2001 From: Pontus Dreij Date: Fri, 1 Nov 2024 10:28:41 +0100 Subject: [PATCH 07/11] feat(sw-343): fixed desktop view --- .../(standard)/select-hotel/map/page.module.css | 6 ------ .../SelectHotel/SelectHotelMap/selectHotelMap.module.css | 3 +++ components/MapModal/mapModal.module.css | 6 ------ 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/page.module.css b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/page.module.css index 3fdff19f7..d0a692d8b 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/page.module.css +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/page.module.css @@ -4,9 +4,3 @@ min-height: 100dvh; position: relative; } - -@media (min-width: 768px) { - .main { - grid-template-columns: 420px 1fr; - } -} diff --git a/components/HotelReservation/SelectHotel/SelectHotelMap/selectHotelMap.module.css b/components/HotelReservation/SelectHotel/SelectHotelMap/selectHotelMap.module.css index 17bf1b39e..c54a77ccf 100644 --- a/components/HotelReservation/SelectHotel/SelectHotelMap/selectHotelMap.module.css +++ b/components/HotelReservation/SelectHotel/SelectHotelMap/selectHotelMap.module.css @@ -34,4 +34,7 @@ .filterContainer { display: none; } + .container { + display: flex; + } } diff --git a/components/MapModal/mapModal.module.css b/components/MapModal/mapModal.module.css index 3000d4673..500da73f5 100644 --- a/components/MapModal/mapModal.module.css +++ b/components/MapModal/mapModal.module.css @@ -16,9 +16,3 @@ top: 0; left: 0; } - -@media screen and (min-width: 768px) { - .dynamicMap { - top: var(--main-menu-desktop-height); - } -} From 32a5b8f3aaf9ab7348e1b07d69182411c9c2217e Mon Sep 17 00:00:00 2001 From: Pontus Dreij Date: Wed, 6 Nov 2024 08:55:46 +0100 Subject: [PATCH 08/11] feat(SW-343): rename button and useSearchParams --- .../hotelreservation/(standard)/select-hotel/page.tsx | 4 ++-- .../index.tsx | 4 ++-- .../mobileMapButtonContainer.module.css} | 0 .../HotelReservation/SelectHotel/SelectHotelMap/index.tsx | 7 +++---- 4 files changed, 7 insertions(+), 8 deletions(-) rename components/HotelReservation/SelectHotel/{MobileButtonContainer => MobileMapButtonContainer}/index.tsx (89%) rename components/HotelReservation/SelectHotel/{MobileButtonContainer/mobileButtonContainer.module.css => MobileMapButtonContainer/mobileMapButtonContainer.module.css} (100%) 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 7977ff63b..f3d920fb7 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/page.tsx +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/page.tsx @@ -9,7 +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 MobileButtonContainer from "@/components/HotelReservation/SelectHotel/MobileButtonContainer" +import MobileMapButtonContainer from "@/components/HotelReservation/SelectHotel/MobileMapButtonContainer" import { generateChildrenString, getHotelReservationQueryParams, @@ -84,7 +84,7 @@ export default async function SelectHotelPage({
- + diff --git a/components/HotelReservation/SelectHotel/MobileButtonContainer/index.tsx b/components/HotelReservation/SelectHotel/MobileMapButtonContainer/index.tsx similarity index 89% rename from components/HotelReservation/SelectHotel/MobileButtonContainer/index.tsx rename to components/HotelReservation/SelectHotel/MobileMapButtonContainer/index.tsx index 730cd780b..8fba327b3 100644 --- a/components/HotelReservation/SelectHotel/MobileButtonContainer/index.tsx +++ b/components/HotelReservation/SelectHotel/MobileMapButtonContainer/index.tsx @@ -9,9 +9,9 @@ import Button from "@/components/TempDesignSystem/Button" import Link from "@/components/TempDesignSystem/Link" import useLang from "@/hooks/useLang" -import styles from "./mobileButtonContainer.module.css" +import styles from "./mobileMapButtonContainer.module.css" -export default function MobileButtonContainer({ city }: { city: string }) { +export default function MobileMapButtonContainer({ city }: { city: string }) { const intl = useIntl() const lang = useLang() diff --git a/components/HotelReservation/SelectHotel/MobileButtonContainer/mobileButtonContainer.module.css b/components/HotelReservation/SelectHotel/MobileMapButtonContainer/mobileMapButtonContainer.module.css similarity index 100% rename from components/HotelReservation/SelectHotel/MobileButtonContainer/mobileButtonContainer.module.css rename to components/HotelReservation/SelectHotel/MobileMapButtonContainer/mobileMapButtonContainer.module.css diff --git a/components/HotelReservation/SelectHotel/SelectHotelMap/index.tsx b/components/HotelReservation/SelectHotel/SelectHotelMap/index.tsx index c25bc4f15..0dc82d7ab 100644 --- a/components/HotelReservation/SelectHotel/SelectHotelMap/index.tsx +++ b/components/HotelReservation/SelectHotel/SelectHotelMap/index.tsx @@ -1,6 +1,6 @@ "use client" import { APIProvider } from "@vis.gl/react-google-maps" -import { useRouter } from "next/navigation" +import { useRouter, useSearchParams } from "next/navigation" import { useState } from "react" import { useIntl } from "react-intl" @@ -24,6 +24,7 @@ export default function SelectHotelMap({ mapId, isModal, }: SelectHotelMapProps) { + const searchParams = useSearchParams() const router = useRouter() const lang = useLang() const intl = useIntl() @@ -34,9 +35,7 @@ export default function SelectHotelMap({ } function handlePageRedirect() { - router.push( - `${selectHotel[lang]}?${new URLSearchParams(window.location.search)}` - ) + router.push(`${selectHotel[lang]}?${searchParams.toString()}`) } const closeButton = ( From a5afc3515e9645372252589624fab9a9bfeeb075 Mon Sep 17 00:00:00 2001 From: Pontus Dreij Date: Wed, 6 Nov 2024 09:21:09 +0100 Subject: [PATCH 09/11] feat(343): reuse of map page modal --- .../(standard)/select-hotel/map/page.tsx | 73 +------------------ 1 file changed, 1 insertion(+), 72 deletions(-) diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/page.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/page.tsx index 97d4ec815..bfd164880 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/page.tsx +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/page.tsx @@ -1,72 +1 @@ -import { notFound } from "next/navigation" - -import { env } from "@/env/server" -import { getLocations } from "@/lib/trpc/memoizedRequests" - -import { - fetchAvailableHotels, - generateChildrenString, - getCentralCoordinates, - getFiltersFromHotels, - getPointOfInterests, -} from "@/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/utils" -import SelectHotelMap from "@/components/HotelReservation/SelectHotel/SelectHotelMap" -import { getHotelReservationQueryParams } from "@/components/HotelReservation/SelectRate/RoomSelection/utils" -import { setLang } from "@/i18n/serverContext" - -import styles from "./page.module.css" - -import { type SelectHotelSearchParams } from "@/types/components/hotelReservation/selectHotel/selectHotelSearchParams" -import type { LangParams, PageArgs } from "@/types/params" - -export default async function SelectHotelMapPage({ - params, - searchParams, -}: PageArgs) { - const googleMapId = env.GOOGLE_DYNAMIC_MAP_ID - const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY - setLang(params.lang) - const locations = await getLocations() - - if (!locations || "error" in locations) { - return null - } - const city = locations.data.find( - (location) => - location.name.toLowerCase() === searchParams.city.toLowerCase() - ) - if (!city) return notFound() - - const selectHotelParams = new URLSearchParams(searchParams) - const selectHotelParamsObject = - getHotelReservationQueryParams(selectHotelParams) - const adults = selectHotelParamsObject.room[0].adults // TODO: Handle multiple rooms - const children = selectHotelParamsObject.room[0].child - ? generateChildrenString(selectHotelParamsObject.room[0].child) - : undefined // TODO: Handle multiple rooms - - const hotels = await fetchAvailableHotels({ - cityId: city.id, - roomStayStartDate: searchParams.fromDate, - roomStayEndDate: searchParams.toDate, - adults, - children, - }) - - const filters = getFiltersFromHotels(hotels) - - const pointOfInterests = getPointOfInterests(hotels) - const centralCoordinates = getCentralCoordinates(pointOfInterests) - - return ( -
- -
- ) -} +export { default } from "../@modal/(.)map/page" From d83126d1333a40f72a53b076d00e31519425c6ee Mon Sep 17 00:00:00 2001 From: Pontus Dreij Date: Wed, 6 Nov 2024 09:23:16 +0100 Subject: [PATCH 10/11] feat(SW-343): Added flag --- .../(standard)/select-hotel/@modal/(.)map/page.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/page.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/page.tsx index eadd81bbb..667d43ad6 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/page.tsx +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/page.tsx @@ -22,6 +22,10 @@ export default async function SelectHotelMapPage({ params, searchParams, }: PageArgs) { + if (env.HIDE_FOR_NEXT_RELEASE) { + return notFound() + } + setLang(params.lang) const locations = await getLocations() From 9593348d3543efc72770917ea39ed2660e772390 Mon Sep 17 00:00:00 2001 From: Pontus Dreij Date: Wed, 6 Nov 2024 09:42:19 +0100 Subject: [PATCH 11/11] feat(SW-343): Handle escape route without useHandleKeyUp --- components/MapModal/index.tsx | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/components/MapModal/index.tsx b/components/MapModal/index.tsx index ddedd622f..282e08151 100644 --- a/components/MapModal/index.tsx +++ b/components/MapModal/index.tsx @@ -4,7 +4,6 @@ import { useRouter } from "next/navigation" import { useCallback, useEffect, useRef, useState } from "react" import { Dialog, Modal } from "react-aria-components" -import { useHandleKeyUp } from "@/hooks/useHandleKeyUp" import { debounce } from "@/utils/debounce" import styles from "./mapModal.module.css" @@ -13,20 +12,18 @@ export function MapModal({ children }: { children: React.ReactNode }) { const router = useRouter() const [mapHeight, setMapHeight] = useState("0px") const [mapTop, setMapTop] = useState("0px") + const [isOpen, setOpen] = useState(true) const [scrollHeightWhenOpened, setScrollHeightWhenOpened] = useState(0) const rootDiv = useRef(null) - function onDismiss() { - router.back() - } - - useHandleKeyUp((event: KeyboardEvent) => { - if (event.key === "Escape") { - onDismiss() + const handleOnOpenChange = (open: boolean) => { + setOpen(open) + if (!open) { + router.back() } - }) + } // Calculate the height of the map based on the viewport height from the start-point (below the header and booking widget) const handleMapHeight = useCallback(() => { @@ -70,7 +67,7 @@ export function MapModal({ children }: { children: React.ReactNode }) { return (
- +