consent.tsx62 lines · main
1'use client'
2
3import { consentState, isBrowser } from 'common'
4import { useCallback, useEffect, useRef } from 'react'
5import { toast } from 'sonner'
6import { cn } from 'ui'
7import { useSnapshot } from 'valtio'
8
9import { ConsentToast } from './ConsentToast'
10
11export const useConsentToast = () => {
12 const consentToastId = useRef<string | number | undefined>(undefined)
13 const snap = useSnapshot(consentState)
14
15 const acceptAll = useCallback(() => {
16 if (!isBrowser) return
17
18 snap.acceptAll()
19
20 if (consentToastId.current) {
21 toast.dismiss(consentToastId.current)
22 }
23 }, [snap.acceptAll])
24
25 const denyAll = useCallback(() => {
26 if (!isBrowser) return
27
28 snap.denyAll()
29
30 // Clear GA4 and sGTM tracking cookies
31 const trackingCookies = ['_ga', '_ga_XW18KGKGNR', 'FPID', 'FPAU', 'FPLC']
32 trackingCookies.forEach((name) => {
33 document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=.supabase.com`
34 })
35
36 if (consentToastId.current) {
37 toast.dismiss(consentToastId.current)
38 }
39 }, [snap.denyAll])
40
41 useEffect(() => {
42 if (isBrowser && snap.showConsentToast) {
43 consentToastId.current = toast(<ConsentToast onAccept={acceptAll} onOptOut={denyAll} />, {
44 id: 'consent-toast',
45 position: 'bottom-right',
46 duration: Infinity,
47 closeButton: false,
48 dismissible: false,
49 className: cn(
50 'w-screen! fixed! border-t! h-auto! left-0! bottom-0! top-auto! right-0! rounded-none! max-w-none! !bg-overlay !text',
51 'sm:w-full! sm:max-w-[356px]! sm:left-auto! sm:right-8! sm:bottom-8! sm:rounded-lg! sm:border'
52 ),
53 })
54 } else if (consentToastId.current) {
55 toast.dismiss(consentToastId.current)
56 }
57 }, [snap.showConsentToast])
58
59 return {
60 hasAcceptedConsent: snap.hasConsented,
61 }
62}