Skip to content

Commit

Permalink
fix: google analytics
Browse files Browse the repository at this point in the history
  • Loading branch information
Marco Blumendorf committed Jan 21, 2025
1 parent 1b80748 commit 06e13c4
Show file tree
Hide file tree
Showing 10 changed files with 72 additions and 222 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@
"lucide-react": "^0.469.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-ga4": "^2.1.0",
"react-router-dom": "^7.1.1"
},
"devDependencies": {
"@eslint/js": "^9.17.0",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.1.0",
"@testing-library/user-event": "^14.5.2",
"@types/gtag.js": "^0.0.20",
"@types/node": "^22.10.5",
"@types/react": "^18.3.18",
"@types/react-dom": "^18.3.5",
Expand Down
16 changes: 16 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 4 additions & 6 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import CookieBanner from './components/CookieBanner'
import PrivacyPolicy from './components/PrivacyPolicy'
import Impressum from './components/Impressum'
import { useDevMessage } from './hooks/useDevMessage'
import { initializeTracking } from './utils/initializeTracking'
import { initializeGoogleAnalytics } from './utils/analytics'

// Add type for section configuration
type SectionConfig = {
Expand Down Expand Up @@ -63,11 +63,6 @@ function MainContent() {
}

function MainLayout() {
// Initialize tracking
React.useEffect(() => {
initializeTracking();
}, []);

// Show development process message
useDevMessage();

Expand All @@ -82,6 +77,9 @@ function MainLayout() {
}

function App() {
// Initialize Google Analytics with your measurement ID
initializeGoogleAnalytics('G-MG5LDT8GT6');

return (
<HashRouter>
<Routes>
Expand Down
89 changes: 17 additions & 72 deletions src/components/CookieBanner.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,35 @@
import { useEffect, useState } from 'react';
import { cookieConsent } from '../utils/cookieConsent';
import '../styles/cookieBanner.css';
import { setAnalyticsConsent } from '../utils/analytics';

export default function CookieBanner() {
const [isVisible, setIsVisible] = useState(false);
const [showDetails, setShowDetails] = useState(false);
const [analyticsEnabled, setAnalyticsEnabled] = useState(cookieConsent.hasAnalyticsConsent());

const hasConsent = localStorage.getItem('cookieConsent');
console.log('hasConsent', hasConsent);

const updateConsent = (consent: boolean) => {
localStorage.setItem('cookieConsent', consent.toString());
setAnalyticsConsent(consent);
};

useEffect(() => {
// Show banner if no consent has been given
if (!cookieConsent.hasConsent()) {
if (hasConsent === null) {
setIsVisible(true);
setAnalyticsConsent(false); // Default to denied
} else {
// Restore previous consent
setAnalyticsConsent(hasConsent === 'true');
}

// If analytics consent exists, initialize it
if (cookieConsent.hasAnalyticsConsent()) {
cookieConsent.updateConsent(true);
}
}, []);

const handleCustomize = () => {
setShowDetails(true);
};
}, [hasConsent]);

const handleAcceptAll = () => {
setAnalyticsEnabled(true);
cookieConsent.updateConsent(true);
updateConsent(true);
setIsVisible(false);
};

const handleDeclineAll = () => {
setAnalyticsEnabled(false);
cookieConsent.updateConsent(false);
setIsVisible(false);
};

const handleSavePreferences = () => {
cookieConsent.updateConsent(analyticsEnabled);
updateConsent(false);
setIsVisible(false);
};

Expand All @@ -50,48 +43,8 @@ export default function CookieBanner() {
We respect your privacy and are committed to transparency. We use cookies to enhance your experience and
analyze site traffic.
</p>
<div className={showDetails ? 'mt-4 space-y-4' : 'hidden mt-4 space-y-4'}>
<div>
<div className="flex items-center gap-2">
<input
id="essential-cookies"
type="checkbox"
checked={true}
disabled
className="rounded text-accent cursor-not-allowed opacity-50"
/>
<label htmlFor="essential-cookies">
<h4 className="font-semibold">Essential Cookies</h4>
<p className="text-xs">Required for the website to function properly. Always active.</p>
</label>
</div>
</div>
<div>
<div className="flex items-center gap-2">
<input
id="analytics-cookies"
type="checkbox"
checked={analyticsEnabled}
onChange={(e) => setAnalyticsEnabled(e.target.checked)}
className="rounded text-accent"
/>
<label htmlFor="analytics-cookies">
<h4 className="font-semibold">Analytics Cookies</h4>
<p className="text-xs">Help us understand how visitors interact with our website.</p>
</label>
</div>
</div>
</div>
</div>
<div className="flex flex-wrap gap-3">
{!showDetails && (
<button
onClick={handleCustomize}
className="px-4 py-2 text-sm text-gray-600 dark:text-gray-300 hover:text-gray-800 dark:hover:text-white transition-colors"
>
Customize
</button>
)}
<button
onClick={handleDeclineAll}
className="px-4 py-2 text-sm text-gray-600 dark:text-gray-300 hover:text-gray-800 dark:hover:text-white transition-colors"
Expand All @@ -104,14 +57,6 @@ export default function CookieBanner() {
>
Accept All
</button>
{showDetails && (
<button
onClick={handleSavePreferences}
className="px-4 py-2 text-sm bg-accent hover:bg-accent-dark text-white rounded-lg transition-colors"
>
Save Preferences
</button>
)}
</div>
</div>
</div>
Expand Down
16 changes: 16 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,19 @@
.dark .border-accent\/40 {
border-color: rgba(5, 200, 0, 0.4);
}

#cookie-banner {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
padding: 1rem;
box-shadow: 0 -4px 6px -1px rgba(0, 0, 0, 0.1);
z-index: 50;
}

.dark #cookie-banner {
background: rgba(31, 41, 55, 0.95);
}
15 changes: 0 additions & 15 deletions src/styles/cookieBanner.css

This file was deleted.

26 changes: 0 additions & 26 deletions src/types/analytics.d.ts

This file was deleted.

67 changes: 17 additions & 50 deletions src/utils/analytics.ts
Original file line number Diff line number Diff line change
@@ -1,56 +1,23 @@
// Initialize dataLayer array if it doesn't exist
if (!window.dataLayer) {
window.dataLayer = [];
}

// Google Analytics Measurement ID
const GA_MEASUREMENT_ID = 'G-MG5LDT8GT6';

// Create dummy gtag function if not loaded
if (!window.gtag) {
window.gtag = function (...args: Parameters<Window['gtag']>) {
window.dataLayer.push(args);
};
}

// Initialize analytics with consent mode
export function initializeGoogleAnalytics(): void {
const script = document.createElement('script');
script.async = true;
script.src = `https://www.googletagmanager.com/gtag/js?id=${GA_MEASUREMENT_ID}`;
document.head.appendChild(script);
import ReactGA from 'react-ga4';

script.onload = function () {
window.dataLayer = window.dataLayer || [];
window.gtag('js', new Date().toISOString());
window.gtag('config', GA_MEASUREMENT_ID, {
'anonymize_ip': true // IP anonymization for GDPR
});
};
declare global {
interface Window {
dataLayer: unknown[][];
gtag: (...args: unknown[]) => void;
}
}

// Set default consent mode settings
export function initializeConsentMode(): void {
window.gtag('consent', 'default', {
'analytics_storage': 'denied',
'ad_storage': 'denied',
'functionality_storage': 'denied',
'personalization_storage': 'denied',
'security_storage': 'granted' // Required for basic functionality
export const initializeGoogleAnalytics = (measurementId: string): void => {
ReactGA.initialize(measurementId, {
// testMode: process.env.NODE_ENV === 'development',
});
}
};

// Update consent settings
export function updateConsentState(consent: boolean): void {
// Update consent state
window.gtag('consent', 'update', {
'analytics_storage': consent ? 'granted' : 'denied',
'functionality_storage': 'granted', // Essential cookies always allowed
'personalization_storage': consent ? 'granted' : 'denied'
export const setAnalyticsConsent = (consent: boolean): void => {
ReactGA.gtag('consent', 'update', {
analytics_storage: consent ? 'granted' : 'denied',
ad_storage: consent ? 'granted' : 'denied',
ad_personalization: consent ? 'granted' : 'denied',
ad_consent: consent ? 'granted' : 'denied',
});

// Initialize analytics if consent is granted
if (consent && !document.querySelector('script[src*="googletagmanager"]')) {
initializeGoogleAnalytics();
}
}
};
22 changes: 0 additions & 22 deletions src/utils/cookieConsent.ts

This file was deleted.

Loading

0 comments on commit 06e13c4

Please sign in to comment.