diff --git a/components/ContentType/HotelPage/IntroSection/index.tsx b/components/ContentType/HotelPage/IntroSection/index.tsx
index d20486c60..cb62ca01c 100644
--- a/components/ContentType/HotelPage/IntroSection/index.tsx
+++ b/components/ContentType/HotelPage/IntroSection/index.tsx
@@ -73,6 +73,7 @@ export default async function IntroSection({
color="burgundy"
variant="icon"
href={`?s=${about[lang]}`}
+ scroll={false}
>
{intl.formatMessage({ id: "Read more about the hotel" })}
diff --git a/components/ContentType/HotelPage/SidePeeks.tsx b/components/ContentType/HotelPage/SidePeeks.tsx
deleted file mode 100644
index 2fcf9b46f..000000000
--- a/components/ContentType/HotelPage/SidePeeks.tsx
+++ /dev/null
@@ -1,99 +0,0 @@
-"use client"
-
-import { usePathname, useRouter, useSearchParams } from "next/navigation"
-import { useEffect, useState } from "react"
-import { useIntl } from "react-intl"
-
-import {
- about,
- activities,
- amenities,
- meetingsAndConferences,
- restaurantAndBar,
- wellnessAndExercise,
-} from "@/constants/routes/hotelPageParams"
-
-import SidePeek from "@/components/TempDesignSystem/SidePeek"
-import SidePeekItem from "@/components/TempDesignSystem/SidePeek/Item"
-import { SidePeekContentKey } from "@/components/TempDesignSystem/SidePeek/types"
-import useLang from "@/hooks/useLang"
-
-function SidePeekContainer() {
- const router = useRouter()
- const pathname = usePathname()
- const searchParams = useSearchParams()
- const [activeSidePeek, setActiveSidePeek] =
- useState(() => {
- const sidePeekParam = searchParams.get("s") as SidePeekContentKey | null
- return sidePeekParam || null
- })
-
- const lang = useLang()
- const intl = useIntl()
-
- useEffect(() => {
- const sidePeekParam = searchParams.get("s") as SidePeekContentKey | null
- if (sidePeekParam !== activeSidePeek) {
- setActiveSidePeek(sidePeekParam)
- }
- }, [searchParams, activeSidePeek])
-
- function handleClose(isOpen: boolean) {
- if (!isOpen) {
- setActiveSidePeek(null)
-
- const nextSearchParams = new URLSearchParams(searchParams.toString())
- nextSearchParams.delete("s")
-
- router.push(`${pathname}?${nextSearchParams}`, { scroll: false })
- }
- }
-
- return (
-
-
- {/* TODO: Render amenities as per the design. */}
- Read more about the amenities here
-
-
- Some additional information about the hotel
-
-
- {/* TODO */}
- Restaurant & Bar
-
-
- {/* TODO */}
- Wellness & Exercise
-
-
- {/* TODO */}
- Activities
-
-
- {/* TODO */}
- Meetings & Conferences
-
-
- )
-}
-
-export default SidePeekContainer
diff --git a/components/ContentType/HotelPage/index.tsx b/components/ContentType/HotelPage/index.tsx
index f37750db4..210bf9b7c 100644
--- a/components/ContentType/HotelPage/index.tsx
+++ b/components/ContentType/HotelPage/index.tsx
@@ -1,6 +1,12 @@
+import hotelPageParams from "@/constants/routes/hotelPageParams"
import { env } from "@/env/server"
import { serverClient } from "@/lib/trpc/server"
+import SidePeekProvider from "@/components/SidePeekProvider"
+import SidePeek from "@/components/TempDesignSystem/SidePeek"
+import { getIntl } from "@/i18n"
+import { getLang } from "@/i18n/serverContext"
+
import { MOCK_FACILITIES } from "./Facilities/mockData"
import { setActivityCard } from "./Facilities/utils"
import DynamicMap from "./Map/DynamicMap"
@@ -12,13 +18,14 @@ import Facilities from "./Facilities"
import IntroSection from "./IntroSection"
import PreviewImages from "./PreviewImages"
import { Rooms } from "./Rooms"
-import SidePeeks from "./SidePeeks"
import TabNavigation from "./TabNavigation"
import styles from "./hotelPage.module.css"
export default async function HotelPage() {
const googleMapsApiKey = env.GOOGLE_STATIC_MAP_KEY
+ const intl = await getIntl()
+ const lang = getLang()
const hotelData = await serverClient().hotel.get({
include: ["RoomCategories"],
})
@@ -61,6 +68,51 @@ export default async function HotelPage() {
address={hotelAddress}
tripAdvisor={hotelRatings?.tripAdvisor}
/>
+
+ {/* eslint-disable import/no-named-as-default-member */}
+
+ {/* TODO: Render amenities as per the design. */}
+ Read more about the amenities here
+
+
+ Some additional information about the hotel
+
+
+ {/* TODO */}
+ Restaurant & Bar
+
+
+ {/* TODO */}
+ Wellness & Exercise
+
+
+ {/* TODO */}
+ Activities
+
+
+ {/* TODO */}
+ Meetings & Conferences
+
+ {/* eslint-enable import/no-named-as-default-member */}
+
@@ -80,7 +132,6 @@ export default async function HotelPage() {
/>
>
) : null}
-
)
}
diff --git a/components/SidePeekProvider/index.tsx b/components/SidePeekProvider/index.tsx
new file mode 100644
index 000000000..dad577b55
--- /dev/null
+++ b/components/SidePeekProvider/index.tsx
@@ -0,0 +1,45 @@
+"use client"
+import { usePathname, useRouter, useSearchParams } from "next/navigation"
+import { createContext, useEffect, useState } from "react"
+
+interface ISidePeekContext {
+ handleClose: (isOpen: boolean) => void
+ activeSidePeek: string | null
+}
+
+export const SidePeekContext = createContext(null)
+
+function SidePeekProvider({ children }: React.PropsWithChildren) {
+ const router = useRouter()
+ const pathname = usePathname()
+ const searchParams = useSearchParams()
+ const [activeSidePeek, setActiveSidePeek] = useState(() => {
+ const sidePeekParam = searchParams.get("s")
+ return sidePeekParam || null
+ })
+
+ useEffect(() => {
+ const sidePeekParam = searchParams.get("s")
+ if (sidePeekParam !== activeSidePeek) {
+ setActiveSidePeek(sidePeekParam)
+ }
+ }, [searchParams, activeSidePeek])
+
+ function handleClose(isOpen: boolean) {
+ if (!isOpen) {
+ const nextSearchParams = new URLSearchParams(searchParams.toString())
+ nextSearchParams.delete("s")
+
+ router.push(`${pathname}?${nextSearchParams}`, { scroll: false })
+ setActiveSidePeek(null)
+ }
+ }
+
+ return (
+
+ {children}
+
+ )
+}
+
+export default SidePeekProvider
diff --git a/components/TempDesignSystem/Link/index.tsx b/components/TempDesignSystem/Link/index.tsx
index 6856f87aa..23cf15e46 100644
--- a/components/TempDesignSystem/Link/index.tsx
+++ b/components/TempDesignSystem/Link/index.tsx
@@ -75,7 +75,7 @@ export default function Link({
trackPageViewStart()
startTransition(() => {
startRouterTransition()
- router.push(href)
+ router.push(href, { scroll })
})
}}
href={href}
diff --git a/components/TempDesignSystem/SidePeek/Item/index.tsx b/components/TempDesignSystem/SidePeek/Item/index.tsx
deleted file mode 100644
index fa897aae9..000000000
--- a/components/TempDesignSystem/SidePeek/Item/index.tsx
+++ /dev/null
@@ -1,39 +0,0 @@
-"use client"
-
-import { PropsWithChildren } from "react"
-
-import { CloseIcon } from "@/components/Icons"
-import { SidePeekContentProps } from "@/components/TempDesignSystem/SidePeek/types"
-import Title from "@/components/TempDesignSystem/Text/Title"
-
-import Button from "../../Button"
-
-import styles from "./sidePeekItem.module.css"
-
-function SidePeekItem({
- title,
- children,
- isActive = false,
- onClose,
-}: PropsWithChildren) {
- return isActive ? (
-
- ) : null
-}
-
-export default SidePeekItem
\ No newline at end of file
diff --git a/components/TempDesignSystem/SidePeek/Item/sidePeekItem.module.css b/components/TempDesignSystem/SidePeek/Item/sidePeekItem.module.css
deleted file mode 100644
index eb90ed60b..000000000
--- a/components/TempDesignSystem/SidePeek/Item/sidePeekItem.module.css
+++ /dev/null
@@ -1,27 +0,0 @@
-.sidePeekItem {
- display: grid;
- grid-template-rows: min-content auto;
- gap: var(--Spacing-x4);
- height: 100%;
-}
-
-.content>* {
- padding: var(--Spacing-x3) var(--Spacing-x2);
-}
-
-.header {
- display: flex;
- justify-content: flex-end;
- border-bottom: 1px solid var(--Base-Border-Subtle);
- align-items: center;
-}
-
-.header:has(> h2) {
- justify-content: space-between;
-}
-
-@media screen and (min-width: 1367px) {
- .content>* {
- padding: var(--Spacing-x4);
- }
-}
\ No newline at end of file
diff --git a/components/TempDesignSystem/SidePeek/index.tsx b/components/TempDesignSystem/SidePeek/index.tsx
index 271ad30e5..df0b8dc44 100644
--- a/components/TempDesignSystem/SidePeek/index.tsx
+++ b/components/TempDesignSystem/SidePeek/index.tsx
@@ -1,15 +1,20 @@
"use client"
import { useIsSSR } from "@react-aria/ssr"
-import React, { Children, cloneElement } from "react"
+import { useContext } from "react"
import {
Dialog,
DialogTrigger,
Modal,
ModalOverlay,
} from "react-aria-components"
+import { useIntl } from "react-intl"
-import { SidePeekContentKey } from "@/components/TempDesignSystem/SidePeek/types"
+import { CloseIcon } from "@/components/Icons"
+import { SidePeekContext } from "@/components/SidePeekProvider"
+
+import Button from "../Button"
+import Title from "../Text/Title"
import styles from "./sidePeek.module.css"
@@ -17,33 +22,61 @@ import type { SidePeekProps } from "./sidePeek"
function SidePeek({
children,
+ title,
+ contentKey,
handleClose,
- activeSidePeek,
+ isOpen,
}: React.PropsWithChildren) {
- const sidePeekChildren = Children.map(children, (child) => {
- if (!React.isValidElement(child)) {
- return child
- }
- return cloneElement(child as React.ReactElement, {
- isActive:
- (child.props.contentKey as SidePeekContentKey) === activeSidePeek,
- onClose: handleClose,
- })
- })
-
const isSSR = useIsSSR()
- return isSSR ? (
- {children}
- ) : (
+ const intl = useIntl()
+ const context = useContext(SidePeekContext)
+ function onClose() {
+ const closeHandler = handleClose || context?.handleClose
+ closeHandler && closeHandler(false)
+ }
+
+ if (isSSR) {
+ return (
+
+
{title}
+ {children}
+
+ )
+ }
+ return (
-
-
+
+
diff --git a/components/TempDesignSystem/SidePeek/sidePeek.module.css b/components/TempDesignSystem/SidePeek/sidePeek.module.css
index 0ed9304c5..2d6de4f00 100644
--- a/components/TempDesignSystem/SidePeek/sidePeek.module.css
+++ b/components/TempDesignSystem/SidePeek/sidePeek.module.css
@@ -1,38 +1,9 @@
-.sidePeek {
- position: fixed;
- top: var(--current-mobile-site-header-height);
- right: auto;
- bottom: 0;
- width: 100%;
- height: calc(100vh - var(--current-mobile-site-header-height));
- background-color: var(--Base-Background-Primary-Normal);
- z-index: 100;
- box-shadow: 0 0 10px rgba(0, 0, 0, 0.85);
-}
-
-.sidePeek[data-entering] {
- animation: slide-up 300ms;
-}
-
-.sidePeek[data-exiting] {
- animation: slide-up 300ms reverse;
-}
-
-.dialog {
- height: 100%;
-}
-
-.overlay {
- position: absolute;
- top: var(--current-mobile-site-header-height);
- bottom: 0;
- left: 0;
- right: 0;
- z-index: 99;
+.modal {
+ --sidepeek-desktop-width: 600px;
}
@keyframes slide-in {
from {
- right: -600px;
+ right: calc(-1 * var(--sidepeek-desktop-width));
}
to {
@@ -46,24 +17,84 @@
}
to {
- top: var(--current-mobile-site-header-height);
+ top: 0;
}
}
+.overlay {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ z-index: 99;
+}
+
+.modal {
+ position: fixed;
+ top: 0;
+ right: auto;
+ bottom: 0;
+ width: 100%;
+ height: 100vh;
+ background-color: var(--Base-Background-Primary-Normal);
+ z-index: 100;
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.85);
+}
+
+.modal[data-entering] {
+ animation: slide-up 300ms;
+}
+
+.modal[data-exiting] {
+ animation: slide-up 300ms reverse;
+}
+
+.dialog {
+ height: 100%;
+}
+
+.sidePeek {
+ display: grid;
+ grid-template-rows: min-content auto;
+ height: 100%;
+}
+
+.header {
+ display: flex;
+ justify-content: flex-end;
+ border-bottom: 1px solid var(--Base-Border-Subtle);
+ align-items: center;
+ padding: var(--Spacing-x4);
+}
+
+.header:has(> h2) {
+ justify-content: space-between;
+}
+
+.closeButton {
+ padding: 0;
+}
+
+.sidePeekContent {
+ padding: var(--Spacing-x4);
+}
@media screen and (min-width: 1367px) {
- .sidePeek {
+ .modal {
top: 0;
right: 0px;
- width: 600px;
+ width: var(--sidepeek-desktop-width);
height: 100vh;
}
- .sidePeek[data-entering] {
+
+ .modal[data-entering] {
animation: slide-in 250ms;
}
- .sidePeek[data-exiting] {
+ .modal[data-exiting] {
animation: slide-in 250ms reverse;
}
+
.overlay {
top: 0;
}
diff --git a/components/TempDesignSystem/SidePeek/sidePeek.ts b/components/TempDesignSystem/SidePeek/sidePeek.ts
index 626fc640c..e1781f137 100644
--- a/components/TempDesignSystem/SidePeek/sidePeek.ts
+++ b/components/TempDesignSystem/SidePeek/sidePeek.ts
@@ -1,4 +1,6 @@
export interface SidePeekProps {
- handleClose: (isOpen: boolean) => void
- activeSidePeek: string | null
+ contentKey: string
+ title: string
+ isOpen?: boolean
+ handleClose?: (isOpen: boolean) => void
}
diff --git a/components/TempDesignSystem/SidePeek/types.ts b/components/TempDesignSystem/SidePeek/types.ts
index f506fc6bf..e37554aff 100644
--- a/components/TempDesignSystem/SidePeek/types.ts
+++ b/components/TempDesignSystem/SidePeek/types.ts
@@ -1,5 +1,3 @@
-export type SidePeekContentKey = string
-
export type SidePeekProps = {
activeContent: string | null
onClose: (isOpen: boolean) => void
@@ -7,7 +5,7 @@ export type SidePeekProps = {
export type SidePeekContentProps = {
title?: string
- contentKey: SidePeekContentKey
+ contentKey: string
isActive?: boolean
onClose?: () => void
}