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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | 1x 1x 1x 1x | import {
useContext,
useCallback,
useRef,
createContext,
FunctionComponent,
useEffect,
} from "react";
import { useLocation } from "react-router-dom";
import { ClickEventConfig, PageViewConfig } from "./types";
import { clickEvent } from "./util";
export interface AnalyticsAPI {
trackCustomEvent: (opts: ClickEventConfig) => void;
trackPageView: (opts: PageViewConfig) => void;
}
const AnalyticsContext = createContext<AnalyticsAPI>({
trackCustomEvent: () => {},
trackPageView: () => {},
});
const dispatchAnalyticsEvent = (
detail: PageViewConfig | ClickEventConfig,
cb?: () => void
) => {
window?.AWSMA?.ready?.(() => {
if (process.env.NODE_ENV === "development") {
console.info(detail.event.name, detail);
}
document.dispatchEvent(
new CustomEvent(window.AWSMA.TRIGGER_EVENT, { detail })
);
cb?.();
});
};
export const useAnalytics = () => useContext(AnalyticsContext);
export const AnalyticsProvider: FunctionComponent = ({ children }) => {
const { pathname } = useLocation();
const prevPath = useRef<null | string>(null);
const trackPageView: AnalyticsAPI["trackPageView"] = useCallback(
(opts) => {
if (prevPath.current === pathname) {
return;
}
dispatchAnalyticsEvent(opts, () => {
prevPath.current = pathname;
});
},
[pathname]
);
// Tracks click events for elements with a `data-event` attr or elements which are nested within a data-event item
useEffect(() => {
const listener = (e: MouseEvent) => {
if (e.target) {
let eventName: string | null = null;
let target: HTMLElement | null = e.target as HTMLElement;
while (target && !eventName) {
if (target.hasAttribute?.("data-event")) {
eventName = target.getAttribute("data-event");
} else if (target.parentElement) {
target = target.parentElement;
} else {
target = null;
}
}
if (eventName) {
dispatchAnalyticsEvent(clickEvent({ name: eventName }));
}
}
};
window.addEventListener("click", listener);
return () => window.removeEventListener("click", listener);
}, []);
return (
<AnalyticsContext.Provider
value={{ trackPageView, trackCustomEvent: dispatchAnalyticsEvent }}
>
{children}
</AnalyticsContext.Provider>
);
};
|