UNPKG

@citiwave/im-disclaimer-modal

Version:

A customizable React disclaimer modal component with theme support

121 lines (104 loc) 3.9 kB
import { useState, useEffect } from 'react'; import { useDisclaimerQueue, DISCLAIMER_PRIORITIES } from './useDisclaimerQueue'; import { renderDisclaimerContent } from '../utils/renderDisclaimerContent'; import type { DisclaimerSection } from '../components/DisclaimerModal'; interface DisclaimerGroup { name: string; disclaimers: string[]; priorities: { [key: string]: number }; } interface DisclaimerConfig { id: string; title: string; defaultAccentColor?: string; } // Default configs that can be overridden by JSON files const DISCLAIMER_CONFIGS: DisclaimerConfig[] = [ { id: 'privacy-policy', title: 'Privacy Policy', defaultAccentColor: '#4A90E2' }, { id: 'financial-terms', title: 'Financial Terms and Conditions', defaultAccentColor: '#2ECC71' } ]; export const useDisclaimerGroup = (groupName: string, defaultTheme: 'light' | 'dark' = 'dark') => { const [group, setGroup] = useState<DisclaimerGroup | null>(null); const [disclaimers, setDisclaimers] = useState<Array<{ id: string; title: string; accentColor: string; theme: 'light' | 'dark'; sections: DisclaimerSection[]; }>>([]); const { isDisclaimerActive, removeFromQueue, addToQueue } = useDisclaimerQueue(); const [initialized, setInitialized] = useState(false); // Load group and process disclaimers useEffect(() => { const loadGroup = async () => { try { // Load group data const groupData = await import(`../../demo/src/data/disclaimers/groups/${groupName}.json`); setGroup(groupData.default); // Load and process all disclaimers const loadedDisclaimers = await Promise.all( DISCLAIMER_CONFIGS.map(async (config) => { const contentModule = await import(`../../demo/src/data/disclaimers/${config.id}.json`); const content = contentModule.default; // Get config from JSON file or use defaults const fileConfig = content.config || {}; const theme = fileConfig.theme || defaultTheme; const accentColor = fileConfig.accentColor || config.defaultAccentColor; // Filter out config from sections const sections = Object.entries(content) .filter(([key]) => key !== 'config') .map(([key, section]: [string, any]) => ({ title: section.title, required: section.required, content: renderDisclaimerContent(section.content, theme) })); return { id: config.id, title: config.title, accentColor, theme, sections }; }) ); // Sort based on group priorities const sortedDisclaimers = loadedDisclaimers.sort((a, b) => { const priorityA = groupData.default.priorities[a.id] ?? Infinity; const priorityB = groupData.default.priorities[b.id] ?? Infinity; return priorityA - priorityB; }); setDisclaimers(sortedDisclaimers); // Initialize queue if not already done if (!initialized) { // Reset priorities Object.keys(DISCLAIMER_PRIORITIES).forEach(key => { delete DISCLAIMER_PRIORITIES[key]; }); // Add to queue in priority order Object.entries(groupData.default.priorities).forEach(([id, priority]) => { Object.assign(DISCLAIMER_PRIORITIES, { [id]: priority }); addToQueue(id); }); setInitialized(true); } } catch (error) { console.error(`Error loading disclaimer group: ${groupName}`, error); } }; loadGroup(); }, [groupName, defaultTheme, initialized, addToQueue]); return { group, disclaimers, isDisclaimerActive, removeFromQueue }; };