From be98c2faf6c369c6a02d75adc5317c49fdd28fd5 Mon Sep 17 00:00:00 2001 From: Erik Tiekstra Date: Tue, 3 Jun 2025 09:22:28 +0000 Subject: [PATCH] feat(SW-1409): Synced tabnavigation headings and section headings on hotel pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(SW-2409): Added same headings to relevant sidepeeks Approved-by: Christian Andolf Approved-by: Matilda Landström --- .../components/Blocks/Accordion/index.tsx | 2 +- .../HotelPage/Facilities/index.tsx | 2 +- .../ContentType/HotelPage/Rooms/index.tsx | 14 +- .../MeetingsAndConferences/index.tsx | 8 +- .../SidePeeks/RestaurantBar/index.tsx | 13 +- .../SidePeeks/WellnessAndExercise/index.tsx | 8 +- .../HotelPage/TabNavigation/index.tsx | 129 +++--------------- .../ContentType/HotelPage/index.tsx | 78 ++++++----- .../components/ContentType/HotelPage/utils.ts | 96 +++++++++++++ .../routers/contentstack/hotelPage/output.ts | 2 +- .../types/components/hotelPage/hotelPage.ts | 5 + .../types/components/hotelPage/room.ts | 1 + .../types/components/hotelPage/sections.ts | 27 ++++ .../sidepeek/meetingsAndConferences.ts | 1 + .../hotelPage/sidepeek/restaurantBar.ts | 1 + .../hotelPage/sidepeek/wellnessAndExercise.ts | 1 + .../components/hotelPage/tabNavigation.ts | 29 ---- apps/scandic-web/types/enums/hotelPage.ts | 10 ++ apps/scandic-web/utils/facilityCards.ts | 43 ++++-- 19 files changed, 251 insertions(+), 219 deletions(-) create mode 100644 apps/scandic-web/types/components/hotelPage/sections.ts delete mode 100644 apps/scandic-web/types/components/hotelPage/tabNavigation.ts diff --git a/apps/scandic-web/components/Blocks/Accordion/index.tsx b/apps/scandic-web/components/Blocks/Accordion/index.tsx index e617293f9..fd0166058 100644 --- a/apps/scandic-web/components/Blocks/Accordion/index.tsx +++ b/apps/scandic-web/components/Blocks/Accordion/index.tsx @@ -12,7 +12,7 @@ import ShowMoreButton from "@/components/TempDesignSystem/ShowMoreButton" import styles from "./accordion.module.css" import type { AccordionProps } from "@/types/components/blocks/Accordion" -import { HotelHashValues } from "@/types/components/hotelPage/tabNavigation" +import { HotelHashValues } from "@/types/enums/hotelPage" export default function AccordionSection({ accordion, title }: AccordionProps) { const showToggleButton = accordion.length > 5 diff --git a/apps/scandic-web/components/ContentType/HotelPage/Facilities/index.tsx b/apps/scandic-web/components/ContentType/HotelPage/Facilities/index.tsx index a897cbd20..51facb18e 100644 --- a/apps/scandic-web/components/ContentType/HotelPage/Facilities/index.tsx +++ b/apps/scandic-web/components/ContentType/HotelPage/Facilities/index.tsx @@ -13,7 +13,7 @@ import { type FacilityCardType, type FacilityGrid, } from "@/types/components/hotelPage/facilities" -import { HotelHashValues } from "@/types/components/hotelPage/tabNavigation" +import { HotelHashValues } from "@/types/enums/hotelPage" export default async function Facilities({ facilities, diff --git a/apps/scandic-web/components/ContentType/HotelPage/Rooms/index.tsx b/apps/scandic-web/components/ContentType/HotelPage/Rooms/index.tsx index 5fe01eee8..0b15642bf 100644 --- a/apps/scandic-web/components/ContentType/HotelPage/Rooms/index.tsx +++ b/apps/scandic-web/components/ContentType/HotelPage/Rooms/index.tsx @@ -2,7 +2,6 @@ import { cx } from "class-variance-authority" import { useMemo, useRef, useState } from "react" -import { useIntl } from "react-intl" import { Typography } from "@scandic-hotels/design-system/Typography" @@ -14,10 +13,9 @@ import { RoomCard } from "./RoomCard" import styles from "./rooms.module.css" import type { RoomsProps } from "@/types/components/hotelPage/room" -import { HotelHashValues } from "@/types/components/hotelPage/tabNavigation" +import { HotelHashValues } from "@/types/enums/hotelPage" -export function Rooms({ rooms, preamble }: RoomsProps) { - const intl = useIntl() +export function Rooms({ heading, rooms, preamble }: RoomsProps) { const showToggleButton = rooms.length > 3 const [allRoomsVisible, setAllRoomsVisible] = useState(!showToggleButton) const sortedRooms = useMemo(() => { @@ -40,12 +38,8 @@ export function Rooms({ rooms, preamble }: RoomsProps) { >
- -

- {intl.formatMessage({ - defaultMessage: "Rooms", - })} -

+ +

{heading}

{preamble && ( diff --git a/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/MeetingsAndConferences/index.tsx b/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/MeetingsAndConferences/index.tsx index 14365f3f5..8d23c5657 100644 --- a/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/MeetingsAndConferences/index.tsx +++ b/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/MeetingsAndConferences/index.tsx @@ -19,6 +19,7 @@ export default async function MeetingsAndConferencesSidePeek({ descriptions, meetingRooms, meetingPageUrl, + heading, }: MeetingsAndConferencesSidePeekProps) { const intl = await getIntl() const { seatingText, roomText } = await getConferenceRoomTexts(meetingRooms) @@ -26,12 +27,7 @@ export default async function MeetingsAndConferencesSidePeek({ const meetingPageHref = await appendSlugToPathname(meetingPageUrl) return ( - +
diff --git a/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/RestaurantBar/index.tsx b/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/RestaurantBar/index.tsx index 3d9646a59..a2ae9b6bd 100644 --- a/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/RestaurantBar/index.tsx +++ b/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/RestaurantBar/index.tsx @@ -1,5 +1,4 @@ import SidePeek from "@/components/TempDesignSystem/SidePeek" -import { getIntl } from "@/i18n" import RestaurantBarItem from "./RestaurantBarItem" @@ -8,18 +7,12 @@ import styles from "./restaurantBar.module.css" import { SidepeekSlugs } from "@/types/components/hotelPage/hotelPage" import type { RestaurantBarSidePeekProps } from "@/types/components/hotelPage/sidepeek/restaurantBar" -export default async function RestaurantBarSidePeek({ +export default function RestaurantBarSidePeek({ restaurants, + heading, }: RestaurantBarSidePeekProps) { - const intl = await getIntl() - return ( - <SidePeek - contentKey={SidepeekSlugs.restaurant} - title={intl.formatMessage({ - defaultMessage: "Restaurant & Bar", - })} - > + <SidePeek contentKey={SidepeekSlugs.restaurant} title={heading}> <div className={styles.content}> {restaurants.map((restaurant) => ( <div key={restaurant.id} className={styles.item}> diff --git a/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/WellnessAndExercise/index.tsx b/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/WellnessAndExercise/index.tsx index 28f97cc94..d75fe2c5c 100644 --- a/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/WellnessAndExercise/index.tsx +++ b/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/WellnessAndExercise/index.tsx @@ -14,6 +14,7 @@ export default async function WellnessAndExerciseSidePeek({ healthFacilities, wellnessExercisePageUrl, spaPage, + heading, }: WellnessAndExerciseSidePeekProps) { const intl = await getIntl() const wellnessExercisePageHref = await appendSlugToPathname( @@ -21,12 +22,7 @@ export default async function WellnessAndExerciseSidePeek({ ) return ( - <SidePeek - contentKey={SidepeekSlugs.wellness} - title={intl.formatMessage({ - defaultMessage: "Gym & Wellness", - })} - > + <SidePeek contentKey={SidepeekSlugs.wellness} title={heading}> <div className={styles.wrapper}> {healthFacilities.map((facility) => ( <Facility key={facility.type} data={facility} /> diff --git a/apps/scandic-web/components/ContentType/HotelPage/TabNavigation/index.tsx b/apps/scandic-web/components/ContentType/HotelPage/TabNavigation/index.tsx index 146d33813..47c3172a0 100644 --- a/apps/scandic-web/components/ContentType/HotelPage/TabNavigation/index.tsx +++ b/apps/scandic-web/components/ContentType/HotelPage/TabNavigation/index.tsx @@ -4,7 +4,6 @@ import { cx } from "class-variance-authority" import NextLink from "next/link" import { useRouter } from "next/navigation" import { useCallback, useEffect, useLayoutEffect, useMemo, useRef } from "react" -import { useIntl } from "react-intl" import { Typography } from "@scandic-hotels/design-system/Typography" @@ -18,24 +17,19 @@ import { trackHotelTabClick } from "@/utils/tracking" import styles from "./tabNavigation.module.css" -import { - HotelHashValues, - type TabNavigationProps, -} from "@/types/components/hotelPage/tabNavigation" +import type { HotelPageSections } from "@/types/components/hotelPage/sections" +import { HotelHashValues } from "@/types/enums/hotelPage" -export default function TabNavigation({ - hasActivities, - hasFAQ, - hasMeetingRooms, - hasRestaurants, - hasWellness, - tabValues, -}: TabNavigationProps) { - const hash = useHash() - const intl = useIntl() +interface TabNavigationProps { + pageSections: HotelPageSections +} + +export default function TabNavigation({ pageSections }: TabNavigationProps) { + const activeHash = useHash() const router = useRouter() const tabNavigationRef = useRef<HTMLDivElement>(null) const tabRefs = useMemo(() => new Map<string, HTMLAnchorElement>(), []) + const tabLinks = Object.values(pageSections).map(({ hash }) => hash) useStickyPosition({ ref: tabNavigationRef, @@ -46,88 +40,7 @@ export default function TabNavigation({ const { containerRef, showLeftShadow, showRightShadow } = useScrollShadows<HTMLDivElement>() - const tabLinks: { hash: HotelHashValues; text: string }[] = [ - { - hash: HotelHashValues.overview, - text: - tabValues?.overview || - intl.formatMessage({ - defaultMessage: "Overview", - }), - }, - { - hash: HotelHashValues.rooms, - text: - tabValues?.rooms || - intl.formatMessage({ - defaultMessage: "Rooms", - }), - }, - ...(hasRestaurants - ? [ - { - hash: HotelHashValues.restaurant, - text: - tabValues?.restaurant_bar || - intl.formatMessage({ - defaultMessage: "Restaurant & Bar", - }), - }, - ] - : []), - ...(hasMeetingRooms - ? [ - { - hash: HotelHashValues.meetings, - text: - tabValues?.conferences_meetings || - intl.formatMessage({ - defaultMessage: "Meetings & Conferences", - }), - }, - ] - : []), - ...(hasWellness - ? [ - { - hash: HotelHashValues.wellness, - text: - tabValues?.health_wellness || - intl.formatMessage({ - defaultMessage: "Gym & Wellness", - }), - }, - ] - : []), - ...(hasActivities - ? [ - { - hash: HotelHashValues.activities, - text: - tabValues?.activities || - intl.formatMessage({ - defaultMessage: "Activities", - }), - }, - ] - : []), - ...(hasFAQ - ? [ - { - hash: HotelHashValues.faq, - text: - tabValues?.faq || - intl.formatMessage({ - defaultMessage: "FAQ", - }), - }, - ] - : []), - ] - - const { activeSectionId, pauseScrollSpy } = useScrollSpy( - tabLinks.map(({ hash }) => hash) - ) + const { activeSectionId, pauseScrollSpy } = useScrollSpy(tabLinks) const scrollLinkToCenter = useCallback( (hash: string) => { @@ -160,9 +73,9 @@ export default function TabNavigation({ ) useLayoutEffect(() => { - const activeHash = hash || HotelHashValues.overview - scrollLinkToCenter(activeHash) - }, [hash, scrollLinkToCenter]) + const hash = activeHash || HotelHashValues.overview + scrollLinkToCenter(hash) + }, [activeHash, scrollLinkToCenter]) useEffect(() => { if (activeSectionId) { @@ -179,19 +92,19 @@ export default function TabNavigation({ })} > <nav className={styles.tabsContainer} ref={containerRef}> - {tabLinks.map((link) => { + {Object.values(pageSections).map(({ hash, heading }) => { const isActive = - hash === link.hash || - (!hash && link.hash === HotelHashValues.overview) + activeHash === hash || + (!activeHash && hash === HotelHashValues.overview) return ( <Typography - key={link.hash} + key={hash} variant={ isActive ? "Body/Paragraph/mdBold" : "Body/Paragraph/mdRegular" } > <NextLink - href={`#${link.hash}`} + href={`#${hash}`} className={cx(styles.link, { [styles.active]: isActive, })} @@ -199,15 +112,15 @@ export default function TabNavigation({ scroll={true} ref={(element) => { if (element) { - tabRefs.set(link.hash, element) + tabRefs.set(hash, element) } }} onClick={() => { pauseScrollSpy() - trackHotelTabClick(link.text) + trackHotelTabClick(heading) }} > - {link.text} + {heading} </NextLink> </Typography> ) diff --git a/apps/scandic-web/components/ContentType/HotelPage/index.tsx b/apps/scandic-web/components/ContentType/HotelPage/index.tsx index be585d0a6..a57c01ffb 100644 --- a/apps/scandic-web/components/ContentType/HotelPage/index.tsx +++ b/apps/scandic-web/components/ContentType/HotelPage/index.tsx @@ -12,6 +12,7 @@ import Breadcrumbs from "@/components/Breadcrumbs" import Alert from "@/components/TempDesignSystem/Alert" import BreadcrumbsSkeleton from "@/components/TempDesignSystem/Breadcrumbs/BreadcrumbsSkeleton" import TrackingSDK from "@/components/TrackingSDK" +import { getIntl } from "@/i18n" import { getLang } from "@/i18n/serverContext" import { setFacilityCards } from "@/utils/facilityCards" import { generateHotelSchema } from "@/utils/jsonSchemas" @@ -35,15 +36,20 @@ import PreviewImages from "./PreviewImages" import { Rooms } from "./Rooms" import SidePeeks from "./SidePeeks" import TabNavigation from "./TabNavigation" -import { getTrackingHotelData, getTrackingPageData } from "./utils" +import { + getPageSectionsData, + getTrackingHotelData, + getTrackingPageData, +} from "./utils" import styles from "./hotelPage.module.css" import type { HotelPageProps } from "@/types/components/hotelPage/hotelPage" -import { HotelHashValues } from "@/types/components/hotelPage/tabNavigation" +import { HotelHashValues } from "@/types/enums/hotelPage" export default async function HotelPage({ hotelId }: HotelPageProps) { const lang = await getLang() + const intl = await getIntl() void getHotelPage() void getHotel({ @@ -68,7 +74,12 @@ export default async function HotelPage({ hotelId }: HotelPageProps) { } const jsonSchema = generateHotelSchema(hotelData) - const { faq, content, tabValues } = hotelPageData + const { + faq, + content: { spaPage, activitiesCards }, + sectionHeadings, + } = hotelPageData + const { hotel, restaurants, roomCategories, additionalData } = hotelData const { name, address, @@ -84,9 +95,7 @@ export default async function HotelPage({ hotelId }: HotelPageProps) { ratings, parking, hotelType, - } = hotelData.hotel - const restaurants = hotelData.restaurants - const roomCategories = hotelData.roomCategories + } = hotel const { healthAndWellness, healthAndFitness, @@ -98,28 +107,29 @@ export default async function HotelPage({ hotelId }: HotelPageProps) { meetingRooms, displayWebPage, hotelSpecialNeeds, - } = hotelData.additionalData + } = additionalData const images = gallery?.smallerImages const description = hotelContent.texts.descriptions?.medium - - const { spaPage, activitiesCards } = content - - const hasRestaurants = restaurants.length > 0 - const hasMeetingRooms = !!meetingRoomsData?.length - const hasWellness = healthFacilities.length > 0 + const pageSections = getPageSectionsData( + intl, + { + hasWellness: healthFacilities.length > 0, + hasRestaurants: restaurants.length > 0, + hasMeetingRooms: !!(meetingRoomsData && meetingRoomsData.length > 0), + hasActivities: activitiesCards.length > 0, + hasFAQ: !!(faq && faq.accordions.length > 0), + }, + sectionHeadings + ) const facilities = setFacilityCards( restaurantImages ?? undefined, conferencesAndMeetings ?? undefined, healthAndWellness ?? undefined, - hasRestaurants, - hasMeetingRooms, - hasWellness + pageSections ) - const topThreePois = pointsOfInterest.slice(0, 3) - const coordinates = { lat: location.latitude, lng: location.longitude, @@ -148,14 +158,7 @@ export default async function HotelPage({ hotelId }: HotelPageProps) { <PreviewImages images={images} hotelName={name} /> ) : null} </header> - <TabNavigation - hasActivities={activitiesCards.length > 0} - hasFAQ={!!faq?.accordions.length} - hasWellness={hasWellness} - hasRestaurants={hasRestaurants} - hasMeetingRooms={hasMeetingRooms} - tabValues={tabValues} - /> + <TabNavigation pageSections={pageSections} /> <main className={styles.mainSection}> <div id={HotelHashValues.overview} className={styles.overview}> @@ -185,7 +188,11 @@ export default async function HotelPage({ hotelId }: HotelPageProps) { </div> ) : null} </div> - <Rooms rooms={roomCategories} preamble={hotelRoomElevatorPitchText} /> + <Rooms + heading={pageSections.rooms.heading} + rooms={roomCategories} + preamble={hotelRoomElevatorPitchText} + /> {facilities && ( <Facilities facilities={facilities} @@ -205,7 +212,7 @@ export default async function HotelPage({ hotelId }: HotelPageProps) { hotelName={name} markerInfo={{ hotelType, hotelId }} /> - <MapCard hotelName={name} pois={topThreePois} /> + <MapCard hotelName={name} pois={pointsOfInterest.slice(0, 3)} /> </MapWithCardWrapper> </aside> <MobileMapToggle /> @@ -237,8 +244,9 @@ export default async function HotelPage({ hotelId }: HotelPageProps) { ecoLabels={hotelFacts.ecoLabels} descriptions={hotelContent.texts} /> - {hasWellness ? ( + {pageSections.wellness ? ( <WellnessAndExerciseSidePeek + heading={pageSections.wellness.heading} healthFacilities={healthFacilities} spaPage={spaPage?.spa_page} wellnessExercisePageUrl={ @@ -246,8 +254,11 @@ export default async function HotelPage({ hotelId }: HotelPageProps) { } /> ) : null} - {hasRestaurants ? ( - <RestaurantBarSidePeek restaurants={restaurants} /> + {pageSections.restaurant ? ( + <RestaurantBarSidePeek + heading={pageSections.restaurant.heading} + restaurants={restaurants} + /> ) : null} {activitiesCards.map((card) => ( <ActivitiesSidePeek @@ -257,8 +268,9 @@ export default async function HotelPage({ hotelId }: HotelPageProps) { sidepeekSlug={card.upcoming_activities_card.sidepeekSlug} /> ))} - {hasMeetingRooms && ( + {pageSections.meetings ? ( <MeetingsAndConferencesSidePeek + heading={pageSections.meetings.heading} meetingFacilities={conferencesAndMeetings} descriptions={hotelContent.texts.meetingDescription} meetingRooms={meetingRoomsData ?? []} @@ -266,7 +278,7 @@ export default async function HotelPage({ hotelId }: HotelPageProps) { displayWebPage.meetingRoom ? meetingRooms.nameInUrl : undefined } /> - )} + ) : null} {roomCategories.map((room) => ( <RoomSidePeek key={room.name} hotelId={hotelId} room={room} /> ))} diff --git a/apps/scandic-web/components/ContentType/HotelPage/utils.ts b/apps/scandic-web/components/ContentType/HotelPage/utils.ts index 718698ba6..4489f3fca 100644 --- a/apps/scandic-web/components/ContentType/HotelPage/utils.ts +++ b/apps/scandic-web/components/ContentType/HotelPage/utils.ts @@ -1,11 +1,16 @@ import type { IntlShape } from "react-intl" import { HealthFacilitiesEnum } from "@/types/components/hotelPage/facilities" +import type { + HotelPageSectionHeadings, + HotelPageSections, +} from "@/types/components/hotelPage/sections" import { TrackingChannelEnum, type TrackingSDKHotelInfo, type TrackingSDKPageData, } from "@/types/components/tracking" +import { HotelHashValues } from "@/types/enums/hotelPage" import type { Hotel, HotelData } from "@/types/hotel" import type { HotelPage } from "@/types/trpc/routers/contentstack/hotelPage" import type { Lang } from "@/constants/languages" @@ -84,3 +89,94 @@ export function translateWellnessType(type: string, intl: IntlShape) { }) } } + +export function getPageSectionsData( + intl: IntlShape, + dynamicSections: { + hasWellness: boolean + hasRestaurants: boolean + hasMeetingRooms: boolean + hasActivities: boolean + hasFAQ: boolean + }, + sectionHeadings?: HotelPageSectionHeadings | null +) { + const { + hasWellness, + hasRestaurants, + hasMeetingRooms, + hasActivities, + hasFAQ, + } = dynamicSections + const sections: HotelPageSections = { + overview: { + hash: HotelHashValues.overview, + heading: + sectionHeadings?.overview || + intl.formatMessage({ + defaultMessage: "Overview", + }), + }, + rooms: { + hash: HotelHashValues.rooms, + heading: + sectionHeadings?.rooms || + intl.formatMessage({ + defaultMessage: "Rooms", + }), + }, + } + + if (hasRestaurants) { + sections.restaurant = { + hash: HotelHashValues.restaurant, + heading: + sectionHeadings?.restaurant_bar || + intl.formatMessage({ + defaultMessage: "Restaurant & Bar", + }), + } + } + if (hasMeetingRooms) { + sections.meetings = { + hash: HotelHashValues.meetings, + heading: + sectionHeadings?.conferences_meetings || + intl.formatMessage({ + defaultMessage: "Meetings & Conferences", + }), + } + } + if (hasWellness) { + sections.wellness = { + hash: HotelHashValues.wellness, + heading: + sectionHeadings?.health_wellness || + intl.formatMessage({ + defaultMessage: "Gym & Wellness", + }), + } + } + if (hasActivities) { + sections.activities = { + hash: HotelHashValues.activities, + heading: + sectionHeadings?.activities || + intl.formatMessage({ + defaultMessage: "Activities", + }), + } + } + if (hasFAQ) { + sections.faq = { + hash: HotelHashValues.faq, + heading: + sectionHeadings?.faq || + intl.formatMessage({ + defaultMessage: "FAQ", + }), + } + } + + return sections +} diff --git a/apps/scandic-web/server/routers/contentstack/hotelPage/output.ts b/apps/scandic-web/server/routers/contentstack/hotelPage/output.ts index 740e3da00..0669f3b77 100644 --- a/apps/scandic-web/server/routers/contentstack/hotelPage/output.ts +++ b/apps/scandic-web/server/routers/contentstack/hotelPage/output.ts @@ -82,7 +82,7 @@ export const hotelPageSchema = z.object({ ), }) .transform(({ hotel_navigation, ...rest }) => ({ - tabValues: hotel_navigation, + sectionHeadings: hotel_navigation, ...rest, })), }) diff --git a/apps/scandic-web/types/components/hotelPage/hotelPage.ts b/apps/scandic-web/types/components/hotelPage/hotelPage.ts index cba8c41d4..29ead7fc6 100644 --- a/apps/scandic-web/types/components/hotelPage/hotelPage.ts +++ b/apps/scandic-web/types/components/hotelPage/hotelPage.ts @@ -1,3 +1,5 @@ +import type { HotelHashValues } from "@/types/enums/hotelPage" + export interface HotelPageProps { hotelId: string } @@ -10,3 +12,6 @@ export enum SidepeekSlugs { meetings = "meetings", wellness = "wellness", } + +export type HotelHashValue = + (typeof HotelHashValues)[keyof typeof HotelHashValues] diff --git a/apps/scandic-web/types/components/hotelPage/room.ts b/apps/scandic-web/types/components/hotelPage/room.ts index 048958f43..0a8a8031c 100644 --- a/apps/scandic-web/types/components/hotelPage/room.ts +++ b/apps/scandic-web/types/components/hotelPage/room.ts @@ -5,6 +5,7 @@ export interface RoomCardProps { } export type RoomsProps = { + heading: string preamble?: string rooms: Room[] } diff --git a/apps/scandic-web/types/components/hotelPage/sections.ts b/apps/scandic-web/types/components/hotelPage/sections.ts new file mode 100644 index 000000000..ca959a2c3 --- /dev/null +++ b/apps/scandic-web/types/components/hotelPage/sections.ts @@ -0,0 +1,27 @@ +import type { HotelHashValue } from "./hotelPage" + +export interface HotelPageSectionHeadings { + overview?: string | null + rooms?: string | null + restaurant_bar?: string | null + conferences_meetings?: string | null + health_wellness?: string | null + activities?: string | null + offers?: string | null + faq?: string | null +} + +interface HotelPageSection { + hash: HotelHashValue + heading: string +} + +export interface HotelPageSections { + overview: HotelPageSection + rooms: HotelPageSection + restaurant?: HotelPageSection + meetings?: HotelPageSection + wellness?: HotelPageSection + activities?: HotelPageSection + faq?: HotelPageSection +} diff --git a/apps/scandic-web/types/components/hotelPage/sidepeek/meetingsAndConferences.ts b/apps/scandic-web/types/components/hotelPage/sidepeek/meetingsAndConferences.ts index a1a843022..3e681e4a1 100644 --- a/apps/scandic-web/types/components/hotelPage/sidepeek/meetingsAndConferences.ts +++ b/apps/scandic-web/types/components/hotelPage/sidepeek/meetingsAndConferences.ts @@ -6,4 +6,5 @@ export type MeetingsAndConferencesSidePeekProps = { descriptions: Hotel["hotelContent"]["texts"]["meetingDescription"] meetingRooms: MeetingRooms meetingPageUrl: string | undefined + heading: string } diff --git a/apps/scandic-web/types/components/hotelPage/sidepeek/restaurantBar.ts b/apps/scandic-web/types/components/hotelPage/sidepeek/restaurantBar.ts index 31ab6b4b7..f30200456 100644 --- a/apps/scandic-web/types/components/hotelPage/sidepeek/restaurantBar.ts +++ b/apps/scandic-web/types/components/hotelPage/sidepeek/restaurantBar.ts @@ -2,6 +2,7 @@ import type { Restaurant } from "@/types/hotel" export interface RestaurantBarSidePeekProps { restaurants: Restaurant[] + heading: string } export interface RestaurantBarItemProps { diff --git a/apps/scandic-web/types/components/hotelPage/sidepeek/wellnessAndExercise.ts b/apps/scandic-web/types/components/hotelPage/sidepeek/wellnessAndExercise.ts index 6897ab864..9d29980e1 100644 --- a/apps/scandic-web/types/components/hotelPage/sidepeek/wellnessAndExercise.ts +++ b/apps/scandic-web/types/components/hotelPage/sidepeek/wellnessAndExercise.ts @@ -7,4 +7,5 @@ export type WellnessAndExerciseSidePeekProps = { buttonCTA: string url: string } + heading: string } diff --git a/apps/scandic-web/types/components/hotelPage/tabNavigation.ts b/apps/scandic-web/types/components/hotelPage/tabNavigation.ts deleted file mode 100644 index de887691b..000000000 --- a/apps/scandic-web/types/components/hotelPage/tabNavigation.ts +++ /dev/null @@ -1,29 +0,0 @@ -export enum HotelHashValues { - overview = "overview", - rooms = "rooms", - restaurant = "restaurants", - meetings = "meetings", - wellness = "wellness", - activities = "activities", - faq = "faq", -} - -type Tabs = { - overview?: string | null - rooms?: string | null - restaurant_bar?: string | null - conferences_meetings?: string | null - health_wellness?: string | null - activities?: string | null - offers?: string | null - faq?: string | null -} - -export type TabNavigationProps = { - hasActivities: boolean - hasFAQ: boolean - hasWellness: boolean - hasRestaurants: boolean - hasMeetingRooms: boolean - tabValues?: Tabs | null -} diff --git a/apps/scandic-web/types/enums/hotelPage.ts b/apps/scandic-web/types/enums/hotelPage.ts index 8cc5f8839..0b1c0260b 100644 --- a/apps/scandic-web/types/enums/hotelPage.ts +++ b/apps/scandic-web/types/enums/hotelPage.ts @@ -7,3 +7,13 @@ export namespace HotelPageEnum { } } } + +export const HotelHashValues = { + overview: "overview", + rooms: "rooms", + restaurant: "restaurants", + meetings: "meetings", + wellness: "wellness", + activities: "activities", + faq: "faq", +} as const diff --git a/apps/scandic-web/utils/facilityCards.ts b/apps/scandic-web/utils/facilityCards.ts index 265db8c3a..c2f3b29cc 100644 --- a/apps/scandic-web/utils/facilityCards.ts +++ b/apps/scandic-web/utils/facilityCards.ts @@ -11,9 +11,13 @@ import { RestaurantHeadings, WellnessHeadings, } from "@/types/components/hotelPage/facilities" -import { SidepeekSlugs } from "@/types/components/hotelPage/hotelPage" -import { HotelHashValues } from "@/types/components/hotelPage/tabNavigation" +import { + type HotelHashValue, + SidepeekSlugs, +} from "@/types/components/hotelPage/hotelPage"; +import type { HotelPageSections } from "@/types/components/hotelPage/sections" import { FacilityEnum } from "@/types/enums/facilities" +import { HotelHashValues } from "@/types/enums/hotelPage" import type { Amenities, Facility, @@ -26,24 +30,34 @@ export function setFacilityCards( restaurantImages: FacilityData | undefined, conferencesAndMeetings: FacilityData | undefined, healthAndWellness: FacilityData | undefined, - hasRestaurants: boolean, - hasMeetingRooms: boolean, - hasWellness: boolean + pageSections: HotelPageSections ): Facility[] { const facilities = [] - if (hasRestaurants) { + if (pageSections.restaurant) { facilities.push( - setFacilityCard(restaurantImages, FacilityCardTypeEnum.restaurant) + setFacilityCard( + restaurantImages, + FacilityCardTypeEnum.restaurant, + pageSections.restaurant.heading + ) ) } - if (hasMeetingRooms) { + if (pageSections.meetings) { facilities.push( - setFacilityCard(conferencesAndMeetings, FacilityCardTypeEnum.conference) + setFacilityCard( + conferencesAndMeetings, + FacilityCardTypeEnum.conference, + pageSections.meetings.heading + ) ) } - if (hasWellness) { + if (pageSections.wellness) { facilities.push( - setFacilityCard(healthAndWellness, FacilityCardTypeEnum.wellness) + setFacilityCard( + healthAndWellness, + FacilityCardTypeEnum.wellness, + pageSections.wellness.heading + ) ) } return facilities @@ -51,12 +65,13 @@ export function setFacilityCards( function setFacilityCard( facility: FacilityData | undefined, - type: FacilityCardTypeEnum + type: FacilityCardTypeEnum, + heading: string ): Facility { return { ...facility, id: type, - headingText: facility?.headingText ?? "", + headingText: heading, heroImages: facility?.heroImages ?? [], } } @@ -72,7 +87,7 @@ export function isFacilityImage(card: FacilityCardType): card is FacilityImage { function setCardProps( theme: CardProps["theme"], buttonText: (typeof FacilityCardButtonText)[keyof typeof FacilityCardButtonText], - href: HotelHashValues, + href: HotelHashValue, heading: string, slug: SidepeekSlugs, scriptedTopTitle?: string