Skip to content

Commit

Permalink
filip(feat): add osano and ga
Browse files Browse the repository at this point in the history
  • Loading branch information
fstoqnov-iohk committed Jan 16, 2025
1 parent af5c305 commit 538d7de
Show file tree
Hide file tree
Showing 8 changed files with 578 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*
.log/
.vercel
7 changes: 7 additions & 0 deletions docs/docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,13 @@ const config = {
],
},
],
[
"@docusaurus/plugin-google-gtag",
{
trackingID: "G-Z847J5GYDW",
anonymizeIP: true,
},
],
],

themeConfig:
Expand Down
65 changes: 65 additions & 0 deletions docs/src/analytics/AnalyticsContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import React, {
PropsWithChildren,
createContext,
useCallback,
useEffect,
} from "react";
import dayjs from "dayjs";
import TrackRoute from "./TrackRoute";
import useHasConsent, { ConsentType } from "./useHasConsent";

export const AnalyticsContext = createContext<
(eventName: string, eventProps?: Record<string, unknown>) => void
>(() => {});

export function AnalyticsProvider({ children }: PropsWithChildren) {
const analyticsAccepted = useHasConsent(ConsentType.ANALYTICS);

const gtag = (...args: any[]) => {
if (typeof window !== "undefined" && (window as any).gtag) {
(window as any).gtag(...args);
}
};

const capture = useCallback(
(eventName: string, eventProperties: Record<string, unknown> = {}) => {
if (analyticsAccepted) {
gtag("event", eventName, {
sent_at_local: dayjs().format(),
...eventProperties,
});
}
},
[analyticsAccepted]
);

useEffect(() => {
const gaMeasurementId = "G-Z847J5GYDW"; // Replace with env variagble
if (analyticsAccepted) {
if (!(window as any).gtag) {
const script = document.createElement("script");
script.async = true;
script.src = `https://www.googletagmanager.com/gtag/js?id=${gaMeasurementId}`;
document.head.appendChild(script);

// Initialize dataLayer and gtag
(window as any).dataLayer = (window as any).dataLayer || [];
(window as any).gtag = function gtag(...args: any[]) {
(window as any).dataLayer.push(args);
};
gtag("js", new Date());
gtag("config", gaMeasurementId);
}
} else {
// Disable Google Analytics if consent is revoked
gtag("config", gaMeasurementId, { send_page_view: false });
}
}, [analyticsAccepted]);

return (
<AnalyticsContext.Provider value={capture}>
<TrackRoute />
{children}
</AnalyticsContext.Provider>
);
}
17 changes: 17 additions & 0 deletions docs/src/analytics/TrackRoute.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useLocation } from "@docusaurus/router";
import React, { useContext, useEffect } from "react";
import { AnalyticsContext } from "./AnalyticsContext";

export default function TrackRoute() {
const location = useLocation();
const capture = useContext(AnalyticsContext);

useEffect(() => {
capture("page_view", {
page_path: location.pathname,
page_search: location.search,
});
}, [capture, location.pathname, location.search]);

return null;
}
41 changes: 41 additions & 0 deletions docs/src/analytics/osano.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
export enum OsanoConsentType {
ESSENTIAL = "ESSENTIAL",
STORAGE = "STORAGE",
MARKETING = "MARKETING",
PERSONALIZATION = "PERSONALIZATION",
ANALYTICS = "ANALYTICS",
OPT_OUT = "OPT_OUT"
}

export enum OsanoConsentDecision {
ACCEPT = "ACCEPT",
DENY = "DENY"
}

export type OsanoConsentMap = Record<OsanoConsentType, OsanoConsentDecision>;

export enum OsanoEvent {
CONSENT_SAVED = "osano-cm-consent-saved"
}

export type OsanoEventCallback = {
[OsanoEvent.CONSENT_SAVED]: (changed: Partial<OsanoConsentMap>) => void;
};

declare global {
interface Osano {
cm?: {
getConsent(): OsanoConsentMap;
addEventListener: <T extends OsanoEvent>(
ev: T,
callback: OsanoEventCallback[T]
) => void;
removeEventListener: <T extends OsanoEvent>(
ev: T,
callback: OsanoEventCallback[T]
) => void;
};
}

var Osano: Osano | undefined;
}
43 changes: 43 additions & 0 deletions docs/src/analytics/useHasConsent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { useEffect, useState } from "react";
import {
OsanoConsentDecision,
OsanoConsentType,
OsanoEvent,
OsanoEventCallback
} from "./osano";

export { OsanoConsentType as ConsentType };

export default function useHasConsent(
type: OsanoConsentType
): boolean | undefined {
const initialConsent =
typeof Osano !== "undefined"
? Osano.cm?.getConsent()[type] === OsanoConsentDecision.ACCEPT
: undefined;

const [state, setState] = useState<boolean | undefined>(initialConsent);

useEffect(() => {
const cm = typeof Osano !== "undefined" ? Osano.cm : undefined;

if (!cm) {
return;
}

setState(cm.getConsent()[type] === OsanoConsentDecision.ACCEPT);

const handler: OsanoEventCallback[OsanoEvent.CONSENT_SAVED] = (changed) => {
if (type in changed) {
setState(changed[type] === OsanoConsentDecision.ACCEPT);
}
};

cm.addEventListener(OsanoEvent.CONSENT_SAVED, handler);
return () => {
cm.removeEventListener(OsanoEvent.CONSENT_SAVED, handler);
};
}, [type]);

return state;
}
Loading

0 comments on commit 538d7de

Please sign in to comment.