From e5c69503b04ffef48a3b74056ee7411866c50516 Mon Sep 17 00:00:00 2001 From: svarona Date: Fri, 26 Jun 2026 16:18:54 +0200 Subject: [PATCH 1/4] Added cookie consent banner --- conf/template_settings.py | 1 + core/config.py | 5 + .../static/core/custom/css/cookie_consent.css | 264 ++++++++++++++++++ core/static/core/custom/img/GDPR.jpg | Bin 0 -> 4690 bytes core/templates/core/base.html | 112 ++++++++ core/urls.py | 1 + core/utils/generic_functions.py | 13 + core/views.py | 36 +++ 8 files changed, 432 insertions(+) create mode 100644 core/static/core/custom/css/cookie_consent.css create mode 100644 core/static/core/custom/img/GDPR.jpg diff --git a/conf/template_settings.py b/conf/template_settings.py index 0cafdf0a..d822775f 100644 --- a/conf/template_settings.py +++ b/conf/template_settings.py @@ -62,6 +62,7 @@ "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", "docs.utils.context_processors.docs_current_path", + "core.utils.generic_functions.cookie_consent", ], }, }, diff --git a/core/config.py b/core/config.py index 975badb7..87404ccc 100644 --- a/core/config.py +++ b/core/config.py @@ -161,3 +161,8 @@ "Submitter": "submitting_institution", "Collector": "lab_code_1", } + +# Cookie consent +COOKIE_CONSENT_NAME = "relecovCookieConsent" +COOKIE_CONSENT_MAX_AGE = 60 * 60 * 24 * 365 +COOKIE_CONSENT_VALUES = {"all", "necessary_only"} diff --git a/core/static/core/custom/css/cookie_consent.css b/core/static/core/custom/css/cookie_consent.css new file mode 100644 index 00000000..e09f726a --- /dev/null +++ b/core/static/core/custom/css/cookie_consent.css @@ -0,0 +1,264 @@ +.cookie-consent, +.cookie-modal { + font-family: var(--font-primary); +} + +.cookie-consent-hidden { + display: none !important; +} + +.cookie-consent { + position: fixed; + right: 24px; + bottom: 24px; + left: 24px; + z-index: 1200; +} + +.cookie-consent-content { + display: flex; + gap: 24px; + align-items: center; + max-width: 1180px; + margin: 0 auto; + padding: 24px; + color: var(--color-default); + background: var(--color-white); + border: 1px solid rgba(var(--color-secondary-rgb), 0.25); + border-radius: 8px; + box-shadow: 0 12px 40px rgba(var(--color-black-rgb), 0.22); +} + +.cookie-consent h2, +.cookie-modal h2 { + margin: 0 0 12px; + color: var(--color-primary); + font-weight: 700; +} + +.cookie-consent p, +.cookie-modal p { + margin: 0 0 10px; + line-height: 1.55; +} + +.cookie-consent-actions, +.cookie-modal-actions { + display: flex; + gap: 12px; + flex-shrink: 0; + justify-content: flex-end; +} + +.cookie-consent-actions form, +.cookie-modal-actions form { + margin: 0; +} + +.cookie-btn { + display: inline-flex; + min-width: 128px; + min-height: 46px; + align-items: center; + justify-content: center; + padding: 11px 18px; + border: 1px solid var(--color-primary); + border-radius: 6px; + font-weight: 700; + text-align: center; + text-decoration: none; + transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease; +} + +.cookie-btn-primary, +.cookie-btn-secondary:hover, +.cookie-btn-outline:hover { + color: var(--color-white); + background: var(--color-primary); +} + +.cookie-btn-secondary { + color: var(--color-primary); + background: var(--color-secondary); +} + +.cookie-btn-primary:hover, +.cookie-btn-secondary:hover, +.cookie-btn-outline:hover { + text-decoration: none; +} + +.cookie-btn-outline { + color: var(--color-primary); + background: var(--color-white); +} + +.cookie-modal { + position: fixed; + inset: 0; + z-index: 1250; +} + +.cookie-modal-backdrop { + position: absolute; + inset: 0; + background: rgba(var(--color-black-rgb), 0.72); +} + +.cookie-modal-panel { + position: relative; + display: grid; + grid-template-columns: 38% 62%; + width: min(1170px, calc(100vw - 36px)); + min-height: 600px; + margin: 54px auto; + overflow: hidden; + background: var(--color-white); + border-radius: 6px; + box-shadow: 0 24px 70px rgba(var(--color-black-rgb), 0.35); +} + +.cookie-modal-close { + position: absolute; + top: 0; + right: 0; + display: inline-flex; + width: 60px; + height: 60px; + align-items: center; + justify-content: center; + color: var(--color-white); + background: var(--color-primary); + border: 0; + border-bottom-left-radius: 30px; + font-size: 22px; + text-decoration: none; + z-index: 2; +} + +.cookie-modal-sidebar { + padding: 44px 60px; + background: var(--color-white); +} + +.cookie-modal-logo { + width: 150px; + height: auto; + margin-bottom: 28px; +} + +.cookie-tab { + display: block; + width: 100%; + margin-bottom: 14px; + padding: 14px 20px; + color: var(--color-primary); + text-align: left; + text-decoration: none; + text-transform: uppercase; + background: var(--color-white); + border: 1px solid rgba(var(--color-secondary-rgb), 0.35); + border-radius: 5px; + font-weight: 700; +} + +.cookie-tab.active { + background: #f0f0f0; +} + +.cookie-modal-body { + display: flex; + flex-direction: column; + padding: 44px 60px 38px; + background: #f7f7f7; +} + +.cookie-tab-panel { + display: none; +} + +.cookie-tab-panel.active { + display: block; +} + +.cookie-table-wrapper { + margin-top: 20px; + overflow-x: auto; +} + +.cookie-table { + width: 100%; + color: var(--color-default); + background: var(--color-white); + border-collapse: collapse; + font-size: 0.92rem; +} + +.cookie-table th, +.cookie-table td { + padding: 10px 12px; + border: 1px solid rgba(var(--color-secondary-rgb), 0.25); + text-align: left; + vertical-align: top; +} + +.cookie-table th { + color: var(--color-primary); + font-weight: 700; +} + +.cookie-toggle-row { + display: flex; + gap: 12px; + align-items: center; + margin-top: 24px; + color: #70b77e; +} + +.cookie-toggle { + position: relative; + display: inline-block; + width: 52px; + height: 30px; + background: #8c8c8c; + border-radius: 999px; +} + +.cookie-toggle::after { + position: absolute; + top: 2px; + right: 2px; + width: 26px; + height: 26px; + content: ""; + background: var(--color-white); + border-radius: 50%; + box-shadow: 0 1px 4px rgba(var(--color-black-rgb), 0.3); +} + +.cookie-modal-actions { + margin-top: auto; + padding-top: 32px; + border-top: 1px solid rgba(var(--color-gray-rgb), 0.35); +} + +@media (max-width: 991px) { + .cookie-consent-content, + .cookie-consent-actions, + .cookie-modal-actions { + flex-direction: column; + align-items: stretch; + } + + .cookie-modal-panel { + display: block; + max-height: calc(100vh - 36px); + margin: 18px auto; + overflow-y: auto; + } + + .cookie-modal-sidebar, + .cookie-modal-body { + padding: 28px; + } +} diff --git a/core/static/core/custom/img/GDPR.jpg b/core/static/core/custom/img/GDPR.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8be61b8e1302666c0030e39e457c453c6650e02c GIT binary patch literal 4690 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 literal 0 HcmV?d00001 diff --git a/core/templates/core/base.html b/core/templates/core/base.html index 2c1acde1..7cb40e19 100644 --- a/core/templates/core/base.html +++ b/core/templates/core/base.html @@ -26,6 +26,7 @@ +