Skip to content

Commit

Permalink
chore: refactor of consent based loading
Browse files Browse the repository at this point in the history
  • Loading branch information
davidnuescheler committed Jul 10, 2024
1 parent 88d66bc commit c2efe45
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 22 deletions.
77 changes: 77 additions & 0 deletions scripts/consent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* Display Consent Banner and return consent details
*/

// eslint-disable-next-line import/no-cycle
import { loadFragment } from '../blocks/fragment/fragment.js';

/* create button helper */
function createButton(text, clickHandler, style, label) {
const button = document.createElement('button');
button.textContent = text;
if (style) button.className = style;
if (label) button.ariaLabel = label;
button.addEventListener('click', clickHandler);
return button;
}

/* display consent banner */
function displayConsentBanner(consentBanner) {
const bannerClose = new Promise((resolve) => {
const dialog = document.createElement('dialog');

const storeAndClose = (status) => {
localStorage.setItem('consentStatus', status);
dialog.remove();
resolve(status);
// eslint-disable-next-line no-use-before-define
displayConsentLink(consentBanner);
};

const close = () => { storeAndClose('declineAll'); };
const accept = () => { storeAndClose('acceptAll'); };
const decline = () => { storeAndClose('declineAll'); };

const config = consentBanner.dataset;
dialog.id = 'consent-banner';
dialog.append(consentBanner);
const buttons = document.createElement('span');
buttons.className = 'consent-banner-buttons';
if (config.accept) buttons.append(createButton(config.accept, accept));
if (config.decline) buttons.append(createButton(config.decline, decline, 'secondary'));
if (config.close) buttons.append(createButton('\u2715', close, 'consent-banner-close', config.close));
dialog.append(buttons);
document.body.append(dialog);
dialog.show();
});

return bannerClose;
}

/* display consent link */
function displayConsentLink(consentBanner) {
const div = document.createElement('div');
div.id = 'consent-link';
const button = createButton(consentBanner.dataset.shortTitle, async () => {
div.remove();
await displayConsentBanner(consentBanner);
}, 'secondary');
div.append(button);
document.body.append(div);
}

/* main consent handler */
export default async function handleConsent() {
const mapStatus = (consentStatus) => {
if (consentStatus === 'declineAll') return false;
return true;
};
const consentStatus = localStorage.getItem('consentStatus');
const consentBanner = (await loadFragment('/drafts/uncled/consent-banner')).firstElementChild;

if (consentStatus === null) {
return mapStatus(await displayConsentBanner(consentBanner));
}
displayConsentLink(consentBanner);
return mapStatus(consentStatus);
}
3 changes: 3 additions & 0 deletions scripts/marketing-tech.js → scripts/consented.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
// add tag management code here, marketing or advertising functionality
// this file is gated by consent

// eslint-disable-next-line no-console
console.log('loading consented.js');
32 changes: 10 additions & 22 deletions scripts/scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,34 +117,22 @@ async function loadLazy(doc) {
}

/**
* Loads everything that happens a lot later,
* without impacting the user experience.
* Checks consent asynchronously and returns true if consented.js
* can be loaded (which should contain the tag manager).
*/
async function loadMarketingTech() {
const mapStatus = (consentStatus) => {
if (consentStatus === 'declineAll') return false;
return true;
};
const checkConsent = () => {
const consentStatus = localStorage.getItem('consentStatus');
if (consentStatus !== null) return mapStatus(consentStatus);
return new Promise((resolve) => {
// display consent banner
document.addEventListener('aem:changeconsent', (e) => {
localStorage.setItem('consentStatus', e.detail.consentStatus);
resolve(mapStatus(e.detail.consentStatus));
});
});
};
// eslint-disable-next-line import/no-cycle
if (await checkConsent()) import('./marketing-tech.js');
// load anything that can be postponed to the latest here
async function checkConsent() {
const mod = await import('./consent.js');

Check failure on line 124 in scripts/scripts.js

View workflow job for this annotation

GitHub Actions / build

Dependency cycle via ../blocks/fragment/fragment.js:6
return mod.default();
}

async function loadConsented() {
import('./consented.js');
}

async function loadPage() {
await loadEager(document);
await loadLazy(document);
loadMarketingTech();
if (await checkConsent()) loadConsented();
}

loadPage();
49 changes: 49 additions & 0 deletions styles/lazy-styles.css
Original file line number Diff line number Diff line change
@@ -1 +1,50 @@
/* add global styles that can be loaded post LCP here */

dialog#consent-banner, div#consent-link {
position: fixed;
left: 0;
bottom: 0;
background-color: var(--light-color);
max-width: 600px;
padding: 16px;
font-size: var(--body-font-size-xs);
margin: 16px;
border-radius: 32px;
border: 0;
box-shadow: 3px 3px 10px #0004;
}

dialog#consent-banner {
border-radius: 16px;
padding-right: 40px;
}

dialog#consent-banner p {
margin: 0px;
}

dialog#consent-banner .consent-banner-buttons {
display: flex;
gap: 8px;
}

dialog#consent-banner .consent-banner-buttons button {
margin: 8px 0;
}

dialog#consent-banner .consent-banner-close {
position: absolute;
margin: 0;
padding: 0;
right: 16px;
top: 12px;
border: unset;
padding: unset;
color: unset;
background-color: unset;
margin: 0;
}

div#consent-link button {
margin: 0;
}

0 comments on commit c2efe45

Please sign in to comment.