fix(BOOK-506): Hiding campaign banner on more hotel-reservation routes and make whole banner clickable
Approved-by: Bianca Widstam
This commit is contained in:
@@ -1,11 +1,9 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import NextLink from "next/link"
|
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
import { trackClick } from "@scandic-hotels/tracking/base"
|
|
||||||
|
|
||||||
import { MarqueeText } from "@/components/MarqueeText"
|
import { MarqueeText } from "@/components/MarqueeText"
|
||||||
|
|
||||||
@@ -22,7 +20,7 @@ export function DesktopCampaignBanner({
|
|||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.innerContent}>
|
<>
|
||||||
<Typography variant="Tag/sm">
|
<Typography variant="Tag/sm">
|
||||||
<span className={styles.tag}>{tag}</span>
|
<span className={styles.tag}>{tag}</span>
|
||||||
</Typography>
|
</Typography>
|
||||||
@@ -53,22 +51,16 @@ export function DesktopCampaignBanner({
|
|||||||
|
|
||||||
{link ? (
|
{link ? (
|
||||||
<Typography variant="Link/sm">
|
<Typography variant="Link/sm">
|
||||||
<NextLink
|
<span className={styles.fakeLink}>
|
||||||
href={link.url}
|
{link.title ||
|
||||||
className={styles.link}
|
intl.formatMessage({
|
||||||
onClick={() => trackClick("BW read more")}
|
id: "common.readMore",
|
||||||
>
|
defaultMessage: "Read more",
|
||||||
<span>
|
})}
|
||||||
{link.title ||
|
</span>
|
||||||
intl.formatMessage({
|
|
||||||
id: "common.readMore",
|
|
||||||
defaultMessage: "Read more",
|
|
||||||
})}
|
|
||||||
</span>
|
|
||||||
</NextLink>
|
|
||||||
</Typography>
|
</Typography>
|
||||||
) : null}
|
) : null}
|
||||||
</MarqueeText>
|
</MarqueeText>
|
||||||
</div>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { cx } from "class-variance-authority"
|
import { cx } from "class-variance-authority"
|
||||||
import NextLink from "next/link"
|
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
import { trackClick } from "@scandic-hotels/tracking/base"
|
|
||||||
|
|
||||||
import { MarqueeText } from "@/components/MarqueeText"
|
import { MarqueeText } from "@/components/MarqueeText"
|
||||||
|
|
||||||
@@ -22,91 +20,63 @@ export function MobileCampaignBanner({
|
|||||||
}: CampaignBannerProps) {
|
}: CampaignBannerProps) {
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
|
|
||||||
return (
|
if (bookingCode) {
|
||||||
<InnerContent link={link} bookingCode={bookingCode}>
|
return (
|
||||||
{bookingCode ? (
|
<p>
|
||||||
<p>
|
<Typography variant="Title/Overline/sm">
|
||||||
<Typography variant="Title/Overline/sm">
|
<span className={cx(styles.tag, styles.withBookingCode)}>{tag}</span>
|
||||||
<span className={cx(styles.tag, styles.withBookingCode)}>
|
</Typography>
|
||||||
{tag}
|
<Typography variant="Body/Supporting text (caption)/smRegular">
|
||||||
</span>
|
<span>
|
||||||
</Typography>
|
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
|
||||||
<Typography variant="Body/Supporting text (caption)/smRegular">
|
<> ∙ {text} </>
|
||||||
<span>
|
<Typography variant="Body/Supporting text (caption)/smBold">
|
||||||
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
|
<span className={styles.bookingCode}>
|
||||||
<> ∙ {text} </>
|
{intl.formatMessage(
|
||||||
<Typography variant="Body/Supporting text (caption)/smBold">
|
{
|
||||||
<span className={styles.bookingCode}>
|
id: "campaignBanner.codeWithBookingCode",
|
||||||
{intl.formatMessage(
|
defaultMessage: "Code: {bookingCode}",
|
||||||
{
|
},
|
||||||
id: "campaignBanner.codeWithBookingCode",
|
{ bookingCode }
|
||||||
defaultMessage: "Code: {bookingCode}",
|
)}
|
||||||
},
|
<MaterialIcon
|
||||||
{ bookingCode }
|
icon="arrow_forward"
|
||||||
)}
|
color="CurrentColor"
|
||||||
<MaterialIcon
|
size={16}
|
||||||
icon="arrow_forward"
|
/>
|
||||||
color="CurrentColor"
|
</span>
|
||||||
size={16}
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</Typography>
|
|
||||||
</span>
|
|
||||||
</Typography>
|
|
||||||
</p>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<Typography variant="Tag/sm">
|
|
||||||
<span className={styles.tag}>{tag}</span>
|
|
||||||
</Typography>
|
|
||||||
<MarqueeText
|
|
||||||
backgroundColor="var(--Surface-Brand-Primary-3-Default)"
|
|
||||||
className={styles.marquee}
|
|
||||||
textWrapperClassName={styles.marqueeText}
|
|
||||||
>
|
|
||||||
<Typography variant="Body/Supporting text (caption)/smRegular">
|
|
||||||
<span>{text}</span>
|
|
||||||
</Typography>
|
</Typography>
|
||||||
{link ? (
|
</span>
|
||||||
<Typography variant="Link/sm">
|
</Typography>
|
||||||
<span>
|
</p>
|
||||||
{link.title ||
|
)
|
||||||
intl.formatMessage({
|
}
|
||||||
id: "common.readMore",
|
|
||||||
defaultMessage: "Read more",
|
|
||||||
})}
|
|
||||||
</span>
|
|
||||||
</Typography>
|
|
||||||
) : null}
|
|
||||||
</MarqueeText>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</InnerContent>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function InnerContent({
|
return (
|
||||||
link,
|
<>
|
||||||
bookingCode,
|
<Typography variant="Tag/sm">
|
||||||
children,
|
<span className={styles.tag}>{tag}</span>
|
||||||
}: React.PropsWithChildren<Pick<CampaignBannerProps, "link" | "bookingCode">>) {
|
</Typography>
|
||||||
return link ? (
|
<MarqueeText
|
||||||
<NextLink
|
backgroundColor="var(--Surface-Brand-Primary-3-Default)"
|
||||||
href={link.url}
|
className={styles.marquee}
|
||||||
className={cx(styles.innerContent, {
|
textWrapperClassName={styles.marqueeText}
|
||||||
[styles.withBookingCode]: !!bookingCode,
|
>
|
||||||
})}
|
<Typography variant="Body/Supporting text (caption)/smRegular">
|
||||||
onClick={() => trackClick("BW campaign banner")}
|
<span>{text}</span>
|
||||||
>
|
</Typography>
|
||||||
{children}
|
{link ? (
|
||||||
</NextLink>
|
<Typography variant="Link/sm">
|
||||||
) : (
|
<span className={styles.fakeLink}>
|
||||||
<div
|
{link.title ||
|
||||||
className={cx(styles.innerContent, {
|
intl.formatMessage({
|
||||||
[styles.withBookingCode]: !!bookingCode,
|
id: "common.readMore",
|
||||||
})}
|
defaultMessage: "Read more",
|
||||||
>
|
})}
|
||||||
{children}
|
</span>
|
||||||
</div>
|
</Typography>
|
||||||
|
) : null}
|
||||||
|
</MarqueeText>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,10 +22,7 @@
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: var(--Text-Inverted);
|
color: var(--Text-Inverted);
|
||||||
padding: var(--Space-x025) 0;
|
padding: var(--Space-x025) 0;
|
||||||
|
gap: var(--Space-x15);
|
||||||
&:not(.withBookingCode) {
|
|
||||||
gap: var(--Space-x15);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.text {
|
.text {
|
||||||
@@ -61,10 +58,14 @@
|
|||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.link {
|
.fakeLink {
|
||||||
color: var(--Text-Inverted);
|
color: var(--Text-Inverted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.innerContent:hover .fakeLink {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
.bookingCode {
|
.bookingCode {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ const SHARED_HIDE_ROUTES = [
|
|||||||
"/hotelreservation/details",
|
"/hotelreservation/details",
|
||||||
"/hotelreservation/booking-confirmation",
|
"/hotelreservation/booking-confirmation",
|
||||||
"/hotelreservation/my-stay",
|
"/hotelreservation/my-stay",
|
||||||
|
"/hotelreservation/gla-payment-callback",
|
||||||
|
"/hotelreservation/payment-callback",
|
||||||
|
"/hotelreservation/get-booking",
|
||||||
]
|
]
|
||||||
|
|
||||||
export const CAMPAIGN_BANNER_HIDE_CONDITIONS = {
|
export const CAMPAIGN_BANNER_HIDE_CONDITIONS = {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
|
import NextLink from "next/link"
|
||||||
import { usePathname } from "next/navigation"
|
import { usePathname } from "next/navigation"
|
||||||
import { useCallback, useEffect, useRef, useState } from "react"
|
import { useCallback, useEffect, useRef, useState } from "react"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
@@ -19,6 +20,8 @@ import { shouldShowCampaignBanner } from "./utils"
|
|||||||
|
|
||||||
import styles from "./campaignBanner.module.css"
|
import styles from "./campaignBanner.module.css"
|
||||||
|
|
||||||
|
import type { CampaignBannerProps } from "@/components/CampaignBanner/types"
|
||||||
|
|
||||||
export default function CampaignBanner() {
|
export default function CampaignBanner() {
|
||||||
const lang = useLang()
|
const lang = useLang()
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
@@ -97,21 +100,23 @@ export default function CampaignBanner() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className={styles.content}>
|
<div className={styles.content}>
|
||||||
{isMobile ? (
|
<InnerContent link={isOnSamePage ? null : campaignBanner.link}>
|
||||||
<MobileCampaignBanner
|
{isMobile ? (
|
||||||
tag={campaignBanner.tag}
|
<MobileCampaignBanner
|
||||||
text={campaignBanner.text}
|
tag={campaignBanner.tag}
|
||||||
link={isOnSamePage ? null : campaignBanner.link}
|
text={campaignBanner.text}
|
||||||
bookingCode={campaignBanner.booking_code}
|
link={isOnSamePage ? null : campaignBanner.link}
|
||||||
/>
|
bookingCode={campaignBanner.booking_code}
|
||||||
) : (
|
/>
|
||||||
<DesktopCampaignBanner
|
) : (
|
||||||
tag={campaignBanner.tag}
|
<DesktopCampaignBanner
|
||||||
text={campaignBanner.text}
|
tag={campaignBanner.tag}
|
||||||
link={isOnSamePage ? null : campaignBanner.link}
|
text={campaignBanner.text}
|
||||||
bookingCode={campaignBanner.booking_code}
|
link={isOnSamePage ? null : campaignBanner.link}
|
||||||
/>
|
bookingCode={campaignBanner.booking_code}
|
||||||
)}
|
/>
|
||||||
|
)}
|
||||||
|
</InnerContent>
|
||||||
<IconButton
|
<IconButton
|
||||||
className={styles.closeButton}
|
className={styles.closeButton}
|
||||||
theme="Inverted"
|
theme="Inverted"
|
||||||
@@ -128,3 +133,22 @@ export default function CampaignBanner() {
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function InnerContent({
|
||||||
|
link,
|
||||||
|
children,
|
||||||
|
}: React.PropsWithChildren<{
|
||||||
|
link: CampaignBannerProps["link"]
|
||||||
|
}>) {
|
||||||
|
return link ? (
|
||||||
|
<NextLink
|
||||||
|
href={link.url}
|
||||||
|
className={styles.innerContent}
|
||||||
|
onClick={() => trackClick("BW campaign banner")}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</NextLink>
|
||||||
|
) : (
|
||||||
|
<div className={styles.innerContent}>{children}</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export function shouldShowCampaignBanner(
|
|||||||
const fullRoute = removeTrailingSlash(
|
const fullRoute = removeTrailingSlash(
|
||||||
removeMultipleSlashes(`/${lang}${route}`)
|
removeMultipleSlashes(`/${lang}${route}`)
|
||||||
)
|
)
|
||||||
return cleanPathname === fullRoute
|
return cleanPathname.startsWith(fullRoute)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user