import React, { useState, useCallback, useEffect } from "react"; import { BrandingContext } from "../src/hooks/useBrandingConfig"; import { BrandingConfig, defaultBrandingConfig } from "../src/config/branding.config"; interface CustomizationDecoratorProps { children: React.ReactNode; } const CUSTOMIZATION_STORAGE_KEY = "email-branding-config"; export const CustomizationDecorator = ({ children }: CustomizationDecoratorProps) => { const [config, setConfig] = useState(() => { // Load from localStorage if available if (typeof window !== "undefined") { const saved = localStorage.getItem(CUSTOMIZATION_STORAGE_KEY); if (saved) { try { return { ...defaultBrandingConfig, ...JSON.parse(saved) }; } catch (e) { return defaultBrandingConfig; } } } return defaultBrandingConfig; }); const updateConfig = useCallback((updates: Partial) => { setConfig((prev) => { const newConfig = { ...prev, ...updates, colors: { ...prev.colors, ...(updates.colors || {}), }, font: { ...prev.font, ...(updates.font || {}), }, }; // Save to localStorage if (typeof window !== "undefined") { localStorage.setItem(CUSTOMIZATION_STORAGE_KEY, JSON.stringify(newConfig)); } return newConfig; }); }, []); // Listen for customization updates from panel useEffect(() => { const handleStorageChange = (e: StorageEvent) => { if (e.key === CUSTOMIZATION_STORAGE_KEY && e.newValue) { try { const newConfig = { ...defaultBrandingConfig, ...JSON.parse(e.newValue) }; setConfig(newConfig); } catch (e) { // Ignore parse errors } } }; const handleCustomEvent = (e: CustomEvent) => { if (e.detail?.config) { setConfig((prev) => ({ ...prev, ...e.detail.config, colors: { ...prev.colors, ...(e.detail.config.colors || {}), }, font: { ...prev.font, ...(e.detail.config.font || {}), }, })); } }; const handleMessage = (event: MessageEvent) => { if (event.data?.type === "CUSTOMIZATION_UPDATE") { updateConfig(event.data.config); } }; // Poll localStorage for changes (for same-tab updates) const pollInterval = setInterval(() => { const saved = localStorage.getItem(CUSTOMIZATION_STORAGE_KEY); if (saved) { try { const savedConfig = JSON.parse(saved); setConfig((prev) => { const prevStr = JSON.stringify(prev); if (prevStr !== saved) { return { ...defaultBrandingConfig, ...savedConfig }; } return prev; }); } catch (e) { // Ignore parse errors } } }, 500); window.addEventListener("storage", handleStorageChange); window.addEventListener("message", handleMessage); window.addEventListener("customization-update" as any, handleCustomEvent as EventListener); return () => { clearInterval(pollInterval); window.removeEventListener("storage", handleStorageChange); window.removeEventListener("message", handleMessage); window.removeEventListener("customization-update" as any, handleCustomEvent as EventListener); }; }, [updateConfig]); return ( {children} ); };