Fortune-Email/stories/CustomizationDecorator.tsx
2025-12-21 18:05:16 +03:00

85 lines
2.4 KiB
TypeScript

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<BrandingConfig>(() => {
// 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<BrandingConfig>) => {
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 handleMessage = (event: MessageEvent) => {
if (event.data?.type === "CUSTOMIZATION_UPDATE") {
updateConfig(event.data.config);
}
};
window.addEventListener("storage", handleStorageChange);
window.addEventListener("message", handleMessage);
return () => {
window.removeEventListener("storage", handleStorageChange);
window.removeEventListener("message", handleMessage);
};
}, [updateConfig]);
return (
<BrandingContext.Provider value={{ config, updateConfig }}>
{children}
</BrandingContext.Provider>
);
};