diff --git a/components/HotelReservation/HotelCard/index.tsx b/components/HotelReservation/HotelCard/index.tsx index 692347284..6c107f2cd 100644 --- a/components/HotelReservation/HotelCard/index.tsx +++ b/components/HotelReservation/HotelCard/index.tsx @@ -4,7 +4,8 @@ import { memo, useCallback } from "react" import { useIntl } from "react-intl" import { Lang } from "@/constants/languages" -import { selectHotelMap, selectRate } from "@/constants/routes/hotelReservation" +import { selectRate } from "@/constants/routes/hotelReservation" +import { useHotelsMapStore } from "@/stores/hotels-map" import { mapFacilityToIcon } from "@/components/ContentType/HotelPage/data" import ImageGallery from "@/components/ImageGallery" @@ -32,26 +33,27 @@ function HotelCard({ hotel, type = HotelCardListingTypeEnum.PageListing, state = "default", - onHotelCardHover, }: HotelCardProps) { const params = useParams() const lang = params.lang as Lang const intl = useIntl() + const { setActiveHotelPin, setActiveHotelCard } = useHotelsMapStore() const { hotelData } = hotel const { price } = hotel const handleMouseEnter = useCallback(() => { - if (onHotelCardHover && hotelData) { - onHotelCardHover(hotelData.name) + if (hotelData) { + setActiveHotelPin(hotelData.name) } - }, [onHotelCardHover, hotelData]) + }, [setActiveHotelPin, hotelData]) const handleMouseLeave = useCallback(() => { - if (onHotelCardHover) { - onHotelCardHover(null) + if (hotelData) { + setActiveHotelPin(null) + setActiveHotelCard(null) } - }, [onHotelCardHover]) + }, [setActiveHotelPin, hotelData, setActiveHotelCard]) if (!hotel || !hotelData) return null diff --git a/components/HotelReservation/HotelCardDialogListing/index.tsx b/components/HotelReservation/HotelCardDialogListing/index.tsx index 4f9e83b36..0a9d0e5fc 100644 --- a/components/HotelReservation/HotelCardDialogListing/index.tsx +++ b/components/HotelReservation/HotelCardDialogListing/index.tsx @@ -3,6 +3,8 @@ import { useCallback, useEffect, useRef } from "react" import { useMediaQuery } from "usehooks-ts" +import { useHotelsMapStore } from "@/stores/hotels-map" + import useClickOutside from "@/hooks/useClickOutside" import HotelCardDialog from "../HotelCardDialog" @@ -14,18 +16,21 @@ import type { HotelCardDialogListingProps } from "@/types/components/hotelReserv export default function HotelCardDialogListing({ hotels, - activeCard, - onActiveCardChange, }: HotelCardDialogListingProps) { const hotelsPinData = hotels ? getHotelPins(hotels) : [] const activeCardRef = useRef(null) const observerRef = useRef(null) const dialogRef = useRef(null) const isMobile = useMediaQuery("(max-width: 768px)") + const { activeHotelCard, setActiveHotelCard, setActiveHotelPin } = + useHotelsMapStore() - useClickOutside(dialogRef, !!activeCard && isMobile, () => { - onActiveCardChange(null) - }) + function handleClose() { + setActiveHotelCard(null) + setActiveHotelPin(null) + } + + useClickOutside(dialogRef, !!activeHotelCard && isMobile, handleClose) const handleIntersection = useCallback( (entries: IntersectionObserverEntry[]) => { @@ -33,12 +38,12 @@ export default function HotelCardDialogListing({ if (entry.isIntersecting) { const cardName = entry.target.getAttribute("data-name") if (cardName) { - onActiveCardChange(cardName) + setActiveHotelCard(cardName) } } }) }, - [onActiveCardChange] + [setActiveHotelCard] ) useEffect(() => { @@ -73,13 +78,13 @@ export default function HotelCardDialogListing({ elements.forEach((el) => observerRef.current?.observe(el)) }, 1000) } - }, [activeCard]) + }, [activeHotelCard]) return (
{!!hotelsPinData?.length && hotelsPinData.map((data) => { - const isActive = data.name === activeCard + const isActive = data.name === activeHotelCard return (
onActiveCardChange(null)} + isOpen={!!activeHotelCard} + handleClose={handleClose} />
) diff --git a/components/HotelReservation/HotelCardListing/index.tsx b/components/HotelReservation/HotelCardListing/index.tsx index ecf9d711a..c7687362b 100644 --- a/components/HotelReservation/HotelCardListing/index.tsx +++ b/components/HotelReservation/HotelCardListing/index.tsx @@ -4,6 +4,7 @@ import { useEffect, useMemo, useState } from "react" import { useIntl } from "react-intl" import { useHotelFilterStore } from "@/stores/hotel-filters" +import { useHotelsMapStore } from "@/stores/hotels-map" import Alert from "@/components/TempDesignSystem/Alert" import { BackToTopButton } from "@/components/TempDesignSystem/BackToTopButton" @@ -24,14 +25,13 @@ import { AlertTypeEnum } from "@/types/enums/alert" export default function HotelCardListing({ hotelData, type = HotelCardListingTypeEnum.PageListing, - activeCard, - onHotelCardHover, }: HotelCardListingProps) { const searchParams = useSearchParams() const activeFilters = useHotelFilterStore((state) => state.activeFilters) const setResultCount = useHotelFilterStore((state) => state.setResultCount) const [showBackToTop, setShowBackToTop] = useState(false) const intl = useIntl() + const { activeHotelCard } = useHotelsMapStore() const sortBy = useMemo( () => searchParams.get("sort") ?? DEFAULT_SORT, @@ -111,13 +111,16 @@ export default function HotelCardListing({ hotels.map((hotel) => (
)) diff --git a/components/HotelReservation/SelectHotel/SelectHotelMap/HotelListing/index.tsx b/components/HotelReservation/SelectHotel/SelectHotelMap/HotelListing/index.tsx index 71d324155..92a302d58 100644 --- a/components/HotelReservation/SelectHotel/SelectHotelMap/HotelListing/index.tsx +++ b/components/HotelReservation/SelectHotel/SelectHotelMap/HotelListing/index.tsx @@ -1,5 +1,7 @@ "use client" +import { useHotelsMapStore } from "@/stores/hotels-map" + import HotelCardDialogListing from "@/components/HotelReservation/HotelCardDialogListing" import HotelCardListing from "@/components/HotelReservation/HotelCardListing" @@ -8,27 +10,18 @@ import styles from "./hotelListing.module.css" import { HotelCardListingTypeEnum } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps" import type { HotelListingProps } from "@/types/components/hotelReservation/selectHotel/map" -export default function HotelListing({ - hotels, - activeHotelPin, - setActiveHotelPin, -}: HotelListingProps) { +export default function HotelListing({ hotels }: HotelListingProps) { + const { activeHotelPin } = useHotelsMapStore() return ( <>
- +
) diff --git a/components/HotelReservation/SelectHotel/SelectHotelMap/SelectHotelMapContainer.tsx b/components/HotelReservation/SelectHotel/SelectHotelMap/SelectHotelMapContainer.tsx index a32b1f773..d8237972e 100644 --- a/components/HotelReservation/SelectHotel/SelectHotelMap/SelectHotelMapContainer.tsx +++ b/components/HotelReservation/SelectHotel/SelectHotelMap/SelectHotelMapContainer.tsx @@ -14,26 +14,18 @@ import type { HotelData, NullableHotelData, } from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps" -import type { SelectHotelSearchParams } from "@/types/components/hotelReservation/selectHotel/selectHotelSearchParams" -import type { Location } from "@/types/trpc/routers/hotel/locations" +import type { SelectHotelMapContainerProps } from "@/types/components/hotelReservation/selectHotel/map" -function isHotelData(hotel: NullableHotelData): hotel is HotelData { +function isValidHotelData(hotel: NullableHotelData): hotel is HotelData { return hotel !== null && hotel !== undefined } -type Props = { - city: Location - searchParams: SelectHotelSearchParams - adultsInRoom: number - childrenInRoom: string | undefined -} - export async function SelectHotelMapContainer({ city, searchParams, adultsInRoom, childrenInRoom, -}: Props) { +}: SelectHotelMapContainerProps) { const googleMapId = env.GOOGLE_DYNAMIC_MAP_ID const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY @@ -47,15 +39,9 @@ export async function SelectHotelMapContainer({ }) ) - const [hotels, hotelsError] = await fetchAvailableHotelsPromise + const [hotels] = await fetchAvailableHotelsPromise - if (hotelsError) { - // TODO: show proper error component - console.error("[SelectHotelMapContainer] unable to fetch hotels") - return null - } - - const validHotels = hotels?.filter(isHotelData) || [] + const validHotels = hotels?.filter(isValidHotelData) || [] const hotelPins = getHotelPins(validHotels) const filterList = getFiltersFromHotels(validHotels) diff --git a/components/HotelReservation/SelectHotel/SelectHotelMap/SelectHotelMapContainerSkeleton.module.css b/components/HotelReservation/SelectHotel/SelectHotelMap/SelectHotelMapContainerSkeleton.module.css index c6e0fa3bf..eea85e7a7 100644 --- a/components/HotelReservation/SelectHotel/SelectHotelMap/SelectHotelMapContainerSkeleton.module.css +++ b/components/HotelReservation/SelectHotel/SelectHotelMap/SelectHotelMapContainerSkeleton.module.css @@ -1,15 +1,12 @@ .container { max-width: var(--max-width); height: 100%; + display: flex; + width: 100%; } .listingContainer { - background-color: var(--Base-Surface-Secondary-light-Normal); - padding: var(--Spacing-x3) var(--Spacing-x4); - overflow-y: auto; - max-width: 505px; - position: relative; - height: 100%; + display: none; } .skeletonContainer { @@ -27,7 +24,20 @@ width: 440px; } +.mapContainer { + flex: 1; +} + @media (min-width: 768px) { + .listingContainer { + background-color: var(--Base-Surface-Secondary-light-Normal); + padding: var(--Spacing-x3) var(--Spacing-x4); + overflow-y: auto; + max-width: 505px; + position: relative; + height: 100%; + display: block; + } .skeletonContainer { display: flex; } diff --git a/components/HotelReservation/SelectHotel/SelectHotelMap/SelectHotelMapContainerSkeleton.tsx b/components/HotelReservation/SelectHotel/SelectHotelMap/SelectHotelMapContainerSkeleton.tsx index 604dde098..75821477f 100644 --- a/components/HotelReservation/SelectHotel/SelectHotelMap/SelectHotelMapContainerSkeleton.tsx +++ b/components/HotelReservation/SelectHotel/SelectHotelMap/SelectHotelMapContainerSkeleton.tsx @@ -1,3 +1,5 @@ +import SkeletonShimmer from "@/components/SkeletonShimmer" + import { RoomCardSkeleton } from "../../SelectRate/RoomSelection/RoomCard/RoomCardSkeleton" import styles from "./SelectHotelMapContainerSkeleton.module.css" @@ -18,6 +20,9 @@ export async function SelectHotelMapContainerSkeleton({ count = 2 }: Props) { ))}
+
+ +
) } diff --git a/components/HotelReservation/SelectHotel/SelectHotelMap/index.tsx b/components/HotelReservation/SelectHotel/SelectHotelMap/index.tsx index 952c8b11a..ec65ec961 100644 --- a/components/HotelReservation/SelectHotel/SelectHotelMap/index.tsx +++ b/components/HotelReservation/SelectHotel/SelectHotelMap/index.tsx @@ -1,13 +1,13 @@ "use client" import { APIProvider } from "@vis.gl/react-google-maps" -import { useSearchParams } from "next/navigation" import { useEffect, useMemo, useRef, useState } from "react" import { useIntl } from "react-intl" import { useMediaQuery } from "usehooks-ts" import { selectHotel } from "@/constants/routes/hotelReservation" import { useHotelFilterStore } from "@/stores/hotel-filters" +import { useHotelsMapStore } from "@/stores/hotels-map" import { CloseIcon, CloseLargeIcon } from "@/components/Icons" import InteractiveMap from "@/components/Maps/InteractiveMap" @@ -31,18 +31,13 @@ export default function SelectHotelMap({ filterList, cityCoordinates, }: SelectHotelMapProps) { - const searchParams = useSearchParams() - const lang = useLang() const intl = useIntl() const isAboveMobile = useMediaQuery("(min-width: 768px)") - const [activeHotelPin, setActiveHotelPin] = useState(null) const [showBackToTop, setShowBackToTop] = useState(false) const listingContainerRef = useRef(null) const activeFilters = useHotelFilterStore((state) => state.activeFilters) - - const selectHotelParams = new URLSearchParams(searchParams.toString()) - const selectedHotel = selectHotelParams.get("selectedHotel") + const { activeHotelCard, activeHotelPin } = useHotelsMapStore() const coordinates = isAboveMobile ? cityCoordinates @@ -56,13 +51,7 @@ export default function SelectHotelMap({ activeElement.scrollIntoView({ behavior: "smooth", block: "nearest" }) } } - }, [activeHotelPin]) - - useEffect(() => { - if (selectedHotel) { - setActiveHotelPin(selectedHotel) - } - }, [selectedHotel]) + }, [activeHotelCard, activeHotelPin]) useEffect(() => { const hotelListingElement = document.querySelector( @@ -96,8 +85,6 @@ export default function SelectHotelMap({ [activeFilters, hotelPins] ) - console.log("hotelPins", hotelPins) - const closeButton = (