fix(SW-2758): Using ?s queryparameter again to handle sidepeeks on hotel pages

Approved-by: Matilda Landström
This commit is contained in:
Erik Tiekstra
2025-05-26 09:09:52 +00:00
parent 532f45a79c
commit c963891ca7
10 changed files with 74 additions and 84 deletions

View File

@@ -7,6 +7,7 @@
gap: var(--Spacing-x-one-and-half);
height: fit-content;
width: min(100%, 300px);
justify-items: start;
}
.amenityItemList {

View File

@@ -1,8 +1,8 @@
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import { Typography } from "@scandic-hotels/design-system/Typography"
import ButtonLink from "@/components/ButtonLink"
import { FacilityToIcon } from "@/components/ContentType/HotelPage/data"
import Link from "@/components/TempDesignSystem/Link"
import { getIntl } from "@/i18n"
import styles from "./amenitiesList.module.css"
@@ -48,19 +48,17 @@ export default async function AmenitiesList({
)
})}
</div>
<Link
<ButtonLink
href={`?s=${SidepeekSlugs.amenities}`}
variant="Text"
typography="Body/Paragraph/mdBold"
scroll={false}
href={`#s-${SidepeekSlugs.amenities}`}
color="burgundy"
variant="icon"
weight="bold"
className={styles.showAllAmenities}
>
{intl.formatMessage({
defaultMessage: "See all amenities",
})}
<MaterialIcon icon="chevron_right" size={20} color="CurrentColor" />
</Link>
<MaterialIcon icon="chevron_right" size={24} color="CurrentColor" />
</ButtonLink>
</section>
)
}

View File

