From 4550ddec5346dc7f0f7c35ecc2dc4671b7c9ea83 Mon Sep 17 00:00:00 2001 From: Anton Gunnarsson Date: Tue, 9 Sep 2025 10:00:25 +0000 Subject: [PATCH] Merged in feat/sw-3416-add-sitewidealert-to-partner-sas (pull request #2773) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat(SW-3416): Add SiteWideAlert to partner-sas * Add SiteWideAlert to partner-sas * Remove log Approved-by: Joakim Jäderberg --- apps/partner-sas/app/[lang]/layout.tsx | 2 + .../components/SitewideAlert/index.tsx | 89 +++++++++++++++++++ .../SitewideAlert/sitewideAlert.module.css | 11 +++ 3 files changed, 102 insertions(+) create mode 100644 apps/partner-sas/components/SitewideAlert/index.tsx create mode 100644 apps/partner-sas/components/SitewideAlert/sitewideAlert.module.css diff --git a/apps/partner-sas/app/[lang]/layout.tsx b/apps/partner-sas/app/[lang]/layout.tsx index 448af0995..77b0e30cb 100644 --- a/apps/partner-sas/app/[lang]/layout.tsx +++ b/apps/partner-sas/app/[lang]/layout.tsx @@ -12,6 +12,7 @@ import { ToastHandler } from "@scandic-hotels/design-system/ToastHandler" import { TrpcProvider } from "@scandic-hotels/trpc/Provider" import { RACRouterProvider } from "@/components/RACRouterProvider" +import { SiteWideAlert } from "@/components/SitewideAlert" import { FontPreload } from "@/fonts/font-preloading" import { getMessages } from "@/i18n" import ClientIntlProvider from "@/i18n/Provider" @@ -83,6 +84,7 @@ export default async function RootLayout(props: RootLayoutProps) { trackGenericEvent, }} > +
{props.bookingwidget}
{children}
diff --git a/apps/partner-sas/components/SitewideAlert/index.tsx b/apps/partner-sas/components/SitewideAlert/index.tsx new file mode 100644 index 000000000..add7c05bc --- /dev/null +++ b/apps/partner-sas/components/SitewideAlert/index.tsx @@ -0,0 +1,89 @@ +"use client" + +import { useCallback, useRef } from "react" + +import { AlertTypeEnum } from "@scandic-hotels/common/constants/alert" +import useStickyPosition from "@scandic-hotels/common/hooks/useStickyPosition" +import { StickyElementNameEnum } from "@scandic-hotels/common/stores/sticky-position" +import { debounce } from "@scandic-hotels/common/utils/debounce" +import { Alert } from "@scandic-hotels/design-system/Alert" +import { trpc } from "@scandic-hotels/trpc/client" + +import useLang from "@/hooks/useLang" + +import styles from "./sitewideAlert.module.css" + +export function SiteWideAlert() { + const alertRef = useRef(null) + const lang = useLang() + const { data: siteConfig, isLoading } = + trpc.contentstack.base.siteConfig.useQuery( + { lang }, + { refetchInterval: 60_000 } + ) + + const alert = siteConfig?.sitewideAlert + + const isAlarm = alert?.type === AlertTypeEnum.Alarm + useStickyPosition({ + ref: isAlarm ? alertRef : undefined, + name: StickyElementNameEnum.SITEWIDE_ALERT, + }) + + const updateHeightRefCallback = useCallback( + (node: HTMLDivElement | null) => { + if (node) { + const debouncedUpdate = debounce(([entry]) => { + const height = entry.contentRect.height + + document.documentElement.style.setProperty( + "--sitewide-alert-height", + `${height}px` + ) + + document.documentElement.style.setProperty( + "--sitewide-alert-sticky-height", + isAlarm ? `${height}px` : "0px" + ) + }, 100) + + const observer = new ResizeObserver(debouncedUpdate) + observer.observe(node) + + return () => { + if (node) { + observer.unobserve(node) + } + observer.disconnect() + } + } + }, + [isAlarm] + ) + + if (isLoading || !alert) { + return null + } + + return ( +
{ + alertRef.current = node + return updateHeightRefCallback(node) + }} + className={`${styles.sitewideAlert} ${isAlarm ? styles.alarm : ""}`} + > + +
+ ) +} diff --git a/apps/partner-sas/components/SitewideAlert/sitewideAlert.module.css b/apps/partner-sas/components/SitewideAlert/sitewideAlert.module.css new file mode 100644 index 000000000..8dad9de49 --- /dev/null +++ b/apps/partner-sas/components/SitewideAlert/sitewideAlert.module.css @@ -0,0 +1,11 @@ +.sitewideAlert { + width: 100%; + z-index: var(--header-z-index); + position: relative; +} + +.alarm { + position: sticky; + top: 0; + z-index: calc(var(--header-z-index) + 1); +}