@yatoday/astro-ui 0.18.2 → 0.18.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/components/Analytics/AnalyticsGTM.astro +3 -3
  2. package/components/Analytics/AnalyticsGTMBody.astro +16 -12
  3. package/components/Analytics/AnalyticsGoogle.astro +3 -1
  4. package/components/BreadcrumbsItem/BreadcrumbsItem.astro +8 -1
  5. package/components/Button/types.ts +2 -1
  6. package/components/CallToAction/CallToAction.astro +1 -1
  7. package/components/Card0/Card0.astro +20 -32
  8. package/components/Card1/Card1.astro +11 -19
  9. package/components/Card2/Card2.astro +10 -14
  10. package/components/Card3/Card3.astro +15 -20
  11. package/components/Card4/Card4.astro +6 -2
  12. package/components/Card5/Card5.astro +8 -1
  13. package/components/Card6/Card6.astro +76 -59
  14. package/components/Card7/Card7.astro +27 -18
  15. package/components/CookieConsent/CookieConsent.astro +323 -308
  16. package/components/CopyToClipboard/CopyToClipboard.astro +6 -14
  17. package/components/CopyToClipboard/copy.ts +1 -1
  18. package/components/DarkMode/__tests__/DarkMode.test.ts +8 -8
  19. package/components/Headline/Headline.astro +4 -1
  20. package/components/HeroSection/HeroSection.astro +13 -16
  21. package/components/Image/Image.astro +1 -7
  22. package/components/ImageGallery/ImageGallery.astro +85 -90
  23. package/components/ImageGalleryIkea/ImageGalleryIkea.astro +3 -2
  24. package/components/ImagePreload/ImagePreload.astro +22 -20
  25. package/components/ItemGrid1/ItemGrid1.astro +34 -24
  26. package/components/Metadata/Metadata.astro +1 -5
  27. package/components/PointMap/PointMap.astro +62 -48
  28. package/components/PointMap/types.ts +3 -3
  29. package/components/SEO/SEO.astro +34 -33
  30. package/components/WidgetBrands/WidgetBrands.astro +8 -1
  31. package/components/WidgetContent/WidgetContent.astro +22 -9
  32. package/components/WidgetContent/types.ts +1 -1
  33. package/components/WidgetFeaturesCard/WidgetFeaturesCard.astro +10 -2
  34. package/components/WidgetHeroSlider/WidgetHeroSlider.astro +6 -1
  35. package/components/WidgetNavbarFlyout/WidgetNavbarFlyout.astro +16 -7
  36. package/components/WidgetSwiperPhotoSlider/WidgetSwiperPhotoSlider.astro +18 -7
  37. package/components/WidgetTestimonials/WidgetTestimonials.astro +8 -1
  38. package/components/WidgetWrapper/WidgetWrapper.astro +11 -2
  39. package/index.d.ts +20 -20
  40. package/package.json +11 -9
  41. package/styles/styles.css +303 -160
  42. package/utils/i18n.ts +2 -2
  43. package/utils/images.ts +0 -1
  44. package/utils/slugify.ts +3 -0
  45. package/vendor-config/config.example.yaml +0 -1
  46. package/vendor-config/index.ts +1 -1
  47. package/vendor-config/utils/loadConfig.ts +15 -18
