diff --git a/dev-dist/sw.js b/dev-dist/sw.js index dc74cc6..e98c1a1 100644 --- a/dev-dist/sw.js +++ b/dev-dist/sw.js @@ -82,7 +82,7 @@ define(['./workbox-4a2e5f00'], (function (workbox) { 'use strict'; "revision": "3ca0b8505b4bec776b69afdba2768812" }, { "url": "index.html", - "revision": "0.lgbjrbj51sg" + "revision": "0.umc7krbmrh" }], {}); workbox.cleanupOutdatedCaches(); workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), { diff --git a/dev-dist/sw.js.map b/dev-dist/sw.js.map index d6c2f5a..dd9c73a 100644 --- a/dev-dist/sw.js.map +++ b/dev-dist/sw.js.map @@ -1 +1 @@ -{"version":3,"file":"sw.js","sources":["../../../Users/DAMJAN~1/AppData/Local/Temp/5bf5eed82d86245bcc11533e21e14e0f/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from 'C:/Development/Damjan Savic/Portfolio/node_modules/workbox-routing/registerRoute.mjs';\nimport {CacheableResponsePlugin as workbox_cacheable_response_CacheableResponsePlugin} from 'C:/Development/Damjan Savic/Portfolio/node_modules/workbox-cacheable-response/CacheableResponsePlugin.mjs';\nimport {CacheFirst as workbox_strategies_CacheFirst} from 'C:/Development/Damjan Savic/Portfolio/node_modules/workbox-strategies/CacheFirst.mjs';\nimport {NetworkOnly as workbox_strategies_NetworkOnly} from 'C:/Development/Damjan Savic/Portfolio/node_modules/workbox-strategies/NetworkOnly.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from 'C:/Development/Damjan Savic/Portfolio/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from 'C:/Development/Damjan Savic/Portfolio/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {cleanupOutdatedCaches as workbox_precaching_cleanupOutdatedCaches} from 'C:/Development/Damjan Savic/Portfolio/node_modules/workbox-precaching/cleanupOutdatedCaches.mjs';\nimport {NavigationRoute as workbox_routing_NavigationRoute} from 'C:/Development/Damjan Savic/Portfolio/node_modules/workbox-routing/NavigationRoute.mjs';\nimport {createHandlerBoundToURL as workbox_precaching_createHandlerBoundToURL} from 'C:/Development/Damjan Savic/Portfolio/node_modules/workbox-precaching/createHandlerBoundToURL.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"registerSW.js\",\n \"revision\": \"3ca0b8505b4bec776b69afdba2768812\"\n },\n {\n \"url\": \"index.html\",\n \"revision\": \"0.lgbjrbj51sg\"\n }\n], {});\nworkbox_precaching_cleanupOutdatedCaches();\nworkbox_routing_registerRoute(new workbox_routing_NavigationRoute(workbox_precaching_createHandlerBoundToURL(\"index.html\"), {\n allowlist: [/^\\/$/],\n \n}));\n\n\nworkbox_routing_registerRoute(/^https:\\/\\/fonts\\.googleapis\\.com\\/.*/i, new workbox_strategies_CacheFirst({ \"cacheName\":\"google-fonts-cache\", plugins: [new workbox_cacheable_response_CacheableResponsePlugin({ statuses: [ 0, 200 ] })] }), 'GET');\nworkbox_routing_registerRoute(/^https:\\/\\/fonts\\.gstatic\\.com\\/.*/i, new workbox_strategies_CacheFirst({ \"cacheName\":\"gstatic-fonts-cache\", plugins: [new workbox_cacheable_response_CacheableResponsePlugin({ statuses: [ 0, 200 ] })] }), 'GET');\nworkbox_routing_registerRoute(/^https:\\/\\/www\\.googletagmanager\\.com\\/.*/i, new workbox_strategies_NetworkOnly(), 'GET');\n\n\n\n\n"],"names":["self","skipWaiting","workbox_core_clientsClaim","workbox_precaching_precacheAndRoute","workbox_precaching_cleanupOutdatedCaches","workbox_routing_registerRoute","workbox_routing_NavigationRoute","workbox_precaching_createHandlerBoundToURL","allowlist","workbox_strategies_CacheFirst","plugins","workbox_cacheable_response_CacheableResponsePlugin","statuses","workbox_strategies_NetworkOnly"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"sw.js","sources":["../../../Users/DAMJAN~1/AppData/Local/Temp/f99c096fae9b2238190d489962edc906/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from 'C:/Development/Damjan Savic/Portfolio/node_modules/workbox-routing/registerRoute.mjs';\nimport {CacheableResponsePlugin as workbox_cacheable_response_CacheableResponsePlugin} from 'C:/Development/Damjan Savic/Portfolio/node_modules/workbox-cacheable-response/CacheableResponsePlugin.mjs';\nimport {CacheFirst as workbox_strategies_CacheFirst} from 'C:/Development/Damjan Savic/Portfolio/node_modules/workbox-strategies/CacheFirst.mjs';\nimport {NetworkOnly as workbox_strategies_NetworkOnly} from 'C:/Development/Damjan Savic/Portfolio/node_modules/workbox-strategies/NetworkOnly.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from 'C:/Development/Damjan Savic/Portfolio/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from 'C:/Development/Damjan Savic/Portfolio/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {cleanupOutdatedCaches as workbox_precaching_cleanupOutdatedCaches} from 'C:/Development/Damjan Savic/Portfolio/node_modules/workbox-precaching/cleanupOutdatedCaches.mjs';\nimport {NavigationRoute as workbox_routing_NavigationRoute} from 'C:/Development/Damjan Savic/Portfolio/node_modules/workbox-routing/NavigationRoute.mjs';\nimport {createHandlerBoundToURL as workbox_precaching_createHandlerBoundToURL} from 'C:/Development/Damjan Savic/Portfolio/node_modules/workbox-precaching/createHandlerBoundToURL.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"registerSW.js\",\n \"revision\": \"3ca0b8505b4bec776b69afdba2768812\"\n },\n {\n \"url\": \"index.html\",\n \"revision\": \"0.umc7krbmrh\"\n }\n], {});\nworkbox_precaching_cleanupOutdatedCaches();\nworkbox_routing_registerRoute(new workbox_routing_NavigationRoute(workbox_precaching_createHandlerBoundToURL(\"index.html\"), {\n allowlist: [/^\\/$/],\n \n}));\n\n\nworkbox_routing_registerRoute(/^https:\\/\\/fonts\\.googleapis\\.com\\/.*/i, new workbox_strategies_CacheFirst({ \"cacheName\":\"google-fonts-cache\", plugins: [new workbox_cacheable_response_CacheableResponsePlugin({ statuses: [ 0, 200 ] })] }), 'GET');\nworkbox_routing_registerRoute(/^https:\\/\\/fonts\\.gstatic\\.com\\/.*/i, new workbox_strategies_CacheFirst({ \"cacheName\":\"gstatic-fonts-cache\", plugins: [new workbox_cacheable_response_CacheableResponsePlugin({ statuses: [ 0, 200 ] })] }), 'GET');\nworkbox_routing_registerRoute(/^https:\\/\\/www\\.googletagmanager\\.com\\/.*/i, new workbox_strategies_NetworkOnly(), 'GET');\n\n\n\n\n"],"names":["self","skipWaiting","workbox_core_clientsClaim","workbox_precaching_precacheAndRoute","workbox_precaching_cleanupOutdatedCaches","workbox_routing_registerRoute","workbox_routing_NavigationRoute","workbox_precaching_createHandlerBoundToURL","allowlist","workbox_strategies_CacheFirst","plugins","workbox_cacheable_response_CacheableResponsePlugin","statuses","workbox_strategies_NetworkOnly"],"mappings":"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"} \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index 74fbcac..a46c1dc 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,6 +1,6 @@ // App.tsx import { useEffect, Suspense } from 'react'; -import { BrowserRouter } from 'react-router-dom'; +import { BrowserRouter, useLocation } from 'react-router-dom'; import { HelmetProvider } from 'react-helmet-async'; import Layout from './components/Layout'; import AppRoutes from './routes'; @@ -12,9 +12,19 @@ import DebugOverlay from './components/DebugOverlay'; import { logPageView } from './utils/analytics'; import './styles/scrollbar.css'; -function App() { +// RouteTracker Component für präzises Seiten-Tracking +const RouteTracker = () => { + const location = useLocation(); + useEffect(() => { logPageView(); + }, [location]); + + return null; +}; + +function App() { + useEffect(() => { document.documentElement.classList.add('custom-scrollbar'); }, []); @@ -27,6 +37,7 @@ function App() { + {/* Tracking bei Routenwechsel */} diff --git a/src/components/CookieBanner.tsx b/src/components/CookieBanner.tsx index cc24674..3361967 100644 --- a/src/components/CookieBanner.tsx +++ b/src/components/CookieBanner.tsx @@ -1,42 +1,313 @@ -import CookieConsent from 'react-cookie-consent'; +import { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; +import { initGA, logPageView } from '../utils/analytics'; + +// Feste Übersetzungen direkt in der Komponente +const translations = { + de: { + title: "Cookie-Einstellungen", + message: "Diese Website verwendet Cookies, um Ihr Erlebnis zu verbessern. Daten werden nicht an Dritte weitergegeben.", + acceptAll: "Alle akzeptieren", + save: "Einstellungen speichern", + decline: "Ablehnen", + necessary: "Notwendige Cookies", + necessaryDesc: "Für grundlegende Funktionen der Website", + analytics: "Analyse-Cookies", + analyticsDesc: "Für Analysen zur Verbesserung der Website", + marketing: "Marketing-Cookies", + marketingDesc: "Für personalisierte Werbung und Inhalte", + functional: "Funktionale Cookies", + functionalDesc: "Für erweiterte Funktionen und Personalisierung", + learnMore: "Mehr erfahren", + alwaysActive: "Immer aktiv" + }, + en: { + title: "Cookie Settings", + message: "This website uses cookies to enhance your browsing experience. The data will not be shared with third parties.", + acceptAll: "Accept All", + save: "Save Settings", + decline: "Decline All", + necessary: "Necessary Cookies", + necessaryDesc: "For basic website functions", + analytics: "Analytics Cookies", + analyticsDesc: "For analyzing website usage", + marketing: "Marketing Cookies", + marketingDesc: "For personalized ads and content", + functional: "Functional Cookies", + functionalDesc: "For enhanced functionality and personalization", + learnMore: "Learn more", + alwaysActive: "Always active" + }, + sr: { + title: "Podešavanja kolačića", + message: "Ovaj sajt koristi kolačiće za bolje iskustvo pretraživanja. Podaci neće biti deljeni sa trećim licima.", + acceptAll: "Prihvati sve", + save: "Sačuvaj podešavanja", + decline: "Odbij sve", + necessary: "Neophodni kolačići", + necessaryDesc: "Za osnovne funkcije sajta", + analytics: "Analitički kolačići", + analyticsDesc: "Za analizu korišćenja sajta", + marketing: "Marketing kolačići", + marketingDesc: "Za personalizovane reklame i sadržaj", + functional: "Funkcionalni kolačići", + functionalDesc: "Za napredne funkcije i personalizaciju", + learnMore: "Saznajte više", + alwaysActive: "Uvek aktivno" + } +}; + +interface CookieSettings { + necessary: boolean; + analytics: boolean; + marketing: boolean; + functional: boolean; +} const CookieBanner = () => { - const { t } = useTranslation(); + const { i18n } = useTranslation(); + const [currentLang, setCurrentLang] = useState<'de' | 'en' | 'sr'>('de'); + const [showSettings, setShowSettings] = useState(false); + const [cookieSettings, setCookieSettings] = useState({ + necessary: true, // Always true and disabled + analytics: false, + marketing: false, + functional: false + }); + + // Aktuelle Sprache erkennen + useEffect(() => { + const lang = i18n.language.substring(0, 2); + if (lang === 'de' || lang === 'en' || lang === 'sr') { + setCurrentLang(lang); + } else { + setCurrentLang('en'); // Fallback to English + } + }, [i18n.language]); + + // Get text based on current language + const getText = (key: keyof typeof translations.en) => { + return translations[currentLang][key]; + }; + + // Prüfe beim Laden, ob bereits Zustimmung vorhanden ist + useEffect(() => { + try { + const storedSettings = localStorage.getItem('cookieSettings'); + if (storedSettings) { + const parsedSettings = JSON.parse(storedSettings) as CookieSettings; + setCookieSettings(parsedSettings); + + // Nur Google Analytics laden, wenn zugestimmt wurde + if (parsedSettings.analytics) { + initGA(); + logPageView(); + } + } + } catch (error) { + console.error('Error loading cookie settings:', error); + } + }, []); + + const handleSaveSettings = () => { + localStorage.setItem('cookieSettings', JSON.stringify(cookieSettings)); + localStorage.setItem('cookieConsent', 'true'); + + if (cookieSettings.analytics) { + initGA(); + logPageView(); + } + + setShowSettings(false); + }; + + const handleAcceptAll = () => { + const allSettings: CookieSettings = { + necessary: true, + analytics: true, + marketing: true, + functional: true + }; + + localStorage.setItem('cookieSettings', JSON.stringify(allSettings)); + localStorage.setItem('cookieConsent', 'true'); + setCookieSettings(allSettings); + + initGA(); + logPageView(); + + setShowSettings(false); + }; + + const handleDeclineAll = () => { + const minimalSettings: CookieSettings = { + necessary: true, + analytics: false, + marketing: false, + functional: false + }; + + localStorage.setItem('cookieSettings', JSON.stringify(minimalSettings)); + localStorage.setItem('cookieConsent', 'false'); + setCookieSettings(minimalSettings); + + setShowSettings(false); + }; + + const toggleSetting = (setting: keyof Omit) => { + setCookieSettings({ + ...cookieSettings, + [setting]: !cookieSettings[setting] + }); + }; + + // If consent already given, don't show banner + if (localStorage.getItem('cookieConsent')) { + return null; + } return ( - { - // Initialize analytics only after consent - window.initializeAnalytics(); - }} - > - {t('common.cookies.message')} - +
+
+
+ {!showSettings ? ( +
+
+

{getText('message')}

+
+
+ + + +
+
+ ) : ( +
+
+

{getText('title')}

+ +
+ +
+

{getText('message')}

+ + {/* Cookie categories */} +
+ {/* Necessary cookies - always enabled */} +
+
+
{getText('necessary')}
+
{getText('alwaysActive')}
+
+

{getText('necessaryDesc')}

+
+ + {/* Analytics cookies */} +
+
+
{getText('analytics')}
+ +
+

{getText('analyticsDesc')}

+
+ + {/* Marketing cookies */} +
+
+
{getText('marketing')}
+ +
+

{getText('marketingDesc')}

+
+ + {/* Functional cookies */} +
+
+
{getText('functional')}
+ +
+

{getText('functionalDesc')}

+
+
+
+ +
+ + +
+ + +
+ )} +
+
+
); }; diff --git a/src/i18n/locales/de/cookiebanner.ts b/src/i18n/locales/de/cookiebanner.ts index a46e545..461949f 100644 --- a/src/i18n/locales/de/cookiebanner.ts +++ b/src/i18n/locales/de/cookiebanner.ts @@ -2,7 +2,12 @@ const cookiebanner = { cookies: { message: "Diese Website verwendet Cookies, um Ihr Browsing-Erlebnis zu verbessern. Die Daten werden nicht an Dritte weitergegeben.", accept: "Cookies akzeptieren", - decline: "Ablehnen" + decline: "Ablehnen", + necessary: "Notwendige Cookies", + necessaryDesc: "Für grundlegende Funktionen der Website", + analytics: "Analyse-Cookies", + analyticsDesc: "Für Analysen zur Verbesserung der Website", + learnMore: "Mehr erfahren" } }; diff --git a/src/i18n/locales/de/index.ts b/src/i18n/locales/de/index.ts index 4ad7327..2f9edb3 100644 --- a/src/i18n/locales/de/index.ts +++ b/src/i18n/locales/de/index.ts @@ -67,7 +67,12 @@ const translations = { cookies: { message: "Diese Website verwendet Cookies, um Ihr Browsing-Erlebnis zu verbessern. Die Daten werden nicht an Dritte weitergegeben.", accept: "Cookies akzeptieren", - decline: "Ablehnen" + decline: "Ablehnen", + necessary: "Notwendige Cookies", + necessaryDesc: "Für grundlegende Funktionen der Website", + analytics: "Analyse-Cookies", + analyticsDesc: "Für Analysen zur Verbesserung der Website", + learnMore: "Mehr erfahren" } }, meta, diff --git a/src/i18n/locales/en/cookiebanner.ts b/src/i18n/locales/en/cookiebanner.ts index 4622f7b..1810718 100644 --- a/src/i18n/locales/en/cookiebanner.ts +++ b/src/i18n/locales/en/cookiebanner.ts @@ -2,7 +2,12 @@ const cookiebanner = { cookies: { message: "This website uses cookies to enhance your browsing experience. The data will not be shared with third parties.", accept: "Accept Cookies", - decline: "Decline" + decline: "Decline", + necessary: "Necessary Cookies", + necessaryDesc: "For basic website functions", + analytics: "Analytics Cookies", + analyticsDesc: "For analyzing website usage", + learnMore: "Learn more" } }; diff --git a/src/i18n/locales/en/index.ts b/src/i18n/locales/en/index.ts index fb4bfeb..b71f495 100644 --- a/src/i18n/locales/en/index.ts +++ b/src/i18n/locales/en/index.ts @@ -67,7 +67,12 @@ const translations = { cookies: { message: "This website uses cookies to enhance your browsing experience and provide personalized content. The collected data will not be shared with third parties.", accept: "Accept Cookies", - decline: "Decline" + decline: "Decline", + necessary: "Necessary Cookies", + necessaryDesc: "For basic website functions", + analytics: "Analytics Cookies", + analyticsDesc: "For analyzing website usage", + learnMore: "Learn more" } }, meta, diff --git a/src/i18n/locales/sr/cookiebanner.ts b/src/i18n/locales/sr/cookiebanner.ts index d0c7215..f2b93c9 100644 --- a/src/i18n/locales/sr/cookiebanner.ts +++ b/src/i18n/locales/sr/cookiebanner.ts @@ -2,7 +2,12 @@ const cookiebanner = { cookies: { message: "Ovaj sajt koristi kolačiće za bolje iskustvo pretraživanja. Podaci neće biti deljeni sa trećim licima.", accept: "Prihvati kolačiće", - decline: "Odbij" + decline: "Odbij", + necessary: "Neophodni kolačići", + necessaryDesc: "Za osnovne funkcije sajta", + analytics: "Analitički kolačići", + analyticsDesc: "Za analizu korišćenja sajta", + learnMore: "Saznajte više" } }; diff --git a/src/i18n/locales/sr/index.ts b/src/i18n/locales/sr/index.ts index f8d69e5..58ed1f8 100644 --- a/src/i18n/locales/sr/index.ts +++ b/src/i18n/locales/sr/index.ts @@ -67,7 +67,12 @@ const translations = { cookies: { message: "Ovaj sajt koristi kolačiće kako bi poboljšao vaše iskustvo pretraživanja i pružio personalizovan sadržaj. Prikupljeni podaci neće biti deljeni sa trećim licima.", accept: "Prihvati kolačiće", - decline: "Odbij" + decline: "Odbij", + necessary: "Neophodni kolačići", + necessaryDesc: "Za osnovne funkcije sajta", + analytics: "Analitički kolačići", + analyticsDesc: "Za analizu korišćenja sajta", + learnMore: "Saznajte više" } }, meta, diff --git a/src/main.tsx b/src/main.tsx index f2a1bdf..ea26fa8 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -6,6 +6,15 @@ import './index.css'; import './i18n'; import { register as registerServiceWorker } from './utils/serviceWorkerRegistration'; +// Typdefinition für Google Analytics +declare global { + interface Window { + dataLayer: unknown[]; + gtag: (command: string, ...args: unknown[]) => void; + initializeAnalytics: () => void; + } +} + const rootElement = document.getElementById('root'); if (!rootElement) { diff --git a/src/utils/analytics.ts b/src/utils/analytics.ts index 39cb76e..cbd3cc5 100644 --- a/src/utils/analytics.ts +++ b/src/utils/analytics.ts @@ -3,14 +3,35 @@ import ReactGA from 'react-ga4'; const TRACKING_ID = 'G-N0PZBL7X18'; export const initGA = () => { - ReactGA.initialize(TRACKING_ID); + if (localStorage.getItem('cookieConsent') !== 'true') { + return; // Keine Analytics-Initialisierung ohne Zustimmung + } + + ReactGA.initialize(TRACKING_ID, { + gaOptions: { + anonymizeIp: true, // DSGVO-konform + cookieFlags: 'SameSite=None;Secure' + } + }); }; export const logPageView = () => { - ReactGA.send({ hitType: "pageview", page: window.location.pathname }); + if (localStorage.getItem('cookieConsent') !== 'true') { + return; // Kein Tracking ohne Zustimmung + } + + ReactGA.send({ + hitType: "pageview", + page: window.location.pathname, + anonymizeIp: true + }); }; export const trackEvent = (category: string, action: string, label?: string) => { + if (localStorage.getItem('cookieConsent') !== 'true') { + return; // Kein Tracking ohne Zustimmung + } + ReactGA.event({ category, action, @@ -19,6 +40,10 @@ export const trackEvent = (category: string, action: string, label?: string) => }; export const trackConversion = (value?: number) => { + if (localStorage.getItem('cookieConsent') !== 'true') { + return; // Kein Tracking ohne Zustimmung + } + ReactGA.event({ category: 'Conversion', action: 'Complete', @@ -27,6 +52,10 @@ export const trackConversion = (value?: number) => { }; export const trackTiming = (category: string, variable: string, value: number) => { + if (localStorage.getItem('cookieConsent') !== 'true') { + return; // Kein Tracking ohne Zustimmung + } + ReactGA.event({ category, action: 'timing', @@ -43,6 +72,7 @@ declare global { // Make analytics initialization available globally for the cookie consent window.initializeAnalytics = () => { + localStorage.setItem('cookieConsent', 'true'); initGA(); logPageView(); }; \ No newline at end of file