"use client" import NextLink from "next/link" import { usePathname } from "next/navigation" import { useCallback, useEffect, useRef, useState } from "react" import { useIntl } from "react-intl" import { useMediaQuery } from "usehooks-ts" import { debounce } from "@scandic-hotels/common/utils/debounce" import { IconButton } from "@scandic-hotels/design-system/IconButton" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { trackClick } from "@scandic-hotels/tracking/base" import { trpc } from "@scandic-hotels/trpc/client" import useLang from "@/hooks/useLang" import { DesktopCampaignBanner } from "./Desktop" import { MobileCampaignBanner } from "./Mobile" import { shouldShowCampaignBanner } from "./utils" import styles from "./campaignBanner.module.css" import type { CampaignBannerProps } from "@/components/CampaignBanner/types" export default function CampaignBanner() { const lang = useLang() const intl = useIntl() const pathname = usePathname() const campaignBannerRef = useRef(null) const isMobile = useMediaQuery("(max-width: 767px)") const [closedPaths, setClosedPaths] = useState>(new Set()) const [ { data: siteConfig, isLoading: siteConfigLoading }, { data: campaignBanner, isLoading: campaignBannerLoading }, ] = trpc.useQueries((t) => [ t.contentstack.base.siteConfig({ lang }, { refetchInterval: 60_000 }), t.contentstack.base.sitewideCampaignBanner.get( { lang }, { refetchInterval: 360_000 } ), ]) const isOnSamePage = pathname === campaignBanner?.link?.url const sitewideAlertType = siteConfig?.sitewideAlert?.type || null const shouldShowBanner = shouldShowCampaignBanner( pathname, lang, closedPaths, sitewideAlertType ) const isVisible = !siteConfigLoading && !campaignBannerLoading && !!campaignBanner && shouldShowBanner const updateHeightRefCallback = useCallback((node: HTMLDivElement | null) => { if (node) { const debouncedUpdate = debounce(([entry]) => { const height = entry.contentRect.height document.documentElement.style.setProperty( "--campaign-banner-height", `${height}px` ) }, 100) const observer = new ResizeObserver(debouncedUpdate) observer.observe(node) return () => { if (node) { observer.unobserve(node) } observer.disconnect() } } }, []) useEffect(() => { if (!isVisible) { document.documentElement.style.removeProperty("--campaign-banner-height") } }, [isVisible]) if (!isVisible) { return null } function handleClose() { trackClick("BW close") setClosedPaths((prev) => new Set(prev).add(pathname)) } return (
{ campaignBannerRef.current = node return updateHeightRefCallback(node) }} >
{isMobile ? ( ) : ( )}
) } function InnerContent({ link, children, }: React.PropsWithChildren<{ link: CampaignBannerProps["link"] }>) { return link ? ( trackClick("BW campaign banner")} > {children} ) : (
{children}
) }