fix(SW-239): make contents in sidepeek component render serverside for seo

This commit is contained in:
Arvid Norlin
2024-08-09 15:28:22 +02:00
parent b9d63d9f01
commit 47c77b62d6
9 changed files with 908 additions and 910 deletions

View File

@@ -1,8 +1,6 @@
import { mapFacilityToIcon } from "@/components/ContentType/HotelPage/data"
import { ChevronRightIcon } from "@/components/Icons"
import Link from "@/components/TempDesignSystem/Link"
import SidePeekContainer from "@/components/TempDesignSystem/SidePeek/Container"
import SidePeekContent from "@/components/TempDesignSystem/SidePeek/Content"
import { generateSidePeekLink } from "@/components/TempDesignSystem/SidePeek/data"
import Body from "@/components/TempDesignSystem/Text/Body"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
@@ -22,6 +20,7 @@ export default async function AmenitiesList({
const sortedAmenities = detailedFacilities
.sort((a, b) => b.sortOrder - a.sortOrder)
.slice(0, 5)
return (
<section className={styles.amenitiesContainer}>
<Subtitle type="two" color="black">
@@ -42,14 +41,6 @@ export default async function AmenitiesList({
{formatMessage({ id: "Show all amenities" })}
<ChevronRightIcon />
</Link>
<SidePeekContainer>
<SidePeekContent
contentKey={"amenities"}
title={formatMessage({ id: "Amenities" })}
>
{/* TODO: Render amenities as per the design. */}
</SidePeekContent>
</SidePeekContainer>
</section>
)
}

View File

@@ -1,6 +1,9 @@
import { serverClient } from "@/lib/trpc/server"
import { getLang } from "@/i18n/serverContext"
import SidePeekContainer from "@/components/TempDesignSystem/SidePeek/Container"
import SidePeekContent from "@/components/TempDesignSystem/SidePeek/Content"
import { getIntl } from "@/i18n"
import AmenitiesList from "./AmenitiesList"
import IntroSection from "./IntroSection"
@@ -23,6 +26,8 @@ export default async function HotelPage() {
include: ["RoomCategories"],
})
const { formatMessage } = await getIntl()
return (
<div className={styles.pageContainer}>
<TabNavigation />
@@ -35,6 +40,21 @@ export default async function HotelPage() {
address={attributes.address}
tripAdvisor={attributes.ratings.tripAdvisor}
/>
<SidePeekContainer>
<SidePeekContent
contentKey={"amenities"}
title={formatMessage({ id: "Amenities" })}
>
{/* TODO: Render amenities as per the design. */}
Read more about the amenities here
</SidePeekContent>
<SidePeekContent
contentKey={"about"}
title={formatMessage({ id: "About the hotel" })}
>
Some additional information about the hotel
</SidePeekContent>
</SidePeekContainer>
<AmenitiesList detailedFacilities={attributes.detailedFacilities} />
</div>
<Rooms rooms={roomCategories} />

View File

@@ -1,6 +1,7 @@
import ArrowRight from "@/components/Icons/ArrowRight"
import TripAdvisorIcon from "@/components/Icons/TripAdvisor"
import Link from "@/components/TempDesignSystem/Link"
import { generateSidePeekLink } from "@/components/TempDesignSystem/SidePeek/data"
import BiroScript from "@/components/TempDesignSystem/Text/BiroScript"
import Body from "@/components/TempDesignSystem/Text/Body"
import Preamble from "@/components/TempDesignSystem/Text/Preamble"
@@ -31,6 +32,7 @@ export default async function IntroSection({
{ id: "Tripadvisor reviews" },
{ rating: tripAdvisor.rating, count: tripAdvisor.numberOfReviews }
)
const aboutTheHotelLink = generateSidePeekLink("about")
return (
<section className={styles.introSection}>
@@ -58,13 +60,11 @@ export default async function IntroSection({
<Preamble>{hotelDescription}</Preamble>
<Link
className={styles.introLink}
target="_blank"
color="peach80"
textDecoration="underline"
variant="icon"
href="#"
href={aboutTheHotelLink}
>
{/*TODO: Ask content team where this should link to. */}
{formatMessage({ id: "Read more about the hotel" })}
<ArrowRight color="peach80" />
</Link>

View File

@@ -13,7 +13,6 @@ import styles from "./content.module.css"
export default function Content({
title,
children,
contentKey,
isActive = false,
onClose,
}: PropsWithChildren<SidePeekContentProps>) {

View File

@@ -1,7 +1,13 @@
"use client"
import { useIsSSR } from "@react-aria/ssr"
import { Children, cloneElement, PropsWithChildren } from "react"
import { Dialog, DialogTrigger, Modal } from "react-aria-components"
import {
Dialog,
DialogTrigger,
Modal,
ModalOverlay,
} from "react-aria-components"
import { SidePeekProps } from "./types"
@@ -12,25 +18,31 @@ export default function SidePeek({
onClose,
activeContent,
}: PropsWithChildren<SidePeekProps>) {
return (
const isSSR = useIsSSR()
return isSSR ? (
<div>{children}</div>
) : (
<DialogTrigger>
<Modal
className={styles.sidePeek}
<ModalOverlay
className={styles.overlay}
isOpen={!!activeContent}
onOpenChange={onClose}
isDismissable
>
<Dialog className={styles.dialog}>
{({ close }) => (
<>
{Children.map(children, (child) => {
return cloneElement(child as React.ReactElement, {
onClose: close,
})
})}
</>
)}
</Dialog>
</Modal>
<Modal className={styles.sidePeek}>
<Dialog className={styles.dialog}>
{({ close }) => (
<>
{Children.map(children, (child) => {
return cloneElement(child as React.ReactElement, {
onClose: close,
})
})}
</>
)}
</Dialog>
</Modal>
</ModalOverlay>
</DialogTrigger>
)
}

View File

@@ -22,6 +22,14 @@
height: 100%;
}
.overlay {
position: absolute;
top: 70.047px;
bottom: 0;
left: 0;
right: 0;
z-index: 99;
}
@keyframes slide-in {
from {
right: -600px;
@@ -56,4 +64,7 @@
.sidePeek[data-exiting] {
animation: slide-in 250ms reverse;
}
.overlay {
top: 0;
}
}

View File

@@ -1,4 +1,4 @@
export type SidePeekContentKey = "amenities" | "read_more_about_the_hotel"
export type SidePeekContentKey = string
export type SidePeekProps = {
activeContent: string | null

1722
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -31,6 +31,7 @@
"@hookform/resolvers": "^3.3.4",
"@netlify/plugin-nextjs": "^5.1.1",
"@radix-ui/react-slot": "^1.0.2",
"@react-aria/ssr": "^3.9.5",
"@scandic-hotels/design-system": "git+https://x-token-auth:$DESIGN_SYSTEM_ACCESS_TOKEN@bitbucket.org/scandic-swap/design-system.git#v0.1.0-rc.8",
"@t3-oss/env-nextjs": "^0.9.2",
"@tanstack/react-query": "^5.28.6",