@@ -45,11 +45,7 @@ const positionClasses = {
45
45
  <!-- Cookie Consent Banner -->
46
46
  <div
47
47
  id="cookie-consent-banner"
48
- class={cn(
49
- 'fixed z-[9999] hidden',
50
- positionClasses[position],
51
- containerClass
52
- )}
48
+ class={cn('fixed z-[9999] hidden', positionClasses[position], containerClass)}
53
49
  data-cookie-name={cookieName}
54
50
  data-cookie-expire-days={cookieExpireDays}
55
51
  data-consent-version={consentVersion}
@@ -71,19 +67,9 @@ const positionClasses = {
71
67
  >
72
68
  <div class="container mx-auto px-4 py-6">
73
69
  <div class="flex flex-col gap-4">
74
- {title && (
75
- <div
76
- class={cn('text-lg font-semibold text-foreground', titleClass)}
77
- set:html={title}
78
- />
79
- )}
80
-
81
- {description && (
82
- <p
83
- class={cn('text-sm text-muted-foreground', descriptionClass)}
84
- set:html={description}
85
- />
86
- )}
70
+ {title && <div class={cn('text-lg font-semibold text-foreground', titleClass)} set:html={title} />}
71
+
72
+ {description && <p class={cn('text-sm text-muted-foreground', descriptionClass)} set:html={description} />}
87
73
 
88
74
  <div class={cn('flex flex-wrap gap-3', actionsClass)}>
89
75
  <button
@@ -127,7 +113,16 @@ const positionClasses = {
127
113
  aria-label="Cookie settings"
128
114
  title="Cookie settings"
129
115
  >
130
- <svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 mx-auto" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
116
+ <svg
117
+ xmlns="http://www.w3.org/2000/svg"
118
+ class="w-6 h-6 mx-auto"
119
+ viewBox="0 0 24 24"
120
+ fill="none"
121
+ stroke="currentColor"
122
+ stroke-width="2"
123
+ stroke-linecap="round"
124
+ stroke-linejoin="round"
125
+ >
131
126
  <path d="M12 2a10 10 0 1 0 10 10 4 4 0 0 1-5-5 4 4 0 0 1-5-5"></path>
132
127
  <path d="M8.5 8.5v.01"></path>
133
128
  <path d="M16 15.5v.01"></path>
@@ -152,7 +147,12 @@ const positionClasses = {
152
147
  <!-- Consent ID -->
153
148
  <div class="text-sm">
154
149
  <span class="text-muted-foreground" id="cookie-info-id-label">{consentIdLabel}</span>
155
- <div class="font-mono text-xs text-foreground mt-1 break-all bg-muted rounded px-2 py-1" id="cookie-info-id-value">—</div>
150
+ <div
151
+ class="font-mono text-xs text-foreground mt-1 break-all bg-muted rounded px-2 py-1"
152
+ id="cookie-info-id-value"
153
+ >
154
+
155
+ </div>
156
156
  </div>
157
157
 
158
158
  <!-- Actions -->
@@ -179,351 +179,366 @@ const positionClasses = {
179
179
  <script is:inline>
180
180
  // Initialize dataLayer and gtag
181
181
  window.dataLayer = window.dataLayer || [];
182
- function gtag(){dataLayer.push(arguments);}
182
+ function gtag() {
183
+ dataLayer.push(arguments);
184
+ }
183
185
 
184
186
  // Set default consent state to denied (GDPR requirement)
185
187
  // This MUST run before Google Analytics loads
186
188
  gtag('consent', 'default', {
187
- 'analytics_storage': 'denied',
188
- 'ad_storage': 'denied',
189
- 'ad_user_data': 'denied',
190
- 'ad_personalization': 'denied',
191
- 'wait_for_update': 500 // Wait 500ms for consent update
189
+ analytics_storage: 'denied',
190
+ ad_storage: 'denied',
191
+ ad_user_data: 'denied',
192
+ ad_personalization: 'denied',
193
+ wait_for_update: 500, // Wait 500ms for consent update
192
194
  });
193
195
  </script>
194
196
 
195
197
  <script is:inline>
196
- (function() {
197
- const banner = document.getElementById('cookie-consent-banner');
198
- const fab = document.getElementById('cookie-consent-fab');
199
- const infoDialog = document.getElementById('cookie-consent-info-dialog');
200
- if (!banner) return;
201
-
202
- // Configuration from data attributes
203
- const config = {
204
- cookieName: banner.dataset.cookieName || 'cookie_consent_id',
205
- cookieExpireDays: parseInt(banner.dataset.cookieExpireDays || '365', 10),
206
- consentVersion: banner.dataset.consentVersion || '1.0',
207
- apiEndpoint: banner.dataset.apiEndpoint || '',
208
- organisationSuid: banner.dataset.organisationSuid || '',
209
- gaId: banner.dataset.gaId || ''
210
- };
211
-
212
- // Generate UUID v4
213
- function generateUUID() {
214
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
215
- const r = Math.random() * 16 | 0;
216
- const v = c === 'x' ? r : (r & 0x3 | 0x8);
217
- return v.toString(16);
218
- });
219
- }
198
+ (function () {
199
+ const banner = document.getElementById('cookie-consent-banner');
200
+ const fab = document.getElementById('cookie-consent-fab');
201
+ const infoDialog = document.getElementById('cookie-consent-info-dialog');
202
+ if (!banner) return;
203
+
204
+ // Configuration from data attributes
205
+ const config = {
206
+ cookieName: banner.dataset.cookieName || 'cookie_consent_id',
207
+ cookieExpireDays: parseInt(banner.dataset.cookieExpireDays || '365', 10),
208
+ consentVersion: banner.dataset.consentVersion || '1.0',
209
+ apiEndpoint: banner.dataset.apiEndpoint || '',
210
+ organisationSuid: banner.dataset.organisationSuid || '',
211
+ gaId: banner.dataset.gaId || '',
212
+ };
220
213
 
221
- // Get or create consent ID
222
- function getConsentId() {
223
- const value = document.cookie
224
- .split('; ')
225
- .find(row => row.startsWith(config.cookieName + '='));
226
- if (value) {
227
- return value.split('=')[1];
214
+ // Generate UUID v4
215
+ function generateUUID() {
216
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
217
+ const r = (Math.random() * 16) | 0;
218
+ const v = c === 'x' ? r : (r & 0x3) | 0x8;
219
+ return v.toString(16);
220
+ });
228
221
  }
229
- return null;
230
- }
231
222
 
232
- // Get consent status from localStorage (faster than API call)
233
- function getConsentStatus() {
234
- try {
235
- const data = localStorage.getItem('cookie_consent_status');
236
- return data ? JSON.parse(data) : null;
237
- } catch (e) {
223
+ // Get or create consent ID
224
+ function getConsentId() {
225
+ const value = document.cookie.split('; ').find((row) => row.startsWith(config.cookieName + '='));
226
+ if (value) {
227
+ return value.split('=')[1];
228
+ }
238
229
  return null;
239
230
  }
240
- }
241
-
242
- // Save consent status to localStorage
243
- function saveConsentStatus(status, categories) {
244
- try {
245
- localStorage.setItem('cookie_consent_status', JSON.stringify({
246
- status: status,
247
- categories: categories,
248
- timestamp: new Date().toISOString()
249
- }));
250
- } catch (e) {
251
- // Ignore localStorage errors
252
- }
253
- }
254
-
255
- // Set consent ID cookie
256
- function setConsentIdCookie(consentId) {
257
- const date = new Date();
258
- date.setTime(date.getTime() + (config.cookieExpireDays * 24 * 60 * 60 * 1000));
259
- document.cookie = config.cookieName + '=' + consentId + ';expires=' + date.toUTCString() + ';path=/;SameSite=Lax';
260
- }
261
-
262
- // Update Google Consent Mode
263
- function updateGoogleConsent(granted) {
264
- if (typeof gtag !== 'function') return;
265
-
266
- const consentState = granted ? 'granted' : 'denied';
267
-
268
- gtag('consent', 'update', {
269
- 'analytics_storage': consentState,
270
- 'ad_storage': consentState,
271
- 'ad_user_data': consentState,
272
- 'ad_personalization': consentState
273
- });
274
-
275
- gtag('event', `consent_${consentState}`);
276
231
 
277
- console.log('[CookieConsent] Google Consent Mode updated:', consentState);
278
- }
279
-
280
- // Send consent to backend API
281
- async function sendConsentToBackend(consentId, status, categories) {
282
- if (!config.apiEndpoint) {
283
- console.log('[CookieConsent] No API endpoint configured, skipping backend call');
284
- return;
232
+ // Get consent status from localStorage (faster than API call)
233
+ function getConsentStatus() {
234
+ try {
235
+ const data = localStorage.getItem('cookie_consent_status');
236
+ return data ? JSON.parse(data) : null;
237
+ } catch (e) {
238
+ return null;
239
+ }
285
240
  }
286
241
 
287
- const payload = {
288
- consent_id: consentId,
289
- organisation_suid: config.organisationSuid || undefined,
290
- status: status,
291
- consent_version: config.consentVersion,
292
- categories: categories,
293
- page_url: window.location.href,
294
- locale: document.documentElement.lang || 'en',
295
- user_agent: navigator.userAgent
296
- };
297
-
298
- try {
299
- const response = await fetch(config.apiEndpoint, {
300
- method: 'POST',
301
- headers: {
302
- 'Content-Type': 'application/json',
303
- },
304
- body: JSON.stringify(payload)
305
- });
306
-
307
- if (!response.ok) {
308
- throw new Error('API response: ' + response.status);
242
+ // Save consent status to localStorage
243
+ function saveConsentStatus(status, categories) {
244
+ try {
245
+ localStorage.setItem(
246
+ 'cookie_consent_status',
247
+ JSON.stringify({
248
+ status: status,
249
+ categories: categories,
250
+ timestamp: new Date().toISOString(),
251
+ })
252
+ );
253
+ } catch (e) {
254
+ // Ignore localStorage errors
309
255
  }
256
+ }
310
257
 
311
- console.log('[CookieConsent] Consent saved to backend');
312
- } catch (error) {
313
- console.error('[CookieConsent] Failed to save consent to backend:', error);
258
+ // Set consent ID cookie
259
+ function setConsentIdCookie(consentId) {
260
+ const date = new Date();
261
+ date.setTime(date.getTime() + config.cookieExpireDays * 24 * 60 * 60 * 1000);
262
+ document.cookie = config.cookieName + '=' + consentId + ';expires=' + date.toUTCString() + ';path=/;SameSite=Lax';
314
263
  }
315
- }
316
264
 
317
- // Show/hide banner, FAB, and info dialog
318
- function showBanner() {
319
- banner.classList.remove('hidden');
320
- if (fab) fab.classList.add('hidden');
321
- if (infoDialog) infoDialog.classList.add('hidden');
322
- }
265
+ // Update Google Consent Mode
266
+ function updateGoogleConsent(granted) {
267
+ if (typeof gtag !== 'function') return;
323
268
 
324
- function hideBanner() {
325
- banner.classList.add('hidden');
326
- if (fab) fab.classList.remove('hidden');
327
- }
269
+ const consentState = granted ? 'granted' : 'denied';
328
270
 
329
- function showFab() {
330
- if (fab) fab.classList.remove('hidden');
331
- }
271
+ gtag('consent', 'update', {
272
+ analytics_storage: consentState,
273
+ ad_storage: consentState,
274
+ ad_user_data: consentState,
275
+ ad_personalization: consentState,
276
+ });
332
277
 
333
- function hideFab() {
334
- if (fab) fab.classList.add('hidden');
335
- }
278
+ gtag('event', `consent_${consentState}`);
336
279
 
337
- function showInfoDialog() {
338
- if (!infoDialog) return;
280
+ console.log('[CookieConsent] Google Consent Mode updated:', consentState);
281
+ }
339
282
 
340
- // Populate dialog with current consent info
341
- const consentId = getConsentId();
342
- const savedConsent = getConsentStatus();
283
+ // Send consent to backend API
284
+ async function sendConsentToBackend(consentId, status, categories) {
285
+ if (!config.apiEndpoint) {
286
+ console.log('[CookieConsent] No API endpoint configured, skipping backend call');
287
+ return;
288
+ }
343
289
 
344
- const dateValueEl = document.getElementById('cookie-info-date-value');
345
- const idValueEl = document.getElementById('cookie-info-id-value');
290
+ const payload = {
291
+ consent_id: consentId,
292
+ organisation_suid: config.organisationSuid || undefined,
293
+ status: status,
294
+ consent_version: config.consentVersion,
295
+ categories: categories,
296
+ page_url: window.location.href,
297
+ locale: document.documentElement.lang || 'en',
298
+ user_agent: navigator.userAgent,
299
+ };
346
300
 
347
- if (dateValueEl && savedConsent && savedConsent.timestamp) {
348
301
  try {
349
- const date = new Date(savedConsent.timestamp);
350
- dateValueEl.textContent = date.toLocaleDateString(document.documentElement.lang || 'en', {
351
- year: 'numeric',
352
- month: 'long',
353
- day: 'numeric',
354
- hour: '2-digit',
355
- minute: '2-digit'
302
+ const response = await fetch(config.apiEndpoint, {
303
+ method: 'POST',
304
+ headers: {
305
+ 'Content-Type': 'application/json',
306
+ },
307
+ body: JSON.stringify(payload),
356
308
  });
357
- } catch (e) {
358
- dateValueEl.textContent = savedConsent.timestamp;
309
+
310
+ if (!response.ok) {
311
+ throw new Error('API response: ' + response.status);
312
+ }
313
+
314
+ console.log('[CookieConsent] Consent saved to backend');
315
+ } catch (error) {
316
+ console.error('[CookieConsent] Failed to save consent to backend:', error);
359
317
  }
360
318
  }
361
319
 
362
- if (idValueEl && consentId) {
363
- idValueEl.textContent = consentId;
320
+ // Show/hide banner, FAB, and info dialog
321
+ function showBanner() {
322
+ banner.classList.remove('hidden');
323
+ if (fab) fab.classList.add('hidden');
324
+ if (infoDialog) infoDialog.classList.add('hidden');
364
325
  }
365
326
 
366
- infoDialog.classList.remove('hidden');
367
- }
368
-
369
- function hideInfoDialog() {
370
- if (infoDialog) infoDialog.classList.add('hidden');
371
- }
372
-
373
- // Handle consent
374
- function handleConsent(accepted) {
375
- const status = accepted ? 'accepted' : 'denied';
376
-
377
- // Get or create consent ID
378
- let consentId = getConsentId();
379
- if (!consentId) {
380
- consentId = generateUUID();
381
- setConsentIdCookie(consentId);
327
+ function hideBanner() {
328
+ banner.classList.add('hidden');
329
+ if (fab) fab.classList.remove('hidden');
382
330
  }
383
331
 
384
- // Define categories based on acceptance
385
- const categories = {
386
- analytics_storage: accepted,
387
- ad_storage: accepted,
388
- ad_user_data: accepted,
389
- ad_personalization: accepted
390
- };
391
-
392
- // Save to localStorage for quick access
393
- saveConsentStatus(status, categories);
394
-
395
- // Update Google Consent Mode
396
- updateGoogleConsent(accepted);
397
-
398
- // Send to backend
399
- sendConsentToBackend(consentId, status, categories);
332
+ function showFab() {
333
+ if (fab) fab.classList.remove('hidden');
334
+ }
400
335
 
401
- // Hide banner, show FAB
402
- hideBanner();
336
+ function hideFab() {
337
+ if (fab) fab.classList.add('hidden');
338
+ }
403
339
 
404
- // Dispatch custom events
405
- const eventName = accepted ? 'cookie-consent-accepted' : 'cookie-consent-denied';
406
- window.dispatchEvent(new CustomEvent(eventName, {
407
- detail: { status, consentId, categories }
408
- }));
340
+ function showInfoDialog() {
341
+ if (!infoDialog) return;
342
+
343
+ // Populate dialog with current consent info
344
+ const consentId = getConsentId();
345
+ const savedConsent = getConsentStatus();
346
+
347
+ const dateValueEl = document.getElementById('cookie-info-date-value');
348
+ const idValueEl = document.getElementById('cookie-info-id-value');
349
+
350
+ if (dateValueEl && savedConsent && savedConsent.timestamp) {
351
+ try {
352
+ const date = new Date(savedConsent.timestamp);
353
+ dateValueEl.textContent = date.toLocaleDateString(document.documentElement.lang || 'en', {
354
+ year: 'numeric',
355
+ month: 'long',
356
+ day: 'numeric',
357
+ hour: '2-digit',
358
+ minute: '2-digit',
359
+ });
360
+ } catch (e) {
361
+ dateValueEl.textContent = savedConsent.timestamp;
362
+ }
363
+ }
409
364
 
410
- window.dispatchEvent(new CustomEvent('cookie-consent-changed', {
411
- detail: { status, accepted, consentId, categories }
412
- }));
365
+ if (idValueEl && consentId) {
366
+ idValueEl.textContent = consentId;
367
+ }
413
368
 
414
- // If accepted, enable analytics
415
- if (accepted) {
416
- window.dispatchEvent(new CustomEvent('cookie-consent-analytics-enabled', {
417
- detail: { consentId }
418
- }));
369
+ infoDialog.classList.remove('hidden');
419
370
  }
420
- }
421
371
 
422
- // Initialize on page load
423
- function init() {
424
- const consentId = getConsentId();
425
- const savedConsent = getConsentStatus();
372
+ function hideInfoDialog() {
373
+ if (infoDialog) infoDialog.classList.add('hidden');
374
+ }
426
375
 
427
- if (consentId && savedConsent) {
428
- // User has already made a choice - show FAB, hide banner
429
- console.log('[CookieConsent] Existing consent found:', savedConsent.status);
430
- showFab();
376
+ // Handle consent
377
+ function handleConsent(accepted) {
378
+ const status = accepted ? 'accepted' : 'denied';
431
379
 
432
- // Apply saved consent to Google
433
- updateGoogleConsent(savedConsent.status === 'accepted');
380
+ // Get or create consent ID
381
+ let consentId = getConsentId();
382
+ if (!consentId) {
383
+ consentId = generateUUID();
384
+ setConsentIdCookie(consentId);
385
+ }
434
386
 
435
- // Re-dispatch event for SPA navigation
436
- if (savedConsent.status === 'accepted') {
437
- window.dispatchEvent(new CustomEvent('cookie-consent-analytics-enabled', {
438
- detail: { consentId }
439
- }));
387
+ // Define categories based on acceptance
388
+ const categories = {
389
+ analytics_storage: accepted,
390
+ ad_storage: accepted,
391
+ ad_user_data: accepted,
392
+ ad_personalization: accepted,
393
+ };
394
+
395
+ // Save to localStorage for quick access
396
+ saveConsentStatus(status, categories);
397
+
398
+ // Update Google Consent Mode
399
+ updateGoogleConsent(accepted);
400
+
401
+ // Send to backend
402
+ sendConsentToBackend(consentId, status, categories);
403
+
404
+ // Hide banner, show FAB
405
+ hideBanner();
406
+
407
+ // Dispatch custom events
408
+ const eventName = accepted ? 'cookie-consent-accepted' : 'cookie-consent-denied';
409
+ window.dispatchEvent(
410
+ new CustomEvent(eventName, {
411
+ detail: { status, consentId, categories },
412
+ })
413
+ );
414
+
415
+ window.dispatchEvent(
416
+ new CustomEvent('cookie-consent-changed', {
417
+ detail: { status, accepted, consentId, categories },
418
+ })
419
+ );
420
+
421
+ // If accepted, enable analytics
422
+ if (accepted) {
423
+ window.dispatchEvent(
424
+ new CustomEvent('cookie-consent-analytics-enabled', {
425
+ detail: { consentId },
426
+ })
427
+ );
440
428
  }
441
- } else {
442
- // No consent yet - show banner, hide FAB
443
- showBanner();
444
429
  }
445
- }
446
-
447
- // Event listeners for buttons
448
- const denyBtn = document.getElementById('cookie-consent-deny');
449
- const allowBtn = document.getElementById('cookie-consent-allow');
450
430
 
451
- if (denyBtn) {
452
- denyBtn.addEventListener('click', function() {
453
- handleConsent(false);
454
- });
455
- }
431
+ // Initialize on page load
432
+ function init() {
433
+ const consentId = getConsentId();
434
+ const savedConsent = getConsentStatus();
435
+
436
+ if (consentId && savedConsent) {
437
+ // User has already made a choice - show FAB, hide banner
438
+ console.log('[CookieConsent] Existing consent found:', savedConsent.status);
439
+ showFab();
440
+
441
+ // Apply saved consent to Google
442
+ updateGoogleConsent(savedConsent.status === 'accepted');
443
+
444
+ // Re-dispatch event for SPA navigation
445
+ if (savedConsent.status === 'accepted') {
446
+ window.dispatchEvent(
447
+ new CustomEvent('cookie-consent-analytics-enabled', {
448
+ detail: { consentId },
449
+ })
450
+ );
451
+ }
452
+ } else {
453
+ // No consent yet - show banner, hide FAB
454
+ showBanner();
455
+ }
456
+ }
456
457
 
457
- if (allowBtn) {
458
- allowBtn.addEventListener('click', function() {
459
- handleConsent(true);
460
- });
461
- }
458
+ // Event listeners for buttons
459
+ const denyBtn = document.getElementById('cookie-consent-deny');
460
+ const allowBtn = document.getElementById('cookie-consent-allow');
462
461
 
463
- // FAB click - show info dialog (not banner directly)
464
- if (fab) {
465
- fab.addEventListener('click', function() {
466
- showInfoDialog();
467
- });
468
- }
462
+ if (denyBtn) {
463
+ denyBtn.addEventListener('click', function () {
464
+ handleConsent(false);
465
+ });
466
+ }
469
467
 
470
- // Info dialog buttons
471
- const infoChangeBtn = document.getElementById('cookie-info-change-btn');
472
- const infoCloseBtn = document.getElementById('cookie-info-close-btn');
468
+ if (allowBtn) {
469
+ allowBtn.addEventListener('click', function () {
470
+ handleConsent(true);
471
+ });
472
+ }
473
473
 
474
- if (infoChangeBtn) {
475
- infoChangeBtn.addEventListener('click', function() {
476
- hideInfoDialog();
477
- showBanner();
478
- });
479
- }
474
+ // FAB click - show info dialog (not banner directly)
475
+ if (fab) {
476
+ fab.addEventListener('click', function () {
477
+ showInfoDialog();
478
+ });
479
+ }
480
480
 
481
- if (infoCloseBtn) {
482
- infoCloseBtn.addEventListener('click', function() {
483
- hideInfoDialog();
484
- });
485
- }
481
+ // Info dialog buttons
482
+ const infoChangeBtn = document.getElementById('cookie-info-change-btn');
483
+ const infoCloseBtn = document.getElementById('cookie-info-close-btn');
486
484
 
487
- // Close info dialog when clicking outside
488
- document.addEventListener('click', function(e) {
489
- if (infoDialog && !infoDialog.classList.contains('hidden')) {
490
- const target = e.target;
491
- if (!infoDialog.contains(target) && target !== fab && !fab.contains(target)) {
485
+ if (infoChangeBtn) {
486
+ infoChangeBtn.addEventListener('click', function () {
492
487
  hideInfoDialog();
493
- }
488
+ showBanner();
489
+ });
494
490
  }
495
- });
496
491
 
497
- // Expose API for external use
498
- window.CookieConsent = {
499
- getConsentId: getConsentId,
500
- getStatus: getConsentStatus,
501
- show: showBanner,
502
- hide: hideBanner,
503
- showInfo: showInfoDialog,
504
- hideInfo: hideInfoDialog,
505
- accept: function() { handleConsent(true); },
506
- deny: function() { handleConsent(false); },
507
- reset: function() {
508
- // Clear cookie
509
- document.cookie = config.cookieName + '=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/';
510
- // Clear localStorage
511
- localStorage.removeItem('cookie_consent_status');
512
- // Reset Google consent to denied
513
- updateGoogleConsent(false);
514
- // Hide info dialog if open
515
- hideInfoDialog();
516
- // Show banner, hide FAB
517
- showBanner();
518
- console.log('[CookieConsent] Consent reset');
519
- },
520
- // For footer "Manage cookies" button - now shows info dialog first
521
- manage: function() {
522
- showInfoDialog();
492
+ if (infoCloseBtn) {
493
+ infoCloseBtn.addEventListener('click', function () {
494
+ hideInfoDialog();
495
+ });
523
496
  }
524
- };
525
497
 
526
- // Initialize
527
- init();
528
- })();
498
+ // Close info dialog when clicking outside
499
+ document.addEventListener('click', function (e) {
500
+ if (infoDialog && !infoDialog.classList.contains('hidden')) {
501
+ const target = e.target;
502
+ if (!infoDialog.contains(target) && target !== fab && !fab.contains(target)) {
503
+ hideInfoDialog();
504
+ }
505
+ }
506
+ });
507
+
508
+ // Expose API for external use
509
+ window.CookieConsent = {
510
+ getConsentId: getConsentId,
511
+ getStatus: getConsentStatus,
512
+ show: showBanner,
513
+ hide: hideBanner,
514
+ showInfo: showInfoDialog,
515
+ hideInfo: hideInfoDialog,
516
+ accept: function () {
517
+ handleConsent(true);
518
+ },
519
+ deny: function () {
520
+ handleConsent(false);
521
+ },
522
+ reset: function () {
523
+ // Clear cookie
524
+ document.cookie = config.cookieName + '=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/';
525
+ // Clear localStorage
526
+ localStorage.removeItem('cookie_consent_status');
527
+ // Reset Google consent to denied
528
+ updateGoogleConsent(false);
529
+ // Hide info dialog if open
530
+ hideInfoDialog();
531
+ // Show banner, hide FAB
532
+ showBanner();
533
+ console.log('[CookieConsent] Consent reset');
534
+ },
535
+ // For footer "Manage cookies" button - now shows info dialog first
536
+ manage: function () {
537
+ showInfoDialog();
538
+ },
539
+ };
540
+
541
+ // Initialize
542
+ init();
543
+ })();
529
544
  </script>