@nextlyhq/plugin-form-builder 0.0.1
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.
- package/LICENSE +22 -0
- package/README.md +122 -0
- package/dist/CheckboxFieldEditor-K4T6QX52.js +121 -0
- package/dist/CheckboxFieldEditor-K4T6QX52.js.map +1 -0
- package/dist/DateFieldEditor-JFJFAVOH.js +187 -0
- package/dist/DateFieldEditor-JFJFAVOH.js.map +1 -0
- package/dist/EmailFieldEditor-MMOXXL7P.js +138 -0
- package/dist/EmailFieldEditor-MMOXXL7P.js.map +1 -0
- package/dist/NumberFieldEditor-UISAYR6Z.js +175 -0
- package/dist/NumberFieldEditor-UISAYR6Z.js.map +1 -0
- package/dist/RadioFieldEditor-6UQFH4WT.js +165 -0
- package/dist/RadioFieldEditor-6UQFH4WT.js.map +1 -0
- package/dist/SelectFieldEditor-PSO4KHV4.js +213 -0
- package/dist/SelectFieldEditor-PSO4KHV4.js.map +1 -0
- package/dist/TextFieldEditor-5EU64EA5.js +187 -0
- package/dist/TextFieldEditor-5EU64EA5.js.map +1 -0
- package/dist/TextareaFieldEditor-773G3LNM.js +190 -0
- package/dist/TextareaFieldEditor-773G3LNM.js.map +1 -0
- package/dist/admin/index.css +934 -0
- package/dist/admin/index.css.map +1 -0
- package/dist/admin/index.d.ts +547 -0
- package/dist/admin/index.js +4030 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/chunk-ABNZFTQK.js +586 -0
- package/dist/chunk-ABNZFTQK.js.map +1 -0
- package/dist/chunk-XTCEPJ7B.js +256 -0
- package/dist/chunk-XTCEPJ7B.js.map +1 -0
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.js +9 -0
- package/dist/components/index.js.map +1 -0
- package/dist/index-C0kBvYjm.d.ts +1012 -0
- package/dist/index.d.ts +1663 -0
- package/dist/index.js +2470 -0
- package/dist/index.js.map +1 -0
- package/dist/styles/form-builder.css +1150 -0
- package/dist/styles/submissions-filter.css +75 -0
- package/package.json +96 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/admin/index.ts","../../src/admin/components/SubmissionsFilter.tsx","../../src/admin/FormBuilderView.tsx","../../src/admin/components/builder/FieldEditor.tsx","../../src/admin/components/builder/ConditionalLogicEditor.tsx","../../src/admin/components/builder/FieldLibrary.tsx","../../src/admin/context/FormBuilderContext.tsx","../../src/admin/components/builder/FormCanvas.tsx","../../src/admin/components/builder/FormNotificationsTab.tsx","../../src/admin/components/builder/FormPreview.tsx","../../src/admin/components/builder/FormSettingsTab.tsx","../../src/admin/components/FormFieldList.tsx","../../src/admin/components/SortableFieldRow.tsx","../../src/admin/fields/index.ts","../../src/admin/components/AddFieldButton.tsx","../../src/admin/components/FieldEditorPanel.tsx"],"sourcesContent":["/**\n * Form Builder Admin Components\n *\n * Entry point for admin UI components used by the Nextly admin panel.\n * These components are referenced via component paths in collection configs.\n *\n * Component paths use the format: \"@nextlyhq/plugin-form-builder/admin#ExportName\"\n *\n * ## Auto-Registration\n *\n * This module automatically registers its components with the admin panel\n * when imported. No manual registration is required - just add the plugin\n * to your Nextly config and the admin will detect and load the components.\n *\n * @module admin\n * @since 0.1.0\n */\n\n// ============================================================================\n// Main View Components\n// ============================================================================\n\n// ============================================================================\n// Component Registration\n// ============================================================================\n\nimport {\n registerComponents,\n registerKnownPlugin,\n type ComponentPath,\n} from \"@nextlyhq/admin/lib/component-registry\";\n\nimport { SubmissionsFilter } from \"./components/SubmissionsFilter\";\nimport { FormBuilderView } from \"./FormBuilderView\";\n\nexport { FormBuilderView, type FormBuilderViewProps } from \"./FormBuilderView\";\nexport {\n SubmissionsFilter,\n type SubmissionsFilterProps,\n} from \"./components/SubmissionsFilter\";\n\n// ============================================================================\n// Builder Sub-Components\n// ============================================================================\n\nexport {\n FieldLibrary,\n FormCanvas,\n FieldEditor,\n FormPreview,\n type FormCanvasProps,\n type FieldEditorProps,\n type FormPreviewProps,\n} from \"./components/builder\";\n\n// ============================================================================\n// New Components\n// ============================================================================\n\nexport {\n FormFieldList,\n type FormFieldListProps,\n SortableFieldRow,\n type SortableFieldRowProps,\n AddFieldButton,\n type AddFieldButtonProps,\n FieldEditorPanel,\n type FieldEditorPanelProps,\n} from \"./components\";\n\n// ============================================================================\n// Context & Hooks\n// ============================================================================\n\nexport {\n FormBuilderProvider,\n useFormBuilder,\n useOptionalFormBuilder,\n createFieldFromType,\n createNotification,\n generateFieldName,\n generateFieldLabel,\n DEFAULT_SETTINGS,\n type FormBuilderState,\n type FormBuilderActions,\n type FormBuilderContextValue,\n type FormBuilderProviderProps,\n type FormSettings,\n type FormNotification,\n} from \"./context/FormBuilderContext\";\n\n// ============================================================================\n// Tab Components\n// ============================================================================\n\nexport { FormSettingsTab } from \"./components/builder/FormSettingsTab\";\nexport { FormNotificationsTab } from \"./components/builder/FormNotificationsTab\";\n\n// ============================================================================\n// Submission Components\n// ============================================================================\n\nexport {\n SubmissionList,\n SubmissionDetail,\n type SubmissionListProps,\n type SubmissionDetailProps,\n} from \"../components/submissions\";\n\n/** Component path for FormBuilderView */\nexport const FORM_BUILDER_VIEW_PATH: ComponentPath =\n \"@nextlyhq/plugin-form-builder/admin#FormBuilderView\";\n\n/** Component path for SubmissionsFilter */\nexport const SUBMISSIONS_FILTER_PATH: ComponentPath =\n \"@nextlyhq/plugin-form-builder/admin#SubmissionsFilter\";\n\n/**\n * Register Form Builder admin components with the Nextly admin panel.\n *\n * @deprecated This function is no longer needed. Components are auto-registered\n * when the admin detects the Form Builder plugin's component paths in collection configs.\n *\n * @example\n * ```typescript\n * // No manual registration needed! Just add the plugin to your config:\n * export default defineConfig({\n * plugins: [formBuilderPlugin.plugin],\n * });\n * ```\n */\nexport function registerFormBuilderAdminComponents(): void {\n registerComponents({\n [FORM_BUILDER_VIEW_PATH]: FormBuilderView,\n });\n}\n\n// ============================================================================\n// Auto-Registration with Admin\n// ============================================================================\n\n/**\n * Eagerly register components at module load time.\n *\n * This ensures components are available immediately when the admin\n * tries to resolve them, without needing to wait for async registration.\n */\nregisterComponents({\n [FORM_BUILDER_VIEW_PATH]: FormBuilderView,\n [SUBMISSIONS_FILTER_PATH]: SubmissionsFilter,\n});\n\n/**\n * Also register with the known plugin system for consistency.\n *\n * This supports the auto-registration flow where the admin detects\n * component paths and triggers registration. Since we eagerly register\n * above, this callback is effectively a no-op but keeps the plugin\n * compatible with both eager and lazy registration patterns.\n */\nregisterKnownPlugin(\n \"@nextlyhq/plugin-form-builder\",\n // eslint-disable-next-line @typescript-eslint/require-await -- registerKnownPlugin's second arg is typed `() => Promise<void>` (strict, not a union); body is synchronous\n async () => {\n // Components already registered above, but re-register for safety\n registerComponents({\n [FORM_BUILDER_VIEW_PATH]: FormBuilderView,\n [SUBMISSIONS_FILTER_PATH]: SubmissionsFilter,\n });\n }\n);\n","\"use client\";\n\n/**\n * Submissions Filter Component\n *\n * A filter component that appears above the form-submissions list table.\n * Allows users to filter submissions by selecting a specific form.\n *\n * @module admin/components/SubmissionsFilter\n * @since 0.1.0\n */\n\n\"use client\";\n\nimport { useRouter, useSearchParams } from \"next/navigation\";\nimport { useCallback, useEffect, useState } from \"react\";\n\n// Import styles - uses aliased path that resolves to dist/styles in consuming apps\nimport \"@nextlyhq/plugin-form-builder/styles/submissions-filter.css\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface Form {\n id: string;\n name: string;\n slug: string;\n}\n\nexport interface SubmissionsFilterProps {\n /** Collection slug (should be \"form-submissions\") */\n collectionSlug: string;\n /** Collection configuration */\n collection: Record<string, unknown>;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * SubmissionsFilter - Filter submissions by form\n *\n * Displays a dropdown of all forms. When a form is selected,\n * updates the URL query params to filter the submissions list.\n */\nexport function SubmissionsFilter({\n collectionSlug,\n}: SubmissionsFilterProps): React.ReactElement | null {\n const router = useRouter();\n const searchParams = useSearchParams();\n const [forms, setForms] = useState<Form[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [selectedFormId, setSelectedFormId] = useState<string>(\"\");\n\n // Get current filter from URL\n useEffect(() => {\n const whereParam = searchParams.get(\"where\");\n if (whereParam) {\n try {\n const where = JSON.parse(whereParam);\n if (where.form?.equals) {\n setSelectedFormId(where.form.equals);\n }\n } catch {\n // Invalid JSON, ignore\n }\n }\n }, [searchParams]);\n\n // Fetch all forms\n useEffect(() => {\n async function fetchForms() {\n try {\n const response = await fetch(\"/admin/api/collections/forms/entries\");\n if (response.ok) {\n const data = (await response.json()) as { items?: Form[] };\n setForms(data.items ?? []);\n }\n } catch (error) {\n console.error(\"Failed to fetch forms:\", error);\n } finally {\n setIsLoading(false);\n }\n }\n\n void fetchForms();\n }, []);\n\n // Handle form selection\n const handleFormChange = useCallback(\n (formId: string) => {\n setSelectedFormId(formId);\n\n // Build new URL with filter\n const params = new URLSearchParams(searchParams.toString());\n\n if (formId) {\n // Set the where parameter to filter by form\n const where = JSON.stringify({ form: { equals: formId } });\n params.set(\"where\", where);\n } else {\n // Clear the filter\n params.delete(\"where\");\n }\n\n // Reset to page 1 when filter changes\n params.delete(\"page\");\n\n // Navigate with new params (route is /admin/collections/ singular)\n router.push(`/admin/collections/${collectionSlug}?${params.toString()}`);\n },\n [router, searchParams, collectionSlug]\n );\n\n // Don't render if not on form-submissions collection\n if (collectionSlug !== \"form-submissions\") {\n return null;\n }\n\n return (\n <div className=\"submissions-filter\">\n <div className=\"submissions-filter-container\">\n <label htmlFor=\"form-filter\" className=\"submissions-filter-label\">\n Filter by Form:\n </label>\n <select\n id=\"form-filter\"\n value={selectedFormId}\n onChange={e => handleFormChange(e.target.value)}\n className=\"submissions-filter-select\"\n disabled={isLoading}\n >\n <option value=\"\">All Forms</option>\n {forms.map(form => (\n <option key={form.id} value={form.id}>\n {form.name}\n </option>\n ))}\n </select>\n {selectedFormId && (\n <button\n type=\"button\"\n onClick={() => handleFormChange(\"\")}\n className=\"submissions-filter-clear\"\n title=\"Clear filter\"\n >\n Clear\n </button>\n )}\n </div>\n </div>\n );\n}\n\nexport default SubmissionsFilter;\n","\"use client\";\n\n/**\n * Form Builder View\n *\n * Custom admin view that provides a visual drag-and-drop form builder.\n * Layout mirrors the Collection Builder for visual consistency.\n *\n * @module admin/FormBuilderView\n * @since 0.1.0\n */\n\n\"use client\";\n\nimport \"../styles/form-builder.css\";\n\nimport {\n DndContext,\n closestCenter,\n KeyboardSensor,\n PointerSensor,\n useSensor,\n useSensors,\n type DragEndEvent,\n} from \"@dnd-kit/core\";\nimport {\n SortableContext,\n sortableKeyboardCoordinates,\n verticalListSortingStrategy,\n} from \"@dnd-kit/sortable\";\nimport {\n Button,\n Input,\n toast,\n Tabs,\n TabsList,\n TabsTrigger,\n Select,\n SelectTrigger,\n SelectValue,\n SelectContent,\n SelectItem,\n} from \"@nextlyhq/ui\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { useCallback, useState } from \"react\";\n\nimport type { FormField, FormFieldType } from \"../types\";\n\nimport { FieldEditor } from \"./components/builder/FieldEditor\";\nimport { FieldLibrary } from \"./components/builder/FieldLibrary\";\nimport { FormCanvas } from \"./components/builder/FormCanvas\";\nimport { FormNotificationsTab } from \"./components/builder/FormNotificationsTab\";\nimport { FormPreview } from \"./components/builder/FormPreview\";\nimport { FormSettingsTab } from \"./components/builder/FormSettingsTab\";\nimport {\n FormBuilderProvider,\n useFormBuilder,\n createFieldFromType,\n type FormNotification,\n} from \"./context/FormBuilderContext\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface FormBuilderViewProps {\n id?: string;\n entryId?: string;\n collection?: string;\n collectionSlug?: string;\n isCreating?: boolean;\n initialData?: {\n id?: string;\n name?: string;\n slug?: string;\n description?: string;\n status?: \"draft\" | \"published\" | \"closed\";\n fields?: unknown[];\n settings?: Record<string, unknown>;\n notifications?: unknown[];\n };\n onSave?: (data: unknown) => void;\n onSuccess?: (entry?: Record<string, unknown>) => void;\n onCancel?: () => void;\n}\n\n// ============================================================================\n// Helper\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}\n\n// ============================================================================\n// Sliders / Spinner inline SVG\n// ============================================================================\n\nfunction SlidersIcon() {\n return (\n <svg\n className=\"h-3 w-3 shrink-0\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"4\" y1=\"21\" x2=\"4\" y2=\"14\" />\n <line x1=\"4\" y1=\"10\" x2=\"4\" y2=\"3\" />\n <line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"12\" />\n <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"3\" />\n <line x1=\"20\" y1=\"21\" x2=\"20\" y2=\"16\" />\n <line x1=\"20\" y1=\"12\" x2=\"20\" y2=\"3\" />\n <line x1=\"1\" y1=\"14\" x2=\"7\" y2=\"14\" />\n <line x1=\"9\" y1=\"8\" x2=\"15\" y2=\"8\" />\n <line x1=\"17\" y1=\"16\" x2=\"23\" y2=\"16\" />\n </svg>\n );\n}\n\n// ============================================================================\n// Inner Component (uses context)\n// ============================================================================\n\nfunction FormBuilderViewInner({\n isCreating = false,\n collectionSlug = \"forms\",\n entryId,\n onSave,\n onSuccess,\n onCancel,\n}: Pick<\n FormBuilderViewProps,\n | \"isCreating\"\n | \"collectionSlug\"\n | \"entryId\"\n | \"onSave\"\n | \"onSuccess\"\n | \"onCancel\"\n>) {\n const {\n fields,\n selectedFieldId,\n activeTab,\n isDirty,\n formData,\n settings,\n notifications,\n setActiveTab,\n addField,\n moveField,\n selectField,\n deleteField,\n updateField,\n duplicateField,\n updateFormData,\n markAsSaved,\n } = useFormBuilder();\n\n const queryClient = useQueryClient();\n\n const [sidebarTab, setSidebarTab] = useState<\"add\" | \"properties\">(\"add\");\n const [isSaving, setIsSaving] = useState(false);\n const [saveError, setSaveError] = useState<string | null>(null);\n\n // ── DnD ──────────────────────────────────────────────────────────────────\n const sensors = useSensors(\n useSensor(PointerSensor, { activationConstraint: { distance: 8 } }),\n useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })\n );\n\n const handleDragEnd = useCallback(\n (event: DragEndEvent) => {\n const { active, over } = event;\n if (!over) return;\n\n const isFromLibrary = active.data.current?.isLibraryItem;\n\n if (isFromLibrary) {\n const fieldType = active.data.current?.fieldType as FormFieldType;\n if (fieldType) {\n const newField = createFieldFromType(fieldType);\n if (over.id === \"canvas-drop-zone\") {\n addField(newField);\n } else {\n const overIndex = fields.findIndex(f => f.name === over.id);\n addField(newField, overIndex !== -1 ? overIndex + 1 : undefined);\n }\n }\n } else {\n if (active.id !== over.id) {\n const oldIndex = fields.findIndex(f => f.name === active.id);\n const newIndex = fields.findIndex(f => f.name === over.id);\n if (oldIndex !== -1 && newIndex !== -1) {\n moveField(oldIndex, newIndex);\n }\n }\n }\n },\n [fields, addField, moveField]\n );\n\n // ── Save / Cancel ─────────────────────────────────────────────────────────\n const handleSave = useCallback(async () => {\n // Check if there are fields\n if (fields.length === 0) {\n toast.error(\"Please add at least one field to the form\");\n return;\n }\n\n const { id: _id, ...formDataWithoutId } = formData;\n const saveData = {\n ...formDataWithoutId,\n title: formDataWithoutId.name,\n fields,\n settings,\n notifications,\n };\n\n if (onSave) {\n onSave(saveData);\n return;\n }\n\n setIsSaving(true);\n setSaveError(null);\n try {\n const url = isCreating\n ? `/admin/api/collections/${collectionSlug}/entries`\n : `/admin/api/collections/${collectionSlug}/entries/${entryId}`;\n const response = await fetch(url, {\n method: isCreating ? \"POST\" : \"PATCH\",\n headers: { \"Content-Type\": \"application/json\" },\n credentials: \"include\",\n body: JSON.stringify(saveData),\n });\n if (!response.ok) {\n const err = (await response.json().catch(() => ({}))) as {\n error?: { message?: string };\n };\n throw new Error(\n err.error?.message ?? `Failed to save form: ${response.statusText}`\n );\n }\n\n const result = (await response.json()) as {\n message?: string;\n item?: Record<string, unknown>;\n } & Record<string, unknown>;\n const savedEntry: Record<string, unknown> = result.item ?? result;\n void queryClient.invalidateQueries({\n queryKey: [\"entries\", \"list\", collectionSlug],\n });\n void queryClient.invalidateQueries({ queryKey: [\"entries\", \"count\"] });\n if (!isCreating && entryId) {\n void queryClient.invalidateQueries({\n queryKey: [\"entries\", \"detail\", collectionSlug, entryId],\n });\n }\n markAsSaved();\n toast.success(\n isCreating ? \"Form created successfully\" : \"Form updated successfully\"\n );\n if (onSuccess) onSuccess(savedEntry);\n } catch (error) {\n const message =\n error instanceof Error ? error.message : \"Failed to save form\";\n setSaveError(message);\n toast.error(message);\n } finally {\n setIsSaving(false);\n }\n }, [\n formData,\n fields,\n settings,\n notifications,\n onSave,\n onSuccess,\n isCreating,\n collectionSlug,\n entryId,\n queryClient,\n markAsSaved,\n ]);\n\n const handleCancel = useCallback(() => {\n if (onCancel) onCancel();\n else if (typeof window !== \"undefined\") window.history.back();\n }, [onCancel]);\n\n const handleFieldSelect = useCallback(\n (fieldName: string | null) => {\n selectField(fieldName);\n if (fieldName) setSidebarTab(\"properties\");\n },\n [selectField]\n );\n\n const handleNameChange = useCallback(\n (name: string) => {\n updateFormData({ name });\n if (!formData.slug || formData.slug === slugify(formData.name)) {\n updateFormData({ slug: slugify(name) });\n }\n },\n [formData.name, formData.slug, updateFormData]\n );\n\n const selectedField = fields.find(f => f.name === selectedFieldId);\n const hasSelectedField = !!selectedFieldId;\n\n // Main tabs\n const mainTabs = [\n {\n value: \"builder\" as const,\n label: \"Builder\",\n count: fields.length > 0 ? fields.length : null,\n },\n {\n value: \"preview\" as const,\n label: \"Preview\",\n count: null,\n },\n { value: \"settings\" as const, label: \"Settings\", count: null },\n {\n value: \"notifications\" as const,\n label: \"Notifications\",\n count: notifications.length > 0 ? notifications.length : null,\n },\n ];\n\n // ── Render ────────────────────────────────────────────────────────────────\n return (\n <DndContext\n sensors={sensors}\n collisionDetection={closestCenter}\n onDragEnd={handleDragEnd}\n >\n {/* ── Page header (Outside the white card) ── */}\n <div className=\"flex flex-col sm:flex-row sm:items-start sm:justify-between gap-4 mb-6 px-1\">\n <div>\n <h1 className=\"text-2xl font-semibold text-foreground tracking-tight\">\n {isCreating ? \"Create Form\" : \"Edit Form\"}\n </h1>\n <p className=\"text-sm text-muted-foreground mt-1\">\n {isCreating\n ? \"Design a new form with drag-and-drop fields.\"\n : \"Modify your form fields and settings.\"}\n </p>\n </div>\n\n {/* Action buttons — same variant/size as Collection Builder */}\n <div className=\"flex items-center gap-2 shrink-0\">\n {isDirty && (\n <span className=\"text-xs font-medium text-amber-600 bg-amber-50 border border-amber-200 px-2.5 py-1 rounded-none whitespace-nowrap\">\n Unsaved changes\n </span>\n )}\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={handleCancel}\n disabled={isSaving}\n >\n Cancel\n </Button>\n <Button\n type=\"button\"\n size=\"sm\"\n onClick={() => {\n void handleSave();\n }}\n disabled={isSaving}\n className=\"flex items-center gap-1.5\"\n >\n {isSaving ? (\n <>\n <svg\n className=\"animate-spin h-3.5 w-3.5\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n >\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z\"\n />\n </svg>\n Saving…\n </>\n ) : isCreating ? (\n \"Create\"\n ) : (\n \"Save Changes\"\n )}\n </Button>\n </div>\n </div>\n\n {/*\n Outer shell — white card with rounded-none border (no shadow).\n Fills available height in the admin page container.\n */}\n <div\n className=\"flex border border-primary/5 bg-background overflow-hidden\"\n style={{\n borderRadius: \"0.5rem\",\n }}\n >\n {/* =================================================================\n LEFT — scrollable main content\n ================================================================= */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"w-full px-8 pt-8 pb-12 space-y-6\">\n {/* ── Fixed Metadata & Tab Navigation ── */}\n <div className=\"bg-background -mx-8 border-b border-primary/5 space-y-4\">\n <div className=\"flex flex-wrap gap-4\">\n {/* Form Name */}\n <div className=\"flex-1 min-w-[200px] max-w-sm space-y-1.5\">\n <label\n htmlFor=\"form-name\"\n className=\"text-sm font-medium text-foreground\"\n >\n Form Name\n </label>\n <Input\n id=\"form-name\"\n type=\"text\"\n value={formData.name || \"\"}\n onChange={e => handleNameChange(e.target.value)}\n placeholder=\"e.g., Contact Form\"\n className=\"bg-transparent\"\n />\n </div>\n\n {/* Slug */}\n <div className=\"flex-1 min-w-[160px] max-w-xs space-y-1.5\">\n <label\n htmlFor=\"form-slug\"\n className=\"text-sm font-medium text-foreground\"\n >\n Slug\n </label>\n <Input\n id=\"form-slug\"\n type=\"text\"\n value={formData.slug || \"\"}\n onChange={e => updateFormData({ slug: e.target.value })}\n placeholder=\"e.g., contact-form\"\n className=\"bg-transparent placeholder:text-muted-foreground/50\"\n />\n </div>\n\n {/* Status */}\n <div className=\"w-36 space-y-1.5\">\n <label\n htmlFor=\"form-status\"\n className=\"text-sm font-medium text-foreground\"\n >\n Status\n </label>\n <Select\n value={formData.status || \"draft\"}\n onValueChange={value =>\n updateFormData({\n status: value as \"draft\" | \"published\" | \"closed\",\n })\n }\n >\n <SelectTrigger id=\"form-status\" className=\"bg-transparent\">\n <SelectValue placeholder=\"Status\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"draft\">Draft</SelectItem>\n <SelectItem value=\"published\">Published</SelectItem>\n <SelectItem value=\"closed\">Closed</SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n\n {/* ── Main tab navigation ── */}\n <Tabs\n value={activeTab}\n onValueChange={v => setActiveTab(v as typeof activeTab)}\n >\n <TabsList className=\"bg-transparent justify-start gap-0 -mb-px border-b-0\">\n {mainTabs.map(tab => (\n <TabsTrigger\n key={tab.value}\n value={tab.value}\n style={{\n borderBottomColor:\n activeTab === tab.value\n ? \"hsl(var(--primary))\"\n : \"transparent\",\n }}\n className=\"border-b-2 relative -mb-0.5 data-[state=active]:text-primary data-[state=inactive]:text-muted-foreground hover:text-primary hover:border-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/20 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer\"\n >\n {tab.label}\n {tab.count !== null && (\n <span\n className={`inline-flex items-center justify-center min-w-[18px] h-[18px] px-1 text-[10px] font-semibold rounded-none ml-2 transition-colors ${\n activeTab === tab.value\n ? \"bg-primary/5 text-primary\"\n : \"bg-primary/5 text-muted-foreground\"\n }`}\n >\n {tab.count}\n </span>\n )}\n </TabsTrigger>\n ))}\n </TabsList>\n </Tabs>\n </div>\n\n {/* ── Tab content ── */}\n\n {/* Builder tab */}\n {activeTab === \"builder\" && (\n <div>\n <SortableContext\n items={fields.map(f => f.name)}\n strategy={verticalListSortingStrategy}\n >\n <FormCanvas\n fields={fields}\n selectedFieldId={selectedFieldId}\n onFieldSelect={handleFieldSelect}\n onFieldDelete={deleteField}\n />\n </SortableContext>\n </div>\n )}\n\n {/* Preview tab */}\n {activeTab === \"preview\" && (\n <FormPreview fields={fields} formData={formData} />\n )}\n\n {/* Settings tab */}\n {activeTab === \"settings\" && (\n <div className=\"w-full\">\n <FormSettingsTab />\n </div>\n )}\n\n {/* Notifications tab */}\n {activeTab === \"notifications\" && (\n <div className=\"w-full\">\n <FormNotificationsTab />\n </div>\n )}\n\n {/* Save error */}\n {saveError && (\n <div className=\"p-3 text-sm text-destructive bg-destructive/10 border border-destructive/20 rounded-none\">\n {saveError}\n </div>\n )}\n </div>\n </div>\n\n {/* =================================================================\n RIGHT SIDEBAR — 360px, white bg, left border divider\n Only shown in Builder tab.\n ================================================================= */}\n {activeTab === \"builder\" && (\n <div\n className=\"shrink-0 border-l border-primary/5 bg-background flex flex-col\"\n style={{ width: \"360px\" }}\n >\n {/* Sidebar tab bar */}\n <div\n className=\"shrink-0 grid grid-cols-2 gap-1.5 px-3 py-2.5 border-b border-primary/5\"\n style={{ minHeight: \"52px\" }}\n >\n {(\n [\n {\n value: \"add\" as const,\n label: \"Add Fields\",\n disabled: false,\n icon: (\n <svg\n className=\"h-3 w-3 shrink-0\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n ),\n },\n {\n value: \"properties\" as const,\n label: \"Properties\",\n disabled: !hasSelectedField,\n icon: <SlidersIcon />,\n },\n ] as const\n ).map(tab => {\n const isActive = sidebarTab === tab.value;\n return (\n <button\n key={tab.value}\n type=\"button\"\n disabled={tab.disabled}\n onClick={() => !tab.disabled && setSidebarTab(tab.value)}\n className={[\n \"flex items-center justify-center gap-1.5 w-full text-[13px] font-medium transition-all duration-150 border rounded-none select-none\",\n \"disabled:opacity-40 disabled:cursor-not-allowed\",\n isActive\n ? \"bg-primary/5 text-primary border-primary/30 cursor-pointer\"\n : \"bg-transparent border-primary/5 text-muted-foreground hover:text-foreground hover:bg-primary/5/50 cursor-pointer\",\n ].join(\" \")}\n style={{ padding: \"8px 12px\" }}\n >\n {tab.icon}\n {tab.label}\n </button>\n );\n })}\n </div>\n\n {/* Sidebar body */}\n <div className=\"flex-1 flex flex-col min-h-0\">\n {/* Add Fields panel */}\n {sidebarTab === \"add\" && (\n <div className=\"flex-1 flex flex-col\">\n <FieldLibrary />\n </div>\n )}\n\n {/* Properties panel */}\n {sidebarTab === \"properties\" && (\n <div className=\"flex-1 flex flex-col relative\">\n {selectedField ? (\n <FieldEditor\n field={selectedField}\n allFields={fields}\n onUpdate={updates =>\n updateField(selectedField.name, updates)\n }\n onDelete={() => {\n deleteField(selectedField.name);\n setSidebarTab(\"add\");\n }}\n onDuplicate={() => duplicateField(selectedField.name)}\n />\n ) : (\n <div className=\"flex flex-col items-center justify-center h-full px-6 py-16 text-center\">\n <div className=\"flex items-center justify-center w-11 h-11 rounded-none bg-primary/5 border border-primary/5 mb-4\">\n <SlidersIcon />\n </div>\n <p className=\"text-sm font-medium text-foreground\">\n No field selected\n </p>\n <p className=\"text-xs text-muted-foreground mt-1\">\n Click a field in the canvas to edit its properties\n </p>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n </DndContext>\n );\n}\n\n// ============================================================================\n// Main Component (provides context)\n// ============================================================================\n\nexport function FormBuilderView({\n id,\n entryId,\n collection,\n collectionSlug,\n isCreating,\n initialData,\n onSave,\n onSuccess,\n onCancel,\n}: FormBuilderViewProps) {\n const resolvedEntryId = entryId || id || initialData?.id;\n const resolvedCollectionSlug = collectionSlug || collection || \"forms\";\n const resolvedIsCreating = isCreating ?? !resolvedEntryId;\n const providerKey = resolvedEntryId || \"new\";\n\n return (\n <FormBuilderProvider\n key={providerKey}\n initialData={{\n id: resolvedEntryId,\n name: initialData?.name,\n slug: initialData?.slug,\n description: initialData?.description,\n status: initialData?.status,\n fields: initialData?.fields as FormField[],\n settings: initialData?.settings as Record<string, unknown>,\n notifications: initialData?.notifications as FormNotification[],\n }}\n >\n <FormBuilderViewInner\n isCreating={resolvedIsCreating}\n collectionSlug={resolvedCollectionSlug}\n entryId={resolvedEntryId}\n onSave={onSave}\n onSuccess={onSuccess}\n onCancel={onCancel}\n />\n </FormBuilderProvider>\n );\n}\n\nexport default FormBuilderView;\n","\"use client\";\n\n/**\n * Field Editor\n *\n * Properties panel for editing the selected field's configuration.\n * Provides tabbed interface for General, Validation, and Conditional settings.\n *\n * @module admin/components/builder/FieldEditor\n * @since 0.1.0\n */\n\n\"use client\";\nimport { FormLabelWithTooltip } from \"@nextlyhq/admin\";\nimport {\n Input,\n Button,\n Checkbox,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@nextlyhq/ui\";\nimport { useState, useCallback, useMemo } from \"react\";\n\nimport type {\n FormField,\n TextFormField,\n SelectFormField,\n RadioFormField,\n} from \"../../../types\";\n\nimport { ConditionalLogicEditor } from \"./ConditionalLogicEditor\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface FieldEditorProps {\n /** The field being edited */\n field: FormField;\n /** All fields in the form (for conditional logic references) */\n allFields: FormField[];\n /** Callback when field is updated */\n onUpdate: (updates: Partial<FormField>) => void;\n /** Callback when field is deleted */\n onDelete: () => void;\n /** Callback when field is duplicated */\n onDuplicate?: () => void;\n}\n\n// ============================================================================\n// Helper Components\n// ============================================================================\n\n/**\n * General properties tab - common field settings\n */\nfunction GeneralTab({\n field,\n allFields,\n onUpdate,\n}: {\n field: FormField;\n allFields: FormField[];\n onUpdate: (updates: Partial<FormField>) => void;\n}) {\n // Check if other fields have conditional logic referencing this field\n const hasConditionalReferences = useMemo(() => {\n return allFields.some(f => {\n if (f.name === field.name || !f.conditionalLogic?.enabled) return false;\n return f.conditionalLogic.conditions.some(c => c.field === field.name);\n });\n }, [allFields, field.name]);\n\n return (\n <div className=\"space-y-6 py-4\">\n {/* Field Name */}\n <div className=\"space-y-2\">\n <FormLabelWithTooltip\n label=\"Field Name (ID)\"\n htmlFor=\"field-name\"\n description=\"Used as the key in submission data. Should be unique and contain no spaces.\"\n />\n <Input\n id=\"field-name\"\n type=\"text\"\n value={field.name}\n onChange={e => onUpdate({ name: e.target.value })}\n pattern=\"^[a-zA-Z][a-zA-Z0-9_]*$\"\n className=\"bg-transparent\"\n />\n {hasConditionalReferences && (\n <p className=\"text-[11px] text-amber-500 font-medium\">\n ⚠️ Changing this may break conditional logic referencing this field\n </p>\n )}\n </div>\n\n {/* Label - not shown for hidden fields */}\n {field.type !== \"hidden\" && (\n <div className=\"space-y-2\">\n <FormLabelWithTooltip\n label=\"Label\"\n htmlFor=\"field-label\"\n description=\"The text displayed above the field in the form.\"\n />\n <Input\n id=\"field-label\"\n type=\"text\"\n value={field.label}\n onChange={e => onUpdate({ label: e.target.value })}\n className=\"bg-transparent\"\n />\n </div>\n )}\n\n {/* Placeholder - for text-like fields */}\n {(field.type === \"text\" ||\n field.type === \"email\" ||\n field.type === \"phone\" ||\n field.type === \"url\" ||\n field.type === \"number\" ||\n field.type === \"textarea\") && (\n <div className=\"space-y-2\">\n <FormLabelWithTooltip\n label=\"Placeholder\"\n htmlFor=\"field-placeholder\"\n description=\"The faint text shown inside the field when empty.\"\n />\n <Input\n id=\"field-placeholder\"\n type=\"text\"\n value={field.placeholder || \"\"}\n onChange={e => onUpdate({ placeholder: e.target.value })}\n className=\"bg-transparent\"\n />\n </div>\n )}\n\n {/* Help Text - not shown for hidden fields */}\n {field.type !== \"hidden\" && (\n <div className=\"space-y-2\">\n <FormLabelWithTooltip\n label=\"Help Text\"\n htmlFor=\"field-help\"\n description=\"Additional instructions displayed below the field.\"\n />\n <Input\n id=\"field-help\"\n type=\"text\"\n value={field.helpText || \"\"}\n onChange={e => onUpdate({ helpText: e.target.value })}\n className=\"bg-transparent\"\n />\n </div>\n )}\n\n {/* Required - not shown for hidden or checkbox fields */}\n {field.type !== \"hidden\" && field.type !== \"checkbox\" && (\n <div className=\"flex items-center gap-3 pt-1\">\n <Checkbox\n id=\"field-required\"\n checked={field.required || false}\n onCheckedChange={checked =>\n onUpdate({ required: checked === true })\n }\n />\n <FormLabelWithTooltip\n label=\"Required field\"\n htmlFor=\"field-required\"\n description=\"Forces the user to fill this field before submitting.\"\n />\n </div>\n )}\n\n {/* Width */}\n <div className=\"space-y-2\">\n <FormLabelWithTooltip\n label=\"Width\"\n htmlFor=\"field-width\"\n description=\"How much space this field takes in a horizontal row.\"\n />\n <Select\n value={field.admin?.width || \"100%\"}\n onValueChange={value =>\n onUpdate({\n admin: {\n ...field.admin,\n width: value as \"25%\" | \"33%\" | \"50%\" | \"66%\" | \"75%\" | \"100%\",\n },\n })\n }\n >\n <SelectTrigger className=\"w-full bg-transparent border-input dark:bg-slate-900/50\">\n <SelectValue placeholder=\"Select width\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"100%\">Full Width (100%)</SelectItem>\n <SelectItem value=\"75%\">Three Quarters (75%)</SelectItem>\n <SelectItem value=\"66%\">Two Thirds (66%)</SelectItem>\n <SelectItem value=\"50%\">Half (50%)</SelectItem>\n <SelectItem value=\"33%\">One Third (33%)</SelectItem>\n <SelectItem value=\"25%\">One Quarter (25%)</SelectItem>\n </SelectContent>\n </Select>\n </div>\n\n {/* Type-specific options */}\n <TypeSpecificOptions field={field} onUpdate={onUpdate} />\n </div>\n );\n}\n\n/**\n * Type-specific field options\n */\nfunction TypeSpecificOptions({\n field,\n onUpdate,\n}: {\n field: FormField;\n onUpdate: (updates: Partial<FormField>) => void;\n}) {\n switch (field.type) {\n case \"select\":\n case \"radio\":\n return <OptionsEditor field={field} onUpdate={onUpdate} />;\n\n case \"textarea\": {\n const textareaField = field;\n return (\n <div className=\"space-y-2\">\n <FormLabelWithTooltip\n label=\"Rows\"\n htmlFor=\"field-rows\"\n description=\"Height of the textarea in text lines.\"\n />\n <Input\n id=\"field-rows\"\n type=\"number\"\n min={2}\n max={20}\n value={textareaField.rows || 4}\n onChange={e => onUpdate({ rows: parseInt(e.target.value) || 4 })}\n className=\"w-24 bg-transparent\"\n />\n </div>\n );\n }\n\n case \"file\": {\n const fileField = field;\n return (\n <>\n <div className=\"space-y-2\">\n <FormLabelWithTooltip\n label=\"Accepted File Types\"\n htmlFor=\"field-accept\"\n description=\"Comma-separated MIME types (e.g., image/*, application/pdf).\"\n />\n <Input\n id=\"field-accept\"\n type=\"text\"\n value={fileField.accept || \"\"}\n onChange={e => onUpdate({ accept: e.target.value })}\n placeholder=\"image/*,application/pdf\"\n className=\"bg-transparent\"\n />\n </div>\n <div className=\"flex items-center gap-3 pt-1\">\n <Checkbox\n id=\"field-multiple\"\n checked={fileField.multiple || false}\n onCheckedChange={checked =>\n onUpdate({ multiple: checked === true })\n }\n />\n <FormLabelWithTooltip\n label=\"Allow multiple files\"\n htmlFor=\"field-multiple\"\n description=\"Users can upload more than one file at once.\"\n />\n </div>\n <div className=\"flex items-center gap-3 pt-1\">\n <Checkbox\n id=\"field-attach-to-email\"\n checked={fileField.attachToEmail || false}\n onCheckedChange={checked =>\n onUpdate({ attachToEmail: checked === true })\n }\n />\n <FormLabelWithTooltip\n label=\"Attach to notification emails\"\n htmlFor=\"field-attach-to-email\"\n description=\"Uploaded files will be attached to all notification emails for this form.\"\n />\n </div>\n </>\n );\n }\n\n case \"hidden\": {\n const hiddenField = field;\n return (\n <div className=\"space-y-2\">\n <FormLabelWithTooltip\n label=\"Default Value\"\n htmlFor=\"field-default\"\n description=\"This value will be submitted silently with the form.\"\n />\n <Input\n id=\"field-default\"\n type=\"text\"\n value={hiddenField.defaultValue || \"\"}\n onChange={e => onUpdate({ defaultValue: e.target.value })}\n className=\"bg-transparent\"\n />\n </div>\n );\n }\n\n case \"date\": {\n const dateField = field;\n return (\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"space-y-2\">\n <FormLabelWithTooltip\n label=\"Minimum Date\"\n htmlFor=\"min-date\"\n description=\"Lower bound for date selection.\"\n />\n <Input\n id=\"min-date\"\n type=\"date\"\n value={dateField.min || \"\"}\n onChange={e => onUpdate({ min: e.target.value })}\n className=\"bg-transparent\"\n />\n </div>\n <div className=\"space-y-2\">\n <FormLabelWithTooltip\n label=\"Maximum Date\"\n htmlFor=\"max-date\"\n description=\"Upper bound for date selection.\"\n />\n <Input\n id=\"max-date\"\n type=\"date\"\n value={dateField.max || \"\"}\n onChange={e => onUpdate({ max: e.target.value })}\n className=\"bg-transparent\"\n />\n </div>\n </div>\n );\n }\n\n case \"number\": {\n const numField = field;\n return (\n <div className=\"space-y-2\">\n <FormLabelWithTooltip\n label=\"Step\"\n htmlFor=\"field-step\"\n description=\"Increment/decrement step (e.g., 0.01 for decimals).\"\n />\n <Input\n id=\"field-step\"\n type=\"number\"\n value={numField.validation?.step || \"\"}\n onChange={e =>\n onUpdate({\n validation: {\n ...numField.validation,\n step: parseFloat(e.target.value) || undefined,\n },\n })\n }\n placeholder=\"1\"\n className=\"w-24 bg-transparent\"\n />\n </div>\n );\n }\n\n default:\n return null;\n }\n}\n\n/**\n * Options editor for select/radio/checkbox-group fields\n */\nfunction OptionsEditor({\n field,\n onUpdate,\n}: {\n field: FormField;\n onUpdate: (updates: Partial<FormField>) => void;\n}) {\n const optionsField = field as SelectFormField | RadioFormField;\n const options = useMemo(\n () => optionsField.options || [],\n [optionsField.options]\n );\n\n const addOption = useCallback(() => {\n const newOptions = [\n ...options,\n {\n label: `Option ${options.length + 1}`,\n value: `option_${options.length + 1}`,\n },\n ];\n onUpdate({ options: newOptions });\n }, [options, onUpdate]);\n\n const updateOption = useCallback(\n (index: number, key: \"label\" | \"value\", value: string) => {\n const newOptions = options.map((opt, i: number) =>\n i === index ? { ...opt, [key]: value } : opt\n );\n onUpdate({ options: newOptions });\n },\n [options, onUpdate]\n );\n\n const removeOption = useCallback(\n (index: number) => {\n const newOptions = options.filter((_, i: number) => i !== index);\n onUpdate({ options: newOptions });\n },\n [options, onUpdate]\n );\n\n return (\n <div className=\"space-y-3 pt-6\">\n <FormLabelWithTooltip\n label=\"Options\"\n description=\"List of choices available for this field.\"\n />\n\n {options.length === 0 ? (\n <div className=\"p-4 bg-primary/5/30 rounded-none border border-dashed border-primary/5 text-center text-xs text-muted-foreground\">\n No options defined. Add an option to get started.\n </div>\n ) : (\n <div className=\"space-y-2\">\n {options.map((opt, index) => (\n <div key={index} className=\"flex items-center gap-2 group\">\n <Input\n type=\"text\"\n value={opt.label}\n onChange={e => updateOption(index, \"label\", e.target.value)}\n placeholder=\"Label\"\n className=\"flex-1 h-9 bg-transparent\"\n />\n <Input\n type=\"text\"\n value={opt.value}\n onChange={e => updateOption(index, \"value\", e.target.value)}\n placeholder=\"Value\"\n className=\"flex-1 h-9 bg-transparent\"\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n onClick={() => removeOption(index)}\n className=\"h-8 w-8 text-muted-foreground hover:text-destructive hover:bg-destructive/10\"\n title=\"Remove option\"\n >\n ×\n </Button>\n </div>\n ))}\n </div>\n )}\n\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={addOption}\n className=\"w-full border-dashed text-xs h-8\"\n >\n + Add Option\n </Button>\n </div>\n );\n}\n\n/**\n * Validation tab - field validation settings\n */\nfunction ValidationTab({\n field,\n onUpdate,\n}: {\n field: FormField;\n onUpdate: (updates: Partial<FormField>) => void;\n}) {\n const validation = useMemo(() => field.validation || {}, [field.validation]);\n\n const updateValidation = useCallback(\n (key: string, value: string | number | undefined) => {\n onUpdate({\n validation: { ...validation, [key]: value },\n });\n },\n [validation, onUpdate]\n );\n\n return (\n <div className=\"space-y-6 pt-2\">\n {/* Custom error message */}\n <div className=\"space-y-2\">\n <FormLabelWithTooltip\n label=\"Custom Error Message\"\n htmlFor=\"error-message\"\n description=\"Override the default browser validation message.\"\n />\n <Input\n id=\"error-message\"\n type=\"text\"\n value={validation.errorMessage || \"\"}\n onChange={e => updateValidation(\"errorMessage\", e.target.value)}\n placeholder=\"This field is required\"\n className=\"bg-transparent\"\n />\n </div>\n\n {/* Text/Textarea length validation */}\n {(field.type === \"text\" || field.type === \"textarea\") && (\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"space-y-2\">\n <FormLabelWithTooltip\n label=\"Min Length\"\n htmlFor=\"min-len\"\n description=\"Minimum characters required.\"\n />\n <Input\n id=\"min-len\"\n type=\"number\"\n min={0}\n value={(field as TextFormField).validation?.minLength ?? \"\"}\n onChange={e =>\n updateValidation(\n \"minLength\",\n e.target.value ? parseInt(e.target.value) : undefined\n )\n }\n className=\"bg-transparent\"\n />\n </div>\n <div className=\"space-y-2\">\n <FormLabelWithTooltip\n label=\"Max Length\"\n htmlFor=\"max-len\"\n description=\"Maximum characters allowed.\"\n />\n <Input\n id=\"max-len\"\n type=\"number\"\n min={0}\n value={(field as TextFormField).validation?.maxLength ?? \"\"}\n onChange={e =>\n updateValidation(\n \"maxLength\",\n e.target.value ? parseInt(e.target.value) : undefined\n )\n }\n className=\"bg-transparent\"\n />\n </div>\n </div>\n )}\n\n {/* Number min/max validation */}\n {field.type === \"number\" && (\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"space-y-2\">\n <FormLabelWithTooltip\n label=\"Min Value\"\n htmlFor=\"min-val\"\n description=\"Minimum numerical value.\"\n />\n <Input\n id=\"min-val\"\n type=\"number\"\n value={field.validation?.min ?? \"\"}\n onChange={e =>\n updateValidation(\n \"min\",\n e.target.value ? parseFloat(e.target.value) : undefined\n )\n }\n className=\"bg-transparent\"\n />\n </div>\n <div className=\"space-y-2\">\n <FormLabelWithTooltip\n label=\"Max Value\"\n htmlFor=\"max-val\"\n description=\"Maximum numerical value.\"\n />\n <Input\n id=\"max-val\"\n type=\"number\"\n value={field.validation?.max ?? \"\"}\n onChange={e =>\n updateValidation(\n \"max\",\n e.target.value ? parseFloat(e.target.value) : undefined\n )\n }\n className=\"bg-transparent\"\n />\n </div>\n </div>\n )}\n\n {/* Pattern validation for text fields */}\n {(field.type === \"text\" ||\n field.type === \"email\" ||\n field.type === \"phone\" ||\n field.type === \"url\") && (\n <div className=\"space-y-2\">\n <FormLabelWithTooltip\n label=\"Pattern (Regex)\"\n htmlFor=\"val-pattern\"\n description=\"Regular expression for advanced validation.\"\n />\n <Input\n id=\"val-pattern\"\n type=\"text\"\n value={(field as TextFormField).validation?.pattern || \"\"}\n onChange={e => updateValidation(\"pattern\", e.target.value)}\n placeholder=\"^[A-Za-z]+$\"\n className=\"bg-transparent\"\n />\n </div>\n )}\n\n {/* File size validation */}\n {field.type === \"file\" && (\n <div className=\"space-y-2\">\n <FormLabelWithTooltip\n label=\"Max File Size (bytes)\"\n htmlFor=\"max-file-size\"\n description=\"Maximum allowed size in bytes (10MB ≈ 10485760).\"\n />\n <Input\n id=\"max-file-size\"\n type=\"number\"\n min={0}\n value={field.maxFileSize ?? \"\"}\n onChange={e =>\n onUpdate({\n maxFileSize: e.target.value\n ? parseInt(e.target.value)\n : undefined,\n })\n }\n placeholder=\"10485760\"\n className=\"bg-transparent\"\n />\n </div>\n )}\n\n {/* Info for fields without validation options */}\n {(field.type === \"checkbox\" || field.type === \"hidden\") && (\n <div className=\"p-3 bg-primary/5/30 rounded-none text-xs text-muted-foreground text-center border border-dashed border-primary/5\">\n No additional validation options for this field type.\n </div>\n )}\n </div>\n );\n}\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\n/**\n * FieldEditor - Field properties configuration panel\n *\n * Provides a tabbed interface for editing field properties:\n * - General: name, label, placeholder, help text, required, width, type-specific options\n * - Validation: error messages, min/max length, patterns, etc.\n * - Conditional: show/hide logic based on other field values\n *\n * @example\n * ```tsx\n * <FieldEditor\n * field={selectedField}\n * allFields={allFields}\n * onUpdate={handleUpdate}\n * onDelete={handleDelete}\n * onDuplicate={handleDuplicate}\n * />\n * ```\n */\nexport function FieldEditor({\n field,\n allFields,\n onUpdate,\n onDelete,\n onDuplicate,\n}: FieldEditorProps) {\n const [activeTab, setActiveTab] = useState<string>(\"general\");\n\n // Get human-readable type label\n const getTypeLabel = (type: string): string => {\n const labels: Record<string, string> = {\n text: \"Text\",\n email: \"Email\",\n number: \"Number\",\n phone: \"Phone\",\n url: \"URL\",\n textarea: \"Textarea\",\n select: \"Select\",\n checkbox: \"Checkbox\",\n radio: \"Radio\",\n file: \"File\",\n date: \"Date\",\n time: \"Time\",\n hidden: \"Hidden\",\n };\n return labels[type] || type;\n };\n\n return (\n <div className=\"flex flex-col h-full\">\n {/* Header */}\n <div className=\"p-4 border-b border-primary/5\">\n <h3 className=\"text-sm font-semibold text-foreground flex items-center gap-2\">\n Field Properties\n <span className=\"text-[10px] uppercase tracking-wider px-1.5 py-0.5 rounded-full bg-primary/5 text-primary font-bold dark:bg-primary/20 dark:text-primary-foreground/90\">\n {getTypeLabel(field.type)}\n </span>\n </h3>\n </div>\n\n {/* Tabs */}\n <Tabs\n value={activeTab}\n onValueChange={setActiveTab}\n className=\"flex-1 flex flex-col\"\n >\n <div className=\"border-b bg-primary/5/10 border-primary/5\">\n <TabsList className=\"w-full justify-start gap-0\">\n <TabsTrigger\n value=\"general\"\n className=\"w-full rounded-none border-b-2 border-transparent data-[state=active]:border-primary data-[state=active]:bg-background/50 transition-all\"\n >\n General\n </TabsTrigger>\n <TabsTrigger\n value=\"validation\"\n className=\"w-full rounded-none border-b-2 border-transparent data-[state=active]:border-primary data-[state=active]:bg-background/50 transition-all\"\n >\n Validation\n </TabsTrigger>\n <TabsTrigger\n value=\"conditional\"\n className=\"w-full rounded-none border-b-2 border-transparent data-[state=active]:border-primary data-[state=active]:bg-background/50 transition-all\"\n >\n Conditional\n </TabsTrigger>\n </TabsList>\n </div>\n\n {/* Scrollable Content */}\n <div className=\"flex-1 overflow-y-auto p-4 pb-20\">\n <TabsContent value=\"general\" className=\"mt-0\">\n <GeneralTab\n field={field}\n allFields={allFields}\n onUpdate={onUpdate}\n />\n </TabsContent>\n\n <TabsContent value=\"validation\" className=\"mt-0\">\n <ValidationTab field={field} onUpdate={onUpdate} />\n </TabsContent>\n\n <TabsContent value=\"conditional\" className=\"mt-0\">\n <ConditionalLogicEditor\n field={field}\n allFields={allFields}\n onUpdate={onUpdate}\n />\n </TabsContent>\n </div>\n </Tabs>\n\n {/* Sticky Footer with actions */}\n <div className=\"p-4 bg-background border-t border-primary/5 flex gap-2 shrink-0\">\n {onDuplicate && (\n <Button\n type=\"button\"\n variant=\"outline\"\n className=\"flex-1 h-9\"\n onClick={onDuplicate}\n >\n Duplicate\n </Button>\n )}\n <Button\n type=\"button\"\n variant=\"destructive\"\n className=\"flex-1 h-9\"\n onClick={onDelete}\n >\n Delete Field\n </Button>\n </div>\n </div>\n );\n}\n\nexport default FieldEditor;\n","\"use client\";\n\n/**\n * Conditional Logic Editor\n *\n * Component for configuring conditional show/hide logic for form fields.\n * Allows users to define conditions based on other field values.\n *\n * @module admin/components/builder/ConditionalLogicEditor\n * @since 0.1.0\n */\n\n\"use client\";\n\nimport { FormLabelWithTooltip } from \"@nextlyhq/admin\";\nimport {\n Input,\n Button,\n Checkbox,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@nextlyhq/ui\";\nimport { useCallback, useMemo } from \"react\";\n\nimport type {\n FormField,\n ConditionalLogic,\n ConditionalLogicCondition,\n} from \"../../../types\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ConditionalLogicEditorProps {\n /** The field being edited */\n field: FormField;\n /** All fields in the form (for field references) */\n allFields: FormField[];\n /** Callback when conditional logic is updated */\n onUpdate: (updates: Partial<FormField>) => void;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst COMPARISON_OPERATORS: Array<{\n value: ConditionalLogicCondition[\"comparison\"];\n label: string;\n}> = [\n { value: \"equals\", label: \"Equals\" },\n { value: \"notEquals\", label: \"Does not equal\" },\n { value: \"contains\", label: \"Contains\" },\n { value: \"isEmpty\", label: \"Is empty\" },\n { value: \"isNotEmpty\", label: \"Is not empty\" },\n { value: \"greaterThan\", label: \"Greater than\" },\n { value: \"lessThan\", label: \"Less than\" },\n];\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Coerce a condition's `value` (stored as `unknown`) into a string\n * suitable for the controlled `<Input>`. Objects are JSON-stringified\n * so we never render `[object Object]`.\n */\nfunction conditionValueToString(value: unknown): string {\n if (value === null || value === undefined) return \"\";\n if (typeof value === \"object\") return JSON.stringify(value);\n // eslint-disable-next-line @typescript-eslint/no-base-to-string -- value narrowed to primitive above; rule doesn't follow control flow on unknown\n return String(value);\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * ConditionalLogicEditor - Configure conditional show/hide logic\n *\n * Allows users to define when a field should be shown or hidden\n * based on the values of other fields in the form.\n *\n * @example\n * ```tsx\n * <ConditionalLogicEditor\n * field={selectedField}\n * allFields={allFields}\n * onUpdate={handleUpdate}\n * />\n * ```\n */\nexport function ConditionalLogicEditor({\n field,\n allFields,\n onUpdate,\n}: ConditionalLogicEditorProps) {\n // Get current conditional logic or create default.\n // Wrapped in useMemo so dependent useCallbacks don't re-create on every render.\n const logic: ConditionalLogic = useMemo(\n () =>\n field.conditionalLogic || {\n enabled: false,\n action: \"show\",\n operator: \"AND\",\n conditions: [],\n },\n [field.conditionalLogic]\n );\n\n // Get other fields that can be referenced (exclude current field)\n const availableFields = allFields.filter(f => f.name !== field.name);\n\n // Update the entire conditional logic object\n const updateLogic = useCallback(\n (updates: Partial<ConditionalLogic>) => {\n onUpdate({\n conditionalLogic: { ...logic, ...updates },\n });\n },\n [logic, onUpdate]\n );\n\n // Toggle enabled state\n const handleToggleEnabled = useCallback(() => {\n updateLogic({ enabled: !logic.enabled });\n }, [logic.enabled, updateLogic]);\n\n // Add a new condition\n const handleAddCondition = useCallback(() => {\n const firstField = availableFields[0];\n if (!firstField) return;\n\n const newCondition: ConditionalLogicCondition = {\n field: firstField.name,\n comparison: \"equals\",\n value: \"\",\n };\n\n updateLogic({\n conditions: [...logic.conditions, newCondition],\n });\n }, [availableFields, logic.conditions, updateLogic]);\n\n // Update a specific condition\n const handleUpdateCondition = useCallback(\n (index: number, updates: Partial<ConditionalLogicCondition>) => {\n const newConditions = logic.conditions.map((c, i) =>\n i === index ? { ...c, ...updates } : c\n );\n updateLogic({ conditions: newConditions });\n },\n [logic.conditions, updateLogic]\n );\n\n // Remove a condition\n const handleRemoveCondition = useCallback(\n (index: number) => {\n const newConditions = logic.conditions.filter((_, i) => i !== index);\n updateLogic({ conditions: newConditions });\n },\n [logic.conditions, updateLogic]\n );\n\n // Check if comparison needs a value input\n const needsValue = (comparison: ConditionalLogicCondition[\"comparison\"]) => {\n return comparison !== \"isEmpty\" && comparison !== \"isNotEmpty\";\n };\n\n return (\n <div className=\"space-y-6 pt-2\">\n {/* Enable toggle */}\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-3\">\n <Checkbox\n id=\"logic-enabled\"\n checked={logic.enabled}\n onCheckedChange={handleToggleEnabled}\n />\n <FormLabelWithTooltip\n label=\"Enable conditional logic\"\n htmlFor=\"logic-enabled\"\n description=\"Show or hide this field based on other field values.\"\n />\n </div>\n </div>\n\n {logic.enabled && (\n <div className=\"space-y-4 pt-4 border-t border-primary/5\">\n {/* Action and operator row */}\n <div className=\"flex flex-wrap items-center gap-2 text-sm text-muted-foreground\">\n <Select\n value={logic.action}\n onValueChange={value =>\n updateLogic({ action: value as \"show\" | \"hide\" })\n }\n >\n <SelectTrigger className=\"w-[100px] h-9 bg-transparent border-input dark:bg-slate-900/50\">\n <SelectValue placeholder=\"Show/Hide\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"show\">Show</SelectItem>\n <SelectItem value=\"hide\">Hide</SelectItem>\n </SelectContent>\n </Select>\n <span>this field when</span>\n <Select\n value={logic.operator}\n onValueChange={value =>\n updateLogic({ operator: value as \"AND\" | \"OR\" })\n }\n >\n <SelectTrigger className=\"w-[80px] h-9 bg-transparent border-input dark:bg-slate-900/50\">\n <SelectValue placeholder=\"All/Any\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"AND\">All</SelectItem>\n <SelectItem value=\"OR\">Any</SelectItem>\n </SelectContent>\n </Select>\n <span>of the following conditions are met:</span>\n </div>\n\n {/* Conditions list */}\n <div className=\"space-y-3 pt-4\">\n {logic.conditions.length === 0 ? (\n <div className=\"p-4 bg-primary/5/30 rounded-none border border-dashed border-primary/5 text-center text-xs text-muted-foreground\">\n No conditions defined. Add a condition to get started.\n </div>\n ) : (\n logic.conditions.map((condition, index) => (\n <div\n key={index}\n className=\"flex flex-col gap-2 p-3 rounded-none bg-primary/5/20 border border-primary/5 relative group\"\n >\n <div className=\"grid grid-cols-1 gap-2\">\n {/* Field selector */}\n <Select\n value={condition.field}\n onValueChange={value =>\n handleUpdateCondition(index, { field: value })\n }\n >\n <SelectTrigger className=\"w-full bg-transparent border-input dark:bg-slate-900/50\">\n <SelectValue placeholder=\"Select field\" />\n </SelectTrigger>\n <SelectContent>\n {availableFields.map(f => (\n <SelectItem key={f.name} value={f.name}>\n {f.label || f.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n\n <div className=\"flex gap-2\">\n {/* Comparison operator */}\n <Select\n value={condition.comparison}\n onValueChange={value =>\n handleUpdateCondition(index, {\n comparison:\n value as ConditionalLogicCondition[\"comparison\"],\n })\n }\n >\n <SelectTrigger className=\"flex-1 h-9 bg-transparent border-input dark:bg-slate-900/50\">\n <SelectValue placeholder=\"Compare operator\" />\n </SelectTrigger>\n <SelectContent>\n {COMPARISON_OPERATORS.map(op => (\n <SelectItem key={op.value} value={op.value}>\n {op.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n\n {/* Value input (if needed) */}\n {needsValue(condition.comparison) && (\n <Input\n type=\"text\"\n value={conditionValueToString(condition.value)}\n onChange={e =>\n handleUpdateCondition(index, {\n value: e.target.value,\n })\n }\n placeholder=\"Value\"\n className=\"flex-1 h-9 bg-transparent\"\n />\n )}\n </div>\n </div>\n\n {/* Remove button */}\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon-sm\"\n onClick={() => handleRemoveCondition(index)}\n className=\"absolute -top-2 -right-2 h-6 w-6 rounded-full bg-background border border-primary/5 opacity-0 group-hover:opacity-100 transition-opacity\"\n title=\"Remove condition\"\n >\n <span className=\"text-xs\">×</span>\n </Button>\n </div>\n ))\n )}\n </div>\n\n {/* Add condition button */}\n {availableFields.length > 0 ? (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={handleAddCondition}\n className=\"w-full mt-4 border-dashed\"\n >\n + Add Condition\n </Button>\n ) : (\n <p className=\"mt-4 text-center text-xs text-amber-500 font-medium bg-amber-500/10 p-2 rounded-none border border-amber-500/20\">\n Add more fields to the form to create conditions.\n </p>\n )}\n </div>\n )}\n </div>\n );\n}\n","\"use client\";\n\n/**\n * Field Library\n *\n * Displays available field types that can be dragged onto the form canvas.\n * Styled to match the Collection Builder's FieldPalette:\n * - Search input at the top\n * - Accordion category sections (Basic / Advanced)\n * - Blue icon boxes with label + description rows\n * - Drag-to-add and click-to-add support\n *\n * @module admin/components/builder/FieldLibrary\n * @since 0.1.0\n */\n\n\"use client\";\n\nimport { useDraggable } from \"@dnd-kit/core\";\nimport { useMemo, useState } from \"react\";\n\nimport type { FormFieldType } from \"../../../types\";\nimport {\n useFormBuilder,\n createFieldFromType,\n} from \"../../context/FormBuilderContext\";\n\n// ============================================================================\n// Field Type Definitions\n// ============================================================================\n\ninterface FieldTypeConfig {\n type: FormFieldType;\n label: string;\n description: string;\n /** Lucide-compatible SVG path data for the icon */\n iconPath: string;\n category: \"basic\" | \"advanced\";\n}\n\nconst FIELD_TYPES: FieldTypeConfig[] = [\n // -------------------------------------------------------------------------\n // Basic\n // -------------------------------------------------------------------------\n {\n type: \"text\",\n label: \"Text\",\n description: \"Single line text input\",\n iconPath: \"M4 7h16M4 12h16M4 17h10\",\n category: \"basic\",\n },\n {\n type: \"email\",\n label: \"Email\",\n description: \"Email address with validation\",\n iconPath:\n \"M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z\",\n category: \"basic\",\n },\n {\n type: \"number\",\n label: \"Number\",\n description: \"Numeric input\",\n iconPath: \"M7 20l4-16m2 16l4-16M6 9h14M4 15h14\",\n category: \"basic\",\n },\n {\n type: \"phone\",\n label: \"Phone\",\n description: \"Phone number input\",\n iconPath:\n \"M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498A1 1 0 0121 15.72V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z\",\n category: \"basic\",\n },\n {\n type: \"url\",\n label: \"URL\",\n description: \"Website URL input\",\n iconPath:\n \"M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1\",\n category: \"basic\",\n },\n {\n type: \"textarea\",\n label: \"Textarea\",\n description: \"Multi-line text input\",\n iconPath: \"M4 6h16M4 12h16M4 18h7\",\n category: \"basic\",\n },\n {\n type: \"select\",\n label: \"Dropdown\",\n description: \"Dropdown select menu\",\n iconPath: \"M8 9l4-4 4 4m0 6l-4 4-4-4\",\n category: \"basic\",\n },\n {\n type: \"checkbox\",\n label: \"Checkbox\",\n description: \"Single checkbox\",\n iconPath: \"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z\",\n category: \"basic\",\n },\n {\n type: \"radio\",\n label: \"Radio\",\n description: \"Radio button group\",\n iconPath:\n \"M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-6a4 4 0 100-8 4 4 0 000 8z\",\n category: \"basic\",\n },\n // -------------------------------------------------------------------------\n // Advanced\n // -------------------------------------------------------------------------\n {\n type: \"file\",\n label: \"File Upload\",\n description: \"File attachment\",\n iconPath:\n \"M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13\",\n category: \"advanced\",\n },\n {\n type: \"date\",\n label: \"Date\",\n description: \"Date picker\",\n iconPath:\n \"M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z\",\n category: \"advanced\",\n },\n {\n type: \"time\",\n label: \"Time\",\n description: \"Time picker\",\n iconPath: \"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z\",\n category: \"advanced\",\n },\n {\n type: \"hidden\",\n label: \"Hidden\",\n description: \"Hidden field with static value\",\n iconPath:\n \"M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21\",\n category: \"advanced\",\n },\n];\n\nconst CATEGORIES = [\n { key: \"basic\" as const, label: \"Basic\" },\n { key: \"advanced\" as const, label: \"Advanced\" },\n];\n\n// ============================================================================\n// Draggable Item\n// ============================================================================\n\nfunction DraggableFieldItem({\n type,\n label,\n description,\n iconPath,\n onAdd,\n}: FieldTypeConfig & { onAdd: (type: FormFieldType) => void }) {\n const { attributes, listeners, setNodeRef, isDragging } = useDraggable({\n id: `library-${type}`,\n data: {\n isLibraryItem: true,\n fieldType: type,\n },\n });\n\n return (\n <button\n ref={setNodeRef}\n type=\"button\"\n onClick={() => onAdd(type)}\n title={description}\n className={`flex items-center gap-3 w-full px-2 py-2 rounded-none text-left group hover:bg-primary/5/50 transition-all duration-150 cursor-grab active:cursor-grabbing active:scale-[0.98] ${\n isDragging ? \"opacity-50 bg-primary/5\" : \"\"\n }`}\n {...attributes}\n {...listeners}\n >\n {/* Blue icon box — same as Collection Builder FieldPalette */}\n <div\n className=\"shrink-0 flex items-center justify-center w-9 h-9 bg-primary/5 text-primary dark:bg-primary/20 dark:text-primary-foreground/80\"\n style={{\n borderRadius: \"6px\",\n border: \"1px solid hsl(var(--primary) / 0.25)\",\n }}\n >\n <svg\n className=\"h-4 w-4\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.75\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d={iconPath} />\n </svg>\n </div>\n\n {/* Label + description */}\n <div className=\"flex flex-col min-w-0\">\n <span className=\"text-[13px] font-semibold text-foreground leading-snug\">\n {label}\n </span>\n <span className=\"text-[11px] text-muted-foreground/80 leading-snug truncate\">\n {description}\n </span>\n </div>\n </button>\n );\n}\n\n// ============================================================================\n// Category Section (accordion)\n// ============================================================================\n\nfunction CategorySection({\n name,\n types,\n isOpen,\n onToggle,\n onAdd,\n}: {\n name: string;\n types: FieldTypeConfig[];\n isOpen: boolean;\n onToggle: () => void;\n onAdd: (type: FormFieldType) => void;\n}) {\n return (\n <div>\n {/* Accordion trigger */}\n <button\n type=\"button\"\n onClick={onToggle}\n className=\"flex items-center gap-1.5 w-full py-2 px-1 text-left select-none cursor-pointer\"\n >\n {/* Chevron */}\n <svg\n className={`h-3 w-3 transition-transform duration-200 shrink-0 ${\n isOpen ? \"rotate-0\" : \"-rotate-90\"\n }`}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"#9ca3af\"\n strokeWidth=\"2\"\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n\n {/* Category name */}\n <span\n className=\"text-[13px] font-semibold tracking-widest uppercase\"\n style={{ color: \"#9ca3af\" }}\n >\n {name}\n </span>\n\n {/* Count badge */}\n <span\n className=\"ml-auto text-[10px] font-medium leading-none\"\n style={{\n background: \"#f3f4f6\",\n color: \"#9ca3af\",\n padding: \"2px 6px\",\n borderRadius: \"4px\",\n }}\n >\n {types.length}\n </span>\n </button>\n\n {/* Expanded items with vertical left line */}\n {isOpen && (\n <div\n className=\"mb-1 space-y-0.5\"\n style={{\n marginLeft: \"10px\",\n paddingLeft: \"10px\",\n borderLeft: \"1px solid #e5e7eb\",\n }}\n >\n {types.map(field => (\n <DraggableFieldItem key={field.type} {...field} onAdd={onAdd} />\n ))}\n </div>\n )}\n </div>\n );\n}\n\n// ============================================================================\n// FieldLibrary Component\n// ============================================================================\n\n/**\n * FieldLibrary — Right-sidebar field type palette\n *\n * Mirrors the Collection Builder's FieldPalette:\n * - Search bar at top\n * - Accordion categories (Basic / Advanced)\n * - Blue icon boxes with draggable rows\n * - Click or drag to add a field\n */\nexport function FieldLibrary() {\n const { addField } = useFormBuilder();\n\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [openSection, setOpenSection] = useState<string>(\"Basic\");\n\n const handleAdd = (type: FormFieldType) => {\n const newField = createFieldFromType(type);\n addField(newField);\n };\n\n const toggleSection = (name: string) => {\n setOpenSection(prev => (prev === name ? \"\" : name));\n };\n\n const isSearching = searchQuery.trim().length > 0;\n\n const filteredCategories = useMemo(() => {\n const byCategory: Record<\"basic\" | \"advanced\", FieldTypeConfig[]> = {\n basic: [],\n advanced: [],\n };\n\n for (const field of FIELD_TYPES) {\n byCategory[field.category].push(field);\n }\n\n return CATEGORIES.map(cat => ({\n ...cat,\n types: byCategory[cat.key].filter(f => {\n if (!isSearching) return true;\n const q = searchQuery.toLowerCase();\n return (\n f.label.toLowerCase().includes(q) ||\n f.type.toLowerCase().includes(q) ||\n f.description.toLowerCase().includes(q)\n );\n }),\n })).filter(c => c.types.length > 0);\n }, [searchQuery, isSearching]);\n\n const activeFieldCount = filteredCategories.reduce(\n (acc, cat) => acc + cat.types.length,\n 0\n );\n\n return (\n <div className=\"h-full flex flex-col bg-background\">\n {/* Search */}\n <div className=\"px-3 py-3 border-b border-primary/5\">\n <div className=\"relative\">\n <svg\n className=\"absolute left-3 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground/50\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\" />\n </svg>\n <input\n type=\"search\"\n placeholder={`Search ${activeFieldCount} field types...`}\n value={searchQuery}\n onChange={e => setSearchQuery(e.target.value)}\n className=\"text-[13px] pl-9 flex h-9 w-full rounded-none border border-input bg-primary/5/20 px-3 py-1 text-sm shadow-none transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n style={{ borderRadius: \"6px\", height: \"38px\" }}\n />\n </div>\n </div>\n\n {/* Accordion list */}\n <div\n className=\"flex-1 overflow-y-auto px-3 py-3 space-y-3\"\n style={{\n scrollbarWidth: \"none\",\n msOverflowStyle: \"none\",\n }}\n >\n {filteredCategories.map(category => (\n <CategorySection\n key={category.key}\n name={category.label}\n types={category.types}\n isOpen={isSearching ? true : openSection === category.label}\n onToggle={() => toggleSection(category.label)}\n onAdd={handleAdd}\n />\n ))}\n\n {filteredCategories.length === 0 && (\n <div className=\"text-center py-12\">\n <svg\n className=\"h-7 w-7 text-muted-foreground/20 mx-auto mb-2\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\" />\n </svg>\n <p className=\"text-sm text-muted-foreground\">No fields found</p>\n </div>\n )}\n </div>\n\n {/* Footer hint */}\n <div className=\"px-3 py-2.5 border-t border-primary/5\">\n <p className=\"text-[11px] text-muted-foreground/50 text-center\">\n Drag fields to the canvas to add them\n </p>\n </div>\n </div>\n );\n}\n\nexport default FieldLibrary;\n","\"use client\";\n\n/**\n * Form Builder Context\n *\n * Provides state management for the Form Builder UI.\n * Manages form fields, selection state, and form metadata.\n *\n * @module admin/context/FormBuilderContext\n * @since 0.1.0\n */\n\n\"use client\";\n\nimport {\n createContext,\n useContext,\n useCallback,\n useMemo,\n useState,\n type ReactNode,\n} from \"react\";\n\nimport type { FormField, FormFieldType } from \"../../types\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Form settings configuration */\nexport interface FormSettings {\n /** Submit button text */\n submitButtonText: string;\n /** Show reset button */\n showResetButton: boolean;\n /** Reset button text */\n resetButtonText: string;\n /** Success message after submission */\n confirmationMessage: string;\n /** Redirect URL after submission (optional) */\n redirectUrl?: string;\n /** Enable honeypot spam protection */\n honeypotEnabled: boolean;\n /** Enable CAPTCHA */\n captchaEnabled: boolean;\n /** Store submissions in database */\n storeSubmissions: boolean;\n /** Limit submissions per user/IP */\n submissionLimit?: number;\n}\n\n/** Email notification configuration */\nexport interface FormNotification {\n /** Unique ID for this notification */\n id: string;\n /** Notification name */\n name: string;\n /** Whether this notification is enabled */\n enabled: boolean;\n /** ID of the email provider to use; undefined = system default */\n providerId?: string;\n /** Sender email override; undefined = use provider's configured address */\n senderEmail?: string;\n /** How the recipient address is determined */\n recipientType: \"static\" | \"field\";\n /** Recipient address: static email or a {{fieldName}} reference */\n to: string;\n /** CC email addresses */\n cc: string[];\n /** BCC email addresses */\n bcc: string[];\n /** Slug of the email template to use */\n templateSlug?: string;\n}\n\nexport interface FormBuilderState {\n /** Form fields array */\n fields: FormField[];\n /** Currently selected field ID (name) */\n selectedFieldId: string | null;\n /** Active tab: builder, preview, settings, or notifications */\n activeTab: \"builder\" | \"preview\" | \"settings\" | \"notifications\";\n /** Whether form has unsaved changes */\n isDirty: boolean;\n /** Form metadata */\n formData: {\n id?: string;\n name: string;\n slug: string;\n description?: string;\n status: \"draft\" | \"published\" | \"closed\";\n };\n /** Form settings */\n settings: FormSettings;\n /** Email notifications */\n notifications: FormNotification[];\n}\n\nexport interface FormBuilderActions {\n /** Set all fields */\n setFields: (fields: FormField[]) => void;\n /** Add a new field */\n addField: (field: FormField, index?: number) => void;\n /** Update a field by name */\n updateField: (fieldName: string, updates: Partial<FormField>) => void;\n /** Delete a field by name */\n deleteField: (fieldName: string) => void;\n /** Move a field from one index to another */\n moveField: (fromIndex: number, toIndex: number) => void;\n /** Duplicate a field */\n duplicateField: (fieldName: string) => void;\n /** Select a field */\n selectField: (fieldName: string | null) => void;\n /** Set active tab */\n setActiveTab: (\n tab: \"builder\" | \"preview\" | \"settings\" | \"notifications\"\n ) => void;\n /** Update form metadata */\n updateFormData: (updates: Partial<FormBuilderState[\"formData\"]>) => void;\n /** Update form settings */\n updateSettings: (updates: Partial<FormSettings>) => void;\n /** Add a notification */\n addNotification: (notification: FormNotification) => void;\n /** Update a notification */\n updateNotification: (id: string, updates: Partial<FormNotification>) => void;\n /** Delete a notification */\n deleteNotification: (id: string) => void;\n /** Mark form as saved (clears dirty flag) */\n markAsSaved: () => void;\n}\n\nexport interface FormBuilderContextValue\n extends FormBuilderState,\n FormBuilderActions {}\n\nexport interface FormBuilderProviderProps {\n /** Initial form data (for editing existing forms) */\n initialData?: {\n id?: string;\n name?: string;\n slug?: string;\n description?: string;\n status?: \"draft\" | \"published\" | \"closed\";\n fields?: FormField[];\n settings?: Partial<FormSettings>;\n notifications?: FormNotification[];\n };\n /** Child components */\n children: ReactNode;\n}\n\n/** Default form settings */\nexport const DEFAULT_SETTINGS: FormSettings = {\n submitButtonText: \"Submit\",\n showResetButton: false,\n resetButtonText: \"Reset\",\n confirmationMessage: \"Thank you for your submission!\",\n redirectUrl: undefined,\n honeypotEnabled: true,\n captchaEnabled: false,\n storeSubmissions: true,\n submissionLimit: undefined,\n};\n\n/** Create a new email integration with default values */\nexport function createNotification(): FormNotification {\n const id = `notif_${Date.now().toString(36)}_${Math.random().toString(36).substring(2, 6)}`;\n return {\n id,\n name: \"Email Notification\",\n enabled: true,\n recipientType: \"static\",\n to: \"\",\n cc: [],\n bcc: [],\n };\n}\n\n// ============================================================================\n// Context\n// ============================================================================\n\nconst FormBuilderContext = createContext<FormBuilderContextValue | null>(null);\n\n// ============================================================================\n// Utilities\n// ============================================================================\n\n/**\n * Generate a unique field name based on type and timestamp.\n */\nexport function generateFieldName(type: FormFieldType): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 6);\n return `${type}_${timestamp}_${random}`;\n}\n\n/**\n * Generate a human-readable label from field type.\n */\nexport function generateFieldLabel(type: FormFieldType): string {\n const labels: Record<FormFieldType, string> = {\n text: \"Text Field\",\n email: \"Email Address\",\n number: \"Number\",\n phone: \"Phone Number\",\n url: \"Website URL\",\n textarea: \"Text Area\",\n select: \"Dropdown\",\n checkbox: \"Checkbox\",\n radio: \"Radio Buttons\",\n file: \"File Upload\",\n date: \"Date\",\n time: \"Time\",\n hidden: \"Hidden Field\",\n };\n return labels[type] || \"New Field\";\n}\n\n/**\n * Create a new field from a field type with default values.\n */\nexport function createFieldFromType(type: FormFieldType): FormField {\n const name = generateFieldName(type);\n const label = generateFieldLabel(type);\n\n const baseField = {\n name,\n label,\n required: false,\n };\n\n switch (type) {\n case \"text\":\n return { ...baseField, type: \"text\" };\n\n case \"email\":\n return { ...baseField, type: \"email\", label: \"Email Address\" };\n\n case \"number\":\n return { ...baseField, type: \"number\" };\n\n case \"phone\":\n return { ...baseField, type: \"phone\", label: \"Phone Number\" };\n\n case \"url\":\n return { ...baseField, type: \"url\", label: \"Website\" };\n\n case \"textarea\":\n return { ...baseField, type: \"textarea\", rows: 4 };\n\n case \"select\":\n return {\n ...baseField,\n type: \"select\",\n options: [\n { label: \"Option 1\", value: \"option_1\" },\n { label: \"Option 2\", value: \"option_2\" },\n ],\n };\n\n case \"checkbox\":\n return { ...baseField, type: \"checkbox\" };\n\n case \"radio\":\n return {\n ...baseField,\n type: \"radio\",\n options: [\n { label: \"Option 1\", value: \"option_1\" },\n { label: \"Option 2\", value: \"option_2\" },\n ],\n };\n\n case \"file\":\n return { ...baseField, type: \"file\" };\n\n case \"date\":\n return { ...baseField, type: \"date\" };\n\n case \"time\":\n return { ...baseField, type: \"time\" };\n\n case \"hidden\":\n return { ...baseField, type: \"hidden\", label: \"Hidden Field\" };\n\n default:\n return { ...baseField, type: \"text\" };\n }\n}\n\n// ============================================================================\n// Provider\n// ============================================================================\n\n/**\n * FormBuilderProvider - Provides form builder state to child components\n *\n * Wraps the form builder UI to provide centralized state management\n * for fields, selection, and form metadata.\n *\n * @example\n * ```tsx\n * <FormBuilderProvider initialData={existingForm}>\n * <FormBuilderView />\n * </FormBuilderProvider>\n * ```\n */\nexport function FormBuilderProvider({\n initialData,\n children,\n}: FormBuilderProviderProps) {\n // State\n const [fields, setFieldsState] = useState<FormField[]>(\n initialData?.fields || []\n );\n const [selectedFieldId, setSelectedFieldId] = useState<string | null>(null);\n const [activeTab, setActiveTab] = useState<\n \"builder\" | \"preview\" | \"settings\" | \"notifications\"\n >(\"builder\");\n const [isDirty, setIsDirty] = useState(false);\n const [formData, setFormData] = useState<FormBuilderState[\"formData\"]>({\n id: initialData?.id,\n name: initialData?.name || \"\",\n slug: initialData?.slug || \"\",\n description: initialData?.description,\n status: initialData?.status || \"draft\",\n });\n const [settings, setSettings] = useState<FormSettings>({\n ...DEFAULT_SETTINGS,\n ...initialData?.settings,\n });\n const [notifications, setNotifications] = useState<FormNotification[]>(\n initialData?.notifications || []\n );\n\n // Actions\n const setFields = useCallback((newFields: FormField[]) => {\n setFieldsState(newFields);\n setIsDirty(true);\n }, []);\n\n const addField = useCallback((field: FormField, index?: number) => {\n setFieldsState(prev => {\n if (index !== undefined && index >= 0 && index <= prev.length) {\n const newFields = [...prev];\n newFields.splice(index, 0, field);\n return newFields;\n }\n return [...prev, field];\n });\n setSelectedFieldId(field.name);\n setIsDirty(true);\n }, []);\n\n const updateField = useCallback(\n (fieldName: string, updates: Partial<FormField>) => {\n setFieldsState(prev =>\n prev.map(f =>\n f.name === fieldName ? ({ ...f, ...updates } as FormField) : f\n )\n );\n // If the field name is being changed, also update selectedFieldId\n // This prevents the sidebar from disappearing when renaming a field\n if (updates.name && updates.name !== fieldName) {\n setSelectedFieldId(updates.name);\n }\n setIsDirty(true);\n },\n []\n );\n\n const deleteField = useCallback(\n (fieldName: string) => {\n setFieldsState(prev => prev.filter(f => f.name !== fieldName));\n if (selectedFieldId === fieldName) {\n setSelectedFieldId(null);\n }\n setIsDirty(true);\n },\n [selectedFieldId]\n );\n\n const moveField = useCallback((fromIndex: number, toIndex: number) => {\n setFieldsState(prev => {\n if (\n fromIndex < 0 ||\n fromIndex >= prev.length ||\n toIndex < 0 ||\n toIndex >= prev.length\n ) {\n return prev;\n }\n const newFields = [...prev];\n const [removed] = newFields.splice(fromIndex, 1);\n newFields.splice(toIndex, 0, removed);\n return newFields;\n });\n setIsDirty(true);\n }, []);\n\n const duplicateField = useCallback((fieldName: string) => {\n let newFieldName: string | null = null;\n\n setFieldsState(prev => {\n const fieldIndex = prev.findIndex(f => f.name === fieldName);\n if (fieldIndex === -1) return prev;\n\n const field = prev[fieldIndex];\n newFieldName = generateFieldName(field.type);\n const newField: FormField = {\n ...field,\n name: newFieldName,\n label: `${field.label} (Copy)`,\n };\n\n const newFields = [...prev];\n newFields.splice(fieldIndex + 1, 0, newField);\n return newFields;\n });\n\n // Select the duplicated field so it appears in the editor panel\n if (newFieldName) {\n setSelectedFieldId(newFieldName);\n }\n setIsDirty(true);\n }, []);\n\n const selectField = useCallback((fieldName: string | null) => {\n setSelectedFieldId(fieldName);\n }, []);\n\n const updateFormData = useCallback(\n (updates: Partial<FormBuilderState[\"formData\"]>) => {\n setFormData(prev => ({ ...prev, ...updates }));\n setIsDirty(true);\n },\n []\n );\n\n const updateSettings = useCallback((updates: Partial<FormSettings>) => {\n setSettings(prev => ({ ...prev, ...updates }));\n setIsDirty(true);\n }, []);\n\n const addNotification = useCallback((notification: FormNotification) => {\n setNotifications(prev => [...prev, notification]);\n setIsDirty(true);\n }, []);\n\n const updateNotification = useCallback(\n (id: string, updates: Partial<FormNotification>) => {\n setNotifications(prev =>\n prev.map(n => (n.id === id ? { ...n, ...updates } : n))\n );\n setIsDirty(true);\n },\n []\n );\n\n const deleteNotification = useCallback((id: string) => {\n setNotifications(prev => prev.filter(n => n.id !== id));\n setIsDirty(true);\n }, []);\n\n const markAsSaved = useCallback(() => {\n setIsDirty(false);\n }, []);\n\n // Memoized context value\n const value = useMemo<FormBuilderContextValue>(\n () => ({\n // State\n fields,\n selectedFieldId,\n activeTab,\n isDirty,\n formData,\n settings,\n notifications,\n // Actions\n setFields,\n addField,\n updateField,\n deleteField,\n moveField,\n duplicateField,\n selectField,\n setActiveTab,\n updateFormData,\n updateSettings,\n addNotification,\n updateNotification,\n deleteNotification,\n markAsSaved,\n }),\n [\n fields,\n selectedFieldId,\n activeTab,\n isDirty,\n formData,\n settings,\n notifications,\n setFields,\n addField,\n updateField,\n deleteField,\n moveField,\n duplicateField,\n selectField,\n updateFormData,\n updateSettings,\n addNotification,\n updateNotification,\n deleteNotification,\n markAsSaved,\n ]\n );\n\n return (\n <FormBuilderContext.Provider value={value}>\n {children}\n </FormBuilderContext.Provider>\n );\n}\n\n// ============================================================================\n// Hooks\n// ============================================================================\n\n/**\n * useFormBuilder - Access form builder context\n *\n * Hook to access form builder state and actions from within the builder UI.\n * Must be used within a FormBuilderProvider.\n *\n * @returns Form builder context value\n * @throws Error if used outside of FormBuilderProvider\n *\n * @example\n * ```tsx\n * function FieldList() {\n * const { fields, selectField, deleteField } = useFormBuilder();\n *\n * return (\n * <ul>\n * {fields.map(field => (\n * <li key={field.name} onClick={() => selectField(field.name)}>\n * {field.label}\n * <button onClick={() => deleteField(field.name)}>Delete</button>\n * </li>\n * ))}\n * </ul>\n * );\n * }\n * ```\n */\nexport function useFormBuilder(): FormBuilderContextValue {\n const context = useContext(FormBuilderContext);\n\n if (!context) {\n throw new Error(\"useFormBuilder must be used within a FormBuilderProvider\");\n }\n\n return context;\n}\n\n/**\n * useOptionalFormBuilder - Access form builder context safely\n *\n * Like useFormBuilder but returns null if not within a provider.\n * Useful for components that may be rendered outside of the form builder.\n *\n * @returns Form builder context value or null\n */\nexport function useOptionalFormBuilder(): FormBuilderContextValue | null {\n return useContext(FormBuilderContext);\n}\n","/**\n * Form Canvas\n *\n * Drop zone where form fields are arranged and can be reordered.\n * Styled to match the Collection Builder's FieldList:\n * - Full-width horizontal rows\n * - Blue icon boxes (matching FieldPalette items)\n * - GripVertical drag handle on the left\n * - Type badge + Required badge on the right\n * - Dashed-border empty state\n *\n * @module admin/components/builder/FormCanvas\n * @since 0.1.0\n */\n\n\"use client\";\n\nimport { useDroppable } from \"@dnd-kit/core\";\nimport { useSortable } from \"@dnd-kit/sortable\";\nimport { CSS } from \"@dnd-kit/utilities\";\n\nimport type { FormField } from \"../../../types\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface FormCanvasProps {\n fields: FormField[];\n selectedFieldId: string | null;\n onFieldSelect: (fieldName: string | null) => void;\n onFieldDelete: (fieldName: string) => void;\n}\n\n// ============================================================================\n// Field Type Icon SVG paths (inline Lucide-compatible)\n// ============================================================================\n\nconst FIELD_ICON_PATHS: Record<string, string> = {\n text: \"M4 7h16M4 12h16M4 17h10\",\n email:\n \"M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z\",\n number: \"M7 20l4-16m2 16l4-16M6 9h14M4 15h14\",\n phone:\n \"M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498A1 1 0 0121 15.72V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z\",\n url: \"M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1\",\n textarea: \"M4 6h16M4 12h16M4 18h7\",\n select: \"M8 9l4-4 4 4m0 6l-4 4-4-4\",\n checkbox: \"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z\",\n radio:\n \"M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-6a4 4 0 100-8 4 4 0 000 8z\",\n file: \"M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13\",\n date: \"M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z\",\n time: \"M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z\",\n hidden:\n \"M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21\",\n};\n\nconst DEFAULT_ICON_PATH = \"M4 7h16M4 12h16M4 17h10\";\n\nconst FIELD_TYPE_LABELS: Record<string, string> = {\n text: \"Text\",\n email: \"Email\",\n number: \"Number\",\n phone: \"Phone\",\n url: \"URL\",\n textarea: \"Textarea\",\n select: \"Dropdown\",\n checkbox: \"Checkbox\",\n radio: \"Radio\",\n file: \"File Upload\",\n date: \"Date\",\n time: \"Time\",\n hidden: \"Hidden\",\n};\n\n// ============================================================================\n// SortableFieldItem — Full-width horizontal row (mirrors FieldList)\n// ============================================================================\n\nfunction SortableFieldItem({\n field,\n isSelected,\n onSelect,\n onDelete,\n}: {\n field: FormField;\n isSelected: boolean;\n onSelect: () => void;\n onDelete: () => void;\n}) {\n const {\n attributes,\n listeners,\n setNodeRef,\n transform,\n transition,\n isDragging,\n } = useSortable({ id: field.name });\n\n const style = {\n transform: CSS.Transform.toString(transform),\n transition,\n };\n\n const iconPath = FIELD_ICON_PATHS[field.type] || DEFAULT_ICON_PATH;\n const typeLabel = FIELD_TYPE_LABELS[field.type] || field.type;\n\n return (\n <div\n ref={setNodeRef}\n style={style}\n onClick={onSelect}\n role=\"button\"\n tabIndex={0}\n onKeyDown={e => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onSelect();\n }\n }}\n className={`flex items-center gap-3 py-3 px-4 border border-solid rounded-none cursor-pointer transition-all duration-150 group outline-none focus:outline-none focus:ring-0 ${\n isSelected\n ? \"bg-transparent dark:bg-transparent shadow-none ring-0\"\n : \"border-primary/5 dark:border-primary/5 dark:bg-transparent dark:hover:bg-transparent\"\n } ${isDragging ? \"opacity-50\" : \"\"}`}\n >\n {/* Drag Handle — GripVertical */}\n <button\n type=\"button\"\n className=\"p-1 shrink-0 cursor-grab active:cursor-grabbing text-muted-foreground/30 hover:text-muted-foreground transition-colors\"\n aria-label={`Drag to reorder ${field.label || field.name}`}\n onClick={e => e.stopPropagation()}\n {...attributes}\n {...listeners}\n >\n <svg\n className=\"h-4 w-4\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n {/* GripVertical dots */}\n <circle cx=\"9\" cy=\"5\" r=\"1\" fill=\"currentColor\" />\n <circle cx=\"9\" cy=\"12\" r=\"1\" fill=\"currentColor\" />\n <circle cx=\"9\" cy=\"19\" r=\"1\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"5\" r=\"1\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"12\" r=\"1\" fill=\"currentColor\" />\n <circle cx=\"15\" cy=\"19\" r=\"1\" fill=\"currentColor\" />\n </svg>\n </button>\n\n {/* Field type icon box — blue, matches FieldPalette */}\n <div\n className=\"shrink-0 flex items-center justify-center w-9 h-9 bg-primary/5 text-primary dark:bg-primary/20 dark:text-white mr-1\"\n style={{\n borderRadius: \"6px\",\n border: \"1px solid hsl(var(--primary) / 0.25)\",\n }}\n >\n <svg\n className=\"h-4 w-4\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.75\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d={iconPath} />\n </svg>\n </div>\n\n {/* Field info */}\n <div className=\"flex-1 flex items-center gap-2 min-w-0 flex-wrap\">\n <span className=\"text-sm font-medium text-foreground truncate\">\n {field.label || field.name || \"Unnamed Field\"}\n </span>\n <span className=\"text-muted-foreground/40 text-xs shrink-0\">•</span>\n <span className=\"text-[10px] font-medium shrink-0 px-2 py-0 leading-5 rounded-full border border-primary/5 bg-primary/5 text-muted-foreground capitalize\">\n {typeLabel}\n </span>\n {field.required && (\n <span className=\"text-[10px] px-2 py-0 leading-5 bg-red-50 text-red-600 dark:bg-red-500/20 dark:text-red-400 font-normal rounded-full border border-red-200 dark:border-red-500/30 shrink-0\">\n Required\n </span>\n )}\n </div>\n\n {/* Delete button — visible on hover */}\n <button\n type=\"button\"\n onClick={e => {\n e.stopPropagation();\n onDelete();\n }}\n title={`Delete ${field.label || field.name}`}\n aria-label={`Delete ${field.label || field.name}`}\n className=\"shrink-0 flex items-center justify-center w-7 h-7 rounded-none text-muted-foreground/40 hover:text-destructive hover:bg-destructive/10 transition-all duration-150 opacity-0 group-hover:opacity-100\"\n >\n <svg\n className=\"h-3.5 w-3.5\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <polyline points=\"3 6 5 6 21 6\" />\n <path d=\"M19 6v14a2 2 0 01-2 2H7a2 2 0 01-2-2V6m3 0V4a1 1 0 011-1h4a1 1 0 011 1v2\" />\n </svg>\n </button>\n </div>\n );\n}\n\n// ============================================================================\n// FormCanvas Component\n// ============================================================================\n\nexport function FormCanvas({\n fields,\n selectedFieldId,\n onFieldSelect,\n onFieldDelete,\n}: FormCanvasProps) {\n const { setNodeRef, isOver } = useDroppable({\n id: \"canvas-drop-zone\",\n });\n\n // Empty state — dashed border, centred icon + text (mirrors Collection Builder)\n if (fields.length === 0) {\n return (\n <div\n ref={setNodeRef}\n id=\"canvas-drop-zone\"\n className={`min-h-[320px] flex flex-col items-center justify-center border-2 border-dashed rounded-none transition-all duration-200 ${\n isOver ? \"border-primary bg-primary/5\" : \"border-primary/5 bg-primary/5/20\"\n }`}\n >\n <div className=\"text-center px-6 py-12\">\n {/* Arrow-down icon */}\n <div\n className={`mx-auto mb-4 flex items-center justify-center w-12 h-12 rounded-none border transition-colors ${\n isOver\n ? \"border-primary/30 bg-primary/5 text-primary\"\n : \"border-primary/5 bg-primary/5 text-muted-foreground/40\"\n }`}\n >\n <svg\n className=\"h-5 w-5\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <polyline points=\"19 12 12 19 5 12\" />\n </svg>\n </div>\n <p\n className={`text-sm font-medium mb-1 ${\n isOver ? \"text-primary\" : \"text-foreground\"\n }`}\n >\n {isOver ? \"Release to add field\" : \"No fields yet\"}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {isOver\n ? \"Drop the field here\"\n : \"Drag a field from the panel on the right to add it here\"}\n </p>\n </div>\n </div>\n );\n }\n\n // Fields present\n return (\n <div\n ref={setNodeRef}\n className={`min-h-[120px] transition-all duration-200 ${\n isOver ? \"bg-primary/5 rounded-none\" : \"\"\n }`}\n >\n {/* Field rows */}\n <div className=\"space-y-2\">\n {fields.map(field => (\n <SortableFieldItem\n key={field.name}\n field={field}\n isSelected={selectedFieldId === field.name}\n onSelect={() => onFieldSelect(field.name)}\n onDelete={() => onFieldDelete(field.name)}\n />\n ))}\n </div>\n\n {/* Drop-here strip at bottom when dragging */}\n {isOver && (\n <div className=\"mt-2 flex items-center justify-center py-3 rounded-none border-2 border-dashed border-primary bg-primary/5\">\n <p className=\"text-xs font-medium text-primary\">\n Release to add field here\n </p>\n </div>\n )}\n </div>\n );\n}\n\nexport default FormCanvas;\n","\"use client\";\n\n/**\n * Form Notifications Tab\n *\n * Email integration configuration panel for form submissions.\n * Allows selecting existing email providers and templates for notifications.\n *\n * @module admin/components/builder/FormNotificationsTab\n * @since 0.1.0\n */\n\n\"use client\";\n\nimport { Button, Input } from \"@nextlyhq/ui\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport {\n useFormBuilder,\n createNotification,\n type FormNotification,\n} from \"../../context/FormBuilderContext\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\ninterface ProviderOption {\n id: string;\n name: string;\n type: string;\n isDefault: boolean;\n}\n\ninterface TemplateOption {\n id: string;\n name: string;\n slug: string;\n isActive: boolean;\n}\n\n// ============================================================================\n// API helpers\n// ============================================================================\n\nasync function fetchProviders(): Promise<ProviderOption[]> {\n try {\n const res = await fetch(\"/admin/api/email-providers?pageSize=100&page=1\", {\n credentials: \"include\",\n });\n if (!res.ok) return [];\n const json = (await res.json()) as { providers?: ProviderOption[] };\n return json.providers ?? [];\n } catch {\n return [];\n }\n}\n\nasync function fetchTemplates(): Promise<TemplateOption[]> {\n try {\n const res = await fetch(\"/admin/api/email-templates\", {\n credentials: \"include\",\n });\n if (!res.ok) return [];\n const json = (await res.json()) as { templates?: TemplateOption[] };\n return json.templates ?? [];\n } catch {\n return [];\n }\n}\n\n// ============================================================================\n// Integration Card\n// ============================================================================\n\ninterface IntegrationCardProps {\n notification: FormNotification;\n providerName: string;\n onEdit: () => void;\n onDelete: () => void;\n}\n\nfunction IntegrationCard({\n notification,\n providerName,\n onEdit,\n onDelete,\n}: IntegrationCardProps) {\n return (\n <div\n className={`form-integration-card ${!notification.enabled ? \"form-integration-card--disabled\" : \"\"}`}\n >\n <div className=\"form-integration-card-left\">\n <div className=\"form-integration-card-info\">\n <span className=\"form-integration-card-name\">\n {notification.name}\n </span>\n <span className=\"form-integration-provider-badge\">\n Provider: {providerName}\n </span>\n </div>\n </div>\n <div className=\"form-integration-card-actions\">\n <button\n type=\"button\"\n className=\"form-integration-btn form-integration-btn--edit\"\n onClick={onEdit}\n >\n Edit\n </button>\n <button\n type=\"button\"\n className=\"form-integration-btn form-integration-btn--delete\"\n onClick={onDelete}\n >\n Delete\n </button>\n </div>\n </div>\n );\n}\n\n// ============================================================================\n// Integration Modal\n// ============================================================================\n\ninterface IntegrationModalProps {\n initial: FormNotification;\n providers: ProviderOption[];\n templates: TemplateOption[];\n fields: { name: string; label: string }[];\n isEditing: boolean;\n onSave: (notification: FormNotification) => void;\n onCancel: () => void;\n}\n\nfunction IntegrationModal({\n initial,\n providers,\n templates,\n fields,\n isEditing,\n onSave,\n onCancel,\n}: IntegrationModalProps) {\n const [form, setForm] = useState<FormNotification>(initial);\n const [newCc, setNewCc] = useState(\"\");\n const [newBcc, setNewBcc] = useState(\"\");\n const overlayRef = useRef<HTMLDivElement>(null);\n\n const update = useCallback(\n <K extends keyof FormNotification>(key: K, value: FormNotification[K]) => {\n setForm(prev => ({ ...prev, [key]: value }));\n },\n []\n );\n\n const addCc = useCallback(() => {\n const email = newCc.trim();\n if (!email) return;\n setForm(prev => ({ ...prev, cc: [...prev.cc, email] }));\n setNewCc(\"\");\n }, [newCc]);\n\n const removeCc = useCallback((index: number) => {\n setForm(prev => ({ ...prev, cc: prev.cc.filter((_, i) => i !== index) }));\n }, []);\n\n const addBcc = useCallback(() => {\n const email = newBcc.trim();\n if (!email) return;\n setForm(prev => ({ ...prev, bcc: [...prev.bcc, email] }));\n setNewBcc(\"\");\n }, [newBcc]);\n\n const removeBcc = useCallback((index: number) => {\n setForm(prev => ({ ...prev, bcc: prev.bcc.filter((_, i) => i !== index) }));\n }, []);\n\n const handleSubmit = useCallback(() => {\n onSave(form);\n }, [form, onSave]);\n\n const handleOverlayClick = useCallback(\n (e: React.MouseEvent) => {\n if (e.target === overlayRef.current) {\n onCancel();\n }\n },\n [onCancel]\n );\n\n const defaultProvider = providers.find(p => p.isDefault);\n const defaultLabel = defaultProvider\n ? `System Default (${defaultProvider.name})`\n : \"System Default\";\n\n return (\n <div\n className=\"fixed inset-0 z-50 bg-background/80 backdrop-blur-sm flex items-center justify-center p-4 sm:p-6\"\n ref={overlayRef}\n onClick={handleOverlayClick}\n >\n <div className=\"bg-background rounded-none border border-primary/5 shadow-md w-full max-w-lg overflow-hidden flex flex-col max-h-[90vh]\">\n <div className=\"px-6 py-5 border-b border-primary/5 flex items-center justify-between sticky top-0 bg-background z-10\">\n <h3 className=\"text-lg font-semibold text-foreground\">\n {isEditing ? \"Edit Email Integration\" : \"Add Email Integration\"}\n </h3>\n <button\n onClick={onCancel}\n className=\"text-muted-foreground hover:text-foreground\"\n >\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n </div>\n\n <div className=\"p-6 overflow-y-auto space-y-6\">\n {/* Integration Name */}\n <div className=\"space-y-1.5\">\n <label className=\"text-sm font-medium text-foreground\">\n Integration Name\n </label>\n <Input\n type=\"text\"\n value={form.name}\n onChange={e => update(\"name\", e.target.value)}\n placeholder=\"e.g. Admin Notification\"\n />\n </div>\n\n {/* Email Provider & Template */}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n <div className=\"space-y-1.5\">\n <label className=\"text-sm font-medium text-foreground\">\n Email Provider\n </label>\n <select\n className=\"flex h-9 w-full rounded-none border border-input bg-transparent px-3 py-1 text-sm shadow-none focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n value={form.providerId ?? \"\"}\n onChange={e =>\n update(\"providerId\", e.target.value || undefined)\n }\n >\n <option value=\"\">{defaultLabel}</option>\n {providers.map(p => (\n <option key={p.id} value={p.id}>\n {p.name}\n {p.isDefault ? \" (Default)\" : \"\"}\n </option>\n ))}\n </select>\n </div>\n\n <div className=\"space-y-1.5\">\n <label className=\"text-sm font-medium text-foreground\">\n Email Template\n </label>\n <select\n className=\"flex h-9 w-full rounded-none border border-input bg-transparent px-3 py-1 text-sm shadow-none focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n value={form.templateSlug ?? \"\"}\n onChange={e =>\n update(\"templateSlug\", e.target.value || undefined)\n }\n >\n <option value=\"\">Select an email template</option>\n {templates\n .filter(t => t.isActive)\n .map(t => (\n <option key={t.id} value={t.slug}>\n {t.name}\n </option>\n ))}\n </select>\n </div>\n </div>\n\n {/* Sender Email */}\n <div className=\"space-y-1.5\">\n <label className=\"text-sm font-medium text-foreground\">\n Sender Email\n </label>\n <Input\n type=\"email\"\n value={form.senderEmail ?? \"\"}\n onChange={e => update(\"senderEmail\", e.target.value || undefined)}\n placeholder=\"noreply@example.com\"\n />\n <p className=\"text-xs text-muted-foreground\">\n Leave blank to use the provider's default configured address.\n </p>\n </div>\n\n {/* Recipient Configuration */}\n <div className=\"space-y-4 pt-4 border-t border-primary/5\">\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n <div className=\"space-y-1.5\">\n <label className=\"text-sm font-medium text-foreground\">\n Recipient Type\n </label>\n <select\n className=\"flex h-9 w-full rounded-none border border-input bg-transparent px-3 py-1 text-sm shadow-none focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n value={form.recipientType}\n onChange={e =>\n update(\n \"recipientType\",\n e.target.value as \"static\" | \"field\"\n )\n }\n >\n <option value=\"static\">Static Email Address</option>\n <option value=\"field\">Email from Form Field</option>\n </select>\n </div>\n\n <div className=\"space-y-1.5\">\n <label className=\"text-sm font-medium text-foreground\">\n {form.recipientType === \"field\"\n ? \"Target Email Field\"\n : \"Recipient Email\"}\n </label>\n {form.recipientType === \"field\" ? (\n <select\n className=\"flex h-9 w-full rounded-none border border-input bg-transparent px-3 py-1 text-sm shadow-none focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\n value={form.to}\n onChange={e => update(\"to\", e.target.value)}\n >\n <option value=\"\">Select a field</option>\n {fields.map(f => (\n <option key={f.name} value={`{{${f.name}}}`}>\n {f.label} ({`{{${f.name}}}`})\n </option>\n ))}\n </select>\n ) : (\n <Input\n type=\"email\"\n value={form.to}\n onChange={e => update(\"to\", e.target.value)}\n placeholder=\"admin@example.com\"\n />\n )}\n </div>\n </div>\n\n {/* CC Recipients */}\n <div className=\"space-y-1.5\">\n <label className=\"text-sm font-medium text-foreground\">\n CC Recipients (Optional)\n </label>\n {form.cc.length > 0 && (\n <div className=\"flex flex-wrap gap-2 mb-2\">\n {form.cc.map((email, i) => (\n <div\n key={i}\n className=\"inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-primary/5 text-xs font-medium border border-primary/5\"\n >\n <span>{email}</span>\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:text-foreground hover:bg-background rounded-full p-0.5\"\n onClick={() => removeCc(i)}\n >\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n </div>\n ))}\n </div>\n )}\n <div className=\"flex items-center gap-2\">\n <Input\n type=\"email\"\n value={newCc}\n onChange={e => setNewCc(e.target.value)}\n onKeyDown={e => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n addCc();\n }\n }}\n placeholder=\"cc@example.com\"\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={addCc}\n className=\"shrink-0 px-3\"\n >\n Add CC\n </Button>\n </div>\n </div>\n\n {/* BCC Recipients */}\n <div className=\"space-y-1.5\">\n <label className=\"text-sm font-medium text-foreground\">\n BCC Recipients (Optional)\n </label>\n {form.bcc.length > 0 && (\n <div className=\"flex flex-wrap gap-2 mb-2\">\n {form.bcc.map((email, i) => (\n <div\n key={i}\n className=\"inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-primary/5 text-xs font-medium border border-primary/5\"\n >\n <span>{email}</span>\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:text-foreground hover:bg-background rounded-full p-0.5\"\n onClick={() => removeBcc(i)}\n >\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n </div>\n ))}\n </div>\n )}\n <div className=\"flex items-center gap-2\">\n <Input\n type=\"email\"\n value={newBcc}\n onChange={e => setNewBcc(e.target.value)}\n onKeyDown={e => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n addBcc();\n }\n }}\n placeholder=\"bcc@example.com\"\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={addBcc}\n className=\"shrink-0 px-3\"\n >\n Add BCC\n </Button>\n </div>\n </div>\n </div>\n\n <div className=\"pt-4 border-t border-primary/5 flex items-center justify-between\">\n <div>\n <label className=\"text-sm font-medium text-foreground\">\n Enable Integration\n </label>\n <p className=\"text-xs text-muted-foreground\">\n Toggle to turn on/off without removing.\n </p>\n </div>\n <label className=\"relative inline-flex items-center cursor-pointer\">\n <input\n type=\"checkbox\"\n className=\"sr-only peer\"\n checked={form.enabled}\n onChange={e => update(\"enabled\", e.target.checked)}\n />\n <div className=\"w-9 h-5 bg-primary/5 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-primary/20 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-primary/5 after:border after:rounded-full after:h-4 after:w-4 after:transition-all peer-checked:bg-primary border border-primary/5\"></div>\n </label>\n </div>\n </div>\n\n <div className=\"px-6 py-4 border-t border-primary/5 bg-primary/5/20 flex items-center justify-end gap-3 rounded-b-xl\">\n <Button type=\"button\" variant=\"outline\" onClick={onCancel}>\n Cancel\n </Button>\n <Button type=\"button\" onClick={handleSubmit}>\n {isEditing ? \"Save Changes\" : \"Add Integration\"}\n </Button>\n </div>\n </div>\n </div>\n );\n}\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\n/**\n * FormNotificationsTab - Email integrations configuration\n *\n * Allows users to configure email integrations that trigger when a form is\n * submitted. Each integration references an existing email provider and\n * template rather than duplicating provider credentials.\n */\nexport function FormNotificationsTab() {\n const {\n notifications,\n fields,\n addNotification,\n updateNotification,\n deleteNotification,\n } = useFormBuilder();\n\n const [providers, setProviders] = useState<ProviderOption[]>([]);\n const [templates, setTemplates] = useState<TemplateOption[]>([]);\n const [modalState, setModalState] = useState<{\n open: boolean;\n editing: FormNotification | null;\n }>({ open: false, editing: null });\n\n useEffect(() => {\n void fetchProviders().then(setProviders);\n void fetchTemplates().then(setTemplates);\n }, []);\n\n const fieldList = fields.map(f => ({ name: f.name, label: f.label }));\n\n const openAddModal = useCallback(() => {\n setModalState({ open: true, editing: null });\n }, []);\n\n const openEditModal = useCallback((notification: FormNotification) => {\n setModalState({ open: true, editing: notification });\n }, []);\n\n const closeModal = useCallback(() => {\n setModalState({ open: false, editing: null });\n }, []);\n\n const handleSave = useCallback(\n (notification: FormNotification) => {\n if (modalState.editing) {\n updateNotification(notification.id, notification);\n } else {\n addNotification(notification);\n }\n closeModal();\n },\n [modalState.editing, addNotification, updateNotification, closeModal]\n );\n\n const getProviderName = useCallback(\n (providerId?: string) => {\n if (!providerId) {\n const def = providers.find(p => p.isDefault);\n return def ? `${def.name} (Default)` : \"System Default\";\n }\n return providers.find(p => p.id === providerId)?.name ?? \"Unknown\";\n },\n [providers]\n );\n\n const initialNotification = modalState.editing ?? createNotification();\n\n return (\n <div className=\"form-notifications-tab\">\n <div className=\"flex items-center justify-between mb-8 pb-4 border-b border-primary/5\">\n <div>\n <h3 className=\"text-xl font-semibold text-foreground\">\n Email Integrations\n </h3>\n <p className=\"text-sm text-muted-foreground mt-1\">\n Configure email notifications sent when someone submits this form.\n </p>\n </div>\n <Button type=\"button\" onClick={openAddModal}>\n + Add Integration\n </Button>\n </div>\n\n {/* List */}\n {notifications.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center p-12 mt-6 border-2 border-dashed border-primary/5 rounded-none bg-primary/5/20\">\n <div className=\"flex items-center justify-center w-12 h-12 rounded-none border border-primary/5 bg-background mb-4 text-primary\">\n <svg\n className=\"h-6 w-6\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect x=\"2\" y=\"4\" width=\"20\" height=\"16\" rx=\"2\" />\n <path d=\"Mm22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7\" />\n </svg>\n </div>\n <p className=\"text-base font-medium text-foreground mb-1\">\n No email integrations yet\n </p>\n <p className=\"text-sm text-muted-foreground mb-6 text-center max-w-sm\">\n Add an email integration to notify recipients when someone submits\n this form.\n </p>\n <Button type=\"button\" onClick={openAddModal}>\n + Add Integration\n </Button>\n </div>\n ) : (\n <div className=\"form-notifications-list\">\n {notifications.map(notification => (\n <IntegrationCard\n key={notification.id}\n notification={notification}\n providerName={getProviderName(notification.providerId)}\n onEdit={() => openEditModal(notification)}\n onDelete={() => deleteNotification(notification.id)}\n />\n ))}\n </div>\n )}\n\n {/* Modal */}\n {modalState.open && (\n <IntegrationModal\n initial={initialNotification}\n providers={providers}\n templates={templates}\n fields={fieldList}\n isEditing={!!modalState.editing}\n onSave={handleSave}\n onCancel={closeModal}\n />\n )}\n </div>\n );\n}\n\nexport default FormNotificationsTab;\n","/**\n * Form Preview\n *\n * Renders a preview of how the form will appear to end users.\n * Shows the form layout with input fields rendered in a disabled\n * (read-only) state so submissions cannot be made from the preview.\n *\n * @module admin/components/builder/FormPreview\n * @since 0.1.0\n */\n\n\"use client\";\n\nimport { Input, Button } from \"@nextlyhq/ui\";\nimport type React from \"react\";\n\nimport type { FormField } from \"../../../types\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface FormPreviewProps {\n /** Array of form fields to preview */\n fields: FormField[];\n /** Form metadata */\n formData?: {\n name?: string;\n slug?: string;\n description?: string;\n status?: string;\n };\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * FormPreview - Visual form preview\n *\n * This is a stub component that shows a preview of the form.\n * The full implementation will include:\n * - Rendered form fields with proper styling\n * - Responsive preview modes (desktop, tablet, mobile)\n * - Theme preview options\n * - Conditional logic simulation\n *\n * @example\n * ```tsx\n * <FormPreview fields={fields} formData={formData} />\n * ```\n */\nexport function FormPreview({ fields, formData }: FormPreviewProps) {\n if (fields.length === 0) {\n return (\n <div className=\"flex flex-col items-center justify-center p-12 bg-primary/5/20 rounded-none border-2 border-dashed border-primary/5 text-center\">\n <div className=\"text-4xl mb-3\">📝</div>\n <p className=\"text-sm font-medium text-muted-foreground\">\n Add some fields to preview your form\n </p>\n </div>\n );\n }\n\n return (\n <div className=\"bg-background max-w-2xl mt-8\">\n <div className=\"mb-8\">\n <h2 className=\"text-2xl font-bold text-foreground\">\n {formData?.name || \"Untitled Form\"}\n </h2>\n {formData?.description && (\n <p className=\"text-sm text-muted-foreground mt-2\">\n {formData.description}\n </p>\n )}\n </div>\n\n <div className=\"space-y-6\">\n {fields.map(field => (\n <div key={field.name} className=\"flex flex-col gap-1.5\">\n <label className=\"text-sm font-medium text-foreground\">\n {field.label}\n {field.required && (\n <span className=\"text-destructive ml-1\">*</span>\n )}\n </label>\n\n {renderFieldPreview(field)}\n\n {field.helpText && (\n <p className=\"text-xs text-muted-foreground mt-1\">\n {field.helpText}\n </p>\n )}\n </div>\n ))}\n </div>\n\n <div className=\"mt-8 pt-6 border-t border-primary/5 flex items-center gap-4\">\n <Button type=\"button\" disabled>\n Submit\n </Button>\n <p className=\"text-xs text-muted-foreground\">\n This is a preview. Submissions are disabled.\n </p>\n </div>\n </div>\n );\n}\n\n/**\n * Render a preview of a field based on its type\n */\nfunction renderFieldPreview(field: FormField): React.ReactNode {\n switch (field.type) {\n case \"text\":\n case \"email\":\n case \"phone\":\n case \"url\":\n return (\n <Input\n type={field.type === \"email\" ? \"email\" : \"text\"}\n placeholder={\n field.placeholder || `Enter ${field.label.toLowerCase()}`\n }\n disabled\n />\n );\n\n case \"number\":\n return (\n <Input\n type=\"number\"\n placeholder={field.placeholder || \"Enter a number\"}\n disabled\n />\n );\n\n case \"textarea\":\n return (\n <textarea\n className=\"flex w-full rounded-none border border-input bg-transparent px-3 py-2 text-sm shadow-none placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\"\n placeholder={\n field.placeholder || `Enter ${field.label.toLowerCase()}`\n }\n rows={field.rows || 4}\n disabled\n />\n );\n\n case \"select\":\n return (\n <select\n className=\"flex h-9 w-full items-center justify-between rounded-none border border-input bg-transparent px-3 py-2 text-sm shadow-none focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50\"\n disabled\n >\n <option value=\"\">Select an option</option>\n {field.options?.map(opt => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n );\n\n case \"checkbox\":\n return (\n <div className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n className=\"h-4 w-4 rounded border-input text-primary focus:ring-primary\"\n disabled\n />\n <span className=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\">\n {field.label}\n </span>\n </div>\n );\n\n case \"radio\":\n return (\n <div className=\"flex flex-col space-y-2\">\n {field.options?.map(opt => (\n <div key={opt.value} className=\"flex items-center space-x-2\">\n <input\n type=\"radio\"\n name={field.name}\n className=\"h-4 w-4 rounded-full border border-input text-primary focus:ring-primary\"\n disabled\n />\n <span className=\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\">\n {opt.label}\n </span>\n </div>\n ))}\n </div>\n );\n\n case \"file\":\n return (\n <div className=\"flex items-center\">\n <Input type=\"file\" disabled />\n </div>\n );\n\n case \"date\":\n return <Input type=\"date\" disabled />;\n\n case \"time\":\n return <Input type=\"time\" disabled />;\n\n case \"hidden\":\n return (\n <div className=\"flex items-center gap-2 p-3 text-sm text-muted-foreground bg-primary/5/20 border-2 border-dashed border-primary/5 rounded-none\">\n <span className=\"text-lg\">👁️</span>\n <span>Hidden field</span>\n </div>\n );\n\n default:\n return <Input type=\"text\" placeholder=\"Unknown field type\" disabled />;\n }\n}\n\nexport default FormPreview;\n","\"use client\";\n\nimport {\n Input,\n Textarea,\n Tabs,\n TabsList,\n TabsTrigger,\n Switch,\n} from \"@nextlyhq/ui\";\nimport type React from \"react\";\n\nimport { useFormBuilder } from \"../../context/FormBuilderContext\";\n\n// ============================================================================\n// Helper Components\n// ============================================================================\n\n/**\n * SettingRow - A layout component for a single setting with label and description on the left,\n * and the control/input on the right.\n */\nfunction SettingRow({\n label,\n description,\n children,\n className = \"\",\n}: {\n label: string;\n description?: string;\n children: React.ReactNode;\n className?: string;\n}) {\n return (\n <div\n className={`flex flex-col sm:flex-row sm:items-center justify-between gap-6 py-2 ${className}`}\n >\n <div className=\"space-y-1 max-w-xl\">\n <h4 className=\"text-[13px] font-semibold text-foreground tracking-tight\">\n {label}\n </h4>\n {description && (\n <p className=\"text-[12px] text-muted-foreground leading-relaxed\">\n {description}\n </p>\n )}\n </div>\n <div className=\"flex-shrink-0 flex items-center justify-end min-w-[100px]\">\n {children}\n </div>\n </div>\n );\n}\n\n/**\n * FormSettingsTab - Form settings configuration panel\n *\n * Refined for Antigravity standard:\n * - Two-column layout for better space utilization.\n * - Title Case headings with improved hierarchy.\n * - Robust state management for action tabs.\n */\nexport function FormSettingsTab() {\n const { settings, updateSettings } = useFormBuilder();\n\n // Handle tab switch for After Submission\n // We check for undefined specifically so empty strings \"\" are treated as \"redirect\"\n const currentActionTab =\n settings.redirectUrl !== undefined ? \"redirect\" : \"message\";\n\n return (\n <div className=\"w-full flex flex-row gap-8\">\n {/* Left Column: Submission & After Submission */}\n <div className=\"w-full flex flex-col gap-8\">\n {/* Submission Settings */}\n <section className=\"mb-12\">\n <div className=\"border-b border-primary/5 pb-3\">\n <h3 className=\"text-[16px] font-bold text-foreground tracking-tight\">\n Submission Settings\n </h3>\n </div>\n\n <div className=\"flex flex-col gap-1\">\n <SettingRow\n label=\"Submit Button Text\"\n description=\"Label on the primary action button\"\n >\n <Input\n type=\"text\"\n value={settings.submitButtonText}\n onChange={e =>\n updateSettings({ submitButtonText: e.target.value })\n }\n placeholder=\"Submit\"\n className=\"bg-transparent h-8 w-40 text-right pr-2 focus-visible:ring-1 border-primary/5 text-[13px]\"\n />\n </SettingRow>\n\n <SettingRow\n label=\"Show Reset Button\"\n description=\"Lets users clear all fields at once\"\n >\n <Switch\n checked={settings.showResetButton}\n onCheckedChange={(checked: boolean) =>\n updateSettings({ showResetButton: checked })\n }\n />\n </SettingRow>\n\n {settings.showResetButton && (\n <SettingRow\n label=\"Reset Button Text\"\n description=\"Label on the secondary action button\"\n className=\"animate-in fade-in slide-in-from-top-2 duration-300\"\n >\n <Input\n type=\"text\"\n value={settings.resetButtonText}\n onChange={e =>\n updateSettings({ resetButtonText: e.target.value })\n }\n placeholder=\"Reset\"\n className=\"bg-transparent h-8 w-40 text-right pr-2 focus-visible:ring-1 border-primary/5 text-[13px]\"\n />\n </SettingRow>\n )}\n </div>\n </section>\n\n {/* After Submission */}\n <section className=\"mb-12\">\n <div className=\"border-b border-primary/5 pb-3\">\n <h3 className=\"text-[16px] font-bold text-foreground tracking-tight\">\n After Submission\n </h3>\n </div>\n\n <div className=\"flex flex-col gap-4\">\n <SettingRow\n label=\"Action\"\n description=\"What happens after the form is submitted\"\n >\n <Tabs\n value={currentActionTab}\n onValueChange={v => {\n if (v === \"message\") {\n updateSettings({ redirectUrl: undefined });\n } else if (v === \"redirect\") {\n updateSettings({ redirectUrl: \"\" });\n }\n }}\n >\n <TabsList className=\"bg-primary/5 p-1 h-8\">\n <TabsTrigger\n value=\"message\"\n className=\"px-4 py-1 text-[11px] font-medium data-[state=active]:bg-background data-[state=active]:shadow-sm\"\n >\n Message\n </TabsTrigger>\n <TabsTrigger\n value=\"redirect\"\n className=\"px-4 py-1 text-[11px] font-medium data-[state=active]:bg-background data-[state=active]:shadow-sm\"\n >\n Redirect\n </TabsTrigger>\n </TabsList>\n </Tabs>\n </SettingRow>\n\n {currentActionTab === \"message\" ? (\n <div className=\"pt-2 animate-in fade-in duration-300\">\n <div className=\"space-y-1.5 mb-4\">\n <h4 className=\"text-[13px] font-semibold text-foreground tracking-tight\">\n Confirmation Message\n </h4>\n <p className=\"text-[12px] text-muted-foreground leading-relaxed\">\n Message shown to user after successful submission\n </p>\n </div>\n <Textarea\n id=\"confirmationMessage\"\n value={settings.confirmationMessage}\n onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) =>\n updateSettings({ confirmationMessage: e.target.value })\n }\n placeholder=\"Thank you for your submission!\"\n rows={4}\n className=\"bg-transparent text-[13px] leading-relaxed w-full border-primary/5 focus-visible:ring-1\"\n />\n </div>\n ) : (\n <div className=\"pt-2 animate-in fade-in duration-300\">\n <SettingRow\n label=\"Redirect URL\"\n description=\"User will be redirected to this URL after submission\"\n >\n <Input\n type=\"url\"\n value={settings.redirectUrl || \"\"}\n onChange={e =>\n updateSettings({ redirectUrl: e.target.value })\n }\n placeholder=\"https://example.com/thank-you\"\n className=\"bg-transparent h-8 w-56 text-right pr-2 focus-visible:ring-1 border-primary/5 text-[13px]\"\n />\n </SettingRow>\n </div>\n )}\n </div>\n </section>\n </div>\n\n {/* Right Column: Spam Protection & Data Storage */}\n <div className=\"w-full flex flex-col gap-8\">\n {/* Spam Protection */}\n <section>\n <div className=\"border-b border-primary/5 pb-3\">\n <h3 className=\"text-[16px] font-bold text-foreground tracking-tight\">\n Spam Protection\n </h3>\n </div>\n\n <div className=\"flex flex-col gap-1\">\n <SettingRow\n label=\"Honeypot Field\"\n description=\"Hidden field that silently catches bots\"\n >\n <Switch\n checked={settings.honeypotEnabled}\n onCheckedChange={(checkedValue: boolean) =>\n updateSettings({ honeypotEnabled: checkedValue })\n }\n />\n </SettingRow>\n\n <SettingRow\n label=\"CAPTCHA Challenge\"\n description=\"Human verification before submitting\"\n >\n <Switch\n checked={settings.captchaEnabled}\n onCheckedChange={(checkedValue: boolean) =>\n updateSettings({ captchaEnabled: checkedValue })\n }\n />\n </SettingRow>\n </div>\n </section>\n\n {/* Data Storage */}\n <section>\n <div className=\"border-b border-primary/5 pb-3\">\n <h3 className=\"text-[16px] font-bold text-foreground tracking-tight\">\n Data Storage\n </h3>\n </div>\n\n <div className=\"flex flex-col gap-1\">\n <SettingRow\n label=\"Store Submissions\"\n description=\"Save responses to the database\"\n >\n <Switch\n checked={settings.storeSubmissions}\n onCheckedChange={(checkedValue: boolean) =>\n updateSettings({ storeSubmissions: checkedValue })\n }\n />\n </SettingRow>\n\n <SettingRow\n label=\"Submission Limit\"\n description=\"Max number of entries to store\"\n >\n <div className=\"flex items-center gap-3\">\n <Input\n type=\"number\"\n value={settings.submissionLimit || \"\"}\n onChange={e =>\n updateSettings({\n submissionLimit: e.target.value\n ? parseInt(e.target.value, 10)\n : undefined,\n })\n }\n placeholder=\"Unlimited\"\n min={1}\n className=\"bg-transparent h-8 w-28 text-right pr-2 focus-visible:ring-1 border-primary/5 text-[13px]\"\n />\n <span className=\"text-[12px] text-muted-foreground font-medium\">\n Entries\n </span>\n </div>\n </SettingRow>\n </div>\n </section>\n </div>\n </div>\n );\n}\n\nexport default FormSettingsTab;\n","\"use client\";\n\n/**\n * Form Field List Component\n *\n * A sortable list container for form fields with drag-and-drop reordering.\n * Uses @dnd-kit for accessible drag-and-drop functionality.\n *\n * Features:\n * - Drag-and-drop reordering via @dnd-kit\n * - Keyboard-accessible drag operations (Arrow keys)\n * - PointerSensor with 8px activation distance (prevents accidental drags)\n * - Empty state display when no fields exist\n * - Visual feedback during drag operations\n *\n * This component provides the DndContext and SortableContext wrappers.\n * Individual field rows are rendered using SortableFieldRow which uses\n * the useSortable hook for drag-and-drop functionality.\n *\n * @module admin/components/FormFieldList\n * @since 0.1.0\n */\n\n\"use client\";\n\nimport {\n DndContext,\n closestCenter,\n KeyboardSensor,\n PointerSensor,\n useSensor,\n useSensors,\n type DragEndEvent,\n} from \"@dnd-kit/core\";\nimport {\n arrayMove,\n SortableContext,\n sortableKeyboardCoordinates,\n verticalListSortingStrategy,\n} from \"@dnd-kit/sortable\";\nimport { useCallback } from \"react\";\n\nimport type { FormField } from \"../../types\";\n\nimport { SortableFieldRow } from \"./SortableFieldRow\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface FormFieldListProps {\n /**\n * Array of form fields to display.\n */\n fields: FormField[];\n\n /**\n * Callback when fields are reordered via drag-and-drop.\n * Receives the new array with fields in updated order.\n */\n onFieldsChange: (fields: FormField[]) => void;\n\n /**\n * Callback when a field is selected for editing.\n * Receives the field name (unique identifier).\n */\n onEditField: (fieldName: string) => void;\n\n /**\n * Callback when a field should be deleted.\n * Receives the field name (unique identifier).\n */\n onDeleteField: (fieldName: string) => void;\n\n /**\n * Currently selected field name for highlighting.\n */\n selectedFieldName?: string | null;\n\n /**\n * Whether the list is disabled (no interactions allowed).\n * @default false\n */\n disabled?: boolean;\n}\n\n// ============================================================================\n// FormFieldList Component\n// ============================================================================\n\n/**\n * FormFieldList provides a drag-and-drop sortable container for form fields.\n *\n * This component wraps fields with DndContext and SortableContext from @dnd-kit,\n * enabling drag-and-drop reordering with full keyboard accessibility.\n *\n * The component follows the pattern established by ArrayInput.tsx in the\n * Nextly admin package:\n * - PointerSensor with 8px activation distance (prevents accidental drags)\n * - KeyboardSensor with sortableKeyboardCoordinates (arrow key navigation)\n * - closestCenter collision detection\n * - verticalListSortingStrategy for vertical lists\n *\n * @example\n * ```tsx\n * <FormFieldList\n * fields={formFields}\n * onFieldsChange={setFormFields}\n * onEditField={(name) => setSelectedField(name)}\n * onDeleteField={(name) => handleDeleteField(name)}\n * selectedFieldName={selectedField}\n * />\n * ```\n */\nexport function FormFieldList({\n fields,\n onFieldsChange,\n onEditField,\n onDeleteField,\n selectedFieldName,\n disabled = false,\n}: FormFieldListProps) {\n // ---------------------------------------------------------------------------\n // Sensor Setup\n // ---------------------------------------------------------------------------\n\n // PointerSensor: mouse/touch with 8px activation distance to prevent accidental drags\n // KeyboardSensor: Arrow keys for accessibility (WCAG 2.2 compliance)\n const sensors = useSensors(\n useSensor(PointerSensor, {\n activationConstraint: {\n distance: 8,\n },\n }),\n useSensor(KeyboardSensor, {\n coordinateGetter: sortableKeyboardCoordinates,\n })\n );\n\n // ---------------------------------------------------------------------------\n // Drag Handlers\n // ---------------------------------------------------------------------------\n\n /**\n * Handle drag end - reorder fields using arrayMove.\n */\n const handleDragEnd = useCallback(\n (event: DragEndEvent) => {\n const { active, over } = event;\n\n if (over && active.id !== over.id) {\n const oldIndex = fields.findIndex(f => f.name === active.id);\n const newIndex = fields.findIndex(f => f.name === over.id);\n\n if (oldIndex !== -1 && newIndex !== -1) {\n const newFields = arrayMove(fields, oldIndex, newIndex);\n onFieldsChange(newFields);\n }\n }\n },\n [fields, onFieldsChange]\n );\n\n // ---------------------------------------------------------------------------\n // Empty State\n // ---------------------------------------------------------------------------\n\n if (fields.length === 0) {\n return (\n <div className=\"form-field-list form-field-list--empty\">\n <div className=\"form-field-list__empty-state\">\n <div className=\"form-field-list__empty-icon\" aria-hidden=\"true\">\n 📋\n </div>\n <p className=\"form-field-list__empty-title\">No fields yet</p>\n <p className=\"form-field-list__empty-hint\">\n Click "Add Field" to get started\n </p>\n </div>\n </div>\n );\n }\n\n // ---------------------------------------------------------------------------\n // Render\n // ---------------------------------------------------------------------------\n\n return (\n <div className=\"form-field-list\">\n <DndContext\n sensors={sensors}\n collisionDetection={closestCenter}\n onDragEnd={handleDragEnd}\n >\n <SortableContext\n items={fields.map(f => f.name)}\n strategy={verticalListSortingStrategy}\n disabled={disabled}\n >\n <div className=\"form-field-list__fields\" role=\"list\">\n {fields.map(field => (\n <SortableFieldRow\n key={field.name}\n field={field}\n isSelected={selectedFieldName === field.name}\n onSelect={() => onEditField(field.name)}\n onDelete={() => onDeleteField(field.name)}\n disabled={disabled}\n />\n ))}\n </div>\n </SortableContext>\n </DndContext>\n\n {/* Footer hint */}\n <div className=\"form-field-list__footer\">\n <p className=\"form-field-list__footer-text\">\n {fields.length} field{fields.length !== 1 ? \"s\" : \"\"} • Drag to\n reorder • Click to edit\n </p>\n </div>\n </div>\n );\n}\n\nexport default FormFieldList;\n","\"use client\";\n\n/**\n * Sortable Field Row Component\n *\n * A draggable row component for form fields in the Visual Form Builder.\n * Uses @dnd-kit's useSortable hook for drag-and-drop reordering.\n *\n * Features:\n * - Drag handle with GripVertical icon for reordering\n * - Visual feedback during drag operations (opacity, ring, shadow)\n * - Field type icon and label display\n * - Required field indicator\n * - Delete button with keyboard accessibility\n * - WCAG 2.2 compliant with proper ARIA attributes\n *\n * This component follows the pattern established by ArrayRow.tsx in the\n * Nextly admin package for consistency across the codebase.\n *\n * @module admin/components/SortableFieldRow\n * @since 0.1.0\n */\n\n\"use client\";\n\nimport { useSortable } from \"@dnd-kit/sortable\";\nimport { CSS } from \"@dnd-kit/utilities\";\nimport { GripVertical, Trash2 } from \"lucide-react\";\nimport { useCallback } from \"react\";\n\nimport type { FormField } from \"../../types\";\nimport {\n getFieldTypeIcon,\n getFieldTypeLabel,\n resolveFieldIcon,\n} from \"../fields\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface SortableFieldRowProps {\n /**\n * The form field to display.\n */\n field: FormField;\n\n /**\n * Whether this row is currently selected for editing.\n */\n isSelected: boolean;\n\n /**\n * Callback when the row is clicked/selected.\n */\n onSelect: () => void;\n\n /**\n * Callback when the delete button is clicked.\n */\n onDelete: () => void;\n\n /**\n * Whether the row is disabled (no interactions allowed).\n * @default false\n */\n disabled?: boolean;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * SortableFieldRow renders a single draggable field row in the form builder.\n *\n * Uses @dnd-kit's useSortable hook to enable drag-and-drop reordering.\n * The component displays:\n * - A drag handle (GripVertical icon) for reordering\n * - The field type icon\n * - The field label (or name as fallback) with required indicator\n * - The field type badge\n * - A delete button\n *\n * Visual feedback is provided during drag operations:\n * - Reduced opacity (50%)\n * - Primary color ring (2px)\n * - Elevated shadow\n * - Higher z-index\n *\n * @example\n * ```tsx\n * <SortableFieldRow\n * field={field}\n * isSelected={selectedFieldName === field.name}\n * onSelect={() => setSelectedFieldName(field.name)}\n * onDelete={() => handleDeleteField(field.name)}\n * />\n * ```\n */\nexport function SortableFieldRow({\n field,\n isSelected,\n onSelect,\n onDelete,\n disabled = false,\n}: SortableFieldRowProps) {\n // ---------------------------------------------------------------------------\n // @dnd-kit Sortable Hook\n // ---------------------------------------------------------------------------\n\n const {\n attributes,\n listeners,\n setNodeRef,\n transform,\n transition,\n isDragging,\n } = useSortable({\n id: field.name,\n disabled,\n });\n\n // Apply CSS transform for drag animation\n const style = {\n transform: CSS.Transform.toString(transform),\n transition,\n };\n\n // ---------------------------------------------------------------------------\n // Field Type Info\n // ---------------------------------------------------------------------------\n\n const iconName = getFieldTypeIcon(field.type);\n const typeLabel = getFieldTypeLabel(field.type);\n const IconComponent = resolveFieldIcon(iconName);\n\n // ---------------------------------------------------------------------------\n // Event Handlers\n // ---------------------------------------------------------------------------\n\n /**\n * Handle delete button click.\n * Stops propagation to prevent row selection.\n */\n const handleDelete = useCallback(\n (e: React.MouseEvent | React.KeyboardEvent) => {\n e.stopPropagation();\n onDelete();\n },\n [onDelete]\n );\n\n /**\n * Handle keyboard navigation on the row.\n */\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onSelect();\n }\n },\n [onSelect]\n );\n\n // ---------------------------------------------------------------------------\n // Render\n // ---------------------------------------------------------------------------\n\n // Build class names based on state\n const rowClassName = [\n \"form-field-row\",\n isSelected && \"form-field-row--selected\",\n isDragging && \"form-field-row--dragging\",\n disabled && \"form-field-row--disabled\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <div\n ref={setNodeRef}\n style={style}\n className={rowClassName}\n onClick={onSelect}\n onKeyDown={handleKeyDown}\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n aria-label={`${field.label || field.name} field, type: ${typeLabel}${isSelected ? \", selected\" : \"\"}`}\n aria-pressed={isSelected}\n aria-disabled={disabled}\n >\n {/* Drag Handle */}\n {!disabled && (\n <button\n type=\"button\"\n className=\"form-field-row__drag-handle\"\n aria-label={`Drag to reorder ${field.label || field.name}`}\n {...attributes}\n {...listeners}\n >\n <GripVertical className=\"form-field-row__drag-icon\" />\n </button>\n )}\n\n {/* Spacer when drag handle is hidden */}\n {disabled && <div className=\"form-field-row__drag-handle-spacer\" />}\n\n {/* Field Type Icon */}\n <span className=\"form-field-row__type-icon\" aria-hidden=\"true\">\n <IconComponent className=\"form-field-row__icon\" />\n </span>\n\n {/* Field Content */}\n <div className=\"form-field-row__content\">\n <span className=\"form-field-row__label\">\n {field.label || field.name}\n {field.required && (\n <span className=\"form-field-row__required\" aria-label=\"Required\">\n *\n </span>\n )}\n </span>\n <span className=\"form-field-row__type-badge\">{typeLabel}</span>\n </div>\n\n {/* Actions */}\n <div className=\"form-field-row__actions\">\n <button\n type=\"button\"\n className=\"form-field-row__action form-field-row__action--delete\"\n onClick={handleDelete}\n onKeyDown={e => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n handleDelete(e);\n }\n }}\n disabled={disabled}\n aria-label={`Delete ${field.label || field.name}`}\n title=\"Delete field\"\n >\n <Trash2 className=\"form-field-row__action-icon\" />\n </button>\n </div>\n </div>\n );\n}\n\nexport default SortableFieldRow;\n","/**\n * Form Field Type Registry\n *\n * Central registry for all supported field types in the Visual Form Builder.\n * Used by AddFieldModal to display available field types grouped by category.\n *\n * Supported Field Types:\n * - Core Fields (8): text, textarea, email, number, checkbox, select, radio, date\n *\n * @module admin/fields\n * @since 0.1.0\n */\n\nimport {\n AlignLeft,\n Calendar,\n CheckSquare,\n ChevronDown,\n Circle,\n FileText,\n Hash,\n Mail,\n Type,\n type LucideIcon,\n} from \"lucide-react\";\nimport type { ComponentType } from \"react\";\n\nimport type { FormField, FormFieldType } from \"../../types\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Props for field editor components.\n *\n * Each field type has a dedicated editor component that receives these props.\n */\nexport interface FieldEditorProps<T extends FormField = FormField> {\n /** The field being edited */\n field: T;\n /** All fields in the form (for references, e.g., state -> country linking) */\n allFields: FormField[];\n /** Callback to update field properties */\n onUpdate: (updates: Partial<T>) => void;\n}\n\n/**\n * Field type configuration for the admin UI.\n *\n * Defines metadata and components for each supported field type.\n */\nexport interface FieldTypeConfig {\n /** Field type identifier (matches FormFieldType) */\n type: FormFieldType;\n /** Display name in field selector */\n label: string;\n /** Lucide icon name */\n icon: string;\n /** Short description shown in field selector */\n description: string;\n /** Category for grouping in the Add Field modal */\n category: \"core\";\n /**\n * Editor component for configuring field properties.\n * Lazy-loaded for code splitting.\n *\n * Note: Uses `any` for the component type to allow field-specific editors.\n * The actual editor component will receive the correctly typed field.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n EditorComponent: () => Promise<{ default: ComponentType<any> }>;\n /** Default field configuration when added to form */\n defaultConfig: Partial<FormField> & { type: FormFieldType };\n}\n\n/**\n * Field type category configuration.\n */\nexport interface FieldCategory {\n /** Category key */\n key: \"core\";\n /** Display label */\n label: string;\n /** Description of the category */\n description: string;\n}\n\n// ============================================================================\n// Category Definitions\n// ============================================================================\n\n/**\n * Field type categories for organizing the Add Field modal.\n */\nexport const FIELD_CATEGORIES: FieldCategory[] = [\n {\n key: \"core\",\n label: \"Core Fields\",\n description: \"Essential form input fields\",\n },\n];\n\n// ============================================================================\n// Field Type Definitions\n// ============================================================================\n\n/**\n * Supported field types.\n *\n * This registry defines 8 field types that cover the most common form use cases:\n * - Contact forms\n * - Registration forms\n * - Surveys and feedback\n *\n * Additional field types (phone, url, file, time, hidden)\n * can be added in future iterations.\n */\nexport const FIELD_TYPES: FieldTypeConfig[] = [\n // ---------------------------------------------------------------------------\n // Core Fields (7 types)\n // ---------------------------------------------------------------------------\n {\n type: \"text\",\n label: \"Text\",\n icon: \"Type\",\n description: \"Single-line text input\",\n category: \"core\",\n EditorComponent: () => import(\"./TextFieldEditor\"),\n defaultConfig: {\n type: \"text\",\n label: \"Text Field\",\n placeholder: \"\",\n required: false,\n },\n },\n {\n type: \"textarea\",\n label: \"Textarea\",\n icon: \"AlignLeft\",\n description: \"Multi-line text input\",\n category: \"core\",\n EditorComponent: () => import(\"./TextareaFieldEditor\"),\n defaultConfig: {\n type: \"textarea\",\n label: \"Message\",\n placeholder: \"\",\n required: false,\n rows: 4,\n },\n },\n {\n type: \"email\",\n label: \"Email\",\n icon: \"Mail\",\n description: \"Email address with validation\",\n category: \"core\",\n EditorComponent: () => import(\"./EmailFieldEditor\"),\n defaultConfig: {\n type: \"email\",\n label: \"Email\",\n placeholder: \"email@example.com\",\n required: false,\n },\n },\n {\n type: \"number\",\n label: \"Number\",\n icon: \"Hash\",\n description: \"Numeric input with min/max\",\n category: \"core\",\n EditorComponent: () => import(\"./NumberFieldEditor\"),\n defaultConfig: {\n type: \"number\",\n label: \"Number\",\n placeholder: \"0\",\n required: false,\n },\n },\n {\n type: \"checkbox\",\n label: \"Checkbox\",\n icon: \"CheckSquare\",\n description: \"Single checkbox (yes/no)\",\n category: \"core\",\n EditorComponent: () => import(\"./CheckboxFieldEditor\"),\n defaultConfig: {\n type: \"checkbox\",\n label: \"I agree to the terms\",\n required: false,\n defaultValue: false,\n },\n },\n {\n type: \"select\",\n label: \"Dropdown\",\n icon: \"ChevronDown\",\n description: \"Dropdown select menu\",\n category: \"core\",\n EditorComponent: () => import(\"./SelectFieldEditor\"),\n defaultConfig: {\n type: \"select\",\n label: \"Select an option\",\n placeholder: \"Choose...\",\n required: false,\n options: [\n { label: \"Option 1\", value: \"option1\" },\n { label: \"Option 2\", value: \"option2\" },\n ],\n },\n },\n {\n type: \"radio\",\n label: \"Radio\",\n icon: \"Circle\",\n description: \"Radio button group\",\n category: \"core\",\n EditorComponent: () => import(\"./RadioFieldEditor\"),\n defaultConfig: {\n type: \"radio\",\n label: \"Choose one\",\n required: false,\n options: [\n { label: \"Option 1\", value: \"option1\" },\n { label: \"Option 2\", value: \"option2\" },\n ],\n },\n },\n\n // ---------------------------------------------------------------------------\n // Date Fields\n // ---------------------------------------------------------------------------\n {\n type: \"date\",\n label: \"Date\",\n icon: \"Calendar\",\n description: \"Date picker\",\n category: \"core\",\n EditorComponent: () => import(\"./DateFieldEditor\"),\n defaultConfig: {\n type: \"date\",\n label: \"Date\",\n required: false,\n },\n },\n];\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Get field types grouped by category.\n *\n * @returns Object with category keys mapping to arrays of field configs\n *\n * @example\n * ```typescript\n * const grouped = getFieldTypesByCategory();\n * // { core: [...], location: [...] }\n * ```\n */\nexport function getFieldTypesByCategory(): Record<string, FieldTypeConfig[]> {\n return FIELD_TYPES.reduce(\n (acc, field) => {\n if (!acc[field.category]) {\n acc[field.category] = [];\n }\n acc[field.category].push(field);\n return acc;\n },\n {} as Record<string, FieldTypeConfig[]>\n );\n}\n\n/**\n * Get field type configuration by type identifier.\n *\n * @param type - The field type to look up\n * @returns The field type config or undefined if not found\n *\n * @example\n * ```typescript\n * const config = getFieldTypeConfig('text');\n * console.log(config?.label); // \"Text\"\n * ```\n */\nexport function getFieldTypeConfig(\n type: FormFieldType\n): FieldTypeConfig | undefined {\n return FIELD_TYPES.find(f => f.type === type);\n}\n\n/**\n * Check if a field type is supported by the registry.\n *\n * @param type - The field type to check\n * @returns True if the field type is supported\n */\nexport function isFieldTypeSupported(type: string): type is FormFieldType {\n return FIELD_TYPES.some(f => f.type === type);\n}\n\n/**\n * Create a new field instance from a field type.\n *\n * Generates a unique field name and applies default configuration.\n *\n * @param type - The field type to create\n * @returns A new FormField instance\n * @throws Error if the field type is unknown\n *\n * @example\n * ```typescript\n * const field = createFieldFromType('email');\n * // { type: 'email', name: 'email_abc123', label: 'Email', ... }\n * ```\n */\nexport function createFieldFromType(type: FormFieldType): FormField {\n const config = getFieldTypeConfig(type);\n\n if (!config) {\n throw new Error(`Unknown field type: ${type}`);\n }\n\n // Generate unique field name\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 6);\n const name = `${type}_${timestamp}_${random}`;\n\n return {\n name,\n ...config.defaultConfig,\n } as FormField;\n}\n\n/**\n * Get the Lucide icon name for a field type.\n *\n * @param type - The field type\n * @returns The Lucide icon name or \"FileText\" as fallback\n */\nexport function getFieldTypeIcon(type: FormFieldType): string {\n return getFieldTypeConfig(type)?.icon ?? \"FileText\";\n}\n\n/**\n * Get the display label for a field type.\n *\n * @param type - The field type\n * @returns The display label or the type itself as fallback\n */\nexport function getFieldTypeLabel(type: FormFieldType): string {\n return getFieldTypeConfig(type)?.label ?? type;\n}\n\n/**\n * Get all supported field types as an array of type identifiers.\n *\n * @returns Array of supported FormFieldType values\n */\nexport function getSupportedFieldTypes(): FormFieldType[] {\n return FIELD_TYPES.map(f => f.type);\n}\n\n// ============================================================================\n// Icon Resolution\n// ============================================================================\n\n/**\n * Mapping of Lucide icon names to their component implementations.\n *\n * This map is used by `resolveFieldIcon()` to convert icon name strings\n * (stored in FIELD_TYPES) to actual React components for rendering.\n *\n * When adding new field types, ensure the corresponding icon is added here.\n */\nconst ICON_MAP: Record<string, LucideIcon> = {\n Type,\n AlignLeft,\n Mail,\n Hash,\n CheckSquare,\n ChevronDown,\n Circle,\n Calendar,\n FileText, // Fallback icon\n};\n\n/**\n * Resolve a Lucide icon name to its component implementation.\n *\n * This function converts icon name strings (e.g., \"Type\", \"Mail\") to actual\n * Lucide React components that can be rendered. Used by SortableFieldRow\n * and other components that display field type icons.\n *\n * @param iconName - The Lucide icon name (from getFieldTypeIcon or FIELD_TYPES)\n * @returns The Lucide icon component, or FileText as fallback\n *\n * @example\n * ```tsx\n * const iconName = getFieldTypeIcon('email'); // \"Mail\"\n * const IconComponent = resolveFieldIcon(iconName);\n * return <IconComponent className=\"h-4 w-4\" />;\n * ```\n */\nexport function resolveFieldIcon(iconName: string): LucideIcon {\n return ICON_MAP[iconName] ?? FileText;\n}\n\n// Re-export LucideIcon type for consumers\nexport type { LucideIcon };\n","\"use client\";\n\n/**\n * Add Field Button Component\n *\n * A button that opens a modal dialog for selecting field types to add to a form.\n * Displays fields grouped by category (Core, Location) with icons and descriptions.\n *\n * Features:\n * - Modal dialog with field type selection\n * - Fields grouped by category\n * - Icon, label, and description for each field type\n * - Keyboard accessible\n * - Auto-closes on selection\n *\n * @module admin/components/AddFieldButton\n * @since 0.1.0\n */\n\n\"use client\";\n\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from \"@nextlyhq/ui\";\nimport { Plus } from \"lucide-react\";\nimport { useCallback, useState } from \"react\";\n\nimport type { FormField, FormFieldType } from \"../../types\";\nimport {\n createFieldFromType,\n FIELD_CATEGORIES,\n getFieldTypesByCategory,\n resolveFieldIcon,\n type FieldTypeConfig,\n} from \"../fields\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface AddFieldButtonProps {\n /**\n * Callback when a new field is created.\n * Receives the newly created FormField instance.\n */\n onAddField: (field: FormField) => void;\n\n /**\n * Whether the button is disabled.\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Additional CSS class names for the button.\n */\n className?: string;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * AddFieldButton renders a button that opens a modal for selecting field types.\n *\n * When a field type is selected, a new field instance is created with default\n * configuration and passed to the onAddField callback. The modal automatically\n * closes after selection.\n *\n * @example\n * ```tsx\n * <AddFieldButton\n * onAddField={(field) => {\n * setFields([...fields, field]);\n * }}\n * />\n * ```\n */\nexport function AddFieldButton({\n onAddField,\n disabled = false,\n className,\n}: AddFieldButtonProps) {\n const [isOpen, setIsOpen] = useState(false);\n\n // Get fields grouped by category\n const fieldsByCategory = getFieldTypesByCategory();\n\n /**\n * Handle field type selection.\n * Creates a new field and calls the callback.\n */\n const handleSelectField = useCallback(\n (type: FormFieldType) => {\n const newField = createFieldFromType(type);\n onAddField(newField);\n setIsOpen(false);\n },\n [onAddField]\n );\n\n // Build button class names\n const buttonClassName = [\n \"add-field-button\",\n disabled && \"add-field-button--disabled\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <>\n {/* Trigger Button */}\n <button\n type=\"button\"\n className={buttonClassName}\n onClick={() => setIsOpen(true)}\n disabled={disabled}\n aria-label=\"Add a new field to the form\"\n >\n <Plus className=\"add-field-button__icon\" aria-hidden=\"true\" />\n <span className=\"add-field-button__label\">Add Field</span>\n </button>\n\n {/* Field Selection Modal */}\n <Dialog open={isOpen} onOpenChange={setIsOpen}>\n <DialogContent size=\"md\" className=\"add-field-modal\">\n <DialogHeader>\n <DialogTitle>Add Field</DialogTitle>\n <DialogDescription>\n Select a field type to add to your form.\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"add-field-modal__content\">\n {FIELD_CATEGORIES.map(category => {\n const fields = fieldsByCategory[category.key] || [];\n if (fields.length === 0) return null;\n\n return (\n <div key={category.key} className=\"add-field-modal__category\">\n <h4 className=\"add-field-modal__category-title\">\n {category.label}\n </h4>\n <p className=\"add-field-modal__category-description\">\n {category.description}\n </p>\n\n <div className=\"add-field-modal__field-grid\">\n {fields.map(fieldConfig => (\n <FieldTypeButton\n key={fieldConfig.type}\n config={fieldConfig}\n onClick={() => handleSelectField(fieldConfig.type)}\n />\n ))}\n </div>\n </div>\n );\n })}\n </div>\n </DialogContent>\n </Dialog>\n </>\n );\n}\n\n// ============================================================================\n// Field Type Button (Internal)\n// ============================================================================\n\ninterface FieldTypeButtonProps {\n config: FieldTypeConfig;\n onClick: () => void;\n}\n\n/**\n * Individual field type button displayed in the modal.\n * Shows icon, label, and description.\n */\nfunction FieldTypeButton({ config, onClick }: FieldTypeButtonProps) {\n const IconComponent = resolveFieldIcon(config.icon);\n\n return (\n <button\n type=\"button\"\n className=\"add-field-modal__field-button\"\n onClick={onClick}\n aria-label={`Add ${config.label} field`}\n >\n <span className=\"add-field-modal__field-icon\" aria-hidden=\"true\">\n <IconComponent className=\"add-field-modal__icon\" />\n </span>\n <span className=\"add-field-modal__field-info\">\n <span className=\"add-field-modal__field-label\">{config.label}</span>\n <span className=\"add-field-modal__field-description\">\n {config.description}\n </span>\n </span>\n </button>\n );\n}\n\nexport default AddFieldButton;\n","\"use client\";\n\n/**\n * Field Editor Panel Component\n *\n * Right-side panel for editing field properties. Dynamically loads the\n * appropriate field editor component based on field type using React.lazy().\n *\n * Features:\n * - Lazy-loaded field editors for code splitting\n * - Loading skeleton during editor load\n * - Graceful handling of unknown field types\n * - Header with field type icon and label\n * - Close button to dismiss the panel\n *\n * @module admin/components/FieldEditorPanel\n * @since 0.1.0\n */\n\n\"use client\";\n\nimport { X } from \"lucide-react\";\nimport React, { Suspense, useMemo } from \"react\";\n\nimport type { FormField } from \"../../types\";\nimport {\n getFieldTypeConfig,\n getFieldTypeLabel,\n resolveFieldIcon,\n} from \"../fields\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface FieldEditorPanelProps {\n /**\n * The field being edited.\n */\n field: FormField;\n\n /**\n * All fields in the form (for references, e.g., conditional logic).\n */\n allFields: FormField[];\n\n /**\n * Callback when field properties are updated.\n * Receives partial updates to merge with current field.\n */\n onUpdate: (updates: Partial<FormField>) => void;\n\n /**\n * Callback when the panel should be closed.\n */\n onClose: () => void;\n}\n\n// ============================================================================\n// Loading Skeleton\n// ============================================================================\n\n/**\n * Loading skeleton displayed while field editor is being lazy-loaded.\n * Provides visual feedback during the brief loading period.\n */\nfunction EditorSkeleton() {\n return (\n <div className=\"field-editor-panel__skeleton\">\n {/* Label skeleton */}\n <div className=\"field-editor-panel__skeleton-row\">\n <div className=\"field-editor-panel__skeleton-label\" />\n <div className=\"field-editor-panel__skeleton-input\" />\n </div>\n {/* Field name skeleton */}\n <div className=\"field-editor-panel__skeleton-row\">\n <div className=\"field-editor-panel__skeleton-label\" />\n <div className=\"field-editor-panel__skeleton-input\" />\n </div>\n {/* Placeholder skeleton */}\n <div className=\"field-editor-panel__skeleton-row\">\n <div className=\"field-editor-panel__skeleton-label\" />\n <div className=\"field-editor-panel__skeleton-input\" />\n </div>\n {/* Checkbox skeleton */}\n <div className=\"field-editor-panel__skeleton-row\">\n <div className=\"field-editor-panel__skeleton-checkbox\" />\n <div className=\"field-editor-panel__skeleton-label--short\" />\n </div>\n </div>\n );\n}\n\n// ============================================================================\n// Unknown Field Type Fallback\n// ============================================================================\n\n/**\n * Fallback displayed when field type is not recognized.\n * This should rarely happen in practice, but provides a graceful degradation.\n */\nfunction UnknownFieldType({ type }: { type: string }) {\n return (\n <div className=\"field-editor-panel__unknown\">\n <p className=\"field-editor-panel__unknown-title\">Unknown Field Type</p>\n <p className=\"field-editor-panel__unknown-message\">\n The field type <code>{type}</code> is not supported by this version of\n the form builder.\n </p>\n </div>\n );\n}\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\n/**\n * FieldEditorPanel - Right-side panel for editing field properties\n *\n * This component dynamically loads the appropriate field editor based on\n * the field type. Each field type has its own editor component that handles\n * the specific configuration options for that type.\n *\n * The panel displays:\n * - Header with field type icon, type label, and field label\n * - Close button to dismiss the panel\n * - Lazy-loaded editor content with loading skeleton\n *\n * @example\n * ```tsx\n * <FieldEditorPanel\n * field={selectedField}\n * allFields={allFields}\n * onUpdate={(updates) => updateField(selectedField.name, updates)}\n * onClose={() => setSelectedField(null)}\n * />\n * ```\n */\nexport function FieldEditorPanel({\n field,\n allFields,\n onUpdate,\n onClose,\n}: FieldEditorPanelProps) {\n // Get field type configuration from registry\n const fieldConfig = getFieldTypeConfig(field.type);\n\n // Lazily load the editor component based on field type\n // useMemo ensures we don't recreate the lazy component on every render\n const EditorComponent = useMemo(() => {\n if (!fieldConfig) return null;\n return React.lazy(fieldConfig.EditorComponent);\n }, [fieldConfig]);\n\n // Handle unknown field type\n if (!fieldConfig || !EditorComponent) {\n return (\n <div className=\"field-editor-panel\">\n <div className=\"field-editor-panel__header\">\n <div className=\"field-editor-panel__title\">\n <span className=\"field-editor-panel__title-text\">Edit Field</span>\n </div>\n <button\n type=\"button\"\n className=\"field-editor-panel__close\"\n onClick={onClose}\n aria-label=\"Close editor panel\"\n >\n <X className=\"field-editor-panel__close-icon\" />\n </button>\n </div>\n <div className=\"field-editor-panel__content\">\n <UnknownFieldType type={field.type} />\n </div>\n </div>\n );\n }\n\n // Resolve the icon component for this field type\n const IconComponent = resolveFieldIcon(fieldConfig.icon);\n\n // Get display label for field type\n const typeLabel = getFieldTypeLabel(field.type);\n\n return (\n <div className=\"field-editor-panel\">\n {/* Header */}\n <div className=\"field-editor-panel__header\">\n <div className=\"field-editor-panel__title\">\n <IconComponent\n className=\"field-editor-panel__title-icon\"\n aria-hidden=\"true\"\n />\n <span className=\"field-editor-panel__title-text\">\n Edit {typeLabel} Field\n {field.label && (\n <span className=\"field-editor-panel__title-label\">\n {\" \"}\n — {field.label}\n </span>\n )}\n </span>\n </div>\n <button\n type=\"button\"\n className=\"field-editor-panel__close\"\n onClick={onClose}\n aria-label=\"Close editor panel\"\n >\n <X className=\"field-editor-panel__close-icon\" />\n </button>\n </div>\n\n {/* Editor Content */}\n <div className=\"field-editor-panel__content\">\n <Suspense fallback={<EditorSkeleton />}>\n <EditorComponent\n field={field}\n allFields={allFields}\n onUpdate={onUpdate}\n />\n </Suspense>\n </div>\n </div>\n );\n}\n\nexport default FieldEditorPanel;\n"],"mappings":"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","names":["Button","Input","Tabs","TabsList","TabsTrigger","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","useCallback","useState","FormLabelWithTooltip","Input","Button","Checkbox","Select","SelectContent","SelectItem","SelectTrigger","SelectValue","useState","useCallback","useMemo","useCallback","jsx","jsxs","jsx","jsxs","useMemo","FormLabelWithTooltip","Input","Checkbox","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","useCallback","Button","useState","useMemo","useState","useCallback","useMemo","useState","jsx","jsx","jsxs","useState","useMemo","jsx","jsxs","Button","Input","useCallback","useEffect","useState","jsx","jsxs","useState","useCallback","Input","Button","useEffect","Input","Button","jsx","jsxs","Input","Tabs","TabsList","TabsTrigger","jsx","jsxs","Input","Tabs","TabsList","TabsTrigger","Fragment","jsx","jsxs","useState","useCallback","Button","Input","Select","SelectTrigger","SelectValue","SelectContent","SelectItem","Tabs","TabsList","TabsTrigger","DndContext","closestCenter","KeyboardSensor","PointerSensor","useSensor","useSensors","SortableContext","sortableKeyboardCoordinates","verticalListSortingStrategy","useCallback","useSortable","CSS","useCallback","FIELD_TYPES","createFieldFromType","jsx","jsxs","useSortable","CSS","useCallback","jsx","jsxs","useSensors","useSensor","PointerSensor","KeyboardSensor","sortableKeyboardCoordinates","useCallback","DndContext","closestCenter","SortableContext","verticalListSortingStrategy","useCallback","useState","Fragment","jsx","jsxs","useState","useCallback","createFieldFromType","useMemo","jsx","jsxs","useMemo"]}
|