feat: Implement cookie consent management with a new banner and introduce a language-aware root redirection.
This commit is contained in:
101
frontend/src/contexts/CookieContext.tsx
Normal file
101
frontend/src/contexts/CookieContext.tsx
Normal file
@@ -0,0 +1,101 @@
|
||||
import React, { createContext, useContext, useEffect, useState } from 'react';
|
||||
|
||||
export interface CookieConsent {
|
||||
essential: boolean; // Always true
|
||||
preferences: boolean; // Language, Theme
|
||||
analytics: boolean; // Optional future use
|
||||
}
|
||||
|
||||
interface CookieContextType {
|
||||
consent: CookieConsent;
|
||||
updateConsent: (newConsent: CookieConsent) => void;
|
||||
acceptAll: () => void;
|
||||
rejectAll: () => void;
|
||||
hasInteracted: boolean; // True if user has made a choice
|
||||
showBanner: boolean;
|
||||
closeBanner: () => void;
|
||||
}
|
||||
|
||||
const defaultConsent: CookieConsent = {
|
||||
essential: true,
|
||||
preferences: false,
|
||||
analytics: false,
|
||||
};
|
||||
|
||||
const CookieContext = createContext<CookieContextType | undefined>(undefined);
|
||||
|
||||
export const CookieProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
||||
const [consent, setConsent] = useState<CookieConsent>(defaultConsent);
|
||||
const [hasInteracted, setHasInteracted] = useState(false);
|
||||
const [showBanner, setShowBanner] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const savedConsent = localStorage.getItem('cookie_consent');
|
||||
if (savedConsent) {
|
||||
try {
|
||||
const parsed = JSON.parse(savedConsent);
|
||||
setConsent({ ...defaultConsent, ...parsed, essential: true });
|
||||
setHasInteracted(true);
|
||||
setShowBanner(false);
|
||||
} catch (e) {
|
||||
// Invalid json, treat as no consent
|
||||
setShowBanner(true);
|
||||
}
|
||||
} else {
|
||||
setShowBanner(true);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const saveConsent = (newConsent: CookieConsent) => {
|
||||
localStorage.setItem('cookie_consent', JSON.stringify(newConsent));
|
||||
setConsent(newConsent);
|
||||
setHasInteracted(true);
|
||||
setShowBanner(false);
|
||||
};
|
||||
|
||||
const updateConsent = (newConsent: CookieConsent) => {
|
||||
saveConsent({ ...newConsent, essential: true });
|
||||
};
|
||||
|
||||
const acceptAll = () => {
|
||||
saveConsent({
|
||||
essential: true,
|
||||
preferences: true,
|
||||
analytics: true,
|
||||
});
|
||||
};
|
||||
|
||||
const rejectAll = () => {
|
||||
saveConsent({
|
||||
essential: true,
|
||||
preferences: false,
|
||||
analytics: false,
|
||||
});
|
||||
};
|
||||
|
||||
const closeBanner = () => {
|
||||
setShowBanner(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<CookieContext.Provider value={{
|
||||
consent,
|
||||
updateConsent,
|
||||
acceptAll,
|
||||
rejectAll,
|
||||
hasInteracted,
|
||||
showBanner,
|
||||
closeBanner
|
||||
}}>
|
||||
{children}
|
||||
</CookieContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useCookie = () => {
|
||||
const context = useContext(CookieContext);
|
||||
if (!context) {
|
||||
throw new Error('useCookie must be used within a CookieProvider');
|
||||
}
|
||||
return context;
|
||||
};
|
||||
Reference in New Issue
Block a user