11import { Link } from '@tanstack/react-router'
2- import { useEffect , useState } from 'react'
2+ import { useCallback , useEffect , useState } from 'react'
33
44declare global {
55 interface Window {
@@ -49,6 +49,56 @@ export default function CookieConsent() {
4949 ? JSON . parse ( localStorage . getItem ( 'cookie_consent' ) || '{}' )
5050 : { analytics : false , ads : false }
5151
52+ const blockGoogleScripts = ( ) => {
53+ document . querySelectorAll ( 'script' ) . forEach ( ( script ) => {
54+ if (
55+ script . src ?. includes ( 'googletagmanager.com' ) ||
56+ script . textContent ?. includes ( 'gtag(' )
57+ ) {
58+ script . remove ( )
59+ }
60+ } )
61+ document . cookie =
62+ '_ga=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.google.com'
63+ document . cookie =
64+ '_gid=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.google.com'
65+ }
66+
67+ const restoreGoogleScripts = ( ) => {
68+ if ( ! document . querySelector ( "script[src*='googletagmanager.com']" ) ) {
69+ const script = document . createElement ( 'script' )
70+ script . src = 'https://www.googletagmanager.com/gtag/js?id=GTM-5N57KQT4'
71+ script . async = true
72+ document . body . appendChild ( script )
73+ }
74+ }
75+
76+ const updateGTMConsent = ( settings : { analytics : boolean ; ads : boolean } ) => {
77+ window . dataLayer = window . dataLayer || [ ]
78+ window . dataLayer . push ( {
79+ event : 'cookie_consent' ,
80+ consent : {
81+ analytics_storage : settings . analytics ? 'granted' : 'denied' ,
82+ ad_storage : settings . ads ? 'granted' : 'denied' ,
83+ ad_personalization : settings . ads ? 'granted' : 'denied' ,
84+ } ,
85+ } )
86+
87+ if ( typeof window . gtag === 'function' ) {
88+ window . gtag ( 'consent' , 'update' , {
89+ analytics_storage : settings . analytics ? 'granted' : 'denied' ,
90+ ad_storage : settings . ads ? 'granted' : 'denied' ,
91+ ad_personalization : settings . ads ? 'granted' : 'denied' ,
92+ } )
93+ }
94+
95+ if ( settings . analytics || settings . ads ) {
96+ restoreGoogleScripts ( )
97+ } else {
98+ blockGoogleScripts ( )
99+ }
100+ }
101+
52102 useEffect ( ( ) => {
53103 const checkLocationAndSetConsent = async ( ) => {
54104 // Only check location if no consent has been set yet
@@ -86,32 +136,6 @@ export default function CookieConsent() {
86136 checkLocationAndSetConsent ( )
87137 } , [ ] )
88138
89- const updateGTMConsent = ( settings : { analytics : boolean ; ads : boolean } ) => {
90- window . dataLayer = window . dataLayer || [ ]
91- window . dataLayer . push ( {
92- event : 'cookie_consent' ,
93- consent : {
94- analytics_storage : settings . analytics ? 'granted' : 'denied' ,
95- ad_storage : settings . ads ? 'granted' : 'denied' ,
96- ad_personalization : settings . ads ? 'granted' : 'denied' ,
97- } ,
98- } )
99-
100- if ( typeof window . gtag === 'function' ) {
101- window . gtag ( 'consent' , 'update' , {
102- analytics_storage : settings . analytics ? 'granted' : 'denied' ,
103- ad_storage : settings . ads ? 'granted' : 'denied' ,
104- ad_personalization : settings . ads ? 'granted' : 'denied' ,
105- } )
106- }
107-
108- if ( settings . analytics || settings . ads ) {
109- restoreGoogleScripts ( )
110- } else {
111- blockGoogleScripts ( )
112- }
113- }
114-
115139 const acceptAllCookies = ( ) => {
116140 const consent = { analytics : true , ads : true }
117141 localStorage . setItem ( 'cookie_consent' , JSON . stringify ( consent ) )
@@ -129,30 +153,6 @@ export default function CookieConsent() {
129153 const openSettings = ( ) => setShowSettings ( true )
130154 const closeSettings = ( ) => setShowSettings ( false )
131155
132- const blockGoogleScripts = ( ) => {
133- document . querySelectorAll ( 'script' ) . forEach ( ( script ) => {
134- if (
135- script . src ?. includes ( 'googletagmanager.com' ) ||
136- script . textContent ?. includes ( 'gtag(' )
137- ) {
138- script . remove ( )
139- }
140- } )
141- document . cookie =
142- '_ga=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.google.com'
143- document . cookie =
144- '_gid=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.google.com'
145- }
146-
147- const restoreGoogleScripts = ( ) => {
148- if ( ! document . querySelector ( "script[src*='googletagmanager.com']" ) ) {
149- const script = document . createElement ( 'script' )
150- script . src = 'https://www.googletagmanager.com/gtag/js?id=GTM-5N57KQT4'
151- script . async = true
152- document . body . appendChild ( script )
153- }
154- }
155-
156156 return (
157157 < >
158158 { showBanner && (
@@ -201,9 +201,10 @@ export default function CookieConsent() {
201201 < div className = "bg-white dark:bg-gray-800 p-6 rounded-lg shadow-lg max-w-md w-full mx-4" >
202202 < h3 className = "text-lg font-bold mb-4" > Cookie Settings</ h3 >
203203 < div className = "space-y-4" >
204- < label className = "flex items-start gap-2" >
204+ < div className = "flex items-start gap-2" >
205205 < input
206206 type = "checkbox"
207+ id = "analytics-checkbox"
207208 defaultChecked = { consentSettings . analytics }
208209 onChange = { ( e ) => {
209210 const updated = {
@@ -218,16 +219,17 @@ export default function CookieConsent() {
218219 } }
219220 className = "mt-1"
220221 />
221- < div >
222- < div > Analytics</ div >
222+ < label htmlFor = "analytics-checkbox" className = "cursor-pointer" >
223+ < span className = "font-medium" > Analytics</ span >
223224 < p className = "text-sm text-gray-600 dark:text-gray-400" >
224225 Track site usage anonymously
225226 </ p >
226- </ div >
227- </ label >
228- < label className = "flex items-start gap-2" >
227+ </ label >
228+ </ div >
229+ < div className = "flex items-start gap-2" >
229230 < input
230231 type = "checkbox"
232+ id = "ads-checkbox"
231233 defaultChecked = { consentSettings . ads }
232234 onChange = { ( e ) => {
233235 const updated = {
@@ -244,13 +246,13 @@ export default function CookieConsent() {
244246 } }
245247 className = "mt-1"
246248 />
247- < div >
248- < div > Advertising</ div >
249+ < label htmlFor = "ads-checkbox" className = "cursor-pointer" >
250+ < span className = "font-medium" > Advertising</ span >
249251 < p className = "text-sm text-gray-600 dark:text-gray-400" >
250252 Show personalized ads
251253 </ p >
252- </ div >
253- </ label >
254+ </ label >
255+ </ div >
254256 < div className = "mt-6" >
255257 < button
256258 onClick = { closeSettings }
0 commit comments