feat: Add tab navigation to hotel page
This commit is contained in:
@@ -3,6 +3,7 @@ import { serverClient } from "@/lib/trpc/server"
|
||||
import AmenitiesList from "./AmenitiesList"
|
||||
import IntroSection from "./IntroSection"
|
||||
import { Rooms } from "./Rooms"
|
||||
import TabNavigation from "./TabNavigation"
|
||||
|
||||
import styles from "./hotelPage.module.css"
|
||||
|
||||
@@ -23,18 +24,21 @@ export default async function HotelPage({ lang }: LangParams) {
|
||||
})
|
||||
|
||||
return (
|
||||
<main className={styles.pageContainer}>
|
||||
<div className={styles.introContainer}>
|
||||
<IntroSection
|
||||
hotelName={attributes.name}
|
||||
hotelDescription={attributes.hotelContent.texts.descriptions.short}
|
||||
location={attributes.location}
|
||||
address={attributes.address}
|
||||
tripAdvisor={attributes.ratings.tripAdvisor}
|
||||
/>
|
||||
<AmenitiesList detailedFacilities={attributes.detailedFacilities} />
|
||||
</div>
|
||||
<Rooms rooms={roomCategories} />
|
||||
</main>
|
||||
<div className={styles.pageContainer}>
|
||||
<TabNavigation />
|
||||
<main className={styles.mainSection}>
|
||||
<div className={styles.introContainer}>
|
||||
<IntroSection
|
||||
hotelName={attributes.name}
|
||||
hotelDescription={attributes.hotelContent.texts.descriptions.short}
|
||||
location={attributes.location}
|
||||
address={attributes.address}
|
||||
tripAdvisor={attributes.ratings.tripAdvisor}
|
||||
/>
|
||||
<AmenitiesList detailedFacilities={attributes.detailedFacilities} />
|
||||
</div>
|
||||
<Rooms rooms={roomCategories} />
|
||||
</main>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -30,10 +30,10 @@ export async function Rooms({ rooms }: RoomsProps) {
|
||||
.sort((a, b) => a.sortOrder - b.sortOrder)
|
||||
.slice(0, 3) //TODO: Remove this and render all rooms once we've implemented "show more" logic in SW-203.
|
||||
return (
|
||||
<SectionContainer>
|
||||
<SectionContainer id="rooms-section">
|
||||
<SectionHeader
|
||||
textTransform="uppercase"
|
||||
title={formatMessage({ id: "hotelPages.rooms.title" })}
|
||||
title={formatMessage({ id: "Rooms" })}
|
||||
subtitle={null}
|
||||
/>
|
||||
<Grids.Stackable>
|
||||
|
||||
44
components/ContentType/HotelPage/TabNavigation/index.tsx
Normal file
44
components/ContentType/HotelPage/TabNavigation/index.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
"use client"
|
||||
import { useIntl } from "react-intl"
|
||||
|
||||
import Link from "@/components/TempDesignSystem/Link"
|
||||
import useHash from "@/hooks/useHash"
|
||||
|
||||
import { HotelHashValues } from "./types"
|
||||
|
||||
import styles from "./tabNavigation.module.css"
|
||||
|
||||
export default function TabNavigation() {
|
||||
const hash = useHash()
|
||||
const { formatMessage } = useIntl()
|
||||
const hotelTabLinks: { href: HotelHashValues; text: string }[] = [
|
||||
{ href: "#overview", text: "Overview" },
|
||||
{ href: "#rooms-section", text: "Rooms" },
|
||||
{ href: "#restaurant-and-bar", text: "Restaurant & Bar" },
|
||||
{ href: "#meetings-and-conferences", text: "Meetings & Conferences" },
|
||||
{ href: "#wellness-and-exercise", text: "Wellness & Exercise" },
|
||||
{ href: "#activities", text: "Activities" },
|
||||
{ href: "#faq", text: "FAQ" },
|
||||
]
|
||||
return (
|
||||
<nav className={styles.tabsContainer}>
|
||||
{hotelTabLinks.map((link) => {
|
||||
const isActive =
|
||||
hash === link.href || (hash === "" && link.href === "#overview")
|
||||
console.log("isActive", isActive, "hash", hash, "link.href", link.href)
|
||||
return (
|
||||
<Link
|
||||
key={link.href}
|
||||
href={link.href}
|
||||
active={isActive}
|
||||
variant="tab"
|
||||
color="burgundy"
|
||||
textDecoration="none"
|
||||
>
|
||||
{formatMessage({ id: link.text })}
|
||||
</Link>
|
||||
)
|
||||
})}
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
.tabsContainer {
|
||||
display: flex;
|
||||
overflow-x: auto;
|
||||
white-space: nowrap;
|
||||
gap: var(--Spacing-x4);
|
||||
background: var(--Base-Surface-Subtle-Normal);
|
||||
justify-content: flex-start;
|
||||
padding-left: var(--Spacing-x4);
|
||||
padding-right: var(--Spacing-x3);
|
||||
border-bottom: 1px solid var(--Base-Border-Subtle);
|
||||
}
|
||||
8
components/ContentType/HotelPage/TabNavigation/types.ts
Normal file
8
components/ContentType/HotelPage/TabNavigation/types.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export type HotelHashValues =
|
||||
| "#overview"
|
||||
| "#rooms-section"
|
||||
| "#restaurant-and-bar"
|
||||
| "#meetings-and-conferences"
|
||||
| "#wellness-and-exercise"
|
||||
| "#activities"
|
||||
| "#faq"
|
||||
@@ -1,4 +1,13 @@
|
||||
.pageContainer {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.pageContainer > * {
|
||||
padding-left: var(--Spacing-x4);
|
||||
padding-right: var(--Spacing-x3);
|
||||
}
|
||||
|
||||
.mainSection {
|
||||
display: grid;
|
||||
gap: var(--Spacing-x9);
|
||||
padding: var(--Spacing-x5) var(--Spacing-x3) var(--Spacing-x4);
|
||||
@@ -11,9 +20,14 @@
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1367px) {
|
||||
.pageContainer {
|
||||
.pageContainer > *:not(nav) {
|
||||
padding: var(--Spacing-x9) var(--Spacing-x5);
|
||||
}
|
||||
|
||||
.pageContainer > nav {
|
||||
padding-left: var(--Spacing-x5);
|
||||
padding-right: var(--Spacing-x5);
|
||||
}
|
||||
.introContainer {
|
||||
display: grid;
|
||||
/* use justify-content: space between once we have the map component*/
|
||||
|
||||
@@ -8,7 +8,7 @@ import styles from "./breadcrumbs.module.css"
|
||||
|
||||
export default async function Breadcrumbs() {
|
||||
const breadcrumbs = await serverClient().contentstack.breadcrumbs.get()
|
||||
if (!breadcrumbs) {
|
||||
if (!breadcrumbs || breadcrumbs.length === 0) {
|
||||
return null
|
||||
}
|
||||
const homeBreadcrumb = breadcrumbs.shift()
|
||||
|
||||
@@ -10,6 +10,7 @@ import { linkVariants } from "./variants"
|
||||
import type { LinkProps } from "./link"
|
||||
|
||||
export default function Link({
|
||||
active,
|
||||
className,
|
||||
color,
|
||||
href,
|
||||
@@ -23,10 +24,12 @@ export default function Link({
|
||||
...props
|
||||
}: LinkProps) {
|
||||
const currentPageSlug = usePathname()
|
||||
let isActive = currentPageSlug === href
|
||||
let isActive = active || currentPageSlug === href
|
||||
|
||||
if (partialMatch && !isActive) {
|
||||
isActive = currentPageSlug === href
|
||||
}
|
||||
|
||||
const classNames = linkVariants({
|
||||
active: isActive,
|
||||
className,
|
||||
|
||||
@@ -93,6 +93,17 @@
|
||||
background-color: var(--Scandic-Peach-20);
|
||||
}
|
||||
|
||||
.tab {
|
||||
font-family: var(--typography-Body-Regular-fontFamily);
|
||||
padding: var(--Spacing-x2) var(--Spacing-x0);
|
||||
color: var(--Base-Text-High-contrast);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
border-bottom: 2px solid var(--Scandic-Brand-Burgundy);
|
||||
}
|
||||
|
||||
.black {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ export const linkVariants = cva(styles.link, {
|
||||
myPageMobileDropdown: styles.myPageMobileDropdown,
|
||||
shortcut: styles.shortcut,
|
||||
sidebar: styles.sidebar,
|
||||
tab: styles.tab,
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
|
||||
Reference in New Issue
Block a user