import { useState, useEffect, useCallback } from 'react'; const STORAGE_KEY_PREFIX = 'widget-settings-'; export interface WidgetConfig { refreshRate: number; accentColor: 'primary' | 'accent' | 'destructive' | 'orange'; showHeader: boolean; expanded: boolean; opacity: number; } interface UseWidgetSettingsOptions { widgetId: string; defaultConfig: WidgetConfig; defaultSettings: T; } interface StoredWidgetData { config: WidgetConfig; settings: T; lastUpdated: number; } export function useWidgetSettings>({ widgetId, defaultConfig, defaultSettings, }: UseWidgetSettingsOptions) { const storageKey = `${STORAGE_KEY_PREFIX}${widgetId}`; // Load initial state from localStorage const loadFromStorage = useCallback((): StoredWidgetData | null => { try { const stored = localStorage.getItem(storageKey); if (stored) { return JSON.parse(stored); } } catch (error) { console.warn(`[WidgetSettings] Failed to load settings for ${widgetId}:`, error); } return null; }, [storageKey, widgetId]); const [config, setConfigState] = useState(() => { const stored = loadFromStorage(); return stored?.config ?? defaultConfig; }); const [settings, setSettingsState] = useState(() => { const stored = loadFromStorage(); return stored?.settings ?? defaultSettings; }); // Save to localStorage whenever config or settings change useEffect(() => { const data: StoredWidgetData = { config, settings, lastUpdated: Date.now(), }; try { localStorage.setItem(storageKey, JSON.stringify(data)); } catch (error) { console.warn(`[WidgetSettings] Failed to save settings for ${widgetId}:`, error); } }, [config, settings, storageKey, widgetId]); const setConfig = useCallback((updates: Partial) => { setConfigState(prev => ({ ...prev, ...updates })); }, []); const setSettings = useCallback((updates: Partial) => { setSettingsState(prev => ({ ...prev, ...updates })); }, []); const resetToDefaults = useCallback(() => { setConfigState(defaultConfig); setSettingsState(defaultSettings); try { localStorage.removeItem(storageKey); } catch (error) { console.warn(`[WidgetSettings] Failed to remove settings for ${widgetId}:`, error); } }, [defaultConfig, defaultSettings, storageKey, widgetId]); return { config, settings, setConfig, setSettings, resetToDefaults, }; } // Utility to generate a stable widget ID export function generateWidgetId(name: string, widgetType?: string): string { const sanitized = name.toLowerCase().replace(/[^a-z0-9]/g, '-'); return widgetType ? `${widgetType}-${sanitized}` : sanitized; } // Utility to clear all widget settings export function clearAllWidgetSettings(): void { const keysToRemove: string[] = []; for (let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i); if (key?.startsWith(STORAGE_KEY_PREFIX)) { keysToRemove.push(key); } } keysToRemove.forEach(key => localStorage.removeItem(key)); } // Utility to export all widget settings export function exportWidgetSettings(): Record { const settings: Record = {}; for (let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i); if (key?.startsWith(STORAGE_KEY_PREFIX)) { try { settings[key] = JSON.parse(localStorage.getItem(key) || '{}'); } catch { // Skip invalid entries } } } return settings; } // Utility to import widget settings export function importWidgetSettings(settings: Record): void { Object.entries(settings).forEach(([key, value]) => { if (key.startsWith(STORAGE_KEY_PREFIX)) { localStorage.setItem(key, JSON.stringify(value)); } }); }