mirror of
https://github.com/Sosokker/B2D-Ventures.git
synced 2025-12-19 05:54:06 +01:00
feat: add cookie consent banner and page
This commit is contained in:
parent
05d2ad739c
commit
d9415534fb
@ -38,6 +38,13 @@ export function NavSidebar() {
|
||||
</li>
|
||||
</Link>
|
||||
<Separator className="bg-gray-200 dark:bg-gray-700" />
|
||||
|
||||
<Link href="/cookies">
|
||||
<li className="flex items-center p-2 relative group hover:scale-105 transition-all duration-200 ease-in-out rounded-md">
|
||||
<span>Cookies</span>
|
||||
<div className="absolute bottom-0 left-0 w-full h-[2px] bg-blue-600 scale-x-0 group-hover:scale-x-100 transition-all duration-300"></div>
|
||||
</li>
|
||||
</Link>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
|
||||
104
src/app/(legal)/cookies/page.tsx
Normal file
104
src/app/(legal)/cookies/page.tsx
Normal file
@ -0,0 +1,104 @@
|
||||
"use client";
|
||||
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import TableOfContent from "../Toc";
|
||||
import { NavSidebar } from "../NavigationSidebar";
|
||||
|
||||
const UseOfCookies = () => {
|
||||
const sections = [
|
||||
{ id: "introduction", title: "Introduction" },
|
||||
{ id: "what-are-cookies", title: "What Are Cookies?" },
|
||||
{ id: "types-of-cookies", title: "Types of Cookies We Use" },
|
||||
{ id: "why-we-use-cookies", title: "Why We Use Cookies" },
|
||||
{ id: "managing-cookies", title: "Managing Your Cookie Preferences" },
|
||||
{ id: "third-party-cookies", title: "Third-Party Cookies" },
|
||||
{ id: "changes", title: "Changes to Cookie Policy" },
|
||||
{ id: "contact", title: "Contact Information" },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="container max-w-screen-xl flex mt-5">
|
||||
<div className="flex gap-2">
|
||||
<NavSidebar />
|
||||
<TableOfContent sections={sections} />
|
||||
</div>
|
||||
|
||||
<div className="flex-1 ml-4">
|
||||
<Card className="w-full max-w-3xl bg-white dark:bg-gray-800 shadow-lg rounded-lg">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-3xl text-blue-600 dark:text-blue-400">Use of Cookies</CardTitle>
|
||||
<CardDescription className="text-sm text-gray-500 dark:text-gray-400">
|
||||
Last Updated: November 17, 2024
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="prose dark:prose-invert text-gray-800 dark:text-gray-200">
|
||||
<h2 id="introduction">1. Introduction</h2>
|
||||
<p>
|
||||
Our Website uses cookies to improve functionality, analyze performance, and personalize your experience.
|
||||
This policy explains what cookies are, how we use them, and your options for managing them.
|
||||
</p>
|
||||
|
||||
<h2 id="what-are-cookies">2. What Are Cookies?</h2>
|
||||
<p>
|
||||
Cookies are small text files stored on your device when you visit a website. They help the website
|
||||
remember your preferences, improve functionality, and provide analytical insights.
|
||||
</p>
|
||||
|
||||
<h2 id="types-of-cookies">3. Types of Cookies We Use</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<span className="font-bold">Essential Cookies </span>Required for the core functionality of the
|
||||
Website, such as navigating pages and accessing secure areas.
|
||||
</li>
|
||||
<li>
|
||||
<span className="font-bold">Analytics Cookies </span>
|
||||
Collect data on user behavior to improve Website performance and user experience.
|
||||
</li>
|
||||
<li>
|
||||
<span className="font-bold">Personalization Cookies </span>Tailor content and features to match your
|
||||
preferences.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="why-we-use-cookies">4. Why We Use Cookies</h2>
|
||||
<span>
|
||||
We use cookies to:
|
||||
<ul>
|
||||
<li>Ensure the Website functions properly.</li>
|
||||
<li>Understand and analyze user behavior.</li>
|
||||
<li>Provide a personalized browsing experience.</li>
|
||||
<li>Deliver relevant advertisements and content.</li>
|
||||
</ul>
|
||||
</span>
|
||||
|
||||
<h2 id="managing-cookies">5. Managing Your Cookie Preferences</h2>
|
||||
<p>
|
||||
You can manage or disable cookies through your browser settings. Note that disabling cookies may affect
|
||||
your experience on our Website. For detailed instructions, refer to your browser's help section.
|
||||
</p>
|
||||
|
||||
<h2 id="third-party-cookies">6. Third-Party Cookies</h2>
|
||||
<p>
|
||||
Some cookies are set by third-party services we use, such as analytics or advertising platforms. These
|
||||
cookies are subject to the policies of the respective third parties.
|
||||
</p>
|
||||
|
||||
<h2 id="changes">7. Changes to Cookie Policy</h2>
|
||||
<p>
|
||||
We may update this cookie policy periodically to reflect changes in technology or legal requirements.
|
||||
Any updates will be posted on this page with the updated date.
|
||||
</p>
|
||||
|
||||
<h2 id="contact">8. Contact Information</h2>
|
||||
<p>For questions about this policy or to exercise your rights, contact us at privacy@b2dventure.com.</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
<CardFooter className="flex justify-center"></CardFooter>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default UseOfCookies;
|
||||
@ -9,6 +9,8 @@ import { NavigationBar } from "@/components/navigationBar/nav";
|
||||
import { Toaster } from "react-hot-toast";
|
||||
import { SiteFooter } from "@/components/siteFooter";
|
||||
|
||||
import CookieConsent from "@/components/CookieConsent";
|
||||
|
||||
const montserrat = Montserrat({
|
||||
subsets: ["latin"],
|
||||
display: "swap",
|
||||
@ -44,6 +46,7 @@ export default function RootLayout({ children }: RootLayoutProps) {
|
||||
</div>
|
||||
<NavigationBar />
|
||||
<div className="flex-1 bg-background">{children}</div>
|
||||
<CookieConsent />
|
||||
</div>
|
||||
<SiteFooter />
|
||||
</ThemeProvider>
|
||||
|
||||
158
src/components/CookieConsent.tsx
Normal file
158
src/components/CookieConsent.tsx
Normal file
@ -0,0 +1,158 @@
|
||||
"use client";
|
||||
|
||||
import { CookieIcon } from "lucide-react";
|
||||
import { Button } from "./ui/button";
|
||||
import { useEffect, useState } from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import Link from "next/link";
|
||||
import { createSupabaseClient } from "@/lib/supabase/clientComponentClient";
|
||||
import useSession from "@/lib/supabase/useSession";
|
||||
|
||||
export default function CookieConsent({
|
||||
variant = "default",
|
||||
demo = false,
|
||||
onAcceptCallback = () => {},
|
||||
onDeclineCallback = () => {},
|
||||
}) {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [hide, setHide] = useState(false);
|
||||
const supabase = createSupabaseClient();
|
||||
|
||||
const { session, loading } = useSession();
|
||||
|
||||
const userId = session?.user?.id;
|
||||
|
||||
const updateConsent = async (consent: boolean) => {
|
||||
try {
|
||||
if (!userId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { error } = await supabase.from("profiles").update({ consent }).eq("id", userId);
|
||||
|
||||
if (error) {
|
||||
console.error("Failed to update consent:", error.message);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Unexpected error updating consent:", e);
|
||||
}
|
||||
};
|
||||
|
||||
const accept = () => {
|
||||
setIsOpen(false);
|
||||
document.cookie = "cookieConsent=true; expires=Fri, 31 Dec 9999 23:59:59 GMT";
|
||||
setTimeout(() => {
|
||||
setHide(true);
|
||||
}, 700);
|
||||
onAcceptCallback();
|
||||
updateConsent(true);
|
||||
};
|
||||
|
||||
const decline = () => {
|
||||
setIsOpen(false);
|
||||
setTimeout(() => {
|
||||
setHide(true);
|
||||
}, 700);
|
||||
onDeclineCallback();
|
||||
updateConsent(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
try {
|
||||
setIsOpen(true);
|
||||
if (document.cookie.includes("cookieConsent=true")) {
|
||||
if (!demo) {
|
||||
setIsOpen(false);
|
||||
setTimeout(() => {
|
||||
setHide(true);
|
||||
}, 700);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// console.log("Error: ", e);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
if (loading) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return variant == "default" ? (
|
||||
<div
|
||||
className={cn(
|
||||
"fixed z-[200] bottom-0 left-0 right-0 sm:left-4 sm:bottom-4 w-full sm:max-w-md duration-700",
|
||||
!isOpen
|
||||
? "transition-[opacity,transform] translate-y-8 opacity-0"
|
||||
: "transition-[opacity,transform] translate-y-0 opacity-100",
|
||||
hide && "hidden"
|
||||
)}
|
||||
>
|
||||
<div className="dark:bg-card bg-background rounded-md m-3 border border-border shadow-lg">
|
||||
<div className="grid gap-2">
|
||||
<div className="border-b border-border h-14 flex items-center justify-between p-4">
|
||||
<h1 className="text-lg font-medium">We use cookies</h1>
|
||||
<CookieIcon className="h-[1.2rem] w-[1.2rem]" />
|
||||
</div>
|
||||
<div className="p-4">
|
||||
<p className="text-sm font-normal text-start">
|
||||
We use cookies to ensure you get the best experience on our website. For more information on how we use
|
||||
cookies, please see our cookie policy.
|
||||
<br />
|
||||
<br />
|
||||
<span className="text-xs">
|
||||
By clicking "<span className="font-medium opacity-80">Accept</span>", you agree to our use of
|
||||
cookies.
|
||||
</span>
|
||||
<br />
|
||||
<Link href="/cookies" className="text-xs underline">
|
||||
Learn more.
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex gap-2 p-4 py-5 border-t border-border dark:bg-background/20">
|
||||
<Button onClick={accept} className="w-full">
|
||||
Accept
|
||||
</Button>
|
||||
<Button onClick={decline} className="w-full" variant="secondary">
|
||||
Decline
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
variant == "small" && (
|
||||
<div
|
||||
className={cn(
|
||||
"fixed z-[200] bottom-0 left-0 right-0 sm:left-4 sm:bottom-4 w-full sm:max-w-md duration-700",
|
||||
!isOpen
|
||||
? "transition-[opacity,transform] translate-y-8 opacity-0"
|
||||
: "transition-[opacity,transform] translate-y-0 opacity-100",
|
||||
hide && "hidden"
|
||||
)}
|
||||
>
|
||||
<div className="m-3 dark:bg-card bg-background border border-border rounded-lg">
|
||||
<div className="flex items-center justify-between p-3">
|
||||
<h1 className="text-lg font-medium">We use cookies</h1>
|
||||
<CookieIcon className="h-[1.2rem] w-[1.2rem]" />
|
||||
</div>
|
||||
<div className="p-3 -mt-2">
|
||||
<p className="text-sm text-left text-muted-foreground">
|
||||
We use cookies to ensure you get the best experience on our website. For more information on how we use
|
||||
cookies, please see our cookie policy.
|
||||
</p>
|
||||
</div>
|
||||
<div className="p-3 flex items-center gap-2 mt-2 border-t">
|
||||
<Button onClick={accept} className="w-full h-9 rounded-full">
|
||||
accept
|
||||
</Button>
|
||||
<Button onClick={decline} className="w-full h-9 rounded-full" variant="outline">
|
||||
decline
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user