diff --git a/app/components/common/Toggle.tsx b/app/components/common/Toggle.tsx
new file mode 100644
index 0000000..22eb730
--- /dev/null
+++ b/app/components/common/Toggle.tsx
@@ -0,0 +1,44 @@
+import clsx from "clsx";
+
+type ToggleProps = {
+ id: string;
+ label: string;
+ onChange?: (checked: boolean) => void;
+ checked: boolean;
+};
+
+export function Toggle(props: ToggleProps) {
+ return (
+
+ props.onChange?.(e.target.checked)}
+ checked={props.checked}
+ aria-checked={props.checked}
+ role="switch"
+ aria-label={props.label}
+ />
+
+
+
+ );
+}
diff --git a/app/components/syntax/Button.tsx b/app/components/syntax/Button.tsx
index 6b5234d..119063f 100644
--- a/app/components/syntax/Button.tsx
+++ b/app/components/syntax/Button.tsx
@@ -7,6 +7,8 @@ const variantStyles = {
"bg-violet-300 font-semibold text-slate-900 hover:bg-violet-200 focus:outline-hidden focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-violet-300/50 active:bg-violet-500",
secondary:
"bg-slate-800 font-medium text-white hover:bg-slate-700 focus:outline-hidden focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white/50 active:text-slate-400",
+ ghost:
+ "bg-transparent font-medium text-slate-900 dark:text-slate-400 hover:bg-slate-100 focus:outline-hidden focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-slate-300/50 active:bg-slate-200",
};
const sizeStyles = {
diff --git a/app/layouts/LayoutDefault.tsx b/app/layouts/LayoutDefault.tsx
index 35181ee..507ca1f 100644
--- a/app/layouts/LayoutDefault.tsx
+++ b/app/layouts/LayoutDefault.tsx
@@ -2,11 +2,14 @@ import { MobileNavigation } from "@syntax/MobileNavigation";
import { usePageContext } from "vike-react/usePageContext";
import { ThemeProvider } from "@/providers/ThemeProvider";
import { ThemeSelector } from "@syntax/ThemeSelector";
+import { Button } from "@/components/syntax/Button";
+import { Toggle } from "@/components/common/Toggle";
import { clientOnly } from "vike-react/clientOnly";
import React, { useEffect, useState } from "react";
import { ToastContainer } from "react-toastify";
import { Navigation } from "@syntax/Navigation";
import { Link } from "@/components/common/Link";
+import { reload } from "vike/client/router";
import { Hero } from "@syntax/Hero";
import { Logo } from "@syntax/Logo";
import clsx from "clsx";
@@ -74,12 +77,107 @@ function Header() {
);
}
+function CookieModal() {
+ const { cookies } = usePageContext();
+
+ const [consentCookies, setConsentCookies] = useState(cookies.consent);
+ const [isSelectionOpen, setIsSelectionOpen] = useState(false);
+ const [isOpen, setIsOpen] = useState(() => {
+ return Object.keys(cookies.consent).every((value) => value);
+ });
+
+ if (isSelectionOpen) {
+ return (
+
+
+
Personnalisation des cookies 🍪
+
+
+ {
+ setConsentCookies((prev) => ({ ...prev, analytics: checked }));
+ reload();
+ }}
+ />
+
+ {
+ setConsentCookies((prev) => ({ ...prev, customization: checked }));
+ reload();
+ }}
+ />
+
+
+
+ );
+ }
+
+ return (
+
+
+
+ Coucou c'est nous...
+
+ les cookies ! 🍪
+
+
+
+ On ne t'embête pas longtemps, on te laisse même le choix (si ça c'est pas la classe 😎).
+
+
+
+ Si tu veux en savoir plus, tu peux consulter la page{" "}
+
+ Politique de confidentialité
+
+ .
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
export default function DefaultLayout({ children }: { children: React.ReactNode }) {
const { urlPathname, cookies } = usePageContext();
const isHomePage = urlPathname === "/";
return (
+
+