All files / src/scripts pro-signup-cta.ts

100% Statements 6/6
100% Branches 4/4
100% Functions 2/2
100% Lines 5/5

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37                                  8x 7x       4x 3x                       1x  
// Pro-signup CTA tracking.
//
// The "Apply as a Pro" CTAs are outbound links to the Portal's /register page
// (JoinAsProCta.astro, how-it-works HeroSection.astro + FinalCTA.astro). The
// Portal has no analytics, so the marketplace fires a GA4 `pro_signup_click`
// conversion (via GTM) on the outbound click as a proxy for signup-page intent.
//
// One delegated listener on document covers every CTA placement, including any
// rendered after view-transition navs — no per-component wiring.
 
import { getCachedHomeownerUser } from "../components/homeowner/auth-check";
import { pushDataLayerEvent } from "../lib/gtm";
 
/** Returns the register-CTA anchor for a click target, or null if none. */
export function findRegisterCta(
	target: EventTarget | null,
): HTMLAnchorElement | null {
	if (!(target instanceof Element)) return null;
	return target.closest<HTMLAnchorElement>('a[href*="/register"]');
}
 
export function handleProSignupClick(e: MouseEvent): void {
	if (findRegisterCta(e.target)) {
		pushDataLayerEvent("pro_signup_click", {
			// Canonical page dimension shared across all marketplace conversion
			// events (generate_lead, sign_up, pro_signup_click) so GA can slice
			// every conversion by page. See apps/marketplace/CLAUDE.md §Analytics.
			page_path: window.location.pathname,
			// Optimistic (cached, no network) homeowner auth state — kept
			// synchronous so the push lands before the outbound navigation.
			logged_in: getCachedHomeownerUser() != null,
		});
	}
}
 
document.addEventListener("click", handleProSignupClick);