From a29657a6b20488fe495f96f82392047ca61803a9 Mon Sep 17 00:00:00 2001 From: Erik Tiekstra Date: Tue, 22 Oct 2024 10:49:01 +0200 Subject: [PATCH] feat(SW-508): Added hotel alerts --- app/[lang]/(live)/@sitewidealert/page.tsx | 9 +++-- .../HotelPage/hotelPage.module.css | 16 +++++---- components/ContentType/HotelPage/index.tsx | 34 ++++++++++++++----- components/SitewideAlert/index.tsx | 28 +++++++-------- components/TempDesignSystem/Alert/alert.ts | 4 +-- components/TempDesignSystem/Alert/index.tsx | 4 +++ server/routers/hotels/output.ts | 21 +++++++++++- server/routers/hotels/query.ts | 2 ++ 8 files changed, 82 insertions(+), 36 deletions(-) diff --git a/app/[lang]/(live)/@sitewidealert/page.tsx b/app/[lang]/(live)/@sitewidealert/page.tsx index 0f0c75eba..b0bbf8765 100644 --- a/app/[lang]/(live)/@sitewidealert/page.tsx +++ b/app/[lang]/(live)/@sitewidealert/page.tsx @@ -1,9 +1,10 @@ import { env } from "@/env/server" +import { Suspense } from "react" import SitewideAlert, { preload } from "@/components/SitewideAlert" import { setLang } from "@/i18n/serverContext" -import { LangParams, PageArgs } from "@/types/params" +import type { LangParams, PageArgs } from "@/types/params" export default function SitewideAlertPage({ params }: PageArgs) { if (env.HIDE_FOR_NEXT_RELEASE) { @@ -13,5 +14,9 @@ export default function SitewideAlertPage({ params }: PageArgs) { setLang(params.lang) preload() - return + return ( + + + + ) } diff --git a/components/ContentType/HotelPage/hotelPage.module.css b/components/ContentType/HotelPage/hotelPage.module.css index 771c4e76e..091444fe2 100644 --- a/components/ContentType/HotelPage/hotelPage.module.css +++ b/components/ContentType/HotelPage/hotelPage.module.css @@ -29,6 +29,11 @@ display: none; } +.overview { + display: grid; + gap: var(--Spacing-x3); +} + .introContainer { display: flex; flex-wrap: wrap; @@ -37,6 +42,11 @@ scroll-margin-top: var(--hotel-page-scroll-margin-top); } +.alertsContainer { + display: grid; + gap: var(--Spacing-x2); +} + @media screen and (min-width: 1367px) { .pageContainer { grid-template-areas: @@ -76,10 +86,4 @@ padding-left: var(--Spacing-x5); padding-right: var(--Spacing-x5); } - .introContainer { - grid-template-columns: 38rem minmax(max-content, 16rem); - justify-content: space-between; - gap: var(--Spacing-x2); - align-items: end; - } } diff --git a/components/ContentType/HotelPage/index.tsx b/components/ContentType/HotelPage/index.tsx index 5b0139d6f..d10244040 100644 --- a/components/ContentType/HotelPage/index.tsx +++ b/components/ContentType/HotelPage/index.tsx @@ -4,6 +4,7 @@ import { serverClient } from "@/lib/trpc/server" import AccordionSection from "@/components/Blocks/Accordion" import SidePeekProvider from "@/components/SidePeekProvider" +import Alert from "@/components/TempDesignSystem/Alert" import SidePeek from "@/components/TempDesignSystem/SidePeek" import { getIntl } from "@/i18n" import { getLang } from "@/i18n/serverContext" @@ -49,6 +50,7 @@ export default async function HotelPage() { pointsOfInterest, facilities, faq, + alerts, } = hotelData const topThreePois = pointsOfInterest.slice(0, 3) @@ -69,16 +71,30 @@ export default async function HotelPage() { hasFAQ={!!faq} />
-
- +
+
+ - + +
+ {alerts.length ? ( +
+ {alerts.map((alert) => ( + + ))} +
+ ) : null}
diff --git a/components/SitewideAlert/index.tsx b/components/SitewideAlert/index.tsx index c2cb6e728..2ce624119 100644 --- a/components/SitewideAlert/index.tsx +++ b/components/SitewideAlert/index.tsx @@ -1,5 +1,3 @@ -import { Suspense } from "react" - import { getSiteConfig } from "@/lib/trpc/memoizedRequests" import Alert from "../TempDesignSystem/Alert" @@ -19,19 +17,17 @@ export default async function SitewideAlert() { const { sitewideAlert } = siteConfig return ( - -
- -
-
+
+ +
) } diff --git a/components/TempDesignSystem/Alert/alert.ts b/components/TempDesignSystem/Alert/alert.ts index 20927d7fc..e63873c66 100644 --- a/components/TempDesignSystem/Alert/alert.ts +++ b/components/TempDesignSystem/Alert/alert.ts @@ -8,8 +8,8 @@ import type { SidepeekContent } from "@/types/trpc/routers/contentstack/siteConf export interface AlertProps extends VariantProps { className?: string type: AlertTypeEnum - heading?: string - text: string + heading?: string | null + text?: string | null phoneContact?: { displayText: string phoneNumber?: string diff --git a/components/TempDesignSystem/Alert/index.tsx b/components/TempDesignSystem/Alert/index.tsx index 6499c7126..2f1e97b6a 100644 --- a/components/TempDesignSystem/Alert/index.tsx +++ b/components/TempDesignSystem/Alert/index.tsx @@ -27,6 +27,10 @@ export default function Alert({ }) const Icon = getIconByAlertType(type) + if (!text && !heading) { + return null + } + return (
diff --git a/server/routers/hotels/output.ts b/server/routers/hotels/output.ts index 89e286185..803ae012f 100644 --- a/server/routers/hotels/output.ts +++ b/server/routers/hotels/output.ts @@ -1,11 +1,13 @@ import { z } from "zod" +import { dt } from "@/lib/dt" import { toLang } from "@/server/utils" import { imageMetaDataSchema, imageSizesSchema } from "./schemas/image" import { roomSchema } from "./schemas/room" import { getPoiGroupByCategoryName } from "./utils" +import { AlertTypeEnum } from "@/types/enums/alert" import { FacilityEnum } from "@/types/enums/facilities" import { PointOfInterestCategoryNameEnum } from "@/types/hotel" @@ -321,6 +323,7 @@ const socialMediaSchema = z.object({ const metaSpecialAlertSchema = z.object({ type: z.string(), + title: z.string().optional(), description: z.string().optional(), displayInBookingFlow: z.boolean(), startDate: z.string(), @@ -328,7 +331,23 @@ const metaSpecialAlertSchema = z.object({ }) const metaSchema = z.object({ - specialAlerts: z.array(metaSpecialAlertSchema), + specialAlerts: z + .array(metaSpecialAlertSchema) + .transform((data) => { + const now = dt().utc().format("YYYY-MM-DD") + const filteredAlerts = data.filter((alert) => { + const shouldShowNow = alert.startDate <= now && alert.endDate >= now + const hasText = alert.description || alert.title + return shouldShowNow && hasText + }) + return filteredAlerts.map((alert, idx) => ({ + id: `alert-${alert.type}-${idx}`, + type: AlertTypeEnum.Info, + heading: alert.title || null, + text: alert.description || null, + })) + }) + .default([]), }) const relationshipsSchema = z.object({ diff --git a/server/routers/hotels/query.ts b/server/routers/hotels/query.ts index 2fa4cfbe8..b5b5ff34b 100644 --- a/server/routers/hotels/query.ts +++ b/server/routers/hotels/query.ts @@ -219,6 +219,7 @@ export const hotelQueryRouter = router({ const hotelAttributes = validatedHotelData.data.data.attributes const images = extractHotelImages(hotelAttributes) + const hotelAlerts = hotelAttributes.meta?.specialAlerts || [] const roomCategories = included ? included.filter((item) => item.type === "roomcategories") @@ -262,6 +263,7 @@ export const hotelQueryRouter = router({ roomCategories, activitiesCard: activities?.upcoming_activities_card, facilities, + alerts: hotelAlerts, faq: contentstackData?.faq, } }),