UNPKG

cookiebanner-finally

Version:

Headless cookie banner library for Next.js with shadcn philosophy

1 lines 41.2 kB
{"version":3,"sources":["../src/types/index.ts","../src/core/cookies.ts","../src/core/ConsentProvider.tsx","../src/hooks/useCookieBanner.ts","../src/hooks/useCookiePreferences.ts","../src/hooks/useConsentGate.ts","../src/scripts/ScriptManager.ts","../src/hooks/useScriptLoader.ts","../src/components/ConsentGate.tsx","../src/components/ScriptLoader.tsx"],"names":["ConsentCategory","DEFAULT_CONSENT_PREFERENCES","DEFAULT_COOKIE_NAME","DEFAULT_COOKIE_OPTIONS","CookieManager","cookieName","cookieOptions","cookieValue","parsed","error","preferences","updatedPreferences","category","Cookies","value","cookieManager","ConsentContext","createContext","ConsentProvider","children","cookieExpires","initialPreferences","autoShowBanner","manager","useState","setPreferences","isConsentGiven","setIsConsentGiven","showBanner","setShowBanner","isMounted","setIsMounted","useEffect","hasGivenConsent","currentPreferences","acceptAll","updated","denyAll","updatePreferences","newPreferences","closeOnUpdate","closeBanner","resetBanner","hasConsentFor","jsx","Fragment","useConsentContext","context","useContext","useCookieBanner","useCookiePreferences","isLoading","enabled","useConsentGate","isClient","setIsClient","ScriptManager","script","scripts","id","hasConsent","resolve","categoryScripts","callback","scriptElement","key","scriptManager","useScriptLoader","s","consent","ConsentGate","fallback","loading","showPromptOnClick","showConsentPrompt","jsxs","ScriptLoader","onLoad","autoLoad","register","load","isLoaded","success","ScriptBatchLoader","registerBatch","results"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Cookie consent categories\n */\nexport enum ConsentCategory {\n Necessary = 'necessary',\n Preferences = 'preferences',\n Analytics = 'analytics',\n Marketing = 'marketing'\n}\n\n/**\n * Cookie consent preferences\n */\nexport interface ConsentPreferences {\n [ConsentCategory.Necessary]: boolean; // Always true\n [ConsentCategory.Preferences]: boolean;\n [ConsentCategory.Analytics]: boolean;\n [ConsentCategory.Marketing]: boolean;\n lastUpdated?: string;\n}\n\n/**\n * Default consent preferences\n */\nexport const DEFAULT_CONSENT_PREFERENCES: ConsentPreferences = {\n [ConsentCategory.Necessary]: true, // Necessary cookies are always allowed\n [ConsentCategory.Preferences]: false,\n [ConsentCategory.Analytics]: false,\n [ConsentCategory.Marketing]: false\n};\n\n/**\n * Script definition\n */\nexport interface Script {\n id: string;\n category: ConsentCategory;\n src?: string;\n content?: string;\n attributes?: Record<string, string>;\n}\n","import Cookies from 'js-cookie';\nimport { ConsentCategory, ConsentPreferences, DEFAULT_CONSENT_PREFERENCES } from '../types';\n\n// Default cookie name for storing consent preferences\nconst DEFAULT_COOKIE_NAME = 'cookie-consent';\n\n// Default cookie options\nconst DEFAULT_COOKIE_OPTIONS = {\n expires: 365, // 1 year\n path: '/',\n sameSite: 'strict' as const\n};\n\n/**\n * Cookie manager for handling consent preferences\n */\nexport class CookieManager {\n private cookieName: string;\n private cookieOptions: Cookies.CookieAttributes;\n \n constructor(\n cookieName: string = DEFAULT_COOKIE_NAME,\n cookieOptions: Cookies.CookieAttributes = DEFAULT_COOKIE_OPTIONS\n ) {\n this.cookieName = cookieName;\n this.cookieOptions = cookieOptions;\n }\n\n /**\n * Get current consent preferences\n */\n getConsentPreferences(): ConsentPreferences {\n try {\n const cookieValue = this.getCookieValue();\n if (!cookieValue) {\n return { ...DEFAULT_CONSENT_PREFERENCES };\n }\n \n const parsed = JSON.parse(cookieValue) as Partial<ConsentPreferences>;\n \n // Always ensure necessary cookies are accepted\n return {\n ...DEFAULT_CONSENT_PREFERENCES,\n ...parsed,\n [ConsentCategory.Necessary]: true\n };\n } catch (error) {\n console.error('Error parsing consent preferences', error);\n return { ...DEFAULT_CONSENT_PREFERENCES };\n }\n }\n\n /**\n * Save consent preferences\n */\n saveConsentPreferences(preferences: Partial<ConsentPreferences>): ConsentPreferences {\n const currentPreferences = this.getConsentPreferences();\n const updatedPreferences: ConsentPreferences = {\n ...currentPreferences,\n ...preferences,\n [ConsentCategory.Necessary]: true, // Always ensure necessary cookies are accepted\n lastUpdated: new Date().toISOString()\n };\n\n try {\n this.setCookieValue(JSON.stringify(updatedPreferences));\n } catch (error) {\n console.error('Error saving consent preferences', error);\n }\n\n return updatedPreferences;\n }\n\n /**\n * Check if consent is given for a specific category\n */\n hasConsent(category: ConsentCategory): boolean {\n const preferences = this.getConsentPreferences();\n return preferences[category] === true;\n }\n\n /**\n * Accept all cookie categories\n */\n acceptAll(): ConsentPreferences {\n return this.saveConsentPreferences({\n [ConsentCategory.Necessary]: true,\n [ConsentCategory.Preferences]: true,\n [ConsentCategory.Analytics]: true,\n [ConsentCategory.Marketing]: true\n });\n }\n\n /**\n * Deny all non-necessary cookie categories\n */\n denyAll(): ConsentPreferences {\n return this.saveConsentPreferences({\n [ConsentCategory.Necessary]: true,\n [ConsentCategory.Preferences]: false,\n [ConsentCategory.Analytics]: false,\n [ConsentCategory.Marketing]: false\n });\n }\n\n /**\n * Check if consent has been given (for any category besides necessary)\n */\n hasConsentBeenGiven(): boolean {\n try {\n return this.getCookieValue() !== null;\n } catch {\n return false;\n }\n }\n\n /**\n * Get cookie value\n */\n private getCookieValue(): string | null {\n // For client-side usage\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n return Cookies.get(this.cookieName) || null;\n }\n \n // For server-side usage, return null since we can't access cookies directly\n return null;\n }\n\n /**\n * Set cookie value\n */\n private setCookieValue(value: string): void {\n // Only set cookies on the client-side\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n Cookies.set(this.cookieName, value, this.cookieOptions);\n }\n }\n}\n\n// Export a default instance\nexport const cookieManager = new CookieManager();\n","'use client';\n\nimport React, { createContext, useContext, useState, useEffect } from 'react';\nimport type { ReactNode } from 'react';\nimport { cookieManager, CookieManager } from './cookies';\nimport { ConsentCategory, DEFAULT_CONSENT_PREFERENCES } from '../types';\nimport type { ConsentPreferences } from '../types';\n\n// Define the consent context shape\ninterface ConsentContextType {\n // Consent state\n preferences: ConsentPreferences;\n isConsentGiven: boolean;\n showBanner: boolean;\n \n // Consent management methods\n acceptAll: () => void;\n denyAll: () => void;\n updatePreferences: (preferences: Partial<ConsentPreferences>, closeOnUpdate?: boolean) => void;\n closeBanner: () => void;\n resetBanner: () => void;\n hasConsentFor: (category: ConsentCategory) => boolean;\n}\n\n// Create context with default values\nconst ConsentContext = createContext<ConsentContextType>({\n preferences: DEFAULT_CONSENT_PREFERENCES,\n isConsentGiven: false,\n showBanner: false,\n acceptAll: () => {},\n denyAll: () => {},\n updatePreferences: () => {},\n closeBanner: () => {},\n resetBanner: () => {},\n hasConsentFor: () => false,\n});\n\n// Provider props\ninterface ConsentProviderProps {\n children: ReactNode;\n cookieName?: string;\n cookieExpires?: number;\n initialPreferences?: Partial<ConsentPreferences>;\n autoShowBanner?: boolean;\n}\n\n/**\n * Provider component for cookie consent management\n */\nexport const ConsentProvider: React.FC<ConsentProviderProps> = ({\n children,\n cookieName,\n cookieExpires,\n initialPreferences,\n autoShowBanner = true,\n}) => {\n // Initialize cookie manager if custom options are provided\n const [manager] = useState(() => {\n if (cookieName || cookieExpires) {\n return new CookieManager(\n cookieName,\n cookieExpires ? { expires: cookieExpires, path: '/', sameSite: 'strict' } : undefined\n );\n }\n return cookieManager;\n });\n\n // State\n const [preferences, setPreferences] = useState<ConsentPreferences>(DEFAULT_CONSENT_PREFERENCES);\n const [isConsentGiven, setIsConsentGiven] = useState(false);\n const [showBanner, setShowBanner] = useState(false);\n const [isMounted, setIsMounted] = useState(false);\n \n // State management\n\n // Initialize on mount (client-side only)\n useEffect(() => {\n const hasGivenConsent = manager.hasConsentBeenGiven();\n \n // Only apply initialPreferences if user hasn't given consent yet\n if (initialPreferences && !hasGivenConsent) {\n manager.saveConsentPreferences(initialPreferences);\n }\n \n const currentPreferences = manager.getConsentPreferences();\n setPreferences(currentPreferences);\n setIsConsentGiven(hasGivenConsent);\n \n // Show banner if consent not given and autoShowBanner is true\n setShowBanner(autoShowBanner && !hasGivenConsent);\n \n // Mark as mounted\n setIsMounted(true);\n }, [manager, initialPreferences, autoShowBanner]);\n\n // Update functions\n const acceptAll = () => {\n const updated = manager.acceptAll();\n setPreferences(updated);\n setIsConsentGiven(true);\n setShowBanner(false);\n // Update state\n };\n\n const denyAll = () => {\n const updated = manager.denyAll();\n setPreferences(updated);\n setIsConsentGiven(true);\n setShowBanner(false);\n // Update state\n };\n\n const updatePreferences = (newPreferences: Partial<ConsentPreferences>, closeOnUpdate: boolean = false) => {\n const updated = manager.saveConsentPreferences(newPreferences);\n setPreferences(updated);\n setIsConsentGiven(true);\n \n // Only close the banner if explicitly requested\n if (closeOnUpdate) {\n setShowBanner(false);\n }\n };\n\n const closeBanner = () => {\n setShowBanner(false);\n };\n\n const resetBanner = () => {\n setShowBanner(true);\n };\n\n const hasConsentFor = (category: ConsentCategory): boolean => {\n return manager.hasConsent(category);\n };\n\n // Skip rendering until mounted (hydration safety)\n if (!isMounted) {\n return <>{children}</>;\n }\n\n return (\n <ConsentContext.Provider\n value={{\n preferences,\n isConsentGiven,\n showBanner,\n acceptAll,\n denyAll,\n updatePreferences,\n closeBanner,\n resetBanner,\n hasConsentFor,\n }}\n >\n {children}\n </ConsentContext.Provider>\n );\n};\n\n/**\n * Hook for using consent context\n */\nexport const useConsentContext = () => {\n const context = useContext(ConsentContext);\n if (context === undefined) {\n throw new Error('useConsentContext must be used within a ConsentProvider');\n }\n return context;\n};\n","'use client';\n\nimport { useConsentContext } from '../core/ConsentProvider';\n\n/**\n * Interface for the useCookieBanner hook\n */\nexport interface UseCookieBannerResult {\n // Banner state\n isVisible: boolean;\n isConsentGiven: boolean;\n \n // User actions\n acceptAll: () => void;\n denyAll: () => void;\n close: () => void;\n show: () => void;\n}\n\n/**\n * Hook for managing the cookie consent banner\n * \n * @returns Banner state and methods\n * \n * @example\n * ```tsx\n * const CookieBanner = () => {\n * const { isVisible, acceptAll, denyAll, close } = useCookieBanner();\n * \n * if (!isVisible) return null;\n * \n * return (\n * <div className=\"cookie-banner\">\n * <p>We use cookies to improve your experience.</p>\n * <div className=\"cookie-banner-buttons\">\n * <button onClick={acceptAll}>Accept All</button>\n * <button onClick={denyAll}>Reject All</button>\n * <button onClick={close}>Close</button>\n * </div>\n * </div>\n * );\n * }\n * ```\n */\nexport function useCookieBanner(): UseCookieBannerResult {\n const {\n showBanner,\n isConsentGiven,\n acceptAll,\n denyAll,\n closeBanner,\n resetBanner,\n } = useConsentContext();\n\n // Update methods to ensure they close the banner\n return {\n isVisible: showBanner,\n isConsentGiven,\n acceptAll,\n denyAll,\n close: closeBanner,\n show: resetBanner,\n };\n}\n","'use client';\n\nimport { useState, useEffect } from 'react';\nimport { useConsentContext } from '../core/ConsentProvider';\nimport { ConsentCategory } from '../types';\nimport type { ConsentPreferences } from '../types';\n\n/**\n * Interface for the useCookiePreferences hook\n */\nexport interface UseCookiePreferencesResult {\n // Preference data\n preferences: ConsentPreferences;\n isLoading: boolean;\n \n // Check specific category\n isEnabled: (category: ConsentCategory) => boolean;\n \n // Update methods\n updatePreferences: (preferences: Partial<ConsentPreferences>) => void;\n updateCategory: (category: ConsentCategory, enabled: boolean) => void;\n}\n\n/**\n * Hook for reading and updating cookie preferences\n * \n * @returns Cookie preferences state and update methods\n * \n * @example\n * ```tsx\n * const CookieSettings = () => {\n * const { preferences, isLoading, updateCategory } = useCookiePreferences();\n * \n * if (isLoading) return <div>Loading preferences...</div>;\n * \n * return (\n * <div className=\"cookie-settings\">\n * <h2>Cookie Settings</h2>\n * \n * <div className=\"cookie-setting\">\n * <input\n * type=\"checkbox\"\n * id=\"necessary\"\n * checked={preferences.necessary}\n * disabled={true}\n * />\n * <label htmlFor=\"necessary\">Necessary (Required)</label>\n * </div>\n * \n * <div className=\"cookie-setting\">\n * <input\n * type=\"checkbox\"\n * id=\"preferences\"\n * checked={preferences.preferences}\n * onChange={(e) => updateCategory('preferences', e.target.checked)}\n * />\n * <label htmlFor=\"preferences\">Preferences</label>\n * </div>\n * \n * <div className=\"cookie-setting\">\n * <input\n * type=\"checkbox\"\n * id=\"analytics\"\n * checked={preferences.analytics}\n * onChange={(e) => updateCategory('analytics', e.target.checked)}\n * />\n * <label htmlFor=\"analytics\">Analytics</label>\n * </div>\n * \n * <div className=\"cookie-setting\">\n * <input\n * type=\"checkbox\"\n * id=\"marketing\"\n * checked={preferences.marketing}\n * onChange={(e) => updateCategory('marketing', e.target.checked)}\n * />\n * <label htmlFor=\"marketing\">Marketing</label>\n * </div>\n * </div>\n * );\n * }\n * ```\n */\nexport function useCookiePreferences(): UseCookiePreferencesResult {\n const { preferences, updatePreferences, hasConsentFor } = useConsentContext();\n // Since ConsentProvider already handles the initial loading state,\n // we only need to track if we've received valid preferences from the context\n const isLoading = !preferences || Object.keys(preferences).length === 0;\n\n // Update a single category\n const updateCategory = (category: ConsentCategory, enabled: boolean) => {\n updatePreferences({ [category]: enabled }, false);\n };\n\n // Check if a category is enabled\n const isEnabled = (category: ConsentCategory) => {\n return hasConsentFor(category);\n };\n\n return {\n preferences,\n isLoading,\n isEnabled,\n updatePreferences,\n updateCategory,\n };\n}\n","'use client';\n\nimport { useState, useEffect } from 'react';\nimport { useConsentContext } from '../core/ConsentProvider';\nimport { ConsentCategory } from '../types';\n\n/**\n * Interface for the useConsentGate hook\n */\nexport interface UseConsentGateResult {\n // State\n hasConsent: boolean;\n isLoading: boolean;\n \n // Show prompt\n showConsentPrompt: () => void;\n}\n\n/**\n * Hook for conditionally rendering content based on consent\n * \n * @param category - The consent category to check\n * @returns State indicating if content can be displayed\n * \n * @example\n * ```tsx\n * const YouTubeEmbed = ({ videoId }: { videoId: string }) => {\n * const { hasConsent, isLoading, showConsentPrompt } = useConsentGate(\n * ConsentCategory.Marketing\n * );\n * \n * if (isLoading) {\n * return <div>Loading...</div>;\n * }\n * \n * if (!hasConsent) {\n * return (\n * <div className=\"consent-placeholder\">\n * <p>This content requires marketing cookies consent.</p>\n * <button onClick={showConsentPrompt}>Manage Cookie Preferences</button>\n * </div>\n * );\n * }\n * \n * return (\n * <iframe\n * src={`https://www.youtube.com/embed/${videoId}`}\n * frameBorder=\"0\"\n * allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\"\n * allowFullScreen\n * />\n * );\n * }\n * ```\n */\nexport function useConsentGate(category: ConsentCategory): UseConsentGateResult {\n const { hasConsentFor, resetBanner } = useConsentContext();\n const [isClient, setIsClient] = useState(false);\n \n // Handle server-side rendering\n useEffect(() => {\n setIsClient(true);\n }, []);\n \n // Check for consent (only client-side)\n const hasConsent = isClient ? hasConsentFor(category) : false;\n \n // Show the consent banner\n const showConsentPrompt = () => {\n resetBanner();\n };\n \n return {\n hasConsent,\n isLoading: !isClient,\n showConsentPrompt,\n };\n}\n","import { ConsentCategory, Script } from '../types';\n\n/**\n * Script manager for loading scripts based on consent\n */\nexport class ScriptManager {\n private scripts: Map<string, Script> = new Map();\n private loadedScripts: Set<string> = new Set();\n\n /**\n * Register a script\n */\n register(script: Script): void {\n if (!script.id) {\n throw new Error('Script ID is required');\n }\n \n if (!script.category) {\n throw new Error('Script category is required');\n }\n \n if (!script.src && !script.content) {\n throw new Error('Either src or content is required');\n }\n \n this.scripts.set(script.id, script);\n }\n\n /**\n * Register multiple scripts\n */\n registerBatch(scripts: Script[]): void {\n scripts.forEach(script => this.register(script));\n }\n\n /**\n * Load a script by ID if consent is given\n */\n loadScript(id: string, hasConsent: boolean): Promise<boolean> {\n const script = this.scripts.get(id);\n \n if (!script) {\n console.error(`Script with ID ${id} not found`);\n return Promise.resolve(false);\n }\n \n // Skip if already loaded\n if (this.loadedScripts.has(id)) {\n return Promise.resolve(true);\n }\n \n // Only load if consent is given\n if (!hasConsent) {\n return Promise.resolve(false);\n }\n \n return new Promise((resolve) => {\n // External script\n if (script.src) {\n this.loadExternalScript(script, () => {\n this.loadedScripts.add(id);\n resolve(true);\n });\n } \n // Inline script\n else if (script.content) {\n this.loadInlineScript(script);\n this.loadedScripts.add(id);\n resolve(true);\n }\n });\n }\n\n /**\n * Load scripts by category if consent is given\n */\n loadScriptsByCategory(category: ConsentCategory, hasConsent: boolean): Promise<boolean[]> {\n const categoryScripts = Array.from(this.scripts.values())\n .filter(script => script.category === category);\n \n return Promise.all(\n categoryScripts.map(script => this.loadScript(script.id, hasConsent))\n );\n }\n\n /**\n * Check if a script is loaded\n */\n isLoaded(id: string): boolean {\n return this.loadedScripts.has(id);\n }\n\n /**\n * Get all registered scripts\n */\n getAllScripts(): Script[] {\n return Array.from(this.scripts.values());\n }\n\n /**\n * Get scripts by category\n */\n getScriptsByCategory(category: ConsentCategory): Script[] {\n return Array.from(this.scripts.values())\n .filter(script => script.category === category);\n }\n\n /**\n * Load an external script\n */\n private loadExternalScript(script: Script, callback: () => void): void {\n if (typeof document === 'undefined') return;\n \n const scriptElement = document.createElement('script');\n \n // Add src attribute\n if (script.src) {\n scriptElement.src = script.src;\n }\n \n // Add custom attributes\n if (script.attributes) {\n Object.entries(script.attributes).forEach(([key, value]) => {\n scriptElement.setAttribute(key, value);\n });\n }\n \n // Set success callback\n scriptElement.onload = callback;\n \n // Set error handling\n scriptElement.onerror = (error) => {\n console.error(`Failed to load script: ${script.id}`, error);\n // Still call callback to resolve the promise, but log the error\n callback();\n };\n \n // Add to document\n document.head.appendChild(scriptElement);\n }\n\n /**\n * Load an inline script\n */\n private loadInlineScript(script: Script): void {\n if (typeof document === 'undefined' || !script.content) return;\n \n const scriptElement = document.createElement('script');\n \n // Set content\n scriptElement.text = script.content;\n \n // Add custom attributes\n if (script.attributes) {\n Object.entries(script.attributes).forEach(([key, value]) => {\n scriptElement.setAttribute(key, value);\n });\n }\n \n try {\n // Add to document\n document.head.appendChild(scriptElement);\n } catch (error) {\n console.error(`Error executing inline script: ${script.id}`, error);\n }\n }\n}\n\n// Create a default instance\nexport const scriptManager = new ScriptManager();\n","'use client';\n\nimport { useState, useEffect } from 'react';\nimport { useConsentContext } from '../core/ConsentProvider';\nimport { scriptManager } from '../scripts/ScriptManager';\nimport { ConsentCategory, Script } from '../types';\n\n/**\n * Interface for the useScriptLoader hook\n */\nexport interface UseScriptLoaderResult {\n register: (script: Script) => void;\n registerBatch: (scripts: Script[]) => void;\n load: (id: string) => Promise<boolean>;\n loadCategory: (category: ConsentCategory) => Promise<boolean[]>;\n isLoaded: (id: string) => boolean;\n}\n\n/**\n * Hook for loading scripts based on consent\n * \n * @returns Methods for registering and loading scripts\n * \n * @example\n * ```tsx\n * // In your layout or setup component\n * const MyAnalyticsSetup = () => {\n * const { register, load } = useScriptLoader();\n * \n * useEffect(() => {\n * // Register analytics scripts\n * register({\n * id: 'google-analytics',\n * category: ConsentCategory.Analytics,\n * src: 'https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX',\n * });\n * \n * register({\n * id: 'ga-config',\n * category: ConsentCategory.Analytics,\n * content: `\n * window.dataLayer = window.dataLayer || [];\n * function gtag(){dataLayer.push(arguments);}\n * gtag('js', new Date());\n * gtag('config', 'G-XXXXXXXXXX');\n * `,\n * });\n * \n * // Attempt to load (will only load if user has given consent)\n * load('google-analytics').then(() => {\n * load('ga-config');\n * });\n * }, [register, load]);\n * \n * return null; // This is a utility component with no UI\n * };\n * ```\n */\nexport function useScriptLoader(): UseScriptLoaderResult {\n const { hasConsentFor } = useConsentContext();\n const [isMounted, setIsMounted] = useState(false);\n \n // Handle server-side rendering\n useEffect(() => {\n setIsMounted(true);\n }, []);\n \n // Register a script\n const register = (script: Script) => {\n if (isMounted) {\n scriptManager.register(script);\n }\n };\n \n // Register multiple scripts\n const registerBatch = (scripts: Script[]) => {\n if (isMounted) {\n scriptManager.registerBatch(scripts);\n }\n };\n \n // Load a script by ID if consent is given\n const load = async (id: string): Promise<boolean> => {\n if (!isMounted) return false;\n \n const script = scriptManager.getAllScripts().find(s => s.id === id);\n \n if (!script) {\n console.error(`Script with ID ${id} not found`);\n return false;\n }\n \n const consent = hasConsentFor(script.category);\n return scriptManager.loadScript(id, consent);\n };\n \n // Load scripts by category if consent is given\n const loadCategory = (category: ConsentCategory): Promise<boolean[]> => {\n if (!isMounted) return Promise.resolve([]);\n \n const consent = hasConsentFor(category);\n return scriptManager.loadScriptsByCategory(category, consent);\n };\n \n // Check if a script is loaded\n const isLoaded = (id: string): boolean => {\n if (!isMounted) return false;\n return scriptManager.isLoaded(id);\n };\n \n return {\n register,\n registerBatch,\n load,\n loadCategory,\n isLoaded,\n };\n}\n","'use client';\n\nimport React from 'react';\nimport type { ReactNode } from 'react';\nimport { useConsentGate } from '../hooks/useConsentGate';\nimport { ConsentCategory } from '../types';\n\nexport interface ConsentGateProps {\n /**\n * The content to render when consent is given\n */\n children: ReactNode;\n \n /**\n * The consent category required\n */\n category: ConsentCategory;\n \n /**\n * Custom component to render when consent is not given\n */\n fallback?: ReactNode;\n \n /**\n * Custom loading component\n */\n loading?: ReactNode;\n \n /**\n * Whether to show the consent banner when clicked\n */\n showPromptOnClick?: boolean;\n}\n\n/**\n * Component that conditionally renders content based on consent\n */\nexport const ConsentGate: React.FC<ConsentGateProps> = ({\n children,\n category,\n fallback,\n loading,\n showPromptOnClick = true,\n}) => {\n const { hasConsent, isLoading, showConsentPrompt } = useConsentGate(category);\n \n // Show loading state\n if (isLoading) {\n return loading ? <>{loading}</> : <div>Loading...</div>;\n }\n \n // Show content if consent is given\n if (hasConsent) {\n return <>{children}</>;\n }\n \n // Show fallback or default fallback\n return fallback ? (\n <>{fallback}</>\n ) : (\n <div className=\"cookie-consent-gate-fallback\">\n <p>This content requires consent for {category} cookies.</p>\n {showPromptOnClick && (\n <button\n onClick={showConsentPrompt}\n className=\"cookie-consent-gate-button\"\n >\n Manage Cookie Preferences\n </button>\n )}\n {/* \n CSS classes to be defined in consumer application:\n \n .cookie-consent-gate-fallback {\n padding: 1rem;\n border: 1px solid #ccc;\n border-radius: 0.25rem;\n background-color: #f8f9fa;\n margin: 0.5rem 0;\n }\n \n .cookie-consent-gate-button {\n padding: 0.5rem 1rem;\n background-color: #0070f3;\n color: white;\n border: none;\n border-radius: 0.25rem;\n cursor: pointer;\n }\n\n .cookie-consent-gate-button:hover {\n background-color: #0051a8;\n }\n */}\n </div>\n );\n};\n","'use client';\n\nimport React, { useEffect } from 'react';\nimport { useScriptLoader } from '../hooks/useScriptLoader';\nimport { Script } from '../types';\n\nexport interface ScriptLoaderProps {\n /**\n * Script to load\n */\n script: Script;\n \n /**\n * Callback when script is loaded\n */\n onLoad?: () => void;\n \n /**\n * Whether to auto-load the script\n * @default true\n */\n autoLoad?: boolean;\n}\n\n/**\n * Component that loads a script based on consent\n */\nexport const ScriptLoader: React.FC<ScriptLoaderProps> = ({\n script,\n onLoad,\n autoLoad = true,\n}) => {\n const { register, load, isLoaded } = useScriptLoader();\n \n // Register the script\n useEffect(() => {\n register(script);\n }, [register, script]);\n \n // Load the script if autoLoad is true\n useEffect(() => {\n if (autoLoad) {\n load(script.id).then(success => {\n if (success && onLoad) {\n onLoad();\n }\n });\n }\n }, [load, script.id, autoLoad, onLoad]);\n \n // This component doesn't render anything\n return null;\n};\n\nexport interface ScriptBatchLoaderProps {\n /**\n * Scripts to load\n */\n scripts: Script[];\n \n /**\n * Callback when all scripts are loaded\n */\n onLoad?: () => void;\n \n /**\n * Whether to auto-load the scripts\n * @default true\n */\n autoLoad?: boolean;\n}\n\n/**\n * Component that loads multiple scripts based on consent\n */\nexport const ScriptBatchLoader: React.FC<ScriptBatchLoaderProps> = ({\n scripts,\n onLoad,\n autoLoad = true,\n}) => {\n const { registerBatch, load } = useScriptLoader();\n \n // Register all scripts\n useEffect(() => {\n registerBatch(scripts);\n }, [registerBatch, scripts]);\n \n // Load all scripts if autoLoad is true\n useEffect(() => {\n if (autoLoad) {\n Promise.all(scripts.map(script => load(script.id)))\n .then(results => {\n if (results.every(Boolean) && onLoad) {\n onLoad();\n }\n });\n }\n }, [load, scripts, autoLoad, onLoad]);\n \n // This component doesn't render anything\n return null;\n};\n"]}