1
0
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:
2025-09-01 19:16:55 +00:00
parent ac7a3e2213
commit e16ab1f6f6
7 changed files with 25 additions and 65 deletions
-1
View File
@@ -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)
+8 -16
View File
@@ -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;
}
} }
} }
} }
+6 -19
View File
@@ -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>
); );
+1 -7
View File
@@ -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";
} }
}; };
-10
View File
@@ -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";
};
+8 -10
View File
@@ -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 &quot;Do Not Track&quot; option is enabled in your browser, If the &quot;Do Not Track&quot; 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 &quot;Revoke my consent&quot; button on this page below
you can revoke it by clicking &quot;Revoke my consent&quot; 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
View File
@@ -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 />