From e6ff6629bcb886133e175ed00481cd0927b95400 Mon Sep 17 00:00:00 2001 From: Dominic Arrojado Date: Tue, 10 Dec 2024 01:09:49 +0800 Subject: [PATCH] track topic and toast events --- components/subscribe-form.tsx | 35 ++++++++++++++++++++++++-------- components/telegram-channels.tsx | 26 ++++++++++++++++++++++-- components/ui/toaster.tsx | 15 +++++++++++++- lib/enums.ts | 5 +++++ lib/google-analytics.ts | 19 +++++++++++++++-- lib/types.ts | 32 +++++++++++++++++++++++++++++ 6 files changed, 118 insertions(+), 14 deletions(-) diff --git a/components/subscribe-form.tsx b/components/subscribe-form.tsx index c27e269..159423c 100644 --- a/components/subscribe-form.tsx +++ b/components/subscribe-form.tsx @@ -60,33 +60,50 @@ export default function SubscribeForm({ const isFormValid = email.includes("@") && email.includes(".") && topics.length > 0; const isLoading = fetchStatus === FetchStatus.Loading; - const scrollDown = () => { + const toastTitle = "👍 Almost there!"; + const scrollDownText = "Scroll Down"; + const scrollDownOnClick = () => { const formCardEl = formCardRef.current; if (formCardEl) { formCardEl.scrollIntoView({ behavior: "smooth" }); } + + trackEvent({ + toastTitle, + event: GoogleAnalyticsEvent.TOAST_CLICK, + buttonText: scrollDownText, + }); }; - const switchOnClick = (topic: SubscriptionTopic) => { - const newTopics = topics.includes(topic) - ? topics.filter((t) => t !== topic) - : [...topics, topic]; + const switchOnClick = (topicId: SubscriptionTopic, topicTitle: string) => { + const newTopics = topics.includes(topicId) + ? topics.filter((t) => t !== topicId) + : [...topics, topicId]; if (newTopics.length !== 0 && !hasToastedRef.current) { hasToastedRef.current = true; const { dismiss } = toast({ - title: "👍 Almost there!", + title: toastTitle, description: "If you're done, scroll down to the last step.", action: ( - - Scroll Down + + {scrollDownText} ), duration: 60000, }); dismissToastRef.current = dismiss; + + trackEvent({ + toastTitle, + event: GoogleAnalyticsEvent.TOAST_OPEN, + buttonText: topicTitle, + }); } setTopics(newTopics); @@ -138,7 +155,7 @@ export default function SubscribeForm({ topicRoute={topicRoute} disabled={isLoading} checked={topics.includes(id)} - onClick={() => switchOnClick(id)} + onClick={() => switchOnClick(id, title)} /> ), )} diff --git a/components/telegram-channels.tsx b/components/telegram-channels.tsx index 50df650..69d3827 100644 --- a/components/telegram-channels.tsx +++ b/components/telegram-channels.tsx @@ -18,7 +18,8 @@ import { Anchor } from "@/components/ui/anchor"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { getTelegramChannelUrl } from "@/lib/telegram"; -import { Routes } from "@/lib/enums"; +import { trackEvent } from "@/lib/google-analytics"; +import { GoogleAnalyticsEvent, Routes } from "@/lib/enums"; import type { TelegramPublicChannels } from "@/lib/types"; type Props = { @@ -27,6 +28,24 @@ type Props = { }; export default function TelegramChannels({ channels, withBackButton }: Props) { + const viewDetailsText = "View Details"; + const topicOnClick = (title: string, linkUrl: string, linkText?: string) => { + trackEvent({ + linkText, + linkUrl, + event: GoogleAnalyticsEvent.TOPIC_CLICK, + topicTitle: title, + }); + }; + const topicPageOnClick = (title: string, linkUrl: string) => { + trackEvent({ + linkUrl, + event: GoogleAnalyticsEvent.TOPIC_PAGE_CLICK, + topicTitle: title, + linkText: viewDetailsText, + }); + }; + return ( @@ -50,6 +69,7 @@ export default function TelegramChannels({ channels, withBackButton }: Props) { topicOnClick(title, channelUrl, title)} isExternal > {title} @@ -61,6 +81,7 @@ export default function TelegramChannels({ channels, withBackButton }: Props) { topicOnClick(title, channelUrl)} isExternal > @@ -70,10 +91,11 @@ export default function TelegramChannels({ channels, withBackButton }: Props) { diff --git a/components/ui/toaster.tsx b/components/ui/toaster.tsx index ce1251d..1b33305 100644 --- a/components/ui/toaster.tsx +++ b/components/ui/toaster.tsx @@ -1,6 +1,7 @@ "use client"; import { useToast } from "@/lib/hooks/use-toast"; +import { trackEvent } from "@/lib/google-analytics"; import { Toast, ToastClose, @@ -9,9 +10,18 @@ import { ToastTitle, ToastViewport, } from "@/components/ui/toast"; +import { GoogleAnalyticsEvent } from "@/lib/enums"; export function Toaster() { const { toasts } = useToast(); + const closeBtnText = "Close Toast"; + const closeBtnOnClick = (title: string) => { + trackEvent({ + event: GoogleAnalyticsEvent.TOAST_CLOSE, + toastTitle: title, + buttonText: closeBtnText, + }); + }; return ( @@ -25,7 +35,10 @@ export function Toaster() { )} {action} - + closeBtnOnClick(title || "")} + /> ); })} diff --git a/lib/enums.ts b/lib/enums.ts index 2b1197d..cff42ef 100644 --- a/lib/enums.ts +++ b/lib/enums.ts @@ -75,6 +75,11 @@ export enum SubscriptionTopic { export enum GoogleAnalyticsEvent { SUBSCRIBE_FORM_SUBMIT = "subscribe_form_submit", UNSUBSCRIBE_FORM_SUBMIT = "unsubscribe_form_submit", + TOPIC_CLICK = "topic_click", + TOPIC_PAGE_CLICK = "topic_page_click", + TOAST_OPEN = "toast_open", + TOAST_CLOSE = "toast_close", + TOAST_CLICK = "toast_click", } export enum FlightAirline { diff --git a/lib/google-analytics.ts b/lib/google-analytics.ts index ab927f4..cd08c21 100644 --- a/lib/google-analytics.ts +++ b/lib/google-analytics.ts @@ -1,6 +1,14 @@ import { SITE_NAME } from "./constants"; import { checkIsLocalhost } from "./location"; -import { EventSubscribeFormSubmit, EventUnsubscribeFormSubmit } from "./types"; +import { + EventSubscribeFormSubmit, + EventToastClick, + EventToastClose, + EventToastOpen, + EventTopicClick, + EventTopicPageClick, + EventUnsubscribeFormSubmit, +} from "./types"; declare global { interface Window { @@ -9,7 +17,14 @@ declare global { } export function trackEvent( - data: EventSubscribeFormSubmit | EventUnsubscribeFormSubmit + data: + | EventSubscribeFormSubmit + | EventUnsubscribeFormSubmit + | EventTopicClick + | EventTopicPageClick + | EventToastOpen + | EventToastClose + | EventToastClick, ) { if (checkIsLocalhost()) { return; diff --git a/lib/types.ts b/lib/types.ts index 6e124e7..cb3848e 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -45,6 +45,38 @@ export type EventUnsubscribeFormSubmit = { buttonText: string; }; +export type EventTopicClick = { + event: GoogleAnalyticsEvent.TOPIC_CLICK; + topicTitle: string; + linkText?: string; + linkUrl: string; +}; + +export type EventTopicPageClick = { + event: GoogleAnalyticsEvent.TOPIC_PAGE_CLICK; + topicTitle: string; + linkText: string; + linkUrl: string; +}; + +export type EventToastOpen = { + event: GoogleAnalyticsEvent.TOAST_OPEN; + toastTitle: string; + buttonText: string; +}; + +export type EventToastClose = { + event: GoogleAnalyticsEvent.TOAST_CLOSE; + toastTitle: string; + buttonText: string; +}; + +export type EventToastClick = { + event: GoogleAnalyticsEvent.TOAST_CLICK; + toastTitle: string; + buttonText: string; +}; + export type DepositRate = { tenure: number; rate: number;