diff --git a/README.md b/README.md index d0e456e..4d4791f 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ Follow the instructions in: [https://github.com/aesirxio/analytics-1stparty](htt ``` @@ -46,9 +47,11 @@ Follow the instructions in: [https://github.com/aesirxio/analytics-1stparty](htt ``` REACT_APP_ENDPOINT_ANALYTICS_URL=https://example.com REACT_APP_SSO_CLIENT_ID=[REPLACE THIS WITH THE PROVIDED CLIENT_ID] +REACT_APP_SSO_CLIENT_SECRET=[REPLACE THIS WITH THE PROVIDED CLIENT_SECRET] (https://example.com is the link to your 1st party server) `CLIENT_ID` replace this with the provided `CLIENT_ID` from https://dapp.shield.aesirx.io/ +`CLIENT_SECRET` replace this with the provided `CLIENT_SECRET` fromhttps://dapp.shield.aesirx.io/ ``` ##### Disable Consent Popup: @@ -87,9 +90,11 @@ export default AnalyticsContainer; ``` NEXT_PUBLIC_ENDPOINT_ANALYTICS_URL=https://example.com NEXT_PUBLIC_SSO_CLIENT_ID=[REPLACE THIS WITH THE PROVIDED CLIENT_ID] +NEXT_PUBLIC_SSO_CLIENT_SECRET=[REPLACE THIS WITH THE PROVIDED CLIENT_SECRET] (https://example.com is the link to your 1st party server) `CLIENT_ID` replace this with the provided `CLIENT_ID` from https://dapp.shield.aesirx.io/ +`CLIENT_SECRET` replace this with the provided `CLIENT_SECRET` fromhttps://dapp.shield.aesirx.io/ ``` ##### Disable Consent Popup: @@ -274,4 +279,37 @@ Please follow below CSS example: [data-bs-theme=dark] .aesirxconsent { color: #fff; } +``` + + +## Choose template for Consent modal + +There is 5 template for Consent modal +1. original +2. default (recommend) +3. simple-consent-mode + 1. Support Basic Consent Mode v2 +4. advance-consent-mode + 1. Support Advance Consent Mode v2 +5. simple-web-2 + +#### Usage in SSR site: +``` + +``` + +#### In ReactJS: + +add this environment variable to `.env` +``` +REACT_APP_CONSENT_LAYOUT=default +``` + +#### In NextJS: + +add this environment variable to `.env` +``` +NEXT_PUBLIC_CONSENT_LAYOUT=default ``` \ No newline at end of file diff --git a/src/AnalyticsNext/index.tsx b/src/AnalyticsNext/index.tsx index acf7d3a..e218a6e 100644 --- a/src/AnalyticsNext/index.tsx +++ b/src/AnalyticsNext/index.tsx @@ -1,9 +1,10 @@ -import React, { ReactNode } from 'react'; +import React, { ReactNode, useEffect, useState } from 'react'; import AnalyticsContextProvider from '../utils/AnalyticsContextProvider'; import AnalyticsHandle from './handle'; import { NextRouter } from 'next/router'; import dynamic from 'next/dynamic'; +import { getConsentTemplate } from '../utils/consent'; const ConsentComponent = dynamic(() => import('../Components/Consent'), { ssr: false }); const ConsentComponentCustom = dynamic(() => import('../Components/ConsentCustom'), { ssr: false }); @@ -25,6 +26,18 @@ const AnalyticsNext = ({ isLoggedApp, children, }: AnalyticsNext) => { + const [layout, setLayout] = useState(process.env.NEXT_PUBLIC_CONSENT_LAYOUT); + const [gtagId, setGtagId] = useState(process.env.NEXT_PUBLIC_ANALYTICS_GTAG_ID); + const [gtmId, setGtmId] = useState(process.env.NEXT_PUBLIC_ANALYTICS_GTM_ID); + useEffect(() => { + const init = async () => { + const data: any = await getConsentTemplate(window.location.host); + setLayout(data?.data?.template ?? process.env.NEXT_PUBLIC_CONSENT_LAYOUT); + setGtagId(data?.data?.gtag_id ?? process.env.NEXT_PUBLIC_ANALYTICS_GTAG_ID); + setGtmId(data?.data?.gtm_id ?? process.env.NEXT_PUBLIC_ANALYTICS_GTM_ID); + }; + init(); + }, []); return ( <> @@ -32,13 +45,15 @@ const AnalyticsNext = ({ {children} {process.env.NEXT_PUBLIC_DISABLE_ANALYTICS_CONSENT !== 'true' && ( <> - {oldLayout ? ( + {oldLayout || layout === 'original' ? ( ) : ( )} diff --git a/src/AnalyticsReact/index.tsx b/src/AnalyticsReact/index.tsx index c96663c..74ac4f9 100644 --- a/src/AnalyticsReact/index.tsx +++ b/src/AnalyticsReact/index.tsx @@ -1,7 +1,8 @@ -import React, { ReactNode, Suspense } from 'react'; +import React, { ReactNode, Suspense, useEffect, useState } from 'react'; import AnalyticsContextProvider from '../utils/AnalyticsContextProvider'; import AnalyticsHandle from './handle'; +import { getConsentTemplate } from '../utils/consent'; const ConsentComponent = React.lazy(() => import('../Components/Consent')); const ConsentComponentCustom = React.lazy(() => import('../Components/ConsentCustom')); @@ -14,23 +15,40 @@ interface AnalyticsReact { } const AnalyticsReact = ({ location, history, oldLayout = false, children }: AnalyticsReact) => { + const [layout, setLayout] = useState(process.env.REACT_APP_CONSENT_LAYOUT); + const [gtagId, setGtagId] = useState(process.env.REACT_APP_ANALYTICS_GTAG_ID); + const [gtmId, setGtmId] = useState(process.env.REACT_APP_ANALYTICS_GTM_ID); + useEffect(() => { + const init = async () => { + const data: any = await getConsentTemplate(window.location.host); + setLayout(data?.data?.template ?? process.env.REACT_APP_CONSENT_LAYOUT); + setGtagId(data?.data?.gtag_id ?? process.env.REACT_APP_ANALYTICS_GTAG_ID); + setGtmId(data?.data?.gtm_id ?? process.env.REACT_APP_ANALYTICS_GTM_ID); + }; + init(); + }, []); return ( {children} {process.env.REACT_APP_DISABLE_ANALYTICS_CONSENT !== 'true' && ( }> - {oldLayout ? ( + {oldLayout || layout === 'original' ? ( ) : ( )} diff --git a/src/Components/Consent.tsx b/src/Components/Consent.tsx index 2f0bb35..1c70b18 100644 --- a/src/Components/Consent.tsx +++ b/src/Components/Consent.tsx @@ -6,6 +6,8 @@ import { getNonce, getSignature, getWalletNonce, + loadGtagScript, + loadGtmScript, revokeConsents, verifySignature, } from '../utils/consent'; @@ -44,14 +46,32 @@ import { useTranslation } from 'react-i18next'; import { useAccount, useSignMessage } from 'wagmi'; import SSOEthereumProvider from './Ethereum'; import { getWeb3ID } from '../utils/Concordium'; +declare global { + interface Window { + dataLayer: any; + } +} +declare const dataLayer: any[]; interface WalletConnectionPropsExtends extends WalletConnectionProps { endpoint: string; aesirXEndpoint: string; networkEnv?: string; loginApp?: any; isLoggedApp?: boolean; + gtagId: string; + gtmId: string; + layout?: string; } -const ConsentComponent = ({ endpoint, aesirXEndpoint, networkEnv, loginApp, isLoggedApp }: any) => { +const ConsentComponent = ({ + endpoint, + aesirXEndpoint, + networkEnv, + loginApp, + isLoggedApp, + gtagId, + gtmId, + layout, +}: any) => { return ( {(props) => ( @@ -63,6 +83,9 @@ const ConsentComponent = ({ endpoint, aesirXEndpoint, networkEnv, loginApp, isLo aesirXEndpoint={aesirXEndpoint} loginApp={loginApp} isLoggedApp={isLoggedApp} + gtagId={gtagId} + gtmId={gtmId} + layout={layout} /> @@ -76,6 +99,9 @@ const ConsentComponentApp = (props: WalletConnectionPropsExtends) => { aesirXEndpoint, loginApp, isLoggedApp, + gtagId, + gtmId, + layout, activeConnectorType, activeConnector, activeConnectorError, @@ -107,7 +133,7 @@ const ConsentComponentApp = (props: WalletConnectionPropsExtends) => { handleLevel, showRevoke, handleRevoke, - ] = useConsentStatus(endpoint, props); + ] = useConsentStatus(endpoint, layout, props); const [consents, setConsents] = useState([1, 2]); const [loading, setLoading] = useState('done'); @@ -176,7 +202,10 @@ const ConsentComponentApp = (props: WalletConnectionPropsExtends) => { signature, web3ID, jwt, - 'metamask' + 'metamask', + gtagId, + gtmId, + layout ); sessionStorage.setItem('aesirx-analytics-uuid', uuid); sessionStorage.setItem('aesirx-analytics-allow', '1'); @@ -265,7 +294,20 @@ const ConsentComponentApp = (props: WalletConnectionPropsExtends) => { : 'Give consent Tier 4:{nonce} {domain} {time}' ); setLoading('saving'); - await agreeConsents(endpoint, level, uuid, consents, account, signature, web3ID, jwt); + await agreeConsents( + endpoint, + level, + uuid, + consents, + account, + signature, + web3ID, + jwt, + 'concordium', + gtagId, + gtmId, + layout + ); sessionStorage.setItem('aesirx-analytics-consent-type', 'concordium'); } else if (connector) { // Metamask @@ -290,13 +332,39 @@ const ConsentComponentApp = (props: WalletConnectionPropsExtends) => { consents.forEach(async (consent) => { const existConsent = consentList.find((item: any) => item?.consent === consent); if (!existConsent) { - await agreeConsents(endpoint, 1, uuid, consent); + await agreeConsents( + endpoint, + 1, + uuid, + consent, + null, + null, + null, + null, + 'concordium', + gtagId, + gtmId, + layout + ); } else if ( !!existConsent?.consent_uuid && existConsent?.expiration && new Date(existConsent.expiration) < new Date() ) { - await agreeConsents(endpoint, 1, uuid, consent); + await agreeConsents( + endpoint, + 1, + uuid, + consent, + null, + null, + null, + null, + 'concordium', + gtagId, + gtmId, + layout + ); } }); } @@ -360,7 +428,11 @@ const ConsentComponentApp = (props: WalletConnectionPropsExtends) => { account, signature, null, - response?.jwt + response?.jwt, + 'concordium', + gtagId, + gtmId, + layout ); setShow(false); handleRevoke(true, level); @@ -403,7 +475,20 @@ const ConsentComponentApp = (props: WalletConnectionPropsExtends) => { } setConsentTier4(response); } else { - await agreeConsents(endpoint, level, uuid, consents, null, null, null, response?.jwt); + await agreeConsents( + endpoint, + level, + uuid, + consents, + null, + null, + null, + response?.jwt, + 'concordium', + gtagId, + gtmId, + layout + ); setShow(false); handleRevoke(true, level); setLoading('done'); @@ -520,6 +605,38 @@ const ConsentComponentApp = (props: WalletConnectionPropsExtends) => { element.click(); }; + const loadConsentDefault = (gtagId: any, gtmId: any) => { + window.dataLayer = window.dataLayer || []; + function gtag( // eslint-disable-next-line @typescript-eslint/no-unused-vars + p0: string, // eslint-disable-next-line @typescript-eslint/no-unused-vars + p1: any, // eslint-disable-next-line @typescript-eslint/no-unused-vars + p2?: any + ) { + // eslint-disable-next-line prefer-rest-params + dataLayer.push(arguments); + } + gtag('consent', 'default', { + ad_user_data: 'denied', + ad_personalization: 'denied', + ad_storage: 'denied', + analytics_storage: 'denied', + wait_for_update: 500, + }); + if (gtagId) { + gtag('js', new Date()); + gtag('config', `${gtagId}`); + } + if (gtmId) { + dataLayer.push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' }); + } + if (layout === 'advance-consent-mode') { + gtagId && loadGtagScript(gtagId); + gtmId && loadGtmScript(gtmId); + gtag('set', 'url_passthrough', true); + gtag('set', 'ads_data_redaction', true); + } + }; + useEffect(() => { if (activeConnectorError) { toast.error(activeConnectorError); @@ -531,6 +648,7 @@ const ConsentComponentApp = (props: WalletConnectionPropsExtends) => { setShowBackdrop(false); setShowExpandConsent(false); } + (gtagId || gtmId) && loadConsentDefault(gtagId, gtmId); }, []); console.log('level', uuid, level, web3ID, account, loading); @@ -690,7 +808,7 @@ const ConsentComponentApp = (props: WalletConnectionPropsExtends) => { <> {level ? ( <> - +
{ return ( @@ -71,6 +86,9 @@ const ConsentComponentCustom = ({ aesirXEndpoint={aesirXEndpoint} loginApp={loginApp} isLoggedApp={isLoggedApp} + gtagId={gtagId} + gtmId={gtmId} + layout={layout} /> @@ -84,6 +102,9 @@ const ConsentComponentCustomApp = (props: WalletConnectionPropsExtends) => { aesirXEndpoint, loginApp, isLoggedApp, + gtagId, + gtmId, + layout, activeConnectorType, activeConnector, activeConnectorError, @@ -115,7 +136,7 @@ const ConsentComponentCustomApp = (props: WalletConnectionPropsExtends) => { handleLevel, showRevoke, handleRevoke, - ] = useConsentStatus(endpoint, props); + ] = useConsentStatus(endpoint, layout, props); const [consents, setConsents] = useState([1, 2]); const [loading, setLoading] = useState('done'); @@ -187,7 +208,10 @@ const ConsentComponentCustomApp = (props: WalletConnectionPropsExtends) => { signature, web3ID, jwt, - 'metamask' + 'metamask', + gtagId, + gtmId, + layout ); sessionStorage.setItem('aesirx-analytics-uuid', uuid); sessionStorage.setItem('aesirx-analytics-allow', '1'); @@ -276,7 +300,20 @@ const ConsentComponentCustomApp = (props: WalletConnectionPropsExtends) => { : 'Give consent Tier 4:{nonce} {domain} {time}' ); setLoading('saving'); - await agreeConsents(endpoint, level, uuid, consents, account, signature, web3ID, jwt); + await agreeConsents( + endpoint, + level, + uuid, + consents, + account, + signature, + web3ID, + jwt, + 'concordium', + gtagId, + gtmId, + layout + ); sessionStorage.setItem('aesirx-analytics-consent-type', 'concordium'); } else if (connector) { // Metamask @@ -301,13 +338,39 @@ const ConsentComponentCustomApp = (props: WalletConnectionPropsExtends) => { consents.forEach(async (consent) => { const existConsent = consentList.find((item: any) => item?.consent === consent); if (!existConsent) { - await agreeConsents(endpoint, 1, uuid, consent); + await agreeConsents( + endpoint, + 1, + uuid, + consent, + null, + null, + null, + null, + null, + gtagId, + gtmId, + layout + ); } else if ( !!existConsent?.consent_uuid && existConsent?.expiration && new Date(existConsent.expiration) < new Date() ) { - await agreeConsents(endpoint, 1, uuid, consent); + await agreeConsents( + endpoint, + 1, + uuid, + consent, + null, + null, + null, + null, + null, + gtagId, + gtmId, + layout + ); } }); } @@ -371,7 +434,11 @@ const ConsentComponentCustomApp = (props: WalletConnectionPropsExtends) => { account, signature, null, - response?.jwt + response?.jwt, + 'concordium', + gtagId, + gtmId, + layout ); setShow(false); handleRevoke(true, level); @@ -414,7 +481,20 @@ const ConsentComponentCustomApp = (props: WalletConnectionPropsExtends) => { } setConsentTier4(response); } else { - await agreeConsents(endpoint, level, uuid, consents, null, null, null, response?.jwt); + await agreeConsents( + endpoint, + level, + uuid, + consents, + null, + null, + null, + response?.jwt, + 'concordium', + gtagId, + gtmId, + layout + ); setShow(false); handleRevoke(true, level); setLoading('done'); @@ -548,6 +628,7 @@ const ConsentComponentCustomApp = (props: WalletConnectionPropsExtends) => { ) { window.funcAfterConsent && window.funcAfterConsent(); } + (gtagId || gtmId) && loadConsentDefault(gtagId, gtmId); }, []); console.log('level', uuid, level, web3ID, account, loading); @@ -611,6 +692,37 @@ const ConsentComponentCustomApp = (props: WalletConnectionPropsExtends) => { ); }; + const loadConsentDefault = (gtagId: any, gtmId: any) => { + window.dataLayer = window.dataLayer || []; + function gtag( // eslint-disable-next-line @typescript-eslint/no-unused-vars + p0: string, // eslint-disable-next-line @typescript-eslint/no-unused-vars + p1: any, // eslint-disable-next-line @typescript-eslint/no-unused-vars + p2?: any + ) { + // eslint-disable-next-line prefer-rest-params + dataLayer.push(arguments); + } + gtag('consent', 'default', { + ad_user_data: 'denied', + ad_personalization: 'denied', + ad_storage: 'denied', + analytics_storage: 'denied', + wait_for_update: 500, + }); + if (gtagId) { + gtag('js', new Date()); + gtag('config', `${gtagId}`); + } + if (gtmId) { + dataLayer.push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' }); + } + if (layout === 'advance-consent-mode') { + gtagId && loadGtagScript(gtagId); + gtmId && loadGtmScript(gtmId); + gtag('set', 'url_passthrough', true); + gtag('set', 'ads_data_redaction', true); + } + }; return (
@@ -772,7 +884,7 @@ const ConsentComponentCustomApp = (props: WalletConnectionPropsExtends) => { <> {upgradeLayout ? ( <> -
+
{loading === 'done' ? ( <>

{t('txt_upgrade_consent_text')}

@@ -804,7 +916,7 @@ const ConsentComponentCustomApp = (props: WalletConnectionPropsExtends) => {
- {level !== 1 && ( + {level !== 1 && layout !== 'advance-consent-mode' && ( { ) : ( <> - + {
{loading === 'done' ? ( <> - {' '} + {layout === 'simple-consent-mode' || layout === 'simple-web-2' ? ( + <> + ) : ( + <> + {' '} + + )}
-
+
{isCustom ? ( <> - setActiveTab(k)} - className="mb-2 mb-lg-3 w-100 flex-nowrap consent_info_tab" - > - -

{t('txt_consent_to_data')}

-
-
{t('txt_ethical_compliant')}
-
-
- - GDPR -
-
- - CCPA -
-
-
-
- {t('txt_your_current_level')} -
+ {layout === 'simple-web-2' ? ( +
- - -
-
- - - -
-
-
-
-
- - - -
-
+
+ ) : ( + <> + setActiveTab(k)} + className="mb-2 mb-lg-3 w-100 flex-nowrap consent_info_tab" + > + +

{t('txt_consent_to_data')}

+
+
{t('txt_ethical_compliant')}
+
+
+ + GDPR +
+
+ + CCPA +
+
-
-
- - - -
-
+
+ {t('txt_your_current_level')}
-
-
- {t('txt_understanding_your_consent')} -
-
{t('txt_this_website_uses')}
- - - - -
- - -
- - - -
-
-
-
-
- - - -
-
-
-
-
- - - -
+ +
-
-
-
- - - -
-
-
-
-
-
{t('txt_ethical_compliant')}
-
-
- - GDPR + className={`about_section ${ + layout !== 'simple-consent-mode' && layout !== 'simple-web-2' + ? 'fix_height' + : '' + }`} + > +
+ + + +
+
+
+
+
+ + + +
+
+
+
+
+ + + +
+
+
+
+
+ {t('txt_understanding_your_consent')} +
+ {layout !== 'simple-consent-mode' && + layout !== 'advance-consent-mode' ? ( +
{t('txt_this_website_uses')}
+ ) : ( + <> + )} + {layout === 'advance-consent-mode' ? ( + <> + ) : ( + <> + + + )} + + {layout !== 'simple-consent-mode' && layout !== 'simple-web-2' ? ( + <> + + + + + ) : ( + <> + )}
-
- - CCPA + + +
+ + + +
+
+
-
-
- - +
+ + + +
+
+
+
+
+ + + +
+
+
+
+
+ + + +
+
+
+
+
+
{t('txt_ethical_compliant')}
+
+
+ + GDPR +
+
+ + CCPA +
+
+
+ + + + )} ) : ( <> diff --git a/src/Hooks/useConsentStatus.ts b/src/Hooks/useConsentStatus.ts index 59dec25..d59f6dd 100644 --- a/src/Hooks/useConsentStatus.ts +++ b/src/Hooks/useConsentStatus.ts @@ -16,7 +16,7 @@ import { isDesktop } from 'react-device-detect'; import { useAccount } from 'wagmi'; import { BlockHash } from '@concordium/web-sdk'; -const useConsentStatus = (endpoint?: string, props?: WalletConnectionProps) => { +const useConsentStatus = (endpoint?: string, layout?: string, props?: WalletConnectionProps) => { const [show, setShow] = useState(false); const [showRevoke, setShowRevoke] = useState(false); const [level, setLevel] = useState(); @@ -121,7 +121,9 @@ const useConsentStatus = (endpoint?: string, props?: WalletConnectionProps) => { isDesktop && sessionStorage.getItem('aesirx-analytics-revoke') !== '1' && sessionStorage.getItem('aesirx-analytics-revoke') !== '2' && - sessionStorage.getItem('aesirx-analytics-rejected') !== 'true' + sessionStorage.getItem('aesirx-analytics-rejected') !== 'true' && + layout !== 'simple-consent-mode' && + layout !== 'simple-web-2' ) { if (window['concordium']) { const address = (await window['concordium']?.requestAccounts()) ?? []; @@ -167,7 +169,6 @@ const useConsentStatus = (endpoint?: string, props?: WalletConnectionProps) => { setLevel(null); l = 3; let web3ID = false; - console.log('test', account); if (account && sessionStorage.getItem('aesirx-analytics-consent-type') !== 'metamask') { web3ID = await getWeb3ID(account, rpc, network?.name); if (web3ID === true) { @@ -175,40 +176,52 @@ const useConsentStatus = (endpoint?: string, props?: WalletConnectionProps) => { } } setWeb3ID(web3ID); - setLevel(l); + if (layout !== 'simple-consent-mode' && layout !== 'simple-web-2') { + setLevel(l); + } else { + setLevel(1); + } } } else if (connector) { // Metamask - if (l < 3) { - l = 3; - const web3ID = false; - setWeb3ID(web3ID); - setLevel(l); - } else { - if (l === 4) { - setLevel(4); + if (layout !== 'simple-consent-mode' && layout !== 'simple-web-2') { + if (l < 3) { + l = 3; + const web3ID = false; + setWeb3ID(web3ID); + setLevel(l); } else { - setLevel(3); + if (l === 4) { + setLevel(4); + } else { + setLevel(3); + } } + } else { + setLevel(1); } } else { - setLevel(level ?? 1); + setLevel(level ?? layout === 'advance-consent-mode' ? 2 : 1); } } catch (error) { - setLevel(level ?? 1); + setLevel(level ?? layout === 'advance-consent-mode' ? 2 : 1); console.error(error); } })(); - }, [account, address, connector]); + }, [account, address, connector, layout]); const handleLevel = useCallback( async (_level: number) => { - setLevel(_level); - if (_level > 3 && isDesktop && !connection && window['concordium']) { - setActiveConnectorType(BROWSER_WALLET); + if (layout !== 'simple-consent-mode' && layout !== 'simple-web-2') { + setLevel(_level); + if (_level > 3 && isDesktop && !connection && window['concordium']) { + setActiveConnectorType(BROWSER_WALLET); + } + } else { + setLevel(1); } }, - [level] + [level, layout] ); const handleRevoke = (status: boolean, level: string) => { diff --git a/src/analytics.tsx b/src/analytics.tsx index 48c9419..3b16736 100644 --- a/src/analytics.tsx +++ b/src/analytics.tsx @@ -5,7 +5,7 @@ import { searchAnalytics, viewProductAnalytics, } from './utils/woocommerce'; -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { createRoot } from 'react-dom/client'; import { AnalyticsContext } from './utils/AnalyticsContextProvider'; @@ -14,6 +14,7 @@ import ConsentComponentCustom from './Components/ConsentCustom'; import { Buffer } from 'buffer'; import { appLanguages } from './translations'; import { AesirXI18nextProvider } from './utils/I18nextProvider'; +import { getConsentTemplate } from './utils/consent'; window.Buffer = Buffer; declare global { @@ -24,6 +25,18 @@ declare global { } const ConsentPopup = ({ visitor_uuid, event_uuid }: any) => { window.process = { env: '' }; + const [layout, setLayout] = useState(window['consentLayout']); + const [gtagId, setGtagId] = useState(window['analyticsGtagId']); + const [gtmId, setGtmId] = useState(window['analyticsGtmId']); + useEffect(() => { + const init = async () => { + const data: any = await getConsentTemplate(window.location.host); + setLayout(data?.data?.template ?? window['consentLayout']); + setGtagId(data?.data?.gtag_id ?? window['analyticsGtagId']); + setGtmId(data?.data?.gtm_id ?? window['analyticsGtmId']); + }; + init(); + }, []); return ( { }} > - {window['oldLayoutConsent'] === 'true' ? ( + {layout === 'original' ? ( ) : ( )} diff --git a/src/styles/style.scss b/src/styles/style.scss index 081e3c9..ea8aae8 100644 --- a/src/styles/style.scss +++ b/src/styles/style.scss @@ -131,6 +131,7 @@ $dark: #222328; font-weight: 600; color: #a5a4b5; border: 0; + cursor: pointer; &.active { color: $primary; border-bottom: 2px solid $success; @@ -139,9 +140,11 @@ $dark: #222328; } } .about_section { - height: 373px; overflow: auto; padding: 0 10px; + &.fix_height { + height: 373px; + } @include media-breakpoint-down(lg) { padding: 0; } @@ -160,16 +163,16 @@ $dark: #222328; } .status-tier { &.tier-1 { - background-color: #F1C40F; + background-color: #f1c40f; } &.tier-2 { - background-color: #E67E22; + background-color: #e67e22; } &.tier-3 { - background-color: #9B59B6; + background-color: #9b59b6; } &.tier-4 { - background-color: #C8192E; + background-color: #c8192e; } } } diff --git a/src/utils/consent.ts b/src/utils/consent.ts index 25f36ef..b4c0ac5 100644 --- a/src/utils/consent.ts +++ b/src/utils/consent.ts @@ -11,11 +11,17 @@ const agreeConsents = async ( signature?: string, web3id?: string, jwt?: string, - network = 'concordium' + network = 'concordium', + gtagId?: string, + gtmId?: string, + layout?: string ) => { const url = `${endpoint}/consent/v1/level${level}/${uuid}`; const urlV2 = `${endpoint}/consent/v2/level${level}/${uuid}`; - + if (sessionStorage.getItem('consentGranted') !== 'true') { + gtagId && consentModeGrant(true, gtagId, layout); + gtmId && consentModeGrant(false, gtmId, layout); + } try { switch (level) { case 1: @@ -63,6 +69,47 @@ const agreeConsents = async ( } }; +declare const dataLayer: any[]; +const consentModeGrant = async (isGtag: any, id: any, layout: any) => { + if (layout !== 'advance-consent-mode') { + isGtag ? loadGtagScript(id) : loadGtmScript(id); + } + sessionStorage.setItem('consentGranted', 'true'); + function gtag( // eslint-disable-next-line @typescript-eslint/no-unused-vars + p0: any, // eslint-disable-next-line @typescript-eslint/no-unused-vars + p1: any, // eslint-disable-next-line @typescript-eslint/no-unused-vars + p2: any + ) { + // eslint-disable-next-line prefer-rest-params + dataLayer.push(arguments); + } + gtag('consent', 'update', { + ad_user_data: 'granted', + ad_personalization: 'granted', + ad_storage: 'granted', + analytics_storage: 'granted', + }); +}; + +const loadGtagScript = (gtagId: any) => { + // Load gtag.js script. + const gtagScript = document.createElement('script'); + gtagScript.async = true; + gtagScript.src = `https://www.googletagmanager.com/gtag/js?id=${gtagId}`; + + const firstScript = document.getElementsByTagName('script')[0]; + firstScript.parentNode.insertBefore(gtagScript, firstScript); +}; + +const loadGtmScript = (gtmId: any) => { + // Load Tag Manager script. + const gtmScript = document.createElement('script'); + gtmScript.async = true; + gtmScript.src = `https://www.googletagmanager.com/gtm.js?id=${gtmId}`; + + const firstScript = document.getElementsByTagName('script')[0]; + firstScript.parentNode.insertBefore(gtmScript, firstScript); +}; const getConsents = async (endpoint: string, uuid: string) => { try { const response = (await axios.get(`${endpoint}/visitor/v1/${uuid}`))?.data?.visitor_consents; @@ -127,6 +174,7 @@ const revokeConsents = async ( ) => { const url = `${endpoint}/consent/v1/level${level}/revoke/${uuid}`; const urlV2 = `${endpoint}/consent/v2/level${level}/revoke/${uuid}`; + sessionStorage.setItem('consentGranted', 'false'); try { switch (level) { case '2': @@ -260,6 +308,23 @@ const verifySignature = async ( } }; +const getConsentTemplate = async (domain: any) => { + try { + const endpointWeb3 = 'https://web3id.backend.aesirx.io:8001'; + const data = await axios.get(`${endpointWeb3}/datastream/template/${domain}`, { + headers: { + 'Content-Type': 'application/json', + }, + }); + + if (data) { + return data; + } + } catch (error) { + console.log('error', error); + } +}; + export { agreeConsents, getConsents, @@ -269,4 +334,7 @@ export { getMember, getWalletNonce, verifySignature, + loadGtagScript, + loadGtmScript, + getConsentTemplate, }; diff --git a/src/utils/index.ts b/src/utils/index.ts index 94beb3f..e6ef0d7 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -79,10 +79,14 @@ const startTracker = async ( sessionStorage.getItem('aesirx-analytics-flow') !== (await responseStart)?.flow_uuid ) { sessionStorage.setItem('aesirx-analytics-flow', (await responseStart)?.flow_uuid); - await trackerService( - rememberFlow(window.location.origin, (await responseStart)?.flow_uuid), - {} - ); + try { + await trackerService( + rememberFlow(window.location.origin, (await responseStart)?.flow_uuid), + {} + ); + } catch (error) { + console.log('Remember Flow Error', error); + } } return responseStart; } catch (error) {