diff --git a/app/[lang]/(live)/(public)/[contentType]/[uid]/layout.module.css b/app/[lang]/(live)/(public)/[contentType]/[uid]/layout.module.css
index 03a7eb926..edd0b9f96 100644
--- a/app/[lang]/(live)/(public)/[contentType]/[uid]/layout.module.css
+++ b/app/[lang]/(live)/(public)/[contentType]/[uid]/layout.module.css
@@ -4,4 +4,5 @@
font-family: var(--typography-Body-Regular-fontFamily);
gap: var(--Spacing-x3);
grid-template-rows: auto 1fr;
+ position: relative;
}
diff --git a/app/globals.css b/app/globals.css
index 480f72fc9..67624cbcf 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -106,11 +106,13 @@
--max-width-navigation: 89.5rem;
--main-menu-mobile-height: 75px;
+ --main-menu-desktop-height: 118px;
+ --hotel-page-map-desktop-width: 23.75rem;
+ /* Z-INDEX */
--header-z-index: 10;
--menu-overlay-z-index: 10;
-
- --hotel-page-map-desktop-width: 23.75rem;
+ --dialog-z-index: 9;
}
* {
diff --git a/components/ContentType/HotelPage/Map/DynamicMap/Content.tsx b/components/ContentType/HotelPage/Map/DynamicMap/Content.tsx
new file mode 100644
index 000000000..c1b04f275
--- /dev/null
+++ b/components/ContentType/HotelPage/Map/DynamicMap/Content.tsx
@@ -0,0 +1,133 @@
+"use client"
+import { AdvancedMarker, Map, useMap } from "@vis.gl/react-google-maps"
+import { useState } from "react"
+
+import useHotelPageStore from "@/stores/hotel-page"
+
+import { CloseIcon, MinusIcon, PlusIcon } from "@/components/Icons"
+import Button from "@/components/TempDesignSystem/Button"
+import Divider from "@/components/TempDesignSystem/Divider"
+import Title from "@/components/TempDesignSystem/Text/Title"
+import { useHandleKeyUp } from "@/hooks/useHandleKeyUp"
+
+import ScandicMarker from "../Markers/Scandic"
+
+import styles from "./dynamicMap.module.css"
+
+export default function DynamicMapContent({
+ hotelName,
+ coordinates,
+}: {
+ hotelName: string
+ coordinates: { lat: number; lng: number }
+}) {
+ const { isDynamicMapOpen, closeDynamicMap } = useHotelPageStore()
+ const [isFullScreenSidebar, setIsFullScreenSidebar] = useState(false)
+ const map = useMap()
+
+ const mapOptions = {
+ defaultZoom: 15,
+ defaultCenter: coordinates,
+ disableDefaultUI: true,
+ clickableIcons: false,
+ mapId: `${hotelName}-map`,
+ // styles: [
+ // {
+ // featureType: "poi",
+ // elementType: "all",
+ // stylers: [{ visibility: "off" }],
+ // },
+ // ],
+ }
+
+ useHandleKeyUp((event: KeyboardEvent) => {
+ if (event.key === "Escape" && isDynamicMapOpen) {
+ closeDynamicMap()
+ }
+ })
+
+ function zoomIn() {
+ const currentZoom = map && map.getZoom()
+ if (currentZoom) {
+ map.setZoom(currentZoom + 1)
+ }
+ }
+ function zoomOut() {
+ const currentZoom = map && map.getZoom()
+ if (currentZoom) {
+ map.setZoom(currentZoom - 1)
+ }
+ }
+
+ function toggleFullScreenSidebar() {
+ setIsFullScreenSidebar((prev) => !prev)
+ }
+
+ return (
+ <>
+
+
+
+
+
+
+ >
+ )
+}
diff --git a/components/ContentType/HotelPage/Map/DynamicMap/dynamicMap.module.css b/components/ContentType/HotelPage/Map/DynamicMap/dynamicMap.module.css
new file mode 100644
index 000000000..d9711e1a5
--- /dev/null
+++ b/components/ContentType/HotelPage/Map/DynamicMap/dynamicMap.module.css
@@ -0,0 +1,156 @@
+.dynamicMap {
+ --sidebar-height: 88px;
+ position: fixed;
+ top: var(--main-menu-mobile-height);
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: var(--dialog-z-index);
+ display: flex;
+}
+
+.sidebar {
+ position: absolute;
+ top: calc(100vh - var(--main-menu-mobile-height) - var(--sidebar-height));
+ height: 100%;
+ right: 0;
+ left: 0;
+ background-color: var(--Base-Surface-Primary-light-Normal);
+ z-index: 1;
+ transition: top 0.3s;
+}
+
+.sidebar:not(.fullscreen) {
+ border-radius: var(--Corner-radius-Large) var(--Corner-radius-Large) 0 0;
+}
+
+.sidebar.fullscreen {
+ top: 0;
+}
+
+.sidebarToggle {
+ display: grid;
+ gap: var(--Spacing-x1);
+ padding: var(--Spacing-x2);
+ height: var(--sidebar-height);
+}
+
+.toggleButton {
+ position: relative;
+ display: flex;
+ justify-content: center;
+ background-color: transparent;
+ border-width: 0;
+ padding: var(--Spacing-x-one-and-half) var(--Spacing-x2);
+ font-family: var(--typography-Body-Bold-fontFamily);
+ font-size: var(--typography-Body-Bold-fontSize);
+ font-weight: 500;
+ color: var(--UI-Text-Medium-contrast);
+ width: 100%;
+}
+
+.toggleButton::before {
+ content: "";
+ position: absolute;
+ display: block;
+ top: -0.5rem;
+ width: 100px;
+ height: 3px;
+ background-color: var(--UI-Text-High-contrast);
+}
+
+.sidebarContent {
+ display: grid;
+ gap: var(--Spacing-x3);
+ align-items: start;
+ padding: var(--Spacing-x3) var(--Spacing-x2);
+ height: 100%;
+ overflow-y: auto;
+}
+
+.mapContainer {
+ flex: 1;
+ position: relative;
+}
+
+.mapContainer::after {
+ content: "";
+ display: block;
+ position: absolute;
+ top: 0;
+ right: 0;
+ background: linear-gradient(
+ 43deg,
+ rgba(172, 172, 172, 0) 57.66%,
+ rgba(0, 0, 0, 0.25) 92.45%
+ );
+ width: 100%;
+ height: 100%;
+ pointer-events: none;
+}
+
+.ctaButtons {
+ position: absolute;
+ top: var(--Spacing-x2);
+ right: var(--Spacing-x2);
+ z-index: 1;
+ display: flex;
+ flex-direction: column;
+ gap: var(--Spacing-x7);
+ align-items: flex-end;
+ pointer-events: none;
+}
+
+.zoomButtons {
+ display: grid;
+ gap: var(--Spacing-x1);
+}
+
+.closeButton {
+ pointer-events: initial;
+ box-shadow: 0 0 8px 1px rgba(0, 0, 0, 0.1);
+}
+
+.zoomButton {
+ width: 40px;
+ padding: 0;
+ pointer-events: initial;
+ box-shadow: 0 0 8px 1px rgba(0, 0, 0, 0.1);
+}
+
+/* @media screen and (max-width: 767px) {
+ .sidebar:not(.fullscreen) .sidebarContent {
+ display: none;
+ }
+} */
+
+@media screen and (min-width: 768px) {
+ .dynamicMap {
+ top: var(--main-menu-desktop-height);
+ }
+ .sidebar {
+ position: static;
+ width: 40vw;
+ min-width: 10rem;
+ max-width: 26.25rem;
+ background-color: var(--Base-Surface-Primary-light-Normal);
+ }
+ .sidebarToggle {
+ display: none;
+ }
+
+ .sidebarContent {
+ padding: var(--Spacing-x4) var(--Spacing-x5);
+ }
+
+ .ctaButtons {
+ top: var(--Spacing-x4);
+ right: var(--Spacing-x4);
+ bottom: var(--Spacing-x4);
+ justify-content: space-between;
+ }
+
+ .zoomButtons {
+ display: flex;
+ }
+}
diff --git a/components/ContentType/HotelPage/Map/DynamicMap/index.tsx b/components/ContentType/HotelPage/Map/DynamicMap/index.tsx
new file mode 100644
index 000000000..8471f5801
--- /dev/null
+++ b/components/ContentType/HotelPage/Map/DynamicMap/index.tsx
@@ -0,0 +1,42 @@
+"use client"
+import { APIProvider } from "@vis.gl/react-google-maps"
+import { Dialog, Modal } from "react-aria-components"
+
+import useHotelPageStore from "@/stores/hotel-page"
+
+import { useHandleKeyUp } from "@/hooks/useHandleKeyUp"
+
+import DynamicMapContent from "./Content"
+
+import styles from "./dynamicMap.module.css"
+
+export default function DynamicMap({
+ apiKey,
+ hotelName,
+ coordinates,
+}: {
+ apiKey: string
+ hotelName: string
+ coordinates: { lat: number; lng: number }
+}) {
+ const { isDynamicMapOpen, closeDynamicMap } = useHotelPageStore()
+
+ useHandleKeyUp((event: KeyboardEvent) => {
+ if (event.key === "Escape" && isDynamicMapOpen) {
+ closeDynamicMap()
+ }
+ })
+
+ return (
+
+
+
+
+
+ )
+}
diff --git a/components/ContentType/HotelPage/Map/MapCard/index.tsx b/components/ContentType/HotelPage/Map/MapCard/index.tsx
index 3b98bde9a..e43cf963e 100644
--- a/components/ContentType/HotelPage/Map/MapCard/index.tsx
+++ b/components/ContentType/HotelPage/Map/MapCard/index.tsx
@@ -1,5 +1,7 @@
"use client"
+import useHotelPageStore from "@/stores/hotel-page"
+
import Button from "@/components/TempDesignSystem/Button"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import Title from "@/components/TempDesignSystem/Text/Title"
@@ -9,9 +11,15 @@ import styles from "./mapCard.module.css"
import { MapCardProps } from "@/types/components/hotelPage/mapCard"
export default function MapCard({ hotelName }: MapCardProps) {
+ const { openDynamicMap } = useHotelPageStore()
+
return (
-
+
Nearby
Explore nearby
diff --git a/components/ContentType/HotelPage/Map/MapCard/mapCard.module.css b/components/ContentType/HotelPage/Map/MapCard/mapCard.module.css
index 7fb7919ec..0dc97db88 100644
--- a/components/ContentType/HotelPage/Map/MapCard/mapCard.module.css
+++ b/components/ContentType/HotelPage/Map/MapCard/mapCard.module.css
@@ -1,12 +1,13 @@
.mapCard {
+ display: grid;
position: absolute;
bottom: 15%;
+ left: var(--Spacing-x2);
+ right: var(--Spacing-x2);
background-color: var(--Base-Surface-Primary-light-Normal);
- margin: 0 var(--Spacing-x4);
padding: var(--Spacing-x2);
box-shadow: 0 0 2.5rem 0 rgba(0, 0, 0, 0.12);
border-radius: var(--Corner-radius-Medium);
- display: grid;
}
.ctaButton {
diff --git a/components/ContentType/HotelPage/Map/Markers/Scandic.tsx b/components/ContentType/HotelPage/Map/Markers/Scandic.tsx
new file mode 100644
index 000000000..0028b37d7
--- /dev/null
+++ b/components/ContentType/HotelPage/Map/Markers/Scandic.tsx
@@ -0,0 +1,153 @@
+export default function ScandicMarker({
+ className,
+ ...props
+}: React.SVGAttributes) {
+ return (
+
+ )
+}
diff --git a/components/ContentType/HotelPage/Map/MobileMapToggle/index.tsx b/components/ContentType/HotelPage/Map/MobileMapToggle/index.tsx
new file mode 100644
index 000000000..bf2ef3b8e
--- /dev/null
+++ b/components/ContentType/HotelPage/Map/MobileMapToggle/index.tsx
@@ -0,0 +1,43 @@
+"use client"
+
+import useHotelPageStore from "@/stores/hotel-page"
+
+import { HouseIcon, LocationIcon } from "@/components/Icons"
+
+import styles from "./mobileToggle.module.css"
+
+export default function MobileMapToggle() {
+ const { isDynamicMapOpen, openDynamicMap, closeDynamicMap } =
+ useHotelPageStore()
+
+ return (
+
+
+
+
+ )
+}
diff --git a/components/ContentType/HotelPage/Map/MobileToggle/mobileToggle.module.css b/components/ContentType/HotelPage/Map/MobileMapToggle/mobileToggle.module.css
similarity index 90%
rename from components/ContentType/HotelPage/Map/MobileToggle/mobileToggle.module.css
rename to components/ContentType/HotelPage/Map/MobileMapToggle/mobileToggle.module.css
index b93941151..2d36929cf 100644
--- a/components/ContentType/HotelPage/Map/MobileToggle/mobileToggle.module.css
+++ b/components/ContentType/HotelPage/Map/MobileMapToggle/mobileToggle.module.css
@@ -1,4 +1,9 @@
.mobileToggle {
+ position: fixed;
+ bottom: var(--Spacing-x5);
+ left: 50%;
+ transform: translateX(-50%);
+ z-index: 1;
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: var(--Spacing-x-half);
diff --git a/components/ContentType/HotelPage/Map/MobileToggle/index.tsx b/components/ContentType/HotelPage/Map/MobileToggle/index.tsx
deleted file mode 100644
index bce32e387..000000000
--- a/components/ContentType/HotelPage/Map/MobileToggle/index.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-"use client"
-
-import { HouseIcon, LocationIcon } from "@/components/Icons"
-
-import styles from "./mobileToggle.module.css"
-
-import { IconName } from "@/types/components/icon"
-
-export default function MobileToggle() {
- const options: { text: string; icon: IconName }[] = [
- {
- text: "Hotel",
- icon: IconName.House,
- },
- {
- text: "Nearby",
- icon: IconName.Location,
- },
- ]
-
- function onToggle() {
- console.log("Toggle mobile map")
- }
-
- return (
-
-
-
-
- )
-}
diff --git a/components/ContentType/HotelPage/Map/StaticMap/index.tsx b/components/ContentType/HotelPage/Map/StaticMap/index.tsx
index 7eeeed944..359d38bb9 100644
--- a/components/ContentType/HotelPage/Map/StaticMap/index.tsx
+++ b/components/ContentType/HotelPage/Map/StaticMap/index.tsx
@@ -4,14 +4,17 @@ import { env } from "@/env/server"
import { getIntl } from "@/i18n"
+import ScandicMarker from "../Markers/Scandic"
import { calculateLatWithOffset, getUrlWithSignature } from "./util"
+import styles from "./staticMap.module.css"
+
import { StaticMapProps } from "@/types/components/hotelPage/staticMap"
export default async function StaticMap({
coordinates,
hotelName,
- zoomLevel = 16,
+ zoomLevel = 14,
}: StaticMapProps) {
const intl = await getIntl()
const key = env.GOOGLE_STATIC_MAP_KEY
@@ -19,8 +22,11 @@ export default async function StaticMap({
const baseUrl = "https://maps.googleapis.com/maps/api/staticmap"
const { lng, lat } = coordinates
const mapHeight = 785
+ const markerHeight = 100
+ const mapLatitudeInPx = mapHeight * 0.2
const size = `380x${mapHeight}`
- const mapLatitude = calculateLatWithOffset(lat, mapHeight * 0.2, zoomLevel)
+
+ const mapLatitude = calculateLatWithOffset(lat, mapLatitudeInPx, zoomLevel)
// Custom Icon should be available from a public URL accessible by Google Static Maps API. At the moment, we don't have a public URL for the custom icon.
// const marker = `icon:https://IMAGE_URL|${lat},${lng}`
const marker = `${lat},${lng}`
@@ -28,10 +34,22 @@ export default async function StaticMap({
const alt = intl.formatMessage({ id: "Map of HOTEL_NAME" }, { hotelName })
const url = new URL(
- `${baseUrl}?zoom=${zoomLevel}¢er=${mapLatitude},${lng}&size=${size}&markers=${marker}&key=${key}`
+ `${baseUrl}?zoom=${zoomLevel}¢er=${mapLatitude},${lng}&size=${size}&key=${key}`
)
+ // const url = new URL(
+ // `${baseUrl}?zoom=${zoomLevel}¢er=${mapLatitude},${lng}&size=${size}&markers=${marker}&key=${key}`
+ // )
const src = getUrlWithSignature(url, secret)
- return
+ return (
+
+

+
+
+ )
}
diff --git a/components/ContentType/HotelPage/Map/StaticMap/staticMap.module.css b/components/ContentType/HotelPage/Map/StaticMap/staticMap.module.css
new file mode 100644
index 000000000..57f45a428
--- /dev/null
+++ b/components/ContentType/HotelPage/Map/StaticMap/staticMap.module.css
@@ -0,0 +1,9 @@
+.staticMap {
+ position: relative;
+}
+
+.mapMarker {
+ position: absolute;
+ left: 50%;
+ transform: translateX(-50%);
+}
diff --git a/components/ContentType/HotelPage/Map/index.tsx b/components/ContentType/HotelPage/Map/index.tsx
deleted file mode 100644
index 0b7823f90..000000000
--- a/components/ContentType/HotelPage/Map/index.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import MapCard from "./MapCard"
-import MobileToggle from "./MobileToggle"
-import StaticMap from "./StaticMap"
-
-import styles from "./map.module.css"
-
-export default function Map({ coordinates, hotelName }: any) {
- return (
- <>
-
-
-
-
-
- >
- )
-}
diff --git a/components/ContentType/HotelPage/Map/map.module.css b/components/ContentType/HotelPage/Map/map.module.css
deleted file mode 100644
index 5fd435396..000000000
--- a/components/ContentType/HotelPage/Map/map.module.css
+++ /dev/null
@@ -1,12 +0,0 @@
-.desktopContent {
- display: none;
-}
-
-@media screen and (min-width: 1367px) {
- .desktopContent {
- align-self: start;
- position: relative;
- display: grid;
- justify-items: center;
- }
-}
diff --git a/components/ContentType/HotelPage/TabNavigation/tabNavigation.module.css b/components/ContentType/HotelPage/TabNavigation/tabNavigation.module.css
index 9e5ee8f5a..679d9f2a0 100644
--- a/components/ContentType/HotelPage/TabNavigation/tabNavigation.module.css
+++ b/components/ContentType/HotelPage/TabNavigation/tabNavigation.module.css
@@ -1,7 +1,7 @@
.stickyWrapper {
position: sticky;
top: 0;
- z-index: 10;
+ z-index: 1;
background-color: var(--Base-Surface-Subtle-Normal);
border-bottom: 1px solid var(--Base-Border-Subtle);
overflow-x: auto;
diff --git a/components/ContentType/HotelPage/hotelPage.module.css b/components/ContentType/HotelPage/hotelPage.module.css
index a594f1902..0c4820ef0 100644
--- a/components/ContentType/HotelPage/hotelPage.module.css
+++ b/components/ContentType/HotelPage/hotelPage.module.css
@@ -22,12 +22,7 @@
}
.mapContainer {
- position: fixed;
- bottom: var(--Spacing-x5);
- display: flex;
- justify-content: center;
- width: 100vw;
- z-index: 1;
+ display: none;
}
.introContainer {
@@ -48,13 +43,13 @@
padding: var(--Spacing-x6) 0;
}
.mapContainer {
+ display: flex;
grid-area: mapContainer;
+ align-self: start;
position: sticky;
top: 0;
- align-self: start;
- justify-content: initial;
+ justify-content: center;
width: 100%;
- z-index: 0;
}
.pageContainer > nav {
diff --git a/components/ContentType/HotelPage/index.tsx b/components/ContentType/HotelPage/index.tsx
index 6d55da887..4c905004e 100644
--- a/components/ContentType/HotelPage/index.tsx
+++ b/components/ContentType/HotelPage/index.tsx
@@ -1,3 +1,4 @@
+import { env } from "@/env/server"
import { serverClient } from "@/lib/trpc/server"
import AmenitiesList from "./AmenitiesList"
@@ -5,7 +6,10 @@ import Facilities from "./Facilities"
import { MOCK_FACILITIES } from "./Facilities/mockData"
import { setActivityCard } from "./Facilities/utils"
import IntroSection from "./IntroSection"
-import Map from "./Map"
+import DynamicMap from "./Map/DynamicMap"
+import MapCard from "./Map/MapCard"
+import MobileMapToggle from "./Map/MobileMapToggle"
+import StaticMap from "./Map/StaticMap"
import PreviewImages from "./PreviewImages"
import { Rooms } from "./Rooms"
import SidePeeks from "./SidePeeks"
@@ -14,6 +18,7 @@ import TabNavigation from "./TabNavigation"
import styles from "./hotelPage.module.css"
export default async function HotelPage() {
+ const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY
const hotelData = await serverClient().hotel.get({
include: ["RoomCategories"],
})
@@ -61,9 +66,21 @@ export default async function HotelPage() {
-
+ {googleMapsApiKey ? (
+ <>
+
+
+
+ >
+ ) : null}
)
diff --git a/components/Icons/Minus.tsx b/components/Icons/Minus.tsx
new file mode 100644
index 000000000..84ada8943
--- /dev/null
+++ b/components/Icons/Minus.tsx
@@ -0,0 +1,23 @@
+import { iconVariants } from "./variants"
+
+import type { IconProps } from "@/types/components/icon"
+
+export default function MinusIcon({ className, color, ...props }: IconProps) {
+ const classNames = iconVariants({ className, color })
+ return (
+
+ )
+}
diff --git a/components/Icons/Plus.tsx b/components/Icons/Plus.tsx
new file mode 100644
index 000000000..b8826bb2f
--- /dev/null
+++ b/components/Icons/Plus.tsx
@@ -0,0 +1,23 @@
+import { iconVariants } from "./variants"
+
+import type { IconProps } from "@/types/components/icon"
+
+export default function PlusIcon({ className, color, ...props }: IconProps) {
+ const classNames = iconVariants({ className, color })
+ return (
+
+ )
+}
diff --git a/components/Icons/get-icon-by-icon-name.ts b/components/Icons/get-icon-by-icon-name.ts
index d7508b83a..6fbc26c0f 100644
--- a/components/Icons/get-icon-by-icon-name.ts
+++ b/components/Icons/get-icon-by-icon-name.ts
@@ -33,12 +33,14 @@ import {
InfoCircleIcon,
LocationIcon,
LockIcon,
+ MinusIcon,
ParkingIcon,
People2Icon,
PersonIcon,
PetsIcon,
PhoneIcon,
PlusCircleIcon,
+ PlusIcon,
RestaurantIcon,
SaunaIcon,
SearchIcon,
@@ -114,6 +116,8 @@ export function getIconByIconName(icon?: IconName): FC | null {
return LocationIcon
case IconName.Lock:
return LockIcon
+ case IconName.Minus:
+ return MinusIcon
case IconName.Parking:
return ParkingIcon
case IconName.Person:
@@ -124,6 +128,8 @@ export function getIconByIconName(icon?: IconName): FC | null {
return PetsIcon
case IconName.Phone:
return PhoneIcon
+ case IconName.Plus:
+ return PlusIcon
case IconName.PlusCircle:
return PlusCircleIcon
case IconName.Restaurant:
diff --git a/components/Icons/index.tsx b/components/Icons/index.tsx
index 9ed34a098..80f978546 100644
--- a/components/Icons/index.tsx
+++ b/components/Icons/index.tsx
@@ -29,11 +29,13 @@ export { default as ImageIcon } from "./Image"
export { default as InfoCircleIcon } from "./InfoCircle"
export { default as LocationIcon } from "./Location"
export { default as LockIcon } from "./Lock"
+export { default as MinusIcon } from "./Minus"
export { default as ParkingIcon } from "./Parking"
export { default as People2Icon } from "./People2"
export { default as PersonIcon } from "./Person"
export { default as PetsIcon } from "./Pets"
export { default as PhoneIcon } from "./Phone"
+export { default as PlusIcon } from "./Plus"
export { default as PlusCircleIcon } from "./PlusCircle"
export { default as PriceTagIcon } from "./PriceTag"
export { default as RestaurantIcon } from "./Restaurant"
diff --git a/components/TempDesignSystem/Text/Caption/caption.module.css b/components/TempDesignSystem/Text/Caption/caption.module.css
index d359c2a36..d2dcd9208 100644
--- a/components/TempDesignSystem/Text/Caption/caption.module.css
+++ b/components/TempDesignSystem/Text/Caption/caption.module.css
@@ -48,7 +48,7 @@
}
.textMediumContrast {
- color: var(--UI-Text-Medium-contrast);
+ color: var(--Base-Text-Medium-contrast);
}
.red {
diff --git a/package-lock.json b/package-lock.json
index cae0b620f..092398c1b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -27,6 +27,7 @@
"@trpc/react-query": "^11.0.0-rc.467",
"@trpc/server": "^11.0.0-rc.467",
"@vercel/otel": "^1.9.1",
+ "@vis.gl/react-google-maps": "^1.1.3",
"class-variance-authority": "^0.7.0",
"clean-deep": "^3.4.0",
"dayjs": "^1.11.10",
@@ -6268,6 +6269,11 @@
"integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==",
"license": "MIT"
},
+ "node_modules/@types/google.maps": {
+ "version": "3.58.0",
+ "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.58.0.tgz",
+ "integrity": "sha512-rZPrbNHoGxeY70uuQYFLGQqcz5mLd3pZy0u286GSugvN7PLFsHNRF2wN2QXtUgNiC33IC0LX+MD3LGAC3wN7Eg=="
+ },
"node_modules/@types/graceful-fs": {
"version": "4.1.9",
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
@@ -6649,6 +6655,19 @@
"@opentelemetry/sdk-trace-base": "^1.19.0"
}
},
+ "node_modules/@vis.gl/react-google-maps": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@vis.gl/react-google-maps/-/react-google-maps-1.1.3.tgz",
+ "integrity": "sha512-jsjj5OpL5AyQDSfzBHU+r5UGAuZxv/7mw9gM2dP4EhqRXkXBpwDKKlml47/4l0m1WL4fSEXLzv85Mrh1VhPiFA==",
+ "dependencies": {
+ "@types/google.maps": "^3.54.10",
+ "fast-deep-equal": "^3.1.3"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0",
+ "react-dom": ">=16.8.0"
+ }
+ },
"node_modules/abab": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
@@ -9968,8 +9987,7 @@
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "dev": true
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
"node_modules/fast-glob": {
"version": "3.3.2",
diff --git a/package.json b/package.json
index 963a2a49a..51a08a525 100644
--- a/package.json
+++ b/package.json
@@ -43,6 +43,7 @@
"@trpc/react-query": "^11.0.0-rc.467",
"@trpc/server": "^11.0.0-rc.467",
"@vercel/otel": "^1.9.1",
+ "@vis.gl/react-google-maps": "^1.1.3",
"class-variance-authority": "^0.7.0",
"clean-deep": "^3.4.0",
"dayjs": "^1.11.10",
diff --git a/public/_static/icons/map-marker-pin.svg b/public/_static/icons/map-marker-pin.svg
deleted file mode 100644
index 93bcc1732..000000000
--- a/public/_static/icons/map-marker-pin.svg
+++ /dev/null
@@ -1,41 +0,0 @@
-
diff --git a/stores/hotel-page.ts b/stores/hotel-page.ts
new file mode 100644
index 000000000..162af53b8
--- /dev/null
+++ b/stores/hotel-page.ts
@@ -0,0 +1,15 @@
+import { create } from "zustand"
+
+interface HotelPageState {
+ isDynamicMapOpen: boolean
+ openDynamicMap: () => void
+ closeDynamicMap: () => void
+}
+
+const useHotelPageStore = create((set) => ({
+ isDynamicMapOpen: false,
+ openDynamicMap: () => set({ isDynamicMapOpen: true }),
+ closeDynamicMap: () => set({ isDynamicMapOpen: false }),
+}))
+
+export default useHotelPageStore
diff --git a/types/components/icon.ts b/types/components/icon.ts
index b0f6359d8..a1d679c43 100644
--- a/types/components/icon.ts
+++ b/types/components/icon.ts
@@ -38,11 +38,13 @@ export enum IconName {
Instagram = "Instagram",
Location = "Location",
Lock = "Lock",
+ Minus = "Minus",
Parking = "Parking",
Person = "Person",
People2 = "People2",
Pets = "Pets",
Phone = "Phone",
+ Plus = "Plus",
PlusCircle = "PlusCircle",
Restaurant = "Restaurant",
Sauna = "Sauna",