Files
OpenSquawk/app/composables/useCookieConsent.ts
2025-10-18 14:48:13 +02:00

99 lines
2.2 KiB
TypeScript

import { computed, watch } from 'vue';
type CookieConsentPreferences = {
necessary: true;
analytics: boolean;
};
type CookieConsentValue = {
version: number;
updatedAt: string;
preferences: CookieConsentPreferences;
};
const CONSENT_COOKIE_NAME = 'osq-cookie-consent';
const CONSENT_VERSION = 1;
const SIX_MONTHS_IN_SECONDS = 60 * 60 * 24 * 180;
export const HOTJAR_LOCAL_STORAGE_KEY = 'osq-hotjar-consent';
export const useCookieConsent = () => {
const consentCookie = useCookie<CookieConsentValue | null>(CONSENT_COOKIE_NAME, {
sameSite: 'lax',
path: '/',
maxAge: SIX_MONTHS_IN_SECONDS,
secure: !process.dev,
});
if (consentCookie.value && consentCookie.value.version !== CONSENT_VERSION) {
consentCookie.value = null;
}
const consentState = useState<CookieConsentValue | null>('cookie-consent', () => consentCookie.value ?? null);
watch(
consentState,
(value) => {
consentCookie.value = value;
},
{ deep: true }
);
if (process.client) {
watch(
consentState,
(value) => {
if (!value) {
window.localStorage.removeItem(HOTJAR_LOCAL_STORAGE_KEY);
return;
}
window.localStorage.setItem(
HOTJAR_LOCAL_STORAGE_KEY,
value.preferences.analytics ? 'granted' : 'denied'
);
},
{ deep: true }
);
}
const hasConsent = computed(() => consentState.value !== null);
const analyticsEnabled = computed(() => {
if (!consentState.value) {
return false;
}
return consentState.value.preferences.analytics === true;
});
const savePreferences = (preferences: { analytics: boolean }) => {
consentState.value = {
version: CONSENT_VERSION,
updatedAt: new Date().toISOString(),
preferences: {
necessary: true,
analytics: preferences.analytics,
},
};
};
const acceptAll = () => savePreferences({ analytics: true });
const rejectAll = () => savePreferences({ analytics: false });
const resetConsent = () => {
consentState.value = null;
consentCookie.value = null;
};
return {
consent: consentState,
hasConsent,
analyticsEnabled,
acceptAll,
rejectAll,
savePreferences,
resetConsent,
};
};