Spaces:
Paused
Paused
| 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<T> { | |
| widgetId: string; | |
| defaultConfig: WidgetConfig; | |
| defaultSettings: T; | |
| } | |
| interface StoredWidgetData<T> { | |
| config: WidgetConfig; | |
| settings: T; | |
| lastUpdated: number; | |
| } | |
| export function useWidgetSettings<T extends Record<string, any>>({ | |
| widgetId, | |
| defaultConfig, | |
| defaultSettings, | |
| }: UseWidgetSettingsOptions<T>) { | |
| const storageKey = `${STORAGE_KEY_PREFIX}${widgetId}`; | |
| // Load initial state from localStorage | |
| const loadFromStorage = useCallback((): StoredWidgetData<T> | 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<WidgetConfig>(() => { | |
| const stored = loadFromStorage(); | |
| return stored?.config ?? defaultConfig; | |
| }); | |
| const [settings, setSettingsState] = useState<T>(() => { | |
| const stored = loadFromStorage(); | |
| return stored?.settings ?? defaultSettings; | |
| }); | |
| // Save to localStorage whenever config or settings change | |
| useEffect(() => { | |
| const data: StoredWidgetData<T> = { | |
| 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<WidgetConfig>) => { | |
| setConfigState(prev => ({ ...prev, ...updates })); | |
| }, []); | |
| const setSettings = useCallback((updates: Partial<T>) => { | |
| 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<string, any> { | |
| const settings: Record<string, any> = {}; | |
| 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<string, any>): void { | |
| Object.entries(settings).forEach(([key, value]) => { | |
| if (key.startsWith(STORAGE_KEY_PREFIX)) { | |
| localStorage.setItem(key, JSON.stringify(value)); | |
| } | |
| }); | |
| } | |