1
0
mirror of https://github.com/XFox111/my-website.git synced 2026-04-22 07:28:01 +03:00

feat!: added cookie consent banner and management system

This commit is contained in:
2024-08-21 00:22:49 +00:00
parent dceb2e44b7
commit 67222999a9
10 changed files with 330 additions and 17 deletions
+83
View File
@@ -0,0 +1,83 @@
@import "../theme.scss";
.banner
{
@include flex(row);
position: fixed;
left: 0;
bottom: 8%;
background-color: $colorNeutralBackground2;
z-index: 20;
.learnMore
{
gap: $spacingL;
padding: $spacingMNudge $spacingL;
background-size: $spacingMNudge 100%;
flex-grow: 1;
justify-content: flex-start;
p
{
color: $colorNeutralForeground2;
@include body1;
span
{
color: $colorNeutralForeground1;
@include body2($fontFamilyBaseAlt);
}
}
&:hover,
&:focus-visible
{
p,
p > span
{
color: $colorNeutralForegroundInverted;
}
}
}
.dismiss
{
border-left: none;
}
.controls
{
display: grid;
grid-auto-flow: column;
@media screen and (min-width: 769px)
{
> button
{
border-left: none;
}
}
}
@media screen and (max-width: 768px)
{
width: 100%;
bottom: 0;
&:not(:has(> .dismiss))
{
flex-flow: column;
.learnMore
{
border-bottom: none;
}
.controls > button:last-child
{
border-left: none;
}
}
}
}
+74
View File
@@ -0,0 +1,74 @@
"use client";
import { acceptCookies, dismissCookies, getCookieChoice, rejectCookies, requireExcplicitConsent } from "@/_utils/analytics/client";
import { Dismiss24Regular } from "@fluentui/react-icons";
import React, { useCallback, useEffect, useState } from "react";
import Button from "./Button";
import cls from "./CookieBanner.module.scss";
const CookieBanner: React.FC = () =>
{
const [visible, setVisible] = useState(false);
useEffect(() =>
{
const choice = getCookieChoice();
setVisible(choice === "none");
// Since Clarity cookies expiration dates extend well beyond 60 days,
// we need to terminate them manually once our consent tracking cookie expires.
if (choice !== "accepted")
window.clarity?.("consent", false);
}, []);
const accept = useCallback(() =>
{
acceptCookies();
setVisible(false);
}, []);
const reject = useCallback(() =>
{
rejectCookies();
setVisible(false);
}, []);
const dismiss = useCallback(() =>
{
dismissCookies();
setVisible(false);
}, []);
if (!visible)
return null;
return (
<div className={ `cookie-banner ${cls.banner}` }>
<Button
as="next" href="/attribution"
className={ cls.learnMore }
aria-label="We use cookies for analytics purposes. Click to learn more"
icon={ <span>🍪</span> }>
<p aria-hidden>
<span>We use cookies for analytics purposes</span><br />
Click to learn more
</p>
</Button>
{ requireExcplicitConsent ?
<div className={ cls.controls }>
<Button onClick={ accept }>Accept</Button>
<Button onClick={ reject }>Reject</Button>
</div>
:
<Button
title="Dismiss" icon={ <Dismiss24Regular /> }
onClick={ dismiss } className={ cls.dismiss } />
}
</div>
);
};
export default CookieBanner;
+30
View File
@@ -0,0 +1,30 @@
"use client";
import Button from "@/_components/Button";
import React, { useCallback, useEffect, useState } from "react";
import { getCookieChoice, rejectCookies } from "../_utils/analytics/client";
const RevokeConsentButton: React.FC = () =>
{
const [hasConsent, setHasConsent] = useState<boolean>(false);
useEffect(() =>
{
console.log("getCookieChoice", getCookieChoice());
setHasConsent(getCookieChoice() === "accepted");
}, []);
const revoke = useCallback(() =>
{
rejectCookies();
setHasConsent(false);
window.alert("Your consent has been revoked");
}, []);
if (!hasConsent)
return null;
return <Button onClick={ revoke }>Revoke my consent</Button>;
};
export default RevokeConsentButton;