From e10892de673e05189a99b325d89ecc53b136c632 Mon Sep 17 00:00:00 2001 From: James Grugett Date: Wed, 20 May 2026 23:12:08 -0700 Subject: [PATCH] Track ad clicks --- cli/src/chat.tsx | 8 +- cli/src/components/choice-ad-banner.tsx | 11 +- cli/src/components/waiting-room-screen.tsx | 8 +- cli/src/hooks/use-gravity-ad.ts | 31 +++++ common/src/constants/analytics-events.ts | 1 + web/src/app/api/v1/ads/click/_post.ts | 125 +++++++++++++++++++++ web/src/app/api/v1/ads/click/route.ts | 18 +++ 7 files changed, 196 insertions(+), 6 deletions(-) create mode 100644 web/src/app/api/v1/ads/click/_post.ts create mode 100644 web/src/app/api/v1/ads/click/route.ts diff --git a/cli/src/chat.tsx b/cli/src/chat.tsx index ba35cda9ee..b24f19c981 100644 --- a/cli/src/chat.tsx +++ b/cli/src/chat.tsx @@ -174,7 +174,7 @@ export const Chat = ({ }) const hasSubscription = subscriptionData?.hasSubscription ?? false - const { ads, recordImpression } = useGravityAd({ + const { ads, recordClick, recordImpression } = useGravityAd({ enabled: IS_FREEBUFF || !hasSubscription, provider: 'gravity', fallbackProvider: 'zeroclick', @@ -1464,7 +1464,11 @@ export const Chat = ({ )} {ads && (IS_FREEBUFF || getAdsEnabled()) && ( - + )} {reviewMode ? ( diff --git a/cli/src/components/choice-ad-banner.tsx b/cli/src/components/choice-ad-banner.tsx index 1ed8586323..ccacbe53b5 100644 --- a/cli/src/components/choice-ad-banner.tsx +++ b/cli/src/components/choice-ad-banner.tsx @@ -11,6 +11,7 @@ import type { AdResponse } from '../hooks/use-gravity-ad' interface ChoiceAdBannerProps { ads: AdResponse[] + onClick?: (ad: AdResponse) => void onImpression?: (ad: AdResponse) => void } @@ -61,7 +62,11 @@ function columnWidths(count: number, availableWidth: number): number[] { return Array.from({ length: count }, (_, i) => base + (i < remainder ? 1 : 0)) } -export const ChoiceAdBanner: React.FC = ({ ads, onImpression }) => { +export const ChoiceAdBanner: React.FC = ({ + ads, + onClick, + onImpression, +}) => { const theme = useTheme() const { terminalWidth } = useTerminalDimensions() const [hoveredIndex, setHoveredIndex] = useState(null) @@ -115,7 +120,9 @@ export const ChoiceAdBanner: React.FC = ({ ads, onImpressio