From 69fa5b9b3194b5c0fffb4f79a0d1daf5e501a97e Mon Sep 17 00:00:00 2001 From: Pontus Dreij Date: Thu, 5 Dec 2024 15:23:02 +0100 Subject: [PATCH] fix(SW-1111) Moved map to a page instead of intercepted route --- .../select-hotel/@modal/(.)map/loading.tsx | 5 -- .../select-hotel/@modal/(.)map/page.tsx | 79 ------------------ .../select-hotel/@modal/default.tsx | 3 - .../(standard)/select-hotel/@modal/page.tsx | 3 - .../(standard)/select-hotel/layout.module.css | 7 ++ .../(standard)/select-hotel/layout.tsx | 12 +-- .../(standard)/select-hotel/map/layout.tsx | 20 +++++ .../(standard)/select-hotel/map/page.tsx | 80 ++++++++++++++++++- app/[lang]/(live)/layout.tsx | 1 - .../Search/SearchList/List/index.tsx | 2 +- .../FormContent/Search/index.tsx | 5 +- .../SelectHotel/SelectHotelMap/index.tsx | 30 +++---- .../SelectHotelMap/selectHotelMap.module.css | 4 - .../{MapModal => MapContainer}/index.tsx | 37 +++------ .../mapModal.module.css | 2 +- .../HotelListingMapContent/index.tsx | 3 +- .../SitewideAlert/sitewideAlert.module.css | 2 + 17 files changed, 140 insertions(+), 155 deletions(-) delete mode 100644 app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/loading.tsx delete mode 100644 app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/page.tsx delete mode 100644 app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/default.tsx delete mode 100644 app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/page.tsx create mode 100644 app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/layout.tsx rename components/{MapModal => MapContainer}/index.tsx (71%) rename components/{MapModal => MapContainer}/mapModal.module.css (94%) diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/loading.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/loading.tsx deleted file mode 100644 index 8f6f8657c..000000000 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/loading.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import LoadingSpinner from "@/components/LoadingSpinner" - -export default function LoadingModal() { - return -} 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 deleted file mode 100644 index 600afbb38..000000000 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/(.)map/page.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import { notFound } from "next/navigation" - -import { env } from "@/env/server" -import { getCityCoordinates, getLocations } from "@/lib/trpc/memoizedRequests" - -import { getHotelPins } from "@/components/HotelReservation/HotelCardDialogListing/utils" -import SelectHotelMap from "@/components/HotelReservation/SelectHotel/SelectHotelMap" -import { - generateChildrenString, - getHotelReservationQueryParams, -} from "@/components/HotelReservation/SelectRate/RoomSelection/utils" -import { MapModal } from "@/components/MapModal" -import { setLang } from "@/i18n/serverContext" - -import { fetchAvailableHotels, getFiltersFromHotels } from "../../utils" - -import type { HotelData } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps" -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 validHotels = hotels.filter( - (hotel): hotel is HotelData => hotel !== null - ) - - const hotelPins = getHotelPins(validHotels) - const filterList = getFiltersFromHotels(validHotels) - const cityCoordinates = await getCityCoordinates({ - city: city.name, - hotel: { address: hotels?.[0]?.hotelData?.address.streetAddress }, - }) - - 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 deleted file mode 100644 index 86b9e9a38..000000000 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/default.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function Default() { - return null -} diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/page.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/page.tsx deleted file mode 100644 index c17431379..000000000 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/@modal/page.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function Page() { - 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 index b86e58a72..8e68022d6 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 @@ -2,4 +2,11 @@ min-height: 100dvh; background-color: var(--Base-Background-Primary-Normal); position: relative; + z-index: var(--header-z-index); +} + +@media screen and (min-width: 768px) { + .layout { + z-index: 0; + } } diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/layout.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/layout.tsx index 907b02c2a..ee96f3c10 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/layout.tsx +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/layout.tsx @@ -4,14 +4,6 @@ import { LangParams, LayoutArgs } from "@/types/params" export default function HotelReservationLayout({ children, - modal, -}: React.PropsWithChildren< - LayoutArgs & { modal: React.ReactNode } ->) { - return ( -
- {children} - {modal} -
- ) +}: React.PropsWithChildren>) { + return
{children}
} diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/layout.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/layout.tsx new file mode 100644 index 000000000..45b344441 --- /dev/null +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/map/layout.tsx @@ -0,0 +1,20 @@ +"use client" + +import { useEffect } from "react" + +import styles from "../layout.module.css" + +import { LangParams, LayoutArgs } from "@/types/params" + +export default function HotelReservationLayout({ + children, +}: React.PropsWithChildren>) { + useEffect(() => { + document.body.style.overflow = "hidden" + + return () => { + document.body.style.overflow = "" + } + }, []) + return
{children}
+} 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 bfd164880..33d4f4096 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 +1,79 @@ -export { default } from "../@modal/(.)map/page" +import { notFound } from "next/navigation" + +import { env } from "@/env/server" +import { getCityCoordinates, getLocations } from "@/lib/trpc/memoizedRequests" + +import { getHotelPins } from "@/components/HotelReservation/HotelCardDialogListing/utils" +import SelectHotelMap from "@/components/HotelReservation/SelectHotel/SelectHotelMap" +import { + generateChildrenString, + getHotelReservationQueryParams, +} from "@/components/HotelReservation/SelectRate/RoomSelection/utils" +import { MapContainer } from "@/components/MapContainer" +import { setLang } from "@/i18n/serverContext" + +import { fetchAvailableHotels, getFiltersFromHotels } from "../utils" + +import type { HotelData } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps" +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 validHotels = hotels.filter( + (hotel): hotel is HotelData => hotel !== null + ) + + const hotelPins = getHotelPins(validHotels) + const filterList = getFiltersFromHotels(validHotels) + const cityCoordinates = await getCityCoordinates({ + city: city.name, + hotel: { address: hotels?.[0]?.hotelData?.address.streetAddress }, + }) + + return ( + + + + ) +} diff --git a/app/[lang]/(live)/layout.tsx b/app/[lang]/(live)/layout.tsx index 353273141..0631bc612 100644 --- a/app/[lang]/(live)/layout.tsx +++ b/app/[lang]/(live)/layout.tsx @@ -3,7 +3,6 @@ import "@scandic-hotels/design-system/style.css" import Script from "next/script" -import { env } from "@/env/server" import TrpcProvider from "@/lib/trpc/Provider" import TokenRefresher from "@/components/Auth/TokenRefresher" diff --git a/components/Forms/BookingWidget/FormContent/Search/SearchList/List/index.tsx b/components/Forms/BookingWidget/FormContent/Search/SearchList/List/index.tsx index 946fb2e28..4ed6998bb 100644 --- a/components/Forms/BookingWidget/FormContent/Search/SearchList/List/index.tsx +++ b/components/Forms/BookingWidget/FormContent/Search/SearchList/List/index.tsx @@ -23,7 +23,7 @@ export default function List({ getItemProps={getItemProps} highlightedIndex={highlightedIndex} index={initialIndex + index} - key={location.id} + key={location.id + index} location={location} /> ))} diff --git a/components/Forms/BookingWidget/FormContent/Search/index.tsx b/components/Forms/BookingWidget/FormContent/Search/index.tsx index 1fe45ed04..93d99a89b 100644 --- a/components/Forms/BookingWidget/FormContent/Search/index.tsx +++ b/components/Forms/BookingWidget/FormContent/Search/index.tsx @@ -26,6 +26,7 @@ import type { SearchProps } from "@/types/components/search" import type { Location } from "@/types/trpc/routers/hotel/locations" const name = "search" + export default function Search({ locations }: SearchProps) { const { register, setValue, trigger, unregister } = useFormContext() @@ -166,7 +167,6 @@ export default function Search({ locations }: SearchProps) { onInputValueChange={(inputValue) => dispatchInputValue(inputValue)} > {({ - closeMenu, getInputProps, getItemProps, getLabelProps, @@ -207,9 +207,6 @@ export default function Search({ locations }: SearchProps) { id: "Destinations & hotels", }), ...register(name, { - onBlur: function () { - closeMenu() - }, onChange: handleOnChange, }), type: "search", diff --git a/components/HotelReservation/SelectHotel/SelectHotelMap/index.tsx b/components/HotelReservation/SelectHotel/SelectHotelMap/index.tsx index 5459ab795..bf83bace1 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, useSearchParams } from "next/navigation" +import { useSearchParams } from "next/navigation" import { useEffect, useRef, useState } from "react" import { useIntl } from "react-intl" import { useMediaQuery } from "usehooks-ts" @@ -11,6 +11,7 @@ import { CloseIcon, CloseLargeIcon } from "@/components/Icons" import InteractiveMap from "@/components/Maps/InteractiveMap" import { BackToTopButton } from "@/components/TempDesignSystem/BackToTopButton" import Button from "@/components/TempDesignSystem/Button" +import Link from "@/components/TempDesignSystem/Link" import useLang from "@/hooks/useLang" import FilterAndSortModal from "../FilterAndSortModal" @@ -29,7 +30,7 @@ export default function SelectHotelMap({ cityCoordinates, }: SelectHotelMapProps) { const searchParams = useSearchParams() - const router = useRouter() + const lang = useLang() const intl = useIntl() const isAboveMobile = useMediaQuery("(min-width: 768px)") @@ -82,25 +83,18 @@ export default function SelectHotelMap({ hotelListingElement?.scrollTo({ top: 0, behavior: "smooth" }) } - function handlePageRedirect() { - const newUrl = `${selectHotel(lang)}?${searchParams.toString()}` - if (window.history.length > 1) { - router.back() - } else { - router.push(newUrl) - } - } - const closeButton = ( ) return ( @@ -113,10 +107,12 @@ export default function SelectHotelMap({ size="small" variant="icon" wrapping - onClick={handlePageRedirect} className={styles.filterContainerCloseButton} + asChild > - + + + @@ -126,7 +122,7 @@ export default function SelectHotelMap({ setActiveHotelPin={setActiveHotelPin} /> {showBackToTop && ( - + )} (null) - const handleOnOpenChange = (open: boolean) => { - setIsOpen(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(() => { const topPosition = rootDiv.current?.getBoundingClientRect().top ?? 0 @@ -66,19 +55,17 @@ export function MapModal({ children }: { children: React.ReactNode }) { return (
- - - {children} - - +
+ {children} +
) } diff --git a/components/MapModal/mapModal.module.css b/components/MapContainer/mapModal.module.css similarity index 94% rename from components/MapModal/mapModal.module.css rename to components/MapContainer/mapModal.module.css index 500da73f5..847176acf 100644 --- a/components/MapModal/mapModal.module.css +++ b/components/MapContainer/mapModal.module.css @@ -1,7 +1,7 @@ .dynamicMap { --hotel-map-height: 100dvh; --hotel-map-top: 0px; - position: absolute; + position: fixed; top: var(--hotel-map-top); left: 0; height: var(--hotel-map-height); diff --git a/components/Maps/InteractiveMap/HotelListingMapContent/index.tsx b/components/Maps/InteractiveMap/HotelListingMapContent/index.tsx index 39498c3b3..911a02da2 100644 --- a/components/Maps/InteractiveMap/HotelListingMapContent/index.tsx +++ b/components/Maps/InteractiveMap/HotelListingMapContent/index.tsx @@ -2,7 +2,7 @@ import { AdvancedMarker, AdvancedMarkerAnchorPoint, } from "@vis.gl/react-google-maps" -import { memo, useCallback, useState } from "react" +import { useCallback, useState } from "react" import HotelCardDialog from "@/components/HotelReservation/HotelCardDialog" import Body from "@/components/TempDesignSystem/Text/Body" @@ -84,6 +84,7 @@ function HotelListingMapContent({ color={isActiveOrHovered ? "burgundy" : "white"} /> +