@zenith-open/zenithcms-admin 1.0.0-beta.5 → 1.0.0-beta.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/assets/{ApiExplorerPage-CLsHG-Ke.js → ApiExplorerPage-85UWt1EW.js} +1 -1
  2. package/dist/assets/{ApiExplorerPage-CLsHG-Ke.js.map → ApiExplorerPage-85UWt1EW.js.map} +1 -1
  3. package/dist/assets/{AuditLogPage-Bp2Nvabr.js → AuditLogPage-CwULx1tr.js} +1 -1
  4. package/dist/assets/{AuditLogPage-Bp2Nvabr.js.map → AuditLogPage-CwULx1tr.js.map} +1 -1
  5. package/dist/assets/{BlockBuilderPage-CeVMk5Ns.js → BlockBuilderPage-XD1IjOgx.js} +1 -1
  6. package/dist/assets/{BlockBuilderPage-CeVMk5Ns.js.map → BlockBuilderPage-XD1IjOgx.js.map} +1 -1
  7. package/dist/assets/{CollectionHooksPage-EFkVZNrc.js → CollectionHooksPage-DIaSrKDj.js} +1 -1
  8. package/dist/assets/{CollectionHooksPage-EFkVZNrc.js.map → CollectionHooksPage-DIaSrKDj.js.map} +1 -1
  9. package/dist/assets/{CollectionsPage-D-N_ykJz.js → CollectionsPage-CL_t5JRI.js} +1 -1
  10. package/dist/assets/{CollectionsPage-D-N_ykJz.js.map → CollectionsPage-CL_t5JRI.js.map} +1 -1
  11. package/dist/assets/{ComponentBuilderPage-C3mhOLPs.js → ComponentBuilderPage-C58Rr1cu.js} +1 -1
  12. package/dist/assets/{ComponentBuilderPage-C3mhOLPs.js.map → ComponentBuilderPage-C58Rr1cu.js.map} +1 -1
  13. package/dist/assets/{DashboardBuilder-Beiurp0v.js → DashboardBuilder-Chjyqyb7.js} +1 -1
  14. package/dist/assets/{DashboardBuilder-Beiurp0v.js.map → DashboardBuilder-Chjyqyb7.js.map} +1 -1
  15. package/dist/assets/{PluginsPage-BjPoOvBl.js → PluginsPage-DAR4Fsz-.js} +1 -1
  16. package/dist/assets/{PluginsPage-BjPoOvBl.js.map → PluginsPage-DAR4Fsz-.js.map} +1 -1
  17. package/dist/assets/{RedirectsPage-GIZCbEll.js → RedirectsPage-DfMTJsac.js} +1 -1
  18. package/dist/assets/{RedirectsPage-GIZCbEll.js.map → RedirectsPage-DfMTJsac.js.map} +1 -1
  19. package/dist/assets/{SchemaBuilderPage-3CDbJi28.js → SchemaBuilderPage-BYprOkEv.js} +1 -1
  20. package/dist/assets/{SchemaBuilderPage-3CDbJi28.js.map → SchemaBuilderPage-BYprOkEv.js.map} +1 -1
  21. package/dist/assets/{SettingsPage-DYYNnxkV.js → SettingsPage-B2r_uNVc.js} +1 -1
  22. package/dist/assets/{SettingsPage-DYYNnxkV.js.map → SettingsPage-B2r_uNVc.js.map} +1 -1
  23. package/dist/assets/SetupWizard-CBA43yJr.js +62 -0
  24. package/dist/assets/SetupWizard-CBA43yJr.js.map +1 -0
  25. package/dist/assets/SpatialEditor-BohlovfE.js +3 -0
  26. package/dist/assets/SpatialEditor-BohlovfE.js.map +1 -0
  27. package/dist/assets/{TemplatesPage-DfeCDCe_.js → TemplatesPage-BplB2ksb.js} +1 -1
  28. package/dist/assets/{TemplatesPage-DfeCDCe_.js.map → TemplatesPage-BplB2ksb.js.map} +1 -1
  29. package/dist/assets/{TrashPage-DGi-7RPl.js → TrashPage-BIhKrs5x.js} +1 -1
  30. package/dist/assets/{TrashPage-DGi-7RPl.js.map → TrashPage-BIhKrs5x.js.map} +1 -1
  31. package/dist/assets/{index-C4J6QNLn.js → index-yE_3fruG.js} +3 -3
  32. package/dist/assets/index-yE_3fruG.js.map +1 -0
  33. package/dist/index.html +1 -1
  34. package/dist/sw.js +1 -1
  35. package/dist/sw.js.map +1 -1
  36. package/package.json +4 -4
  37. package/dist/assets/SetupWizard-D57HIkrs.js +0 -62
  38. package/dist/assets/SetupWizard-D57HIkrs.js.map +0 -1
  39. package/dist/assets/SpatialEditor-DlyP5PPa.js +0 -3
  40. package/dist/assets/SpatialEditor-DlyP5PPa.js.map +0 -1
  41. package/dist/assets/index-C4J6QNLn.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SpatialEditor-BohlovfE.js","names":[],"sources":["../../src/pages/editor/components/BlockContextMenu.tsx","../../src/store/slices/utils.ts","../../src/store/slices/documentSlice.ts","../../src/store/slices/uiSlice.ts","../../src/store/slices/mediaSlice.ts","../../src/store/slices/relationsSlice.ts","../../src/store/editorStore.ts","../../src/store/panelStore.ts","../../src/pages/editor/components/LeftPanel.tsx","../../src/hooks/useTenantStorage.ts","../../src/store/commentsStore.ts","../../src/pages/editor/components/CommentsPanel.tsx","../../src/pages/editor/components/RightPanel.tsx","../../src/components/FocalPointCropper.tsx","../../src/components/MediaPicker.tsx","../../src/components/RelationPicker.tsx","../../src/lib/form-utils.ts","../../src/components/fields/TextField.tsx","../../src/components/fields/TextareaField.tsx","../../src/components/fields/SelectField.tsx","../../src/components/fields/BooleanField.tsx","../../src/components/fields/NumberField.tsx","../../src/components/fields/CodeField.tsx","../../src/components/fields/CollapsibleField.tsx","../../src/components/fields/GroupField.tsx","../../src/components/fields/JSONField.tsx","../../src/components/fields/DateField.tsx","../../src/components/fields/SlugField.tsx","../../src/components/fields/UIDField.tsx","../../src/components/fields/TabField.tsx","../../src/components/fields/SpecialFields.tsx","../../src/components/BlocksBuilder.tsx","../../src/components/SimpleArrayBuilder.tsx","../../src/components/FormBuilder.tsx","../../src/components/DocumentEditModal.tsx","../../src/pages/editor/components/InlineRelationPicker.tsx","../../src/pages/editor/components/NestedDynamicZone.tsx","../../src/pages/editor/fieldRegistry.ts","../../src/pages/editor/FieldRenderer.tsx","../../src/pages/editor/components/SectionBlock.tsx","../../src/pages/editor/components/BlockPickerModal.tsx","../../src/pages/editor/components/SEOModal.tsx","../../src/pages/editor/components/TemplatesModal.tsx","../../src/pages/editor/components/RelationsModal.tsx","../../src/pages/editor/components/MediaLibraryModal.tsx","../../src/pages/editor/components/DynamicZoneModal.tsx","../../src/store/workflowStore.ts","../../src/store/i18nStore.ts","../../src/pages/editor/components/AutoSaveIndicator.tsx","../../src/pages/editor/components/SchedulePicker.tsx","../../src/pages/editor/components/ConfirmPublishModal.tsx","../../src/pages/editor/components/TranslationModal.tsx","../../src/hooks/useCollab.ts","../../src/pages/editor/components/CollabAvatars.tsx","../../src/pages/editor/EditorToolbar.tsx","../../src/pages/editor/SpatialBlockRenderer.tsx","../../src/components/EditorErrorBoundary.tsx","../../src/pages/editor/components/DocumentDiffModal.tsx","../../src/pages/editor/components/ConflictResolutionModal.tsx","../../src/pages/editor/components/EditorStatusBar.tsx","../../src/hooks/usePreviewSync.ts","../../src/hooks/useValidation.ts","../../src/pages/editor/hooks/useSpatialSave.ts","../../src/pages/SpatialEditor.tsx"],"sourcesContent":["import React, { useEffect, useRef } from 'react'\nimport { motion } from 'framer-motion'\nimport { Copy, Trash2, AlignLeft, AlignCenter, AlignRight, RefreshCw, ChevronRight } from 'lucide-react'\nimport { cn } from '../../../lib/utils'\nimport { useEditorBlocks } from '../../../context/BlockLibraryContext'\n\ninterface BlockContextMenuProps {\n x: number\n y: number\n theme: 'light' | 'dark'\n onClose: () => void\n onDuplicate: () => void\n onDelete: () => void\n onAlign: (align: 'left' | 'center' | 'right') => void\n onConvert: (blockType: string) => void\n}\n\nexport const BlockContextMenu: React.FC<BlockContextMenuProps> = ({\n x,\n y,\n theme,\n onClose,\n onDuplicate,\n onDelete,\n onAlign,\n onConvert,\n}) => {\n const BLOCK_LIBRARY = useEditorBlocks()\n const menuRef = useRef<HTMLDivElement>(null)\n const [showConvertMenu, setShowConvertMenu] = React.useState(false)\n\n useEffect(() => {\n const handleOutsideClick = (e: MouseEvent) => {\n if (menuRef.current && !menuRef.current.contains(e.target as Node)) {\n onClose()\n }\n }\n window.addEventListener('mousedown', handleOutsideClick)\n return () => window.removeEventListener('mousedown', handleOutsideClick)\n }, [onClose])\n\n // Adjust coordinates if menu would render off screen\n const [coords, setCoords] = React.useState({ top: y, left: x })\n\n useEffect(() => {\n if (menuRef.current) {\n const rect = menuRef.current.getBoundingClientRect()\n const newCoords = { top: y, left: x }\n if (x + rect.width > window.innerWidth) {\n newCoords.left = x - rect.width\n }\n if (y + rect.height > window.innerHeight) {\n newCoords.top = y - rect.height\n }\n setCoords(newCoords)\n }\n }, [x, y])\n\n return (\n <div\n ref={menuRef}\n style={{ top: coords.top, left: coords.left }}\n className=\"fixed z-[999] w-56 select-none font-sans\"\n >\n <motion.div\n initial={{ opacity: 0, scale: 0.95, y: -5 }}\n animate={{ opacity: 1, scale: 1, y: 0 }}\n exit={{ opacity: 0, scale: 0.95, y: -5 }}\n transition={{ duration: 0.15 }}\n className={cn(\n 'p-1.5 border rounded-none-none shadow-2xl backdrop-blur-xl relative',\n theme === 'dark'\n ? 'bg-app/95 border-z-border text-z-primary'\n : 'bg-z-panel/95 border-z-border text-z-primary shadow-sm/50'\n )}\n >\n {/* Transform Submenu Trigger */}\n <div className=\"relative\">\n <button\n onMouseEnter={() => setShowConvertMenu(true)}\n onClick={() => setShowConvertMenu(!showConvertMenu)}\n className={cn(\n 'w-full flex items-center justify-between px-3 py-2 text-left text-xs font-semibold rounded-none-none transition-colors',\n theme === 'dark' ? 'hover:bg-z-hover' : 'hover:bg-[var(--z-bg-hover)]'\n )}\n >\n <span className=\"flex items-center gap-2\">\n <RefreshCw size={13} className=\"text-z-secondary\" />\n Convert to Layout\n </span>\n <ChevronRight size={12} className=\"opacity-50\" />\n </button>\n\n {/* Submenu */}\n {showConvertMenu && (\n <div\n className=\"absolute left-full top-0 ml-1 w-52 select-none\"\n onMouseLeave={() => setShowConvertMenu(false)}\n >\n <motion.div\n initial={{ opacity: 0, x: -5 }}\n animate={{ opacity: 1, x: 0 }}\n className={cn(\n 'p-1.5 border rounded-none-none shadow-2xl backdrop-blur-xl max-h-72 overflow-y-auto custom-editor-scrollbar',\n theme === 'dark'\n ? 'bg-app/95 border-z-border text-z-primary'\n : 'bg-z-panel/95 border-z-border text-z-primary'\n )}\n >\n {BLOCK_LIBRARY.map((block) => (\n <button\n key={block.type}\n onClick={() => {\n onConvert(block.type)\n onClose()\n }}\n className={cn(\n 'w-full flex items-center gap-2.5 px-2.5 py-1.5 text-left text-xs rounded-none-none transition-colors font-medium',\n theme === 'dark' ? 'hover:bg-z-hover' : 'hover:bg-[var(--z-bg-hover)]'\n )}\n >\n {block.icon && <block.icon size={13} className=\"text-z-secondary shrink-0\" />}\n <span className=\"truncate\">{block.title}</span>\n </button>\n ))}\n </motion.div>\n </div>\n )}\n </div>\n\n <div className={cn('h-px my-1', theme === 'dark' ? 'bg-z-hover' : 'bg-[var(--z-bg-hover)]')} />\n\n {/* Duplicate */}\n <button\n onClick={() => {\n onDuplicate()\n onClose()\n }}\n className={cn(\n 'w-full flex items-center gap-2 px-3 py-2 text-left text-xs font-semibold rounded-none-none transition-colors',\n theme === 'dark' ? 'hover:bg-z-hover' : 'hover:bg-[var(--z-bg-hover)]'\n )}\n >\n <Copy size={13} className=\"text-z-secondary\" />\n Duplicate Section\n </button>\n\n {/* Align Submenu */}\n <div className={cn('h-px my-1', theme === 'dark' ? 'bg-z-hover' : 'bg-[var(--z-bg-hover)]')} />\n <div className=\"px-3 py-1.5 text-xs font-semibold opacity-40\">Alignment</div>\n <div className=\"flex gap-1 px-1.5 pb-1\">\n <button\n onClick={() => { onAlign('left'); onClose() }}\n aria-label=\"Align left\"\n className={cn('flex-1 flex items-center justify-center p-1.5 border rounded-none-none transition-all', theme === 'dark' ? 'border-z-border hover:border-z-border/30 hover:bg-z-hover text-z-muted hover:text-z-secondary' : 'border-z-border hover:border-z-border hover:bg-[var(--z-bg-input)] text-z-secondary hover:text-z-secondary')}\n >\n <AlignLeft size={13} aria-hidden=\"true\" />\n </button>\n <button\n onClick={() => { onAlign('center'); onClose() }}\n aria-label=\"Align center\"\n className={cn('flex-1 flex items-center justify-center p-1.5 border rounded-none-none transition-all', theme === 'dark' ? 'border-z-border hover:border-z-border/30 hover:bg-z-hover text-z-muted hover:text-z-secondary' : 'border-z-border hover:border-z-border hover:bg-[var(--z-bg-input)] text-z-secondary hover:text-z-secondary')}\n >\n <AlignCenter size={13} aria-hidden=\"true\" />\n </button>\n <button\n onClick={() => { onAlign('right'); onClose() }}\n aria-label=\"Align right\"\n className={cn('flex-1 flex items-center justify-center p-1.5 border rounded-none-none transition-all', theme === 'dark' ? 'border-z-border hover:border-z-border/30 hover:bg-z-hover text-z-muted hover:text-z-secondary' : 'border-z-border hover:border-z-border hover:bg-[var(--z-bg-input)] text-z-secondary hover:text-z-secondary')}\n >\n <AlignRight size={13} aria-hidden=\"true\" />\n </button>\n </div>\n\n <div className={cn('h-px my-1', theme === 'dark' ? 'bg-z-hover' : 'bg-[var(--z-bg-hover)]')} />\n\n {/* Delete */}\n <button\n onClick={() => {\n onDelete()\n onClose()\n }}\n className={cn(\n 'w-full flex items-center gap-2 px-3 py-2 text-left text-xs font-semibold rounded-none-none transition-colors',\n theme === 'dark' ? 'hover:bg-rose-500/10 text-rose-400' : 'hover:bg-rose-50 text-rose-600'\n )}\n >\n <Trash2 size={13} className=\"text-rose-500\" />\n Delete Section\n </button>\n </motion.div>\n </div>\n )\n}\n","import type { PageData } from './types'\n\nexport const STORAGE_KEY = 'zenith_editor_state'\nexport const MAX_UNDO_STACK = 200\nexport const UNDO_DEBOUNCE_MS = 1200\n\nexport const loadPersisted = () => {\n try {\n const raw = localStorage.getItem(STORAGE_KEY)\n if (!raw) return null\n const parsed = JSON.parse(raw)\n if (parsed && typeof parsed === 'object') {\n const d = parsed.data || parsed\n const undoStack = Array.isArray(parsed.undoStack) ? parsed.undoStack : []\n const redoStack = Array.isArray(parsed.redoStack) ? parsed.redoStack : []\n return { data: d as PageData, undoStack: undoStack as PageData[], redoStack: redoStack as PageData[] }\n }\n } catch { /* ignore corrupt storage */ }\n return null\n}\n\nexport const deepClone = <T,>(obj: T): T =>\n typeof structuredClone === 'function'\n ? structuredClone(obj)\n : JSON.parse(JSON.stringify(obj))\n","import { produce } from 'immer'\nimport api from '../../lib/api'\nimport type { EditorSliceCreator, DocumentSlice, PageData } from './types'\nimport { loadPersisted, deepClone, UNDO_DEBOUNCE_MS, MAX_UNDO_STACK } from './utils'\n\nlet lastUndoTime = 0\nconst restored = loadPersisted()\n\nexport const createDocumentSlice: EditorSliceCreator<DocumentSlice> = (set, get) => ({\n data: restored ? (restored.data as PageData) : null,\n loading: false,\n saving: false,\n hasUnsavedChanges: false,\n lastSavedAt: null,\n undoStack: restored ? restored.undoStack : [],\n redoStack: restored ? restored.redoStack : [],\n dirtySections: new Set<string>(),\n\n schemaFields: [],\n fieldSettings: {},\n fieldErrors: {},\n history: [],\n templates: [],\n topLevelFields: [],\n\n setData: (data) => set({ data }),\n setLoading: (loading) => set({ loading }),\n setSaving: (saving) => set({ saving }),\n setHasUnsavedChanges: (hasUnsavedChanges) => set({ hasUnsavedChanges }),\n setLastSavedAt: (lastSavedAt) => set({ lastSavedAt }),\n setSchemaFields: (schemaFields) => set({ schemaFields }),\n setFieldSettings: (fieldSettings) => set({ fieldSettings }),\n setFieldErrors: (fieldErrors) => set({ fieldErrors }),\n setHistory: (history) => set({ history }),\n setTemplates: (templates) => set({ templates }),\n setTopLevelFields: (topLevelFields) => set({ topLevelFields }),\n\n updateData: (updater) => {\n const current = get().data\n if (!current) return\n const newData = produce(current, (draft) => {\n const result = updater(draft as PageData)\n if (result !== undefined) Object.assign(draft, result)\n })\n set((state) => {\n const now = Date.now()\n const shouldPushUndo = (now - lastUndoTime) > UNDO_DEBOUNCE_MS\n const nextUndoStack = shouldPushUndo\n ? [...state.undoStack.slice(-MAX_UNDO_STACK + 1), current]\n : state.undoStack\n if (shouldPushUndo) lastUndoTime = now\n \n const nextDirty = new Set(state.dirtySections)\n newData.sections.forEach((s) => nextDirty.add(s.id))\n return ({\n data: newData,\n hasUnsavedChanges: true,\n undoStack: nextUndoStack,\n redoStack: [],\n dirtySections: nextDirty,\n })\n })\n },\n\n setField: (sectionId, fieldKey, value) => {\n let current: PageData | null\n try {\n current = get().data\n } catch {\n return\n }\n if (!current) return\n const now = Date.now()\n const shouldPushUndo = (now - lastUndoTime) > UNDO_DEBOUNCE_MS\n const nextUndoStack = shouldPushUndo\n ? [...get().undoStack.slice(-MAX_UNDO_STACK + 1), deepClone(current)]\n : get().undoStack\n if (shouldPushUndo) lastUndoTime = now\n\n const newSections = current.sections.map((s) => {\n if (s.id !== sectionId) return s\n if (s.content[fieldKey] === value) return s\n return { ...s, content: { ...s.content, [fieldKey]: value } }\n })\n const newData = { ...current, sections: newSections }\n const nextDirty = new Set(get().dirtySections)\n nextDirty.add(sectionId)\n set({\n data: newData,\n hasUnsavedChanges: true,\n undoStack: nextUndoStack,\n redoStack: [],\n dirtySections: nextDirty,\n })\n },\n\n undo: () => {\n const { data, undoStack, redoStack } = get()\n if (!data || undoStack.length === 0) return\n const previous = undoStack[undoStack.length - 1]\n const newUndoStack = undoStack.slice(0, -1)\n const redoState = deepClone(data)\n const nextRedo = [...redoStack.slice(-MAX_UNDO_STACK + 1), redoState]\n set({\n data: previous,\n undoStack: newUndoStack,\n redoStack: nextRedo,\n hasUnsavedChanges: true,\n })\n },\n\n redo: () => {\n const { data, undoStack, redoStack } = get()\n if (!data || redoStack.length === 0) return\n const next = redoStack[redoStack.length - 1]\n const newRedoStack = redoStack.slice(0, -1)\n const currentState = deepClone(data)\n const nextUndo = [...undoStack.slice(-MAX_UNDO_STACK + 1), currentState]\n set({\n data: next,\n undoStack: nextUndo,\n redoStack: newRedoStack,\n hasUnsavedChanges: true,\n })\n },\n\n load: async (slug, id, isGlobal) => {\n set({ data: null, loading: true, undoStack: [], redoStack: [], hasUnsavedChanges: false })\n try {\n const res = isGlobal\n ? await api.get(`/globals/${id}`)\n : await api.get(`/${slug}/${id}`)\n\n const normalizedSections = (res.data.data.sections || []).map(\n (s: any, idx: number) => ({\n ...s,\n id: (s.id as string) || `node_${idx + 1}`,\n content: (s.content || s.blockData) as any,\n })\n )\n\n const pageData: PageData = { ...res.data.data, sections: normalizedSections }\n set({ data: pageData, activeSection: 'root' })\n return pageData\n } finally {\n set({ loading: false })\n }\n },\n\n save: async (slug, id, isGlobal, getPayload) => {\n const { data } = get()\n if (!data) return\n set({ saving: true })\n try {\n const payload = getPayload(data)\n const res = isGlobal\n ? await api.patch(`/globals/${id}`, payload)\n : await api.patch(`/${slug}/${id}`, payload)\n const serverVersion = res.data?.data?._version\n if (serverVersion !== undefined) {\n set({ data: { ...data, _version: serverVersion }, hasUnsavedChanges: false, dirtySections: new Set<string>() })\n } else {\n set({ hasUnsavedChanges: false, dirtySections: new Set<string>() })\n }\n } finally {\n set({ saving: false })\n }\n },\n})\n","import type { EditorSliceCreator, UiSlice } from './types'\n\nexport const createUiSlice: EditorSliceCreator<UiSlice> = (set) => ({\n activeSection: 'root',\n selectedField: null,\n selectedFieldId: null,\n\n setActiveSection: (activeSection) => set({ activeSection }),\n setSelectedField: (selectedField) => set({ selectedField }),\n setSelectedFieldId: (selectedFieldId) => set({ selectedFieldId }),\n})\n","import type { EditorSliceCreator, MediaSlice } from './types'\n\nexport const createMediaSlice: EditorSliceCreator<MediaSlice> = (set) => ({\n mediaAssets: [],\n mediaSearch: '',\n mediaTypeFilter: 'all',\n mediaLoading: false,\n\n setMediaAssets: (mediaAssets) => set({ mediaAssets }),\n setMediaSearch: (mediaSearch) => set({ mediaSearch }),\n setMediaTypeFilter: (mediaTypeFilter) => set({ mediaTypeFilter }),\n setMediaLoading: (mediaLoading) => set({ mediaLoading }),\n})\n","import type { EditorSliceCreator, RelationsSlice } from './types'\n\nexport const createRelationsSlice: EditorSliceCreator<RelationsSlice> = (set) => ({\n relationsField: null,\n relationsSearch: '',\n relationResults: [],\n selectedRelations: new Set<string>(),\n availableCollections: [],\n\n setRelationsField: (relationsField) => set({ relationsField }),\n setRelationsSearch: (relationsSearch) => set({ relationsSearch }),\n setRelationResults: (relationResults) => set({ relationResults }),\n setSelectedRelations: (selectedRelations) => set({ selectedRelations }),\n setAvailableCollections: (availableCollections) => set({ availableCollections }),\n})\n","import { create } from 'zustand'\nimport type { EditorState } from './slices/types'\nimport { createDocumentSlice } from './slices/documentSlice'\nimport { createUiSlice } from './slices/uiSlice'\nimport { createMediaSlice } from './slices/mediaSlice'\nimport { createRelationsSlice } from './slices/relationsSlice'\nimport { STORAGE_KEY } from './slices/utils'\n\n// Re-export all domain types for compatibility\nexport * from './slices/types'\n\nexport const useEditorStore = create<EditorState>((set, get, api) => ({\n ...createDocumentSlice(set, get, api),\n ...createUiSlice(set, get, api),\n ...createMediaSlice(set, get, api),\n ...createRelationsSlice(set, get, api),\n\n reset: () => {\n // Clear persisted state for previous document\n try { localStorage.removeItem(STORAGE_KEY) } catch { /* ignore */ }\n set({\n data: null,\n loading: false,\n saving: false,\n hasUnsavedChanges: false,\n lastSavedAt: null,\n undoStack: [],\n redoStack: [],\n dirtySections: new Set<string>(),\n activeSection: 'root',\n selectedField: null,\n fieldErrors: {},\n relationsField: null,\n relationsSearch: '',\n relationResults: [],\n selectedRelations: new Set<string>(),\n mediaAssets: [],\n mediaSearch: '',\n mediaTypeFilter: 'all',\n mediaLoading: false,\n })\n },\n}))\n","import { create } from 'zustand'\n\nexport type RightTab = 'preview' | 'history' | 'comments'\nexport type ViewMode = 'visual' | 'code'\nexport type PreviewMode = 'desktop' | 'tablet' | 'mobile'\n\ninterface PanelState {\n leftOpen: boolean\n rightOpen: boolean\n leftWidth: number\n rightWidth: number\n activeRightTab: RightTab\n viewMode: ViewMode\n previewMode: PreviewMode\n focusMode: boolean\n\n setLeftOpen: (open: boolean) => void\n setRightOpen: (open: boolean) => void\n setLeftWidth: (width: number) => void\n setRightWidth: (width: number) => void\n setActiveRightTab: (tab: RightTab) => void\n setViewMode: (mode: ViewMode) => void\n setPreviewMode: (mode: PreviewMode) => void\n toggleFocusMode: () => void\n}\n\nexport const usePanelStore = create<PanelState>((set) => ({\n leftOpen: true,\n rightOpen: true,\n leftWidth: 300,\n rightWidth: 420,\n activeRightTab: 'preview',\n viewMode: 'visual',\n previewMode: 'desktop',\n focusMode: false,\n\n setLeftOpen: (leftOpen) => set({ leftOpen }),\n setRightOpen: (rightOpen) => set({ rightOpen }),\n setLeftWidth: (leftWidth) => set({ leftWidth }),\n setRightWidth: (rightWidth) => set({ rightWidth }),\n setActiveRightTab: (activeRightTab) => set({ activeRightTab }),\n setViewMode: (viewMode) => set({ viewMode }),\n setPreviewMode: (previewMode) => set({ previewMode }),\n toggleFocusMode: () => set((state) => ({ focusMode: !state.focusMode })),\n}))\n","import React, { useState, useMemo } from 'react'\nimport {\n Plus,\n GripVertical,\n Layout,\n Search,\n X,\n Trash2,\n} from 'lucide-react'\nimport { useTheme } from '../../../context/ThemeContext'\nimport { useEditorStore } from '../../../store/editorStore'\nimport { usePanelStore } from '../../../store/panelStore'\nimport { cn } from '../../../lib/utils'\nimport { AnimatePresence, motion, Reorder } from 'framer-motion'\nimport { type Section, humanize } from '../constants'\nimport { useEditorBlocks } from '../../../context/BlockLibraryContext'\nimport EmptyState from '../../../components/EmptyState'\nimport { useShallow } from 'zustand/react/shallow'\n\ninterface LeftPanelProps {\n isGlobal?: boolean\n resizingSide: 'left' | 'right' | null\n startResizing: (side: 'left' | 'right') => (e: React.MouseEvent) => void\n addBlock: (type: string, data?: any) => void\n setInjectionIndex: (index: number | null) => void\n setBlockPickerOpen: (open: boolean) => void\n removeSection: (id: string) => void\n}\n\nexport const LeftPanel: React.FC<LeftPanelProps> = ({\n isGlobal,\n resizingSide,\n startResizing,\n addBlock,\n setInjectionIndex,\n setBlockPickerOpen,\n removeSection,\n}) => {\n const { theme } = useTheme()\n const BLOCK_LIBRARY = useEditorBlocks()\n const [searchQuery, setSearchQuery] = useState('')\n\n const {\n data,\n activeSection: editorActiveSection,\n setActiveSection: editorSetActiveSection,\n updateData,\n } = useEditorStore(useShallow(state => ({\n data: state.data,\n activeSection: state.activeSection,\n setActiveSection: state.setActiveSection,\n updateData: state.updateData,\n })))\n\n const { leftOpen,\n leftWidth,\n setLeftOpen,\n focusMode,\n } = usePanelStore(useShallow(state => ({ leftOpen: state.leftOpen, leftWidth: state.leftWidth, setLeftOpen: state.setLeftOpen, focusMode: state.focusMode })))\n\n const activeSection = editorActiveSection ?? 'root'\n\n // Filter sections by search query\n const searchActive = searchQuery.trim().length > 0\n const filteredSections = useMemo(() => {\n const sections = data?.sections || []\n if (!searchActive) return sections\n const q = searchQuery.toLowerCase()\n return sections.filter((s: Section) =>\n (s.blockName || s.title || humanize(s.blockType)).toLowerCase().includes(q) ||\n s.blockType.toLowerCase().includes(q)\n )\n }, [data?.sections, searchQuery, searchActive])\n\n /**\n * Transactional reorder guard:\n * - Blocked entirely while search is active (filtered list != full list)\n * - Validates that every id in newSections exists in the current document\n * before committing, preventing phantom-section bugs\n */\n const handleLayerReorder = (newSections: Section[]) => {\n if (searchActive) return // block reorder in filtered mode\n const allIds = new Set(data?.sections.map((s) => s.id))\n if (!newSections.every((s) => allIds.has(s.id))) return // integrity check\n updateData((draft) => { draft.sections = newSections })\n }\n\n // Get block icon for a section\n const getBlockIcon = (blockType: string) => {\n const block = BLOCK_LIBRARY.find((b) => b.type === blockType)\n return block?.icon || Layout\n }\n\n const dark = theme === 'dark'\n const effectiveLeftOpen = leftOpen && !focusMode\n\n return (\n <AnimatePresence>\n {effectiveLeftOpen && (\n <>\n {/* Mobile backdrop */}\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n onClick={() => setLeftOpen(false)}\n className=\"md:hidden fixed inset-0 bg-app/50 backdrop-blur-sm z-[99]\"\n />\n <motion.aside\n initial={{ x: '-100%' }}\n animate={{ x: 0 }}\n exit={{ x: '-100%' }}\n transition={{ type: 'spring', damping: 25, stiffness: 200 }}\n style={{ width: leftWidth }}\n className={cn(\n 'border-r flex flex-col z-50 overflow-hidden shrink-0 h-full',\n 'md:relative fixed inset-y-0 left-0 max-md:!w-[280px] max-md:z-[100] max-md:shadow-2xl',\n dark ? 'bg-app border-z-border' : 'bg-z-panel border-z-border'\n )}\n >\n {/* Resize handle */}\n <div\n onMouseDown={startResizing('left')}\n className={cn(\n 'absolute right-0 top-0 bottom-0 w-1 cursor-col-resize z-50 transition-colors',\n resizingSide === 'left' ? 'bg-z-border' : 'bg-transparent hover:bg-z-hover'\n )}\n />\n\n {/* Header */}\n <div className={cn('px-3 py-3 border-b flex items-center justify-between',\n dark ? 'border-z-border' : 'border-z-border shadow-sm'\n )}>\n <span className=\"text-xs font-semibold text-z-muted\">\n Layers\n </span>\n <div className=\"flex items-center gap-2\">\n <button\n onClick={() => { setInjectionIndex(0); setBlockPickerOpen(true); }}\n className={cn(\n 'p-1 rounded-none-none border transition-all text-z-muted hover:text-z-secondary ',\n dark ? 'bg-z-hover border-z-border' : 'bg-z-input border-z-border'\n )}\n aria-label=\"Add new section\"\n title=\"Add section\"\n >\n <Plus size={14} />\n </button>\n <button\n onClick={() => setLeftOpen(false)}\n className=\"md:hidden p-1 rounded-none-none border transition-all text-z-muted hover:text-rose-500\"\n aria-label=\"Close layers panel\"\n >\n <X size={14} />\n </button>\n </div>\n </div>\n\n {/* Search */}\n {(data?.sections?.length || 0) > 3 && (\n <div className=\"px-3 pt-2 pb-1\">\n <div className=\"relative\">\n <Search size={11} className={cn(\n 'absolute left-2.5 top-1/2 -translate-y-1/2',\n dark ? 'text-z-secondary' : 'text-z-muted'\n )} />\n <input\n type=\"text\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n placeholder=\"Filter layers...\"\n className={cn(\n 'w-full pl-7 pr-7 py-1.5 text-xs font-bold border rounded-none-none bg-transparent transition-all',\n dark\n ? 'border-z-border text-z-primary placeholder:text-z-muted focus:border-z-border/30'\n : 'border-z-border text-z-primary placeholder:text-z-muted focus:border-z-border/30'\n )}\n aria-label=\"Filter layers\"\n />\n {searchQuery && (\n <button\n onClick={() => setSearchQuery('')}\n className={cn(\n 'absolute right-2 top-1/2 -translate-y-1/2 p-0.5',\n dark ? 'text-z-secondary hover:text-z-primary' : 'text-z-muted hover:text-z-primary'\n )}\n aria-label=\"Clear filter\"\n >\n <X size={10} />\n </button>\n )}\n </div>\n </div>\n )}\n\n {/* Layers List */}\n <div className=\"flex-1 overflow-y-auto custom-editor-scrollbar px-2 pt-3 pb-4 space-y-2\">\n {filteredSections.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center h-full gap-3 text-center px-4\">\n {data?.sections?.length === 0 ? (\n <EmptyState\n icon={Layout}\n title=\"No sections yet\"\n message=\"Add your first section to start building\"\n />\n ) : (\n <EmptyState\n icon={Search}\n title=\"No matches\"\n message=\"Try a different search term\"\n />\n )}\n </div>\n ) : searchActive ? (\n <div className=\"space-y-1\">\n {filteredSections.map((section: Section) => {\n const BlockIcon = getBlockIcon(section.blockType)\n return (\n <button\n key={section.id}\n onClick={() => editorSetActiveSection(section.id)}\n className={cn(\n 'w-full flex items-center gap-2.5 px-2.5 py-2 rounded-none-none border text-left transition-all',\n activeSection === section.id\n ? dark\n ? 'bg-z-panel border-z-border text-z-primary'\n : 'bg-[var(--z-active-bg)] text-[var(--z-active-text)] border border-[var(--z-active-border)] shadow-sm'\n : dark\n ? 'bg-z-hover border-z-border text-z-secondary hover:bg-[var(--z-bg-hover)]'\n : 'bg-z-panel border-z-border text-z-secondary hover:bg-[var(--z-bg-hover)] hover:text-z-primary'\n )}\n aria-label={`Select section: ${section.blockName || section.title || humanize(section.blockType)}`}\n >\n <BlockIcon size={12} className={cn(\n 'shrink-0',\n activeSection === section.id\n ? ''\n : dark ? 'text-z-muted/60' : 'text-z-secondary/60'\n )} />\n <span className=\"text-xs font-semibold truncate flex-1\">\n {section.blockName || section.title || humanize(section.blockType)}\n </span>\n {section.blockType !== humanize(section.blockType) && (\n <span className={cn(\n 'text-sm font-semibold shrink-0',\n activeSection === section.id\n ? 'opacity-60'\n : dark ? 'text-z-secondary' : 'text-z-muted'\n )}>\n {humanize(section.blockType)}\n </span>\n )}\n </button>\n )\n })}\n </div>\n ) : (\n <Reorder.Group\n axis=\"y\"\n values={data?.sections || []}\n onReorder={handleLayerReorder}\n className=\"space-y-1\"\n as=\"div\"\n >\n {(data?.sections || []).map((section: Section) => {\n const BlockIcon = getBlockIcon(section.blockType)\n return (\n <Reorder.Item key={section.id} value={section} as=\"div\">\n <div className=\"w-full flex items-center gap-0\">\n <div\n onClick={() => editorSetActiveSection(section.id)}\n className={cn(\n 'flex-1 flex items-center gap-2.5 px-2.5 py-2 rounded-none-none border text-left transition-all cursor-pointer',\n activeSection === section.id\n ? dark\n ? 'bg-z-panel border-z-border text-z-primary'\n : 'bg-[var(--z-active-bg)] text-[var(--z-active-text)] border border-[var(--z-active-border)] shadow-sm'\n : dark\n ? 'bg-z-hover border-z-border text-z-secondary hover:bg-[var(--z-bg-hover)]'\n : 'bg-z-panel border-z-border text-z-secondary hover:bg-[var(--z-bg-hover)] hover:text-z-primary'\n )}\n aria-label={`Select section: ${section.blockName || section.title || humanize(section.blockType)}`}\n >\n <GripVertical\n size={12}\n className=\"opacity-30 shrink-0 cursor-grab active:cursor-grabbing\"\n aria-hidden=\"true\"\n />\n <BlockIcon size={12} className={cn(\n 'shrink-0',\n activeSection === section.id\n ? ''\n : dark ? 'text-z-muted/60' : 'text-z-secondary/60'\n )} aria-hidden=\"true\" />\n <span className=\"text-xs font-semibold truncate flex-1\">\n {section.blockName || section.title || humanize(section.blockType)}\n </span>\n {section.blockType !== humanize(section.blockType) && (\n <span className={cn(\n 'text-sm font-semibold shrink-0',\n activeSection === section.id\n ? dark ? 'text-z-muted/80' : 'text-z-secondary/80'\n : 'text-z-muted'\n )}>\n {humanize(section.blockType)}\n </span>\n )}\n <button\n onClick={(e) => {\n e.stopPropagation()\n removeSection(section.id)\n }}\n className={cn(\n 'p-1 shrink-0 rounded-none opacity-0 group-hover:opacity-100 transition-opacity ml-1',\n dark\n ? 'hover:bg-rose-500/20 text-rose-500/70 hover:text-rose-500'\n : 'hover:bg-rose-100 text-rose-500/70 hover:text-rose-600'\n )}\n aria-label=\"Delete layer\"\n >\n <Trash2 size={12} />\n </button>\n </div>\n </div>\n </Reorder.Item>\n )\n })}\n </Reorder.Group>\n )}\n </div>\n </motion.aside>\n </>\n )}\n </AnimatePresence>\n )\n}\n","import { useCallback } from 'react'\nimport { useSiteStore } from '../lib/siteStore'\nimport { useTenantStore } from '../lib/tenantStore'\nimport { useShallow } from 'zustand/react/shallow'\n\n/** Keys used in localStorage for tenant context */\nexport const TENANT_KEYS = {\n siteId: 'activeSiteId',\n siteSlug: 'activeSiteSlug',\n siteDomain: 'activeSiteDomain',\n workspaceId: 'activeWorkspaceId',\n} as const\n\n/** Routes that are allowed to operate without a resolved siteId */\nconst TENANT_EXEMPT_PATHS = ['/login', '/select-site', '/sites', '/auth']\n\nfunction isTenantExempt(): boolean {\n if (typeof window === 'undefined') return true\n return TENANT_EXEMPT_PATHS.some((p) => window.location.pathname.startsWith(p))\n}\n\n/**\n * useTenantStorage\n *\n * Single source of truth for all tenant-scoped values.\n *\n * - Reads `siteId` and `workspaceId` from Zustand (`useSiteStore`) as primary source.\n * - Falls back to localStorage for `siteSlug` / `siteDomain` (not in Zustand yet).\n * - `requireSiteId()` throws if `siteId` is null and we are not on an exempt route.\n * Call this at the top of any component that must operate within a tenant context.\n */\nexport function useTenantStorage() {\n const { activeSiteId, activeWorkspaceId, setActiveSiteId, setActiveWorkspaceId } = useSiteStore(useShallow(state => ({ activeSiteId: state.activeSiteId, activeWorkspaceId: state.activeWorkspaceId, setActiveSiteId: state.setActiveSiteId, setActiveWorkspaceId: state.setActiveWorkspaceId })))\n\n const safeGet = (key: string): string => {\n try { return localStorage.getItem(key) || '' } catch { return '' }\n }\n\n const safeSet = (key: string, value: string) => {\n try { localStorage.setItem(key, value) } catch { /* ignore */ }\n }\n\n const safeRemove = (key: string) => {\n try { localStorage.removeItem(key) } catch { /* ignore */ }\n }\n\n const siteId = activeSiteId || safeGet(TENANT_KEYS.siteId)\n const siteSlug = safeGet(TENANT_KEYS.siteSlug)\n const siteDomain = safeGet(TENANT_KEYS.siteDomain)\n const workspaceId = activeWorkspaceId || safeGet(TENANT_KEYS.workspaceId)\n\n /**\n * Asserts that a valid siteId is available.\n * Throws a descriptive error if missing and not on an exempt route.\n */\n const requireSiteId = useCallback((): string => {\n if (siteId) return siteId\n if (isTenantExempt()) return ''\n throw Object.assign(\n new Error(\n 'Tenant context is required but activeSiteId is missing. ' +\n 'Navigate to Site Selection to choose an active site.'\n ),\n { code: 'ERR_NO_TENANT' }\n )\n }, [siteId])\n\n /**\n * Set the active site — updates both Zustand store and localStorage.\n */\n const setSite = useCallback((id: string, slug?: string, domain?: string) => {\n setActiveSiteId(id)\n useTenantStore.getState().setActiveSiteId(id)\n if (slug) safeSet(TENANT_KEYS.siteSlug, slug)\n if (domain) safeSet(TENANT_KEYS.siteDomain, domain)\n }, [setActiveSiteId])\n\n /**\n * Clear the active tenant context — used on logout or site switch.\n */\n const clearSite = useCallback(() => {\n setActiveSiteId(null)\n useTenantStore.getState().setActiveSiteId(null)\n safeRemove(TENANT_KEYS.siteSlug)\n safeRemove(TENANT_KEYS.siteDomain)\n }, [setActiveSiteId])\n\n const setWorkspace = useCallback((id: string) => {\n setActiveWorkspaceId(id)\n }, [setActiveWorkspaceId])\n\n return {\n siteId,\n siteSlug,\n siteDomain,\n workspaceId,\n requireSiteId,\n setSite,\n clearSite,\n setWorkspace,\n }\n}\n","import { create } from 'zustand'\nimport api from '../lib/api'\nimport toast from 'react-hot-toast'\n\nexport interface Comment {\n _id: string\n collection: string\n documentId: string\n blockId?: string\n fieldKey?: string\n author: string\n authorEmail: string\n authorId?: string\n content: string\n resolved: boolean\n resolvedBy?: string\n resolvedAt?: string\n replies: Reply[]\n createdAt: string\n updatedAt: string\n}\n\nexport interface Reply {\n author: string\n authorEmail: string\n authorId?: string\n content: string\n createdAt: string\n updatedAt: string\n}\n\ninterface CommentsState {\n comments: Comment[]\n loading: boolean\n posting: boolean\n activeCommentId: string | null\n\n setActiveCommentId: (id: string | null) => void\n fetchComments: (collection: string, documentId: string) => Promise<void>\n createComment: (data: {\n collection: string\n documentId: string\n blockId?: string\n fieldKey?: string\n content: string\n }) => Promise<void>\n replyToComment: (commentId: string, content: string) => Promise<void>\n resolveComment: (commentId: string, resolved: boolean) => Promise<void>\n deleteComment: (commentId: string) => Promise<void>\n}\n\nexport const useCommentsStore = create<CommentsState>((set, get) => ({\n comments: [],\n loading: false,\n posting: false,\n activeCommentId: null,\n\n setActiveCommentId: (activeCommentId) => set({ activeCommentId }),\n\n fetchComments: async (collection, documentId) => {\n set({ comments: [], loading: true })\n try {\n const res = await api.get('/comments', { params: { collection, documentId } })\n set({ comments: res.data.data || [] })\n } catch {\n set({ comments: [] })\n } finally {\n set({ loading: false })\n }\n },\n\n createComment: async ({ collection, documentId, blockId, fieldKey, content }) => {\n set({ posting: true })\n try {\n const res = await api.post('/comments', { collection, documentId, blockId, fieldKey, content })\n set((state) => ({ comments: [res.data.data, ...state.comments] }))\n } finally {\n set({ posting: false })\n }\n },\n\n replyToComment: async (commentId, content) => {\n set({ posting: true })\n try {\n const res = await api.post(`/comments/${commentId}/reply`, { content })\n set((state) => ({\n comments: state.comments.map((c) =>\n c._id === commentId ? res.data.data : c\n ),\n }))\n } finally {\n set({ posting: false })\n }\n },\n\n resolveComment: async (commentId, resolved) => {\n try {\n const res = await api.patch(`/comments/${commentId}`, { resolved })\n set((state) => ({\n comments: state.comments.map((c) =>\n c._id === commentId ? res.data.data : c\n ),\n }))\n } catch { toast.error('Failed to update comment') }\n },\n\n deleteComment: async (commentId) => {\n try {\n await api.delete(`/comments/${commentId}`)\n set((state) => ({\n comments: state.comments.filter((c) => c._id !== commentId),\n }))\n } catch { toast.error('Failed to delete comment') }\n },\n}))\n","import React, { useEffect, useState } from 'react'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport { MessageSquare, Check, CheckCheck, Trash2, Send, X, ChevronDown, ChevronUp, CornerDownRight } from 'lucide-react'\nimport { useTheme } from '../../../context/ThemeContext'\nimport { useCommentsStore, type Comment } from '../../../store/commentsStore'\nimport { useAuthStore } from '../../../store/authStore'\nimport { cn } from '../../../lib/utils'\nimport { useShallow } from 'zustand/react/shallow'\n\ninterface CommentsPanelProps {\n collection: string\n documentId: string\n theme: 'light' | 'dark'\n}\n\nfunction timeAgo(dateStr: string): string {\n const now = Date.now()\n const then = new Date(dateStr).getTime()\n const diff = Math.floor((now - then) / 1000)\n if (diff < 60) return `${diff}s ago`\n if (diff < 3600) return `${Math.floor(diff / 60)}m ago`\n if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`\n return `${Math.floor(diff / 86400)}d ago`\n}\n\nconst CommentItem: React.FC<{\n comment: Comment\n onResolve: (id: string, resolved: boolean) => void\n onReply: (id: string, content: string) => void\n onDelete: (id: string) => void\n posting: boolean\n theme: 'light' | 'dark'\n currentUserId?: string\n}> = ({ comment, onResolve, onReply, onDelete, posting, theme, currentUserId }) => {\n const [replyOpen, setReplyOpen] = useState(false)\n const [replyContent, setReplyContent] = useState('')\n const [repliesOpen, setRepliesOpen] = useState(true)\n const isOwner = comment.authorId === currentUserId\n\n const handleReply = () => {\n if (!replyContent.trim()) return\n onReply(comment._id, replyContent)\n setReplyContent('')\n setReplyOpen(false)\n }\n\n return (\n <motion.div\n initial={{ opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -2 }}\n className={cn(\n 'border rounded-none-none overflow-hidden',\n comment.resolved\n ? theme === 'dark' ? 'border-z-border/10 bg-z-border/[0.03]' : 'border-z-border bg-[var(--z-bg-input)]/50'\n : theme === 'dark' ? 'border-z-border bg-z-panel' : 'border-z-border bg-z-panel'\n )}\n >\n {/* Thread header */}\n <div className=\"px-3 py-2.5 flex items-start gap-2.5\">\n <div className={cn(\n 'w-7 h-7 rounded-none-none flex items-center justify-center shrink-0 mt-0.5',\n theme === 'dark' ? 'bg-z-panel border border-z-border/20' : 'bg-[var(--z-bg-input)] border border-z-border'\n )}>\n <span className=\"text-xs font-semibold text-z-secondary\">\n {comment.author?.[0] || '?'}\n </span>\n </div>\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 flex-wrap\">\n <span className=\"text-xs font-semibold text-z-secondary\">\n {comment.author}\n </span>\n <span className=\"text-sm text-z-secondary font-bold\">\n {timeAgo(comment.createdAt)}\n </span>\n {comment.resolved && (\n <span className={cn(\n 'text-sm font-semibold px-1.5 py-0.5 rounded-none-none',\n theme === 'dark' ? 'bg-z-panel/5 text-z-secondary' : 'bg-[var(--z-bg-hover)] text-z-secondary'\n )}>\n Resolved\n </span>\n )}\n {comment.blockId && (\n <span className={cn(\n 'text-sm font-mono px-1 py-0.5 rounded-none-none',\n theme === 'dark' ? 'bg-amber-500/10 text-amber-400' : 'bg-amber-50 text-amber-600'\n )}>\n Block: {comment.blockId}\n </span>\n )}\n </div>\n <p className={cn(\n 'text-xs leading-relaxed font-medium mt-1',\n comment.resolved ? ' text-z-secondary' : 'text-z-secondary'\n )}>\n {comment.content}\n </p>\n </div>\n </div>\n\n {/* Replies */}\n {comment.replies?.length > 0 && (\n <div className={cn(\n 'border-t',\n theme === 'dark' ? 'border-z-border' : 'border-z-border shadow-sm'\n )}>\n <button\n onClick={() => setRepliesOpen((v) => !v)}\n className={cn(\n 'w-full flex items-center gap-1.5 px-3 py-1.5 text-xs font-semibold transition-colors',\n theme === 'dark' ? 'text-z-secondary hover:text-z-secondary' : 'text-z-muted hover:text-z-secondary'\n )}\n >\n <CornerDownRight size={8} />\n {comment.replies.length} {comment.replies.length === 1 ? 'reply' : 'replies'}\n {repliesOpen ? <ChevronUp size={8} className=\"ml-auto\" /> : <ChevronDown size={8} className=\"ml-auto\" />}\n </button>\n\n <AnimatePresence initial={false}>\n {repliesOpen && (\n <motion.div\n initial={{ height: 0 }}\n animate={{ height: 'auto' }}\n exit={{ height: 0 }}\n transition={{ duration: 0.15 }}\n className=\"overflow-hidden\"\n >\n <div className=\"px-3 pb-2 space-y-2\">\n {comment.replies.map((reply, idx) => (\n <div key={idx} className={cn(\n 'flex gap-2 pl-3 border-l-2',\n theme === 'dark' ? 'border-z-border/20' : 'border-z-border'\n )}>\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"text-xs font-semibold text-z-muted\">{reply.author}</span>\n <span className=\"text-sm text-z-secondary\">{timeAgo(reply.createdAt)}</span>\n </div>\n <p className=\"text-xs text-z-secondary font-medium\">{reply.content}</p>\n </div>\n </div>\n ))}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n )}\n\n {/* Actions */}\n <div className={cn(\n 'px-3 py-1.5 border-t flex items-center gap-3',\n theme === 'dark' ? 'border-z-border' : 'border-z-border shadow-sm'\n )}>\n <button\n onClick={() => setReplyOpen((v) => !v)}\n className={cn(\n 'flex items-center gap-1 text-xs font-semibold transition-colors',\n theme === 'dark' ? 'text-z-secondary hover:text-z-secondary' : 'text-z-muted hover:text-z-secondary'\n )}\n >\n <CornerDownRight size={9} />\n Reply\n </button>\n\n <button\n onClick={() => onResolve(comment._id, !comment.resolved)}\n className={cn(\n 'flex items-center gap-1 text-xs font-semibold transition-colors',\n comment.resolved\n ? theme === 'dark' ? 'text-z-secondary hover:text-z-secondary' : 'text-z-secondary hover:text-z-secondary'\n : theme === 'dark' ? 'text-z-muted/50 hover:text-z-secondary' : 'text-z-secondary hover:text-z-secondary '\n )}\n >\n {comment.resolved ? <CheckCheck size={9} /> : <Check size={9} />}\n {comment.resolved ? 'Reopen' : 'Resolve'}\n </button>\n\n {isOwner && (\n <button\n onClick={() => onDelete(comment._id)}\n className={cn(\n 'flex items-center gap-1 text-xs font-semibold transition-colors ml-auto',\n theme === 'dark' ? 'text-z-secondary hover:text-rose-400' : 'text-z-muted hover:text-rose-500'\n )}\n >\n <Trash2 size={9} />\n Delete\n </button>\n )}\n </div>\n\n {/* Reply box */}\n <AnimatePresence initial={false}>\n {replyOpen && (\n <motion.div\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: 'auto', opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n transition={{ duration: 0.15 }}\n className=\"overflow-hidden\"\n >\n <div className={cn(\n 'px-3 py-2 border-t flex gap-2',\n theme === 'dark' ? 'border-z-border' : 'border-z-border shadow-sm'\n )}>\n <input\n autoFocus\n type=\"text\"\n value={replyContent}\n onChange={(e) => setReplyContent(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && handleReply()}\n placeholder=\"Write a reply...\"\n className={cn(\n 'flex-1 px-2.5 py-1.5 text-xs rounded-none-none border transition-all',\n theme === 'dark'\n ? 'bg-z-hover border-z-border text-z-primary placeholder:text-z-muted focus:border-z-border/50'\n : 'bg-z-input border-z-border text-z-primary placeholder:text-z-muted focus:border-z-border-strong'\n )}\n />\n <button\n onClick={handleReply}\n disabled={posting || !replyContent.trim()}\n aria-label=\"Send reply\"\n className={cn(\n 'px-2.5 py-1.5 text-xs font-semibold border transition-all rounded-none-none disabled:opacity-50',\n theme === 'dark'\n ? 'bg-z-hover border-z-border-strong border-z-border/20 text-z-secondary hover:bg-z-border/30'\n : 'bg-z-input border-z-border text-z-secondary hover:bg-[var(--z-bg-hover)]'\n )}\n >\n <Send size={10} aria-hidden=\"true\" />\n </button>\n <button\n onClick={() => { setReplyOpen(false); setReplyContent('') }}\n aria-label=\"Cancel reply\"\n className={cn(\n 'px-2 py-1.5 text-xs font-semibold border rounded-none-none',\n theme === 'dark' ? 'border-z-border text-z-secondary' : 'border-z-border text-z-muted'\n )}\n >\n <X size={10} aria-hidden=\"true\" />\n </button>\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </motion.div>\n )\n}\n\nexport const CommentsPanel: React.FC<CommentsPanelProps> = ({\n collection,\n documentId,\n theme,\n}) => {\n const { comments, loading, posting, fetchComments, createComment, replyToComment, resolveComment, deleteComment } = useCommentsStore(useShallow(state => ({ comments: state.comments, loading: state.loading, posting: state.posting, fetchComments: state.fetchComments, createComment: state.createComment, replyToComment: state.replyToComment, resolveComment: state.resolveComment, deleteComment: state.deleteComment })))\n const { user } = useAuthStore(useShallow(state => ({ user: state.user })))\n const [newComment, setNewComment] = useState('')\n const [showResolved, setShowResolved] = useState(false)\n\n useEffect(() => {\n fetchComments(collection, documentId)\n }, [collection, documentId])\n\n const handleCreate = () => {\n if (!newComment.trim()) return\n createComment({ collection, documentId, content: newComment })\n setNewComment('')\n }\n\n const open = comments.length > 0 || !showResolved\n const filteredComments = showResolved ? comments : comments.filter((c) => !c.resolved)\n\n return (\n <div className=\"space-y-3\">\n {/* Panel header */}\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <MessageSquare size={11} className=\"text-z-secondary\" />\n <span className=\"text-xs font-semibold text-z-secondary\">\n Review\n </span>\n <span className={cn(\n 'px-1.5 py-0.5 text-sm font-semibold rounded-none-none',\n theme === 'dark' ? 'bg-z-hover text-z-secondary' : 'bg-[var(--z-bg-hover)] text-z-secondary'\n )}>\n {comments.filter((c) => !c.resolved).length} open / {comments.length} total\n </span>\n </div>\n <button\n onClick={() => setShowResolved((v) => !v)}\n className={cn(\n 'text-xs font-semibold transition-colors',\n theme === 'dark' ? 'text-z-secondary hover:text-z-secondary' : 'text-z-muted hover:text-z-secondary'\n )}\n >\n {showResolved ? 'Hide resolved' : 'Show resolved'}\n </button>\n </div>\n\n {/* New comment input */}\n <div className={cn(\n 'border rounded-none-none p-2.5',\n theme === 'dark' ? 'border-z-border bg-z-panel' : 'border-z-border bg-[var(--z-bg-input)]/50'\n )}>\n <textarea\n value={newComment}\n onChange={(e) => setNewComment(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) handleCreate()\n }}\n placeholder=\"Add a comment... (Cmd+Enter to submit)\"\n rows={2}\n className={cn(\n 'w-full px-2 py-1.5 text-xs rounded-none-none border-none bg-transparent resize-none focus:outline-none focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:ring-offset-1 focus-visible:ring-offset-black focus:ring-0 placeholder:text-z-muted',\n theme === 'dark' ? 'text-z-secondary placeholder:text-z-muted' : 'text-z-primary placeholder:text-z-muted'\n )}\n />\n <div className=\"flex items-center justify-between mt-1.5\">\n <span className=\"text-sm text-z-secondary font-bold\">Cmd+Enter to submit</span>\n <button\n onClick={handleCreate}\n disabled={posting || !newComment.trim()}\n className={cn(\n 'flex items-center gap-1.5 px-3 py-1.5 text-xs font-semibold border rounded-none-none transition-all disabled:opacity-50',\n theme === 'dark'\n ? 'bg-z-hover border-z-border-strong border-z-border/30 text-z-secondary hover:bg-z-border/30 hover:border-z-border/50'\n : 'bg-z-input border-z-border text-z-secondary hover:bg-[var(--z-bg-hover)] hover:border-z-border-strong'\n )}\n >\n <MessageSquare size={9} />\n Comment\n </button>\n </div>\n </div>\n\n {/* Comments list */}\n {loading ? (\n <div className=\"text-center py-4\">\n <div className={cn(\n 'w-4 h-4 border-2 border-z-border border-t-transparent rounded-none-none animate-spin mx-auto mb-2'\n )} />\n <p className=\"text-xs text-z-secondary font-bold\">Loading comments...</p>\n </div>\n ) : filteredComments.length === 0 ? (\n <div className={cn(\n 'py-5 text-center border border-dashed rounded-none-none',\n 'border-z-border'\n )}>\n <MessageSquare size={16} className=\"mx-auto text-z-secondary mb-1.5\" />\n <p className=\"text-xs text-z-secondary font-bold\">No comments yet</p>\n <p className=\"text-xs text-z-secondary mt-0.5\">Be the first to leave a review note</p>\n </div>\n ) : (\n <div className=\"space-y-2\">\n <AnimatePresence initial={false}>\n {filteredComments.map((comment) => (\n <CommentItem\n key={comment._id}\n comment={comment}\n onResolve={resolveComment}\n onReply={replyToComment}\n onDelete={deleteComment}\n posting={posting}\n theme={theme}\n currentUserId={user?.id}\n />\n ))}\n </AnimatePresence>\n </div>\n )}\n </div>\n )\n}\n\nexport default CommentsPanel\n","import React from 'react'\nimport { useParams } from 'react-router-dom'\nimport { X, Eye, History, MessageSquare, Monitor, Tablet, Smartphone } from 'lucide-react'\nimport { useTheme } from '../../../context/ThemeContext'\nimport { useEditorStore } from '../../../store/editorStore'\nimport { usePanelStore } from '../../../store/panelStore'\nimport { useTenantStorage } from '../../../hooks/useTenantStorage'\nimport { cn } from '../../../lib/utils'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport api from '../../../lib/api'\nimport { CommentsPanel } from './CommentsPanel'\nimport EmptyState from '../../../components/EmptyState'\nimport toast from 'react-hot-toast'\nimport { useShallow } from 'zustand/react/shallow'\n\ninterface RightPanelProps {\n isGlobal?: boolean\n resizingSide: 'left' | 'right' | null\n startResizing: (side: 'left' | 'right') => (e: React.MouseEvent) => void\n iframeRef: React.RefObject<HTMLIFrameElement | null>\n handleRestore: (versionId: string) => Promise<void>\n onCompareDiff: (versionId: string, versionNumber: number) => void\n}\n\nconst storefrontUrl = import.meta.env.VITE_STOREFRONT_URL as string | undefined\n\ntype ViewportSize = 'desktop' | 'tablet' | 'mobile'\n\nconst VIEWPORT_SIZES: Record<ViewportSize, { width: number; height: number; icon: typeof Monitor }> = {\n desktop: { width: 1440, height: 900, icon: Monitor },\n tablet: { width: 768, height: 1024, icon: Tablet },\n mobile: { width: 375, height: 812, icon: Smartphone },\n}\n\nexport const RightPanel: React.FC<RightPanelProps> = ({\n isGlobal = false,\n resizingSide,\n startResizing,\n iframeRef,\n handleRestore,\n onCompareDiff,\n}) => {\n const { id, slug } = useParams<{ id: string; slug: string }>()\n const documentId = id || slug\n const { theme } = useTheme()\n const { history, data, availableCollections } = useEditorStore(useShallow(state => ({ history: state.history, data: state.data, availableCollections: state.availableCollections })))\n const { rightOpen, rightWidth, activeRightTab, setActiveRightTab, setRightOpen, previewMode, setPreviewMode, focusMode } = usePanelStore(useShallow(state => ({ rightOpen: state.rightOpen, rightWidth: state.rightWidth, activeRightTab: state.activeRightTab, setActiveRightTab: state.setActiveRightTab, setRightOpen: state.setRightOpen, previewMode: state.previewMode, setPreviewMode: state.setPreviewMode, focusMode: state.focusMode })))\n const { siteId: tenantSiteId, siteSlug, siteDomain } = useTenantStorage()\n\n const [sites, setSites] = React.useState<any[]>([])\n const [previewToken, setPreviewToken] = React.useState<string | null>(null)\n const collectionSlug = isGlobal ? 'globals' : (slug || 'pages')\n\n React.useEffect(() => {\n api.get('/sites')\n .then((res) => {\n setSites(res.data?.data || [])\n })\n .catch(() => { toast.error('Failed to load sites') })\n }, [])\n\n React.useEffect(() => {\n const fetchToken = async () => {\n if (!documentId || documentId === 'new') return\n if (collectionSlug === 'globals') return // Globals do not support preview tokens yet\n try {\n const res = await api.post(`/${collectionSlug}/${documentId}/preview-token`)\n setPreviewToken(res.data.data?.token || null)\n } catch { /* ignore */ }\n }\n fetchToken()\n }, [collectionSlug, documentId])\n\n const docSiteId = data?.siteId\n const isValidDocSiteId = docSiteId && sites.some((s) => (s._id || s.id) === docSiteId)\n const pageSiteId = isValidDocSiteId ? docSiteId : tenantSiteId || ''\n const matchingSite = sites.find((s) => (s._id || s.id) === pageSiteId)\n\n const domainToUse = matchingSite ? matchingSite.domain : 'http://localhost:5177'\n let resolvedStorefrontUrl = ''\n\n if (domainToUse && domainToUse.trim() !== '') {\n resolvedStorefrontUrl = domainToUse.startsWith('http')\n ? domainToUse\n : `http://${domainToUse}`\n } else if (storefrontUrl) {\n resolvedStorefrontUrl = storefrontUrl\n }\n\n const currentCollection = availableCollections?.find(c => c.slug === collectionSlug)\n const previewUrlTemplate = (currentCollection as any)?.admin?.previewUrl\n\n let finalPreviewUrl = ''\n if (typeof previewUrlTemplate === 'string') {\n finalPreviewUrl = previewUrlTemplate\n .replace(/{{storefrontUrl}}/g, resolvedStorefrontUrl)\n .replace(/{{previewToken}}/g, previewToken || '')\n .replace(/{{id}}/g, documentId || '')\n .replace(/{{slug}}/g, (data as any)?.slug || documentId || '')\n .replace(/{{siteId}}/g, pageSiteId)\n .replace(/{{viewport}}/g, previewMode)\n .replace(/{{collection}}/g, collectionSlug)\n } else if (resolvedStorefrontUrl) {\n // Fallback legacy logic\n finalPreviewUrl = `${resolvedStorefrontUrl}${collectionSlug === 'posts' ? '/post/preview' : ''}?preview=true&token=${previewToken || ''}&collection=${collectionSlug}&id=${documentId}&siteId=${pageSiteId}&viewport=${previewMode}`\n }\n\n const TABS = [\n { id: 'preview', icon: Eye, label: 'Live' },\n { id: 'history', icon: History, label: 'Versions' },\n { id: 'comments', icon: MessageSquare, label: 'Review' },\n ] as const\n\n const viewport = VIEWPORT_SIZES[previewMode as ViewportSize] || VIEWPORT_SIZES.desktop\n const isDesktop = previewMode === 'desktop'\n const dark = theme === 'dark'\n const effectiveRightOpen = rightOpen && !focusMode\n\n return (\n <AnimatePresence initial={false}>\n {effectiveRightOpen && (\n <motion.aside\n initial={{ width: 0, opacity: 0 }}\n animate={{ width: rightWidth, opacity: 1 }}\n exit={{ width: 0, opacity: 0 }}\n className={cn(\n 'border-l flex flex-col z-50 overflow-hidden shrink-0',\n 'md:relative fixed inset-y-0 right-0 max-md:!w-[280px] max-md:z-[100] max-md:shadow-2xl',\n dark\n ? 'bg-app border-z-border'\n : 'bg-z-panel border-z-border shadow-xl'\n )}\n >\n {/* Mobile backdrop */}\n <div\n onClick={() => setRightOpen(false)}\n className=\"md:hidden fixed inset-0 bg-app/50 backdrop-blur-sm z-[99]\"\n />\n {/* Resize handle */}\n <div\n onMouseDown={startResizing('right')}\n className={cn(\n 'absolute left-0 top-0 bottom-0 w-1 cursor-col-resize z-50 transition-colors',\n resizingSide === 'right'\n ? 'bg-z-border shadow-sm'\n : 'bg-transparent hover:bg-z-hover'\n )}\n />\n\n {/* Tab bar */}\n <div\n className={cn(\n 'px-3 py-2 border-b flex items-center justify-between shrink-0',\n dark ? 'border-z-border' : 'border-z-border shadow-sm'\n )}\n >\n <div className=\"flex items-center gap-4\">\n {TABS.map((tab) => (\n <button\n key={tab.id}\n onClick={() => setActiveRightTab(tab.id)}\n className={cn(\n 'flex flex-col transition-all',\n activeRightTab === tab.id ? 'opacity-100' : 'opacity-40 hover:opacity-100'\n )}\n aria-label={tab.label}\n >\n <span\n className={cn(\n 'text-xs font-semibold ',\n activeRightTab === tab.id\n ? dark ? 'text-z-primary' : 'text-z-primary'\n : dark ? 'text-z-secondary' : 'text-z-muted'\n )}\n >\n {tab.label}\n </span>\n <div\n className=\"h-0.5 w-full mt-1\"\n style={{\n backgroundColor: activeRightTab === tab.id ? 'var(--z-accent)' : 'transparent',\n }}\n />\n </button>\n ))}\n </div>\n <button type=\"button\" onClick={() => setRightOpen(false)} className=\"p-1 hover:text-z-secondary transition-colors\" aria-label=\"Close panel\">\n <X size={16} />\n </button>\n </div>\n\n {/* Content */}\n <div className=\"flex-1 overflow-hidden relative custom-editor-scrollbar\">\n {activeRightTab === 'preview' ? (\n <div className=\"w-full h-full flex flex-col\">\n {/* Viewport size toggles */}\n <div className={cn(\n 'flex items-center justify-center gap-1 px-3 py-2 border-b shrink-0',\n dark ? 'border-z-border' : 'border-z-border shadow-sm'\n )}>\n {(['desktop', 'tablet', 'mobile'] as const).map((vp) => {\n const vpConfig = VIEWPORT_SIZES[vp]\n const VpIcon = vpConfig.icon\n const isActive = previewMode === vp\n return (\n <button\n key={vp}\n onClick={() => setPreviewMode(vp)}\n className={cn(\n 'flex items-center gap-1.5 px-2.5 py-1 rounded-none-none border text-sm font-semibold transition-all',\n isActive\n ? dark\n ? 'bg-z-panel/5 border-z-border text-z-secondary'\n : 'bg-z-panel shadow-sm border border-z-border text-z-primary'\n : dark\n ? 'bg-z-hover border-z-border text-z-secondary hover:text-z-secondary'\n : 'bg-z-panel border-z-border text-z-secondary hover:bg-[var(--z-bg-hover)] hover:text-z-primary'\n )}\n aria-label={`${vp} preview`}\n title={`${vp} (${vpConfig.width}×${vpConfig.height})`}\n >\n <VpIcon size={11} />\n {vp}\n </button>\n )\n })}\n </div>\n\n {/* Preview Frame */}\n <div className=\"flex-1 flex items-center justify-center overflow-auto p-3\">\n {finalPreviewUrl ? (\n <div\n className={cn(\n 'transition-all duration-300 border overflow-hidden',\n dark ? 'border-z-border bg-[#030303] shadow-[0_0_40px_rgba(0,0,0,0.5)]' : 'border-z-border bg-z-panel shadow-2xl',\n isDesktop ? 'w-full h-full' : 'rounded-none-none'\n )}\n style={\n isDesktop\n ? undefined\n : {\n width: Math.min(viewport.width, rightWidth - 40),\n height: viewport.height,\n }\n }\n >\n <iframe\n allow=\"clipboard-read; clipboard-write\"\n ref={iframeRef}\n src={finalPreviewUrl}\n className=\"w-full h-full border-none rounded-none-none\"\n title=\"Live Preview\"\n sandbox=\"allow-same-origin allow-scripts allow-forms\"\n />\n </div>\n ) : (\n <div className={cn(\n 'flex flex-col items-center justify-center h-full gap-3 text-center p-8',\n dark ? 'bg-[#0a0a0a]' : 'bg-[var(--z-bg-input)]'\n )}>\n <Eye size={28} className={dark ? 'text-z-secondary' : 'text-z-secondary'} />\n <div>\n <p className={cn('text-xs font-semibold ', 'text-z-secondary')}>\n Preview unavailable\n </p>\n <p className={cn('text-xs font-bold', dark ? 'text-z-primary' : 'text-z-secondary')}>\n {resolvedStorefrontUrl ? 'Preview URL is not configured for this collection.' : 'Set VITE_STOREFRONT_URL to enable live preview'}\n </p>\n </div>\n </div>\n )}\n </div>\n </div>\n ) : activeRightTab === 'comments' ? (\n <div className=\"w-full h-full p-3 overflow-y-auto custom-editor-scrollbar\">\n <CommentsPanel\n collection={isGlobal ? 'globals' : 'pages'}\n documentId={documentId || ''}\n theme={theme}\n />\n </div>\n ) : (\n /* Versions */\n <div className=\"w-full h-full p-3 overflow-y-auto custom-editor-scrollbar\">\n {history.length === 0 ? (\n <div className=\"flex flex-col h-full justify-center\">\n <EmptyState\n icon={History}\n title=\"No versions yet\"\n message=\"Save your page to create a version snapshot\"\n />\n </div>\n ) : (\n <div className=\"space-y-2\">\n {history.map((v, idx) => (\n <div\n key={v._id || v.id}\n className={cn(\n 'group p-4 rounded-none-none border transition-all cursor-pointer space-y-2',\n dark\n ? 'bg-z-panel/5 border-z-border hover:bg-[var(--z-bg-hover)]'\n : 'bg-z-input border-z-border hover:bg-[var(--z-bg-hover)]'\n )}\n >\n <div className=\"flex items-center justify-between\">\n <span className={cn('text-xs font-semibold ', dark ? 'text-z-primary' : 'text-z-primary')}>\n {idx === 0 ? 'Current' : `V.${history.length - idx}`}\n </span>\n <span className=\"text-xs font-bold text-z-secondary\">\n {new Date(v.createdAt).toLocaleDateString()}\n </span>\n </div>\n <p className=\"text-xs text-z-secondary font-medium truncate\">\n {v.changeLog || 'Saved'}\n </p>\n {idx > 0 && (\n <div className=\"flex gap-1.5 opacity-0 group-hover:opacity-100 transition-all mt-1.5\">\n <button\n onClick={(e) => { e.stopPropagation(); onCompareDiff(v._id, history.length - idx) }}\n className={cn(\n 'flex-1 py-1 border text-xs font-semibold text-center transition-all',\n dark\n ? 'bg-z-hover border-z-border text-z-secondary hover:bg-[var(--z-bg-hover)] hover:text-z-primary'\n : 'bg-[var(--z-bg-hover)] border-z-border text-z-primary hover:bg-[var(--z-border)] hover:text-z-primary'\n )}\n >\n Compare\n </button>\n <button\n onClick={(e) => { e.stopPropagation(); handleRestore(v._id) }}\n className=\"flex-1 py-1 bg-z-accent hover:bg-z-border text-z-primary text-xs font-semibold text-center transition-all\"\n >\n Restore\n </button>\n </div>\n )}\n </div>\n ))}\n </div>\n )}\n </div>\n )}\n </div>\n </motion.aside>\n )}\n </AnimatePresence>\n )\n}\n","import React, { useState, useRef } from 'react'\n\ninterface FocalPointCropperProps {\n imageUrl: string\n initialX?: number\n initialY?: number\n onSave?: (x: number, y: number) => void\n}\n\nexport const FocalPointCropper: React.FC<FocalPointCropperProps> = ({\n imageUrl,\n initialX = 50,\n initialY = 50,\n onSave\n}) => {\n const [focalPoint, setFocalPoint] = useState({ x: initialX, y: initialY })\n const containerRef = useRef<HTMLDivElement>(null)\n\n const handleImageClick = (e: React.MouseEvent<HTMLDivElement>) => {\n if (!containerRef.current) return\n const rect = containerRef.current.getBoundingClientRect()\n const clickX = e.clientX - rect.left\n const clickY = e.clientY - rect.top\n\n // Calculate percentages\n const xPct = Math.round((clickX / rect.width) * 100)\n const yPct = Math.round((clickY / rect.height) * 100)\n\n // Constrain 0-100\n const constrainedX = Math.max(0, Math.min(100, xPct))\n const constrainedY = Math.max(0, Math.min(100, yPct))\n\n setFocalPoint({ x: constrainedX, y: constrainedY })\n }\n\n const triggerSave = () => {\n if (onSave) {\n onSave(focalPoint.x, focalPoint.y)\n }\n }\n\n return (\n <div\n style={{\n backgroundColor: 'rgba(17, 24, 39, 0.65)',\n backdropFilter: 'blur(12px)',\n WebkitBackdropFilter: 'blur(12px)',\n border: '1px solid rgba(255, 255, 255, 0.08)',\n borderRadius: '12px',\n boxShadow: '0 4px 30px rgba(0, 0, 0, 0.1)',\n padding: '24px',\n maxWidth: '500px',\n width: '100%',\n margin: '0 auto',\n fontFamily: \"'Inter', sans-serif\",\n color: '#F3F4F6'\n }}\n >\n <h3\n style={{\n fontSize: '18px',\n fontWeight: 600,\n marginBottom: '8px',\n color: '#F3F4F6',\n letterSpacing: '-0.025em'\n }}\n >\n AI Focal Point & Responsive Cropper\n </h3>\n <p style={{ fontSize: '13px', color: '#9CA3AF', marginBottom: '16px', lineHeight: '1.4' }}>\n Click anywhere on the image preview to set the focal focus coordinates. The storefront background positioning will dynamically scale around this center point.\n </p>\n\n {/* Interactive Crop Image Frame */}\n <div\n ref={containerRef}\n onClick={handleImageClick}\n style={{\n position: 'relative',\n width: '100%',\n height: '260px',\n borderRadius: '8px',\n overflow: 'hidden',\n cursor: 'crosshair',\n border: '1.5px dashed rgba(255, 255, 255, 0.15)',\n background: '#0B0F19'\n }}\n >\n <img\n src={imageUrl}\n alt=\"Salient Crop Preview\"\n style={{\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n userSelect: 'none',\n opacity: 0.8\n }}\n />\n\n {/* Dynamic Focal Target Ring */}\n <div\n style={{\n position: 'absolute',\n left: `${focalPoint.x}%`,\n top: `${focalPoint.y}%`,\n transform: 'translate(-50%, -50%)',\n width: '28px',\n height: '28px',\n borderRadius: '50%',\n border: '2.5px solid var(--z-accent)',\n boxShadow: '0 0 12px var(--z-accent), inset 0 0 4px var(--z-accent)',\n pointerEvents: 'none',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n transition: 'left 0.15s cubic-bezier(0.25, 0.8, 0.25, 1), top 0.15s cubic-bezier(0.25, 0.8, 0.25, 1)'\n }}\n >\n <div\n style={{\n width: '6px',\n height: '6px',\n borderRadius: '50%',\n backgroundColor: 'var(--z-accent)'\n }}\n />\n </div>\n </div>\n\n {/* Information Row */}\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n marginTop: '16px',\n fontSize: '12px',\n color: '#9CA3AF'\n }}\n >\n <div>\n Focus Position:{' '}\n <span style={{ color: 'var(--z-accent)', fontWeight: 600 }}>\n X: {focalPoint.x}%, Y: {focalPoint.y}%\n </span>\n </div>\n <button\n type=\"button\"\n onClick={triggerSave}\n style={{\n backgroundColor: 'var(--z-accent)',\n color: '#FFFFFF',\n border: 'none',\n padding: '8px 16px',\n borderRadius: '6px',\n fontWeight: 600,\n cursor: 'pointer',\n boxShadow: '0 4px 10px rgba(139, 92, 246, 0.3)',\n transition: 'transform 0.1s ease'\n }}\n onMouseDown={(e) => (e.currentTarget.style.transform = 'scale(0.96)')}\n onMouseUp={(e) => (e.currentTarget.style.transform = 'scale(1)')}\n >\n Confirm Focal Selection\n </button>\n </div>\n </div>\n )\n}\n","/* eslint-disable */\nimport React, { useEffect, useState } from 'react'\nimport { createPortal } from 'react-dom'\nimport { Image as ImageIcon, X, Plus, Search, Check, Loader2, UploadCloud, Link } from 'lucide-react'\nimport api from '../lib/api'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport { cn } from '../lib/utils'\nimport { toast } from 'react-hot-toast'\nimport { FocalPointCropper } from './FocalPointCropper'\nimport EmptyState from './EmptyState'\nimport { useTheme } from '../context/ThemeContext'\n\ninterface MediaPickerProps {\n value?: any\n onChange: (value: any) => void\n hasMany?: boolean\n disabled?: boolean\n /** Enable the focal point editor step after image selection */\n focalPoint?: boolean\n}\n\nconst MediaPicker: React.FC<MediaPickerProps> = ({ value, onChange, hasMany, disabled = false, focalPoint = false }) => {\n const { theme } = useTheme()\n const [isOpen, setIsOpen] = useState(false)\n const [files, setFiles] = useState<any[]>([])\n const [loading, setLoading] = useState(false)\n const [search, setSearch] = useState('')\n const [externalUrl, setExternalUrl] = useState('')\n // Focal point state: null = not active, { file, candidate } = pending confirmation\n const [focalPending, setFocalPending] = useState<any>(null)\n const [mounted, setMounted] = useState(false)\n\n useEffect(() => {\n setMounted(true)\n }, [])\n\n const selectedFiles = Array.isArray(value) ? value : value ? [value] : []\n\n // Blob URL cache for authenticated media — prevents naked <img src> that skip auth cookies\n const blobMap = React.useRef<Record<string, string>>({})\n const blobTokens = React.useRef<Set<string>>(new Set())\n\n const getMediaUrl = (url: string): string => {\n if (!url) return ''\n if (url.startsWith('http')) return url\n // Return cached blob URL if already fetched\n return blobMap.current[url] || url\n }\n\n // Pre-fetch internal media URLs with auth credentials when files change\n useEffect(() => {\n if (!files.length) return\n const toFetch = files.filter((f: any) => f.url && !f.url.startsWith('http') && !blobMap.current[f.url])\n if (!toFetch.length) return\n const apiUrl = (import.meta.env.VITE_API_URL || '').replace('/api/v1', '')\n toFetch.forEach((file: any) => {\n fetch(`${apiUrl}${file.url}`, { credentials: 'include' })\n .then((r) => r.blob())\n .then((blob) => {\n const objectUrl = URL.createObjectURL(blob)\n blobTokens.current.add(objectUrl)\n blobMap.current[file.url] = objectUrl\n setRenderTrigger((n) => n + 1) // force re-render to pick up new blob URL\n })\n .catch(() => {\n // Non-fatal: leave url as-is; browser will fail gracefully\n })\n })\n }, [files])\n\n // Re-render trigger for blob map updates\n const [, setRenderTrigger] = React.useState(0)\n\n // Clean up blob URLs on unmount\n useEffect(() => {\n return () => {\n blobTokens.current.forEach((url) => URL.revokeObjectURL(url))\n }\n }, [])\n\n const fetchFiles = async () => {\n setLoading(true)\n try {\n const res = await api.get('/media')\n setFiles(res.data.data || [])\n } catch {\n console.error('Failed to fetch media')\n toast.error('Failed to load media library')\n } finally {\n setLoading(false)\n }\n }\n\n useEffect(() => {\n if (isOpen) {\n const timer = setTimeout(() => fetchFiles(), 0)\n return () => clearTimeout(timer)\n }\n }, [isOpen])\n\n const toggleSelect = (file: any) => {\n // If focal point mode enabled and single-select, enter the focal-editor step\n if (focalPoint && !hasMany) {\n setFocalPending(file)\n return\n }\n if (hasMany) {\n const exists = selectedFiles.find((f) => f._id === file._id)\n if (exists) {\n onChange(selectedFiles.filter((f) => f._id !== file._id))\n } else {\n onChange([...selectedFiles, file])\n }\n } else {\n onChange(file)\n setIsOpen(false)\n }\n }\n\n const confirmFocalSelection = async (file: any, x: number, y: number) => {\n const updated = { ...file, focalPoint: { x, y } }\n // Persist focal point to the media record\n try {\n if (file._id) {\n await api.patch(`/media/${file._id}`, { focalPoint: { x, y } })\n }\n } catch {\n console.error('Failed to save focal point')\n toast.error('Failed to save focal point')\n }\n onChange(updated)\n setFocalPending(null)\n setIsOpen(false)\n }\n\n const handleUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {\n if (!e.target.files?.[0]) return\n const formData = new FormData()\n formData.append('file', e.target.files[0])\n\n // If focal point mode is active, prompt user to set focal point after upload\n try {\n const res = await api.post('/upload', formData, {\n headers: { 'Content-Type': 'multipart/form-data' },\n })\n const newFile = res.data.data\n setFiles([newFile, ...files])\n\n // If focal point mode and single-select, open the cropper for the new upload\n if (focalPoint && !hasMany) {\n setFocalPending(newFile)\n return\n }\n\n if (!hasMany) {\n onChange(newFile)\n setIsOpen(false)\n }\n } catch {\n console.error('Upload failed')\n toast.error('Upload failed')\n }\n }\n\n const handleAddExternalUrl = () => {\n if (!externalUrl.trim()) return\n const newFile = {\n _id: Math.random().toString(36).substring(7),\n url: externalUrl.trim(),\n filename: externalUrl.trim().split('/').pop() || 'External URL'\n }\n if (hasMany) {\n onChange([...selectedFiles, newFile])\n } else {\n onChange(newFile)\n setIsOpen(false)\n }\n setExternalUrl('')\n }\n\n return (\n <div className=\"space-y-2\">\n <div className=\"flex flex-wrap gap-3\">\n {selectedFiles.map((file, i) => (\n <div\n key={file._id || i}\n className=\"relative w-20 h-20 rounded-none-none border border-z-border overflow-hidden group shadow-sm transition-all hover:scale-105 active:scale-95\"\n >\n <img \n src={getMediaUrl(file.url)} \n className=\"w-full h-full object-cover\" \n alt=\"\" \n />\n {!disabled && (\n <button\n type=\"button\"\n onClick={() =>\n hasMany ? onChange(selectedFiles.filter((_, idx) => idx !== i)) : onChange(null)\n }\n className=\"absolute top-1 right-1 p-1 bg-app/60 text-z-primary rounded-none-none opacity-0 group-hover:opacity-100 transition-opacity\"\n >\n <X size={10} />\n </button>\n )}\n </div>\n ))}\n {!disabled && (hasMany || selectedFiles.length === 0) && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n setIsOpen(true)\n }}\n className=\"w-20 h-20 rounded-none-none border border-dashed border-z-border flex flex-col items-center justify-center gap-1.5 text-z-muted hover:border-z-border/50 hover:text-z-secondary hover:bg-z-hover transition-all group\"\n >\n <Plus\n size={18}\n strokeWidth={3}\n className=\"group-hover:scale-110 transition-transform\"\n />\n <span className=\"text-sm font-semibold\">\n Add_Media\n </span>\n </button>\n )}\n </div>\n\n {mounted && createPortal(\n <AnimatePresence>\n {isOpen && (\n <motion.div\n key=\"media-picker-backdrop\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n className=\"fixed inset-0 z-[1000] flex items-center justify-center bg-[var(--z-bg-modal)] backdrop-blur-sm p-4 md:p-12\"\n onClick={() => setIsOpen(false)}\n >\n <motion.div\n initial={{ opacity: 0, scale: 0.95, y: 10 }}\n animate={{ opacity: 1, scale: 1, y: 0 }}\n exit={{ opacity: 0, scale: 0.95, y: 10 }}\n transition={{ type: 'spring', damping: 25, stiffness: 300 }}\n className={cn(\n 'w-full max-w-5xl max-h-full border rounded-none-none shadow-2xl flex flex-col overflow-hidden',\n theme === 'dark' ? 'bg-app/90 backdrop-blur-xl border-z-border' : 'bg-z-popover border-z-border'\n )}\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"flex flex-col p-4 gap-4\">\n <div className=\"flex items-center justify-between\">\n <h3 className={cn('text-sm font-semibold ', theme === 'dark' ? 'text-z-primary' : 'text-z-primary')}>\n Asset Registry\n </h3>\n <button\n type=\"button\"\n onClick={() => setIsOpen(false)}\n className={cn('p-1 rounded-none-none transition-colors', theme === 'dark' ? 'text-z-muted hover:text-z-primary hover:bg-[var(--z-bg-hover)]' : 'text-z-secondary hover:text-z-primary hover:bg-app/5')}\n >\n <X size={14} />\n </button>\n </div>\n\n <AnimatePresence mode=\"wait\">\n {focalPending ? (\n <motion.div key=\"focal-step\" initial={{ opacity: 0, x: 20 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0, x: -20 }} className=\"flex flex-col gap-4\">\n {/* Focal Point Editor */}\n <div className=\"flex items-center gap-3\">\n <button type=\"button\" onClick={() => setFocalPending(null)} className=\"text-sm font-semibold text-z-muted hover:text-z-primary transition-colors border border-z-border px-3 py-1.5 rounded-none-none\">\n ← Back\n </button>\n </div>\n <div className=\"flex-1 min-h-[300px] flex items-center justify-center\">\n <FocalPointCropper\n imageUrl={getMediaUrl(focalPending.url)}\n initialX={focalPending.focalPoint?.x ?? 50}\n initialY={focalPending.focalPoint?.y ?? 50}\n onSave={(x, y) => confirmFocalSelection(focalPending, x, y)}\n />\n </div>\n </motion.div>\n ) : (\n <motion.div key=\"asset-grid\" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} className=\"flex flex-col gap-4\">\n {/* Top Bar: Search, URL, and Upload */}\n <div className=\"flex flex-col md:flex-row gap-3\">\n <div className=\"flex-[2] relative group\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 text-z-secondary group-focus-within:text-z-secondary transition-colors\" size={14} />\n <input\n type=\"text\"\n placeholder=\"Search assets...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"w-full bg-z-hover border border-z-border rounded-none-none pl-9 pr-3 py-2 text-sm font-medium text-z-primary placeholder:text-z-secondary transition-all focus:bg-z-panel/10 focus:border-z-border/50 outline-none focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:ring-offset-1 focus-visible:ring-offset-black\"\n />\n </div>\n <div className=\"flex-[2] relative flex gap-2\">\n <div className=\"relative flex-1 group\">\n <Link className=\"absolute left-3 top-1/2 -translate-y-1/2 text-z-secondary group-focus-within:text-z-secondary transition-colors\" size={14} />\n <input\n type=\"url\"\n placeholder=\"https://...\"\n value={externalUrl}\n onChange={(e) => setExternalUrl(e.target.value)}\n onKeyDown={(e) => e.key === 'Enter' && handleAddExternalUrl()}\n className=\"w-full bg-z-hover border border-z-border rounded-none-none pl-9 pr-3 py-2 text-sm font-medium text-z-primary placeholder:text-z-secondary transition-all focus:bg-z-panel/10 focus:border-z-border/50 outline-none focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:ring-offset-1 focus-visible:ring-offset-black\"\n />\n </div>\n <button\n type=\"button\"\n onClick={handleAddExternalUrl}\n disabled={!externalUrl.trim()}\n className=\"px-3 py-2 bg-z-hover border-z-border-strong text-z-secondary hover:bg-z-border/30 hover:text-z-primary rounded-none-none text-sm font-bold transition-all border border-z-border/30 disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n Add\n </button>\n </div>\n <label className=\"flex-1 flex items-center justify-center gap-2 px-4 py-2 bg-z-accent/20 hover:bg-z-accent/30 text-z-secondary rounded-none-none transition-all text-sm font-bold cursor-pointer border border-z-border/30\">\n <UploadCloud size={14} />\n <span>Upload</span>\n <input type=\"file\" className=\"hidden\" onChange={handleUpload} />\n </label>\n </div>\n\n {/* Middle Area: Scrollable Grid */}\n <div className=\"flex-1 min-h-[300px] max-h-[50vh] overflow-y-auto grid grid-cols-3 sm:grid-cols-4 lg:grid-cols-5 gap-3 pr-2 custom-scrollbar border border-z-border rounded-none-none p-3 bg-app/20\">\n {loading ? (\n <div className=\"col-span-full h-full flex flex-col items-center justify-center gap-4\">\n <Loader2 className=\"animate-spin text-z-secondary \" size={24} />\n <span className=\"text-sm font-semibold text-z-secondary animate-pulse\">Syncing...</span>\n </div>\n ) : (\n (() => {\n const filtered = files.filter((f) =>\n (f.alt || f.id || f.filename || '')\n .toLowerCase()\n .includes(search.toLowerCase())\n )\n \n if (filtered.length === 0) {\n return (\n <div className=\"col-span-full h-full flex flex-col justify-center py-6\">\n <EmptyState\n icon={ImageIcon}\n title={search ? 'No matches found' : 'No media assets'}\n message={search ? 'Try a different search term' : 'Upload an image to get started'}\n />\n </div>\n )\n }\n\n return filtered.map((file) => {\n const isSelected = selectedFiles.some((f) => f._id === file._id)\n return (\n <div\n key={file._id}\n onClick={() => toggleSelect(file)}\n className={cn(\n 'group relative aspect-square rounded-none-none border overflow-hidden cursor-pointer transition-all',\n isSelected\n ? 'border-z-border shadow-sm scale-[0.98]'\n : 'border-z-border hover:border-z-border/30'\n )}\n >\n <img\n src={getMediaUrl(file.url)}\n className=\"w-full h-full object-cover transition-transform duration-700 group-hover:scale-110\"\n alt=\"\"\n />\n <div\n className={cn(\n 'absolute inset-0 transition-all duration-300',\n isSelected\n ? 'bg-z-accent/10'\n : 'bg-app/0 group-hover:bg-app/40'\n )}\n />\n <div className=\"absolute inset-x-0 bottom-0 p-2 opacity-0 group-hover:opacity-100 translate-y-2 group-hover:translate-y-0 transition-all bg-gradient-to-t from-[var(--z-bg-panel)] to-transparent\">\n <p className=\"text-sm font-semibold text-z-primary truncate\">\n {file.filename || 'Untitled_Asset'}\n </p>\n </div>\n {isSelected && (\n <div className=\"absolute top-2 right-2 bg-z-accent text-z-primary rounded-none-none p-1.5 shadow-xl animate-in zoom-in-50 duration-300\">\n <Check size={10} strokeWidth={4} />\n </div>\n )}\n </div>\n )\n })\n })()\n )}\n </div>\n\n {/* Bottom Area: Actions */}\n <div className=\"pt-2 border-t border-z-border flex items-center justify-end gap-3 mt-2\">\n <button\n type=\"button\"\n onClick={() => { setIsOpen(false); setFocalPending(null) }}\n className=\"px-4 py-2 text-sm font-bold text-z-muted hover:text-z-primary transition-colors\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={() => { setIsOpen(false); setFocalPending(null) }}\n className=\"px-6 py-2 bg-z-hover border-z-border-strong text-z-secondary hover:bg-z-border/30 hover:text-z-primary rounded-none-none text-sm font-bold transition-all border border-z-border/30\"\n >\n Done\n </button>\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n </motion.div>\n </motion.div>\n )}\n </AnimatePresence>,\n document.body\n )}\n </div>\n )\n}\n\nexport default MediaPicker\n\n","import React, { useEffect, useState } from 'react'\nimport { Link2, X, Plus, Search, Check, Loader2, Database } from 'lucide-react'\nimport api from '../lib/api'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport { cn } from '../lib/utils'\nimport { useTheme } from '../context/ThemeContext'\nimport DocumentEditModal from './DocumentEditModal'\n\ninterface RelationItem {\n _id: string\n name?: string\n title?: string\n email?: string\n id?: string\n [key: string]: unknown\n}\n\ninterface RelationPickerProps {\n value?: unknown\n onChange: (value: unknown) => void\n relationTo: string\n hasMany?: boolean\n disabled?: boolean\n}\n\nconst RelationPicker: React.FC<RelationPickerProps> = ({\n value,\n onChange,\n relationTo,\n hasMany,\n disabled = false,\n}) => {\n const { theme } = useTheme()\n const [isOpen, setIsOpen] = useState(false)\n const [editItemId, setEditItemId] = useState<string | null>(null)\n const [items, setItems] = useState<RelationItem[]>([])\n const [loading, setLoading] = useState(false)\n const [search, setSearch] = useState('')\n const [, setSchema] = useState<Record<string, unknown> | null>(null)\n\n const selectedItems = (Array.isArray(value) ? value : value ? [value] : []) as RelationItem[]\n\n const fetchData = async () => {\n setLoading(true)\n try {\n // First get health to find the schema of the related collection\n const healthRes = await api.get('/health')\n const collections = healthRes.data.data?.collections || []\n const globals = healthRes.data.data?.globals || []\n const colSchema =\n collections.find((c: { slug: string }) => c.slug === relationTo) ||\n globals.find((g: { slug: string }) => g.slug === relationTo)\n setSchema(colSchema)\n\n // Then get the items\n const res = await api.get(`/${relationTo}`)\n setItems(res.data.data || [])\n } catch {\n console.error('Failed to fetch relation data')\n } finally {\n setLoading(false)\n }\n }\n\n useEffect(() => {\n if (isOpen) {\n const timer = setTimeout(() => fetchData(), 0)\n return () => clearTimeout(timer)\n }\n \n }, [isOpen, relationTo])\n\n const toggleSelect = (item: RelationItem) => {\n if (hasMany) {\n const exists = selectedItems.find((i) => i._id === item._id)\n if (exists) {\n onChange(selectedItems.filter((i) => i._id !== item._id))\n } else {\n onChange([...selectedItems, item])\n }\n } else {\n onChange(item)\n setIsOpen(false)\n }\n }\n\n const getDisplayValue = (item: RelationItem | string) => {\n if (!item) return ''\n if (typeof item === 'string') return item\n return item.name || item.title || item.email || item.id || item._id\n }\n\n return (\n <div className=\"space-y-2\">\n <div className=\"flex flex-wrap gap-2\">\n {selectedItems.map((item, i) => (\n <div\n key={item._id || i}\n onClick={() => setEditItemId(item._id)}\n className=\"flex items-center gap-3 px-4 py-2 bg-z-active-bg/30 border border-z-active-border rounded-none-none group transition-all hover:border-z-active-border cursor-pointer hover:bg-z-active-bg\"\n >\n <Link2 size={12} className=\"text-z-active-text\" />\n <span className=\"text-sm font-bold text-z-primary\">{getDisplayValue(item)}</span>\n {!disabled && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n if (hasMany) {\n onChange(selectedItems.filter((_, idx) => idx !== i))\n } else {\n onChange(null)\n }\n }}\n className=\"p-1 hover:bg-z-active-bg rounded-none-none text-z-muted hover:text-z-accent transition-colors\"\n >\n <X size={10} />\n </button>\n )}\n </div>\n ))}\n {!disabled && (hasMany || selectedItems.length === 0) && (\n <button\n type=\"button\"\n onClick={() => setIsOpen(true)}\n className=\"flex items-center gap-2.5 px-4 py-2 rounded-xl border-2 border-dashed border-z-border text-z-muted hover:border-z-active-border hover:text-z-accent hover:bg-z-active-bg/20 transition-all group\"\n >\n <Plus size={14} strokeWidth={3} />\n <span className=\"text-sm font-semibold\">\n Link Record\n </span>\n </button>\n )}\n </div>\n\n <DocumentEditModal\n isOpen={!!editItemId}\n onClose={() => setEditItemId(null)}\n collectionSlug={relationTo}\n documentId={editItemId || ''}\n onSaved={(updatedItem) => {\n if (hasMany) {\n onChange(selectedItems.map((item) => item._id === updatedItem._id ? updatedItem : item))\n } else {\n onChange(updatedItem)\n }\n }}\n />\n\n <AnimatePresence>\n {isOpen && (\n <div className=\"fixed inset-0 z-[1000] flex items-center justify-center p-4 md:p-10 bg-app/70 backdrop-blur-md\">\n <motion.div\n initial={{ opacity: 0, scale: 0.98, y: 10 }}\n animate={{ opacity: 1, scale: 1, y: 0 }}\n exit={{ opacity: 0, scale: 0.98, y: 10 }}\n className={cn(\n \"w-full max-w-2xl h-[70vh] flex flex-col shadow-2xl overflow-hidden rounded-xl border\",\n theme === 'dark' ? \"bg-app/65 backdrop-blur-xl border-z-border\" : \"bg-z-panel border-z-border\"\n )}\n >\n <div className={cn(\"p-8 border-b flex items-center justify-between\", theme === 'dark' ? \"border-z-border\" : \"border-z-border\")}>\n <div className=\"flex items-center gap-4\">\n <div className=\"w-10 h-10 bg-indigo-500 rounded-lg flex items-center justify-center text-z-primary shadow-lg shadow-sm\">\n <Database size={20} />\n </div>\n <div className=\"flex flex-col\">\n <h3 className={cn(\"text-lg font-semibold leading-none\", theme === 'dark' ? \"text-z-primary\" : \"text-z-primary\")}>\n Select Relation\n </h3>\n <p className=\"text-sm font-bold text-z-muted mt-1.5\">\n Targeting Collection: {relationTo.toUpperCase()}\n </p>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => setIsOpen(false)}\n className={cn(\"w-10 h-10 flex items-center justify-center rounded-lg transition-all\", theme === 'dark' ? \"bg-z-panel/5 hover:bg-[var(--z-bg-hover)] text-z-primary\" : \"bg-[var(--z-bg-input)] hover:bg-[var(--z-bg-hover)] text-z-muted\")}\n >\n <X size={18} />\n </button>\n </div>\n\n <div className=\"flex-1 overflow-hidden flex flex-col p-8 gap-6\">\n <div className=\"relative group\">\n <Search\n className=\"absolute left-4 top-1/2 -translate-y-1/2 text-z-muted group-focus-within:text-z-accent transition-colors\"\n size={16}\n />\n <input\n type=\"text\"\n placeholder=\"Search records...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className={cn(\n \"w-full rounded-lg pl-12 pr-4 py-3 text-xs font-bold outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 border\",\n theme === 'dark' ? \"bg-app/20 border-z-border text-z-primary\" : \"bg-[var(--z-bg-input)] border-z-border text-z-primary\"\n )}\n />\n </div>\n\n <div className=\"flex-1 overflow-y-auto space-y-2 pr-2 custom-scrollbar\">\n {loading ? (\n <div className=\"h-full flex flex-col items-center justify-center gap-4\">\n <Loader2 className=\"animate-spin text-z-active-text\" size={24} />\n <span className=\"text-sm font-semibold text-z-muted animate-pulse\">\n Syncing Records...\n </span>\n </div>\n ) : items.length === 0 ? (\n <div className=\"h-full flex flex-col items-center justify-center gap-4 opacity-30\">\n <Database size={32} className={theme === 'dark' ? 'text-z-primary' : 'text-z-primary'} />\n <span className={cn(\"text-sm font-semibold\", theme === 'dark' ? 'text-z-primary' : 'text-z-primary')}>\n No Records Found\n </span>\n </div>\n ) : (\n items\n .filter((i) =>\n getDisplayValue(i).toLowerCase().includes(search.toLowerCase())\n )\n .map((item) => {\n const isSelected = selectedItems.some((si) => si._id === item._id)\n return (\n <div\n key={item._id}\n onClick={() => toggleSelect(item)}\n className={cn(\n 'flex items-center justify-between p-4 rounded-lg border transition-all cursor-pointer group',\n isSelected\n ? 'bg-indigo-500 border-indigo-500 text-z-primary shadow-xl shadow-sm'\n : theme === 'dark' ? 'bg-app/20 border-z-border hover:border-z-border' : 'bg-z-panel border-z-border hover:border-z-active-border hover:bg-z-active-bg/10'\n )}\n >\n <div className=\"flex flex-col\">\n <span\n className={cn(\n 'text-xs font-semibold',\n isSelected ? 'text-z-primary' : 'text-z-primary'\n )}\n >\n {getDisplayValue(item)}\n </span>\n <span\n className={cn(\n 'text-sm font-bold mt-1',\n isSelected ? 'text-z-primary/60' : 'text-z-muted'\n )}\n >\n ID: {item._id.slice(-8)}\n </span>\n </div>\n {isSelected && <Check size={16} strokeWidth={3} />}\n </div>\n )\n })\n )}\n </div>\n </div>\n\n <div className={cn(\"p-8 border-t flex justify-end\", theme === 'dark' ? \"border-z-border bg-app/20\" : \"border-z-border bg-[var(--z-bg-input)]/50\")}>\n <button\n type=\"button\"\n onClick={() => setIsOpen(false)}\n className={cn(\"px-8 py-3 rounded-lg text-sm font-semibold shadow-xl transition-all\", theme === 'dark' ? \"bg-z-panel/10 text-z-primary hover:bg-z-panel/20\" : \"bg-z-accent text-z-primary shadow-[var(--z-border)] hover:brightness-110\")}\n >\n Close Registry\n </button>\n </div>\n </motion.div>\n </div>\n )}\n </AnimatePresence>\n </div>\n )\n}\n\nexport default RelationPicker\n","/** Shared utilities for FormBuilder and field renderers */\n\n/**\n * Check if a value is a plain object (not array, not null).\n */\nexport function isObject(item: any): boolean {\n return !!item && typeof item === 'object' && !Array.isArray(item)\n}\n\n/**\n * Recursive deep merge — source values take precedence.\n */\nexport function deepMerge(target: any, source: any): any {\n const output = isObject(target) ? { ...(target as any) } : {}\n if (isObject(target) && isObject(source)) {\n Object.entries(source as any).forEach(([key, val]) => {\n if (isObject(val)) {\n if (!(key in (target as any))) {\n Object.assign(output as any, { [key]: val })\n } else {\n ;(output as any)[key] = deepMerge(\n (target as any)[key],\n val\n )\n }\n } else {\n Object.assign(output as any, { [key]: val })\n }\n })\n }\n return output\n}\n\n/**\n * Navigate nested errors object by dot-notation path.\n */\nexport function getFieldError(\n errors: any | undefined,\n name: string\n): any {\n if (!name.includes('.')) return errors?.[name]\n const parts = name.split('.')\n let current: any = errors\n for (const part of parts) {\n if (!current || typeof current !== 'object') return undefined\n current = (current as any)[part]\n }\n return current\n}\n\n/**\n * Evaluate a field's conditional-display rule.\n */\nexport function evaluateCondition(\n condition: any,\n formValues: any\n): boolean {\n if (!condition) return true\n\n if (typeof condition === 'function') {\n try {\n return (condition as (v: any) => boolean)(formValues)\n } catch {\n return true\n }\n }\n\n if (typeof condition === 'object' && condition !== null) {\n const cond = condition as any\n const targetField = cond.field as string | undefined\n if (!targetField) return true\n\n const targetValue = formValues[targetField]\n\n if (cond.equals !== undefined) return targetValue === cond.equals\n if (cond.notEquals !== undefined) return targetValue !== cond.notEquals\n if (cond.contains !== undefined) return Array.isArray(targetValue) && targetValue.includes(cond.contains)\n }\n\n return true\n}\n\n/**\n * Determine the full field name including locale suffix if localized.\n */\nexport function getFieldName(field: { name: string; localized?: boolean }, locale: string): string {\n return field.localized ? `${field.name}.${locale}` : field.name\n}\n\n/**\n * Returns CSS class list for field casing.\n */\nexport function textCasingStyle(\n casing?: '' | 'lowercase' | 'capitalize'\n): React.CSSProperties | undefined {\n if (!casing) return undefined\n return { textTransform: casing }\n}\n","import React from 'react'\nimport { cn } from '../../lib/utils'\nimport { textCasingStyle } from '../../lib/form-utils'\nimport type { FieldConfig, TextFieldConfig } from '@zenith-open/zenithcms-types'\nimport { useTheme } from '../../context/ThemeContext'\n\ntype TextFieldWithExtras = TextFieldConfig & {\n casing?: '' | 'lowercase' | 'capitalize'\n}\n\ninterface Props {\n field: FieldConfig\n value: unknown\n onChange: (val: unknown) => void\n disabled?: boolean\n}\n\nconst TextField: React.FC<Props> = ({ field, value, onChange, disabled }) => {\n const { theme } = useTheme()\n const cf = field as TextFieldWithExtras\n const casingStyle = textCasingStyle(cf.casing)\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n let val: string = e.target.value\n if (cf.casing === '') val = val.toUpperCase()\n else if (cf.casing === 'lowercase') val = val.toLowerCase()\n else if (cf.casing === 'capitalize')\n val = val.replace(/\\b\\w/g, (c) => c.toUpperCase())\n onChange(val)\n }\n\n return (\n <div className=\"relative w-full\">\n <input\n type={['date', 'password', 'color', 'email'].includes(cf.type) ? cf.type : 'text'}\n value={(value as string) || ''}\n onChange={handleChange}\n maxLength={cf.maxLength}\n style={casingStyle}\n disabled={disabled}\n className={cn(\n \"w-full px-4 py-3 text-sm transition-all outline-none rounded-none-none border\",\n theme === 'dark' \n ? \"bg-z-base/65 backdrop-blur-md border-z-border text-z-primary placeholder:text-z-secondary focus:border-z-accent/50 focus-visible:ring-2 focus-visible:ring-z-active-border\"\n : \"bg-z-panel/80 backdrop-blur-md border-z-border text-z-primary placeholder:text-z-muted focus:border-z-accent/50 focus-visible:ring-2 focus-visible:ring-z-active-border\",\n cf.type === 'color' && \"h-11 p-1 cursor-pointer\",\n cf.type === 'uid' && \"font-mono text-z-active-text\",\n \"disabled:opacity-60 disabled:cursor-not-allowed\"\n )}\n placeholder={`Enter ${cf.name}...`}\n />\n {cf.maxLength && (cf.type as string) !== 'date' && (\n <span className=\"absolute right-3 top-2.5 text-sm font-bold text-z-secondary font-mono pointer-events-none\">\n {((value as string) || '').length} / {cf.maxLength}\n </span>\n )}\n </div>\n )\n}\n\n\nexport default TextField\n","import React from 'react'\nimport { textCasingStyle } from '../../lib/form-utils'\nimport type { FieldConfig, TextFieldConfig } from '@zenith-open/zenithcms-types'\nimport { useTheme } from '../../context/ThemeContext'\nimport { cn } from '../../lib/utils'\n\ntype TextareaFieldWithExtras = TextFieldConfig & {\n casing?: '' | 'lowercase' | 'capitalize'\n}\n\ninterface Props {\n field: FieldConfig\n value: unknown\n onChange: (val: unknown) => void\n disabled?: boolean\n}\n\nconst TextareaField: React.FC<Props> = ({ field, value, onChange, disabled }) => {\n const { theme } = useTheme()\n const cf = field as TextareaFieldWithExtras\n const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n let val: string = e.target.value\n if (cf.casing === '') val = val.toUpperCase()\n else if (cf.casing === 'lowercase') val = val.toLowerCase()\n else if (cf.casing === 'capitalize')\n val = val.replace(/\\b\\w/g, (c) => c.toUpperCase())\n onChange(val)\n }\n\n return (\n <div className=\"relative w-full\">\n <textarea\n value={(value as string) || ''}\n onChange={handleChange}\n maxLength={cf.maxLength}\n rows={8}\n style={textCasingStyle(cf.casing)}\n disabled={disabled}\n className={cn(\n \"w-full px-4 py-3 text-sm transition-all outline-none rounded-none-none border min-h-[140px]\",\n theme === 'dark' \n ? \"bg-z-base/65 backdrop-blur-md border-z-border text-z-primary placeholder:text-z-secondary focus:border-z-accent/50 focus-visible:ring-2 focus-visible:ring-z-active-border\"\n : \"bg-z-panel/80 backdrop-blur-md border-z-border text-z-primary placeholder:text-z-muted focus:border-z-accent/50 focus-visible:ring-2 focus-visible:ring-z-active-border\",\n \"disabled:opacity-60 disabled:cursor-not-allowed\"\n )}\n placeholder={`Enter ${cf.name}...`}\n />\n {cf.maxLength && (\n <span className=\"absolute bottom-2 right-3 text-sm font-bold text-z-secondary font-mono\">\n {((value as string) || '').length} / {cf.maxLength}\n </span>\n )}\n </div>\n )\n}\n\n\nexport default TextareaField\n","import React from 'react'\nimport type { FieldConfig, SelectFieldConfig } from '@zenith-open/zenithcms-types'\nimport { useTheme } from '../../context/ThemeContext'\nimport { cn } from '../../lib/utils'\n\ninterface Props {\n field: FieldConfig\n value: unknown\n onChange: (val: unknown) => void\n disabled?: boolean\n}\n\nconst SelectField: React.FC<Props> = ({ field, value, onChange, disabled }) => {\n const { theme } = useTheme()\n const selectField = field as SelectFieldConfig\n const isMulti = selectField.hasMany ?? false\n\n const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {\n const val = isMulti\n ? Array.from(e.target.selectedOptions, (option) => option.value)\n : e.target.value\n onChange(val)\n }\n\n const selectedVals: string[] = isMulti\n ? (Array.isArray(value) ? value.map(String) : [])\n : []\n\n return (\n <select\n value={isMulti ? undefined : ((value as string) || '')}\n onChange={handleChange}\n multiple={isMulti}\n disabled={disabled}\n className={cn(\n \"w-full px-4 py-3 text-sm transition-all duration-350 outline-none focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:ring-offset-1 focus-visible:ring-offset-black\",\n \"backdrop-blur-md\",\n theme === 'dark'\n ? 'bg-z-base/65 backdrop-blur-md border-z-border text-z-primary focus:border-z-accent/50 focus-visible:ring-2 focus-visible:ring-z-active-border'\n : 'bg-z-panel/80 backdrop-blur-md border-z-border text-z-primary focus:border-z-accent/50 focus-visible:ring-2 focus-visible:ring-z-active-border',\n isMulti ? \"rounded-none-none min-h-[120px]\" : \"rounded-none-none\",\n \"disabled:opacity-60 disabled:cursor-not-allowed\"\n )}\n >\n {!selectField.required && !isMulti && <option value=\"\">Select...</option>}\n {(selectField.options || []).map((opt: string | { value?: string; label?: string }) => {\n const optVal = typeof opt === 'string' ? opt : (opt.value || opt)\n const optLabel = typeof opt === 'string' ? opt : (opt.label || opt)\n const strVal = String(optVal)\n return (\n <option key={strVal} value={strVal}>\n {String(optLabel)}\n </option>\n )\n })}\n </select>\n )\n}\n\nexport default SelectField\n","import React from 'react'\nimport type { FieldConfig } from '@zenith-open/zenithcms-types'\n\ninterface Props {\n field: FieldConfig\n value: unknown\n onChange: (val: unknown) => void\n disabled?: boolean\n}\n\nconst BooleanField: React.FC<Props> = ({ field: _field, value, onChange, disabled }) => {\n return (\n <div className=\"flex items-center h-9\">\n <input\n type=\"checkbox\"\n checked={!!value}\n onChange={(e) => onChange(e.target.checked)}\n disabled={disabled}\n className=\"w-4 h-4 rounded-none-none border border-z-border bg-z-input backdrop-blur-md text-z-active-text focus:ring-z-active-border focus:ring-2 disabled:opacity-60 disabled:cursor-not-allowed transition-all\"\n />\n </div>\n )\n}\n\nexport default BooleanField\n","import React from 'react'\nimport type { FieldConfig } from '@zenith-open/zenithcms-types'\n\ninterface Props {\n field: FieldConfig\n value: unknown\n onChange: (val: unknown) => void\n disabled?: boolean\n}\n\nconst NumberField: React.FC<Props> = ({ field: _field, value, onChange, disabled }) => {\n return (\n <input\n type=\"number\"\n value={(value as number | string) ?? ''}\n onChange={(e) => onChange(e.target.value === '' ? null : Number(e.target.value))}\n disabled={disabled}\n className=\"w-full bg-z-base/65 backdrop-blur-md border border-z-border rounded-none-none px-4 py-3 text-sm focus:border-z-accent/50 focus-visible:ring-2 focus-visible:ring-z-active-border outline-none disabled:opacity-60 disabled:cursor-not-allowed text-z-primary placeholder:text-z-secondary transition-all font-mono\"\n />\n )\n}\n\nexport default NumberField\n","import React from 'react'\nimport { cn } from '../../lib/utils'\nimport type { FieldConfig, CodeFieldConfig } from '@zenith-open/zenithcms-types'\n\ninterface Props {\n field: FieldConfig\n value: unknown\n onChange: (val: unknown) => void\n disabled?: boolean\n}\n\nconst CodeField: React.FC<Props> = ({ field, value, onChange, disabled }) => {\n const cf = field as CodeFieldConfig\n return (\n <div className=\"relative w-full\">\n <textarea\n value={(value as string) || ''}\n onChange={(e) => onChange(e.target.value)}\n maxLength={cf.maxLength}\n rows={10}\n disabled={disabled}\n spellCheck={false}\n className={cn(\n 'w-full bg-[#0d1117] backdrop-blur-md border border-z-border rounded-none-none px-4 py-3 text-sm font-mono',\n 'focus:border-z-accent/50 outline-none focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:ring-offset-1 focus-visible:ring-offset-black disabled:opacity-60 disabled:cursor-not-allowed',\n 'text-[#e6edf3] placeholder:text-z-secondary'\n )}\n placeholder={`Enter ${cf.language || 'code'}...`}\n />\n <div className=\"absolute top-2 right-3 flex items-center gap-2\">\n {cf.language && (\n <span className=\"text-sm font-bold text-z-active-text/60 font-mono\">\n {cf.language}\n </span>\n )}\n {cf.maxLength && (\n <span className=\"text-sm font-bold text-z-secondary font-mono\">\n {((value as string) || '').length}/{cf.maxLength}\n </span>\n )}\n </div>\n </div>\n )\n}\n\nexport default CodeField\n","import React from 'react'\nimport type { FieldConfig } from '@zenith-open/zenithcms-types'\n\ntype CollapsibleFieldConfig = FieldConfig & {\n initCollapsed?: boolean\n fields?: FieldConfig[]\n}\n\ninterface Props {\n field: FieldConfig\n value: unknown\n onChange: (val: unknown) => void\n disabled?: boolean\n renderField: (f: FieldConfig, val: unknown, change: (val: unknown) => void) => React.ReactNode\n}\n\nconst CollapsibleField: React.FC<Props> = ({\n field,\n value,\n onChange,\n disabled: _disabled,\n renderField,\n}) => {\n const cfField = field as CollapsibleFieldConfig\n const [isOpen, setIsOpen] = React.useState(!cfField.initCollapsed)\n const collapsibleFields = cfField.fields || []\n\n return (\n <div className=\"border border-z-border rounded-none-none overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => setIsOpen(!isOpen)}\n className=\"w-full flex items-center justify-between px-4 py-3 bg-z-hover hover:bg-z-panel/[0.06] transition-colors text-sm font-semibold text-z-primary\"\n >\n <span className=\"flex items-center gap-2\">\n <span\n className={`transition-transform duration-200 text-z-active-text ${\n isOpen ? 'rotate-90' : ''\n }`}\n >\n \n </span>\n {field.label || field.name}\n </span>\n </button>\n {isOpen && (\n <div className=\"p-4 grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-4 border-t border-z-border\">\n {collapsibleFields.map((f) => (\n <div key={f.name} className=\"space-y-1.5\">\n <label className=\"text-xs font-semibold text-z-secondary capitalize\">\n {f.label || f.name}\n {(f as any).required && <span className=\"text-danger ml-1\">*</span>}\n </label>\n {renderField(f, (value as Record<string, unknown>)?.[f.name], (val: unknown) =>\n onChange({ ...((value as Record<string, unknown>) || {}), [f.name]: val })\n )}\n </div>\n ))}\n </div>\n )}\n </div>\n )\n}\n\nexport default CollapsibleField\n","import React from 'react'\nimport type { FieldConfig, GroupFieldConfig } from '@zenith-open/zenithcms-types'\nimport { cn } from '../../lib/utils'\n\ninterface GroupFieldProps {\n field: FieldConfig\n value: unknown\n onChange: (val: unknown) => void\n disabled?: boolean\n renderField: (f: FieldConfig, val: unknown, change: (val: unknown) => void, disabled?: boolean) => React.ReactNode\n}\n\nconst GroupField: React.FC<GroupFieldProps> = ({ field, value, onChange, disabled, renderField }) => {\n const groupValue = (value && typeof value === 'object' ? value : {}) as Record<string, unknown>\n const gf = field as GroupFieldConfig\n const subFields = gf.fields || []\n\n return (\n <div className={cn(\n 'border border-z-border bg-z-panel backdrop-blur-md p-4 space-y-4'\n )}>\n <div className=\"flex items-center gap-2 pb-3 border-b border-z-border\">\n <span className=\"text-sm font-semibold text-z-active-text\">\n {field.label || field.name}\n </span>\n {gf.admin?.description && (\n <span className=\"text-sm text-z-secondary italic\">{gf.admin.description}</span>\n )}\n </div>\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-x-6 gap-y-5 pt-2\">\n {subFields.map((f: FieldConfig) => (\n <div key={f.name} className=\"space-y-1.5\">\n <label className=\"text-sm font-bold text-z-muted\">\n {f.label || f.name}\n {(f as any).required && <span className=\"text-danger ml-1\">*</span>}\n </label>\n {renderField(\n f,\n groupValue[f.name],\n (val: unknown) => onChange({ ...groupValue, [f.name]: val }),\n disabled\n )}\n </div>\n ))}\n </div>\n </div>\n )\n}\n\nexport default GroupField\n","import React, { useState, useCallback } from 'react'\nimport { CheckCircle, AlertCircle, Code } from 'lucide-react'\nimport { cn } from '../../lib/utils'\n\ninterface JSONFieldProps {\n value: unknown\n onChange: (val: unknown) => void\n disabled?: boolean\n rows?: number\n}\n\nfunction tryParseJson(value: unknown): boolean | null {\n if (value === undefined || value === null || value === '') return null\n const str = typeof value === 'string' ? value : JSON.stringify(value)\n try {\n JSON.parse(str)\n return true\n } catch {\n return false\n }\n}\n\nconst JSONField: React.FC<JSONFieldProps> = ({ value, onChange, disabled, rows = 8 }) => {\n const [focused, setFocused] = useState(false)\n const jsonValid = tryParseJson(value)\n\n const displayValue = typeof value === 'string'\n ? value\n : value !== undefined && value !== null\n ? JSON.stringify(value, null, 2)\n : ''\n\n const handleChange = useCallback((e: React.ChangeEvent<HTMLTextAreaElement>) => {\n const raw = e.target.value\n onChange(raw)\n }, [onChange])\n\n const handleFormat = useCallback(() => {\n try {\n const parsed = JSON.parse(typeof value === 'string' ? value : JSON.stringify(value))\n onChange(JSON.stringify(parsed, null, 2))\n } catch {\n // ignore — can't format invalid JSON\n }\n }, [value, onChange])\n\n return (\n <div className=\"space-y-1.5\">\n <div className=\"relative\">\n <div className=\"absolute left-3 top-2.5 text-z-secondary pointer-events-none\">\n <Code size={14} />\n </div>\n <textarea\n value={displayValue}\n onChange={handleChange}\n onFocus={() => setFocused(true)}\n onBlur={() => setFocused(false)}\n rows={rows}\n disabled={disabled}\n spellCheck={false}\n className={cn(\n 'w-full bg-[#0d1117] backdrop-blur-md border rounded-none-none px-9 py-3 text-sm font-mono resize-y outline-none focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:ring-offset-1 focus-visible:ring-offset-black transition-colors',\n 'text-[#e6edf3] placeholder:text-z-secondary disabled:opacity-60 disabled:cursor-not-allowed',\n focused\n ? 'border-z-accent/50'\n : jsonValid === false\n ? 'border-red-500/40'\n : 'border-z-border'\n )}\n placeholder='{\"key\": \"value\"}'\n />\n </div>\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <span className={cn(\n 'inline-block w-1.5 h-1.5 rounded-none-full',\n jsonValid === true ? 'bg-z-accent shadow-sm' : jsonValid === false ? 'bg-red-500 shadow-[0_0_6px_#ef4444]' : 'bg-z-accent'\n )} />\n <span className={cn(\n 'text-sm font-bold ',\n jsonValid === true ? 'text-z-active-text' : jsonValid === false ? 'text-red-400' : 'text-z-secondary'\n )}>\n {jsonValid === true ? 'Valid JSON' : jsonValid === false ? 'Invalid JSON' : 'JSON'}\n </span>\n </div>\n {jsonValid === true && (\n <button\n type=\"button\"\n onClick={handleFormat}\n className=\"text-sm font-bold text-z-secondary hover:text-z-active-text transition-colors\"\n >\n Format\n </button>\n )}\n </div>\n </div>\n )\n}\n\nexport default JSONField\n","import React from 'react'\nimport { Calendar } from 'lucide-react'\nimport { useTheme } from '../../context/ThemeContext'\nimport { cn } from '../../lib/utils'\n\ninterface DateFieldProps {\n value: unknown\n onChange: (val: unknown) => void\n disabled?: boolean\n format?: 'date' | 'datetime' | 'time'\n}\n\nfunction formatForInput(value: unknown, format: 'date' | 'datetime' | 'time'): string {\n if (!value) return ''\n try {\n const d = new Date(value as string)\n if (isNaN(d.getTime())) return typeof value === 'string' ? value : ''\n if (format === 'datetime') return d.toISOString().slice(0, 16)\n if (format === 'time') return d.toISOString().slice(11, 16)\n return d.toISOString().slice(0, 10)\n } catch {\n return typeof value === 'string' ? value : ''\n }\n}\n\nfunction parseInput(value: string, format: 'date' | 'datetime' | 'time'): string {\n if (!value) return ''\n if (format === 'time') return value\n try {\n return new Date(value).toISOString()\n } catch {\n return value\n }\n}\n\nconst DateField: React.FC<DateFieldProps> = ({ value, onChange, disabled, format = 'date' }) => {\n const { theme } = useTheme()\n const inputType = format === 'datetime' ? 'datetime-local' : format === 'time' ? 'time' : 'date'\n\n return (\n <div className=\"relative w-full\">\n <div className={cn(\n \"absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none\",\n theme === 'dark' ? 'text-z-primary/60' : 'text-z-secondary'\n )}>\n <Calendar size={14} />\n </div>\n <input\n type={inputType}\n value={formatForInput(value, format)}\n onChange={(e) => onChange(parseInput(e.target.value, format))}\n disabled={disabled}\n style={{ colorScheme: theme === 'dark' ? 'dark' : 'light' }}\n className={cn(\n 'w-full pl-9 pr-4 py-3 text-sm transition-all outline-none rounded-none-none border',\n theme === 'dark'\n ? 'bg-z-input backdrop-blur-md border-z-border text-z-primary placeholder:text-z-secondary focus:border-z-accent/50 focus-visible:ring-2 focus-visible:ring-z-active-border'\n : 'bg-z-panel/80 backdrop-blur-md border-z-border text-z-primary placeholder:text-z-muted focus:border-z-accent/50 focus-visible:ring-2 focus-visible:ring-z-active-border',\n 'disabled:opacity-60 disabled:cursor-not-allowed font-mono'\n )}\n />\n </div>\n )\n}\n\nexport default DateField\n","import React, { useCallback } from 'react'\nimport { Link, RefreshCw } from 'lucide-react'\nimport { cn } from '../../lib/utils'\n\ninterface SlugFieldProps {\n value: unknown\n onChange: (val: unknown) => void\n disabled?: boolean\n sourceField?: string\n formValues?: Record<string, unknown>\n}\n\nfunction slugify(text: string): string {\n return text\n .toLowerCase()\n .trim()\n .replace(/[^\\w\\s-]/g, '')\n .replace(/[\\s_]+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n}\n\nconst SlugField: React.FC<SlugFieldProps> = ({ value, onChange, disabled, sourceField, formValues }) => {\n const handleGenerate = useCallback(() => {\n if (sourceField && formValues) {\n const source = formValues[sourceField]\n if (typeof source === 'string' && source.trim()) {\n onChange(slugify(source))\n }\n }\n }, [sourceField, formValues, onChange])\n\n return (\n <div className=\"relative w-full\">\n <div className=\"absolute left-3 top-1/2 -translate-y-1/2 text-z-secondary pointer-events-none\">\n <Link size={14} />\n </div>\n <input\n type=\"text\"\n value={(value as string) || ''}\n onChange={(e) => onChange(e.target.value)}\n disabled={disabled}\n className={cn(\n 'w-full bg-z-panel/[0.05] backdrop-blur-md border border-z-border rounded-none-none pl-9 pr-10 py-3 text-sm',\n 'focus:border-z-accent/50 outline-none focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:ring-offset-1 focus-visible:ring-offset-black disabled:opacity-60 disabled:cursor-not-allowed',\n 'text-z-active-text font-mono placeholder:text-z-secondary'\n )}\n placeholder=\"auto-generated-slug\"\n />\n {sourceField && (\n <button\n type=\"button\"\n onClick={handleGenerate}\n disabled={disabled}\n title={`Generate from ${sourceField}`}\n className=\"absolute right-2 top-1/2 -translate-y-1/2 p-1 text-z-secondary hover:text-z-active-text disabled:opacity-30 transition-colors\"\n >\n <RefreshCw size={13} />\n </button>\n )}\n </div>\n )\n}\n\nexport default SlugField\n","import React, { useCallback } from 'react'\nimport { Hash, RefreshCw } from 'lucide-react'\nimport { cn } from '../../lib/utils'\n\ninterface UIDFieldProps {\n value: unknown\n onChange: (val: unknown) => void\n disabled?: boolean\n}\n\nfunction generateUID(): string {\n return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)\n}\n\nconst UIDField: React.FC<UIDFieldProps> = ({ value, onChange, disabled }) => {\n const handleRegenerate = useCallback(() => {\n onChange(generateUID())\n }, [onChange])\n\n return (\n <div className=\"relative w-full\">\n <div className=\"absolute left-3 top-1/2 -translate-y-1/2 text-z-secondary pointer-events-none\">\n <Hash size={14} />\n </div>\n <input\n type=\"text\"\n value={(value as string) || ''}\n onChange={(e) => onChange(e.target.value)}\n disabled={disabled}\n readOnly\n className={cn(\n 'w-full bg-z-hover backdrop-blur-md border border-z-border rounded-none-none pl-9 pr-10 py-2 text-sm',\n 'focus:border-z-accent/50 outline-none focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:ring-offset-1 focus-visible:ring-offset-black disabled:opacity-60 disabled:cursor-not-allowed',\n 'text-z-active-text/80 font-mono'\n )}\n placeholder=\"auto-generated-uid\"\n />\n <button\n type=\"button\"\n onClick={handleRegenerate}\n disabled={disabled}\n title=\"Regenerate UID\"\n className=\"absolute right-2 top-1/2 -translate-y-1/2 p-1 text-z-secondary hover:text-z-active-text disabled:opacity-30 transition-colors\"\n >\n <RefreshCw size={13} />\n </button>\n </div>\n )\n}\n\nexport default UIDField\n","import React, { useState } from 'react'\nimport type { FieldConfig, BaseFieldConfig } from '@zenith-open/zenithcms-types'\nimport { cn } from '../../lib/utils'\n\ninterface TabFieldProps {\n field: FieldConfig\n value: unknown\n onChange: (val: unknown) => void\n disabled?: boolean\n renderField: (f: FieldConfig, val: unknown, change: (val: unknown) => void, disabled?: boolean) => React.ReactNode\n}\n\ninterface TabConfig {\n name: string\n label?: string\n fields?: FieldConfig[]\n}\n\ninterface TabsFieldConfig extends BaseFieldConfig {\n type: 'tabs'\n tabs: TabConfig[]\n}\n\nconst TabField: React.FC<TabFieldProps> = ({ field, value, onChange, disabled, renderField }) => {\n const tf = field as unknown as TabsFieldConfig\n const tabs = tf.tabs || []\n const [activeTab, setActiveTab] = useState(0)\n const tabValue = (value && typeof value === 'object' ? value : {}) as Record<string, unknown>\n\n if (tabs.length === 0) return null\n\n const currentTab = tabs[activeTab]\n const currentFields = currentTab?.fields || []\n\n return (\n <div className=\"border border-z-border bg-z-panel backdrop-blur-md\">\n {/* Tab Headers */}\n <div className=\"flex border-b border-z-border\">\n {tabs.map((tab, idx) => (\n <button\n key={tab.name}\n type=\"button\"\n onClick={() => setActiveTab(idx)}\n className={cn(\n 'px-4 py-2.5 text-sm font-semibold transition-colors',\n activeTab === idx\n ? 'text-z-active-text border-b-2 border-z-accent bg-z-hover'\n : 'text-z-secondary hover:text-z-secondary'\n )}\n >\n {tab.label || tab.name}\n </button>\n ))}\n </div>\n\n {/* Tab Content */}\n {currentFields.length > 0 && (\n <div className=\"p-4 space-y-3\">\n {currentFields.map((f) => (\n <div key={f.name} className=\"space-y-1.5\">\n <label className=\"text-sm font-bold text-z-muted\">\n {f.label || f.name}\n {(f as any).required && <span className=\"text-danger ml-1\">*</span>}\n </label>\n {renderField(\n f,\n tabValue[f.name],\n (val: unknown) => onChange({ ...tabValue, [f.name]: val }),\n disabled\n )}\n </div>\n ))}\n </div>\n )}\n </div>\n )\n}\n\nexport default TabField\n","import React from 'react'\nimport type { FieldConfig } from '@zenith-open/zenithcms-types'\nimport { cn } from '../../lib/utils'\n\ninterface Props {\n field: FieldConfig\n value: unknown\n onChange: (val: unknown) => void\n disabled?: boolean\n}\n\ntype RowFieldConfig = FieldConfig & {\n layout?: 'horizontal' | 'vertical'\n fields?: FieldConfig[]\n}\n\ninterface RowFieldProps extends Props {\n renderField: (f: FieldConfig, val: unknown, change: (val: unknown) => void) => React.ReactNode\n}\n\nconst PointField: React.FC<Props> = ({ field: _field, value, onChange, disabled }) => {\n const coords: [number, number] = Array.isArray(value) && value.length === 2 ? (value as [number, number]) : [0, 0]\n\n return (\n <div className=\"flex gap-3\">\n <div className=\"flex-1 space-y-1\">\n <label className=\"text-sm font-bold text-z-secondary\">\n Longitude\n </label>\n <input\n type=\"number\"\n value={coords[0]}\n onChange={(e) => onChange([Number(e.target.value), coords[1]])}\n step=\"any\"\n disabled={disabled}\n className=\"w-full bg-z-panel/[0.05] backdrop-blur-md border border-z-border rounded-none-none px-3 py-3 text-sm focus:border-z-accent/50 outline-none focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:ring-offset-1 focus-visible:ring-offset-black disabled:opacity-60 disabled:cursor-not-allowed text-z-primary placeholder:text-z-secondary\"\n placeholder=\"0.0\"\n />\n </div>\n <div className=\"flex-1 space-y-1\">\n <label className=\"text-sm font-bold text-z-secondary\">\n Latitude\n </label>\n <input\n type=\"number\"\n value={coords[1]}\n onChange={(e) => onChange([coords[0], Number(e.target.value)])}\n step=\"any\"\n disabled={disabled}\n className=\"w-full bg-z-panel/[0.05] backdrop-blur-md border border-z-border rounded-none-none px-3 py-3 text-sm focus:border-z-accent/50 outline-none focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:ring-offset-1 focus-visible:ring-offset-black disabled:opacity-60 disabled:cursor-not-allowed text-z-primary placeholder:text-z-secondary\"\n placeholder=\"0.0\"\n />\n </div>\n </div>\n )\n}\n\nconst RowField: React.FC<RowFieldProps> = ({ field, value, onChange, renderField }) => {\n const cf = field as RowFieldConfig\n const rowFields = cf.fields || []\n\n return (\n <div className=\"flex gap-4 items-end\">\n {rowFields.map((f) => (\n <div key={f.name} className=\"flex-1 space-y-1.5\">\n <label className=\"text-xs font-semibold text-z-secondary capitalize\">\n {f.label || f.name}\n {(f as any).required && <span className=\"text-danger ml-1\">*</span>}\n </label>\n {renderField(\n f,\n (value as Record<string, unknown>)?.[f.name],\n (val: unknown) =>\n onChange({ ...((value as Record<string, unknown>) || {}), [f.name]: val })\n )}\n </div>\n ))}\n </div>\n )\n}\n\nconst JoinField: React.FC<{ field: { collection?: string } }> = ({ field }) => (\n <div className=\"w-full bg-z-hover border border-z-border rounded-none-none px-4 py-3 text-sm text-z-muted italic flex items-center gap-2\">\n <span className=\"text-z-active-text\">⧉</span>\n Joined data from{' '}\n <span className=\"font-mono text-z-active-text text-xs\">{field.collection}</span> — read-only\n </div>\n)\n\ntype RadioFieldConfig = FieldConfig & {\n layout?: 'horizontal' | 'vertical'\n options?: Array<{ value?: string; label?: string } | string>\n}\n\n\nconst RadioField: React.FC<Props> = ({ field, value, onChange, disabled }) => {\n const cf = field as RadioFieldConfig\n const isHorizontal = cf.layout === 'horizontal'\n\n return (\n <div className={cn('flex gap-4', isHorizontal ? 'flex-row flex-wrap' : 'flex-col gap-2')}>\n {(cf.options || []).map((opt, i) => {\n const optVal = typeof opt === 'string' ? opt : (opt.value || '')\n const optLabel = typeof opt === 'string' ? opt : (opt.label || optVal)\n return (\n <label key={`${String(optVal)}-${i}`} className=\"flex items-center gap-2.5 cursor-pointer group\">\n <input\n type=\"radio\"\n name={field.name}\n value={String(optVal)}\n checked={value === optVal}\n onChange={(e) => onChange(e.target.value)}\n disabled={disabled}\n className=\"w-4 h-4 border border-z-border text-z-active-text focus:ring-z-active-border disabled:opacity-60 accent-z-accent\"\n />\n <span className=\"text-sm text-z-secondary group-hover:text-z-primary transition-colors\">\n {String(optLabel)}\n </span>\n </label>\n )\n })}\n </div>\n )\n}\n\nexport { PointField, RowField, JoinField, RadioField }\n","import React, { useState, useCallback, useEffect, useRef } from 'react'\nimport { createPortal } from 'react-dom'\nimport { useTheme } from '../context/ThemeContext'\nimport {\n Plus,\n GripVertical,\n Trash2,\n ChevronDown,\n Layers,\n Box,\n CreditCard,\n Layout,\n Puzzle,\n Copy,\n ArrowUp,\n ArrowDown,\n BarChart4,\n MessageSquare,\n Zap,\n Star,\n Mail,\n FileText,\n Users,\n AlertCircle,\n Code,\n Table,\n X,\n Search,\n Eye,\n EyeOff,\n} from 'lucide-react'\nimport { motion, AnimatePresence, Reorder } from 'framer-motion'\nimport { cn, uid } from '../lib/utils'\n\nimport type { FieldConfig } from '@zenith-open/zenithcms-types'\nimport { useBlockLibrary } from '../hooks/useBlockLibrary'\nimport { useModalStore } from '../store/modalStore'\nimport { UNIFIED_BLOCK_LIBRARY } from '../pages/editor/unifiedBlocks'\n\n// ── Types ─────────────────────────────────────────────────────────────────────\ninterface Block {\n blockType: string\n _id?: string\n [key: string]: unknown\n}\n\ninterface BlockField {\n name: string\n label?: string\n type: string\n required?: boolean\n defaultValue?: unknown\n options?: unknown\n [key: string]: unknown\n}\n\ninterface BlockDefinition {\n slug: string\n labels?: { singular: string; plural: string }\n fields: BlockField[]\n admin?: {\n description?: string\n icon?: string\n imageURL?: string\n category?: string\n }\n}\n\ninterface BlocksBuilderProps {\n value: Block[]\n onChange: (value: Block[]) => void\n availableBlocks?: unknown[]\n renderField?: (field: FieldConfig, value: unknown, onChange: (val: unknown) => void) => React.ReactNode\n disabled?: boolean\n}\n\n// Helper to humanize names if label is missing\nconst humanize = (str: string) => {\n return str\n .replace(/^root:/, '')\n .replace(/([A-Z])/g, ' $1')\n .replace(/^./, (s) => s.toUpperCase())\n}\n\nconst IconMap: Record<string, React.ComponentType<any>> = {\n Star,\n Grid: Layout,\n BarChart4,\n MessageSquare,\n Mail,\n CreditCard,\n Zap,\n FileText,\n Layout,\n Users,\n AlertCircle,\n Code,\n Table,\n Puzzle,\n}\n\nconst getBlockIcon = (slug: string): React.ReactNode => {\n const blockDef = UNIFIED_BLOCK_LIBRARY.find((b) => b.type === slug)\n const IconComp = blockDef ? IconMap[blockDef.iconName] : null\n if (IconComp) return React.createElement(IconComp, { size: 16 })\n if (slug === 'plugin-node') return <Puzzle size={16} />\n return <Box size={16} />\n}\n\n// ── Gradient Map ──────────────────────────────────────────────────────────────\nconst CATEGORY_GRADIENTS: Record<string, string> = {\n Layout: 'from-z-accent to-transparent',\n Content: 'from-z-accent to-transparent',\n Commerce: 'from-z-accent to-transparent',\n Media: 'from-rose-900/60 to-pink-900/40',\n Social: 'from-amber-900/60 to-orange-900/40',\n General: 'from-[#1a1a2e]/80 to-[#16213e]/60',\n}\n\nconst DEFAULT_BLOCKS: BlockDefinition[] = UNIFIED_BLOCK_LIBRARY.map((b) => ({\n slug: b.type,\n labels: { singular: b.title, plural: b.title + 's' },\n fields: b.fields.map((f) => ({\n name: f.name,\n label: f.label || humanize(f.name),\n type: f.type,\n required: f.required,\n defaultValue: b.defaultContent[f.name],\n options: f.options,\n })),\n admin: {\n description: b.description,\n category: b.category,\n }\n}))\n\n// ── Block Row ─────────────────────────────────────────────────────────────────\nfunction BlockRow({\n block, index, total, blockDef, isExpanded, disabled,\n onToggle, onRemove, onDuplicate, onMoveUp, onMoveDown, renderField, onUpdate,\n}: {\n block: Block; index: number; total: number; blockDef?: BlockDefinition\n isExpanded: boolean; disabled: boolean\n onToggle: () => void; onRemove: () => void; onDuplicate: () => void\n onMoveUp: () => void; onMoveDown: () => void\n renderField?: BlocksBuilderProps['renderField']\n onUpdate: (updates: Partial<Block>) => void\n}) {\n const previewText = (() => {\n for (const f of ['headline', 'title', 'name', 'content', 'subheadline']) {\n if (block[f] && typeof block[f] === 'string') return block[f]\n }\n return null\n })()\n\n const grad = CATEGORY_GRADIENTS[blockDef?.admin?.category || ''] ?? CATEGORY_GRADIENTS.General\n\n return (\n <Reorder.Item\n value={block}\n drag={!disabled ? 'y' : false}\n whileDrag={{ scale: 1.01, zIndex: 50, boxShadow: '0 20px 40px rgba(0,0,0,0.4)' }}\n className={cn(\n 'group relative bg-app border rounded-none-none overflow-visible shadow-sm transition-colors duration-150',\n isExpanded ? 'border-accent/60 shadow-sm' : 'border-border hover:border-z-border'\n )}\n >\n {/* Index Badge */}\n <div className={cn(\n 'absolute -left-3.5 top-1/2 -translate-y-1/2 w-5 h-5 rounded-none-full flex items-center justify-center text-sm font-semibold border z-10 transition-all',\n isExpanded\n ? 'bg-accent text-z-primary border-accent shadow-sm'\n : 'bg-app text-z-muted border-border group-hover:border-accent/40 group-hover:text-accent'\n )}>\n {index + 1}\n </div>\n\n {/* Accent bar when expanded */}\n {isExpanded && <div className=\"absolute left-0 top-0 bottom-0 w-[3px] bg-accent rounded-none-l\" />}\n\n {/* Header Row */}\n <div className=\"flex items-center gap-2.5 px-4 py-3 cursor-pointer\" onClick={onToggle}>\n {!disabled && (\n <div className=\"p-1 text-z-muted/30 hover:text-z-muted cursor-grab active:cursor-grabbing flex-shrink-0\" onPointerDown={(e) => e.stopPropagation()}>\n <GripVertical size={13} />\n </div>\n )}\n\n {/* Icon */}\n <div className={cn('w-7 h-7 rounded-none flex items-center justify-center flex-shrink-0 bg-gradient-to-br text-z-primary/70', grad)}>\n {getBlockIcon(block.blockType)}\n </div>\n\n {/* Labels */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-bold text-z-primary truncate\">\n {previewText || blockDef?.labels?.singular || block.blockType}\n </span>\n <span className=\"flex-shrink-0 px-1.5 py-px text-sm font-semibold text-z-muted bg-z-panel/[0.05] border border-border rounded-none\">\n {block.blockType}\n </span>\n </div>\n {blockDef?.admin?.description && (\n <p className=\"text-sm text-z-muted/70 truncate mt-0.5\">{blockDef.admin.description}</p>\n )}\n </div>\n\n {/* Actions */}\n <div className=\"flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity flex-shrink-0\" onClick={(e) => e.stopPropagation()}>\n {!disabled && (\n <>\n <button type=\"button\" onClick={onMoveUp} disabled={index === 0} title=\"Move Up\" className=\"p-1.5 text-z-muted hover:text-z-primary disabled:opacity-20 disabled:cursor-not-allowed transition-colors\"><ArrowUp size={11} /></button>\n <button type=\"button\" onClick={onMoveDown} disabled={index === total - 1} title=\"Move Down\" className=\"p-1.5 text-z-muted hover:text-z-primary disabled:opacity-20 disabled:cursor-not-allowed transition-colors\"><ArrowDown size={11} /></button>\n <button type=\"button\" onClick={onDuplicate} title=\"Duplicate\" className=\"p-1.5 text-z-muted hover:text-accent transition-colors\"><Copy size={11} /></button>\n <button type=\"button\" onClick={onRemove} title=\"Remove\" className=\"p-1.5 text-z-muted hover:text-danger transition-colors\"><Trash2 size={11} /></button>\n </>\n )}\n <motion.div animate={{ rotate: isExpanded ? 180 : 0 }} transition={{ duration: 0.2 }} className=\"p-1.5 text-z-muted/50 ml-0.5\">\n <ChevronDown size={13} />\n </motion.div>\n </div>\n </div>\n\n {/* Expanded Fields */}\n <AnimatePresence initial={false}>\n {isExpanded && (\n <motion.div\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: 'auto', opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n transition={{ duration: 0.2, ease: [0.4, 0, 0.2, 1] }}\n className=\"overflow-hidden\"\n >\n <div className=\"px-5 pb-6 pt-4 border-t border-border bg-z-panel/[0.05]/40\">\n {blockDef ? (\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {blockDef.fields.map((f) => {\n const fullWidth = ['richtext','textarea','blocks','array','media','code','collapsible'].includes(f.type)\n return (\n <div key={f.name} className={cn('flex flex-col gap-1.5', fullWidth && 'col-span-2')}>\n <label className=\"text-sm font-semibold text-z-muted flex items-center gap-1\">\n {f.label || f.name}\n {f.required && <span className=\"text-danger\">*</span>}\n </label>\n {renderField\n ? renderField(f as unknown as FieldConfig, block[f.name], (val: any) => onUpdate({ [f.name]: val }))\n : <input type=\"text\" value={(block[f.name] as string) || ''} onChange={(e) => onUpdate({ [f.name]: e.target.value })} placeholder={`Enter ${f.label || f.name}...`} className=\"w-full bg-app border border-border px-3 py-2 text-sm focus:border-accent focus:ring-2 focus:ring-accent/10 outline-none focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:ring-offset-1 focus-visible:ring-offset-black transition-all rounded-none-none\" />\n }\n </div>\n )\n })}\n </div>\n ) : (\n <p className=\"text-xs text-z-muted text-center py-4 italic\">Unknown block type: \"{block.blockType}\"</p>\n )}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </Reorder.Item>\n )\n}\n\n// ── Component Picker ──────────────────────────────────────────────────────────\nfunction ComponentPicker({ blocksList, onSelect, onClose }: {\n blocksList: BlockDefinition[]; onSelect: (slug: string) => void; onClose: () => void\n}) {\n const { theme } = useTheme()\n const [search, setSearch] = useState('')\n const [activeCategory, setActiveCategory] = useState('All')\n const searchRef = useRef<HTMLInputElement>(null)\n\n useEffect(() => {\n searchRef.current?.focus()\n const handler = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose() }\n window.addEventListener('keydown', handler)\n return () => window.removeEventListener('keydown', handler)\n }, [onClose])\n\n const categories = ['All', ...Array.from(new Set(blocksList.map((b) => b.admin?.category || 'General')))]\n\n const filtered = blocksList.filter((b) => {\n const q = search.toLowerCase()\n const matchSearch = !q || b.slug.includes(q) || (b.labels?.singular || '').toLowerCase().includes(q) || (b.admin?.description || '').toLowerCase().includes(q)\n const matchCat = activeCategory === 'All' || (b.admin?.category || 'General') === activeCategory\n return matchSearch && matchCat\n })\n\n const grouped = activeCategory === 'All'\n ? filtered.reduce((acc, b) => {\n const cat = b.admin?.category || 'General'\n if (!acc[cat]) acc[cat] = []\n acc[cat].push(b)\n return acc\n }, {} as Record<string, BlockDefinition[]>)\n : { [activeCategory]: filtered }\n\n return createPortal(\n <div className=\"fixed inset-0 z-[1000] flex items-center justify-center p-4 md:p-8 bg-app/70 backdrop-blur-md\" onClick={onClose}>\n <motion.div\n initial={{ opacity: 0, scale: 0.96, y: 12 }}\n animate={{ opacity: 1, scale: 1, y: 0 }}\n exit={{ opacity: 0, scale: 0.96, y: 12 }}\n transition={{ duration: 0.18, ease: [0.4, 0, 0.2, 1] }}\n onClick={(e) => e.stopPropagation()}\n className={cn(\n \"w-full max-w-4xl border rounded-none-none overflow-hidden shadow-2xl flex flex-col h-[85vh]\",\n theme === 'dark' ? 'bg-[#0B0F19] border-z-border' : 'bg-z-panel border-z-border'\n )}\n >\n {/* Header */}\n <div\n className={cn(\n 'p-6 border-b flex items-center justify-between shrink-0',\n theme === 'dark' ? 'border-z-border' : 'border-z-border',\n )}\n >\n <h3\n className={cn(\n 'text-lg font-semibold italic leading-none',\n theme === 'dark' ? 'text-z-primary' : 'text-z-primary',\n )}\n >\n Add Component\n </h3>\n <button\n onClick={onClose}\n aria-label=\"Close\"\n className={cn(\n 'p-1 transition-colors',\n theme === 'dark' ? 'text-z-muted hover:text-z-active-text' : 'text-z-secondary hover:text-z-accent'\n )}\n >\n <X size={18} />\n </button>\n </div>\n\n <div className={cn(\n \"flex-1 overflow-hidden flex flex-col p-6\",\n theme === 'dark' ? 'bg-[#0B0F19]' : 'bg-z-panel'\n )}>\n {/* Search */}\n <div className=\"relative mb-6 shrink-0\">\n <Search size={14} className={cn(\n \"absolute left-4 top-1/2 -translate-y-1/2\",\n 'text-z-secondary'\n )} />\n <input \n ref={searchRef} \n type=\"text\" \n value={search} \n onChange={(e) => setSearch(e.target.value)} \n placeholder=\"Search components...\" \n className={cn(\n \"w-full rounded-none-none pl-11 pr-11 py-3 text-xs font-bold transition-all outline-none focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:ring-offset-1 focus-visible:ring-offset-black\",\n theme === 'dark' \n ? 'bg-z-hover border border-z-border text-z-primary placeholder:text-z-secondary focus:border-z-accent/40 focus:bg-z-panel/[0.05]'\n : 'bg-[var(--z-bg-input)] border border-z-border text-z-primary placeholder:text-z-muted focus:border-z-active-border focus:bg-z-panel'\n )} \n />\n {search && (\n <button \n onClick={() => setSearch('')} \n className={cn(\n \"absolute right-4 top-1/2 -translate-y-1/2 transition-colors\",\n theme === 'dark' ? 'text-z-secondary hover:text-z-primary' : 'text-z-muted hover:text-z-primary'\n )}\n >\n <X size={14} />\n </button>\n )}\n </div>\n\n {/* Categories Tab Bar */}\n <div className=\"flex items-center gap-1 p-1 border border-z-border bg-z-panel rounded-none-none shrink-0 mb-4 overflow-x-auto no-scrollbar\">\n {categories.map((cat) => (\n <button \n key={cat} \n type=\"button\" \n onClick={() => setActiveCategory(cat)} \n className={cn(\n 'flex items-center gap-2 px-4 py-2 text-sm font-semibold italic transition-all border rounded-none-none whitespace-nowrap',\n activeCategory === cat\n ? theme === 'dark'\n ? 'bg-z-accent/20 border-z-active-border text-z-active-text'\n : 'bg-z-active-bg border-z-active-border text-z-accent shadow-sm'\n : theme === 'dark'\n ? 'bg-transparent border-transparent text-z-secondary hover:bg-z-hover'\n : 'bg-transparent border-transparent text-z-secondary hover:bg-[var(--z-bg-hover)]'\n )}\n >\n {cat}\n </button>\n ))}\n </div>\n\n {/* Component Grid */}\n <div className=\"flex-1 overflow-y-auto custom-scrollbar pr-2 pb-4 space-y-6\">\n {Object.keys(grouped).length === 0 ? (\n <div className=\"text-center py-14\">\n <Search size={28} className=\"mx-auto text-z-muted/20 mb-3\" />\n <p className=\"text-sm font-semibold text-z-muted\">No results for \"{search}\"</p>\n <p className=\"text-xs text-z-muted/60 mt-1\">Try a different keyword</p>\n </div>\n ) : (\n Object.entries(grouped).map(([category, blocks]) => (\n <div key={category}>\n {activeCategory === 'All' && (\n <div className=\"flex items-center gap-3 mb-4\">\n <span className=\"h-px flex-1 bg-border\" />\n <span className=\"text-sm font-semibold text-z-muted\">{category}</span>\n <span className=\"h-px flex-1 bg-border\" />\n </div>\n )}\n <div className=\"grid grid-cols-2 sm:grid-cols-3 gap-3\">\n {blocks.map((stock) => {\n const grad = CATEGORY_GRADIENTS[stock.admin?.category || ''] ?? CATEGORY_GRADIENTS.General\n return (\n <motion.button\n key={stock.slug}\n type=\"button\"\n whileHover={{ scale: 1.02 }}\n whileTap={{ scale: 0.97 }}\n onClick={() => onSelect(stock.slug)}\n className=\"flex flex-col text-left group border border-border bg-app hover:border-accent/60 hover:shadow-sm transition-all overflow-hidden rounded-none-none\"\n >\n <div className=\"w-full h-24 overflow-hidden relative flex-shrink-0\">\n {stock.admin?.imageURL ? (\n <img src={stock.admin.imageURL} alt={stock.slug} className=\"w-full h-full object-cover group-hover:scale-105 transition-transform duration-700\" />\n ) : (\n <div className={cn('absolute inset-0 bg-gradient-to-br flex items-center justify-center', grad)}>\n <div className=\"text-z-primary/40 group-hover:text-z-primary/80 transition-colors\" style={{ transform: 'scale(2)' }}>\n {getBlockIcon(stock.slug)}\n </div>\n </div>\n )}\n {stock.admin?.category && (\n <span className=\"absolute top-2 left-2 px-1.5 py-0.5 text-sm font-semibold bg-app/60 backdrop-blur text-z-primary/80 rounded-none-none\">\n {stock.admin.category}\n </span>\n )}\n {stock.admin?.imageURL && (\n <div className=\"absolute top-2 right-2 w-5 h-5 bg-app/50 backdrop-blur flex items-center justify-center text-z-primary/70 rounded-none-none\">\n {getBlockIcon(stock.slug)}\n </div>\n )}\n </div>\n <div className=\"p-3 flex-1 bg-app group-hover:bg-accent/5 transition-colors\">\n <p className=\"text-sm font-semibold text-z-primary mb-0.5\">{stock.labels?.singular || stock.slug}</p>\n <p className=\"text-sm text-z-muted leading-relaxed line-clamp-2\">{stock.admin?.description || `Add ${stock.slug} to your page.`}</p>\n </div>\n </motion.button>\n )\n })}\n </div>\n </div>\n ))\n )}\n </div>\n </div>\n </motion.div>\n </div>,\n document.body\n )\n}\n\n// ── Main Export ───────────────────────────────────────────────────────────────\nconst BlocksBuilder: React.FC<BlocksBuilderProps> = ({\n value, onChange, availableBlocks, renderField, disabled = false,\n}) => {\n const apiBlocks = useBlockLibrary()\n const { openComponentPicker } = useModalStore()\n const [expandedIds, setExpandedIds] = useState<Record<string, boolean>>({})\n const [showPreview, setShowPreview] = useState(false)\n \n const previewUrl = import.meta.env.VITE_PREVIEW_URL || '/preview'\n\n const rawBlocks = (availableBlocks as BlockDefinition[]) || []\n const blocksList: BlockDefinition[] = rawBlocks.length > 0 ? rawBlocks : (apiBlocks.length > 0 ? (apiBlocks as BlockDefinition[]) : DEFAULT_BLOCKS)\n const blocks = value || []\n\n const toggleBlock = useCallback((key: string) => {\n setExpandedIds((prev) => ({\n ...prev,\n [key]: !prev[key],\n }))\n }, [])\n\n const addBlock = useCallback((slug: string) => {\n const def = blocksList.find((b) => b.slug === slug)\n const newId = 'block_' + uid()\n const newBlock: Block = { \n blockType: slug,\n _id: newId,\n id: newId\n }\n def?.fields.forEach((f) => { if (f.defaultValue !== undefined) newBlock[f.name] = f.defaultValue })\n onChange([...blocks, newBlock])\n setExpandedIds((prev) => ({ ...prev, [newId]: true }))\n }, [blocks, blocksList, onChange])\n\n const handleOpenPicker = useCallback(() => {\n openComponentPicker((slug) => addBlock(slug))\n }, [openComponentPicker, addBlock])\n\n const removeBlock = useCallback((i: number) => {\n const next = blocks.filter((_, idx) => idx !== i)\n onChange(next)\n }, [blocks, onChange])\n\n const duplicateBlock = useCallback((i: number) => {\n const next = [...blocks]\n const newId = 'block_' + uid()\n const dupBlock = { ...blocks[i], _id: newId, id: newId }\n next.splice(i + 1, 0, dupBlock)\n onChange(next)\n setExpandedIds((prev) => ({ ...prev, [newId]: true }))\n }, [blocks, onChange])\n\n const moveBlock = useCallback((i: number, dir: 'up' | 'down') => {\n const next = [...blocks]\n const t = dir === 'up' ? i - 1 : i + 1\n if (t < 0 || t >= next.length) return\n ;[next[i], next[t]] = [next[t], next[i]]\n onChange(next)\n }, [blocks, onChange])\n\n const updateBlock = useCallback((i: number, updates: Partial<Block>) => {\n const next = [...blocks]\n next[i] = { ...next[i], ...updates }\n onChange(next)\n }, [blocks, onChange])\n\n const expandAll = useCallback(() => {\n const next: Record<string, boolean> = {}\n blocks.forEach((b, idx) => {\n const key = b._id || String(idx)\n next[key] = true\n })\n setExpandedIds(next)\n }, [blocks])\n\n const collapseAll = useCallback(() => {\n setExpandedIds({})\n }, [])\n\n return (\n <div className={cn(\"select-none\", showPreview ? \"grid grid-cols-2 gap-8\" : \"pl-5\")}>\n <div className=\"flex flex-col gap-4 w-full\">\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2.5\">\n <Layers size={16} className=\"text-accent\" />\n <span className=\"text-sm font-semibold text-z-primary\">Page Components</span>\n {blocks.length > 0 && (\n <span className=\"px-1.5 py-0.5 text-sm font-semibold bg-accent/15 text-accent border border-accent/25 rounded-none-full\">\n {blocks.length}\n </span>\n )}\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => setShowPreview(!showPreview)}\n className={cn(\n \"flex items-center gap-1.5 px-3 py-1.5 text-sm font-semibold transition-all rounded-none-none border\",\n showPreview ? \"bg-z-active-bg text-z-active-text border-z-active-border\" : \"bg-z-panel text-z-muted border-z-border hover:text-z-primary\"\n )}\n >\n {showPreview ? <EyeOff size={12} /> : <Eye size={12} />}\n {showPreview ? 'Close Preview' : 'Live Preview'}\n </button>\n {blocks.length > 0 && (\n <div className=\"flex items-center gap-1.5 border border-z-border bg-z-panel p-0.5 rounded-none-none mr-2\">\n <button\n type=\"button\"\n onClick={expandAll}\n className=\"px-2.5 py-1 text-sm font-semibold text-z-muted hover:text-z-primary transition-all hover:bg-z-panel/[0.05]\"\n >\n Expand All\n </button>\n <div className=\"w-px h-3 bg-z-panel/10\" />\n <button\n type=\"button\"\n onClick={collapseAll}\n className=\"px-2.5 py-1 text-sm font-semibold text-z-muted hover:text-z-primary transition-all hover:bg-z-panel/[0.05]\"\n >\n Collapse All\n </button>\n </div>\n )}\n {!disabled && (\n <button type=\"button\" onClick={handleOpenPicker} className=\"flex items-center gap-1.5 px-3 py-1.5 bg-accent text-z-primary text-sm font-semibold hover:bg-accent/90 transition-all shadow-sm shadow-accent/20 rounded-none-none\">\n <Plus size={11} /> Add Component\n </button>\n )}\n </div>\n </div>\n\n {/* Empty State */}\n {blocks.length === 0 && (\n <motion.div initial={{ opacity: 0, y: 6 }} animate={{ opacity: 1, y: 0 }} className=\"border border-dashed border-border p-10 flex flex-col items-center gap-4 text-center bg-z-panel/[0.05]/20 rounded-none-none\">\n <div className=\"w-12 h-12 rounded-none-full bg-accent/10 border border-accent/20 flex items-center justify-center\">\n <Layers size={20} className=\"text-accent/50\" />\n </div>\n <div>\n <p className=\"text-sm font-bold text-z-primary mb-1\">No components yet</p>\n <p className=\"text-xs text-z-muted max-w-xs leading-relaxed\">Build your page by stacking components — hero sections, feature grids, pricing tables and more.</p>\n </div>\n {!disabled && (\n <button type=\"button\" onClick={handleOpenPicker} className=\"flex items-center gap-2 px-4 py-2 bg-accent text-z-primary text-sm font-semibold hover:bg-accent/90 transition-all shadow-sm shadow-accent/20 mt-1 rounded-none-none\">\n <Plus size={12} /> Add Your First Component\n </button>\n )}\n </motion.div>\n )}\n\n {/* Block List */}\n <Reorder.Group axis=\"y\" values={blocks} onReorder={onChange} className=\"space-y-3\">\n <AnimatePresence initial={false}>\n {blocks.map((block, index) => {\n const blockDef = blocksList.find((b) => b.slug === block.blockType)\n const blockKey = block._id || String(index)\n return (\n <motion.div\n key={`block-${blockKey}`}\n initial={{ opacity: 0, x: -8 }}\n animate={{ opacity: 1, x: 0 }}\n exit={{ opacity: 0, x: -8, height: 0, marginTop: 0 }}\n transition={{ duration: 0.15 }}\n >\n <BlockRow\n block={block} index={index} total={blocks.length} blockDef={blockDef}\n isExpanded={!!expandedIds[blockKey]} disabled={disabled}\n onToggle={() => toggleBlock(blockKey)}\n onRemove={() => removeBlock(index)}\n onDuplicate={() => duplicateBlock(index)}\n onMoveUp={() => moveBlock(index, 'up')}\n onMoveDown={() => moveBlock(index, 'down')}\n renderField={renderField}\n onUpdate={(u) => updateBlock(index, u)}\n />\n </motion.div>\n )\n })}\n </AnimatePresence>\n </Reorder.Group>\n\n {/* Bottom Add Button */}\n {blocks.length > 0 && !disabled && (\n <motion.button\n type=\"button\"\n initial={{ opacity: 0 }} animate={{ opacity: 1 }}\n onClick={handleOpenPicker}\n className=\"flex items-center justify-center gap-2 w-full py-2.5 border border-dashed border-border text-z-muted/60 text-sm font-semibold hover:border-accent/50 hover:text-accent hover:bg-accent/5 transition-all rounded-none-none\"\n >\n <Plus size={11} /> Add Component\n </motion.button>\n )}\n </div>\n\n {/* Side-by-Side Live Preview Iframe */}\n {showPreview && (\n <div className=\"w-full h-full min-h-[700px] border border-z-border rounded-none-none overflow-hidden sticky top-4 bg-[#0B0F19] shadow-2xl flex flex-col\">\n <div className=\"px-4 py-2 border-b border-z-border flex items-center justify-between shrink-0\">\n <span className=\"text-sm font-semibold text-z-active-text italic flex items-center gap-2\">\n <div className=\"w-2 h-2 rounded-none-full bg-z-accent animate-pulse shadow-sm\" />\n Live Preview Connected\n </span>\n <span className=\"text-sm font-mono text-z-secondary\">{previewUrl}</span>\n </div>\n <iframe \n src={previewUrl} \n className=\"w-full flex-1 border-0 bg-z-panel\" \n title=\"Live Preview\"\n />\n </div>\n )}\n </div>\n )\n}\n\nexport default BlocksBuilder\n","import React, { useState, useCallback } from 'react'\nimport {\n Plus,\n GripVertical,\n Trash2,\n ChevronDown,\n ArrowUp,\n ArrowDown,\n Copy,\n Layers,\n} from 'lucide-react'\nimport { motion, AnimatePresence, Reorder } from 'framer-motion'\nimport { cn, uid } from '../lib/utils'\n\ninterface FieldConfig {\n name: string\n label?: string\n type: string\n required?: boolean\n [key: string]: any\n}\n\ninterface SimpleArrayBuilderProps {\n value?: any[]\n onChange: (value: any[]) => void\n fields: FieldConfig[]\n label: string\n renderField: (\n field: FieldConfig,\n value: any,\n onChange: (val: any) => void\n ) => React.ReactNode\n disabled?: boolean\n}\n\nconst SimpleArrayBuilder: React.FC<SimpleArrayBuilderProps> = ({\n value = [],\n onChange,\n fields,\n label,\n renderField,\n disabled = false,\n}) => {\n const [expandedIds, setExpandedIds] = useState<Record<string, boolean>>({})\n\n // Ensure every item has an internal `_id` for Framer Motion Reorder tracking\n const items = React.useMemo(() => {\n return value.map((item, idx) => ({\n ...item,\n _id: (item as any)._id || `array_item_${uid()}_${idx}`\n }))\n }, [value])\n\n const toggleItem = (id: string) => {\n setExpandedIds((prev) => ({ ...prev, [id]: !prev[id] }))\n }\n\n const expandAll = () => {\n const next: Record<string, boolean> = {}\n items.forEach((item) => { next[item._id as string] = true })\n setExpandedIds(next)\n }\n\n const collapseAll = () => {\n setExpandedIds({})\n }\n\n const addItem = useCallback(() => {\n const newId = `array_item_${uid()}`\n const newItem: any = { _id: newId, id: newId }\n fields.forEach((f) => {\n if (f.defaultValue !== undefined) {\n newItem[f.name] = f.defaultValue\n }\n })\n onChange([...value, newItem])\n setExpandedIds((prev) => ({ ...prev, [newId]: true }))\n }, [value, fields, onChange])\n\n const removeItem = useCallback((index: number) => {\n const next = [...value]\n next.splice(index, 1)\n onChange(next)\n }, [value, onChange])\n\n const duplicateItem = useCallback((index: number) => {\n const next = [...value]\n const newId = `array_item_${uid()}`\n const dupItem = { ...value[index], _id: newId, id: newId }\n next.splice(index + 1, 0, dupItem)\n onChange(next)\n setExpandedIds((prev) => ({ ...prev, [newId]: true }))\n }, [value, onChange])\n\n const moveItem = useCallback((index: number, direction: 'up' | 'down') => {\n if (direction === 'up' && index === 0) return\n if (direction === 'down' && index === value.length - 1) return\n const next = [...value]\n const targetIndex = direction === 'up' ? index - 1 : index + 1\n const temp = next[index]\n next[index] = next[targetIndex]\n next[targetIndex] = temp\n onChange(next)\n }, [value, onChange])\n\n const updateItem = useCallback((index: number, updates: any) => {\n const next = [...value]\n next[index] = { ...next[index], ...updates }\n onChange(next)\n }, [value, onChange])\n\n return (\n <div className=\"flex flex-col gap-4 pl-5 select-none\">\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2.5\">\n <Layers size={16} strokeWidth={2} className=\"text-z-secondary \" />\n <span className=\"text-sm font-semibold text-z-primary\">\n {label}\n </span>\n <span className=\"px-1.5 py-0.5 text-sm font-semibold bg-z-border/15 text-z-secondary border border-z-border/25 rounded-none-none\">\n {value.length}\n </span>\n </div>\n \n <div className=\"flex items-center gap-2\">\n {value.length > 0 && (\n <div className=\"flex items-center gap-1.5 border border-z-border bg-z-panel p-0.5 rounded-none-none mr-2\">\n <button type=\"button\" onClick={expandAll} className=\"px-2.5 py-1 text-sm font-semibold text-z-muted hover:text-z-primary transition-all hover:bg-z-panel/[0.05]\">Expand All</button>\n <div className=\"w-px h-3 bg-z-panel/10\" />\n <button type=\"button\" onClick={collapseAll} className=\"px-2.5 py-1 text-sm font-semibold text-z-muted hover:text-z-primary transition-all hover:bg-z-panel/[0.05]\">Collapse All</button>\n </div>\n )}\n {!disabled && (\n <button\n type=\"button\"\n onClick={addItem}\n className=\"flex items-center gap-1.5 px-3 py-1.5 bg-z-accent text-z-primary text-sm font-semibold hover:bg-z-border transition-all shadow-sm shadow-[var(--z-border)] rounded-none-none\"\n >\n <Plus size={11} strokeWidth={2} /> Add Component\n </button>\n )}\n </div>\n </div>\n\n {/* List */}\n <Reorder.Group axis=\"y\" values={items} onReorder={(reordered) => onChange(reordered.map(item => { const { _id, ...rest } = item; return rest }))} className=\"space-y-3\">\n <AnimatePresence initial={false}>\n {items.map((item, index) => {\n const itemKey = item._id as string\n const isExpanded = !!expandedIds[itemKey]\n \n // Generate a simple preview text from the first string field if available\n const previewText = (() => {\n for (const f of fields) {\n if (['text', 'string'].includes(f.type) && typeof item[f.name] === 'string') {\n return item[f.name]\n }\n }\n return `Component ${index + 1}`\n })()\n\n return (\n <motion.div\n key={itemKey}\n initial={{ opacity: 0, height: 0 }}\n animate={{ opacity: 1, height: 'auto' }}\n exit={{ opacity: 0, height: 0 }}\n transition={{ duration: 0.2 }}\n >\n <Reorder.Item\n value={item}\n drag={!disabled ? 'y' : false}\n whileDrag={{ scale: 1.01, zIndex: 50, boxShadow: '0 20px 40px rgba(0,0,0,0.4)' }}\n className={cn(\n 'group relative bg-app border rounded-none-none overflow-visible shadow-sm transition-colors duration-150',\n isExpanded ? 'border-z-border/60 shadow-sm' : 'border-border hover:border-z-border'\n )}\n >\n {/* Index Badge */}\n <div className={cn(\n 'absolute -left-3.5 top-1/2 -translate-y-1/2 w-5 h-5 rounded-none-none flex items-center justify-center text-sm font-semibold border z-10 transition-all',\n isExpanded\n ? 'bg-z-border text-z-primary border-z-border shadow-sm'\n : 'bg-app text-z-muted border-border group-hover:border-z-border/40 group-hover:text-z-secondary '\n )}>\n {index + 1}\n </div>\n\n {/* Accent bar when expanded */}\n {isExpanded && <div className=\"absolute left-0 top-0 bottom-0 w-[3px] bg-z-border rounded-none-l\" />}\n\n {/* Header Row */}\n <div className=\"flex items-center gap-2.5 px-4 py-3 cursor-pointer\" onClick={() => toggleItem(itemKey)}>\n {!disabled && (\n <div className=\"p-1 text-z-muted/30 hover:text-z-muted cursor-grab active:cursor-grabbing flex-shrink-0\" onPointerDown={(e) => e.stopPropagation()}>\n <GripVertical size={13} />\n </div>\n )}\n\n {/* Labels */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-bold text-z-primary truncate\">\n {previewText}\n </span>\n </div>\n </div>\n\n {/* Actions */}\n <div className=\"flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity flex-shrink-0\" onClick={(e) => e.stopPropagation()}>\n {!disabled && (\n <>\n <button type=\"button\" onClick={() => moveItem(index, 'up')} disabled={index === 0} title=\"Move Up\" className=\"p-1.5 text-z-muted hover:text-z-primary disabled:opacity-20 disabled:cursor-not-allowed transition-colors\"><ArrowUp size={11} /></button>\n <button type=\"button\" onClick={() => moveItem(index, 'down')} disabled={index === items.length - 1} title=\"Move Down\" className=\"p-1.5 text-z-muted hover:text-z-primary disabled:opacity-20 disabled:cursor-not-allowed transition-colors\"><ArrowDown size={11} /></button>\n <button type=\"button\" onClick={() => duplicateItem(index)} title=\"Duplicate\" className=\"p-1.5 text-z-muted hover:text-z-secondary transition-colors\"><Copy size={11} /></button>\n <button type=\"button\" onClick={() => removeItem(index)} title=\"Remove\" className=\"p-1.5 text-z-muted hover:text-danger transition-colors\"><Trash2 size={11} /></button>\n </>\n )}\n <motion.div animate={{ rotate: isExpanded ? 180 : 0 }} transition={{ duration: 0.2 }} className=\"p-1.5 text-z-muted/50 ml-0.5\">\n <ChevronDown size={13} />\n </motion.div>\n </div>\n </div>\n\n {/* Expanded Fields */}\n <AnimatePresence initial={false}>\n {isExpanded && (\n <motion.div\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: 'auto', opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n transition={{ duration: 0.2, ease: [0.4, 0, 0.2, 1] }}\n className=\"overflow-hidden\"\n >\n <div className=\"px-5 pb-6 pt-4 border-t border-border bg-z-panel/[0.05]/40\">\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {fields.map((f) => {\n const fullWidth = ['richtext','textarea','blocks','array','media','code','collapsible'].includes(f.type)\n return (\n <div key={f.name} className={cn('flex flex-col gap-1.5', fullWidth && 'col-span-2')}>\n <label className=\"text-sm font-semibold text-z-muted flex items-center gap-1\">\n {f.label || f.name}\n {f.required && <span className=\"text-danger\">*</span>}\n </label>\n {renderField(f as any as FieldConfig, item[f.name], (val: any) => updateItem(index, { [f.name]: val }))}\n </div>\n )\n })}\n </div>\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </Reorder.Item>\n </motion.div>\n )\n })}\n </AnimatePresence>\n </Reorder.Group>\n\n {/* Empty State / Add Button */}\n {!disabled && (\n <motion.button\n layout\n type=\"button\"\n onClick={addItem}\n className=\"flex items-center justify-center gap-2 w-full py-2.5 border border-dashed border-border text-z-muted/60 text-sm font-semibold hover:border-z-border/50 hover:text-z-secondary hover:bg-z-hover transition-all rounded-none-none\"\n >\n <Plus size={11} strokeWidth={2} /> Add {label}\n </motion.button>\n )}\n </div>\n )\n}\n\nexport default SimpleArrayBuilder\n","import React from 'react'\nimport { useForm, Controller } from 'react-hook-form'\nimport { Loader2, Lock } from 'lucide-react'\nimport { useAuthStore } from '../store/authStore'\n\nimport MediaPicker from './MediaPicker'\nimport RelationPicker from './RelationPicker'\nimport {\n evaluateCondition,\n getFieldError,\n deepMerge,\n getFieldName,\n} from '../lib/form-utils'\nimport TextField from './fields/TextField'\nimport TextareaField from './fields/TextareaField'\nimport SelectField from './fields/SelectField'\nimport BooleanField from './fields/BooleanField'\nimport NumberField from './fields/NumberField'\nimport CodeField from './fields/CodeField'\nimport CollapsibleField from './fields/CollapsibleField'\nimport GroupField from './fields/GroupField'\nimport JSONField from './fields/JSONField'\nimport DateField from './fields/DateField'\nimport SlugField from './fields/SlugField'\nimport UIDField from './fields/UIDField'\nimport TabField from './fields/TabField'\nimport {\n PointField,\n RowField,\n JoinField,\n RadioField,\n} from './fields/SpecialFields'\n\nimport BlocksBuilder from './BlocksBuilder'\nimport SimpleArrayBuilder from './SimpleArrayBuilder'\nimport { useShallow } from 'zustand/react/shallow'\n\n/** Field config used by the form builder — keeps a flexible shape since runtime\n * field configs can have additional properties not in the base discriminated union. */\n \ntype FieldConfig = any\n\ninterface FormBuilderProps {\n fields: FieldConfig[]\n initialData?: any\n onSubmit?: (data: any) => Promise<void>\n onValuesChange?: (data: any) => void\n isSubmitting?: boolean\n activeLocale?: string\n readOnlyLocale?: string\n hideSubmitButton?: boolean\n}\n\nconst FormBuilder: React.FC<FormBuilderProps> = ({\n fields,\n initialData,\n onSubmit,\n onValuesChange,\n isSubmitting = false,\n activeLocale,\n readOnlyLocale,\n hideSubmitButton = false,\n}) => {\n const { user } = useAuthStore(useShallow(state => ({ user: state.user })))\n const currentLocale = activeLocale || 'en'\n const isReadOnly = !!readOnlyLocale\n\n const {\n handleSubmit,\n control,\n reset,\n watch,\n formState: { errors },\n } = useForm({\n defaultValues: initialData || {},\n })\n\n React.useEffect(() => {\n if (onValuesChange) {\n const subscription = watch((value) => {\n onValuesChange(value)\n })\n return () => subscription.unsubscribe()\n }\n }, [watch, onValuesChange])\n\n const formValues = watch()\n const initialDataRef = React.useRef(initialData)\n\n React.useEffect(() => {\n if (initialData && initialData !== initialDataRef.current) {\n initialDataRef.current = initialData\n reset(initialData)\n }\n }, [initialData, reset])\n\n const renderField = (\n field: FieldConfig,\n value: any,\n onChange: (val: any) => void,\n disabled = false\n ) => {\n // ── UI slot — render custom field component if registered ────────────────\n if (field.type === 'ui') {\n const CustomComponent = field.admin?.components?.Field\n if (CustomComponent) {\n return <CustomComponent field={field} value={value} onChange={onChange} disabled={disabled} />\n }\n return null\n }\n\n // ── Structural fields — pass renderField for nesting ─────────────────────\n if (field.type === 'collapsible') {\n return (\n <CollapsibleField\n field={field}\n value={value}\n onChange={onChange}\n disabled={disabled}\n renderField={renderField}\n />\n )\n }\n\n if (field.type === 'group') {\n return (\n <GroupField\n field={field}\n value={value}\n onChange={onChange}\n disabled={disabled}\n renderField={renderField}\n />\n )\n }\n\n if (field.type === 'tabs') {\n return (\n <TabField\n field={field}\n value={value}\n onChange={onChange}\n disabled={disabled}\n renderField={renderField}\n />\n )\n }\n\n if (field.type === 'row') {\n return (\n <RowField\n field={field}\n value={value}\n onChange={onChange}\n disabled={disabled}\n renderField={renderField}\n />\n )\n }\n\n // ── Complex fields with their own internal state ────────────────────────\n if (field.type === 'richtext' || field.type === 'lexical') {\n return (\n <TextareaField\n field={field}\n value={value}\n onChange={onChange}\n disabled={disabled}\n />\n )\n }\n\n if (field.type === 'media') {\n return (\n <MediaPicker\n value={value}\n onChange={onChange}\n hasMany={field.hasMany}\n disabled={disabled}\n focalPoint={field.admin?.focalPoint ?? true}\n />\n )\n }\n\n if (field.type === 'relation' || field.type === 'relationship') {\n return (\n <RelationPicker\n value={value}\n onChange={onChange}\n relationTo={field.relationTo}\n hasMany={field.hasMany}\n disabled={disabled}\n />\n )\n }\n\n if (field.type === 'blocks' || field.type === 'dz') {\n return (\n <BlocksBuilder\n value={value}\n onChange={onChange}\n availableBlocks={field.blocks || []}\n renderField={(f: any, val: any, change: any) => renderField(f, val, change, disabled)}\n disabled={disabled}\n />\n )\n }\n\n if (field.type === 'array') {\n return (\n <SimpleArrayBuilder\n value={value}\n onChange={onChange}\n fields={field.fields || []}\n label={field.label || field.name}\n renderField={(f: any, val: any, change: any) => renderField(f, val, change, disabled)}\n disabled={disabled}\n />\n )\n }\n\n // ── Read-only informational fields ───────────────────────────────────────\n if (field.type === 'join') {\n return <JoinField field={field} />\n }\n\n if (field.type === 'point') {\n return <PointField field={field} value={value} onChange={onChange} disabled={disabled} />\n }\n\n // ── Basic input fields ───────────────────────────────────────────────────\n if (field.type === 'select') {\n return <SelectField field={field} value={value} onChange={onChange} disabled={disabled} />\n }\n\n if (field.type === 'boolean' || field.type === 'checkbox') {\n return <BooleanField field={field} value={value} onChange={onChange} disabled={disabled} />\n }\n\n if (field.type === 'number') {\n return <NumberField field={field} value={value} onChange={onChange} disabled={disabled} />\n }\n\n if (field.type === 'textarea') {\n return <TextareaField field={field} value={value} onChange={onChange} disabled={disabled} />\n }\n\n if (field.type === 'code') {\n return <CodeField field={field} value={value} onChange={onChange} disabled={disabled} />\n }\n\n if (field.type === 'radio') {\n return <RadioField field={field} value={value} onChange={onChange} disabled={disabled} />\n }\n\n if (field.type === 'json') {\n return <JSONField value={value} onChange={onChange} disabled={disabled} />\n }\n\n if (field.type === 'date') {\n return <DateField value={value} onChange={onChange} disabled={disabled} format={field.dateFormat || 'date'} />\n }\n\n if (field.type === 'slug') {\n return (\n <SlugField\n value={value}\n onChange={onChange}\n disabled={disabled}\n sourceField={field.sourceField || 'title'}\n formValues={formValues}\n />\n )\n }\n\n if (field.type === 'uid') {\n return <UIDField value={value} onChange={onChange} disabled={disabled} />\n }\n\n // Default: text, email, password, color\n return <TextField field={field} value={value} onChange={onChange} disabled={disabled} />\n }\n\n const handleFormSubmit = async (formData: any) => {\n if (onSubmit) {\n const merged = deepMerge(initialData || {}, formData)\n await onSubmit(merged)\n }\n }\n\n const renderFormContent = () => (\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-x-8 gap-y-6\">\n {fields.map((field: FieldConfig) => {\n if (field.name === '_status' || field.name === 'id') return null\n\n const condition = field.condition || field.admin?.condition\n if (condition && !evaluateCondition(condition, formValues)) return null\n\n const isFullWidth = ['richtext', 'blocks', 'array', 'code', 'collapsible', 'group', 'tabs', 'json'].includes(field.type)\n const fieldName = getFieldName(field, currentLocale)\n\n // Field Level Security (RBAC)\n let isFieldDisabled = isReadOnly\n if (user?.role !== 'admin') {\n const readAccess = field.admin?.readAccess\n if (readAccess && readAccess.length > 0 && !readAccess.includes(user!.role)) {\n return null // Hide field completely\n }\n const writeAccess = field.admin?.writeAccess\n if (writeAccess && writeAccess.length > 0 && !writeAccess.includes(user!.role)) {\n isFieldDisabled = true\n }\n }\n\n return (\n <div key={field.name} data-field={fieldName} className={`space-y-2 ${isFullWidth ? 'col-span-2' : ''}`}>\n <div className=\"flex items-center justify-between\">\n <label className=\"text-sm font-semibold text-z-secondary flex items-center gap-2\">\n {field.label || field.name.replace(/([A-Z])/g, ' $1')}\n {field.required && <span className=\"text-rose-500\">*</span>}\n {field.localized && (\n <span className=\"px-1.5 py-0.5 text-sm font-semibold text-z-secondary bg-z-panel border border-z-border/20 rounded-none-none\">\n {isFieldDisabled ? readOnlyLocale || currentLocale : currentLocale}\n </span>\n )}\n {isFieldDisabled && !isReadOnly && (\n <Lock size={10} className=\"text-z-secondary ml-1\" />\n )}\n </label>\n {field.admin?.description && (\n <span className=\"text-sm text-z-muted\">{field.admin.description}</span>\n )}\n </div>\n\n {isFieldDisabled ? (\n (() => {\n const staticValue = field.localized\n ? (initialData?.[field.name]?.[readOnlyLocale || currentLocale] ?? '')\n : (initialData?.[field.name] ?? '')\n return renderField(field, staticValue, () => {}, true)\n })()\n ) : (\n <Controller\n name={fieldName}\n control={control}\n render={({ field: { onChange, value } }) => <>{renderField(field, value, onChange)}</>}\n />\n )}\n\n {!isFieldDisabled && !!getFieldError(errors, fieldName) && (\n <p className=\"text-xs text-danger mt-1 font-medium\">\n {(getFieldError(errors, fieldName) as any)?.message || 'Required field'}\n </p>\n )}\n </div>\n )\n })}\n </div>\n )\n\n if (isReadOnly) {\n return <div className=\"space-y-8\">{renderFormContent()}</div>\n }\n\n return (\n <form onSubmit={onSubmit ? handleSubmit(handleFormSubmit) : undefined} className=\"space-y-8\">\n {renderFormContent()}\n\n {/* Submit Button */}\n {!hideSubmitButton && (\n <div className=\"mt-10 pt-6 border-t border-z-border shadow-sm flex items-center justify-between\">\n <p className=\"text-xs text-z-muted\">\n Fields marked with <span className=\"text-danger\">*</span> are required.\n </p>\n <div className=\"flex gap-3\">\n <button\n type=\"submit\"\n disabled={isSubmitting}\n className=\"btn btn-primary min-w-[140px] h-11\"\n >\n {isSubmitting ? (\n <div className=\"flex items-center justify-center gap-2\">\n <Loader2 size={16} className=\"animate-spin\" />\n Saving...\n </div>\n ) : (\n 'Save Changes'\n )}\n </button>\n </div>\n </div>\n )}\n </form>\n )\n}\n\nexport default FormBuilder\n","import React, { useState, useEffect } from 'react'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport { X, Loader2 } from 'lucide-react'\nimport FormBuilder from './FormBuilder'\nimport api from '../lib/api'\nimport toast from 'react-hot-toast'\nimport { useTheme } from '../context/ThemeContext'\nimport { cn } from '../lib/utils'\n\ninterface DocumentEditModalProps {\n isOpen: boolean\n onClose: () => void\n collectionSlug: string\n documentId: string\n onSaved?: (doc: any) => void\n}\n\nconst DocumentEditModal: React.FC<DocumentEditModalProps> = ({ \n isOpen, \n onClose, \n collectionSlug, \n documentId, \n onSaved \n}) => {\n const { theme } = useTheme()\n const [data, setData] = useState<any>(null)\n const [schema, setSchema] = useState<any>(null)\n const [loading, setLoading] = useState(true)\n const [saving, setSaving] = useState(false)\n\n useEffect(() => {\n if (!isOpen || !documentId) return\n\n const fetchDoc = async () => {\n setLoading(true)\n try {\n const healthRes = await api.get('/health')\n const collections = healthRes.data.data?.collections || []\n const colSchema = collections.find((c: any) => c.slug === collectionSlug)\n setSchema(colSchema)\n\n const docRes = await api.get(`/${collectionSlug}/${documentId}`)\n setData(docRes.data.data)\n } catch (err) {\n toast.error('Failed to load document')\n } finally {\n setLoading(false)\n }\n }\n fetchDoc()\n }, [isOpen, documentId, collectionSlug])\n\n const handleSave = async (formData: any) => {\n setSaving(true)\n try {\n const res = await api.patch(`/${collectionSlug}/${documentId}`, formData)\n toast.success('Document updated')\n if (onSaved) onSaved(res.data.data)\n onClose()\n } catch (err) {\n toast.error('Update failed')\n } finally {\n setSaving(false)\n }\n }\n\n if (!isOpen) return null\n\n return (\n <AnimatePresence>\n <div className=\"fixed inset-0 z-[1100] flex items-center justify-center p-4 md:p-8 bg-app/60 backdrop-blur-md\">\n <motion.div\n initial={{ opacity: 0, y: 10, scale: 0.98 }}\n animate={{ opacity: 1, y: 0, scale: 1 }}\n exit={{ opacity: 0, y: 10, scale: 0.98 }}\n className={cn(\n 'w-full max-w-4xl border rounded-none-none overflow-hidden shadow-2xl flex flex-col h-[85vh]',\n theme === 'dark' ? 'bg-app border-z-border' : 'bg-z-panel border-z-border'\n )}\n >\n <div\n className={cn(\n 'p-6 border-b flex items-center justify-between shrink-0',\n theme === 'dark' ? 'border-z-border' : 'border-z-border shadow-sm',\n )}\n >\n <h3\n className={cn(\n 'text-lg font-semibold leading-none',\n theme === 'dark' ? 'text-z-primary' : 'text-z-primary',\n )}\n >\n Edit Record\n </h3>\n <button\n type=\"button\"\n onClick={onClose}\n aria-label=\"Close\"\n className={cn(\n 'p-1 transition-colors',\n theme === 'dark' ? 'text-z-muted hover:text-z-secondary ' : 'text-z-secondary hover:text-z-secondary'\n )}\n >\n <X size={18} />\n </button>\n </div>\n\n <div className=\"flex-1 overflow-y-auto p-8 custom-scrollbar\">\n {loading ? (\n <div className=\"h-full flex items-center justify-center flex-col gap-4\">\n <Loader2 className=\"animate-spin text-z-secondary \" size={32} />\n <span className=\"text-sm font-semibold text-z-secondary\">\n Loading Document...\n </span>\n </div>\n ) : schema && data ? (\n <FormBuilder\n fields={schema.fields}\n initialData={data}\n onSubmit={handleSave}\n isSubmitting={saving}\n />\n ) : (\n <div className=\"h-full flex items-center justify-center text-z-secondary font-semibold text-xs\">\n Failed to load schema or data.\n </div>\n )}\n </div>\n </motion.div>\n </div>\n </AnimatePresence>\n )\n}\n\nexport default DocumentEditModal\n","import React, { useState, useEffect, useRef } from 'react'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport { Link2, Search, X, Check, Loader2, Plus, Minus, Edit3 } from 'lucide-react'\nimport { useTheme } from '../../../context/ThemeContext'\nimport { cn } from '../../../lib/utils'\nimport api from '../../../lib/api'\nimport toast from 'react-hot-toast'\nimport DocumentEditModal from '../../../components/DocumentEditModal'\n\ninterface InlineRelationPickerProps {\n blockId: string\n fieldKey: string\n value: string | string[]\n onChange: (val: string | string[]) => void\n theme: 'light' | 'dark'\n hasMany?: boolean\n relationTo?: string | string[]\n anchorEl?: HTMLElement | null\n}\n\nexport const InlineRelationPicker: React.FC<InlineRelationPickerProps> = ({\n blockId,\n fieldKey,\n value,\n onChange,\n theme,\n hasMany = false,\n relationTo,\n anchorEl,\n}) => {\n const [open, setOpen] = useState(false)\n const [search, setSearch] = useState('')\n const [results, setResults] = useState<any[]>([])\n const [loading, setLoading] = useState(false)\n const [editItemId, setEditItemId] = useState<string | null>(null)\n const [selected, setSelected] = useState<Set<string>>(new Set(\n value ? (Array.isArray(value) ? value : [value]) : []\n ))\n const popoverRef = useRef<HTMLDivElement>(null)\n const searchInputRef = useRef<HTMLInputElement>(null)\n const collection = typeof relationTo === 'string' ? relationTo : (Array.isArray(relationTo) ? relationTo[0] : null)\n\n // Keep local selection in sync with external value changes\n useEffect(() => {\n setSelected(new Set(value ? (Array.isArray(value) ? value : [value]) : []))\n }, [value])\n\n // Close on outside click\n useEffect(() => {\n if (!open) return\n const handle = (e: MouseEvent) => {\n if (popoverRef.current && !popoverRef.current.contains(e.target as Node)) {\n setOpen(false)\n }\n }\n window.addEventListener('mousedown', handle)\n return () => window.removeEventListener('mousedown', handle)\n }, [open])\n\n // Focus search input when opening\n useEffect(() => {\n if (open && searchInputRef.current) {\n searchInputRef.current.focus()\n }\n }, [open])\n\n // Auto-fetch all relation targets on first open\n useEffect(() => {\n if (!open) return\n if (collection) {\n fetchResults(collection, '')\n }\n }, [open, collection])\n\n const fetchResults = async (col: string, q: string) => {\n setLoading(true)\n try {\n const params: any = { limit: 20 }\n if (q) params.search = q\n const res = await api.get(`/${col}`, { params })\n setResults(res.data.data || [])\n } catch {\n setResults([])\n toast.error('Failed to fetch relation entries')\n } finally {\n setLoading(false)\n }\n }\n\n const toggleItem = (itemId: string) => {\n const next = new Set(selected)\n if (next.has(itemId)) {\n next.delete(itemId)\n } else {\n if (!hasMany) {\n next.clear()\n }\n next.add(itemId)\n }\n setSelected(next)\n const newVal = hasMany ? Array.from(next) : (next.size > 0 ? Array.from(next)[0] : null)\n onChange(newVal as string | string[] | null)\n if (!hasMany) setOpen(false)\n }\n\n const handleApply = () => {\n setOpen(false)\n setSearch('')\n }\n\n const handleClear = () => {\n setSelected(new Set())\n onChange(hasMany ? [] : null)\n }\n\n // ── Positioning ──────────────────────────────────────────────────────────────\n const [pos, setPos] = useState({ top: 0, left: 0 })\n\n useEffect(() => {\n if (!open) return\n if (anchorEl) {\n const rect = anchorEl.getBoundingClientRect()\n setPos({\n top: rect.bottom + window.scrollY + 4,\n left: Math.max(8, rect.left + window.scrollX),\n })\n } else {\n // Fallback: use a default centered position\n setPos({ top: 120, left: window.innerWidth / 2 - 160 })\n }\n }, [open, anchorEl])\n\n const selectedCount = selected.size\n const displayLabel = !value || (Array.isArray(value) && value.length === 0)\n ? 'Manage Relations'\n : ` ${Array.isArray(value) ? `${value.length} linked` : '1 linked'}`\n\n return (\n <div className=\"relative\" ref={popoverRef}>\n {/* Trigger button */}\n <button\n type=\"button\"\n onClick={() => setOpen(!open)}\n className={cn(\n 'w-full px-4 py-3 flex items-center justify-between border text-xs font-bold transition-all rounded-none-none',\n theme === 'dark'\n ? 'bg-z-panel/5 border-z-border text-z-secondary hover:bg-z-hover border-z-border-strong'\n : 'bg-z-input border-z-border text-z-secondary hover:bg-[var(--z-bg-hover)]'\n )}\n >\n <span className=\"flex items-center gap-2\">\n <Link2 size={14} />\n {displayLabel}\n </span>\n <span className=\"text-xs opacity-60\">\n {open ? 'Close ▲' : 'Edit ▼'}\n </span>\n </button>\n\n {/* Popover panel */}\n <AnimatePresence>\n {open && (\n <motion.div\n initial={{ opacity: 0, y: -6, scale: 0.98 }}\n animate={{ opacity: 1, y: 0, scale: 1 }}\n exit={{ opacity: 0, y: -6, scale: 0.98 }}\n transition={{ duration: 0.15 }}\n style={{ top: pos.top, left: pos.left }}\n className={cn(\n 'fixed z-[900] w-80 border rounded-none-none shadow-2xl overflow-hidden flex flex-col',\n theme === 'dark'\n ? 'bg-app/98 backdrop-blur-xl border-z-border text-z-primary'\n : 'bg-z-panel/98 backdrop-blur-xl border-z-border text-z-primary'\n )}\n >\n {/* Header */}\n <div className={cn(\n 'px-4 py-3 border-b flex items-center justify-between shrink-0',\n theme === 'dark' ? 'border-z-border' : 'border-z-border shadow-sm'\n )}>\n <span className=\"text-xs font-semibold text-z-secondary\">\n Content Relations\n </span>\n <div className=\"flex items-center gap-1.5\">\n {selectedCount > 0 && (\n <span className=\"text-xs font-semibold text-z-secondary\">\n {selectedCount} selected\n </span>\n )}\n <button\n type=\"button\"\n onClick={handleClear}\n aria-label=\"Clear all selected relations\"\n className={cn(\n 'p-1 transition-colors',\n theme === 'dark' ? 'text-z-secondary hover:text-rose-400' : 'text-z-muted hover:text-rose-500'\n )}\n >\n <X size={11} aria-hidden=\"true\" />\n </button>\n <button\n type=\"button\"\n onClick={() => setOpen(false)}\n aria-label=\"Close relation picker\"\n className={cn(\n 'p-1 transition-colors',\n theme === 'dark' ? 'text-z-secondary hover:text-z-primary' : 'text-z-muted hover:text-z-primary'\n )}\n >\n <X size={12} aria-hidden=\"true\" />\n </button>\n </div>\n </div>\n\n {!collection ? (\n <div className=\"p-6 text-center\">\n <p className=\"text-xs font-semibold text-z-secondary mb-1\">No collection configured</p>\n <p className=\"text-xs text-z-secondary\">Set <code className=\"text-xs\">relationTo</code> on the field to enable inline relation picker.</p>\n </div>\n ) : (\n <>\n {/* Search */}\n <div className=\"shrink-0 px-3 pt-3 pb-2\">\n <div className=\"relative\">\n <Search size={11} className=\"absolute left-3 top-1/2 -translate-y-1/2 text-z-secondary\" />\n <input\n ref={searchInputRef}\n type=\"text\"\n placeholder=\"Search to link...\"\n value={search}\n onChange={(e) => {\n setSearch(e.target.value)\n fetchResults(collection, e.target.value)\n }}\n className={cn(\n 'w-full rounded-none-none py-2 pl-9 pr-3 text-xs font-bold border transition-all',\n theme === 'dark'\n ? 'bg-z-hover border-z-border text-z-primary placeholder:text-z-muted'\n : 'bg-z-input border-z-border text-z-primary placeholder:text-z-muted'\n )}\n />\n </div>\n </div>\n\n {/* Results */}\n <div className=\"flex-1 overflow-y-auto max-h-56 custom-editor-scrollbar px-2 pb-2 space-y-0.5\">\n {loading ? (\n <div className=\"flex items-center justify-center py-8 gap-2\">\n <Loader2 size={14} className=\"animate-spin text-z-secondary \" />\n <span className=\"text-xs font-bold text-z-secondary animate-pulse\">Searching...</span>\n </div>\n ) : results.length === 0 ? (\n <div className=\"py-8 text-center\">\n <p className=\"text-xs font-semibold text-z-secondary\">No results found</p>\n <p className=\"text-xs text-z-secondary mt-1\">Try a different search term</p>\n </div>\n ) : (\n results.map((item) => {\n const id = item._id || item.id\n const title = item.title || item.name || item.headline || id\n const isSelected = selected.has(id)\n\n return (\n <button\n key={id}\n type=\"button\"\n onClick={() => toggleItem(id)}\n className={cn(\n 'w-full flex items-center gap-2.5 px-3 py-2 rounded-none-none text-left text-xs font-semibold transition-all border',\n isSelected\n ? theme === 'dark'\n ? 'bg-z-border/15 border-z-border/20 text-z-secondary'\n : 'bg-z-input border-z-border text-z-primary'\n : theme === 'dark'\n ? 'border-z-border text-z-secondary hover:bg-z-hover hover:border-z-border'\n : 'border-transparent text-z-primary hover:bg-[var(--z-bg-input)] hover:border-z-border shadow-sm'\n )}\n >\n {/* Selection indicator */}\n <div className={cn(\n 'w-4 h-4 rounded-none-none border flex items-center justify-center shrink-0 transition-all',\n isSelected\n ? 'bg-z-border border-z-border text-z-primary'\n : theme === 'dark'\n ? 'border-z-border bg-z-hover'\n : 'border-z-border-strong bg-z-panel'\n )}>\n {isSelected && <Check size={9} />}\n </div>\n\n {/* Item title */}\n <div className=\"flex-1 min-w-0\">\n <p className=\"truncate font-semibold\">\n {String(title)}\n </p>\n {item._status && (\n <span className={cn(\n 'text-sm font-bold ',\n item._status === 'published'\n ? 'text-z-secondary '\n : 'text-amber-500'\n )}>\n {item._status}\n </span>\n )}\n </div>\n\n {/* +/- for hasMany */}\n {hasMany && isSelected && (\n <div className=\"shrink-0 ml-1\">\n <Minus size={10} className=\"text-z-secondary\" />\n </div>\n )}\n \n {/* Edit button */}\n {isSelected && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n setEditItemId(id)\n }}\n className={cn(\n 'shrink-0 p-1.5 ml-2 transition-colors border',\n theme === 'dark'\n ? 'border-z-border hover:bg-[var(--z-bg-hover)] text-z-primary'\n : 'border-z-border hover:bg-[var(--z-bg-hover)] text-z-primary'\n )}\n title=\"Edit Document\"\n >\n <Edit3 size={10} />\n </button>\n )}\n </button>\n )\n })\n )}\n </div>\n\n {/* Footer */}\n <div className={cn(\n 'px-3 py-2.5 border-t flex items-center gap-2 shrink-0',\n theme === 'dark' ? 'border-z-border' : 'border-z-border shadow-sm'\n )}>\n <button\n type=\"button\"\n onClick={handleClear}\n className={cn(\n 'flex-1 py-1.5 text-xs font-semibold border rounded-none-none transition-all',\n theme === 'dark'\n ? 'border-z-border text-z-secondary hover:border-rose-500/20 hover:text-rose-400'\n : 'border-z-border text-z-muted hover:border-rose-200 hover:text-rose-500'\n )}\n >\n Clear\n </button>\n <button\n type=\"button\"\n onClick={handleApply}\n className={cn(\n 'flex-1 py-1.5 text-xs font-semibold rounded-none-none transition-all bg-z-accent text-z-primary hover:bg-z-border'\n )}\n >\n Done\n </button>\n </div>\n </>\n )}\n </motion.div>\n )}\n </AnimatePresence>\n\n {collection && (\n <DocumentEditModal\n isOpen={!!editItemId}\n onClose={() => setEditItemId(null)}\n collectionSlug={collection}\n documentId={editItemId || ''}\n onSaved={() => {\n fetchResults(collection, search)\n }}\n />\n )}\n </div>\n )\n}\n\nexport default InlineRelationPicker\n","import React, { useState, useCallback } from 'react'\nimport { motion, AnimatePresence, Reorder, useDragControls } from 'framer-motion'\nimport { Layers, ChevronDown, ChevronUp, Plus, Trash2, GripVertical, Layout } from 'lucide-react'\nimport { useEditorBlocks } from '../../../context/BlockLibraryContext'\nimport { useModalStore } from '../../../store/modalStore'\nimport { humanize, type FieldDefinition } from '../constants'\nimport { FieldRenderer } from '../FieldRenderer'\nimport { cn } from '../../../lib/utils'\nimport { useShallow } from 'zustand/react/shallow'\n\ninterface NestedDynamicZoneProps {\n blockId: string\n fieldName: string\n value: any[]\n onChange: (items: any[]) => void\n theme: 'light' | 'dark'\n components?: string[]\n onOpenDynamicZone?: (componentType: string) => void\n}\n\nconst DraggableZoneItem = ({ \n item, idx, theme, dzId, isExpanded, toggleExpand, removeItem, def, blockId, fieldName, updateItem \n}: any) => {\n const dragControls = useDragControls()\n const componentLabel = def?.title || humanize((item.__component || '').replace(/^content\\./, ''))\n const BlockIcon = def?.icon || Layout\n\n return (\n <Reorder.Item\n value={item}\n dragListener={false}\n dragControls={dragControls}\n initial={{ opacity: 0, height: 0 }}\n animate={{ opacity: 1, height: 'auto' }}\n exit={{ opacity: 0, height: 0 }}\n transition={{ duration: 0.15 }}\n as=\"div\"\n className={cn(\n 'border rounded-none-none overflow-hidden',\n theme === 'dark' ? 'bg-z-panel border-z-border' : 'bg-z-input border-z-border'\n )}\n >\n <div\n className={cn(\n 'flex items-center gap-2 px-3 py-2.5 cursor-pointer select-none',\n theme === 'dark' ? 'bg-z-panel hover:bg-z-hover' : 'bg-[var(--z-bg-hover)]/50 hover:bg-[var(--z-bg-hover)]'\n )}\n onClick={() => toggleExpand(dzId)}\n >\n <div \n onPointerDown={(e) => dragControls.start(e)}\n className=\"shrink-0 cursor-grab active:cursor-grabbing p-1\"\n onClick={(e) => e.stopPropagation()}\n >\n <GripVertical size={12} className=\"text-z-secondary\" />\n </div>\n <div className={cn(\n 'w-5 h-5 rounded-none-none flex items-center justify-center shrink-0',\n theme === 'dark' ? 'bg-z-panel/5' : 'bg-[var(--z-bg-input)]'\n )}>\n <BlockIcon size={10} className=\"text-z-secondary\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-xs font-semibold text-z-secondary truncate\">\n {componentLabel}\n </p>\n </div>\n <span className={cn('text-sm font-semibold shrink-0', 'text-z-secondary')}>\n #{idx + 1}\n </span>\n <div className=\"flex items-center gap-0.5 shrink-0\" onClick={(e) => e.stopPropagation()}>\n <button\n onClick={() => removeItem(dzId)}\n className=\"p-1 text-z-secondary hover:text-rose-500 transition-colors\"\n >\n <Trash2 size={12} />\n </button>\n <button\n onClick={() => toggleExpand(dzId)}\n className=\"p-1 text-z-secondary hover:text-z-secondary transition-colors\"\n >\n {isExpanded ? <ChevronUp size={12} className=\"text-z-secondary\" /> : <ChevronDown size={12} className=\"text-z-muted\" />}\n </button>\n </div>\n </div>\n <AnimatePresence initial={false}>\n {isExpanded && def && (\n <motion.div\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: 'auto', opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n transition={{ duration: 0.15 }}\n className=\"overflow-hidden\"\n >\n <div className={cn('px-4 py-4 space-y-4 border-t', 'border-z-border')}>\n {def.fields.map((field: any) => (\n <div key={field.name} className=\"space-y-1\">\n <label className=\"text-xs font-semibold text-z-muted block\">\n {field.label || humanize(field.name)}\n </label>\n <FieldRenderer\n blockId={`${blockId}:${fieldName}:${dzId}`}\n field={field}\n value={item[field.name]}\n onChange={(val) => updateItem(dzId, field.name, val)}\n theme={theme}\n />\n </div>\n ))}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </Reorder.Item>\n )\n}\n\n\nexport const NestedDynamicZone: React.FC<NestedDynamicZoneProps> = ({\n blockId,\n fieldName,\n value = [],\n onChange,\n theme,\n components,\n}) => {\n const BLOCK_LIBRARY = useEditorBlocks()\n const { openComponentPicker } = useModalStore(useShallow(state => ({ openComponentPicker: state.openComponentPicker })))\n const [expandedIds, setExpandedIds] = useState<Set<string>>(new Set())\n\n const componentTypeLabel = (type: string) =>\n humanize(type.replace(/^content\\./, ''))\n\n const getBlockDefForItem = (item: any): import('../constants').BlockDefinition | undefined => {\n const compType = item?.__component as string | undefined\n if (!compType) return undefined\n return BLOCK_LIBRARY.find((b) => b.type === compType || b.type === compType.replace('content.', ''))\n }\n\n const toggleExpand = (id: string) => {\n setExpandedIds((prev) => {\n const next = new Set(prev)\n if (next.has(id)) next.delete(id)\n else next.add(id)\n return next\n })\n }\n\n const addItem = useCallback((type: string) => {\n const def = BLOCK_LIBRARY.find((b) => b.type === type)\n const newItem: any = {\n __component: `content.${type}`,\n ...(def?.defaultContent ? JSON.parse(JSON.stringify(def.defaultContent)) : {}),\n }\n const id = `dz_${Date.now()}_${Math.random().toString(36).slice(2)}`\n newItem._dzId = id\n const items = [...value, newItem]\n onChange(items)\n setExpandedIds((prev) => new Set([...prev, id]))\n }, [BLOCK_LIBRARY, value, onChange])\n\n const handleOpenPicker = useCallback(() => {\n openComponentPicker((blockType) => addItem(blockType))\n }, [openComponentPicker, addItem])\n\n const removeItem = (dzId: string) => {\n onChange(value.filter((item) => item._dzId !== dzId))\n }\n\n const updateItem = (dzId: string, key: string, val: any) => {\n onChange(\n value.map((item) =>\n item._dzId === dzId ? { ...item, [key]: val } : item\n )\n )\n }\n\n const handleReorder = (newItems: any[]) => {\n onChange(newItems)\n }\n\n const availableComponents = components && components.length > 0\n ? BLOCK_LIBRARY.filter((b) => components.includes(b.type))\n : BLOCK_LIBRARY\n\n return (\n <div className=\"space-y-3\">\n {/* Zone label */}\n <div className=\"flex items-center gap-2 px-1\">\n <Layers size={10} className=\"text-z-secondary\" />\n <span className=\"text-xs font-semibold text-z-secondary\">\n Dynamic Zone\n </span>\n <span className=\"text-xs text-z-secondary\">— {value.length} component{value.length !== 1 ? 's' : ''}</span>\n </div>\n\n {/* Items with drag-and-drop reorder */}\n {value.length === 0 ? (\n <div className={cn(\n 'py-5 text-center border border-dashed rounded-none-none',\n 'border-z-border text-z-secondary'\n )}>\n <p className=\"text-xs font-bold\">No components — add one below</p>\n </div>\n ) : (\n <Reorder.Group axis=\"y\" values={value} onReorder={handleReorder} className=\"space-y-2\">\n <AnimatePresence initial={false}>\n {value.map((item, idx) => {\n const dzId = item._dzId || `dz_${idx}`\n const isExpanded = expandedIds.has(dzId)\n const def = getBlockDefForItem(item)\n return (\n <DraggableZoneItem\n key={dzId}\n item={item}\n idx={idx}\n theme={theme}\n dzId={dzId}\n isExpanded={isExpanded}\n toggleExpand={toggleExpand}\n removeItem={removeItem}\n def={def}\n blockId={blockId}\n fieldName={fieldName}\n updateItem={updateItem}\n />\n )\n })}\n </AnimatePresence>\n </Reorder.Group>\n )}\n\n {/* Add Component — opens global picker modal */}\n <button\n type=\"button\"\n onClick={handleOpenPicker}\n className={cn(\n 'w-full flex items-center justify-center gap-2 py-2.5 border border-dashed rounded-none-none transition-all text-xs font-semibold ',\n theme === 'dark'\n ? 'border-z-border text-z-secondary hover:border-z-border/40 hover:text-z-secondary hover:bg-z-hover'\n : 'border-z-border text-z-muted hover:border-z-border hover:text-z-secondary hover:bg-[var(--z-bg-input)]/50'\n )}\n >\n <Plus size={12} />\n Add Component\n {availableComponents.length > 0 && (\n <span className={cn('text-sm font-semibold ml-1', 'text-z-secondary')}>\n ({availableComponents.length} available)\n </span>\n )}\n </button>\n </div>\n )\n}\n\nexport default NestedDynamicZone\n","import React from 'react'\nimport type { FieldDefinition } from './constants'\n\n/**\n * Props passed to every registered field component.\n */\nexport interface FieldRendererComponentProps {\n blockId: string\n field: FieldDefinition\n value: any\n onChange: (value: any) => void\n onFieldSelect?: (blockId: string, fieldKey: string) => void\n theme: 'light' | 'dark'\n error?: string\n isSelected?: boolean\n}\n\n/**\n * Registry mapping field type strings to their rendering component.\n *\n * To add a custom field type without editing `FieldRenderer.tsx`:\n *\n * ```ts\n * import { registerField } from './fieldRegistry'\n * import MyCustomField from './MyCustomField'\n *\n * registerField('myCustomType', MyCustomField)\n * ```\n */\nconst registry = new Map<string, React.ComponentType<FieldRendererComponentProps>>()\n\nexport function registerField(type: string, component: React.ComponentType<FieldRendererComponentProps>): void {\n if (registry.has(type)) {\n if (import.meta.env.DEV) {\n console.warn(`[Zenith] Field type \"${type}\" is being overridden in the registry.`)\n }\n }\n registry.set(type, component)\n}\n\nexport function getFieldComponent(type: string): React.ComponentType<FieldRendererComponentProps> | undefined {\n return registry.get(type)\n}\n\nexport function hasFieldComponent(type: string): boolean {\n return registry.has(type)\n}\n\n/**\n * Register a batch of field components from a map object.\n */\nexport function registerFieldMap(\n map: Record<string, React.ComponentType<FieldRendererComponentProps>>\n): void {\n for (const [type, component] of Object.entries(map)) {\n registerField(type, component)\n }\n}\n\nexport { registry as fieldRegistry }\n","/* eslint-disable */\nimport React, { useState } from 'react'\nimport { Plus, Trash2, Settings2, HelpCircle, GripVertical } from 'lucide-react'\nimport { Reorder, useDragControls } from 'framer-motion'\n\nimport MediaPicker from '../../components/MediaPicker'\nimport { InlineRelationPicker } from './components/InlineRelationPicker'\nimport { NestedDynamicZone } from './components/NestedDynamicZone'\nimport { humanize, type FieldDefinition } from './constants'\nimport { getFieldComponent } from './fieldRegistry'\nimport { useEditorStore } from '../../store/editorStore'\nimport { useModalStore } from '../../store/modalStore'\nimport { cn, uid } from '../../lib/utils'\nimport { useShallow } from 'zustand/react/shallow'\n\ninterface FieldRendererProps {\n blockId: string\n field: FieldDefinition\n value: any\n onChange: (value: any) => void\n onFieldSelect?: (blockId: string, fieldKey: string) => void\n theme: 'light' | 'dark'\n error?: string\n}\n\n// ── Date helper utilities ───────────────────────────────────────────────────\nfunction formatDateForInput(value: string, format: 'date' | 'datetime' | 'time'): string {\n if (!value) return ''\n try {\n const d = new Date(value)\n if (isNaN(d.getTime())) return value\n if (format === 'datetime') {\n // datetime-local expects YYYY-MM-DDTHH:MM\n return d.toISOString().slice(0, 16)\n }\n if (format === 'time') {\n return d.toISOString().slice(11, 16)\n }\n return d.toISOString().slice(0, 10)\n } catch {\n return value\n }\n}\n\nfunction parseInputDate(value: string, format: 'date' | 'datetime' | 'time'): string {\n if (!value) return ''\n // For date and datetime, store ISO string; for time, store HH:MM\n if (format === 'time') return value\n try {\n return new Date(value).toISOString()\n } catch {\n return value\n }\n}\n\n/** Returns true if valid JSON, false if invalid, null if empty/undefined */\nfunction tryParseJson(value: any): boolean | null {\n if (value === undefined || value === null || value === '') return null\n const str = typeof value === 'string' ? value : JSON.stringify(value)\n try {\n JSON.parse(str)\n return true\n } catch {\n return false\n }\n}\n\nconst ReorderableArrayItem = React.memo(({ item, idx, theme, onRemove, onChange, field, blockId }: any) => {\n const dragControls = useDragControls()\n return (\n <Reorder.Item key={item._id || idx} value={item._id || idx} dragListener={false} dragControls={dragControls} as=\"div\">\n <div\n className={cn(\n 'p-3 border rounded-none-none relative transition-all group/item',\n theme === 'dark'\n ? 'bg-z-panel/5 border-z-border hover:border-z-border'\n : 'bg-[var(--z-bg-input)] border-z-border hover:border-z-border-strong shadow-sm'\n )}\n >\n <div className=\"flex items-center gap-2 mb-2\">\n <div onPointerDown={(e) => dragControls.start(e)} className=\"cursor-grab\">\n <GripVertical size={12} className={cn('opacity-30', 'text-z-secondary')} />\n </div>\n <span className={cn('text-sm font-semibold ', 'text-z-secondary')}>\n #{idx + 1}\n </span>\n <button\n type=\"button\"\n onClick={() => onRemove(idx)}\n aria-label=\"Remove item\"\n className={cn(\n 'ml-auto p-1 transition-colors',\n 'opacity-0 group-hover/item:opacity-100',\n theme === 'dark' ? 'text-red-500/50 hover:text-red-400' : 'text-red-400/50 hover:text-red-600'\n )}\n >\n <Trash2 size={12} />\n </button>\n </div>\n <div className=\"space-y-3\">\n {field.fields?.map((subField: any) => (\n <div key={subField.name} className=\"space-y-1\">\n <label className=\"text-xs font-semibold text-z-muted block\">\n {humanize(subField.name)}\n </label>\n <FieldRenderer\n blockId={`${blockId}-array-${idx}`}\n field={subField}\n value={item[subField.name]}\n onChange={(newVal) => onChange(subField.name, newVal)}\n theme={theme}\n />\n </div>\n ))}\n </div>\n </div>\n </Reorder.Item>\n )\n})\n\nexport const FieldRenderer = React.memo(({\n blockId,\n field,\n value,\n onChange,\n onFieldSelect,\n theme,\n error,\n isSelected: isSelectedProp,\n}: FieldRendererProps & { isSelected?: boolean }) => {\n const { selectedFieldId, setSelectedFieldId, setSelectedField, data } = useEditorStore(useShallow(state => ({ selectedFieldId: state.selectedFieldId, setSelectedFieldId: state.setSelectedFieldId, setSelectedField: state.setSelectedField, data: state.data })))\n const { openComponentPicker, showFieldIndicators } = useModalStore(useShallow(state => ({ openComponentPicker: state.openComponentPicker, showFieldIndicators: state.showFieldIndicators })))\n const isSelected = !!isSelectedProp || selectedFieldId === `${blockId}:${field.name}`\n\n // Conditional Fields Evaluation\n if (field.admin?.condition) {\n const cond = field.admin.condition\n const targetValue = data?.[cond.field]\n let isMatch = false\n \n switch (cond.operator) {\n case 'equals': isMatch = targetValue === cond.value; break;\n case 'not_equals': isMatch = targetValue !== cond.value; break;\n case 'in': isMatch = Array.isArray(cond.value) && cond.value.includes(targetValue); break;\n case 'not_in': isMatch = Array.isArray(cond.value) && !cond.value.includes(targetValue); break;\n case 'contains': isMatch = typeof targetValue === 'string' && targetValue.includes(cond.value); break;\n case 'exists': isMatch = cond.value ? (targetValue !== undefined && targetValue !== null && targetValue !== '') : (targetValue === undefined || targetValue === null || targetValue === ''); break;\n }\n \n if (!isMatch) return null;\n }\n\n // Handle Array manipulation\n const handleAddArrayItem = () => {\n const list = Array.isArray(value) ? [...value] : []\n const newItem: any = { _id: uid() }\n field.fields?.forEach((subField) => {\n newItem[subField.name] = subField.type === 'array' ? [] : ''\n })\n list.push(newItem)\n onChange(list)\n }\n\n const handleRemoveArrayItem = (index: number) => {\n if (!Array.isArray(value)) return\n const list = value.filter((_, idx) => idx !== index)\n onChange(list)\n }\n\n const handleUpdateArrayItem = (index: number, subFieldName: string, subValue: any) => {\n if (!Array.isArray(value)) return\n const list = [...value]\n list[index] = {\n ...list[index],\n [subFieldName]: subValue,\n }\n onChange(list)\n }\n\n const renderInnerField = () => {\n // Check the pluggable registry first — allows external code to add or\n // override field types without editing this file.\n const RegisteredComponent = getFieldComponent(field.type)\n if (RegisteredComponent) {\n return (\n <RegisteredComponent\n blockId={blockId}\n field={field}\n value={value}\n onChange={onChange}\n onFieldSelect={onFieldSelect}\n theme={theme}\n error={error}\n isSelected={isSelected}\n />\n )\n }\n switch (field.type) {\n case 'media':\n return (\n <MediaPicker\n value={value}\n onChange={onChange}\n hasMany={field.hasMany}\n />\n )\n\n case 'richtext':\n case 'lexical':\n return (\n <textarea\n value={value || ''}\n onChange={(e) => onChange(e.target.value)}\n placeholder={field.placeholder || `Enter ${field.name}...`}\n className={cn(\n \"w-full px-4 py-3 text-sm transition-all rounded-none-none min-h-[120px] resize-y\",\n theme === 'dark'\n ? \"bg-z-base/65 backdrop-blur-md border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-accent/50 text-z-primary\"\n : \"bg-z-panel border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-border text-z-primary\"\n )}\n />\n )\n\n case 'email':\n return (\n <input\n type=\"email\"\n value={value || ''}\n onChange={(e) => onChange(e.target.value)}\n placeholder={field.placeholder || 'Enter email address...'}\n autoComplete=\"email\"\n className={cn(\n \"w-full px-4 py-2.5 text-xs transition-all rounded-none-none\",\n theme === 'dark'\n ? \"bg-z-base/65 backdrop-blur-md border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-accent/50 text-z-primary\"\n : \"bg-z-panel border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-border text-z-primary\"\n )}\n />\n )\n\n case 'password':\n return (\n <input\n type=\"password\"\n value={value || ''}\n onChange={(e) => onChange(e.target.value)}\n placeholder={field.placeholder || 'Enter password...'}\n autoComplete=\"new-password\"\n className={cn(\n \"w-full px-4 py-2.5 text-xs transition-all rounded-none-none\",\n theme === 'dark'\n ? \"bg-z-base/65 backdrop-blur-md border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-accent/50 text-z-primary\"\n : \"bg-z-panel border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-border text-z-primary\"\n )}\n />\n )\n\n case 'uid': {\n const [isAuto, setIsAuto] = React.useState(!value)\n const sourceField = field.sourceField || 'title'\n return (\n <div className=\"space-y-1.5\">\n <div className=\"flex items-center gap-2\">\n <input\n type=\"text\"\n value={value || ''}\n onChange={(e) => { onChange(e.target.value); setIsAuto(false) }}\n placeholder={field.placeholder || `Auto-generated from ${sourceField}...`}\n className={cn(\n \"flex-1 px-4 py-2.5 text-xs transition-all rounded-none-none font-mono\",\n theme === 'dark'\n ? \"bg-z-base/65 backdrop-blur-md border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-accent/50 text-z-primary\"\n : \"bg-z-panel border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-border text-z-primary\"\n )}\n />\n <button\n type=\"button\"\n onClick={() => setIsAuto(!isAuto)}\n className={cn(\n 'px-2.5 py-2.5 text-sm font-semibold border rounded-none-none transition-all shrink-0',\n isAuto\n ? 'bg-z-panel border-z-border/30 text-z-secondary'\n : theme === 'dark'\n ? 'border-z-border text-z-secondary hover:text-z-secondary'\n : 'border-z-border text-z-muted hover:text-z-secondary'\n )}\n title={isAuto ? 'Auto-generation enabled' : 'Enable auto-generation'}\n >\n {isAuto ? ' Auto' : 'Manual'}\n </button>\n </div>\n {isAuto && (\n <p className={cn('text-sm font-bold px-1', 'text-z-secondary')}>\n Will be auto-generated from the \"{sourceField}\" field\n </p>\n )}\n </div>\n )\n }\n\n case 'color': {\n const presetColors = field.options || ['#000000', '#ffffff', '#ef4444', '#f59e0b', 'var(--z-accent)', '#3b82f6', 'var(--z-accent)', 'var(--z-accent)', '#ec4899']\n return (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-2\">\n <div className=\"relative\">\n <input\n type=\"color\"\n value={value || '#000000'}\n onChange={(e) => onChange(e.target.value)}\n className=\"w-10 h-10 rounded-none-none border cursor-pointer p-0.5\"\n style={{ background: 'transparent' }}\n />\n </div>\n <input\n type=\"text\"\n value={value || ''}\n onChange={(e) => onChange(e.target.value)}\n placeholder=\"#000000\"\n className={cn(\n \"flex-1 px-4 py-2.5 text-xs font-mono transition-all rounded-none-none \",\n theme === 'dark'\n ? \"bg-z-base/65 backdrop-blur-md border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-accent/50 text-z-primary\"\n : \"bg-z-panel border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-border text-z-primary\"\n )}\n />\n </div>\n {presetColors.length > 0 && (\n <div className=\"flex flex-wrap gap-1.5\">\n {presetColors.map((color: any) => {\n const colorVal = typeof color === 'string' ? color : color.value\n const colorLabel = typeof color === 'string' ? color : color.label\n return (\n <button\n key={colorVal}\n type=\"button\"\n onClick={() => onChange(colorVal)}\n className={cn(\n 'w-6 h-6 rounded-none-none border-2 transition-all',\n value === colorVal\n ? 'border-z-border scale-110'\n : theme === 'dark' ? 'border-z-border hover:border-z-border' : 'border-z-border hover:border-z-border'\n )}\n style={{ backgroundColor: colorVal }}\n title={colorLabel}\n />\n )\n })}\n </div>\n )}\n </div>\n )\n }\n\n case 'text':\n return (\n <input\n type=\"text\"\n value={value || ''}\n onChange={(e) => onChange(e.target.value)}\n placeholder={field.placeholder || `Enter ${humanize(field.name)}...`}\n className={cn(\n \"w-full px-4 py-2.5 text-xs transition-all rounded-none-none\",\n theme === 'dark'\n ? \"bg-z-base/65 backdrop-blur-md border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-accent/50 text-z-primary\"\n : \"bg-z-panel border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-border text-z-primary\"\n )}\n />\n )\n\n case 'textarea':\n return (\n <textarea\n value={value || ''}\n onChange={(e) => onChange(e.target.value)}\n placeholder={field.placeholder || `Enter ${humanize(field.name)}...`}\n rows={4}\n className={cn(\n \"w-full px-4 py-2.5 text-xs transition-all rounded-none-none resize-y\",\n theme === 'dark'\n ? \"bg-z-base/65 backdrop-blur-md border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-accent/50 text-z-primary\"\n : \"bg-z-panel border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-border text-z-primary\"\n )}\n />\n )\n\n case 'code':\n return (\n <textarea\n value={value || ''}\n onChange={(e) => onChange(e.target.value)}\n placeholder={field.placeholder || `Enter ${field.language || 'code'}...`}\n rows={8}\n spellCheck={false}\n className={cn(\n \"w-full px-4 py-2.5 text-xs font-mono transition-all rounded-none-none resize-y\",\n theme === 'dark'\n ? \"bg-z-base/65 backdrop-blur-md border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-accent/50 text-[#e6edf3]\"\n : \"bg-z-accent border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-border text-z-primary\"\n )}\n />\n )\n\n case 'collapsible': {\n const collapsibleFields = field.fields || []\n const collapsibleVal = value && typeof value === 'object' ? value : {}\n return (\n <div className={cn(\n \"border-l-2 pl-3 space-y-2\",\n theme === 'dark' ? \"border-z-border/30\" : \"border-z-border-strong\"\n )}>\n {collapsibleFields.map((subField) => (\n <div key={subField.name} className=\"space-y-1\">\n <label className=\"text-xs font-semibold text-z-muted block\">\n {humanize(subField.name)}\n </label>\n <FieldRenderer\n blockId={`${blockId}:${field.name}`}\n field={subField}\n value={collapsibleVal[subField.name]}\n onChange={(val) => onChange({ ...collapsibleVal, [subField.name]: val })}\n theme={theme}\n />\n </div>\n ))}\n </div>\n )\n }\n\n case 'join':\n return (\n <div className={cn(\n \"w-full px-4 py-3 border text-xs rounded-none-none\",\n theme === 'dark'\n ? \"bg-z-hover border-z-border/20 text-z-secondary\"\n : \"bg-z-input border-z-border text-z-secondary\"\n )}>\n ⧉ Joined data — read-only\n </div>\n )\n\n case 'point': {\n const coords = (Array.isArray(value) && value.length === 2 && !isNaN(value[0]) && !isNaN(value[1])\n ? value\n : [0, 0]) as [number, number]\n return (\n <div className=\"flex gap-2\">\n <div className=\"flex-1 space-y-1\">\n <label className=\"text-xs font-semibold text-z-secondary\">Lng</label>\n <input\n type=\"number\"\n value={coords[0]}\n onChange={(e) => onChange([Number(e.target.value), coords[1]])}\n step=\"any\"\n className={cn(\n \"w-full px-3 py-2 text-xs transition-all rounded-none-none\",\n theme === 'dark'\n ? \"bg-z-base/65 backdrop-blur-md border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-accent/50 text-z-primary\"\n : \"bg-z-panel border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-border text-z-primary\"\n )}\n />\n </div>\n <div className=\"flex-1 space-y-1\">\n <label className=\"text-xs font-semibold text-z-secondary\">Lat</label>\n <input\n type=\"number\"\n value={coords[1]}\n onChange={(e) => onChange([coords[0], Number(e.target.value)])}\n step=\"any\"\n className={cn(\n \"w-full px-3 py-2 text-xs transition-all rounded-none-none\",\n theme === 'dark'\n ? \"bg-z-base/65 backdrop-blur-md border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-accent/50 text-z-primary\"\n : \"bg-z-panel border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-border text-z-primary\"\n )}\n />\n </div>\n </div>\n )\n }\n\n case 'radio': {\n const options = field.options || []\n const isHorizontal = field.layout === 'horizontal'\n return (\n <div className={cn(\"flex gap-3\", isHorizontal ? \"flex-row flex-wrap\" : \"flex-col gap-1.5\")}>\n {options.map((opt: string | { label: string; value: any }) => {\n const optVal = typeof opt === 'string' ? opt : opt.value\n const optLabel = typeof opt === 'string' ? opt : opt.label\n return (\n <label key={optVal} className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"radio\"\n name={`${blockId}:${field.name}`}\n value={optVal}\n checked={value == optVal}\n onChange={(e) => {\n // Preserve numeric type when option value is a number\n const nextVal = typeof optVal === 'number' ? Number(e.target.value) : e.target.value\n onChange(nextVal)\n }}\n className=\"w-3.5 h-3.5 accent-gray-500\"\n />\n <span className={cn(\n \"text-xs\",\n theme === 'dark' ? \"text-z-secondary\" : \"text-z-primary\"\n )}>\n {optLabel}\n </span>\n </label>\n )\n })}\n </div>\n )\n }\n\n case 'row': {\n const rowFields = field.fields || []\n const rowVal = value && typeof value === 'object' ? value : {}\n return (\n <div className=\"flex gap-2 items-end\">\n {rowFields.map((subField) => (\n <div key={subField.name} className=\"flex-1 space-y-1\">\n <label className=\"text-xs font-semibold text-z-muted block\">\n {humanize(subField.name)}\n </label>\n <FieldRenderer\n blockId={`${blockId}:${field.name}`}\n field={subField}\n value={rowVal[subField.name]}\n onChange={(val) => onChange({ ...rowVal, [subField.name]: val })}\n theme={theme}\n />\n </div>\n ))}\n </div>\n )\n }\n\n case 'ui': {\n const CustomComponent = field.admin?.components?.Field\n if (CustomComponent) {\n return <CustomComponent field={field} value={value} onChange={onChange} />\n }\n return null\n }\n\n case 'number':\n return (\n <input\n type=\"number\"\n value={value ?? ''}\n onChange={(e) => {\n const val = e.target.value === '' ? '' : Number(e.target.value)\n onChange(val)\n }}\n placeholder={field.placeholder || `Enter ${humanize(field.name)}...`}\n className={cn(\n \"w-full px-4 py-2.5 text-xs transition-all rounded-none-none\",\n theme === 'dark'\n ? \"bg-z-base/65 backdrop-blur-md border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-accent/50 text-z-primary\"\n : \"bg-z-panel border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-border text-z-primary\"\n )}\n />\n )\n\n case 'boolean':\n case 'checkbox':\n return (\n <label className=\"flex items-center gap-3 cursor-pointer py-2\">\n <input\n type=\"checkbox\"\n checked={!!value}\n onChange={(e) => onChange(e.target.checked)}\n className=\"w-4 h-4 rounded-none-none border border-z-border bg-z-hover checked:bg-[var(--z-bg-input)] checked:border-z-border transition-all accent-gray-500\"\n />\n <span className={cn(\n \"text-xs font-medium\",\n theme === 'dark' ? \"text-z-secondary\" : \"text-z-primary\"\n )}>\n {humanize(field.name)}\n </span>\n </label>\n )\n\n case 'select': {\n const options = field.options || []\n const hasMany = !!field.hasMany\n const [dropdownOpen, setDropdownOpen] = React.useState(false)\n const dropdownRef = React.useRef<HTMLDivElement>(null)\n const selectedValues = hasMany\n ? (Array.isArray(value) ? value : [])\n : (value != null && value !== '' ? [value] : [])\n\n const getLabel = (opt: string | { label: string; value: any }) =>\n typeof opt === 'string' ? opt : opt.label\n const getVal = (opt: string | { label: string; value: any }) =>\n typeof opt === 'string' ? opt : opt.value\n const selectedLabels = selectedValues\n .map((v) => getLabel(options.find((o) => getVal(o) === v)) || String(v))\n .join(', ')\n\n const toggleOption = (optVal: any) => {\n if (hasMany) {\n const current = Array.isArray(value) ? [...value] : []\n const idx = current.indexOf(optVal)\n if (idx >= 0) current.splice(idx, 1); else current.push(optVal)\n onChange(current)\n } else {\n onChange(optVal)\n setDropdownOpen(false)\n }\n }\n\n React.useEffect(() => {\n if (!dropdownOpen) return\n const handleClick = (e: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(e.target as Node)) {\n setDropdownOpen(false)\n }\n }\n document.addEventListener('mousedown', handleClick)\n return () => document.removeEventListener('mousedown', handleClick)\n }, [dropdownOpen])\n\n return (\n <div className=\"relative\" ref={dropdownRef}>\n <button\n type=\"button\"\n onClick={() => setDropdownOpen(!dropdownOpen)}\n className={cn(\n 'w-full px-4 py-2.5 text-xs transition-all rounded-none-none flex items-center justify-between gap-2',\n theme === 'dark'\n ? 'bg-z-base/65 backdrop-blur-md border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-accent/50 text-z-primary'\n : 'bg-z-panel border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-border text-z-primary'\n )}\n >\n <span className={cn('truncate', !selectedValues.length && ('text-z-secondary'))}>\n {selectedLabels || 'Select option...'}\n </span>\n <svg className={cn('w-3 h-3 shrink-0 transition-transform', dropdownOpen && 'rotate-180', theme === 'dark' ? 'text-z-muted' : 'text-z-secondary')} fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\"><path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" /></svg>\n </button>\n {dropdownOpen && (\n <div\n className={cn(\n 'absolute z-50 left-0 right-0 mt-1 border shadow-xl max-h-60 overflow-y-auto',\n theme === 'dark' ? 'bg-[#0a0a0a] border-z-border' : 'bg-z-panel border-z-border'\n )}\n >\n {hasMany && selectedValues.length > 0 && (\n <button\n type=\"button\"\n onClick={() => onChange([])}\n className={cn('w-full text-left px-3 py-1.5 text-sm font-semibold ', theme === 'dark' ? 'text-z-secondary hover:bg-z-hover' : 'text-z-muted hover:bg-[var(--z-bg-input)]')}\n >Clear all</button>\n )}\n {options.map((opt: string | { label: string; value: any }) => {\n const optLabel = getLabel(opt)\n const optVal = getVal(opt)\n const isSelected = selectedValues.includes(optVal)\n return (\n <button\n key={optVal}\n type=\"button\"\n onClick={() => toggleOption(optVal)}\n className={cn(\n 'w-full text-left px-3 py-2 text-xs flex items-center gap-2 transition-colors',\n isSelected\n ? theme === 'dark' ? 'bg-z-panel/5 text-z-secondary' : 'bg-[var(--z-bg-input)] text-z-secondary'\n : theme === 'dark' ? 'text-z-secondary hover:bg-z-hover' : 'text-z-primary hover:bg-[var(--z-bg-input)]'\n )}\n >\n <span className={cn(\n 'w-3.5 h-3.5 border shrink-0 flex items-center justify-center transition-all rounded-none-none',\n isSelected\n ? 'bg-z-border border-z-border'\n : theme === 'dark' ? 'border-z-border' : 'border-z-border-strong'\n )}>\n {isSelected && (\n <svg className=\"w-2.5 h-2.5 text-z-primary\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\"><path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={3} d=\"M5 13l4 4L19 7\" /></svg>\n )}\n </span>\n <span className=\"font-bold truncate\">{optLabel}</span>\n </button>\n )\n })}\n </div>\n )}\n </div>\n )\n }\n\n case 'relation':\n return (\n <InlineRelationPicker\n blockId={blockId}\n fieldKey={field.name}\n value={value}\n onChange={onChange}\n theme={theme}\n hasMany={field.hasMany}\n relationTo={field.relationTo}\n anchorEl={null}\n />\n )\n\n case 'date': {\n const dateFormat = field.dateFormat || 'date'\n const dateInputType = dateFormat === 'datetime' ? 'datetime-local' : dateFormat === 'time' ? 'time' : 'date'\n return (\n <input\n type={dateInputType}\n value={value ? formatDateForInput(value, dateFormat) : ''}\n onChange={(e) => onChange(e.target.value ? parseInputDate(e.target.value, dateFormat) : '')}\n className={cn(\n \"w-full px-4 py-2.5 text-xs transition-all rounded-none-none\",\n theme === 'dark'\n ? \"bg-z-base/65 backdrop-blur-md border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-accent/50 text-z-primary\"\n : \"bg-z-panel border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-border text-z-primary\"\n )}\n />\n )\n }\n\n case 'array': {\n const items = Array.isArray(value) ? value : []\n /**\n * Transactional reorder guard:\n * Validates every item in the new order still belongs to this field\n * before committing — prevents out-of-sync state from cross-zone drops.\n */\n const handleReorder = (newItems: any[]) => {\n const origIds = new Set(items.map((item: any, idx: number) => item._id ?? idx))\n if (!newItems.every((item: any, idx: number) => origIds.has(item._id ?? idx))) return\n onChange(newItems)\n }\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs font-semibold text-z-secondary\">\n {items.length} {items.length === 1 ? 'Item' : 'Items'}\n </span>\n <button\n type=\"button\"\n onClick={handleAddArrayItem}\n className={cn(\n 'flex items-center gap-1 px-2.5 py-1 text-xs font-semibold transition-all border',\n theme === 'dark'\n ? 'bg-z-panel/5 border-z-border text-z-secondary hover:bg-z-hover border-z-border-strong'\n : 'bg-z-input border-z-border text-z-secondary hover:bg-[var(--z-bg-hover)]'\n )}\n >\n <Plus size={10} /> Add Item\n </button>\n </div>\n\n <Reorder.Group axis=\"y\" values={items.map((i: any, idx: number) => i._id || idx)} onReorder={(newIds) => {\n const origMap = new Map(items.map((i: any, idx: number) => [i._id || idx, i]))\n const newItems = newIds.map((id) => origMap.get(id)).filter(Boolean)\n handleReorder(newItems)\n }} className=\"space-y-3\">\n {items.map((item: any, idx: number) => (\n <ReorderableArrayItem\n key={item._id || idx}\n item={item}\n idx={idx}\n theme={theme}\n onRemove={handleRemoveArrayItem}\n onChange={(subKey: string, val: any) => {\n const next = [...items]\n next[idx] = { ...next[idx], [subKey]: val }\n onChange(next)\n }}\n field={field}\n blockId={blockId}\n humanize={humanize}\n />\n ))}\n </Reorder.Group>\n </div>\n )\n }\n\n case 'group': {\n const groupVal = value && typeof value === 'object' ? value : {}\n return (\n <div className=\"border-l border-z-border/20 pl-3 space-y-3\">\n {field.fields?.map((subField) => (\n <div key={subField.name} className=\"space-y-1\">\n <label className=\"text-xs font-semibold text-z-muted block\">\n {humanize(subField.name)}\n </label>\n <FieldRenderer\n blockId={`${blockId}:${field.name}`}\n field={subField}\n value={groupVal[subField.name]}\n onChange={(val) => onChange({ ...groupVal, [subField.name]: val })}\n theme={theme}\n />\n </div>\n ))}\n </div>\n )\n }\n\n case 'json': {\n const jsonValid = tryParseJson(value)\n return (\n <div className=\"space-y-1\">\n <textarea\n value={typeof value === 'string' ? value : JSON.stringify(value, null, 2) ?? ''}\n onChange={(e) => onChange(e.target.value)}\n placeholder={field.placeholder || 'Enter JSON...'}\n rows={8}\n spellCheck={false}\n className={cn(\n \"w-full px-4 py-2.5 text-xs font-mono transition-all rounded-none-none resize-y\",\n theme === 'dark'\n ? \"bg-z-base/65 backdrop-blur-md border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-accent/50 text-[#e6edf3]\"\n : \"bg-z-accent border border-z-border focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:border-z-border text-z-primary\"\n )}\n />\n <div className=\"flex items-center gap-2\">\n <span className={cn(\n \"inline-block w-1.5 h-1.5 rounded-none-none\",\n jsonValid === true ? \"bg-z-border shadow-sm\" : jsonValid === false ? \"bg-red-500 shadow-[0_0_6px_#ef4444]\" : \"bg-z-accent\"\n )} />\n <span className=\"text-xs font-bold\" style={{ color: jsonValid === true ? 'var(--z-accent)' : jsonValid === false ? '#ef4444' : '#6b7280' }}>\n {jsonValid === true ? 'Valid JSON' : jsonValid === false ? 'Invalid JSON' : 'JSON'}\n </span>\n </div>\n </div>\n )\n }\n\n case 'blocks': {\n const blocks = value && Array.isArray(value) ? value : []\n const availableBlocks = field.blocks || []\n return (\n <div className=\"space-y-3\">\n {blocks.length > 0 && (\n <div className=\"space-y-2\">\n {blocks.map((block: any, idx: number) => {\n const blockType = block.blockType || block.__blockType\n const blockDef = availableBlocks.find((b: any) => b.slug === blockType)\n const blockFields = blockDef?.fields || []\n return (\n <div\n key={block._id || idx}\n className={cn(\n 'border rounded-none-none overflow-hidden',\n theme === 'dark' ? 'bg-z-panel/5 border-z-border' : 'bg-z-input border-z-border'\n )}\n >\n <div className={cn(\n 'flex items-center gap-2 px-3 py-2 border-b',\n theme === 'dark' ? 'bg-z-panel/5 border-z-border' : 'bg-[var(--z-bg-hover)]/50 border-z-border'\n )}>\n <span className={cn(\n 'text-sm font-semibold px-1.5 py-0.5 border rounded-none-none',\n theme === 'dark' ? 'bg-z-panel/5 border-z-border text-z-secondary' : 'bg-z-input border-z-border text-z-primary'\n )}>\n {blockDef?.labels?.singular || humanize(blockType || 'block')}\n </span>\n <button\n type=\"button\"\n onClick={() => {\n const next = blocks.filter((_: any, i: number) => i !== idx)\n onChange(next)\n }}\n className=\"ml-auto p-1 text-z-secondary hover:text-rose-500 transition-colors\"\n aria-label=\"Remove block\"\n >\n <Trash2 size={10} />\n </button>\n </div>\n <div className=\"px-3 py-3 space-y-3\">\n {blockFields.map((subField: FieldDefinition) => (\n <div key={subField.name} className=\"space-y-1\">\n <label className=\"text-xs font-semibold text-z-muted block\">\n {subField.label || humanize(subField.name)}\n </label>\n <FieldRenderer\n blockId={`${blockId}:${field.name}:${idx}`}\n field={subField}\n value={block[subField.name]}\n onChange={(val) => {\n const next = [...blocks]\n next[idx] = { ...next[idx], [subField.name]: val }\n onChange(next)\n }}\n theme={theme}\n />\n </div>\n ))}\n </div>\n </div>\n )\n })}\n </div>\n )}\n {(!(field as any).maxRows || blocks.length < (field as any).maxRows) && (\n <button\n type=\"button\"\n onClick={() => {\n openComponentPicker((blockType) => {\n const newBlock = { blockType, _id: uid() }\n onChange([...blocks, newBlock])\n }, availableBlocks.length > 0 ? availableBlocks : undefined)\n }}\n className={cn(\n 'w-full py-2.5 border-2 border-dashed flex flex-col items-center justify-center gap-1.5 transition-all group rounded-none-none',\n theme === 'dark'\n ? 'border-z-border hover:border-z-border/50 hover:bg-z-hover text-z-muted hover:text-z-secondary'\n : 'border-z-border-strong hover:border-z-border hover:bg-[var(--z-bg-input)] text-z-secondary hover:text-z-secondary'\n )}\n >\n <div className={cn(\n 'p-1.5 rounded-none-none transition-colors',\n theme === 'dark' ? 'bg-z-hover group-hover:bg-z-hover border-z-border-strong' : 'bg-[var(--z-bg-hover)] group-hover:bg-[var(--z-bg-hover)]'\n )}>\n <Plus size={14} className=\"stroke-[3]\" />\n </div>\n <span className=\"text-sm font-semibold\">\n Add Block\n </span>\n </button>\n )}\n </div>\n )\n }\n\n case 'tabs': {\n const tabs = field.tabs || []\n const [activeTab, setActiveTab] = useState(0)\n const tabData = value && typeof value === 'object' ? value : {}\n return (\n <div className=\"space-y-3\">\n {tabs.length > 1 && (\n <div className={cn(\n 'flex gap-0.5 p-0.5 rounded-none-none border',\n 'bg-z-panel border-z-border'\n )}>\n {tabs.map((tab: any, idx: number) => (\n <button\n key={tab.label || idx}\n type=\"button\"\n onClick={() => setActiveTab(idx)}\n className={cn(\n 'px-3 py-1.5 text-sm font-semibold transition-all',\n activeTab === idx\n ? theme === 'dark'\n ? 'bg-z-hover text-z-primary'\n : 'bg-z-panel text-z-primary shadow-sm'\n : theme === 'dark'\n ? 'text-z-secondary hover:text-z-primary'\n : 'text-z-muted hover:text-z-primary'\n )}\n >\n {tab.label || `Tab ${idx + 1}`}\n </button>\n ))}\n </div>\n )}\n {tabs[activeTab] && (\n <div className=\"space-y-3\">\n {tabs[activeTab].fields?.map((subField: FieldDefinition) => (\n <div key={subField.name} className=\"space-y-1\">\n <label className=\"text-xs font-semibold text-z-muted block\">\n {subField.label || humanize(subField.name)}\n </label>\n <FieldRenderer\n blockId={`${blockId}:${field.name}`}\n field={subField}\n value={tabData[subField.name]}\n onChange={(val) => onChange({ ...tabData, [subField.name]: val })}\n theme={theme}\n />\n </div>\n ))}\n </div>\n )}\n </div>\n )\n }\n\n case 'dz':\n return (\n <NestedDynamicZone\n blockId={blockId}\n fieldName={field.name}\n value={value || []}\n onChange={onChange}\n theme={theme}\n components={field.components || []}\n />\n )\n\n default:\n return (\n <div className=\"flex items-center gap-2 p-2 border border-dashed border-red-500/30 text-red-400 text-xs\">\n <HelpCircle size={14} /> Unsupported field type: {field.type}\n </div>\n )\n }\n }\n\n return (\n <div\n className={cn(\n 'stega-field-wrapper relative transition-all duration-200',\n showFieldIndicators && 'group/field',\n isSelected && 'field-selected'\n )}\n onClick={(e) => {\n e.stopPropagation()\n if (onFieldSelect) {\n onFieldSelect(blockId, field.name)\n } else {\n setSelectedField({ blockId, fieldKey: field.name })\n }\n useEditorStore.getState().setActiveSection(blockId)\n }}\n style={{ padding: showFieldIndicators ? '2px' : 0 }}\n >\n {showFieldIndicators && (\n <div className=\"stega-field-indicator\">\n {isSelected ? <Settings2 size={10} /> : <span className=\"text-sm\"></span>}\n </div>\n )}\n {field.description && (\n <p className={cn('text-sm font-medium mt-0.5 mb-1', 'text-z-secondary')}>\n {field.description}\n </p>\n )}\n {renderInnerField()}\n {error && (\n <p className=\"text-xs text-red-500 mt-1\" role=\"alert\" aria-live=\"polite\">{error}</p>\n )}\n </div>\n )\n})\n\nexport default FieldRenderer\n","import React from 'react'\nimport { createPortal } from 'react-dom'\nimport { Grip, Copy, Trash2, AlignLeft, AlignCenter, AlignRight, ChevronDown, ChevronRight, MoreHorizontal, ArrowUp, ArrowDown, Clipboard, ClipboardPaste, Edit3 } from 'lucide-react'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport { cn } from '../../../lib/utils'\nimport { useEditorBlocks } from '../../../context/BlockLibraryContext'\nimport { useEditorStore } from '../../../store/editorStore'\nimport { type Section, type FieldDefinition, humanize } from '../constants'\nimport { FieldRenderer } from '../FieldRenderer'\n\ninterface SectionBlockProps {\n section: Section\n index: number\n totalSections: number\n isActive: boolean\n isMultiSelected?: boolean\n onSelect: (e?: React.MouseEvent) => void\n onDuplicate: () => void\n onDelete: () => void\n onAlign: (align: 'left' | 'center' | 'right') => void\n onFieldChange: (fieldKey: string, value: any) => void\n onToggleCollapse: () => void\n onMoveUp: () => void\n onMoveDown: () => void\n onCopy: () => void\n onPaste: () => void\n onBlockNameChange: (name: string) => void\n theme: 'light' | 'dark'\n showFieldIndicators?: boolean\n selectedField?: { blockId: string; fieldKey: string } | null\n schemaFields?: any[]\n fieldErrors?: Record<string, string>\n onFieldSelect?: (blockId: string, fieldKey: string) => void\n i18nEnabled?: boolean\n currentLocale?: string\n getTranslatedValue?: (sectionId: string, fieldKey: string, defaultValue: any) => any\n setTranslatedValue?: (sectionId: string, fieldKey: string, value: any) => void\n onAddToDynamicZone?: (sectionId: string, fieldKey: string) => void\n dragControls?: any\n onContextMenu?: (e: React.MouseEvent) => void\n}\n\nconst detectFieldType = (key: string, value: any): 'text' | 'richtext' | 'media' | 'array' | 'group' | 'number' | 'boolean' | 'select' | 'relation' => {\n const k = key.toLowerCase()\n if (k.includes('image') || k.includes('photo') || k.includes('thumbnail') || k.includes('cover') || k.includes('banner') || k.includes('logo')) {\n return 'media'\n }\n if (k.includes('content') || k.includes('description') || k.includes('bio') || (typeof value === 'string' && value.length > 200)) {\n return 'richtext'\n }\n if (Array.isArray(value)) {\n return 'array'\n }\n if (typeof value === 'object' && value !== null) {\n return 'group'\n }\n return 'text'\n}\n\nexport const SectionBlock: React.FC<SectionBlockProps> = ({\n section,\n index,\n totalSections,\n isActive,\n isMultiSelected = false,\n onSelect,\n onDuplicate,\n onDelete,\n onAlign,\n onFieldChange,\n onToggleCollapse,\n onMoveUp,\n onMoveDown,\n onCopy,\n onPaste,\n onBlockNameChange,\n onFieldSelect,\n theme,\n showFieldIndicators,\n selectedField,\n schemaFields,\n fieldErrors = {},\n i18nEnabled,\n currentLocale,\n getTranslatedValue,\n setTranslatedValue,\n onAddToDynamicZone,\n dragControls,\n onContextMenu,\n}) => {\n const BLOCK_LIBRARY = useEditorBlocks()\n const blockDef = BLOCK_LIBRARY.find((b) => b.type === section.blockType)\n const [menuOpen, setMenuOpen] = React.useState(false)\n const menuRef = React.useRef<HTMLDivElement>(null)\n const menuAnchorRef = React.useRef<HTMLButtonElement>(null)\n const [menuPos, setMenuPos] = React.useState<{ top: number; left: number } | null>(null)\n const [editingBlockName, setEditingBlockName] = React.useState(false)\n const blockNameInputRef = React.useRef<HTMLInputElement>(null)\n\n // Global undo/redo available via Ctrl+Z / Ctrl+Y (see EditorToolbar for step-count badge)\n const { undo: _globalUndo, redo: _globalRedo } = useEditorStore()\n\n // Close menu on outside click\n React.useEffect(() => {\n if (!menuOpen) return\n const handleClick = (e: MouseEvent) => {\n if (menuAnchorRef.current?.contains(e.target as Node)) return // let the button toggle\n if (menuRef.current && !menuRef.current.contains(e.target as Node)) {\n setMenuOpen(false)\n }\n }\n document.addEventListener('mousedown', handleClick)\n return () => document.removeEventListener('mousedown', handleClick)\n }, [menuOpen])\n\n const handleFieldChange = (key: string, value: any) => {\n onFieldChange(key, value)\n }\n\n const isCallout = section.blockType === 'callout'\n const calloutType = section.content?.type || 'info'\n const calloutClasses = isCallout\n ? {\n info: 'border-l-4 border-l-sky-500 bg-sky-500/5',\n warning: 'border-l-4 border-l-amber-500 bg-amber-500/5',\n success: 'border-l-4 border-z-border bg-z-hover',\n error: 'border-l-4 border-l-rose-500 bg-rose-500/5',\n }[calloutType as 'info' | 'warning' | 'success' | 'error'] || 'border-l-4 border-l-sky-500 bg-sky-500/5'\n : ''\n\n const blockTheme = section.content?.theme || 'default'\n const blockPaddingY = section.content?.paddingY || 'medium'\n const blockWidth = section.content?.containerWidth || 'boxed'\n const anchorId = section.content?.anchorId || undefined\n\n const themeClasses = {\n default: '',\n light: 'bg-z-panel/90 text-z-primary border-z-border shadow-sm',\n dark: 'bg-z-popover text-z-primary border-z-border shadow-lg',\n 'cyber-gray': 'bg-gradient-to-br from-[var(--z-bg-panel)] via-[var(--z-bg-base)] to-[var(--z-bg-panel)] text-z-primary border-z-border/20 shadow-sm/5',\n glassmorphic: 'bg-z-input backdrop-blur-[12px] border-z-border shadow-sm text-z-primary'\n }[blockTheme as 'default' | 'light' | 'dark' | 'cyber-gray' | 'glassmorphic'] || ''\n\n const paddingClasses = {\n none: 'py-2 px-6',\n small: 'py-6 px-6',\n medium: 'py-12 px-6',\n large: 'py-20 px-8'\n }[blockPaddingY as 'none' | 'small' | 'medium' | 'large'] || 'py-6 px-6'\n\n const widthClasses = {\n boxed: 'max-w-6xl mx-auto',\n 'full-width': 'w-full'\n }[blockWidth as 'boxed' | 'full-width'] || ''\n\n // Count errors for this section\n const sectionErrorCount = Object.keys(fieldErrors).filter((k) => k.startsWith(section.id + ':')).length\n\n // Get field definitions\n const fieldsToRender: FieldDefinition[] = React.useMemo(() => {\n if (blockDef?.fields) {\n return blockDef.fields\n }\n return Object.keys(section.content || {}).map((key) => {\n const val = section.content[key]\n return {\n name: key,\n type: detectFieldType(key, val),\n label: key.replace(/_/g, ' ').replace(/([A-Z])/g, ' $1').replace(/^./, (s) => s.toUpperCase()).trim(),\n }\n })\n }, [blockDef, section.content])\n\n const regularFieldCount = React.useMemo(() => (\n fieldsToRender.filter(f =>\n f.name !== 'content' && f.name !== 'description' && f.name !== 'bio' && f.type !== 'richtext'\n ).length\n ), [fieldsToRender])\n\n const isCollapsed = section.collapsed ?? false\n\n const handleBlockNameKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Enter') {\n setEditingBlockName(false)\n }\n }\n\n return (\n <div\n id={anchorId || section.id}\n onClick={onSelect}\n onContextMenu={onContextMenu}\n className={cn(\n 'rounded-none-none border transition-all duration-500 relative cursor-pointer',\n calloutClasses,\n themeClasses || (theme === 'dark' ? 'bg-z-panel border-z-border hover:border-z-border' : 'bg-z-panel border-z-border shadow-sm hover:border-z-border'),\n isActive && 'ring-2 ring-z-active-border scale-[1.005]',\n isMultiSelected && !isActive && 'ring-2 ring-amber-500/40'\n )}\n >\n {/* Section Header — always visible, even when collapsed */}\n <div\n className={cn(\n 'flex items-center justify-between px-6 py-4 border-b select-none',\n isCollapsed ? 'border-b-0' : '',\n theme === 'dark' ? 'border-z-border bg-z-panel' : 'border-z-border shadow-sm bg-[var(--z-bg-input)]/50'\n )}\n >\n <div className=\"flex items-center gap-3 min-w-0\">\n {/* Drag handle */}\n <div\n onPointerDown={(e) => dragControls && dragControls.start(e)}\n title=\"Drag to reorder\"\n role=\"button\"\n aria-label=\"Drag to reorder section\"\n aria-grabbed=\"false\"\n tabIndex={-1}\n className={cn(\n 'w-7 h-7 rounded-none-none border flex items-center justify-center cursor-grab active:cursor-grabbing shrink-0 transition-all',\n theme === 'dark'\n ? 'bg-z-hover border-z-border text-z-muted/60 hover:bg-z-panel hover:border-z-border/30 hover:text-z-secondary'\n : 'bg-[var(--z-bg-hover)] border-z-border text-z-secondary/60 hover:bg-[var(--z-bg-input)] hover:border-z-border-strong hover:text-z-secondary'\n )}\n >\n <Grip size={12} aria-hidden=\"true\" />\n </div>\n\n {/* Index badge */}\n <span className={cn(\n 'text-sm font-semibold leading-none w-5 text-center',\n 'text-z-secondary'\n )}>\n {String(index + 1).padStart(2, '0')}\n </span>\n\n {/* Block type pill — human-readable */}\n <span className={cn(\n 'px-2 py-0.5 text-sm font-semibold border shrink-0',\n theme === 'dark' ? 'bg-z-panel/5 border-z-border text-z-secondary' : 'bg-z-input border-z-border text-z-primary'\n )}>\n {humanize(section.blockType)}\n </span>\n\n {/* Block name (editable) */}\n {editingBlockName ? (\n <input\n ref={blockNameInputRef}\n autoFocus\n value={section.blockName || ''}\n onChange={(e) => onBlockNameChange(e.target.value)}\n onBlur={() => setEditingBlockName(false)}\n onKeyDown={handleBlockNameKeyDown}\n onClick={(e) => e.stopPropagation()}\n className={cn(\n 'text-xs font-semibold bg-transparent border-b px-1 min-w-[80px] max-w-[200px]',\n theme === 'dark' ? 'text-z-primary border-z-border' : 'text-z-primary border-z-border-strong'\n )}\n placeholder=\"Block name...\"\n />\n ) : (\n <span\n onClick={(e) => {\n e.stopPropagation()\n setEditingBlockName(true)\n setTimeout(() => blockNameInputRef.current?.focus(), 0)\n }}\n className={cn(\n 'text-xs font-semibold truncate cursor-text px-1 flex items-center gap-1.5',\n section.blockName\n ? theme === 'dark' ? 'text-z-primary' : 'text-z-primary'\n : 'text-z-secondary'\n )}\n >\n {section.blockName || 'Add name...'}\n <Edit3 size={10} className=\"opacity-0 group-hover/item:opacity-40 transition-opacity\" />\n </span>\n )}\n\n {/* Error pill */}\n {sectionErrorCount > 0 && (\n <span className=\"px-1.5 py-0.5 text-sm font-semibold bg-rose-500/10 border border-rose-500/20 text-rose-500 shrink-0\">\n {sectionErrorCount} error{sectionErrorCount !== 1 ? 's' : ''}\n </span>\n )}\n </div>\n\n <div className=\"flex items-center gap-0.5 shrink-0\">\n {/* Collapse toggle */}\n <button\n onClick={(e) => { e.stopPropagation(); onToggleCollapse() }}\n className={cn(\n 'p-1.5 rounded-none-none border transition-all',\n theme === 'dark' ? 'text-z-secondary border-transparent hover:text-z-secondary' : 'text-z-muted border-transparent hover:text-z-secondary '\n )}\n title={isCollapsed ? 'Expand' : 'Collapse'}\n >\n {isCollapsed ? <ChevronRight size={12} /> : <ChevronDown size={12} />}\n </button>\n\n {/* Compact action menu */}\n <button\n ref={menuAnchorRef}\n onClick={(e) => {\n e.stopPropagation()\n if (!menuOpen && menuAnchorRef.current) {\n const rect = menuAnchorRef.current.getBoundingClientRect()\n setMenuPos({ top: rect.bottom + 4, left: rect.right - 160 })\n }\n setMenuOpen(!menuOpen)\n }}\n className={cn(\n 'p-1.5 rounded-none-none border transition-all',\n menuOpen\n ? theme === 'dark' ? 'bg-z-hover border-z-border-strong border-z-border/30 text-z-secondary' : 'bg-[var(--z-bg-hover)] border-z-border text-z-secondary'\n : theme === 'dark' ? 'text-z-secondary border-transparent hover:text-z-secondary' : 'text-z-muted border-transparent hover:text-z-secondary '\n )}\n title=\"Actions\"\n >\n <MoreHorizontal size={14} />\n </button>\n </div>\n </div>\n\n {/* Collapsible fields area */}\n <AnimatePresence initial={false}>\n {!isCollapsed && (\n <motion.div\n initial={{ height: 0, opacity: 0 }}\n animate={{ height: 'auto', opacity: 1 }}\n exit={{ height: 0, opacity: 0 }}\n transition={{ duration: 0.15 }}\n className=\"overflow-visible\"\n >\n <div className={cn('transition-all duration-300', paddingClasses, widthClasses)}>\n {/* Sub-toolbar: align + undo/redo (moved from header to reduce clutter) */}\n <div className={cn(\n 'flex items-center justify-between -mx-6 -mt-6 mb-6 px-4 py-2 border-b',\n theme === 'dark' ? 'bg-z-panel/5 border-z-border' : 'bg-[var(--z-bg-input)]/50 border-z-border shadow-sm'\n )}>\n <div className={cn(\n 'flex items-center gap-0.5 p-0.5 rounded-none-none border',\n theme === 'dark' ? 'bg-app/20 border-z-border' : 'bg-z-panel border-z-border'\n )}>\n {(['left', 'center', 'right'] as const).map((align) => (\n <button\n key={align}\n aria-label={`Align ${align}`}\n onClick={(e) => { e.stopPropagation(); onAlign(align) }}\n className={cn(\n 'p-1 transition-all',\n section.align === align || (!section.align && align === 'left')\n ? theme === 'dark' ? 'bg-z-hover text-z-primary' : 'bg-app text-z-primary shadow-sm'\n : 'text-z-muted hover:text-z-secondary '\n )}\n >\n {align === 'left' && <AlignLeft size={10} />}\n {align === 'center' && <AlignCenter size={10} />}\n {align === 'right' && <AlignRight size={10} />}\n </button>\n ))}\n </div>\n <div className=\"flex items-center gap-1\">\n <span\n className={cn(\n 'text-sm font-bold select-none',\n theme === 'dark' ? 'text-z-primary' : 'text-z-muted'\n )}\n title=\"Use Ctrl+Z / Ctrl+Y to undo or redo changes\"\n >\n Ctrl+Z / Ctrl+Y to undo/redo\n </span>\n </div>\n </div>\n\n {section.blockType === 'code' && (\n <div className={cn(\n \"w-full px-4 py-2 border-b flex items-center justify-between -mx-6 -mt-6 mb-6\",\n theme === 'dark' ? 'bg-[#0F172A]/80 border-z-border' : 'bg-[var(--z-bg-hover)] border-z-border'\n )}>\n <div className=\"flex gap-1.5\">\n <span className=\"w-2.5 h-2.5 rounded-none-none bg-rose-500\" />\n <span className=\"w-2.5 h-2.5 rounded-none-none bg-amber-500\" />\n <span className=\"w-2.5 h-2.5 rounded-none-none bg-z-border\" />\n </div>\n <span className=\"text-xs font-semibold text-z-secondary\">\n {section.content?.language || 'javascript'} terminal\n </span>\n </div>\n )}\n\n {section.blockType === 'table' ? (\n <div className=\"w-full overflow-x-auto border border-z-border bg-app/20 p-4 rounded-none-none\">\n <div className=\"overflow-x-auto min-w-full pb-4\"><table className=\"w-full border-collapse text-left text-xs font-mono\">\n <thead>\n <tr className={cn(theme === 'dark' ? 'bg-z-hover border-b border-z-border' : 'bg-[var(--z-bg-hover)] border-b border-z-border')}>\n {((section.content?.headers) || []).map((h, hIdx) => (\n <th key={hIdx} className=\"p-2.5\">\n <input\n type=\"text\"\n value={h.text || ''}\n onChange={(e) => {\n const headers = [...(section.content.headers || [])]\n headers[hIdx] = { ...headers[hIdx], text: e.target.value }\n handleFieldChange('headers', headers)\n }}\n className=\"bg-transparent border-none font-bold w-full focus:bg-z-hover focus-visible:ring-2 focus-visible:ring-z-active-border rounded-none px-1 text-xs\"\n placeholder={`Header ${hIdx + 1}`}\n />\n </th>\n ))}\n <th className=\"w-10\">\n <button\n onClick={(e) => {\n e.stopPropagation()\n const headers = [...(section.content.headers || [])]\n headers.push({ text: '' })\n handleFieldChange('headers', headers)\n const rows = (section.content.rows || []).map((r: any) => ({\n cells: [...(r.cells || []), { text: '' }]\n }))\n handleFieldChange('rows', rows)\n }}\n className=\"text-xs text-z-secondary font-bold hover:text-z-secondary\"\n >\n + Col\n </button>\n </th>\n </tr>\n </thead>\n <tbody>\n {((section.content?.rows) || []).map((row, rIdx) => (\n <tr key={rIdx} className={cn(theme === 'dark' ? 'border-b border-z-border hover:bg-z-panel' : 'border-b border-z-border hover:bg-[var(--z-bg-input)]')}>\n {((row.cells) || []).map((cell, cIdx) => (\n <td key={cIdx} className=\"p-2\">\n <input\n type=\"text\"\n value={cell.text || ''}\n onChange={(e) => {\n const rows = [...(section.content.rows || [])]\n const cells = [...(rows[rIdx].cells || [])]\n cells[cIdx] = { ...cells[cIdx], text: e.target.value }\n rows[rIdx] = { ...rows[rIdx], cells }\n handleFieldChange('rows', rows)\n }}\n className=\"bg-transparent border-none w-full focus:bg-z-hover focus-visible:ring-2 focus-visible:ring-z-active-border rounded-none px-1\"\n placeholder=\"Cell...\"\n />\n </td>\n ))}\n <td className=\"p-2\">\n <button\n onClick={(e) => {\n e.stopPropagation()\n const rows = (section.content.rows || []).filter((_: any, idx: number) => idx !== rIdx)\n handleFieldChange('rows', rows)\n }}\n className=\"text-xs text-rose-500 font-bold hover:text-rose-400\"\n >\n Delete\n </button>\n </td>\n </tr>\n ))}\n <tr>\n <td colSpan={((section.content?.headers) || []).length + 1} className=\"p-2\">\n <button\n onClick={(e) => {\n e.stopPropagation()\n const rows = [...(section.content.rows || [])]\n const numCols = ((section.content?.headers) || []).length\n const newCells = Array.from({ length: numCols }, () => ({ text: '' }))\n rows.push({ cells: newCells })\n handleFieldChange('rows', rows)\n }}\n className=\"text-xs text-z-secondary font-bold hover:text-z-secondary flex items-center gap-1\"\n >\n + Add Row\n </button>\n </td>\n </tr>\n </tbody>\n </table></div>\n </div>\n ) : (\n <div className=\"space-y-8\">\n {/* Content Fields */}\n <div\n className={cn(\n 'gap-8',\n fieldsToRender.filter(f => !['anchorId', 'theme', 'paddingY', 'containerWidth', 'bgImage'].includes(f.name) && f.name !== 'content' && f.name !== 'description' && f.name !== 'bio' && f.type !== 'richtext').length >= 4 ? 'grid grid-cols-1 md:grid-cols-2' : 'space-y-6',\n section.align === 'center' && 'text-center',\n section.align === 'right' && 'text-right'\n )}\n >\n {fieldsToRender.filter(f => !['anchorId', 'theme', 'paddingY', 'containerWidth', 'bgImage'].includes(f.name)).map((field) => {\n const rawVal = section.content?.[field.name]\n const displayValue = i18nEnabled && getTranslatedValue\n ? getTranslatedValue(section.id, field.name, rawVal)\n : rawVal\n const isFullWidth = field.name === 'content' || field.name === 'description' || field.name === 'bio' || field.type === 'richtext'\n const errorKey = `${section.id}:${field.name}`\n\n return (\n <div\n key={field.name}\n className={cn(\n 'space-y-2',\n isFullWidth && 'md:col-span-2'\n )}\n >\n <div className=\"space-y-1.5\">\n <div className=\"flex items-center gap-2\">\n <label className=\"text-sm font-semibold text-z-secondary px-1\">\n {field.label || field.name}\n </label>\n <span className={cn(\n 'px-2 py-0.5 text-[10px] uppercase tracking-wider font-bold rounded-none-none border',\n theme === 'dark'\n ? 'bg-z-panel/5 border-z-border text-z-secondary'\n : 'bg-[var(--z-bg-hover)] border-z-border text-z-muted'\n )}>\n {field.type}\n </span>\n {fieldErrors[errorKey] && (\n <span className=\"text-sm font-semibold text-rose-500 ml-auto\">\n {fieldErrors[errorKey]}\n </span>\n )}\n </div>\n {field.description && (\n <p className={cn('text-xs font-medium px-1.5 opacity-60', theme === 'dark' ? 'text-z-muted' : 'text-z-secondary')}>\n {field.description}\n </p>\n )}\n </div>\n\n <FieldRenderer\n blockId={section.id}\n field={field}\n value={displayValue}\n onChange={(newVal) => {\n if (i18nEnabled && currentLocale !== 'en' && setTranslatedValue) {\n setTranslatedValue(section.id, field.name, newVal)\n } else {\n handleFieldChange(field.name, newVal)\n }\n }}\n onFieldSelect={onFieldSelect}\n theme={theme}\n error={fieldErrors[errorKey]}\n isSelected={selectedField?.blockId === section.id && selectedField?.fieldKey === field.name}\n />\n </div>\n )\n })}\n </div>\n\n {/* Settings Fields */}\n {fieldsToRender.some(f => ['anchorId', 'theme', 'paddingY', 'containerWidth', 'bgImage'].includes(f.name)) && (\n <div className={cn(\n 'pt-6 mt-6 border-t',\n 'border-z-border'\n )}>\n <h4 className=\"text-sm font-semibold text-z-secondary/50 mb-4 px-1\">\n Layout & Styling\n </h4>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-4\">\n {fieldsToRender.filter(f => ['anchorId', 'theme', 'paddingY', 'containerWidth', 'bgImage'].includes(f.name)).map((field) => {\n const rawVal = section.content?.[field.name]\n const displayValue = i18nEnabled && getTranslatedValue\n ? getTranslatedValue(section.id, field.name, rawVal)\n : rawVal\n const errorKey = `${section.id}:${field.name}`\n\n return (\n <div key={field.name} className=\"space-y-1.5\">\n <div className=\"flex items-center gap-2\">\n <label className=\"text-sm font-semibold text-z-secondary px-1\">\n {field.label || field.name}\n </label>\n </div>\n <FieldRenderer\n blockId={section.id}\n field={field}\n value={displayValue}\n onChange={(newVal) => {\n if (i18nEnabled && currentLocale !== 'en' && setTranslatedValue) {\n setTranslatedValue(section.id, field.name, newVal)\n } else {\n handleFieldChange(field.name, newVal)\n }\n }}\n onFieldSelect={onFieldSelect}\n theme={theme}\n error={fieldErrors[errorKey]}\n isSelected={selectedField?.blockId === section.id && selectedField?.fieldKey === field.name}\n />\n </div>\n )\n })}\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n\n {/* Action menu rendered via portal to escape overflow-hidden clipping */}\n {menuOpen && menuPos && createPortal(\n <div\n ref={menuRef}\n style={{ position: 'fixed', top: menuPos.top, left: menuPos.left, zIndex: 900 }}\n className={cn(\n 'min-w-[160px] border shadow-xl rounded-none-none',\n theme === 'dark' ? 'bg-app border-z-border' : 'bg-z-panel border-z-border'\n )}\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"py-1\">\n {index > 0 && (\n <ActionItem icon={<ArrowUp size={12} />} label=\"Move Up\" onClick={() => { onMoveUp(); setMenuOpen(false) }} theme={theme} />\n )}\n {index < totalSections - 1 && (\n <ActionItem icon={<ArrowDown size={12} />} label=\"Move Down\" onClick={() => { onMoveDown(); setMenuOpen(false) }} theme={theme} />\n )}\n <ActionItem icon={<Copy size={12} />} label=\"Duplicate\" onClick={() => { onDuplicate(); setMenuOpen(false) }} theme={theme} />\n <ActionItem icon={<Clipboard size={12} />} label=\"Copy\" onClick={() => { onCopy(); setMenuOpen(false) }} theme={theme} />\n <ActionItem icon={<ClipboardPaste size={12} />} label=\"Paste\" onClick={() => { onPaste(); setMenuOpen(false) }} theme={theme} />\n <div className={cn('border-t my-1', theme === 'dark' ? 'border-z-border' : 'border-z-border shadow-sm')} />\n <ActionItem icon={<Trash2 size={12} />} label=\"Remove\" onClick={() => { onDelete(); setMenuOpen(false) }} theme={theme} danger />\n </div>\n </div>,\n document.body\n )}\n\n </div>\n )\n}\n\n// Small helper for action menu items\nconst ActionItem: React.FC<{\n icon: React.ReactNode\n label: string\n onClick: () => void\n theme: 'light' | 'dark'\n danger?: boolean\n}> = ({ icon, label, onClick, theme, danger }) => (\n <button\n onClick={onClick}\n className={cn(\n 'w-full flex items-center gap-3 px-3 py-2 text-sm font-semibold transition-all',\n danger\n ? 'text-rose-500 hover:bg-rose-500/10'\n : theme === 'dark'\n ? 'text-z-muted hover:bg-z-hover hover:text-z-primary'\n : 'text-z-secondary hover:bg-[var(--z-bg-input)] hover:text-z-primary'\n )}\n >\n <span className=\"opacity-60\">{icon}</span>\n {label}\n </button>\n)\n","/**\n * BlockPickerModal — thin wrapper that keeps the `blockPickerOpen` Zustand\n * toggle working while delegating all UI to the global GlobalComponentPickerModal.\n *\n * When `blockPickerOpen` becomes true (keyboard \"/\" shortcut, toolbar button,\n * or the between-block \"Insert\" portal), we immediately open the global\n * picker with the `addBlock` callback, then clear `blockPickerOpen` so the\n * two flags don't stay out of sync.\n */\nimport React, { useEffect } from 'react'\nimport { useModalStore } from '../../../store/modalStore'\nimport { useShallow } from 'zustand/react/shallow'\n\ninterface BlockPickerModalProps {\n addBlock: (blockType: string) => void\n}\n\nexport const BlockPickerModal: React.FC<BlockPickerModalProps> = ({ addBlock }) => {\n const { blockPickerOpen, setBlockPickerOpen, openComponentPicker } = useModalStore(useShallow(state => ({ blockPickerOpen: state.blockPickerOpen, setBlockPickerOpen: state.setBlockPickerOpen, openComponentPicker: state.openComponentPicker })))\n\n useEffect(() => {\n if (blockPickerOpen) {\n // Hand off to the global picker, then clear the local flag\n openComponentPicker((blockType) => {\n addBlock(blockType)\n })\n setBlockPickerOpen(false)\n }\n }, [blockPickerOpen]) \n\n return null\n}\n","import React, { useRef, useState, useEffect } from 'react'\nimport { X, Save, RotateCcw, Globe, Wand2, Loader2 } from 'lucide-react'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport { useTheme } from '../../../context/ThemeContext'\nimport { useEditorStore } from '../../../store/editorStore'\nimport { useModalStore } from '../../../store/modalStore'\n\nconst Twitter: React.FC<React.SVGProps<SVGSVGElement>> = (props) => (\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" stroke=\"currentColor\" strokeWidth=\"2\" fill=\"none\" strokeLinecap=\"round\" strokeLinejoin=\"round\" {...props}>\n <path d=\"M22 4s-.7 2.1-2 3.4c1.6 10-9.4 17.3-18 11.6 2.2.1 4.4-.6 6-2C3 15.5.5 9.6 3 5c2.2 2.6 5.6 4.1 9 4-.9-4.2 4-6.6 7-3.8 1.1 0 3-1.2 3-1.2z\" />\n </svg>\n)\n\nconst Facebook: React.FC<React.SVGProps<SVGSVGElement>> = (props) => (\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" stroke=\"currentColor\" strokeWidth=\"2\" fill=\"none\" strokeLinecap=\"round\" strokeLinejoin=\"round\" {...props}>\n <path d=\"M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z\" />\n </svg>\n)\nimport { humanize } from '../constants'\nimport { cn, extractTextFromBlocks } from '../../../lib/utils'\nimport { useFocusTrap } from '../../../hooks/useFocusTrap'\nimport { useShallow } from 'zustand/react/shallow'\nimport api from '../../../lib/api'\nimport { toast } from 'react-hot-toast'\n\ninterface SEOModalProps {\n onSave?: () => void | Promise<void>\n}\n\nconst META_FIELDS = ['title', 'description', 'keywords'] as const\n\ntype MetaField = { title: string; description: string; keywords: string }\n\nexport const SEOModal: React.FC<SEOModalProps> = ({ onSave }) => {\n const { theme } = useTheme()\n const { data, updateData: editorUpdateData } = useEditorStore()\n const { seoOpen, setSeoOpen } = useModalStore(useShallow(state => ({ seoOpen: state.seoOpen, setSeoOpen: state.setSeoOpen })))\n const activeSiteSlug = localStorage.getItem('activeSiteSlug')\n\n const [localMeta, setLocalMeta] = useState<MetaField>({\n title: '',\n description: '',\n keywords: '',\n })\n const [previewTab, setPreviewTab] = useState<'google' | 'twitter' | 'facebook'>('google')\n const [isGenerating, setIsGenerating] = useState<Record<string, boolean>>({})\n\n const generateAIContent = async (field: keyof MetaField) => {\n setIsGenerating(prev => ({ ...prev, [field]: true }))\n try {\n const contentText = extractTextFromBlocks(data?.sections)\n if (!contentText) throw new Error('No content available to analyze')\n\n let response: any;\n if (field === 'description') {\n response = await api.post('/content-tools/ai/meta-description', {\n title: localMeta.title || data?.title || 'Untitled',\n content: contentText\n })\n if (response.data?.data?.description) {\n handleFieldChange(field, response.data.data.description)\n toast.success('Generated description')\n }\n } else if (field === 'title') {\n response = await api.post('/content-tools/ai/generate', {\n prompt: `Write a highly optimized, compelling SEO title (max 60 chars) for this page. The page content is: ${contentText}. Follow SEO best practices: include the primary keyword near the beginning if possible, keep it engaging but accurate, and avoid clickbait.`\n })\n if (response.data?.data?.text) {\n handleFieldChange(field, response.data.data.text.replace(/[\"']/g, '').trim())\n toast.success('Generated title')\n }\n } else if (field === 'keywords') {\n response = await api.post('/content-tools/ai/generate', {\n prompt: `Extract exactly 5 highly relevant SEO keywords as a simple comma-separated list from this content: ${contentText}. Ensure these are context-based, specific, and reflect the true topic of the page.`\n })\n if (response.data?.data?.text) {\n handleFieldChange(field, response.data.data.text.trim())\n toast.success('Generated keywords')\n }\n }\n } catch (e: any) {\n toast.error(e?.response?.data?.error?.message || 'Failed to generate content')\n } finally {\n setIsGenerating(prev => ({ ...prev, [field]: false }))\n }\n }\n\n const siteUrl = activeSiteSlug === 'blog-demo'\n ? 'https://blog-demo.zenith.dev'\n : activeSiteSlug === 'storefront-glass'\n ? 'https://storefront.zenith.dev'\n : activeSiteSlug === 'demo'\n ? 'https://demo.zenith.dev'\n : 'https://zenith.dev'\n\n const pageUrl = data?.title\n ? `${siteUrl}/${data.title.toLowerCase().replace(/\\s+/g, '-').replace(/[^a-z0-9-]/g, '')}`\n : `${siteUrl}/page`\n\n const seoTitle = localMeta.title || data?.title || 'Page Title'\n const seoDescription = localMeta.description || data?.heroDescription || 'Your page description goes here. This is what search engines will display in search results.'\n const seoKeywords = localMeta.keywords || ''\n const ogImage = (data?.meta as any)?.ogImage || ''\n\n const charCount = (s: string) => s.length\n const truncate = (s: string, len: number) => s.length > len ? s.slice(0, len) + '…' : s\n\n\n // Initialise local state when modal opens\n useEffect(() => {\n if (seoOpen) {\n setLocalMeta({\n title: (data?.meta?.title as string) || '',\n description: (data?.meta?.description as string) || '',\n keywords: (data?.meta?.keywords as string) || '',\n })\n }\n }, [seoOpen, data])\n\n const dialogRef = useRef<HTMLDivElement>(null)\n const modalTitleId = 'seo-modal-title'\n\n useFocusTrap(seoOpen, {\n onEscape: () => setSeoOpen(false),\n containerRef: dialogRef,\n })\n\n const handleFieldChange = (field: keyof MetaField, value: string) => {\n setLocalMeta((prev) => ({ ...prev, [field]: value }))\n }\n\n const commitAndClose = async () => {\n editorUpdateData((prev) => ({\n ...prev,\n meta: { ...(prev.meta || {}), ...localMeta },\n }))\n if (onSave) await onSave()\n setSeoOpen(false)\n }\n\n const resetToDefaults = () => {\n setLocalMeta({ title: '', description: '', keywords: '' })\n }\n\n return (\n <AnimatePresence>\n {seoOpen && (\n <div className=\"fixed inset-0 z-[600] flex items-center justify-center p-6 bg-[var(--z-bg-modal)] backdrop-blur-sm\">\n <motion.div\n ref={dialogRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={modalTitleId}\n initial={{ scale: 0.95, opacity: 0 }}\n animate={{ scale: 1, opacity: 1 }}\n exit={{ scale: 0.95, opacity: 0 }}\n className={cn(\n 'w-full max-w-lg border rounded-none-none overflow-hidden shadow-2xl flex flex-col max-h-[85vh]',\n theme === 'dark'\n ? 'bg-[#0a0a0a] border-z-border'\n : 'bg-z-panel border-z-border',\n )}\n >\n {/* Header */}\n <div\n className={cn(\n 'p-6 border-b flex items-center justify-between',\n theme === 'dark' ? 'border-z-border' : 'border-z-border shadow-sm',\n )}\n >\n <h3\n id={modalTitleId}\n className={cn(\n 'text-lg font-semibold leading-none',\n theme === 'dark' ? 'text-z-primary' : 'text-z-primary',\n )}\n >\n SEO Meta\n </h3>\n <button\n type=\"button\"\n onClick={() => setSeoOpen(false)}\n aria-label=\"Close\"\n className=\"p-1 hover:text-z-secondary transition-colors\"\n >\n <X size={18} />\n </button>\n </div>\n\n {/* Body */}\n <div className=\"p-6 space-y-4 overflow-y-auto flex-1\">\n {/* Preview Tab Bar */}\n <div className=\"flex items-center gap-1 p-1 border border-z-border bg-z-panel rounded-none-none shrink-0\">\n {([\n { id: 'google', icon: Globe, label: 'Google' },\n { id: 'twitter', icon: Twitter, label: 'Twitter / X' },\n { id: 'facebook', icon: Facebook, label: 'Facebook' },\n ] as const).map((tab) => (\n <button\n key={tab.id}\n type=\"button\"\n onClick={() => setPreviewTab(tab.id)}\n aria-label={`${tab.label} preview`}\n className={cn(\n 'flex items-center gap-2 px-3 py-2 text-xs font-semibold transition-all border rounded-none-none flex-1 justify-center',\n previewTab === tab.id\n ? theme === 'dark'\n ? 'bg-z-panel/10 border-z-border text-z-primary'\n : 'bg-z-panel border-z-border text-z-primary shadow-sm'\n : theme === 'dark'\n ? 'text-z-secondary border-transparent hover:text-z-secondary'\n : 'text-z-muted border-transparent hover:text-z-secondary'\n )}\n >\n <tab.icon size={11} aria-hidden=\"true\" />\n {tab.label}\n </button>\n ))}\n </div>\n\n {/* Preview iframe area */}\n <div\n className={cn(\n 'rounded-none-none border overflow-hidden transition-all min-h-[180px]',\n theme === 'dark' ? 'bg-z-panel/5 border-z-border' : 'bg-z-input border-z-border'\n )}\n >\n {/* ── Google SERP Preview ── */}\n <AnimatePresence mode=\"wait\">\n {previewTab === 'google' && (\n <motion.div\n key=\"google\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n className=\"p-5\"\n >\n <div className=\"space-y-1\">\n <div className=\"text-xs text-z-secondary truncate\">{pageUrl}</div>\n <h2\n className=\"text-lg font-normal text-[#1a0dab] leading-5 truncate cursor-pointer hover:underline\"\n style={{ fontFamily: 'Arial, sans-serif' }}\n >\n {seoTitle}\n </h2>\n <p\n className=\"text-[13px] text-z-primary leading-4\"\n style={{ fontFamily: 'Arial, sans-serif' }}\n >\n {truncate(seoDescription, 160)}\n </p>\n {seoKeywords && (\n <div className=\"flex gap-1 flex-wrap mt-1.5\">\n {seoKeywords.split(',').slice(0, 4).map((kw, i) => (\n <span\n key={i}\n className=\"text-xs px-1.5 py-0.5 border border-z-border-strong rounded-none text-z-secondary\"\n >\n {kw.trim()}\n </span>\n ))}\n </div>\n )}\n </div>\n </motion.div>\n )}\n\n {/* ── Twitter/X Card Preview ── */}\n {previewTab === 'twitter' && (\n <motion.div\n key=\"twitter\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n className=\"p-5\"\n >\n <div\n className={cn(\n 'border rounded-none shadow-sm overflow-hidden max-w-[400px]',\n theme === 'dark' ? 'bg-[#15202b] border-z-border' : 'bg-z-panel border-z-border'\n )}\n >\n {/* Header */}\n <div className=\"flex items-center gap-3 px-3 py-2\">\n <div className=\"w-8 h-8 rounded-none-none bg-z-border flex items-center justify-center text-z-primary text-xs font-semibold shrink-0\">\n Z\n </div>\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-1\">\n <span className={cn('text-sm font-semibold', theme === 'dark' ? 'text-z-primary' : 'text-z-primary')}>\n Zenith CMS\n </span>\n <span className={cn('text-xs', 'text-z-secondary')}>@zenith·now</span>\n </div>\n <span className={cn('text-xs', 'text-z-secondary')}>{pageUrl}</span>\n </div>\n </div>\n {/* Card content */}\n <div className={cn('px-3 pb-2 text-sm leading-4 font-normal', theme === 'dark' ? 'text-z-primary' : 'text-z-primary')}>\n {seoTitle}\n </div>\n {/* Image */}\n <div\n className=\"w-full bg-cover bg-center border-t border-b\"\n style={{\n backgroundImage: `url(${ogImage})`,\n height: '157px',\n borderColor: 'var(--z-border)',\n }}\n />\n {/* Card footer */}\n </div>\n </motion.div>\n )}\n\n {/* ── Facebook Card Preview ── */}\n {previewTab === 'facebook' && (\n <motion.div\n key=\"facebook\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n className=\"p-5\"\n >\n <div\n className={cn(\n 'border rounded-none shadow-sm overflow-hidden max-w-[400px]',\n theme === 'dark' ? 'bg-[#1c1e21] border-z-border' : 'bg-z-panel border-z-border'\n )}\n >\n {/* Image */}\n <div\n className=\"w-full bg-cover bg-center\"\n style={{\n backgroundImage: `url(${ogImage})`,\n height: '180px',\n }}\n />\n {/* Card body */}\n <div\n className={cn(\n 'p-3 border-t',\n theme === 'dark' ? 'bg-[#242526] border-z-border' : 'bg-z-input border-z-border'\n )}\n >\n <div className=\"text-xs font-semibold text-z-muted mb-1\">\n {siteUrl.replace(/^https?:\\/\\//, '')}\n </div>\n <div\n className={cn(\n 'text-[13px] font-bold leading-4 line-clamp-2 mb-1',\n 'text-z-primary'\n )}\n style={{ fontFamily: 'Helvetica, Arial, sans-serif' }}\n >\n {seoTitle}\n </div>\n <div\n className={cn(\n 'text-sm leading-3 line-clamp-2',\n theme === 'dark' ? 'text-z-muted' : 'text-z-secondary'\n )}\n style={{ fontFamily: 'Helvetica, Arial, sans-serif' }}\n >\n {truncate(seoDescription, 100)}\n </div>\n </div>\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n\n {/* SEO Fields */}\n {META_FIELDS.map((field) => (\n <div key={field} className=\"space-y-1.5\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <label\n htmlFor={`seo-${field}`}\n className=\"text-xs font-semibold text-z-secondary px-1\"\n >\n {humanize(field)}\n </label>\n <button\n type=\"button\"\n onClick={() => generateAIContent(field)}\n disabled={isGenerating[field]}\n title={`Auto-generate ${field} with AI`}\n className=\"text-z-muted hover:text-indigo-500 transition-colors disabled:opacity-50\"\n >\n {isGenerating[field] ? <Loader2 size={12} className=\"animate-spin\" /> : <Wand2 size={12} />}\n </button>\n </div>\n {field === 'description' && (\n <span className={cn(\n 'text-xs font-semibold ',\n charCount(localMeta.description) > 155\n ? 'text-rose-500'\n : 'text-z-secondary'\n )}>\n {charCount(localMeta.description)} / 155\n </span>\n )}\n {field === 'title' && (\n <span className={cn(\n 'text-xs font-semibold ',\n charCount(localMeta.title) > 60\n ? 'text-rose-500'\n : 'text-z-secondary'\n )}>\n {charCount(localMeta.title)} / 60\n </span>\n )}\n </div>\n {field === 'description' ? (\n <textarea\n id={`seo-${field}`}\n value={localMeta[field]}\n onChange={(e) =>\n handleFieldChange(field, e.target.value)\n }\n className={cn(\n 'w-full rounded-none-none py-3 px-4 text-xs font-semibold h-24 resize-none transition-all border',\n theme === 'dark'\n ? 'bg-z-hover border-z-border text-z-primary focus-visible:border-z-border/30'\n : 'bg-z-input border-z-border text-z-primary focus-visible:border-z-border/30',\n )}\n placeholder=\"Enter page description...\"\n />\n ) : (\n <input\n id={`seo-${field}`}\n type=\"text\"\n value={localMeta[field]}\n onChange={(e) =>\n handleFieldChange(field, e.target.value)\n }\n className={cn(\n 'w-full rounded-none-none py-3 px-4 text-xs font-semibold transition-all border',\n theme === 'dark'\n ? 'bg-z-hover border-z-border text-z-primary focus-visible:border-z-border/30'\n : 'bg-z-input border-z-border text-z-primary focus-visible:border-z-border/30',\n )}\n placeholder={field === 'title' ? 'Enter SEO title...' : 'Enter keywords (comma separated)...'}\n />\n )}\n </div>\n ))}\n </div>\n\n {/* Footer */}\n <div\n className={cn(\n 'p-4 border-t flex items-center justify-between shrink-0',\n theme === 'dark'\n ? 'border-z-border bg-z-panel'\n : 'border-z-border shadow-sm bg-[var(--z-bg-input)]',\n )}\n >\n <button\n type=\"button\"\n onClick={resetToDefaults}\n aria-label=\"Reset SEO fields\"\n className={cn(\n 'flex items-center gap-2 px-4 py-2 text-xs font-semibold rounded-none-none border transition-all',\n theme === 'dark'\n ? 'border-z-border text-z-muted hover:border-rose-500/20 hover:text-rose-400'\n : 'border-z-border text-z-secondary hover:border-rose-200 hover:text-rose-500',\n )}\n >\n <RotateCcw size={12} />\n Reset\n </button>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => setSeoOpen(false)}\n aria-label=\"Cancel and close\"\n className={cn(\n 'px-4 py-2 text-xs font-semibold rounded-none-none border transition-all',\n theme === 'dark'\n ? 'border-z-border text-z-muted hover:border-z-border hover:text-z-primary'\n : 'border-z-border text-z-secondary hover:border-z-border-strong hover:text-z-primary',\n )}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={commitAndClose}\n aria-label=\"Save SEO and close\"\n className=\"flex items-center gap-2 px-4 py-2 bg-z-accent text-z-primary text-xs font-semibold rounded-none-none hover:bg-z-border transition-all\"\n >\n <Save size={12} aria-hidden=\"true\" />\n Save & Close\n </button>\n </div>\n </div>\n </motion.div>\n </div>\n )}\n </AnimatePresence>\n )\n}\n","import React, { useRef } from 'react'\nimport { Layout, X, Trash2, Download } from 'lucide-react'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport { useTheme } from '../../../context/ThemeContext'\nimport { useEditorStore } from '../../../store/editorStore'\nimport { useModalStore } from '../../../store/modalStore'\nimport { cn } from '../../../lib/utils'\nimport { useFocusTrap } from '../../../hooks/useFocusTrap'\nimport { confirm } from '../../../store/confirmStore'\nimport { useShallow } from 'zustand/react/shallow'\n\ninterface TemplatesModalProps {\n selectedSections: Set<string>\n setSelectedSections: (s: Set<string>) => void\n applyTemplate: (template: any) => Promise<void>\n deleteTemplate: (templateId: string) => Promise<void>\n saveAsTemplate: (sectionIds: string[]) => Promise<void>\n}\n\nexport const TemplatesModal: React.FC<TemplatesModalProps> = ({\n selectedSections,\n setSelectedSections,\n applyTemplate,\n deleteTemplate,\n saveAsTemplate,\n}) => {\n const { theme } = useTheme()\n const { templates } = useEditorStore(useShallow(state => ({ templates: state.templates })))\n const { templatesOpen, setTemplatesOpen } = useModalStore(useShallow(state => ({ templatesOpen: state.templatesOpen, setTemplatesOpen: state.setTemplatesOpen })))\n\n const dialogRef = useRef<HTMLDivElement>(null)\n const modalTitleId = 'templates-modal-title'\n\n useFocusTrap(templatesOpen, {\n onEscape: () => setTemplatesOpen(false),\n containerRef: dialogRef\n })\n\n return (\n <AnimatePresence>\n {templatesOpen && (\n <div className=\"fixed inset-0 z-[600] flex items-center justify-center p-6 bg-[var(--z-bg-modal)] backdrop-blur-sm\">\n <motion.div\n ref={dialogRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={modalTitleId}\n initial={{ scale: 0.95, opacity: 0, y: 20 }}\n animate={{ scale: 1, opacity: 1, y: 0 }}\n exit={{ scale: 0.95, opacity: 0 }}\n className={cn(\n 'w-full max-w-2xl border rounded-none-none overflow-hidden shadow-2xl',\n theme === 'dark' ? 'bg-[#0a0a0a] border-z-border' : 'bg-z-panel border-z-border'\n )}\n >\n <div\n className={cn(\n 'p-6 border-b flex items-center justify-between',\n theme === 'dark' ? 'border-z-border' : 'border-z-border shadow-sm'\n )}\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"w-8 h-8 rounded-none-none bg-z-accent flex items-center justify-center text-z-primary\">\n <Layout size={16} />\n </div>\n <div>\n <h3\n id={modalTitleId}\n className=\"text-lg font-semibold leading-none text-z-secondary \"\n >\n Block Templates\n </h3>\n <p className=\"text-xs text-z-secondary\">\n Save & reuse component combinations\n </p>\n </div>\n </div>\n <button\n onClick={() => setTemplatesOpen(false)}\n aria-label=\"Close\"\n className=\"p-1 hover:text-z-secondary transition-colors\"\n style={{ color: theme === 'dark' ? '#fff' : '#000' }}\n >\n <X size={18} />\n </button>\n </div>\n\n <div className=\"p-6 max-h-[60vh] overflow-y-auto custom-editor-scrollbar\">\n {templates.length === 0 ? (\n <div className=\"py-12 text-center\">\n <Layout size={40} className=\"mx-auto mb-4 text-z-secondary\" />\n <p className=\"text-xs text-z-secondary font-semibold\">\n No saved templates yet\n </p>\n <p className=\"text-xs text-z-secondary mt-2\">\n Select blocks, then save as template from the context menu\n </p>\n </div>\n ) : (\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n {templates.map((template: any) => (\n <div\n key={template.id || template._id}\n className={cn(\n 'p-4 border rounded-none-none space-y-3 relative group',\n theme === 'dark'\n ? 'bg-z-panel border-z-border hover:border-z-border/30'\n : 'bg-z-input border-z-border hover:border-z-border-strong'\n )}\n >\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs font-semibold text-z-secondary\">\n {template.name}\n </span>\n <span className=\"text-xs text-z-secondary\">\n {template.content?.sections?.length || template.sections?.length || 0} blocks\n </span>\n </div>\n <div className=\"flex gap-2\">\n <button\n onClick={() => applyTemplate(template)}\n className=\"flex-1 py-2 bg-z-accent text-z-primary text-xs font-semibold rounded-none-none hover:bg-z-border transition-colors\"\n >\n Apply\n </button>\n <button\n onClick={async () => {\n if (!await confirm({ message: `Delete template \"${template.name}\"? This cannot be undone.` })) return\n deleteTemplate(template.id || template._id)\n setTemplatesOpen(false)\n setTimeout(() => setTemplatesOpen(true), 50)\n }}\n aria-label={`Delete template ${template.name}`}\n className={cn(\n 'p-2 border rounded-none-none transition-colors',\n theme === 'dark'\n ? 'border-z-border text-z-secondary hover:border-rose-500/30 hover:text-rose-500'\n : 'border-z-border text-z-muted hover:border-rose-300 hover:text-rose-500'\n )}\n >\n <Trash2 size={12} />\n </button>\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n\n {selectedSections.size > 0 && (\n <div className={cn(\n 'p-4 border-t flex items-center justify-between',\n theme === 'dark' ? 'border-z-border bg-z-panel' : 'border-z-border shadow-sm bg-[var(--z-bg-input)]/50'\n )}>\n <span className=\"text-xs text-z-secondary font-semibold\">\n {selectedSections.size} block{selectedSections.size > 1 ? 's' : ''} selected\n </span>\n <button\n onClick={() => {\n saveAsTemplate(Array.from(selectedSections))\n setSelectedSections(new Set())\n }}\n aria-label=\"Save selection as template\"\n className=\"flex items-center gap-2 px-4 py-2 bg-z-accent text-z-primary text-xs font-semibold rounded-none-none hover:bg-z-border transition-colors\"\n >\n <Download size={12} aria-hidden=\"true\" />\n Save as Template\n </button>\n </div>\n )}\n </motion.div>\n </div>\n )}\n </AnimatePresence>\n )\n}\n","import React, { useRef, useState, useEffect, useCallback } from 'react'\nimport { Link2, X, Search, GitBranch, Check } from 'lucide-react'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport { useTheme } from '../../../context/ThemeContext'\nimport { useEditorStore } from '../../../store/editorStore'\nimport { useModalStore } from '../../../store/modalStore'\nimport { cn } from '../../../lib/utils'\nimport { useFocusTrap } from '../../../hooks/useFocusTrap'\nimport api from '../../../lib/api'\nimport toast from 'react-hot-toast'\nimport { useShallow } from 'zustand/react/shallow'\n\nexport const RelationsModal: React.FC = () => {\n const { theme } = useTheme()\n\n const {\n selectedRelations,\n setSelectedRelations,\n availableCollections,\n relationsSearch,\n setRelationsSearch,\n relationResults,\n setRelationResults,\n relationsField,\n fieldSettings,\n updateData: editorUpdateData,\n } = useEditorStore(useShallow(state => ({\n selectedRelations: state.selectedRelations,\n setSelectedRelations: state.setSelectedRelations,\n availableCollections: state.availableCollections,\n relationsSearch: state.relationsSearch,\n setRelationsSearch: state.setRelationsSearch,\n relationResults: state.relationResults,\n setRelationResults: state.setRelationResults,\n relationsField: state.relationsField,\n fieldSettings: state.fieldSettings,\n updateData: state.updateData,\n })))\n\n const { relationsModalOpen, setRelationsModalOpen } = useModalStore(useShallow(state => ({ relationsModalOpen: state.relationsModalOpen, setRelationsModalOpen: state.setRelationsModalOpen })))\n\n // Track the currently selected collection for visual feedback\n const [activeCollection, setActiveCollection] = useState<string | null>(null)\n // Debounced search to avoid API spam on every keystroke\n const [debouncedSearch, setDebouncedSearch] = useState('')\n const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n const fetchRelationResults = useCallback(async (collection: string, search?: string) => {\n try {\n const params: any = { limit: 20 }\n if (search) params.search = search\n const res = await api.get(`/${collection}`, { params })\n setRelationResults(res.data.data || [])\n } catch {\n toast.error('Failed to load relation entries')\n }\n }, [setRelationResults])\n\n // Initialize active collection from field settings\n useEffect(() => {\n if (!relationsModalOpen) return\n const relatedField = Object.values(fieldSettings).find(\n (f) => !!(f as any).relationTo\n )\n const col = (relatedField as any)?.relationTo\n if (col) {\n const collectionSlug = Array.isArray(col) ? col[0] : col\n setActiveCollection(collectionSlug)\n fetchRelationResults(collectionSlug, debouncedSearch)\n }\n \n }, [relationsModalOpen])\n\n // Debounce search input — wait 300ms after last keystroke before hitting API\n useEffect(() => {\n if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current)\n debounceTimerRef.current = setTimeout(() => {\n setDebouncedSearch(relationsSearch)\n if (activeCollection) fetchRelationResults(activeCollection, relationsSearch)\n }, 300)\n return () => {\n if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current)\n }\n }, [relationsSearch, activeCollection, fetchRelationResults])\n\n const handleCollectionSelect = (col: any) => {\n setActiveCollection(col.slug)\n fetchRelationResults(col.slug, debouncedSearch)\n }\n\n const toggleRelation = (itemId: string) => {\n const next = new Set(selectedRelations)\n if (next.has(itemId)) {\n next.delete(itemId)\n } else {\n next.add(itemId)\n }\n setSelectedRelations(next)\n }\n\n const applyRelations = () => {\n if (!relationsField) return\n editorUpdateData((prev) => {\n const newSections = [...prev.sections]\n const sIdx = newSections.findIndex((s) => s.id === relationsField.sectionId)\n if (sIdx !== -1) {\n newSections[sIdx].content[relationsField.fieldKey] = Array.from(selectedRelations)\n }\n return { ...prev, sections: newSections }\n })\n setRelationsModalOpen(false)\n toast.success(`${selectedRelations.size} items linked`)\n }\n\n const dialogRef = useRef<HTMLDivElement>(null)\n const modalTitleId = 'relations-modal-title'\n\n useFocusTrap(relationsModalOpen, {\n onEscape: () => setRelationsModalOpen(false),\n containerRef: dialogRef\n })\n\n return (\n <AnimatePresence>\n {relationsModalOpen && (\n <div className=\"fixed inset-0 z-[700]\">\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n onClick={() => setRelationsModalOpen(false)}\n className=\"absolute inset-0 bg-app/70 backdrop-blur-md\"\n />\n <motion.div\n ref={dialogRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={modalTitleId}\n initial={{ scale: 0.9, opacity: 0 }}\n animate={{ scale: 1, opacity: 1 }}\n exit={{ scale: 0.9, opacity: 0 }}\n className={cn(\n 'absolute inset-4 md:inset-10 border rounded-xl shadow-2xl flex flex-col overflow-hidden',\n theme === 'dark' \n ? 'bg-app/65 backdrop-blur-xl border-z-border'\n : 'bg-z-panel/95 backdrop-blur-xl border-z-border shadow-2xl'\n )}\n >\n {/* Header */}\n <div className={cn(\n 'p-6 border-b flex items-start justify-between shrink-0',\n theme === 'dark' ? 'border-z-border' : 'border-z-border'\n )}>\n <div className=\"flex items-center gap-3\">\n <div className={cn(\"w-10 h-10 rounded-lg flex items-center justify-center border\", theme === 'dark' ? 'bg-z-panel/10 border-z-border' : 'bg-[var(--z-bg-hover)] border-z-border')}>\n <Link2 size={18} className={theme === 'dark' ? \"text-z-primary\" : \"text-z-primary\"} />\n </div>\n <div>\n <h2\n id={modalTitleId}\n className={cn(\"text-lg font-semibold\", theme === 'dark' ? \"text-z-primary\" : \"text-z-primary\")}\n >\n Content Relations\n </h2>\n <p className={cn(\"text-xs font-bold\", theme === 'dark' ? \"text-z-muted\" : \"text-z-muted\")}>\n Connect entries from other collections\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-z-muted font-mono\">\n {selectedRelations.size} selected\n </span>\n <button\n type=\"button\"\n onClick={() => setRelationsModalOpen(false)}\n aria-label=\"Close\"\n className={cn(\n 'p-2 rounded-xl border transition-all',\n theme === 'dark' ? 'bg-z-panel/5 border-z-border text-z-primary hover:bg-[var(--z-bg-hover)]' : 'bg-[var(--z-bg-input)] border-z-border text-z-secondary hover:bg-[var(--z-bg-hover)]'\n )}\n >\n <X size={16} />\n </button>\n </div>\n </div>\n\n {/* Collection Selector */}\n <div className={cn(\n 'p-4 border-b flex gap-2 overflow-x-auto',\n theme === 'dark' ? 'border-z-border bg-z-panel/5' : 'border-z-border bg-[var(--z-bg-input)]/50'\n )}>\n {availableCollections.map((col) => {\n const isActive = activeCollection === col.slug\n return (\n <button\n key={col.slug}\n type=\"button\"\n onClick={() => handleCollectionSelect(col)}\n className={cn(\n 'px-3 py-1.5 text-xs font-semibold rounded-lg border shrink-0 transition-all',\n isActive\n ? theme === 'dark' ? 'bg-z-panel/20 border-z-border text-z-primary' : 'bg-[var(--z-border)] border-[var(--z-border-strong)] text-z-primary'\n : theme === 'dark' ? 'border-z-border text-z-muted hover:border-z-border hover:text-z-primary' : 'border-z-border text-z-muted hover:border-[var(--z-border-strong)] hover:text-z-primary'\n )}\n >\n {col.label || col.slug}\n </button>\n )\n })}\n </div>\n\n {/* Search */}\n <div className=\"p-4 shrink-0\">\n <div className=\"relative\">\n <Search size={14} className=\"absolute left-4 top-1/2 -translate-y-1/2 text-z-muted\" />\n <input\n type=\"text\"\n aria-label=\"Search relation entries\"\n placeholder=\"Search entries to link...\"\n value={relationsSearch}\n onChange={(e) => setRelationsSearch(e.target.value)}\n className={cn(\n 'w-full rounded-lg py-3 pl-12 pr-4 text-xs font-bold border transition-colors',\n theme === 'dark' ? 'bg-app/20 border-z-border text-z-primary focus-visible:border-z-border' : 'bg-z-panel border-z-border text-z-primary focus-visible:border-z-border'\n )}\n />\n </div>\n </div>\n\n {/* Results */}\n <div className=\"flex-1 overflow-y-auto p-4 custom-editor-scrollbar\">\n {!activeCollection ? (\n <div className=\"flex flex-col items-center justify-center h-full gap-4\">\n <GitBranch size={40} className={cn(\"opacity-20\", theme === 'dark' ? \"text-z-primary\" : \"text-z-primary\")} />\n <p className={cn(\"text-xs font-semibold text-center\", theme === 'dark' ? \"text-z-muted\" : \"text-z-muted\")}>\n Select a collection above to view entries\n </p>\n </div>\n ) : relationResults.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center h-full gap-4\">\n <Search size={32} className={cn(\"opacity-20\", theme === 'dark' ? \"text-z-primary\" : \"text-z-primary\")} />\n <p className={cn(\"text-xs font-semibold text-center\", theme === 'dark' ? \"text-z-muted\" : \"text-z-muted\")}>\n {debouncedSearch ? 'No entries match your search' : 'No entries found in this collection'}\n </p>\n </div>\n ) : (\n <div className=\"space-y-1\">\n {relationResults.map((item: any) => (\n <button\n key={item.id || item._id}\n type=\"button\"\n onClick={() => toggleRelation(item.id || item._id)}\n className={cn(\n 'w-full flex items-center gap-3 p-3 rounded-lg border transition-all text-left',\n selectedRelations.has(item.id || item._id)\n ? theme === 'dark' ? 'bg-z-panel/10 border-z-border' : 'bg-[var(--z-bg-hover)] border-[var(--z-border-strong)]'\n : theme === 'dark' ? 'bg-app/20 border-z-border hover:border-z-border' : 'bg-z-panel border-z-border hover:border-[var(--z-border-strong)]'\n )}\n >\n <div className={cn(\n 'w-5 h-5 rounded border-2 flex items-center justify-center shrink-0 transition-all',\n selectedRelations.has(item.id || item._id)\n ? 'bg-indigo-500 border-indigo-500'\n : theme === 'dark' ? 'border-z-border' : 'border-[var(--z-border-strong)] bg-[var(--z-bg-input)]'\n )}>\n {selectedRelations.has(item.id || item._id) && <Check size={12} className=\"text-z-primary\" />}\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className={cn(\"text-xs font-semibold truncate\", theme === 'dark' ? \"text-z-primary\" : \"text-z-primary\")}>\n {item.title || item.name || item.headline || item.id}\n </p>\n <p className={cn(\"text-sm font-mono truncate\", theme === 'dark' ? \"text-z-muted\" : \"text-z-muted\")}>\n ID: {item.id || item._id}\n </p>\n </div>\n <span className={cn(\"text-sm font-mono shrink-0\", theme === 'dark' ? \"text-z-muted\" : \"text-z-muted\")}>\n {item._status || item.status || 'active'}\n </span>\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div className={cn(\n 'p-4 border-t flex items-center justify-between',\n theme === 'dark' ? 'border-z-border bg-app/20' : 'border-z-border bg-[var(--z-bg-input)]/50'\n )}>\n <span className={cn(\"text-xs font-bold\", theme === 'dark' ? \"text-z-muted\" : \"text-z-muted\")}>\n Click entries to select/deselect for relation\n </span>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => setRelationsModalOpen(false)}\n className={cn(\n 'px-4 py-2 text-xs font-semibold rounded-lg border transition-all',\n theme === 'dark' ? 'border-z-border text-z-muted hover:border-z-border hover:text-z-primary' : 'border-z-border text-z-secondary hover:border-z-border hover:text-z-primary'\n )}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={applyRelations}\n disabled={selectedRelations.size === 0}\n className=\"px-4 py-2 bg-z-accent text-z-logo-text text-xs font-semibold rounded-lg hover:opacity-80 transition-all disabled:opacity-50\"\n >\n Link {selectedRelations.size} items\n </button>\n </div>\n </div>\n </motion.div>\n </div>\n )}\n </AnimatePresence>\n )\n}\n","import React, { useRef, useMemo } from 'react'\nimport { X, Image as ImageIcon, Search, Upload, Loader2, File } from 'lucide-react'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport { useTheme } from '../../../context/ThemeContext'\nimport { useEditorStore } from '../../../store/editorStore'\nimport { useModalStore } from '../../../store/modalStore'\nimport { cn } from '../../../lib/utils'\nimport { useFocusTrap } from '../../../hooks/useFocusTrap'\nimport api from '../../../lib/api'\nimport toast from 'react-hot-toast'\n\nimport { useShallow } from 'zustand/react/shallow'\n\nconst fileFullUrl = (file: any): string => {\n if (!file.url) return ''\n if (file.url.startsWith('http')) return file.url\n return `${(import.meta.env.VITE_API_URL || '').replace('/api/v1', '')}${file.url}`\n}\n\nexport const MediaLibraryModal: React.FC = () => {\n const { theme } = useTheme()\n const { mediaLibraryOpen, setMediaLibraryOpen } = useModalStore(useShallow(state => ({ mediaLibraryOpen: state.mediaLibraryOpen, setMediaLibraryOpen: state.setMediaLibraryOpen })))\n const { mediaAssets,\n setMediaAssets,\n mediaSearch,\n setMediaSearch,\n mediaTypeFilter,\n setMediaTypeFilter,\n mediaLoading,\n setMediaLoading,\n } = useEditorStore(useShallow(state => ({ mediaAssets: state.mediaAssets, setMediaAssets: state.setMediaAssets, mediaSearch: state.mediaSearch, setMediaSearch: state.setMediaSearch, mediaTypeFilter: state.mediaTypeFilter, setMediaTypeFilter: state.setMediaTypeFilter, mediaLoading: state.mediaLoading, setMediaLoading: state.setMediaLoading })))\n\n\n\n React.useEffect(() => {\n if (!mediaLibraryOpen) return\n setMediaSearch('')\n setMediaTypeFilter('all')\n setMediaLoading(true)\n api.get('/media')\n .then((res) => {\n setMediaAssets(res.data.data || [])\n })\n .catch(() => {})\n .finally(() => {\n setMediaLoading(false)\n })\n }, [mediaLibraryOpen, setMediaAssets, setMediaLoading, setMediaSearch, setMediaTypeFilter])\n\n // Pre-filter assets to avoid duplicating filter logic in render\n const filteredAssets = useMemo(() => {\n return mediaAssets.filter((file) => {\n const matchSearch = !mediaSearch ||\n file.name?.toLowerCase().includes(mediaSearch.toLowerCase()) ||\n file.alt?.toLowerCase().includes(mediaSearch.toLowerCase()) ||\n file.url?.toLowerCase().includes(mediaSearch.toLowerCase())\n const fileType = file.mimetype || ''\n const matchType = mediaTypeFilter === 'all' ||\n (mediaTypeFilter === 'image' && fileType.startsWith('image/')) ||\n (mediaTypeFilter === 'video' && fileType.startsWith('video/')) ||\n (mediaTypeFilter === 'audio' && fileType.startsWith('audio/')) ||\n (mediaTypeFilter === 'application/pdf' && fileType.includes('pdf')) ||\n (mediaTypeFilter === 'other' && !fileType.startsWith('image/') && !fileType.startsWith('video/') && !fileType.startsWith('audio/') && !fileType.includes('pdf'))\n return matchSearch && matchType\n })\n }, [mediaAssets, mediaSearch, mediaTypeFilter])\n\n const dialogRef = useRef<HTMLDivElement>(null)\n const modalTitleId = 'media-library-modal-title'\n\n useFocusTrap(mediaLibraryOpen, {\n onEscape: () => setMediaLibraryOpen(false),\n containerRef: dialogRef\n })\n\n return (\n <AnimatePresence>\n {mediaLibraryOpen && (\n <div className=\"fixed inset-0 z-[900] flex items-center justify-center p-4 md:p-10\">\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n onClick={() => setMediaLibraryOpen(false)}\n className=\"absolute inset-0 bg-[var(--z-bg-modal)] backdrop-blur-md\"\n />\n <motion.div\n ref={dialogRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={modalTitleId}\n initial={{ scale: 0.95, opacity: 0 }}\n animate={{ scale: 1, opacity: 1 }}\n exit={{ scale: 0.95, opacity: 0 }}\n className={cn(\n 'w-full max-w-6xl border rounded-none-none overflow-hidden shadow-2xl flex flex-col h-[85vh]',\n theme === 'dark'\n ? 'bg-[#0a0a0a] border-z-border'\n : 'bg-z-panel border-z-border'\n )}\n >\n <div\n className={cn(\n 'p-6 border-b flex items-center justify-between shrink-0',\n theme === 'dark' ? 'border-z-border' : 'border-z-border shadow-sm',\n )}\n >\n <h3\n id={modalTitleId}\n className={cn(\n 'text-lg font-semibold leading-none',\n theme === 'dark' ? 'text-z-primary' : 'text-z-primary',\n )}\n >\n Asset Registry\n </h3>\n <button\n type=\"button\"\n onClick={() => setMediaLibraryOpen(false)}\n aria-label=\"Close\"\n className={cn(\n 'p-1 transition-colors',\n theme === 'dark' ? 'text-z-muted hover:text-z-secondary ' : 'text-z-secondary hover:text-z-secondary'\n )}\n >\n <X size={18} />\n </button>\n </div>\n\n {/* Toolbar: search, filters, upload */}\n <div className={cn(\n 'flex items-center gap-4 px-8 py-4 border-b shrink-0',\n theme === 'dark' ? 'border-z-border' : 'border-z-border shadow-sm'\n )}>\n <div className=\"relative group flex-1\">\n <Search\n className={cn(\n 'absolute left-4 top-1/2 -translate-y-1/2 transition-colors',\n theme === 'dark' ? 'text-z-secondary group-focus-within:text-z-secondary' : 'text-z-muted group-focus-within:text-z-secondary'\n )}\n size={15}\n />\n <input\n type=\"text\"\n aria-label=\"Search assets\"\n placeholder=\"Search assets by name or type...\"\n value={mediaSearch}\n onChange={(e) => setMediaSearch(e.target.value)}\n className={cn(\n 'w-full rounded-none-none pl-12 pr-4 py-3 text-xs font-bold transition-all',\n theme === 'dark'\n ? 'bg-z-hover border border-z-border text-z-primary placeholder:text-z-secondary focus-visible:border-z-border/40 focus-visible:bg-z-panel/[0.05]'\n : 'bg-[var(--z-bg-input)] border border-z-border text-z-primary placeholder:text-z-muted focus-visible:border-z-border focus-visible:bg-z-panel'\n )}\n />\n </div>\n\n {/* Type filter */}\n <select\n aria-label=\"Filter by file type\"\n value={mediaTypeFilter}\n onChange={(e) => setMediaTypeFilter(e.target.value)}\n className={cn(\n 'rounded-none-none border py-3 px-4 text-xs font-semibold transition-all',\n theme === 'dark'\n ? 'bg-z-hover border-z-border text-z-muted focus-visible:border-z-border/40'\n : 'bg-[var(--z-bg-hover)] border-z-border text-z-secondary focus-visible:border-z-border'\n )}\n >\n <option value=\"all\">All Types</option>\n <option value=\"image\">Images</option>\n <option value=\"video\">Video</option>\n <option value=\"audio\">Audio</option>\n <option value=\"application/pdf\">PDF</option>\n <option value=\"other\">Other</option>\n </select>\n\n {/* Upload button */}\n <label className={cn(\n 'flex items-center gap-2 px-5 py-3 rounded-none-none border cursor-pointer transition-all text-xs font-semibold ',\n theme === 'dark'\n ? 'bg-z-accent/20 border-z-border/30 text-z-secondary hover:bg-z-accent/30 hover:border-z-border/50'\n : 'bg-z-input border-z-border text-z-primary hover:bg-[var(--z-bg-hover)] hover:border-z-border-strong'\n )}>\n <Upload size={14} />\n Ingest\n <input\n type=\"file\"\n className=\"hidden\"\n onChange={async (e) => {\n const file = e.target.files?.[0]\n if (!file) return\n const formData = new FormData()\n formData.append('file', file)\n try {\n const res = await api.post('/upload', formData, {\n headers: { 'Content-Type': 'multipart/form-data' },\n })\n setMediaAssets([res.data.data, ...mediaAssets])\n toast.success(`\"${file.name}\" ingested`)\n } catch {\n toast.error('Upload failed')\n }\n }}\n />\n </label>\n </div>\n\n {/* Asset Grid */}\n <div className=\"flex-1 overflow-y-auto p-6\">\n {mediaLoading ? (\n <div className=\"flex flex-col items-center justify-center h-full gap-5\">\n <Loader2 size={36} className=\"animate-spin text-z-secondary \" />\n <span className=\"text-xs font-semibold text-z-secondary animate-pulse\">\n Loading Registry...\n </span>\n </div>\n ) : (\n (() => {\n if (mediaAssets.length === 0) {\n return (\n <div className=\"flex flex-col items-center justify-center h-full gap-4 text-center\">\n <div className={cn(\n 'w-16 h-16 rounded-none-none border-2 border-dashed flex items-center justify-center',\n theme === 'dark' ? 'border-z-border text-z-secondary' : 'border-z-border text-z-secondary'\n )}>\n <ImageIcon size={28} />\n </div>\n <p className={cn(\n 'text-xs font-semibold ',\n 'text-z-secondary'\n )}>\n No assets in the registry\n </p>\n <span className={cn(\n 'text-xs font-bold ',\n theme === 'dark' ? 'text-z-primary' : 'text-z-secondary'\n )}>\n Upload files using the ingest button above\n </span>\n </div>\n )\n }\n\n if (filteredAssets.length === 0) {\n return (\n <div className=\"flex flex-col items-center justify-center h-40 gap-3\">\n <Search size={28} className={theme === 'dark' ? 'text-z-primary' : 'text-z-secondary'} />\n <span className={cn(\n 'text-xs font-semibold ',\n 'text-z-secondary'\n )}>\n No assets match your filter\n </span>\n </div>\n )\n }\n\n return (\n <div className=\"grid grid-cols-1 md:grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 xl:grid-cols-8 gap-4\">\n {filteredAssets.map((file, i) => {\n const isImage = (file.mimetype || '').startsWith('image/')\n const url = fileFullUrl(file)\n return (\n <motion.div\n key={file._id || i}\n role=\"button\"\n tabIndex={0}\n aria-label={`Asset: ${file.name}${file.mimetype ? `, ${file.mimetype.split('/')[1]?.toUpperCase()}` : ''}. Press Enter to copy URL.`}\n initial={{ opacity: 0, scale: 0.9 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={{ delay: Math.min(i * 0.015, 1) }}\n className=\"group relative aspect-square border rounded-none-none overflow-hidden cursor-pointer transition-all hover:scale-[1.04] hover:z-10\"\n onClick={() => {\n navigator.clipboard.writeText(url).catch(() => {})\n toast.success('URL copied to clipboard')\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n navigator.clipboard.writeText(url).catch(() => {})\n toast.success('URL copied to clipboard')\n }\n }}\n >\n {isImage ? (\n <img\n src={url}\n alt={file.alt || file.name || ''}\n className=\"w-full h-full object-cover\"\n loading=\"lazy\"\n />\n ) : (\n <div className={cn(\n 'w-full h-full flex flex-col items-center justify-center gap-2',\n theme === 'dark' ? 'bg-z-hover' : 'bg-[var(--z-bg-input)]'\n )}>\n <File size={24} className={'text-z-secondary'} />\n <span className={cn(\n 'text-sm font-semibold text-center px-1 truncate w-full',\n 'text-z-secondary'\n )}>\n {(file.mimetype || 'file').split('/')[1]?.toUpperCase().slice(0, 4) || 'FILE'}\n </span>\n </div>\n )}\n {/* Hover overlay */}\n <div className={cn(\n 'absolute inset-0 flex flex-col items-start justify-end p-2 opacity-0 group-hover:opacity-100 transition-opacity',\n theme === 'dark' ? 'bg-gradient-to-t from-[var(--z-bg-panel)] via-[var(--z-bg-base)]' : 'bg-gradient-to-t from-[var(--z-bg-panel)] via-[var(--z-bg-base)]'\n )}>\n <p className=\"text-z-primary text-xs font-semibold truncate w-full leading-tight\">\n {file.name}\n </p>\n {file.size && (\n <span className=\"text-z-primary/50 text-xs font-bold\">\n {(file.size / 1024).toFixed(1)} KB\n </span>\n )}\n {/* Copy URL button */}\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n navigator.clipboard.writeText(url)\n toast.success('URL copied')\n }}\n className={cn(\n 'mt-1.5 px-2 py-1 rounded-none-none border text-xs font-semibold transition-all',\n theme === 'dark'\n ? 'border-z-border text-z-primary/70 hover:border-z-border hover:text-z-primary bg-z-hover'\n : 'border-z-border text-z-primary/80 hover:border-z-border0 hover:text-z-primary bg-z-panel/10'\n )}\n >\n Copy URL\n </button>\n {/* Select for editor button */}\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation()\n window.dispatchEvent(new CustomEvent('zenith:media-selected', {\n detail: {\n url: url,\n alt: file.alt || file.name || '',\n mimeType: file.mimetype || 'image/jpeg',\n width: (file as any).width,\n height: (file as any).height,\n },\n }))\n setMediaLibraryOpen(false)\n toast.success('Media selected')\n }}\n className={cn(\n 'mt-1 px-2 py-1 rounded-none-none border text-xs font-semibold transition-all',\n 'border-z-border/40 text-z-secondary hover:border-z-border hover:text-z-secondary bg-z-panel'\n )}\n >\n Select\n </button>\n </div>\n {/* Type badge */}\n <div className={cn(\n 'absolute top-1.5 left-1.5 px-1.5 py-0.5 text-sm font-semibold border rounded-none-none',\n theme === 'dark'\n ? 'bg-app/60 border-z-border text-z-muted'\n : 'bg-z-panel/80 border-z-border text-z-secondary'\n )}>\n {(file.mimetype || 'file').split('/')[1]?.toUpperCase().slice(0, 4) || 'FILE'}\n </div>\n </motion.div>\n )\n })}\n </div>\n )\n })()\n )}\n </div>\n\n {/* Footer */}\n <div className={cn(\n 'flex items-center justify-between px-8 py-3 border-t shrink-0',\n theme === 'dark' ? 'border-z-border bg-z-panel/[0.015]' : 'border-z-border shadow-sm bg-[var(--z-bg-input)]'\n )}>\n <span className={cn(\n 'text-xs font-bold ',\n theme === 'dark' ? 'text-z-secondary' : 'text-z-muted'\n )}>\n Click any asset to copy its URL • Supports images, video, audio, PDF\n </span>\n <button\n type=\"button\"\n onClick={() => setMediaLibraryOpen(false)}\n aria-label=\"Close media library\"\n className={cn(\n 'px-5 py-2 text-xs font-semibold rounded-none-none border transition-all',\n theme === 'dark'\n ? 'border-z-border text-z-muted hover:border-z-border hover:text-z-primary'\n : 'border-z-border text-z-secondary hover:border-z-border-strong hover:text-z-primary'\n )}\n >\n Close\n </button>\n </div>\n </motion.div>\n </div>\n )}\n </AnimatePresence>\n )\n}\n","import React, { useRef, useState, useMemo } from 'react'\nimport { Layers, X, GripVertical, Layout, Trash2, PlusCircle, Box, Search } from 'lucide-react'\nimport { motion, AnimatePresence, Reorder, useDragControls } from 'framer-motion'\nimport { useTheme } from '../../../context/ThemeContext'\nimport { useEditorStore } from '../../../store/editorStore'\nimport { useShallow } from 'zustand/react/shallow'\nimport { useEditorBlocks } from '../../../context/BlockLibraryContext'\nimport { humanize, type PageData } from '../constants'\nimport { cn } from '../../../lib/utils'\nimport { useFocusTrap } from '../../../hooks/useFocusTrap'\n\ninterface DynamicZoneModalProps {\n dynamicZoneModalOpen: boolean\n setDynamicZoneModalOpen: (val: boolean) => void\n activeDynamicZone: { sectionId: string; fieldKey: string } | null\n addToDynamicZone: (componentType: string) => void\n removeFromDynamicZone: (index: number) => void\n onReorder?: (sectionId: string, fieldKey: string, newItems: any[]) => void\n}\n\ninterface DraggableItemProps {\n item: any\n idx: number\n theme: 'light' | 'dark'\n removeFromDynamicZone: (index: number) => void\n}\n\nconst DraggableItem: React.FC<DraggableItemProps> = ({ item, idx, theme, removeFromDynamicZone }) => {\n const dragControls = useDragControls()\n return (\n <Reorder.Item\n value={item}\n dragListener={false}\n dragControls={dragControls}\n as=\"div\"\n className={cn(\n 'flex items-center gap-3 p-3 rounded-none-none border group',\n theme === 'dark'\n ? 'bg-z-hover border-z-border hover:border-z-border/20'\n : 'bg-z-input border-z-border hover:border-z-border'\n )}\n >\n <div\n onPointerDown={(e) => dragControls.start(e)}\n className=\"cursor-grab active:cursor-grabbing shrink-0\"\n >\n <GripVertical size={12} className=\"text-z-secondary\" />\n </div>\n <div className=\"w-6 h-6 rounded-none-none bg-z-panel flex items-center justify-center shrink-0\">\n <Layout size={12} className=\"text-z-secondary\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-xs font-semibold truncate\">\n {humanize(item.__component?.replace('content.', '') || item.__component || 'Component')}\n </p>\n </div>\n <button\n type=\"button\"\n onClick={() => removeFromDynamicZone(idx)}\n aria-label={`Remove component ${idx + 1}`}\n className=\"p-1 text-z-secondary hover:text-rose-500 transition-colors opacity-0 group-hover:opacity-100 shrink-0\"\n >\n <Trash2 size={12} aria-hidden=\"true\" />\n </button>\n </Reorder.Item>\n )\n}\n\nexport const DynamicZoneModal: React.FC<DynamicZoneModalProps> = ({\n dynamicZoneModalOpen,\n setDynamicZoneModalOpen,\n activeDynamicZone,\n addToDynamicZone,\n removeFromDynamicZone,\n onReorder,\n}) => {\n const { theme } = useTheme()\n const { data: dataRaw } = useEditorStore(useShallow(state => ({ data: state.data })))\n const data = dataRaw as PageData | null\n const BLOCK_LIBRARY = useEditorBlocks()\n\n const [componentSearch, setComponentSearch] = useState('')\n\n const dialogRef = useRef<HTMLDivElement>(null)\n const modalTitleId = 'dynamic-zone-modal-title'\n\n useFocusTrap(dynamicZoneModalOpen, {\n onEscape: () => setDynamicZoneModalOpen(false),\n containerRef: dialogRef\n })\n\n const filteredBlocks = useMemo(() => {\n if (!componentSearch.trim()) return BLOCK_LIBRARY\n const q = componentSearch.toLowerCase()\n return BLOCK_LIBRARY.filter(\n (b) => b.title.toLowerCase().includes(q) || b.type.toLowerCase().includes(q) || b.description.toLowerCase().includes(q)\n )\n }, [BLOCK_LIBRARY, componentSearch])\n\n return (\n <AnimatePresence>\n {dynamicZoneModalOpen && (\n <div className=\"fixed inset-0 z-[700]\">\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n onClick={() => setDynamicZoneModalOpen(false)}\n className=\"absolute inset-0 bg-app/70 backdrop-blur-md\"\n />\n <motion.div\n ref={dialogRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={modalTitleId}\n initial={{ scale: 0.9, opacity: 0 }}\n animate={{ scale: 1, opacity: 1 }}\n exit={{ scale: 0.9, opacity: 0 }}\n className={cn(\n 'absolute right-0 top-0 bottom-0 w-[450px] border-l shadow-2xl flex flex-col overflow-hidden',\n theme === 'dark' ? 'bg-[#060606] border-z-border' : 'bg-z-panel border-z-border'\n )}\n >\n <div className={cn(\n 'p-6 border-b flex items-center justify-between',\n theme === 'dark' ? 'border-z-border' : 'border-z-border shadow-sm'\n )}>\n <div className=\"flex items-center gap-3\">\n <div className=\"w-8 h-8 rounded-none-none bg-z-accent/20 border border-z-border/30 flex items-center justify-center\">\n <Layers size={16} className=\"text-z-secondary\" />\n </div>\n <div>\n <h2\n id={modalTitleId}\n className=\"text-base font-semibold text-z-secondary leading-none\"\n >\n Dynamic Zone\n </h2>\n <p className=\"text-xs text-z-secondary font-bold mt-1\">\n Add/arrange component blocks\n </p>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => setDynamicZoneModalOpen(false)}\n aria-label=\"Close\"\n className={cn(\n 'p-1.5 rounded-none-none border transition-all',\n theme === 'dark'\n ? 'bg-z-hover border-z-border hover:bg-z-panel hover:text-z-primary'\n : 'bg-[var(--z-bg-hover)] border-z-border hover:bg-app hover:text-z-primary'\n )}\n >\n <X size={14} />\n </button>\n </div>\n\n <div className=\"flex-1 overflow-y-auto p-4 custom-editor-scrollbar space-y-4\">\n {/* Current Zone Items */}\n {activeDynamicZone && (\n (() => {\n const section = data?.sections?.find((s) => s.id === activeDynamicZone.sectionId)\n const zone = section?.content?.[activeDynamicZone.fieldKey] || []\n return zone.length > 0 ? (\n <div className=\"space-y-2\">\n <p className=\"text-xs font-semibold text-z-secondary px-1\">\n Zone Contents ({zone.length})\n </p>\n <Reorder.Group\n axis=\"y\"\n values={zone}\n onReorder={(newItems) => onReorder?.(activeDynamicZone.sectionId, activeDynamicZone.fieldKey, newItems)}\n className=\"space-y-2\"\n >\n {zone.map((item: any, idx: number) => (\n <DraggableItem\n key={item.id || idx}\n item={item}\n idx={idx}\n theme={theme}\n removeFromDynamicZone={removeFromDynamicZone}\n />\n ))}\n </Reorder.Group>\n </div>\n ) : (\n <div className=\"text-center py-6\">\n <Box size={24} className=\"mx-auto text-z-secondary mb-2\" />\n <p className=\"text-xs text-z-secondary font-bold\">\n Zone is empty — add components below\n </p>\n </div>\n )\n })()\n )}\n\n {/* Add Components */}\n <div className=\"space-y-2\">\n <p className=\"text-xs font-semibold text-z-secondary px-1\">\n Available Components\n </p>\n <div className=\"relative\">\n <Search size={12} className={cn(\n 'absolute left-3 top-1/2 -translate-y-1/2',\n 'text-z-secondary'\n )} />\n <input\n type=\"text\"\n value={componentSearch}\n onChange={(e) => setComponentSearch(e.target.value)}\n placeholder=\"Search components...\"\n className={cn(\n 'w-full pl-8 pr-3 py-2 text-xs font-bold border rounded-none-none bg-transparent',\n theme === 'dark'\n ? 'border-z-border text-z-primary placeholder:text-z-muted focus:border-z-border/30'\n : 'border-z-border text-z-primary placeholder:text-z-muted focus:border-z-border/30'\n )}\n />\n </div>\n <div className=\"max-h-64 overflow-y-auto space-y-1.5 custom-editor-scrollbar\">\n {filteredBlocks.length === 0 ? (\n <p className={cn('text-xs font-bold text-center py-4', 'text-z-secondary')}>\n No components match your search\n </p>\n ) : (\n filteredBlocks.map((block) => {\n const Icon = block.icon\n return (\n <button\n key={block.type}\n type=\"button\"\n onClick={() => addToDynamicZone(block.type)}\n aria-label={`Add ${block.title} to dynamic zone`}\n className={cn(\n 'w-full flex items-center gap-3 p-3 rounded-none-none border transition-all text-left',\n theme === 'dark'\n ? 'bg-z-panel border-z-border hover:border-z-border/30 hover:bg-z-hover'\n : 'bg-z-input border-z-border hover:border-z-border-strong hover:bg-[var(--z-bg-input)]'\n )}\n >\n <div className=\"w-8 h-8 rounded-none-none bg-z-panel flex items-center justify-center shrink-0\">\n <Icon size={14} className=\"text-z-secondary\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-xs font-semibold truncate\">{block.title}</p>\n <p className={cn('text-sm font-bold truncate', 'text-z-secondary')}>\n {block.description}\n </p>\n </div>\n <PlusCircle size={14} aria-hidden=\"true\" className=\"text-z-secondary opacity-50 shrink-0\" />\n </button>\n )\n })\n )}\n </div>\n </div>\n </div>\n </motion.div>\n </div>\n )}\n </AnimatePresence>\n )\n}\n","import { create } from 'zustand'\n\nexport type WorkflowStatus = 'draft' | 'in_review' | 'changes_requested' | 'scheduled' | 'published'\nexport type PublishStatus = 'draft' | 'published'\n\ninterface WorkflowState {\n workflowStatus: WorkflowStatus\n publishStatus: PublishStatus\n workflowReviewers: string[]\n scheduledAt: string\n workflowComments: any[]\n releases: any[]\n activeRelease: any\n\n setWorkflowStatus: (status: WorkflowStatus) => void\n setPublishStatus: (status: PublishStatus) => void\n setWorkflowReviewers: (reviewers: string[]) => void\n setScheduledAt: (date: string) => void\n setWorkflowComments: (comments: any[]) => void\n setReleases: (releases: any[]) => void\n setActiveRelease: (release: any) => void\n}\n\nexport const useWorkflowStore = create<WorkflowState>((set) => ({\n workflowStatus: 'draft',\n publishStatus: 'draft',\n workflowReviewers: [],\n scheduledAt: '',\n workflowComments: [],\n releases: [],\n activeRelease: null,\n\n setWorkflowStatus: (workflowStatus) => set({ workflowStatus }),\n setPublishStatus: (publishStatus) => set({ publishStatus }),\n setWorkflowReviewers: (workflowReviewers) => set({ workflowReviewers }),\n setScheduledAt: (scheduledAt) => set({ scheduledAt }),\n setWorkflowComments: (workflowComments) => set({ workflowComments }),\n setReleases: (releases) => set({ releases }),\n setActiveRelease: (activeRelease) => set({ activeRelease }),\n}))\n","import { create } from 'zustand'\n\nexport interface Locale {\n code: string\n name: string\n flag: string\n default?: boolean\n}\n\ninterface I18nState {\n i18nEnabled: boolean\n currentLocale: string\n availableLocales: Locale[]\n // Backend-compatible format: { fieldKey: { locale: value } }\n // e.g. { title: { en: \"Hello\", es: \"Hola\" } }\n translations: Record<string, Record<string, string>>\n\n setI18nEnabled: (enabled: boolean) => void\n setCurrentLocale: (locale: string) => void\n setTranslations: (translations: Record<string, Record<string, string>>) => void\n updateTranslation: (fieldKey: string, locale: string, value: string) => void\n /** Converts from legacy flat locale-first format: { locale: { fieldKey: value } } */\n importLegacyFormat: (legacy: Record<string, Record<string, string>>) => void\n /** Returns the value for a field + current locale, or the default locale fallback */\n getLocalizedValue: (fieldKey: string) => string | undefined\n}\n\nexport const useI18nStore = create<I18nState>((set, get) => ({\n i18nEnabled: false,\n currentLocale: 'en',\n availableLocales: [\n { code: 'en', name: 'English', flag: '', default: true },\n { code: 'es', name: 'Español', flag: '', default: false },\n { code: 'fr', name: 'Français', flag: '', default: false },\n { code: 'de', name: 'Deutsch', flag: '', default: false },\n { code: 'zh', name: '中文', flag: '', default: false },\n { code: 'ja', name: '日本語', flag: '', default: false },\n ],\n translations: {},\n\n setI18nEnabled: (i18nEnabled) => set({ i18nEnabled }),\n setCurrentLocale: (currentLocale) => set({ currentLocale }),\n setTranslations: (translations) => set({ translations }),\n\n /** Set a specific locale value for a field — merges into the existing locale map */\n updateTranslation: (fieldKey, locale, value) =>\n set((state) => ({\n translations: {\n ...state.translations,\n [fieldKey]: {\n ...(state.translations[fieldKey] || {}),\n [locale]: value,\n },\n },\n })),\n\n /** Convert from legacy { en: { \"title\": \"Hello\" } } → { title: { en: \"Hello\" } } */\n importLegacyFormat: (legacy) =>\n set(() => {\n const converted: Record<string, Record<string, string>> = {}\n for (const [locale, fieldMap] of Object.entries(legacy)) {\n for (const [fieldKey, value] of Object.entries(fieldMap as Record<string, string>)) {\n if (!converted[fieldKey]) converted[fieldKey] = {}\n converted[fieldKey][locale] = value\n }\n }\n return { translations: converted }\n }),\n\n /** Read the current locale value for a field, falling back to the default locale */\n getLocalizedValue: (fieldKey) => {\n const { translations, currentLocale, availableLocales } = get()\n const fieldMap = translations[fieldKey]\n if (!fieldMap) return undefined\n return (\n fieldMap[currentLocale] ??\n fieldMap[availableLocales.find((l) => l.default)?.code ?? 'en']\n )\n },\n}))\n","import React from 'react'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport { Loader2, Check, AlertCircle } from 'lucide-react'\nimport { useEditorStore } from '../../../store/editorStore'\nimport { useTheme } from '../../../context/ThemeContext'\nimport { cn } from '../../../lib/utils'\nimport { useShallow } from 'zustand/react/shallow'\n\nexport const AutoSaveIndicator: React.FC = () => {\n const { saving, hasUnsavedChanges } = useEditorStore(useShallow(state => ({ saving: state.saving, hasUnsavedChanges: state.hasUnsavedChanges })))\n const { theme } = useTheme()\n\n // Determine active status: 'saving' | 'unsaved' | 'saved'\n const status = saving ? 'saving' : hasUnsavedChanges ? 'unsaved' : 'saved'\n\n return (\n <div className=\"flex items-center select-none font-sans\">\n <AnimatePresence mode=\"wait\">\n {status === 'saving' && (\n <motion.div\n key=\"saving\"\n initial={{ opacity: 0, scale: 0.9 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.9 }}\n className={cn(\n 'px-2.5 py-1 flex items-center gap-1.5 border text-xs font-semibold rounded-none-none',\n theme === 'dark'\n ? 'bg-z-panel/5 border-z-border text-z-secondary'\n : 'bg-z-input border-z-border text-z-secondary'\n )}\n >\n <Loader2 size={11} className=\"animate-spin\" />\n <span>Saving...</span>\n </motion.div>\n )}\n\n {status === 'unsaved' && (\n <motion.div\n key=\"unsaved\"\n initial={{ opacity: 0, scale: 0.9 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.9 }}\n className={cn(\n 'px-2.5 py-1 flex items-center gap-1.5 border text-xs font-semibold rounded-none-none',\n theme === 'dark'\n ? 'bg-amber-500/10 border-amber-500/20 text-amber-400'\n : 'bg-amber-50 border-amber-200 text-amber-600'\n )}\n >\n <AlertCircle size={11} className=\"animate-pulse\" />\n <span>Unsaved</span>\n </motion.div>\n )}\n\n {status === 'saved' && (\n <motion.div\n key=\"saved\"\n initial={{ opacity: 0, scale: 0.9 }}\n animate={{ opacity: 1, scale: 1 }}\n exit={{ opacity: 0, scale: 0.9 }}\n className={cn(\n 'px-2.5 py-1 flex items-center gap-1.5 border text-xs font-semibold rounded-none-none',\n theme === 'dark'\n ? 'bg-z-panel/5 border-z-border text-z-secondary'\n : 'bg-z-input border-z-border text-z-secondary'\n )}\n >\n <Check size={11} className=\"text-z-secondary \" />\n <span>Saved</span>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n )\n}\n\nexport default AutoSaveIndicator\n","import React, { useState, useEffect, useRef } from 'react'\nimport { Clock, X } from 'lucide-react'\nimport { useTheme } from '../../../context/ThemeContext'\nimport { useWorkflowStore } from '../../../store/workflowStore'\nimport { useEditorStore } from '../../../store/editorStore'\nimport { cn } from '../../../lib/utils'\nimport toast from 'react-hot-toast'\nimport { useShallow } from 'zustand/react/shallow'\n\ninterface SchedulePickerProps {\n open: boolean\n onClose: () => void\n}\n\nexport const SchedulePicker: React.FC<SchedulePickerProps> = ({ open, onClose }) => {\n const { theme } = useTheme()\n const { scheduledAt, setScheduledAt } = useWorkflowStore(useShallow(state => ({ scheduledAt: state.scheduledAt, setScheduledAt: state.setScheduledAt })))\n const [scheduleInput, setScheduleInput] = useState('')\n const popoverRef = useRef<HTMLDivElement>(null)\n\n useEffect(() => {\n if (open) {\n if (scheduledAt) {\n setScheduleInput(new Date(scheduledAt).toISOString().slice(0, 16))\n } else {\n const tomorrow = new Date()\n tomorrow.setDate(tomorrow.getDate() + 1)\n tomorrow.setHours(9, 0, 0, 0)\n setScheduleInput(tomorrow.toISOString().slice(0, 16))\n }\n }\n }, [open, scheduledAt])\n\n useEffect(() => {\n if (!open) return\n const handleClick = (e: MouseEvent) => {\n if (popoverRef.current && !popoverRef.current.contains(e.target as Node)) {\n onClose()\n }\n }\n document.addEventListener('mousedown', handleClick)\n return () => document.removeEventListener('mousedown', handleClick)\n }, [open, onClose])\n\n const handleApply = () => {\n if (!scheduleInput) return\n const iso = new Date(scheduleInput).toISOString()\n setScheduledAt(iso)\n useWorkflowStore.getState().setWorkflowStatus('scheduled')\n useEditorStore.getState().setHasUnsavedChanges(true)\n toast.success(`Scheduled for ${new Date(iso).toLocaleString()}`, { icon: '⏰' })\n onClose()\n }\n\n const handleClear = () => {\n setScheduledAt('')\n onClose()\n }\n\n if (!open) return null\n\n return (\n <div\n ref={popoverRef}\n className={cn(\n 'absolute top-full mt-2 right-0 w-64 border shadow-2xl z-50 p-3',\n theme === 'dark' ? 'bg-[#0a0a0a] border-z-border' : 'bg-z-panel border-z-border'\n )}\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"flex items-center justify-between mb-2\">\n <span className={cn('text-xs font-semibold ', theme === 'dark' ? 'text-z-muted' : 'text-z-secondary')}>\n Schedule Publish\n </span>\n <div className=\"flex items-center gap-1\">\n {scheduledAt && (\n <button\n onClick={handleClear}\n className=\"text-xs font-semibold text-red-400 hover:text-red-300\"\n >\n Clear\n </button>\n )}\n <button\n onClick={onClose}\n aria-label=\"Close scheduler\"\n className={cn('p-0.5', theme === 'dark' ? 'text-z-secondary hover:text-z-primary' : 'text-z-muted hover:text-z-primary')}\n >\n <X size={12} aria-hidden=\"true\" />\n </button>\n </div>\n </div>\n <input\n type=\"datetime-local\"\n value={scheduleInput}\n onChange={(e) => setScheduleInput(e.target.value)}\n className={cn(\n 'w-full px-2 py-1.5 rounded-none-none border text-xs font-mono',\n theme === 'dark'\n ? 'bg-z-hover border-z-border text-z-primary'\n : 'bg-z-input border-z-border text-z-primary'\n )}\n />\n <div className=\"flex gap-2 mt-2\">\n <button\n onClick={onClose}\n className={cn(\n 'flex-1 py-1.5 border text-xs font-semibold text-center transition-all',\n theme === 'dark' ? 'border-z-border text-z-muted hover:bg-z-hover' : 'border-z-border text-z-secondary hover:bg-[var(--z-bg-input)]'\n )}\n >\n Cancel\n </button>\n <button\n onClick={handleApply}\n disabled={!scheduleInput}\n className={cn(\n 'flex-1 py-1.5 text-xs font-semibold text-center transition-all disabled:opacity-40',\n 'bg-z-accent hover:bg-z-border text-z-primary'\n )}\n >\n Apply\n </button>\n </div>\n </div>\n )\n}\n\nexport default SchedulePicker\n","import React from 'react'\nimport { createPortal } from 'react-dom'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport { AlertTriangle, X, Rocket } from 'lucide-react'\nimport { useTheme } from '../../../context/ThemeContext'\nimport { cn } from '../../../lib/utils'\n\ninterface ConfirmPublishModalProps {\n open: boolean\n onConfirm: () => void\n onCancel: () => void\n}\n\nexport const ConfirmPublishModal: React.FC<ConfirmPublishModalProps> = ({\n open,\n onConfirm,\n onCancel,\n}) => {\n const { theme } = useTheme()\n\n return createPortal(\n <AnimatePresence>\n {open && (\n <div className=\"fixed inset-0 z-[800] flex items-center justify-center bg-[var(--z-bg-modal)] backdrop-blur-sm\">\n <motion.div\n initial={{ opacity: 0, scale: 0.95, y: 10 }}\n animate={{ opacity: 1, scale: 1, y: 0 }}\n exit={{ opacity: 0, scale: 0.95, y: 10 }}\n transition={{ duration: 0.15 }}\n className={cn(\n 'w-full max-w-sm border rounded-none-none shadow-2xl p-6',\n theme === 'dark'\n ? 'bg-app border-z-border text-z-primary'\n : 'bg-z-panel border-z-border text-z-primary'\n )}\n >\n <div className=\"flex items-start gap-4\">\n <div className={cn(\n 'w-10 h-10 rounded-none-none border flex items-center justify-center shrink-0',\n theme === 'dark'\n ? 'bg-amber-500/10 border-amber-500/20 text-amber-400'\n : 'bg-amber-50 border-amber-200 text-amber-500'\n )}>\n <AlertTriangle size={18} />\n </div>\n <div className=\"flex-1\">\n <h3 className=\"text-sm font-semibold\">Publish Document</h3>\n <p className={cn('text-xs font-bold mt-2 leading-relaxed', theme === 'dark' ? 'text-z-muted' : 'text-z-secondary')}>\n This will make the content live and visible to all visitors. Are you sure you want to publish?\n </p>\n </div>\n <button\n onClick={onCancel}\n aria-label=\"Close\"\n className={cn('shrink-0 p-1 transition-colors', theme === 'dark' ? 'text-z-secondary hover:text-z-primary' : 'text-z-muted hover:text-z-primary')}\n >\n <X size={16} />\n </button>\n </div>\n <div className=\"flex gap-3 mt-5\">\n <button\n onClick={onCancel}\n className={cn(\n 'flex-1 py-2.5 text-xs font-semibold border rounded-none-none transition-all',\n theme === 'dark'\n ? 'border-z-border text-z-muted hover:border-z-border hover:text-z-primary'\n : 'border-z-border text-z-secondary hover:border-z-border-strong hover:text-z-primary'\n )}\n >\n Cancel\n </button>\n <button\n onClick={onConfirm}\n className=\"flex-1 flex items-center justify-center gap-2 py-2.5 bg-z-accent text-z-primary text-xs font-semibold rounded-none-none hover:bg-z-border transition-all\"\n >\n <Rocket size={12} />\n Publish Now\n </button>\n </div>\n </motion.div>\n </div>\n )}\n </AnimatePresence>,\n document.body\n )\n}\n\nexport default ConfirmPublishModal\n","import React, { useState, useMemo } from 'react'\nimport { createPortal } from 'react-dom'\nimport { X, Languages, Globe, Check, AlertCircle } from 'lucide-react'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport { useEditorStore } from '../../../store/editorStore'\nimport { useI18nStore } from '../../../store/i18nStore'\nimport { useTheme } from '../../../context/ThemeContext'\nimport { cn } from '../../../lib/utils'\nimport { type Section, humanize } from '../constants'\nimport { FieldRenderer } from '../FieldRenderer'\nimport { useEditorBlocks } from '../../../context/BlockLibraryContext'\nimport { useShallow } from 'zustand/react/shallow'\n\ninterface TranslationModalProps {\n open: boolean\n onClose: () => void\n}\n\nexport const TranslationModal: React.FC<TranslationModalProps> = ({ open, onClose }) => {\n const { theme } = useTheme()\n const dark = theme === 'dark'\n \n const { data, topLevelFields } = useEditorStore(useShallow(state => ({ data: state.data, topLevelFields: state.topLevelFields })))\n const { availableLocales, translations, updateTranslation } = useI18nStore()\n \n const [referenceLocale, setReferenceLocale] = useState('en')\n const [targetLocale, setTargetLocale] = useState('es')\n const BLOCK_LIBRARY = useEditorBlocks()\n\n // Extract all translatable fields from the sections\n const translatableFields = useMemo(() => {\n const fields: Array<{ sectionId: string; sectionName: string; fieldName: string; fieldType: string; originalValue: any }> = []\n \n // 1. Top-level translatable fields from schema\n topLevelFields.forEach((field) => {\n if (['text', 'richtext', 'textarea', 'lexical'].includes(field.type)) {\n fields.push({\n sectionId: 'root',\n sectionName: 'Document Data',\n fieldName: field.name,\n fieldType: field.type,\n originalValue: data?.[field.name]\n })\n }\n })\n\n // 2. Section-level translatable fields\n if (!data?.sections) return fields\n\n data.sections.forEach((section: Section) => {\n const blockDef = BLOCK_LIBRARY.find((b) => b.type === section.blockType)\n if (!blockDef) return\n\n blockDef.fields.forEach((field) => {\n if (['text', 'richtext', 'textarea', 'lexical'].includes(field.type)) {\n fields.push({\n sectionId: section.id,\n sectionName: section.blockName || section.title || humanize(section.blockType),\n fieldName: field.name,\n fieldType: field.type,\n originalValue: section.content[field.name]\n })\n }\n })\n })\n\n return fields\n }, [data, BLOCK_LIBRARY, topLevelFields])\n\n // Progress calculation\n const progress = useMemo(() => {\n if (translatableFields.length === 0) return 0\n let translatedCount = 0\n translatableFields.forEach((field) => {\n const fieldKey = field.sectionId === 'root' ? field.fieldName : `${field.sectionId}.${field.fieldName}`\n const translation = translations[fieldKey]?.[targetLocale]\n if (translation && translation.trim() !== '') {\n translatedCount++\n }\n })\n return Math.round((translatedCount / translatableFields.length) * 100)\n }, [translatableFields, translations, targetLocale])\n\n return createPortal(\n <AnimatePresence>\n {open && (\n <div className=\"fixed inset-0 z-[100] flex items-center justify-center p-4 sm:p-6 bg-[var(--z-bg-modal)] backdrop-blur-sm\">\n <motion.div\n initial={{ opacity: 0, scale: 0.98, y: 15 }}\n animate={{ opacity: 1, scale: 1, y: 0 }}\n exit={{ opacity: 0, scale: 0.98, y: 15 }}\n className={cn(\n 'border rounded-none-none w-full max-w-6xl shadow-2xl flex flex-col overflow-hidden max-h-[90vh]',\n dark ? 'bg-app border-z-border text-z-primary' : 'bg-z-panel border-z-border shadow-sm text-z-primary'\n )}\n >\n {/* Header */}\n <div className=\"p-6 border-b border-z-border dark:border-z-border flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4\">\n <div className=\"flex items-center gap-4\">\n <div className=\"w-10 h-10 bg-z-accent rounded-none-none flex items-center justify-center text-z-primary shadow-lg shrink-0\">\n <Languages size={18} />\n </div>\n <div className=\"flex flex-col\">\n <h3 className=\"text-sm font-semibold\">\n Translation_Engine\n </h3>\n <p className=\"text-sm font-bold text-z-muted mt-1\">\n Side-by-side content localization\n </p>\n </div>\n </div>\n\n {/* Locale Selectors */}\n <div className=\"flex items-center gap-4 w-full sm:w-auto\">\n <div className=\"flex items-center gap-2 flex-1 sm:flex-none\">\n <span className=\"text-sm font-bold text-z-secondary\">Reference:</span>\n <select\n value={referenceLocale}\n onChange={(e) => setReferenceLocale(e.target.value)}\n className={cn(\n 'w-32 px-3 py-1.5 text-xs font-bold border rounded-none-none bg-transparent outline-none focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:ring-offset-1 focus-visible:ring-offset-black transition-colors appearance-none cursor-pointer',\n dark ? 'border-z-border hover:border-z-border text-z-primary' : 'border-z-border hover:border-z-border text-z-primary'\n )}\n >\n {availableLocales.map(l => (\n <option key={l.code} value={l.code} className=\"text-z-primary bg-z-panel\">{l.flag} {l.name}</option>\n ))}\n </select>\n </div>\n \n <div className=\"text-z-muted\"><Globe size={14} /></div>\n \n <div className=\"flex items-center gap-2 flex-1 sm:flex-none\">\n <span className=\"text-sm font-bold text-z-secondary \">Target:</span>\n <select\n value={targetLocale}\n onChange={(e) => setTargetLocale(e.target.value)}\n className={cn(\n 'w-32 px-3 py-1.5 text-xs font-bold border rounded-none-none dark:bg-z-panel/5 bg-z-panel outline-none focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:ring-offset-1 focus-visible:ring-offset-black transition-colors appearance-none cursor-pointer',\n dark ? 'border-z-border/30 hover:border-z-border/60 text-z-secondary' : 'border-z-border/30 hover:border-z-border/60 text-z-secondary'\n )}\n >\n {availableLocales.map(l => (\n <option key={l.code} value={l.code} className=\"text-z-primary bg-z-panel\">{l.flag} {l.name}</option>\n ))}\n </select>\n </div>\n\n <button\n onClick={onClose}\n className=\"ml-4 p-2 text-z-muted hover:text-z-primary transition-colors\"\n >\n <X size={16} />\n </button>\n </div>\n </div>\n\n {/* Progress Bar */}\n <div className=\"h-1 bg-[var(--z-bg-hover)] dark:bg-z-hover w-full relative\">\n <div \n className=\"absolute left-0 top-0 bottom-0 bg-z-border transition-all duration-500\" \n style={{ width: `${progress}%` }}\n />\n </div>\n\n {/* Content Area */}\n <div className=\"flex-1 overflow-y-auto p-6 space-y-12\">\n {translatableFields.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center py-20 text-z-secondary\">\n <AlertCircle size={48} className=\"mb-4 opacity-20\" />\n <p className=\"text-xs font-bold\">No text fields found to translate.</p>\n </div>\n ) : (\n translatableFields.map((field, _idx) => {\n const fieldKey = field.sectionId === 'root' ? field.fieldName : `${field.sectionId}.${field.fieldName}`\n const refValue = translations[fieldKey]?.[referenceLocale] || (referenceLocale === 'en' ? field.originalValue : '') || ''\n const targetValue = translations[fieldKey]?.[targetLocale] || ''\n\n return (\n <div key={`${field.sectionId}-${field.fieldName}`} className=\"space-y-4 relative\">\n <div className=\"flex items-center gap-2\">\n <div className=\"w-1.5 h-1.5 bg-z-border rounded-none-none\" />\n <h4 className=\"text-sm font-semibold text-z-secondary\">\n {field.sectionName} <span className=\"text-z-secondary mx-1\">&gt;</span> {humanize(field.fieldName)}\n </h4>\n </div>\n \n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-8\">\n {/* Left: Reference (Read-only) */}\n <div className=\"opacity-70 pointer-events-none relative\">\n <div className=\"absolute top-0 right-0 p-2 text-sm font-semibold text-z-muted z-10 bg-app/50 backdrop-blur-md\">\n Reference ({referenceLocale})\n </div>\n <FieldRenderer\n blockId={field.sectionId}\n field={{ name: field.fieldName, type: field.fieldType as any, label: '' }}\n value={refValue}\n onChange={() => {}}\n theme={theme}\n /></div>\n \n {/* Right: Target (Editable) */}\n <div className=\"relative border border-z-border/20 p-4 -m-4 bg-z-hover\">\n <div className=\"absolute top-0 right-0 p-2 text-sm font-semibold text-z-secondary z-10 bg-app/50 backdrop-blur-md flex items-center gap-1.5\">\n {targetValue ? <Check size={10} className=\"text-z-secondary\" /> : null}\n Target ({targetLocale})\n </div>\n <FieldRenderer\n blockId={field.sectionId}\n field={{ name: field.fieldName, type: field.fieldType as any, label: '' }}\n value={targetValue}\n onChange={(newVal) => updateTranslation(fieldKey, targetLocale, newVal)}\n theme={theme}\n /></div>\n </div>\n </div>\n )\n })\n )}\n </div>\n </motion.div>\n </div>\n )}\n </AnimatePresence>,\n document.body\n )\n}\n","import { useEffect, useRef, useState, useCallback } from 'react'\nimport { useAuthStore } from '../store/authStore'\nimport api from '../lib/api'\nimport { useShallow } from 'zustand/react/shallow'\n\nexport interface CollabUser {\n id: string\n email: string\n name?: string\n color: string\n cursor?: { sectionId?: string; fieldKey?: string }\n}\n\nconst YJS_COLORS = [\n 'var(--z-accent)', // indigo\n 'var(--z-accent)', // violet\n '#ec4899', // pink\n '#f43f5e', // rose\n '#f97316', // orange\n '#84cc16', // lime\n '#14b8a6', // teal\n '#06b6d4', // cyan\n '#3b82f6', // blue\n '#a855f7', // gray\n]\n\nfunction colorForId(id: string): string {\n let hash = 0\n for (let i = 0; i < id.length; i++) {\n hash = (hash * 31 + id.charCodeAt(i)) & 0xffff\n }\n return YJS_COLORS[hash % YJS_COLORS.length]\n}\n\nfunction initials(name?: string, email?: string): string {\n if (name) return name.slice(0, 2).toUpperCase()\n if (email) return email.slice(0, 2).toUpperCase()\n return '??'\n}\n\ninterface UseCollabOptions {\n collection: string\n documentId: string\n /** Y.js WebSocket server URL. If omitted, falls back to presence-polling only. */\n wsUrl?: string\n /** How often to poll presence (ms). Only used when wsUrl is not set. */\n pollInterval?: number\n enabled?: boolean\n}\n\ninterface UseCollabReturn {\n /** Connected collab users (from awareness / presence) */\n collabUsers: CollabUser[]\n /** Your own local user */\n localUser: CollabUser\n /** Y.Doc instance (deprecated from core, returns null) */\n doc: any | null\n /** Whether Y.js WebSocket is connected (always false in core) */\n isConnected: boolean\n /** Broadcast a field-level cursor position to other users */\n broadcastCursor: (sectionId?: string, fieldKey?: string) => void\n}\n\n/**\n * Zenith Collaborative Editing Hook\n * ─────────────────────────────────\n * Provides Y.js backed document + awareness (live cursors / user presence).\n *\n * Falls back to HTTP polling of /api/v1/presence when wsUrl is not set,\n * so it works out-of-the-box without a dedicated collab server.\n *\n * To enable full real-time sync, point wsUrl at a y-websocket or Hocuspocus\n * server running at /collaboration (see vite.config.ts proxy).\n */\nexport function useCollab({\n collection,\n documentId,\n wsUrl,\n pollInterval = 15000,\n enabled = true,\n}: UseCollabOptions): UseCollabReturn {\n const { user } = useAuthStore(useShallow(state => ({ user: state.user })))\n const [collabUsers, setCollabUsers] = useState<CollabUser[]>([])\n const [isConnected] = useState(false)\n const [doc] = useState<any | null>(null)\n\n const pollTimerRef = useRef<ReturnType<typeof setInterval> | null>(null)\n\n const localUser: CollabUser = {\n id: user?.id || 'local',\n email: user?.email || 'local@example.com',\n name: user?.name,\n color: colorForId(user?.id || 'local'),\n }\n\n // ── Polling fallback (no WebSocket required) ─────────────────────────────────\n useEffect(() => {\n if (!enabled) return\n\n const fetchPresence = async () => {\n try {\n // Use heartbeat + list API to get active users\n // First send heartbeat so we're counted, then list\n await api.post('/presence/heartbeat', {\n collection,\n documentId,\n userId: user?.id,\n }).catch(() => {})\n\n const res = await api.get(`/presence/${collection}/${documentId}`, {\n params: { collection, documentId },\n }).catch(() => ({ data: { data: { activeUsers: [] } } }))\n\n const raw = res.data?.data?.activeUsers || []\n const mapped: CollabUser[] = raw.map((u: { id?: string; userId?: string; email?: string; name?: string }) => ({\n id: u.id || u.userId || '?',\n email: u.email || '?',\n name: u.name,\n color: colorForId(u.id || u.userId || ''),\n }))\n setCollabUsers(mapped)\n } catch { /* ignore */ }\n }\n\n fetchPresence()\n pollTimerRef.current = setInterval(fetchPresence, pollInterval)\n\n return () => {\n if (pollTimerRef.current) clearInterval(pollTimerRef.current)\n }\n }, [wsUrl, isConnected, collection, documentId, pollInterval, enabled, user])\n\n // ── Broadcast cursor ────────────────────────────────────────────────────────\n const broadcastCursor = useCallback((sectionId?: string, fieldKey?: string) => {\n // Cursor broadcasting requires the multiplayer plugin\n }, [])\n\n return {\n collabUsers,\n localUser,\n doc,\n isConnected,\n broadcastCursor,\n }\n}\n\nexport { colorForId, initials }\n","import React, { useState } from 'react'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport { Wifi, WifiOff, Circle } from 'lucide-react'\nimport type { CollabUser } from '../../../hooks/useCollab'\nimport { initials } from '../../../hooks/useCollab'\nimport { useTheme } from '../../../context/ThemeContext'\nimport { cn } from '../../../lib/utils'\n\ninterface CollabAvatarsProps {\n users: CollabUser[]\n localUser: CollabUser\n isConnected: boolean\n theme: 'light' | 'dark'\n}\n\nconst MAX_SHOWN = 5\n\nexport const CollabAvatars: React.FC<CollabAvatarsProps> = ({\n users,\n localUser,\n isConnected,\n theme,\n}) => {\n const [expanded, setExpanded] = useState(false)\n\n const visibleUsers = users.slice(0, MAX_SHOWN)\n const overflowCount = Math.max(0, users.length - MAX_SHOWN)\n\n const userColors: Record<string, string> = {}\n users.forEach((u) => { userColors[u.id] = u.color })\n\n return (\n <div \n className=\"relative flex items-center gap-0\"\n onMouseEnter={() => setExpanded(true)}\n onMouseLeave={() => setExpanded(false)}\n >\n {/* Connection badge */}\n <div\n className={cn(\n 'flex items-center gap-1 px-2 py-1 rounded-none-none border text-sm font-semibold ',\n isConnected\n ? theme === 'dark'\n ? 'bg-z-panel/5 border-z-border text-z-secondary'\n : 'bg-z-input border-z-border text-z-secondary'\n : theme === 'dark'\n ? 'bg-z-hover border-z-border text-z-secondary'\n : 'bg-[var(--z-bg-hover)] border-z-border text-z-muted'\n )}\n title={isConnected ? 'Live collaboration active' : 'Offline — changes saved locally'}\n >\n {isConnected ? <Wifi size={8} /> : <WifiOff size={8} />}\n {isConnected ? 'Live' : 'Local'}\n </div>\n\n {/* Avatar stack */}\n <div className=\"flex items-center ml-1.5\">\n {/* Local user is always first */}\n <div\n className=\"relative\"\n title={`${localUser.name || localUser.email} (you)`}\n >\n <motion.div\n initial={{ scale: 0 }}\n animate={{ scale: 1 }}\n className={cn(\n 'w-8 h-8 rounded-full flex items-center justify-center text-xs font-bold shadow-sm ring-2',\n theme === 'dark' ? 'ring-[#050505]' : 'ring-z-active-border'\n )}\n style={{ backgroundColor: localUser.color }}\n >\n {initials(localUser.name, localUser.email)}\n </motion.div>\n <motion.div\n animate={{ scale: [1, 1.3, 1], opacity: [1, 0.4, 1] }}\n transition={{ duration: 2, repeat: Infinity }}\n className=\"absolute -bottom-0.5 -right-0.5\"\n >\n <Circle\n size={6}\n fill={localUser.color}\n stroke=\"none\"\n className=\"text-z-secondary\"\n />\n </motion.div>\n </div>\n\n {/* Other user avatars */}\n {visibleUsers\n .filter((u) => u.id !== localUser.id)\n .map((u, idx) => (\n <motion.div\n key={u.id}\n initial={{ scale: 0, x: -10 }}\n animate={{ scale: 1, x: 0 }}\n transition={{ delay: idx * 0.05 }}\n className={cn(\n 'relative -ml-2 w-8 h-8 rounded-full flex items-center justify-center text-xs font-bold shadow-sm ring-2',\n theme === 'dark' ? 'ring-[#050505]' : 'ring-z-active-border'\n )}\n style={{\n backgroundColor: u.color,\n borderColor: 'var(--z-border)',\n zIndex: visibleUsers.length - idx,\n }}\n title={u.name || u.email}\n >\n {initials(u.name, u.email)}\n </motion.div>\n ))}\n\n {/* Overflow count */}\n {overflowCount > 0 && (\n <motion.button\n type=\"button\"\n initial={{ scale: 0 }}\n animate={{ scale: 1 }}\n onClick={() => setExpanded((v) => !v)}\n aria-label={`${overflowCount} more users editing`}\n className={cn(\n 'relative -ml-2 w-8 h-8 rounded-full flex items-center justify-center text-xs font-bold shadow-sm ring-2 transition-transform cursor-pointer',\n theme === 'dark'\n ? 'bg-z-base text-z-secondary ring-[#050505] hover:scale-105'\n : 'bg-[var(--z-border)] text-z-secondary ring-z-active-border hover:scale-105'\n )}\n style={{ zIndex: 0 }}\n >\n +{overflowCount}\n </motion.button>\n )}\n </div>\n\n {/* Expanded tooltip */}\n <AnimatePresence>\n {expanded && (\n <motion.div\n initial={{ opacity: 0, y: -4 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: -4 }}\n transition={{ duration: 0.1 }}\n className={cn(\n 'absolute top-full right-0 mt-2 z-[999] w-64 rounded-xl shadow-2xl p-4 border',\n theme === 'dark'\n ? 'bg-[#111] border-z-border text-z-primary'\n : 'bg-z-panel border-z-border text-z-primary shadow-[var(--z-border)]'\n )}\n onClick={() => setExpanded(false)}\n >\n <p className=\"text-xs font-semibold text-z-secondary mb-2\">\n {users.length} {users.length === 1 ? 'person' : 'people'} editing\n </p>\n <div className=\"space-y-1.5\">\n {[localUser, ...users.filter((u) => u.id !== localUser.id)].map((u) => (\n <div key={u.id} className=\"flex items-center gap-2\">\n <div\n className=\"w-6 h-6 rounded-full flex items-center justify-center text-[10px] font-bold text-z-primary shrink-0\"\n style={{ backgroundColor: u.color }}\n >\n {initials(u.name, u.email)}\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-xs font-semibold truncate\">{u.name || u.email}</p>\n {u.cursor?.fieldKey && (\n <p className=\"text-xs text-z-secondary truncate\">\n → {u.cursor.fieldKey}\n </p>\n )}\n </div>\n {u.id === localUser.id && (\n <span className=\"text-xs text-z-secondary\">you</span>\n )}\n </div>\n ))}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </div>\n )\n}\n\nexport default CollabAvatars\n","import React, { useState, useEffect, useRef } from 'react'\nimport { useNavigate, useParams } from 'react-router-dom'\nimport {\n ChevronLeft,\n Undo2,\n Redo2,\n PanelLeft,\n PanelRight,\n Sun,\n Moon,\n Languages,\n Globe,\n Circle,\n Check,\n Save,\n Loader2,\n Clock,\n Maximize,\n Minimize\n} from 'lucide-react'\nimport { useTheme } from '../../context/ThemeContext'\nimport { useEditorStore } from '../../store/editorStore'\nimport { usePanelStore } from '../../store/panelStore'\nimport { useModalStore } from '../../store/modalStore'\nimport { useWorkflowStore } from '../../store/workflowStore'\nimport { useI18nStore } from '../../store/i18nStore'\nimport { cn } from '../../lib/utils'\nimport { AutoSaveIndicator } from './components/AutoSaveIndicator'\nimport { SchedulePicker } from './components/SchedulePicker'\nimport { ConfirmPublishModal } from './components/ConfirmPublishModal'\nimport { TranslationModal } from './components/TranslationModal'\nimport { CollabAvatars } from './components/CollabAvatars'\nimport { useShallow } from 'zustand/react/shallow'\n\ninterface EditorToolbarProps {\n handleSave: () => Promise<void>\n handlePublish: () => Promise<void>\n handleUnpublish: () => Promise<void>\n isGlobal?: boolean\n onClose?: () => void\n collab?: any\n}\n\nexport const EditorToolbar: React.FC<EditorToolbarProps> = ({\n handleSave,\n handlePublish,\n handleUnpublish,\n isGlobal,\n onClose,\n collab,\n}) => {\n const navigate = useNavigate()\n const { id, slug } = useParams<{ id: string; slug: string }>()\n const { theme, toggleTheme } = useTheme()\n\n const handleBack = () => {\n if (onClose) {\n onClose()\n } else {\n if (isGlobal) {\n navigate('/')\n } else {\n navigate(`/collections/${slug || 'pages'}`)\n }\n }\n }\n\n const { saving,\n undoStack,\n redoStack,\n undo,\n redo,\n lastSavedAt,\n } = useEditorStore(useShallow(state => ({ saving: state.saving, undoStack: state.undoStack, redoStack: state.redoStack, undo: state.undo, redo: state.redo, lastSavedAt: state.lastSavedAt })))\n\n const { viewMode,\n setViewMode,\n leftOpen,\n setLeftOpen,\n rightOpen,\n setRightOpen,\n focusMode,\n toggleFocusMode\n } = usePanelStore(useShallow(state => ({ viewMode: state.viewMode, setViewMode: state.setViewMode, leftOpen: state.leftOpen, setLeftOpen: state.setLeftOpen, rightOpen: state.rightOpen, setRightOpen: state.setRightOpen, focusMode: state.focusMode, toggleFocusMode: state.toggleFocusMode })))\n\n const { seoOpen,\n setSeoOpen,\n } = useModalStore(useShallow(state => ({ seoOpen: state.seoOpen, setSeoOpen: state.setSeoOpen })))\n\n const { publishStatus,\n workflowStatus,\n scheduledAt,\n } = useWorkflowStore(useShallow(state => ({ publishStatus: state.publishStatus, workflowStatus: state.workflowStatus, scheduledAt: state.scheduledAt })))\n\n const {\n i18nEnabled,\n availableLocales,\n currentLocale,\n setCurrentLocale,\n setI18nEnabled,\n } = useI18nStore()\n\n const [showSchedulePicker, setShowSchedulePicker] = useState(false)\n const [showLocaleDropdown, setShowLocaleDropdown] = useState(false)\n const [showPublishConfirm, setShowPublishConfirm] = useState(false)\n const [showTranslationModal, setShowTranslationModal] = useState(false)\n\n const localeRef = useRef<HTMLDivElement>(null)\n\n // Close locale dropdown on outside click\n useEffect(() => {\n if (!showLocaleDropdown) return\n const handle = (e: MouseEvent) => {\n if (localeRef.current && !localeRef.current.contains(e.target as Node)) {\n setShowLocaleDropdown(false)\n }\n }\n document.addEventListener('mousedown', handle)\n return () => document.removeEventListener('mousedown', handle)\n }, [showLocaleDropdown])\n\n const dark = theme === 'dark'\n\n // Common button class for toolbar icon buttons\n const iconBtn = cn(\n 'w-8 h-8 rounded-none-none flex items-center justify-center border transition-all',\n dark ? 'bg-z-hover border-z-border' : 'bg-z-panel border-z-border'\n )\n\n const iconBtnActive = (active: boolean) =>\n active\n ? dark ? 'bg-z-panel/10 border-z-border text-z-primary' : 'bg-[var(--z-active-bg)] text-[var(--z-active-text)] border border-[var(--z-active-border)] shadow-sm'\n : dark ? 'text-z-secondary hover:text-z-primary' : 'text-z-muted hover:text-z-primary'\n\n const iconBtnDisabled = (disabled: boolean) =>\n disabled\n ? dark ? 'bg-app/20 border-z-border text-z-primary/20 cursor-not-allowed' : 'bg-z-input border-z-border shadow-sm text-z-secondary cursor-not-allowed'\n : dark ? 'bg-z-hover border-z-border text-z-muted hover:text-z-secondary' : 'bg-z-panel border-z-border text-z-secondary hover:bg-[var(--z-bg-input)]'\n\n // Last saved time display\n const lastSavedLabel = lastSavedAt\n ? `Saved ${new Date(lastSavedAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`\n : null\n\n return (\n <header\n className={cn(\n 'h-14 border-b flex items-center justify-between px-4 z-[100] backdrop-blur-3xl transition-all gap-3 shrink-0 overflow-visible',\n dark ? 'bg-z-popover border-z-border' : 'bg-z-panel border-z-border shadow-sm'\n )}\n >\n {/* Left: Back + SEO */}\n <div className=\"flex items-center gap-2 shrink-0\">\n <button\n onClick={handleBack}\n className={cn(iconBtn, dark ? 'text-z-muted hover:text-z-primary' : 'text-z-secondary hover:text-z-primary')}\n aria-label=\"Back to collection\"\n title=\"Back\"\n >\n <ChevronLeft size={16} />\n </button>\n <div className={cn('h-4 w-px mx-1', dark ? 'bg-z-panel/10' : 'bg-[var(--z-border)]')} />\n <button\n onClick={() => setSeoOpen(!seoOpen)}\n className={cn(\n 'px-2.5 py-1.5 rounded-none-none border text-xs font-semibold flex items-center gap-1.5 transition-all',\n seoOpen\n ? 'bg-z-panel/5 border-z-border text-z-secondary'\n : dark ? 'bg-z-hover border-z-border text-z-muted' : 'bg-z-input border-z-border text-z-secondary'\n )}\n aria-label={seoOpen ? 'Close SEO panel' : 'Open SEO panel'}\n title=\"SEO\"\n >\n <Globe size={12} />\n SEO\n </button>\n </div>\n\n {/* Center: Essential actions */}\n <div className=\"flex items-center gap-1 shrink-0\">\n {/* Undo / Redo */}\n <button\n onClick={undo}\n disabled={undoStack.length === 0}\n aria-label={undoStack.length > 0 ? `Undo (${undoStack.length} step${undoStack.length !== 1 ? 's' : ''} available)` : 'Nothing to undo'}\n title={undoStack.length > 0 ? `Undo (${undoStack.length} step${undoStack.length !== 1 ? 's' : ''})` : 'Nothing to undo'}\n className={cn(iconBtn, iconBtnDisabled(undoStack.length === 0), 'relative')}\n >\n <Undo2 size={15} />\n {undoStack.length > 0 && (\n <span\n className=\"absolute -top-1.5 -right-1.5 min-w-[14px] h-3.5 px-0.5 flex items-center justify-center text-sm font-semibold tabular-nums rounded-none-none bg-z-accent text-z-primary leading-none\"\n aria-hidden=\"true\"\n >\n {undoStack.length > 99 ? '99+' : undoStack.length}\n </span>\n )}\n </button>\n <button\n onClick={redo}\n disabled={redoStack.length === 0}\n aria-label={redoStack.length > 0 ? `Redo (${redoStack.length} step${redoStack.length !== 1 ? 's' : ''} available)` : 'Nothing to redo'}\n title={redoStack.length > 0 ? `Redo (${redoStack.length} step${redoStack.length !== 1 ? 's' : ''})` : 'Nothing to redo'}\n className={cn(iconBtn, iconBtnDisabled(redoStack.length === 0), 'relative')}\n >\n <Redo2 size={15} />\n {redoStack.length > 0 && (\n <span\n className=\"absolute -top-1.5 -right-1.5 min-w-[14px] h-3.5 px-0.5 flex items-center justify-center text-sm font-semibold tabular-nums rounded-none-none bg-z-accent/80 text-z-primary leading-none\"\n aria-hidden=\"true\"\n >\n {redoStack.length > 99 ? '99+' : redoStack.length}\n </span>\n )}\n </button>\n\n <div className=\"w-px h-6 bg-z-hover mx-1\" />\n\n {/* Panel toggles */}\n <button\n onClick={() => setLeftOpen(!leftOpen)}\n aria-label={leftOpen ? 'Close layers panel' : 'Open layers panel'}\n title=\"Layers (Ctrl+\\\\)\"\n className={cn(iconBtn, iconBtnActive(leftOpen))}\n >\n <PanelLeft size={15} />\n </button>\n <button\n onClick={() => setRightOpen(!rightOpen)}\n aria-label={rightOpen ? 'Close preview panel' : 'Open preview panel'}\n title=\"Preview (Ctrl+P)\"\n className={cn(iconBtn, iconBtnActive(rightOpen))}\n >\n <PanelRight size={15} />\n </button>\n <button\n onClick={toggleFocusMode}\n aria-label={focusMode ? 'Exit focus mode' : 'Enter focus mode'}\n title=\"Focus Mode\"\n className={cn(iconBtn, iconBtnActive(focusMode))}\n >\n {focusMode ? <Minimize size={15} /> : <Maximize size={15} />}\n </button>\n\n <div className=\"w-px h-6 bg-z-hover mx-1\" />\n\n {/* Theme toggle */}\n <button\n onClick={toggleTheme}\n aria-label={dark ? 'Switch to light mode' : 'Switch to dark mode'}\n className={cn(iconBtn, dark ? 'text-z-muted hover:text-z-primary' : 'text-z-secondary hover:text-z-primary')}\n >\n {dark ? <Sun size={15} /> : <Moon size={15} />}\n </button>\n\n {/* i18n toggle */}\n <button\n onClick={() => setI18nEnabled(!i18nEnabled)}\n className={cn(iconBtn, iconBtnActive(i18nEnabled))}\n aria-label={i18nEnabled ? 'Disable translations' : 'Enable translations'}\n title={i18nEnabled ? 'Disable translations' : 'Enable translations'}\n >\n <Languages size={13} />\n </button>\n\n {/* Translation Mode */}\n {i18nEnabled && (\n <button\n onClick={() => setShowTranslationModal(true)}\n className={cn(iconBtn, 'text-z-secondary hover:text-z-secondary')}\n title=\"Translation Mode (Side-by-Side)\"\n aria-label=\"Open Translation Mode\"\n >\n <Globe size={13} />\n </button>\n )}\n\n {/* Locale dropdown */}\n {i18nEnabled && (\n <div className=\"relative\" ref={localeRef}>\n <button\n onClick={() => setShowLocaleDropdown(!showLocaleDropdown)}\n aria-label={`Current language: ${currentLocale.toUpperCase()}. Click to change.`}\n className={cn(\n 'h-8 px-2 rounded-none-none border flex items-center gap-1.5 text-xs font-semibold transition-all',\n dark ? 'bg-z-hover border-z-border text-z-muted hover:text-z-primary' : 'bg-z-panel border-z-border text-z-secondary hover:bg-[var(--z-bg-input)] hover:text-z-primary'\n )}\n >\n <Languages size={13} />\n {currentLocale.toUpperCase()}\n </button>\n {showLocaleDropdown && (\n <div\n className={cn(\n 'absolute top-full mt-2 w-36 border rounded-none-none shadow-2xl z-50 overflow-hidden',\n dark ? 'bg-[#0a0a0a] border-z-border' : 'bg-z-panel border-z-border'\n )}\n >\n {availableLocales.map((locale) => (\n <button\n key={locale.code}\n onClick={() => { setCurrentLocale(locale.code); setShowLocaleDropdown(false) }}\n className={cn(\n 'w-full flex items-center gap-2 px-3 py-2 text-xs font-bold transition-colors',\n currentLocale === locale.code\n ? dark ? 'bg-z-panel/5 text-z-secondary' : 'bg-z-hover text-z-primary shadow-sm'\n : dark ? 'text-z-muted hover:bg-z-hover' : 'text-z-secondary hover:bg-[var(--z-bg-hover)] hover:text-z-primary'\n )}\n >\n <span>{locale.flag}</span>\n <span className=\"flex-1 text-left\">{locale.name}</span>\n </button>\n ))}\n </div>\n )}\n </div>\n )}\n\n <div className=\"w-px h-6 bg-z-hover mx-1\" />\n\n {/* Visual / JSON toggle */}\n <div className={cn('flex items-center gap-0.5 p-0.5 rounded-none-none border', dark ? 'bg-z-hover border-z-border' : 'bg-z-panel border-z-border')}>\n <button\n onClick={() => setViewMode('visual')}\n className={cn(\n 'px-2.5 py-1 rounded-none-none text-xs font-semibold transition-all',\n viewMode === 'visual'\n ? dark ? 'bg-z-panel text-z-primary' : 'bg-[var(--z-active-bg)] text-[var(--z-active-text)] border border-[var(--z-active-border)] shadow-sm'\n : dark ? 'text-z-primary/50 hover:text-z-primary' : 'text-z-secondary hover:text-z-primary'\n )}\n >\n Visual\n </button>\n <button\n onClick={() => setViewMode('code')}\n className={cn(\n 'px-2.5 py-1 rounded-none-none text-xs font-semibold transition-all',\n viewMode === 'code'\n ? dark ? 'bg-z-panel text-z-primary' : 'bg-[var(--z-active-bg)] text-[var(--z-active-text)] border border-[var(--z-active-border)] shadow-sm'\n : dark ? 'text-z-primary/50 hover:text-z-primary' : 'text-z-secondary hover:text-z-primary'\n )}\n >\n JSON\n </button>\n </div>\n </div>\n\n {/* Right: Status + Save */}\n <div className=\"flex items-center gap-2 shrink-0\">\n {/* Draft / Publish */}\n <div className=\"flex items-center gap-1\">\n <button\n onClick={handleUnpublish}\n disabled={publishStatus === 'draft'}\n className={cn(\n 'flex items-center gap-1 px-2.5 py-1.5 rounded-none-none border text-xs font-semibold transition-all',\n publishStatus === 'draft' && workflowStatus !== 'scheduled'\n ? dark ? 'bg-amber-500/10 border-amber-500/20 text-amber-400' : 'bg-amber-50 border-amber-200 text-amber-600'\n : dark ? 'bg-z-hover border-z-border text-z-secondary' : 'bg-z-input border-z-border text-z-muted'\n )}\n aria-label=\"Set as draft\"\n >\n <Circle size={7} className={(publishStatus === 'draft' && workflowStatus !== 'scheduled') || workflowStatus === 'scheduled' ? 'fill-current' : ''} />\n {workflowStatus === 'scheduled' ? 'Scheduled' : 'Draft'}\n </button>\n <button\n onClick={() => setShowPublishConfirm(true)}\n disabled={publishStatus === 'published'}\n className={cn(\n 'flex items-center gap-1 px-2.5 py-1.5 rounded-none-none border text-xs font-semibold transition-all',\n publishStatus === 'published'\n ? dark ? 'bg-green-500/10 border-green-500/20 text-green-400' : 'bg-green-50 border-green-200 text-green-600'\n : dark ? 'bg-z-hover border-z-border text-z-secondary hover:text-z-primary' : 'bg-z-input border-z-border text-z-muted hover:text-z-primary'\n )}\n aria-label=\"Publish document\"\n >\n <Check size={10} />\n Publish\n </button>\n </div>\n\n <AutoSaveIndicator />\n\n {/* Last saved timestamp */}\n {lastSavedLabel && (\n <span className={cn('text-sm font-semibold ', dark ? 'text-z-secondary' : 'text-z-muted')}>\n {lastSavedLabel}\n </span>\n )}\n\n {/* Schedule publish */}\n <div className=\"relative\">\n <button\n onClick={() => setShowSchedulePicker(!showSchedulePicker)}\n className={cn(\n 'h-8 px-2.5 rounded-none-none border flex items-center gap-1.5 text-xs font-semibold transition-all',\n scheduledAt\n ? dark ? 'bg-amber-500/10 border-amber-500/20 text-amber-400' : 'bg-amber-50 border-amber-200 text-amber-600'\n : dark ? 'bg-z-hover border-z-border text-z-secondary hover:text-z-primary' : 'bg-[var(--z-bg-hover)] border-z-border text-z-muted hover:text-z-primary'\n )}\n title={scheduledAt ? `Scheduled: ${new Date(scheduledAt).toLocaleString()}` : 'Schedule publish'}\n aria-label={scheduledAt ? `Scheduled for ${new Date(scheduledAt).toLocaleDateString()}` : 'Schedule publish'}\n >\n <Clock size={12} />\n {scheduledAt\n ? new Date(scheduledAt).toLocaleDateString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' })\n : 'Schedule'}\n </button>\n <SchedulePicker open={showSchedulePicker} onClose={() => setShowSchedulePicker(false)} />\n </div>\n\n {/* Collab Avatars */}\n {collab && (\n <div className=\"mx-2\">\n <CollabAvatars\n users={collab.collabUsers}\n localUser={collab.localUser}\n isConnected={collab.isConnected}\n theme={theme}\n />\n </div>\n )}\n\n {/* Save */}\n <button\n onClick={handleSave}\n disabled={saving}\n className=\"flex items-center gap-1.5 px-4 py-1.5 rounded-none-none text-xs font-semibold bg-z-accent text-z-primary shadow-[0_0_16px_rgba(79,70,229,0.3)] hover:bg-z-border transition-all active:scale-95 disabled:opacity-50\"\n aria-label=\"Save document\"\n >\n {saving ? <Loader2 size={13} className=\"animate-spin\" /> : <Save size={13} />}\n {saving ? 'Saving...' : 'Save'}\n </button>\n </div>\n\n {/* Publish confirmation modal */}\n <ConfirmPublishModal\n open={showPublishConfirm}\n onConfirm={() => {\n setShowPublishConfirm(false)\n handlePublish()\n }}\n onCancel={() => setShowPublishConfirm(false)}\n />\n\n {/* Translation modal */}\n <TranslationModal\n open={showTranslationModal}\n onClose={() => setShowTranslationModal(false)}\n />\n </header>\n )\n}\n","import React from 'react'\nimport { Reorder, useDragControls } from 'framer-motion'\nimport { Plus } from 'lucide-react'\nimport { SectionBlock } from './components/SectionBlock'\nimport type { Section } from './constants'\nimport { cn } from '../../lib/utils'\n\nexport const ReorderableSectionBlock = React.memo(\n ({\n section,\n index,\n totalSections,\n theme,\n showFieldIndicators,\n editorSelectedField,\n editorSchemaFields,\n editorFieldErrors,\n editorActiveSection,\n editorSetActiveSection,\n duplicateSection,\n removeSection,\n updateAlign,\n handleFieldChange,\n setSelectedField,\n i18nEnabled,\n currentLocale,\n getTranslatedValue,\n setTranslatedValue,\n setActiveDynamicZone,\n setDynamicZoneModalOpen,\n setInjectionIndex,\n setBlockPickerOpen,\n onOpenContextMenu,\n broadcastCursor,\n toggleCollapse,\n moveSection,\n copySection,\n pasteSection,\n handleBlockNameChange,\n selectedSections,\n onMultiSelect,\n collab,\n }: {\n section: Section\n index: number\n totalSections: number\n theme: 'light' | 'dark'\n showFieldIndicators: boolean\n editorSelectedField: any\n editorSchemaFields: any[]\n editorFieldErrors: any\n editorActiveSection: string | null\n editorSetActiveSection: (id: string | null) => void\n duplicateSection: (id: string) => void\n removeSection: (id: string) => void\n updateAlign: (id: string, align: 'left' | 'center' | 'right') => void\n handleFieldChange: (id: string, key: string, val: any) => void\n setSelectedField: (field: any) => void\n i18nEnabled: boolean\n currentLocale: string\n getTranslatedValue: any\n setTranslatedValue: any\n setActiveDynamicZone: any\n setDynamicZoneModalOpen: any\n setInjectionIndex: any\n setBlockPickerOpen: any\n onOpenContextMenu: (e: React.MouseEvent, sectionId: string) => void\n broadcastCursor?: (sectionId?: string, fieldKey?: string) => void\n collab?: any // collaboration context — passed through but only broadcastCursor is consumed\n toggleCollapse: (id: string) => void\n moveSection: (id: string, dir: 'up' | 'down') => void\n copySection: (id: string) => void\n pasteSection: (id: string) => void\n handleBlockNameChange: (id: string, name: string) => void\n selectedSections: Set<string>\n onMultiSelect: (id: string, multi: boolean) => void\n }) => {\n const dragControls = useDragControls()\n\n return (\n <Reorder.Item\n key={section.id}\n value={section.id}\n dragListener={false}\n dragControls={dragControls}\n as=\"div\"\n role=\"article\"\n aria-label={`Section block ${section.title || section.blockType}`}\n tabIndex={0}\n onKeyDown={(e: React.KeyboardEvent) => {\n if (e.key === 'ArrowUp' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault()\n moveSection(section.id, 'up')\n // Announce to screen reader\n const liveRegion = document.getElementById('editor-live-region')\n if (liveRegion) liveRegion.innerText = `Moved ${section.title || section.blockType} up`\n }\n if (e.key === 'ArrowDown' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault()\n moveSection(section.id, 'down')\n const liveRegion = document.getElementById('editor-live-region')\n if (liveRegion) liveRegion.innerText = `Moved ${section.title || section.blockType} down`\n }\n }}\n whileDrag={{\n scale: 1.02,\n opacity: 0.9,\n boxShadow: '0 20px 60px rgba(0,0,0,0.3)',\n zIndex: 50,\n cursor: 'grabbing',\n }}\n className=\"relative group/item focus-visible:ring-2 focus-visible:ring-z-active-border focus-visible:outline-none\"\n >\n <div className=\"relative h-8 group/portal -mt-4\">\n <button\n onClick={() => {\n setInjectionIndex(index)\n setBlockPickerOpen(true)\n }}\n className=\"absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 opacity-0 group-hover/item:opacity-60 hover:!opacity-100 transition-all z-20 px-3 py-1 rounded-none-none border-2 border-dashed border-z-border/40 hover:border-z-border/70 backdrop-blur-xl\"\n >\n <span className={cn(\n 'text-sm font-semibold flex items-center gap-1.5 ',\n theme === 'dark' ? 'text-z-primary/70' : 'text-z-primary/70'\n )}>\n <Plus size={10} className=\"text-z-secondary \" /> Insert\n </span>\n </button>\n </div>\n <SectionBlock\n section={section}\n index={index}\n totalSections={totalSections}\n isActive={editorActiveSection === section.id}\n isMultiSelected={selectedSections.has(section.id)}\n theme={theme}\n showFieldIndicators={showFieldIndicators}\n selectedField={editorSelectedField}\n schemaFields={editorSchemaFields}\n fieldErrors={editorFieldErrors}\n onSelect={(e) => onMultiSelect(section.id, e?.shiftKey || false)}\n onDuplicate={() => duplicateSection(section.id)}\n onDelete={() => removeSection(section.id)}\n onAlign={(align) => updateAlign(section.id, align)}\n onFieldChange={(key, val) => handleFieldChange(section.id, key, val)}\n onFieldSelect={(blockId: string, fieldKey: string) => { \n setSelectedField({ blockId, fieldKey }); \n broadcastCursor?.(blockId, fieldKey);\n editorSetActiveSection(blockId);\n onMultiSelect(blockId, false);\n }}\n i18nEnabled={i18nEnabled}\n currentLocale={currentLocale}\n getTranslatedValue={getTranslatedValue}\n setTranslatedValue={setTranslatedValue}\n onAddToDynamicZone={(sectionId, fieldKey) => {\n setActiveDynamicZone({ sectionId, fieldKey })\n setDynamicZoneModalOpen(true)\n }}\n dragControls={dragControls}\n onContextMenu={(e) => onOpenContextMenu(e, section.id)}\n onToggleCollapse={() => toggleCollapse(section.id)}\n onMoveUp={() => moveSection(section.id, 'up')}\n onMoveDown={() => moveSection(section.id, 'down')}\n onCopy={() => copySection(section.id)}\n onPaste={() => pasteSection(section.id)}\n onBlockNameChange={(name) => handleBlockNameChange(section.id, name)}\n />\n </Reorder.Item>\n )\n },\n (prev, next) => {\n if (prev.section !== next.section) return false\n if (prev.index !== next.index) return false\n if (prev.totalSections !== next.totalSections) return false\n if (prev.theme !== next.theme) return false\n if (prev.showFieldIndicators !== next.showFieldIndicators) return false\n if (prev.editorActiveSection !== next.editorActiveSection) return false\n if (prev.editorFieldErrors !== next.editorFieldErrors) return false\n if (prev.editorSelectedField !== next.editorSelectedField) return false\n if (prev.editorSchemaFields !== next.editorSchemaFields) return false\n if (prev.i18nEnabled !== next.i18nEnabled) return false\n if (prev.currentLocale !== next.currentLocale) return false\n if (prev.broadcastCursor !== next.broadcastCursor) return false\n if (prev.handleFieldChange !== next.handleFieldChange) return false\n if (prev.selectedSections !== next.selectedSections) return false\n if (prev.onMultiSelect !== next.onMultiSelect) return false\n return true\n }\n)\n\n","import React from 'react'\nimport { AlertTriangle, RefreshCw, Copy } from 'lucide-react'\nimport { useTheme } from '../context/ThemeContext'\nimport { cn } from '../lib/utils'\n\ninterface EditorErrorBoundaryProps {\n children: React.ReactNode\n onReset?: () => void\n}\n\ninterface ErrorInfo {\n message: string\n stack?: string\n componentStack?: string\n}\n\ninterface State {\n hasError: boolean\n error: ErrorInfo | null\n}\n\n/**\n * Editor-level error boundary that catches React render errors\n * and displays a glassmorphic recovery UI instead of a blank white screen.\n */\nexport class EditorErrorBoundary extends React.Component<EditorErrorBoundaryProps, State> {\n constructor(props: EditorErrorBoundaryProps) {\n super(props)\n this.state = { hasError: false, error: null }\n }\n\n static getDerivedStateFromError(error: Error): State {\n return { hasError: true, error: { message: (error instanceof Error ? error.message : String(error)), stack: (error instanceof Error ? error.stack : undefined) } }\n }\n\n componentDidCatch(error: Error, info: React.ErrorInfo) {\n this.setState({\n error: { message: (error instanceof Error ? error.message : String(error)), stack: (error instanceof Error ? error.stack : undefined), componentStack: info.componentStack },\n })\n }\n\n handleReset = () => {\n this.setState({ hasError: false, error: null })\n this.props.onReset?.()\n }\n\n handleCopyError = () => {\n const { error } = this.state\n if (!error) return\n const text = [(error instanceof Error ? error.message : String(error)), (error instanceof Error ? error.stack : undefined), error.componentStack].filter(Boolean).join('\\n\\n')\n navigator.clipboard.writeText(text).catch(() => {})\n }\n\n render() {\n if (this.state.hasError && this.state.error) {\n return <ErrorUI error={this.state.error} onReset={this.handleReset} onCopy={this.handleCopyError} />\n }\n return this.props.children\n }\n}\n\n// Extracted so it can access theme context\nconst ErrorUI: React.FC<{ error: ErrorInfo; onReset: () => void; onCopy: () => void }> = ({ error, onReset, onCopy }) => {\n const { theme } = useTheme()\n\n return (\n <div className=\"flex flex-col items-center justify-center h-full min-h-64 gap-6 p-8\">\n <div\n className={cn(\n 'w-14 h-14 rounded-none-none flex items-center justify-center border-2',\n theme === 'dark' ? 'bg-rose-500/10 border-rose-500/20' : 'bg-rose-50 border-rose-200'\n )}\n >\n <AlertTriangle size={24} className={theme === 'dark' ? 'text-rose-400' : 'text-rose-500'} />\n </div>\n\n <div className=\"text-center max-w-md\">\n <h2\n className={cn(\n 'text-sm font-semibold mb-2',\n theme === 'dark' ? 'text-z-primary' : 'text-z-primary'\n )}\n >\n Something went wrong\n </h2>\n <p\n className={cn(\n 'text-xs leading-relaxed font-mono px-3 py-2 border rounded-none-none',\n theme === 'dark' ? 'text-rose-400 bg-rose-500/5 border-rose-500/10' : 'text-rose-600 bg-rose-50 border-rose-200'\n )}\n >\n {(error instanceof Error ? error.message : String(error))}\n </p>\n </div>\n\n <div className=\"flex items-center gap-3\">\n <button\n onClick={onReset}\n className={cn(\n 'flex items-center gap-2 px-4 py-2 text-xs font-semibold border rounded-none-none transition-all',\n 'bg-z-accent hover:bg-z-border text-z-primary border-z-border'\n )}\n >\n <RefreshCw size={12} />\n Try Again\n </button>\n <button\n onClick={onCopy}\n className={cn(\n 'flex items-center gap-2 px-3 py-2 text-xs font-semibold border rounded-none-none transition-all',\n theme === 'dark'\n ? 'border-z-border text-z-muted hover:bg-z-hover'\n : 'border-z-border text-z-secondary hover:bg-[var(--z-bg-input)]'\n )}\n >\n <Copy size={11} />\n Copy Error\n </button>\n </div>\n\n {error.componentStack && (\n <details className=\"w-full max-w-2xl\">\n <summary\n className={cn(\n 'text-sm font-semibold cursor-pointer mb-1',\n 'text-z-secondary'\n )}\n >\n Component Stack\n </summary>\n <pre\n className={cn(\n 'w-full text-sm font-mono p-3 border rounded-none-none overflow-x-auto max-h-48',\n theme === 'dark' ? 'bg-z-hover border-z-border text-z-secondary' : 'bg-z-input border-z-border text-z-secondary'\n )}\n >\n {error.componentStack}\n </pre>\n </details>\n )}\n </div>\n )\n}\n\nexport default EditorErrorBoundary\n","import React, { useEffect, useState } from 'react'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport { X, ArrowLeftRight, RotateCcw, Loader2, FileText, CheckCircle2 } from 'lucide-react'\nimport { useTheme } from '../../../context/ThemeContext'\nimport { cn } from '../../../lib/utils'\nimport api from '../../../lib/api'\nimport toast from 'react-hot-toast'\n\ninterface DocumentDiffModalProps {\n versionId: string | null\n versionNumber: number\n collection: string\n documentId: string\n onClose: () => void\n onRestoreSuccess: (restoredDoc: any) => void\n}\n\ninterface DiffItem {\n field: string\n from: any\n to: any\n}\n\nexport const DocumentDiffModal: React.FC<DocumentDiffModalProps> = ({\n versionId,\n versionNumber,\n collection,\n documentId,\n onClose,\n onRestoreSuccess,\n}) => {\n const { theme } = useTheme()\n const [loading, setLoading] = useState(true)\n const [diffs, setDiffs] = useState<DiffItem[]>([])\n const [rollingBackField, setRollingBackField] = useState<string | null>(null)\n\n useEffect(() => {\n if (!versionId) return\n setLoading(true)\n api.get(`/versions/${collection}/${documentId}/${versionId}/diff`)\n .then((res) => {\n setDiffs(res.data?.data?.diffs || [])\n })\n .catch(() => {\n toast.error('Failed to load version differences')\n onClose()\n })\n .finally(() => {\n setLoading(false)\n })\n }, [versionId, collection, documentId, onClose])\n\n const handleRollbackField = async (fieldName: string) => {\n if (!versionId) return\n setRollingBackField(fieldName)\n try {\n const res = await api.post(`/versions/${collection}/${documentId}/${versionId}/rollback-fields`, {\n fields: [fieldName]\n })\n toast.success(`Successfully rolled back field: ${fieldName.toUpperCase()}`)\n if (res.data?.data?.document) {\n onRestoreSuccess(res.data.data.document)\n }\n // Remove field from active diff list\n setDiffs(prev => prev.filter(d => d.field !== fieldName))\n } catch {\n toast.error(`Failed to rollback field: ${fieldName}`)\n } finally {\n setRollingBackField(null)\n }\n }\n\n const renderValuePreview = (val: any) => {\n if (val === null || val === undefined) {\n return <span className=\"text-z-secondary text-xs\">None / Empty</span>\n }\n if (typeof val === 'object') {\n return (\n <pre className=\"text-xs font-mono whitespace-pre-wrap leading-relaxed opacity-85\">\n {JSON.stringify(val, null, 2)}\n </pre>\n )\n }\n const valStr = String(val)\n if (valStr.startsWith('<') && valStr.endsWith('>')) {\n // Basic HTML tags strip for preview\n const cleanText = valStr.replace(/<\\/?[^>]+(>|$)/g, \"\")\n return <span className=\"text-sm leading-relaxed\">{cleanText}</span>\n }\n return <span className=\"text-sm leading-relaxed\">{valStr}</span>\n }\n\n const isDark = theme === 'dark'\n\n return (\n <AnimatePresence>\n {versionId && (\n <>\n {/* Backdrop */}\n <div className=\"fixed inset-0 z-[110] bg-app/50 backdrop-blur-md\" onClick={onClose} />\n\n {/* Modal Container */}\n <motion.div\n initial={{ opacity: 0, scale: 0.95, y: 15 }}\n animate={{ opacity: 1, scale: 1, y: 0 }}\n exit={{ opacity: 0, scale: 0.95, y: 15 }}\n transition={{ type: 'spring', damping: 25, stiffness: 250 }}\n className={cn(\n 'fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 z-[120] w-[85vw] max-w-[1100px] h-[80vh] flex flex-col border shadow-2xl overflow-hidden font-sans',\n isDark ? 'bg-app border-z-border text-z-primary' : 'bg-z-panel border-z-border text-z-primary'\n )}\n >\n {/* Header */}\n <div className=\"p-6 border-b border-z-border flex items-center justify-between shrink-0 bg-gradient-to-r from-[var(--z-bg-panel)] to-transparent\">\n <div className=\"flex items-center gap-3\">\n <div className=\"w-9 h-9 border flex items-center justify-center text-z-secondary\">\n <ArrowLeftRight size={16} />\n </div>\n <div>\n <h3 className=\"text-base font-semibold\">\n Compare Differences — V.{versionNumber}\n </h3>\n <p className=\"text-xs text-z-secondary mt-0.5\">\n Compare historical version snapshot with current working draft\n </p>\n </div>\n </div>\n <button\n onClick={onClose}\n aria-label=\"Close diff view\"\n className={cn(\n 'p-2 rounded-none-none transition-colors',\n isDark ? 'hover:bg-z-hover text-z-muted hover:text-z-primary' : 'hover:bg-[var(--z-bg-hover)] text-z-secondary hover:text-z-primary'\n )}\n >\n <X size={15} aria-hidden=\"true\" />\n </button>\n </div>\n\n {/* Content Body */}\n <div className=\"flex-1 overflow-y-auto p-6 space-y-6 custom-editor-scrollbar\">\n {loading ? (\n <div className=\"h-full flex flex-col items-center justify-center gap-4\">\n <Loader2 size={32} className=\"animate-spin text-z-secondary \" />\n <p className=\"text-xs font-semibold text-z-secondary animate-pulse\">\n Analyzing delta changes...\n </p>\n </div>\n ) : diffs.length === 0 ? (\n <div className=\"h-full flex flex-col items-center justify-center gap-3 text-center\">\n <CheckCircle2 size={36} className=\"text-z-secondary \" />\n <div>\n <h4 className=\"text-xs font-semibold\">No Differences Detected</h4>\n <p className=\"text-xs text-z-secondary mt-1\">\n This version snapshot matches the current working copy exactly.\n </p>\n </div>\n </div>\n ) : (\n <div className=\"space-y-8\">\n {diffs.map((diff) => (\n <div\n key={diff.field}\n className={cn(\n 'border rounded-none-none overflow-hidden',\n isDark ? 'border-z-border bg-app/10' : 'border-z-border bg-[var(--z-bg-input)]/50'\n )}\n >\n {/* Diff Item Header */}\n <div className={cn(\n 'px-4 py-2.5 border-b flex items-center justify-between',\n isDark ? 'bg-z-panel border-z-border' : 'bg-[var(--z-bg-hover)] border-z-border'\n )}>\n <div className=\"flex items-center gap-2\">\n <FileText size={13} className=\"text-z-secondary\" />\n <span className=\"text-xs font-semibold\">\n {diff.field.replace(':', ' ').toUpperCase()}\n </span>\n </div>\n <button\n onClick={() => handleRollbackField(diff.field)}\n disabled={rollingBackField === diff.field}\n className=\"flex items-center gap-1.5 px-2.5 py-1 text-xs font-semibold bg-z-accent/10 hover:bg-z-accent border border-z-border/20 hover:border-z-border text-z-secondary hover:text-z-primary transition-all disabled:opacity-50\"\n >\n {rollingBackField === diff.field ? (\n <Loader2 size={10} className=\"animate-spin\" />\n ) : (\n <RotateCcw size={10} />\n )}\n Rollback Field\n </button>\n </div>\n\n {/* Side-by-Side Comparison */}\n <div className=\"grid grid-cols-1 md:grid-cols-2 divide-y md:divide-y-0 md:divide-x divide-z-border\">\n {/* Old Version Val (Red Tint) */}\n <div className=\"p-4 bg-red-500/[0.01] flex flex-col gap-2\">\n <span className=\"text-xs font-semibold text-rose-500 block\">\n Previous Value (V.{versionNumber})\n </span>\n <div className=\"flex-1 bg-red-500/[0.03] border border-red-500/10 rounded-none p-3 text-red-100/90 min-h-16 overflow-x-auto custom-editor-scrollbar\">\n {renderValuePreview(diff.from)}\n </div>\n </div>\n\n {/* Current Value (Green Tint) */}\n <div className=\"p-4 bg-z-border/[0.01] flex flex-col gap-2\">\n <span className=\"text-xs font-semibold text-z-secondary block\">\n Current Value\n </span>\n <div className=\"flex-1 bg-z-border/[0.03] border border-z-border/10 rounded-none p-3 text-z-primary/90 min-h-16 overflow-x-auto custom-editor-scrollbar\">\n {renderValuePreview(diff.to)}\n </div>\n </div>\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n\n {/* Footer */}\n <div className=\"p-4 border-t border-z-border flex items-center justify-end bg-gradient-to-r from-transparent to-[var(--z-bg-panel)]\">\n <button\n onClick={onClose}\n className=\"px-5 py-2 border border-z-border hover:border-z-border text-xs font-semibold hover:bg-z-hover transition-all text-z-muted hover:text-z-primary\"\n >\n Close Comparison\n </button>\n </div>\n </motion.div>\n </>\n )}\n </AnimatePresence>\n )\n}\n","import React, { useState } from 'react'\nimport { motion, AnimatePresence } from 'framer-motion'\nimport { AlertTriangle, RefreshCw, X, Check } from 'lucide-react'\nimport { useTheme } from '../../../context/ThemeContext'\nimport { cn } from '../../../lib/utils'\n\ninterface ConflictResolutionModalProps {\n open: boolean\n onClose: () => void\n /** Reload the server's version, discarding local changes */\n onReload: () => void\n /** Force-save: keep local changes but tell the server to accept the conflict */\n onForceSave: () => void\n /** Message from the server about why conflict occurred */\n conflictMessage?: string\n /** Server's current version number */\n serverVersion?: number\n /** What local version the user had when the conflict occurred */\n localVersion?: number\n theme: 'light' | 'dark'\n}\n\nexport const ConflictResolutionModal: React.FC<ConflictResolutionModalProps> = ({\n open,\n onClose,\n onReload,\n onForceSave,\n conflictMessage,\n serverVersion,\n localVersion,\n theme,\n}) => {\n const [loading, setLoading] = useState(false)\n\n const handleReload = async () => {\n setLoading(true)\n try {\n await onReload()\n } finally {\n setLoading(false)\n onClose()\n }\n }\n\n const handleForceSave = async () => {\n setLoading(true)\n try {\n await onForceSave()\n } finally {\n setLoading(false)\n onClose()\n }\n }\n\n return (\n <AnimatePresence>\n {open && (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n className=\"fixed inset-0 z-[1000] flex items-center justify-center bg-app/70 backdrop-blur-sm\"\n onClick={(e) => {\n if (e.target === e.currentTarget) onClose()\n }}\n >\n <motion.div\n initial={{ opacity: 0, scale: 0.95, y: 10 }}\n animate={{ opacity: 1, scale: 1, y: 0 }}\n exit={{ opacity: 0, scale: 0.95, y: 10 }}\n transition={{ duration: 0.15 }}\n className={cn(\n 'w-full max-w-md border rounded-none-none shadow-2xl',\n theme === 'dark'\n ? 'bg-app border-rose-500/20 text-z-primary'\n : 'bg-z-panel border-rose-200 text-z-primary'\n )}\n >\n {/* Header */}\n <div className={cn(\n 'px-6 py-5 border-b flex items-start gap-4',\n theme === 'dark' ? 'border-z-border' : 'border-z-border shadow-sm'\n )}>\n <div className={cn(\n 'w-10 h-10 rounded-none-none border flex items-center justify-center shrink-0',\n theme === 'dark'\n ? 'bg-rose-500/10 border-rose-500/20 text-rose-400'\n : 'bg-rose-50 border-rose-200 text-rose-500'\n )}>\n <AlertTriangle size={18} />\n </div>\n <div className=\"flex-1\">\n <h2 className=\"text-xs font-semibold text-rose-400\">\n Conflict Detected\n </h2>\n <p className=\"text-xs font-bold text-z-secondary mt-1 leading-relaxed\">\n Another editor saved changes to this document while you were editing.\n <br />\n Version mismatch: you had <span className=\"font-semibold text-z-secondary\">v{localVersion ?? '?'}</span>, server now at <span className=\"font-semibold text-amber-400\">v{serverVersion ?? '?'}</span>.\n </p>\n {conflictMessage && (\n <p className=\"text-xs font-bold text-rose-400/70 mt-1.5 tracking-wide\">\n {conflictMessage}\n </p>\n )}\n </div>\n <button\n onClick={onClose}\n className={cn(\n 'shrink-0 p-1 transition-colors',\n theme === 'dark' ? 'text-z-secondary hover:text-z-primary' : 'text-z-muted hover:text-z-primary'\n )}\n >\n <X size={16} />\n </button>\n </div>\n\n {/* Body */}\n <div className=\"px-6 py-5 space-y-4\">\n <div className={cn(\n 'p-4 border rounded-none-none text-xs font-bold tracking-wide leading-relaxed',\n theme === 'dark'\n ? 'bg-z-panel/3 border-z-border text-z-muted'\n : 'bg-z-input border-z-border shadow-sm text-z-secondary'\n )}>\n <p>Choose <span className=\"font-semibold text-z-primary\">\"Use Their Version\"</span> to discard your unsaved changes and reload the server's latest content.</p>\n <p className=\"mt-2\">Choose <span className=\"font-semibold text-z-primary\">\"Keep My Changes\"</span> to overwrite the server's changes with yours (the server will update its version to match).</p>\n </div>\n\n {/* Version comparison */}\n <div className={cn(\n 'grid grid-cols-1 md:grid-cols-2 gap-3 p-3 border border-dashed rounded-none-none',\n 'border-z-border'\n )}>\n <div className=\"text-center\">\n <p className=\"text-sm font-semibold text-z-secondary mb-1\">Your Version</p>\n <p className=\"text-lg font-semibold text-z-secondary\">v{localVersion ?? '?'}</p>\n </div>\n <div className=\"text-center\">\n <p className=\"text-sm font-semibold text-z-secondary mb-1\">Server Version</p>\n <p className=\"text-lg font-semibold text-amber-400\">v{serverVersion ?? '?'}</p>\n </div>\n </div>\n </div>\n\n {/* Actions */}\n <div className={cn(\n 'px-6 py-4 border-t flex gap-3',\n theme === 'dark' ? 'border-z-border' : 'border-z-border shadow-sm'\n )}>\n <button\n type=\"button\"\n disabled={loading}\n onClick={handleReload}\n className={cn(\n 'flex-1 flex items-center justify-center gap-2 py-3 text-xs font-semibold border rounded-none-none transition-all',\n theme === 'dark'\n ? 'border-amber-500/30 text-amber-400 hover:bg-amber-500/10 hover:border-amber-500/50'\n : 'border-amber-300 text-amber-600 hover:bg-amber-50 hover:border-amber-400',\n loading && 'opacity-50 cursor-not-allowed'\n )}\n >\n <RefreshCw size={11} className={loading ? 'animate-spin' : ''} />\n Use Their Version\n </button>\n <button\n type=\"button\"\n disabled={loading}\n onClick={handleForceSave}\n className={cn(\n 'flex-1 flex items-center justify-center gap-2 py-3 text-xs font-semibold rounded-none-none transition-all bg-z-accent text-z-primary hover:bg-z-border border border-z-border',\n loading && 'opacity-50 cursor-not-allowed'\n )}\n >\n <Check size={11} className={loading ? 'animate-spin' : ''} />\n Keep My Changes\n </button>\n </div>\n </motion.div>\n </motion.div>\n )}\n </AnimatePresence>\n )\n}\n\nexport default ConflictResolutionModal\n","import React, { useMemo } from 'react'\nimport { useEditorStore } from '../../../store/editorStore'\nimport { useTheme } from '../../../context/ThemeContext'\nimport { cn } from '../../../lib/utils'\n\nexport const EditorStatusBar: React.FC = () => {\n const { theme } = useTheme()\n const data = useEditorStore((s) => s.data)\n\n const stats = useMemo(() => {\n if (!data) return { words: 0, chars: 0, blocks: 0 }\n\n const allText: string[] = []\n\n if (data.title) allText.push(data.title)\n if (data.heroDescription) allText.push(\n typeof data.heroDescription === 'string'\n ? data.heroDescription\n : String(data.heroDescription)\n )\n ;(data.sections || []).forEach((section: any) => {\n Object.values(section.content || {}).forEach((val) => {\n if (typeof val === 'string') allText.push(val)\n else if (typeof val === 'object') {\n try {\n const str = JSON.stringify(val)\n if (!str.startsWith('[{') && !str.startsWith('{')) {\n const clean = str.replace(/<[^>]+>/g, ' ').trim()\n if (clean) allText.push(clean)\n }\n } catch {\n // silent ignore\n }\n }\n })\n })\n\n const combined = allText.join(' ')\n const words = combined.trim() ? combined.trim().split(/\\s+/).length : 0\n const chars = combined.replace(/\\s+/g, '').length\n\n return {\n words,\n chars,\n blocks: (data.sections || []).length,\n }\n }, [data])\n\n return (\n <div\n className={cn(\n 'h-7 border-t flex items-center justify-between px-5 shrink-0 select-none',\n theme === 'dark'\n ? 'bg-z-popover border-z-border text-z-secondary'\n : 'bg-z-panel/90 border-z-border shadow-sm text-z-muted'\n )}\n >\n <div className=\"flex items-center gap-4 text-xs font-semibold\">\n <span>\n <span className=\"font-semibold\">{stats.words.toLocaleString()}</span>{' '}\n <span className={stats.words === 0 ? 'text-rose-500/50' : ''}>words</span>\n </span>\n <span className=\"w-px h-3 bg-z-panel/10\" />\n <span>\n <span className=\"font-semibold\">{stats.chars.toLocaleString()}</span>{' '}\n <span className={stats.chars === 0 ? 'text-rose-500/50' : ''}>chars</span>\n </span>\n <span className=\"w-px h-3 bg-z-panel/10\" />\n <span>\n <span className=\"font-semibold\">{stats.blocks}</span>{' '}\n {stats.blocks === 1 ? 'block' : 'blocks'}\n </span>\n </div>\n <div className=\"flex items-center gap-4 text-xs font-semibold text-z-secondary/50\">\n <span>ZENITH EDITOR</span>\n <span>v0.2</span>\n </div>\n </div>\n )\n}\n\nexport default EditorStatusBar\n","import { useEffect, useRef } from 'react'\n\nconst debounce = <T extends (...args: any[]) => void>(fn: T, ms: number) => {\n let timer: ReturnType<typeof setTimeout>\n const debounced = (...args: Parameters<T>) => {\n clearTimeout(timer)\n timer = setTimeout(() => fn(...args), ms)\n }\n debounced.cancel = () => clearTimeout(timer)\n return debounced\n}\n\n/**\n * Content hash for change detection — samples enough of each string value\n * to catch single-character edits anywhere in the content.\n */\nfunction quickHash(data: any): string {\n if (!data) return ''\n try {\n return JSON.stringify(data)\n } catch {\n return String(Date.now())\n }\n}\n\n/** Debounced, diff-guarded postMessage sync to the storefront iframe. */\nexport function usePreviewSync<T>(\n iframeRef: React.RefObject<HTMLIFrameElement | null>,\n data: T | null,\n delayMs = 300\n) {\n const lastHashRef = useRef<string>('')\n const syncRef = useRef<ReturnType<typeof debounce> | null>(null)\n\n useEffect(() => {\n syncRef.current = debounce((payload: T) => {\n const hash = quickHash(payload)\n if (hash === lastHashRef.current) return // no change — skip\n lastHashRef.current = hash\n\n const target = iframeRef.current?.contentWindow\n if (!target) return\n\n const iframeUrl = iframeRef.current?.src\n let origin = '*'\n if (iframeUrl) {\n try {\n const urlObj = new URL(iframeUrl)\n origin = urlObj.origin\n } catch {\n // ignore\n }\n }\n target.postMessage({ type: 'ZENITH_DATA_UPDATE', data: payload }, origin)\n }, delayMs)\n\n return () => {\n if (syncRef.current) {\n syncRef.current.cancel()\n }\n }\n }, [delayMs, iframeRef])\n\n const dataRef = useRef(data)\n useEffect(() => {\n dataRef.current = data\n }, [data])\n\n useEffect(() => {\n const sync = syncRef.current\n if (data && sync) sync(data)\n }, [data])\n\n // Attach load event listener to the iframe to send data immediately upon load\n useEffect(() => {\n const iframe = iframeRef.current\n if (!iframe) return\n\n const handleLoad = () => {\n lastHashRef.current = '' // Force sync\n const sync = syncRef.current\n if (sync && dataRef.current) sync(dataRef.current)\n }\n\n iframe.addEventListener('load', handleLoad)\n return () => iframe.removeEventListener('load', handleLoad)\n }, [iframeRef])\n}\n","import { useCallback } from 'react'\n\nexport interface ValidationError {\n sectionId: string\n fieldName: string\n message: string\n}\n\nexport interface FieldDef {\n name: string\n label?: string\n type: string\n required?: boolean\n maxLength?: number\n minLength?: number\n min?: number\n max?: number\n}\n\nexport interface BlockDef {\n slug: string\n label?: string\n fields?: FieldDef[]\n defaultContent?: any\n}\n\nexport interface SectionData {\n id?: string\n blockType?: string\n content?: any\n [key: string]: any\n}\n\nexport interface PageData {\n sections?: SectionData[]\n [key: string]: any\n}\n\n/** Validates section content against block field definitions before saving. */\nexport function validateBeforeSave(\n pageData: PageData | null,\n blockLibrary: BlockDef[]\n): ValidationError[] {\n if (!pageData?.sections?.length) return []\n\n const errors: ValidationError[] = []\n\n for (const section of pageData.sections) {\n const blockDef = blockLibrary.find((b) => b.slug === section.blockType)\n if (!blockDef?.fields) continue\n\n for (const field of blockDef.fields) {\n const value = section.content?.[field.name]\n\n if (field.required && (value === undefined || value === null)) {\n errors.push({\n sectionId: section.id ?? section.blockType ?? 'unknown',\n fieldName: field.name,\n message: `${field.label ?? field.name} is required`,\n })\n continue\n }\n\n if (typeof value === 'string') {\n if (field.maxLength && value.length > field.maxLength) {\n errors.push({\n sectionId: section.id ?? section.blockType ?? 'unknown',\n fieldName: field.name,\n message: `${field.label ?? field.name} exceeds ${field.maxLength} characters (current: ${value.length})`,\n })\n }\n if (field.minLength && value.length < field.minLength) {\n errors.push({\n sectionId: section.id ?? section.blockType ?? 'unknown',\n fieldName: field.name,\n message: `${field.label ?? field.name} must be at least ${field.minLength} characters`,\n })\n }\n }\n\n if (typeof value === 'number') {\n if (field.min !== undefined && value < field.min) {\n errors.push({\n sectionId: section.id ?? section.blockType ?? 'unknown',\n fieldName: field.name,\n message: `${field.label ?? field.name} must be at least ${field.min}`,\n })\n }\n if (field.max !== undefined && value > field.max) {\n errors.push({\n sectionId: section.id ?? section.blockType ?? 'unknown',\n fieldName: field.name,\n message: `${field.label ?? field.name} must be at most ${field.max}`,\n })\n }\n }\n }\n }\n\n return errors\n}\n\n/** React hook wrapping the validator with useCallback + toast feedback. */\nexport function useValidation(blockLibrary: BlockDef[]) {\n return useCallback(\n (pageData: PageData | null): ValidationError[] => validateBeforeSave(pageData, blockLibrary),\n [blockLibrary]\n )\n}\n","import { useEffect, useRef } from 'react'\nimport { useNavigate, useParams } from 'react-router-dom'\nimport toast from 'react-hot-toast'\nimport api from '../../../lib/api'\nimport { useEditorStore } from '../../../store/editorStore'\nimport { useWorkflowStore } from '../../../store/workflowStore'\nimport type { PageData, Section } from '../constants'\nimport { uid } from '../../../lib/utils'\n\nexport function useSpatialSave({\n isGlobal,\n isNewDoc,\n id,\n data,\n dataRef,\n hasUnsavedChanges,\n saving,\n validate,\n publishStatusRef,\n workflowStatusRef,\n workflowReviewersRef,\n workflowCommentsRef,\n scheduledAtRef,\n translationsRef,\n fieldSettingsRef,\n publishStatus,\n workflowStatus,\n workflowReviewers,\n workflowComments,\n scheduledAt,\n translations,\n editorFieldSettings,\n setConflictData,\n conflictData,\n}: any) {\n\n const navigate = useNavigate()\n const params = useParams<{ id?: string; slug?: string }>()\n const saveTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n const isSavingRef = useRef(false)\n\n const editorSetSaving = useEditorStore((s) => s.setSaving)\n const editorSetHasUnsavedChanges = useEditorStore((s) => s.setHasUnsavedChanges)\n const setStoreFieldErrors = useEditorStore((s) => s.setFieldErrors)\n const editorUpdateData = useEditorStore((s) => s.updateData)\n const editorSetData = useEditorStore((s) => s.setData)\n const setHistory = useEditorStore((s) => s.setHistory)\n const undo = useEditorStore((s) => s.undo)\n const redo = useEditorStore((s) => s.redo)\n \n const setPublishStatus = useWorkflowStore((s) => s.setPublishStatus)\n const setScheduledAt = useWorkflowStore((s) => s.setScheduledAt)\n const setWorkflowStatus = useWorkflowStore((s) => s.setWorkflowStatus)\n\n // Store latest state in refs so the timeout callback always reads fresh values\n const autoSaveStateRef = useRef<{ data: PageData | null; publishStatus: string; workflowStatus: string; workflowReviewers: any[]; workflowComments: any[]; scheduledAt: string; translations: any; fieldSettings: any }>({\n data: null, publishStatus: 'draft', workflowStatus: 'draft', workflowReviewers: [], workflowComments: [], scheduledAt: '', translations: {}, fieldSettings: {},\n })\n // Keep refs in sync with latest state\n useEffect(() => {\n autoSaveStateRef.current = {\n data, publishStatus, workflowStatus, workflowReviewers, workflowComments, scheduledAt, translations, fieldSettings: editorFieldSettings,\n }\n }, [data, publishStatus, workflowStatus, workflowReviewers, workflowComments, scheduledAt, translations, editorFieldSettings])\n\n useEffect(() => {\n if (!hasUnsavedChanges || saving) return\n if (saveTimeoutRef.current) clearTimeout(saveTimeoutRef.current)\n saveTimeoutRef.current = setTimeout(() => {\n // Read from refs at fire time — always fresh\n const s = autoSaveStateRef.current\n if (!s.data) return\n // Build a handleSave-equivalent inline to avoid stale closure\n ;(async () => {\n if (!s.data) return\n const errors = validate(s.data)\n if (errors.length > 0) {\n const errorMap: Record<string, string> = {}\n errors.forEach(e => {\n const key = `${e.sectionId}:${e.fieldName}`\n errorMap[key] = (e instanceof Error ? e.message : String(e))\n })\n setStoreFieldErrors(errorMap)\n toast.error(`${errors.length} validation error(s) found. Please fix the errors.`)\n return\n }\n // Clear errors\n setStoreFieldErrors({})\n editorSetSaving(true)\n try {\n const autoTitleSection = (s.data?.sections || []).find((sec: any) => sec.blockType === 'pageTitle')\n const autoDescSection = (s.data?.sections || []).find((sec: any) => sec.blockType === 'pageDescription')\n const payload = {\n ...s.data,\n title: autoTitleSection?.content?.title ?? s.data?.title,\n heroDescription: autoDescSection?.content?.description ?? s.data?.heroDescription,\n sections: (s.data?.sections || []).map((sec: any) => {\n const { id, content, ...rest } = sec;\n return { ...rest, ...(sanitizeContent(content || {})) };\n }) || [],\n _status: s.publishStatus, workflowStatus: s.workflowStatus, reviewers: s.workflowReviewers, comments: s.workflowComments, scheduledAt: s.scheduledAt || undefined, publishedAt: s.publishStatus === 'published' ? (s.data.publishedAt || new Date().toISOString()) : null, i18n: s.translations, _fieldSettings: s.fieldSettings\n }\n if (isGlobal) {\n await api.patch(`/globals/${id}`, payload)\n } else if (isNewDoc) {\n const res = await api.post(`/${params.slug || 'pages'}`, payload)\n const newId = res.data?.data?._id || res.data?.data?.id\n if (newId) {\n navigate(`/collections/${params.slug || 'pages'}/${newId}`, { replace: true })\n }\n } else {\n await api.patch(`/${params.slug || 'pages'}/${id}`, payload)\n }\n editorSetHasUnsavedChanges(false)\n useEditorStore.getState().setLastSavedAt(new Date().toISOString())\n } catch { toast.error('Auto-save failed', { icon: '️', duration: 3000 }) } finally { editorSetSaving(false) }\n })()\n }, 30000)\n return () => { if (saveTimeoutRef.current) clearTimeout(saveTimeoutRef.current) }\n }, [data, hasUnsavedChanges, saving, isGlobal, id, validate])\n\n\n const sanitizeContent = (content: any): any => {\n const cleaned: any = {}\n for (const [key, val] of Object.entries(content)) {\n if (val === '' || val === null || val === undefined) continue\n if (Array.isArray(val) && val.length === 0) continue\n if (typeof val === 'object' && !Array.isArray(val) && Object.keys(val).length === 0) continue\n cleaned[key] = val\n }\n return cleaned\n }\n\n const handleSave = async () => {\n if (isSavingRef.current) return\n isSavingRef.current = true\n const latest = dataRef.current\n if (!latest) { isSavingRef.current = false; return }\n const errors = validate(latest)\n if (errors.length > 0) {\n const errorMap: Record<string, string> = {}\n errors.forEach(e => {\n const key = `${e.sectionId}:${e.fieldName}`\n errorMap[key] = (e instanceof Error ? e.message : String(e))\n })\n setStoreFieldErrors(errorMap)\n toast.error(`${errors.length} validation error(s) found. Please fix the errors before saving.`)\n isSavingRef.current = false\n return\n }\n setStoreFieldErrors({})\n if (saveTimeoutRef.current) clearTimeout(saveTimeoutRef.current)\n editorSetSaving(true)\n let savedVersion: number | undefined\n try {\n const pStatus = publishStatusRef.current\n // Extract pageTitle/pageDescription from sections back to root fields for backward compat\n const pageTitleSection = (latest.sections || []).find((s: any) => s.blockType === 'pageTitle')\n const pageDescSection = (latest.sections || []).find((s: any) => s.blockType === 'pageDescription')\n const payload = {\n ...latest,\n title: pageTitleSection?.content?.title ?? latest.title,\n heroDescription: pageDescSection?.content?.description ?? latest.heroDescription,\n sections: (latest.sections || []).map((s: any) => {\n const { id, content, ...rest } = s;\n return { ...rest, ...sanitizeContent(content || {}) };\n }) || [],\n _status: pStatus, workflowStatus: workflowStatusRef.current, reviewers: workflowReviewersRef.current, comments: workflowCommentsRef.current, scheduledAt: scheduledAtRef.current || undefined, publishedAt: pStatus === 'published' ? (latest.publishedAt || new Date().toISOString()) : null, i18n: translationsRef.current, _fieldSettings: fieldSettingsRef.current\n }\n let res;\n if (isGlobal) {\n res = await api.patch(`/globals/${id}`, payload)\n } else if (isNewDoc) {\n res = await api.post(`/${params.slug || 'pages'}`, payload)\n } else {\n res = await api.patch(`/${params.slug || 'pages'}/${id}`, payload)\n }\n savedVersion = res.data.data?._version\n const newId = res.data?.data?._id || res.data?.data?.id\n editorSetHasUnsavedChanges(false)\n useEditorStore.getState().setLastSavedAt(new Date().toISOString())\n toast.success(pStatus === 'published' ? ' Published!' : ' Saved as Draft', {})\n \n if (isNewDoc && newId) {\n navigate(`/collections/${params.slug || 'pages'}/${newId}`, { replace: true })\n }\n } catch (err: any) {\n if (err?.response?.status === 409) {\n const serverMsg = err?.response?.data?.error?.message || ''\n const serverVerMatch = serverMsg.match(/current\\s+(\\d+)/i)\n setConflictData({\n open: true,\n message: serverMsg,\n serverVersion: serverVerMatch ? parseInt(serverVerMatch[1]) : (err?.response?.data?.data?.currentVersion ?? undefined),\n localVersion: latest._version ?? undefined,\n })\n editorSetSaving(false)\n isSavingRef.current = false\n return\n }\n toast.error(err?.response?.data?.error?.message || err?.response?.data?.message || 'Failed to save changes')\n editorSetSaving(false)\n isSavingRef.current = false\n return\n }\n editorSetSaving(false)\n isSavingRef.current = false\n if (savedVersion !== undefined) {\n editorUpdateData((draft) => { draft._version = savedVersion })\n const collectionName = isGlobal ? 'globals' : (params.slug || 'pages')\n api.get(`/versions/${collectionName}/${id}`)\n .then((res) => setHistory(res.data.data || []))\n .catch(() => {})\n }\n }\n\n const handleUndo = () => { undo(); toast.success('Undone', { icon: '↩️' }) }\n const handleRedo = () => { redo(); toast.success('Redone', { icon: '↪️' }) }\n const handleReload = async () => {\n toast.loading('Reloading server version...', { id: 'conflict' })\n try {\n const collectionSlug = params.slug || 'pages'\n const res = isGlobal\n ? await api.get(`/globals/${id}`)\n : await api.get(`/${collectionSlug}/${id}`)\n const serverData = res.data.data\n const normalized = {\n ...serverData,\n sections: (serverData.sections || []).map((s: any) => ({\n ...s,\n id: s.id || uid(),\n content: s.content || s.blockData || {},\n })),\n }\n editorSetData(normalized as PageData)\n editorSetHasUnsavedChanges(false)\n setConflictData({ open: false })\n toast.success('Reloaded server version', { id: 'conflict' })\n } catch {\n toast.error('Failed to reload', { id: 'conflict' })\n }\n }\n const handleForceSave = async () => {\n const latest = dataRef.current\n if (!latest) return\n toast.loading('Force-saving your version...', { id: 'conflict' })\n try {\n const forceTitleSection = (latest.sections || []).find((s: any) => s.blockType === 'pageTitle')\n const forceDescSection = (latest.sections || []).find((s: any) => s.blockType === 'pageDescription')\n const payload = {\n ...latest,\n title: forceTitleSection?.content?.title ?? latest.title,\n heroDescription: forceDescSection?.content?.description ?? latest.heroDescription,\n sections: (latest.sections || []).map((s: any) => {\n const { id, content, ...rest } = s;\n return { ...rest, ...sanitizeContent(content || {}) };\n }) || [],\n _version: conflictData.serverVersion !== undefined ? conflictData.serverVersion : latest._version,\n _status: publishStatusRef.current, workflowStatus: workflowStatusRef.current, reviewers: workflowReviewersRef.current, comments: workflowCommentsRef.current, scheduledAt: scheduledAtRef.current || undefined, publishedAt: publishStatusRef.current === 'published' ? (latest.publishedAt || new Date().toISOString()) : null, i18n: translationsRef.current, _fieldSettings: fieldSettingsRef.current\n }\n let res;\n if (isGlobal) {\n res = await api.patch(`/globals/${id}`, payload)\n } else if (isNewDoc) {\n res = await api.post(`/${params.slug || 'pages'}`, payload)\n } else {\n res = await api.patch(`/${params.slug || 'pages'}/${id}`, payload)\n }\n const newVersion = res.data.data?._version\n const newId = res.data?.data?._id || res.data?.data?.id\n if (newVersion !== undefined) editorSetData({ ...latest, _version: newVersion })\n editorSetHasUnsavedChanges(false)\n useEditorStore.getState().setLastSavedAt(new Date().toISOString())\n setConflictData({ open: false })\n toast.success('Force-saved your version', { id: 'conflict' })\n \n if (isNewDoc && newId) {\n navigate(`/collections/${params.slug || 'pages'}/${newId}`, { replace: true })\n }\n } catch (err: any) {\n const serverMsg = err?.response?.data?.error?.message || err?.response?.data?.message || 'Force-save failed'\n toast.error(serverMsg, { id: 'conflict' })\n }\n }\n\n const handlePublish = async () => { setPublishStatus('published'); await handleSave() }\n const handleUnpublish = async () => { setPublishStatus('draft'); setScheduledAt(''); useWorkflowStore.getState().setWorkflowStatus('draft'); toast.success('Unpublished - now visible only to editors') }\n\n\n return { handleSave, handleUndo, handleRedo, handleReload, handleForceSave, handlePublish, handleUnpublish }\n\n}\n","import React, { useState, useEffect, useRef, useCallback } from 'react'\nimport { useParams, useNavigate } from 'react-router-dom'\nimport { Reorder, useDragControls } from 'framer-motion'\nimport { BlockContextMenu } from './editor/components/BlockContextMenu'\nimport {\n Plus,\n AlignLeft,\n AlignCenter,\n AlignRight,\n Cpu,\n ChevronsUpDown,\n Terminal,\n Loader2,\n} from 'lucide-react'\nimport { useTheme } from '../context/ThemeContext'\nimport api from '../lib/api'\nimport toast from 'react-hot-toast'\n\n// Import new modular components from ./editor/components/\nimport { LeftPanel } from './editor/components/LeftPanel'\nimport { RightPanel } from './editor/components/RightPanel'\nimport { SectionBlock } from './editor/components/SectionBlock'\nimport { BlockPickerModal as BlockPicker } from './editor/components/BlockPickerModal'\nimport { SEOModal as SeoModal } from './editor/components/SEOModal'\nimport { TemplatesModal } from './editor/components/TemplatesModal'\nimport { RelationsModal } from './editor/components/RelationsModal'\nimport { MediaLibraryModal as MediaLibrary } from './editor/components/MediaLibraryModal'\nimport { DynamicZoneModal as DynamicZoneEditor } from './editor/components/DynamicZoneModal'\nimport { ConfirmDialog } from './editor/components/ConfirmDialog'\nimport { EditorToolbar } from './editor/EditorToolbar'\nimport FormBuilder from '../components/FormBuilder'\nimport { ReorderableSectionBlock } from './editor/SpatialBlockRenderer'\nimport { EditorErrorBoundary } from '../components/EditorErrorBoundary'\nimport { DocumentDiffModal } from './editor/components/DocumentDiffModal'\nimport { ConflictResolutionModal } from './editor/components/ConflictResolutionModal'\nimport { EditorStatusBar } from './editor/components/EditorStatusBar'\nimport { type Section, type PageData, detectFieldType, humanize } from './editor/constants'\nimport { useEditorBlocks } from '../context/BlockLibraryContext'\nimport { useCollab } from '../hooks/useCollab'\nimport { cn, uid } from '../lib/utils'\n\n// Stores & Hooks\nimport { useEditorStore } from '../store/editorStore'\nimport { useShallow } from 'zustand/react/shallow'\nimport { usePanelStore } from '../store/panelStore'\nimport { useModalStore } from '../store/modalStore'\nimport { useWorkflowStore } from '../store/workflowStore'\nimport { useI18nStore } from '../store/i18nStore'\nimport { usePreviewSync } from '../hooks/usePreviewSync'\nimport { useUnsavedGuard } from '../hooks/useUnsavedGuard'\nimport { useValidation } from '../hooks/useValidation'\nimport { useSpatialSave } from './editor/hooks/useSpatialSave'\nimport { useAuthStore } from '../store/authStore'\n\ninterface SpatialEditorProps {\n isGlobal?: boolean\n id?: string\n /** Pre-select a specific section/block and scroll to it on mount */\n focusedSectionId?: string\n onClose?: () => void\n}\n\n// Main Component\nconst SpatialEditor: React.FC<SpatialEditorProps> = ({ isGlobal, id: propId, focusedSectionId, onClose }) => {\n const params = useParams<{ id?: string; slug?: string }>()\n const navigate = useNavigate()\n const isNewDoc = !isGlobal && !params.id\n const id = propId || params.id || (isGlobal ? params.slug : 'new')\n const { theme } = useTheme()\n const iframeRef = useRef<HTMLIFrameElement>(null)\n\n const BLOCK_LIBRARY = useEditorBlocks()\n\n // Zustand stores — useShallow prevents full re-render on unrelated state changes\n const {\n data: dataRaw,\n setData: editorSetData,\n setLoading: editorSetLoading,\n setSaving: editorSetSaving,\n setHasUnsavedChanges: editorSetHasUnsavedChanges,\n updateData: editorUpdateData,\n undo,\n redo,\n activeSection: editorActiveSection,\n selectedField: editorSelectedField,\n schemaFields: editorSchemaFields,\n fieldSettings: editorFieldSettings,\n fieldErrors: editorFieldErrors,\n topLevelFields,\n setHistory,\n setSelectedField,\n setSchemaFields,\n setTopLevelFields,\n setFieldSettings,\n setFieldErrors: setStoreFieldErrors,\n setAvailableCollections,\n setActiveSection: editorSetActiveSection,\n } = useEditorStore(useShallow((s) => ({\n data: s.data,\n setData: s.setData,\n setLoading: s.setLoading,\n setSaving: s.setSaving,\n setHasUnsavedChanges: s.setHasUnsavedChanges,\n updateData: s.updateData,\n undo: s.undo,\n redo: s.redo,\n activeSection: s.activeSection,\n selectedField: s.selectedField,\n schemaFields: s.schemaFields,\n fieldSettings: s.fieldSettings,\n fieldErrors: s.fieldErrors,\n topLevelFields: s.topLevelFields,\n setHistory: s.setHistory,\n setSelectedField: s.setSelectedField,\n setSchemaFields: s.setSchemaFields,\n setTopLevelFields: s.setTopLevelFields,\n setFieldSettings: s.setFieldSettings,\n setFieldErrors: s.setFieldErrors,\n setAvailableCollections: s.setAvailableCollections,\n setActiveSection: s.setActiveSection,\n })))\n const { viewMode } = usePanelStore(useShallow(state => ({ viewMode: state.viewMode })))\n const { templatesOpen, setTemplatesOpen, setSeoOpen, showFieldIndicators, blockPickerOpen, setBlockPickerOpen } = useModalStore(useShallow(state => ({ templatesOpen: state.templatesOpen, setTemplatesOpen: state.setTemplatesOpen, setSeoOpen: state.setSeoOpen, showFieldIndicators: state.showFieldIndicators, blockPickerOpen: state.blockPickerOpen, setBlockPickerOpen: state.setBlockPickerOpen })))\n const { workflowStatus, setWorkflowStatus, publishStatus, setPublishStatus, workflowReviewers, setWorkflowReviewers, workflowComments, setWorkflowComments, scheduledAt, setScheduledAt, setReleases, setActiveRelease } = useWorkflowStore(useShallow(state => ({ workflowStatus: state.workflowStatus, setWorkflowStatus: state.setWorkflowStatus, publishStatus: state.publishStatus, setPublishStatus: state.setPublishStatus, workflowReviewers: state.workflowReviewers, setWorkflowReviewers: state.setWorkflowReviewers, workflowComments: state.workflowComments, setWorkflowComments: state.setWorkflowComments, scheduledAt: state.scheduledAt, setScheduledAt: state.setScheduledAt, setReleases: state.setReleases, setActiveRelease: state.setActiveRelease })))\n const { i18nEnabled, currentLocale, translations, setTranslations, updateTranslation: i18nUpdateTranslation } = useI18nStore()\n \n const siteId = useAuthStore((s) => s.siteId)\n\n const loading = useEditorStore((s) => s.loading)\n const saving = useEditorStore((s) => s.saving)\n const hasUnsavedChanges = useEditorStore((s) => s.hasUnsavedChanges)\n\n const data = dataRaw as PageData | null\n // const storefrontUrl = import.meta.env.VITE_STOREFRONT_URL as string | undefined\n\n // ── Local UI state ──────────────────────────────────────────────────────────\n const [resizingSide, setResizingSide] = useState<'left' | 'right' | null>(null)\n const [selectedSections, setSelectedSections] = useState<Set<string>>(new Set())\n const [dynamicZoneModalOpen, setDynamicZoneModalOpen] = useState(false)\n const [activeDynamicZone, setActiveDynamicZone] = useState<{ sectionId: string; fieldKey: string } | null>(null)\n const [injectionIndex, setInjectionIndex] = useState<number | null>(null)\n const [contextMenu, setContextMenu] = useState<{ x: number; y: number; sectionId: string } | null>(null)\n const [diffVersion, setDiffVersion] = useState<{ id: string; num: number } | null>(null)\n const hasBlocksField = React.useMemo(() => {\n return topLevelFields.some((f: any) => f.type === 'blocks' || f.name === 'layout' || f.name === 'sections')\n }, [topLevelFields])\n const sectionIdsMemo = React.useMemo(() => {\n return (dataRaw as PageData | null)?.sections?.map((s: any) => s.id) || []\n }, [(dataRaw as PageData | null)?.sections?.length])\n const [conflictData, setConflictData] = useState<{\n open: boolean\n message?: string\n serverVersion?: number\n localVersion?: number\n }>({ open: false })\n const [deleteConfirm, setDeleteConfirm] = useState<{ open: boolean; sectionId: string | null }>({ open: false, sectionId: null })\n\n // Hooks\n usePreviewSync(iframeRef, data, 300)\n useUnsavedGuard({ hasUnsavedChanges })\n const collab = useCollab({\n collection: isGlobal ? 'globals' : 'pages',\n documentId: id || '',\n wsUrl: typeof window !== 'undefined' && import.meta.env.VITE_ENABLE_WS === 'true'\n ? `${window.location.protocol === 'https:' ? 'wss' : 'ws'}://${window.location.host}/collaboration`\n : undefined,\n enabled: true,\n })\n const validate = useValidation(BLOCK_LIBRARY.map((b) => ({ slug: b.type, label: b.title, fields: b.fields || [], defaultContent: b.defaultContent })))\n\n // Keep a ref to latest data so force-save never uses stale closure state\n const dataRef = useRef(data)\n useEffect(() => { dataRef.current = data }, [data])\n // Refs for workflow/i18n state — keeps handlers from reading stale closure values\n const publishStatusRef = useRef(publishStatus)\n const workflowStatusRef = useRef(workflowStatus)\n const workflowReviewersRef = useRef(workflowReviewers)\n const workflowCommentsRef = useRef(workflowComments)\n const scheduledAtRef = useRef(scheduledAt)\n const translationsRef = useRef(translations)\n const fieldSettingsRef = useRef(editorFieldSettings)\n useEffect(() => { publishStatusRef.current = publishStatus }, [publishStatus])\n useEffect(() => { workflowStatusRef.current = workflowStatus }, [workflowStatus])\n useEffect(() => { workflowReviewersRef.current = workflowReviewers }, [workflowReviewers])\n useEffect(() => { workflowCommentsRef.current = workflowComments }, [workflowComments])\n useEffect(() => { scheduledAtRef.current = scheduledAt }, [scheduledAt])\n useEffect(() => { translationsRef.current = translations }, [translations])\n useEffect(() => { fieldSettingsRef.current = editorFieldSettings }, [editorFieldSettings])\n const mountedRef = useRef(true)\n useEffect(() => { mountedRef.current = true; return () => { mountedRef.current = false } }, [])\n const prevDocIdRef = useRef<string | undefined>(id)\n const copiedSectionRef = useRef<Section | null>(null)\n // Guards fetchData callbacks from running after the component unmounts\n const isCancelledRef = useRef(false)\n useEffect(() => { \n isCancelledRef.current = false\n return () => { isCancelledRef.current = true } \n }, [id, isGlobal, siteId])\n // Guards against concurrent saves (spam Ctrl+S) — only one save runs at a time\n // Guards templates API from racing with rapid open/close toggles\n const templatesLoadIdRef = useRef(0)\n // Safe deep clone — avoids JSON.parse/JSON.stringify crashes on circular structures\n const safeDeepClone = <T,>(obj: T): T => {\n try { return structuredClone(obj) } catch { return JSON.parse(JSON.stringify(obj)) }\n }\n const getTranslatedValue = (sectionId: string, fieldKey: string, defaultValue: string): string => {\n if (!i18nEnabled || currentLocale === 'en') return defaultValue\n return translations[`${sectionId}:${fieldKey}`]?.[currentLocale] || defaultValue\n }\n const setTranslatedValue = (sectionId: string, fieldKey: string, value: string) => {\n i18nUpdateTranslation(`${sectionId}:${fieldKey}`, currentLocale, value)\n editorSetHasUnsavedChanges(true)\n }\n\n const handleOpenContextMenu = (e: React.MouseEvent, sectionId: string) => {\n e.preventDefault()\n setContextMenu({\n x: e.clientX,\n y: e.clientY,\n sectionId,\n })\n }\n\n // Resize handlers\n const startResizing = useCallback((side: 'left' | 'right') => () => setResizingSide(side), [])\n const stopResizing = useCallback(() => setResizingSide(null), [])\n const resize = useCallback((e: MouseEvent) => {\n if (resizingSide === 'left') { const w = e.clientX; if (w >= 200 && w <= 500) usePanelStore.getState().setLeftWidth(w) }\n else if (resizingSide === 'right') { const w = window.innerWidth - e.clientX; if (w >= 200 && w <= 700) usePanelStore.getState().setRightWidth(w) }\n }, [resizingSide])\n\n useEffect(() => {\n if (resizingSide) { window.addEventListener('mousemove', resize); window.addEventListener('mouseup', stopResizing) }\n return () => { window.removeEventListener('mousemove', resize); window.removeEventListener('mouseup', stopResizing) }\n }, [resizingSide, resize, stopResizing])\n\n // Preview sync effects\n // Intentionally removed SET_THEME sync so the preview maintains its own theme.\n useEffect(() => { if (iframeRef.current?.contentWindow && editorActiveSection) iframeRef.current.contentWindow.postMessage({ type: 'ZENITH_PARENT_SELECT', sectionId: editorActiveSection, id: editorActiveSection }, '*') }, [editorActiveSection])\n \n // Auto-scroll to top-level fields when focused\n useEffect(() => {\n const handleFocus = (e: FocusEvent) => {\n const target = e.target as HTMLElement\n // Rich text editors might use data-field or data-name, inputs use name\n const name = target.getAttribute('name') || target.getAttribute('data-field') || target.closest('[data-field]')?.getAttribute('data-field')\n if (name && iframeRef.current?.contentWindow) {\n iframeRef.current.contentWindow.postMessage({ type: 'ZENITH_PARENT_SELECT', id: name }, '*')\n }\n }\n document.addEventListener('focusin', handleFocus)\n return () => document.removeEventListener('focusin', handleFocus)\n }, [])\n\n // Task 04: iframe message handler — versioned protocol with type guard + cleanup\n useEffect(() => {\n const handleMessage = (event: MessageEvent) => {\n // Only accept messages from our storefront origin (or '*' in dev)\n const expectedOrigin = import.meta.env.VITE_STOREFRONT_URL || window.location.origin\n if (expectedOrigin !== '*' && event.origin !== expectedOrigin && event.origin !== window.location.origin) return\n // Versioned protocol guard\n switch (event.data?.type) {\n case 'ZENITH_IFRAME_READY':\n if (editorActiveSection) {\n iframeRef.current?.contentWindow?.postMessage({ type: 'ZENITH_PARENT_SELECT', sectionId: editorActiveSection, id: editorActiveSection }, '*')\n }\n break\n case 'ZENITH_SECTION_SELECT': {\n const sectionId = event.data.sectionId || event.data.id\n if (sectionId) { editorSetActiveSection(sectionId); setSelectedSections(new Set([sectionId])) }\n break\n }\n default:\n // Silently ignore unknown message types\n break\n }\n }\n window.addEventListener('message', handleMessage)\n return () => window.removeEventListener('message', handleMessage)\n }, [editorSetActiveSection])\n\n // Keyboard shortcuts — use refs to avoid stale closures\n const keyboardStateRef = useRef({ editorActiveSection, selectedSections })\n useEffect(() => {\n keyboardStateRef.current = { editorActiveSection, selectedSections }\n }, [editorActiveSection, selectedSections])\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n // Don't capture keys when typing in inputs\n const tagName = (e.target as any)?.tagName\n const isInput = tagName === 'INPUT' || tagName === 'TEXTAREA' || (e.target as any)?.isContentEditable\n\n const isMeta = e.metaKey || e.ctrlKey\n if (isMeta && e.key === 's') { e.preventDefault(); handleSave(); return }\n if (isMeta && e.key === 'z' && !e.shiftKey) { e.preventDefault(); handleUndo(); return }\n if (isMeta && ((e.key === 'z' && e.shiftKey) || e.key === 'y')) { e.preventDefault(); handleRedo(); return }\n if (isMeta && e.key === '\\\\') { e.preventDefault(); const p = usePanelStore.getState(); p.setLeftOpen(!p.leftOpen); return }\n if (isMeta && e.key === 'p') { e.preventDefault(); const p = usePanelStore.getState(); p.setRightOpen(!p.rightOpen); return }\n\n if (isInput) return\n\n const { editorActiveSection: activeSec, selectedSections: selSecs } = keyboardStateRef.current\n if (isMeta && e.key === 'd' && activeSec && activeSec !== 'root') { e.preventDefault(); duplicateSection(activeSec); return }\n if ((e.key === 'Backspace' || e.key === 'Delete') && selSecs.size > 0) { e.preventDefault(); selSecs.forEach((sectionId) => removeSection(sectionId)); setSelectedSections(new Set()); return }\n if (e.key === 'Escape') { setSelectedSections(new Set()); editorSetActiveSection(null); setBlockPickerOpen(false); setSeoOpen(false); setTemplatesOpen(false); return }\n if (e.key === '/') { setBlockPickerOpen(true) }\n }\n window.addEventListener('keydown', handleKeyDown)\n return () => window.removeEventListener('keydown', handleKeyDown)\n }, []) \n\n // Task 03: Auto-save with ref-based state capture to avoid stale closures\n const {\n handleSave,\n handleUndo,\n handleRedo,\n handleReload,\n handleForceSave,\n handlePublish,\n handleUnpublish\n } = useSpatialSave({\n isGlobal,\n isNewDoc,\n id,\n data,\n dataRef,\n hasUnsavedChanges,\n saving,\n validate,\n publishStatusRef,\n workflowStatusRef,\n workflowReviewersRef,\n workflowCommentsRef,\n scheduledAtRef,\n translationsRef,\n fieldSettingsRef,\n publishStatus,\n workflowStatus,\n workflowReviewers,\n workflowComments,\n scheduledAt,\n translations,\n editorFieldSettings,\n setConflictData,\n conflictData,\n })\n // Load templates\n useEffect(() => {\n if (!templatesOpen) return\n const loadId = ++templatesLoadIdRef.current\n api.get('/templates').then((res) => {\n if (loadId !== templatesLoadIdRef.current) return // stale race — drop\n useEditorStore.getState().setTemplates(res.data.data || [])\n }).catch(() => { /* ignore */ })\n }, [templatesOpen])\n\n // Load initial data\n useEffect(() => {\n // Clear undo/redo stacks when navigating to a different document\n if (prevDocIdRef.current && prevDocIdRef.current !== id) {\n useEditorStore.setState({ undoStack: [], redoStack: [] })\n }\n prevDocIdRef.current = id\n\n const fetchData = async () => {\n editorSetLoading(true)\n try {\n const collectionSlug = params.slug || 'pages'\n let serverData: any = { sections: [] };\n if (!isNewDoc) {\n const res = isGlobal ? await api.get(`/globals/${id}`) : await api.get(`/${collectionSlug}/${id}`)\n if (res.data?.data) {\n serverData = res.data.data;\n }\n }\n if (isCancelledRef.current) return\n const pageData = serverData\n const migratedSections = (pageData.sections || []).map((s: any) => {\n const { id, blockType, align, blockName, collapsed, content, blockData, ...restProps } = s\n const hasContent = content && Object.keys(content).length > 0\n const hasBlockData = blockData && Object.keys(blockData).length > 0\n return {\n id: id || uid(),\n blockType,\n align,\n blockName,\n collapsed,\n content: hasContent ? content : (hasBlockData ? blockData : restProps)\n }\n })\n\n editorSetData({ ...pageData, sections: migratedSections })\n if (isCancelledRef.current) return\n if (migratedSections.length > 0) editorSetActiveSection(migratedSections[0].id)\n\n const collection = isGlobal ? 'globals' : (params.slug || 'pages')\n const docId = id\n if (!isNewDoc) {\n const historyRes = await api.get(`/versions/${collection}/${docId}`)\n if (!isCancelledRef.current) {\n setHistory(historyRes.data.data || [])\n }\n }\n\n setPublishStatus(pageData._status || pageData.status || 'draft')\n setWorkflowStatus(pageData.workflowStatus || 'draft')\n setWorkflowReviewers(pageData.reviewers || [])\n setWorkflowComments(pageData.comments || [])\n setScheduledAt(pageData.scheduledAt || '')\n setTranslations(pageData.i18n || {})\n\n if (isCancelledRef.current) return\n try { const releasesRes = await api.get('/releases'); if (isCancelledRef.current) return; setReleases(releasesRes.data.data || []); setActiveRelease(releasesRes.data.data?.find((r: any) => r.status === 'pending') || null) } catch { if (!isCancelledRef.current) toast.error('Failed to load releases') }\n try { \n const colsRes = await api.get('/health'); \n if (isCancelledRef.current) return; \n const healthData = colsRes?.data?.data || {};\n setAvailableCollections(healthData.collections || []);\n const colList = isGlobal ? (healthData.globals || []) : (healthData.collections || []);\n const col = colList.find((c: any) => c.slug === (params.slug || 'pages'));\n setTopLevelFields(col?.fields || []);\n } catch { if (!isCancelledRef.current) toast.error('Failed to load collections') }\n\n const settings: Record<string, any> = {}\n migratedSections.forEach((s: any) => {\n Object.keys(s.content || {}).forEach((key) => {\n const settingKey = `${s.id}:${key}`\n settings[settingKey] = { required: false, unique: false, maxLength: null, minLength: null, private: false, relation: null, ...pageData._fieldSettings?.[settingKey] }\n })\n })\n setFieldSettings(settings)\n\n const schema: any[] = []\n migratedSections.forEach((s: any) => {\n Object.keys(s.content || {}).forEach((key) => {\n schema.push({ id: `${s.id}:${key}`, name: key, blockId: s.id, blockType: s.blockType, type: detectFieldType(key, s.content[key]), label: humanize(key), required: false, unique: false, sortable: true, filterable: true, private: false })\n })\n })\n setSchemaFields(schema)\n } catch { if (!isCancelledRef.current) toast.error('Failed to sync editor', { icon: '️', duration: 5000 }) } finally { if (!isCancelledRef.current) setTimeout(() => editorSetLoading(false), 500) }\n }\n fetchData()\n }, [id, isGlobal, siteId])\n\n const initialFocusDoneRef = useRef(false)\n \n // Reset initial focus when document ID changes\n useEffect(() => {\n initialFocusDoneRef.current = false;\n }, [id])\n\n // Focus a specific section when navigated directly (e.g. from collection detail) \n useEffect(() => {\n if (!data?.sections?.length) return\n if (initialFocusDoneRef.current) return\n\n if (focusedSectionId) {\n const exists = data.sections.some((s: Section) => s.id === focusedSectionId)\n if (exists) {\n editorSetActiveSection(focusedSectionId)\n setSelectedSections(new Set([focusedSectionId]))\n initialFocusDoneRef.current = true\n }\n } else {\n const firstSectionId = data.sections[0].id\n editorSetActiveSection(firstSectionId)\n setSelectedSections(new Set([firstSectionId]))\n initialFocusDoneRef.current = true\n }\n \n }, [focusedSectionId, data?.sections?.length])\n\n // Issue 7: Reset injectionIndex when BlockPicker closes (via any path)\n // Issue 7: Scroll active section into view when it changes\n useEffect(() => {\n if (!editorActiveSection) return\n const el = document.getElementById(editorActiveSection)\n if (el) {\n el.scrollIntoView({ behavior: 'smooth', block: 'center' })\n // Add a visual flash effect to the selected block in the left panel\n el.classList.add('ring-2', 'ring-[var(--z-accent)]', 'ring-offset-2', 'ring-offset-[#0B0F19]', 'transition-all', 'duration-500')\n setTimeout(() => {\n el.classList.remove('ring-2', 'ring-[var(--z-accent)]', 'ring-offset-2', 'ring-offset-[#0B0F19]')\n }, 1000)\n }\n }, [editorActiveSection])\n\n useEffect(() => {\n if (blockPickerOpen === false) setInjectionIndex(null)\n }, [blockPickerOpen])\n\n /** Strip empty strings, nulls, and empty objects from section content to avoid Zod 422 on media/relation fields */\n // Section operations\n const addBlock = (blockType: string) => {\n const block = BLOCK_LIBRARY.find((b) => b.type === blockType)\n if (!block) return\n const newId = uid()\n const anchorId = `${block.type}-${newId.slice(0, 4)}`\n const newSection: Section = { \n id: newId, \n blockType: block.type, \n title: block.title, \n content: { ...block.defaultContent, anchorId } \n }\n editorUpdateData((prev) => {\n const sections = prev?.sections || []\n const newSections = [...sections]\n if (injectionIndex !== null) {\n newSections.splice(injectionIndex, 0, newSection)\n } else {\n newSections.push(newSection)\n }\n return { ...prev, sections: newSections }\n })\n editorSetActiveSection(newSection.id)\n setBlockPickerOpen(false)\n setInjectionIndex(null)\n toast.success(`Section added: ${blockType.toUpperCase()}`, { icon: '' })\n }\n\n const duplicateSection = useCallback((sectionId: string) => {\n const latest = dataRef.current\n if (!latest) return\n const sectionToDuplicate = latest.sections.find((s) => s.id === sectionId)\n if (!sectionToDuplicate) return\n const newId = uid()\n const anchorId = `${sectionToDuplicate.blockType}-${newId.slice(0, 4)}`\n const duplicatedSection: Section = { \n ...sectionToDuplicate, \n id: newId, \n title: `${sectionToDuplicate.title} (Copy)`, \n content: { ...safeDeepClone(sectionToDuplicate.content), anchorId } \n }\n editorUpdateData((prev) => { const idx = prev.sections.findIndex((s) => s.id === sectionId); const newSections = [...prev.sections]; newSections.splice(idx + 1, 0, duplicatedSection); return { ...prev, sections: newSections } })\n editorSetActiveSection(duplicatedSection.id)\n toast.success('Section duplicated', { icon: '' })\n }, [dataRef, editorUpdateData, editorSetActiveSection]);\n\n const removeSection = useCallback((id: string) => {\n const target = dataRef.current?.sections?.find((s) => s.id === id)\n if (!target) return\n setDeleteConfirm({ open: true, sectionId: id })\n }, [dataRef]);\n\n const confirmRemoveSection = () => {\n const id = deleteConfirm.sectionId\n if (!id) return\n const target = dataRef.current?.sections?.find((s) => s.id === id)\n setDeleteConfirm({ open: false, sectionId: null })\n editorUpdateData((prev) => ({ ...prev, sections: prev.sections.filter((s) => s.id !== id) }))\n if (editorActiveSection === id) editorSetActiveSection(null)\n if (selectedSections.has(id)) { const newSelected = new Set(selectedSections); newSelected.delete(id); setSelectedSections(newSelected) }\n toast.error(`Section \"${target?.title || target?.blockType}\" removed`)\n }\n\n const convertBlockType = (sectionId: string, newBlockType: string) => {\n const targetBlockDef = BLOCK_LIBRARY.find((b) => b.type === newBlockType)\n if (!targetBlockDef) return\n editorUpdateData((prev) => {\n if (!prev) return prev\n const newSections = [...(prev.sections || [])]\n const idx = newSections.findIndex((s) => s.id === sectionId)\n if (idx !== -1) {\n const oldSection = newSections[idx]\n const oldContent = oldSection.content || {}\n const newContent = { ...targetBlockDef.defaultContent }\n\n // Heuristic field mapping:\n const titleKeys = ['title', 'heading', 'headline', 'name']\n const bodyKeys = ['content', 'description', 'bio', 'body', 'subheadline']\n\n const oldTitleVal = Object.entries(oldContent).find(([k]) => titleKeys.some((tk) => k.toLowerCase().includes(tk)))?.[1]\n const oldBodyVal = Object.entries(oldContent).find(([k]) => bodyKeys.some((bk) => k.toLowerCase().includes(bk)))?.[1]\n\n Object.keys(newContent).forEach((key) => {\n const kLower = key.toLowerCase()\n if (titleKeys.some((tk) => kLower.includes(tk)) && oldTitleVal !== undefined) {\n newContent[key] = oldTitleVal\n } else if (bodyKeys.some((bk) => kLower.includes(bk)) && oldBodyVal !== undefined) {\n newContent[key] = oldBodyVal\n } else if (oldContent[key] !== undefined) {\n newContent[key] = oldContent[key]\n }\n })\n\n newSections[idx] = {\n ...oldSection,\n blockType: newBlockType,\n title: targetBlockDef.title,\n content: newContent,\n }\n }\n return { ...prev, sections: newSections }\n })\n editorSetHasUnsavedChanges(true)\n toast.success(`Converted block layout to: ${targetBlockDef.title}`, { icon: '' })\n }\n\n const toggleCollapse = useCallback((sectionId: string) => {\n editorUpdateData((prev) => {\n const newSections = [...prev.sections]\n const idx = newSections.findIndex((s) => s.id === sectionId)\n if (idx !== -1) {\n newSections[idx] = { ...newSections[idx], collapsed: !newSections[idx].collapsed }\n }\n return { ...prev, sections: newSections }\n })\n editorSetHasUnsavedChanges(true)\n }, [editorUpdateData, editorSetHasUnsavedChanges])\n\n const moveSection = (sectionId: string, direction: 'up' | 'down') => {\n editorUpdateData((prev) => {\n const newSections = [...prev.sections]\n const idx = newSections.findIndex((s) => s.id === sectionId)\n if (idx === -1) return prev\n const targetIdx = direction === 'up' ? idx - 1 : idx + 1\n if (targetIdx < 0 || targetIdx >= newSections.length) return prev\n ;[newSections[idx], newSections[targetIdx]] = [newSections[targetIdx], newSections[idx]]\n return { ...prev, sections: newSections }\n })\n editorSetHasUnsavedChanges(true)\n }\n\n const copySection = (sectionId: string) => {\n const latest = dataRef.current\n if (!latest) return\n const section = latest.sections.find((s) => s.id === sectionId)\n if (!section) return\n try {\n navigator.clipboard.writeText(JSON.stringify({ type: 'zenith-section', section }))\n } catch {\n copiedSectionRef.current = section\n }\n toast.success('Section copied', { icon: '' })\n }\n\n const insertCopiedSection = (sourceSection: Section, afterSectionId?: string) => {\n const newSection: Section = {\n ...sourceSection,\n id: uid(),\n title: `${sourceSection.title} (Copied)`,\n content: safeDeepClone(sourceSection.content),\n }\n editorUpdateData((prev) => {\n const sections = [...prev.sections]\n if (afterSectionId) {\n const idx = sections.findIndex((s) => s.id === afterSectionId)\n sections.splice(idx + 1, 0, newSection)\n } else {\n sections.push(newSection)\n }\n return { ...prev, sections }\n })\n editorSetActiveSection(newSection.id)\n editorSetHasUnsavedChanges(true)\n toast.success('Section pasted', { icon: '' })\n }\n\n const pasteSection = (sectionId: string) => {\n navigator.clipboard.readText().then((text) => {\n try {\n const parsed = JSON.parse(text)\n if (parsed.type === 'zenith-section') {\n insertCopiedSection(parsed.section, sectionId)\n return\n }\n } catch {}\n if (copiedSectionRef.current) {\n insertCopiedSection(copiedSectionRef.current, sectionId)\n } else {\n toast.error('No copied section found', { icon: '️' })\n }\n }).catch(() => {\n if (copiedSectionRef.current) {\n insertCopiedSection(copiedSectionRef.current, sectionId)\n } else {\n toast.error('No copied section found', { icon: '️' })\n }\n })\n }\n\n const handleBlockNameChange = useCallback((sectionId: string, name: string) => {\n editorUpdateData((prev) => {\n const newSections = [...prev.sections]\n const idx = newSections.findIndex((s) => s.id === sectionId)\n if (idx !== -1) {\n newSections[idx] = { ...newSections[idx], blockName: name }\n }\n return { ...prev, sections: newSections }\n })\n editorSetHasUnsavedChanges(true)\n }, [editorUpdateData, editorSetHasUnsavedChanges])\n\n const handleCollapseAll = () => {\n const latest = dataRef.current\n if (!latest) return\n const allCollapsed = latest.sections.every((s) => s.collapsed)\n editorUpdateData((prev) => ({\n ...prev,\n sections: prev.sections.map((s) => ({ ...s, collapsed: !allCollapsed })),\n }))\n editorSetHasUnsavedChanges(true)\n toast.success(allCollapsed ? 'All sections expanded' : 'All sections collapsed', { icon: '' })\n }\n\n const updateAlign = useCallback((sectionId: string, align: 'left' | 'center' | 'right') => {\n editorUpdateData((prev) => { const newSections = [...prev.sections]; const idx = newSections.findIndex((s) => s.id === sectionId); if (idx !== -1) newSections[idx].align = align; return { ...prev, sections: newSections } })\n }, [editorUpdateData])\n\n const handleReorder = (newIds: string[]) => {\n editorUpdateData((prev) => {\n const sectionsMap = new Map((prev?.sections || []).map((s) => [s.id, s]))\n const newSections = newIds.map((id) => sectionsMap.get(id)).filter(Boolean) as Section[]\n return { ...prev, sections: newSections }\n })\n }\n\n const handleDynamicZoneReorder = (sectionId: string, fieldKey: string, newItems: any[]) => {\n editorUpdateData((prev) => {\n const newSections = [...prev.sections]\n const sIdx = newSections.findIndex((s) => s.id === sectionId)\n if (sIdx !== -1) {\n newSections[sIdx].content[fieldKey] = newItems\n }\n return { ...prev, sections: newSections }\n })\n }\n\n const handleFieldChange = useCallback((sectionId: string, key: string, value: any) => {\n useEditorStore.getState().setField(sectionId, key, value)\n const errorKey = `${sectionId}:${key}`\n if (useEditorStore.getState().fieldErrors[errorKey]) {\n const next = { ...useEditorStore.getState().fieldErrors }\n delete next[errorKey]\n useEditorStore.getState().setFieldErrors(next)\n }\n }, [])\n\n // Template operations\n const saveAsTemplate = async (sectionIds: string[]) => {\n const templateSections = data?.sections.filter((s) => sectionIds.includes(s.id)) || []\n if (templateSections.length === 0) return\n try { await api.post('/templates', { name: `Template ${new Date().toLocaleTimeString()}`, content: { sections: templateSections } }); setTemplatesOpen(false); toast.success('Template saved to server!', { icon: '' }) } catch { toast.error('Failed to save template', { icon: '️', duration: 5000 }) }\n }\n\n const applyTemplate = async (template: any) => {\n editorUpdateData((prev) => ({ ...prev, sections: [...(prev.sections || []), ...(template.sections || []).map((s: Section) => ({ ...s, id: uid() }))] }))\n setTemplatesOpen(false)\n toast.success(`${template.name} applied!`, { icon: '' })\n }\n\n const deleteTemplate = async (templateId: string) => {\n try { await api.delete(`/templates/${templateId}`); toast.success('Template deleted') } catch { toast.error('Failed to delete template', { icon: '️', duration: 5000 }) }\n }\n\n // Version restore\n const handleRestore = async (versionId: string) => {\n const collection = isGlobal ? 'globals' : 'pages'\n const docId = id\n editorSetSaving(true)\n try { const res = await api.post(`/versions/${collection}/${docId}/${versionId}/restore`); editorUpdateData(() => res.data.data.document); toast.success('Version restored') } catch { toast.error('Restore failed') } finally { editorSetSaving(false) }\n }\n\n // Dynamic Zone\n const addToDynamicZone = (componentType: string) => {\n if (!activeDynamicZone) return\n const component = BLOCK_LIBRARY.find((b) => b.type === componentType)\n if (!component) return\n editorUpdateData((prev) => {\n const newSections = [...prev.sections]\n const sIdx = newSections.findIndex((s) => s.id === activeDynamicZone.sectionId)\n if (sIdx !== -1) {\n const zone = (newSections[sIdx].content[activeDynamicZone.fieldKey] as any[]) || []\n newSections[sIdx].content[activeDynamicZone.fieldKey] = [...zone, { __component: `content.${componentType}`, ...component.defaultContent, id: `dz_${Date.now()}` }]\n }\n return { ...prev, sections: newSections }\n })\n toast.success(`${component.title} added to zone`)\n }\n\n const removeFromDynamicZone = (index: number) => {\n if (!activeDynamicZone) return\n editorUpdateData((prev) => {\n const newSections = [...prev.sections]\n const sIdx = newSections.findIndex((s) => s.id === activeDynamicZone.sectionId)\n if (sIdx !== -1) { const zone = [...((newSections[sIdx].content[activeDynamicZone.fieldKey] as any[]) || [])]; zone.splice(index, 1); newSections[sIdx].content[activeDynamicZone.fieldKey] = zone }\n return { ...prev, sections: newSections }\n })\n }\n\n // Loading state\n if (loading)\n return (\n <div className={cn('h-screen w-full flex flex-col items-center justify-center gap-6', theme === 'dark' ? 'bg-app' : 'bg-[#fafafa]')}>\n <div className=\"relative flex items-center justify-center w-24 h-24\">\n <div className={cn(\"absolute inset-0 rounded-full border-2\", theme === 'dark' ? 'border-z-border border-z-border' : 'border-z-border border-z-border', \"animate-spin\")} />\n <Loader2 size={32} className={cn(\"animate-spin opacity-50\", theme === 'dark' ? 'text-z-primary' : 'text-z-primary')} strokeWidth={1} style={{ animationDuration: '3s' }} />\n <div className={cn(\"absolute inset-0 blur-3xl animate-pulse\", theme === 'dark' ? 'bg-z-panel/5' : 'bg-app/5')} />\n </div>\n <p className={cn(\"text-sm font-semibold tracking-widest uppercase\", theme === 'dark' ? 'text-z-primary/40' : 'text-z-primary/40')}>\n Loading\n </p>\n </div>\n )\n\n return (\n <div className={cn('h-screen flex flex-col overflow-hidden transition-colors duration-500', theme === 'dark' ? 'bg-app text-z-primary' : 'bg-z-panel text-z-primary')}>\n {/* ── Header ── */}\n {/* ── Editor Toolbar ── */}\n <EditorToolbar\n handleSave={handleSave}\n handlePublish={handlePublish}\n handleUnpublish={handleUnpublish}\n isGlobal={isGlobal}\n onClose={onClose}\n collab={collab}\n />\n\n {/* ── Screen reader live region ── */}\n <div aria-live=\"polite\" aria-atomic=\"true\" className=\"sr-only\" id=\"editor-live-region\" />\n\n <EditorErrorBoundary>\n {/* ── Main Layout ── */}\n <div className=\"flex-1 flex overflow-hidden relative\">\n {/* Left Panel */}\n {hasBlocksField && (\n <LeftPanel\n isGlobal={isGlobal}\n resizingSide={resizingSide}\n startResizing={startResizing}\n addBlock={addBlock}\n removeSection={removeSection}\n setInjectionIndex={setInjectionIndex}\n setBlockPickerOpen={setBlockPickerOpen}\n />\n )}\n\n {/* Canvas */}\n <main className={cn('flex-1 relative flex flex-col overflow-hidden transition-colors', theme === 'dark' ? 'bg-[#030303]' : 'bg-[var(--z-bg-input)]')}>\n\n <div className=\"flex-1 overflow-y-auto px-4 sm:px-6 lg:px-10 pt-6 lg:pt-10 pb-20 no-scrollbar scroll-smooth relative z-10 custom-editor-scrollbar\">\n <div className=\"max-w-[1400px] mx-auto min-h-screen flex flex-col\">\n {viewMode === 'visual' ? (\n <div className=\"flex-1 space-y-12\">\n {/* Document Kernel (Root Fields) */}\n <div id=\"document-kernel\" className={cn('space-y-6 transition-all duration-500', data?.align === 'center' && 'text-center', data?.align === 'right' && 'text-right')}>\n <div className=\"flex items-center justify-between\">\n <div className={cn('flex items-center gap-0.5 p-0.5 rounded-none-none border', theme === 'dark' ? 'bg-z-hover border-z-border' : 'bg-[var(--z-bg-hover)] border-z-border')}>\n {(['left', 'center', 'right'] as const).map((align) => (\n <button key={align} onClick={() => data && editorSetData({ ...data, align })} className={cn('p-1 transition-all', data?.align === align || (!data?.align && align === 'left') ? theme === 'dark' ? 'bg-z-accent/20 text-z-accent dark:text-z-active-text' : 'bg-z-active-bg text-z-active-text shadow-sm border border-z-active-border' : 'text-z-muted hover:text-z-primary hover:bg-[var(--z-bg-hover)] rounded dark:text-z-active-text')}>\n {align === 'left' && <AlignLeft size={12} />} {align === 'center' && <AlignCenter size={12} />} {align === 'right' && <AlignRight size={12} />}\n </button>\n ))}\n </div>\n <button\n onClick={handleCollapseAll}\n className={cn(\n 'flex items-center gap-1.5 px-2 py-1 text-sm font-semibold rounded-none-none border transition-all',\n theme === 'dark'\n ? 'border-z-border text-z-secondary hover:text-z-accent dark:text-z-active-text hover:border-z-accent/20'\n : 'border-z-border text-z-muted hover:text-z-accent hover:border-z-active-border'\n )}\n title=\"Collapse / Expand All\"\n >\n <ChevronsUpDown size={10} />\n Collapse All\n </button>\n </div>\n\n </div>\n\n {hasBlocksField && (\n <>\n <Reorder.Group axis=\"y\" values={data?.sections?.map((s: Section) => s.id) || []} onReorder={handleReorder} className=\"space-y-8\">\n {data?.sections?.map((section: Section, index: number) => (\n <ReorderableSectionBlock\n key={section.id}\n section={section}\n index={index}\n totalSections={data?.sections?.length || 0}\n theme={theme}\n showFieldIndicators={showFieldIndicators || false}\n editorSelectedField={editorSelectedField}\n editorSchemaFields={editorSchemaFields}\n editorFieldErrors={editorFieldErrors}\n editorActiveSection={editorActiveSection}\n editorSetActiveSection={editorSetActiveSection}\n duplicateSection={duplicateSection}\n removeSection={removeSection}\n updateAlign={updateAlign}\n handleFieldChange={handleFieldChange}\n setSelectedField={setSelectedField}\n i18nEnabled={i18nEnabled}\n currentLocale={currentLocale}\n getTranslatedValue={getTranslatedValue}\n setTranslatedValue={setTranslatedValue}\n setActiveDynamicZone={setActiveDynamicZone}\n setDynamicZoneModalOpen={setDynamicZoneModalOpen}\n setInjectionIndex={setInjectionIndex}\n setBlockPickerOpen={setBlockPickerOpen}\n onOpenContextMenu={handleOpenContextMenu}\n collab={collab}\n broadcastCursor={collab.broadcastCursor}\n toggleCollapse={toggleCollapse}\n moveSection={moveSection}\n copySection={copySection}\n pasteSection={pasteSection}\n handleBlockNameChange={handleBlockNameChange}\n selectedSections={selectedSections}\n onMultiSelect={(id, multi) => {\n if (multi) {\n setSelectedSections((prev) => {\n const next = new Set(prev)\n if (next.has(id)) next.delete(id); else next.add(id)\n return next\n })\n } else {\n editorSetActiveSection(id)\n setSelectedSections(new Set([id]))\n }\n }}\n />\n ))}\n </Reorder.Group>\n\n {/* Add Section Button */}\n <button onClick={() => { setInjectionIndex(null); setBlockPickerOpen(true) }} className={cn('w-full py-10 rounded-none-none border-2 border-dashed transition-all flex flex-col items-center gap-4 group', theme === 'dark' ? 'border-z-border hover:border-z-accent/40 hover:opacity-90/5' : 'border-z-border hover:border-z-active-border hover:bg-z-active-bg')}>\n <div className={cn('w-12 h-12 rounded-none-none border-2 border-dashed flex items-center justify-center group-hover:scale-110 transition-all', theme === 'dark' ? 'border-z-active-border bg-z-accent/5' : 'border-z-active-border bg-z-active-bg/50')}><Plus size={22} className=\"text-z-accent dark:text-z-active-text\" /></div>\n <p className=\"text-sm font-semibold text-z-secondary group-hover:text-z-accent dark:text-z-active-text transition-colors\">Append Section</p>\n </button>\n </>\n )}\n\n {topLevelFields.length > 0 && (\n <div className={cn(\"border rounded-none-none p-10 shadow-sm relative overflow-hidden transition-colors\", theme === 'dark' ? 'bg-app border-z-border' : 'bg-z-panel border-z-border shadow-sm')}>\n <div className=\"absolute top-0 right-0 p-10 opacity-[0.01] pointer-events-none\">\n <Terminal size={180} strokeWidth={0.5} />\n </div>\n <div className=\"relative z-10\">\n <FormBuilder\n fields={topLevelFields}\n initialData={data}\n onValuesChange={(formValues) => {\n editorUpdateData((prev) => {\n const updates: any = {}\n let hasChanges = false\n topLevelFields.forEach((f: any) => {\n if (formValues[f.name] !== undefined) {\n if (JSON.stringify(prev[f.name]) !== JSON.stringify(formValues[f.name])) {\n updates[f.name] = formValues[f.name]\n hasChanges = true\n }\n }\n })\n if (!hasChanges) return prev // Break infinite react-hook-form loop\n return { ...prev, ...updates }\n })\n }}\n hideSubmitButton={true}\n />\n </div>\n </div>\n )}\n </div>\n ) : (\n <div className=\"flex-1 flex flex-col pt-10\">\n <div className={cn('flex-1 p-10 font-mono text-sm overflow-auto rounded-none-none border', theme === 'dark' ? 'bg-app/50 border-z-border text-z-active-text' : 'bg-[var(--z-bg-hover)] border-z-border text-z-accent')}>\n <pre className=\"no-scrollbar\">{JSON.stringify(data, null, 3)}</pre>\n </div>\n </div>\n )}\n\n <EditorStatusBar />\n </div>\n </div>\n </main>\n\n {/* Right Panel */}\n <RightPanel\n isGlobal={isGlobal}\n resizingSide={resizingSide}\n startResizing={startResizing}\n iframeRef={iframeRef}\n handleRestore={handleRestore}\n onCompareDiff={(vId, vNum) => setDiffVersion({ id: vId, num: vNum })}\n />\n </div>\n </EditorErrorBoundary>\n\n {/* ── Modals ── */}\n <BlockPicker addBlock={addBlock} />\n <SeoModal onSave={handleSave} />\n <TemplatesModal selectedSections={selectedSections} setSelectedSections={setSelectedSections} applyTemplate={applyTemplate} deleteTemplate={deleteTemplate} saveAsTemplate={saveAsTemplate} />\n <RelationsModal />\n <MediaLibrary />\n <DynamicZoneEditor dynamicZoneModalOpen={dynamicZoneModalOpen} setDynamicZoneModalOpen={setDynamicZoneModalOpen} activeDynamicZone={activeDynamicZone} addToDynamicZone={addToDynamicZone} removeFromDynamicZone={removeFromDynamicZone} onReorder={handleDynamicZoneReorder} />\n {contextMenu && (\n <BlockContextMenu\n x={contextMenu.x}\n y={contextMenu.y}\n theme={theme}\n onClose={() => setContextMenu(null)}\n onDuplicate={() => duplicateSection(contextMenu.sectionId)}\n onDelete={() => removeSection(contextMenu.sectionId)}\n onAlign={(align) => updateAlign(contextMenu.sectionId, align)}\n onConvert={(blockType) => convertBlockType(contextMenu.sectionId, blockType)}\n />\n )}\n {diffVersion && (\n <DocumentDiffModal\n versionId={diffVersion.id}\n versionNumber={diffVersion.num}\n collection={isGlobal ? 'globals' : 'pages'}\n documentId={id || ''}\n onClose={() => setDiffVersion(null)}\n onRestoreSuccess={(restored) => {\n editorUpdateData(() => restored)\n const collectionName = isGlobal ? 'globals' : (params.slug || 'pages')\n const docIdVal = id || ''\n api.get(`/versions/${collectionName}/${docIdVal}`)\n .then((res) => setHistory(res.data.data || []))\n .catch(() => {})\n }}\n />\n )}\n <ConflictResolutionModal\n open={conflictData.open}\n onClose={() => setConflictData({ open: false })}\n onReload={handleReload}\n onForceSave={handleForceSave}\n conflictMessage={conflictData.message}\n serverVersion={conflictData.serverVersion}\n localVersion={conflictData.localVersion}\n theme={theme}\n />\n <ConfirmDialog\n open={deleteConfirm.open}\n title=\"Delete Section\"\n message={`Are you sure you want to delete \"${data?.sections?.find((s) => s.id === deleteConfirm.sectionId)?.title || 'this section'}\"? This action cannot be undone.`}\n confirmLabel=\"Delete\"\n danger\n onConfirm={confirmRemoveSection}\n onCancel={() => setDeleteConfirm({ open: false, sectionId: null })}\n />\n </div>\n )\n}\n\nexport default SpatialEditor\n"],"mappings":"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"}