Merged in fix/SW-946-map-center (pull request #954)

fix(946) Center from town name instead of calculate center

Approved-by: Niclas Edenvin
This commit is contained in:
Pontus Dreij
2024-11-22 07:19:13 +00:00
12 changed files with 63 additions and 44 deletions

View File

@@ -1,7 +1,7 @@
import { notFound } from "next/navigation"
import { env } from "@/env/server"
import { getLocations } from "@/lib/trpc/memoizedRequests"
import { getCityCoordinates, getLocations } from "@/lib/trpc/memoizedRequests"
import { getHotelPins } from "@/components/HotelReservation/HotelCardDialogListing/utils"
import SelectHotelMap from "@/components/HotelReservation/SelectHotel/SelectHotelMap"
@@ -58,6 +58,7 @@ export default async function SelectHotelMapPage({
const hotelPins = getHotelPins(hotels)
const filterList = getFiltersFromHotels(hotels)
const cityCoordinates = await getCityCoordinates({ city: city.name })
return (
<MapModal>
@@ -67,6 +68,7 @@ export default async function SelectHotelMapPage({
mapId={googleMapId}
hotels={hotels}
filterList={filterList}
cityCoordinates={cityCoordinates}
/>
</MapModal>
)

View File

@@ -60,13 +60,20 @@ export default function Sidebar({
}
}
function handleMouseEnter(poiName: string) {
function handleMouseEnter(poiName: string | undefined) {
if (!poiName) return
if (!isClicking) {
onActivePoiChange(poiName)
}
}
function handlePoiClick(poiName: string, poiCoordinates: Coordinates) {
function handlePoiClick(
poiName: string | undefined,
poiCoordinates: Coordinates
) {
if (!poiName || !poiCoordinates) return
setIsClicking(true)
toggleFullScreenSidebar()
onActivePoiChange(poiName)

View File

@@ -113,7 +113,7 @@ export default function DynamicMap({
activePoi={activePoi}
hotelName={hotelName}
pointsOfInterest={pointsOfInterest}
onActivePoiChange={setActivePoi}
onActivePoiChange={(poi) => setActivePoi(poi ?? null)}
coordinates={coordinates}
/>
<InteractiveMap
@@ -121,7 +121,7 @@ export default function DynamicMap({
coordinates={coordinates}
pointsOfInterest={pointsOfInterest}
activePoi={activePoi}
onActivePoiChange={setActivePoi}
onActivePoiChange={(poi) => setActivePoi(poi ?? null)}
mapId={mapId}
/>
</Dialog>

View File

@@ -7,7 +7,7 @@ import { useMediaQuery } from "usehooks-ts"
import { selectHotel } from "@/constants/routes/hotelReservation"
import { ArrowUpIcon, CloseIcon, CloseLargeIcon } from "@/components/Icons"
import { CloseIcon, CloseLargeIcon } from "@/components/Icons"
import InteractiveMap from "@/components/Maps/InteractiveMap"
import { BackToTopButton } from "@/components/TempDesignSystem/BackToTopButton"
import Button from "@/components/TempDesignSystem/Button"
@@ -15,7 +15,6 @@ import useLang from "@/hooks/useLang"
import FilterAndSortModal from "../FilterAndSortModal"
import HotelListing from "./HotelListing"
import { getCentralCoordinates } from "./utils"
import styles from "./selectHotelMap.module.css"
@@ -27,6 +26,7 @@ export default function SelectHotelMap({
mapId,
hotels,
filterList,
cityCoordinates,
}: SelectHotelMapProps) {
const searchParams = useSearchParams()
const router = useRouter()
@@ -36,15 +36,13 @@ export default function SelectHotelMap({
const [activeHotelPin, setActiveHotelPin] = useState<string | null>(null)
const [showBackToTop, setShowBackToTop] = useState<boolean>(false)
const centralCoordinates = getCentralCoordinates(hotelPins)
const coordinates = isAboveMobile
? centralCoordinates
: { ...centralCoordinates, lat: centralCoordinates.lat - 0.006 }
const selectHotelParams = new URLSearchParams(searchParams.toString())
const selectedHotel = selectHotelParams.get("selectedHotel")
const coordinates = isAboveMobile
? cityCoordinates
: { ...cityCoordinates, lat: cityCoordinates.lat - 0.006 }
useEffect(() => {
if (selectedHotel) {
setActiveHotelPin(selectedHotel)

View File

@@ -1,17 +0,0 @@
import { HotelPin } from "@/types/components/hotelReservation/selectHotel/map"
export function getCentralCoordinates(hotels: HotelPin[]) {
const centralCoordinates = hotels.reduce(
(acc, pin) => {
acc.lat += pin.coordinates.lat
acc.lng += pin.coordinates.lng
return acc
},
{ lat: 0, lng: 0 }
)
centralCoordinates.lat /= hotels.length
centralCoordinates.lng /= hotels.length
return centralCoordinates
}

View File

@@ -35,9 +35,9 @@ export default function HotelMapContent({
position={poi.coordinates}
anchorPoint={AdvancedMarkerAnchorPoint.CENTER}
zIndex={activePoi === poi.name ? 2 : 0}
onMouseEnter={() => onActivePoiChange?.(poi.name)}
onMouseEnter={() => onActivePoiChange?.(poi.name ?? null)}
onMouseLeave={() => onActivePoiChange?.(null)}
onClick={() => toggleActivePoi(poi.name)}
onClick={() => toggleActivePoi(poi.name ?? "")}
>
<span
className={`${styles.poi} ${activePoi === poi.name ? styles.active : ""}`}

View File

@@ -158,3 +158,9 @@ export const getBookingConfirmation = cache(
return serverClient().booking.confirmation({ confirmationNumber })
}
)
export const getCityCoordinates = cache(
async function getMemoizedCityCoordinates(input: { city: string }) {
return serverClient().hotel.map.city(input)
}
)

View File

@@ -74,3 +74,6 @@ export const getRoomPackagesInputSchema = z.object({
children: z.number().optional().default(0),
packageCodes: z.array(z.string()).optional().default([]),
})
export const getCityCoordinatesInputSchema = z.object({
city: z.string(),
})

View File

@@ -200,14 +200,14 @@ const rewardNightSchema = z.object({
export const pointOfInterestSchema = z
.object({
name: z.string(),
distance: z.number(),
name: z.string().optional(),
distance: z.number().optional(),
category: z.object({
name: z.string(),
group: z.string(),
name: z.string().optional(),
group: z.string().optional(),
}),
location: locationSchema,
isHighlighted: z.boolean(),
location: locationSchema.optional(),
isHighlighted: z.boolean().optional(),
})
.transform((poi) => ({
name: poi.name,
@@ -215,8 +215,8 @@ export const pointOfInterestSchema = z
categoryName: poi.category.name,
group: getPoiGroupByCategoryName(poi.category.name),
coordinates: {
lat: poi.location.latitude,
lng: poi.location.longitude,
lat: poi.location?.latitude ?? 0,
lng: poi.location?.longitude ?? 0,
},
}))
@@ -463,7 +463,9 @@ export const getHotelDataSchema = z.object({
parking: z.array(parkingSchema),
pointsOfInterest: z
.array(pointOfInterestSchema)
.transform((pois) => pois.sort((a, b) => a.distance - b.distance)),
.transform((pois) =>
pois.sort((a, b) => (a.distance ?? 0) - (b.distance ?? 0))
),
ratings: ratingsSchema,
rewardNight: rewardNightSchema,
restaurantImages: facilitySchema.optional(),

View File

@@ -30,6 +30,7 @@ import {
import { getVerifiedUser, parsedUser } from "../user/query"
import {
getBreakfastPackageInputSchema,
getCityCoordinatesInputSchema,
getHotelDataInputSchema,
getHotelsAvailabilityInputSchema,
getRatesInputSchema,
@@ -1081,4 +1082,19 @@ export const hotelQueryRouter = router({
)
}),
}),
map: router({
city: serviceProcedure
.input(getCityCoordinatesInputSchema)
.query(async function ({ input }) {
const apiKey = process.env.GOOGLE_STATIC_MAP_KEY
const { city } = input
const url = `https://maps.googleapis.com/maps/api/geocode/json?address=${encodeURIComponent(city)}&key=${apiKey}`
const response = await fetch(url)
const data = await response.json()
const { lat, lng } = data.results[0].geometry.location
return { lat, lng }
}),
}),
})

View File

@@ -12,13 +12,14 @@ import {
type Countries,
} from "./output"
import type { Lang } from "@/constants/languages"
import type { Endpoint } from "@/lib/api/endpoints"
import type { RequestOptionsWithOutBody } from "@/types/fetch"
import { PointOfInterestGroupEnum } from "@/types/hotel"
import { HotelLocation } from "@/types/trpc/routers/hotel/locations"
import type { Lang } from "@/constants/languages"
import type { Endpoint } from "@/lib/api/endpoints"
export function getPoiGroupByCategoryName(category: string) {
export function getPoiGroupByCategoryName(category: string | undefined) {
if (!category) return PointOfInterestGroupEnum.LOCATION
switch (category) {
case "Airport":
case "Bus terminal":

View File

@@ -22,6 +22,7 @@ export interface SelectHotelMapProps {
mapId: string
hotels: HotelData[]
filterList: CategorizedFilters
cityCoordinates: Coordinates
}
type ImageSizes = z.infer<typeof imageSizesSchema>