chore: transfer repo
This commit is contained in:
160
components/cookies/CookieContext.tsx
Normal file
160
components/cookies/CookieContext.tsx
Normal file
@@ -0,0 +1,160 @@
|
||||
'use client';
|
||||
|
||||
import Cookies from 'js-cookie';
|
||||
import { createContext, ReactNode, useContext, useEffect, useState } from 'react';
|
||||
|
||||
// Define cookie categories and their default state
|
||||
export const COOKIE_CATEGORIES = {
|
||||
NECESSARY: 'necessary',
|
||||
ANALYTICS: 'analytics',
|
||||
MARKETING: 'marketing',
|
||||
PREFERENCES: 'preferences'
|
||||
} as const;
|
||||
|
||||
export type CookieCategory = typeof COOKIE_CATEGORIES[keyof typeof COOKIE_CATEGORIES];
|
||||
|
||||
export interface CookiePreferences {
|
||||
necessary: boolean; // Always true, can't be disabled
|
||||
analytics: boolean;
|
||||
marketing: boolean;
|
||||
preferences: boolean;
|
||||
}
|
||||
|
||||
export const DEFAULT_PREFERENCES: CookiePreferences = {
|
||||
necessary: true, // Always true
|
||||
analytics: false,
|
||||
marketing: false,
|
||||
preferences: false
|
||||
};
|
||||
|
||||
const CONSENT_COOKIE_NAME = 'cookie-consent';
|
||||
const COOKIE_EXPIRY_DAYS = 365;
|
||||
|
||||
interface CookieContextType {
|
||||
preferences: CookiePreferences;
|
||||
hasConsent: boolean;
|
||||
showBanner: boolean;
|
||||
showModal: boolean;
|
||||
acceptAll: () => void;
|
||||
savePreferences: (newPrefs: CookiePreferences) => void;
|
||||
openModal: () => void;
|
||||
closeModal: () => void;
|
||||
resetConsent: () => void;
|
||||
}
|
||||
|
||||
const CookieContext = createContext<CookieContextType | undefined>(undefined);
|
||||
|
||||
export function CookieProvider({ children }: { children: ReactNode }) {
|
||||
const [preferences, setPreferences] = useState<CookiePreferences>(DEFAULT_PREFERENCES);
|
||||
const [hasConsent, setHasConsent] = useState<boolean>(false);
|
||||
const [showBanner, setShowBanner] = useState<boolean>(false);
|
||||
const [showModal, setShowModal] = useState<boolean>(false);
|
||||
|
||||
// Load stored consent preferences on mount (client-side only)
|
||||
useEffect(() => {
|
||||
const storedConsent = Cookies.get(CONSENT_COOKIE_NAME);
|
||||
|
||||
if (storedConsent) {
|
||||
try {
|
||||
const parsedPreferences = JSON.parse(storedConsent);
|
||||
setPreferences({
|
||||
...DEFAULT_PREFERENCES,
|
||||
...parsedPreferences,
|
||||
// Ensure necessary cookies are always enabled
|
||||
necessary: true
|
||||
});
|
||||
setHasConsent(true);
|
||||
setShowBanner(false);
|
||||
} catch (error) {
|
||||
console.error('Failed to parse cookie consent', error);
|
||||
setShowBanner(true);
|
||||
}
|
||||
} else {
|
||||
// No stored consent, show the banner
|
||||
setShowBanner(true);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const savePreferences = (newPrefs: CookiePreferences) => {
|
||||
const updatedPrefs = {
|
||||
...newPrefs,
|
||||
necessary: true
|
||||
};
|
||||
|
||||
// Update state
|
||||
setPreferences(updatedPrefs);
|
||||
setHasConsent(true);
|
||||
setShowBanner(false);
|
||||
setShowModal(false);
|
||||
|
||||
// Save to cookie
|
||||
Cookies.set(CONSENT_COOKIE_NAME, JSON.stringify(updatedPrefs), {
|
||||
expires: COOKIE_EXPIRY_DAYS,
|
||||
path: '/',
|
||||
sameSite: 'strict'
|
||||
});
|
||||
|
||||
applyPreferences(updatedPrefs);
|
||||
};
|
||||
|
||||
// Accept all cookies
|
||||
const acceptAll = () => {
|
||||
const allAccepted = {
|
||||
necessary: true,
|
||||
analytics: true,
|
||||
marketing: true,
|
||||
preferences: true
|
||||
};
|
||||
|
||||
savePreferences(allAccepted);
|
||||
};
|
||||
|
||||
// Reset consent (for testing)
|
||||
const resetConsent = () => {
|
||||
Cookies.remove(CONSENT_COOKIE_NAME);
|
||||
setPreferences(DEFAULT_PREFERENCES);
|
||||
setHasConsent(false);
|
||||
setShowBanner(true);
|
||||
};
|
||||
|
||||
const openModal = () => setShowModal(true);
|
||||
const closeModal = () => setShowModal(false);
|
||||
|
||||
// Apply preferences based on consent
|
||||
const applyPreferences = (prefs: CookiePreferences) => {
|
||||
// Apply analytics preference (without console logs)
|
||||
if (prefs.analytics) {
|
||||
// Enable analytics tracking
|
||||
// Add analytics initialization code here if needed
|
||||
} else {
|
||||
// Disable analytics tracking
|
||||
// Add analytics disabling code here if needed
|
||||
}
|
||||
};
|
||||
|
||||
const value = {
|
||||
preferences,
|
||||
hasConsent,
|
||||
showBanner,
|
||||
showModal,
|
||||
acceptAll,
|
||||
savePreferences,
|
||||
openModal,
|
||||
closeModal,
|
||||
resetConsent
|
||||
};
|
||||
|
||||
return (
|
||||
<CookieContext.Provider value={value}>
|
||||
{children}
|
||||
</CookieContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useCookieConsent() {
|
||||
const context = useContext(CookieContext);
|
||||
if (context === undefined) {
|
||||
throw new Error('useCookieConsent must be used within a CookieProvider');
|
||||
}
|
||||
return context;
|
||||
}
|
||||
Reference in New Issue
Block a user