Compare commits
2 Commits
a36aca1ad3
...
4901eb8477
| Author | SHA1 | Date | |
|---|---|---|---|
| 4901eb8477 | |||
| ca55b7a282 |
@ -14,12 +14,12 @@ export async function onUpdateConsentCookie(cookieName: ConsentCookies, cookieVa
|
|||||||
return { ok: true, message: "Updated consent cookie", cookieName, cookieValue };
|
return { ok: true, message: "Updated consent cookie", cookieName, cookieValue };
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function onAcceptAllConsentCookie() {
|
export async function onSetAllConsentCookie(cookieValue: boolean) {
|
||||||
const context = getTelefuncContext();
|
const context = getTelefuncContext();
|
||||||
const { reply } = context;
|
const { reply } = context;
|
||||||
|
|
||||||
CookieParser.set(reply, "analytics", "true", 365);
|
CookieParser.set(reply, "analytics", cookieValue.toString(), 365);
|
||||||
CookieParser.set(reply, "customization", "true", 365);
|
CookieParser.set(reply, "customization", cookieValue.toString(), 365);
|
||||||
|
|
||||||
return { ok: true, message: "Updated consents cookies" };
|
return { ok: true, message: "Updated consents cookies" };
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { onUpdateConsentCookie, onAcceptAllConsentCookie, type ConsentCookies } from "./Cookies.telefunc";
|
import { onUpdateConsentCookie, onSetAllConsentCookie, type ConsentCookies } from "./Cookies.telefunc";
|
||||||
import React, { useState, useContext, createContext } from "react";
|
import React, { useState, useContext, createContext, useMemo } from "react";
|
||||||
import { usePageContext } from "vike-react/usePageContext";
|
import { usePageContext } from "vike-react/usePageContext";
|
||||||
import { reload } from "vike/client/router";
|
import { reload } from "vike/client/router";
|
||||||
import { Button } from "@syntax/Button";
|
import { Button } from "@syntax/Button";
|
||||||
@ -13,7 +13,7 @@ export const CookiesContext = createContext<{
|
|||||||
customization: boolean;
|
customization: boolean;
|
||||||
};
|
};
|
||||||
setCookie: (cookieName: ConsentCookies, cookieValue: boolean) => void;
|
setCookie: (cookieName: ConsentCookies, cookieValue: boolean) => void;
|
||||||
acceptAll: () => void;
|
setAllCookies: (cookieValue: boolean) => void;
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
setIsOpen: (isOpen: boolean) => void;
|
setIsOpen: (isOpen: boolean) => void;
|
||||||
isSelectionOpen: boolean;
|
isSelectionOpen: boolean;
|
||||||
@ -24,7 +24,7 @@ export const CookiesContext = createContext<{
|
|||||||
customization: false,
|
customization: false,
|
||||||
},
|
},
|
||||||
setCookie: (_cookieName: ConsentCookies, _cookieValue: boolean) => {},
|
setCookie: (_cookieName: ConsentCookies, _cookieValue: boolean) => {},
|
||||||
acceptAll: () => {},
|
setAllCookies: () => {},
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
setIsOpen: () => {},
|
setIsOpen: () => {},
|
||||||
isSelectionOpen: false,
|
isSelectionOpen: false,
|
||||||
@ -44,34 +44,31 @@ export function CookiesContainer(props: CookiesContainerProps) {
|
|||||||
return !Object.keys(cookies.consent).every((value) => value);
|
return !Object.keys(cookies.consent).every((value) => value);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const toastPromiseMessages = useMemo(
|
||||||
|
() => ({
|
||||||
|
pending: "Mise à jour des cookies...",
|
||||||
|
success: "Cookies mis à jour !",
|
||||||
|
error: "Erreur lors de la mise à jour des cookies",
|
||||||
|
}),
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
const handleUpdateCookie = (cookieName: ConsentCookies, cookieValue: boolean) => {
|
const handleUpdateCookie = (cookieName: ConsentCookies, cookieValue: boolean) => {
|
||||||
setConsentCookies((prev) => ({
|
setConsentCookies((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
[cookieName]: cookieValue,
|
[cookieName]: cookieValue,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
toast
|
toast.promise(onUpdateConsentCookie(cookieName, cookieValue), toastPromiseMessages).then(() => {
|
||||||
.promise(onUpdateConsentCookie(cookieName, cookieValue), {
|
|
||||||
pending: "Mise à jour des cookies...",
|
|
||||||
success: "Cookies mis à jour !",
|
|
||||||
error: "Erreur lors de la mise à jour des cookies",
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
reload();
|
reload();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleAcceptAll = () => {
|
const handleSetAll = (value: boolean) => {
|
||||||
setConsentCookies({ analytics: true, customization: true });
|
setConsentCookies({ analytics: true, customization: true });
|
||||||
|
|
||||||
toast
|
toast.promise(onSetAllConsentCookie(value), toastPromiseMessages).then(() => {
|
||||||
.promise(onAcceptAllConsentCookie(), {
|
|
||||||
pending: "Acceptation des cookies...",
|
|
||||||
success: "Cookies acceptés !",
|
|
||||||
error: "Erreur lors de l'acceptation des cookies",
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
setIsSelectionOpen(false);
|
setIsSelectionOpen(false);
|
||||||
reload();
|
reload();
|
||||||
@ -83,7 +80,7 @@ export function CookiesContainer(props: CookiesContainerProps) {
|
|||||||
value={{
|
value={{
|
||||||
cookies: consentCookies,
|
cookies: consentCookies,
|
||||||
setCookie: handleUpdateCookie,
|
setCookie: handleUpdateCookie,
|
||||||
acceptAll: handleAcceptAll,
|
setAllCookies: handleSetAll,
|
||||||
isOpen,
|
isOpen,
|
||||||
setIsOpen,
|
setIsOpen,
|
||||||
isSelectionOpen,
|
isSelectionOpen,
|
||||||
@ -171,7 +168,7 @@ function CookieModal() {
|
|||||||
<div className="grid items-center grid-cols-3 justify-between bg-slate-100 dark:bg-slate-700">
|
<div className="grid items-center grid-cols-3 justify-between bg-slate-100 dark:bg-slate-700">
|
||||||
<button
|
<button
|
||||||
className="cursor-pointer px-2 py-1 text-slate-600 dark:text-slate-300"
|
className="cursor-pointer px-2 py-1 text-slate-600 dark:text-slate-300"
|
||||||
onClick={() => cookiesContext.setIsOpen(false)}
|
onClick={() => cookiesContext.setAllCookies(false)}
|
||||||
>
|
>
|
||||||
Non merci
|
Non merci
|
||||||
</button>
|
</button>
|
||||||
@ -185,7 +182,7 @@ function CookieModal() {
|
|||||||
|
|
||||||
<button
|
<button
|
||||||
className="cursor-pointer px-2 py-1 font-bold text-white dark:text-black bg-violet-600 dark:bg-violet-300"
|
className="cursor-pointer px-2 py-1 font-bold text-white dark:text-black bg-violet-600 dark:bg-violet-300"
|
||||||
onClick={cookiesContext.acceptAll}
|
onClick={() => cookiesContext.setAllCookies(true)}
|
||||||
>
|
>
|
||||||
Oui, j‘ai faim !
|
Oui, j‘ai faim !
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@ -134,7 +134,7 @@ export default function DefaultLayout({ children }: { children: React.ReactNode
|
|||||||
<Navigation />
|
<Navigation />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{children}
|
<div className="grow">{children}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Footer />
|
<Footer />
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import React from "react";
|
|||||||
|
|
||||||
export function Page() {
|
export function Page() {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-4 p-4 text-slate-700 dark:text-slate-300">
|
<div className="px-4 py-16 lg:max-w-none lg:pr-0 lg:pl-8 xl:px-16 flex flex-col gap-4 text-slate-700 dark:text-slate-300">
|
||||||
<h1 className="font-display text-3xl tracking-tight text-slate-900 dark:text-white">Mentions légales</h1>
|
<h1 className="font-display text-3xl tracking-tight text-slate-900 dark:text-white">Mentions légales</h1>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
|
|||||||
@ -7,7 +7,7 @@ export function Page() {
|
|||||||
const { setIsOpen } = useContext(CookiesContext);
|
const { setIsOpen } = useContext(CookiesContext);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-4 p-4 text-slate-700 dark:text-slate-300">
|
<div className="px-4 py-16 lg:max-w-none lg:pr-0 lg:pl-8 xl:px-16 flex flex-col gap-4 text-slate-700 dark:text-slate-300">
|
||||||
<h1 className="font-display text-3xl tracking-tight text-slate-900 dark:text-white">
|
<h1 className="font-display text-3xl tracking-tight text-slate-900 dark:text-white">
|
||||||
Politique de confidentialité
|
Politique de confidentialité
|
||||||
</h1>
|
</h1>
|
||||||
|
|||||||
@ -11,3 +11,12 @@ export async function onUpdateThemeCookie(value: Theme) {
|
|||||||
|
|
||||||
return { ok: true, message: "Updated theme cookie", value };
|
return { ok: true, message: "Updated theme cookie", value };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function onDeleteThemeCookie() {
|
||||||
|
const context = getTelefuncContext();
|
||||||
|
const { reply } = context;
|
||||||
|
|
||||||
|
CookieParser.delete(reply, "theme");
|
||||||
|
|
||||||
|
return { ok: true, message: "Deleted theme cookie" };
|
||||||
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { onUpdateThemeCookie } from "@/providers/ThemeProvider.telefunc";
|
import { onUpdateThemeCookie, onDeleteThemeCookie } from "@/providers/ThemeProvider.telefunc";
|
||||||
import { ThemeContext, type Theme } from "@/contexts/ThemeContext";
|
import { ThemeContext, type Theme } from "@/contexts/ThemeContext";
|
||||||
import { usePageContext } from "vike-react/usePageContext";
|
import { usePageContext } from "vike-react/usePageContext";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
@ -23,8 +23,12 @@ export function ThemeProvider(props: ThemeProviderProps) {
|
|||||||
onUpdateThemeCookie(theme).catch(() => {
|
onUpdateThemeCookie(theme).catch(() => {
|
||||||
toast.error("Erreur lors de la mise à jour du cookie de thème");
|
toast.error("Erreur lors de la mise à jour du cookie de thème");
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
onDeleteThemeCookie().catch(() => {
|
||||||
|
toast.error("Erreur lors de la suppression du cookie de thème");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}, [theme]);
|
}, [theme, cookies.consent.customization]);
|
||||||
|
|
||||||
return <ThemeContext.Provider value={{ theme, setTheme }}>{props.children}</ThemeContext.Provider>;
|
return <ThemeContext.Provider value={{ theme, setTheme }}>{props.children}</ThemeContext.Provider>;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,6 +17,23 @@ export class CookieParser {
|
|||||||
this.parse();
|
this.parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static buildOptions(daysDuration: number | Date) {
|
||||||
|
let expires: Date;
|
||||||
|
|
||||||
|
if (daysDuration instanceof Date) {
|
||||||
|
expires = daysDuration;
|
||||||
|
} else {
|
||||||
|
expires = new Date(Date.now() + 60 * 60 * 24 * daysDuration * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
path: "/",
|
||||||
|
httpOnly: true,
|
||||||
|
secure: process.env.NODE_ENV === "production",
|
||||||
|
expires,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
parse() {
|
parse() {
|
||||||
this.cookies = this.rawCookies.split("; ").reduce(
|
this.cookies = this.rawCookies.split("; ").reduce(
|
||||||
(acc, cookie) => {
|
(acc, cookie) => {
|
||||||
@ -38,15 +55,16 @@ export class CookieParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static set(reply: FastifyReply, key: CookieKeys, value: string, daysDuration = 30): FastifyReply {
|
static set(reply: FastifyReply, key: CookieKeys, value: string, daysDuration = 30): FastifyReply {
|
||||||
const options = {
|
const options = CookieParser.buildOptions(daysDuration);
|
||||||
path: "/",
|
|
||||||
httpOnly: true,
|
|
||||||
secure: process.env.NODE_ENV === "production",
|
|
||||||
expires: new Date(Date.now() + 60 * 60 * 24 * daysDuration * 1000),
|
|
||||||
};
|
|
||||||
|
|
||||||
reply.setCookie(key, value, options);
|
reply.setCookie(key, value, options);
|
||||||
|
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static delete(reply: FastifyReply, key: CookieKeys): FastifyReply {
|
||||||
|
const options = CookieParser.buildOptions(new Date("1900-01-01"));
|
||||||
|
reply.setCookie(key, "", options);
|
||||||
|
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user