Merged in feat/SW-2901-hotel-pins (pull request #2206)
feat(SW-2901): add dynamic hotel markers * feat(SW-2901): add dynamic hotel markers * fix(SW-2901): update type Approved-by: Christian Andolf Approved-by: Erik Tiekstra
This commit is contained in:
@@ -57,7 +57,7 @@ export default function Marker({ position, properties }: MarkerProps) {
|
|||||||
zIndex={isActive ? 300 : 0}
|
zIndex={isActive ? 300 : 0}
|
||||||
>
|
>
|
||||||
<HotelMarkerByType
|
<HotelMarkerByType
|
||||||
smallSize={!isHovered && !isActive}
|
size={isHovered || isActive ? "large" : "small"}
|
||||||
hotelId={properties.id}
|
hotelId={properties.id}
|
||||||
hotelType={properties.type}
|
hotelType={properties.type}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import Sidebar from "./Sidebar"
|
|||||||
import styles from "./hotelMapPage.module.css"
|
import styles from "./hotelMapPage.module.css"
|
||||||
|
|
||||||
import type { Coordinates } from "@/types/components/maps/coordinates"
|
import type { Coordinates } from "@/types/components/maps/coordinates"
|
||||||
|
import type { MarkerInfo } from "@/types/components/maps/marker"
|
||||||
import type { PointOfInterest } from "@/types/hotel"
|
import type { PointOfInterest } from "@/types/hotel"
|
||||||
|
|
||||||
interface HotelMapPageClientProps {
|
interface HotelMapPageClientProps {
|
||||||
@@ -29,11 +30,13 @@ interface HotelMapPageClientProps {
|
|||||||
coordinates: Coordinates
|
coordinates: Coordinates
|
||||||
pointsOfInterest: PointOfInterest[]
|
pointsOfInterest: PointOfInterest[]
|
||||||
mapId: string
|
mapId: string
|
||||||
|
markerInfo: MarkerInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function HotelMapPageClient({
|
export default function HotelMapPageClient({
|
||||||
apiKey,
|
apiKey,
|
||||||
hotelName,
|
hotelName,
|
||||||
|
markerInfo,
|
||||||
coordinates,
|
coordinates,
|
||||||
pointsOfInterest,
|
pointsOfInterest,
|
||||||
mapId,
|
mapId,
|
||||||
@@ -127,6 +130,7 @@ export default function HotelMapPageClient({
|
|||||||
activePoi={activePoi}
|
activePoi={activePoi}
|
||||||
onActivePoiChange={(poi) => setActivePoi(poi ?? null)}
|
onActivePoiChange={(poi) => setActivePoi(poi ?? null)}
|
||||||
mapId={mapId}
|
mapId={mapId}
|
||||||
|
markerInfo={markerInfo}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</APIProvider>
|
</APIProvider>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export default async function HotelMapPage({ hotelId }: HotelMapPageProps) {
|
|||||||
notFound()
|
notFound()
|
||||||
}
|
}
|
||||||
|
|
||||||
const { name, location, pointsOfInterest } = hotelData.hotel
|
const { name, location, pointsOfInterest, hotelType } = hotelData.hotel
|
||||||
|
|
||||||
const coordinates = {
|
const coordinates = {
|
||||||
lat: location.latitude,
|
lat: location.latitude,
|
||||||
@@ -35,6 +35,7 @@ export default async function HotelMapPage({ hotelId }: HotelMapPageProps) {
|
|||||||
apiKey={env.GOOGLE_STATIC_MAP_KEY}
|
apiKey={env.GOOGLE_STATIC_MAP_KEY}
|
||||||
mapId={env.GOOGLE_DYNAMIC_MAP_ID}
|
mapId={env.GOOGLE_DYNAMIC_MAP_ID}
|
||||||
hotelName={name}
|
hotelName={name}
|
||||||
|
markerInfo={{ hotelId, hotelType }}
|
||||||
coordinates={coordinates}
|
coordinates={coordinates}
|
||||||
pointsOfInterest={pointsOfInterest}
|
pointsOfInterest={pointsOfInterest}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import { env } from "@/env/server"
|
import { env } from "@/env/server"
|
||||||
|
|
||||||
import ScandicMarker from "@/components/Maps/Markers/Scandic"
|
import HotelMarkerByType from "@/components/Maps/Markers"
|
||||||
import StaticMapComp from "@/components/Maps/StaticMap"
|
import StaticMapComp from "@/components/Maps/StaticMap"
|
||||||
import { getIntl } from "@/i18n"
|
import { getIntl } from "@/i18n"
|
||||||
import { calculateLatWithOffset } from "@/utils/map"
|
import { calculateLatWithOffset } from "@/utils/map"
|
||||||
@@ -14,6 +14,7 @@ import type { StaticMapProps } from "@/types/components/hotelPage/map/staticMap"
|
|||||||
export default async function StaticMap({
|
export default async function StaticMap({
|
||||||
coordinates,
|
coordinates,
|
||||||
hotelName,
|
hotelName,
|
||||||
|
markerInfo,
|
||||||
zoomLevel = 14,
|
zoomLevel = 14,
|
||||||
}: StaticMapProps) {
|
}: StaticMapProps) {
|
||||||
const intl = await getIntl()
|
const intl = await getIntl()
|
||||||
@@ -41,7 +42,9 @@ export default async function StaticMap({
|
|||||||
)}
|
)}
|
||||||
mapId={mapId}
|
mapId={mapId}
|
||||||
/>
|
/>
|
||||||
<ScandicMarker
|
<HotelMarkerByType
|
||||||
|
hotelId={markerInfo.hotelId}
|
||||||
|
hotelType={markerInfo.hotelType}
|
||||||
className={styles.mapMarker}
|
className={styles.mapMarker}
|
||||||
height={markerHeight}
|
height={markerHeight}
|
||||||
style={{ top: `${mapLatitudeInPx - markerHeight}px` }}
|
style={{ top: `${mapLatitudeInPx - markerHeight}px` }}
|
||||||
|
|||||||
@@ -200,7 +200,11 @@ export default async function HotelPage({ hotelId }: HotelPageProps) {
|
|||||||
</main>
|
</main>
|
||||||
<aside className={styles.mapContainer}>
|
<aside className={styles.mapContainer}>
|
||||||
<MapWithCardWrapper>
|
<MapWithCardWrapper>
|
||||||
<StaticMap coordinates={coordinates} hotelName={name} />
|
<StaticMap
|
||||||
|
coordinates={coordinates}
|
||||||
|
hotelName={name}
|
||||||
|
markerInfo={{ hotelType, hotelId }}
|
||||||
|
/>
|
||||||
<MapCard hotelName={name} pois={topThreePois} />
|
<MapCard hotelName={name} pois={topThreePois} />
|
||||||
</MapWithCardWrapper>
|
</MapWithCardWrapper>
|
||||||
</aside>
|
</aside>
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import { useIntl } from "react-intl"
|
|||||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||||
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
||||||
|
|
||||||
|
import HotelMarkerByType from "../../Markers"
|
||||||
import PoiMarker from "../../Markers/Poi"
|
import PoiMarker from "../../Markers/Poi"
|
||||||
import ScandicMarker from "../../Markers/Scandic"
|
|
||||||
|
|
||||||
import styles from "./poiMapMarkers.module.css"
|
import styles from "./poiMapMarkers.module.css"
|
||||||
|
|
||||||
@@ -19,6 +19,7 @@ export default function PoiMapMarkers({
|
|||||||
pointsOfInterest,
|
pointsOfInterest,
|
||||||
onActivePoiChange,
|
onActivePoiChange,
|
||||||
activePoi,
|
activePoi,
|
||||||
|
markerInfo,
|
||||||
}: PoiMapMarkersProps) {
|
}: PoiMapMarkersProps) {
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
|
|
||||||
@@ -28,7 +29,10 @@ export default function PoiMapMarkers({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<AdvancedMarker position={coordinates} zIndex={1}>
|
<AdvancedMarker position={coordinates} zIndex={1}>
|
||||||
<ScandicMarker />
|
<HotelMarkerByType
|
||||||
|
hotelId={markerInfo.hotelId}
|
||||||
|
hotelType={markerInfo.hotelType}
|
||||||
|
/>
|
||||||
</AdvancedMarker>
|
</AdvancedMarker>
|
||||||
|
|
||||||
{pointsOfInterest.map((poi) => (
|
{pointsOfInterest.map((poi) => (
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ export default function InteractiveMap({
|
|||||||
hotelPins,
|
hotelPins,
|
||||||
mapId,
|
mapId,
|
||||||
closeButton,
|
closeButton,
|
||||||
|
markerInfo,
|
||||||
fitBounds = true,
|
fitBounds = true,
|
||||||
onTilesLoaded,
|
onTilesLoaded,
|
||||||
onActivePoiChange,
|
onActivePoiChange,
|
||||||
@@ -67,12 +68,13 @@ export default function InteractiveMap({
|
|||||||
<div className={styles.mapContainer}>
|
<div className={styles.mapContainer}>
|
||||||
<Map {...mapOptions} onTilesLoaded={onTilesLoaded}>
|
<Map {...mapOptions} onTilesLoaded={onTilesLoaded}>
|
||||||
{hotelPins && <HotelListingMapContent hotelPins={hotelPins} />}
|
{hotelPins && <HotelListingMapContent hotelPins={hotelPins} />}
|
||||||
{pointsOfInterest && (
|
{pointsOfInterest && markerInfo && (
|
||||||
<PoiMapMarkers
|
<PoiMapMarkers
|
||||||
coordinates={coordinates}
|
coordinates={coordinates}
|
||||||
pointsOfInterest={pointsOfInterest}
|
pointsOfInterest={pointsOfInterest}
|
||||||
onActivePoiChange={onActivePoiChange}
|
onActivePoiChange={onActivePoiChange}
|
||||||
activePoi={activePoi}
|
activePoi={activePoi}
|
||||||
|
markerInfo={markerInfo}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Map>
|
</Map>
|
||||||
|
|||||||
@@ -13,40 +13,66 @@ import ScandicGoMarker from "./ScandicGo"
|
|||||||
import ScandicGoSmallMarker from "./ScandicGoSmall"
|
import ScandicGoSmallMarker from "./ScandicGoSmall"
|
||||||
import ScandicSmallMarker from "./ScandicSmall"
|
import ScandicSmallMarker from "./ScandicSmall"
|
||||||
|
|
||||||
|
import type { MarkerInfo } from "@/types/components/maps/marker"
|
||||||
import { HotelTypeEnum } from "@/types/enums/hotelType"
|
import { HotelTypeEnum } from "@/types/enums/hotelType"
|
||||||
import { SignatureHotelEnum } from "@/types/enums/signatureHotel"
|
import { SignatureHotelEnum } from "@/types/enums/signatureHotel"
|
||||||
|
|
||||||
interface HotelMarkerByTypeProps {
|
interface HotelMarkerByTypeProps
|
||||||
hotelId: string
|
extends MarkerInfo,
|
||||||
hotelType: string
|
React.SVGAttributes<HTMLOrSVGElement> {
|
||||||
smallSize?: boolean
|
size?: "large" | "small"
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function HotelMarkerByType({
|
export default function HotelMarkerByType({
|
||||||
hotelId,
|
hotelId,
|
||||||
hotelType,
|
hotelType,
|
||||||
smallSize = true,
|
size = "large",
|
||||||
|
...props
|
||||||
}: HotelMarkerByTypeProps) {
|
}: HotelMarkerByTypeProps) {
|
||||||
if (hotelType === HotelTypeEnum.ScandicGo) {
|
if (hotelType === HotelTypeEnum.ScandicGo) {
|
||||||
return smallSize ? <ScandicGoSmallMarker /> : <ScandicGoMarker />
|
return size === "small" ? (
|
||||||
|
<ScandicGoSmallMarker {...props} />
|
||||||
|
) : (
|
||||||
|
<ScandicGoMarker {...props} />
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (hotelId) {
|
switch (hotelId) {
|
||||||
case SignatureHotelEnum.Haymarket:
|
case SignatureHotelEnum.Haymarket:
|
||||||
return smallSize ? <HaymarketSmallMarker /> : <HaymarketMarker />
|
return size === "small" ? (
|
||||||
case SignatureHotelEnum.HotelNorge:
|
<HaymarketSmallMarker {...props} />
|
||||||
return smallSize ? <HotelNorgeSmallMarker /> : <HotelNorgeMarker />
|
|
||||||
case SignatureHotelEnum.DowntownCamper:
|
|
||||||
return smallSize ? (
|
|
||||||
<DowntownCamperSmallMarker />
|
|
||||||
) : (
|
) : (
|
||||||
<DowntownCamperMarker />
|
<HaymarketMarker {...props} />
|
||||||
|
)
|
||||||
|
case SignatureHotelEnum.HotelNorge:
|
||||||
|
return size === "small" ? (
|
||||||
|
<HotelNorgeSmallMarker {...props} />
|
||||||
|
) : (
|
||||||
|
<HotelNorgeMarker {...props} />
|
||||||
|
)
|
||||||
|
case SignatureHotelEnum.DowntownCamper:
|
||||||
|
return size === "small" ? (
|
||||||
|
<DowntownCamperSmallMarker {...props} />
|
||||||
|
) : (
|
||||||
|
<DowntownCamperMarker {...props} />
|
||||||
)
|
)
|
||||||
case SignatureHotelEnum.GrandHotelOslo:
|
case SignatureHotelEnum.GrandHotelOslo:
|
||||||
return smallSize ? <GrandHotelSmallMarker /> : <GrandHotelMarker />
|
return size === "small" ? (
|
||||||
|
<GrandHotelSmallMarker {...props} />
|
||||||
|
) : (
|
||||||
|
<GrandHotelMarker {...props} />
|
||||||
|
)
|
||||||
case SignatureHotelEnum.Marski:
|
case SignatureHotelEnum.Marski:
|
||||||
return smallSize ? <MarskiSmallMarker /> : <MarskiMarker />
|
return size === "small" ? (
|
||||||
|
<MarskiSmallMarker {...props} />
|
||||||
|
) : (
|
||||||
|
<MarskiMarker {...props} />
|
||||||
|
)
|
||||||
default:
|
default:
|
||||||
return smallSize ? <ScandicSmallMarker /> : <ScandicMarker />
|
return size === "small" ? (
|
||||||
|
<ScandicSmallMarker {...props} />
|
||||||
|
) : (
|
||||||
|
<ScandicMarker {...props} />
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,15 @@ import type { ReactElement } from "react"
|
|||||||
|
|
||||||
import type { HotelPin } from "@/types/components/hotelReservation/selectHotel/map"
|
import type { HotelPin } from "@/types/components/hotelReservation/selectHotel/map"
|
||||||
import type { Coordinates } from "@/types/components/maps/coordinates"
|
import type { Coordinates } from "@/types/components/maps/coordinates"
|
||||||
|
import type { MarkerInfo } from "@/types/components/maps/marker"
|
||||||
import type { PointOfInterest } from "@/types/hotel"
|
import type { PointOfInterest } from "@/types/hotel"
|
||||||
|
|
||||||
export interface InteractiveMapProps {
|
export interface InteractiveMapProps {
|
||||||
coordinates: Coordinates
|
coordinates: Coordinates
|
||||||
pointsOfInterest?: PointOfInterest[]
|
|
||||||
activePoi?: PointOfInterest["name"] | null
|
activePoi?: PointOfInterest["name"] | null
|
||||||
hotelPins?: HotelPin[]
|
hotelPins?: HotelPin[]
|
||||||
|
pointsOfInterest?: PointOfInterest[]
|
||||||
|
markerInfo?: MarkerInfo
|
||||||
mapId: string
|
mapId: string
|
||||||
closeButton: ReactElement
|
closeButton: ReactElement
|
||||||
fitBounds?: boolean
|
fitBounds?: boolean
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
|
import type { MarkerInfo } from "@/types/components/maps/marker"
|
||||||
import type { Coordinates } from "../../maps/coordinates"
|
import type { Coordinates } from "../../maps/coordinates"
|
||||||
|
|
||||||
export type StaticMapProps = {
|
export type StaticMapProps = {
|
||||||
coordinates: Coordinates
|
coordinates: Coordinates
|
||||||
hotelName: string
|
hotelName: string
|
||||||
zoomLevel?: number
|
zoomLevel?: number
|
||||||
|
markerInfo: MarkerInfo
|
||||||
}
|
}
|
||||||
|
|||||||
4
apps/scandic-web/types/components/maps/marker.ts
Normal file
4
apps/scandic-web/types/components/maps/marker.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export type MarkerInfo = {
|
||||||
|
hotelId: string
|
||||||
|
hotelType: string
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { z } from "zod"
|
import type { z } from "zod"
|
||||||
|
|
||||||
|
import type { MarkerInfo } from "@/types/components/maps/marker"
|
||||||
import type {
|
import type {
|
||||||
destinationPagesHotelDataSchema,
|
destinationPagesHotelDataSchema,
|
||||||
hotelSchema,
|
hotelSchema,
|
||||||
@@ -70,6 +71,7 @@ export type PoiMapMarkersProps = {
|
|||||||
coordinates: { lat: number; lng: number }
|
coordinates: { lat: number; lng: number }
|
||||||
onActivePoiChange?: (poiName: string | null) => void
|
onActivePoiChange?: (poiName: string | null) => void
|
||||||
pointsOfInterest: PointOfInterest[]
|
pointsOfInterest: PointOfInterest[]
|
||||||
|
markerInfo: MarkerInfo
|
||||||
}
|
}
|
||||||
export type HotelTripAdvisor =
|
export type HotelTripAdvisor =
|
||||||
| NonNullable<HotelRatings>["tripAdvisor"]
|
| NonNullable<HotelRatings>["tripAdvisor"]
|
||||||
|
|||||||
Reference in New Issue
Block a user