import { useState, useEffect, useCallback, useRef } from "react"; import { sanitizeHtml } from "@/shared/lib/sanitize"; import { useTranslation } from "react-i18next"; import { ArrowLeft, Loader, X, Plus } from "lucide-react"; import { TemplateService } from "@/user-management/services/api/templateService"; import { TemplateSampleRequest, TemplateResource, TemplateSampleData, TemplateSampleSetting, } from "@/user-management/services/TemplateConfiguration/types/templateTypes"; import { useTemplateFormData } from "./hooks/useTemplateFormData"; import { useHeaderFooterPresigned } from "@/record-management/components/hooks/useHeaderFooterPresigned"; import { useAuthUser } from "@/shared/hooks/useAuthUser"; import { toast } from "sonner"; import { TemplateLivePreview } from "./TemplateLivePreview"; import { isLetterLabelsSetting, normalizeLetterLabelsValue, } from "./utils/letterLabelsConstants"; import { isPageMarginSetting, normalizePageMarginValue, } from "./components/PageMarginEditor"; import { StyleSettingsEditor } from "./components/StyleSettingsEditor"; import CollapsibleSection from "./CollapsibleSection"; import { normalizeListStyleProps, styleObjectToCss, parseCSSDeclarations, cssStringToObject, parseCSSStringToObject, } from "./TemplateSampleForm.utils"; import { useListBulletResources } from "./hooks/useListBulletResources"; import { buildTemplateSamplePayload } from "./utils/templateSamplePayloadUtils"; interface TemplateSampleFormProps { templateId: string; onBack: () => void; onGeneratePreview: ( pdfUrl: string, valuesToSave: Array<{ templateSettingId: string; resourceId: string | null; value: Record; }>, ) => void; initialPayload?: { data: TemplateSampleData; settings: TemplateSampleSetting[]; }; } export const TemplateSampleForm = ({ templateId, onBack, onGeneratePreview, initialPayload, }: TemplateSampleFormProps) => { const { t } = useTranslation(); const { defaultFormData, departments, employees } = useTemplateFormData(); const { userDetails } = useAuthUser(); const unitId = userDetails?.employee?.[0]?.unitId; const [loading, setLoading] = useState(false); const [template, setTemplate] = useState(null); const [error, setError] = useState(null); const [selectedCollaborators, setSelectedCollaborators] = useState( [], ); const [selectedInternalCC, setSelectedInternalCC] = useState([]); const [selectedExternalCC, setSelectedExternalCC] = useState([]); const [selectedRecipients, setSelectedRecipients] = useState([]); const [formData, setFormData] = useState({ collaborators: [ { am: "ዮሃንስ ዶ", en: "John Doe" }, { am: "ማርያም ስሚዝ", en: "Mary Smith" }, ], preferredLanguage: "am", content: { isWithDelegateSignature: false, delegatorName: "", body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n\n- First item\n- Second item\n- Third item", date: new Date().toISOString().split("T")[0], internalCC: ["Finance Department", "HR Department"], externalCC: ["External Unit 1", "External Unit 2"], prefixCC: "CC:", suffixCC: "---", from: ["John Doe", "Mary Smith"], subject: "Sample Letter Subject - Important Notice", sincerelyText: "Sincerely", to: ["Jane Smith", "Robert Johnson"], prefix: "RE:", suffix: "---", }, recordType: "external", }); const [selectedHeaderId, setSelectedHeaderId] = useState(""); const [selectedFooterId, setSelectedFooterId] = useState(""); const [selectedHeader, setSelectedHeader] = useState(""); const [selectedFooter, setSelectedFooter] = useState(""); // Use the same hook as record form for headers/footers const { data: headerFooterData, isLoading: isHeaderFooterLoading } = useHeaderFooterPresigned(unitId!); const headers = headerFooterData?.headers || []; const footers = headerFooterData?.footers || []; // Settings state with default/custom tracking const [settings, setSettings] = useState([]); const [settingsLoading, setSettingsLoading] = useState(false); const [useDefaultSettings, setUseDefaultSettings] = useState< Record >({}); const [customSettings, setCustomSettings] = useState>( {}, ); const [resourceIds, setResourceIds] = useState>( {}, ); const { resources: bulletResources } = useListBulletResources(); const [payloadSample, setPayloadSample] = useState(); // State for collapsible sections const [expandedSections, setExpandedSections] = useState({ basicInfo: true, headerFooter: false, content: false, collaborators: false, recipients: false, }); const toggleSection = (section: keyof typeof expandedSections) => { setExpandedSections((prev) => ({ ...prev, [section]: !prev[section] })); }; useEffect(() => { if (templateId) { loadTemplate(); // Only load settings if they haven't been loaded yet if (settings.length === 0) { loadSettings(); } } // Cleanup timer on unmount return () => { if (settingsDebounceTimer.current) { clearTimeout(settingsDebounceTimer.current); } }; }, [templateId]); // Load initial payload if provided useEffect(() => { if (initialPayload) { // Set form data from payload if (initialPayload.data) { setFormData(initialPayload.data); } // Set settings from payload - use the outer 'value' property if (initialPayload.settings && initialPayload.settings.length > 0) { const processedSettings = initialPayload.settings.map((setting) => { let cssString = ""; // Use the outer 'value' property, not templateSettingValues const valueToUse = setting.value; // Typed (non-CSS) settings keep their object value intact. if (isLetterLabelsSetting(setting.code)) { return { ...setting, value: normalizeLetterLabelsValue(valueToUse) }; } if (isPageMarginSetting(setting.code)) { return { ...setting, value: normalizePageMarginValue(valueToUse) }; } // Convert object to CSS string if needed if (typeof valueToUse === "object" && valueToUse !== null) { cssString = Object.entries(valueToUse) .map(([key, value]) => { // Skip null values but keep SVG data URIs if (value === null || value === "null") return null; return `${key}: ${value};`; }) .filter(Boolean) .join(" "); } else if (typeof valueToUse === "string") { cssString = valueToUse; } return { ...setting, value: cssString, }; }); setSettings(processedSettings); // Mark all as using defaults initially const defaultMap: Record = {}; processedSettings.forEach((setting) => { defaultMap[setting.id] = true; }); setUseDefaultSettings(defaultMap); } } }, [initialPayload]); useEffect(() => { if (!defaultFormData) return; // Only update with defaultFormData if it has meaningful values // Otherwise keep the initialized defaults from component state setFormData((prev) => ({ ...prev, recordType: defaultFormData.recordType || prev.recordType, preferredLanguage: defaultFormData.preferredLanguage || prev.preferredLanguage, collaborators: defaultFormData.collaborators?.length > 0 ? defaultFormData.collaborators : prev.collaborators, content: { ...prev.content, isWithDelegateSignature: defaultFormData.content.isWithDelegateSignature ?? prev.content.isWithDelegateSignature, delegatorName: defaultFormData.content.delegatorName || prev.content.delegatorName, // Keep initialized defaults for body, subject, etc. if defaultFormData doesn't have them body: defaultFormData.content.body || prev.content.body, date: defaultFormData.content.date || prev.content.date, subject: defaultFormData.content.subject?.trim() ? defaultFormData.content.subject : prev.content.subject, sincerelyText: defaultFormData.content.sincerelyText || prev.content.sincerelyText, prefix: defaultFormData.content.prefix || prev.content.prefix, suffix: defaultFormData.content.suffix || prev.content.suffix, // Keep initialized defaults for CC and recipients if defaultFormData doesn't have them internalCC: defaultFormData.content.internalCC?.length > 0 ? defaultFormData.content.internalCC : prev.content.internalCC, externalCC: defaultFormData.content.externalCC?.length > 0 ? defaultFormData.content.externalCC : prev.content.externalCC, prefixCC: defaultFormData.content.prefixCC || prev.content.prefixCC, suffixCC: defaultFormData.content.suffixCC || prev.content.suffixCC, from: defaultFormData.content.from?.length > 0 ? defaultFormData.content.from : prev.content.from, to: defaultFormData.content.to?.length > 0 ? defaultFormData.content.to : prev.content.to, }, })); }, [defaultFormData]); // Keep UI selection state in sync when form data/defaults are loaded. useEffect(() => { if (!departments.length && !employees.length) return; const recipientIds = (formData.content.to || []) .map((name) => { const dept = departments.find( (d: any) => (d?.name?.en || d?.name?.am) === name, ); if (dept?.id) return dept.id; const emp = employees.find( (e: any) => (e?.user?.name?.en || e?.user?.name?.am) === name, ); return emp?.employeePositions?.[0]?.id || ""; }) .filter(Boolean); const internalCcIds = (formData.content.internalCC || []) .map((name) => { const dept = departments.find( (d: any) => (d?.name?.en || d?.name?.am) === name, ); return dept?.id || ""; }) .filter(Boolean); const collaboratorIds = (formData.collaborators || []) .map((collab) => { const fullName = collab.en || collab.am; const emp = employees.find( (e: any) => (e?.user?.name?.en || e?.user?.name?.am) === fullName, ); return emp?.employeePositions?.[0]?.id || ""; }) .filter(Boolean); setSelectedRecipients(recipientIds); setSelectedInternalCC(internalCcIds); setSelectedExternalCC(formData.content.externalCC || []); setSelectedCollaborators(collaboratorIds); }, [ formData.content.to, formData.content.internalCC, formData.content.externalCC, formData.collaborators, departments, employees, ]); // Update header/footer previews when selected or when headers/footers load useEffect(() => { if (headers.length) { if (selectedHeaderId) { const h = headers.find((x) => x.id === selectedHeaderId); if (h) setSelectedHeader( `
Header
`, ); } else { // Show first header by default setSelectedHeader( `
Header
`, ); } } if (footers.length) { if (selectedFooterId) { const f = footers.find((x) => x.id === selectedFooterId); if (f) setSelectedFooter( ``, ); } else { // Show first footer by default setSelectedFooter( ``, ); } } }, [headers, footers, selectedHeaderId, selectedFooterId]); const loadTemplate = async () => { try { setLoading(true); const data = await TemplateService.getTemplate(templateId); setTemplate(data); } catch (err) { setError(t("error.loadingTemplate", "Error loading template")); console.error(err); } finally { setLoading(false); } }; const loadSettings = async () => { try { setSettingsLoading(true); setError(null); const response = await TemplateService.getTemplateSettingsByUnit(templateId); const fetchedSettings = Array.isArray(response?.items) ? response.items : []; // ─── RAW API RESPONSE ──────────────────────────────────────────────── console.groupCollapsed( `%c[TemplateSettings] Raw fetch — ${fetchedSettings.length} settings`, "color:#6366f1; font-weight:bold;", ); console.table( fetchedSettings.map((s: any) => ({ code: s.code, id: s.id, rank: s.rank, outerValue: JSON.stringify(s.value), settingValuesCount: s.templateSettingValues?.length ?? 0, })), ); console.groupEnd(); // ───────────────────────────────────────────────────────────────────── if (fetchedSettings.length === 0) { console.warn("No template settings found for template:", templateId); } // Initialize settings with default values from API const initializedSettings = fetchedSettings .map((setting: any) => { // Ensure setting has required fields if (!setting.id || !setting.code) { console.warn("Setting missing required fields:", setting); return null; } let defaultValue: any = undefined; let chosenFrom = "none"; // ── 1. Prefer the outer `value` – this is the API's resolved current value // (e.g. what was saved last time the user clicked Generate Sample) if (setting.value !== null && setting.value !== undefined) { defaultValue = setting.value; chosenFrom = "outer setting.value (API resolved)"; } // ── 2. Fall back to templateSettingValues – prioritise entry with a unitId else if (setting.templateSettingValues?.length > 0) { const valueWithUnitId = setting.templateSettingValues.find( (tv: any) => tv.unitId !== null && tv.unitId !== undefined, ); if (valueWithUnitId?.value != null) { defaultValue = valueWithUnitId.value; chosenFrom = `templateSettingValues (unitId: ${valueWithUnitId.unitId})`; } else { const fallback = setting.templateSettingValues.find( (tv: any) => tv.value !== null && tv.value !== undefined, ); defaultValue = fallback?.value; chosenFrom = fallback ? "templateSettingValues (no unitId)" : "none"; } } // Typed (non-CSS) settings keep their object value intact. if (isLetterLabelsSetting(setting.code)) { return { ...setting, value: normalizeLetterLabelsValue(defaultValue) }; } if (isPageMarginSetting(setting.code)) { return { ...setting, value: normalizePageMarginValue(defaultValue) }; } // Convert the resolved value object → CSS string let cssString = ""; if ( typeof defaultValue === "object" && defaultValue !== null && Object.keys(defaultValue).length > 0 ) { cssString = Object.entries(defaultValue) .filter(([, v]) => v !== null && v !== undefined && v !== "null") .map(([key, value]) => `${key}: ${value};`) .join(" "); } else if (typeof defaultValue === "string" && defaultValue.trim()) { cssString = defaultValue; } // ─── PER-SETTING DEBUG ───────────────────────────────────────────── console.groupCollapsed( `%c[TemplateSettings] ${setting.code}`, "color:#0ea5e9; font-weight:bold;", ); console.log(" Full setting object: ", setting); console.log(" Outer value (API): ", setting.value); console.log( " templateSettingValues: ", setting.templateSettingValues, ); console.log(" ✅ Chosen from: ", chosenFrom); console.log(" Raw defaultValue used: ", defaultValue); console.log( " Final CSS string: ", cssString || "(empty — no value)", ); console.groupEnd(); // ────────────────────────────────────────────────────────────────── return { ...setting, value: cssString, }; }) .filter((s: any) => s !== null); setSettings(initializedSettings); const loadedResourceIds: Record = {}; initializedSettings.forEach((setting) => { if (!setting) return; const unitValue = setting.templateSettingValues?.find( (value: NonNullable[number]) => value.unitId != null, ); const defaultValue = setting.templateSettingValues?.find( (value: NonNullable[number]) => value.unitId == null, ); loadedResourceIds[setting.id] = setting.resourceId ?? unitValue?.resourceId ?? defaultValue?.resourceId ?? null; }); setResourceIds(loadedResourceIds); // Initialize all settings as using defaults const defaultMap: Record = {}; initializedSettings.forEach((setting) => { if (setting) { defaultMap[setting.id] = true; } }); setUseDefaultSettings(defaultMap); setCustomSettings({}); } catch (err) { console.error("Error loading settings:", err); setError(t("error.loadingSettings", "Error loading style settings")); toast.error(t("error.loadingSettings", "Error loading style settings")); } finally { setSettingsLoading(false); } }; const handleResourceIdChange = useCallback( (settingId: string, resourceId: string | null) => { setResourceIds((previous) => ({ ...previous, [settingId]: resourceId })); }, [], ); const handleGenerateSample = async () => { if (!templateId) return; try { setLoading(true); setError(null); // Build header object - use first header if available let headerObj: any = undefined; if (selectedHeaderId) { const selectedHeaderData = headers.find( (h) => h.id === selectedHeaderId, ); if (selectedHeaderData?.fileInfo) { headerObj = selectedHeaderData.fileInfo; } } else if (headers.length > 0) { // Use first header as default headerObj = headers[0].fileInfo; } // Build footer object - use first footer if available let footerObj: any = undefined; if (selectedFooterId) { const selectedFooterData = footers.find( (f) => f.id === selectedFooterId, ); if (selectedFooterData?.fileInfo) { footerObj = selectedFooterData.fileInfo; } } else if (footers.length > 0) { // Use first footer as default footerObj = footers[0].fileInfo; } // Add unitId and header/footer to formData const dataWithUnitIdAndHeaderFooter = { ...formData, unitId: unitId || "", ...(headerObj && { header: headerObj }), ...(footerObj && { footer: footerObj }), }; const resolveSettingValue = ( setting: TemplateSampleSetting, ): Record => { if (isLetterLabelsSetting(setting.code)) { return normalizeLetterLabelsValue(setting.value); } if (isPageMarginSetting(setting.code)) { return normalizePageMarginValue(setting.value); } const cssString = typeof setting.value === "string" ? setting.value : ""; const valueObj = cssStringToObject(cssString); if (valueObj["list-style"] === "disclosure-closed") { const svgTriangle = ``; valueObj["list-style-image"] = `url('data:image/svg+xml;base64,${btoa(svgTriangle)}')`; } if ( valueObj["list-style-image"] === "null" && valueObj["list-style"] === "disclosure-closed" ) { const svgTriangle = ``; valueObj["list-style-image"] = `url('data:image/svg+xml;base64,${btoa(svgTriangle)}')`; } return valueObj; }; const payload = buildTemplateSamplePayload({ data: dataWithUnitIdAndHeaderFooter, settings, resourceIds, bulletResources, resolveSettingValue, }); const settingsForAPI = payload.settings ?? []; const valuesToSave = settingsForAPI .map((setting) => { const valueObj = setting.value as Record; if (!valueObj || Object.keys(valueObj).length === 0) return null; const resourceId = setting.resourceId ?? null; return { templateSettingId: setting.id!, resourceId, value: valueObj, }; }) .filter((item) => item !== null) as Array<{ templateSettingId: string; resourceId: string | null; value: Record; }>; console.log("Values to save:", valuesToSave); const response = await TemplateService.generateSampleTemplate( templateId, payload, ); if (response.pdf) { console.log("PDF URL set:", response.pdf); onGeneratePreview(response.pdf, valuesToSave); } else { setError(t("error.noPdfInResponse", "No PDF in response")); } } catch (err: any) { const errorMessage = err?.response?.data?.message || err?.message || t("error.generatingSample", "Error generating sample"); console.error("Error generating sample:", err); setError(errorMessage); } finally { setLoading(false); } }; const handleContentChange = useCallback((field: string, value: any) => { setFormData((prev) => ({ ...prev, content: { ...prev.content, [field]: value, }, })); }, []); // Debounce timer for settings changes const settingsDebounceTimer = useRef(null); const handleSettingChange = useCallback( (index: number, cssString: string) => { console.log("handleSettingChange called", { index, cssString }); // ✅ Update settings immediately using functional update setSettings((prevSettings) => { const settingId = prevSettings[index]?.id; if (!settingId) { console.log("No settingId found at index", index); return prevSettings; } // Create a new array with a new object for the changed item (avoid mutation) const newSettings = prevSettings.map((s, i) => i === index ? { ...s, value: cssString } : s, ); // Update related state immediately setUseDefaultSettings((prev) => ({ ...prev, [settingId]: false, })); setCustomSettings((prev) => ({ ...prev, [settingId]: cssString, })); return newSettings; }); }, [], // ✅ No dependencies - uses functional updates to avoid stale closures ); const handleToggleDefault = useCallback( (settingId: string) => { setUseDefaultSettings((prev) => { const newValue = !prev[settingId]; if (newValue) { // Switching back to default - remove from custom setCustomSettings((prevCustom) => { const newCustom = { ...prevCustom }; delete newCustom[settingId]; return newCustom; }); // Reset the setting value to default const settingIndex = settings.findIndex((s) => s.id === settingId); if (settingIndex >= 0) { const defaultValue = (settings[settingIndex] as any).templateSettingValues?.[0] ?.value || {}; let cssString = ""; if (typeof defaultValue === "object" && defaultValue !== null) { cssString = Object.entries(defaultValue) .map(([key, value]) => `${key}: ${value};`) .join(" "); } setSettings((prev) => { const newSettings = [...prev]; newSettings[settingIndex].value = cssString; return newSettings; }); } } return { ...prev, [settingId]: newValue }; }); }, [settings], ); const handleAddCollaborator = () => { setFormData((prev) => ({ ...prev, collaborators: [...prev.collaborators, { am: "", en: "" }], })); }; const handleCollaboratorChange = ( index: number, lang: "am" | "en", value: string, ) => { const newCollaborators = [...formData.collaborators]; newCollaborators[index][lang] = value; setFormData((prev) => ({ ...prev, collaborators: newCollaborators, })); }; const handleSelectCollaborator = (employeeId: string) => { const employee = employees.find( (emp: any) => emp.employeePositions?.[0]?.id === employeeId, ); if (employee && !selectedCollaborators.includes(employeeId)) { const newCollaborators = [ ...formData.collaborators, { am: employee.user?.name?.am || "", en: employee.user?.name?.en || "", }, ]; setFormData((prev) => ({ ...prev, collaborators: newCollaborators, content: { ...prev.content, from: newCollaborators.map((c) => c.en || c.am), }, })); setSelectedCollaborators([...selectedCollaborators, employeeId]); } }; const handleRemoveCollaborator = (index: number) => { const newCollaborators = formData.collaborators.filter( (_, i) => i !== index, ); setFormData((prev) => ({ ...prev, collaborators: newCollaborators, content: { ...prev.content, from: newCollaborators.map((c) => c.en || c.am), }, })); }; const handleSelectInternalCC = (departmentId: string) => { const dept = departments.find((d: any) => d.id === departmentId); if (dept && !selectedInternalCC.includes(departmentId)) { const newInternalCC = [...selectedInternalCC, departmentId]; setSelectedInternalCC(newInternalCC); setFormData((prev) => ({ ...prev, content: { ...prev.content, internalCC: newInternalCC.map((id) => { const d = departments.find((d: any) => d.id === id); return d?.name?.en || d?.name?.am || id; }), }, })); } }; const handleRemoveInternalCC = (departmentId: string) => { const newInternalCC = selectedInternalCC.filter( (id) => id !== departmentId, ); setSelectedInternalCC(newInternalCC); setFormData((prev) => ({ ...prev, content: { ...prev.content, internalCC: newInternalCC.map((id) => { const d = departments.find((d: any) => d.id === id); return d?.name?.en || d?.name?.am || id; }), }, })); }; const handleSelectExternalCC = (unitName: string) => { if (!selectedExternalCC.includes(unitName)) { const newExternalCC = [...selectedExternalCC, unitName]; setSelectedExternalCC(newExternalCC); setFormData((prev) => ({ ...prev, content: { ...prev.content, externalCC: newExternalCC, }, })); } }; const handleRemoveExternalCC = (unitName: string) => { const newExternalCC = selectedExternalCC.filter((u) => u !== unitName); setSelectedExternalCC(newExternalCC); setFormData((prev) => ({ ...prev, content: { ...prev.content, externalCC: newExternalCC, }, })); }; const handleSelectRecipient = (recipientId: string) => { if (!selectedRecipients.includes(recipientId)) { const newRecipients = [...selectedRecipients, recipientId]; setSelectedRecipients(newRecipients); setFormData((prev) => ({ ...prev, content: { ...prev.content, to: newRecipients.map((id) => { const dept = departments.find((d: any) => d.id === id); const emp = employees.find( (e: any) => e.employeePositions?.[0]?.id === id, ); return ( dept?.name?.en || dept?.name?.am || emp?.user?.name?.en || emp?.user?.name?.am || id ); }), }, })); } }; const handleRemoveRecipient = (recipientId: string) => { const newRecipients = selectedRecipients.filter((id) => id !== recipientId); setSelectedRecipients(newRecipients); setFormData((prev) => ({ ...prev, content: { ...prev.content, to: newRecipients.map((id) => { const dept = departments.find((d: any) => d.id === id); const emp = employees.find( (e: any) => e.employeePositions?.[0]?.id === id, ); return ( dept?.name?.en || dept?.name?.am || emp?.user?.name?.en || emp?.user?.name?.am || id ); }), }, })); }; if (loading && !template) { return (
); } // Helper to get settings for a specific section const getSettingsBySection = (sectionCode: string) => { return settings.filter((s) => s.code.includes(sectionCode)); }; // Match any of the provided aliases so API code variations can still show in UI. const getSettingsByAliases = (aliases: string[]) => { const normalizedAliases = aliases.map((alias) => alias.toLowerCase()); return settings.filter((setting) => { const code = setting.code.toLowerCase(); return normalizedAliases.some((alias) => code.includes(alias)); }); }; const renderSettingsEditors = (matchedSettings: TemplateSampleSetting[]) => { if (matchedSettings.length === 0) return null; return matchedSettings.map((setting) => { const originalIndex = settings.findIndex((s) => s.code === setting.code); return ( handleResourceIdChange(setting.id, resourceId) } /> ); }); }; console.log("form data", formData); console.log("settings", settings); return (
{/* Header */}

{t("template.sample", "Template Sample")}

{template && (

{template.name?.en || template.name?.am}

)}
{error && (
{error}
)} {/* Two-column layout - grid with proper alignment */}
{/* Left column: collapsible sections (2 columns wide) */}
{/* Basic Information (unchanged) */} toggleSection("basicInfo")}>
{/* Header & Footer Section */} toggleSection("headerFooter")}>
{selectedHeader && (

{t("addRecord.Header Preview", "Header Preview")}

)} {/* Header Style Settings */} {getSettingsBySection("header").length > 0 && (

{t("template.headerStyleSettings", "Header Style Settings")}

{getSettingsBySection("header").map((setting) => { const originalIndex = settings.findIndex( (s) => s.code === setting.code, ); return ( ); })}
)} {selectedFooter && (

{t("addRecord.Footer Preview", "Footer Preview")}

)} {/* Footer Style Settings */} {getSettingsBySection("footer").length > 0 && (

{t("template.footerStyleSettings", "Footer Style Settings")}

{getSettingsBySection("footer").map((setting) => { const originalIndex = settings.findIndex( (s) => s.code === setting.code, ); return ( ); })}
)}
{/* Content Section */} toggleSection("content")}>
handleContentChange("subject", e.target.value) } className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500" /> {/* Subject Style Settings */} {getSettingsBySection("subject").length > 0 && (

{t( "template.subjectStyleSettings", "Subject Style Settings", )}

{getSettingsBySection("subject").map((setting) => { const originalIndex = settings.findIndex( (s) => s.code === setting.code, ); return ( ); })}
)}
handleContentChange("date", e.target.value)} className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500" />