feat(SW-392): Added book a table link click

This commit is contained in:
Erik Tiekstra
2025-01-09 13:08:25 +01:00
parent a68f3cc8e6
commit 14e8e2254c
7 changed files with 73 additions and 19 deletions

View File

@@ -0,0 +1,37 @@
"use client"
import NextLink from "next/link"
import Button from "@/components/TempDesignSystem/Button"
import { trackClick } from "@/utils/tracking"
import type { ButtonLinkProps } from "@/types/components/buttonLink"
export default function ButtonLink({
children,
href,
target,
trackingId,
trackingParams,
onClick,
...buttonProps
}: ButtonLinkProps) {
return (
<Button {...buttonProps} asChild>
<NextLink
href={href}
target={target}
onClick={(e) => {
if (onClick) {
onClick(e)
}
if (trackingId) {
trackClick(trackingId, trackingParams)
}
}}
>
{children}
</NextLink>
</Button>
)
}

View File

@@ -1,8 +1,6 @@
import NextLink from "next/link" import ButtonLink from "@/components/ButtonLink"
import { OpenInNewSmallIcon } from "@/components/Icons" import { OpenInNewSmallIcon } from "@/components/Icons"
import Image from "@/components/Image" import Image from "@/components/Image"
import Button from "@/components/TempDesignSystem/Button"
import Link from "@/components/TempDesignSystem/Link" import Link from "@/components/TempDesignSystem/Link"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import { getIntl } from "@/i18n" import { getIntl } from "@/i18n"
@@ -18,7 +16,7 @@ export default async function RestaurantBarItem({
}: RestaurantBarItemProps) { }: RestaurantBarItemProps) {
const intl = await getIntl() const intl = await getIntl()
const { name, openingDetails, menus } = restaurant const { name, openingDetails, menus } = restaurant
const { images, bookTableUrl } = restaurant.content const { bookTableUrl, images } = restaurant.content
const visibleImages = restaurant.content.images.slice(0, 2) const visibleImages = restaurant.content.images.slice(0, 2)
const imageWidth = images.length === 2 ? 240 : 496 const imageWidth = images.length === 2 ? 240 : 496
@@ -86,18 +84,22 @@ export default async function RestaurantBarItem({
{bookTableUrl || ctaUrl ? ( {bookTableUrl || ctaUrl ? (
<div className={styles.ctaWrapper}> <div className={styles.ctaWrapper}>
{bookTableUrl ? ( {bookTableUrl ? (
<Button fullWidth theme="base" intent="primary" asChild> <ButtonLink
<NextLink href={bookTableUrl} target="_blank"> fullWidth
{intl.formatMessage({ id: "Book a table online" })} theme="base"
</NextLink> intent="primary"
</Button> href={bookTableUrl}
target="_blank"
trackingId="book a table"
trackingParams={{ restaurantName: name }}
>
{intl.formatMessage({ id: "Book a table online" })}
</ButtonLink>
) : null} ) : null}
{ctaUrl ? ( {ctaUrl ? (
<Button fullWidth theme="base" intent="secondary" asChild> <ButtonLink fullWidth theme="base" intent="secondary" href={ctaUrl}>
<NextLink href={ctaUrl}> {`${intl.formatMessage({ id: "Discover" })} ${name}`}
{`${intl.formatMessage({ id: "Discover" })} ${name}`} </ButtonLink>
</NextLink>
</Button>
) : null} ) : null}
</div> </div>
) : null} ) : null}

View File

@@ -23,6 +23,7 @@ export default function Link({
variant, variant,
weight, weight,
trackingId, trackingId,
trackingParams,
onClick, onClick,
/** /**
* Decides if the link should include the current search params in the URL * Decides if the link should include the current search params in the URL
@@ -60,9 +61,9 @@ export default function Link({
const trackClickById = useCallback(() => { const trackClickById = useCallback(() => {
if (trackingId) { if (trackingId) {
trackClick(trackingId) trackClick(trackingId, trackingParams)
} }
}, [trackingId]) }, [trackingId, trackingParams])
const linkProps = { const linkProps = {
href: fullUrl, href: fullUrl,

View File

@@ -10,5 +10,6 @@ export interface LinkProps
partialMatch?: boolean partialMatch?: boolean
prefetch?: boolean prefetch?: boolean
trackingId?: string trackingId?: string
trackingParams?: Record<string, string>
keepSearchParams?: boolean keepSearchParams?: boolean
} }

View File

@@ -36,7 +36,7 @@ const restaurantOpeningDetailSchema = z.object({
export const restaurantSchema = z export const restaurantSchema = z
.object({ .object({
attributes: z.object({ attributes: z.object({
name: z.string().optional(), name: z.string(),
isPublished: z.boolean().default(false), isPublished: z.boolean().default(false),
email: z.string().optional(), email: z.string().optional(),
phoneNumber: z.string().optional(), phoneNumber: z.string().optional(),

View File

@@ -0,0 +1,9 @@
import type { ButtonPropsSlot } from "@/components/TempDesignSystem/Button/button"
export type ButtonLinkProps = React.PropsWithChildren &
Omit<ButtonPropsSlot, "asChild"> &
Pick<React.AnchorHTMLAttributes<HTMLAnchorElement>, "onClick" | "target"> & {
href: string
trackingId?: string
trackingParams?: Record<string, string>
}

View File

@@ -5,10 +5,14 @@ import type {
TrackingSDKData, TrackingSDKData,
} from "@/types/components/tracking" } from "@/types/components/tracking"
export function trackClick(name: string) { export function trackClick(
name: string,
additionalParams?: Record<string, string>
) {
pushToDataLayer({ pushToDataLayer({
event: "linkClick", event: "linkClick",
cta: { cta: {
...additionalParams,
name, name,
}, },
}) })
@@ -56,7 +60,7 @@ export function trackHotelMapClick() {
const event = { const event = {
event: "map click", event: "map click",
map: { map: {
action: "map click open/explore mearby", action: "map click - open/explore mearby",
}, },
} }
pushToDataLayer(event) pushToDataLayer(event)