diff --git a/marketing-website/components/layout/ConsentBanner.tsx b/marketing-website/components/layout/ConsentBanner.tsx index 1e7fa10..9274537 100644 --- a/marketing-website/components/layout/ConsentBanner.tsx +++ b/marketing-website/components/layout/ConsentBanner.tsx @@ -70,8 +70,25 @@ function getSavedConsent(): ConsentState | null { return null } -async function sendConsent(consent: ConsentState) { +function detectDevice(): { device_type: string; browser: string; os: string } { + const ua = navigator.userAgent + const device_type = /Mobi|Android/i.test(ua) + ? (/Tablet|iPad/i.test(ua) ? 'tablet' : 'mobile') + : 'desktop' + const browserMatch = ua.match(/(Chrome|Safari|Firefox|Edge|Opera|OPR)\/[\d.]+/) + const browser = browserMatch + ? browserMatch[0].replace('OPR', 'Opera') + : 'Unknown' + const osMatch = ua.match(/(Windows NT [\d.]+|Mac OS X [\d_.]+|Linux|Android [\d.]+|iOS [\d._]+)/) + const os = osMatch ? osMatch[0].replace(/_/g, '.') : 'Unknown' + return { device_type, browser, os } +} + +type ConsentMethod = 'accept_all' | 'reject_all' | 'custom_selection' + +async function sendConsent(consent: ConsentState, method: ConsentMethod) { try { + const { device_type, browser, os } = detectDevice() await fetch('/api/consent', { method: 'POST', headers: { 'Content-Type': 'application/json' }, @@ -85,6 +102,14 @@ async function sendConsent(consent: ConsentState) { ], vendors: [], user_agent: navigator.userAgent, + consent_method: method, + page_url: window.location.href, + referrer: document.referrer || null, + device_type, + browser, + os, + screen_resolution: `${screen.width}x${screen.height}`, + consent_scope: 'domain', }), }) } catch { @@ -106,16 +131,16 @@ export default function ConsentBanner() { } }, []) - const save = useCallback((state: ConsentState) => { + const save = useCallback((state: ConsentState, method: ConsentMethod) => { localStorage.setItem(COOKIE_NAME, JSON.stringify(state)) - sendConsent(state) + sendConsent(state, method) setVisible(false) window.dispatchEvent(new CustomEvent('consent-change', { detail: state })) }, []) - const acceptAll = () => save({ essential: true, functional: true, analytics: true }) - const rejectAll = () => save({ essential: true, functional: false, analytics: false }) - const saveSelection = () => save(consent) + const acceptAll = () => save({ essential: true, functional: true, analytics: true }, 'accept_all') + const rejectAll = () => save({ essential: true, functional: false, analytics: false }, 'reject_all') + const saveSelection = () => save(consent, 'custom_selection') if (!visible) return null