feat(03-cookie-consent): integrate CookieNoticePro with Google Consent Mode v2
Phase 3 complete: - Copy CookieNoticePro library to libraries/CookieNoticePro/ - Fix bug: analytics_storage sent 'granted' instead of 'denied' on rejection - Add Consent Mode v2 default-denied init before GTM snippet in layout-logged.php - Fix plugin init: cookieNoticePro.init() per library docs - Fix duplicate button label (CSS display:none for acceptBtnSettingsLabel) - Add Bootstrap 5 compatibility reset for banner buttons - Set regulamin link to https://bilety.brzezovka.pl/tickets/regulamin/ v0.2 Analytics & Privacy milestone complete. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -13,7 +13,7 @@ Uzytkownicy moga szybko i bezpiecznie kupic bilety online oraz otrzymac natychmi
|
|||||||
- [x] Poprawne rejestrowanie zamowien i danych transakcyjnych
|
- [x] Poprawne rejestrowanie zamowien i danych transakcyjnych
|
||||||
- [x] Data layer purchase po finalizacji zakupu (wdrozone w Phase 1)
|
- [x] Data layer purchase po finalizacji zakupu (wdrozone w Phase 1)
|
||||||
- [x] Event purchase capturuje 100% zamowien — fires przy skladaniu, nie przy powrocie z P24 (Phase 2)
|
- [x] Event purchase capturuje 100% zamowien — fires przy skladaniu, nie przy powrocie z P24 (Phase 2)
|
||||||
- [ ] Zgodnosc z RODO — baner zgody na cookies z Google Consent Mode v2 (Phase 3)
|
- [x] Zgodnosc z RODO — baner zgody na cookies z Google Consent Mode v2 (Phase 3)
|
||||||
|
|
||||||
### Should Have
|
### Should Have
|
||||||
- [x] Spojny tracking analityczny dla zdarzen ecommerce
|
- [x] Spojny tracking analityczny dla zdarzen ecommerce
|
||||||
@@ -34,13 +34,15 @@ Uzytkownicy moga szybko i bezpiecznie kupic bilety online oraz otrzymac natychmi
|
|||||||
| Event purchase na order-confirm (post-payment) | Phase 1 | Eliminuje falszywe konwersje |
|
| Event purchase na order-confirm (post-payment) | Phase 1 | Eliminuje falszywe konwersje |
|
||||||
| ZMIANA: Event purchase na przelewy24 (pre-payment, post-order) | Phase 2 | Capturuje 100% zamowien, beacon transport |
|
| ZMIANA: Event purchase na przelewy24 (pre-payment, post-order) | Phase 2 | Capturuje 100% zamowien, beacon transport |
|
||||||
| Payload ecommerce budowany w backendzie | Phase 1 | Bezpieczenstwo, brak XSS |
|
| Payload ecommerce budowany w backendzie | Phase 1 | Bezpieczenstwo, brak XSS |
|
||||||
|
| cookieNoticePro.init() zamiast $.fn.cookieNoticePro() | Phase 3 | Zgodnie z dokumentacja biblioteki |
|
||||||
|
| Consent Mode v2 default-denied przed GTM snippetem | Phase 3 | Wymog Google od marca 2024 |
|
||||||
|
|
||||||
## Success Criteria
|
## Success Criteria
|
||||||
- Event purchase trafia do data layer po zlozeniu zamowienia (osiagniete — Phase 2)
|
- Event purchase trafia do data layer po zlozeniu zamowienia (osiagniete — Phase 2)
|
||||||
- Payload zawiera wszystkie dostepne dane transakcyjne i produktowe
|
- Payload zawiera wszystkie dostepne dane transakcyjne i produktowe
|
||||||
- Integracja nie wplywa negatywnie na istniejacy checkout
|
- Integracja nie wplywa negatywnie na istniejacy checkout
|
||||||
- Baner cookies zgodny z RODO + Google Consent Mode v2 (cel Phase 3)
|
- Baner cookies zgodny z RODO + Google Consent Mode v2 (osiagniete — Phase 3)
|
||||||
|
|
||||||
---
|
---
|
||||||
*Created: 2026-04-19 20:20*
|
*Created: 2026-04-19 20:20*
|
||||||
*Last updated: 2026-04-26 after Phase 2*
|
*Last updated: 2026-04-26 after Phase 3 (v0.2 complete)*
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ W najblizszej iteracji skupiamy sie na uzupelnieniu warstwy analitycznej po zaku
|
|||||||
|
|
||||||
## Current Milestone
|
## Current Milestone
|
||||||
**v0.2 Analytics & Privacy** (v0.2.0)
|
**v0.2 Analytics & Privacy** (v0.2.0)
|
||||||
Status: In progress
|
Status: Complete (2026-04-26)
|
||||||
Phases: 1 of 2 complete
|
Phases: 3 of 3 complete
|
||||||
|
|
||||||
## Previous Milestones
|
## Previous Milestones
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ Phases: 1 of 1 complete
|
|||||||
|-------|------|-------|--------|-----------|
|
|-------|------|-------|--------|-----------|
|
||||||
| 1 | Purchase Data Layer | 1 | Complete | 2026-04-19 |
|
| 1 | Purchase Data Layer | 1 | Complete | 2026-04-19 |
|
||||||
| 2 | Purchase Event Pre-Payment | 1 | Complete | 2026-04-26 |
|
| 2 | Purchase Event Pre-Payment | 1 | Complete | 2026-04-26 |
|
||||||
| 3 | Cookie Consent Banner | 1 | Not started | — |
|
| 3 | Cookie Consent Banner | 1 | Complete | 2026-04-26 |
|
||||||
|
|
||||||
## Phase Details
|
## Phase Details
|
||||||
|
|
||||||
|
|||||||
@@ -2,29 +2,29 @@
|
|||||||
|
|
||||||
## Project Reference
|
## Project Reference
|
||||||
|
|
||||||
See: .paul/PROJECT.md (updated 2026-04-19)
|
See: .paul/PROJECT.md (updated 2026-04-26)
|
||||||
|
|
||||||
**Core value:** Uzytkownicy moga szybko i bezpiecznie kupic bilety online oraz otrzymac natychmiastowe potwierdzenie zakupu.
|
**Core value:** Uzytkownicy moga szybko i bezpiecznie kupic bilety online oraz otrzymac natychmiastowe potwierdzenie zakupu.
|
||||||
**Current focus:** v0.2 Analytics & Privacy — Phase 2 (Purchase Event Pre-Payment) planning
|
**Current focus:** v0.2 Analytics & Privacy — COMPLETE
|
||||||
|
|
||||||
## Current Position
|
## Current Position
|
||||||
|
|
||||||
Milestone: v0.2 Analytics & Privacy
|
Milestone: v0.2 Analytics & Privacy — COMPLETE
|
||||||
Phase: 2 of 3 (Purchase Event Pre-Payment) — Planning
|
Phase: 3 of 3 (Cookie Consent Banner) — Complete
|
||||||
Plan: 02-01 executed
|
Plan: 03-01 complete
|
||||||
Status: APPLY complete, ready for UNIFY
|
Status: Milestone complete — ready for next milestone
|
||||||
Last activity: 2026-04-26 — Executed 02-01-PLAN.md (2 tasks, 3 files modified)
|
Last activity: 2026-04-26 — Phase 3 complete, v0.2 shipped
|
||||||
|
|
||||||
Progress:
|
Progress:
|
||||||
- Milestone: [░░░░░░░░░░] 0%
|
- Milestone: [##########] 100%
|
||||||
- Phase 2: [░░░░░░░░░░] 0%
|
- Phase 3: [##########] 100%
|
||||||
|
|
||||||
## Loop Position
|
## Loop Position
|
||||||
|
|
||||||
Current loop state:
|
Current loop state:
|
||||||
```
|
```
|
||||||
PLAN --> APPLY --> UNIFY
|
PLAN ──▶ APPLY ──▶ UNIFY
|
||||||
✓ ✓ ○ [APPLY complete, awaiting UNIFY]
|
✓ ✓ ✓ [Loop complete — milestone complete]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Accumulated Context
|
## Accumulated Context
|
||||||
@@ -34,34 +34,39 @@ Date: 2026-04-26
|
|||||||
Documents: `.paul/codebase/` (8 files — stack, architecture, structure, conventions, testing, integrations, concerns, db_schema)
|
Documents: `.paul/codebase/` (8 files — stack, architecture, structure, conventions, testing, integrations, concerns, db_schema)
|
||||||
|
|
||||||
### GTM Status
|
### GTM Status
|
||||||
- GTM-TW9WCD9J już wdrożony w templates/site/layout-logged.php (i layout-unlogged.php)
|
- GTM-TW9WCD9J już wdrożony w templates/site/layout-logged.php
|
||||||
- layout-unlogged.php NIE jest renderowany — view/class.Site.php zawsze używa layout-logged.php
|
- layout-unlogged.php NIE jest renderowany — view/class.Site.php zawsze używa layout-logged.php
|
||||||
|
|
||||||
### Decisions
|
### Decisions
|
||||||
- 2026-04-19: Event `purchase` emitowany na `order-confirm`, nie na `przelewy24` (eliminuje falszywe konwersje).
|
- 2026-04-19: Event purchase emitowany na order-confirm, nie na przelewy24 (eliminuje falszywe konwersje).
|
||||||
- 2026-04-19: Payload ecommerce budowany w backendzie i serializowany bezpiecznie do widoku.
|
- 2026-04-19: Payload ecommerce budowany w backendzie i serializowany bezpiecznie do widoku.
|
||||||
- 2026-04-26: ZMIANA DECYZJI — event purchase przenoszony na `przelewy24` (post-order, pre-payment) aby capturować użytkowników którzy nie wracają po płatności.
|
- 2026-04-26: ZMIANA — event purchase przeniesiony na przelewy24 (post-order, pre-payment). Capturuje 100% zamowien.
|
||||||
|
- 2026-04-26: cookieNoticePro.init() zamiast $.fn.cookieNoticePro() — zgodnie z dokumentacja biblioteki.
|
||||||
|
- 2026-04-26: Consent Mode v2 default-denied inicjalizowany przed GTM snippetem (wymog Google od marca 2024).
|
||||||
|
|
||||||
### Cookie Consent Bug
|
### Cookie Consent (Phase 3 — COMPLETE)
|
||||||
- cookienoticepro.script.js ~linia 351: gdy analytics NIE zaakceptowane, kod wywołuje gtag('consent','update',{'analytics_storage':'granted'}) zamiast 'denied'
|
- Biblioteka: libraries/CookieNoticePro/ (skopiowana z pomysloweprezenty.pl)
|
||||||
|
- Bug naprawiony: linia ~351 — blok else teraz wysyla analytics_storage: 'denied'
|
||||||
|
- Dodatkowe poprawki: CSS initial hide dla acceptBtnSettingsLabel, Bootstrap 5 compat reset
|
||||||
|
- Consent Mode v2 init PRZED snippetem GTM w layout-logged.php
|
||||||
|
|
||||||
### Deferred Issues
|
### Deferred Issues
|
||||||
- Phase 3: Cookie Consent Banner (zaplanowane po Phase 2)
|
None.
|
||||||
|
|
||||||
### Blockers/Concerns
|
### Blockers/Concerns
|
||||||
None yet.
|
None.
|
||||||
|
|
||||||
### Git State
|
### Git State
|
||||||
Last commit: 9de0429
|
Last commit: 86e712b
|
||||||
Branch: main
|
Branch: main
|
||||||
Feature branches merged: none
|
Feature branches merged: none
|
||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-04-26
|
Last session: 2026-04-26
|
||||||
Stopped at: Plan 02-01 created
|
Stopped at: v0.2 milestone complete
|
||||||
Next action: Review and approve plan, then run /paul:apply .paul/phases/02-purchase-event-prepayment/02-01-PLAN.md
|
Next action: /paul:milestone — zdefiniuj v0.3 lub /paul:complete-milestone
|
||||||
Resume file: .paul/phases/02-purchase-event-prepayment/02-01-PLAN.md
|
Resume file: .paul/ROADMAP.md
|
||||||
|
|
||||||
---
|
---
|
||||||
*STATE.md - Updated after every significant action*
|
*STATE.md - Updated after every significant action*
|
||||||
|
|||||||
@@ -12,3 +12,18 @@
|
|||||||
- `autoload/controls/class.Tickets.php`
|
- `autoload/controls/class.Tickets.php`
|
||||||
- `templates/tickets/przelewy24.php`
|
- `templates/tickets/przelewy24.php`
|
||||||
- `templates/tickets/order-confirm.php`
|
- `templates/tickets/order-confirm.php`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
- [Phase 3, Plan 01] Wdrożono baner zgody na cookies (CookieNoticePro) z Google Consent Mode v2
|
||||||
|
- Skopiowano bibliotekę CookieNoticePro do libraries/CookieNoticePro/
|
||||||
|
- Naprawiono błąd biblioteki: analytics_storage wysyłało 'granted' zamiast 'denied' przy odmowie
|
||||||
|
- Dodano inicjalizację Consent Mode v2 (default: denied) przed snippetem GTM w layout-logged.php
|
||||||
|
- Naprawiono inicjalizację pluginu: cookieNoticePro.init()
|
||||||
|
- Naprawiono duplikat tekstu w przycisku (CSS display:none dla acceptBtnSettingsLabel)
|
||||||
|
- Zmieniono link regulaminu na https://bilety.brzezovka.pl/tickets/regulamin/
|
||||||
|
- Milestone v0.2 Analytics & Privacy — COMPLETE
|
||||||
|
|
||||||
|
- `libraries/CookieNoticePro/cookienoticepro.script.js`
|
||||||
|
- `libraries/CookieNoticePro/cookienoticepro.style.css`
|
||||||
|
- `templates/site/layout-logged.php`
|
||||||
|
|||||||
227
.paul/phases/03-cookie-consent/03-01-PLAN.md
Normal file
227
.paul/phases/03-cookie-consent/03-01-PLAN.md
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
---
|
||||||
|
phase: 03-cookie-consent
|
||||||
|
plan: 01
|
||||||
|
type: execute
|
||||||
|
wave: 1
|
||||||
|
depends_on: []
|
||||||
|
files_modified:
|
||||||
|
- libraries/CookieNoticePro/cookienoticepro.script.js
|
||||||
|
- libraries/CookieNoticePro/cookienoticepro.style.css
|
||||||
|
- templates/site/layout-logged.php
|
||||||
|
autonomous: false
|
||||||
|
delegation: off
|
||||||
|
---
|
||||||
|
|
||||||
|
<objective>
|
||||||
|
## Goal
|
||||||
|
Wdrożyć baner zgody na cookies (CookieNoticePro) z Google Consent Mode v2, naprawić błąd `analytics_storage: 'granted'` w bibliotece oraz dodać domyślną inicjalizację consent mode przed snippetem GTM.
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
Wymaganie RODO — serwis musi uzyskać zgodę użytkownika przed uruchomieniem trackerów analitycznych i marketingowych. Google Consent Mode v2 zapewnia zgodność z wymaganiami Google (od marca 2024) i zachowanie modelowanych danych konwersji nawet przy braku zgody.
|
||||||
|
|
||||||
|
## Output
|
||||||
|
- `libraries/CookieNoticePro/cookienoticepro.script.js` — zkopiony z pomysloweprezenty.pl i naprawiony (linia ~351: `'granted'` → `'denied'`)
|
||||||
|
- `libraries/CookieNoticePro/cookienoticepro.style.css` — zkopiony z pomysloweprezenty.pl
|
||||||
|
- `templates/site/layout-logged.php` — consent mode v2 default init przed GTM, załadowane CSS/JS banera, wywołanie `$.cookieNoticePro()`
|
||||||
|
</objective>
|
||||||
|
|
||||||
|
<context>
|
||||||
|
## Project Context
|
||||||
|
@.paul/PROJECT.md
|
||||||
|
@.paul/ROADMAP.md
|
||||||
|
@.paul/STATE.md
|
||||||
|
|
||||||
|
## Source Files
|
||||||
|
@templates/site/layout-logged.php
|
||||||
|
|
||||||
|
## Biblioteka źródłowa (pomysloweprezenty.pl)
|
||||||
|
Pliki do skopiowania:
|
||||||
|
- `c:\visual studio code\projekty\pomysloweprezenty.pl\libraries\CookieNoticePro\cookienoticepro.script.js`
|
||||||
|
- `c:\visual studio code\projekty\pomysloweprezenty.pl\libraries\CookieNoticePro\cookienoticepro.style.css`
|
||||||
|
</context>
|
||||||
|
|
||||||
|
<acceptance_criteria>
|
||||||
|
|
||||||
|
## AC-1: Consent Mode v2 default init przed GTM
|
||||||
|
```gherkin
|
||||||
|
Given layout-logged.php jest renderowany w przeglądarce
|
||||||
|
When strona się ładuje
|
||||||
|
Then w <head>, PRZED snippetem GTM, znajduje się blok gtag('consent','default',{...}) ustawiający wszystkie storage na 'denied'
|
||||||
|
```
|
||||||
|
|
||||||
|
## AC-2: Baner cookies wyświetla się przy pierwszej wizycie
|
||||||
|
```gherkin
|
||||||
|
Given użytkownik odwiedza serwis po raz pierwszy (brak cookie COOKIE_CONSENT)
|
||||||
|
When strona się załaduje
|
||||||
|
Then pojawia się baner CookieNoticePro z przyciskami akceptacji/odrzucenia/dostosowania
|
||||||
|
```
|
||||||
|
|
||||||
|
## AC-3: Naprawa błędu analytics_storage denied
|
||||||
|
```gherkin
|
||||||
|
Given użytkownik odwiedza serwis i wybiera "Odrzuć" lub wyłącza analytics w ustawieniach
|
||||||
|
When biblioteka wywołuje googleConsentModeHandler()
|
||||||
|
Then gtag('consent','update') wysyła {'analytics_storage': 'denied'} (nie 'granted')
|
||||||
|
```
|
||||||
|
|
||||||
|
## AC-4: Akceptacja cookies uruchamia gtag update z 'granted'
|
||||||
|
```gherkin
|
||||||
|
Given użytkownik wybrał akceptację wszystkich cookies
|
||||||
|
When biblioteka wywołuje googleConsentModeHandler()
|
||||||
|
Then gtag('consent','update') wysyła {'analytics_storage': 'granted'} i {'ad_storage': 'granted', ...}
|
||||||
|
```
|
||||||
|
|
||||||
|
## AC-5: Pliki biblioteki obecne w projekcie
|
||||||
|
```gherkin
|
||||||
|
Given wdrożenie jest kompletne
|
||||||
|
When sprawdzamy strukturę projektu
|
||||||
|
Then istnieją pliki libraries/CookieNoticePro/cookienoticepro.script.js i cookienoticepro.style.css
|
||||||
|
```
|
||||||
|
|
||||||
|
</acceptance_criteria>
|
||||||
|
|
||||||
|
<tasks>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 1: Skopiuj pliki CookieNoticePro i napraw błąd analytics_storage</name>
|
||||||
|
<files>libraries/CookieNoticePro/cookienoticepro.script.js, libraries/CookieNoticePro/cookienoticepro.style.css</files>
|
||||||
|
<action>
|
||||||
|
1. Skopiuj oba pliki z `c:\visual studio code\projekty\pomysloweprezenty.pl\libraries\CookieNoticePro\` do `libraries/CookieNoticePro\` w tym projekcie.
|
||||||
|
|
||||||
|
2. W `cookienoticepro.script.js`, napraw błąd w funkcji `googleConsentModeHandler` (~linia 351):
|
||||||
|
- Znajdź blok `else` po `if(preferences.indexOf("analytics") > -1)` — ten blok obsługuje sytuację gdy analytics NIE jest zaakceptowane
|
||||||
|
- W tym bloku `else`, zmień:
|
||||||
|
```js
|
||||||
|
gtag('consent', 'update', {
|
||||||
|
'analytics_storage': 'granted'
|
||||||
|
});
|
||||||
|
```
|
||||||
|
na:
|
||||||
|
```js
|
||||||
|
gtag('consent', 'update', {
|
||||||
|
'analytics_storage': 'denied'
|
||||||
|
});
|
||||||
|
```
|
||||||
|
- Blok `if` (analytics zaakceptowane, ~linia 341-343) musi pozostać z `'granted'` — nie ruszaj go.
|
||||||
|
|
||||||
|
Unikaj: modyfikowania innych fragmentów pliku; zmiany konfiguracji `config {}` (kolory, tekst) — to ustawi się w layout.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
Grep w skopiowanym pliku:
|
||||||
|
- Potwierdź że istnieje dokładnie JEDNO wywołanie `'analytics_storage': 'denied'` w bloku else
|
||||||
|
- Potwierdź że `'analytics_storage': 'granted'` nadal istnieje w bloku if (analytics accepted)
|
||||||
|
Komenda: grep -n "analytics_storage" libraries/CookieNoticePro/cookienoticepro.script.js
|
||||||
|
</verify>
|
||||||
|
<done>AC-3, AC-4, AC-5 satisfied: plik skopiowany, błąd naprawiony, 'denied' w else, 'granted' w if</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="auto">
|
||||||
|
<name>Task 2: Dodaj Consent Mode v2 default init i integruj baner w layout-logged.php</name>
|
||||||
|
<files>templates/site/layout-logged.php</files>
|
||||||
|
<action>
|
||||||
|
W `templates/site/layout-logged.php`:
|
||||||
|
|
||||||
|
1. **Consent Mode v2 default — PRZED snippetem GTM** (wstaw przed komentarzem `<!-- Google Tag Manager -->`):
|
||||||
|
```html
|
||||||
|
<!-- Google Consent Mode v2 - default -->
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag(){dataLayer.push(arguments);}
|
||||||
|
gtag('consent', 'default', {
|
||||||
|
'analytics_storage': 'denied',
|
||||||
|
'ad_storage': 'denied',
|
||||||
|
'ad_user_data': 'denied',
|
||||||
|
'ad_personalization': 'denied',
|
||||||
|
'wait_for_update': 500
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<!-- End Google Consent Mode v2 - default -->
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **CSS banera** — dodaj do sekcji `<head>` po istniejących linkach CSS (przed zamknięciem `</head>`):
|
||||||
|
```html
|
||||||
|
<link rel="stylesheet" type="text/css" href="/libraries/CookieNoticePro/cookienoticepro.style.css">
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **JS banera + inicjalizacja** — dodaj przed zamknięciem `</body>`, po istniejącym bloku `<script>` z hamburger menu:
|
||||||
|
```html
|
||||||
|
<script type="text/javascript" src="/libraries/CookieNoticePro/cookienoticepro.script.js"></script>
|
||||||
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
$.cookieNoticePro();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
Kolejność w `<head>` po zmianie (od góry):
|
||||||
|
1. Meta tagi
|
||||||
|
2. Linki CSS (istniejące + nowy CSS banera)
|
||||||
|
3. jQuery i inne JS
|
||||||
|
4. **Consent Mode v2 default** ← NOWE (musi być przed GTM)
|
||||||
|
5. **GTM snippet** ← istniejący (bez zmian)
|
||||||
|
|
||||||
|
Unikaj: modyfikowania snippetu GTM; zmiany kolejności istniejących skryptów; dodawania atrybutu `async` lub `defer` do skryptu banera.
|
||||||
|
</action>
|
||||||
|
<verify>
|
||||||
|
Sprawdź w pliku layout-logged.php:
|
||||||
|
- Blok consent default pojawia się PRZED `<!-- Google Tag Manager -->`
|
||||||
|
- `cookienoticepro.style.css` jest linkowany w `<head>`
|
||||||
|
- `cookienoticepro.script.js` i wywołanie `$.cookieNoticePro()` są przed `</body>`
|
||||||
|
Komenda: grep -n "Consent Mode\|cookienoticepro\|GTM-TW9WCD9J" templates/site/layout-logged.php
|
||||||
|
</verify>
|
||||||
|
<done>AC-1, AC-2 satisfied: consent default init przed GTM, CSS i JS banera załadowane</done>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
<task type="checkpoint:human-verify" gate="blocking">
|
||||||
|
<what-built>Baner CookieNoticePro z Consent Mode v2 zintegrowany w layout-logged.php. Pliki biblioteki w libraries/CookieNoticePro/. Błąd analytics_storage naprawiony.</what-built>
|
||||||
|
<how-to-verify>
|
||||||
|
1. Wyślij pliki na serwer przez FTP (Ctrl+Shift+P → "FTP-kr: Upload")
|
||||||
|
2. Otwórz https://bilety.brzezovka.pl w trybie incognito (brak cookies)
|
||||||
|
3. Sprawdź czy pojawia się baner zgody na cookies
|
||||||
|
4. Otwórz DevTools → Console — sprawdź czy NIE ma błędów JS
|
||||||
|
5. Otwórz DevTools → Network → filtruj "gtm" — sprawdź czy GTM się ładuje
|
||||||
|
6. W Console wpisz: `document.cookie` — nie powinno być COOKIE_CONSENT (przed akceptacją)
|
||||||
|
7. Kliknij "Odrzuć wszystkie" → w DevTools → Application → Cookies sprawdź czy GOOGLE_CONSENT_MODE_ANALYTICS_STORAGE ma wartość false/brak
|
||||||
|
8. Odśwież stronę — baner NIE powinien się pojawić ponownie (cookie zapamiętane)
|
||||||
|
9. Kliknij ikonę ciasteczka (minimize) → wybierz "Akceptuj wszystkie" → sprawdź że gtag update wysyła 'granted' (DevTools → Console → wpisz: `dataLayer` i poszukaj consent update)
|
||||||
|
</how-to-verify>
|
||||||
|
<resume-signal>Wpisz "approved" jeśli baner działa poprawnie, lub opisz problemy do naprawienia</resume-signal>
|
||||||
|
</task>
|
||||||
|
|
||||||
|
</tasks>
|
||||||
|
|
||||||
|
<boundaries>
|
||||||
|
|
||||||
|
## DO NOT CHANGE
|
||||||
|
- `templates/tickets/przelewy24.php` — purchase event (Phase 2, nie ruszać)
|
||||||
|
- `templates/tickets/order-confirm.php` — po czyszczeniu Phase 2
|
||||||
|
- Snippet GTM w layout-logged.php — tylko kolejność, nie treść
|
||||||
|
- `config.php` — konfiguracja poza zakresem
|
||||||
|
|
||||||
|
## SCOPE LIMITS
|
||||||
|
- Nie konfiguruj cookienoticepro dla innych layoutów (layout-unlogged.php nie jest używany)
|
||||||
|
- Nie zmieniaj kolorów/tekstu/języka banera — domyślna konfiguracja z biblioteki jest wystarczająca na start
|
||||||
|
- Nie dodawaj nowych zależności JS poza biblioteką CookieNoticePro
|
||||||
|
- Nie wdrażaj server-side consent storage — tylko frontend cookies
|
||||||
|
|
||||||
|
</boundaries>
|
||||||
|
|
||||||
|
<verification>
|
||||||
|
Przed ogłoszeniem planu za kompletny:
|
||||||
|
- [ ] `grep -n "analytics_storage" libraries/CookieNoticePro/cookienoticepro.script.js` → pokazuje 'denied' w else i 'granted' w if
|
||||||
|
- [ ] `grep -n "consent.*default\|cookienoticepro\|GTM-TW9WCD9J" templates/site/layout-logged.php` → consent default PRZED GTM
|
||||||
|
- [ ] Baner pojawia się na stronie przy pierwszej wizycie (weryfikacja manualna — checkpoint)
|
||||||
|
- [ ] Brak błędów JS w konsoli
|
||||||
|
- [ ] Odrzucenie cookies → analytics_storage pozostaje denied (nie grantowane)
|
||||||
|
</verification>
|
||||||
|
|
||||||
|
<success_criteria>
|
||||||
|
- Pliki CookieNoticePro obecne w libraries/CookieNoticePro/
|
||||||
|
- Błąd analytics_storage naprawiony (denied zamiast granted w bloku else)
|
||||||
|
- Consent Mode v2 default init znajduje się przed GTM snippetem w layout-logged.php
|
||||||
|
- Baner wyświetla się przy pierwszej wizycie i zapamiętuje wybór
|
||||||
|
- Serwis spełnia wymaganie RODO z PROJECT.md (Must Have: Zgodność z RODO)
|
||||||
|
</success_criteria>
|
||||||
|
|
||||||
|
<output>
|
||||||
|
Po zakończeniu utwórz `.paul/phases/03-cookie-consent/03-01-SUMMARY.md`
|
||||||
|
</output>
|
||||||
134
.paul/phases/03-cookie-consent/03-01-SUMMARY.md
Normal file
134
.paul/phases/03-cookie-consent/03-01-SUMMARY.md
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
---
|
||||||
|
phase: 03-cookie-consent
|
||||||
|
plan: 01
|
||||||
|
subsystem: ui
|
||||||
|
tags: [cookies, gdpr, consent-mode-v2, gtm, cookienoticepro]
|
||||||
|
|
||||||
|
requires:
|
||||||
|
- phase: 02-purchase-event-prepayment
|
||||||
|
provides: GTM już wdrożony w layout-logged.php
|
||||||
|
|
||||||
|
provides:
|
||||||
|
- Baner zgody na cookies (CookieNoticePro) zintegrowany z serwisem
|
||||||
|
- Google Consent Mode v2 z domyślnymi denied przed GTM
|
||||||
|
- Naprawiony błąd analytics_storage w bibliotece CookieNoticePro
|
||||||
|
affects: []
|
||||||
|
|
||||||
|
tech-stack:
|
||||||
|
added: [CookieNoticePro jQuery plugin]
|
||||||
|
patterns: [Consent Mode v2 default-denied init before GTM snippet]
|
||||||
|
|
||||||
|
key-files:
|
||||||
|
created:
|
||||||
|
- libraries/CookieNoticePro/cookienoticepro.script.js
|
||||||
|
- libraries/CookieNoticePro/cookienoticepro.style.css
|
||||||
|
modified:
|
||||||
|
- templates/site/layout-logged.php
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "Inicjalizacja: cookieNoticePro.init() zamiast $.fn.cookieNoticePro() — zgodnie z dokumentacją biblioteki"
|
||||||
|
- "acceptBtnSettingsLabel ukryty przez CSS (display:none) — JS nie ustawiał stanu początkowego"
|
||||||
|
|
||||||
|
patterns-established:
|
||||||
|
- "Consent Mode v2 default init zawsze przed snippetem GTM w <head>"
|
||||||
|
|
||||||
|
duration: ~45min
|
||||||
|
started: 2026-04-26T00:00:00Z
|
||||||
|
completed: 2026-04-26T00:00:00Z
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 3 Plan 01: Cookie Consent Banner Summary
|
||||||
|
|
||||||
|
**CookieNoticePro z Google Consent Mode v2 wdrożony — serwis spełnia wymogi RODO, analytics_storage poprawnie ustawiane na denied przy odmowie zgody.**
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
| Metric | Value |
|
||||||
|
|--------|-------|
|
||||||
|
| Duration | ~45 min |
|
||||||
|
| Tasks | 2 auto + 1 checkpoint |
|
||||||
|
| Files modified | 3 |
|
||||||
|
|
||||||
|
## Acceptance Criteria Results
|
||||||
|
|
||||||
|
| Criterion | Status | Notes |
|
||||||
|
|-----------|--------|-------|
|
||||||
|
| AC-1: Consent Mode v2 default przed GTM | Pass | Blok w `<head>` przed `<!-- Google Tag Manager -->` |
|
||||||
|
| AC-2: Baner przy pierwszej wizycie | Pass | Zweryfikowane manualnie |
|
||||||
|
| AC-3: Naprawa analytics_storage denied | Pass | Linia ~351: `'granted'` → `'denied'` w bloku else |
|
||||||
|
| AC-4: Akceptacja → granted | Pass | Blok if (analytics accepted) bez zmian |
|
||||||
|
| AC-5: Pliki biblioteki obecne | Pass | `libraries/CookieNoticePro/` skonfigurowany |
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
|
||||||
|
- Skopiowano i zintegrowano bibliotekę CookieNoticePro z istniejącym projektem
|
||||||
|
- Naprawiono błąd biblioteki: `analytics_storage: 'granted'` → `'denied'` w bloku odrzucenia analytics
|
||||||
|
- Consent Mode v2 inicjalizowany z defaultami `denied` przed snippetem GTM — wymaganie Google od marca 2024
|
||||||
|
- Baner wyświetla się przy pierwszej wizycie, zapamiętuje wybór przez 365 dni
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
|
||||||
|
| File | Change | Purpose |
|
||||||
|
|------|--------|---------|
|
||||||
|
| `libraries/CookieNoticePro/cookienoticepro.script.js` | Created | Biblioteka banera — zkopiona + naprawiony błąd analytics_storage + link regulaminu |
|
||||||
|
| `libraries/CookieNoticePro/cookienoticepro.style.css` | Created | Style banera — zkopione + Bootstrap 5 compat reset + initial state fix |
|
||||||
|
| `templates/site/layout-logged.php` | Modified | Consent Mode v2 default przed GTM, CSS/JS banera, inicjalizacja `cookieNoticePro.init()` |
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
|
||||||
|
| Decision | Rationale | Impact |
|
||||||
|
|----------|-----------|--------|
|
||||||
|
| `cookieNoticePro.init()` zamiast `$.fn.cookieNoticePro()` | Demo `index.html` z biblioteki pokazuje właściwy sposób inicjalizacji | Poprawne uruchomienie banera |
|
||||||
|
| CSS `display:none` na `.acceptBtnSettingsLabel` | JS przełącza etykiety tylko na click — nie ustawia stanu początkowego | Brak duplikatu tekstu w przycisku "Akceptuj/Zatwierdź" |
|
||||||
|
| Bootstrap 5 compat reset w CSS | Bootstrap nadpisuje `line-height`, `font-size` przycisków | Poprawny wygląd przycisków banera |
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
### Summary
|
||||||
|
|
||||||
|
| Type | Count | Impact |
|
||||||
|
|------|-------|--------|
|
||||||
|
| Auto-fixed | 3 | Niezbędne poprawki, brak scope creep |
|
||||||
|
| Scope additions | 1 | Drobna zmiana na prośbę użytkownika |
|
||||||
|
|
||||||
|
**Total impact:** Drobne poprawki wynikające z integracji z Bootstrap 5 i specyfiki biblioteki
|
||||||
|
|
||||||
|
### Auto-fixed Issues
|
||||||
|
|
||||||
|
**1. Inicjalizacja pluginu**
|
||||||
|
- **Found during:** Checkpoint (błąd konsoli)
|
||||||
|
- **Issue:** `$.cookieNoticePro is not a function` — plugin rejestruje się jako `$.fn`, nie `$`
|
||||||
|
- **Fix:** `$.cookieNoticePro()` → `$.fn.cookieNoticePro()` → `cookieNoticePro.init()`
|
||||||
|
- **Files:** `templates/site/layout-logged.php`
|
||||||
|
|
||||||
|
**2. Duplikat tekstu w przycisku akceptacji**
|
||||||
|
- **Found during:** Checkpoint (feedback użytkownika)
|
||||||
|
- **Issue:** `.acceptBtnSettingsLabel` ("Zatwierdź") widoczny razem z `.acceptBtnLabel` ("Akceptuj") — brak initial hide w JS
|
||||||
|
- **Fix:** Dodano `display: none` w CSS dla `.acceptBtnSettingsLabel`
|
||||||
|
- **Files:** `libraries/CookieNoticePro/cookienoticepro.style.css`
|
||||||
|
|
||||||
|
**3. Bootstrap 5 button override**
|
||||||
|
- **Found during:** Checkpoint (button layout)
|
||||||
|
- **Issue:** Bootstrap nadpisuje `line-height` i `font-size` przycisków banera
|
||||||
|
- **Fix:** CSS reset z `!important`-safe specificity dla `.btn-wrap button`
|
||||||
|
- **Files:** `libraries/CookieNoticePro/cookienoticepro.style.css`
|
||||||
|
|
||||||
|
### Scope Additions
|
||||||
|
|
||||||
|
- Link regulaminu zmieniony na `https://bilety.brzezovka.pl/tickets/regulamin/` (prośba użytkownika podczas weryfikacji)
|
||||||
|
|
||||||
|
## Next Phase Readiness
|
||||||
|
|
||||||
|
**Ready:**
|
||||||
|
- v0.2 Analytics & Privacy — wszystkie 3 fazy kompletne
|
||||||
|
- Tracking ecommerce (Phase 1+2) + RODO (Phase 3) wdrożone
|
||||||
|
|
||||||
|
**Concerns:**
|
||||||
|
- Brak — integracja stabilna
|
||||||
|
|
||||||
|
**Blockers:**
|
||||||
|
- None
|
||||||
|
|
||||||
|
---
|
||||||
|
*Phase: 03-cookie-consent, Plan: 01*
|
||||||
|
*Completed: 2026-04-26*
|
||||||
438
libraries/CookieNoticePro/cookienoticepro.script.js
Normal file
438
libraries/CookieNoticePro/cookienoticepro.script.js
Normal file
File diff suppressed because one or more lines are too long
560
libraries/CookieNoticePro/cookienoticepro.style.css
Normal file
560
libraries/CookieNoticePro/cookienoticepro.style.css
Normal file
@@ -0,0 +1,560 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Flerosoft (https://flerosoft.com)
|
||||||
|
* Software Name: Cookie Notice Pro - jQuery Plugin
|
||||||
|
* Product Page : https://cookienoticepro.flerosoft.com
|
||||||
|
* Documentation: https://cookienoticepro.flerosoft.com/docs
|
||||||
|
* Description: Cookie Notice Pro, a lightweight jQuery plugin, helps you to comply with GDPR.
|
||||||
|
Make your own cookie information popup in minutes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*********************** Cookie Dialog ***********************/
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500&display=swap');
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--cookieNoticeProLight: #ffffff;
|
||||||
|
--cookieNoticeProDark: #393d4d;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes cookieNoticeProZoomIn {
|
||||||
|
from {
|
||||||
|
transform: scale(0);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
transform: scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes cookieNoticeProZoomOut {
|
||||||
|
from {
|
||||||
|
transform: scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
transform: scale(0);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro * {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
text-decoration: none;
|
||||||
|
list-style: none;
|
||||||
|
font-family: 'Poppins', sans-serif;
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro button,
|
||||||
|
#cookieNoticePro a {
|
||||||
|
cursor: pointer;
|
||||||
|
color: inherit;
|
||||||
|
font-family: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro button {
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro strong,
|
||||||
|
#cookieNoticePro em {
|
||||||
|
font-weight: bold;
|
||||||
|
font-family: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro a:focus,
|
||||||
|
#cookieNoticePro input:focus {
|
||||||
|
outline: none;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#cookieNoticePro.light {
|
||||||
|
background-color: #ffffff;
|
||||||
|
background-color: var(--cookieNoticeProLight);
|
||||||
|
color: #393d4d;
|
||||||
|
color: var(--cookieNoticeProDark);
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.light p,
|
||||||
|
#cookieNoticePro.light ul {
|
||||||
|
color: #393d4d;
|
||||||
|
color: var(--cookieNoticeProDark);
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.light h5 {
|
||||||
|
color: var(--cookieNoticeProDark);
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.light button#cookieReject {
|
||||||
|
background: #ffffff;
|
||||||
|
background: var(--cookieNoticeProLight);
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
#cookieNoticePro.light button#cookieReject {
|
||||||
|
order: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.light button#cookieAccept {
|
||||||
|
order: 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.dark {
|
||||||
|
background-color: #393d4d;
|
||||||
|
background-color: var(--cookieNoticeProDark);
|
||||||
|
color: #ffffff;
|
||||||
|
color: var(--cookieNoticeProLight);
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.dark p,
|
||||||
|
#cookieNoticePro.dark ul {
|
||||||
|
color: #ffffff;
|
||||||
|
color: var(--cookieNoticeProLight);
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.dark h5 {
|
||||||
|
color: #ffffff;
|
||||||
|
color: var(--cookieNoticeProLight);
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.dark button#cookieReject {
|
||||||
|
background: transparent;
|
||||||
|
color: #ffffff;
|
||||||
|
color: var(--cookieNoticeProLight);
|
||||||
|
border: 1px solid #ffffff;
|
||||||
|
border: 1px solid var(--cookieNoticeProLight);
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro {
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: fixed;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
-webkit-box-shadow: 0 6px 6px rgba(0, 0, 0, 0.25);
|
||||||
|
box-shadow: 0 6px 6px rgba(0, 0, 0, 0.25);
|
||||||
|
font-family: inherit;
|
||||||
|
z-index: 999997;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro #closeIcon {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #bfb9b9;
|
||||||
|
overflow: hidden;
|
||||||
|
opacity: 0.85;
|
||||||
|
z-index: 999999;
|
||||||
|
position: absolute;
|
||||||
|
top: 4px;
|
||||||
|
right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro svg {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.display-left {
|
||||||
|
left: 30px;
|
||||||
|
bottom: 30px;
|
||||||
|
max-width: 395px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.display-right {
|
||||||
|
right: 30px;
|
||||||
|
bottom: 30px;
|
||||||
|
max-width: 395px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.display-top {
|
||||||
|
top: 30px;
|
||||||
|
width: 800px;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.display-bottom {
|
||||||
|
bottom: 30px;
|
||||||
|
width: 800px;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.display-top .content-wrap,
|
||||||
|
#cookieNoticePro.display-bottom .content-wrap {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-webkit-box-pack: justify;
|
||||||
|
-ms-flex-pack: justify;
|
||||||
|
justify-content: space-between;
|
||||||
|
-webkit-box-align: center;
|
||||||
|
-ms-flex-align: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.display-top .msg-wrap,
|
||||||
|
#cookieNoticePro.display-bottom .msg-wrap {
|
||||||
|
max-width: 65%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.display-top .msg-wrap,
|
||||||
|
#cookieNoticePro.display-bottom .msg-wrap {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.display-top #cookieSettings,
|
||||||
|
#cookieNoticePro.display-bottom #cookieSettings {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.display-top #cookieTypes,
|
||||||
|
#cookieNoticePro.display-bottom #cookieTypes {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro .btn-wrap {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-webkit-box-orient: horizontal;
|
||||||
|
-webkit-box-direction: normal;
|
||||||
|
-ms-flex-direction: row;
|
||||||
|
flex-direction: row;
|
||||||
|
font-weight: bold;
|
||||||
|
-webkit-box-pack: center;
|
||||||
|
-ms-flex-pack: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 0 -5px 0 -5px;
|
||||||
|
-ms-flex-wrap: wrap;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro .btn-wrap button {
|
||||||
|
-webkit-box-flex: 1;
|
||||||
|
-ms-flex-positive: 1;
|
||||||
|
flex-grow: 1;
|
||||||
|
padding: 0 7px;
|
||||||
|
margin: 0 5px 10px 5px;
|
||||||
|
border-radius: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
white-space: nowrap;
|
||||||
|
min-width: 130px;
|
||||||
|
line-height: 36px;
|
||||||
|
border: none;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: 16px;
|
||||||
|
-webkit-transition: -webkit-box-shadow .3s;
|
||||||
|
transition: -webkit-box-shadow .3s;
|
||||||
|
-o-transition: box-shadow .3s;
|
||||||
|
transition: box-shadow .3s;
|
||||||
|
transition: box-shadow .3s, -webkit-box-shadow .3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro .btn-wrap button:hover {
|
||||||
|
-webkit-transition: -webkit-box-shadow .4s cubic-bezier(.25, .8, .25, 1), -webkit-transform .4s cubic-bezier(.25, .8, .25, 1);
|
||||||
|
transition: -webkit-box-shadow .4s cubic-bezier(.25, .8, .25, 1), -webkit-transform .4s cubic-bezier(.25, .8, .25, 1);
|
||||||
|
-o-transition: box-shadow .4s cubic-bezier(.25, .8, .25, 1), transform .4s cubic-bezier(.25, .8, .25, 1);
|
||||||
|
transition: box-shadow .4s cubic-bezier(.25, .8, .25, 1), transform .4s cubic-bezier(.25, .8, .25, 1);
|
||||||
|
transition: box-shadow .4s cubic-bezier(.25, .8, .25, 1), transform .4s cubic-bezier(.25, .8, .25, 1), -webkit-box-shadow .4s cubic-bezier(.25, .8, .25, 1), -webkit-transform .4s cubic-bezier(.25, .8, .25, 1);
|
||||||
|
-webkit-box-shadow: 0 2px 5px 0 rgba(0, 0, 0, .3);
|
||||||
|
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, .3);
|
||||||
|
-webkit-transform: translate3d(0, -1px, 0);
|
||||||
|
transform: translate3d(0, -1px, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro #cookieSettings {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-webkit-box-align: center;
|
||||||
|
-ms-flex-align: center;
|
||||||
|
align-items: center;
|
||||||
|
text-transform: uppercase;
|
||||||
|
cursor: pointer;
|
||||||
|
font-weight: normal;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro #cookieSettings svg {
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro h4 {
|
||||||
|
font-family: inherit;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro .title-wrap {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-webkit-box-align: center;
|
||||||
|
-ms-flex-align: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro .title-wrap svg {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro h5 {
|
||||||
|
font-family: inherit;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro p,
|
||||||
|
#cookieNoticePro ul {
|
||||||
|
font-size: 12px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro p:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro li {
|
||||||
|
width: 49%;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro a {
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 14px;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
border-bottom: 1px dotted rgba(255, 255, 255, 0.75);
|
||||||
|
-webkit-transition: all 0.3s ease-in;
|
||||||
|
-o-transition: all 0.3s ease-in;
|
||||||
|
transition: all 0.3s ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#cookieTypes label {
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro button:disabled {
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro input[type="checkbox"] {
|
||||||
|
-webkit-appearance: auto;
|
||||||
|
-moz-appearance: auto;
|
||||||
|
appearance: auto;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
text-rendering: optimizeSpeed;
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
margin: 4px 10px 0px 0px;
|
||||||
|
display: block;
|
||||||
|
float: left;
|
||||||
|
position: relative;
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro input[type="checkbox"]:checked:after {
|
||||||
|
background: #d3d3d3;
|
||||||
|
content: "\2714";
|
||||||
|
color: #808080;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro input[type="checkbox"]:after {
|
||||||
|
content: "";
|
||||||
|
vertical-align: middle;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 13px;
|
||||||
|
position: absolute;
|
||||||
|
cursor: pointer;
|
||||||
|
height: 14px;
|
||||||
|
width: 14px;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
font-size: 10px;
|
||||||
|
background: #d3d3d3;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.display-top.full-width-true,
|
||||||
|
#cookieNoticePro.display-bottom.full-width-true {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
left: auto;
|
||||||
|
right: auto;
|
||||||
|
bottom: auto;
|
||||||
|
top: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.display-bottom.full-width-true {
|
||||||
|
bottom: 0;
|
||||||
|
top: auto;
|
||||||
|
-webkit-box-shadow: 0 -3px 3px rgb(0 0 0 / 25%);
|
||||||
|
box-shadow: 0 -3px 3px rgb(0 0 0 / 25%);
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.display-top.full-width-true .title-wrap,
|
||||||
|
#cookieNoticePro.display-bottom.full-width-true .title-wrap {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.display-top.full-width-true .btn-wrap button,
|
||||||
|
#cookieNoticePro.display-bottom.full-width-true .btn-wrap button {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieMinimizeIcon {
|
||||||
|
position: fixed;
|
||||||
|
right: 20px;
|
||||||
|
bottom: 20px;
|
||||||
|
border-radius: 50%;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0 6px 6px rgba(0, 0, 0, 0.25);
|
||||||
|
cursor: pointer;
|
||||||
|
animation: cookieNoticeProZoomIn 0.2s forwards;
|
||||||
|
transition: box-shadow 0.1s ease-in-out;
|
||||||
|
z-index: 99999;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieMinimizeIcon svg {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieMinimizeIcon.zoomIn {
|
||||||
|
animation: cookieNoticeProZoomIn 0.2s forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieMinimizeIcon.zoomOut {
|
||||||
|
animation: cookieNoticeProZoomOut 0.2s forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieMinimizeIcon .floating-text {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: -10%;
|
||||||
|
transform: translate(-100%, -50%);
|
||||||
|
background: rgba(51, 51, 51, 0.5);
|
||||||
|
padding: 2px 4px;
|
||||||
|
color: #ffffff;
|
||||||
|
border-radius: 2px;
|
||||||
|
font-family: 'Poppins', sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
text-wrap: nowrap;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieMinimizeIcon:hover {
|
||||||
|
box-shadow: 0 12px 12px rgba(0, 0, 0, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieMinimizeIcon:hover>.floating-text {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@media only screen and (max-width: 800px) {
|
||||||
|
|
||||||
|
#cookieNoticePro.display-top,
|
||||||
|
#cookieNoticePro.display-bottom {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
left: auto;
|
||||||
|
right: auto;
|
||||||
|
bottom: auto;
|
||||||
|
top: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.display-bottom {
|
||||||
|
bottom: 0;
|
||||||
|
top: auto;
|
||||||
|
-webkit-box-shadow: 0 -3px 3px rgb(0 0 0 / 25%);
|
||||||
|
box-shadow: 0 -3px 3px rgb(0 0 0 / 25%);
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.display-top .btn-wrap button,
|
||||||
|
#cookieNoticePro.display-bottom .btn-wrap button {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.display-top .msg-wrap,
|
||||||
|
#cookieNoticePro.display-bottom .msg-wrap {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 600px) {
|
||||||
|
|
||||||
|
#cookieNoticePro.display-left,
|
||||||
|
#cookieNoticePro.display-right {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
left: auto;
|
||||||
|
right: auto;
|
||||||
|
bottom: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
-webkit-box-shadow: 0 -3px 3px rgb(0 0 0 / 25%);
|
||||||
|
box-shadow: 0 -3px 3px rgb(0 0 0 / 25%);
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.display-top .content-wrap,
|
||||||
|
#cookieNoticePro.display-bottom .content-wrap {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.display-top .msg-wrap,
|
||||||
|
#cookieNoticePro.display-bottom .msg-wrap {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#cookieNoticePro.display-top #cookieSettings,
|
||||||
|
#cookieNoticePro.display-bottom #cookieSettings {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initial state: settings label hidden until settings panel opens */
|
||||||
|
#cookieNoticePro .acceptBtnSettingsLabel {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Bootstrap 5 compatibility reset */
|
||||||
|
#cookieNoticePro .btn-wrap button {
|
||||||
|
line-height: 36px;
|
||||||
|
font-size: 16px;
|
||||||
|
padding: 0 7px;
|
||||||
|
border-radius: 20px;
|
||||||
|
border: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
}
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
<link rel="stylesheet" type="text/css" href="/libraries/datepicker/css/datepicker.min.css">
|
<link rel="stylesheet" type="text/css" href="/libraries/datepicker/css/datepicker.min.css">
|
||||||
<link rel="stylesheet" type="text/css" href="/layout/style-css/style.css">
|
<link rel="stylesheet" type="text/css" href="/layout/style-css/style.css">
|
||||||
<link rel="stylesheet" type="text/css" href="/libraries/dataTable/jquery.dataTables.min.css">
|
<link rel="stylesheet" type="text/css" href="/libraries/dataTable/jquery.dataTables.min.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="/libraries/CookieNoticePro/cookienoticepro.style.css">
|
||||||
|
|
||||||
<script type="text/javascript" src="/libraries/jquery/jquery-3.6.0.min.js"></script>
|
<script type="text/javascript" src="/libraries/jquery/jquery-3.6.0.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.bundle.min.js"
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.bundle.min.js"
|
||||||
@@ -33,6 +34,19 @@
|
|||||||
<script type="text/javascript" src="/libraries/qrcode-scanner/html5-qrcode.min.js"></script>
|
<script type="text/javascript" src="/libraries/qrcode-scanner/html5-qrcode.min.js"></script>
|
||||||
<script type="text/javascript" src="/libraries/dataTable/jquery.dataTables.min.js"></script>
|
<script type="text/javascript" src="/libraries/dataTable/jquery.dataTables.min.js"></script>
|
||||||
<script type="text/javascript" src="https://cdn.datatables.net/1.12.1/js/dataTables.bootstrap5.min.js"></script>
|
<script type="text/javascript" src="https://cdn.datatables.net/1.12.1/js/dataTables.bootstrap5.min.js"></script>
|
||||||
|
<!-- Google Consent Mode v2 - default -->
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag(){dataLayer.push(arguments);}
|
||||||
|
gtag('consent', 'default', {
|
||||||
|
'analytics_storage': 'denied',
|
||||||
|
'ad_storage': 'denied',
|
||||||
|
'ad_user_data': 'denied',
|
||||||
|
'ad_personalization': 'denied',
|
||||||
|
'wait_for_update': 500
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<!-- End Google Consent Mode v2 - default -->
|
||||||
<!-- Google Tag Manager -->
|
<!-- Google Tag Manager -->
|
||||||
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
||||||
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
||||||
@@ -142,6 +156,12 @@
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
<script type="text/javascript" src="/libraries/CookieNoticePro/cookienoticepro.script.js"></script>
|
||||||
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
cookieNoticePro.init();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user