From 4901eb8477b3005c7ab7e493e26ec94e748f5b6e Mon Sep 17 00:00:00 2001 From: GauthierWebDev Date: Fri, 18 Apr 2025 17:04:35 +0200 Subject: [PATCH] feat: Update consent cookie setting function --- app/components/common/Cookies.telefunc.ts | 6 +- app/components/common/Cookies.tsx | 55 +++++++++---------- app/pages/mentions-legales/+Page.tsx | 2 +- .../politique-de-confidentialite/+Page.tsx | 2 +- app/providers/ThemeProvider.telefunc.ts | 9 +++ app/providers/ThemeProvider.tsx | 8 ++- app/services/CookieParser.ts | 32 ++++++++--- 7 files changed, 71 insertions(+), 43 deletions(-) diff --git a/app/components/common/Cookies.telefunc.ts b/app/components/common/Cookies.telefunc.ts index e58234e..723a2c2 100644 --- a/app/components/common/Cookies.telefunc.ts +++ b/app/components/common/Cookies.telefunc.ts @@ -14,12 +14,12 @@ export async function onUpdateConsentCookie(cookieName: ConsentCookies, cookieVa return { ok: true, message: "Updated consent cookie", cookieName, cookieValue }; } -export async function onAcceptAllConsentCookie() { +export async function onSetAllConsentCookie(cookieValue: boolean) { const context = getTelefuncContext(); const { reply } = context; - CookieParser.set(reply, "analytics", "true", 365); - CookieParser.set(reply, "customization", "true", 365); + CookieParser.set(reply, "analytics", cookieValue.toString(), 365); + CookieParser.set(reply, "customization", cookieValue.toString(), 365); return { ok: true, message: "Updated consents cookies" }; } diff --git a/app/components/common/Cookies.tsx b/app/components/common/Cookies.tsx index a9d3f20..1074590 100644 --- a/app/components/common/Cookies.tsx +++ b/app/components/common/Cookies.tsx @@ -1,5 +1,5 @@ -import { onUpdateConsentCookie, onAcceptAllConsentCookie, type ConsentCookies } from "./Cookies.telefunc"; -import React, { useState, useContext, createContext } from "react"; +import { onUpdateConsentCookie, onSetAllConsentCookie, type ConsentCookies } from "./Cookies.telefunc"; +import React, { useState, useContext, createContext, useMemo } from "react"; import { usePageContext } from "vike-react/usePageContext"; import { reload } from "vike/client/router"; import { Button } from "@syntax/Button"; @@ -13,7 +13,7 @@ export const CookiesContext = createContext<{ customization: boolean; }; setCookie: (cookieName: ConsentCookies, cookieValue: boolean) => void; - acceptAll: () => void; + setAllCookies: (cookieValue: boolean) => void; isOpen: boolean; setIsOpen: (isOpen: boolean) => void; isSelectionOpen: boolean; @@ -24,7 +24,7 @@ export const CookiesContext = createContext<{ customization: false, }, setCookie: (_cookieName: ConsentCookies, _cookieValue: boolean) => {}, - acceptAll: () => {}, + setAllCookies: () => {}, isOpen: false, setIsOpen: () => {}, isSelectionOpen: false, @@ -44,38 +44,35 @@ export function CookiesContainer(props: CookiesContainerProps) { 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) => { setConsentCookies((prev) => ({ ...prev, [cookieName]: cookieValue, })); - toast - .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); - reload(); - }); + toast.promise(onUpdateConsentCookie(cookieName, cookieValue), toastPromiseMessages).then(() => { + setIsOpen(false); + reload(); + }); }; - const handleAcceptAll = () => { + const handleSetAll = (value: boolean) => { setConsentCookies({ analytics: true, customization: true }); - toast - .promise(onAcceptAllConsentCookie(), { - pending: "Acceptation des cookies...", - success: "Cookies acceptés !", - error: "Erreur lors de l'acceptation des cookies", - }) - .then(() => { - setIsOpen(false); - setIsSelectionOpen(false); - reload(); - }); + toast.promise(onSetAllConsentCookie(value), toastPromiseMessages).then(() => { + setIsOpen(false); + setIsSelectionOpen(false); + reload(); + }); }; return ( @@ -83,7 +80,7 @@ export function CookiesContainer(props: CookiesContainerProps) { value={{ cookies: consentCookies, setCookie: handleUpdateCookie, - acceptAll: handleAcceptAll, + setAllCookies: handleSetAll, isOpen, setIsOpen, isSelectionOpen, @@ -171,7 +168,7 @@ function CookieModal() {
@@ -185,7 +182,7 @@ function CookieModal() { diff --git a/app/pages/mentions-legales/+Page.tsx b/app/pages/mentions-legales/+Page.tsx index c051a55..8e0d668 100644 --- a/app/pages/mentions-legales/+Page.tsx +++ b/app/pages/mentions-legales/+Page.tsx @@ -2,7 +2,7 @@ import React from "react"; export function Page() { return ( -
+

Mentions légales

diff --git a/app/pages/politique-de-confidentialite/+Page.tsx b/app/pages/politique-de-confidentialite/+Page.tsx index 7f98780..e87265a 100644 --- a/app/pages/politique-de-confidentialite/+Page.tsx +++ b/app/pages/politique-de-confidentialite/+Page.tsx @@ -7,7 +7,7 @@ export function Page() { const { setIsOpen } = useContext(CookiesContext); return ( -
+

Politique de confidentialité

diff --git a/app/providers/ThemeProvider.telefunc.ts b/app/providers/ThemeProvider.telefunc.ts index 3dfc4a1..e1f1fc8 100644 --- a/app/providers/ThemeProvider.telefunc.ts +++ b/app/providers/ThemeProvider.telefunc.ts @@ -11,3 +11,12 @@ export async function onUpdateThemeCookie(value: Theme) { 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" }; +} diff --git a/app/providers/ThemeProvider.tsx b/app/providers/ThemeProvider.tsx index 79961e4..279ce56 100644 --- a/app/providers/ThemeProvider.tsx +++ b/app/providers/ThemeProvider.tsx @@ -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 { usePageContext } from "vike-react/usePageContext"; import React, { useEffect, useState } from "react"; @@ -23,8 +23,12 @@ export function ThemeProvider(props: ThemeProviderProps) { onUpdateThemeCookie(theme).catch(() => { 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 {props.children}; } diff --git a/app/services/CookieParser.ts b/app/services/CookieParser.ts index 7cf5268..dfab89e 100644 --- a/app/services/CookieParser.ts +++ b/app/services/CookieParser.ts @@ -17,6 +17,23 @@ export class CookieParser { 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() { this.cookies = this.rawCookies.split("; ").reduce( (acc, cookie) => { @@ -38,15 +55,16 @@ export class CookieParser { } static set(reply: FastifyReply, key: CookieKeys, value: string, daysDuration = 30): FastifyReply { - const options = { - path: "/", - httpOnly: true, - secure: process.env.NODE_ENV === "production", - expires: new Date(Date.now() + 60 * 60 * 24 * daysDuration * 1000), - }; - + const options = CookieParser.buildOptions(daysDuration); reply.setCookie(key, value, options); return reply; } + + static delete(reply: FastifyReply, key: CookieKeys): FastifyReply { + const options = CookieParser.buildOptions(new Date("1900-01-01")); + reply.setCookie(key, "", options); + + return reply; + } }