From 0d0dbdded2fd5c27824c1cc5da7a68b2d56a2f4e Mon Sep 17 00:00:00 2001 From: Ivan <45982459+ivntsng@users.noreply.github.com> Date: Fri, 4 Oct 2024 21:21:37 -0700 Subject: [PATCH] 439: GDPR Cookie Consent Banner (#449) * 439: GDPR Cookie Consent Banner * Updated GDPR banner text and consent option grouping * Resolved linting issues --------- Co-authored-by: casper --- frontend/index.html | 78 +++++----- frontend/src/App.tsx | 2 + frontend/src/components/SprigInitializer.tsx | 40 +++--- frontend/src/components/gdpr/gdprbanner.tsx | 144 +++++++++++++++++++ 4 files changed, 215 insertions(+), 49 deletions(-) create mode 100644 frontend/src/components/gdpr/gdprbanner.tsx diff --git a/frontend/index.html b/frontend/index.html index eff9b53d..2fb127c7 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -4,16 +4,6 @@ - - - - @@ -50,30 +40,54 @@ + + + const sprigConsent = localStorage.getItem('sprig-consent') === 'true'; + const googleAnalyticsConsent = localStorage.getItem('google-analytics-consent') === 'true'; + const pendoConsent = localStorage.getItem('pendo-consent') === 'true'; + + if (googleAnalyticsConsent) { + (function () { + var gtagScript = document.createElement('script'); + gtagScript.async = true; + gtagScript.src = 'https://www.googletagmanager.com/gtag/js?id=G-QG3C4SS5YY'; + document.head.appendChild(gtagScript); + + gtagScript.onload = function () { + window.dataLayer = window.dataLayer || []; + function gtag() { dataLayer.push(arguments); } + gtag('js', new Date()); + gtag('config', 'G-QG3C4SS5YY'); + }; + })(); + } + if (sprigConsent) { + (function (l, e, a, p) { + if (window.Sprig) return; + window.Sprig = function () { S._queue.push(arguments) } + var S = window.Sprig; S.appId = 'bHT8PZvMNWLZ'; S._queue = []; + window.UserLeap = S; + a = l.createElement('script'); + a.async = 1; a.src = e + '?id=' + S.appId; + p = l.getElementsByTagName('script')[0]; + p.parentNode.insertBefore(a, p); + })(document, 'https://cdn.sprig.com/shim.js'); + } - @@ -85,4 +99,4 @@ - \ No newline at end of file + diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index b5aedb71..894ce471 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -28,6 +28,7 @@ import Signup from "@/components/pages/Signup"; import { AlertQueue, AlertQueueProvider } from "@/hooks/useAlertQueue"; import { AuthenticationProvider } from "@/hooks/useAuth"; +import GDPRBanner from "./components/gdpr/gdprbanner"; import DownloadsPage from "./components/pages/Download"; import MuJoCoTestPage from "./components/pages/MuJoCoTest"; import PrivacyPolicy from "./components/pages/PrivacyPolicy"; @@ -42,6 +43,7 @@ const App = () => {
+
diff --git a/frontend/src/components/SprigInitializer.tsx b/frontend/src/components/SprigInitializer.tsx index 26e18117..6a7d3d37 100644 --- a/frontend/src/components/SprigInitializer.tsx +++ b/frontend/src/components/SprigInitializer.tsx @@ -8,25 +8,31 @@ const SprigInitializer = () => { const { currentUser, isAuthenticated } = useAuthentication(); useEffect(() => { - const initializeSprig = () => { - if (window.Sprig && typeof window.Sprig === "function") { - console.log("Sprig initialized"); - - // Set user ID and email in Sprig if user is authenticated - if (isAuthenticated && currentUser) { - window.Sprig("setUserId", currentUser.id); - window.Sprig("setUserEmail", currentUser.email); + const sprigConsent = localStorage.getItem("sprig-consent") === "true"; + + if (sprigConsent) { + const initializeSprig = () => { + if (window.Sprig && typeof window.Sprig === "function") { + console.log("Sprig initialized"); + + // Set user ID and email in Sprig if user is authenticated + if (isAuthenticated && currentUser) { + window.Sprig("setUserId", currentUser.id); + window.Sprig("setUserEmail", currentUser.email); + } + + // Track page view + window.Sprig("track", "page_view", { path: location.pathname }); + } else { + console.log("Sprig is not ready yet. Retrying..."); + setTimeout(initializeSprig, 500); } + }; - // Track page view - window.Sprig("track", "page_view", { path: location.pathname }); - } else { - console.log("Sprig is not ready yet. Retrying..."); - setTimeout(initializeSprig, 500); - } - }; - - initializeSprig(); + initializeSprig(); + } else { + console.log("Sprig tracking is disabled due to user preferences."); + } }, [location.pathname, isAuthenticated, currentUser]); return null; diff --git a/frontend/src/components/gdpr/gdprbanner.tsx b/frontend/src/components/gdpr/gdprbanner.tsx new file mode 100644 index 00000000..bbdb34ca --- /dev/null +++ b/frontend/src/components/gdpr/gdprbanner.tsx @@ -0,0 +1,144 @@ +import React, { useEffect, useState } from "react"; + +const GDPRBanner: React.FC = () => { + const [isVisible, setIsVisible] = useState(false); + const [showOptOutForm, setShowOptOutForm] = useState(false); + const [sprigConsent, setSprigConsent] = useState(true); + const [googleAnalyticsConsent, setGoogleAnalyticsConsent] = useState(true); + const [pendoConsent, setPendoConsent] = useState(true); + + useEffect(() => { + const consentGiven = localStorage.getItem("gdpr-consent"); + if (!consentGiven) { + setIsVisible(true); + } + }, []); + + const handleAccept = () => { + localStorage.setItem("sprig-consent", "true"); + localStorage.setItem("google-analytics-consent", "true"); + localStorage.setItem("pendo-consent", "true"); + localStorage.setItem("gdpr-consent", "true"); + setIsVisible(false); + window.location.reload(); + }; + + const handleOptOut = () => { + setShowOptOutForm(true); + }; + + const handleSaveOptOutPreferences = () => { + localStorage.setItem("sprig-consent", sprigConsent.toString()); + localStorage.setItem( + "google-analytics-consent", + googleAnalyticsConsent.toString(), + ); + localStorage.setItem("pendo-consent", pendoConsent.toString()); + localStorage.setItem("gdpr-consent", "true"); + setShowOptOutForm(false); + setIsVisible(false); + window.location.reload(); + }; + + const handleBackToBanner = () => { + setShowOptOutForm(false); + }; + + return ( + <> + {isVisible && !showOptOutForm && ( +
+
+ We value your privacy 🔒 we use cookies to make it easier to + interact with our website and to improve it. We want to better + understand how our website is used. You can find out more about our + use of cookies in our + + Privacy Policy + + . +
+
+ + +
+
+ )} + + {showOptOutForm && ( +
+
+ Please select which services you would like to opt out of. +
+ +
+ + +
+ +
+ + + setGoogleAnalyticsConsent(!googleAnalyticsConsent) + } + className="toggle-checkbox" + /> +
+ +
+ + { + setSprigConsent(!sprigConsent); + setPendoConsent(!pendoConsent); + }} + className="toggle-checkbox" + /> +
+ +
+ + +
+
+ )} + + ); +}; + +export default GDPRBanner;