@@ -15,7 +15,7 @@ export default function ActivitiesCardGrid(activitiesCard: ActivityCard) {
theme: hasImage ? "image" : "primaryDark",
primaryButton: hasImage
? {
href: `#s-${activitiesCard.sidepeekSlug}`,
href: `?s=${activitiesCard.sidepeekSlug}`,
title: activitiesCard.ctaText,
isExternal: false,
scrollOnClick: false,
@@ -24,7 +24,7 @@ export default function ActivitiesCardGrid(activitiesCard: ActivityCard) {
secondaryButton: hasImage
? undefined
: {
href: `#s-${activitiesCard.sidepeekSlug}`,
href: `?s=${activitiesCard.sidepeekSlug}`,
title: activitiesCard.ctaText,
isExternal: false,
scrollOnClick: false,

View File

@@ -1,7 +1,7 @@
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import { Typography } from "@scandic-hotels/design-system/Typography"
import Link from "@/components/TempDesignSystem/Link"
import ButtonLink from "@/components/ButtonLink"
import { getIntl } from "@/i18n"
import { getSingleDecimal } from "@/utils/numberFormatting"
@@ -56,24 +56,17 @@ export default async function IntroSection({
<Typography variant="Body/Lead text">
<p>{hotelDescription}</p>
</Typography>
<Link
className={styles.introLink}
color="burgundy"
variant="icon"
weight="bold"
href={`#s-${SidepeekSlugs.about}`}
<ButtonLink
href={`?s=${SidepeekSlugs.about}`}
variant="Text"
typography="Body/Paragraph/mdBold"
scroll={false}
>
{intl.formatMessage({
defaultMessage: "Read more",
})}
<MaterialIcon
icon="chevron_right"
size={20}
color="CurrentColor"
className={styles.introLink}
/>
</Link>
<MaterialIcon icon="chevron_right" size={24} color="CurrentColor" />
</ButtonLink>
</div>
</section>
)

View File

@@ -1,19 +1,20 @@
.introSection {
display: grid;
gap: var(--Spacing-x2);
gap: var(--Space-x2);
position: relative;
max-width: var(--hotel-page-intro-section-width);
}
.mainContent {
display: grid;
gap: var(--Spacing-x1);
gap: var(--Space-x1);
justify-items: start;
}
.subtitleContent {
display: grid;
gap: var(--Spacing-x-one-and-half);
gap: var(--Space-x05);
justify-items: start;
}
.title {
@@ -31,10 +32,5 @@
.titleContainer {
display: grid;
gap: var(--Spacing-x2);
}
.introLink {
text-decoration-color: var(--Scandic-Peach-80);
width: fit-content;
gap: var(--Space-x2);
}

View File

@@ -1,14 +1,12 @@
"use client"
import Link from "next/link"
import { useIntl } from "react-intl"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import { Typography } from "@scandic-hotels/design-system/Typography"
import ButtonLink from "@/components/ButtonLink"
import ImageGallery from "@/components/ImageGallery"
import Button from "@/components/TempDesignSystem/Button"
import Body from "@/components/TempDesignSystem/Text/Body"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import { mapApiImagesToGalleryImages } from "@/utils/imageGallery"
import { getRoomNameAsParam } from "../../utils"
@@ -46,36 +44,36 @@ export function RoomCard({ room }: RoomCardProps) {
</div>
<div className={styles.content}>
<div className={styles.innerContent}>
<Subtitle
textTransform="capitalize"
textAlign="center"
type="one"
color="black"
>
{name}
</Subtitle>
<Body color="grey">
{intl.formatMessage(
{
defaultMessage:
"{size} ({max, plural, one {{range} guest} other {{range} guests}})",
},
{
size,
max: totalOccupancy.max,
range: totalOccupancy.range,
}
)}
</Body>
<Typography variant="Title/Subtitle/lg">
<h3>{name}</h3>
</Typography>
<Typography variant="Body/Paragraph/mdRegular">
<p className={styles.roomSize}>
{intl.formatMessage(
{
defaultMessage:
"{size} ({max, plural, one {{range} guest} other {{range} guests}})",
},
{
size,
max: totalOccupancy.max,
range: totalOccupancy.range,
}
)}
</p>
</Typography>
</div>
<Button intent="text" type="button" size="medium" theme="base" asChild>
<Link scroll={false} href={`#s-room-${getRoomNameAsParam(name)}`}>
{intl.formatMessage({
defaultMessage: "See room details",
})}
<MaterialIcon icon="chevron_right" size={20} color="CurrentColor" />
</Link>
</Button>
<ButtonLink
href={`?s=room-${getRoomNameAsParam(name)}`}
variant="Text"
typography="Body/Paragraph/mdBold"
scroll={false}
>
{intl.formatMessage({
defaultMessage: "See room details",
})}
<MaterialIcon icon="chevron_right" size={24} color="CurrentColor" />
</ButtonLink>
</div>
</article>
)

View File

@@ -1,25 +1,30 @@
.roomCard {
border-radius: var(--Corner-radius-md);
background-color: var(--UI-Opacity-White-100);
border: 1px solid var(--Base-Border-Subtle);
background-color: var(--Surface-Primary-Default);
border: 1px solid var(--Border-Default);
display: grid;
overflow: hidden;
color: var(--Text-Default);
}
.content {
display: grid;
justify-items: center;
gap: var(--Spacing-x-one-and-half);
padding: var(--Spacing-x2);
gap: var(--Space-x05);
padding: var(--Space-x2);
}
.innerContent {
display: grid;
justify-items: center;
gap: var(--Spacing-x1);
gap: var(--Space-x1);
}
.imageContainer {
position: relative;
height: 200px;
}
.roomSize {
color: var(--Text-Tertiary);
}

View File

@@ -1,9 +1,7 @@
"use client"
import { useRouter } from "next/navigation"
import { usePathname, useRouter, useSearchParams } from "next/navigation"
import { createContext, useEffect, useState } from "react"
import useHash from "@/hooks/useHash"
interface SidepeekProviderProps extends React.PropsWithChildren {
onOpen?: (sidePeek: string) => void
}
@@ -20,16 +18,15 @@ export default function SidePeekProvider({
onOpen,
}: SidepeekProviderProps) {
const router = useRouter()
const hash = useHash()
const pathname = usePathname()
const searchParams = useSearchParams()
const [activeSidePeek, setActiveSidePeek] = useState<string | null>(null)
useEffect(() => {
if (hash?.startsWith("s-")) {
setActiveSidePeek(hash.slice(2))
} else {
setActiveSidePeek(null)
const sidePeekParam = searchParams.get("s")
if (sidePeekParam !== activeSidePeek) {
setActiveSidePeek(sidePeekParam)
}
}, [hash, setActiveSidePeek])
}, [searchParams, activeSidePeek])
useEffect(() => {
if (activeSidePeek && onOpen) {
@@ -39,7 +36,9 @@ export default function SidePeekProvider({
function handleClose(isOpen: boolean) {
if (!isOpen) {
router.push(window.location.pathname, { scroll: false })
const nextSearchParams = new URLSearchParams(searchParams.toString())
nextSearchParams.delete("s")
router.push(`${pathname}?${nextSearchParams}`, { scroll: false })
setActiveSidePeek(null)
}
}

View File

@@ -83,7 +83,7 @@ function setCardProps(
heading,
scriptedTopTitle,
secondaryButton: {
href: `#s-${slug}`,
href: `?s=${slug}`,
title: buttonText,
isExternal: false,
scrollOnClick: false,