mirror of
https://github.com/XFox111/my-website.git
synced 2026-04-22 07:28:01 +03:00
feat!: remove Clarity implicit consent option (EU compliance)
This commit is contained in:
@@ -15,7 +15,6 @@ ATS_RESUME_URL=URL # Location of the ATS-compatible resume PDF (optional, remo
|
|||||||
RESUME_HAS_REFS=false # Appends last page of the resume to a result PDF file (only appies to non-ATS version)
|
RESUME_HAS_REFS=false # Appends last page of the resume to a result PDF file (only appies to non-ATS version)
|
||||||
ALERT_TEXT_URL=URL # URL of a txt file with urgent message to be displayed (see app/_components/AlertMessage.tsx)
|
ALERT_TEXT_URL=URL # URL of a txt file with urgent message to be displayed (see app/_components/AlertMessage.tsx)
|
||||||
CLARITY_ID=string # Clarity Analytics ID (optional, remove to disable)
|
CLARITY_ID=string # Clarity Analytics ID (optional, remove to disable)
|
||||||
CLARITY_CONSENT=1 # 1 if you need to request explicit consent from user, 0 if not (requires CLARITY_ID)
|
|
||||||
|
|
||||||
CF_SITEKEY=3x00000000000000000000FF # Cloudflare Turnstile captcha sitekey for contact form (optional, remove to siable)
|
CF_SITEKEY=3x00000000000000000000FF # Cloudflare Turnstile captcha sitekey for contact form (optional, remove to siable)
|
||||||
CF_SECRET=1x0000000000000000000000000000000AA # Secret for token validation (requries CF_SITEKEY)
|
CF_SECRET=1x0000000000000000000000000000000AA # Secret for token validation (requries CF_SITEKEY)
|
||||||
|
|||||||
@@ -41,11 +41,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dismiss
|
|
||||||
{
|
|
||||||
border-left: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.controls
|
.controls
|
||||||
{
|
{
|
||||||
display: grid;
|
display: grid;
|
||||||
@@ -65,19 +60,16 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
|
||||||
&:not(:has(> .dismiss))
|
flex-flow: column;
|
||||||
|
|
||||||
|
.learnMore
|
||||||
{
|
{
|
||||||
flex-flow: column;
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
.learnMore
|
.controls > button:last-child
|
||||||
{
|
{
|
||||||
border-bottom: none;
|
border-left: none;
|
||||||
}
|
|
||||||
|
|
||||||
.controls > button:last-child
|
|
||||||
{
|
|
||||||
border-left: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { acceptCookies, dismissCookies, getCookieChoice, rejectCookies } from "@/_utils/analytics/client";
|
import { acceptCookies, getCookieChoice, rejectCookies } from "@/_utils/analytics/client";
|
||||||
import { Dismiss24Regular } from "@fluentui/react-icons";
|
|
||||||
import React, { useCallback, useEffect, useState } from "react";
|
import React, { useCallback, useEffect, useState } from "react";
|
||||||
import Button from "./Button";
|
import Button from "./Button";
|
||||||
import cls from "./CookieBanner.module.scss";
|
import cls from "./CookieBanner.module.scss";
|
||||||
|
|
||||||
const CookieBanner: React.FC<{ askForConsent: boolean; }> = props =>
|
const CookieBanner: React.FC = () =>
|
||||||
{
|
{
|
||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
|
|
||||||
@@ -36,12 +35,6 @@ const CookieBanner: React.FC<{ askForConsent: boolean; }> = props =>
|
|||||||
setVisible(false);
|
setVisible(false);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const dismiss = useCallback(() =>
|
|
||||||
{
|
|
||||||
dismissCookies();
|
|
||||||
setVisible(false);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if (!visible)
|
if (!visible)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@@ -59,16 +52,10 @@ const CookieBanner: React.FC<{ askForConsent: boolean; }> = props =>
|
|||||||
</p>
|
</p>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
{ props.askForConsent ?
|
<div className={ cls.controls }>
|
||||||
<div className={ cls.controls }>
|
<Button onClick={ accept }>Accept</Button>
|
||||||
<Button onClick={ accept }>Accept</Button>
|
<Button onClick={ reject }>Reject</Button>
|
||||||
<Button onClick={ reject }>Reject</Button>
|
</div>
|
||||||
</div>
|
|
||||||
:
|
|
||||||
<Button
|
|
||||||
title="Dismiss" icon={ <Dismiss24Regular /> }
|
|
||||||
onClick={ dismiss } className={ cls.dismiss } />
|
|
||||||
}
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -12,18 +12,12 @@ export const rejectCookies = (): void =>
|
|||||||
window.clarity?.("consent", false);
|
window.clarity?.("consent", false);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const dismissCookies = (): void =>
|
export const getCookieChoice = (): "accepted" | "rejected" | "none" =>
|
||||||
{
|
|
||||||
setCookie("CC", "", 1209600); // 14 days
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getCookieChoice = (): "accepted" | "rejected" | "acknowledged" | "none" =>
|
|
||||||
{
|
{
|
||||||
switch (getCookie("CC"))
|
switch (getCookie("CC"))
|
||||||
{
|
{
|
||||||
case "1": return "accepted";
|
case "1": return "accepted";
|
||||||
case "0": return "rejected";
|
case "0": return "rejected";
|
||||||
case "": return "acknowledged";
|
|
||||||
default: return "none";
|
default: return "none";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,13 +9,3 @@ export const analyticsEnabled = (): boolean =>
|
|||||||
unstable_noStore();
|
unstable_noStore();
|
||||||
return !!process.env.CLARITY_ID;
|
return !!process.env.CLARITY_ID;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if Clarity requires explicit consent
|
|
||||||
* @returns true if Clarity requires explicit consent
|
|
||||||
*/
|
|
||||||
export const requireExplicitConsent = (): boolean =>
|
|
||||||
{
|
|
||||||
unstable_noStore();
|
|
||||||
return process.env.CLARITY_CONSENT === "1";
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import Button from "@/_components/Button";
|
|||||||
import RevokeConsentButton from "@/_components/RevokeConsentButton";
|
import RevokeConsentButton from "@/_components/RevokeConsentButton";
|
||||||
import { canonicalName, getTitle } from "@/_data/metadata";
|
import { canonicalName, getTitle } from "@/_data/metadata";
|
||||||
import ThirdPartyAttribution from "@/_data/ThirdPartyAttributiont";
|
import ThirdPartyAttribution from "@/_data/ThirdPartyAttributiont";
|
||||||
import { analyticsEnabled, requireExplicitConsent } from "@/_utils/analytics/server";
|
import { analyticsEnabled } from "@/_utils/analytics/server";
|
||||||
import { ArrowLeft24Regular, ArrowRight24Regular } from "@fluentui/react-icons";
|
import { ArrowLeft24Regular, ArrowRight24Regular } from "@fluentui/react-icons";
|
||||||
import { Metadata } from "next";
|
import { Metadata } from "next";
|
||||||
import { unstable_noStore } from "next/cache";
|
import { unstable_noStore } from "next/cache";
|
||||||
@@ -45,17 +45,15 @@ const AttributionPage: React.FC = () => (
|
|||||||
If the "Do Not Track" option is enabled in your browser,
|
If the "Do Not Track" option is enabled in your browser,
|
||||||
the website will not execute any tracking code.
|
the website will not execute any tracking code.
|
||||||
</p>
|
</p>
|
||||||
{ requireExplicitConsent() &&
|
<p>
|
||||||
<p>
|
If you previously gave your consent to use cookies,
|
||||||
If you previously gave your consent to use cookies,
|
you can revoke it by clicking "Revoke my consent" button on this page below
|
||||||
you can revoke it by clicking "Revoke my consent" button on this page below
|
(the button is available only if the consent was given).
|
||||||
(the button is available only if the consent was given).
|
Recorded data will be deleted after 30-day retention period.
|
||||||
Recorded data will be deleted after 30-day retention period.
|
</p>
|
||||||
</p>
|
|
||||||
}
|
|
||||||
|
|
||||||
<div className={ cls.buttonRow }>
|
<div className={ cls.buttonRow }>
|
||||||
{ requireExplicitConsent() && <RevokeConsentButton /> }
|
<RevokeConsentButton />
|
||||||
<Button appearance="secondary"
|
<Button appearance="secondary"
|
||||||
href="https://learn.microsoft.com/clarity/faq#privacy" target="_blank"
|
href="https://learn.microsoft.com/clarity/faq#privacy" target="_blank"
|
||||||
iconAfter={ <ArrowRight24Regular /> }>
|
iconAfter={ <ArrowRight24Regular /> }>
|
||||||
|
|||||||
+2
-2
@@ -5,7 +5,7 @@ import { PropsWithChildren } from "react";
|
|||||||
import CookieBanner from "./_components/CookieBanner";
|
import CookieBanner from "./_components/CookieBanner";
|
||||||
import Footer from "./_components/Footer";
|
import Footer from "./_components/Footer";
|
||||||
import Header from "./_components/Header";
|
import Header from "./_components/Header";
|
||||||
import { analyticsEnabled, requireExplicitConsent } from "./_utils/analytics/server";
|
import { analyticsEnabled } from "./_utils/analytics/server";
|
||||||
import fonts from "./fonts";
|
import fonts from "./fonts";
|
||||||
import "./_styles/globals.scss";
|
import "./_styles/globals.scss";
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ export default function RootLayout(props: PropsWithChildren)
|
|||||||
}
|
}
|
||||||
<body>
|
<body>
|
||||||
{ analyticsEnabled() &&
|
{ analyticsEnabled() &&
|
||||||
<CookieBanner askForConsent={ requireExplicitConsent() } />
|
<CookieBanner />
|
||||||
}
|
}
|
||||||
|
|
||||||
<Header />
|
<Header />
|
||||||
|
|||||||
Reference in New Issue
Block a user