@digiform/builder 0.2.1 → 0.2.5

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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../packages/ui/src/component-registry/renderComponent.tsx","../../../packages/forms/src/navigation/context.tsx","../../../packages/forms/src/navigation/hooks.ts","../../../packages/builder/src/features/form-management/hooks/useFormData.ts","../../../packages/builder/src/features/form-management/components/FormBuilderView/FormBuilderView.tsx","../../../packages/builder/src/features/form-management/hooks/useFormsQuery.ts","../../../packages/builder/src/features/form-management/layout/BaseHeader/BaseHeader.tsx","../../../packages/builder/src/features/form-management/layout/BaseLayout/BaseLayout.tsx","../../../packages/builder/src/features/form-management/components/NewFormDialog/NewFormDialog.tsx","../../../packages/builder/src/features/form-management/components/SearchInput/SearchInput.tsx","../../../packages/builder/src/features/form-management/components/ViewCard/ViewCard.tsx","../../../packages/builder/src/features/form-management/components/FormsView/FormsView.tsx","../../../packages/builder/src/features/form-management/hooks/useProjectActions.ts","../../../packages/builder/src/features/form-management/hooks/useProjectsData.ts","../../../packages/builder/src/features/form-management/components/NewProjectDialog/NewProjectDialog.tsx","../../../packages/builder/src/features/form-management/components/ProjectsView/ProjectsView.tsx","../../../packages/builder/src/features/form-management/components/ProjectCard/ProjectCard.tsx","../../../packages/builder/src/features/form-management/hooks/useFormExplorerState.ts","../../../packages/builder/src/features/form-management/hooks/useFormOperations.ts","../../../packages/builder/src/features/form-management/hooks/useProjectOperations.ts","../../../packages/builder/src/components/DatabaseStatusIndicator/DatabaseStatusIndicator.tsx","../../../packages/builder/src/components/ConnectionErrorScreen/ConnectionErrorScreen.tsx","../../../packages/builder/src/features/form-management/types/viewTypes.ts","../../../packages/builder/src/features/form-management/components/FormExplorerCore/FormExplorerCore.tsx","../../../packages/builder/src/features/form-management/components/FormExplorer/FormExplorer.tsx","../../../node_modules/react-router/dist/index.js","../../../packages/builder/src/integrations/react-router/FormBuilderPage/FormBuilderPage.tsx","../../../packages/builder/src/integrations/react-router/FormsPage.tsx","../../../packages/builder/src/features/form-management/components/pages/ProjectsPage.tsx","../../../packages/builder/src/index.ts"],"sourcesContent":["import type { ComponentConfig } from \"@formbuilder/core\";\nimport type { ComponentValue } from \"./types\";\nimport type { ReactNode } from \"react\";\n\n/**\n * Props passed to renderComponent.\n * Matches the signature used in @formbuilder/builder's component-registry.\n */\nexport interface RenderComponentProps {\n component: ComponentConfig;\n value: ComponentValue;\n onChange: (value: ComponentValue) => void;\n isFormView: boolean;\n}\n\n/**\n * Type of the render function that must be registered by the consuming package\n * (i.e. @formbuilder/builder) before renderComponent is called.\n */\nexport type RenderComponentFn = (props: RenderComponentProps) => ReactNode;\n\n// Module-level registry slot — populated at runtime by @formbuilder/builder\nlet registeredRenderer: RenderComponentFn | null = null;\n\n/**\n * Register the concrete renderComponent implementation.\n * Must be called once by @formbuilder/builder (or any package that owns the\n * component registry) before renderComponent is used at runtime.\n */\nexport const registerRenderComponent = (fn: RenderComponentFn): void => {\n registeredRenderer = fn;\n};\n\n/**\n * Render a form component using the registered component registry.\n *\n * This function lives in @formbuilder/ui so that @formbuilder/wizard can\n * import it without depending on @formbuilder/builder, breaking the\n * wizard → builder circular dependency.\n *\n * The actual rendering is delegated to the implementation registered via\n * registerRenderComponent(), which is called by @formbuilder/builder on\n * initialisation.\n */\nexport const renderComponent = (props: RenderComponentProps): ReactNode => {\n if (!registeredRenderer) {\n console.error(\n \"[renderComponent] No renderer registered. \" +\n \"Ensure @formbuilder/builder has been initialised before rendering form components.\"\n );\n return null;\n }\n return registeredRenderer(props);\n};\n","import { createContext, useMemo } from \"react\";\nimport type { NavigationContextValue, NavigationProviderProps } from \"./types\";\nimport { routeConfigSchema } from \"./schema\";\nimport { buildPath } from \"./builders\";\n\n/**\n * React context for navigation callbacks.\n * Use useFormNavigation() hook to access this context.\n */\nexport const NavigationContext = createContext<NavigationContextValue | null>(\n\tnull,\n);\n\n/**\n * Provider component that makes navigation callbacks available to child components.\n *\n * Accepts a generic navigate function (router.push, router.navigate, etc.) and\n * optional route configuration overrides. Creates type-safe navigation callbacks\n * that build paths using the route templates and call the provided navigate function.\n *\n * @example\n * // Next.js App Router\n * import { useRouter } from 'next/navigation';\n *\n * function App() {\n * const router = useRouter();\n * return (\n * <NavigationProvider navigate={router.push}>\n * <YourComponents />\n * </NavigationProvider>\n * );\n * }\n *\n * @example\n * // With custom routes\n * <NavigationProvider\n * navigate={router.push}\n * routes={{ builder: '/custom/:projectId/:formId' }}\n * >\n * <YourComponents />\n * </NavigationProvider>\n */\nexport function NavigationProvider({\n\tnavigate,\n\troutes,\n\tchildren,\n}: NavigationProviderProps) {\n\t// Merge provided routes with defaults using Zod schema\n\tconst resolvedRoutes = useMemo(\n\t\t() => routeConfigSchema.parse(routes ?? {}),\n\t\t[routes],\n\t);\n\n\t// Create memoized navigation callbacks\n\tconst value = useMemo<NavigationContextValue>(\n\t\t() => ({\n\t\t\tnavigateToProjects: () => {\n\t\t\t\tnavigate(buildPath(resolvedRoutes.projects));\n\t\t\t},\n\t\t\tnavigateToForms: (projectId: string) => {\n\t\t\t\tnavigate(buildPath(resolvedRoutes.forms, { projectId }));\n\t\t\t},\n\t\t\tnavigateToBuilder: (projectId: string, formId: string) => {\n\t\t\t\tnavigate(buildPath(resolvedRoutes.builder, { projectId, formId }));\n\t\t\t},\n\t\t\tnavigateToPreview: (projectId: string, formId: string) => {\n\t\t\t\tnavigate(buildPath(resolvedRoutes.preview, { projectId, formId }));\n\t\t\t},\n\t\t}),\n\t\t[navigate, resolvedRoutes],\n\t);\n\n\treturn (\n\t\t<NavigationContext.Provider value={value}>\n\t\t\t{children}\n\t\t</NavigationContext.Provider>\n\t);\n}\n","import { useContext } from \"react\";\nimport { NavigationContext } from \"./context\";\nimport type { NavigationContextValue } from \"./types\";\n\n/**\n * Hook to access navigation callbacks within a NavigationProvider.\n *\n * Returns an object with four type-safe navigation methods:\n * - navigateToProjects(): Navigate to projects list\n * - navigateToForms(projectId): Navigate to forms list for a project\n * - navigateToBuilder(projectId, formId): Navigate to form builder\n * - navigateToPreview(projectId, formId): Navigate to form preview\n *\n * @throws Error if used outside of NavigationProvider\n *\n * @example\n * function MyComponent() {\n * const { navigateToBuilder } = useFormNavigation();\n *\n * return (\n * <button onClick={() => navigateToBuilder('proj-1', 'form-1')}>\n * Edit Form\n * </button>\n * );\n * }\n */\nexport function useFormNavigation(): NavigationContextValue {\n\tconst context = useContext(NavigationContext);\n\n\tif (context === null) {\n\t\tthrow new Error(\n\t\t\t`useFormNavigation must be used within a NavigationProvider.\n\nWrap your app with NavigationProvider:\n<NavigationProvider navigate={router.push} routes={config.navigation?.routes}>\n {children}\n</NavigationProvider>`,\n\t\t);\n\t}\n\n\treturn context;\n}\n","/**\n * TanStack Query hook for loading a single form config\n * Used by FormBuilderView for data fetching\n */\n\nimport type { FormWizardConfig } from \"@formbuilder/core\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { FormConfig } from \"../../../config/types\";\nimport { StorageProviderFactory } from \"../../../storage/StorageProviderFactory\";\nimport { getFormConfig } from \"../../../utils/formsExplorer\";\n\ninterface UseFormDataOptions {\n\tprojectId: string;\n\tformId: string;\n\tconfig?: FormConfig;\n}\n\n/**\n * Query hook for loading a single form configuration\n * Returns form config with loading and error states\n */\nexport function useFormData({ projectId, formId, config }: UseFormDataOptions) {\n\treturn useQuery({\n\t\tqueryKey: [\"form\", projectId, formId],\n\t\tqueryFn: async () => {\n\t\t\t// Get form configuration\n\t\t\tconst formConfig = config || (await getFormConfig());\n\n\t\t\t// Get storage provider\n\t\t\tconst factory = StorageProviderFactory.getInstance();\n\t\t\tconst provider = await factory.createProvider(formConfig.storage);\n\n\t\t\tif (!provider) {\n\t\t\t\tthrow new Error(\"Storage provider not available\");\n\t\t\t}\n\n\t\t\t// Load form data\n\t\t\tconst result = await provider.loadForm(projectId, formId);\n\n\t\t\tif (result.success && result.data) {\n\t\t\t\treturn result.data as FormWizardConfig;\n\t\t\t} else {\n\t\t\t\tthrow new Error(`Form \"${formId}\" not found in project \"${projectId}\"`);\n\t\t\t}\n\t\t},\n\t\tenabled: Boolean(projectId && formId),\n\t\tstaleTime: 30000, // Consider data fresh for 30 seconds\n\t\trefetchOnWindowFocus: true,\n\t\trefetchOnMount: true,\n\t});\n}\n","/**\n * FormBuilderView - Standalone component wrapping FormBuilder with data loading and navigation\n * Framework-agnostic: Uses useFormNavigation instead of react-router-dom\n */\n\nimport { useFormNavigation } from \"@formbuilder/forms/navigation\";\nimport type { FormWizardConfig } from \"@formbuilder/core\";\nimport type React from \"react\";\nimport type { FormConfig } from \"../../../../config/types\";\nimport styles from \"./FormBuilderView.module.css\";\nimport { StorageProviderFactory } from \"../../../../storage/StorageProviderFactory\";\nimport { getFormConfig } from \"../../../../utils/formsExplorer\";\nimport { FormBuilder } from \"../../../form-builder\";\nimport { useFormData } from \"../../hooks/useFormData\";\n\nexport interface FormBuilderViewProps {\n\tprojectId: string;\n\tformId: string;\n\tconfig?: FormConfig;\n\tshowPreview?: boolean;\n\tclassName?: string;\n\tstyle?: React.CSSProperties;\n\tonSave?: (config: FormWizardConfig) => Promise<void>;\n}\n\n/**\n * Standalone FormBuilderView component\n * Wraps FormBuilder with loading, error handling, and navigation\n */\nexport const FormBuilderView: React.FC<FormBuilderViewProps> = ({\n\tprojectId,\n\tformId,\n\tconfig,\n\tshowPreview = true,\n\tclassName,\n\tstyle,\n\tonSave,\n}) => {\n\tconst {\n\t\tdata: formConfig,\n\t\tisLoading,\n\t\terror,\n\t} = useFormData({ projectId, formId, config });\n\tconst { navigateToForms } = useFormNavigation();\n\n\t// Create save handler\n\tconst handleSave = async (updatedConfig: FormWizardConfig) => {\n\t\tif (onSave) {\n\t\t\t// Use custom save handler if provided\n\t\t\tawait onSave(updatedConfig);\n\t\t} else {\n\t\t\t// Default save logic via storage provider\n\t\t\tconst formConfigData = config || (await getFormConfig());\n\t\t\tconst factory = StorageProviderFactory.getInstance();\n\t\t\tconst provider = await factory.createProvider(formConfigData.storage);\n\n\t\t\tif (!provider) {\n\t\t\t\tthrow new Error(\"Storage provider not available\");\n\t\t\t}\n\n\t\t\tconst result = await provider.saveForm(projectId, formId, updatedConfig);\n\n\t\t\tif (!result.success) {\n\t\t\t\tthrow new Error(result.error || `Failed to save form \"${formId}\"`);\n\t\t\t}\n\t\t}\n\t};\n\n\t// Loading state\n\tif (isLoading) {\n\t\treturn (\n\t\t\t<div className={styles.loadingContainer}>\n\t\t\t\t<div className={styles.loadingInner}>\n\t\t\t\t\t<div className={styles.loadingSpinner}></div>\n\t\t\t\t\t<p className={styles.loadingText}>Loading form...</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\t// Error state\n\tif (error || !formConfig) {\n\t\treturn (\n\t\t\t<div className={styles.errorContainer}>\n\t\t\t\t<div className={styles.errorInner}>\n\t\t\t\t\t<h2 className={styles.errorTitle}>\n\t\t\t\t\t\tForm Not Found\n\t\t\t\t\t</h2>\n\t\t\t\t\t<p className={styles.errorMessage}>\n\t\t\t\t\t\t{error instanceof Error\n\t\t\t\t\t\t\t? error.message\n\t\t\t\t\t\t\t: \"Form could not be loaded\"}\n\t\t\t\t\t</p>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={() => navigateToForms(projectId)}\n\t\t\t\t\t\tclassName={styles.backButton}\n\t\t\t\t\t>\n\t\t\t\t\t\tBack to Forms\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\t// Render FormBuilder\n\treturn (\n\t\t<div className={className} style={style}>\n\t\t\t<FormBuilder\n\t\t\t\tinitialConfig={formConfig}\n\t\t\t\tonSave={handleSave}\n\t\t\t\tproject={projectId}\n\t\t\t\twizardId={formId}\n\t\t\t\tshowPreviewButton={showPreview}\n\t\t\t\tonNavigateToForms={() => navigateToForms(projectId)}\n\t\t\t/>\n\t\t</div>\n\t);\n};\n","/**\n * TanStack Query hooks for form management\n * Replaces manual caching with robust query management\n */\n\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport type { FormConfig } from \"../../../config/types\";\nimport {\n\tcreateForm,\n\tdeleteForm,\n\tscanFormsDirectory,\n} from \"../../../utils/formsExplorer\";\n\n// Query keys for cache management\nexport const formsQueryKeys = {\n\tall: [\"forms\"] as const,\n\tprojects: () => [...formsQueryKeys.all, \"projects\"] as const,\n\tproject: (projectId: string) =>\n\t\t[...formsQueryKeys.projects(), projectId] as const,\n\tform: (projectId: string, formId: string) =>\n\t\t[...formsQueryKeys.project(projectId), formId] as const,\n};\n\ninterface UseFormsQueryOptions {\n\tconfig?: FormConfig;\n}\n\n/**\n * Query hook for fetching all projects and forms\n * Replaces useFormExplorerState with automatic caching and background updates\n */\nexport function useFormsQuery({ config }: UseFormsQueryOptions = {}) {\n\treturn useQuery({\n\t\tqueryKey: formsQueryKeys.projects(),\n\t\tqueryFn: async () => {\n\t\t\tconst operationsConfig = config ? { formConfig: config } : {};\n\t\t\tconst result = await scanFormsDirectory(operationsConfig);\n\t\t\treturn result.projects;\n\t\t},\n\t\tstaleTime: 30000, // Consider data fresh for 30 seconds\n\t\trefetchOnWindowFocus: true, // Refetch when user returns to tab\n\t\trefetchOnMount: true, // Always refetch on component mount\n\t});\n}\n\n/**\n * Mutation hook for creating forms with optimistic updates\n */\nexport function useCreateFormMutation() {\n\tconst queryClient = useQueryClient();\n\n\treturn useMutation({\n\t\tmutationFn: async (request: {\n\t\t\tprojectId: string;\n\t\t\tformId: string;\n\t\t\ttitle: string;\n\t\t\tdescription?: string;\n\t\t}) => {\n\t\t\tconst result = await createForm(request);\n\t\t\tif (!result) {\n\t\t\t\tthrow new Error(\"Failed to create form\");\n\t\t\t}\n\t\t\treturn { ...request, config: result };\n\t\t},\n\n\t\t// Optimistic update: immediately add form to cache\n\t\tonMutate: async (newForm) => {\n\t\t\t// Cancel outgoing refetches so they don't overwrite optimistic update\n\t\t\tawait queryClient.cancelQueries({ queryKey: formsQueryKeys.projects() });\n\n\t\t\t// Snapshot previous value for rollback\n\t\t\tconst previousProjects = queryClient.getQueryData(\n\t\t\t\tformsQueryKeys.projects()\n\t\t\t);\n\n\t\t\t// Optimistically update cache\n\t\t\tqueryClient.setQueryData(formsQueryKeys.projects(), (old: any) => {\n\t\t\t\tif (!old) return old;\n\n\t\t\t\treturn old.map((project: any) =>\n\t\t\t\t\tproject.id === newForm.projectId\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t...project,\n\t\t\t\t\t\t\t\tforms: [\n\t\t\t\t\t\t\t\t\t...project.forms,\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tid: newForm.formId,\n\t\t\t\t\t\t\t\t\t\ttitle: newForm.title,\n\t\t\t\t\t\t\t\t\t\tfileName: `${newForm.formId}.json`,\n\t\t\t\t\t\t\t\t\t\tdescription: newForm.description || \"\",\n\t\t\t\t\t\t\t\t\t\tlastModified: Date.now(),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: project\n\t\t\t\t);\n\t\t\t});\n\n\t\t\treturn { previousProjects };\n\t\t},\n\n\t\t// On error, rollback optimistic update\n\t\tonError: (_err, _newForm, context) => {\n\t\t\tif (context?.previousProjects) {\n\t\t\t\tqueryClient.setQueryData(\n\t\t\t\t\tformsQueryKeys.projects(),\n\t\t\t\t\tcontext.previousProjects\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\n\t\t// Always refetch after mutation to ensure data consistency\n\t\tonSettled: () => {\n\t\t\tqueryClient.invalidateQueries({ queryKey: formsQueryKeys.projects() });\n\t\t},\n\t});\n}\n\n/**\n * Mutation hook for deleting forms with optimistic updates\n */\nexport function useDeleteFormMutation() {\n\tconst queryClient = useQueryClient();\n\n\treturn useMutation({\n\t\tmutationFn: async ({\n\t\t\tprojectId,\n\t\t\tformId,\n\t\t}: {\n\t\t\tprojectId: string;\n\t\t\tformId: string;\n\t\t}) => {\n\t\t\tconst success = await deleteForm(projectId, formId);\n\t\t\tif (!success) {\n\t\t\t\tthrow new Error(\"Failed to delete form\");\n\t\t\t}\n\t\t\treturn { projectId, formId };\n\t\t},\n\n\t\t// Optimistic update: immediately remove form from cache\n\t\tonMutate: async ({ projectId, formId }) => {\n\t\t\tawait queryClient.cancelQueries({ queryKey: formsQueryKeys.projects() });\n\n\t\t\tconst previousProjects = queryClient.getQueryData(\n\t\t\t\tformsQueryKeys.projects()\n\t\t\t);\n\n\t\t\t// Optimistically update cache\n\t\t\tqueryClient.setQueryData(formsQueryKeys.projects(), (old: any) => {\n\t\t\t\tif (!old) return old;\n\n\t\t\t\treturn old.map((project: any) =>\n\t\t\t\t\tproject.id === projectId\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t...project,\n\t\t\t\t\t\t\t\tforms: project.forms.filter((form: any) => form.id !== formId),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: project\n\t\t\t\t);\n\t\t\t});\n\n\t\t\treturn { previousProjects };\n\t\t},\n\n\t\t// On error, rollback optimistic update\n\t\tonError: (_err, _variables, context) => {\n\t\t\tif (context?.previousProjects) {\n\t\t\t\tqueryClient.setQueryData(\n\t\t\t\t\tformsQueryKeys.projects(),\n\t\t\t\t\tcontext.previousProjects\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\n\t\t// Always refetch to ensure data consistency with database\n\t\tonSettled: () => {\n\t\t\tqueryClient.invalidateQueries({ queryKey: formsQueryKeys.projects() });\n\t\t},\n\t});\n}\n\n/**\n * Hook to force refresh all form data\n * Useful for manual sync when needed\n */\nexport function useRefreshForms() {\n\tconst queryClient = useQueryClient();\n\n\treturn () => {\n\t\tqueryClient.invalidateQueries({ queryKey: formsQueryKeys.projects() });\n\t};\n}\n","import { Heading } from \"@formbuilder/design-system\";\nimport styles from \"./BaseHeader.module.css\";\n\nconst APP_NAME = \"Formeel\";\n\nexport const BaseHeader = () => {\n\treturn (\n\t\t<div className={styles.headerContainer}>\n\t\t\t<div className={styles.headerContent}>\n\t\t\t\t<Heading level={4}>{APP_NAME}</Heading>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n","/**\n * BaseLayout - Generic layout component for consistent navigation structure\n * Provides header, breadcrumb navigation, and content area\n */\n\nimport {\n\tButton,\n\ttype ButtonProps,\n\tHeading,\n\tParagraph,\n} from \"@formbuilder/design-system\";\nimport { ChevronLeft, Plus } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\nimport { BaseHeader } from \"../BaseHeader/BaseHeader\";\nimport styles from \"./BaseLayout.module.css\";\n\nexport interface BaseLayoutProps {\n\t// Header props\n\ttitle: string;\n\tsubtitle?: string;\n\n\t// Navigation props\n\tshowBackButton?: boolean;\n\tonBack?: () => void;\n\tbackButtonText?: string;\n\n\t// Search slot for inline positioning with actions\n\tsearchSlot?: ReactNode;\n\n\t// Action buttons\n\tprimaryAction?: {\n\t\tlabel: string;\n\t\tonClick: () => void;\n\t\ticon?: ReactNode;\n\t};\n\tsecondaryActions?: Array<{\n\t\tlabel: string;\n\t\tonClick: () => void;\n\t\ticon?: ReactNode;\n\t\tvariant?: ButtonProps[\"appearance\"];\n\t}>;\n\n\t// Loading state\n\tisLoading?: boolean;\n\n\t// Content\n\tchildren: ReactNode;\n\n\t// Styling\n\tclassName?: string;\n}\n\nexport const BaseLayout: React.FC<BaseLayoutProps> = ({\n\ttitle,\n\tsubtitle,\n\tshowBackButton = false,\n\tonBack,\n\tbackButtonText = \"Back\",\n\tsearchSlot,\n\tprimaryAction,\n\tsecondaryActions = [],\n\tisLoading = false,\n\tchildren,\n\tclassName = \"\",\n}) => {\n\treturn (\n\t\t<div className={`form-explorer-layout ${styles.layout} ${className}`}>\n\t\t\t<BaseHeader />\n\t\t\t<div className={styles.canvas}>\n\t\t\t\t{/* Header */}\n\t\t\t\t<div>\n\t\t\t\t\t{showBackButton && onBack && (\n\t\t\t\t\t\t<Button appearance=\"subtle-button\" onClick={onBack}>\n\t\t\t\t\t\t\t<ChevronLeft />\n\t\t\t\t\t\t\t{backButtonText}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\t\t\t\t\t<div className={styles.headerSection}>\n\t\t\t\t\t\t<Heading level={1}>{title}</Heading>\n\t\t\t\t\t\t{subtitle && <Paragraph>{subtitle}</Paragraph>}\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div className={styles.actionsRow}>\n\t\t\t\t\t\t{/* Search Slot - positioned inline with actions */}\n\t\t\t\t\t\t{searchSlot && <div className={styles.searchSlot}>{searchSlot}</div>}\n\n\t\t\t\t\t\t<div className={styles.actionsGroup}>\n\t\t\t\t\t\t\t{/* Secondary Actions */}\n\t\t\t\t\t\t\t{secondaryActions.map((action) => (\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tkey={`secondary-action-${action.label}`}\n\t\t\t\t\t\t\t\t\tappearance={action.variant || \"secondary-action-button\"}\n\t\t\t\t\t\t\t\t\tonClick={action.onClick}\n\t\t\t\t\t\t\t\t\tdisabled={isLoading}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{action.icon}\n\t\t\t\t\t\t\t\t\t{action.label}\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t))}\n\n\t\t\t\t\t\t\t{/* Primary Action */}\n\t\t\t\t\t\t\t{primaryAction && (\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tonClick={primaryAction.onClick}\n\t\t\t\t\t\t\t\t\tappearance=\"primary-action-button\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{primaryAction.icon || <Plus className={`${styles.iconSm} ${styles.mr2}`} />}\n\t\t\t\t\t\t\t\t\t{primaryAction.label}\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t{/* Content */}\n\t\t\t\t<div className={styles.content}>{children}</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n","/**\n * NewFormDialog component - dialog for creating new forms\n */\n\nimport {\n\tButton,\n\tDialog,\n\tDialogContent,\n\tDialogDescription,\n\tDialogFooter,\n\tDialogHeader,\n\tDialogTitle,\n\tInput,\n\tLabel,\n\tTextarea,\n\ttoast,\n} from \"@formbuilder/ui\";\nimport { useForm } from \"@tanstack/react-form\";\nimport { useCallback, useEffect } from \"react\";\nimport { useCreateFormMutation } from \"../../hooks/useFormsQuery\";\nimport styles from \"./NewFormDialog.module.css\";\n\nexport interface NewFormDialogProps {\n\topen: boolean;\n\tonOpenChange: (open: boolean) => void;\n\tselectedProjectId?: string;\n\tonFormCreated?: (projectId: string, formId: string) => void;\n\tonFormAdded?: (\n\t\tprojectId: string,\n\t\tform: { id: string; title: string; description?: string }\n\t) => void;\n\t/** Custom form creation handler — bypasses the default formsExplorer storage path */\n\tonCreateForm?: (request: {\n\t\tprojectId: string;\n\t\tformId: string;\n\t\ttitle: string;\n\t\tdescription?: string;\n\t}) => Promise<{ success: boolean; formId?: string }>;\n}\n\nexport const NewFormDialog: React.FC<NewFormDialogProps> = ({\n\topen,\n\tonOpenChange,\n\tselectedProjectId,\n\tonFormCreated,\n\tonFormAdded,\n\tonCreateForm,\n}) => {\n\t// Use TanStack Query mutation for optimistic updates (fallback path)\n\tconst createFormMutation = useCreateFormMutation();\n\tconst form = useForm({\n\t\tdefaultValues: {\n\t\t\ttitle: \"\",\n\t\t\tdescription: \"\",\n\t\t},\n\t\tonSubmit: async ({ value }) => {\n\t\t\tif (!selectedProjectId) {\n\t\t\t\ttoast.error(\"No project selected\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Generate form ID from title\n\t\t\tconst formId = value.title\n\t\t\t\t.toLowerCase()\n\t\t\t\t.replace(/[^a-z0-9]/g, \"-\")\n\t\t\t\t.replace(/-+/g, \"-\")\n\t\t\t\t.replace(/^-|-$/g, \"\");\n\n\t\t\tconst request = {\n\t\t\t\tprojectId: selectedProjectId,\n\t\t\t\tformId,\n\t\t\t\ttitle: value.title.trim(),\n\t\t\t\tdescription: value.description.trim() || undefined,\n\t\t\t};\n\n\t\t\ttry {\n\t\t\t\tlet resultFormId = formId;\n\n\t\t\t\tif (onCreateForm) {\n\t\t\t\t\tconst result = await onCreateForm(request);\n\t\t\t\t\tif (!result.success) {\n\t\t\t\t\t\ttoast.error(\"Failed to create form\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tresultFormId = result.formId ?? formId;\n\t\t\t\t} else {\n\t\t\t\t\tawait createFormMutation.mutateAsync(request);\n\t\t\t\t}\n\n\t\t\t\ttoast.success(`Form \"${value.title}\" created successfully`);\n\t\t\t\tonOpenChange(false);\n\n\t\t\t\tonFormCreated?.(selectedProjectId, resultFormId);\n\t\t\t\tonFormAdded?.(selectedProjectId, {\n\t\t\t\t\tid: resultFormId,\n\t\t\t\t\ttitle: value.title.trim(),\n\t\t\t\t\tdescription: value.description.trim(),\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Failed to create form:\", error);\n\t\t\t\ttoast.error(\n\t\t\t\t\t\terror instanceof Error ? error.message : \"Failed to create form\",\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t});\n\n\t// Reset form when dialog opens\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tform.reset();\n\t\t}\n\t}, [open, form]);\n\n\tconst handleCancel = useCallback(() => {\n\t\tonOpenChange(false);\n\t}, [onOpenChange]);\n\n\treturn (\n\t\t<Dialog open={open} onOpenChange={onOpenChange}>\n\t\t\t<DialogContent>\n\t\t\t\t<DialogHeader>\n\t\t\t\t\t<DialogTitle>Nieuwe formulier aanmaken</DialogTitle>\n\t\t\t\t\t<DialogDescription>\n\t\t\t\t\t\tVoeg een formulier toe aan een project.{\" \"}\n\t\t\t\t\t</DialogDescription>\n\t\t\t\t</DialogHeader>\n\t\t\t\t<form\n\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\tform.handleSubmit();\n\t\t\t\t\t}}\n\t\t\t\t\tclassName={styles.formBody}\n\t\t\t\t>\n\t\t\t\t\t<div className={styles.fieldGroup}>\n\t\t\t\t\t\t<form.Field\n\t\t\t\t\t\t\tname=\"title\"\n\t\t\t\t\t\t\tvalidators={{\n\t\t\t\t\t\t\t\tonChange: ({ value }) =>\n\t\t\t\t\t\t\t\t\t!value.trim() ? \"Form title is required\" : undefined,\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{(field) => (\n\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t<Label htmlFor=\"form-title\">Formulier titel</Label>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\tid=\"form-title\"\n\t\t\t\t\t\t\t\t\t\tvalue={field.state.value}\n\t\t\t\t\t\t\t\t\t\tonChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n\t\t\t\t\t\t\t\t\t\t\tfield.handleChange(e.target.value)\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tplaceholder=\"bijv. 'Nieuwe medewerker aanmaken'\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t{field.state.meta.errors?.length > 0 && (\n\t\t\t\t\t\t\t\t\t\t<p className={styles.fieldError}>\n\t\t\t\t\t\t\t\t\t\t\t{field.state.meta.errors[0]}\n\t\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</form.Field>\n\n\t\t\t\t\t\t<form.Field name=\"description\">\n\t\t\t\t\t\t\t{(field) => (\n\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t<Label htmlFor=\"form-description\">\n\t\t\t\t\t\t\t\t\t\tBeschrijving (Optioneel)\n\t\t\t\t\t\t\t\t\t</Label>\n\t\t\t\t\t\t\t\t\t<Textarea\n\t\t\t\t\t\t\t\t\t\tid=\"form-description\"\n\t\t\t\t\t\t\t\t\t\tvalue={field.state.value}\n\t\t\t\t\t\t\t\t\t\tonChange={(e: React.ChangeEvent<HTMLTextAreaElement>) =>\n\t\t\t\t\t\t\t\t\t\t\tfield.handleChange(e.target.value)\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tplaceholder=\"bijv. 'Proces om een nieuwe medewerker aan te melden in het systeem'\"\n\t\t\t\t\t\t\t\t\t\trows={3}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</form.Field>\n\t\t\t\t\t</div>\n\t\t\t\t\t<DialogFooter>\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={handleCancel}\n\t\t\t\t\t\t\tdisabled={createFormMutation.isPending}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tAnnuleren\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t<Button type=\"submit\" disabled={createFormMutation.isPending}>\n\t\t\t\t\t\t\t{createFormMutation.isPending\n\t\t\t\t\t\t\t\t? \"Aanmaken...\"\n\t\t\t\t\t\t\t\t: \"Formulier aanmaken\"}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</DialogFooter>\n\t\t\t\t</form>\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n};\n","/**\n * SearchInput - Reusable search input component for views\n */\n\nimport { Input } from \"@formbuilder/ui\";\nimport { Search } from \"lucide-react\";\nimport { useState } from \"react\";\nimport styles from \"./SearchInput.module.css\";\n\nexport interface SearchInputProps {\n\tplaceholder?: string;\n\tonSearchChange: (query: string) => void;\n\tclassName?: string;\n}\n\nexport const SearchInput: React.FC<SearchInputProps> = ({\n\tplaceholder = \"Search...\",\n\tonSearchChange,\n\tclassName = \"\",\n}) => {\n\tconst [searchValue, setSearchValue] = useState(\"\");\n\n\tconst handleSearchChange = (value: string) => {\n\t\tsetSearchValue(value);\n\t\tonSearchChange(value);\n\t};\n\n\treturn (\n\t\t<div className={`${styles.searchWrapper}${className ? ` ${className}` : \"\"}`}>\n\t\t\t<Search className={styles.searchIcon} />\n\t\t\t<Input\n\t\t\t\ttype=\"text\"\n\t\t\t\tplaceholder={placeholder}\n\t\t\t\tvalue={searchValue}\n\t\t\t\tonChange={(e) => handleSearchChange(e.target.value)}\n\t\t\t\tclassName={styles.searchField}\n\t\t\t/>\n\t\t</div>\n\t);\n};\n","/**\n * ViewCard - Generic card component for different view types (projects, forms, etc.)\n *\n * This component provides a consistent card layout across all view types with:\n * - Configurable icon and title\n * - Optional description text\n * - Flexible metadata display (e.g., creation date, item count)\n * - Dropdown menu with customizable actions\n * - Primary action button at the bottom\n *\n * Usage examples:\n * - ProjectsView: Folder icon, project name, creation date + form count, delete action, open button\n * - FormsView: File icon, form title, creation date + form count, edit/delete actions, open button\n * - FlowsView: Can be used instead of table layout for card-based view\n */\n\nimport {\n\ttype ButtonProps,\n\tHeading,\n\tButton as RhcButton,\n} from \"@formbuilder/design-system\";\nimport {\n\tButton,\n\tCard,\n\tCardContent,\n\tCardDescription,\n\tCardHeader,\n\tDropdownMenu,\n\tDropdownMenuContent,\n\tDropdownMenuItem,\n\tDropdownMenuTrigger,\n} from \"@formbuilder/ui\";\nimport { MoreVertical } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\nimport styles from \"./ViewCard.module.css\";\n\nexport interface ViewCardMetaData {\n\tlabel: string;\n\tvalue: string | number;\n}\n\nexport interface ViewCardAction {\n\tlabel?: string;\n\ticon?: ReactNode;\n\tonClick: () => void;\n\tappearance?: ButtonProps[\"appearance\"];\n\tclassName?: string;\n}\n\nexport interface ViewCardDropdownAction {\n\tlabel?: string;\n\ticon?: ReactNode;\n\tonClick: () => void;\n\tvariant?: \"default\" | \"destructive\";\n\tclassName?: string;\n\tdisabled?: boolean;\n}\n\nexport interface ViewCardProps {\n\t/** Icon to display next to the title */\n\ticon: ReactNode;\n\t/** Main title of the card */\n\ttitle: string;\n\t/** Optional description text */\n\tdescription?: string;\n\t/** Array of metadata items to display */\n\tmetadata?: ViewCardMetaData[];\n\t/** Dropdown menu actions (appears in top-right) */\n\tdropdownActions?: ViewCardDropdownAction[];\n\t/** Primary action button (appears at bottom) */\n\tprimaryAction?: ViewCardAction;\n\t/** Additional CSS classes */\n\tclassName?: string;\n\t/** Click handler for the entire card */\n\tonClick?: () => void;\n}\n\nexport const ViewCard: React.FC<ViewCardProps> = ({\n\ticon,\n\ttitle,\n\tdescription,\n\tmetadata = [],\n\tdropdownActions = [],\n\tprimaryAction,\n\tclassName = \"\",\n\tonClick,\n}) => {\n\treturn (\n\t\t<Card\n\t\t\tclassName={`${styles.card} ${onClick ? styles.cardClickable : \"\"} ${className}`}\n\t\t\tonClick={onClick}\n\t\t>\n\t\t\t<CardHeader>\n\t\t\t\t<div className={styles.cardHeaderRow}>\n\t\t\t\t\t<div className={styles.cardTitleGroup}>\n\t\t\t\t\t\t{icon}\n\t\t\t\t\t\t<div className={styles.cardTitleContainer}>\n\t\t\t\t\t\t\t<Heading level={2}>{title}</Heading>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t{dropdownActions.length > 0 && (\n\t\t\t\t\t\t<DropdownMenu>\n\t\t\t\t\t\t\t<DropdownMenuTrigger asChild>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\tonClick={(e) => e.stopPropagation()}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<MoreVertical className={styles.iconSm} />\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</DropdownMenuTrigger>\n\t\t\t\t\t\t\t<DropdownMenuContent align=\"end\">\n\t\t\t\t\t\t\t\t{dropdownActions.map((action) => (\n\t\t\t\t\t\t\t\t\t<DropdownMenuItem\n\t\t\t\t\t\t\t\t\t\tkey={action.label}\n\t\t\t\t\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\t\t\t\t\tif (!action.disabled) {\n\t\t\t\t\t\t\t\t\t\t\t\taction.onClick();\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\tdisabled={action.disabled}\n\t\t\t\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\t\t\t\taction.variant === \"destructive\"\n\t\t\t\t\t\t\t\t\t\t\t\t? \"text-red-600\"\n\t\t\t\t\t\t\t\t\t\t\t\t: action.className\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{action.icon}\n\t\t\t\t\t\t\t\t\t\t{action.label}\n\t\t\t\t\t\t\t\t\t</DropdownMenuItem>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</DropdownMenuContent>\n\t\t\t\t\t\t</DropdownMenu>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t{(metadata.length > 0 || description) && (\n\t\t\t\t\t<div className={styles.metadataSection}>\n\t\t\t\t\t\t{metadata.map((meta) => (\n\t\t\t\t\t\t\t<CardDescription\n\t\t\t\t\t\t\t\tkey={`${meta.label}-${meta.value}`}\n\t\t\t\t\t\t\t\tclassName={styles.metadataText}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{meta.label}: {meta.value}\n\t\t\t\t\t\t\t</CardDescription>\n\t\t\t\t\t\t))}\n\t\t\t\t\t\t{description && (\n\t\t\t\t\t\t\t<CardDescription className={styles.descriptionText}>\n\t\t\t\t\t\t\t\t{description}\n\t\t\t\t\t\t\t</CardDescription>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</CardHeader>\n\t\t\t{primaryAction && (\n\t\t\t\t<CardContent className={styles.cardFooter}>\n\t\t\t\t\t<RhcButton\n\t\t\t\t\t\tonClick={(e: React.MouseEvent) => {\n\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\tprimaryAction.onClick();\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tclassName={`${primaryAction.className || \"\"}`}\n\t\t\t\t\t\tappearance={primaryAction.appearance || \"primary-action-button\"}\n\t\t\t\t\t>\n\t\t\t\t\t\t{primaryAction.icon}\n\t\t\t\t\t\t{primaryAction.label}\n\t\t\t\t\t</RhcButton>\n\t\t\t\t</CardContent>\n\t\t\t)}\n\t\t</Card>\n\t);\n};\n","/**\n * FormsView with TanStack Query - Example implementation\n * Demonstrates how to replace manual state management with TanStack Query\n */\n\nimport { useFormNavigation } from \"@formbuilder/forms/navigation\";\nimport { Button } from \"@formbuilder/ui\";\nimport { ChevronRight, FileText, Plus, Settings, Trash2 } from \"lucide-react\";\nimport { useState } from \"react\";\nimport { useDeleteFormMutation, useFormsQuery } from \"../../hooks/useFormsQuery\";\nimport { BaseLayout } from \"../../layout/BaseLayout/BaseLayout\";\nimport { NewFormDialog } from \"../NewFormDialog/NewFormDialog\";\nimport { SearchInput } from \"../SearchInput/SearchInput\";\nimport { ViewCard } from \"../ViewCard/ViewCard\";\nimport styles from \"./FormsView.module.css\";\n\nexport interface FormsViewProps {\n\tprojectId: string;\n\t/** If provided, used instead of internal TanStack Query fetch */\n\tforms?: { id: string; title: string; fileName: string; lastModified: number; description?: string }[];\n\t/** Project name override — used when forms prop is provided */\n\tprojectName?: string;\n\t/** If provided, used instead of internal loading state */\n\tisLoading?: boolean;\n\tonNavigateToProjects?: () => void; // Keep for backward compat but not required\n\tonRefresh?: () => void;\n\t/** Custom form creation handler — bypasses the default formsExplorer storage path */\n\tonCreateForm?: (request: {\n\t\tprojectId: string;\n\t\tformId: string;\n\t\ttitle: string;\n\t\tdescription?: string;\n\t}) => Promise<{ success: boolean; formId?: string }>;\n\tonFormDeleted?: (projectId: string, formId: string) => void;\n\tonFormAdded?: (\n\t\tprojectId: string,\n\t\tform: { id: string; title: string; description?: string }\n\t) => void;\n\tclassName?: string;\n\tstyle?: React.CSSProperties;\n}\n\nconst formatDate = (timestamp?: number): string => {\n\tif (!timestamp) return \"Unknown\";\n\treturn new Date(timestamp).toLocaleDateString();\n};\n\nexport const FormsView: React.FC<FormsViewProps> = ({\n\tprojectId,\n\tforms: formsProp,\n\tprojectName: projectNameProp,\n\tisLoading: isLoadingProp,\n\tonNavigateToProjects,\n\tonRefresh,\n\tonCreateForm,\n\tonFormDeleted,\n\tonFormAdded,\n}) => {\n\tconst [searchQuery, setSearchQuery] = useState(\"\");\n\tconst [showNewFormDialog, setShowNewFormDialog] = useState(false);\n\n\t// Use navigation context\n\tconst { navigateToProjects, navigateToBuilder } = useFormNavigation();\n\n\t// Use TanStack Query for data fetching (skipped when props are provided)\n\tconst internalQuery = useFormsQuery();\n\tconst deleteFormMutation = useDeleteFormMutation();\n\n\t// Find the current project from internal data (when no props override)\n\tconst internalProject = internalQuery.data?.find((p) => p.id === projectId);\n\n\t// Resolve data: props override internal query\n\tconst resolvedForms = formsProp ?? internalProject?.forms ?? [];\n\tconst resolvedProjectName = projectNameProp ?? internalProject?.name;\n\tconst isLoading = isLoadingProp ?? internalQuery.isLoading;\n\tconst error = formsProp ? null : internalQuery.error;\n\tconst projectFound = formsProp !== undefined || internalProject !== undefined;\n\n\t// Filter forms based on search\n\tconst filteredForms = resolvedForms.filter(\n\t\t(form) =>\n\t\t\tform.title.toLowerCase().includes(searchQuery.toLowerCase()) ||\n\t\t\tform.description?.toLowerCase().includes(searchQuery.toLowerCase()) ||\n\t\t\tform.id.toLowerCase().includes(searchQuery.toLowerCase())\n\t);\n\n\t// Action handlers with TanStack Query\n\tconst handleCreateForm = () => {\n\t\tsetShowNewFormDialog(true);\n\t};\n\n\tconst handleFormCreated = (createdProjectId: string, formId: string) => {\n\t\tconsole.log(\"Form created:\", formId);\n\n\t\t// Call the optional callback if provided\n\t\tif (onFormAdded) {\n\t\t\tconst form = resolvedForms.find((f) => f.id === formId);\n\t\t\tif (form) {\n\t\t\t\tonFormAdded(createdProjectId, {\n\t\t\t\t\tid: form.id,\n\t\t\t\t\ttitle: form.title,\n\t\t\t\t\tdescription: form.description,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Call the optional refresh callback if provided\n\t\tonRefresh?.();\n\t};\n\n\tconst handleDeleteForm = async (formId: string) => {\n\t\tconst confirmed = confirm(\n\t\t\t`Are you sure you want to delete the form \"${formId}\"? This action cannot be undone.`\n\t\t);\n\n\t\tif (!confirmed) return;\n\n\t\t// Call optimistic update callback if provided\n\t\tif (onFormDeleted) {\n\t\t\tonFormDeleted(projectId, formId);\n\t\t}\n\n\t\t// Execute mutation - this handles optimistic updates automatically\n\t\ttry {\n\t\t\tawait deleteFormMutation.mutateAsync({\n\t\t\t\tprojectId,\n\t\t\t\tformId,\n\t\t\t});\n\t\t\tconsole.log(`✅ Form deleted: ${projectId}/${formId}`);\n\t\t} catch (error) {\n\t\t\tconsole.error(`❌ Failed to delete form: ${projectId}/${formId}`, error);\n\t\t\t// Error is automatically handled by mutation (rollback optimistic update)\n\t\t}\n\n\t\t// Call refresh callback if provided\n\t\tif (onRefresh) {\n\t\t\tonRefresh();\n\t\t}\n\t};\n\n\tconst handleEditForm = (formId: string) => {\n\t\t// Navigate to form builder using navigation context\n\t\tnavigateToBuilder(projectId, formId);\n\t};\n\n\tconst handleFormClick = (form: {\n\t\tid: string;\n\t\ttitle: string;\n\t\tdescription?: string;\n\t}) => {\n\t\thandleEditForm(form.id);\n\t};\n\n\tconst handleBackToProjects = () => {\n\t\tonNavigateToProjects?.(); // Call callback if provided (backward compat)\n\t\tnavigateToProjects(); // Always navigate via context\n\t};\n\n\t// Handle loading state\n\tif (isLoading) {\n\t\treturn (\n\t\t\t<BaseLayout\n\t\t\t\ttitle=\"Loading...\"\n\t\t\t\tsubtitle=\"Loading project data...\"\n\t\t\t\tisLoading={true}\n\t\t\t>\n\t\t\t\t<div>Loading forms...</div>\n\t\t\t</BaseLayout>\n\t\t);\n\t}\n\n\t// Handle error state\n\tif (error) {\n\t\treturn (\n\t\t\t<BaseLayout title=\"Error\" subtitle=\"Failed to load project data\">\n\t\t\t\t<div className={styles.emptyState}>\n\t\t\t\t\t<p className={styles.errorText}>\n\t\t\t\t\t\tFailed to load forms: {error.message}\n\t\t\t\t\t</p>\n\t\t\t\t\t<Button onClick={() => window.location.reload()}>Retry</Button>\n\t\t\t\t</div>\n\t\t\t</BaseLayout>\n\t\t);\n\t}\n\n\t// Handle project not found\n\tif (!isLoading && !projectFound) {\n\t\treturn (\n\t\t\t<BaseLayout\n\t\t\t\ttitle=\"Project Not Found\"\n\t\t\t\tsubtitle=\"The requested project could not be found\"\n\t\t\t>\n\t\t\t\t<div className={styles.emptyState}>\n\t\t\t\t\t<p className={styles.notFoundText}>\n\t\t\t\t\t\tProject with ID \"{projectId}\" was not found.\n\t\t\t\t\t</p>\n\t\t\t\t\t<Button onClick={handleBackToProjects}>Back to Projects</Button>\n\t\t\t\t</div>\n\t\t\t</BaseLayout>\n\t\t);\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t<BaseLayout\n\t\t\t\ttitle={resolvedProjectName ?? projectId}\n\t\t\t\tsubtitle=\"Maak en beheer projecten en de instellingen\"\n\t\t\t\tshowBackButton\n\t\t\t\tonBack={handleBackToProjects}\n\t\t\t\tbackButtonText=\"Terug naar Projecten\"\n\t\t\t\tsearchSlot={\n\t\t\t\t\t<SearchInput\n\t\t\t\t\t\tplaceholder=\"Zoek op formuliernaam\"\n\t\t\t\t\t\tonSearchChange={setSearchQuery}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t\tprimaryAction={{\n\t\t\t\t\tlabel: \"Formulier toevoegen\",\n\t\t\t\t\tonClick: handleCreateForm,\n\t\t\t\t\ticon: <Plus className={`${styles.iconSm} ${styles.mr2}`} />,\n\t\t\t\t}}\n\t\t\t\tisLoading={deleteFormMutation.isPending}\n\t\t\t>\n\t\t\t\t{/* Forms Grid */}\n\t\t\t\t{filteredForms.length > 0 ? (\n\t\t\t\t\t<div className={styles.formsGrid}>\n\t\t\t\t\t\t{filteredForms.map((form) => (\n\t\t\t\t\t\t\t<ViewCard\n\t\t\t\t\t\t\t\tkey={form.id}\n\t\t\t\t\t\t\t\ticon={<FileText className={`${styles.iconMd} ${styles.shrink0}`} />}\n\t\t\t\t\t\t\t\ttitle={form.title}\n\t\t\t\t\t\t\t\tdescription={form.description}\n\t\t\t\t\t\t\t\tmetadata={[\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tlabel: \"Aanmaakdatum\",\n\t\t\t\t\t\t\t\t\t\tvalue: formatDate(form.lastModified),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t// { label: \"Formulieren\", value: 3 },\n\t\t\t\t\t\t\t\t]}\n\t\t\t\t\t\t\t\tdropdownActions={[\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tlabel: \"Edit Form\",\n\t\t\t\t\t\t\t\t\t\ticon: <Settings className={`${styles.iconSm} ${styles.mr2}`} />,\n\t\t\t\t\t\t\t\t\t\tonClick: () => handleEditForm(form.id),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tlabel: \"Delete Form\",\n\t\t\t\t\t\t\t\t\t\ticon: <Trash2 className={`${styles.iconSm} ${styles.mr2}`} />,\n\t\t\t\t\t\t\t\t\t\tonClick: () => handleDeleteForm(form.id),\n\t\t\t\t\t\t\t\t\t\tvariant: \"destructive\",\n\t\t\t\t\t\t\t\t\t\tdisabled: deleteFormMutation.isPending,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t]}\n\t\t\t\t\t\t\t\tprimaryAction={{\n\t\t\t\t\t\t\t\t\ticon: <ChevronRight className={styles.iconSm} />,\n\t\t\t\t\t\t\t\t\tonClick: () => handleFormClick(form),\n\t\t\t\t\t\t\t\t\tappearance: \"secondary-action-button\",\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t) : (\n\t\t\t\t\t<div className={styles.emptyState}>\n\t\t\t\t\t\t<FileText className={`${styles.icon3xl} ${styles.mxAuto} ${styles.mb4}`} />\n\t\t\t\t\t\t<h3 className={styles.emptyStateTitle}>\n\t\t\t\t\t\t\tGeen formulieren gevonden\n\t\t\t\t\t\t</h3>\n\t\t\t\t\t\t<p className={styles.emptyStateText}>\n\t\t\t\t\t\t\t{searchQuery\n\t\t\t\t\t\t\t\t? \"Geen formulieren komen overeen met je zoekopdracht.\"\n\t\t\t\t\t\t\t\t: \"Maak je eerste formulier om te beginnen.\"}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t{!searchQuery && (\n\t\t\t\t\t\t\t<Button onClick={handleCreateForm}>\n\t\t\t\t\t\t\t\t<Plus className={`${styles.iconSm} ${styles.mr2}`} />\n\t\t\t\t\t\t\t\tFormulier aanmaken\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</BaseLayout>\n\n\t\t\t{/* New Form Dialog */}\n\t\t\t<NewFormDialog\n\t\t\t\topen={showNewFormDialog}\n\t\t\t\tonOpenChange={setShowNewFormDialog}\n\t\t\t\tselectedProjectId={projectId}\n\t\t\t\tonFormCreated={handleFormCreated}\n\t\t\t\tonCreateForm={onCreateForm}\n\t\t\t/>\n\t\t</>\n\t);\n};\n","/**\n * useProjectActions - Hook providing centralized project operations\n * Eliminates prop drilling by directly accessing storage layer functions\n */\n\nimport { useFormNavigation } from \"@formbuilder/forms/navigation\";\nimport type { CreateProjectRequest } from \"@formbuilder/core\";\nimport { useCallback } from \"react\";\nimport { StorageProviderFactory } from \"../../../storage/StorageProviderFactory\";\nimport { createProject, deleteForm } from \"../../../utils/formsExplorer\";\n\nexport interface UseProjectActionsReturn {\n\t/**\n\t * Create a new project\n\t */\n\tcreateProject: (request: CreateProjectRequest) => Promise<boolean>;\n\n\t/**\n\t * Delete a project by deleting all its forms\n\t * Note: Some storage providers may have direct project deletion methods\n\t */\n\tdeleteProject: (projectId: string) => Promise<boolean>;\n\n\t/**\n\t * Delete a specific form from a project\n\t */\n\tdeleteForm: (projectId: string, formId: string) => Promise<boolean>;\n\n\t/**\n\t * Navigate to a project's forms view (navigation helper)\n\t */\n\tnavigateToProject: (projectId: string) => void;\n}\n\n/**\n * Hook providing centralized project and form operations\n * Uses the storage layer directly to avoid prop drilling\n */\nexport function useProjectActions(): UseProjectActionsReturn {\n\tconst { navigateToForms } = useFormNavigation();\n\n\tconst handleCreateProject = useCallback(\n\t\tasync (request: CreateProjectRequest): Promise<boolean> => {\n\t\t\ttry {\n\t\t\t\tconsole.log(\"🔄 Creating project via hook:\", request.name);\n\t\t\t\tconst result = await createProject(request);\n\n\t\t\t\tif (result.success) {\n\t\t\t\t\tconsole.log(\"✅ Project created successfully:\", request.name);\n\t\t\t\t\treturn true;\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(\"❌ Failed to create project:\", request.name);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"❌ Exception during project creation:\", error);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\t[]\n\t);\n\n\tconst handleDeleteProject = useCallback(\n\t\tasync (projectId: string): Promise<boolean> => {\n\t\t\ttry {\n\t\t\t\tconsole.log(\"🔄 Deleting project via hook:\", projectId);\n\n\t\t\t\t// Get the current storage provider directly from factory to avoid creating new instances\n\t\t\t\tconst factory = StorageProviderFactory.getInstance();\n\t\t\t\tconst storageProvider = factory.getCurrentProvider();\n\n\t\t\t\tif (!storageProvider) {\n\t\t\t\t\tconsole.error(\"❌ No storage provider available\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t`🔍 Using existing storage provider: ${storageProvider.getType()}`\n\t\t\t\t);\n\n\t\t\t\t// Try using direct project deletion if supported\n\t\t\t\tif (storageProvider.deleteProject) {\n\t\t\t\t\tconsole.log(`🎯 Using direct project deletion for: ${projectId}`);\n\t\t\t\t\tconst deleteResult = await storageProvider.deleteProject(projectId);\n\n\t\t\t\t\tif (deleteResult.success) {\n\t\t\t\t\t\tconsole.log(`✅ Successfully deleted project: ${projectId}`);\n\t\t\t\t\t\tif (deleteResult.data) {\n\t\t\t\t\t\t\tconsole.log(`📊 Deletion stats:`, deleteResult.data);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t`❌ Direct project deletion failed: ${deleteResult.error}`\n\t\t\t\t\t\t);\n\t\t\t\t\t\t// Fall back to form-by-form deletion\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t`⚠️ Storage provider doesn't support direct project deletion, falling back to form-by-form deletion`\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Fallback: Delete forms individually (legacy approach)\n\t\t\t\tconsole.log(\n\t\t\t\t\t`🔄 Falling back to form-by-form deletion for project: ${projectId}`\n\t\t\t\t);\n\n\t\t\t\t// Get the forms directly from the storage provider\n\t\t\t\tconst formsResult = await storageProvider.listForms();\n\t\t\t\tif (!formsResult.success || !formsResult.data) {\n\t\t\t\t\tconsole.error(\"❌ Failed to list forms from storage provider\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// Filter forms for this project (excluding empty project placeholders)\n\t\t\t\tconst projectForms = formsResult.data.filter((form) => {\n\t\t\t\t\tif (form.wizardId === \"__empty_project__\") {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\treturn form.project === projectId;\n\t\t\t\t});\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t`📋 Found ${projectForms.length} forms to delete in project ${projectId}`\n\t\t\t\t);\n\t\t\t\tconsole.log(\n\t\t\t\t\t`🔍 Forms in project: ${projectForms.map((f) => f.wizardId).join(\", \")}`\n\t\t\t\t);\n\n\t\t\t\t// Delete each form directly using the storage provider\n\t\t\t\tlet deletedCount = 0;\n\t\t\t\tfor (const form of projectForms) {\n\t\t\t\t\tif (storageProvider.deleteForm) {\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t`🗑️ Attempting to delete form: ${projectId}/${form.wizardId}`\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst deleteResult = await storageProvider.deleteForm(\n\t\t\t\t\t\t\tprojectId,\n\t\t\t\t\t\t\tform.wizardId\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (deleteResult.success) {\n\t\t\t\t\t\t\tdeletedCount++;\n\t\t\t\t\t\t\tconsole.log(`✅ Deleted form: ${form.wizardId}`);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t\t`❌ Failed to delete form: ${form.wizardId}`,\n\t\t\t\t\t\t\t\tdeleteResult.error\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst success = deletedCount === projectForms.length;\n\t\t\t\tif (success) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t`✅ Successfully deleted project ${projectId} (${deletedCount} forms)`\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`⚠️ Partial deletion: ${deletedCount}/${projectForms.length} forms deleted`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn success;\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"❌ Exception during project deletion:\", error);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\t[]\n\t);\n\n\tconst handleDeleteForm = useCallback(\n\t\tasync (projectId: string, formId: string): Promise<boolean> => {\n\t\t\ttry {\n\t\t\t\tconsole.log(\"🔄 Deleting form via hook:\", `${projectId}/${formId}`);\n\t\t\t\tconst success = await deleteForm(projectId, formId);\n\n\t\t\t\tif (success) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\"✅ Form deleted successfully:\",\n\t\t\t\t\t\t`${projectId}/${formId}`\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(\"❌ Failed to delete form:\", `${projectId}/${formId}`);\n\t\t\t\t}\n\n\t\t\t\treturn success;\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"❌ Exception during form deletion:\", error);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\t[]\n\t);\n\n\tconst handleNavigateToProject = useCallback(\n\t\t(projectId: string): void => {\n\t\t\t// Navigate to the project's forms view using navigation context\n\t\t\tconsole.log(\"🔄 Navigating to project:\", projectId);\n\t\t\tnavigateToForms(projectId);\n\t\t},\n\t\t[navigateToForms]\n\t);\n\n\treturn {\n\t\tcreateProject: handleCreateProject,\n\t\tdeleteProject: handleDeleteProject,\n\t\tdeleteForm: handleDeleteForm,\n\t\tnavigateToProject: handleNavigateToProject,\n\t};\n}\n","/**\n * TanStack Query hook for projects data fetching\n * Follows the pattern of useFormsQuery.ts\n */\n\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { FormConfig } from \"../../../config/types\";\nimport { scanFormsDirectory } from \"../../../utils/formsExplorer\";\n\n// Query keys for cache management\nexport const projectsQueryKeys = {\n\tall: [\"projects\"] as const,\n};\n\ninterface UseProjectsDataOptions {\n\tconfig?: FormConfig;\n}\n\n/**\n * Query hook for fetching all projects\n * Provides automatic caching and background updates via TanStack Query\n */\nexport function useProjectsData({ config }: UseProjectsDataOptions = {}) {\n\treturn useQuery({\n\t\tqueryKey: projectsQueryKeys.all,\n\t\tqueryFn: async () => {\n\t\t\tconst operationsConfig = config ? { formConfig: config } : {};\n\t\t\tconst result = await scanFormsDirectory(operationsConfig);\n\t\t\treturn result.projects;\n\t\t},\n\t\tstaleTime: 30000, // Consider data fresh for 30 seconds\n\t\trefetchOnWindowFocus: true, // Refetch when user returns to tab\n\t\trefetchOnMount: true, // Always refetch on component mount\n\t});\n}\n","/**\n * NewProjectDialog component - dialog for creating new projects\n */\n\nimport {\n\tButton,\n\tDialog,\n\tDialogContent,\n\tDialogDescription,\n\tDialogFooter,\n\tDialogHeader,\n\tDialogTitle,\n\tInput,\n\tLabel,\n\tTextarea,\n\ttoast,\n} from \"@formbuilder/ui\";\nimport { useForm } from \"@tanstack/react-form\";\nimport { useCallback, useEffect } from \"react\";\nimport { createProject } from \"../../../../utils/formsExplorer\";\nimport styles from \"./NewProjectDialog.module.css\";\n\nexport interface NewProjectDialogProps {\n\topen: boolean;\n\tonOpenChange: (open: boolean) => void;\n\tonProjectCreated?: (projectData?: {\n\t\tprojectId: string;\n\t\tname: string;\n\t\tdescription?: string;\n\t}) => void;\n\t/** Custom project creation handler — bypasses the default formsExplorer storage path */\n\tonCreateProject?: (request: {\n\t\tname: string;\n\t\tdescription?: string;\n\t}) => Promise<{\n\t\tsuccess: boolean;\n\t\tprojectId?: string;\n\t\tname?: string;\n\t\tdescription?: string;\n\t}>;\n}\n\nexport const NewProjectDialog: React.FC<NewProjectDialogProps> = ({\n\topen,\n\tonOpenChange,\n\tonProjectCreated,\n\tonCreateProject,\n}) => {\n\tconst form = useForm({\n\t\tdefaultValues: {\n\t\t\tname: \"\",\n\t\t\tdescription: \"\",\n\t\t},\n\t\tonSubmit: async ({ value }) => {\n\t\t\ttry {\n\t\t\t\tconst request = {\n\t\t\t\t\tname: value.name.trim(),\n\t\t\t\t\tdescription: value.description.trim() || undefined,\n\t\t\t\t};\n\n\t\t\t\tconst result = onCreateProject\n\t\t\t\t\t? await onCreateProject(request)\n\t\t\t\t\t: await createProject(request);\n\n\t\t\t\tif (result.success) {\n\t\t\t\t\ttoast.success(`Project \"${value.name}\" created successfully`);\n\t\t\t\t\tonOpenChange(false);\n\t\t\t\t\tonProjectCreated?.({\n\t\t\t\t\t\tprojectId: result.projectId ?? \"unknown\",\n\t\t\t\t\t\tname: result.name ?? request.name,\n\t\t\t\t\t\tdescription: result.description,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\ttoast.error(\"Failed to create project\");\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Failed to create project:\", error);\n\t\t\t\ttoast.error(\n\t\t\t\t\terror instanceof Error ? error.message : \"Failed to create project\",\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t});\n\n\t// Reset form when dialog opens\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tform.reset();\n\t\t}\n\t}, [open, form]);\n\n\tconst handleCancel = useCallback(() => {\n\t\tonOpenChange(false);\n\t}, [onOpenChange]);\n\n\treturn (\n\t\t<Dialog open={open} onOpenChange={onOpenChange}>\n\t\t\t<DialogContent>\n\t\t\t\t<DialogHeader>\n\t\t\t\t\t<DialogTitle>Create New Project</DialogTitle>\n\t\t\t\t\t<DialogDescription>\n\t\t\t\t\t\tCreate a new project to organize your forms.\n\t\t\t\t\t</DialogDescription>\n\t\t\t\t</DialogHeader>\n\t\t\t\t<form\n\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\tform.handleSubmit();\n\t\t\t\t\t}}\n\t\t\t\t\tclassName={styles.formBody}\n\t\t\t\t>\n\t\t\t\t\t<div className={styles.fieldGroup}>\n\t\t\t\t\t\t<form.Field\n\t\t\t\t\t\t\tname=\"name\"\n\t\t\t\t\t\t\tvalidators={{\n\t\t\t\t\t\t\t\tonChange: ({ value }) =>\n\t\t\t\t\t\t\t\t\t!value.trim() ? \"Project name is required\" : undefined,\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{(field) => (\n\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t<Label htmlFor=\"project-name\">Project Name</Label>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\tid=\"project-name\"\n\t\t\t\t\t\t\t\t\t\tvalue={field.state.value}\n\t\t\t\t\t\t\t\t\t\tonChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n\t\t\t\t\t\t\t\t\t\t\tfield.handleChange(e.target.value)\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tplaceholder=\"Enter project name\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t{field.state.meta.errors?.length > 0 && (\n\t\t\t\t\t\t\t\t\t\t<p className={styles.fieldError}>\n\t\t\t\t\t\t\t\t\t\t\t{field.state.meta.errors[0]}\n\t\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</form.Field>\n\n\t\t\t\t\t\t<form.Field name=\"description\">\n\t\t\t\t\t\t\t{(field) => (\n\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t<Label htmlFor=\"project-description\">\n\t\t\t\t\t\t\t\t\t\tDescription (Optional)\n\t\t\t\t\t\t\t\t\t</Label>\n\t\t\t\t\t\t\t\t\t<Textarea\n\t\t\t\t\t\t\t\t\t\tid=\"project-description\"\n\t\t\t\t\t\t\t\t\t\tvalue={field.state.value}\n\t\t\t\t\t\t\t\t\t\tonChange={(e: React.ChangeEvent<HTMLTextAreaElement>) =>\n\t\t\t\t\t\t\t\t\t\t\tfield.handleChange(e.target.value)\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tplaceholder=\"Enter project description...\"\n\t\t\t\t\t\t\t\t\t\trows={3}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</form.Field>\n\t\t\t\t\t</div>\n\t\t\t\t\t<DialogFooter>\n\t\t\t\t\t\t<Button variant=\"outline\" type=\"button\" onClick={handleCancel}>\n\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t<Button type=\"submit\">Create Project</Button>\n\t\t\t\t\t</DialogFooter>\n\t\t\t\t</form>\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n};\n","/**\n * ProjectsView - Main projects overview with cards showing project information\n */\n\nimport type { ProjectMetadata } from \"@formbuilder/core\";\nimport { Button, GridLayout, GridLayoutColumn, toast } from \"@formbuilder/ui\";\nimport { ChevronRight, Folder, Plus, Trash2 } from \"lucide-react\";\nimport { useReducer, useState } from \"react\";\nimport styles from \"./ProjectsView.module.css\";\nimport { ConfirmDialog } from \"../../../dialog-system/components/ConfirmDialog\";\nimport { useProjectActions } from \"../../hooks/useProjectActions\";\nimport { useProjectsData } from \"../../hooks/useProjectsData\";\nimport { BaseLayout } from \"../../layout/BaseLayout/BaseLayout\";\nimport { NewProjectDialog } from \"../NewProjectDialog/NewProjectDialog\";\nimport { SearchInput } from \"../SearchInput/SearchInput\";\nimport { ViewCard } from \"../ViewCard/ViewCard\";\n\nexport interface ProjectsViewProps {\n\t// Optional overrides for backward compatibility with FormExplorerCore\n\tprojects?: ProjectMetadata[]; // If provided, used instead of internal fetch\n\tisLoading?: boolean; // If provided, used instead of internal state\n\tonRefresh?: () => void; // If provided, called alongside internal refetch\n\tonProjectDeleted?: (projectId: string) => void;\n\t/** Custom project creation handler — bypasses the default formsExplorer storage path */\n\tonCreateProject?: (request: {\n\t\tname: string;\n\t\tdescription?: string;\n\t}) => Promise<{\n\t\tsuccess: boolean;\n\t\tprojectId?: string;\n\t\tname?: string;\n\t\tdescription?: string;\n\t}>;\n\tclassName?: string;\n\tstyle?: React.CSSProperties;\n}\n\nconst formatDate = (timestamp?: number): string => {\n\tif (!timestamp) return \"Unknown\";\n\treturn new Date(timestamp).toLocaleDateString();\n};\n\n// Dialog state management with useReducer\ntype DialogState = {\n\tnewProject: boolean;\n\tdeleteConfirm: boolean;\n\tprojectToDelete: ProjectMetadata | null;\n};\n\ntype DialogAction =\n\t| { type: \"OPEN_NEW_PROJECT\" }\n\t| { type: \"CLOSE_NEW_PROJECT\" }\n\t| { type: \"OPEN_DELETE_CONFIRM\"; project: ProjectMetadata }\n\t| { type: \"CLOSE_DELETE_CONFIRM\" }\n\t| { type: \"RESET_ALL\" };\n\nconst dialogReducer = (\n\tstate: DialogState,\n\taction: DialogAction\n): DialogState => {\n\tswitch (action.type) {\n\t\tcase \"OPEN_NEW_PROJECT\":\n\t\t\treturn { ...state, newProject: true };\n\t\tcase \"CLOSE_NEW_PROJECT\":\n\t\t\treturn { ...state, newProject: false };\n\t\tcase \"OPEN_DELETE_CONFIRM\":\n\t\t\treturn { ...state, deleteConfirm: true, projectToDelete: action.project };\n\t\tcase \"CLOSE_DELETE_CONFIRM\":\n\t\t\treturn { ...state, deleteConfirm: false, projectToDelete: null };\n\t\tcase \"RESET_ALL\":\n\t\t\treturn { newProject: false, deleteConfirm: false, projectToDelete: null };\n\t\tdefault:\n\t\t\treturn state;\n\t}\n};\n\nconst initialDialogState: DialogState = {\n\tnewProject: false,\n\tdeleteConfirm: false,\n\tprojectToDelete: null,\n};\n\nexport const ProjectsView: React.FC<ProjectsViewProps> = ({\n\tprojects: projectsProp,\n\tisLoading: isLoadingProp,\n\tonRefresh,\n\tonProjectDeleted,\n\tonCreateProject,\n}) => {\n\tconst [searchQuery, setSearchQuery] = useState(\"\");\n\tconst [dialogState, dispatchDialog] = useReducer(\n\t\tdialogReducer,\n\t\tinitialDialogState\n\t);\n\tconst { deleteProject, navigateToProject } = useProjectActions();\n\n\t// Fetch data internally, but allow props to override\n\tconst internalQuery = useProjectsData();\n\tconst projects = projectsProp ?? internalQuery.data ?? [];\n\tconst isLoading = isLoadingProp ?? internalQuery.isLoading;\n\n\t// Merge internal and external refresh handlers\n\tconst handleRefresh = () => {\n\t\tinternalQuery.refetch();\n\t\tonRefresh?.();\n\t};\n\n\tconst filteredProjects = projects.filter(\n\t\t(project) =>\n\t\t\tproject.name.toLowerCase().includes(searchQuery.toLowerCase()) ||\n\t\t\tproject.description?.toLowerCase().includes(searchQuery.toLowerCase())\n\t);\n\n\t// Action handlers using centralized storage operations\n\tconst handleCreateProject = () => {\n\t\tdispatchDialog({ type: \"OPEN_NEW_PROJECT\" });\n\t};\n\n\tconst handleProjectCreated = () => {\n\t\tdispatchDialog({ type: \"CLOSE_NEW_PROJECT\" });\n\t\thandleRefresh(); // Refresh the projects list\n\t};\n\n\tconst handleDeleteProject = (project: ProjectMetadata) => {\n\t\tdispatchDialog({ type: \"OPEN_DELETE_CONFIRM\", project });\n\t};\n\n\tconst confirmDeleteProject = async () => {\n\t\tif (!dialogState.projectToDelete) return;\n\n\t\tconst projectName = dialogState.projectToDelete.name;\n\t\tconst projectId = dialogState.projectToDelete.id;\n\n\t\ttry {\n\t\t\tconsole.log(\n\t\t\t\t`🔄 Starting deletion process for project: ${projectName} (${projectId})`\n\t\t\t);\n\n\t\t\tconst success = await deleteProject(projectId);\n\n\t\t\tif (success) {\n\t\t\t\tconsole.log(`✅ Project deletion successful: ${projectName}`);\n\n\t\t\t\t// Only remove from UI after successful deletion\n\t\t\t\tif (onProjectDeleted) {\n\t\t\t\t\tonProjectDeleted(projectId);\n\t\t\t\t\tconsole.log(\"🚀 Project removed from UI after successful deletion\");\n\t\t\t\t}\n\n\t\t\t\ttoast.success(`Project \"${projectName}\" and all its forms have been permanently deleted.`);\n\n\t\t\t\t// Trigger refresh to ensure UI is in sync with database\n\t\t\t\thandleRefresh();\n\t\t\t} else {\n\t\t\t\tconsole.error(`❌ Project deletion failed: ${projectName}`);\n\t\t\t\ttoast.error(`Failed to delete project \"${projectName}\". This might be due to a database connection issue. Please check your connection and try again.`);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(\"❌ Exception during project deletion:\", error);\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error);\n\n\t\t\t// Provide more specific error messaging\n\t\t\tlet userMessage = `An unexpected error occurred while deleting project \"${projectName}\".`;\n\n\t\t\tif (errorMessage.includes(\"Database not initialized\")) {\n\t\t\t\tuserMessage = `Database connection error. Please refresh the page and try again.`;\n\t\t\t} else if (errorMessage.includes(\"Project not found\")) {\n\t\t\t\tuserMessage = `Project \"${projectName}\" no longer exists. The page will be refreshed.`;\n\t\t\t\t// Auto-refresh for this case since the project is already gone\n\t\t\t\thandleRefresh();\n\t\t\t} else if (errorMessage.includes(\"Failed to delete project\")) {\n\t\t\t\tuserMessage = `Could not delete project \"${projectName}\" from the database. Please check your connection and try again.`;\n\t\t\t}\n\n\t\t\ttoast.error(userMessage);\n\t\t} finally {\n\t\t\tdispatchDialog({ type: \"CLOSE_DELETE_CONFIRM\" });\n\t\t}\n\t};\n\n\t// Self-contained navigation handler\n\tconst handleProjectClick = (project: ProjectMetadata) => {\n\t\t// Use URL-based navigation like FormsView does\n\t\tnavigateToProject(project.id);\n\t};\n\n\treturn (\n\t\t<>\n\t\t\t<BaseLayout\n\t\t\t\ttitle=\"Projecten\"\n\t\t\t\tsubtitle=\"Maak en beheer projecten en de instellingen\"\n\t\t\t\tsearchSlot={\n\t\t\t\t\t<SearchInput\n\t\t\t\t\t\tplaceholder=\"Zoek op project- of formuliernaam\"\n\t\t\t\t\t\tonSearchChange={setSearchQuery}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t\tprimaryAction={{\n\t\t\t\t\tlabel: \"Project toevoegen\",\n\t\t\t\t\tonClick: handleCreateProject,\n\t\t\t\t\ticon: <Plus className={`${styles.iconSm} ${styles.mr2}`} />,\n\t\t\t\t}}\n\t\t\t\tisLoading={isLoading}\n\t\t\t>\n\t\t\t\t{/* Projects Grid */}\n\t\t\t\t{filteredProjects.length > 0 ? (\n\t\t\t\t\t<GridLayout maxColumns={12} fullWidth>\n\t\t\t\t\t\t{filteredProjects.map((project, index) => (\n\t\t\t\t\t\t\t<GridLayoutColumn\n\t\t\t\t\t\t\t\tkey={project.id}\n\t\t\t\t\t\t\t\tstartSlice={(index % 3) * 4 + 1}\n\t\t\t\t\t\t\t\tendSlice={(index % 3) * 4 + 5}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<ViewCard\n\t\t\t\t\t\t\t\t\ticon={<Folder className={`${styles.iconMd} ${styles.shrink0}`} />}\n\t\t\t\t\t\t\t\t\ttitle={project.name}\n\t\t\t\t\t\t\t\t\tdescription={project.description}\n\t\t\t\t\t\t\t\t\tmetadata={[\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tlabel: \"Aanmaakdatum\",\n\t\t\t\t\t\t\t\t\t\t\tvalue: formatDate(project.createdAt),\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{ label: \"Formulieren\", value: project.forms.length },\n\t\t\t\t\t\t\t\t\t]}\n\t\t\t\t\t\t\t\t\tdropdownActions={[\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tlabel: \"Delete Project\",\n\t\t\t\t\t\t\t\t\t\t\ticon: <Trash2 className={`${styles.iconSm} ${styles.mr2}`} />,\n\t\t\t\t\t\t\t\t\t\t\tonClick: () => handleDeleteProject(project),\n\t\t\t\t\t\t\t\t\t\t\tvariant: \"destructive\" as const,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t]}\n\t\t\t\t\t\t\t\t\tprimaryAction={{\n\t\t\t\t\t\t\t\t\t\ticon: <ChevronRight className={styles.iconSm} />,\n\t\t\t\t\t\t\t\t\t\tonClick: () => handleProjectClick(project),\n\t\t\t\t\t\t\t\t\t\tappearance: \"secondary-action-button\",\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</GridLayoutColumn>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</GridLayout>\n\t\t\t\t) : (\n\t\t\t\t\t<div className={styles.emptyState}>\n\t\t\t\t\t\t<Folder className={`${styles.icon3xl} ${styles.mxAuto} ${styles.mb4}`} />\n\t\t\t\t\t\t<h3 className={styles.emptyStateTitle}>\n\t\t\t\t\t\t\tGeen projecten gevonden\n\t\t\t\t\t\t</h3>\n\t\t\t\t\t\t<p className={styles.emptyStateText}>\n\t\t\t\t\t\t\t{searchQuery\n\t\t\t\t\t\t\t\t? \"Geen projecten komen overeen met je zoekopdracht.\"\n\t\t\t\t\t\t\t\t: \"Maak je eerste project om te beginnen.\"}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t{!searchQuery && (\n\t\t\t\t\t\t\t<Button onClick={handleCreateProject}>\n\t\t\t\t\t\t\t\t<Plus className={`${styles.iconSm} ${styles.mr2}`} />\n\t\t\t\t\t\t\t\tProject aanmaken\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</BaseLayout>\n\n\t\t\t{/* New Project Dialog */}\n\t\t\t<NewProjectDialog\n\t\t\t\topen={dialogState.newProject}\n\t\t\t\tonOpenChange={(open) =>\n\t\t\t\t\tdispatchDialog({\n\t\t\t\t\t\ttype: open ? \"OPEN_NEW_PROJECT\" : \"CLOSE_NEW_PROJECT\",\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tonProjectCreated={handleProjectCreated}\n\t\t\t\tonCreateProject={onCreateProject}\n\t\t\t/>\n\n\t\t\t{/* Delete Confirmation Dialog */}\n\t\t\t<ConfirmDialog\n\t\t\t\topen={dialogState.deleteConfirm}\n\t\t\t\tonOpenChange={(open) => {\n\t\t\t\t\tif (!open) {\n\t\t\t\t\t\tdispatchDialog({ type: \"CLOSE_DELETE_CONFIRM\" });\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t\ttitle=\"Delete Project\"\n\t\t\t\tdescription={`Are you sure you want to delete the project \"${dialogState.projectToDelete?.name}\"? This action cannot be undone and will remove all forms within the project.`}\n\t\t\t\tconfirmText=\"Delete\"\n\t\t\t\tcancelText=\"Cancel\"\n\t\t\t\tvariant=\"destructive\"\n\t\t\t\tonConfirm={confirmDeleteProject}\n\t\t\t/>\n\t\t</>\n\t);\n};\n","/**\n * ProjectCard component - displays project information and forms\n */\n\nimport type { ProjectMetadata } from \"@formbuilder/core\";\nimport {\n\tButton,\n\tCard,\n\tCardContent,\n\tCardDescription,\n\tCardHeader,\n\tCardTitle,\n\tDropdownMenu,\n\tDropdownMenuContent,\n\tDropdownMenuItem,\n\tDropdownMenuTrigger,\n\tSeparator,\n} from \"@formbuilder/ui\";\nimport {\n\tFileText,\n\tFolder,\n\tFolderOpen,\n\tMoreHorizontal,\n\tPlus,\n\tSettings,\n} from \"lucide-react\";\nimport { useState } from \"react\";\nimport styles from \"./ProjectCard.module.css\";\n\nexport interface ProjectCardProps {\n\tproject: ProjectMetadata;\n\tonCreateForm: () => void;\n\tonEditForm: (projectId: string, wizardId: string) => void;\n\tonDeleteForm: (projectId: string, wizardId: string) => void;\n\tonPreviewForm?: (projectId: string, wizardId: string) => void;\n}\n\nexport const ProjectCard: React.FC<ProjectCardProps> = ({\n\tproject,\n\tonCreateForm,\n\tonEditForm,\n\tonDeleteForm,\n}) => {\n\tconst [isExpanded, setIsExpanded] = useState(false);\n\n\treturn (\n\t\t<Card className={styles.card}>\n\t\t\t<CardHeader>\n\t\t\t\t<div className={styles.headerRow}>\n\t\t\t\t\t<div className={styles.titleGroup}>\n\t\t\t\t\t\t{isExpanded ? (\n\t\t\t\t\t\t\t<FolderOpen className={`${styles.iconMd} ${styles.iconBlue}`} />\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<Folder className={`${styles.iconMd} ${styles.iconBlue}`} />\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<CardTitle className={styles.cardTitle}>{project.name}</CardTitle>\n\t\t\t\t\t</div>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tonClick={() => setIsExpanded(!isExpanded)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{isExpanded ? \"Collapse\" : \"Expand\"}\n\t\t\t\t\t</Button>\n\t\t\t\t</div>\n\t\t\t\t<CardDescription className={styles.descriptionStack}>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t{project.forms.length} form{project.forms.length !== 1 ? \"s\" : \"\"}\n\t\t\t\t\t</div>\n\t\t\t\t\t{project.description && (\n\t\t\t\t\t\t<div className={styles.descriptionText}>\n\t\t\t\t\t\t\t{project.description}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t</CardDescription>\n\t\t\t</CardHeader>\n\n\t\t\t{isExpanded && (\n\t\t\t\t<CardContent>\n\t\t\t\t\t<div className={styles.formsList}>\n\t\t\t\t\t\t{project.forms.map((form) => (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tkey={form.id}\n\t\t\t\t\t\t\t\tclassName={styles.formItem}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<div className={styles.formItemContent}>\n\t\t\t\t\t\t\t\t\t<FileText className={`${styles.iconSm} ${styles.iconGreen} ${styles.shrink0}`} />\n\t\t\t\t\t\t\t\t\t<div className={styles.formItemText}>\n\t\t\t\t\t\t\t\t\t\t<p className={styles.formItemTitle}>{form.title}</p>\n\t\t\t\t\t\t\t\t\t\t<p className={styles.formItemId}>{form.id}</p>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<DropdownMenu>\n\t\t\t\t\t\t\t\t\t<DropdownMenuTrigger asChild>\n\t\t\t\t\t\t\t\t\t\t<Button variant=\"ghost\" size=\"sm\">\n\t\t\t\t\t\t\t\t\t\t\t<MoreHorizontal className={styles.iconSm} />\n\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t</DropdownMenuTrigger>\n\t\t\t\t\t\t\t\t\t<DropdownMenuContent align=\"end\">\n\t\t\t\t\t\t\t\t\t\t<DropdownMenuItem\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => onEditForm(project.id, form.id)}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<Settings className={`${styles.iconSm} ${styles.mr2}`} />\n\t\t\t\t\t\t\t\t\t\t\tEdit Form\n\t\t\t\t\t\t\t\t\t\t</DropdownMenuItem>\n\t\t\t\t\t\t\t\t\t\t<DropdownMenuItem\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => onDeleteForm(project.id, form.id)}\n\t\t\t\t\t\t\t\t\t\t\tclassName={styles.deleteItem}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\tDelete Form\n\t\t\t\t\t\t\t\t\t\t</DropdownMenuItem>\n\t\t\t\t\t\t\t\t\t</DropdownMenuContent>\n\t\t\t\t\t\t\t\t</DropdownMenu>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t))}\n\n\t\t\t\t\t\t<Separator className=\"my-3\" />\n\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\tonClick={onCreateForm}\n\t\t\t\t\t\t\tclassName={styles.addFormButton}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Plus className={`${styles.iconSm} ${styles.mr2}`} />\n\t\t\t\t\t\t\tAdd Form\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</div>\n\t\t\t\t</CardContent>\n\t\t\t)}\n\t\t</Card>\n\t);\n};\n","/**\n * useFormExplorerState - Hook for managing form explorer state\n */\n\nimport { initializeFormConfiguration } from \"../../../utils/configInitializer\";\nimport {\n\tclearScanCache,\n\tscanFormsDirectory,\n} from \"../../../utils/formsExplorer\";\nimport type { FormsExplorerState } from \"@formbuilder/core\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport type { FormConfig } from \"../../../config/types\";\n\nexport interface UseFormExplorerStateOptions {\n\tautoLoad?: boolean;\n\tconfig?: FormConfig;\n}\n\nexport interface UseFormExplorerStateReturn {\n\tstate: FormsExplorerState;\n\tsearchQuery: string;\n\tsetSearchQuery: (query: string) => void;\n\tfilteredProjects: FormsExplorerState[\"projects\"];\n\tloadProjects: () => Promise<void>;\n\tselectedProject: string | null;\n\tsetSelectedProject: (projectId: string | null) => void;\n\t// Real-time update functions\n\taddProjectOptimistic: (\n\t\tproject: Omit<FormsExplorerState[\"projects\"][0], \"lastModified\">\n\t) => void;\n\tremoveProjectOptimistic: (projectId: string) => void;\n\taddFormOptimistic: (\n\t\tprojectId: string,\n\t\tform: {\n\t\t\tid: string;\n\t\t\ttitle: string;\n\t\t\tdescription?: string;\n\t\t}\n\t) => void;\n\tremoveFormOptimistic: (projectId: string, formId: string) => void;\n\trefreshProjectsList: () => Promise<void>;\n\tinvalidateCache: () => void;\n}\n\nexport function useFormExplorerState({\n\tautoLoad = true,\n\tconfig,\n}: UseFormExplorerStateOptions = {}): UseFormExplorerStateReturn {\n\tconst [state, setState] = useState<FormsExplorerState>({\n\t\tprojects: [],\n\t\tisLoading: true,\n\t\terror: null,\n\t\tselectedProject: null,\n\t});\n\n\tconst [searchQuery, setSearchQuery] = useState(\"\");\n\n\t// Load projects function\n\tconst loadProjects = useCallback(async () => {\n\t\tconsole.log(\"🔄 loadProjects called - refreshing projects list...\");\n\t\tsetState((prev) => ({ ...prev, isLoading: true, error: null }));\n\n\t\ttry {\n\t\t\tconst operationsConfig = config ? { formConfig: config } : {};\n\t\t\tconsole.log(\"📋 Scanning forms directory with config:\", operationsConfig);\n\t\t\tconst index = await scanFormsDirectory(operationsConfig);\n\t\t\tconsole.log(\"📊 Scan result:\", {\n\t\t\t\tprojectCount: index.projects.length,\n\t\t\t\tprojects: index.projects.map((p) => p.name),\n\t\t\t});\n\t\t\tsetState((prev) => ({\n\t\t\t\t...prev,\n\t\t\t\tprojects: index.projects,\n\t\t\t\tisLoading: false,\n\t\t\t}));\n\t\t\tconsole.log(\"✅ Projects list updated in state\");\n\t\t} catch (error) {\n\t\t\tconsole.error(\"❌ Failed to load projects:\", error);\n\t\t\tsetState((prev) => ({\n\t\t\t\t...prev,\n\t\t\t\terror:\n\t\t\t\t\terror instanceof Error ? error.message : \"Failed to load projects\",\n\t\t\t\tisLoading: false,\n\t\t\t}));\n\t\t}\n\t}, [config]);\n\n\t// Initialize configuration and load projects on mount with optimizations\n\tuseEffect(() => {\n\t\tif (!autoLoad) return;\n\n\t\tlet isCancelled = false;\n\n\t\tconst initialize = async () => {\n\t\t\tif (isCancelled) return;\n\n\t\t\ttry {\n\t\t\t\t// Initialize form configuration service (fast, non-blocking)\n\t\t\t\tawait initializeFormConfiguration();\n\n\t\t\t\tif (isCancelled) return;\n\n\t\t\t\t// Load projects with timeout and error handling\n\t\t\t\tconst timeoutPromise = new Promise((_, reject) => {\n\t\t\t\t\tsetTimeout(\n\t\t\t\t\t\t() =>\n\t\t\t\t\t\t\treject(\n\t\t\t\t\t\t\t\tnew Error(\"Connection timeout - unable to connect to database\")\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t10000 // Increased to 10 seconds for database initialization\n\t\t\t\t\t);\n\t\t\t\t});\n\n\t\t\t\ttry {\n\t\t\t\t\tawait Promise.race([loadProjects(), timeoutPromise]);\n\t\t\t\t} catch (connectionError) {\n\t\t\t\t\tif (isCancelled) return;\n\t\t\t\t\tconsole.error(\"Failed to connect to storage:\", connectionError);\n\t\t\t\t\t// Show connection error with retry option\n\t\t\t\t\tsetState((prev) => ({\n\t\t\t\t\t\t...prev,\n\t\t\t\t\t\tprojects: [],\n\t\t\t\t\t\tisLoading: false,\n\t\t\t\t\t\terror:\n\t\t\t\t\t\t\t\"Failed to connect to database. Please check your connection and try again.\",\n\t\t\t\t\t}));\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (isCancelled) return;\n\t\t\t\tconsole.error(\"Failed to initialize FormExplorer:\", error);\n\n\t\t\t\t// Set a user-friendly error message\n\t\t\t\tsetState((prev) => ({\n\t\t\t\t\t...prev,\n\t\t\t\t\tprojects: [],\n\t\t\t\t\terror:\n\t\t\t\t\t\t\"Failed to initialize application. Please check your configuration and try again.\",\n\t\t\t\t\tisLoading: false,\n\t\t\t\t}));\n\t\t\t}\n\t\t};\n\n\t\t// Initialize immediately without delay for better performance\n\t\tinitialize();\n\n\t\t// Cleanup function\n\t\treturn () => {\n\t\t\tisCancelled = true;\n\t\t};\n\t}, [loadProjects, autoLoad]);\n\n\t// Filter projects and forms based on search query\n\tconst filteredProjects = state.projects.filter((project) => {\n\t\tif (!searchQuery) return true;\n\n\t\tconst query = searchQuery.toLowerCase();\n\t\treturn (\n\t\t\tproject.name.toLowerCase().includes(query) ||\n\t\t\tproject.forms.some(\n\t\t\t\t(form) =>\n\t\t\t\t\tform.title.toLowerCase().includes(query) ||\n\t\t\t\t\tform.id.toLowerCase().includes(query)\n\t\t\t)\n\t\t);\n\t});\n\n\tconst setSelectedProject = useCallback((projectId: string | null) => {\n\t\tsetState((prev) => ({ ...prev, selectedProject: projectId }));\n\t}, []);\n\n\t// Real-time update functions for immediate UI feedback\n\tconst addProjectOptimistic = useCallback(\n\t\t(project: Omit<FormsExplorerState[\"projects\"][0], \"lastModified\">) => {\n\t\t\tconsole.log(\"🚀 Adding project optimistically:\", project.name);\n\t\t\tsetState((prev) => ({\n\t\t\t\t...prev,\n\t\t\t\tprojects: [\n\t\t\t\t\t{\n\t\t\t\t\t\t...project,\n\t\t\t\t\t\tlastModified: Date.now(),\n\t\t\t\t\t},\n\t\t\t\t\t...prev.projects,\n\t\t\t\t],\n\t\t\t}));\n\t\t},\n\t\t[]\n\t);\n\n\tconst removeProjectOptimistic = useCallback((projectId: string) => {\n\t\tconsole.log(\"🗑️ Removing project optimistically:\", projectId);\n\t\tsetState((prev) => ({\n\t\t\t...prev,\n\t\t\tprojects: prev.projects.filter((p) => p.id !== projectId),\n\t\t}));\n\t}, []);\n\n\tconst addFormOptimistic = useCallback(\n\t\t(\n\t\t\tprojectId: string,\n\t\t\tform: {\n\t\t\t\tid: string;\n\t\t\t\ttitle: string;\n\t\t\t\tdescription?: string;\n\t\t\t}\n\t\t) => {\n\t\t\tconsole.log(\"🚀 Adding form optimistically:\", `${projectId}/${form.id}`);\n\t\t\tsetState((prev) => ({\n\t\t\t\t...prev,\n\t\t\t\tprojects: prev.projects.map((project) =>\n\t\t\t\t\tproject.id === projectId\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t...project,\n\t\t\t\t\t\t\t\tforms: [\n\t\t\t\t\t\t\t\t\t...project.forms,\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tid: form.id,\n\t\t\t\t\t\t\t\t\t\ttitle: form.title,\n\t\t\t\t\t\t\t\t\t\tfileName: `${form.id}.json`, // Required by FormMetadata interface\n\t\t\t\t\t\t\t\t\t\tdescription: form.description || \"\",\n\t\t\t\t\t\t\t\t\t\tlastModified: Date.now(),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: project\n\t\t\t\t),\n\t\t\t}));\n\t\t},\n\t\t[]\n\t);\n\n\tconst removeFormOptimistic = useCallback(\n\t\t(projectId: string, formId: string) => {\n\t\t\tconsole.log(\"🗑️ Removing form optimistically:\", `${projectId}/${formId}`);\n\t\t\tsetState((prev) => ({\n\t\t\t\t...prev,\n\t\t\t\tprojects: prev.projects.map((project) =>\n\t\t\t\t\tproject.id === projectId\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t...project,\n\t\t\t\t\t\t\t\tforms: project.forms.filter((form) => form.id !== formId),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: project\n\t\t\t\t),\n\t\t\t}));\n\t\t},\n\t\t[]\n\t);\n\n\tconst refreshProjectsList = useCallback(async () => {\n\t\tconsole.log(\"🔄 Refreshing projects list immediately...\");\n\t\t// Clear both local and global caches before refreshing\n\t\tclearScanCache();\n\t\t// This is an alias for loadProjects but more explicit about intent\n\t\tawait loadProjects();\n\t}, [loadProjects]);\n\n\tconst invalidateCache = useCallback(() => {\n\t\tconsole.log(\"🗑️ Invalidating cache - clearing scan cache\");\n\t\tclearScanCache();\n\t}, []);\n\n\treturn {\n\t\tstate,\n\t\tsearchQuery,\n\t\tsetSearchQuery,\n\t\tfilteredProjects,\n\t\tloadProjects,\n\t\tselectedProject: state.selectedProject,\n\t\tsetSelectedProject,\n\t\t// Real-time update functions\n\t\taddProjectOptimistic,\n\t\tremoveProjectOptimistic,\n\t\taddFormOptimistic,\n\t\tremoveFormOptimistic,\n\t\trefreshProjectsList,\n\t\tinvalidateCache,\n\t};\n}\n","/**\n * useFormOperations - Hook for form CRUD operations with config support\n */\n\nimport type { CreateFormRequest, FormWizardConfig } from \"@formbuilder/core\";\nimport { toast } from \"@formbuilder/ui\";\nimport { useCallback, useMemo } from \"react\";\nimport { useFormConfiguration } from \"../../../config/hooks\";\nimport {\n\tcreateForm,\n\tdeleteForm,\n\ttype FormOperationsConfig,\n\tloadFormConfigFromExplorer,\n\tsaveFormConfig,\n} from \"../../../utils/formsExplorer\";\n\nexport interface UseFormOperationsOptions {\n\tonFormLoad?: (\n\t\tprojectId: string,\n\t\twizardId: string\n\t) => Promise<FormWizardConfig>;\n\tonFormCreate?: (\n\t\tprojectId: string,\n\t\tformId: string,\n\t\ttitle: string\n\t) => Promise<FormWizardConfig | null>;\n\tonFormDelete?: (projectId: string, wizardId: string) => Promise<boolean>;\n\tonFormSave?: (\n\t\tprojectId: string,\n\t\twizardId: string,\n\t\tconfig: FormWizardConfig\n\t) => Promise<void>;\n\tonFormEdit?: (\n\t\tprojectId: string,\n\t\twizardId: string,\n\t\tconfig: FormWizardConfig\n\t) => void;\n\tonFormCreated?: (\n\t\tprojectId: string,\n\t\twizardId: string,\n\t\tconfig: FormWizardConfig\n\t) => void;\n\tonProjectsRefresh?: () => Promise<void>;\n}\n\nexport interface UseFormOperationsReturn {\n\thandleCreateForm: (\n\t\tprojectId: string,\n\t\tformTitle: string,\n\t\tformId?: string\n\t) => Promise<FormWizardConfig | null>;\n\thandleDeleteForm: (projectId: string, wizardId: string) => Promise<boolean>;\n\thandleEditForm: (projectId: string, wizardId: string) => Promise<void>;\n\thandleSaveForm: (\n\t\tprojectId: string,\n\t\twizardId: string,\n\t\tconfig: FormWizardConfig\n\t) => Promise<void>;\n}\n\nexport function useFormOperations({\n\tonFormLoad,\n\tonFormCreate,\n\tonFormDelete,\n\tonFormSave,\n\tonFormEdit,\n\tonFormCreated,\n\tonProjectsRefresh,\n}: UseFormOperationsOptions = {}): UseFormOperationsReturn {\n\t// Get configuration from context\n\tconst formConfig = useFormConfiguration();\n\n\t// Memoize operations config to ensure stable reference for useCallback dependencies\n\tconst operationsConfig: FormOperationsConfig = useMemo(\n\t\t() => ({\n\t\t\tformConfig,\n\t\t}),\n\t\t[formConfig]\n\t);\n\tconst handleCreateForm = useCallback(\n\t\tasync (\n\t\t\tprojectId: string,\n\t\t\tformTitle: string,\n\t\t\tformId?: string\n\t\t): Promise<FormWizardConfig | null> => {\n\t\t\tif (!formTitle.trim()) return null;\n\n\t\t\tconst finalFormId =\n\t\t\t\tformId ||\n\t\t\t\tformTitle\n\t\t\t\t\t.toLowerCase()\n\t\t\t\t\t.replace(/[^a-z0-9]/g, \"-\")\n\t\t\t\t\t.replace(/-+/g, \"-\")\n\t\t\t\t\t.replace(/^-|-$/g, \"\");\n\n\t\t\tlet config: FormWizardConfig | null = null;\n\n\t\t\ttry {\n\t\t\t\tif (onFormCreate) {\n\t\t\t\t\tconfig = await onFormCreate(projectId, finalFormId, formTitle);\n\t\t\t\t} else {\n\t\t\t\t\tconst request: CreateFormRequest = {\n\t\t\t\t\t\tprojectId,\n\t\t\t\t\t\tformId: finalFormId,\n\t\t\t\t\t\ttitle: formTitle,\n\t\t\t\t\t};\n\t\t\t\t\tconfig = await createForm(request, operationsConfig);\n\t\t\t\t}\n\n\t\t\t\tif (config) {\n\t\t\t\t\ttoast.success(`Form \"${formTitle}\" created successfully`);\n\t\t\t\t\tawait onProjectsRefresh?.();\n\t\t\t\t\tonFormCreated?.(projectId, finalFormId, config);\n\t\t\t\t} else {\n\t\t\t\t\ttoast.error(\"Failed to create form\");\n\t\t\t\t}\n\n\t\t\t\treturn config;\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Failed to create form:\", error);\n\t\t\t\ttoast.error(\n\t\t\t\t\terror instanceof Error ? error.message : \"Failed to create form\",\n\t\t\t\t);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t},\n\t\t[onFormCreate, onFormCreated, onProjectsRefresh, operationsConfig]\n\t);\n\n\tconst handleDeleteForm = useCallback(\n\t\tasync (projectId: string, wizardId: string): Promise<boolean> => {\n\t\t\ttry {\n\t\t\t\tlet success = false;\n\n\t\t\t\tif (onFormDelete) {\n\t\t\t\t\tsuccess = await onFormDelete(projectId, wizardId);\n\t\t\t\t} else {\n\t\t\t\t\tsuccess = await deleteForm(projectId, wizardId, operationsConfig);\n\t\t\t\t}\n\n\t\t\t\tif (success) {\n\t\t\t\t\ttoast.success(\"Form deleted successfully\");\n\t\t\t\t\tawait onProjectsRefresh?.();\n\t\t\t\t} else {\n\t\t\t\t\ttoast.error(\"Failed to delete form\");\n\t\t\t\t}\n\n\t\t\t\treturn success;\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Failed to delete form:\", error);\n\t\t\t\ttoast.error(\n\t\t\t\t\terror instanceof Error ? error.message : \"Failed to delete form\",\n\t\t\t\t);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\t[onFormDelete, onProjectsRefresh, operationsConfig]\n\t);\n\n\tconst handleEditForm = useCallback(\n\t\tasync (projectId: string, wizardId: string): Promise<void> => {\n\t\t\ttry {\n\t\t\t\tlet config: FormWizardConfig | null = null;\n\n\t\t\t\tif (onFormLoad) {\n\t\t\t\t\tconfig = await onFormLoad(projectId, wizardId);\n\t\t\t\t} else {\n\t\t\t\t\tconfig = await loadFormConfigFromExplorer(\n\t\t\t\t\t\tprojectId,\n\t\t\t\t\t\twizardId,\n\t\t\t\t\t\toperationsConfig\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (config) {\n\t\t\t\t\tif (onFormEdit) {\n\t\t\t\t\t\t// Use external handler if provided\n\t\t\t\t\t\tonFormEdit(projectId, wizardId, config);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\ttoast.error(\"Failed to load form configuration\");\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Failed to load form for editing:\", error);\n\t\t\t\ttoast.error(\n\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t? error.message\n\t\t\t\t\t\t: \"Failed to load form configuration\",\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\t[onFormLoad, onFormEdit, operationsConfig]\n\t);\n\n\tconst handleSaveForm = useCallback(\n\t\tasync (\n\t\t\tprojectId: string,\n\t\t\twizardId: string,\n\t\t\tconfig: FormWizardConfig\n\t\t): Promise<void> => {\n\t\t\ttry {\n\t\t\t\tif (onFormSave) {\n\t\t\t\t\tawait onFormSave(projectId, wizardId, config);\n\t\t\t\t} else {\n\t\t\t\t\tconst success = await saveFormConfig(\n\t\t\t\t\t\tprojectId,\n\t\t\t\t\t\twizardId,\n\t\t\t\t\t\tconfig,\n\t\t\t\t\t\toperationsConfig\n\t\t\t\t\t);\n\t\t\t\t\tif (!success) {\n\t\t\t\t\t\tthrow new Error(\"Failed to save form configuration\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Failed to save form:\", error);\n\t\t\t\tthrow error; // Re-throw to let caller handle the error display\n\t\t\t}\n\t\t},\n\t\t[onFormSave, operationsConfig]\n\t);\n\n\treturn {\n\t\thandleCreateForm,\n\t\thandleDeleteForm,\n\t\thandleEditForm,\n\t\thandleSaveForm,\n\t};\n}\n","/**\n * useProjectOperations - Hook for project operations\n */\n\nimport { createProject } from \"../../../utils/formsExplorer\";\nimport { toast } from \"@formbuilder/ui\";\nimport { useCallback } from \"react\";\n\nexport interface UseProjectOperationsOptions {\n\tonProjectsRefresh?: () => Promise<void>;\n}\n\nexport interface UseProjectOperationsReturn {\n\thandleCreateProject: (\n\t\tprojectName: string,\n\t\tdescription?: string\n\t) => Promise<boolean>;\n}\n\nexport function useProjectOperations({\n\tonProjectsRefresh,\n}: UseProjectOperationsOptions = {}): UseProjectOperationsReturn {\n\tconst handleCreateProject = useCallback(\n\t\tasync (projectName: string, description?: string): Promise<boolean> => {\n\t\t\tif (!projectName.trim()) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\t// Use the existing createProject function from formsExplorer.ts\n\t\t\t\t// which internally handles storage strategy determination\n\t\t\t\tconst result = await createProject({\n\t\t\t\t\tname: projectName.trim(),\n\t\t\t\t\tdescription: description?.trim() || undefined,\n\t\t\t\t});\n\n\t\t\t\tif (result.success) {\n\t\t\t\t\ttoast.success(`Project \"${projectName}\" created successfully`);\n\n\t\t\t\t\t// Refresh projects list after successful creation\n\t\t\t\t\tawait onProjectsRefresh?.();\n\t\t\t\t\treturn true;\n\t\t\t\t} else {\n\t\t\t\t\ttoast.error(\"Failed to create project\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Failed to create project:\", error);\n\t\t\t\ttoast.error(\n\t\t\t\t\terror instanceof Error ? error.message : \"Failed to create project\",\n\t\t\t\t);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\t[onProjectsRefresh]\n\t);\n\n\treturn {\n\t\thandleCreateProject,\n\t};\n}\n","import { useEffect, useState } from \"react\";\nimport {\n\ttype ProviderCapabilities,\n\tStorageProviderFactory,\n} from \"../../storage/StorageProviderFactory\";\nimport styles from \"./DatabaseStatusIndicator.module.css\";\n\ninterface SyncStatus {\n\tonline: boolean;\n\tconnected: boolean;\n\tconnectionStatus: \"connected\" | \"disconnected\" | \"connecting\" | \"retrying\";\n\tlastSync: string | null;\n\tsyncing: boolean;\n\tretryCount?: number;\n\tmaxRetries?: number;\n\tlastConnectionError?: string | null;\n\tpendingOperations?: number;\n\treconciling?: boolean;\n\tintegrityStatus?: \"consistent\" | \"inconsistent\" | \"unknown\";\n}\n\ninterface DatabaseStatusIndicatorProps {\n\tclassName?: string;\n\tgetSyncStatus?: () => SyncStatus;\n\tonForceSync?: () => Promise<void>;\n\tonReconnect?: () => Promise<boolean>;\n\tonValidateConsistency?: () => Promise<boolean>;\n\tonResetLocalData?: () => Promise<boolean>;\n\tonReconcileConflicts?: () => Promise<boolean>;\n}\n\nexport const DatabaseStatusIndicator = ({\n\tclassName = \"\",\n\tgetSyncStatus,\n\tonForceSync,\n\tonReconnect,\n\tonValidateConsistency,\n\tonResetLocalData,\n\tonReconcileConflicts,\n}: DatabaseStatusIndicatorProps) => {\n\tconst [capabilities, setCapabilities] = useState<ProviderCapabilities | null>(\n\t\tnull\n\t);\n\tconst [syncStatus, setSyncStatus] = useState<SyncStatus>({\n\t\tonline: navigator.onLine,\n\t\tconnected: false,\n\t\tconnectionStatus: \"disconnected\",\n\t\tlastSync: null,\n\t\tsyncing: false,\n\t\tretryCount: 0,\n\t\tmaxRetries: 5,\n\t\tlastConnectionError: null,\n\t\tpendingOperations: 0,\n\t\treconciling: false,\n\t\tintegrityStatus: \"unknown\",\n\t});\n\tconst [showDetails, setShowDetails] = useState(false);\n\n\tuseEffect(() => {\n\t\tconst updateCapabilities = () => {\n\t\t\tconst factory = StorageProviderFactory.getInstance();\n\t\t\tconst providerCapabilities = factory.getProviderCapabilities();\n\t\t\tconsole.log(\n\t\t\t\t\"🔍 DatabaseStatusIndicator capabilities:\",\n\t\t\t\tproviderCapabilities\n\t\t\t);\n\t\t\tsetCapabilities(providerCapabilities);\n\t\t};\n\n\t\t// Initial check\n\t\tupdateCapabilities();\n\n\t\t// Listen for storage provider ready event\n\t\tconst handleProviderReady = (event: CustomEvent) => {\n\t\t\tconsole.log(\"🎉 Storage provider ready:\", event.detail);\n\t\t\tupdateCapabilities();\n\t\t};\n\n\t\twindow.addEventListener(\n\t\t\t\"storageProviderReady\",\n\t\t\thandleProviderReady as EventListener\n\t\t);\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\n\t\t\t\t\"storageProviderReady\",\n\t\t\t\thandleProviderReady as EventListener\n\t\t\t);\n\t\t};\n\t}, []);\n\n\tuseEffect(() => {\n\t\t// Update online status\n\t\tconst handleOnline = () =>\n\t\t\tsetSyncStatus((prev) => ({ ...prev, online: true }));\n\t\tconst handleOffline = () =>\n\t\t\tsetSyncStatus((prev) => ({ ...prev, online: false }));\n\n\t\twindow.addEventListener(\"online\", handleOnline);\n\t\twindow.addEventListener(\"offline\", handleOffline);\n\n\t\t// Poll for sync status if function provided\n\t\tlet interval: NodeJS.Timeout;\n\t\tif (getSyncStatus) {\n\t\t\tinterval = setInterval(() => {\n\t\t\t\ttry {\n\t\t\t\t\tconst currentStatus = getSyncStatus();\n\t\t\t\t\tsetSyncStatus(currentStatus);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error(\"Failed to get sync status:\", error);\n\t\t\t\t}\n\t\t\t}, 1000);\n\t\t}\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"online\", handleOnline);\n\t\t\twindow.removeEventListener(\"offline\", handleOffline);\n\t\t\tif (interval) clearInterval(interval);\n\t\t};\n\t}, [getSyncStatus]);\n\n\tconst handleForceSync = async () => {\n\t\tif (onForceSync && !syncStatus.syncing) {\n\t\t\ttry {\n\t\t\t\tsetSyncStatus((prev) => ({ ...prev, syncing: true }));\n\t\t\t\tawait onForceSync();\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Force sync failed:\", error);\n\t\t\t} finally {\n\t\t\t\tsetSyncStatus((prev) => ({ ...prev, syncing: false }));\n\t\t\t}\n\t\t}\n\t};\n\n\tconst handleReconnect = async () => {\n\t\tif (\n\t\t\tonReconnect &&\n\t\t\t!syncStatus.syncing &&\n\t\t\tsyncStatus.connectionStatus !== \"connecting\"\n\t\t) {\n\t\t\ttry {\n\t\t\t\tsetSyncStatus((prev) => ({ ...prev, syncing: true }));\n\t\t\t\tconst success = await onReconnect();\n\t\t\t\tif (success) {\n\t\t\t\t\tconsole.log(\"Manual reconnection successful\");\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Manual reconnection failed:\", error);\n\t\t\t} finally {\n\t\t\t\tsetSyncStatus((prev) => ({ ...prev, syncing: false }));\n\t\t\t}\n\t\t}\n\t};\n\n\tconst handleValidateConsistency = async () => {\n\t\tif (onValidateConsistency && !syncStatus.reconciling) {\n\t\t\ttry {\n\t\t\t\tsetSyncStatus((prev) => ({ ...prev, reconciling: true }));\n\t\t\t\tconst isConsistent = await onValidateConsistency();\n\t\t\t\tconsole.log(\n\t\t\t\t\t`Data consistency validation: ${isConsistent ? \"consistent\" : \"inconsistent\"}`\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Data consistency validation failed:\", error);\n\t\t\t} finally {\n\t\t\t\tsetSyncStatus((prev) => ({ ...prev, reconciling: false }));\n\t\t\t}\n\t\t}\n\t};\n\n\tconst handleResetLocalData = async () => {\n\t\tif (\n\t\t\tonResetLocalData &&\n\t\t\t!syncStatus.reconciling &&\n\t\t\tconfirm(\n\t\t\t\t\"Are you sure you want to reset all local data? This will reload everything from the remote database.\"\n\t\t\t)\n\t\t) {\n\t\t\ttry {\n\t\t\t\tsetSyncStatus((prev) => ({ ...prev, reconciling: true }));\n\t\t\t\tconst success = await onResetLocalData();\n\t\t\t\tif (success) {\n\t\t\t\t\tconsole.log(\"Local data reset successful\");\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Local data reset failed:\", error);\n\t\t\t} finally {\n\t\t\t\tsetSyncStatus((prev) => ({ ...prev, reconciling: false }));\n\t\t\t}\n\t\t}\n\t};\n\n\tconst handleReconcileConflicts = async () => {\n\t\tif (onReconcileConflicts && !syncStatus.reconciling) {\n\t\t\ttry {\n\t\t\t\tsetSyncStatus((prev) => ({ ...prev, reconciling: true }));\n\t\t\t\tconst success = await onReconcileConflicts();\n\t\t\t\tif (success) {\n\t\t\t\t\tconsole.log(\"Data conflict reconciliation successful\");\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Data conflict reconciliation failed:\", error);\n\t\t\t} finally {\n\t\t\t\tsetSyncStatus((prev) => ({ ...prev, reconciling: false }));\n\t\t\t}\n\t\t}\n\t};\n\n\tconst getStatusConfig = () => {\n\t\t// If sync status is available, prioritize sync information\n\t\tif (getSyncStatus) {\n\t\t\tif (syncStatus.reconciling) {\n\t\t\t\treturn {\n\t\t\t\t\tcolorClass: styles.statusPurple,\n\t\t\t\t\ttitle: \"Reconciling Data...\",\n\t\t\t\t\ticon: \"🔄\",\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (syncStatus.syncing) {\n\t\t\t\treturn {\n\t\t\t\t\tcolorClass: styles.statusLoading,\n\t\t\t\t\ttitle: \"Syncing...\",\n\t\t\t\t\ticon: \"🔄\",\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (!syncStatus.online) {\n\t\t\t\treturn {\n\t\t\t\t\tcolorClass: styles.statusOffline,\n\t\t\t\t\ttitle: \"Offline\",\n\t\t\t\t\ticon: \"📴\",\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (syncStatus.connectionStatus === \"connecting\") {\n\t\t\t\treturn {\n\t\t\t\t\tcolorClass: styles.statusOrange,\n\t\t\t\t\ttitle: \"Connecting...\",\n\t\t\t\t\ticon: \"🔌\",\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (syncStatus.connectionStatus === \"retrying\") {\n\t\t\t\treturn {\n\t\t\t\t\tcolorClass: styles.statusOrange,\n\t\t\t\t\ttitle: `Retrying (${syncStatus.retryCount}/${syncStatus.maxRetries})`,\n\t\t\t\t\ticon: \"🔄\",\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (!syncStatus.connected) {\n\t\t\t\treturn {\n\t\t\t\t\tcolorClass: styles.statusWarning,\n\t\t\t\t\ttitle: \"Sync Disabled\",\n\t\t\t\t\ticon: \"⚠️\",\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (syncStatus.integrityStatus === \"inconsistent\") {\n\t\t\t\treturn {\n\t\t\t\t\tcolorClass: styles.statusError,\n\t\t\t\t\ttitle: \"Data Inconsistent\",\n\t\t\t\t\ticon: \"⚠️\",\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tcolorClass: styles.statusConnected,\n\t\t\t\ttitle: \"Synced\",\n\t\t\t\ticon: \"✅\",\n\t\t\t};\n\t\t}\n\n\t\t// Fallback to capabilities-based status\n\t\tif (!capabilities) {\n\t\t\treturn {\n\t\t\t\tcolorClass: styles.statusError,\n\t\t\t\ttitle: \"Database Not Available\",\n\t\t\t\ticon: \"❌\",\n\t\t\t};\n\t\t}\n\n\t\tif (capabilities.isLive) {\n\t\t\treturn {\n\t\t\t\tcolorClass: styles.statusConnected,\n\t\t\t\ttitle: \"Database Connected (Live)\",\n\t\t\t\ticon: \"✅\",\n\t\t\t};\n\t\t}\n\n\t\tif (capabilities.hasSync) {\n\t\t\treturn {\n\t\t\t\tcolorClass: styles.statusConnected,\n\t\t\t\ttitle: \"Database Connected (Sync)\",\n\t\t\t\ticon: \"🔄\",\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tcolorClass: styles.statusError,\n\t\t\ttitle: \"Database Offline\",\n\t\t\ticon: \"❌\",\n\t\t};\n\t};\n\n\tconst formatLastSync = (timestamp: string | null) => {\n\t\tif (!timestamp) return \"Never\";\n\n\t\tconst date = new Date(timestamp);\n\t\tconst now = new Date();\n\t\tconst diff = now.getTime() - date.getTime();\n\n\t\tif (diff < 60000) {\n\t\t\treturn \"Just now\";\n\t\t} else if (diff < 3600000) {\n\t\t\treturn `${Math.floor(diff / 60000)}m ago`;\n\t\t} else if (diff < 86400000) {\n\t\t\treturn `${Math.floor(diff / 3600000)}h ago`;\n\t\t} else {\n\t\t\treturn date.toLocaleDateString();\n\t\t}\n\t};\n\n\tconst config = getStatusConfig();\n\n\tconst getDatabaseValueClass = () => {\n\t\tif (capabilities?.isLive || capabilities?.hasSync) return styles.detailValueConnected;\n\t\treturn styles.detailValueError;\n\t};\n\n\tconst getPersistenceValueClass = () => {\n\t\tif (capabilities?.isLive) return styles.detailValueConnected;\n\t\tif (capabilities?.hasSync) return styles.detailValueWarning;\n\t\treturn styles.detailValueMuted;\n\t};\n\n\tconst getIntegrityValueClass = () => {\n\t\tif (syncStatus.integrityStatus === \"consistent\") return styles.detailValueConnected;\n\t\tif (syncStatus.integrityStatus === \"inconsistent\") return styles.detailValueError;\n\t\treturn styles.detailValueMuted;\n\t};\n\n\treturn (\n\t\t<div className={`${styles.wrapper} ${className}`}>\n\t\t\t{/* Status Indicator */}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonClick={() => setShowDetails(!showDetails)}\n\t\t\t\tclassName={`${styles.statusDot} ${config.colorClass}`}\n\t\t\t\ttitle={config.title}\n\t\t\t/>\n\n\t\t\t{/* Detailed Status Popover */}\n\t\t\t{showDetails && (\n\t\t\t\t<div className={styles.popover}>\n\t\t\t\t\t<div className={styles.popoverContent}>\n\t\t\t\t\t\t<div className={styles.popoverHeader}>\n\t\t\t\t\t\t\t<h3 className={styles.popoverTitle}>Database Status</h3>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tonClick={() => setShowDetails(false)}\n\t\t\t\t\t\t\t\tclassName={styles.closeButton}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t✕\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<div className={styles.detailsList}>\n\t\t\t\t\t\t\t{/* Database Connection Status */}\n\t\t\t\t\t\t\t<div className={styles.detailRow}>\n\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Database:</span>\n\t\t\t\t\t\t\t\t<span className={getDatabaseValueClass()}>\n\t\t\t\t\t\t\t\t\t{capabilities?.isLive\n\t\t\t\t\t\t\t\t\t\t? \"Connected (Live)\"\n\t\t\t\t\t\t\t\t\t\t: capabilities?.hasSync\n\t\t\t\t\t\t\t\t\t\t\t? \"Connected (Sync)\"\n\t\t\t\t\t\t\t\t\t\t\t: \"Offline/Local\"}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t{/* Provider Type */}\n\t\t\t\t\t\t\t<div className={styles.detailRow}>\n\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Provider:</span>\n\t\t\t\t\t\t\t\t<span className={styles.detailValue}>\n\t\t\t\t\t\t\t\t\t{capabilities?.isLive\n\t\t\t\t\t\t\t\t\t\t? \"Supabase PostgreSQL\"\n\t\t\t\t\t\t\t\t\t\t: \"PgLite (Local)\"}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t{/* Data Persistence */}\n\t\t\t\t\t\t\t<div className={styles.detailRow}>\n\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Data Persistence:</span>\n\t\t\t\t\t\t\t\t<span className={getPersistenceValueClass()}>\n\t\t\t\t\t\t\t\t\t{capabilities?.isLive\n\t\t\t\t\t\t\t\t\t\t? \"Direct to Database\"\n\t\t\t\t\t\t\t\t\t\t: capabilities?.hasSync\n\t\t\t\t\t\t\t\t\t\t\t? \"Local with Sync\"\n\t\t\t\t\t\t\t\t\t\t\t: \"Local Only\"}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t{/* Network Status (if sync is available) */}\n\t\t\t\t\t\t\t{getSyncStatus && (\n\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t<div className={styles.detailRow}>\n\t\t\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Network:</span>\n\t\t\t\t\t\t\t\t\t\t<span className={syncStatus.online ? styles.detailValueConnected : styles.detailValueError}>\n\t\t\t\t\t\t\t\t\t\t\t{syncStatus.online ? \"Online\" : \"Offline\"}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t\t\t<div className={styles.detailRow}>\n\t\t\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Sync Status:</span>\n\t\t\t\t\t\t\t\t\t\t<span className={syncStatus.connected ? styles.detailValueConnected : styles.detailValueMuted}>\n\t\t\t\t\t\t\t\t\t\t\t{syncStatus.connected ? \"Connected\" : \"Disabled\"}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t\t\t<div className={styles.detailRow}>\n\t\t\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Last Sync:</span>\n\t\t\t\t\t\t\t\t\t\t<span className={styles.detailValue}>\n\t\t\t\t\t\t\t\t\t\t\t{formatLastSync(syncStatus.lastSync)}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t\t\t{/* Data Integrity Status */}\n\t\t\t\t\t\t\t\t\t<div className={styles.detailRow}>\n\t\t\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Data Integrity:</span>\n\t\t\t\t\t\t\t\t\t\t<span className={getIntegrityValueClass()}>\n\t\t\t\t\t\t\t\t\t\t\t{syncStatus.integrityStatus === \"consistent\"\n\t\t\t\t\t\t\t\t\t\t\t\t? \"Consistent\"\n\t\t\t\t\t\t\t\t\t\t\t\t: syncStatus.integrityStatus === \"inconsistent\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t? \"Inconsistent\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t: \"Unknown\"}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t\t\t{/* Reconciliation Status */}\n\t\t\t\t\t\t\t\t\t{syncStatus.reconciling && (\n\t\t\t\t\t\t\t\t\t\t<div className={styles.detailRow}>\n\t\t\t\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Status:</span>\n\t\t\t\t\t\t\t\t\t\t\t<span className={styles.detailValuePurple}>Reconciling...</span>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t\t\t{/* Connection Details */}\n\t\t\t\t\t\t\t\t\t{(syncStatus.connectionStatus === \"retrying\" ||\n\t\t\t\t\t\t\t\t\t\tsyncStatus.lastConnectionError) && (\n\t\t\t\t\t\t\t\t\t\t<div className={styles.dividerSection}>\n\t\t\t\t\t\t\t\t\t\t\t{syncStatus.connectionStatus === \"retrying\" && (\n\t\t\t\t\t\t\t\t\t\t\t\t<div className={styles.retryRow}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Retry:</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span className={styles.detailValueOrange}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{syncStatus.retryCount}/{syncStatus.maxRetries}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t\t\t\t\t{syncStatus.lastConnectionError && (\n\t\t\t\t\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div className={styles.errorLabel}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tLast Error:\n\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div className={styles.errorBox}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{syncStatus.lastConnectionError.length > 100\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? `${syncStatus.lastConnectionError.substring(0, 100)}...`\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: syncStatus.lastConnectionError}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t\t\t{/* Pending Operations */}\n\t\t\t\t\t\t\t\t\t{(syncStatus.pendingOperations ?? 0) > 0 && (\n\t\t\t\t\t\t\t\t\t\t<div className={styles.detailRow}>\n\t\t\t\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Pending:</span>\n\t\t\t\t\t\t\t\t\t\t\t<span className={styles.detailValueBlue}>\n\t\t\t\t\t\t\t\t\t\t\t\t{syncStatus.pendingOperations} operations\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t{/* Actions (if sync functions are available) */}\n\t\t\t\t\t\t{(onForceSync ||\n\t\t\t\t\t\t\tonReconnect ||\n\t\t\t\t\t\t\tonValidateConsistency ||\n\t\t\t\t\t\t\tonResetLocalData ||\n\t\t\t\t\t\t\tonReconcileConflicts) && (\n\t\t\t\t\t\t\t<div className={styles.actionsSection}>\n\t\t\t\t\t\t\t\t{syncStatus.connected && onForceSync && (\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tonClick={handleForceSync}\n\t\t\t\t\t\t\t\t\t\tdisabled={syncStatus.syncing || syncStatus.reconciling}\n\t\t\t\t\t\t\t\t\t\tclassName={`${styles.actionButton} ${styles.actionButtonBlue}`}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{syncStatus.syncing ? \"Syncing...\" : \"Force Sync\"}\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t\t{!syncStatus.connected && onReconnect && (\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tonClick={handleReconnect}\n\t\t\t\t\t\t\t\t\t\tdisabled={\n\t\t\t\t\t\t\t\t\t\t\tsyncStatus.syncing ||\n\t\t\t\t\t\t\t\t\t\t\tsyncStatus.reconciling ||\n\t\t\t\t\t\t\t\t\t\t\tsyncStatus.connectionStatus === \"connecting\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tclassName={`${styles.actionButton} ${styles.actionButtonOrange}`}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{syncStatus.syncing ? \"Reconnecting...\" : \"Reconnect\"}\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t\t{/* Data Consistency Actions */}\n\t\t\t\t\t\t\t\t{syncStatus.connected && onValidateConsistency && (\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tonClick={handleValidateConsistency}\n\t\t\t\t\t\t\t\t\t\tdisabled={syncStatus.syncing || syncStatus.reconciling}\n\t\t\t\t\t\t\t\t\t\tclassName={`${styles.actionButton} ${styles.actionButtonGreen}`}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{syncStatus.reconciling ? \"Validating...\" : \"Validate Data\"}\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t\t{syncStatus.connected &&\n\t\t\t\t\t\t\t\t\tsyncStatus.integrityStatus === \"inconsistent\" &&\n\t\t\t\t\t\t\t\t\tonReconcileConflicts && (\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tonClick={handleReconcileConflicts}\n\t\t\t\t\t\t\t\t\t\t\tdisabled={syncStatus.syncing || syncStatus.reconciling}\n\t\t\t\t\t\t\t\t\t\t\tclassName={`${styles.actionButton} ${styles.actionButtonPurple}`}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{syncStatus.reconciling\n\t\t\t\t\t\t\t\t\t\t\t\t? \"Reconciling...\"\n\t\t\t\t\t\t\t\t\t\t\t\t: \"Fix Data Issues\"}\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t\t{syncStatus.connected && onResetLocalData && (\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tonClick={handleResetLocalData}\n\t\t\t\t\t\t\t\t\t\tdisabled={syncStatus.syncing || syncStatus.reconciling}\n\t\t\t\t\t\t\t\t\t\tclassName={`${styles.actionButton} ${styles.actionButtonRed}`}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{syncStatus.reconciling\n\t\t\t\t\t\t\t\t\t\t\t? \"Resetting...\"\n\t\t\t\t\t\t\t\t\t\t\t: \"Reset Local Data\"}\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{/* Additional Info */}\n\t\t\t\t\t\t<div className={styles.storageInfo}>\n\t\t\t\t\t\t\t<div className={styles.storageInfoTitle}>Storage Info:</div>\n\t\t\t\t\t\t\t<div>Local: PgLite (In-Browser)</div>\n\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\tRemote:{\" \"}\n\t\t\t\t\t\t\t\t{capabilities?.isLive\n\t\t\t\t\t\t\t\t\t? \"Supabase PostgreSQL\"\n\t\t\t\t\t\t\t\t\t: capabilities?.hasSync\n\t\t\t\t\t\t\t\t\t\t? \"Connected (Sync)\"\n\t\t\t\t\t\t\t\t\t\t: \"Unavailable\"}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{syncStatus.connectionStatus === \"retrying\" && (\n\t\t\t\t\t\t\t\t<div className={styles.storageInfoNoteOrange}>\n\t\t\t\t\t\t\t\t\tAuto-retry enabled with exponential backoff\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{syncStatus.reconciling && (\n\t\t\t\t\t\t\t\t<div className={styles.storageInfoNotePurple}>\n\t\t\t\t\t\t\t\t\tData reconciliation in progress...\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{syncStatus.integrityStatus === \"inconsistent\" &&\n\t\t\t\t\t\t\t\t!syncStatus.reconciling && (\n\t\t\t\t\t\t\t\t\t<div className={styles.storageInfoNoteError}>\n\t\t\t\t\t\t\t\t\t\tData inconsistency detected - reconciliation recommended\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n};\n","/**\n * ConnectionErrorScreen - Shows when database is not available\n * Blocks UI to prevent user actions that won't work without database connection\n */\n\nimport { AlertTriangle, RefreshCw, Wifi, WifiOff } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport {\n\ttype ProviderCapabilities,\n\tStorageProviderFactory,\n} from \"../../storage/StorageProviderFactory\";\nimport styles from \"./ConnectionErrorScreen.module.css\";\n\ninterface ConnectionErrorScreenProps {\n\tonRetry?: () => void;\n\tclassName?: string;\n}\n\nexport const ConnectionErrorScreen: React.FC<ConnectionErrorScreenProps> = ({\n\tonRetry,\n\tclassName = \"\",\n}) => {\n\tconst [capabilities, setCapabilities] = useState<ProviderCapabilities | null>(\n\t\tnull\n\t);\n\tconst [isRetrying, setIsRetrying] = useState(false);\n\n\tuseEffect(() => {\n\t\tconst updateCapabilities = () => {\n\t\t\tconst factory = StorageProviderFactory.getInstance();\n\t\t\tconst providerCapabilities = factory.getProviderCapabilities();\n\t\t\tsetCapabilities(providerCapabilities);\n\t\t};\n\n\t\t// Initial check\n\t\tupdateCapabilities();\n\n\t\t// Listen for storage provider ready event\n\t\tconst handleProviderReady = (event: CustomEvent) => {\n\t\t\tconsole.log(\"🎉 Storage provider ready:\", event.detail);\n\t\t\tupdateCapabilities();\n\t\t};\n\n\t\twindow.addEventListener(\n\t\t\t\"storageProviderReady\",\n\t\t\thandleProviderReady as EventListener\n\t\t);\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\n\t\t\t\t\"storageProviderReady\",\n\t\t\t\thandleProviderReady as EventListener\n\t\t\t);\n\t\t};\n\t}, []);\n\n\tconst handleRetry = async () => {\n\t\tsetIsRetrying(true);\n\t\ttry {\n\t\t\tif (onRetry) {\n\t\t\t\tawait onRetry();\n\t\t\t} else {\n\t\t\t\t// Default retry - reload the page\n\t\t\t\twindow.location.reload();\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Retry failed:\", error);\n\t\t} finally {\n\t\t\tsetIsRetrying(false);\n\t\t}\n\t};\n\n\tconst getErrorInfo = () => {\n\t\tif (!capabilities) {\n\t\t\treturn {\n\t\t\t\ttitle: \"Database Connection Required\",\n\t\t\t\tdescription:\n\t\t\t\t\t\"The application is still initializing. Please wait a moment...\",\n\t\t\t\ticon: <RefreshCw className={`${styles.icon4xl} ${styles.iconWarning} ${styles.spinAnimation}`} />,\n\t\t\t\tactionText: \"Initializing...\",\n\t\t\t\tshowRetry: false,\n\t\t\t};\n\t\t}\n\n\t\t// Filesystem strategy should never show connection errors\n\t\tif (capabilities.strategy === \"filesystem\") {\n\t\t\treturn null; // Filesystem strategy doesn't need database connection\n\t\t}\n\n\t\tif (!capabilities.isLive && !capabilities.hasSync) {\n\t\t\treturn {\n\t\t\t\ttitle: \"Database Connection Unavailable\",\n\t\t\t\tdescription:\n\t\t\t\t\t\"This application requires a database connection to create and manage projects. Without a connection, your work cannot be saved.\",\n\t\t\t\ticon: <WifiOff className={`${styles.icon4xl} ${styles.iconNegative}`} />,\n\t\t\t\tactionText: \"Retry Connection\",\n\t\t\t\tshowRetry: true,\n\t\t\t};\n\t\t}\n\n\t\tif (!capabilities.isLive && capabilities.hasSync) {\n\t\t\treturn {\n\t\t\t\ttitle: \"Working Offline\",\n\t\t\t\tdescription:\n\t\t\t\t\t\"You're currently working in offline mode. Your changes will sync when connection is restored.\",\n\t\t\t\ticon: <Wifi className={`${styles.icon4xl} ${styles.iconWarningHover}`} />,\n\t\t\t\tactionText: \"Try to Connect\",\n\t\t\t\tshowRetry: true,\n\t\t\t};\n\t\t}\n\n\t\treturn null; // Connection is fine\n\t};\n\n\tconst errorInfo = getErrorInfo();\n\n\tif (!errorInfo) {\n\t\treturn null; // No error, don't show this screen\n\t}\n\n\tconst getStatusValueClass = () => {\n\t\tif (capabilities?.isLive) return styles.detailValueConnected;\n\t\tif (capabilities?.hasSync) return styles.detailValueOffline;\n\t\treturn styles.detailValueError;\n\t};\n\n\treturn (\n\t\t<div className={`${styles.container} ${className}`}>\n\t\t\t<div className={styles.card}>\n\t\t\t\t{/* Icon */}\n\t\t\t\t<div className={styles.iconWrapper}>{errorInfo.icon}</div>\n\n\t\t\t\t{/* Title */}\n\t\t\t\t<h1 className={styles.title}>\n\t\t\t\t\t{errorInfo.title}\n\t\t\t\t</h1>\n\n\t\t\t\t{/* Description */}\n\t\t\t\t<p className={styles.description}>\n\t\t\t\t\t{errorInfo.description}\n\t\t\t\t</p>\n\n\t\t\t\t{/* Connection Details */}\n\t\t\t\t{capabilities && (\n\t\t\t\t\t<div className={styles.detailsPanel}>\n\t\t\t\t\t\t<div className={styles.detailsList}>\n\t\t\t\t\t\t\t<div className={styles.detailRow}>\n\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Provider:</span>\n\t\t\t\t\t\t\t\t<span className={styles.detailValue}>\n\t\t\t\t\t\t\t\t\t{capabilities.isLive\n\t\t\t\t\t\t\t\t\t\t? \"Supabase PostgreSQL\"\n\t\t\t\t\t\t\t\t\t\t: capabilities.hasSync\n\t\t\t\t\t\t\t\t\t\t\t? \"PgLite with Sync\"\n\t\t\t\t\t\t\t\t\t\t\t: \"PgLite (Local Only)\"}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div className={styles.detailRow}>\n\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Strategy:</span>\n\t\t\t\t\t\t\t\t<span className={styles.detailValueCapitalize}>\n\t\t\t\t\t\t\t\t\t{capabilities.strategy}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div className={styles.detailRow}>\n\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Status:</span>\n\t\t\t\t\t\t\t\t<span className={getStatusValueClass()}>\n\t\t\t\t\t\t\t\t\t{capabilities.isLive\n\t\t\t\t\t\t\t\t\t\t? \"Connected\"\n\t\t\t\t\t\t\t\t\t\t: capabilities.hasSync\n\t\t\t\t\t\t\t\t\t\t\t? \"Offline with Sync\"\n\t\t\t\t\t\t\t\t\t\t\t: \"Local Only\"}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t{/* Actions */}\n\t\t\t\t<div className={styles.actions}>\n\t\t\t\t\t{errorInfo.showRetry && (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={handleRetry}\n\t\t\t\t\t\t\tdisabled={isRetrying}\n\t\t\t\t\t\t\tclassName={styles.retryButton}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{isRetrying ? (\n\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t<RefreshCw className={`${styles.iconSm} ${styles.mr2}`} />\n\t\t\t\t\t\t\t\t\tRetrying...\n\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t<RefreshCw className={`${styles.iconSm} ${styles.mr2}`} />\n\t\t\t\t\t\t\t\t\t{errorInfo.actionText}\n\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<div className={styles.hint}>\n\t\t\t\t\t\t<AlertTriangle className={`${styles.iconXs} ${styles.inlineIcon} ${styles.mr1}`} />\n\t\t\t\t\t\tMake sure your database configuration is correct and the database is\n\t\t\t\t\t\taccessible.\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n","/**\n * View types for the SPA-style FormExplorer navigation\n *\n * @deprecated These types support the legacy FormExplorerCore SPA architecture.\n * Standalone components (ProjectsView, FormsView, FormBuilderView) do not need these types.\n */\n\n/** @deprecated Use standalone view components instead */\nexport type ExplorerViewType =\n\t| \"projects\" // Main projects overview\n\t| \"forms\" // Forms within a project\n\t| \"builder\" // Form builder\n\t| \"preview\"; // Form preview\n\n/** @deprecated Use standalone view components instead */\nexport interface BaseViewState {\n\ttype: ExplorerViewType;\n}\n\n/** @deprecated Use standalone view components instead */\nexport interface ProjectsViewState extends BaseViewState {\n\ttype: \"projects\";\n}\n\n/** @deprecated Use standalone view components instead */\nexport interface FormsViewState extends BaseViewState {\n\ttype: \"forms\";\n\tprojectId: string;\n\tprojectName: string;\n}\n\n// FlowsViewState removed - flows concept eliminated\n\n/** @deprecated Use standalone view components instead */\nexport interface BuilderViewState extends BaseViewState {\n\ttype: \"builder\";\n\tprojectId: string;\n\tformId: string;\n\tconfig?: unknown;\n}\n\n/** @deprecated Use standalone view components instead */\nexport interface PreviewViewState extends BaseViewState {\n\ttype: \"preview\";\n\tprojectId: string;\n\tformId: string;\n}\n\n/** @deprecated Use standalone view components instead */\nexport type ViewState =\n\t| ProjectsViewState\n\t| FormsViewState\n\t| BuilderViewState\n\t| PreviewViewState;\n\n/** @deprecated Use standalone view components instead */\nexport interface NavigationContext {\n\tcurrentView: ViewState;\n\tviewHistory: ViewState[];\n\tnavigateToView: (view: ViewState, addToHistory?: boolean) => void;\n\tnavigateBack: () => void;\n\tcanGoBack: boolean;\n}\n\n// FlowMetadata removed - flows concept eliminated\n\n// Helper functions for creating view states\n/** @deprecated Use standalone view components instead */\nexport const createProjectsView = (): ProjectsViewState => ({\n\ttype: \"projects\",\n});\n\n/** @deprecated Use standalone view components instead */\nexport const createFormsView = (\n\tprojectId: string,\n\tprojectName: string\n): FormsViewState => ({\n\ttype: \"forms\",\n\tprojectId,\n\tprojectName,\n});\n\n// createFlowsView removed - flows concept eliminated\n\n/** @deprecated Use standalone view components instead */\nexport const createBuilderView = (\n\tprojectId: string,\n\tformId: string,\n\tconfig?: unknown\n): BuilderViewState => ({\n\ttype: \"builder\",\n\tprojectId,\n\tformId,\n\tconfig,\n});\n\n/** @deprecated Use standalone view components instead */\nexport const createPreviewView = (\n\tprojectId: string,\n\tformId: string\n): PreviewViewState => ({\n\ttype: \"preview\",\n\tprojectId,\n\tformId,\n});\n","/**\n * FormExplorerCore - Legacy SPA-style form explorer orchestrator\n *\n * @deprecated Use standalone view components instead:\n * - ProjectsView for projects list\n * - FormsView for forms list\n * - FormBuilderView for form editing\n *\n * These components work with any routing framework via NavigationProvider.\n * FormExplorerCore couples your app to internal view state management.\n *\n * @see ProjectsView\n * @see FormsView\n * @see FormBuilderView\n */\n\nimport type { FormWizardConfig } from \"@formbuilder/core\";\nimport { Button } from \"@formbuilder/ui\";\nimport { RefreshCw } from \"lucide-react\";\nimport type React from \"react\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\n// Type definition for sync status\ninterface SyncStatus {\n\tonline: boolean;\n\tconnected: boolean;\n\tconnectionStatus: \"connected\" | \"disconnected\" | \"connecting\" | \"retrying\";\n\tlastSync: string | null;\n\tsyncing: boolean;\n\tretryCount?: number;\n\tmaxRetries?: number;\n\tlastConnectionError?: string | null;\n\tpendingOperations?: number;\n\treconciling?: boolean;\n\tintegrityStatus?: \"consistent\" | \"inconsistent\" | \"unknown\";\n}\n\nimport styles from \"./FormExplorerCore.module.css\";\nimport { DatabaseStatusIndicator } from \"../../../../components/DatabaseStatusIndicator/DatabaseStatusIndicator\";\nimport { ConnectionErrorScreen } from \"../../../../components/ConnectionErrorScreen/ConnectionErrorScreen\";\nimport type { FormConfig } from \"../../../../config/types\";\nimport {\n\ttype ProviderCapabilities,\n\tStorageProviderFactory,\n} from \"../../../../storage/StorageProviderFactory\";\nimport type { FormStorageProvider } from \"../../../../storage/types\";\nimport { getFormConfig } from \"../../../../utils/formsExplorer\";\nimport { FormBuilder } from \"../../../form-builder\";\nimport { useFormExplorerState, useFormOperations } from \"../../hooks/index\";\n// Import new view types and components\nimport type { NavigationContext, ViewState } from \"../../types/viewTypes\";\nimport { createBuilderView, createProjectsView } from \"../../types/viewTypes\";\nimport { FormsView } from \"../FormsView/FormsView\";\nimport { NewFormDialog } from \"../NewFormDialog/NewFormDialog\";\nimport { NewProjectDialog } from \"../NewProjectDialog/NewProjectDialog\";\nimport { ProjectsView } from \"../ProjectsView/ProjectsView\";\n\n// Re-export view types for backward compatibility\nexport type ExplorerView = ViewState;\n\nexport interface FormExplorerCoreProps {\n\t/**\n\t * Optional form configuration\n\t */\n\tconfig?: FormConfig;\n\n\t/**\n\t * Optional initial view configuration\n\t */\n\tinitialView?: ExplorerView;\n\n\t/**\n\t * Optional custom save handler for forms\n\t */\n\tonFormSave?: (\n\t\tprojectId: string,\n\t\twizardId: string,\n\t\tconfig: FormWizardConfig\n\t) => Promise<void>;\n\n\t/**\n\t * Optional custom load handler for forms\n\t */\n\tonFormLoad?: (\n\t\tprojectId: string,\n\t\twizardId: string\n\t) => Promise<FormWizardConfig>;\n\n\t/**\n\t * Optional custom form creation handler\n\t */\n\tonFormCreate?: (\n\t\tprojectId: string,\n\t\tformId: string,\n\t\ttitle: string\n\t) => Promise<FormWizardConfig | null>;\n\n\t/**\n\t * Optional custom form deletion handler\n\t */\n\tonFormDelete?: (projectId: string, wizardId: string) => Promise<boolean>;\n\n\t/**\n\t * Optional form edit handler\n\t */\n\tonFormEdit?: (\n\t\tprojectId: string,\n\t\twizardId: string,\n\t\tconfig: FormWizardConfig\n\t) => void;\n\n\t/**\n\t * Whether to show preview functionality\n\t */\n\tshowPreview?: boolean;\n\n\t/**\n\t * Custom preview URL generator\n\t */\n\tgetPreviewUrl?: (projectId: string, wizardId: string) => string;\n\n\t/**\n\t * Custom navigation handler for going back from builder to forms list\n\t * If not provided, will use internal navigateBack handler\n\t */\n\tonNavigateToForms?: (projectId: string) => void;\n\n\t/**\n\t * Custom navigation handler for going back to projects list\n\t * If not provided, will use internal view state navigation\n\t */\n\tonNavigateToProjects?: () => void;\n\n\t/**\n\t * Whether to disable automatic route-based navigation\n\t * @deprecated No longer has effect - route navigation removed\n\t */\n\tdisableRouteNavigation?: boolean;\n\n\t/**\n\t * Additional CSS class name\n\t */\n\tclassName?: string;\n\n\t/**\n\t * Custom styles\n\t */\n\tstyle?: React.CSSProperties;\n}\n\nexport const FormExplorerCore: React.FC<FormExplorerCoreProps> = ({\n\tconfig,\n\tinitialView = createProjectsView(),\n\tonFormSave,\n\tonFormLoad,\n\tonFormCreate,\n\tonFormDelete,\n\tonFormEdit,\n\tshowPreview = true,\n\t// getPreviewUrl, // Unused - using configured routes instead\n\tonNavigateToForms,\n\tonNavigateToProjects,\n\t// disableRouteNavigation, // Deprecated - no longer has effect\n\tclassName,\n\tstyle,\n}) => {\n\t// View state management with stable references\n\tconst [currentView, setCurrentView] = useState<ExplorerView>(initialView);\n\tconst navigationInProgress = useRef(false);\n\tconst [providerCapabilities, setProviderCapabilities] =\n\t\tuseState<ProviderCapabilities | null>(null);\n\n\t// Monitor provider capabilities for connection status\n\tuseEffect(() => {\n\t\tconst updateCapabilities = () => {\n\t\t\tconst factory = StorageProviderFactory.getInstance();\n\t\t\tconst capabilities = factory.getProviderCapabilities();\n\t\t\tsetProviderCapabilities(capabilities);\n\t\t};\n\n\t\t// Initial check\n\t\tupdateCapabilities();\n\n\t\t// Listen for storage provider ready event\n\t\tconst handleProviderReady = () => {\n\t\t\tupdateCapabilities();\n\t\t};\n\n\t\twindow.addEventListener(\"storageProviderReady\", handleProviderReady);\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"storageProviderReady\", handleProviderReady);\n\t\t};\n\t}, []);\n\n\t// Dialog state\n\tconst [showNewProjectDialog, setShowNewProjectDialog] = useState(false);\n\tconst [showNewFormDialog, setShowNewFormDialog] = useState(false);\n\n\t// Storage and sync status state\n\tconst [storageProvider, setStorageProvider] =\n\t\tuseState<FormStorageProvider | null>(null);\n\n\t// Use feature hooks\n\tconst {\n\t\tstate,\n\t\tfilteredProjects,\n\t\tloadProjects,\n\t\tselectedProject,\n\t\taddProjectOptimistic,\n\t\tremoveProjectOptimistic,\n\t\taddFormOptimistic,\n\t\tremoveFormOptimistic,\n\t\trefreshProjectsList,\n\t} = useFormExplorerState({ config });\n\n\tconst { handleSaveForm } = useFormOperations({\n\t\tonFormLoad,\n\t\tonFormCreate,\n\t\tonFormDelete,\n\t\tonFormSave,\n\t\tonFormEdit,\n\t\tonFormCreated: (projectId, formId, config) => {\n\t\t\tnavigateToView({\n\t\t\t\ttype: \"builder\",\n\t\t\t\tprojectId,\n\t\t\t\tformId,\n\t\t\t\tconfig,\n\t\t\t});\n\t\t},\n\t\tonProjectsRefresh: loadProjects,\n\t});\n\n\t// Sync currentView with initialView prop changes\n\tuseEffect(() => {\n\t\tif (\n\t\t\t!navigationInProgress.current &&\n\t\t\tcurrentView.type !== initialView.type\n\t\t) {\n\t\t\tsetCurrentView(initialView);\n\t\t}\n\t}, [currentView.type, initialView]);\n\n\t// Initialize storage provider for sync status monitoring\n\tuseEffect(() => {\n\t\tconst initStorageProvider = async () => {\n\t\t\ttry {\n\t\t\t\tconst formConfig = config || (await getFormConfig());\n\t\t\t\tconst factory = StorageProviderFactory.getInstance();\n\t\t\t\tconst provider = await factory.createProvider(formConfig.storage);\n\t\t\t\tsetStorageProvider(provider);\n\n\t\t\t\t// Get provider capabilities using the factory\n\t\t\t\tconst capabilities = factory.getProviderCapabilities();\n\t\t\t\tsetProviderCapabilities(capabilities);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Failed to get storage provider:\", error);\n\t\t\t}\n\t\t};\n\n\t\tinitStorageProvider();\n\t}, [config]);\n\n\t// Sync status handlers\n\tconst getSyncStatus = useCallback((): SyncStatus => {\n\t\tif (\n\t\t\tstorageProvider &&\n\t\t\t\"getSyncStatus\" in storageProvider &&\n\t\t\ttypeof (storageProvider as { getSyncStatus?: () => SyncStatus })\n\t\t\t\t.getSyncStatus === \"function\"\n\t\t) {\n\t\t\treturn (\n\t\t\t\tstorageProvider as { getSyncStatus: () => SyncStatus }\n\t\t\t).getSyncStatus();\n\t\t}\n\t\treturn {\n\t\t\tonline: navigator.onLine,\n\t\t\tconnected: false,\n\t\t\tconnectionStatus: \"disconnected\" as const,\n\t\t\tlastSync: null,\n\t\t\tsyncing: false,\n\t\t\tretryCount: 0,\n\t\t\tmaxRetries: 5,\n\t\t\tlastConnectionError: null,\n\t\t\tpendingOperations: 0,\n\t\t\treconciling: false,\n\t\t\tintegrityStatus: \"unknown\" as const,\n\t\t};\n\t}, [storageProvider]);\n\n\tconst handleForceSync = useCallback(async () => {\n\t\tif (\n\t\t\tstorageProvider &&\n\t\t\t\"forceSync\" in storageProvider &&\n\t\t\ttypeof (storageProvider as { forceSync?: () => Promise<void> })\n\t\t\t\t.forceSync === \"function\"\n\t\t) {\n\t\t\tawait (storageProvider as { forceSync: () => Promise<void> }).forceSync();\n\t\t}\n\t}, [storageProvider]);\n\n\tconst handleReconnect = useCallback(async (): Promise<boolean> => {\n\t\tif (\n\t\t\tstorageProvider &&\n\t\t\t\"reconnect\" in storageProvider &&\n\t\t\ttypeof (storageProvider as { reconnect?: () => Promise<boolean> })\n\t\t\t\t.reconnect === \"function\"\n\t\t) {\n\t\t\treturn await (\n\t\t\t\tstorageProvider as { reconnect: () => Promise<boolean> }\n\t\t\t).reconnect();\n\t\t}\n\t\treturn false;\n\t}, [storageProvider]);\n\n\t// Data consistency handlers\n\tconst handleValidateConsistency = useCallback(async (): Promise<boolean> => {\n\t\tif (\n\t\t\tstorageProvider &&\n\t\t\t\"validateDataConsistency\" in storageProvider &&\n\t\t\ttypeof (\n\t\t\t\tstorageProvider as { validateDataConsistency?: () => Promise<boolean> }\n\t\t\t).validateDataConsistency === \"function\"\n\t\t) {\n\t\t\treturn await (\n\t\t\t\tstorageProvider as { validateDataConsistency: () => Promise<boolean> }\n\t\t\t).validateDataConsistency();\n\t\t}\n\t\treturn true; // Default to consistent if method not available\n\t}, [storageProvider]);\n\n\tconst handleResetLocalData = useCallback(async (): Promise<boolean> => {\n\t\tif (\n\t\t\tstorageProvider &&\n\t\t\t\"resetLocalData\" in storageProvider &&\n\t\t\ttypeof (storageProvider as { resetLocalData?: () => Promise<boolean> })\n\t\t\t\t.resetLocalData === \"function\"\n\t\t) {\n\t\t\treturn await (\n\t\t\t\tstorageProvider as { resetLocalData: () => Promise<boolean> }\n\t\t\t).resetLocalData();\n\t\t}\n\t\treturn false;\n\t}, [storageProvider]);\n\n\tconst handleReconcileConflicts = useCallback(async (): Promise<boolean> => {\n\t\tif (\n\t\t\tstorageProvider &&\n\t\t\t\"reconcileConflicts\" in storageProvider &&\n\t\t\ttypeof (\n\t\t\t\tstorageProvider as { reconcileConflicts?: () => Promise<boolean> }\n\t\t\t).reconcileConflicts === \"function\"\n\t\t) {\n\t\t\treturn await (\n\t\t\t\tstorageProvider as { reconcileConflicts: () => Promise<boolean> }\n\t\t\t).reconcileConflicts();\n\t\t}\n\t\treturn false;\n\t}, [storageProvider]);\n\n\t// Navigation helpers - stable and immediate\n\tconst navigateToView = useCallback((view: ViewState) => {\n\t\tnavigationInProgress.current = true;\n\t\tsetCurrentView(view);\n\t\tsetTimeout(() => {\n\t\t\tnavigationInProgress.current = false;\n\t\t}, 0);\n\t}, []);\n\n\tconst navigateBack = useCallback(() => {\n\t\t// Without internal history, back navigation goes to projects\n\t\t// Consumer should provide onNavigateToProjects for proper behavior\n\t\tif (onNavigateToProjects) {\n\t\t\tonNavigateToProjects();\n\t\t}\n\t}, [onNavigateToProjects]);\n\n\t// Create stable navigation context with proper memoization\n\tconst navigationContext: NavigationContext = {\n\t\tcurrentView,\n\t\tviewHistory: [], // Empty - no longer tracked\n\t\tnavigateToView,\n\t\tnavigateBack,\n\t\tcanGoBack: false, // No internal history\n\t};\n\n\t// Handle project creation completion with immediate UI update\n\tconst handleProjectCreated = useCallback(\n\t\t(projectData?: {\n\t\t\tprojectId: string;\n\t\t\tname: string;\n\t\t\tdescription?: string;\n\t\t}) => {\n\t\t\tif (projectData) {\n\t\t\t\t// Add project optimistically for immediate UI feedback\n\t\t\t\taddProjectOptimistic({\n\t\t\t\t\tid: projectData.projectId,\n\t\t\t\t\tname: projectData.name,\n\t\t\t\t\tdescription: projectData.description || \"\",\n\t\t\t\t\tforms: [],\n\t\t\t\t\tcreatedAt: Date.now(),\n\t\t\t\t});\n\t\t\t\tconsole.log(\n\t\t\t\t\t\"✨ Project added optimistically, scheduling background refresh...\"\n\t\t\t\t);\n\n\t\t\t\t// Trigger background refresh to sync with actual data\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\trefreshProjectsList();\n\t\t\t\t}, 500); // Small delay to allow sync to complete\n\t\t\t} else {\n\t\t\t\t// Fallback to full refresh if no project data provided\n\t\t\t\tloadProjects();\n\t\t\t}\n\t\t},\n\t\t[addProjectOptimistic, refreshProjectsList, loadProjects]\n\t);\n\n\t// Handle form creation completion\n\tconst handleFormCreated = useCallback(\n\t\t(projectId: string, formId: string) => {\n\t\t\tloadProjects();\n\t\t\tnavigateToView(createBuilderView(projectId, formId));\n\t\t},\n\t\t[loadProjects, navigateToView]\n\t);\n\n\t// Handle preview (currently unused but kept for future implementation)\n\t// const handlePreview = useCallback(\n\t// \t(projectId: string, wizardId: string) => {\n\t// \t\tif (getPreviewUrl) {\n\t// \t\t\twindow.open(getPreviewUrl(projectId, wizardId), \"_blank\");\n\t// \t\t} else {\n\t// \t\t\t// Use configured preview route\n\t// \t\t\tconst previewUrl = navigationUrls.preview(projectId, wizardId);\n\t// \t\t\twindow.open(previewUrl, \"_blank\");\n\t// \t\t}\n\t// \t},\n\t// \t[getPreviewUrl, navigationUrls]\n\t// );\n\n\t// Handle saving a form in builder view\n\tconst handleFormSave = useCallback(\n\t\tasync (config: FormWizardConfig) => {\n\t\t\tif (currentView.type !== \"builder\") return;\n\n\t\t\tconst { projectId, formId } = currentView;\n\n\t\t\ttry {\n\t\t\t\tawait handleSaveForm(projectId, formId, config);\n\n\t\t\t\t// Update the view with the new config\n\t\t\t\tsetCurrentView((prev) =>\n\t\t\t\t\tprev.type === \"builder\"\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t...prev,\n\t\t\t\t\t\t\t\tconfig,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: prev\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Failed to save form:\", error);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\t\t[currentView, handleSaveForm]\n\t);\n\n\t// Render based on current view\n\tconst renderView = () => {\n\t\t// Handle loading and error states at the top level\n\t\tif (state.isLoading) {\n\t\t\treturn (\n\t\t\t\t<div className={styles.container}>\n\t\t\t\t\t<div className={styles.loadingCenter}>\n\t\t\t\t\t\t<RefreshCw className={`${styles.iconXl} ${styles.spinAnimation}`} />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t);\n\t\t}\n\n\t\tif (state.error) {\n\t\t\tconst isDatabaseSetupError =\n\t\t\t\tstate.error.includes(\"Database tables not found\") ||\n\t\t\t\tstate.error.includes(\"404\") ||\n\t\t\t\tstate.error.includes(\"relation\") ||\n\t\t\t\tstate.error.includes(\"does not exist\");\n\n\t\t\treturn (\n\t\t\t\t<div className={styles.container}>\n\t\t\t\t\t<div className={styles.errorCenter}>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={`${styles.errorBox} ${isDatabaseSetupError ? styles.errorBoxSetup : styles.errorBoxFailed}`}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName={`${styles.errorTitle} ${isDatabaseSetupError ? styles.errorTitleSetup : styles.errorTitleFailed}`}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{isDatabaseSetupError\n\t\t\t\t\t\t\t\t\t? \"🔧 Database Setup Required\"\n\t\t\t\t\t\t\t\t\t: \"Connection Failed\"}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<p className={styles.errorMessage}>{state.error}</p>\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\tonClick={loadProjects}\n\t\t\t\t\t\t\t\tclassName={isDatabaseSetupError ? styles.retryButtonSetup : styles.retryButtonFailed}\n\t\t\t\t\t\t\t\tdisabled={state.isLoading}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<RefreshCw className={styles.retryButtonIcon} />\n\t\t\t\t\t\t\t\t{isDatabaseSetupError ? \"Check Again\" : \"Try Again\"}\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t);\n\t\t}\n\n\t\tswitch (currentView.type) {\n\t\t\tcase \"projects\":\n\t\t\t\treturn (\n\t\t\t\t\t<ProjectsView\n\t\t\t\t\t\tprojects={filteredProjects}\n\t\t\t\t\t\tisLoading={state.isLoading}\n\t\t\t\t\t\tonRefresh={refreshProjectsList}\n\t\t\t\t\t\tonProjectDeleted={removeProjectOptimistic}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\tcase \"forms\": {\n\t\t\t\tconst project = filteredProjects.find(\n\t\t\t\t\t(p) => p.id === currentView.projectId\n\t\t\t\t);\n\t\t\t\tif (!project) {\n\t\t\t\t\t// Use setTimeout to avoid immediate state updates during render\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tnavigationContext.navigateToView(createProjectsView(), false);\n\t\t\t\t\t}, 0);\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<div className={styles.container}>\n\t\t\t\t\t\t\t<div className={styles.loadingCenter}>\n\t\t\t\t\t\t\t\t<RefreshCw className={`${styles.iconXl} ${styles.spinAnimation}`} />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn (\n\t\t\t\t\t<FormsView\n\t\t\t\t\t\tprojectId={currentView.projectId}\n\t\t\t\t\t\tonRefresh={refreshProjectsList}\n\t\t\t\t\t\tonFormDeleted={removeFormOptimistic}\n\t\t\t\t\t\tonFormAdded={addFormOptimistic}\n\t\t\t\t\t\tonNavigateToProjects={() => {\n\t\t\t\t\t\t\tif (onNavigateToProjects) {\n\t\t\t\t\t\t\t\tonNavigateToProjects();\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Fall back to internal view navigation\n\t\t\t\t\t\t\tnavigationContext.navigateToView(createProjectsView());\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tcase \"builder\":\n\t\t\t\treturn (\n\t\t\t\t\t<FormBuilder\n\t\t\t\t\t\tinitialConfig={currentView.config as FormWizardConfig | undefined}\n\t\t\t\t\t\tonSave={handleFormSave}\n\t\t\t\t\t\tproject={currentView.projectId}\n\t\t\t\t\t\twizardId={currentView.formId}\n\t\t\t\t\t\tshowPreviewButton={showPreview}\n\t\t\t\t\t\t// Pass navigation handlers to FormBuilder\n\t\t\t\t\t\tonNavigateToForms={\n\t\t\t\t\t\t\tonNavigateToForms\n\t\t\t\t\t\t\t\t? () => onNavigateToForms(currentView.projectId)\n\t\t\t\t\t\t\t\t: navigateBack\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\tdefault:\n\t\t\t\t// Fallback to projects view for unsupported view types\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tnavigationContext.navigateToView(createProjectsView(), false);\n\t\t\t\t}, 0);\n\t\t\t\treturn (\n\t\t\t\t\t<div className={styles.container}>\n\t\t\t\t\t\t<div className={styles.loadingCenter}>\n\t\t\t\t\t\t\t<RefreshCw className={`${styles.iconXl} ${styles.spinAnimation}`} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t}\n\t};\n\n\t// Check if we need to show connection error screen\n\tconst shouldShowConnectionError = () => {\n\t\t// No capabilities means still loading - don't show error yet\n\t\tif (!providerCapabilities) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Filesystem strategy should never show connection errors\n\t\tif (providerCapabilities.strategy === \"filesystem\") {\n\t\t\treturn false;\n\t\t}\n\n\t\t// For database strategy, show error if neither live nor sync is available\n\t\treturn !providerCapabilities.isLive && !providerCapabilities.hasSync;\n\t};\n\n\t// Show connection error screen if database is not properly connected\n\tif (shouldShowConnectionError()) {\n\t\treturn <ConnectionErrorScreen onRetry={() => window.location.reload()} />;\n\t}\n\n\treturn (\n\t\t<div className={`${styles.formExplorer}${className ? \" \" + className : \"\"}`} style={style}>\n\t\t\t{renderView()}\n\n\t\t\t{/* Dialogs */}\n\t\t\t<NewProjectDialog\n\t\t\t\topen={showNewProjectDialog}\n\t\t\t\tonOpenChange={setShowNewProjectDialog}\n\t\t\t\tonProjectCreated={handleProjectCreated}\n\t\t\t/>\n\n\t\t\t<NewFormDialog\n\t\t\t\topen={showNewFormDialog}\n\t\t\t\tonOpenChange={setShowNewFormDialog}\n\t\t\t\tselectedProjectId={selectedProject || undefined}\n\t\t\t\tonFormCreated={handleFormCreated}\n\t\t\t/>\n\t\t\t{/* Only show DatabaseStatusIndicator when using database storage */}\n\t\t\t{providerCapabilities?.strategy === \"database\" && (\n\t\t\t\t<DatabaseStatusIndicator\n\t\t\t\t\tgetSyncStatus={getSyncStatus}\n\t\t\t\t\tonForceSync={handleForceSync}\n\t\t\t\t\tonReconnect={handleReconnect}\n\t\t\t\t\tonValidateConsistency={handleValidateConsistency}\n\t\t\t\t\tonResetLocalData={handleResetLocalData}\n\t\t\t\t\tonReconcileConflicts={handleReconcileConflicts}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</div>\n\t);\n};\n","/**\n * FormExplorer - A comprehensive form management component\n * Provides form discovery, creation, editing, and management capabilities\n * Designed to be easily imported and used in any React application\n *\n * @example Basic usage with filesystem config\n * ```tsx\n * import { FormExplorer, type FormConfig } from '@dragstep/form-builder-component';\n *\n * const config: FormConfig = {\n * storage: {\n * strategy: \"filesystem\",\n * paths: { primaryStorage: \"./forms\" },\n * fileExtension: \".json\"\n * }\n * };\n *\n * function App() {\n * return <FormExplorer config={config} />;\n * }\n * ```\n *\n * @example Auto-detection (recommended for NPM packages)\n * ```tsx\n * // 1. Create /form.config.json in your project root\n * // 2. Import and use the component\n * import { FormExplorer } from '@dragstep/form-builder-component';\n *\n * function App() {\n * // FormExplorer automatically finds /form.config.json\n * // and resolves environment variables like ${DATABASE_URL}\n * return <FormExplorer />;\n * }\n * ```\n *\n * @example Manual config (for custom setups)\n * ```tsx\n * import { FormExplorer } from '@dragstep/form-builder-component';\n * import formConfig from './form.config.json';\n *\n * function App() {\n * return <FormExplorer config={formConfig} />;\n * }\n * ```\n */\n\nimport type { FormWizardConfig } from \"@formbuilder/core\";\nimport { useEffect, useState } from \"react\";\nimport \"../../../../styles/styles.css\";\nimport type { FormConfig } from \"../../../../config/types\";\nimport styles from \"./FormExplorer.module.css\";\nimport {\n\tThemeProvider,\n\tuseThemeConfig,\n} from \"../../../../providers/ThemeProvider\";\nimport { resolveConfigVariables } from \"../../../../utils/configReader\";\nimport { type ExplorerView, FormExplorerCore } from \"../FormExplorerCore/FormExplorerCore\";\n\n// Re-export the props interface for backwards compatibility with explicit config typing\nexport interface FormExplorerProps {\n\t/**\n\t * Optional form configuration\n\t * If not provided, FormExplorer will automatically search for form.config.json in the user's project\n\t * Supports both strict FormConfig and raw JSON objects (which will be processed)\n\t */\n\tconfig?: FormConfig | Record<string, unknown>;\n\n\t// Optional props from FormExplorerCoreProps\n\tinitialView?: ExplorerView;\n\tonFormSave?: (\n\t\tprojectId: string,\n\t\twizardId: string,\n\t\tconfig: FormWizardConfig\n\t) => Promise<void>;\n\tonFormLoad?: (\n\t\tprojectId: string,\n\t\twizardId: string\n\t) => Promise<FormWizardConfig>;\n\tonProjectCreate?: (projectName: string) => Promise<boolean>;\n\tonFormCreate?: (\n\t\tprojectId: string,\n\t\tformId: string,\n\t\ttitle: string\n\t) => Promise<FormWizardConfig | null>;\n\tonFormDelete?: (projectId: string, wizardId: string) => Promise<boolean>;\n\tonFormEdit?: (\n\t\tprojectId: string,\n\t\twizardId: string,\n\t\tconfig: FormWizardConfig\n\t) => void;\n\tshowPreview?: boolean;\n\tgetPreviewUrl?: (projectId: string, wizardId: string) => string;\n\tclassName?: string;\n\tstyle?: React.CSSProperties;\n}\n\n/**\n * FormExplorer - Legacy form management wrapper with config auto-detection\n *\n * @deprecated Use standalone view components with NavigationProvider instead:\n * - ProjectsView, FormsView, FormBuilderView\n *\n * @see ProjectsView\n * @see FormsView\n * @see FormBuilderView\n */\nconst FormExplorer: React.FC<FormExplorerProps> = ({ config, ...props }) => {\n\tconst themeConfig = useThemeConfig();\n\tconst [resolvedConfig, setResolvedConfig] = useState<FormConfig | null>(null);\n\tconst [isLoading, setIsLoading] = useState(true);\n\tconst [error, setError] = useState<string | null>(null);\n\n\tuseEffect(() => {\n\t\tconst loadConfig = async () => {\n\t\t\ttry {\n\t\t\t\tif (config) {\n\t\t\t\t\t// User provided config explicitly\n\t\t\t\t\tconst processedConfig = resolveConfigVariables(config);\n\t\t\t\t\tsetResolvedConfig(processedConfig);\n\t\t\t\t\tsetIsLoading(false);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Auto-detect form.config.json in project root\n\t\t\t\tconst configPath = \"/form.config.json\";\n\n\t\t\t\ttry {\n\t\t\t\t\tconst response = await fetch(configPath);\n\t\t\t\t\tif (response.ok) {\n\t\t\t\t\t\tconst rawConfig = await response.json();\n\t\t\t\t\t\tconst processedConfig = resolveConfigVariables(rawConfig);\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t`✅ FormExplorer: Found config at ${configPath}`,\n\t\t\t\t\t\t\tprocessedConfig\n\t\t\t\t\t\t);\n\t\t\t\t\t\tsetResolvedConfig(processedConfig);\n\t\t\t\t\t\tsetIsLoading(false);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Config file not found or invalid\n\t\t\t\t}\n\n\t\t\t\t// No config found, show error\n\t\t\t\tsetError(\n\t\t\t\t\t\"No form.config.json found in project root. Please create /form.config.json or provide a config prop.\"\n\t\t\t\t);\n\t\t\t\tsetIsLoading(false);\n\t\t\t} catch (loadError) {\n\t\t\t\tsetError(\n\t\t\t\t\t`Failed to load configuration: ${loadError instanceof Error ? loadError.message : \"Unknown error\"}`\n\t\t\t\t);\n\t\t\t\tsetIsLoading(false);\n\t\t\t}\n\t\t};\n\n\t\tloadConfig();\n\t}, [config]);\n\n\t// Loading state\n\tif (isLoading) {\n\t\treturn (\n\t\t\t<div className={styles.loadingContainer}>\n\t\t\t\t<div className={styles.loadingInner}>\n\t\t\t\t\t<div className={styles.loadingSpinner}></div>\n\t\t\t\t\t<p className={styles.loadingText}>Loading configuration...</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\t// Error state\n\tif (error || !resolvedConfig) {\n\t\treturn (\n\t\t\t<div className={styles.errorContainer}>\n\t\t\t\t<div className={styles.errorInner}>\n\t\t\t\t\t<h3 className={styles.errorTitle}>\n\t\t\t\t\t\tConfiguration Required\n\t\t\t\t\t</h3>\n\t\t\t\t\t<p className={styles.errorMessage}>\n\t\t\t\t\t\t{error ||\n\t\t\t\t\t\t\t\"FormExplorer requires a configuration to determine storage strategy.\"}\n\t\t\t\t\t</p>\n\t\t\t\t\t<div className={styles.errorCodeBlock}>\n\t\t\t\t\t\t<strong>\n\t\t\t\t\t\t\tOption 1: Create /form.config.json in your project root:\n\t\t\t\t\t\t</strong>\n\t\t\t\t\t\t<pre>{`{\n \"storage\": {\n \"strategy\": \"database\",\n \"databaseConfig\": {\n \"url\": \"\\${DATABASE_URL}\"\n }\n }\n}`}</pre>\n\t\t\t\t\t\t<strong className={styles.errorCodeBlockLabel}>\n\t\t\t\t\t\t\tOption 2: Pass config as prop:\n\t\t\t\t\t\t</strong>\n\t\t\t\t\t\t<pre>{`<FormExplorer config={yourConfig} />`}</pre>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<ThemeProvider config={themeConfig}>\n\t\t\t<FormExplorerCore config={resolvedConfig} {...props} />\n\t\t</ThemeProvider>\n\t);\n};\n\n/** @deprecated Use standalone view components instead */\nexport default FormExplorer;\n/** @deprecated Use standalone view components instead */\nexport { FormExplorer };\nexport type { ExplorerView };\n","/**\n * React Router v6.30.3\n *\n * Copyright (c) Remix Software Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE.md file in the root directory of this source tree.\n *\n * @license MIT\n */\nimport * as React from 'react';\nimport { UNSAFE_invariant, joinPaths, matchPath, UNSAFE_decodePath, UNSAFE_getResolveToMatches, UNSAFE_warning, resolveTo, parsePath, matchRoutes, Action, UNSAFE_convertRouteMatchToUiMatch, stripBasename, IDLE_BLOCKER, isRouteErrorResponse, createMemoryHistory, AbortedDeferredError, createRouter } from '@remix-run/router';\nexport { AbortedDeferredError, Action as NavigationType, createPath, defer, generatePath, isRouteErrorResponse, json, matchPath, matchRoutes, parsePath, redirect, redirectDocument, replace, resolvePath } from '@remix-run/router';\n\nfunction _extends() {\n _extends = Object.assign ? Object.assign.bind() : function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n return target;\n };\n return _extends.apply(this, arguments);\n}\n\n// Create react-specific types from the agnostic types in @remix-run/router to\n// export from react-router\nconst DataRouterContext = /*#__PURE__*/React.createContext(null);\nif (process.env.NODE_ENV !== \"production\") {\n DataRouterContext.displayName = \"DataRouter\";\n}\nconst DataRouterStateContext = /*#__PURE__*/React.createContext(null);\nif (process.env.NODE_ENV !== \"production\") {\n DataRouterStateContext.displayName = \"DataRouterState\";\n}\nconst AwaitContext = /*#__PURE__*/React.createContext(null);\nif (process.env.NODE_ENV !== \"production\") {\n AwaitContext.displayName = \"Await\";\n}\n\n/**\n * A Navigator is a \"location changer\"; it's how you get to different locations.\n *\n * Every history instance conforms to the Navigator interface, but the\n * distinction is useful primarily when it comes to the low-level `<Router>` API\n * where both the location and a navigator must be provided separately in order\n * to avoid \"tearing\" that may occur in a suspense-enabled app if the action\n * and/or location were to be read directly from the history instance.\n */\n\nconst NavigationContext = /*#__PURE__*/React.createContext(null);\nif (process.env.NODE_ENV !== \"production\") {\n NavigationContext.displayName = \"Navigation\";\n}\nconst LocationContext = /*#__PURE__*/React.createContext(null);\nif (process.env.NODE_ENV !== \"production\") {\n LocationContext.displayName = \"Location\";\n}\nconst RouteContext = /*#__PURE__*/React.createContext({\n outlet: null,\n matches: [],\n isDataRoute: false\n});\nif (process.env.NODE_ENV !== \"production\") {\n RouteContext.displayName = \"Route\";\n}\nconst RouteErrorContext = /*#__PURE__*/React.createContext(null);\nif (process.env.NODE_ENV !== \"production\") {\n RouteErrorContext.displayName = \"RouteError\";\n}\n\n/**\n * Returns the full href for the given \"to\" value. This is useful for building\n * custom links that are also accessible and preserve right-click behavior.\n *\n * @see https://reactrouter.com/v6/hooks/use-href\n */\nfunction useHref(to, _temp) {\n let {\n relative\n } = _temp === void 0 ? {} : _temp;\n !useInRouterContext() ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n \"useHref() may be used only in the context of a <Router> component.\") : UNSAFE_invariant(false) : void 0;\n let {\n basename,\n navigator\n } = React.useContext(NavigationContext);\n let {\n hash,\n pathname,\n search\n } = useResolvedPath(to, {\n relative\n });\n let joinedPathname = pathname;\n\n // If we're operating within a basename, prepend it to the pathname prior\n // to creating the href. If this is a root navigation, then just use the raw\n // basename which allows the basename to have full control over the presence\n // of a trailing slash on root links\n if (basename !== \"/\") {\n joinedPathname = pathname === \"/\" ? basename : joinPaths([basename, pathname]);\n }\n return navigator.createHref({\n pathname: joinedPathname,\n search,\n hash\n });\n}\n\n/**\n * Returns true if this component is a descendant of a `<Router>`.\n *\n * @see https://reactrouter.com/v6/hooks/use-in-router-context\n */\nfunction useInRouterContext() {\n return React.useContext(LocationContext) != null;\n}\n\n/**\n * Returns the current location object, which represents the current URL in web\n * browsers.\n *\n * Note: If you're using this it may mean you're doing some of your own\n * \"routing\" in your app, and we'd like to know what your use case is. We may\n * be able to provide something higher-level to better suit your needs.\n *\n * @see https://reactrouter.com/v6/hooks/use-location\n */\nfunction useLocation() {\n !useInRouterContext() ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n \"useLocation() may be used only in the context of a <Router> component.\") : UNSAFE_invariant(false) : void 0;\n return React.useContext(LocationContext).location;\n}\n\n/**\n * Returns the current navigation action which describes how the router came to\n * the current location, either by a pop, push, or replace on the history stack.\n *\n * @see https://reactrouter.com/v6/hooks/use-navigation-type\n */\nfunction useNavigationType() {\n return React.useContext(LocationContext).navigationType;\n}\n\n/**\n * Returns a PathMatch object if the given pattern matches the current URL.\n * This is useful for components that need to know \"active\" state, e.g.\n * `<NavLink>`.\n *\n * @see https://reactrouter.com/v6/hooks/use-match\n */\nfunction useMatch(pattern) {\n !useInRouterContext() ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n \"useMatch() may be used only in the context of a <Router> component.\") : UNSAFE_invariant(false) : void 0;\n let {\n pathname\n } = useLocation();\n return React.useMemo(() => matchPath(pattern, UNSAFE_decodePath(pathname)), [pathname, pattern]);\n}\n\n/**\n * The interface for the navigate() function returned from useNavigate().\n */\n\nconst navigateEffectWarning = \"You should call navigate() in a React.useEffect(), not when \" + \"your component is first rendered.\";\n\n// Mute warnings for calls to useNavigate in SSR environments\nfunction useIsomorphicLayoutEffect(cb) {\n let isStatic = React.useContext(NavigationContext).static;\n if (!isStatic) {\n // We should be able to get rid of this once react 18.3 is released\n // See: https://github.com/facebook/react/pull/26395\n // eslint-disable-next-line react-hooks/rules-of-hooks\n React.useLayoutEffect(cb);\n }\n}\n\n/**\n * Returns an imperative method for changing the location. Used by `<Link>`s, but\n * may also be used by other elements to change the location.\n *\n * @see https://reactrouter.com/v6/hooks/use-navigate\n */\nfunction useNavigate() {\n let {\n isDataRoute\n } = React.useContext(RouteContext);\n // Conditional usage is OK here because the usage of a data router is static\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return isDataRoute ? useNavigateStable() : useNavigateUnstable();\n}\nfunction useNavigateUnstable() {\n !useInRouterContext() ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n \"useNavigate() may be used only in the context of a <Router> component.\") : UNSAFE_invariant(false) : void 0;\n let dataRouterContext = React.useContext(DataRouterContext);\n let {\n basename,\n future,\n navigator\n } = React.useContext(NavigationContext);\n let {\n matches\n } = React.useContext(RouteContext);\n let {\n pathname: locationPathname\n } = useLocation();\n let routePathnamesJson = JSON.stringify(UNSAFE_getResolveToMatches(matches, future.v7_relativeSplatPath));\n let activeRef = React.useRef(false);\n useIsomorphicLayoutEffect(() => {\n activeRef.current = true;\n });\n let navigate = React.useCallback(function (to, options) {\n if (options === void 0) {\n options = {};\n }\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(activeRef.current, navigateEffectWarning) : void 0;\n\n // Short circuit here since if this happens on first render the navigate\n // is useless because we haven't wired up our history listener yet\n if (!activeRef.current) return;\n if (typeof to === \"number\") {\n navigator.go(to);\n return;\n }\n let path = resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, options.relative === \"path\");\n\n // If we're operating within a basename, prepend it to the pathname prior\n // to handing off to history (but only if we're not in a data router,\n // otherwise it'll prepend the basename inside of the router).\n // If this is a root navigation, then we navigate to the raw basename\n // which allows the basename to have full control over the presence of a\n // trailing slash on root links\n if (dataRouterContext == null && basename !== \"/\") {\n path.pathname = path.pathname === \"/\" ? basename : joinPaths([basename, path.pathname]);\n }\n (!!options.replace ? navigator.replace : navigator.push)(path, options.state, options);\n }, [basename, navigator, routePathnamesJson, locationPathname, dataRouterContext]);\n return navigate;\n}\nconst OutletContext = /*#__PURE__*/React.createContext(null);\n\n/**\n * Returns the context (if provided) for the child route at this level of the route\n * hierarchy.\n * @see https://reactrouter.com/v6/hooks/use-outlet-context\n */\nfunction useOutletContext() {\n return React.useContext(OutletContext);\n}\n\n/**\n * Returns the element for the child route at this level of the route\n * hierarchy. Used internally by `<Outlet>` to render child routes.\n *\n * @see https://reactrouter.com/v6/hooks/use-outlet\n */\nfunction useOutlet(context) {\n let outlet = React.useContext(RouteContext).outlet;\n if (outlet) {\n return /*#__PURE__*/React.createElement(OutletContext.Provider, {\n value: context\n }, outlet);\n }\n return outlet;\n}\n\n/**\n * Returns an object of key/value pairs of the dynamic params from the current\n * URL that were matched by the route path.\n *\n * @see https://reactrouter.com/v6/hooks/use-params\n */\nfunction useParams() {\n let {\n matches\n } = React.useContext(RouteContext);\n let routeMatch = matches[matches.length - 1];\n return routeMatch ? routeMatch.params : {};\n}\n\n/**\n * Resolves the pathname of the given `to` value against the current location.\n *\n * @see https://reactrouter.com/v6/hooks/use-resolved-path\n */\nfunction useResolvedPath(to, _temp2) {\n let {\n relative\n } = _temp2 === void 0 ? {} : _temp2;\n let {\n future\n } = React.useContext(NavigationContext);\n let {\n matches\n } = React.useContext(RouteContext);\n let {\n pathname: locationPathname\n } = useLocation();\n let routePathnamesJson = JSON.stringify(UNSAFE_getResolveToMatches(matches, future.v7_relativeSplatPath));\n return React.useMemo(() => resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, relative === \"path\"), [to, routePathnamesJson, locationPathname, relative]);\n}\n\n/**\n * Returns the element of the route that matched the current location, prepared\n * with the correct context to render the remainder of the route tree. Route\n * elements in the tree must render an `<Outlet>` to render their child route's\n * element.\n *\n * @see https://reactrouter.com/v6/hooks/use-routes\n */\nfunction useRoutes(routes, locationArg) {\n return useRoutesImpl(routes, locationArg);\n}\n\n// Internal implementation with accept optional param for RouterProvider usage\nfunction useRoutesImpl(routes, locationArg, dataRouterState, future) {\n !useInRouterContext() ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n \"useRoutes() may be used only in the context of a <Router> component.\") : UNSAFE_invariant(false) : void 0;\n let {\n navigator\n } = React.useContext(NavigationContext);\n let {\n matches: parentMatches\n } = React.useContext(RouteContext);\n let routeMatch = parentMatches[parentMatches.length - 1];\n let parentParams = routeMatch ? routeMatch.params : {};\n let parentPathname = routeMatch ? routeMatch.pathname : \"/\";\n let parentPathnameBase = routeMatch ? routeMatch.pathnameBase : \"/\";\n let parentRoute = routeMatch && routeMatch.route;\n if (process.env.NODE_ENV !== \"production\") {\n // You won't get a warning about 2 different <Routes> under a <Route>\n // without a trailing *, but this is a best-effort warning anyway since we\n // cannot even give the warning unless they land at the parent route.\n //\n // Example:\n //\n // <Routes>\n // {/* This route path MUST end with /* because otherwise\n // it will never match /blog/post/123 */}\n // <Route path=\"blog\" element={<Blog />} />\n // <Route path=\"blog/feed\" element={<BlogFeed />} />\n // </Routes>\n //\n // function Blog() {\n // return (\n // <Routes>\n // <Route path=\"post/:id\" element={<Post />} />\n // </Routes>\n // );\n // }\n let parentPath = parentRoute && parentRoute.path || \"\";\n warningOnce(parentPathname, !parentRoute || parentPath.endsWith(\"*\"), \"You rendered descendant <Routes> (or called `useRoutes()`) at \" + (\"\\\"\" + parentPathname + \"\\\" (under <Route path=\\\"\" + parentPath + \"\\\">) but the \") + \"parent route path has no trailing \\\"*\\\". This means if you navigate \" + \"deeper, the parent won't match anymore and therefore the child \" + \"routes will never render.\\n\\n\" + (\"Please change the parent <Route path=\\\"\" + parentPath + \"\\\"> to <Route \") + (\"path=\\\"\" + (parentPath === \"/\" ? \"*\" : parentPath + \"/*\") + \"\\\">.\"));\n }\n let locationFromContext = useLocation();\n let location;\n if (locationArg) {\n var _parsedLocationArg$pa;\n let parsedLocationArg = typeof locationArg === \"string\" ? parsePath(locationArg) : locationArg;\n !(parentPathnameBase === \"/\" || ((_parsedLocationArg$pa = parsedLocationArg.pathname) == null ? void 0 : _parsedLocationArg$pa.startsWith(parentPathnameBase))) ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, \"When overriding the location using `<Routes location>` or `useRoutes(routes, location)`, \" + \"the location pathname must begin with the portion of the URL pathname that was \" + (\"matched by all parent routes. The current pathname base is \\\"\" + parentPathnameBase + \"\\\" \") + (\"but pathname \\\"\" + parsedLocationArg.pathname + \"\\\" was given in the `location` prop.\")) : UNSAFE_invariant(false) : void 0;\n location = parsedLocationArg;\n } else {\n location = locationFromContext;\n }\n let pathname = location.pathname || \"/\";\n let remainingPathname = pathname;\n if (parentPathnameBase !== \"/\") {\n // Determine the remaining pathname by removing the # of URL segments the\n // parentPathnameBase has, instead of removing based on character count.\n // This is because we can't guarantee that incoming/outgoing encodings/\n // decodings will match exactly.\n // We decode paths before matching on a per-segment basis with\n // decodeURIComponent(), but we re-encode pathnames via `new URL()` so they\n // match what `window.location.pathname` would reflect. Those don't 100%\n // align when it comes to encoded URI characters such as % and &.\n //\n // So we may end up with:\n // pathname: \"/descendant/a%25b/match\"\n // parentPathnameBase: \"/descendant/a%b\"\n //\n // And the direct substring removal approach won't work :/\n let parentSegments = parentPathnameBase.replace(/^\\//, \"\").split(\"/\");\n let segments = pathname.replace(/^\\//, \"\").split(\"/\");\n remainingPathname = \"/\" + segments.slice(parentSegments.length).join(\"/\");\n }\n let matches = matchRoutes(routes, {\n pathname: remainingPathname\n });\n if (process.env.NODE_ENV !== \"production\") {\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(parentRoute || matches != null, \"No routes matched location \\\"\" + location.pathname + location.search + location.hash + \"\\\" \") : void 0;\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(matches == null || matches[matches.length - 1].route.element !== undefined || matches[matches.length - 1].route.Component !== undefined || matches[matches.length - 1].route.lazy !== undefined, \"Matched leaf route at location \\\"\" + location.pathname + location.search + location.hash + \"\\\" \" + \"does not have an element or Component. This means it will render an <Outlet /> with a \" + \"null value by default resulting in an \\\"empty\\\" page.\") : void 0;\n }\n let renderedMatches = _renderMatches(matches && matches.map(match => Object.assign({}, match, {\n params: Object.assign({}, parentParams, match.params),\n pathname: joinPaths([parentPathnameBase,\n // Re-encode pathnames that were decoded inside matchRoutes\n navigator.encodeLocation ? navigator.encodeLocation(match.pathname).pathname : match.pathname]),\n pathnameBase: match.pathnameBase === \"/\" ? parentPathnameBase : joinPaths([parentPathnameBase,\n // Re-encode pathnames that were decoded inside matchRoutes\n navigator.encodeLocation ? navigator.encodeLocation(match.pathnameBase).pathname : match.pathnameBase])\n })), parentMatches, dataRouterState, future);\n\n // When a user passes in a `locationArg`, the associated routes need to\n // be wrapped in a new `LocationContext.Provider` in order for `useLocation`\n // to use the scoped location instead of the global location.\n if (locationArg && renderedMatches) {\n return /*#__PURE__*/React.createElement(LocationContext.Provider, {\n value: {\n location: _extends({\n pathname: \"/\",\n search: \"\",\n hash: \"\",\n state: null,\n key: \"default\"\n }, location),\n navigationType: Action.Pop\n }\n }, renderedMatches);\n }\n return renderedMatches;\n}\nfunction DefaultErrorComponent() {\n let error = useRouteError();\n let message = isRouteErrorResponse(error) ? error.status + \" \" + error.statusText : error instanceof Error ? error.message : JSON.stringify(error);\n let stack = error instanceof Error ? error.stack : null;\n let lightgrey = \"rgba(200,200,200, 0.5)\";\n let preStyles = {\n padding: \"0.5rem\",\n backgroundColor: lightgrey\n };\n let codeStyles = {\n padding: \"2px 4px\",\n backgroundColor: lightgrey\n };\n let devInfo = null;\n if (process.env.NODE_ENV !== \"production\") {\n console.error(\"Error handled by React Router default ErrorBoundary:\", error);\n devInfo = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(\"p\", null, \"\\uD83D\\uDCBF Hey developer \\uD83D\\uDC4B\"), /*#__PURE__*/React.createElement(\"p\", null, \"You can provide a way better UX than this when your app throws errors by providing your own \", /*#__PURE__*/React.createElement(\"code\", {\n style: codeStyles\n }, \"ErrorBoundary\"), \" or\", \" \", /*#__PURE__*/React.createElement(\"code\", {\n style: codeStyles\n }, \"errorElement\"), \" prop on your route.\"));\n }\n return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(\"h2\", null, \"Unexpected Application Error!\"), /*#__PURE__*/React.createElement(\"h3\", {\n style: {\n fontStyle: \"italic\"\n }\n }, message), stack ? /*#__PURE__*/React.createElement(\"pre\", {\n style: preStyles\n }, stack) : null, devInfo);\n}\nconst defaultErrorElement = /*#__PURE__*/React.createElement(DefaultErrorComponent, null);\nclass RenderErrorBoundary extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n location: props.location,\n revalidation: props.revalidation,\n error: props.error\n };\n }\n static getDerivedStateFromError(error) {\n return {\n error: error\n };\n }\n static getDerivedStateFromProps(props, state) {\n // When we get into an error state, the user will likely click \"back\" to the\n // previous page that didn't have an error. Because this wraps the entire\n // application, that will have no effect--the error page continues to display.\n // This gives us a mechanism to recover from the error when the location changes.\n //\n // Whether we're in an error state or not, we update the location in state\n // so that when we are in an error state, it gets reset when a new location\n // comes in and the user recovers from the error.\n if (state.location !== props.location || state.revalidation !== \"idle\" && props.revalidation === \"idle\") {\n return {\n error: props.error,\n location: props.location,\n revalidation: props.revalidation\n };\n }\n\n // If we're not changing locations, preserve the location but still surface\n // any new errors that may come through. We retain the existing error, we do\n // this because the error provided from the app state may be cleared without\n // the location changing.\n return {\n error: props.error !== undefined ? props.error : state.error,\n location: state.location,\n revalidation: props.revalidation || state.revalidation\n };\n }\n componentDidCatch(error, errorInfo) {\n console.error(\"React Router caught the following error during render\", error, errorInfo);\n }\n render() {\n return this.state.error !== undefined ? /*#__PURE__*/React.createElement(RouteContext.Provider, {\n value: this.props.routeContext\n }, /*#__PURE__*/React.createElement(RouteErrorContext.Provider, {\n value: this.state.error,\n children: this.props.component\n })) : this.props.children;\n }\n}\nfunction RenderedRoute(_ref) {\n let {\n routeContext,\n match,\n children\n } = _ref;\n let dataRouterContext = React.useContext(DataRouterContext);\n\n // Track how deep we got in our render pass to emulate SSR componentDidCatch\n // in a DataStaticRouter\n if (dataRouterContext && dataRouterContext.static && dataRouterContext.staticContext && (match.route.errorElement || match.route.ErrorBoundary)) {\n dataRouterContext.staticContext._deepestRenderedBoundaryId = match.route.id;\n }\n return /*#__PURE__*/React.createElement(RouteContext.Provider, {\n value: routeContext\n }, children);\n}\nfunction _renderMatches(matches, parentMatches, dataRouterState, future) {\n var _dataRouterState;\n if (parentMatches === void 0) {\n parentMatches = [];\n }\n if (dataRouterState === void 0) {\n dataRouterState = null;\n }\n if (future === void 0) {\n future = null;\n }\n if (matches == null) {\n var _future;\n if (!dataRouterState) {\n return null;\n }\n if (dataRouterState.errors) {\n // Don't bail if we have data router errors so we can render them in the\n // boundary. Use the pre-matched (or shimmed) matches\n matches = dataRouterState.matches;\n } else if ((_future = future) != null && _future.v7_partialHydration && parentMatches.length === 0 && !dataRouterState.initialized && dataRouterState.matches.length > 0) {\n // Don't bail if we're initializing with partial hydration and we have\n // router matches. That means we're actively running `patchRoutesOnNavigation`\n // so we should render down the partial matches to the appropriate\n // `HydrateFallback`. We only do this if `parentMatches` is empty so it\n // only impacts the root matches for `RouterProvider` and no descendant\n // `<Routes>`\n matches = dataRouterState.matches;\n } else {\n return null;\n }\n }\n let renderedMatches = matches;\n\n // If we have data errors, trim matches to the highest error boundary\n let errors = (_dataRouterState = dataRouterState) == null ? void 0 : _dataRouterState.errors;\n if (errors != null) {\n let errorIndex = renderedMatches.findIndex(m => m.route.id && (errors == null ? void 0 : errors[m.route.id]) !== undefined);\n !(errorIndex >= 0) ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, \"Could not find a matching route for errors on route IDs: \" + Object.keys(errors).join(\",\")) : UNSAFE_invariant(false) : void 0;\n renderedMatches = renderedMatches.slice(0, Math.min(renderedMatches.length, errorIndex + 1));\n }\n\n // If we're in a partial hydration mode, detect if we need to render down to\n // a given HydrateFallback while we load the rest of the hydration data\n let renderFallback = false;\n let fallbackIndex = -1;\n if (dataRouterState && future && future.v7_partialHydration) {\n for (let i = 0; i < renderedMatches.length; i++) {\n let match = renderedMatches[i];\n // Track the deepest fallback up until the first route without data\n if (match.route.HydrateFallback || match.route.hydrateFallbackElement) {\n fallbackIndex = i;\n }\n if (match.route.id) {\n let {\n loaderData,\n errors\n } = dataRouterState;\n let needsToRunLoader = match.route.loader && loaderData[match.route.id] === undefined && (!errors || errors[match.route.id] === undefined);\n if (match.route.lazy || needsToRunLoader) {\n // We found the first route that's not ready to render (waiting on\n // lazy, or has a loader that hasn't run yet). Flag that we need to\n // render a fallback and render up until the appropriate fallback\n renderFallback = true;\n if (fallbackIndex >= 0) {\n renderedMatches = renderedMatches.slice(0, fallbackIndex + 1);\n } else {\n renderedMatches = [renderedMatches[0]];\n }\n break;\n }\n }\n }\n }\n return renderedMatches.reduceRight((outlet, match, index) => {\n // Only data routers handle errors/fallbacks\n let error;\n let shouldRenderHydrateFallback = false;\n let errorElement = null;\n let hydrateFallbackElement = null;\n if (dataRouterState) {\n error = errors && match.route.id ? errors[match.route.id] : undefined;\n errorElement = match.route.errorElement || defaultErrorElement;\n if (renderFallback) {\n if (fallbackIndex < 0 && index === 0) {\n warningOnce(\"route-fallback\", false, \"No `HydrateFallback` element provided to render during initial hydration\");\n shouldRenderHydrateFallback = true;\n hydrateFallbackElement = null;\n } else if (fallbackIndex === index) {\n shouldRenderHydrateFallback = true;\n hydrateFallbackElement = match.route.hydrateFallbackElement || null;\n }\n }\n }\n let matches = parentMatches.concat(renderedMatches.slice(0, index + 1));\n let getChildren = () => {\n let children;\n if (error) {\n children = errorElement;\n } else if (shouldRenderHydrateFallback) {\n children = hydrateFallbackElement;\n } else if (match.route.Component) {\n // Note: This is a de-optimized path since React won't re-use the\n // ReactElement since it's identity changes with each new\n // React.createElement call. We keep this so folks can use\n // `<Route Component={...}>` in `<Routes>` but generally `Component`\n // usage is only advised in `RouterProvider` when we can convert it to\n // `element` ahead of time.\n children = /*#__PURE__*/React.createElement(match.route.Component, null);\n } else if (match.route.element) {\n children = match.route.element;\n } else {\n children = outlet;\n }\n return /*#__PURE__*/React.createElement(RenderedRoute, {\n match: match,\n routeContext: {\n outlet,\n matches,\n isDataRoute: dataRouterState != null\n },\n children: children\n });\n };\n // Only wrap in an error boundary within data router usages when we have an\n // ErrorBoundary/errorElement on this route. Otherwise let it bubble up to\n // an ancestor ErrorBoundary/errorElement\n return dataRouterState && (match.route.ErrorBoundary || match.route.errorElement || index === 0) ? /*#__PURE__*/React.createElement(RenderErrorBoundary, {\n location: dataRouterState.location,\n revalidation: dataRouterState.revalidation,\n component: errorElement,\n error: error,\n children: getChildren(),\n routeContext: {\n outlet: null,\n matches,\n isDataRoute: true\n }\n }) : getChildren();\n }, null);\n}\nvar DataRouterHook = /*#__PURE__*/function (DataRouterHook) {\n DataRouterHook[\"UseBlocker\"] = \"useBlocker\";\n DataRouterHook[\"UseRevalidator\"] = \"useRevalidator\";\n DataRouterHook[\"UseNavigateStable\"] = \"useNavigate\";\n return DataRouterHook;\n}(DataRouterHook || {});\nvar DataRouterStateHook = /*#__PURE__*/function (DataRouterStateHook) {\n DataRouterStateHook[\"UseBlocker\"] = \"useBlocker\";\n DataRouterStateHook[\"UseLoaderData\"] = \"useLoaderData\";\n DataRouterStateHook[\"UseActionData\"] = \"useActionData\";\n DataRouterStateHook[\"UseRouteError\"] = \"useRouteError\";\n DataRouterStateHook[\"UseNavigation\"] = \"useNavigation\";\n DataRouterStateHook[\"UseRouteLoaderData\"] = \"useRouteLoaderData\";\n DataRouterStateHook[\"UseMatches\"] = \"useMatches\";\n DataRouterStateHook[\"UseRevalidator\"] = \"useRevalidator\";\n DataRouterStateHook[\"UseNavigateStable\"] = \"useNavigate\";\n DataRouterStateHook[\"UseRouteId\"] = \"useRouteId\";\n return DataRouterStateHook;\n}(DataRouterStateHook || {});\nfunction getDataRouterConsoleError(hookName) {\n return hookName + \" must be used within a data router. See https://reactrouter.com/v6/routers/picking-a-router.\";\n}\nfunction useDataRouterContext(hookName) {\n let ctx = React.useContext(DataRouterContext);\n !ctx ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, getDataRouterConsoleError(hookName)) : UNSAFE_invariant(false) : void 0;\n return ctx;\n}\nfunction useDataRouterState(hookName) {\n let state = React.useContext(DataRouterStateContext);\n !state ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, getDataRouterConsoleError(hookName)) : UNSAFE_invariant(false) : void 0;\n return state;\n}\nfunction useRouteContext(hookName) {\n let route = React.useContext(RouteContext);\n !route ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, getDataRouterConsoleError(hookName)) : UNSAFE_invariant(false) : void 0;\n return route;\n}\n\n// Internal version with hookName-aware debugging\nfunction useCurrentRouteId(hookName) {\n let route = useRouteContext(hookName);\n let thisRoute = route.matches[route.matches.length - 1];\n !thisRoute.route.id ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, hookName + \" can only be used on routes that contain a unique \\\"id\\\"\") : UNSAFE_invariant(false) : void 0;\n return thisRoute.route.id;\n}\n\n/**\n * Returns the ID for the nearest contextual route\n */\nfunction useRouteId() {\n return useCurrentRouteId(DataRouterStateHook.UseRouteId);\n}\n\n/**\n * Returns the current navigation, defaulting to an \"idle\" navigation when\n * no navigation is in progress\n */\nfunction useNavigation() {\n let state = useDataRouterState(DataRouterStateHook.UseNavigation);\n return state.navigation;\n}\n\n/**\n * Returns a revalidate function for manually triggering revalidation, as well\n * as the current state of any manual revalidations\n */\nfunction useRevalidator() {\n let dataRouterContext = useDataRouterContext(DataRouterHook.UseRevalidator);\n let state = useDataRouterState(DataRouterStateHook.UseRevalidator);\n return React.useMemo(() => ({\n revalidate: dataRouterContext.router.revalidate,\n state: state.revalidation\n }), [dataRouterContext.router.revalidate, state.revalidation]);\n}\n\n/**\n * Returns the active route matches, useful for accessing loaderData for\n * parent/child routes or the route \"handle\" property\n */\nfunction useMatches() {\n let {\n matches,\n loaderData\n } = useDataRouterState(DataRouterStateHook.UseMatches);\n return React.useMemo(() => matches.map(m => UNSAFE_convertRouteMatchToUiMatch(m, loaderData)), [matches, loaderData]);\n}\n\n/**\n * Returns the loader data for the nearest ancestor Route loader\n */\nfunction useLoaderData() {\n let state = useDataRouterState(DataRouterStateHook.UseLoaderData);\n let routeId = useCurrentRouteId(DataRouterStateHook.UseLoaderData);\n if (state.errors && state.errors[routeId] != null) {\n console.error(\"You cannot `useLoaderData` in an errorElement (routeId: \" + routeId + \")\");\n return undefined;\n }\n return state.loaderData[routeId];\n}\n\n/**\n * Returns the loaderData for the given routeId\n */\nfunction useRouteLoaderData(routeId) {\n let state = useDataRouterState(DataRouterStateHook.UseRouteLoaderData);\n return state.loaderData[routeId];\n}\n\n/**\n * Returns the action data for the nearest ancestor Route action\n */\nfunction useActionData() {\n let state = useDataRouterState(DataRouterStateHook.UseActionData);\n let routeId = useCurrentRouteId(DataRouterStateHook.UseLoaderData);\n return state.actionData ? state.actionData[routeId] : undefined;\n}\n\n/**\n * Returns the nearest ancestor Route error, which could be a loader/action\n * error or a render error. This is intended to be called from your\n * ErrorBoundary/errorElement to display a proper error message.\n */\nfunction useRouteError() {\n var _state$errors;\n let error = React.useContext(RouteErrorContext);\n let state = useDataRouterState(DataRouterStateHook.UseRouteError);\n let routeId = useCurrentRouteId(DataRouterStateHook.UseRouteError);\n\n // If this was a render error, we put it in a RouteError context inside\n // of RenderErrorBoundary\n if (error !== undefined) {\n return error;\n }\n\n // Otherwise look for errors from our data router state\n return (_state$errors = state.errors) == null ? void 0 : _state$errors[routeId];\n}\n\n/**\n * Returns the happy-path data from the nearest ancestor `<Await />` value\n */\nfunction useAsyncValue() {\n let value = React.useContext(AwaitContext);\n return value == null ? void 0 : value._data;\n}\n\n/**\n * Returns the error from the nearest ancestor `<Await />` value\n */\nfunction useAsyncError() {\n let value = React.useContext(AwaitContext);\n return value == null ? void 0 : value._error;\n}\nlet blockerId = 0;\n\n/**\n * Allow the application to block navigations within the SPA and present the\n * user a confirmation dialog to confirm the navigation. Mostly used to avoid\n * using half-filled form data. This does not handle hard-reloads or\n * cross-origin navigations.\n */\nfunction useBlocker(shouldBlock) {\n let {\n router,\n basename\n } = useDataRouterContext(DataRouterHook.UseBlocker);\n let state = useDataRouterState(DataRouterStateHook.UseBlocker);\n let [blockerKey, setBlockerKey] = React.useState(\"\");\n let blockerFunction = React.useCallback(arg => {\n if (typeof shouldBlock !== \"function\") {\n return !!shouldBlock;\n }\n if (basename === \"/\") {\n return shouldBlock(arg);\n }\n\n // If they provided us a function and we've got an active basename, strip\n // it from the locations we expose to the user to match the behavior of\n // useLocation\n let {\n currentLocation,\n nextLocation,\n historyAction\n } = arg;\n return shouldBlock({\n currentLocation: _extends({}, currentLocation, {\n pathname: stripBasename(currentLocation.pathname, basename) || currentLocation.pathname\n }),\n nextLocation: _extends({}, nextLocation, {\n pathname: stripBasename(nextLocation.pathname, basename) || nextLocation.pathname\n }),\n historyAction\n });\n }, [basename, shouldBlock]);\n\n // This effect is in charge of blocker key assignment and deletion (which is\n // tightly coupled to the key)\n React.useEffect(() => {\n let key = String(++blockerId);\n setBlockerKey(key);\n return () => router.deleteBlocker(key);\n }, [router]);\n\n // This effect handles assigning the blockerFunction. This is to handle\n // unstable blocker function identities, and happens only after the prior\n // effect so we don't get an orphaned blockerFunction in the router with a\n // key of \"\". Until then we just have the IDLE_BLOCKER.\n React.useEffect(() => {\n if (blockerKey !== \"\") {\n router.getBlocker(blockerKey, blockerFunction);\n }\n }, [router, blockerKey, blockerFunction]);\n\n // Prefer the blocker from `state` not `router.state` since DataRouterContext\n // is memoized so this ensures we update on blocker state updates\n return blockerKey && state.blockers.has(blockerKey) ? state.blockers.get(blockerKey) : IDLE_BLOCKER;\n}\n\n/**\n * Stable version of useNavigate that is used when we are in the context of\n * a RouterProvider.\n */\nfunction useNavigateStable() {\n let {\n router\n } = useDataRouterContext(DataRouterHook.UseNavigateStable);\n let id = useCurrentRouteId(DataRouterStateHook.UseNavigateStable);\n let activeRef = React.useRef(false);\n useIsomorphicLayoutEffect(() => {\n activeRef.current = true;\n });\n let navigate = React.useCallback(function (to, options) {\n if (options === void 0) {\n options = {};\n }\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(activeRef.current, navigateEffectWarning) : void 0;\n\n // Short circuit here since if this happens on first render the navigate\n // is useless because we haven't wired up our router subscriber yet\n if (!activeRef.current) return;\n if (typeof to === \"number\") {\n router.navigate(to);\n } else {\n router.navigate(to, _extends({\n fromRouteId: id\n }, options));\n }\n }, [router, id]);\n return navigate;\n}\nconst alreadyWarned$1 = {};\nfunction warningOnce(key, cond, message) {\n if (!cond && !alreadyWarned$1[key]) {\n alreadyWarned$1[key] = true;\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(false, message) : void 0;\n }\n}\n\nconst alreadyWarned = {};\nfunction warnOnce(key, message) {\n if (process.env.NODE_ENV !== \"production\" && !alreadyWarned[message]) {\n alreadyWarned[message] = true;\n console.warn(message);\n }\n}\nconst logDeprecation = (flag, msg, link) => warnOnce(flag, \"\\u26A0\\uFE0F React Router Future Flag Warning: \" + msg + \". \" + (\"You can use the `\" + flag + \"` future flag to opt-in early. \") + (\"For more information, see \" + link + \".\"));\nfunction logV6DeprecationWarnings(renderFuture, routerFuture) {\n if ((renderFuture == null ? void 0 : renderFuture.v7_startTransition) === undefined) {\n logDeprecation(\"v7_startTransition\", \"React Router will begin wrapping state updates in `React.startTransition` in v7\", \"https://reactrouter.com/v6/upgrading/future#v7_starttransition\");\n }\n if ((renderFuture == null ? void 0 : renderFuture.v7_relativeSplatPath) === undefined && (!routerFuture || routerFuture.v7_relativeSplatPath === undefined)) {\n logDeprecation(\"v7_relativeSplatPath\", \"Relative route resolution within Splat routes is changing in v7\", \"https://reactrouter.com/v6/upgrading/future#v7_relativesplatpath\");\n }\n if (routerFuture) {\n if (routerFuture.v7_fetcherPersist === undefined) {\n logDeprecation(\"v7_fetcherPersist\", \"The persistence behavior of fetchers is changing in v7\", \"https://reactrouter.com/v6/upgrading/future#v7_fetcherpersist\");\n }\n if (routerFuture.v7_normalizeFormMethod === undefined) {\n logDeprecation(\"v7_normalizeFormMethod\", \"Casing of `formMethod` fields is being normalized to uppercase in v7\", \"https://reactrouter.com/v6/upgrading/future#v7_normalizeformmethod\");\n }\n if (routerFuture.v7_partialHydration === undefined) {\n logDeprecation(\"v7_partialHydration\", \"`RouterProvider` hydration behavior is changing in v7\", \"https://reactrouter.com/v6/upgrading/future#v7_partialhydration\");\n }\n if (routerFuture.v7_skipActionErrorRevalidation === undefined) {\n logDeprecation(\"v7_skipActionErrorRevalidation\", \"The revalidation behavior after 4xx/5xx `action` responses is changing in v7\", \"https://reactrouter.com/v6/upgrading/future#v7_skipactionerrorrevalidation\");\n }\n }\n}\n\n/**\n Webpack + React 17 fails to compile on any of the following because webpack\n complains that `startTransition` doesn't exist in `React`:\n * import { startTransition } from \"react\"\n * import * as React from from \"react\";\n \"startTransition\" in React ? React.startTransition(() => setState()) : setState()\n * import * as React from from \"react\";\n \"startTransition\" in React ? React[\"startTransition\"](() => setState()) : setState()\n\n Moving it to a constant such as the following solves the Webpack/React 17 issue:\n * import * as React from from \"react\";\n const START_TRANSITION = \"startTransition\";\n START_TRANSITION in React ? React[START_TRANSITION](() => setState()) : setState()\n\n However, that introduces webpack/terser minification issues in production builds\n in React 18 where minification/obfuscation ends up removing the call of\n React.startTransition entirely from the first half of the ternary. Grabbing\n this exported reference once up front resolves that issue.\n\n See https://github.com/remix-run/react-router/issues/10579\n*/\nconst START_TRANSITION = \"startTransition\";\nconst startTransitionImpl = React[START_TRANSITION];\n\n/**\n * Given a Remix Router instance, render the appropriate UI\n */\nfunction RouterProvider(_ref) {\n let {\n fallbackElement,\n router,\n future\n } = _ref;\n let [state, setStateImpl] = React.useState(router.state);\n let {\n v7_startTransition\n } = future || {};\n let setState = React.useCallback(newState => {\n if (v7_startTransition && startTransitionImpl) {\n startTransitionImpl(() => setStateImpl(newState));\n } else {\n setStateImpl(newState);\n }\n }, [setStateImpl, v7_startTransition]);\n\n // Need to use a layout effect here so we are subscribed early enough to\n // pick up on any render-driven redirects/navigations (useEffect/<Navigate>)\n React.useLayoutEffect(() => router.subscribe(setState), [router, setState]);\n React.useEffect(() => {\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(fallbackElement == null || !router.future.v7_partialHydration, \"`<RouterProvider fallbackElement>` is deprecated when using \" + \"`v7_partialHydration`, use a `HydrateFallback` component instead\") : void 0;\n // Only log this once on initial mount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n let navigator = React.useMemo(() => {\n return {\n createHref: router.createHref,\n encodeLocation: router.encodeLocation,\n go: n => router.navigate(n),\n push: (to, state, opts) => router.navigate(to, {\n state,\n preventScrollReset: opts == null ? void 0 : opts.preventScrollReset\n }),\n replace: (to, state, opts) => router.navigate(to, {\n replace: true,\n state,\n preventScrollReset: opts == null ? void 0 : opts.preventScrollReset\n })\n };\n }, [router]);\n let basename = router.basename || \"/\";\n let dataRouterContext = React.useMemo(() => ({\n router,\n navigator,\n static: false,\n basename\n }), [router, navigator, basename]);\n React.useEffect(() => logV6DeprecationWarnings(future, router.future), [router, future]);\n\n // The fragment and {null} here are important! We need them to keep React 18's\n // useId happy when we are server-rendering since we may have a <script> here\n // containing the hydrated server-side staticContext (from StaticRouterProvider).\n // useId relies on the component tree structure to generate deterministic id's\n // so we need to ensure it remains the same on the client even though\n // we don't need the <script> tag\n return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(DataRouterContext.Provider, {\n value: dataRouterContext\n }, /*#__PURE__*/React.createElement(DataRouterStateContext.Provider, {\n value: state\n }, /*#__PURE__*/React.createElement(Router, {\n basename: basename,\n location: state.location,\n navigationType: state.historyAction,\n navigator: navigator,\n future: {\n v7_relativeSplatPath: router.future.v7_relativeSplatPath\n }\n }, state.initialized || router.future.v7_partialHydration ? /*#__PURE__*/React.createElement(DataRoutes, {\n routes: router.routes,\n future: router.future,\n state: state\n }) : fallbackElement))), null);\n}\nfunction DataRoutes(_ref2) {\n let {\n routes,\n future,\n state\n } = _ref2;\n return useRoutesImpl(routes, undefined, state, future);\n}\n/**\n * A `<Router>` that stores all entries in memory.\n *\n * @see https://reactrouter.com/v6/router-components/memory-router\n */\nfunction MemoryRouter(_ref3) {\n let {\n basename,\n children,\n initialEntries,\n initialIndex,\n future\n } = _ref3;\n let historyRef = React.useRef();\n if (historyRef.current == null) {\n historyRef.current = createMemoryHistory({\n initialEntries,\n initialIndex,\n v5Compat: true\n });\n }\n let history = historyRef.current;\n let [state, setStateImpl] = React.useState({\n action: history.action,\n location: history.location\n });\n let {\n v7_startTransition\n } = future || {};\n let setState = React.useCallback(newState => {\n v7_startTransition && startTransitionImpl ? startTransitionImpl(() => setStateImpl(newState)) : setStateImpl(newState);\n }, [setStateImpl, v7_startTransition]);\n React.useLayoutEffect(() => history.listen(setState), [history, setState]);\n React.useEffect(() => logV6DeprecationWarnings(future), [future]);\n return /*#__PURE__*/React.createElement(Router, {\n basename: basename,\n children: children,\n location: state.location,\n navigationType: state.action,\n navigator: history,\n future: future\n });\n}\n/**\n * Changes the current location.\n *\n * Note: This API is mostly useful in React.Component subclasses that are not\n * able to use hooks. In functional components, we recommend you use the\n * `useNavigate` hook instead.\n *\n * @see https://reactrouter.com/v6/components/navigate\n */\nfunction Navigate(_ref4) {\n let {\n to,\n replace,\n state,\n relative\n } = _ref4;\n !useInRouterContext() ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of\n // the router loaded. We can help them understand how to avoid that.\n \"<Navigate> may be used only in the context of a <Router> component.\") : UNSAFE_invariant(false) : void 0;\n let {\n future,\n static: isStatic\n } = React.useContext(NavigationContext);\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(!isStatic, \"<Navigate> must not be used on the initial render in a <StaticRouter>. \" + \"This is a no-op, but you should modify your code so the <Navigate> is \" + \"only ever rendered in response to some user interaction or state change.\") : void 0;\n let {\n matches\n } = React.useContext(RouteContext);\n let {\n pathname: locationPathname\n } = useLocation();\n let navigate = useNavigate();\n\n // Resolve the path outside of the effect so that when effects run twice in\n // StrictMode they navigate to the same place\n let path = resolveTo(to, UNSAFE_getResolveToMatches(matches, future.v7_relativeSplatPath), locationPathname, relative === \"path\");\n let jsonPath = JSON.stringify(path);\n React.useEffect(() => navigate(JSON.parse(jsonPath), {\n replace,\n state,\n relative\n }), [navigate, jsonPath, relative, replace, state]);\n return null;\n}\n/**\n * Renders the child route's element, if there is one.\n *\n * @see https://reactrouter.com/v6/components/outlet\n */\nfunction Outlet(props) {\n return useOutlet(props.context);\n}\n/**\n * Declares an element that should be rendered at a certain URL path.\n *\n * @see https://reactrouter.com/v6/components/route\n */\nfunction Route(_props) {\n process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, \"A <Route> is only ever to be used as the child of <Routes> element, \" + \"never rendered directly. Please wrap your <Route> in a <Routes>.\") : UNSAFE_invariant(false) ;\n}\n/**\n * Provides location context for the rest of the app.\n *\n * Note: You usually won't render a `<Router>` directly. Instead, you'll render a\n * router that is more specific to your environment such as a `<BrowserRouter>`\n * in web browsers or a `<StaticRouter>` for server rendering.\n *\n * @see https://reactrouter.com/v6/router-components/router\n */\nfunction Router(_ref5) {\n let {\n basename: basenameProp = \"/\",\n children = null,\n location: locationProp,\n navigationType = Action.Pop,\n navigator,\n static: staticProp = false,\n future\n } = _ref5;\n !!useInRouterContext() ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, \"You cannot render a <Router> inside another <Router>.\" + \" You should never have more than one in your app.\") : UNSAFE_invariant(false) : void 0;\n\n // Preserve trailing slashes on basename, so we can let the user control\n // the enforcement of trailing slashes throughout the app\n let basename = basenameProp.replace(/^\\/*/, \"/\");\n let navigationContext = React.useMemo(() => ({\n basename,\n navigator,\n static: staticProp,\n future: _extends({\n v7_relativeSplatPath: false\n }, future)\n }), [basename, future, navigator, staticProp]);\n if (typeof locationProp === \"string\") {\n locationProp = parsePath(locationProp);\n }\n let {\n pathname = \"/\",\n search = \"\",\n hash = \"\",\n state = null,\n key = \"default\"\n } = locationProp;\n let locationContext = React.useMemo(() => {\n let trailingPathname = stripBasename(pathname, basename);\n if (trailingPathname == null) {\n return null;\n }\n return {\n location: {\n pathname: trailingPathname,\n search,\n hash,\n state,\n key\n },\n navigationType\n };\n }, [basename, pathname, search, hash, state, key, navigationType]);\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(locationContext != null, \"<Router basename=\\\"\" + basename + \"\\\"> is not able to match the URL \" + (\"\\\"\" + pathname + search + hash + \"\\\" because it does not start with the \") + \"basename, so the <Router> won't render anything.\") : void 0;\n if (locationContext == null) {\n return null;\n }\n return /*#__PURE__*/React.createElement(NavigationContext.Provider, {\n value: navigationContext\n }, /*#__PURE__*/React.createElement(LocationContext.Provider, {\n children: children,\n value: locationContext\n }));\n}\n/**\n * A container for a nested tree of `<Route>` elements that renders the branch\n * that best matches the current location.\n *\n * @see https://reactrouter.com/v6/components/routes\n */\nfunction Routes(_ref6) {\n let {\n children,\n location\n } = _ref6;\n return useRoutes(createRoutesFromChildren(children), location);\n}\n/**\n * Component to use for rendering lazily loaded data from returning defer()\n * in a loader function\n */\nfunction Await(_ref7) {\n let {\n children,\n errorElement,\n resolve\n } = _ref7;\n return /*#__PURE__*/React.createElement(AwaitErrorBoundary, {\n resolve: resolve,\n errorElement: errorElement\n }, /*#__PURE__*/React.createElement(ResolveAwait, null, children));\n}\nvar AwaitRenderStatus = /*#__PURE__*/function (AwaitRenderStatus) {\n AwaitRenderStatus[AwaitRenderStatus[\"pending\"] = 0] = \"pending\";\n AwaitRenderStatus[AwaitRenderStatus[\"success\"] = 1] = \"success\";\n AwaitRenderStatus[AwaitRenderStatus[\"error\"] = 2] = \"error\";\n return AwaitRenderStatus;\n}(AwaitRenderStatus || {});\nconst neverSettledPromise = new Promise(() => {});\nclass AwaitErrorBoundary extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n error: null\n };\n }\n static getDerivedStateFromError(error) {\n return {\n error\n };\n }\n componentDidCatch(error, errorInfo) {\n console.error(\"<Await> caught the following error during render\", error, errorInfo);\n }\n render() {\n let {\n children,\n errorElement,\n resolve\n } = this.props;\n let promise = null;\n let status = AwaitRenderStatus.pending;\n if (!(resolve instanceof Promise)) {\n // Didn't get a promise - provide as a resolved promise\n status = AwaitRenderStatus.success;\n promise = Promise.resolve();\n Object.defineProperty(promise, \"_tracked\", {\n get: () => true\n });\n Object.defineProperty(promise, \"_data\", {\n get: () => resolve\n });\n } else if (this.state.error) {\n // Caught a render error, provide it as a rejected promise\n status = AwaitRenderStatus.error;\n let renderError = this.state.error;\n promise = Promise.reject().catch(() => {}); // Avoid unhandled rejection warnings\n Object.defineProperty(promise, \"_tracked\", {\n get: () => true\n });\n Object.defineProperty(promise, \"_error\", {\n get: () => renderError\n });\n } else if (resolve._tracked) {\n // Already tracked promise - check contents\n promise = resolve;\n status = \"_error\" in promise ? AwaitRenderStatus.error : \"_data\" in promise ? AwaitRenderStatus.success : AwaitRenderStatus.pending;\n } else {\n // Raw (untracked) promise - track it\n status = AwaitRenderStatus.pending;\n Object.defineProperty(resolve, \"_tracked\", {\n get: () => true\n });\n promise = resolve.then(data => Object.defineProperty(resolve, \"_data\", {\n get: () => data\n }), error => Object.defineProperty(resolve, \"_error\", {\n get: () => error\n }));\n }\n if (status === AwaitRenderStatus.error && promise._error instanceof AbortedDeferredError) {\n // Freeze the UI by throwing a never resolved promise\n throw neverSettledPromise;\n }\n if (status === AwaitRenderStatus.error && !errorElement) {\n // No errorElement, throw to the nearest route-level error boundary\n throw promise._error;\n }\n if (status === AwaitRenderStatus.error) {\n // Render via our errorElement\n return /*#__PURE__*/React.createElement(AwaitContext.Provider, {\n value: promise,\n children: errorElement\n });\n }\n if (status === AwaitRenderStatus.success) {\n // Render children with resolved value\n return /*#__PURE__*/React.createElement(AwaitContext.Provider, {\n value: promise,\n children: children\n });\n }\n\n // Throw to the suspense boundary\n throw promise;\n }\n}\n\n/**\n * @private\n * Indirection to leverage useAsyncValue for a render-prop API on `<Await>`\n */\nfunction ResolveAwait(_ref8) {\n let {\n children\n } = _ref8;\n let data = useAsyncValue();\n let toRender = typeof children === \"function\" ? children(data) : children;\n return /*#__PURE__*/React.createElement(React.Fragment, null, toRender);\n}\n\n///////////////////////////////////////////////////////////////////////////////\n// UTILS\n///////////////////////////////////////////////////////////////////////////////\n\n/**\n * Creates a route config from a React \"children\" object, which is usually\n * either a `<Route>` element or an array of them. Used internally by\n * `<Routes>` to create a route config from its children.\n *\n * @see https://reactrouter.com/v6/utils/create-routes-from-children\n */\nfunction createRoutesFromChildren(children, parentPath) {\n if (parentPath === void 0) {\n parentPath = [];\n }\n let routes = [];\n React.Children.forEach(children, (element, index) => {\n if (! /*#__PURE__*/React.isValidElement(element)) {\n // Ignore non-elements. This allows people to more easily inline\n // conditionals in their route config.\n return;\n }\n let treePath = [...parentPath, index];\n if (element.type === React.Fragment) {\n // Transparently support React.Fragment and its children.\n routes.push.apply(routes, createRoutesFromChildren(element.props.children, treePath));\n return;\n }\n !(element.type === Route) ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, \"[\" + (typeof element.type === \"string\" ? element.type : element.type.name) + \"] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>\") : UNSAFE_invariant(false) : void 0;\n !(!element.props.index || !element.props.children) ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, \"An index route cannot have child routes.\") : UNSAFE_invariant(false) : void 0;\n let route = {\n id: element.props.id || treePath.join(\"-\"),\n caseSensitive: element.props.caseSensitive,\n element: element.props.element,\n Component: element.props.Component,\n index: element.props.index,\n path: element.props.path,\n loader: element.props.loader,\n action: element.props.action,\n errorElement: element.props.errorElement,\n ErrorBoundary: element.props.ErrorBoundary,\n hasErrorBoundary: element.props.ErrorBoundary != null || element.props.errorElement != null,\n shouldRevalidate: element.props.shouldRevalidate,\n handle: element.props.handle,\n lazy: element.props.lazy\n };\n if (element.props.children) {\n route.children = createRoutesFromChildren(element.props.children, treePath);\n }\n routes.push(route);\n });\n return routes;\n}\n\n/**\n * Renders the result of `matchRoutes()` into a React element.\n */\nfunction renderMatches(matches) {\n return _renderMatches(matches);\n}\n\nfunction mapRouteProperties(route) {\n let updates = {\n // Note: this check also occurs in createRoutesFromChildren so update\n // there if you change this -- please and thank you!\n hasErrorBoundary: route.ErrorBoundary != null || route.errorElement != null\n };\n if (route.Component) {\n if (process.env.NODE_ENV !== \"production\") {\n if (route.element) {\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(false, \"You should not include both `Component` and `element` on your route - \" + \"`Component` will be used.\") : void 0;\n }\n }\n Object.assign(updates, {\n element: /*#__PURE__*/React.createElement(route.Component),\n Component: undefined\n });\n }\n if (route.HydrateFallback) {\n if (process.env.NODE_ENV !== \"production\") {\n if (route.hydrateFallbackElement) {\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(false, \"You should not include both `HydrateFallback` and `hydrateFallbackElement` on your route - \" + \"`HydrateFallback` will be used.\") : void 0;\n }\n }\n Object.assign(updates, {\n hydrateFallbackElement: /*#__PURE__*/React.createElement(route.HydrateFallback),\n HydrateFallback: undefined\n });\n }\n if (route.ErrorBoundary) {\n if (process.env.NODE_ENV !== \"production\") {\n if (route.errorElement) {\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(false, \"You should not include both `ErrorBoundary` and `errorElement` on your route - \" + \"`ErrorBoundary` will be used.\") : void 0;\n }\n }\n Object.assign(updates, {\n errorElement: /*#__PURE__*/React.createElement(route.ErrorBoundary),\n ErrorBoundary: undefined\n });\n }\n return updates;\n}\nfunction createMemoryRouter(routes, opts) {\n return createRouter({\n basename: opts == null ? void 0 : opts.basename,\n future: _extends({}, opts == null ? void 0 : opts.future, {\n v7_prependBasename: true\n }),\n history: createMemoryHistory({\n initialEntries: opts == null ? void 0 : opts.initialEntries,\n initialIndex: opts == null ? void 0 : opts.initialIndex\n }),\n hydrationData: opts == null ? void 0 : opts.hydrationData,\n routes,\n mapRouteProperties,\n dataStrategy: opts == null ? void 0 : opts.dataStrategy,\n patchRoutesOnNavigation: opts == null ? void 0 : opts.patchRoutesOnNavigation\n }).initialize();\n}\n\nexport { Await, MemoryRouter, Navigate, Outlet, Route, Router, RouterProvider, Routes, DataRouterContext as UNSAFE_DataRouterContext, DataRouterStateContext as UNSAFE_DataRouterStateContext, LocationContext as UNSAFE_LocationContext, NavigationContext as UNSAFE_NavigationContext, RouteContext as UNSAFE_RouteContext, logV6DeprecationWarnings as UNSAFE_logV6DeprecationWarnings, mapRouteProperties as UNSAFE_mapRouteProperties, useRouteId as UNSAFE_useRouteId, useRoutesImpl as UNSAFE_useRoutesImpl, createMemoryRouter, createRoutesFromChildren, createRoutesFromChildren as createRoutesFromElements, renderMatches, useActionData, useAsyncError, useAsyncValue, useBlocker, useHref, useInRouterContext, useLoaderData, useLocation, useMatch, useMatches, useNavigate, useNavigation, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRevalidator, useRouteError, useRouteLoaderData, useRoutes };\n//# sourceMappingURL=index.js.map\n","/**\n * FormBuilderPage - Standalone form builder page component for user-defined routing\n *\n * @deprecated Use FormBuilderView directly with your framework's param reading\n */\n\nimport { useFormNavigation } from \"@formbuilder/forms/navigation\";\nimport type React from \"react\";\nimport { useParams } from \"react-router-dom\";\nimport type { FormConfig } from \"../../../config/types\";\nimport { FormBuilderView } from \"../../../features/form-management/components/FormBuilderView/FormBuilderView\";\nimport styles from \"./FormBuilderPage.module.css\";\n\nexport interface FormBuilderPageProps {\n\t/**\n\t * Optional form configuration\n\t */\n\tconfig?: FormConfig;\n\n\t/**\n\t * Optional CSS class name\n\t */\n\tclassName?: string;\n\n\t/**\n\t * Optional inline styles\n\t */\n\tstyle?: React.CSSProperties;\n}\n\n/**\n * Standalone FormBuilderPage component for user-defined routing\n * Shows the form builder for a specific form\n *\n * @deprecated Use FormBuilderView directly with your framework's param reading\n */\nexport const FormBuilderPage: React.FC<FormBuilderPageProps> = ({\n\tconfig,\n\tclassName,\n\tstyle,\n}) => {\n\tconst params = useParams();\n\tconst { project: projectId, wizardId } = params;\n\tconst { navigateToProjects } = useFormNavigation();\n\n\t// If no project ID or wizard ID in URL, show error state\n\tif (!projectId || !wizardId) {\n\t\treturn (\n\t\t\t<div className={styles.errorContainer}>\n\t\t\t\t<div className={styles.errorContent}>\n\t\t\t\t\t<h2 className={styles.errorHeading}>\n\t\t\t\t\t\tMissing Parameters\n\t\t\t\t\t</h2>\n\t\t\t\t\t<p className={styles.errorText}>\n\t\t\t\t\t\tProject ID or Form ID is missing from the URL.\n\t\t\t\t\t</p>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={() => navigateToProjects()}\n\t\t\t\t\t\tclassName={styles.backButton}\n\t\t\t\t\t>\n\t\t\t\t\t\tBack to Projects\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<FormBuilderView\n\t\t\tprojectId={projectId}\n\t\t\tformId={wizardId}\n\t\t\tconfig={config}\n\t\t\tclassName={className}\n\t\t\tstyle={style}\n\t\t/>\n\t);\n};\n","/**\n * FormsPage - Standalone forms page component for user-defined routing\n *\n * @deprecated Use FormsView directly with your framework's param reading\n */\n\nimport { useFormNavigation } from \"@formbuilder/forms/navigation\";\nimport type React from \"react\";\nimport { useParams } from \"react-router-dom\";\nimport { FormsView } from \"../../features/form-management/components/FormsView/FormsView\";\n\nexport interface FormsPageProps {\n\t/**\n\t * Optional CSS class name\n\t */\n\tclassName?: string;\n\n\t/**\n\t * Optional inline styles\n\t */\n\tstyle?: React.CSSProperties;\n}\n\n/**\n * Standalone FormsPage component for user-defined routing\n * Shows forms within a specific project\n *\n * @deprecated Use FormsView directly with your framework's param reading\n */\nexport const FormsPage: React.FC<FormsPageProps> = ({ className, style }) => {\n\tconst params = useParams();\n\tconst projectId = params.project;\n\tconst { navigateToProjects } = useFormNavigation();\n\n\t// If no project ID in URL, redirect to projects\n\tif (!projectId) {\n\t\tnavigateToProjects();\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<FormsView projectId={projectId} className={className} style={style} />\n\t);\n};\n","/**\n * ProjectsPage - Standalone projects page component for user-defined routing\n */\n\nimport type React from \"react\";\nimport { ProjectsView } from \"../ProjectsView/ProjectsView\";\n\nexport interface ProjectsPageProps {\n\t/**\n\t * Optional CSS class name\n\t */\n\tclassName?: string;\n\n\t/**\n\t * Optional inline styles\n\t */\n\tstyle?: React.CSSProperties;\n}\n\n/**\n * Standalone ProjectsPage component for user-defined routing\n * Shows the projects overview and allows navigation to forms\n */\nexport const ProjectsPage: React.FC<ProjectsPageProps> = ({\n\tclassName,\n\tstyle,\n}) => {\n\treturn <ProjectsView className={className} style={style} />;\n};\n","\"use client\";\n\n// Main FormBuilder component and related exports\n\n// Import fonts CSS to ensure they're available when using the library\nimport \"./styles/fonts.css\";\n\nexport { isFormFieldComponent } from \"./component-registry/components\";\n// ComponentValue and renderComponent now live in @formbuilder/ui; re-exported here for backward compat\nexport type { ComponentValue } from \"@formbuilder/ui\";\nexport { renderComponent } from \"@formbuilder/ui\";\n\n// Register builder's concrete renderComponent implementation so wizard consumers work at runtime\nimport {\n\trenderComponent as builderRenderComponent,\n} from \"./component-registry/components\";\nimport { registerRenderComponent } from \"@formbuilder/ui\";\nregisterRenderComponent(builderRenderComponent);\n// Configuration system - Unified configuration types\nexport {\n\tDEFAULT_FORM_CONFIG,\n\ttype FormConfig,\n\ttype FormStorageConfig,\n\tuseFormConfiguration,\n} from \"./config\";\nexport { FlowBuilderErrorBoundary } from \"./error-boundaries\";\nexport * from \"./features/condition-editor\";\nexport * from \"./features/dialog-system\";\nexport * from \"./features/form-builder\";\nexport * from \"./features/form-management\";\n/** @deprecated Use ProjectsView, FormsView, FormBuilderView with NavigationProvider instead */\nexport type { FormExplorerProps } from \"./features/form-management/components/FormExplorer/FormExplorer\";\n/** @deprecated Use ProjectsView, FormsView, FormBuilderView with NavigationProvider instead */\nexport { FormExplorer } from \"./features/form-management/components/FormExplorer/FormExplorer\";\nexport type {\n\t/** @deprecated Use FormBuilderView directly - FormBuilderPage requires react-router-dom */\n\tFormBuilderPageProps,\n\t/** @deprecated Use FormsView directly - FormsPage requires react-router-dom */\n\tFormsPageProps,\n\tProjectsPageProps,\n} from \"./features/form-management/components/pages\";\n// Export page components for user-defined routing\nexport {\n\t/** @deprecated Use FormBuilderView directly - FormBuilderPage requires react-router-dom */\n\tFormBuilderPage,\n\t/** @deprecated Use FormsView directly - FormsPage requires react-router-dom */\n\tFormsPage,\n\tProjectsPage,\n} from \"./features/form-management/components/pages\";\nexport * from \"./features/property-editors\";\nexport * from \"./features/template-system\";\n// Shared utilities and services\nexport { TemplateStorageService } from \"./features/template-system/services/TemplateStorageService\";\nexport * from \"./features/trigger-action-system\";\nexport * from \"./features/visual-mapping\";\nexport * from \"./providers\";\n// Note: FilesystemStorageProvider removed from exports - it uses node:fs/node:path\n// Import directly from './storage/FilesystemStorageProvider' in server-side code only\n// Export storage types\nexport type {\n\tCreateFormRequest,\n\tCreateProjectRequest,\n\tFileStorageError,\n\tFormBuilderSettings,\n\tFormFile,\n\tFormMetadata,\n\tFormStorageProvider,\n\tGenericTemplate,\n\tPersonalTemplate,\n\tSharedTemplate,\n\tStorageResult,\n\tTeamTemplate,\n\tTemplateCategory,\n\tTemplateCategoryInfo,\n\tTemplateDirectory,\n\tTemplateFile,\n\tTemplateStorageConfig,\n} from \"./storage/types\";\n// export * from \"./integrations\"; // Commented out to resolve useCurrentStep conflict\n// Selective exports to avoid useCurrentStep conflict\nexport type {\n\tComponentConfig,\n\tFormSectionConfig,\n\tFormStepConfig,\n\tFormWizardConfig,\n\tStepNavigation,\n\tStepNavigationItem,\n\tStepTemplate,\n\tTemplateHistoryEntry,\n} from \"./store\";\nexport {\n\tuseCanUndo,\n\tuseCurrentSection,\n\tuseFormBuilderActions,\n\tuseFormBuilderStore,\n\tuseFormConfig,\n\tuseFormSteps,\n\tuseHasUnsavedChanges,\n\tuseIsSaving,\n\tuseLastSavedAt,\n\tuseSaveError,\n\tuseSelectedSectionId,\n\tuseSelectedStepId,\n\t// useCurrentStep excluded to avoid conflict with features/form-builder\n} from \"./store\";\nexport * from \"./utils\";\nexport {\n\tgetDatabaseConfig,\n\tresolveConfigVariables,\n} from \"./utils/configReader\";\n// Utilities\nexport {\n\ttype FormOperationsConfig,\n\tformatProjectName,\n\tgetStorageProvider,\n\tloadFormConfigFromExplorer,\n\tregisterStorageStrategy,\n\ttype StorageStrategy,\n} from \"./utils/formsExplorer\";\n"],"names":["registeredRenderer","registerRenderComponent","fn","renderComponent","props","NavigationContext","createContext","useFormNavigation","context","useContext","useFormData","projectId","formId","config","useQuery","formConfig","getFormConfig","provider","StorageProviderFactory","result","FormBuilderView","showPreview","className","style","onSave","isLoading","error","navigateToForms","handleSave","updatedConfig","formConfigData","jsx","styles","jsxs","FormBuilder","formsQueryKeys","useFormsQuery","scanFormsDirectory","useCreateFormMutation","queryClient","useQueryClient","useMutation","request","createForm","newForm","previousProjects","old","project","_err","_newForm","useDeleteFormMutation","deleteForm","form","_variables","APP_NAME","BaseHeader","Heading","BaseLayout","title","subtitle","showBackButton","onBack","backButtonText","searchSlot","primaryAction","secondaryActions","children","Button","ChevronLeft","Paragraph","action","Plus","NewFormDialog","open","onOpenChange","selectedProjectId","onFormCreated","onFormAdded","onCreateForm","createFormMutation","useForm","value","toast","resultFormId","useEffect","handleCancel","useCallback","Dialog","DialogContent","DialogHeader","DialogTitle","DialogDescription","e","field","Label","Input","Textarea","DialogFooter","SearchInput","placeholder","onSearchChange","searchValue","setSearchValue","useState","handleSearchChange","Search","ViewCard","icon","description","metadata","dropdownActions","onClick","Card","CardHeader","DropdownMenu","DropdownMenuTrigger","MoreVertical","DropdownMenuContent","DropdownMenuItem","meta","CardDescription","CardContent","RhcButton","formatDate","timestamp","FormsView","formsProp","projectNameProp","isLoadingProp","onNavigateToProjects","onRefresh","onFormDeleted","searchQuery","setSearchQuery","showNewFormDialog","setShowNewFormDialog","navigateToProjects","navigateToBuilder","internalQuery","deleteFormMutation","internalProject","p","resolvedForms","resolvedProjectName","projectFound","filteredForms","handleCreateForm","handleFormCreated","createdProjectId","f","handleDeleteForm","handleEditForm","handleFormClick","handleBackToProjects","Fragment","FileText","Settings","Trash2","ChevronRight","useProjectActions","handleCreateProject","createProject","handleDeleteProject","storageProvider","deleteResult","formsResult","projectForms","deletedCount","success","handleNavigateToProject","projectsQueryKeys","useProjectsData","NewProjectDialog","onProjectCreated","onCreateProject","dialogReducer","state","initialDialogState","ProjectsView","projectsProp","onProjectDeleted","dialogState","dispatchDialog","useReducer","deleteProject","navigateToProject","projects","handleRefresh","filteredProjects","handleProjectCreated","confirmDeleteProject","projectName","errorMessage","userMessage","handleProjectClick","GridLayout","index","GridLayoutColumn","Folder","ConfirmDialog","ProjectCard","onEditForm","onDeleteForm","isExpanded","setIsExpanded","FolderOpen","CardTitle","MoreHorizontal","Separator","useFormExplorerState","autoLoad","setState","loadProjects","prev","operationsConfig","isCancelled","initializeFormConfiguration","timeoutPromise","_","reject","connectionError","query","setSelectedProject","addProjectOptimistic","removeProjectOptimistic","addFormOptimistic","removeFormOptimistic","refreshProjectsList","clearScanCache","invalidateCache","useFormOperations","onFormLoad","onFormCreate","onFormDelete","onFormSave","onFormEdit","onProjectsRefresh","useFormConfiguration","useMemo","formTitle","finalFormId","wizardId","loadFormConfigFromExplorer","handleSaveForm","saveFormConfig","useProjectOperations","DatabaseStatusIndicator","getSyncStatus","onForceSync","onReconnect","onValidateConsistency","onResetLocalData","onReconcileConflicts","capabilities","setCapabilities","syncStatus","setSyncStatus","showDetails","setShowDetails","updateCapabilities","providerCapabilities","handleProviderReady","event","handleOnline","handleOffline","interval","currentStatus","handleForceSync","handleReconnect","handleValidateConsistency","isConsistent","handleResetLocalData","handleReconcileConflicts","getStatusConfig","formatLastSync","date","diff","getDatabaseValueClass","getPersistenceValueClass","getIntegrityValueClass","ConnectionErrorScreen","onRetry","isRetrying","setIsRetrying","handleRetry","errorInfo","WifiOff","Wifi","RefreshCw","getStatusValueClass","AlertTriangle","createProjectsView","createBuilderView","FormExplorerCore","initialView","onNavigateToForms","currentView","setCurrentView","navigationInProgress","useRef","setProviderCapabilities","showNewProjectDialog","setShowNewProjectDialog","setStorageProvider","selectedProject","navigateToView","factory","view","navigateBack","navigationContext","projectData","handleFormSave","renderView","isDatabaseSetupError","FormExplorer","themeConfig","useThemeConfig","resolvedConfig","setResolvedConfig","setIsLoading","setError","processedConfig","resolveConfigVariables","configPath","response","rawConfig","loadError","ThemeProvider","DataRouterContext","React","DataRouterStateContext","AwaitContext","LocationContext","RouteContext","RouteErrorContext","useParams","matches","routeMatch","FormBuilderPage","params","FormsPage","ProjectsPage","builderRenderComponent"],"mappings":"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","x_google_ignoreList":[25]}
1
+ {"version":3,"file":"index.js","sources":["../../../packages/ui/src/component-registry/renderComponent.tsx","../../../packages/forms/src/navigation/context.tsx","../../../packages/forms/src/navigation/hooks.ts","../../../packages/builder/src/features/form-management/hooks/useFormData.ts","../../../packages/builder/src/features/form-management/components/FormBuilderView/FormBuilderView.tsx","../../../packages/builder/src/features/form-management/hooks/useFormsQuery.ts","../../../packages/builder/src/features/form-management/layout/BaseHeader/BaseHeader.tsx","../../../packages/builder/src/features/form-management/layout/BaseLayout/BaseLayout.tsx","../../../packages/builder/src/features/form-management/components/NewFormDialog/NewFormDialog.tsx","../../../packages/builder/src/features/form-management/components/SearchInput/SearchInput.tsx","../../../packages/builder/src/features/form-management/components/ViewCard/ViewCard.tsx","../../../packages/builder/src/features/form-management/components/FormsView/FormsView.tsx","../../../packages/builder/src/features/form-management/hooks/useProjectActions.ts","../../../packages/builder/src/features/form-management/hooks/useProjectsData.ts","../../../packages/builder/src/features/form-management/components/NewProjectDialog/NewProjectDialog.tsx","../../../packages/builder/src/features/form-management/components/ProjectsView/ProjectsView.tsx","../../../packages/builder/src/features/form-management/components/ProjectCard/ProjectCard.tsx","../../../packages/builder/src/features/form-management/hooks/useFormExplorerState.ts","../../../packages/builder/src/features/form-management/hooks/useFormOperations.ts","../../../packages/builder/src/features/form-management/hooks/useProjectOperations.ts","../../../packages/builder/src/components/DatabaseStatusIndicator/DatabaseStatusIndicator.tsx","../../../packages/builder/src/components/ConnectionErrorScreen/ConnectionErrorScreen.tsx","../../../packages/builder/src/features/form-management/types/viewTypes.ts","../../../packages/builder/src/features/form-management/components/FormExplorerCore/FormExplorerCore.tsx","../../../packages/builder/src/features/form-management/components/FormExplorer/FormExplorer.tsx","../../../node_modules/react-router/dist/index.js","../../../packages/builder/src/integrations/react-router/FormBuilderPage/FormBuilderPage.tsx","../../../packages/builder/src/integrations/react-router/FormsPage.tsx","../../../packages/builder/src/features/form-management/components/pages/ProjectsPage.tsx","../../../packages/builder/src/index.ts"],"sourcesContent":["import type { ComponentConfig } from \"@formbuilder/core\";\nimport type { ComponentValue } from \"./types\";\nimport type { ReactNode } from \"react\";\n\n/**\n * Props passed to renderComponent.\n * Matches the signature used in @formbuilder/builder's component-registry.\n */\nexport interface RenderComponentProps {\n component: ComponentConfig;\n value: ComponentValue;\n onChange: (value: ComponentValue) => void;\n isFormView: boolean;\n}\n\n/**\n * Type of the render function that must be registered by the consuming package\n * (i.e. @formbuilder/builder) before renderComponent is called.\n */\nexport type RenderComponentFn = (props: RenderComponentProps) => ReactNode;\n\n// Module-level registry slot — populated at runtime by @formbuilder/builder\nlet registeredRenderer: RenderComponentFn | null = null;\n\n/**\n * Register the concrete renderComponent implementation.\n * Must be called once by @formbuilder/builder (or any package that owns the\n * component registry) before renderComponent is used at runtime.\n */\nexport const registerRenderComponent = (fn: RenderComponentFn): void => {\n registeredRenderer = fn;\n};\n\n/**\n * Render a form component using the registered component registry.\n *\n * This function lives in @formbuilder/ui so that @formbuilder/wizard can\n * import it without depending on @formbuilder/builder, breaking the\n * wizard → builder circular dependency.\n *\n * The actual rendering is delegated to the implementation registered via\n * registerRenderComponent(), which is called by @formbuilder/builder on\n * initialisation.\n */\nexport const renderComponent = (props: RenderComponentProps): ReactNode => {\n if (!registeredRenderer) {\n console.error(\n \"[renderComponent] No renderer registered. \" +\n \"Ensure @formbuilder/builder has been initialised before rendering form components.\"\n );\n return null;\n }\n return registeredRenderer(props);\n};\n","import { createContext, useMemo } from \"react\";\nimport type { NavigationContextValue, NavigationProviderProps } from \"./types\";\nimport { routeConfigSchema } from \"./schema\";\nimport { buildPath } from \"./builders\";\n\n/**\n * React context for navigation callbacks.\n * Use useFormNavigation() hook to access this context.\n */\nexport const NavigationContext = createContext<NavigationContextValue | null>(\n\tnull,\n);\n\n/**\n * Provider component that makes navigation callbacks available to child components.\n *\n * Accepts a generic navigate function (router.push, router.navigate, etc.) and\n * optional route configuration overrides. Creates type-safe navigation callbacks\n * that build paths using the route templates and call the provided navigate function.\n *\n * @example\n * // Next.js App Router\n * import { useRouter } from 'next/navigation';\n *\n * function App() {\n * const router = useRouter();\n * return (\n * <NavigationProvider navigate={router.push}>\n * <YourComponents />\n * </NavigationProvider>\n * );\n * }\n *\n * @example\n * // With custom routes\n * <NavigationProvider\n * navigate={router.push}\n * routes={{ builder: '/custom/:projectId/:formId' }}\n * >\n * <YourComponents />\n * </NavigationProvider>\n */\nexport function NavigationProvider({\n\tnavigate,\n\troutes,\n\tchildren,\n}: NavigationProviderProps) {\n\t// Merge provided routes with defaults using Zod schema\n\tconst resolvedRoutes = useMemo(\n\t\t() => routeConfigSchema.parse(routes ?? {}),\n\t\t[routes],\n\t);\n\n\t// Create memoized navigation callbacks\n\tconst value = useMemo<NavigationContextValue>(\n\t\t() => ({\n\t\t\tnavigateToProjects: () => {\n\t\t\t\tnavigate(buildPath(resolvedRoutes.projects));\n\t\t\t},\n\t\t\tnavigateToForms: (projectId: string) => {\n\t\t\t\tnavigate(buildPath(resolvedRoutes.forms, { projectId }));\n\t\t\t},\n\t\t\tnavigateToBuilder: (projectId: string, formId: string) => {\n\t\t\t\tnavigate(buildPath(resolvedRoutes.builder, { projectId, formId }));\n\t\t\t},\n\t\t\tnavigateToPreview: (projectId: string, formId: string) => {\n\t\t\t\tnavigate(buildPath(resolvedRoutes.preview, { projectId, formId }));\n\t\t\t},\n\t\t}),\n\t\t[navigate, resolvedRoutes],\n\t);\n\n\treturn (\n\t\t<NavigationContext.Provider value={value}>\n\t\t\t{children}\n\t\t</NavigationContext.Provider>\n\t);\n}\n","import { useContext } from \"react\";\nimport { NavigationContext } from \"./context\";\nimport type { NavigationContextValue } from \"./types\";\n\n/**\n * Hook to access navigation callbacks within a NavigationProvider.\n *\n * Returns an object with four type-safe navigation methods:\n * - navigateToProjects(): Navigate to projects list\n * - navigateToForms(projectId): Navigate to forms list for a project\n * - navigateToBuilder(projectId, formId): Navigate to form builder\n * - navigateToPreview(projectId, formId): Navigate to form preview\n *\n * @throws Error if used outside of NavigationProvider\n *\n * @example\n * function MyComponent() {\n * const { navigateToBuilder } = useFormNavigation();\n *\n * return (\n * <button onClick={() => navigateToBuilder('proj-1', 'form-1')}>\n * Edit Form\n * </button>\n * );\n * }\n */\nexport function useFormNavigation(): NavigationContextValue {\n\tconst context = useContext(NavigationContext);\n\n\tif (context === null) {\n\t\tthrow new Error(\n\t\t\t`useFormNavigation must be used within a NavigationProvider.\n\nWrap your app with NavigationProvider:\n<NavigationProvider navigate={router.push} routes={config.navigation?.routes}>\n {children}\n</NavigationProvider>`,\n\t\t);\n\t}\n\n\treturn context;\n}\n","/**\n * TanStack Query hook for loading a single form config\n * Used by FormBuilderView for data fetching\n */\n\nimport type { FormWizardConfig } from \"@formbuilder/core\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { FormConfig } from \"../../../config/types\";\nimport { StorageProviderFactory } from \"../../../storage/StorageProviderFactory\";\nimport { getFormConfig } from \"../../../utils/formsExplorer\";\n\ninterface UseFormDataOptions {\n\tprojectId: string;\n\tformId: string;\n\tconfig?: FormConfig;\n}\n\n/**\n * Query hook for loading a single form configuration\n * Returns form config with loading and error states\n */\nexport function useFormData({ projectId, formId, config }: UseFormDataOptions) {\n\treturn useQuery({\n\t\tqueryKey: [\"form\", projectId, formId],\n\t\tqueryFn: async () => {\n\t\t\t// Get form configuration\n\t\t\tconst formConfig = config || (await getFormConfig());\n\n\t\t\t// Get storage provider\n\t\t\tconst factory = StorageProviderFactory.getInstance();\n\t\t\tconst provider = await factory.createProvider(formConfig.storage);\n\n\t\t\tif (!provider) {\n\t\t\t\tthrow new Error(\"Storage provider not available\");\n\t\t\t}\n\n\t\t\t// Load form data\n\t\t\tconst result = await provider.loadForm(projectId, formId);\n\n\t\t\tif (result.success && result.data) {\n\t\t\t\treturn result.data as FormWizardConfig;\n\t\t\t} else {\n\t\t\t\tthrow new Error(`Form \"${formId}\" not found in project \"${projectId}\"`);\n\t\t\t}\n\t\t},\n\t\tenabled: Boolean(projectId && formId),\n\t\tstaleTime: 30000, // Consider data fresh for 30 seconds\n\t\trefetchOnWindowFocus: true,\n\t\trefetchOnMount: true,\n\t});\n}\n","/**\n * FormBuilderView - Standalone component wrapping FormBuilder with data loading and navigation\n * Framework-agnostic: Uses useFormNavigation instead of react-router-dom\n */\n\nimport { useFormNavigation } from \"@formbuilder/forms/navigation\";\nimport type { FormWizardConfig } from \"@formbuilder/core\";\nimport type React from \"react\";\nimport type { FormConfig } from \"../../../../config/types\";\nimport styles from \"./FormBuilderView.module.css\";\nimport { StorageProviderFactory } from \"../../../../storage/StorageProviderFactory\";\nimport { getFormConfig } from \"../../../../utils/formsExplorer\";\nimport { FormBuilder } from \"../../../form-builder\";\nimport { useFormData } from \"../../hooks/useFormData\";\n\nexport interface FormBuilderViewProps {\n\tprojectId: string;\n\tformId: string;\n\tconfig?: FormConfig;\n\tshowPreview?: boolean;\n\tclassName?: string;\n\tstyle?: React.CSSProperties;\n\tonSave?: (config: FormWizardConfig) => Promise<void>;\n}\n\n/**\n * Standalone FormBuilderView component\n * Wraps FormBuilder with loading, error handling, and navigation\n */\nexport const FormBuilderView: React.FC<FormBuilderViewProps> = ({\n\tprojectId,\n\tformId,\n\tconfig,\n\tshowPreview = true,\n\tclassName,\n\tstyle,\n\tonSave,\n}) => {\n\tconst {\n\t\tdata: formConfig,\n\t\tisLoading,\n\t\terror,\n\t} = useFormData({ projectId, formId, config });\n\tconst { navigateToForms } = useFormNavigation();\n\n\t// Create save handler\n\tconst handleSave = async (updatedConfig: FormWizardConfig) => {\n\t\tif (onSave) {\n\t\t\t// Use custom save handler if provided\n\t\t\tawait onSave(updatedConfig);\n\t\t} else {\n\t\t\t// Default save logic via storage provider\n\t\t\tconst formConfigData = config || (await getFormConfig());\n\t\t\tconst factory = StorageProviderFactory.getInstance();\n\t\t\tconst provider = await factory.createProvider(formConfigData.storage);\n\n\t\t\tif (!provider) {\n\t\t\t\tthrow new Error(\"Storage provider not available\");\n\t\t\t}\n\n\t\t\tconst result = await provider.saveForm(projectId, formId, updatedConfig);\n\n\t\t\tif (!result.success) {\n\t\t\t\tthrow new Error(result.error || `Failed to save form \"${formId}\"`);\n\t\t\t}\n\t\t}\n\t};\n\n\t// Loading state\n\tif (isLoading) {\n\t\treturn (\n\t\t\t<div className={styles.loadingContainer}>\n\t\t\t\t<div className={styles.loadingInner}>\n\t\t\t\t\t<div className={styles.loadingSpinner}></div>\n\t\t\t\t\t<p className={styles.loadingText}>Loading form...</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\t// Error state\n\tif (error || !formConfig) {\n\t\treturn (\n\t\t\t<div className={styles.errorContainer}>\n\t\t\t\t<div className={styles.errorInner}>\n\t\t\t\t\t<h2 className={styles.errorTitle}>\n\t\t\t\t\t\tForm Not Found\n\t\t\t\t\t</h2>\n\t\t\t\t\t<p className={styles.errorMessage}>\n\t\t\t\t\t\t{error instanceof Error\n\t\t\t\t\t\t\t? error.message\n\t\t\t\t\t\t\t: \"Form could not be loaded\"}\n\t\t\t\t\t</p>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={() => navigateToForms(projectId)}\n\t\t\t\t\t\tclassName={styles.backButton}\n\t\t\t\t\t>\n\t\t\t\t\t\tBack to Forms\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\t// Render FormBuilder\n\treturn (\n\t\t<div className={className} style={style}>\n\t\t\t<FormBuilder\n\t\t\t\tinitialConfig={formConfig}\n\t\t\t\tonSave={handleSave}\n\t\t\t\tproject={projectId}\n\t\t\t\twizardId={formId}\n\t\t\t\tshowPreviewButton={showPreview}\n\t\t\t\tonNavigateToForms={() => navigateToForms(projectId)}\n\t\t\t/>\n\t\t</div>\n\t);\n};\n","/**\n * TanStack Query hooks for form management\n * Replaces manual caching with robust query management\n */\n\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport type { FormConfig } from \"../../../config/types\";\nimport {\n\tcreateForm,\n\tdeleteForm,\n\tscanFormsDirectory,\n} from \"../../../utils/formsExplorer\";\n\n// Query keys for cache management\nexport const formsQueryKeys = {\n\tall: [\"forms\"] as const,\n\tprojects: () => [...formsQueryKeys.all, \"projects\"] as const,\n\tproject: (projectId: string) =>\n\t\t[...formsQueryKeys.projects(), projectId] as const,\n\tform: (projectId: string, formId: string) =>\n\t\t[...formsQueryKeys.project(projectId), formId] as const,\n};\n\ninterface UseFormsQueryOptions {\n\tconfig?: FormConfig;\n}\n\n/**\n * Query hook for fetching all projects and forms\n * Replaces useFormExplorerState with automatic caching and background updates\n */\nexport function useFormsQuery({ config }: UseFormsQueryOptions = {}) {\n\treturn useQuery({\n\t\tqueryKey: formsQueryKeys.projects(),\n\t\tqueryFn: async () => {\n\t\t\tconst operationsConfig = config ? { formConfig: config } : {};\n\t\t\tconst result = await scanFormsDirectory(operationsConfig);\n\t\t\treturn result.projects;\n\t\t},\n\t\tstaleTime: 30000, // Consider data fresh for 30 seconds\n\t\trefetchOnWindowFocus: true, // Refetch when user returns to tab\n\t\trefetchOnMount: true, // Always refetch on component mount\n\t});\n}\n\n/**\n * Mutation hook for creating forms with optimistic updates\n */\nexport function useCreateFormMutation() {\n\tconst queryClient = useQueryClient();\n\n\treturn useMutation({\n\t\tmutationFn: async (request: {\n\t\t\tprojectId: string;\n\t\t\tformId: string;\n\t\t\ttitle: string;\n\t\t\tdescription?: string;\n\t\t}) => {\n\t\t\tconst result = await createForm(request);\n\t\t\tif (!result) {\n\t\t\t\tthrow new Error(\"Failed to create form\");\n\t\t\t}\n\t\t\treturn { ...request, config: result };\n\t\t},\n\n\t\t// Optimistic update: immediately add form to cache\n\t\tonMutate: async (newForm) => {\n\t\t\t// Cancel outgoing refetches so they don't overwrite optimistic update\n\t\t\tawait queryClient.cancelQueries({ queryKey: formsQueryKeys.projects() });\n\n\t\t\t// Snapshot previous value for rollback\n\t\t\tconst previousProjects = queryClient.getQueryData(\n\t\t\t\tformsQueryKeys.projects()\n\t\t\t);\n\n\t\t\t// Optimistically update cache\n\t\t\tqueryClient.setQueryData(formsQueryKeys.projects(), (old: any) => {\n\t\t\t\tif (!old) return old;\n\n\t\t\t\treturn old.map((project: any) =>\n\t\t\t\t\tproject.id === newForm.projectId\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t...project,\n\t\t\t\t\t\t\t\tforms: [\n\t\t\t\t\t\t\t\t\t...project.forms,\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tid: newForm.formId,\n\t\t\t\t\t\t\t\t\t\ttitle: newForm.title,\n\t\t\t\t\t\t\t\t\t\tfileName: `${newForm.formId}.json`,\n\t\t\t\t\t\t\t\t\t\tdescription: newForm.description || \"\",\n\t\t\t\t\t\t\t\t\t\tlastModified: Date.now(),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: project\n\t\t\t\t);\n\t\t\t});\n\n\t\t\treturn { previousProjects };\n\t\t},\n\n\t\t// On error, rollback optimistic update\n\t\tonError: (_err, _newForm, context) => {\n\t\t\tif (context?.previousProjects) {\n\t\t\t\tqueryClient.setQueryData(\n\t\t\t\t\tformsQueryKeys.projects(),\n\t\t\t\t\tcontext.previousProjects\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\n\t\t// Always refetch after mutation to ensure data consistency\n\t\tonSettled: () => {\n\t\t\tqueryClient.invalidateQueries({ queryKey: formsQueryKeys.projects() });\n\t\t},\n\t});\n}\n\n/**\n * Mutation hook for deleting forms with optimistic updates\n */\nexport function useDeleteFormMutation() {\n\tconst queryClient = useQueryClient();\n\n\treturn useMutation({\n\t\tmutationFn: async ({\n\t\t\tprojectId,\n\t\t\tformId,\n\t\t}: {\n\t\t\tprojectId: string;\n\t\t\tformId: string;\n\t\t}) => {\n\t\t\tconst success = await deleteForm(projectId, formId);\n\t\t\tif (!success) {\n\t\t\t\tthrow new Error(\"Failed to delete form\");\n\t\t\t}\n\t\t\treturn { projectId, formId };\n\t\t},\n\n\t\t// Optimistic update: immediately remove form from cache\n\t\tonMutate: async ({ projectId, formId }) => {\n\t\t\tawait queryClient.cancelQueries({ queryKey: formsQueryKeys.projects() });\n\n\t\t\tconst previousProjects = queryClient.getQueryData(\n\t\t\t\tformsQueryKeys.projects()\n\t\t\t);\n\n\t\t\t// Optimistically update cache\n\t\t\tqueryClient.setQueryData(formsQueryKeys.projects(), (old: any) => {\n\t\t\t\tif (!old) return old;\n\n\t\t\t\treturn old.map((project: any) =>\n\t\t\t\t\tproject.id === projectId\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t...project,\n\t\t\t\t\t\t\t\tforms: project.forms.filter((form: any) => form.id !== formId),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: project\n\t\t\t\t);\n\t\t\t});\n\n\t\t\treturn { previousProjects };\n\t\t},\n\n\t\t// On error, rollback optimistic update\n\t\tonError: (_err, _variables, context) => {\n\t\t\tif (context?.previousProjects) {\n\t\t\t\tqueryClient.setQueryData(\n\t\t\t\t\tformsQueryKeys.projects(),\n\t\t\t\t\tcontext.previousProjects\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\n\t\t// Always refetch to ensure data consistency with database\n\t\tonSettled: () => {\n\t\t\tqueryClient.invalidateQueries({ queryKey: formsQueryKeys.projects() });\n\t\t},\n\t});\n}\n\n/**\n * Hook to force refresh all form data\n * Useful for manual sync when needed\n */\nexport function useRefreshForms() {\n\tconst queryClient = useQueryClient();\n\n\treturn () => {\n\t\tqueryClient.invalidateQueries({ queryKey: formsQueryKeys.projects() });\n\t};\n}\n","import { Heading } from \"@formbuilder/design-system\";\nimport styles from \"./BaseHeader.module.css\";\n\nconst APP_NAME = \"Formeel\";\n\nexport const BaseHeader = () => {\n\treturn (\n\t\t<div className={styles.headerContainer}>\n\t\t\t<div className={styles.headerContent}>\n\t\t\t\t<Heading level={4}>{APP_NAME}</Heading>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n","/**\n * BaseLayout - Generic layout component for consistent navigation structure\n * Provides header, breadcrumb navigation, and content area\n */\n\nimport {\n\tButton,\n\ttype ButtonProps,\n\tHeading,\n\tParagraph,\n} from \"@formbuilder/design-system\";\nimport { ChevronLeft, Plus } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\nimport { BaseHeader } from \"../BaseHeader/BaseHeader\";\nimport styles from \"./BaseLayout.module.css\";\n\nexport interface BaseLayoutProps {\n\t// Header props\n\ttitle: string;\n\tsubtitle?: string;\n\n\t// Navigation props\n\tshowBackButton?: boolean;\n\tonBack?: () => void;\n\tbackButtonText?: string;\n\n\t// Search slot for inline positioning with actions\n\tsearchSlot?: ReactNode;\n\n\t// Action buttons\n\tprimaryAction?: {\n\t\tlabel: string;\n\t\tonClick: () => void;\n\t\ticon?: ReactNode;\n\t};\n\tsecondaryActions?: Array<{\n\t\tlabel: string;\n\t\tonClick: () => void;\n\t\ticon?: ReactNode;\n\t\tvariant?: ButtonProps[\"appearance\"];\n\t}>;\n\n\t// Loading state\n\tisLoading?: boolean;\n\n\t// Content\n\tchildren: ReactNode;\n\n\t// Styling\n\tclassName?: string;\n}\n\nexport const BaseLayout: React.FC<BaseLayoutProps> = ({\n\ttitle,\n\tsubtitle,\n\tshowBackButton = false,\n\tonBack,\n\tbackButtonText = \"Back\",\n\tsearchSlot,\n\tprimaryAction,\n\tsecondaryActions = [],\n\tisLoading = false,\n\tchildren,\n\tclassName = \"\",\n}) => {\n\treturn (\n\t\t<div className={`form-explorer-layout ${styles.layout} ${className}`}>\n\t\t\t<BaseHeader />\n\t\t\t<div className={styles.canvas}>\n\t\t\t\t{/* Header */}\n\t\t\t\t<div>\n\t\t\t\t\t{showBackButton && onBack && (\n\t\t\t\t\t\t<Button appearance=\"subtle-button\" onClick={onBack}>\n\t\t\t\t\t\t\t<ChevronLeft />\n\t\t\t\t\t\t\t{backButtonText}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t)}\n\t\t\t\t\t<div className={styles.headerSection}>\n\t\t\t\t\t\t<Heading level={1}>{title}</Heading>\n\t\t\t\t\t\t{subtitle && <Paragraph>{subtitle}</Paragraph>}\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div className={styles.actionsRow}>\n\t\t\t\t\t\t{/* Search Slot - positioned inline with actions */}\n\t\t\t\t\t\t{searchSlot && <div className={styles.searchSlot}>{searchSlot}</div>}\n\n\t\t\t\t\t\t<div className={styles.actionsGroup}>\n\t\t\t\t\t\t\t{/* Secondary Actions */}\n\t\t\t\t\t\t\t{secondaryActions.map((action) => (\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tkey={`secondary-action-${action.label}`}\n\t\t\t\t\t\t\t\t\tappearance={action.variant || \"secondary-action-button\"}\n\t\t\t\t\t\t\t\t\tonClick={action.onClick}\n\t\t\t\t\t\t\t\t\tdisabled={isLoading}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{action.icon}\n\t\t\t\t\t\t\t\t\t{action.label}\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t))}\n\n\t\t\t\t\t\t\t{/* Primary Action */}\n\t\t\t\t\t\t\t{primaryAction && (\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tonClick={primaryAction.onClick}\n\t\t\t\t\t\t\t\t\tappearance=\"primary-action-button\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{primaryAction.icon || <Plus className={`${styles.iconSm} ${styles.mr2}`} />}\n\t\t\t\t\t\t\t\t\t{primaryAction.label}\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t{/* Content */}\n\t\t\t\t<div className={styles.content}>{children}</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n","/**\n * NewFormDialog component - dialog for creating new forms\n */\n\nimport {\n\tButton,\n\tDialog,\n\tDialogContent,\n\tDialogDescription,\n\tDialogFooter,\n\tDialogHeader,\n\tDialogTitle,\n\tInput,\n\tLabel,\n\tTextarea,\n} from \"@formbuilder/ui\";\nimport { toast } from \"sonner\";\nimport { useForm } from \"@tanstack/react-form\";\nimport { useCallback, useEffect } from \"react\";\nimport { useCreateFormMutation } from \"../../hooks/useFormsQuery\";\nimport styles from \"./NewFormDialog.module.css\";\n\nexport interface NewFormDialogProps {\n\topen: boolean;\n\tonOpenChange: (open: boolean) => void;\n\tselectedProjectId?: string;\n\tonFormCreated?: (projectId: string, formId: string) => void;\n\tonFormAdded?: (\n\t\tprojectId: string,\n\t\tform: { id: string; title: string; description?: string }\n\t) => void;\n\t/** Custom form creation handler — bypasses the default formsExplorer storage path */\n\tonCreateForm?: (request: {\n\t\tprojectId: string;\n\t\tformId: string;\n\t\ttitle: string;\n\t\tdescription?: string;\n\t}) => Promise<{ success: boolean; formId?: string }>;\n}\n\nexport const NewFormDialog: React.FC<NewFormDialogProps> = ({\n\topen,\n\tonOpenChange,\n\tselectedProjectId,\n\tonFormCreated,\n\tonFormAdded,\n\tonCreateForm,\n}) => {\n\t// Use TanStack Query mutation for optimistic updates (fallback path)\n\tconst createFormMutation = useCreateFormMutation();\n\tconst form = useForm({\n\t\tdefaultValues: {\n\t\t\ttitle: \"\",\n\t\t\tdescription: \"\",\n\t\t},\n\t\tonSubmit: async ({ value }) => {\n\t\t\tif (!selectedProjectId) {\n\t\t\t\ttoast.error(\"No project selected\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Generate form ID from title\n\t\t\tconst formId = value.title\n\t\t\t\t.toLowerCase()\n\t\t\t\t.replace(/[^a-z0-9]/g, \"-\")\n\t\t\t\t.replace(/-+/g, \"-\")\n\t\t\t\t.replace(/^-|-$/g, \"\");\n\n\t\t\tconst request = {\n\t\t\t\tprojectId: selectedProjectId,\n\t\t\t\tformId,\n\t\t\t\ttitle: value.title.trim(),\n\t\t\t\tdescription: value.description.trim() || undefined,\n\t\t\t};\n\n\t\t\ttry {\n\t\t\t\tlet resultFormId = formId;\n\n\t\t\t\tif (onCreateForm) {\n\t\t\t\t\tconst result = await onCreateForm(request);\n\t\t\t\t\tif (!result.success) {\n\t\t\t\t\t\ttoast.error(\"Failed to create form\");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tresultFormId = result.formId ?? formId;\n\t\t\t\t} else {\n\t\t\t\t\tawait createFormMutation.mutateAsync(request);\n\t\t\t\t}\n\n\t\t\t\ttoast.success(`Form \"${value.title}\" created successfully`);\n\t\t\t\tonOpenChange(false);\n\n\t\t\t\tonFormCreated?.(selectedProjectId, resultFormId);\n\t\t\t\tonFormAdded?.(selectedProjectId, {\n\t\t\t\t\tid: resultFormId,\n\t\t\t\t\ttitle: value.title.trim(),\n\t\t\t\t\tdescription: value.description.trim(),\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Failed to create form:\", error);\n\t\t\t\ttoast.error(\n\t\t\t\t\t\terror instanceof Error ? error.message : \"Failed to create form\",\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t});\n\n\t// Reset form when dialog opens\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tform.reset();\n\t\t}\n\t}, [open, form]);\n\n\tconst handleCancel = useCallback(() => {\n\t\tonOpenChange(false);\n\t}, [onOpenChange]);\n\n\treturn (\n\t\t<Dialog open={open} onOpenChange={onOpenChange}>\n\t\t\t<DialogContent>\n\t\t\t\t<DialogHeader>\n\t\t\t\t\t<DialogTitle>Nieuwe formulier aanmaken</DialogTitle>\n\t\t\t\t\t<DialogDescription>\n\t\t\t\t\t\tVoeg een formulier toe aan een project.{\" \"}\n\t\t\t\t\t</DialogDescription>\n\t\t\t\t</DialogHeader>\n\t\t\t\t<form\n\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\tform.handleSubmit();\n\t\t\t\t\t}}\n\t\t\t\t\tclassName={styles.formBody}\n\t\t\t\t>\n\t\t\t\t\t<div className={styles.fieldGroup}>\n\t\t\t\t\t\t<form.Field\n\t\t\t\t\t\t\tname=\"title\"\n\t\t\t\t\t\t\tvalidators={{\n\t\t\t\t\t\t\t\tonChange: ({ value }) =>\n\t\t\t\t\t\t\t\t\t!value.trim() ? \"Form title is required\" : undefined,\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{(field) => (\n\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t<Label htmlFor=\"form-title\">Formulier titel</Label>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\tid=\"form-title\"\n\t\t\t\t\t\t\t\t\t\tvalue={field.state.value}\n\t\t\t\t\t\t\t\t\t\tonChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n\t\t\t\t\t\t\t\t\t\t\tfield.handleChange(e.target.value)\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tplaceholder=\"bijv. 'Nieuwe medewerker aanmaken'\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t{field.state.meta.errors?.length > 0 && (\n\t\t\t\t\t\t\t\t\t\t<p className={styles.fieldError}>\n\t\t\t\t\t\t\t\t\t\t\t{field.state.meta.errors[0]}\n\t\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</form.Field>\n\n\t\t\t\t\t\t<form.Field name=\"description\">\n\t\t\t\t\t\t\t{(field) => (\n\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t<Label htmlFor=\"form-description\">\n\t\t\t\t\t\t\t\t\t\tBeschrijving (Optioneel)\n\t\t\t\t\t\t\t\t\t</Label>\n\t\t\t\t\t\t\t\t\t<Textarea\n\t\t\t\t\t\t\t\t\t\tid=\"form-description\"\n\t\t\t\t\t\t\t\t\t\tvalue={field.state.value}\n\t\t\t\t\t\t\t\t\t\tonChange={(e: React.ChangeEvent<HTMLTextAreaElement>) =>\n\t\t\t\t\t\t\t\t\t\t\tfield.handleChange(e.target.value)\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tplaceholder=\"bijv. 'Proces om een nieuwe medewerker aan te melden in het systeem'\"\n\t\t\t\t\t\t\t\t\t\trows={3}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</form.Field>\n\t\t\t\t\t</div>\n\t\t\t\t\t<DialogFooter>\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={handleCancel}\n\t\t\t\t\t\t\tdisabled={createFormMutation.isPending}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tAnnuleren\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t<Button type=\"submit\" disabled={createFormMutation.isPending}>\n\t\t\t\t\t\t\t{createFormMutation.isPending\n\t\t\t\t\t\t\t\t? \"Aanmaken...\"\n\t\t\t\t\t\t\t\t: \"Formulier aanmaken\"}\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</DialogFooter>\n\t\t\t\t</form>\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n};\n","/**\n * SearchInput - Reusable search input component for views\n */\n\nimport { Input } from \"@formbuilder/ui\";\nimport { Search } from \"lucide-react\";\nimport { useState } from \"react\";\nimport styles from \"./SearchInput.module.css\";\n\nexport interface SearchInputProps {\n\tplaceholder?: string;\n\tonSearchChange: (query: string) => void;\n\tclassName?: string;\n}\n\nexport const SearchInput: React.FC<SearchInputProps> = ({\n\tplaceholder = \"Search...\",\n\tonSearchChange,\n\tclassName = \"\",\n}) => {\n\tconst [searchValue, setSearchValue] = useState(\"\");\n\n\tconst handleSearchChange = (value: string) => {\n\t\tsetSearchValue(value);\n\t\tonSearchChange(value);\n\t};\n\n\treturn (\n\t\t<div className={`${styles.searchWrapper}${className ? ` ${className}` : \"\"}`}>\n\t\t\t<Search className={styles.searchIcon} />\n\t\t\t<Input\n\t\t\t\ttype=\"text\"\n\t\t\t\tplaceholder={placeholder}\n\t\t\t\tvalue={searchValue}\n\t\t\t\tonChange={(e) => handleSearchChange(e.target.value)}\n\t\t\t\tclassName={styles.searchField}\n\t\t\t/>\n\t\t</div>\n\t);\n};\n","/**\n * ViewCard - Generic card component for different view types (projects, forms, etc.)\n *\n * This component provides a consistent card layout across all view types with:\n * - Configurable icon and title\n * - Optional description text\n * - Flexible metadata display (e.g., creation date, item count)\n * - Dropdown menu with customizable actions\n * - Primary action button at the bottom\n *\n * Usage examples:\n * - ProjectsView: Folder icon, project name, creation date + form count, delete action, open button\n * - FormsView: File icon, form title, creation date + form count, edit/delete actions, open button\n * - FlowsView: Can be used instead of table layout for card-based view\n */\n\nimport {\n\ttype ButtonProps,\n\tHeading,\n\tButton as RhcButton,\n} from \"@formbuilder/design-system\";\nimport {\n\tButton,\n\tCard,\n\tCardContent,\n\tCardDescription,\n\tCardHeader,\n\tDropdownMenu,\n\tDropdownMenuContent,\n\tDropdownMenuItem,\n\tDropdownMenuTrigger,\n} from \"@formbuilder/ui\";\nimport { MoreVertical } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\nimport styles from \"./ViewCard.module.css\";\n\nexport interface ViewCardMetaData {\n\tlabel: string;\n\tvalue: string | number;\n}\n\nexport interface ViewCardAction {\n\tlabel?: string;\n\ticon?: ReactNode;\n\tonClick: () => void;\n\tappearance?: ButtonProps[\"appearance\"];\n\tclassName?: string;\n}\n\nexport interface ViewCardDropdownAction {\n\tlabel?: string;\n\ticon?: ReactNode;\n\tonClick: () => void;\n\tvariant?: \"default\" | \"destructive\";\n\tclassName?: string;\n\tdisabled?: boolean;\n}\n\nexport interface ViewCardProps {\n\t/** Icon to display next to the title */\n\ticon: ReactNode;\n\t/** Main title of the card */\n\ttitle: string;\n\t/** Optional description text */\n\tdescription?: string;\n\t/** Array of metadata items to display */\n\tmetadata?: ViewCardMetaData[];\n\t/** Dropdown menu actions (appears in top-right) */\n\tdropdownActions?: ViewCardDropdownAction[];\n\t/** Primary action button (appears at bottom) */\n\tprimaryAction?: ViewCardAction;\n\t/** Additional CSS classes */\n\tclassName?: string;\n\t/** Click handler for the entire card */\n\tonClick?: () => void;\n}\n\nexport const ViewCard: React.FC<ViewCardProps> = ({\n\ticon,\n\ttitle,\n\tdescription,\n\tmetadata = [],\n\tdropdownActions = [],\n\tprimaryAction,\n\tclassName = \"\",\n\tonClick,\n}) => {\n\treturn (\n\t\t<Card\n\t\t\tclassName={`${styles.card} ${onClick ? styles.cardClickable : \"\"} ${className}`}\n\t\t\tonClick={onClick}\n\t\t>\n\t\t\t<CardHeader>\n\t\t\t\t<div className={styles.cardHeaderRow}>\n\t\t\t\t\t<div className={styles.cardTitleGroup}>\n\t\t\t\t\t\t{icon}\n\t\t\t\t\t\t<div className={styles.cardTitleContainer}>\n\t\t\t\t\t\t\t<Heading level={2}>{title}</Heading>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t{dropdownActions.length > 0 && (\n\t\t\t\t\t\t<DropdownMenu>\n\t\t\t\t\t\t\t<DropdownMenuTrigger asChild>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\tonClick={(e) => e.stopPropagation()}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<MoreVertical className={styles.iconSm} />\n\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t</DropdownMenuTrigger>\n\t\t\t\t\t\t\t<DropdownMenuContent align=\"end\">\n\t\t\t\t\t\t\t\t{dropdownActions.map((action) => (\n\t\t\t\t\t\t\t\t\t<DropdownMenuItem\n\t\t\t\t\t\t\t\t\t\tkey={action.label}\n\t\t\t\t\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\t\t\t\t\tif (!action.disabled) {\n\t\t\t\t\t\t\t\t\t\t\t\taction.onClick();\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\tdisabled={action.disabled}\n\t\t\t\t\t\t\t\t\t\tclassName={\n\t\t\t\t\t\t\t\t\t\t\taction.variant === \"destructive\"\n\t\t\t\t\t\t\t\t\t\t\t\t? \"text-red-600\"\n\t\t\t\t\t\t\t\t\t\t\t\t: action.className\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{action.icon}\n\t\t\t\t\t\t\t\t\t\t{action.label}\n\t\t\t\t\t\t\t\t\t</DropdownMenuItem>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</DropdownMenuContent>\n\t\t\t\t\t\t</DropdownMenu>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t{(metadata.length > 0 || description) && (\n\t\t\t\t\t<div className={styles.metadataSection}>\n\t\t\t\t\t\t{metadata.map((meta) => (\n\t\t\t\t\t\t\t<CardDescription\n\t\t\t\t\t\t\t\tkey={`${meta.label}-${meta.value}`}\n\t\t\t\t\t\t\t\tclassName={styles.metadataText}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{meta.label}: {meta.value}\n\t\t\t\t\t\t\t</CardDescription>\n\t\t\t\t\t\t))}\n\t\t\t\t\t\t{description && (\n\t\t\t\t\t\t\t<CardDescription className={styles.descriptionText}>\n\t\t\t\t\t\t\t\t{description}\n\t\t\t\t\t\t\t</CardDescription>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</CardHeader>\n\t\t\t{primaryAction && (\n\t\t\t\t<CardContent className={styles.cardFooter}>\n\t\t\t\t\t<RhcButton\n\t\t\t\t\t\tonClick={(e: React.MouseEvent) => {\n\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\tprimaryAction.onClick();\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tclassName={`${primaryAction.className || \"\"}`}\n\t\t\t\t\t\tappearance={primaryAction.appearance || \"primary-action-button\"}\n\t\t\t\t\t>\n\t\t\t\t\t\t{primaryAction.icon}\n\t\t\t\t\t\t{primaryAction.label}\n\t\t\t\t\t</RhcButton>\n\t\t\t\t</CardContent>\n\t\t\t)}\n\t\t</Card>\n\t);\n};\n","/**\n * FormsView with TanStack Query - Example implementation\n * Demonstrates how to replace manual state management with TanStack Query\n */\n\nimport { useFormNavigation } from \"@formbuilder/forms/navigation\";\nimport { Button } from \"@formbuilder/ui\";\nimport { ChevronRight, FileText, Plus, Settings, Trash2 } from \"lucide-react\";\nimport { useState } from \"react\";\nimport { useDeleteFormMutation, useFormsQuery } from \"../../hooks/useFormsQuery\";\nimport { BaseLayout } from \"../../layout/BaseLayout/BaseLayout\";\nimport { NewFormDialog } from \"../NewFormDialog/NewFormDialog\";\nimport { SearchInput } from \"../SearchInput/SearchInput\";\nimport { ViewCard } from \"../ViewCard/ViewCard\";\nimport styles from \"./FormsView.module.css\";\n\nexport interface FormsViewProps {\n\tprojectId: string;\n\t/** If provided, used instead of internal TanStack Query fetch */\n\tforms?: { id: string; title: string; fileName: string; lastModified: number; description?: string }[];\n\t/** Project name override — used when forms prop is provided */\n\tprojectName?: string;\n\t/** If provided, used instead of internal loading state */\n\tisLoading?: boolean;\n\tonNavigateToProjects?: () => void; // Keep for backward compat but not required\n\tonRefresh?: () => void;\n\t/** Custom form creation handler — bypasses the default formsExplorer storage path */\n\tonCreateForm?: (request: {\n\t\tprojectId: string;\n\t\tformId: string;\n\t\ttitle: string;\n\t\tdescription?: string;\n\t}) => Promise<{ success: boolean; formId?: string }>;\n\tonFormDeleted?: (projectId: string, formId: string) => void;\n\tonFormAdded?: (\n\t\tprojectId: string,\n\t\tform: { id: string; title: string; description?: string }\n\t) => void;\n\tclassName?: string;\n\tstyle?: React.CSSProperties;\n}\n\nconst formatDate = (timestamp?: number): string => {\n\tif (!timestamp) return \"Unknown\";\n\treturn new Date(timestamp).toLocaleDateString();\n};\n\nexport const FormsView: React.FC<FormsViewProps> = ({\n\tprojectId,\n\tforms: formsProp,\n\tprojectName: projectNameProp,\n\tisLoading: isLoadingProp,\n\tonNavigateToProjects,\n\tonRefresh,\n\tonCreateForm,\n\tonFormDeleted,\n\tonFormAdded,\n}) => {\n\tconst [searchQuery, setSearchQuery] = useState(\"\");\n\tconst [showNewFormDialog, setShowNewFormDialog] = useState(false);\n\n\t// Use navigation context\n\tconst { navigateToProjects, navigateToBuilder } = useFormNavigation();\n\n\t// Use TanStack Query for data fetching (skipped when props are provided)\n\tconst internalQuery = useFormsQuery();\n\tconst deleteFormMutation = useDeleteFormMutation();\n\n\t// Find the current project from internal data (when no props override)\n\tconst internalProject = internalQuery.data?.find((p) => p.id === projectId);\n\n\t// Resolve data: props override internal query\n\tconst resolvedForms = formsProp ?? internalProject?.forms ?? [];\n\tconst resolvedProjectName = projectNameProp ?? internalProject?.name;\n\tconst isLoading = isLoadingProp ?? internalQuery.isLoading;\n\tconst error = formsProp ? null : internalQuery.error;\n\tconst projectFound = formsProp !== undefined || internalProject !== undefined;\n\n\t// Filter forms based on search\n\tconst filteredForms = resolvedForms.filter(\n\t\t(form) =>\n\t\t\tform.title.toLowerCase().includes(searchQuery.toLowerCase()) ||\n\t\t\tform.description?.toLowerCase().includes(searchQuery.toLowerCase()) ||\n\t\t\tform.id.toLowerCase().includes(searchQuery.toLowerCase())\n\t);\n\n\t// Action handlers with TanStack Query\n\tconst handleCreateForm = () => {\n\t\tsetShowNewFormDialog(true);\n\t};\n\n\tconst handleFormCreated = (createdProjectId: string, formId: string) => {\n\t\tconsole.log(\"Form created:\", formId);\n\n\t\t// Call the optional callback if provided\n\t\tif (onFormAdded) {\n\t\t\tconst form = resolvedForms.find((f) => f.id === formId);\n\t\t\tif (form) {\n\t\t\t\tonFormAdded(createdProjectId, {\n\t\t\t\t\tid: form.id,\n\t\t\t\t\ttitle: form.title,\n\t\t\t\t\tdescription: form.description,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Call the optional refresh callback if provided\n\t\tonRefresh?.();\n\t};\n\n\tconst handleDeleteForm = async (formId: string) => {\n\t\tconst confirmed = confirm(\n\t\t\t`Are you sure you want to delete the form \"${formId}\"? This action cannot be undone.`\n\t\t);\n\n\t\tif (!confirmed) return;\n\n\t\t// Call optimistic update callback if provided\n\t\tif (onFormDeleted) {\n\t\t\tonFormDeleted(projectId, formId);\n\t\t}\n\n\t\t// Execute mutation - this handles optimistic updates automatically\n\t\ttry {\n\t\t\tawait deleteFormMutation.mutateAsync({\n\t\t\t\tprojectId,\n\t\t\t\tformId,\n\t\t\t});\n\t\t\tconsole.log(`✅ Form deleted: ${projectId}/${formId}`);\n\t\t} catch (error) {\n\t\t\tconsole.error(`❌ Failed to delete form: ${projectId}/${formId}`, error);\n\t\t\t// Error is automatically handled by mutation (rollback optimistic update)\n\t\t}\n\n\t\t// Call refresh callback if provided\n\t\tif (onRefresh) {\n\t\t\tonRefresh();\n\t\t}\n\t};\n\n\tconst handleEditForm = (formId: string) => {\n\t\t// Navigate to form builder using navigation context\n\t\tnavigateToBuilder(projectId, formId);\n\t};\n\n\tconst handleFormClick = (form: {\n\t\tid: string;\n\t\ttitle: string;\n\t\tdescription?: string;\n\t}) => {\n\t\thandleEditForm(form.id);\n\t};\n\n\tconst handleBackToProjects = () => {\n\t\tonNavigateToProjects?.(); // Call callback if provided (backward compat)\n\t\tnavigateToProjects(); // Always navigate via context\n\t};\n\n\t// Handle loading state\n\tif (isLoading) {\n\t\treturn (\n\t\t\t<BaseLayout\n\t\t\t\ttitle=\"Loading...\"\n\t\t\t\tsubtitle=\"Loading project data...\"\n\t\t\t\tisLoading={true}\n\t\t\t>\n\t\t\t\t<div>Loading forms...</div>\n\t\t\t</BaseLayout>\n\t\t);\n\t}\n\n\t// Handle error state\n\tif (error) {\n\t\treturn (\n\t\t\t<BaseLayout title=\"Error\" subtitle=\"Failed to load project data\">\n\t\t\t\t<div className={styles.emptyState}>\n\t\t\t\t\t<p className={styles.errorText}>\n\t\t\t\t\t\tFailed to load forms: {error.message}\n\t\t\t\t\t</p>\n\t\t\t\t\t<Button onClick={() => window.location.reload()}>Retry</Button>\n\t\t\t\t</div>\n\t\t\t</BaseLayout>\n\t\t);\n\t}\n\n\t// Handle project not found\n\tif (!isLoading && !projectFound) {\n\t\treturn (\n\t\t\t<BaseLayout\n\t\t\t\ttitle=\"Project Not Found\"\n\t\t\t\tsubtitle=\"The requested project could not be found\"\n\t\t\t>\n\t\t\t\t<div className={styles.emptyState}>\n\t\t\t\t\t<p className={styles.notFoundText}>\n\t\t\t\t\t\tProject with ID \"{projectId}\" was not found.\n\t\t\t\t\t</p>\n\t\t\t\t\t<Button onClick={handleBackToProjects}>Back to Projects</Button>\n\t\t\t\t</div>\n\t\t\t</BaseLayout>\n\t\t);\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t<BaseLayout\n\t\t\t\ttitle={resolvedProjectName ?? projectId}\n\t\t\t\tsubtitle=\"Maak en beheer projecten en de instellingen\"\n\t\t\t\tshowBackButton\n\t\t\t\tonBack={handleBackToProjects}\n\t\t\t\tbackButtonText=\"Terug naar Projecten\"\n\t\t\t\tsearchSlot={\n\t\t\t\t\t<SearchInput\n\t\t\t\t\t\tplaceholder=\"Zoek op formuliernaam\"\n\t\t\t\t\t\tonSearchChange={setSearchQuery}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t\tprimaryAction={{\n\t\t\t\t\tlabel: \"Formulier toevoegen\",\n\t\t\t\t\tonClick: handleCreateForm,\n\t\t\t\t\ticon: <Plus className={`${styles.iconSm} ${styles.mr2}`} />,\n\t\t\t\t}}\n\t\t\t\tisLoading={deleteFormMutation.isPending}\n\t\t\t>\n\t\t\t\t{/* Forms Grid */}\n\t\t\t\t{filteredForms.length > 0 ? (\n\t\t\t\t\t<div className={styles.formsGrid}>\n\t\t\t\t\t\t{filteredForms.map((form) => (\n\t\t\t\t\t\t\t<ViewCard\n\t\t\t\t\t\t\t\tkey={form.id}\n\t\t\t\t\t\t\t\ticon={<FileText className={`${styles.iconMd} ${styles.shrink0}`} />}\n\t\t\t\t\t\t\t\ttitle={form.title}\n\t\t\t\t\t\t\t\tdescription={form.description}\n\t\t\t\t\t\t\t\tmetadata={[\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tlabel: \"Aanmaakdatum\",\n\t\t\t\t\t\t\t\t\t\tvalue: formatDate(form.lastModified),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t// { label: \"Formulieren\", value: 3 },\n\t\t\t\t\t\t\t\t]}\n\t\t\t\t\t\t\t\tdropdownActions={[\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tlabel: \"Edit Form\",\n\t\t\t\t\t\t\t\t\t\ticon: <Settings className={`${styles.iconSm} ${styles.mr2}`} />,\n\t\t\t\t\t\t\t\t\t\tonClick: () => handleEditForm(form.id),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tlabel: \"Delete Form\",\n\t\t\t\t\t\t\t\t\t\ticon: <Trash2 className={`${styles.iconSm} ${styles.mr2}`} />,\n\t\t\t\t\t\t\t\t\t\tonClick: () => handleDeleteForm(form.id),\n\t\t\t\t\t\t\t\t\t\tvariant: \"destructive\",\n\t\t\t\t\t\t\t\t\t\tdisabled: deleteFormMutation.isPending,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t]}\n\t\t\t\t\t\t\t\tprimaryAction={{\n\t\t\t\t\t\t\t\t\ticon: <ChevronRight className={styles.iconSm} />,\n\t\t\t\t\t\t\t\t\tonClick: () => handleFormClick(form),\n\t\t\t\t\t\t\t\t\tappearance: \"secondary-action-button\",\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</div>\n\t\t\t\t) : (\n\t\t\t\t\t<div className={styles.emptyState}>\n\t\t\t\t\t\t<FileText className={`${styles.icon3xl} ${styles.mxAuto} ${styles.mb4}`} />\n\t\t\t\t\t\t<h3 className={styles.emptyStateTitle}>\n\t\t\t\t\t\t\tGeen formulieren gevonden\n\t\t\t\t\t\t</h3>\n\t\t\t\t\t\t<p className={styles.emptyStateText}>\n\t\t\t\t\t\t\t{searchQuery\n\t\t\t\t\t\t\t\t? \"Geen formulieren komen overeen met je zoekopdracht.\"\n\t\t\t\t\t\t\t\t: \"Maak je eerste formulier om te beginnen.\"}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t{!searchQuery && (\n\t\t\t\t\t\t\t<Button onClick={handleCreateForm}>\n\t\t\t\t\t\t\t\t<Plus className={`${styles.iconSm} ${styles.mr2}`} />\n\t\t\t\t\t\t\t\tFormulier aanmaken\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</BaseLayout>\n\n\t\t\t{/* New Form Dialog */}\n\t\t\t<NewFormDialog\n\t\t\t\topen={showNewFormDialog}\n\t\t\t\tonOpenChange={setShowNewFormDialog}\n\t\t\t\tselectedProjectId={projectId}\n\t\t\t\tonFormCreated={handleFormCreated}\n\t\t\t\tonCreateForm={onCreateForm}\n\t\t\t/>\n\t\t</>\n\t);\n};\n","/**\n * useProjectActions - Hook providing centralized project operations\n * Eliminates prop drilling by directly accessing storage layer functions\n */\n\nimport { useFormNavigation } from \"@formbuilder/forms/navigation\";\nimport type { CreateProjectRequest } from \"@formbuilder/core\";\nimport { useCallback } from \"react\";\nimport { StorageProviderFactory } from \"../../../storage/StorageProviderFactory\";\nimport { createProject, deleteForm } from \"../../../utils/formsExplorer\";\n\nexport interface UseProjectActionsReturn {\n\t/**\n\t * Create a new project\n\t */\n\tcreateProject: (request: CreateProjectRequest) => Promise<boolean>;\n\n\t/**\n\t * Delete a project by deleting all its forms\n\t * Note: Some storage providers may have direct project deletion methods\n\t */\n\tdeleteProject: (projectId: string) => Promise<boolean>;\n\n\t/**\n\t * Delete a specific form from a project\n\t */\n\tdeleteForm: (projectId: string, formId: string) => Promise<boolean>;\n\n\t/**\n\t * Navigate to a project's forms view (navigation helper)\n\t */\n\tnavigateToProject: (projectId: string) => void;\n}\n\n/**\n * Hook providing centralized project and form operations\n * Uses the storage layer directly to avoid prop drilling\n */\nexport function useProjectActions(): UseProjectActionsReturn {\n\tconst { navigateToForms } = useFormNavigation();\n\n\tconst handleCreateProject = useCallback(\n\t\tasync (request: CreateProjectRequest): Promise<boolean> => {\n\t\t\ttry {\n\t\t\t\tconsole.log(\"🔄 Creating project via hook:\", request.name);\n\t\t\t\tconst result = await createProject(request);\n\n\t\t\t\tif (result.success) {\n\t\t\t\t\tconsole.log(\"✅ Project created successfully:\", request.name);\n\t\t\t\t\treturn true;\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(\"❌ Failed to create project:\", request.name);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"❌ Exception during project creation:\", error);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\t[]\n\t);\n\n\tconst handleDeleteProject = useCallback(\n\t\tasync (projectId: string): Promise<boolean> => {\n\t\t\ttry {\n\t\t\t\tconsole.log(\"🔄 Deleting project via hook:\", projectId);\n\n\t\t\t\t// Get the current storage provider directly from factory to avoid creating new instances\n\t\t\t\tconst factory = StorageProviderFactory.getInstance();\n\t\t\t\tconst storageProvider = factory.getCurrentProvider();\n\n\t\t\t\tif (!storageProvider) {\n\t\t\t\t\tconsole.error(\"❌ No storage provider available\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t`🔍 Using existing storage provider: ${storageProvider.getType()}`\n\t\t\t\t);\n\n\t\t\t\t// Try using direct project deletion if supported\n\t\t\t\tif (storageProvider.deleteProject) {\n\t\t\t\t\tconsole.log(`🎯 Using direct project deletion for: ${projectId}`);\n\t\t\t\t\tconst deleteResult = await storageProvider.deleteProject(projectId);\n\n\t\t\t\t\tif (deleteResult.success) {\n\t\t\t\t\t\tconsole.log(`✅ Successfully deleted project: ${projectId}`);\n\t\t\t\t\t\tif (deleteResult.data) {\n\t\t\t\t\t\t\tconsole.log(`📊 Deletion stats:`, deleteResult.data);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t`❌ Direct project deletion failed: ${deleteResult.error}`\n\t\t\t\t\t\t);\n\t\t\t\t\t\t// Fall back to form-by-form deletion\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t`⚠️ Storage provider doesn't support direct project deletion, falling back to form-by-form deletion`\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Fallback: Delete forms individually (legacy approach)\n\t\t\t\tconsole.log(\n\t\t\t\t\t`🔄 Falling back to form-by-form deletion for project: ${projectId}`\n\t\t\t\t);\n\n\t\t\t\t// Get the forms directly from the storage provider\n\t\t\t\tconst formsResult = await storageProvider.listForms();\n\t\t\t\tif (!formsResult.success || !formsResult.data) {\n\t\t\t\t\tconsole.error(\"❌ Failed to list forms from storage provider\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// Filter forms for this project (excluding empty project placeholders)\n\t\t\t\tconst projectForms = formsResult.data.filter((form) => {\n\t\t\t\t\tif (form.wizardId === \"__empty_project__\") {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\treturn form.project === projectId;\n\t\t\t\t});\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t`📋 Found ${projectForms.length} forms to delete in project ${projectId}`\n\t\t\t\t);\n\t\t\t\tconsole.log(\n\t\t\t\t\t`🔍 Forms in project: ${projectForms.map((f) => f.wizardId).join(\", \")}`\n\t\t\t\t);\n\n\t\t\t\t// Delete each form directly using the storage provider\n\t\t\t\tlet deletedCount = 0;\n\t\t\t\tfor (const form of projectForms) {\n\t\t\t\t\tif (storageProvider.deleteForm) {\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t`🗑️ Attempting to delete form: ${projectId}/${form.wizardId}`\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst deleteResult = await storageProvider.deleteForm(\n\t\t\t\t\t\t\tprojectId,\n\t\t\t\t\t\t\tform.wizardId\n\t\t\t\t\t\t);\n\t\t\t\t\t\tif (deleteResult.success) {\n\t\t\t\t\t\t\tdeletedCount++;\n\t\t\t\t\t\t\tconsole.log(`✅ Deleted form: ${form.wizardId}`);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t\t`❌ Failed to delete form: ${form.wizardId}`,\n\t\t\t\t\t\t\t\tdeleteResult.error\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst success = deletedCount === projectForms.length;\n\t\t\t\tif (success) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t`✅ Successfully deleted project ${projectId} (${deletedCount} forms)`\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`⚠️ Partial deletion: ${deletedCount}/${projectForms.length} forms deleted`\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn success;\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"❌ Exception during project deletion:\", error);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\t[]\n\t);\n\n\tconst handleDeleteForm = useCallback(\n\t\tasync (projectId: string, formId: string): Promise<boolean> => {\n\t\t\ttry {\n\t\t\t\tconsole.log(\"🔄 Deleting form via hook:\", `${projectId}/${formId}`);\n\t\t\t\tconst success = await deleteForm(projectId, formId);\n\n\t\t\t\tif (success) {\n\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\"✅ Form deleted successfully:\",\n\t\t\t\t\t\t`${projectId}/${formId}`\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(\"❌ Failed to delete form:\", `${projectId}/${formId}`);\n\t\t\t\t}\n\n\t\t\t\treturn success;\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"❌ Exception during form deletion:\", error);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\t[]\n\t);\n\n\tconst handleNavigateToProject = useCallback(\n\t\t(projectId: string): void => {\n\t\t\t// Navigate to the project's forms view using navigation context\n\t\t\tconsole.log(\"🔄 Navigating to project:\", projectId);\n\t\t\tnavigateToForms(projectId);\n\t\t},\n\t\t[navigateToForms]\n\t);\n\n\treturn {\n\t\tcreateProject: handleCreateProject,\n\t\tdeleteProject: handleDeleteProject,\n\t\tdeleteForm: handleDeleteForm,\n\t\tnavigateToProject: handleNavigateToProject,\n\t};\n}\n","/**\n * TanStack Query hook for projects data fetching\n * Follows the pattern of useFormsQuery.ts\n */\n\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { FormConfig } from \"../../../config/types\";\nimport { scanFormsDirectory } from \"../../../utils/formsExplorer\";\n\n// Query keys for cache management\nexport const projectsQueryKeys = {\n\tall: [\"projects\"] as const,\n};\n\ninterface UseProjectsDataOptions {\n\tconfig?: FormConfig;\n}\n\n/**\n * Query hook for fetching all projects\n * Provides automatic caching and background updates via TanStack Query\n */\nexport function useProjectsData({ config }: UseProjectsDataOptions = {}) {\n\treturn useQuery({\n\t\tqueryKey: projectsQueryKeys.all,\n\t\tqueryFn: async () => {\n\t\t\tconst operationsConfig = config ? { formConfig: config } : {};\n\t\t\tconst result = await scanFormsDirectory(operationsConfig);\n\t\t\treturn result.projects;\n\t\t},\n\t\tstaleTime: 30000, // Consider data fresh for 30 seconds\n\t\trefetchOnWindowFocus: true, // Refetch when user returns to tab\n\t\trefetchOnMount: true, // Always refetch on component mount\n\t});\n}\n","/**\n * NewProjectDialog component - dialog for creating new projects\n */\n\nimport {\n\tButton,\n\tDialog,\n\tDialogContent,\n\tDialogDescription,\n\tDialogFooter,\n\tDialogHeader,\n\tDialogTitle,\n\tInput,\n\tLabel,\n\tTextarea,\n} from \"@formbuilder/ui\";\nimport { toast } from \"sonner\";\nimport { useForm } from \"@tanstack/react-form\";\nimport { useCallback, useEffect } from \"react\";\nimport { createProject } from \"../../../../utils/formsExplorer\";\nimport styles from \"./NewProjectDialog.module.css\";\n\nexport interface NewProjectDialogProps {\n\topen: boolean;\n\tonOpenChange: (open: boolean) => void;\n\tonProjectCreated?: (projectData?: {\n\t\tprojectId: string;\n\t\tname: string;\n\t\tdescription?: string;\n\t}) => void;\n\t/** Custom project creation handler — bypasses the default formsExplorer storage path */\n\tonCreateProject?: (request: {\n\t\tname: string;\n\t\tdescription?: string;\n\t}) => Promise<{\n\t\tsuccess: boolean;\n\t\tprojectId?: string;\n\t\tname?: string;\n\t\tdescription?: string;\n\t}>;\n}\n\nexport const NewProjectDialog: React.FC<NewProjectDialogProps> = ({\n\topen,\n\tonOpenChange,\n\tonProjectCreated,\n\tonCreateProject,\n}) => {\n\tconst form = useForm({\n\t\tdefaultValues: {\n\t\t\tname: \"\",\n\t\t\tdescription: \"\",\n\t\t},\n\t\tonSubmit: async ({ value }) => {\n\t\t\ttry {\n\t\t\t\tconst request = {\n\t\t\t\t\tname: value.name.trim(),\n\t\t\t\t\tdescription: value.description.trim() || undefined,\n\t\t\t\t};\n\n\t\t\t\tconst result = onCreateProject\n\t\t\t\t\t? await onCreateProject(request)\n\t\t\t\t\t: await createProject(request);\n\n\t\t\t\tif (result.success) {\n\t\t\t\t\ttoast.success(`Project \"${value.name}\" created successfully`);\n\t\t\t\t\tonOpenChange(false);\n\t\t\t\t\tonProjectCreated?.({\n\t\t\t\t\t\tprojectId: result.projectId ?? \"unknown\",\n\t\t\t\t\t\tname: result.name ?? request.name,\n\t\t\t\t\t\tdescription: result.description,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\ttoast.error(\"Failed to create project\");\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Failed to create project:\", error);\n\t\t\t\ttoast.error(\n\t\t\t\t\terror instanceof Error ? error.message : \"Failed to create project\",\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t});\n\n\t// Reset form when dialog opens\n\tuseEffect(() => {\n\t\tif (open) {\n\t\t\tform.reset();\n\t\t}\n\t}, [open, form]);\n\n\tconst handleCancel = useCallback(() => {\n\t\tonOpenChange(false);\n\t}, [onOpenChange]);\n\n\treturn (\n\t\t<Dialog open={open} onOpenChange={onOpenChange}>\n\t\t\t<DialogContent>\n\t\t\t\t<DialogHeader>\n\t\t\t\t\t<DialogTitle>Create New Project</DialogTitle>\n\t\t\t\t\t<DialogDescription>\n\t\t\t\t\t\tCreate a new project to organize your forms.\n\t\t\t\t\t</DialogDescription>\n\t\t\t\t</DialogHeader>\n\t\t\t\t<form\n\t\t\t\t\tonSubmit={(e) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\tform.handleSubmit();\n\t\t\t\t\t}}\n\t\t\t\t\tclassName={styles.formBody}\n\t\t\t\t>\n\t\t\t\t\t<div className={styles.fieldGroup}>\n\t\t\t\t\t\t<form.Field\n\t\t\t\t\t\t\tname=\"name\"\n\t\t\t\t\t\t\tvalidators={{\n\t\t\t\t\t\t\t\tonChange: ({ value }) =>\n\t\t\t\t\t\t\t\t\t!value.trim() ? \"Project name is required\" : undefined,\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{(field) => (\n\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t<Label htmlFor=\"project-name\">Project Name</Label>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\tid=\"project-name\"\n\t\t\t\t\t\t\t\t\t\tvalue={field.state.value}\n\t\t\t\t\t\t\t\t\t\tonChange={(e: React.ChangeEvent<HTMLInputElement>) =>\n\t\t\t\t\t\t\t\t\t\t\tfield.handleChange(e.target.value)\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tplaceholder=\"Enter project name\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t{field.state.meta.errors?.length > 0 && (\n\t\t\t\t\t\t\t\t\t\t<p className={styles.fieldError}>\n\t\t\t\t\t\t\t\t\t\t\t{field.state.meta.errors[0]}\n\t\t\t\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</form.Field>\n\n\t\t\t\t\t\t<form.Field name=\"description\">\n\t\t\t\t\t\t\t{(field) => (\n\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t<Label htmlFor=\"project-description\">\n\t\t\t\t\t\t\t\t\t\tDescription (Optional)\n\t\t\t\t\t\t\t\t\t</Label>\n\t\t\t\t\t\t\t\t\t<Textarea\n\t\t\t\t\t\t\t\t\t\tid=\"project-description\"\n\t\t\t\t\t\t\t\t\t\tvalue={field.state.value}\n\t\t\t\t\t\t\t\t\t\tonChange={(e: React.ChangeEvent<HTMLTextAreaElement>) =>\n\t\t\t\t\t\t\t\t\t\t\tfield.handleChange(e.target.value)\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tplaceholder=\"Enter project description...\"\n\t\t\t\t\t\t\t\t\t\trows={3}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</form.Field>\n\t\t\t\t\t</div>\n\t\t\t\t\t<DialogFooter>\n\t\t\t\t\t\t<Button variant=\"outline\" type=\"button\" onClick={handleCancel}>\n\t\t\t\t\t\t\tCancel\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t<Button type=\"submit\">Create Project</Button>\n\t\t\t\t\t</DialogFooter>\n\t\t\t\t</form>\n\t\t\t</DialogContent>\n\t\t</Dialog>\n\t);\n};\n","/**\n * ProjectsView - Main projects overview with cards showing project information\n */\n\nimport type { ProjectMetadata } from \"@formbuilder/core\";\nimport { Button, GridLayout, GridLayoutColumn } from \"@formbuilder/ui\";\nimport { toast } from \"sonner\";\nimport { ChevronRight, Folder, Plus, Trash2 } from \"lucide-react\";\nimport { useReducer, useState } from \"react\";\nimport styles from \"./ProjectsView.module.css\";\nimport { ConfirmDialog } from \"../../../dialog-system/components/ConfirmDialog\";\nimport { useProjectActions } from \"../../hooks/useProjectActions\";\nimport { useProjectsData } from \"../../hooks/useProjectsData\";\nimport { BaseLayout } from \"../../layout/BaseLayout/BaseLayout\";\nimport { NewProjectDialog } from \"../NewProjectDialog/NewProjectDialog\";\nimport { SearchInput } from \"../SearchInput/SearchInput\";\nimport { ViewCard } from \"../ViewCard/ViewCard\";\n\nexport interface ProjectsViewProps {\n\t// Optional overrides for backward compatibility with FormExplorerCore\n\tprojects?: ProjectMetadata[]; // If provided, used instead of internal fetch\n\tisLoading?: boolean; // If provided, used instead of internal state\n\tonRefresh?: () => void; // If provided, called alongside internal refetch\n\tonProjectDeleted?: (projectId: string) => void;\n\t/** Custom project creation handler — bypasses the default formsExplorer storage path */\n\tonCreateProject?: (request: {\n\t\tname: string;\n\t\tdescription?: string;\n\t}) => Promise<{\n\t\tsuccess: boolean;\n\t\tprojectId?: string;\n\t\tname?: string;\n\t\tdescription?: string;\n\t}>;\n\tclassName?: string;\n\tstyle?: React.CSSProperties;\n}\n\nconst formatDate = (timestamp?: number): string => {\n\tif (!timestamp) return \"Unknown\";\n\treturn new Date(timestamp).toLocaleDateString();\n};\n\n// Dialog state management with useReducer\ntype DialogState = {\n\tnewProject: boolean;\n\tdeleteConfirm: boolean;\n\tprojectToDelete: ProjectMetadata | null;\n};\n\ntype DialogAction =\n\t| { type: \"OPEN_NEW_PROJECT\" }\n\t| { type: \"CLOSE_NEW_PROJECT\" }\n\t| { type: \"OPEN_DELETE_CONFIRM\"; project: ProjectMetadata }\n\t| { type: \"CLOSE_DELETE_CONFIRM\" }\n\t| { type: \"RESET_ALL\" };\n\nconst dialogReducer = (\n\tstate: DialogState,\n\taction: DialogAction\n): DialogState => {\n\tswitch (action.type) {\n\t\tcase \"OPEN_NEW_PROJECT\":\n\t\t\treturn { ...state, newProject: true };\n\t\tcase \"CLOSE_NEW_PROJECT\":\n\t\t\treturn { ...state, newProject: false };\n\t\tcase \"OPEN_DELETE_CONFIRM\":\n\t\t\treturn { ...state, deleteConfirm: true, projectToDelete: action.project };\n\t\tcase \"CLOSE_DELETE_CONFIRM\":\n\t\t\treturn { ...state, deleteConfirm: false, projectToDelete: null };\n\t\tcase \"RESET_ALL\":\n\t\t\treturn { newProject: false, deleteConfirm: false, projectToDelete: null };\n\t\tdefault:\n\t\t\treturn state;\n\t}\n};\n\nconst initialDialogState: DialogState = {\n\tnewProject: false,\n\tdeleteConfirm: false,\n\tprojectToDelete: null,\n};\n\nexport const ProjectsView: React.FC<ProjectsViewProps> = ({\n\tprojects: projectsProp,\n\tisLoading: isLoadingProp,\n\tonRefresh,\n\tonProjectDeleted,\n\tonCreateProject,\n}) => {\n\tconst [searchQuery, setSearchQuery] = useState(\"\");\n\tconst [dialogState, dispatchDialog] = useReducer(\n\t\tdialogReducer,\n\t\tinitialDialogState\n\t);\n\tconst { deleteProject, navigateToProject } = useProjectActions();\n\n\t// Fetch data internally, but allow props to override\n\tconst internalQuery = useProjectsData();\n\tconst projects = projectsProp ?? internalQuery.data ?? [];\n\tconst isLoading = isLoadingProp ?? internalQuery.isLoading;\n\n\t// Merge internal and external refresh handlers\n\tconst handleRefresh = () => {\n\t\tinternalQuery.refetch();\n\t\tonRefresh?.();\n\t};\n\n\tconst filteredProjects = projects.filter(\n\t\t(project) =>\n\t\t\tproject.name.toLowerCase().includes(searchQuery.toLowerCase()) ||\n\t\t\tproject.description?.toLowerCase().includes(searchQuery.toLowerCase())\n\t);\n\n\t// Action handlers using centralized storage operations\n\tconst handleCreateProject = () => {\n\t\tdispatchDialog({ type: \"OPEN_NEW_PROJECT\" });\n\t};\n\n\tconst handleProjectCreated = () => {\n\t\tdispatchDialog({ type: \"CLOSE_NEW_PROJECT\" });\n\t\thandleRefresh(); // Refresh the projects list\n\t};\n\n\tconst handleDeleteProject = (project: ProjectMetadata) => {\n\t\tdispatchDialog({ type: \"OPEN_DELETE_CONFIRM\", project });\n\t};\n\n\tconst confirmDeleteProject = async () => {\n\t\tif (!dialogState.projectToDelete) return;\n\n\t\tconst projectName = dialogState.projectToDelete.name;\n\t\tconst projectId = dialogState.projectToDelete.id;\n\n\t\ttry {\n\t\t\tconsole.log(\n\t\t\t\t`🔄 Starting deletion process for project: ${projectName} (${projectId})`\n\t\t\t);\n\n\t\t\tconst success = await deleteProject(projectId);\n\n\t\t\tif (success) {\n\t\t\t\tconsole.log(`✅ Project deletion successful: ${projectName}`);\n\n\t\t\t\t// Only remove from UI after successful deletion\n\t\t\t\tif (onProjectDeleted) {\n\t\t\t\t\tonProjectDeleted(projectId);\n\t\t\t\t\tconsole.log(\"🚀 Project removed from UI after successful deletion\");\n\t\t\t\t}\n\n\t\t\t\ttoast.success(`Project \"${projectName}\" and all its forms have been permanently deleted.`);\n\n\t\t\t\t// Trigger refresh to ensure UI is in sync with database\n\t\t\t\thandleRefresh();\n\t\t\t} else {\n\t\t\t\tconsole.error(`❌ Project deletion failed: ${projectName}`);\n\t\t\t\ttoast.error(`Failed to delete project \"${projectName}\". This might be due to a database connection issue. Please check your connection and try again.`);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(\"❌ Exception during project deletion:\", error);\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error);\n\n\t\t\t// Provide more specific error messaging\n\t\t\tlet userMessage = `An unexpected error occurred while deleting project \"${projectName}\".`;\n\n\t\t\tif (errorMessage.includes(\"Database not initialized\")) {\n\t\t\t\tuserMessage = `Database connection error. Please refresh the page and try again.`;\n\t\t\t} else if (errorMessage.includes(\"Project not found\")) {\n\t\t\t\tuserMessage = `Project \"${projectName}\" no longer exists. The page will be refreshed.`;\n\t\t\t\t// Auto-refresh for this case since the project is already gone\n\t\t\t\thandleRefresh();\n\t\t\t} else if (errorMessage.includes(\"Failed to delete project\")) {\n\t\t\t\tuserMessage = `Could not delete project \"${projectName}\" from the database. Please check your connection and try again.`;\n\t\t\t}\n\n\t\t\ttoast.error(userMessage);\n\t\t} finally {\n\t\t\tdispatchDialog({ type: \"CLOSE_DELETE_CONFIRM\" });\n\t\t}\n\t};\n\n\t// Self-contained navigation handler\n\tconst handleProjectClick = (project: ProjectMetadata) => {\n\t\t// Use URL-based navigation like FormsView does\n\t\tnavigateToProject(project.id);\n\t};\n\n\treturn (\n\t\t<>\n\t\t\t<BaseLayout\n\t\t\t\ttitle=\"Projecten\"\n\t\t\t\tsubtitle=\"Maak en beheer projecten en de instellingen\"\n\t\t\t\tsearchSlot={\n\t\t\t\t\t<SearchInput\n\t\t\t\t\t\tplaceholder=\"Zoek op project- of formuliernaam\"\n\t\t\t\t\t\tonSearchChange={setSearchQuery}\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t\tprimaryAction={{\n\t\t\t\t\tlabel: \"Project toevoegen\",\n\t\t\t\t\tonClick: handleCreateProject,\n\t\t\t\t\ticon: <Plus className={`${styles.iconSm} ${styles.mr2}`} />,\n\t\t\t\t}}\n\t\t\t\tisLoading={isLoading}\n\t\t\t>\n\t\t\t\t{/* Projects Grid */}\n\t\t\t\t{filteredProjects.length > 0 ? (\n\t\t\t\t\t<GridLayout maxColumns={12} fullWidth>\n\t\t\t\t\t\t{filteredProjects.map((project, index) => (\n\t\t\t\t\t\t\t<GridLayoutColumn\n\t\t\t\t\t\t\t\tkey={project.id}\n\t\t\t\t\t\t\t\tstartSlice={(index % 3) * 4 + 1}\n\t\t\t\t\t\t\t\tendSlice={(index % 3) * 4 + 5}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<ViewCard\n\t\t\t\t\t\t\t\t\ticon={<Folder className={`${styles.iconMd} ${styles.shrink0}`} />}\n\t\t\t\t\t\t\t\t\ttitle={project.name}\n\t\t\t\t\t\t\t\t\tdescription={project.description}\n\t\t\t\t\t\t\t\t\tmetadata={[\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tlabel: \"Aanmaakdatum\",\n\t\t\t\t\t\t\t\t\t\t\tvalue: formatDate(project.createdAt),\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{ label: \"Formulieren\", value: project.forms.length },\n\t\t\t\t\t\t\t\t\t]}\n\t\t\t\t\t\t\t\t\tdropdownActions={[\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tlabel: \"Delete Project\",\n\t\t\t\t\t\t\t\t\t\t\ticon: <Trash2 className={`${styles.iconSm} ${styles.mr2}`} />,\n\t\t\t\t\t\t\t\t\t\t\tonClick: () => handleDeleteProject(project),\n\t\t\t\t\t\t\t\t\t\t\tvariant: \"destructive\" as const,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t]}\n\t\t\t\t\t\t\t\t\tprimaryAction={{\n\t\t\t\t\t\t\t\t\t\ticon: <ChevronRight className={styles.iconSm} />,\n\t\t\t\t\t\t\t\t\t\tonClick: () => handleProjectClick(project),\n\t\t\t\t\t\t\t\t\t\tappearance: \"secondary-action-button\",\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</GridLayoutColumn>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</GridLayout>\n\t\t\t\t) : (\n\t\t\t\t\t<div className={styles.emptyState}>\n\t\t\t\t\t\t<Folder className={`${styles.icon3xl} ${styles.mxAuto} ${styles.mb4}`} />\n\t\t\t\t\t\t<h3 className={styles.emptyStateTitle}>\n\t\t\t\t\t\t\tGeen projecten gevonden\n\t\t\t\t\t\t</h3>\n\t\t\t\t\t\t<p className={styles.emptyStateText}>\n\t\t\t\t\t\t\t{searchQuery\n\t\t\t\t\t\t\t\t? \"Geen projecten komen overeen met je zoekopdracht.\"\n\t\t\t\t\t\t\t\t: \"Maak je eerste project om te beginnen.\"}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t\t{!searchQuery && (\n\t\t\t\t\t\t\t<Button onClick={handleCreateProject}>\n\t\t\t\t\t\t\t\t<Plus className={`${styles.iconSm} ${styles.mr2}`} />\n\t\t\t\t\t\t\t\tProject aanmaken\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</BaseLayout>\n\n\t\t\t{/* New Project Dialog */}\n\t\t\t<NewProjectDialog\n\t\t\t\topen={dialogState.newProject}\n\t\t\t\tonOpenChange={(open) =>\n\t\t\t\t\tdispatchDialog({\n\t\t\t\t\t\ttype: open ? \"OPEN_NEW_PROJECT\" : \"CLOSE_NEW_PROJECT\",\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tonProjectCreated={handleProjectCreated}\n\t\t\t\tonCreateProject={onCreateProject}\n\t\t\t/>\n\n\t\t\t{/* Delete Confirmation Dialog */}\n\t\t\t<ConfirmDialog\n\t\t\t\topen={dialogState.deleteConfirm}\n\t\t\t\tonOpenChange={(open) => {\n\t\t\t\t\tif (!open) {\n\t\t\t\t\t\tdispatchDialog({ type: \"CLOSE_DELETE_CONFIRM\" });\n\t\t\t\t\t}\n\t\t\t\t}}\n\t\t\t\ttitle=\"Delete Project\"\n\t\t\t\tdescription={`Are you sure you want to delete the project \"${dialogState.projectToDelete?.name}\"? This action cannot be undone and will remove all forms within the project.`}\n\t\t\t\tconfirmText=\"Delete\"\n\t\t\t\tcancelText=\"Cancel\"\n\t\t\t\tvariant=\"destructive\"\n\t\t\t\tonConfirm={confirmDeleteProject}\n\t\t\t/>\n\t\t</>\n\t);\n};\n","/**\n * ProjectCard component - displays project information and forms\n */\n\nimport type { ProjectMetadata } from \"@formbuilder/core\";\nimport {\n\tButton,\n\tCard,\n\tCardContent,\n\tCardDescription,\n\tCardHeader,\n\tCardTitle,\n\tDropdownMenu,\n\tDropdownMenuContent,\n\tDropdownMenuItem,\n\tDropdownMenuTrigger,\n\tSeparator,\n} from \"@formbuilder/ui\";\nimport {\n\tFileText,\n\tFolder,\n\tFolderOpen,\n\tMoreHorizontal,\n\tPlus,\n\tSettings,\n} from \"lucide-react\";\nimport { useState } from \"react\";\nimport styles from \"./ProjectCard.module.css\";\n\nexport interface ProjectCardProps {\n\tproject: ProjectMetadata;\n\tonCreateForm: () => void;\n\tonEditForm: (projectId: string, wizardId: string) => void;\n\tonDeleteForm: (projectId: string, wizardId: string) => void;\n\tonPreviewForm?: (projectId: string, wizardId: string) => void;\n}\n\nexport const ProjectCard: React.FC<ProjectCardProps> = ({\n\tproject,\n\tonCreateForm,\n\tonEditForm,\n\tonDeleteForm,\n}) => {\n\tconst [isExpanded, setIsExpanded] = useState(false);\n\n\treturn (\n\t\t<Card className={styles.card}>\n\t\t\t<CardHeader>\n\t\t\t\t<div className={styles.headerRow}>\n\t\t\t\t\t<div className={styles.titleGroup}>\n\t\t\t\t\t\t{isExpanded ? (\n\t\t\t\t\t\t\t<FolderOpen className={`${styles.iconMd} ${styles.iconBlue}`} />\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<Folder className={`${styles.iconMd} ${styles.iconBlue}`} />\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<CardTitle className={styles.cardTitle}>{project.name}</CardTitle>\n\t\t\t\t\t</div>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tonClick={() => setIsExpanded(!isExpanded)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{isExpanded ? \"Collapse\" : \"Expand\"}\n\t\t\t\t\t</Button>\n\t\t\t\t</div>\n\t\t\t\t<CardDescription className={styles.descriptionStack}>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t{project.forms.length} form{project.forms.length !== 1 ? \"s\" : \"\"}\n\t\t\t\t\t</div>\n\t\t\t\t\t{project.description && (\n\t\t\t\t\t\t<div className={styles.descriptionText}>\n\t\t\t\t\t\t\t{project.description}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t</CardDescription>\n\t\t\t</CardHeader>\n\n\t\t\t{isExpanded && (\n\t\t\t\t<CardContent>\n\t\t\t\t\t<div className={styles.formsList}>\n\t\t\t\t\t\t{project.forms.map((form) => (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tkey={form.id}\n\t\t\t\t\t\t\t\tclassName={styles.formItem}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<div className={styles.formItemContent}>\n\t\t\t\t\t\t\t\t\t<FileText className={`${styles.iconSm} ${styles.iconGreen} ${styles.shrink0}`} />\n\t\t\t\t\t\t\t\t\t<div className={styles.formItemText}>\n\t\t\t\t\t\t\t\t\t\t<p className={styles.formItemTitle}>{form.title}</p>\n\t\t\t\t\t\t\t\t\t\t<p className={styles.formItemId}>{form.id}</p>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t<DropdownMenu>\n\t\t\t\t\t\t\t\t\t<DropdownMenuTrigger asChild>\n\t\t\t\t\t\t\t\t\t\t<Button variant=\"ghost\" size=\"sm\">\n\t\t\t\t\t\t\t\t\t\t\t<MoreHorizontal className={styles.iconSm} />\n\t\t\t\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t\t\t\t</DropdownMenuTrigger>\n\t\t\t\t\t\t\t\t\t<DropdownMenuContent align=\"end\">\n\t\t\t\t\t\t\t\t\t\t<DropdownMenuItem\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => onEditForm(project.id, form.id)}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<Settings className={`${styles.iconSm} ${styles.mr2}`} />\n\t\t\t\t\t\t\t\t\t\t\tEdit Form\n\t\t\t\t\t\t\t\t\t\t</DropdownMenuItem>\n\t\t\t\t\t\t\t\t\t\t<DropdownMenuItem\n\t\t\t\t\t\t\t\t\t\t\tonClick={() => onDeleteForm(project.id, form.id)}\n\t\t\t\t\t\t\t\t\t\t\tclassName={styles.deleteItem}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\tDelete Form\n\t\t\t\t\t\t\t\t\t\t</DropdownMenuItem>\n\t\t\t\t\t\t\t\t\t</DropdownMenuContent>\n\t\t\t\t\t\t\t\t</DropdownMenu>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t))}\n\n\t\t\t\t\t\t<Separator className=\"my-3\" />\n\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\tonClick={onCreateForm}\n\t\t\t\t\t\t\tclassName={styles.addFormButton}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Plus className={`${styles.iconSm} ${styles.mr2}`} />\n\t\t\t\t\t\t\tAdd Form\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</div>\n\t\t\t\t</CardContent>\n\t\t\t)}\n\t\t</Card>\n\t);\n};\n","/**\n * useFormExplorerState - Hook for managing form explorer state\n */\n\nimport { initializeFormConfiguration } from \"../../../utils/configInitializer\";\nimport {\n\tclearScanCache,\n\tscanFormsDirectory,\n} from \"../../../utils/formsExplorer\";\nimport type { FormsExplorerState } from \"@formbuilder/core\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport type { FormConfig } from \"../../../config/types\";\n\nexport interface UseFormExplorerStateOptions {\n\tautoLoad?: boolean;\n\tconfig?: FormConfig;\n}\n\nexport interface UseFormExplorerStateReturn {\n\tstate: FormsExplorerState;\n\tsearchQuery: string;\n\tsetSearchQuery: (query: string) => void;\n\tfilteredProjects: FormsExplorerState[\"projects\"];\n\tloadProjects: () => Promise<void>;\n\tselectedProject: string | null;\n\tsetSelectedProject: (projectId: string | null) => void;\n\t// Real-time update functions\n\taddProjectOptimistic: (\n\t\tproject: Omit<FormsExplorerState[\"projects\"][0], \"lastModified\">\n\t) => void;\n\tremoveProjectOptimistic: (projectId: string) => void;\n\taddFormOptimistic: (\n\t\tprojectId: string,\n\t\tform: {\n\t\t\tid: string;\n\t\t\ttitle: string;\n\t\t\tdescription?: string;\n\t\t}\n\t) => void;\n\tremoveFormOptimistic: (projectId: string, formId: string) => void;\n\trefreshProjectsList: () => Promise<void>;\n\tinvalidateCache: () => void;\n}\n\nexport function useFormExplorerState({\n\tautoLoad = true,\n\tconfig,\n}: UseFormExplorerStateOptions = {}): UseFormExplorerStateReturn {\n\tconst [state, setState] = useState<FormsExplorerState>({\n\t\tprojects: [],\n\t\tisLoading: true,\n\t\terror: null,\n\t\tselectedProject: null,\n\t});\n\n\tconst [searchQuery, setSearchQuery] = useState(\"\");\n\n\t// Load projects function\n\tconst loadProjects = useCallback(async () => {\n\t\tconsole.log(\"🔄 loadProjects called - refreshing projects list...\");\n\t\tsetState((prev) => ({ ...prev, isLoading: true, error: null }));\n\n\t\ttry {\n\t\t\tconst operationsConfig = config ? { formConfig: config } : {};\n\t\t\tconsole.log(\"📋 Scanning forms directory with config:\", operationsConfig);\n\t\t\tconst index = await scanFormsDirectory(operationsConfig);\n\t\t\tconsole.log(\"📊 Scan result:\", {\n\t\t\t\tprojectCount: index.projects.length,\n\t\t\t\tprojects: index.projects.map((p) => p.name),\n\t\t\t});\n\t\t\tsetState((prev) => ({\n\t\t\t\t...prev,\n\t\t\t\tprojects: index.projects,\n\t\t\t\tisLoading: false,\n\t\t\t}));\n\t\t\tconsole.log(\"✅ Projects list updated in state\");\n\t\t} catch (error) {\n\t\t\tconsole.error(\"❌ Failed to load projects:\", error);\n\t\t\tsetState((prev) => ({\n\t\t\t\t...prev,\n\t\t\t\terror:\n\t\t\t\t\terror instanceof Error ? error.message : \"Failed to load projects\",\n\t\t\t\tisLoading: false,\n\t\t\t}));\n\t\t}\n\t}, [config]);\n\n\t// Initialize configuration and load projects on mount with optimizations\n\tuseEffect(() => {\n\t\tif (!autoLoad) return;\n\n\t\tlet isCancelled = false;\n\n\t\tconst initialize = async () => {\n\t\t\tif (isCancelled) return;\n\n\t\t\ttry {\n\t\t\t\t// Initialize form configuration service (fast, non-blocking)\n\t\t\t\tawait initializeFormConfiguration();\n\n\t\t\t\tif (isCancelled) return;\n\n\t\t\t\t// Load projects with timeout and error handling\n\t\t\t\tconst timeoutPromise = new Promise((_, reject) => {\n\t\t\t\t\tsetTimeout(\n\t\t\t\t\t\t() =>\n\t\t\t\t\t\t\treject(\n\t\t\t\t\t\t\t\tnew Error(\"Connection timeout - unable to connect to database\")\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t10000 // Increased to 10 seconds for database initialization\n\t\t\t\t\t);\n\t\t\t\t});\n\n\t\t\t\ttry {\n\t\t\t\t\tawait Promise.race([loadProjects(), timeoutPromise]);\n\t\t\t\t} catch (connectionError) {\n\t\t\t\t\tif (isCancelled) return;\n\t\t\t\t\tconsole.error(\"Failed to connect to storage:\", connectionError);\n\t\t\t\t\t// Show connection error with retry option\n\t\t\t\t\tsetState((prev) => ({\n\t\t\t\t\t\t...prev,\n\t\t\t\t\t\tprojects: [],\n\t\t\t\t\t\tisLoading: false,\n\t\t\t\t\t\terror:\n\t\t\t\t\t\t\t\"Failed to connect to database. Please check your connection and try again.\",\n\t\t\t\t\t}));\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (isCancelled) return;\n\t\t\t\tconsole.error(\"Failed to initialize FormExplorer:\", error);\n\n\t\t\t\t// Set a user-friendly error message\n\t\t\t\tsetState((prev) => ({\n\t\t\t\t\t...prev,\n\t\t\t\t\tprojects: [],\n\t\t\t\t\terror:\n\t\t\t\t\t\t\"Failed to initialize application. Please check your configuration and try again.\",\n\t\t\t\t\tisLoading: false,\n\t\t\t\t}));\n\t\t\t}\n\t\t};\n\n\t\t// Initialize immediately without delay for better performance\n\t\tinitialize();\n\n\t\t// Cleanup function\n\t\treturn () => {\n\t\t\tisCancelled = true;\n\t\t};\n\t}, [loadProjects, autoLoad]);\n\n\t// Filter projects and forms based on search query\n\tconst filteredProjects = state.projects.filter((project) => {\n\t\tif (!searchQuery) return true;\n\n\t\tconst query = searchQuery.toLowerCase();\n\t\treturn (\n\t\t\tproject.name.toLowerCase().includes(query) ||\n\t\t\tproject.forms.some(\n\t\t\t\t(form) =>\n\t\t\t\t\tform.title.toLowerCase().includes(query) ||\n\t\t\t\t\tform.id.toLowerCase().includes(query)\n\t\t\t)\n\t\t);\n\t});\n\n\tconst setSelectedProject = useCallback((projectId: string | null) => {\n\t\tsetState((prev) => ({ ...prev, selectedProject: projectId }));\n\t}, []);\n\n\t// Real-time update functions for immediate UI feedback\n\tconst addProjectOptimistic = useCallback(\n\t\t(project: Omit<FormsExplorerState[\"projects\"][0], \"lastModified\">) => {\n\t\t\tconsole.log(\"🚀 Adding project optimistically:\", project.name);\n\t\t\tsetState((prev) => ({\n\t\t\t\t...prev,\n\t\t\t\tprojects: [\n\t\t\t\t\t{\n\t\t\t\t\t\t...project,\n\t\t\t\t\t\tlastModified: Date.now(),\n\t\t\t\t\t},\n\t\t\t\t\t...prev.projects,\n\t\t\t\t],\n\t\t\t}));\n\t\t},\n\t\t[]\n\t);\n\n\tconst removeProjectOptimistic = useCallback((projectId: string) => {\n\t\tconsole.log(\"🗑️ Removing project optimistically:\", projectId);\n\t\tsetState((prev) => ({\n\t\t\t...prev,\n\t\t\tprojects: prev.projects.filter((p) => p.id !== projectId),\n\t\t}));\n\t}, []);\n\n\tconst addFormOptimistic = useCallback(\n\t\t(\n\t\t\tprojectId: string,\n\t\t\tform: {\n\t\t\t\tid: string;\n\t\t\t\ttitle: string;\n\t\t\t\tdescription?: string;\n\t\t\t}\n\t\t) => {\n\t\t\tconsole.log(\"🚀 Adding form optimistically:\", `${projectId}/${form.id}`);\n\t\t\tsetState((prev) => ({\n\t\t\t\t...prev,\n\t\t\t\tprojects: prev.projects.map((project) =>\n\t\t\t\t\tproject.id === projectId\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t...project,\n\t\t\t\t\t\t\t\tforms: [\n\t\t\t\t\t\t\t\t\t...project.forms,\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tid: form.id,\n\t\t\t\t\t\t\t\t\t\ttitle: form.title,\n\t\t\t\t\t\t\t\t\t\tfileName: `${form.id}.json`, // Required by FormMetadata interface\n\t\t\t\t\t\t\t\t\t\tdescription: form.description || \"\",\n\t\t\t\t\t\t\t\t\t\tlastModified: Date.now(),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: project\n\t\t\t\t),\n\t\t\t}));\n\t\t},\n\t\t[]\n\t);\n\n\tconst removeFormOptimistic = useCallback(\n\t\t(projectId: string, formId: string) => {\n\t\t\tconsole.log(\"🗑️ Removing form optimistically:\", `${projectId}/${formId}`);\n\t\t\tsetState((prev) => ({\n\t\t\t\t...prev,\n\t\t\t\tprojects: prev.projects.map((project) =>\n\t\t\t\t\tproject.id === projectId\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t...project,\n\t\t\t\t\t\t\t\tforms: project.forms.filter((form) => form.id !== formId),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: project\n\t\t\t\t),\n\t\t\t}));\n\t\t},\n\t\t[]\n\t);\n\n\tconst refreshProjectsList = useCallback(async () => {\n\t\tconsole.log(\"🔄 Refreshing projects list immediately...\");\n\t\t// Clear both local and global caches before refreshing\n\t\tclearScanCache();\n\t\t// This is an alias for loadProjects but more explicit about intent\n\t\tawait loadProjects();\n\t}, [loadProjects]);\n\n\tconst invalidateCache = useCallback(() => {\n\t\tconsole.log(\"🗑️ Invalidating cache - clearing scan cache\");\n\t\tclearScanCache();\n\t}, []);\n\n\treturn {\n\t\tstate,\n\t\tsearchQuery,\n\t\tsetSearchQuery,\n\t\tfilteredProjects,\n\t\tloadProjects,\n\t\tselectedProject: state.selectedProject,\n\t\tsetSelectedProject,\n\t\t// Real-time update functions\n\t\taddProjectOptimistic,\n\t\tremoveProjectOptimistic,\n\t\taddFormOptimistic,\n\t\tremoveFormOptimistic,\n\t\trefreshProjectsList,\n\t\tinvalidateCache,\n\t};\n}\n","/**\n * useFormOperations - Hook for form CRUD operations with config support\n */\n\nimport type { CreateFormRequest, FormWizardConfig } from \"@formbuilder/core\";\nimport { toast } from \"sonner\";\nimport { useCallback, useMemo } from \"react\";\nimport { useFormConfiguration } from \"../../../config/hooks\";\nimport {\n\tcreateForm,\n\tdeleteForm,\n\ttype FormOperationsConfig,\n\tloadFormConfigFromExplorer,\n\tsaveFormConfig,\n} from \"../../../utils/formsExplorer\";\n\nexport interface UseFormOperationsOptions {\n\tonFormLoad?: (\n\t\tprojectId: string,\n\t\twizardId: string\n\t) => Promise<FormWizardConfig>;\n\tonFormCreate?: (\n\t\tprojectId: string,\n\t\tformId: string,\n\t\ttitle: string\n\t) => Promise<FormWizardConfig | null>;\n\tonFormDelete?: (projectId: string, wizardId: string) => Promise<boolean>;\n\tonFormSave?: (\n\t\tprojectId: string,\n\t\twizardId: string,\n\t\tconfig: FormWizardConfig\n\t) => Promise<void>;\n\tonFormEdit?: (\n\t\tprojectId: string,\n\t\twizardId: string,\n\t\tconfig: FormWizardConfig\n\t) => void;\n\tonFormCreated?: (\n\t\tprojectId: string,\n\t\twizardId: string,\n\t\tconfig: FormWizardConfig\n\t) => void;\n\tonProjectsRefresh?: () => Promise<void>;\n}\n\nexport interface UseFormOperationsReturn {\n\thandleCreateForm: (\n\t\tprojectId: string,\n\t\tformTitle: string,\n\t\tformId?: string\n\t) => Promise<FormWizardConfig | null>;\n\thandleDeleteForm: (projectId: string, wizardId: string) => Promise<boolean>;\n\thandleEditForm: (projectId: string, wizardId: string) => Promise<void>;\n\thandleSaveForm: (\n\t\tprojectId: string,\n\t\twizardId: string,\n\t\tconfig: FormWizardConfig\n\t) => Promise<void>;\n}\n\nexport function useFormOperations({\n\tonFormLoad,\n\tonFormCreate,\n\tonFormDelete,\n\tonFormSave,\n\tonFormEdit,\n\tonFormCreated,\n\tonProjectsRefresh,\n}: UseFormOperationsOptions = {}): UseFormOperationsReturn {\n\t// Get configuration from context\n\tconst formConfig = useFormConfiguration();\n\n\t// Memoize operations config to ensure stable reference for useCallback dependencies\n\tconst operationsConfig: FormOperationsConfig = useMemo(\n\t\t() => ({\n\t\t\tformConfig,\n\t\t}),\n\t\t[formConfig]\n\t);\n\tconst handleCreateForm = useCallback(\n\t\tasync (\n\t\t\tprojectId: string,\n\t\t\tformTitle: string,\n\t\t\tformId?: string\n\t\t): Promise<FormWizardConfig | null> => {\n\t\t\tif (!formTitle.trim()) return null;\n\n\t\t\tconst finalFormId =\n\t\t\t\tformId ||\n\t\t\t\tformTitle\n\t\t\t\t\t.toLowerCase()\n\t\t\t\t\t.replace(/[^a-z0-9]/g, \"-\")\n\t\t\t\t\t.replace(/-+/g, \"-\")\n\t\t\t\t\t.replace(/^-|-$/g, \"\");\n\n\t\t\tlet config: FormWizardConfig | null = null;\n\n\t\t\ttry {\n\t\t\t\tif (onFormCreate) {\n\t\t\t\t\tconfig = await onFormCreate(projectId, finalFormId, formTitle);\n\t\t\t\t} else {\n\t\t\t\t\tconst request: CreateFormRequest = {\n\t\t\t\t\t\tprojectId,\n\t\t\t\t\t\tformId: finalFormId,\n\t\t\t\t\t\ttitle: formTitle,\n\t\t\t\t\t};\n\t\t\t\t\tconfig = await createForm(request, operationsConfig);\n\t\t\t\t}\n\n\t\t\t\tif (config) {\n\t\t\t\t\ttoast.success(`Form \"${formTitle}\" created successfully`);\n\t\t\t\t\tawait onProjectsRefresh?.();\n\t\t\t\t\tonFormCreated?.(projectId, finalFormId, config);\n\t\t\t\t} else {\n\t\t\t\t\ttoast.error(\"Failed to create form\");\n\t\t\t\t}\n\n\t\t\t\treturn config;\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Failed to create form:\", error);\n\t\t\t\ttoast.error(\n\t\t\t\t\terror instanceof Error ? error.message : \"Failed to create form\",\n\t\t\t\t);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t},\n\t\t[onFormCreate, onFormCreated, onProjectsRefresh, operationsConfig]\n\t);\n\n\tconst handleDeleteForm = useCallback(\n\t\tasync (projectId: string, wizardId: string): Promise<boolean> => {\n\t\t\ttry {\n\t\t\t\tlet success = false;\n\n\t\t\t\tif (onFormDelete) {\n\t\t\t\t\tsuccess = await onFormDelete(projectId, wizardId);\n\t\t\t\t} else {\n\t\t\t\t\tsuccess = await deleteForm(projectId, wizardId, operationsConfig);\n\t\t\t\t}\n\n\t\t\t\tif (success) {\n\t\t\t\t\ttoast.success(\"Form deleted successfully\");\n\t\t\t\t\tawait onProjectsRefresh?.();\n\t\t\t\t} else {\n\t\t\t\t\ttoast.error(\"Failed to delete form\");\n\t\t\t\t}\n\n\t\t\t\treturn success;\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Failed to delete form:\", error);\n\t\t\t\ttoast.error(\n\t\t\t\t\terror instanceof Error ? error.message : \"Failed to delete form\",\n\t\t\t\t);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\t[onFormDelete, onProjectsRefresh, operationsConfig]\n\t);\n\n\tconst handleEditForm = useCallback(\n\t\tasync (projectId: string, wizardId: string): Promise<void> => {\n\t\t\ttry {\n\t\t\t\tlet config: FormWizardConfig | null = null;\n\n\t\t\t\tif (onFormLoad) {\n\t\t\t\t\tconfig = await onFormLoad(projectId, wizardId);\n\t\t\t\t} else {\n\t\t\t\t\tconfig = await loadFormConfigFromExplorer(\n\t\t\t\t\t\tprojectId,\n\t\t\t\t\t\twizardId,\n\t\t\t\t\t\toperationsConfig\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (config) {\n\t\t\t\t\tif (onFormEdit) {\n\t\t\t\t\t\t// Use external handler if provided\n\t\t\t\t\t\tonFormEdit(projectId, wizardId, config);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\ttoast.error(\"Failed to load form configuration\");\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Failed to load form for editing:\", error);\n\t\t\t\ttoast.error(\n\t\t\t\t\terror instanceof Error\n\t\t\t\t\t\t? error.message\n\t\t\t\t\t\t: \"Failed to load form configuration\",\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t\t[onFormLoad, onFormEdit, operationsConfig]\n\t);\n\n\tconst handleSaveForm = useCallback(\n\t\tasync (\n\t\t\tprojectId: string,\n\t\t\twizardId: string,\n\t\t\tconfig: FormWizardConfig\n\t\t): Promise<void> => {\n\t\t\ttry {\n\t\t\t\tif (onFormSave) {\n\t\t\t\t\tawait onFormSave(projectId, wizardId, config);\n\t\t\t\t} else {\n\t\t\t\t\tconst success = await saveFormConfig(\n\t\t\t\t\t\tprojectId,\n\t\t\t\t\t\twizardId,\n\t\t\t\t\t\tconfig,\n\t\t\t\t\t\toperationsConfig\n\t\t\t\t\t);\n\t\t\t\t\tif (!success) {\n\t\t\t\t\t\tthrow new Error(\"Failed to save form configuration\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Failed to save form:\", error);\n\t\t\t\tthrow error; // Re-throw to let caller handle the error display\n\t\t\t}\n\t\t},\n\t\t[onFormSave, operationsConfig]\n\t);\n\n\treturn {\n\t\thandleCreateForm,\n\t\thandleDeleteForm,\n\t\thandleEditForm,\n\t\thandleSaveForm,\n\t};\n}\n","/**\n * useProjectOperations - Hook for project operations\n */\n\nimport { createProject } from \"../../../utils/formsExplorer\";\nimport { toast } from \"sonner\";\nimport { useCallback } from \"react\";\n\nexport interface UseProjectOperationsOptions {\n\tonProjectsRefresh?: () => Promise<void>;\n}\n\nexport interface UseProjectOperationsReturn {\n\thandleCreateProject: (\n\t\tprojectName: string,\n\t\tdescription?: string\n\t) => Promise<boolean>;\n}\n\nexport function useProjectOperations({\n\tonProjectsRefresh,\n}: UseProjectOperationsOptions = {}): UseProjectOperationsReturn {\n\tconst handleCreateProject = useCallback(\n\t\tasync (projectName: string, description?: string): Promise<boolean> => {\n\t\t\tif (!projectName.trim()) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\t// Use the existing createProject function from formsExplorer.ts\n\t\t\t\t// which internally handles storage strategy determination\n\t\t\t\tconst result = await createProject({\n\t\t\t\t\tname: projectName.trim(),\n\t\t\t\t\tdescription: description?.trim() || undefined,\n\t\t\t\t});\n\n\t\t\t\tif (result.success) {\n\t\t\t\t\ttoast.success(`Project \"${projectName}\" created successfully`);\n\n\t\t\t\t\t// Refresh projects list after successful creation\n\t\t\t\t\tawait onProjectsRefresh?.();\n\t\t\t\t\treturn true;\n\t\t\t\t} else {\n\t\t\t\t\ttoast.error(\"Failed to create project\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Failed to create project:\", error);\n\t\t\t\ttoast.error(\n\t\t\t\t\terror instanceof Error ? error.message : \"Failed to create project\",\n\t\t\t\t);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\t[onProjectsRefresh]\n\t);\n\n\treturn {\n\t\thandleCreateProject,\n\t};\n}\n","import { useEffect, useState } from \"react\";\nimport {\n\ttype ProviderCapabilities,\n\tStorageProviderFactory,\n} from \"../../storage/StorageProviderFactory\";\nimport styles from \"./DatabaseStatusIndicator.module.css\";\n\ninterface SyncStatus {\n\tonline: boolean;\n\tconnected: boolean;\n\tconnectionStatus: \"connected\" | \"disconnected\" | \"connecting\" | \"retrying\";\n\tlastSync: string | null;\n\tsyncing: boolean;\n\tretryCount?: number;\n\tmaxRetries?: number;\n\tlastConnectionError?: string | null;\n\tpendingOperations?: number;\n\treconciling?: boolean;\n\tintegrityStatus?: \"consistent\" | \"inconsistent\" | \"unknown\";\n}\n\ninterface DatabaseStatusIndicatorProps {\n\tclassName?: string;\n\tgetSyncStatus?: () => SyncStatus;\n\tonForceSync?: () => Promise<void>;\n\tonReconnect?: () => Promise<boolean>;\n\tonValidateConsistency?: () => Promise<boolean>;\n\tonResetLocalData?: () => Promise<boolean>;\n\tonReconcileConflicts?: () => Promise<boolean>;\n}\n\nexport const DatabaseStatusIndicator = ({\n\tclassName = \"\",\n\tgetSyncStatus,\n\tonForceSync,\n\tonReconnect,\n\tonValidateConsistency,\n\tonResetLocalData,\n\tonReconcileConflicts,\n}: DatabaseStatusIndicatorProps) => {\n\tconst [capabilities, setCapabilities] = useState<ProviderCapabilities | null>(\n\t\tnull\n\t);\n\tconst [syncStatus, setSyncStatus] = useState<SyncStatus>({\n\t\tonline: navigator.onLine,\n\t\tconnected: false,\n\t\tconnectionStatus: \"disconnected\",\n\t\tlastSync: null,\n\t\tsyncing: false,\n\t\tretryCount: 0,\n\t\tmaxRetries: 5,\n\t\tlastConnectionError: null,\n\t\tpendingOperations: 0,\n\t\treconciling: false,\n\t\tintegrityStatus: \"unknown\",\n\t});\n\tconst [showDetails, setShowDetails] = useState(false);\n\n\tuseEffect(() => {\n\t\tconst updateCapabilities = () => {\n\t\t\tconst factory = StorageProviderFactory.getInstance();\n\t\t\tconst providerCapabilities = factory.getProviderCapabilities();\n\t\t\tconsole.log(\n\t\t\t\t\"🔍 DatabaseStatusIndicator capabilities:\",\n\t\t\t\tproviderCapabilities\n\t\t\t);\n\t\t\tsetCapabilities(providerCapabilities);\n\t\t};\n\n\t\t// Initial check\n\t\tupdateCapabilities();\n\n\t\t// Listen for storage provider ready event\n\t\tconst handleProviderReady = (event: CustomEvent) => {\n\t\t\tconsole.log(\"🎉 Storage provider ready:\", event.detail);\n\t\t\tupdateCapabilities();\n\t\t};\n\n\t\twindow.addEventListener(\n\t\t\t\"storageProviderReady\",\n\t\t\thandleProviderReady as EventListener\n\t\t);\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\n\t\t\t\t\"storageProviderReady\",\n\t\t\t\thandleProviderReady as EventListener\n\t\t\t);\n\t\t};\n\t}, []);\n\n\tuseEffect(() => {\n\t\t// Update online status\n\t\tconst handleOnline = () =>\n\t\t\tsetSyncStatus((prev) => ({ ...prev, online: true }));\n\t\tconst handleOffline = () =>\n\t\t\tsetSyncStatus((prev) => ({ ...prev, online: false }));\n\n\t\twindow.addEventListener(\"online\", handleOnline);\n\t\twindow.addEventListener(\"offline\", handleOffline);\n\n\t\t// Poll for sync status if function provided\n\t\tlet interval: NodeJS.Timeout;\n\t\tif (getSyncStatus) {\n\t\t\tinterval = setInterval(() => {\n\t\t\t\ttry {\n\t\t\t\t\tconst currentStatus = getSyncStatus();\n\t\t\t\t\tsetSyncStatus(currentStatus);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error(\"Failed to get sync status:\", error);\n\t\t\t\t}\n\t\t\t}, 1000);\n\t\t}\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"online\", handleOnline);\n\t\t\twindow.removeEventListener(\"offline\", handleOffline);\n\t\t\tif (interval) clearInterval(interval);\n\t\t};\n\t}, [getSyncStatus]);\n\n\tconst handleForceSync = async () => {\n\t\tif (onForceSync && !syncStatus.syncing) {\n\t\t\ttry {\n\t\t\t\tsetSyncStatus((prev) => ({ ...prev, syncing: true }));\n\t\t\t\tawait onForceSync();\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Force sync failed:\", error);\n\t\t\t} finally {\n\t\t\t\tsetSyncStatus((prev) => ({ ...prev, syncing: false }));\n\t\t\t}\n\t\t}\n\t};\n\n\tconst handleReconnect = async () => {\n\t\tif (\n\t\t\tonReconnect &&\n\t\t\t!syncStatus.syncing &&\n\t\t\tsyncStatus.connectionStatus !== \"connecting\"\n\t\t) {\n\t\t\ttry {\n\t\t\t\tsetSyncStatus((prev) => ({ ...prev, syncing: true }));\n\t\t\t\tconst success = await onReconnect();\n\t\t\t\tif (success) {\n\t\t\t\t\tconsole.log(\"Manual reconnection successful\");\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Manual reconnection failed:\", error);\n\t\t\t} finally {\n\t\t\t\tsetSyncStatus((prev) => ({ ...prev, syncing: false }));\n\t\t\t}\n\t\t}\n\t};\n\n\tconst handleValidateConsistency = async () => {\n\t\tif (onValidateConsistency && !syncStatus.reconciling) {\n\t\t\ttry {\n\t\t\t\tsetSyncStatus((prev) => ({ ...prev, reconciling: true }));\n\t\t\t\tconst isConsistent = await onValidateConsistency();\n\t\t\t\tconsole.log(\n\t\t\t\t\t`Data consistency validation: ${isConsistent ? \"consistent\" : \"inconsistent\"}`\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Data consistency validation failed:\", error);\n\t\t\t} finally {\n\t\t\t\tsetSyncStatus((prev) => ({ ...prev, reconciling: false }));\n\t\t\t}\n\t\t}\n\t};\n\n\tconst handleResetLocalData = async () => {\n\t\tif (\n\t\t\tonResetLocalData &&\n\t\t\t!syncStatus.reconciling &&\n\t\t\tconfirm(\n\t\t\t\t\"Are you sure you want to reset all local data? This will reload everything from the remote database.\"\n\t\t\t)\n\t\t) {\n\t\t\ttry {\n\t\t\t\tsetSyncStatus((prev) => ({ ...prev, reconciling: true }));\n\t\t\t\tconst success = await onResetLocalData();\n\t\t\t\tif (success) {\n\t\t\t\t\tconsole.log(\"Local data reset successful\");\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Local data reset failed:\", error);\n\t\t\t} finally {\n\t\t\t\tsetSyncStatus((prev) => ({ ...prev, reconciling: false }));\n\t\t\t}\n\t\t}\n\t};\n\n\tconst handleReconcileConflicts = async () => {\n\t\tif (onReconcileConflicts && !syncStatus.reconciling) {\n\t\t\ttry {\n\t\t\t\tsetSyncStatus((prev) => ({ ...prev, reconciling: true }));\n\t\t\t\tconst success = await onReconcileConflicts();\n\t\t\t\tif (success) {\n\t\t\t\t\tconsole.log(\"Data conflict reconciliation successful\");\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Data conflict reconciliation failed:\", error);\n\t\t\t} finally {\n\t\t\t\tsetSyncStatus((prev) => ({ ...prev, reconciling: false }));\n\t\t\t}\n\t\t}\n\t};\n\n\tconst getStatusConfig = () => {\n\t\t// If sync status is available, prioritize sync information\n\t\tif (getSyncStatus) {\n\t\t\tif (syncStatus.reconciling) {\n\t\t\t\treturn {\n\t\t\t\t\tcolorClass: styles.statusPurple,\n\t\t\t\t\ttitle: \"Reconciling Data...\",\n\t\t\t\t\ticon: \"🔄\",\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (syncStatus.syncing) {\n\t\t\t\treturn {\n\t\t\t\t\tcolorClass: styles.statusLoading,\n\t\t\t\t\ttitle: \"Syncing...\",\n\t\t\t\t\ticon: \"🔄\",\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (!syncStatus.online) {\n\t\t\t\treturn {\n\t\t\t\t\tcolorClass: styles.statusOffline,\n\t\t\t\t\ttitle: \"Offline\",\n\t\t\t\t\ticon: \"📴\",\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (syncStatus.connectionStatus === \"connecting\") {\n\t\t\t\treturn {\n\t\t\t\t\tcolorClass: styles.statusOrange,\n\t\t\t\t\ttitle: \"Connecting...\",\n\t\t\t\t\ticon: \"🔌\",\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (syncStatus.connectionStatus === \"retrying\") {\n\t\t\t\treturn {\n\t\t\t\t\tcolorClass: styles.statusOrange,\n\t\t\t\t\ttitle: `Retrying (${syncStatus.retryCount}/${syncStatus.maxRetries})`,\n\t\t\t\t\ticon: \"🔄\",\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (!syncStatus.connected) {\n\t\t\t\treturn {\n\t\t\t\t\tcolorClass: styles.statusWarning,\n\t\t\t\t\ttitle: \"Sync Disabled\",\n\t\t\t\t\ticon: \"⚠️\",\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (syncStatus.integrityStatus === \"inconsistent\") {\n\t\t\t\treturn {\n\t\t\t\t\tcolorClass: styles.statusError,\n\t\t\t\t\ttitle: \"Data Inconsistent\",\n\t\t\t\t\ticon: \"⚠️\",\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tcolorClass: styles.statusConnected,\n\t\t\t\ttitle: \"Synced\",\n\t\t\t\ticon: \"✅\",\n\t\t\t};\n\t\t}\n\n\t\t// Fallback to capabilities-based status\n\t\tif (!capabilities) {\n\t\t\treturn {\n\t\t\t\tcolorClass: styles.statusError,\n\t\t\t\ttitle: \"Database Not Available\",\n\t\t\t\ticon: \"❌\",\n\t\t\t};\n\t\t}\n\n\t\tif (capabilities.isLive) {\n\t\t\treturn {\n\t\t\t\tcolorClass: styles.statusConnected,\n\t\t\t\ttitle: \"Database Connected (Live)\",\n\t\t\t\ticon: \"✅\",\n\t\t\t};\n\t\t}\n\n\t\tif (capabilities.hasSync) {\n\t\t\treturn {\n\t\t\t\tcolorClass: styles.statusConnected,\n\t\t\t\ttitle: \"Database Connected (Sync)\",\n\t\t\t\ticon: \"🔄\",\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tcolorClass: styles.statusError,\n\t\t\ttitle: \"Database Offline\",\n\t\t\ticon: \"❌\",\n\t\t};\n\t};\n\n\tconst formatLastSync = (timestamp: string | null) => {\n\t\tif (!timestamp) return \"Never\";\n\n\t\tconst date = new Date(timestamp);\n\t\tconst now = new Date();\n\t\tconst diff = now.getTime() - date.getTime();\n\n\t\tif (diff < 60000) {\n\t\t\treturn \"Just now\";\n\t\t} else if (diff < 3600000) {\n\t\t\treturn `${Math.floor(diff / 60000)}m ago`;\n\t\t} else if (diff < 86400000) {\n\t\t\treturn `${Math.floor(diff / 3600000)}h ago`;\n\t\t} else {\n\t\t\treturn date.toLocaleDateString();\n\t\t}\n\t};\n\n\tconst config = getStatusConfig();\n\n\tconst getDatabaseValueClass = () => {\n\t\tif (capabilities?.isLive || capabilities?.hasSync) return styles.detailValueConnected;\n\t\treturn styles.detailValueError;\n\t};\n\n\tconst getPersistenceValueClass = () => {\n\t\tif (capabilities?.isLive) return styles.detailValueConnected;\n\t\tif (capabilities?.hasSync) return styles.detailValueWarning;\n\t\treturn styles.detailValueMuted;\n\t};\n\n\tconst getIntegrityValueClass = () => {\n\t\tif (syncStatus.integrityStatus === \"consistent\") return styles.detailValueConnected;\n\t\tif (syncStatus.integrityStatus === \"inconsistent\") return styles.detailValueError;\n\t\treturn styles.detailValueMuted;\n\t};\n\n\treturn (\n\t\t<div className={`${styles.wrapper} ${className}`}>\n\t\t\t{/* Status Indicator */}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tonClick={() => setShowDetails(!showDetails)}\n\t\t\t\tclassName={`${styles.statusDot} ${config.colorClass}`}\n\t\t\t\ttitle={config.title}\n\t\t\t/>\n\n\t\t\t{/* Detailed Status Popover */}\n\t\t\t{showDetails && (\n\t\t\t\t<div className={styles.popover}>\n\t\t\t\t\t<div className={styles.popoverContent}>\n\t\t\t\t\t\t<div className={styles.popoverHeader}>\n\t\t\t\t\t\t\t<h3 className={styles.popoverTitle}>Database Status</h3>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tonClick={() => setShowDetails(false)}\n\t\t\t\t\t\t\t\tclassName={styles.closeButton}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t✕\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<div className={styles.detailsList}>\n\t\t\t\t\t\t\t{/* Database Connection Status */}\n\t\t\t\t\t\t\t<div className={styles.detailRow}>\n\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Database:</span>\n\t\t\t\t\t\t\t\t<span className={getDatabaseValueClass()}>\n\t\t\t\t\t\t\t\t\t{capabilities?.isLive\n\t\t\t\t\t\t\t\t\t\t? \"Connected (Live)\"\n\t\t\t\t\t\t\t\t\t\t: capabilities?.hasSync\n\t\t\t\t\t\t\t\t\t\t\t? \"Connected (Sync)\"\n\t\t\t\t\t\t\t\t\t\t\t: \"Offline/Local\"}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t{/* Provider Type */}\n\t\t\t\t\t\t\t<div className={styles.detailRow}>\n\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Provider:</span>\n\t\t\t\t\t\t\t\t<span className={styles.detailValue}>\n\t\t\t\t\t\t\t\t\t{capabilities?.isLive\n\t\t\t\t\t\t\t\t\t\t? \"Supabase PostgreSQL\"\n\t\t\t\t\t\t\t\t\t\t: \"PgLite (Local)\"}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t{/* Data Persistence */}\n\t\t\t\t\t\t\t<div className={styles.detailRow}>\n\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Data Persistence:</span>\n\t\t\t\t\t\t\t\t<span className={getPersistenceValueClass()}>\n\t\t\t\t\t\t\t\t\t{capabilities?.isLive\n\t\t\t\t\t\t\t\t\t\t? \"Direct to Database\"\n\t\t\t\t\t\t\t\t\t\t: capabilities?.hasSync\n\t\t\t\t\t\t\t\t\t\t\t? \"Local with Sync\"\n\t\t\t\t\t\t\t\t\t\t\t: \"Local Only\"}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t{/* Network Status (if sync is available) */}\n\t\t\t\t\t\t\t{getSyncStatus && (\n\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t<div className={styles.detailRow}>\n\t\t\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Network:</span>\n\t\t\t\t\t\t\t\t\t\t<span className={syncStatus.online ? styles.detailValueConnected : styles.detailValueError}>\n\t\t\t\t\t\t\t\t\t\t\t{syncStatus.online ? \"Online\" : \"Offline\"}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t\t\t<div className={styles.detailRow}>\n\t\t\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Sync Status:</span>\n\t\t\t\t\t\t\t\t\t\t<span className={syncStatus.connected ? styles.detailValueConnected : styles.detailValueMuted}>\n\t\t\t\t\t\t\t\t\t\t\t{syncStatus.connected ? \"Connected\" : \"Disabled\"}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t\t\t<div className={styles.detailRow}>\n\t\t\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Last Sync:</span>\n\t\t\t\t\t\t\t\t\t\t<span className={styles.detailValue}>\n\t\t\t\t\t\t\t\t\t\t\t{formatLastSync(syncStatus.lastSync)}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t\t\t{/* Data Integrity Status */}\n\t\t\t\t\t\t\t\t\t<div className={styles.detailRow}>\n\t\t\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Data Integrity:</span>\n\t\t\t\t\t\t\t\t\t\t<span className={getIntegrityValueClass()}>\n\t\t\t\t\t\t\t\t\t\t\t{syncStatus.integrityStatus === \"consistent\"\n\t\t\t\t\t\t\t\t\t\t\t\t? \"Consistent\"\n\t\t\t\t\t\t\t\t\t\t\t\t: syncStatus.integrityStatus === \"inconsistent\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t? \"Inconsistent\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t: \"Unknown\"}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t\t\t\t{/* Reconciliation Status */}\n\t\t\t\t\t\t\t\t\t{syncStatus.reconciling && (\n\t\t\t\t\t\t\t\t\t\t<div className={styles.detailRow}>\n\t\t\t\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Status:</span>\n\t\t\t\t\t\t\t\t\t\t\t<span className={styles.detailValuePurple}>Reconciling...</span>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t\t\t{/* Connection Details */}\n\t\t\t\t\t\t\t\t\t{(syncStatus.connectionStatus === \"retrying\" ||\n\t\t\t\t\t\t\t\t\t\tsyncStatus.lastConnectionError) && (\n\t\t\t\t\t\t\t\t\t\t<div className={styles.dividerSection}>\n\t\t\t\t\t\t\t\t\t\t\t{syncStatus.connectionStatus === \"retrying\" && (\n\t\t\t\t\t\t\t\t\t\t\t\t<div className={styles.retryRow}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Retry:</span>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<span className={styles.detailValueOrange}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{syncStatus.retryCount}/{syncStatus.maxRetries}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t\t\t\t\t{syncStatus.lastConnectionError && (\n\t\t\t\t\t\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div className={styles.errorLabel}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tLast Error:\n\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<div className={styles.errorBox}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{syncStatus.lastConnectionError.length > 100\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? `${syncStatus.lastConnectionError.substring(0, 100)}...`\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: syncStatus.lastConnectionError}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t\t\t{/* Pending Operations */}\n\t\t\t\t\t\t\t\t\t{(syncStatus.pendingOperations ?? 0) > 0 && (\n\t\t\t\t\t\t\t\t\t\t<div className={styles.detailRow}>\n\t\t\t\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Pending:</span>\n\t\t\t\t\t\t\t\t\t\t\t<span className={styles.detailValueBlue}>\n\t\t\t\t\t\t\t\t\t\t\t\t{syncStatus.pendingOperations} operations\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t{/* Actions (if sync functions are available) */}\n\t\t\t\t\t\t{(onForceSync ||\n\t\t\t\t\t\t\tonReconnect ||\n\t\t\t\t\t\t\tonValidateConsistency ||\n\t\t\t\t\t\t\tonResetLocalData ||\n\t\t\t\t\t\t\tonReconcileConflicts) && (\n\t\t\t\t\t\t\t<div className={styles.actionsSection}>\n\t\t\t\t\t\t\t\t{syncStatus.connected && onForceSync && (\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tonClick={handleForceSync}\n\t\t\t\t\t\t\t\t\t\tdisabled={syncStatus.syncing || syncStatus.reconciling}\n\t\t\t\t\t\t\t\t\t\tclassName={`${styles.actionButton} ${styles.actionButtonBlue}`}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{syncStatus.syncing ? \"Syncing...\" : \"Force Sync\"}\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t\t{!syncStatus.connected && onReconnect && (\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tonClick={handleReconnect}\n\t\t\t\t\t\t\t\t\t\tdisabled={\n\t\t\t\t\t\t\t\t\t\t\tsyncStatus.syncing ||\n\t\t\t\t\t\t\t\t\t\t\tsyncStatus.reconciling ||\n\t\t\t\t\t\t\t\t\t\t\tsyncStatus.connectionStatus === \"connecting\"\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tclassName={`${styles.actionButton} ${styles.actionButtonOrange}`}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{syncStatus.syncing ? \"Reconnecting...\" : \"Reconnect\"}\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t\t{/* Data Consistency Actions */}\n\t\t\t\t\t\t\t\t{syncStatus.connected && onValidateConsistency && (\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tonClick={handleValidateConsistency}\n\t\t\t\t\t\t\t\t\t\tdisabled={syncStatus.syncing || syncStatus.reconciling}\n\t\t\t\t\t\t\t\t\t\tclassName={`${styles.actionButton} ${styles.actionButtonGreen}`}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{syncStatus.reconciling ? \"Validating...\" : \"Validate Data\"}\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t\t{syncStatus.connected &&\n\t\t\t\t\t\t\t\t\tsyncStatus.integrityStatus === \"inconsistent\" &&\n\t\t\t\t\t\t\t\t\tonReconcileConflicts && (\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tonClick={handleReconcileConflicts}\n\t\t\t\t\t\t\t\t\t\t\tdisabled={syncStatus.syncing || syncStatus.reconciling}\n\t\t\t\t\t\t\t\t\t\t\tclassName={`${styles.actionButton} ${styles.actionButtonPurple}`}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t{syncStatus.reconciling\n\t\t\t\t\t\t\t\t\t\t\t\t? \"Reconciling...\"\n\t\t\t\t\t\t\t\t\t\t\t\t: \"Fix Data Issues\"}\n\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t\t\t{syncStatus.connected && onResetLocalData && (\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tonClick={handleResetLocalData}\n\t\t\t\t\t\t\t\t\t\tdisabled={syncStatus.syncing || syncStatus.reconciling}\n\t\t\t\t\t\t\t\t\t\tclassName={`${styles.actionButton} ${styles.actionButtonRed}`}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{syncStatus.reconciling\n\t\t\t\t\t\t\t\t\t\t\t? \"Resetting...\"\n\t\t\t\t\t\t\t\t\t\t\t: \"Reset Local Data\"}\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\n\t\t\t\t\t\t{/* Additional Info */}\n\t\t\t\t\t\t<div className={styles.storageInfo}>\n\t\t\t\t\t\t\t<div className={styles.storageInfoTitle}>Storage Info:</div>\n\t\t\t\t\t\t\t<div>Local: PgLite (In-Browser)</div>\n\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\tRemote:{\" \"}\n\t\t\t\t\t\t\t\t{capabilities?.isLive\n\t\t\t\t\t\t\t\t\t? \"Supabase PostgreSQL\"\n\t\t\t\t\t\t\t\t\t: capabilities?.hasSync\n\t\t\t\t\t\t\t\t\t\t? \"Connected (Sync)\"\n\t\t\t\t\t\t\t\t\t\t: \"Unavailable\"}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{syncStatus.connectionStatus === \"retrying\" && (\n\t\t\t\t\t\t\t\t<div className={styles.storageInfoNoteOrange}>\n\t\t\t\t\t\t\t\t\tAuto-retry enabled with exponential backoff\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{syncStatus.reconciling && (\n\t\t\t\t\t\t\t\t<div className={styles.storageInfoNotePurple}>\n\t\t\t\t\t\t\t\t\tData reconciliation in progress...\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{syncStatus.integrityStatus === \"inconsistent\" &&\n\t\t\t\t\t\t\t\t!syncStatus.reconciling && (\n\t\t\t\t\t\t\t\t\t<div className={styles.storageInfoNoteError}>\n\t\t\t\t\t\t\t\t\t\tData inconsistency detected - reconciliation recommended\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n};\n","/**\n * ConnectionErrorScreen - Shows when database is not available\n * Blocks UI to prevent user actions that won't work without database connection\n */\n\nimport { AlertTriangle, RefreshCw, Wifi, WifiOff } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport {\n\ttype ProviderCapabilities,\n\tStorageProviderFactory,\n} from \"../../storage/StorageProviderFactory\";\nimport styles from \"./ConnectionErrorScreen.module.css\";\n\ninterface ConnectionErrorScreenProps {\n\tonRetry?: () => void;\n\tclassName?: string;\n}\n\nexport const ConnectionErrorScreen: React.FC<ConnectionErrorScreenProps> = ({\n\tonRetry,\n\tclassName = \"\",\n}) => {\n\tconst [capabilities, setCapabilities] = useState<ProviderCapabilities | null>(\n\t\tnull\n\t);\n\tconst [isRetrying, setIsRetrying] = useState(false);\n\n\tuseEffect(() => {\n\t\tconst updateCapabilities = () => {\n\t\t\tconst factory = StorageProviderFactory.getInstance();\n\t\t\tconst providerCapabilities = factory.getProviderCapabilities();\n\t\t\tsetCapabilities(providerCapabilities);\n\t\t};\n\n\t\t// Initial check\n\t\tupdateCapabilities();\n\n\t\t// Listen for storage provider ready event\n\t\tconst handleProviderReady = (event: CustomEvent) => {\n\t\t\tconsole.log(\"🎉 Storage provider ready:\", event.detail);\n\t\t\tupdateCapabilities();\n\t\t};\n\n\t\twindow.addEventListener(\n\t\t\t\"storageProviderReady\",\n\t\t\thandleProviderReady as EventListener\n\t\t);\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\n\t\t\t\t\"storageProviderReady\",\n\t\t\t\thandleProviderReady as EventListener\n\t\t\t);\n\t\t};\n\t}, []);\n\n\tconst handleRetry = async () => {\n\t\tsetIsRetrying(true);\n\t\ttry {\n\t\t\tif (onRetry) {\n\t\t\t\tawait onRetry();\n\t\t\t} else {\n\t\t\t\t// Default retry - reload the page\n\t\t\t\twindow.location.reload();\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(\"Retry failed:\", error);\n\t\t} finally {\n\t\t\tsetIsRetrying(false);\n\t\t}\n\t};\n\n\tconst getErrorInfo = () => {\n\t\tif (!capabilities) {\n\t\t\treturn {\n\t\t\t\ttitle: \"Database Connection Required\",\n\t\t\t\tdescription:\n\t\t\t\t\t\"The application is still initializing. Please wait a moment...\",\n\t\t\t\ticon: <RefreshCw className={`${styles.icon4xl} ${styles.iconWarning} ${styles.spinAnimation}`} />,\n\t\t\t\tactionText: \"Initializing...\",\n\t\t\t\tshowRetry: false,\n\t\t\t};\n\t\t}\n\n\t\t// Filesystem strategy should never show connection errors\n\t\tif (capabilities.strategy === \"filesystem\") {\n\t\t\treturn null; // Filesystem strategy doesn't need database connection\n\t\t}\n\n\t\tif (!capabilities.isLive && !capabilities.hasSync) {\n\t\t\treturn {\n\t\t\t\ttitle: \"Database Connection Unavailable\",\n\t\t\t\tdescription:\n\t\t\t\t\t\"This application requires a database connection to create and manage projects. Without a connection, your work cannot be saved.\",\n\t\t\t\ticon: <WifiOff className={`${styles.icon4xl} ${styles.iconNegative}`} />,\n\t\t\t\tactionText: \"Retry Connection\",\n\t\t\t\tshowRetry: true,\n\t\t\t};\n\t\t}\n\n\t\tif (!capabilities.isLive && capabilities.hasSync) {\n\t\t\treturn {\n\t\t\t\ttitle: \"Working Offline\",\n\t\t\t\tdescription:\n\t\t\t\t\t\"You're currently working in offline mode. Your changes will sync when connection is restored.\",\n\t\t\t\ticon: <Wifi className={`${styles.icon4xl} ${styles.iconWarningHover}`} />,\n\t\t\t\tactionText: \"Try to Connect\",\n\t\t\t\tshowRetry: true,\n\t\t\t};\n\t\t}\n\n\t\treturn null; // Connection is fine\n\t};\n\n\tconst errorInfo = getErrorInfo();\n\n\tif (!errorInfo) {\n\t\treturn null; // No error, don't show this screen\n\t}\n\n\tconst getStatusValueClass = () => {\n\t\tif (capabilities?.isLive) return styles.detailValueConnected;\n\t\tif (capabilities?.hasSync) return styles.detailValueOffline;\n\t\treturn styles.detailValueError;\n\t};\n\n\treturn (\n\t\t<div className={`${styles.container} ${className}`}>\n\t\t\t<div className={styles.card}>\n\t\t\t\t{/* Icon */}\n\t\t\t\t<div className={styles.iconWrapper}>{errorInfo.icon}</div>\n\n\t\t\t\t{/* Title */}\n\t\t\t\t<h1 className={styles.title}>\n\t\t\t\t\t{errorInfo.title}\n\t\t\t\t</h1>\n\n\t\t\t\t{/* Description */}\n\t\t\t\t<p className={styles.description}>\n\t\t\t\t\t{errorInfo.description}\n\t\t\t\t</p>\n\n\t\t\t\t{/* Connection Details */}\n\t\t\t\t{capabilities && (\n\t\t\t\t\t<div className={styles.detailsPanel}>\n\t\t\t\t\t\t<div className={styles.detailsList}>\n\t\t\t\t\t\t\t<div className={styles.detailRow}>\n\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Provider:</span>\n\t\t\t\t\t\t\t\t<span className={styles.detailValue}>\n\t\t\t\t\t\t\t\t\t{capabilities.isLive\n\t\t\t\t\t\t\t\t\t\t? \"Supabase PostgreSQL\"\n\t\t\t\t\t\t\t\t\t\t: capabilities.hasSync\n\t\t\t\t\t\t\t\t\t\t\t? \"PgLite with Sync\"\n\t\t\t\t\t\t\t\t\t\t\t: \"PgLite (Local Only)\"}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div className={styles.detailRow}>\n\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Strategy:</span>\n\t\t\t\t\t\t\t\t<span className={styles.detailValueCapitalize}>\n\t\t\t\t\t\t\t\t\t{capabilities.strategy}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<div className={styles.detailRow}>\n\t\t\t\t\t\t\t\t<span className={styles.detailLabel}>Status:</span>\n\t\t\t\t\t\t\t\t<span className={getStatusValueClass()}>\n\t\t\t\t\t\t\t\t\t{capabilities.isLive\n\t\t\t\t\t\t\t\t\t\t? \"Connected\"\n\t\t\t\t\t\t\t\t\t\t: capabilities.hasSync\n\t\t\t\t\t\t\t\t\t\t\t? \"Offline with Sync\"\n\t\t\t\t\t\t\t\t\t\t\t: \"Local Only\"}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\n\t\t\t\t{/* Actions */}\n\t\t\t\t<div className={styles.actions}>\n\t\t\t\t\t{errorInfo.showRetry && (\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tonClick={handleRetry}\n\t\t\t\t\t\t\tdisabled={isRetrying}\n\t\t\t\t\t\t\tclassName={styles.retryButton}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{isRetrying ? (\n\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t<RefreshCw className={`${styles.iconSm} ${styles.mr2}`} />\n\t\t\t\t\t\t\t\t\tRetrying...\n\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t<RefreshCw className={`${styles.iconSm} ${styles.mr2}`} />\n\t\t\t\t\t\t\t\t\t{errorInfo.actionText}\n\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</button>\n\t\t\t\t\t)}\n\n\t\t\t\t\t<div className={styles.hint}>\n\t\t\t\t\t\t<AlertTriangle className={`${styles.iconXs} ${styles.inlineIcon} ${styles.mr1}`} />\n\t\t\t\t\t\tMake sure your database configuration is correct and the database is\n\t\t\t\t\t\taccessible.\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t);\n};\n","/**\n * View types for the SPA-style FormExplorer navigation\n *\n * @deprecated These types support the legacy FormExplorerCore SPA architecture.\n * Standalone components (ProjectsView, FormsView, FormBuilderView) do not need these types.\n */\n\n/** @deprecated Use standalone view components instead */\nexport type ExplorerViewType =\n\t| \"projects\" // Main projects overview\n\t| \"forms\" // Forms within a project\n\t| \"builder\" // Form builder\n\t| \"preview\"; // Form preview\n\n/** @deprecated Use standalone view components instead */\nexport interface BaseViewState {\n\ttype: ExplorerViewType;\n}\n\n/** @deprecated Use standalone view components instead */\nexport interface ProjectsViewState extends BaseViewState {\n\ttype: \"projects\";\n}\n\n/** @deprecated Use standalone view components instead */\nexport interface FormsViewState extends BaseViewState {\n\ttype: \"forms\";\n\tprojectId: string;\n\tprojectName: string;\n}\n\n// FlowsViewState removed - flows concept eliminated\n\n/** @deprecated Use standalone view components instead */\nexport interface BuilderViewState extends BaseViewState {\n\ttype: \"builder\";\n\tprojectId: string;\n\tformId: string;\n\tconfig?: unknown;\n}\n\n/** @deprecated Use standalone view components instead */\nexport interface PreviewViewState extends BaseViewState {\n\ttype: \"preview\";\n\tprojectId: string;\n\tformId: string;\n}\n\n/** @deprecated Use standalone view components instead */\nexport type ViewState =\n\t| ProjectsViewState\n\t| FormsViewState\n\t| BuilderViewState\n\t| PreviewViewState;\n\n/** @deprecated Use standalone view components instead */\nexport interface NavigationContext {\n\tcurrentView: ViewState;\n\tviewHistory: ViewState[];\n\tnavigateToView: (view: ViewState, addToHistory?: boolean) => void;\n\tnavigateBack: () => void;\n\tcanGoBack: boolean;\n}\n\n// FlowMetadata removed - flows concept eliminated\n\n// Helper functions for creating view states\n/** @deprecated Use standalone view components instead */\nexport const createProjectsView = (): ProjectsViewState => ({\n\ttype: \"projects\",\n});\n\n/** @deprecated Use standalone view components instead */\nexport const createFormsView = (\n\tprojectId: string,\n\tprojectName: string\n): FormsViewState => ({\n\ttype: \"forms\",\n\tprojectId,\n\tprojectName,\n});\n\n// createFlowsView removed - flows concept eliminated\n\n/** @deprecated Use standalone view components instead */\nexport const createBuilderView = (\n\tprojectId: string,\n\tformId: string,\n\tconfig?: unknown\n): BuilderViewState => ({\n\ttype: \"builder\",\n\tprojectId,\n\tformId,\n\tconfig,\n});\n\n/** @deprecated Use standalone view components instead */\nexport const createPreviewView = (\n\tprojectId: string,\n\tformId: string\n): PreviewViewState => ({\n\ttype: \"preview\",\n\tprojectId,\n\tformId,\n});\n","/**\n * FormExplorerCore - Legacy SPA-style form explorer orchestrator\n *\n * @deprecated Use standalone view components instead:\n * - ProjectsView for projects list\n * - FormsView for forms list\n * - FormBuilderView for form editing\n *\n * These components work with any routing framework via NavigationProvider.\n * FormExplorerCore couples your app to internal view state management.\n *\n * @see ProjectsView\n * @see FormsView\n * @see FormBuilderView\n */\n\nimport type { FormWizardConfig } from \"@formbuilder/core\";\nimport { Button } from \"@formbuilder/ui\";\nimport { RefreshCw } from \"lucide-react\";\nimport type React from \"react\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\n// Type definition for sync status\ninterface SyncStatus {\n\tonline: boolean;\n\tconnected: boolean;\n\tconnectionStatus: \"connected\" | \"disconnected\" | \"connecting\" | \"retrying\";\n\tlastSync: string | null;\n\tsyncing: boolean;\n\tretryCount?: number;\n\tmaxRetries?: number;\n\tlastConnectionError?: string | null;\n\tpendingOperations?: number;\n\treconciling?: boolean;\n\tintegrityStatus?: \"consistent\" | \"inconsistent\" | \"unknown\";\n}\n\nimport styles from \"./FormExplorerCore.module.css\";\nimport { DatabaseStatusIndicator } from \"../../../../components/DatabaseStatusIndicator/DatabaseStatusIndicator\";\nimport { ConnectionErrorScreen } from \"../../../../components/ConnectionErrorScreen/ConnectionErrorScreen\";\nimport type { FormConfig } from \"../../../../config/types\";\nimport {\n\ttype ProviderCapabilities,\n\tStorageProviderFactory,\n} from \"../../../../storage/StorageProviderFactory\";\nimport type { FormStorageProvider } from \"../../../../storage/types\";\nimport { getFormConfig } from \"../../../../utils/formsExplorer\";\nimport { FormBuilder } from \"../../../form-builder\";\nimport { useFormExplorerState, useFormOperations } from \"../../hooks/index\";\n// Import new view types and components\nimport type { NavigationContext, ViewState } from \"../../types/viewTypes\";\nimport { createBuilderView, createProjectsView } from \"../../types/viewTypes\";\nimport { FormsView } from \"../FormsView/FormsView\";\nimport { NewFormDialog } from \"../NewFormDialog/NewFormDialog\";\nimport { NewProjectDialog } from \"../NewProjectDialog/NewProjectDialog\";\nimport { ProjectsView } from \"../ProjectsView/ProjectsView\";\n\n// Re-export view types for backward compatibility\nexport type ExplorerView = ViewState;\n\nexport interface FormExplorerCoreProps {\n\t/**\n\t * Optional form configuration\n\t */\n\tconfig?: FormConfig;\n\n\t/**\n\t * Optional initial view configuration\n\t */\n\tinitialView?: ExplorerView;\n\n\t/**\n\t * Optional custom save handler for forms\n\t */\n\tonFormSave?: (\n\t\tprojectId: string,\n\t\twizardId: string,\n\t\tconfig: FormWizardConfig\n\t) => Promise<void>;\n\n\t/**\n\t * Optional custom load handler for forms\n\t */\n\tonFormLoad?: (\n\t\tprojectId: string,\n\t\twizardId: string\n\t) => Promise<FormWizardConfig>;\n\n\t/**\n\t * Optional custom form creation handler\n\t */\n\tonFormCreate?: (\n\t\tprojectId: string,\n\t\tformId: string,\n\t\ttitle: string\n\t) => Promise<FormWizardConfig | null>;\n\n\t/**\n\t * Optional custom form deletion handler\n\t */\n\tonFormDelete?: (projectId: string, wizardId: string) => Promise<boolean>;\n\n\t/**\n\t * Optional form edit handler\n\t */\n\tonFormEdit?: (\n\t\tprojectId: string,\n\t\twizardId: string,\n\t\tconfig: FormWizardConfig\n\t) => void;\n\n\t/**\n\t * Whether to show preview functionality\n\t */\n\tshowPreview?: boolean;\n\n\t/**\n\t * Custom preview URL generator\n\t */\n\tgetPreviewUrl?: (projectId: string, wizardId: string) => string;\n\n\t/**\n\t * Custom navigation handler for going back from builder to forms list\n\t * If not provided, will use internal navigateBack handler\n\t */\n\tonNavigateToForms?: (projectId: string) => void;\n\n\t/**\n\t * Custom navigation handler for going back to projects list\n\t * If not provided, will use internal view state navigation\n\t */\n\tonNavigateToProjects?: () => void;\n\n\t/**\n\t * Whether to disable automatic route-based navigation\n\t * @deprecated No longer has effect - route navigation removed\n\t */\n\tdisableRouteNavigation?: boolean;\n\n\t/**\n\t * Additional CSS class name\n\t */\n\tclassName?: string;\n\n\t/**\n\t * Custom styles\n\t */\n\tstyle?: React.CSSProperties;\n}\n\nexport const FormExplorerCore: React.FC<FormExplorerCoreProps> = ({\n\tconfig,\n\tinitialView = createProjectsView(),\n\tonFormSave,\n\tonFormLoad,\n\tonFormCreate,\n\tonFormDelete,\n\tonFormEdit,\n\tshowPreview = true,\n\t// getPreviewUrl, // Unused - using configured routes instead\n\tonNavigateToForms,\n\tonNavigateToProjects,\n\t// disableRouteNavigation, // Deprecated - no longer has effect\n\tclassName,\n\tstyle,\n}) => {\n\t// View state management with stable references\n\tconst [currentView, setCurrentView] = useState<ExplorerView>(initialView);\n\tconst navigationInProgress = useRef(false);\n\tconst [providerCapabilities, setProviderCapabilities] =\n\t\tuseState<ProviderCapabilities | null>(null);\n\n\t// Monitor provider capabilities for connection status\n\tuseEffect(() => {\n\t\tconst updateCapabilities = () => {\n\t\t\tconst factory = StorageProviderFactory.getInstance();\n\t\t\tconst capabilities = factory.getProviderCapabilities();\n\t\t\tsetProviderCapabilities(capabilities);\n\t\t};\n\n\t\t// Initial check\n\t\tupdateCapabilities();\n\n\t\t// Listen for storage provider ready event\n\t\tconst handleProviderReady = () => {\n\t\t\tupdateCapabilities();\n\t\t};\n\n\t\twindow.addEventListener(\"storageProviderReady\", handleProviderReady);\n\n\t\treturn () => {\n\t\t\twindow.removeEventListener(\"storageProviderReady\", handleProviderReady);\n\t\t};\n\t}, []);\n\n\t// Dialog state\n\tconst [showNewProjectDialog, setShowNewProjectDialog] = useState(false);\n\tconst [showNewFormDialog, setShowNewFormDialog] = useState(false);\n\n\t// Storage and sync status state\n\tconst [storageProvider, setStorageProvider] =\n\t\tuseState<FormStorageProvider | null>(null);\n\n\t// Use feature hooks\n\tconst {\n\t\tstate,\n\t\tfilteredProjects,\n\t\tloadProjects,\n\t\tselectedProject,\n\t\taddProjectOptimistic,\n\t\tremoveProjectOptimistic,\n\t\taddFormOptimistic,\n\t\tremoveFormOptimistic,\n\t\trefreshProjectsList,\n\t} = useFormExplorerState({ config });\n\n\tconst { handleSaveForm } = useFormOperations({\n\t\tonFormLoad,\n\t\tonFormCreate,\n\t\tonFormDelete,\n\t\tonFormSave,\n\t\tonFormEdit,\n\t\tonFormCreated: (projectId, formId, config) => {\n\t\t\tnavigateToView({\n\t\t\t\ttype: \"builder\",\n\t\t\t\tprojectId,\n\t\t\t\tformId,\n\t\t\t\tconfig,\n\t\t\t});\n\t\t},\n\t\tonProjectsRefresh: loadProjects,\n\t});\n\n\t// Sync currentView with initialView prop changes\n\tuseEffect(() => {\n\t\tif (\n\t\t\t!navigationInProgress.current &&\n\t\t\tcurrentView.type !== initialView.type\n\t\t) {\n\t\t\tsetCurrentView(initialView);\n\t\t}\n\t}, [currentView.type, initialView]);\n\n\t// Initialize storage provider for sync status monitoring\n\tuseEffect(() => {\n\t\tconst initStorageProvider = async () => {\n\t\t\ttry {\n\t\t\t\tconst formConfig = config || (await getFormConfig());\n\t\t\t\tconst factory = StorageProviderFactory.getInstance();\n\t\t\t\tconst provider = await factory.createProvider(formConfig.storage);\n\t\t\t\tsetStorageProvider(provider);\n\n\t\t\t\t// Get provider capabilities using the factory\n\t\t\t\tconst capabilities = factory.getProviderCapabilities();\n\t\t\t\tsetProviderCapabilities(capabilities);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Failed to get storage provider:\", error);\n\t\t\t}\n\t\t};\n\n\t\tinitStorageProvider();\n\t}, [config]);\n\n\t// Sync status handlers\n\tconst getSyncStatus = useCallback((): SyncStatus => {\n\t\tif (\n\t\t\tstorageProvider &&\n\t\t\t\"getSyncStatus\" in storageProvider &&\n\t\t\ttypeof (storageProvider as { getSyncStatus?: () => SyncStatus })\n\t\t\t\t.getSyncStatus === \"function\"\n\t\t) {\n\t\t\treturn (\n\t\t\t\tstorageProvider as { getSyncStatus: () => SyncStatus }\n\t\t\t).getSyncStatus();\n\t\t}\n\t\treturn {\n\t\t\tonline: navigator.onLine,\n\t\t\tconnected: false,\n\t\t\tconnectionStatus: \"disconnected\" as const,\n\t\t\tlastSync: null,\n\t\t\tsyncing: false,\n\t\t\tretryCount: 0,\n\t\t\tmaxRetries: 5,\n\t\t\tlastConnectionError: null,\n\t\t\tpendingOperations: 0,\n\t\t\treconciling: false,\n\t\t\tintegrityStatus: \"unknown\" as const,\n\t\t};\n\t}, [storageProvider]);\n\n\tconst handleForceSync = useCallback(async () => {\n\t\tif (\n\t\t\tstorageProvider &&\n\t\t\t\"forceSync\" in storageProvider &&\n\t\t\ttypeof (storageProvider as { forceSync?: () => Promise<void> })\n\t\t\t\t.forceSync === \"function\"\n\t\t) {\n\t\t\tawait (storageProvider as { forceSync: () => Promise<void> }).forceSync();\n\t\t}\n\t}, [storageProvider]);\n\n\tconst handleReconnect = useCallback(async (): Promise<boolean> => {\n\t\tif (\n\t\t\tstorageProvider &&\n\t\t\t\"reconnect\" in storageProvider &&\n\t\t\ttypeof (storageProvider as { reconnect?: () => Promise<boolean> })\n\t\t\t\t.reconnect === \"function\"\n\t\t) {\n\t\t\treturn await (\n\t\t\t\tstorageProvider as { reconnect: () => Promise<boolean> }\n\t\t\t).reconnect();\n\t\t}\n\t\treturn false;\n\t}, [storageProvider]);\n\n\t// Data consistency handlers\n\tconst handleValidateConsistency = useCallback(async (): Promise<boolean> => {\n\t\tif (\n\t\t\tstorageProvider &&\n\t\t\t\"validateDataConsistency\" in storageProvider &&\n\t\t\ttypeof (\n\t\t\t\tstorageProvider as { validateDataConsistency?: () => Promise<boolean> }\n\t\t\t).validateDataConsistency === \"function\"\n\t\t) {\n\t\t\treturn await (\n\t\t\t\tstorageProvider as { validateDataConsistency: () => Promise<boolean> }\n\t\t\t).validateDataConsistency();\n\t\t}\n\t\treturn true; // Default to consistent if method not available\n\t}, [storageProvider]);\n\n\tconst handleResetLocalData = useCallback(async (): Promise<boolean> => {\n\t\tif (\n\t\t\tstorageProvider &&\n\t\t\t\"resetLocalData\" in storageProvider &&\n\t\t\ttypeof (storageProvider as { resetLocalData?: () => Promise<boolean> })\n\t\t\t\t.resetLocalData === \"function\"\n\t\t) {\n\t\t\treturn await (\n\t\t\t\tstorageProvider as { resetLocalData: () => Promise<boolean> }\n\t\t\t).resetLocalData();\n\t\t}\n\t\treturn false;\n\t}, [storageProvider]);\n\n\tconst handleReconcileConflicts = useCallback(async (): Promise<boolean> => {\n\t\tif (\n\t\t\tstorageProvider &&\n\t\t\t\"reconcileConflicts\" in storageProvider &&\n\t\t\ttypeof (\n\t\t\t\tstorageProvider as { reconcileConflicts?: () => Promise<boolean> }\n\t\t\t).reconcileConflicts === \"function\"\n\t\t) {\n\t\t\treturn await (\n\t\t\t\tstorageProvider as { reconcileConflicts: () => Promise<boolean> }\n\t\t\t).reconcileConflicts();\n\t\t}\n\t\treturn false;\n\t}, [storageProvider]);\n\n\t// Navigation helpers - stable and immediate\n\tconst navigateToView = useCallback((view: ViewState) => {\n\t\tnavigationInProgress.current = true;\n\t\tsetCurrentView(view);\n\t\tsetTimeout(() => {\n\t\t\tnavigationInProgress.current = false;\n\t\t}, 0);\n\t}, []);\n\n\tconst navigateBack = useCallback(() => {\n\t\t// Without internal history, back navigation goes to projects\n\t\t// Consumer should provide onNavigateToProjects for proper behavior\n\t\tif (onNavigateToProjects) {\n\t\t\tonNavigateToProjects();\n\t\t}\n\t}, [onNavigateToProjects]);\n\n\t// Create stable navigation context with proper memoization\n\tconst navigationContext: NavigationContext = {\n\t\tcurrentView,\n\t\tviewHistory: [], // Empty - no longer tracked\n\t\tnavigateToView,\n\t\tnavigateBack,\n\t\tcanGoBack: false, // No internal history\n\t};\n\n\t// Handle project creation completion with immediate UI update\n\tconst handleProjectCreated = useCallback(\n\t\t(projectData?: {\n\t\t\tprojectId: string;\n\t\t\tname: string;\n\t\t\tdescription?: string;\n\t\t}) => {\n\t\t\tif (projectData) {\n\t\t\t\t// Add project optimistically for immediate UI feedback\n\t\t\t\taddProjectOptimistic({\n\t\t\t\t\tid: projectData.projectId,\n\t\t\t\t\tname: projectData.name,\n\t\t\t\t\tdescription: projectData.description || \"\",\n\t\t\t\t\tforms: [],\n\t\t\t\t\tcreatedAt: Date.now(),\n\t\t\t\t});\n\t\t\t\tconsole.log(\n\t\t\t\t\t\"✨ Project added optimistically, scheduling background refresh...\"\n\t\t\t\t);\n\n\t\t\t\t// Trigger background refresh to sync with actual data\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\trefreshProjectsList();\n\t\t\t\t}, 500); // Small delay to allow sync to complete\n\t\t\t} else {\n\t\t\t\t// Fallback to full refresh if no project data provided\n\t\t\t\tloadProjects();\n\t\t\t}\n\t\t},\n\t\t[addProjectOptimistic, refreshProjectsList, loadProjects]\n\t);\n\n\t// Handle form creation completion\n\tconst handleFormCreated = useCallback(\n\t\t(projectId: string, formId: string) => {\n\t\t\tloadProjects();\n\t\t\tnavigateToView(createBuilderView(projectId, formId));\n\t\t},\n\t\t[loadProjects, navigateToView]\n\t);\n\n\t// Handle preview (currently unused but kept for future implementation)\n\t// const handlePreview = useCallback(\n\t// \t(projectId: string, wizardId: string) => {\n\t// \t\tif (getPreviewUrl) {\n\t// \t\t\twindow.open(getPreviewUrl(projectId, wizardId), \"_blank\");\n\t// \t\t} else {\n\t// \t\t\t// Use configured preview route\n\t// \t\t\tconst previewUrl = navigationUrls.preview(projectId, wizardId);\n\t// \t\t\twindow.open(previewUrl, \"_blank\");\n\t// \t\t}\n\t// \t},\n\t// \t[getPreviewUrl, navigationUrls]\n\t// );\n\n\t// Handle saving a form in builder view\n\tconst handleFormSave = useCallback(\n\t\tasync (config: FormWizardConfig) => {\n\t\t\tif (currentView.type !== \"builder\") return;\n\n\t\t\tconst { projectId, formId } = currentView;\n\n\t\t\ttry {\n\t\t\t\tawait handleSaveForm(projectId, formId, config);\n\n\t\t\t\t// Update the view with the new config\n\t\t\t\tsetCurrentView((prev) =>\n\t\t\t\t\tprev.type === \"builder\"\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t...prev,\n\t\t\t\t\t\t\t\tconfig,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: prev\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\"Failed to save form:\", error);\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\t\t[currentView, handleSaveForm]\n\t);\n\n\t// Render based on current view\n\tconst renderView = () => {\n\t\t// Handle loading and error states at the top level\n\t\tif (state.isLoading) {\n\t\t\treturn (\n\t\t\t\t<div className={styles.container}>\n\t\t\t\t\t<div className={styles.loadingCenter}>\n\t\t\t\t\t\t<RefreshCw className={`${styles.iconXl} ${styles.spinAnimation}`} />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t);\n\t\t}\n\n\t\tif (state.error) {\n\t\t\tconst isDatabaseSetupError =\n\t\t\t\tstate.error.includes(\"Database tables not found\") ||\n\t\t\t\tstate.error.includes(\"404\") ||\n\t\t\t\tstate.error.includes(\"relation\") ||\n\t\t\t\tstate.error.includes(\"does not exist\");\n\n\t\t\treturn (\n\t\t\t\t<div className={styles.container}>\n\t\t\t\t\t<div className={styles.errorCenter}>\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={`${styles.errorBox} ${isDatabaseSetupError ? styles.errorBoxSetup : styles.errorBoxFailed}`}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclassName={`${styles.errorTitle} ${isDatabaseSetupError ? styles.errorTitleSetup : styles.errorTitleFailed}`}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{isDatabaseSetupError\n\t\t\t\t\t\t\t\t\t? \"🔧 Database Setup Required\"\n\t\t\t\t\t\t\t\t\t: \"Connection Failed\"}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<p className={styles.errorMessage}>{state.error}</p>\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\tonClick={loadProjects}\n\t\t\t\t\t\t\t\tclassName={isDatabaseSetupError ? styles.retryButtonSetup : styles.retryButtonFailed}\n\t\t\t\t\t\t\t\tdisabled={state.isLoading}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<RefreshCw className={styles.retryButtonIcon} />\n\t\t\t\t\t\t\t\t{isDatabaseSetupError ? \"Check Again\" : \"Try Again\"}\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t);\n\t\t}\n\n\t\tswitch (currentView.type) {\n\t\t\tcase \"projects\":\n\t\t\t\treturn (\n\t\t\t\t\t<ProjectsView\n\t\t\t\t\t\tprojects={filteredProjects}\n\t\t\t\t\t\tisLoading={state.isLoading}\n\t\t\t\t\t\tonRefresh={refreshProjectsList}\n\t\t\t\t\t\tonProjectDeleted={removeProjectOptimistic}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\tcase \"forms\": {\n\t\t\t\tconst project = filteredProjects.find(\n\t\t\t\t\t(p) => p.id === currentView.projectId\n\t\t\t\t);\n\t\t\t\tif (!project) {\n\t\t\t\t\t// Use setTimeout to avoid immediate state updates during render\n\t\t\t\t\tsetTimeout(() => {\n\t\t\t\t\t\tnavigationContext.navigateToView(createProjectsView(), false);\n\t\t\t\t\t}, 0);\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<div className={styles.container}>\n\t\t\t\t\t\t\t<div className={styles.loadingCenter}>\n\t\t\t\t\t\t\t\t<RefreshCw className={`${styles.iconXl} ${styles.spinAnimation}`} />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn (\n\t\t\t\t\t<FormsView\n\t\t\t\t\t\tprojectId={currentView.projectId}\n\t\t\t\t\t\tonRefresh={refreshProjectsList}\n\t\t\t\t\t\tonFormDeleted={removeFormOptimistic}\n\t\t\t\t\t\tonFormAdded={addFormOptimistic}\n\t\t\t\t\t\tonNavigateToProjects={() => {\n\t\t\t\t\t\t\tif (onNavigateToProjects) {\n\t\t\t\t\t\t\t\tonNavigateToProjects();\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Fall back to internal view navigation\n\t\t\t\t\t\t\tnavigationContext.navigateToView(createProjectsView());\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tcase \"builder\":\n\t\t\t\treturn (\n\t\t\t\t\t<FormBuilder\n\t\t\t\t\t\tinitialConfig={currentView.config as FormWizardConfig | undefined}\n\t\t\t\t\t\tonSave={handleFormSave}\n\t\t\t\t\t\tproject={currentView.projectId}\n\t\t\t\t\t\twizardId={currentView.formId}\n\t\t\t\t\t\tshowPreviewButton={showPreview}\n\t\t\t\t\t\t// Pass navigation handlers to FormBuilder\n\t\t\t\t\t\tonNavigateToForms={\n\t\t\t\t\t\t\tonNavigateToForms\n\t\t\t\t\t\t\t\t? () => onNavigateToForms(currentView.projectId)\n\t\t\t\t\t\t\t\t: navigateBack\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t);\n\n\t\t\tdefault:\n\t\t\t\t// Fallback to projects view for unsupported view types\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tnavigationContext.navigateToView(createProjectsView(), false);\n\t\t\t\t}, 0);\n\t\t\t\treturn (\n\t\t\t\t\t<div className={styles.container}>\n\t\t\t\t\t\t<div className={styles.loadingCenter}>\n\t\t\t\t\t\t\t<RefreshCw className={`${styles.iconXl} ${styles.spinAnimation}`} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t}\n\t};\n\n\t// Check if we need to show connection error screen\n\tconst shouldShowConnectionError = () => {\n\t\t// No capabilities means still loading - don't show error yet\n\t\tif (!providerCapabilities) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Filesystem strategy should never show connection errors\n\t\tif (providerCapabilities.strategy === \"filesystem\") {\n\t\t\treturn false;\n\t\t}\n\n\t\t// For database strategy, show error if neither live nor sync is available\n\t\treturn !providerCapabilities.isLive && !providerCapabilities.hasSync;\n\t};\n\n\t// Show connection error screen if database is not properly connected\n\tif (shouldShowConnectionError()) {\n\t\treturn <ConnectionErrorScreen onRetry={() => window.location.reload()} />;\n\t}\n\n\treturn (\n\t\t<div className={`${styles.formExplorer}${className ? \" \" + className : \"\"}`} style={style}>\n\t\t\t{renderView()}\n\n\t\t\t{/* Dialogs */}\n\t\t\t<NewProjectDialog\n\t\t\t\topen={showNewProjectDialog}\n\t\t\t\tonOpenChange={setShowNewProjectDialog}\n\t\t\t\tonProjectCreated={handleProjectCreated}\n\t\t\t/>\n\n\t\t\t<NewFormDialog\n\t\t\t\topen={showNewFormDialog}\n\t\t\t\tonOpenChange={setShowNewFormDialog}\n\t\t\t\tselectedProjectId={selectedProject || undefined}\n\t\t\t\tonFormCreated={handleFormCreated}\n\t\t\t/>\n\t\t\t{/* Only show DatabaseStatusIndicator when using database storage */}\n\t\t\t{providerCapabilities?.strategy === \"database\" && (\n\t\t\t\t<DatabaseStatusIndicator\n\t\t\t\t\tgetSyncStatus={getSyncStatus}\n\t\t\t\t\tonForceSync={handleForceSync}\n\t\t\t\t\tonReconnect={handleReconnect}\n\t\t\t\t\tonValidateConsistency={handleValidateConsistency}\n\t\t\t\t\tonResetLocalData={handleResetLocalData}\n\t\t\t\t\tonReconcileConflicts={handleReconcileConflicts}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</div>\n\t);\n};\n","/**\n * FormExplorer - A comprehensive form management component\n * Provides form discovery, creation, editing, and management capabilities\n * Designed to be easily imported and used in any React application\n *\n * @example Basic usage with filesystem config\n * ```tsx\n * import { FormExplorer, type FormConfig } from '@dragstep/form-builder-component';\n *\n * const config: FormConfig = {\n * storage: {\n * strategy: \"filesystem\",\n * paths: { primaryStorage: \"./forms\" },\n * fileExtension: \".json\"\n * }\n * };\n *\n * function App() {\n * return <FormExplorer config={config} />;\n * }\n * ```\n *\n * @example Auto-detection (recommended for NPM packages)\n * ```tsx\n * // 1. Create /form.config.json in your project root\n * // 2. Import and use the component\n * import { FormExplorer } from '@dragstep/form-builder-component';\n *\n * function App() {\n * // FormExplorer automatically finds /form.config.json\n * // and resolves environment variables like ${DATABASE_URL}\n * return <FormExplorer />;\n * }\n * ```\n *\n * @example Manual config (for custom setups)\n * ```tsx\n * import { FormExplorer } from '@dragstep/form-builder-component';\n * import formConfig from './form.config.json';\n *\n * function App() {\n * return <FormExplorer config={formConfig} />;\n * }\n * ```\n */\n\nimport type { FormWizardConfig } from \"@formbuilder/core\";\nimport { useEffect, useState } from \"react\";\nimport \"../../../../styles/styles.css\";\nimport type { FormConfig } from \"../../../../config/types\";\nimport styles from \"./FormExplorer.module.css\";\nimport {\n\tThemeProvider,\n\tuseThemeConfig,\n} from \"../../../../providers/ThemeProvider\";\nimport { resolveConfigVariables } from \"../../../../utils/configReader\";\nimport { type ExplorerView, FormExplorerCore } from \"../FormExplorerCore/FormExplorerCore\";\n\n// Re-export the props interface for backwards compatibility with explicit config typing\nexport interface FormExplorerProps {\n\t/**\n\t * Optional form configuration\n\t * If not provided, FormExplorer will automatically search for form.config.json in the user's project\n\t * Supports both strict FormConfig and raw JSON objects (which will be processed)\n\t */\n\tconfig?: FormConfig | Record<string, unknown>;\n\n\t// Optional props from FormExplorerCoreProps\n\tinitialView?: ExplorerView;\n\tonFormSave?: (\n\t\tprojectId: string,\n\t\twizardId: string,\n\t\tconfig: FormWizardConfig\n\t) => Promise<void>;\n\tonFormLoad?: (\n\t\tprojectId: string,\n\t\twizardId: string\n\t) => Promise<FormWizardConfig>;\n\tonProjectCreate?: (projectName: string) => Promise<boolean>;\n\tonFormCreate?: (\n\t\tprojectId: string,\n\t\tformId: string,\n\t\ttitle: string\n\t) => Promise<FormWizardConfig | null>;\n\tonFormDelete?: (projectId: string, wizardId: string) => Promise<boolean>;\n\tonFormEdit?: (\n\t\tprojectId: string,\n\t\twizardId: string,\n\t\tconfig: FormWizardConfig\n\t) => void;\n\tshowPreview?: boolean;\n\tgetPreviewUrl?: (projectId: string, wizardId: string) => string;\n\tclassName?: string;\n\tstyle?: React.CSSProperties;\n}\n\n/**\n * FormExplorer - Legacy form management wrapper with config auto-detection\n *\n * @deprecated Use standalone view components with NavigationProvider instead:\n * - ProjectsView, FormsView, FormBuilderView\n *\n * @see ProjectsView\n * @see FormsView\n * @see FormBuilderView\n */\nconst FormExplorer: React.FC<FormExplorerProps> = ({ config, ...props }) => {\n\tconst themeConfig = useThemeConfig();\n\tconst [resolvedConfig, setResolvedConfig] = useState<FormConfig | null>(null);\n\tconst [isLoading, setIsLoading] = useState(true);\n\tconst [error, setError] = useState<string | null>(null);\n\n\tuseEffect(() => {\n\t\tconst loadConfig = async () => {\n\t\t\ttry {\n\t\t\t\tif (config) {\n\t\t\t\t\t// User provided config explicitly\n\t\t\t\t\tconst processedConfig = resolveConfigVariables(config);\n\t\t\t\t\tsetResolvedConfig(processedConfig);\n\t\t\t\t\tsetIsLoading(false);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Auto-detect form.config.json in project root\n\t\t\t\tconst configPath = \"/form.config.json\";\n\n\t\t\t\ttry {\n\t\t\t\t\tconst response = await fetch(configPath);\n\t\t\t\t\tif (response.ok) {\n\t\t\t\t\t\tconst rawConfig = await response.json();\n\t\t\t\t\t\tconst processedConfig = resolveConfigVariables(rawConfig);\n\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t`✅ FormExplorer: Found config at ${configPath}`,\n\t\t\t\t\t\t\tprocessedConfig\n\t\t\t\t\t\t);\n\t\t\t\t\t\tsetResolvedConfig(processedConfig);\n\t\t\t\t\t\tsetIsLoading(false);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Config file not found or invalid\n\t\t\t\t}\n\n\t\t\t\t// No config found, show error\n\t\t\t\tsetError(\n\t\t\t\t\t\"No form.config.json found in project root. Please create /form.config.json or provide a config prop.\"\n\t\t\t\t);\n\t\t\t\tsetIsLoading(false);\n\t\t\t} catch (loadError) {\n\t\t\t\tsetError(\n\t\t\t\t\t`Failed to load configuration: ${loadError instanceof Error ? loadError.message : \"Unknown error\"}`\n\t\t\t\t);\n\t\t\t\tsetIsLoading(false);\n\t\t\t}\n\t\t};\n\n\t\tloadConfig();\n\t}, [config]);\n\n\t// Loading state\n\tif (isLoading) {\n\t\treturn (\n\t\t\t<div className={styles.loadingContainer}>\n\t\t\t\t<div className={styles.loadingInner}>\n\t\t\t\t\t<div className={styles.loadingSpinner}></div>\n\t\t\t\t\t<p className={styles.loadingText}>Loading configuration...</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\t// Error state\n\tif (error || !resolvedConfig) {\n\t\treturn (\n\t\t\t<div className={styles.errorContainer}>\n\t\t\t\t<div className={styles.errorInner}>\n\t\t\t\t\t<h3 className={styles.errorTitle}>\n\t\t\t\t\t\tConfiguration Required\n\t\t\t\t\t</h3>\n\t\t\t\t\t<p className={styles.errorMessage}>\n\t\t\t\t\t\t{error ||\n\t\t\t\t\t\t\t\"FormExplorer requires a configuration to determine storage strategy.\"}\n\t\t\t\t\t</p>\n\t\t\t\t\t<div className={styles.errorCodeBlock}>\n\t\t\t\t\t\t<strong>\n\t\t\t\t\t\t\tOption 1: Create /form.config.json in your project root:\n\t\t\t\t\t\t</strong>\n\t\t\t\t\t\t<pre>{`{\n \"storage\": {\n \"strategy\": \"database\",\n \"databaseConfig\": {\n \"url\": \"\\${DATABASE_URL}\"\n }\n }\n}`}</pre>\n\t\t\t\t\t\t<strong className={styles.errorCodeBlockLabel}>\n\t\t\t\t\t\t\tOption 2: Pass config as prop:\n\t\t\t\t\t\t</strong>\n\t\t\t\t\t\t<pre>{`<FormExplorer config={yourConfig} />`}</pre>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<ThemeProvider config={themeConfig}>\n\t\t\t<FormExplorerCore config={resolvedConfig} {...props} />\n\t\t</ThemeProvider>\n\t);\n};\n\n/** @deprecated Use standalone view components instead */\nexport default FormExplorer;\n/** @deprecated Use standalone view components instead */\nexport { FormExplorer };\nexport type { ExplorerView };\n","/**\n * React Router v6.30.3\n *\n * Copyright (c) Remix Software Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE.md file in the root directory of this source tree.\n *\n * @license MIT\n */\nimport * as React from 'react';\nimport { UNSAFE_invariant, joinPaths, matchPath, UNSAFE_decodePath, UNSAFE_getResolveToMatches, UNSAFE_warning, resolveTo, parsePath, matchRoutes, Action, UNSAFE_convertRouteMatchToUiMatch, stripBasename, IDLE_BLOCKER, isRouteErrorResponse, createMemoryHistory, AbortedDeferredError, createRouter } from '@remix-run/router';\nexport { AbortedDeferredError, Action as NavigationType, createPath, defer, generatePath, isRouteErrorResponse, json, matchPath, matchRoutes, parsePath, redirect, redirectDocument, replace, resolvePath } from '@remix-run/router';\n\nfunction _extends() {\n _extends = Object.assign ? Object.assign.bind() : function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n return target;\n };\n return _extends.apply(this, arguments);\n}\n\n// Create react-specific types from the agnostic types in @remix-run/router to\n// export from react-router\nconst DataRouterContext = /*#__PURE__*/React.createContext(null);\nif (process.env.NODE_ENV !== \"production\") {\n DataRouterContext.displayName = \"DataRouter\";\n}\nconst DataRouterStateContext = /*#__PURE__*/React.createContext(null);\nif (process.env.NODE_ENV !== \"production\") {\n DataRouterStateContext.displayName = \"DataRouterState\";\n}\nconst AwaitContext = /*#__PURE__*/React.createContext(null);\nif (process.env.NODE_ENV !== \"production\") {\n AwaitContext.displayName = \"Await\";\n}\n\n/**\n * A Navigator is a \"location changer\"; it's how you get to different locations.\n *\n * Every history instance conforms to the Navigator interface, but the\n * distinction is useful primarily when it comes to the low-level `<Router>` API\n * where both the location and a navigator must be provided separately in order\n * to avoid \"tearing\" that may occur in a suspense-enabled app if the action\n * and/or location were to be read directly from the history instance.\n */\n\nconst NavigationContext = /*#__PURE__*/React.createContext(null);\nif (process.env.NODE_ENV !== \"production\") {\n NavigationContext.displayName = \"Navigation\";\n}\nconst LocationContext = /*#__PURE__*/React.createContext(null);\nif (process.env.NODE_ENV !== \"production\") {\n LocationContext.displayName = \"Location\";\n}\nconst RouteContext = /*#__PURE__*/React.createContext({\n outlet: null,\n matches: [],\n isDataRoute: false\n});\nif (process.env.NODE_ENV !== \"production\") {\n RouteContext.displayName = \"Route\";\n}\nconst RouteErrorContext = /*#__PURE__*/React.createContext(null);\nif (process.env.NODE_ENV !== \"production\") {\n RouteErrorContext.displayName = \"RouteError\";\n}\n\n/**\n * Returns the full href for the given \"to\" value. This is useful for building\n * custom links that are also accessible and preserve right-click behavior.\n *\n * @see https://reactrouter.com/v6/hooks/use-href\n */\nfunction useHref(to, _temp) {\n let {\n relative\n } = _temp === void 0 ? {} : _temp;\n !useInRouterContext() ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n \"useHref() may be used only in the context of a <Router> component.\") : UNSAFE_invariant(false) : void 0;\n let {\n basename,\n navigator\n } = React.useContext(NavigationContext);\n let {\n hash,\n pathname,\n search\n } = useResolvedPath(to, {\n relative\n });\n let joinedPathname = pathname;\n\n // If we're operating within a basename, prepend it to the pathname prior\n // to creating the href. If this is a root navigation, then just use the raw\n // basename which allows the basename to have full control over the presence\n // of a trailing slash on root links\n if (basename !== \"/\") {\n joinedPathname = pathname === \"/\" ? basename : joinPaths([basename, pathname]);\n }\n return navigator.createHref({\n pathname: joinedPathname,\n search,\n hash\n });\n}\n\n/**\n * Returns true if this component is a descendant of a `<Router>`.\n *\n * @see https://reactrouter.com/v6/hooks/use-in-router-context\n */\nfunction useInRouterContext() {\n return React.useContext(LocationContext) != null;\n}\n\n/**\n * Returns the current location object, which represents the current URL in web\n * browsers.\n *\n * Note: If you're using this it may mean you're doing some of your own\n * \"routing\" in your app, and we'd like to know what your use case is. We may\n * be able to provide something higher-level to better suit your needs.\n *\n * @see https://reactrouter.com/v6/hooks/use-location\n */\nfunction useLocation() {\n !useInRouterContext() ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n \"useLocation() may be used only in the context of a <Router> component.\") : UNSAFE_invariant(false) : void 0;\n return React.useContext(LocationContext).location;\n}\n\n/**\n * Returns the current navigation action which describes how the router came to\n * the current location, either by a pop, push, or replace on the history stack.\n *\n * @see https://reactrouter.com/v6/hooks/use-navigation-type\n */\nfunction useNavigationType() {\n return React.useContext(LocationContext).navigationType;\n}\n\n/**\n * Returns a PathMatch object if the given pattern matches the current URL.\n * This is useful for components that need to know \"active\" state, e.g.\n * `<NavLink>`.\n *\n * @see https://reactrouter.com/v6/hooks/use-match\n */\nfunction useMatch(pattern) {\n !useInRouterContext() ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n \"useMatch() may be used only in the context of a <Router> component.\") : UNSAFE_invariant(false) : void 0;\n let {\n pathname\n } = useLocation();\n return React.useMemo(() => matchPath(pattern, UNSAFE_decodePath(pathname)), [pathname, pattern]);\n}\n\n/**\n * The interface for the navigate() function returned from useNavigate().\n */\n\nconst navigateEffectWarning = \"You should call navigate() in a React.useEffect(), not when \" + \"your component is first rendered.\";\n\n// Mute warnings for calls to useNavigate in SSR environments\nfunction useIsomorphicLayoutEffect(cb) {\n let isStatic = React.useContext(NavigationContext).static;\n if (!isStatic) {\n // We should be able to get rid of this once react 18.3 is released\n // See: https://github.com/facebook/react/pull/26395\n // eslint-disable-next-line react-hooks/rules-of-hooks\n React.useLayoutEffect(cb);\n }\n}\n\n/**\n * Returns an imperative method for changing the location. Used by `<Link>`s, but\n * may also be used by other elements to change the location.\n *\n * @see https://reactrouter.com/v6/hooks/use-navigate\n */\nfunction useNavigate() {\n let {\n isDataRoute\n } = React.useContext(RouteContext);\n // Conditional usage is OK here because the usage of a data router is static\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return isDataRoute ? useNavigateStable() : useNavigateUnstable();\n}\nfunction useNavigateUnstable() {\n !useInRouterContext() ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n \"useNavigate() may be used only in the context of a <Router> component.\") : UNSAFE_invariant(false) : void 0;\n let dataRouterContext = React.useContext(DataRouterContext);\n let {\n basename,\n future,\n navigator\n } = React.useContext(NavigationContext);\n let {\n matches\n } = React.useContext(RouteContext);\n let {\n pathname: locationPathname\n } = useLocation();\n let routePathnamesJson = JSON.stringify(UNSAFE_getResolveToMatches(matches, future.v7_relativeSplatPath));\n let activeRef = React.useRef(false);\n useIsomorphicLayoutEffect(() => {\n activeRef.current = true;\n });\n let navigate = React.useCallback(function (to, options) {\n if (options === void 0) {\n options = {};\n }\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(activeRef.current, navigateEffectWarning) : void 0;\n\n // Short circuit here since if this happens on first render the navigate\n // is useless because we haven't wired up our history listener yet\n if (!activeRef.current) return;\n if (typeof to === \"number\") {\n navigator.go(to);\n return;\n }\n let path = resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, options.relative === \"path\");\n\n // If we're operating within a basename, prepend it to the pathname prior\n // to handing off to history (but only if we're not in a data router,\n // otherwise it'll prepend the basename inside of the router).\n // If this is a root navigation, then we navigate to the raw basename\n // which allows the basename to have full control over the presence of a\n // trailing slash on root links\n if (dataRouterContext == null && basename !== \"/\") {\n path.pathname = path.pathname === \"/\" ? basename : joinPaths([basename, path.pathname]);\n }\n (!!options.replace ? navigator.replace : navigator.push)(path, options.state, options);\n }, [basename, navigator, routePathnamesJson, locationPathname, dataRouterContext]);\n return navigate;\n}\nconst OutletContext = /*#__PURE__*/React.createContext(null);\n\n/**\n * Returns the context (if provided) for the child route at this level of the route\n * hierarchy.\n * @see https://reactrouter.com/v6/hooks/use-outlet-context\n */\nfunction useOutletContext() {\n return React.useContext(OutletContext);\n}\n\n/**\n * Returns the element for the child route at this level of the route\n * hierarchy. Used internally by `<Outlet>` to render child routes.\n *\n * @see https://reactrouter.com/v6/hooks/use-outlet\n */\nfunction useOutlet(context) {\n let outlet = React.useContext(RouteContext).outlet;\n if (outlet) {\n return /*#__PURE__*/React.createElement(OutletContext.Provider, {\n value: context\n }, outlet);\n }\n return outlet;\n}\n\n/**\n * Returns an object of key/value pairs of the dynamic params from the current\n * URL that were matched by the route path.\n *\n * @see https://reactrouter.com/v6/hooks/use-params\n */\nfunction useParams() {\n let {\n matches\n } = React.useContext(RouteContext);\n let routeMatch = matches[matches.length - 1];\n return routeMatch ? routeMatch.params : {};\n}\n\n/**\n * Resolves the pathname of the given `to` value against the current location.\n *\n * @see https://reactrouter.com/v6/hooks/use-resolved-path\n */\nfunction useResolvedPath(to, _temp2) {\n let {\n relative\n } = _temp2 === void 0 ? {} : _temp2;\n let {\n future\n } = React.useContext(NavigationContext);\n let {\n matches\n } = React.useContext(RouteContext);\n let {\n pathname: locationPathname\n } = useLocation();\n let routePathnamesJson = JSON.stringify(UNSAFE_getResolveToMatches(matches, future.v7_relativeSplatPath));\n return React.useMemo(() => resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, relative === \"path\"), [to, routePathnamesJson, locationPathname, relative]);\n}\n\n/**\n * Returns the element of the route that matched the current location, prepared\n * with the correct context to render the remainder of the route tree. Route\n * elements in the tree must render an `<Outlet>` to render their child route's\n * element.\n *\n * @see https://reactrouter.com/v6/hooks/use-routes\n */\nfunction useRoutes(routes, locationArg) {\n return useRoutesImpl(routes, locationArg);\n}\n\n// Internal implementation with accept optional param for RouterProvider usage\nfunction useRoutesImpl(routes, locationArg, dataRouterState, future) {\n !useInRouterContext() ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of the\n // router loaded. We can help them understand how to avoid that.\n \"useRoutes() may be used only in the context of a <Router> component.\") : UNSAFE_invariant(false) : void 0;\n let {\n navigator\n } = React.useContext(NavigationContext);\n let {\n matches: parentMatches\n } = React.useContext(RouteContext);\n let routeMatch = parentMatches[parentMatches.length - 1];\n let parentParams = routeMatch ? routeMatch.params : {};\n let parentPathname = routeMatch ? routeMatch.pathname : \"/\";\n let parentPathnameBase = routeMatch ? routeMatch.pathnameBase : \"/\";\n let parentRoute = routeMatch && routeMatch.route;\n if (process.env.NODE_ENV !== \"production\") {\n // You won't get a warning about 2 different <Routes> under a <Route>\n // without a trailing *, but this is a best-effort warning anyway since we\n // cannot even give the warning unless they land at the parent route.\n //\n // Example:\n //\n // <Routes>\n // {/* This route path MUST end with /* because otherwise\n // it will never match /blog/post/123 */}\n // <Route path=\"blog\" element={<Blog />} />\n // <Route path=\"blog/feed\" element={<BlogFeed />} />\n // </Routes>\n //\n // function Blog() {\n // return (\n // <Routes>\n // <Route path=\"post/:id\" element={<Post />} />\n // </Routes>\n // );\n // }\n let parentPath = parentRoute && parentRoute.path || \"\";\n warningOnce(parentPathname, !parentRoute || parentPath.endsWith(\"*\"), \"You rendered descendant <Routes> (or called `useRoutes()`) at \" + (\"\\\"\" + parentPathname + \"\\\" (under <Route path=\\\"\" + parentPath + \"\\\">) but the \") + \"parent route path has no trailing \\\"*\\\". This means if you navigate \" + \"deeper, the parent won't match anymore and therefore the child \" + \"routes will never render.\\n\\n\" + (\"Please change the parent <Route path=\\\"\" + parentPath + \"\\\"> to <Route \") + (\"path=\\\"\" + (parentPath === \"/\" ? \"*\" : parentPath + \"/*\") + \"\\\">.\"));\n }\n let locationFromContext = useLocation();\n let location;\n if (locationArg) {\n var _parsedLocationArg$pa;\n let parsedLocationArg = typeof locationArg === \"string\" ? parsePath(locationArg) : locationArg;\n !(parentPathnameBase === \"/\" || ((_parsedLocationArg$pa = parsedLocationArg.pathname) == null ? void 0 : _parsedLocationArg$pa.startsWith(parentPathnameBase))) ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, \"When overriding the location using `<Routes location>` or `useRoutes(routes, location)`, \" + \"the location pathname must begin with the portion of the URL pathname that was \" + (\"matched by all parent routes. The current pathname base is \\\"\" + parentPathnameBase + \"\\\" \") + (\"but pathname \\\"\" + parsedLocationArg.pathname + \"\\\" was given in the `location` prop.\")) : UNSAFE_invariant(false) : void 0;\n location = parsedLocationArg;\n } else {\n location = locationFromContext;\n }\n let pathname = location.pathname || \"/\";\n let remainingPathname = pathname;\n if (parentPathnameBase !== \"/\") {\n // Determine the remaining pathname by removing the # of URL segments the\n // parentPathnameBase has, instead of removing based on character count.\n // This is because we can't guarantee that incoming/outgoing encodings/\n // decodings will match exactly.\n // We decode paths before matching on a per-segment basis with\n // decodeURIComponent(), but we re-encode pathnames via `new URL()` so they\n // match what `window.location.pathname` would reflect. Those don't 100%\n // align when it comes to encoded URI characters such as % and &.\n //\n // So we may end up with:\n // pathname: \"/descendant/a%25b/match\"\n // parentPathnameBase: \"/descendant/a%b\"\n //\n // And the direct substring removal approach won't work :/\n let parentSegments = parentPathnameBase.replace(/^\\//, \"\").split(\"/\");\n let segments = pathname.replace(/^\\//, \"\").split(\"/\");\n remainingPathname = \"/\" + segments.slice(parentSegments.length).join(\"/\");\n }\n let matches = matchRoutes(routes, {\n pathname: remainingPathname\n });\n if (process.env.NODE_ENV !== \"production\") {\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(parentRoute || matches != null, \"No routes matched location \\\"\" + location.pathname + location.search + location.hash + \"\\\" \") : void 0;\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(matches == null || matches[matches.length - 1].route.element !== undefined || matches[matches.length - 1].route.Component !== undefined || matches[matches.length - 1].route.lazy !== undefined, \"Matched leaf route at location \\\"\" + location.pathname + location.search + location.hash + \"\\\" \" + \"does not have an element or Component. This means it will render an <Outlet /> with a \" + \"null value by default resulting in an \\\"empty\\\" page.\") : void 0;\n }\n let renderedMatches = _renderMatches(matches && matches.map(match => Object.assign({}, match, {\n params: Object.assign({}, parentParams, match.params),\n pathname: joinPaths([parentPathnameBase,\n // Re-encode pathnames that were decoded inside matchRoutes\n navigator.encodeLocation ? navigator.encodeLocation(match.pathname).pathname : match.pathname]),\n pathnameBase: match.pathnameBase === \"/\" ? parentPathnameBase : joinPaths([parentPathnameBase,\n // Re-encode pathnames that were decoded inside matchRoutes\n navigator.encodeLocation ? navigator.encodeLocation(match.pathnameBase).pathname : match.pathnameBase])\n })), parentMatches, dataRouterState, future);\n\n // When a user passes in a `locationArg`, the associated routes need to\n // be wrapped in a new `LocationContext.Provider` in order for `useLocation`\n // to use the scoped location instead of the global location.\n if (locationArg && renderedMatches) {\n return /*#__PURE__*/React.createElement(LocationContext.Provider, {\n value: {\n location: _extends({\n pathname: \"/\",\n search: \"\",\n hash: \"\",\n state: null,\n key: \"default\"\n }, location),\n navigationType: Action.Pop\n }\n }, renderedMatches);\n }\n return renderedMatches;\n}\nfunction DefaultErrorComponent() {\n let error = useRouteError();\n let message = isRouteErrorResponse(error) ? error.status + \" \" + error.statusText : error instanceof Error ? error.message : JSON.stringify(error);\n let stack = error instanceof Error ? error.stack : null;\n let lightgrey = \"rgba(200,200,200, 0.5)\";\n let preStyles = {\n padding: \"0.5rem\",\n backgroundColor: lightgrey\n };\n let codeStyles = {\n padding: \"2px 4px\",\n backgroundColor: lightgrey\n };\n let devInfo = null;\n if (process.env.NODE_ENV !== \"production\") {\n console.error(\"Error handled by React Router default ErrorBoundary:\", error);\n devInfo = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(\"p\", null, \"\\uD83D\\uDCBF Hey developer \\uD83D\\uDC4B\"), /*#__PURE__*/React.createElement(\"p\", null, \"You can provide a way better UX than this when your app throws errors by providing your own \", /*#__PURE__*/React.createElement(\"code\", {\n style: codeStyles\n }, \"ErrorBoundary\"), \" or\", \" \", /*#__PURE__*/React.createElement(\"code\", {\n style: codeStyles\n }, \"errorElement\"), \" prop on your route.\"));\n }\n return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(\"h2\", null, \"Unexpected Application Error!\"), /*#__PURE__*/React.createElement(\"h3\", {\n style: {\n fontStyle: \"italic\"\n }\n }, message), stack ? /*#__PURE__*/React.createElement(\"pre\", {\n style: preStyles\n }, stack) : null, devInfo);\n}\nconst defaultErrorElement = /*#__PURE__*/React.createElement(DefaultErrorComponent, null);\nclass RenderErrorBoundary extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n location: props.location,\n revalidation: props.revalidation,\n error: props.error\n };\n }\n static getDerivedStateFromError(error) {\n return {\n error: error\n };\n }\n static getDerivedStateFromProps(props, state) {\n // When we get into an error state, the user will likely click \"back\" to the\n // previous page that didn't have an error. Because this wraps the entire\n // application, that will have no effect--the error page continues to display.\n // This gives us a mechanism to recover from the error when the location changes.\n //\n // Whether we're in an error state or not, we update the location in state\n // so that when we are in an error state, it gets reset when a new location\n // comes in and the user recovers from the error.\n if (state.location !== props.location || state.revalidation !== \"idle\" && props.revalidation === \"idle\") {\n return {\n error: props.error,\n location: props.location,\n revalidation: props.revalidation\n };\n }\n\n // If we're not changing locations, preserve the location but still surface\n // any new errors that may come through. We retain the existing error, we do\n // this because the error provided from the app state may be cleared without\n // the location changing.\n return {\n error: props.error !== undefined ? props.error : state.error,\n location: state.location,\n revalidation: props.revalidation || state.revalidation\n };\n }\n componentDidCatch(error, errorInfo) {\n console.error(\"React Router caught the following error during render\", error, errorInfo);\n }\n render() {\n return this.state.error !== undefined ? /*#__PURE__*/React.createElement(RouteContext.Provider, {\n value: this.props.routeContext\n }, /*#__PURE__*/React.createElement(RouteErrorContext.Provider, {\n value: this.state.error,\n children: this.props.component\n })) : this.props.children;\n }\n}\nfunction RenderedRoute(_ref) {\n let {\n routeContext,\n match,\n children\n } = _ref;\n let dataRouterContext = React.useContext(DataRouterContext);\n\n // Track how deep we got in our render pass to emulate SSR componentDidCatch\n // in a DataStaticRouter\n if (dataRouterContext && dataRouterContext.static && dataRouterContext.staticContext && (match.route.errorElement || match.route.ErrorBoundary)) {\n dataRouterContext.staticContext._deepestRenderedBoundaryId = match.route.id;\n }\n return /*#__PURE__*/React.createElement(RouteContext.Provider, {\n value: routeContext\n }, children);\n}\nfunction _renderMatches(matches, parentMatches, dataRouterState, future) {\n var _dataRouterState;\n if (parentMatches === void 0) {\n parentMatches = [];\n }\n if (dataRouterState === void 0) {\n dataRouterState = null;\n }\n if (future === void 0) {\n future = null;\n }\n if (matches == null) {\n var _future;\n if (!dataRouterState) {\n return null;\n }\n if (dataRouterState.errors) {\n // Don't bail if we have data router errors so we can render them in the\n // boundary. Use the pre-matched (or shimmed) matches\n matches = dataRouterState.matches;\n } else if ((_future = future) != null && _future.v7_partialHydration && parentMatches.length === 0 && !dataRouterState.initialized && dataRouterState.matches.length > 0) {\n // Don't bail if we're initializing with partial hydration and we have\n // router matches. That means we're actively running `patchRoutesOnNavigation`\n // so we should render down the partial matches to the appropriate\n // `HydrateFallback`. We only do this if `parentMatches` is empty so it\n // only impacts the root matches for `RouterProvider` and no descendant\n // `<Routes>`\n matches = dataRouterState.matches;\n } else {\n return null;\n }\n }\n let renderedMatches = matches;\n\n // If we have data errors, trim matches to the highest error boundary\n let errors = (_dataRouterState = dataRouterState) == null ? void 0 : _dataRouterState.errors;\n if (errors != null) {\n let errorIndex = renderedMatches.findIndex(m => m.route.id && (errors == null ? void 0 : errors[m.route.id]) !== undefined);\n !(errorIndex >= 0) ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, \"Could not find a matching route for errors on route IDs: \" + Object.keys(errors).join(\",\")) : UNSAFE_invariant(false) : void 0;\n renderedMatches = renderedMatches.slice(0, Math.min(renderedMatches.length, errorIndex + 1));\n }\n\n // If we're in a partial hydration mode, detect if we need to render down to\n // a given HydrateFallback while we load the rest of the hydration data\n let renderFallback = false;\n let fallbackIndex = -1;\n if (dataRouterState && future && future.v7_partialHydration) {\n for (let i = 0; i < renderedMatches.length; i++) {\n let match = renderedMatches[i];\n // Track the deepest fallback up until the first route without data\n if (match.route.HydrateFallback || match.route.hydrateFallbackElement) {\n fallbackIndex = i;\n }\n if (match.route.id) {\n let {\n loaderData,\n errors\n } = dataRouterState;\n let needsToRunLoader = match.route.loader && loaderData[match.route.id] === undefined && (!errors || errors[match.route.id] === undefined);\n if (match.route.lazy || needsToRunLoader) {\n // We found the first route that's not ready to render (waiting on\n // lazy, or has a loader that hasn't run yet). Flag that we need to\n // render a fallback and render up until the appropriate fallback\n renderFallback = true;\n if (fallbackIndex >= 0) {\n renderedMatches = renderedMatches.slice(0, fallbackIndex + 1);\n } else {\n renderedMatches = [renderedMatches[0]];\n }\n break;\n }\n }\n }\n }\n return renderedMatches.reduceRight((outlet, match, index) => {\n // Only data routers handle errors/fallbacks\n let error;\n let shouldRenderHydrateFallback = false;\n let errorElement = null;\n let hydrateFallbackElement = null;\n if (dataRouterState) {\n error = errors && match.route.id ? errors[match.route.id] : undefined;\n errorElement = match.route.errorElement || defaultErrorElement;\n if (renderFallback) {\n if (fallbackIndex < 0 && index === 0) {\n warningOnce(\"route-fallback\", false, \"No `HydrateFallback` element provided to render during initial hydration\");\n shouldRenderHydrateFallback = true;\n hydrateFallbackElement = null;\n } else if (fallbackIndex === index) {\n shouldRenderHydrateFallback = true;\n hydrateFallbackElement = match.route.hydrateFallbackElement || null;\n }\n }\n }\n let matches = parentMatches.concat(renderedMatches.slice(0, index + 1));\n let getChildren = () => {\n let children;\n if (error) {\n children = errorElement;\n } else if (shouldRenderHydrateFallback) {\n children = hydrateFallbackElement;\n } else if (match.route.Component) {\n // Note: This is a de-optimized path since React won't re-use the\n // ReactElement since it's identity changes with each new\n // React.createElement call. We keep this so folks can use\n // `<Route Component={...}>` in `<Routes>` but generally `Component`\n // usage is only advised in `RouterProvider` when we can convert it to\n // `element` ahead of time.\n children = /*#__PURE__*/React.createElement(match.route.Component, null);\n } else if (match.route.element) {\n children = match.route.element;\n } else {\n children = outlet;\n }\n return /*#__PURE__*/React.createElement(RenderedRoute, {\n match: match,\n routeContext: {\n outlet,\n matches,\n isDataRoute: dataRouterState != null\n },\n children: children\n });\n };\n // Only wrap in an error boundary within data router usages when we have an\n // ErrorBoundary/errorElement on this route. Otherwise let it bubble up to\n // an ancestor ErrorBoundary/errorElement\n return dataRouterState && (match.route.ErrorBoundary || match.route.errorElement || index === 0) ? /*#__PURE__*/React.createElement(RenderErrorBoundary, {\n location: dataRouterState.location,\n revalidation: dataRouterState.revalidation,\n component: errorElement,\n error: error,\n children: getChildren(),\n routeContext: {\n outlet: null,\n matches,\n isDataRoute: true\n }\n }) : getChildren();\n }, null);\n}\nvar DataRouterHook = /*#__PURE__*/function (DataRouterHook) {\n DataRouterHook[\"UseBlocker\"] = \"useBlocker\";\n DataRouterHook[\"UseRevalidator\"] = \"useRevalidator\";\n DataRouterHook[\"UseNavigateStable\"] = \"useNavigate\";\n return DataRouterHook;\n}(DataRouterHook || {});\nvar DataRouterStateHook = /*#__PURE__*/function (DataRouterStateHook) {\n DataRouterStateHook[\"UseBlocker\"] = \"useBlocker\";\n DataRouterStateHook[\"UseLoaderData\"] = \"useLoaderData\";\n DataRouterStateHook[\"UseActionData\"] = \"useActionData\";\n DataRouterStateHook[\"UseRouteError\"] = \"useRouteError\";\n DataRouterStateHook[\"UseNavigation\"] = \"useNavigation\";\n DataRouterStateHook[\"UseRouteLoaderData\"] = \"useRouteLoaderData\";\n DataRouterStateHook[\"UseMatches\"] = \"useMatches\";\n DataRouterStateHook[\"UseRevalidator\"] = \"useRevalidator\";\n DataRouterStateHook[\"UseNavigateStable\"] = \"useNavigate\";\n DataRouterStateHook[\"UseRouteId\"] = \"useRouteId\";\n return DataRouterStateHook;\n}(DataRouterStateHook || {});\nfunction getDataRouterConsoleError(hookName) {\n return hookName + \" must be used within a data router. See https://reactrouter.com/v6/routers/picking-a-router.\";\n}\nfunction useDataRouterContext(hookName) {\n let ctx = React.useContext(DataRouterContext);\n !ctx ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, getDataRouterConsoleError(hookName)) : UNSAFE_invariant(false) : void 0;\n return ctx;\n}\nfunction useDataRouterState(hookName) {\n let state = React.useContext(DataRouterStateContext);\n !state ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, getDataRouterConsoleError(hookName)) : UNSAFE_invariant(false) : void 0;\n return state;\n}\nfunction useRouteContext(hookName) {\n let route = React.useContext(RouteContext);\n !route ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, getDataRouterConsoleError(hookName)) : UNSAFE_invariant(false) : void 0;\n return route;\n}\n\n// Internal version with hookName-aware debugging\nfunction useCurrentRouteId(hookName) {\n let route = useRouteContext(hookName);\n let thisRoute = route.matches[route.matches.length - 1];\n !thisRoute.route.id ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, hookName + \" can only be used on routes that contain a unique \\\"id\\\"\") : UNSAFE_invariant(false) : void 0;\n return thisRoute.route.id;\n}\n\n/**\n * Returns the ID for the nearest contextual route\n */\nfunction useRouteId() {\n return useCurrentRouteId(DataRouterStateHook.UseRouteId);\n}\n\n/**\n * Returns the current navigation, defaulting to an \"idle\" navigation when\n * no navigation is in progress\n */\nfunction useNavigation() {\n let state = useDataRouterState(DataRouterStateHook.UseNavigation);\n return state.navigation;\n}\n\n/**\n * Returns a revalidate function for manually triggering revalidation, as well\n * as the current state of any manual revalidations\n */\nfunction useRevalidator() {\n let dataRouterContext = useDataRouterContext(DataRouterHook.UseRevalidator);\n let state = useDataRouterState(DataRouterStateHook.UseRevalidator);\n return React.useMemo(() => ({\n revalidate: dataRouterContext.router.revalidate,\n state: state.revalidation\n }), [dataRouterContext.router.revalidate, state.revalidation]);\n}\n\n/**\n * Returns the active route matches, useful for accessing loaderData for\n * parent/child routes or the route \"handle\" property\n */\nfunction useMatches() {\n let {\n matches,\n loaderData\n } = useDataRouterState(DataRouterStateHook.UseMatches);\n return React.useMemo(() => matches.map(m => UNSAFE_convertRouteMatchToUiMatch(m, loaderData)), [matches, loaderData]);\n}\n\n/**\n * Returns the loader data for the nearest ancestor Route loader\n */\nfunction useLoaderData() {\n let state = useDataRouterState(DataRouterStateHook.UseLoaderData);\n let routeId = useCurrentRouteId(DataRouterStateHook.UseLoaderData);\n if (state.errors && state.errors[routeId] != null) {\n console.error(\"You cannot `useLoaderData` in an errorElement (routeId: \" + routeId + \")\");\n return undefined;\n }\n return state.loaderData[routeId];\n}\n\n/**\n * Returns the loaderData for the given routeId\n */\nfunction useRouteLoaderData(routeId) {\n let state = useDataRouterState(DataRouterStateHook.UseRouteLoaderData);\n return state.loaderData[routeId];\n}\n\n/**\n * Returns the action data for the nearest ancestor Route action\n */\nfunction useActionData() {\n let state = useDataRouterState(DataRouterStateHook.UseActionData);\n let routeId = useCurrentRouteId(DataRouterStateHook.UseLoaderData);\n return state.actionData ? state.actionData[routeId] : undefined;\n}\n\n/**\n * Returns the nearest ancestor Route error, which could be a loader/action\n * error or a render error. This is intended to be called from your\n * ErrorBoundary/errorElement to display a proper error message.\n */\nfunction useRouteError() {\n var _state$errors;\n let error = React.useContext(RouteErrorContext);\n let state = useDataRouterState(DataRouterStateHook.UseRouteError);\n let routeId = useCurrentRouteId(DataRouterStateHook.UseRouteError);\n\n // If this was a render error, we put it in a RouteError context inside\n // of RenderErrorBoundary\n if (error !== undefined) {\n return error;\n }\n\n // Otherwise look for errors from our data router state\n return (_state$errors = state.errors) == null ? void 0 : _state$errors[routeId];\n}\n\n/**\n * Returns the happy-path data from the nearest ancestor `<Await />` value\n */\nfunction useAsyncValue() {\n let value = React.useContext(AwaitContext);\n return value == null ? void 0 : value._data;\n}\n\n/**\n * Returns the error from the nearest ancestor `<Await />` value\n */\nfunction useAsyncError() {\n let value = React.useContext(AwaitContext);\n return value == null ? void 0 : value._error;\n}\nlet blockerId = 0;\n\n/**\n * Allow the application to block navigations within the SPA and present the\n * user a confirmation dialog to confirm the navigation. Mostly used to avoid\n * using half-filled form data. This does not handle hard-reloads or\n * cross-origin navigations.\n */\nfunction useBlocker(shouldBlock) {\n let {\n router,\n basename\n } = useDataRouterContext(DataRouterHook.UseBlocker);\n let state = useDataRouterState(DataRouterStateHook.UseBlocker);\n let [blockerKey, setBlockerKey] = React.useState(\"\");\n let blockerFunction = React.useCallback(arg => {\n if (typeof shouldBlock !== \"function\") {\n return !!shouldBlock;\n }\n if (basename === \"/\") {\n return shouldBlock(arg);\n }\n\n // If they provided us a function and we've got an active basename, strip\n // it from the locations we expose to the user to match the behavior of\n // useLocation\n let {\n currentLocation,\n nextLocation,\n historyAction\n } = arg;\n return shouldBlock({\n currentLocation: _extends({}, currentLocation, {\n pathname: stripBasename(currentLocation.pathname, basename) || currentLocation.pathname\n }),\n nextLocation: _extends({}, nextLocation, {\n pathname: stripBasename(nextLocation.pathname, basename) || nextLocation.pathname\n }),\n historyAction\n });\n }, [basename, shouldBlock]);\n\n // This effect is in charge of blocker key assignment and deletion (which is\n // tightly coupled to the key)\n React.useEffect(() => {\n let key = String(++blockerId);\n setBlockerKey(key);\n return () => router.deleteBlocker(key);\n }, [router]);\n\n // This effect handles assigning the blockerFunction. This is to handle\n // unstable blocker function identities, and happens only after the prior\n // effect so we don't get an orphaned blockerFunction in the router with a\n // key of \"\". Until then we just have the IDLE_BLOCKER.\n React.useEffect(() => {\n if (blockerKey !== \"\") {\n router.getBlocker(blockerKey, blockerFunction);\n }\n }, [router, blockerKey, blockerFunction]);\n\n // Prefer the blocker from `state` not `router.state` since DataRouterContext\n // is memoized so this ensures we update on blocker state updates\n return blockerKey && state.blockers.has(blockerKey) ? state.blockers.get(blockerKey) : IDLE_BLOCKER;\n}\n\n/**\n * Stable version of useNavigate that is used when we are in the context of\n * a RouterProvider.\n */\nfunction useNavigateStable() {\n let {\n router\n } = useDataRouterContext(DataRouterHook.UseNavigateStable);\n let id = useCurrentRouteId(DataRouterStateHook.UseNavigateStable);\n let activeRef = React.useRef(false);\n useIsomorphicLayoutEffect(() => {\n activeRef.current = true;\n });\n let navigate = React.useCallback(function (to, options) {\n if (options === void 0) {\n options = {};\n }\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(activeRef.current, navigateEffectWarning) : void 0;\n\n // Short circuit here since if this happens on first render the navigate\n // is useless because we haven't wired up our router subscriber yet\n if (!activeRef.current) return;\n if (typeof to === \"number\") {\n router.navigate(to);\n } else {\n router.navigate(to, _extends({\n fromRouteId: id\n }, options));\n }\n }, [router, id]);\n return navigate;\n}\nconst alreadyWarned$1 = {};\nfunction warningOnce(key, cond, message) {\n if (!cond && !alreadyWarned$1[key]) {\n alreadyWarned$1[key] = true;\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(false, message) : void 0;\n }\n}\n\nconst alreadyWarned = {};\nfunction warnOnce(key, message) {\n if (process.env.NODE_ENV !== \"production\" && !alreadyWarned[message]) {\n alreadyWarned[message] = true;\n console.warn(message);\n }\n}\nconst logDeprecation = (flag, msg, link) => warnOnce(flag, \"\\u26A0\\uFE0F React Router Future Flag Warning: \" + msg + \". \" + (\"You can use the `\" + flag + \"` future flag to opt-in early. \") + (\"For more information, see \" + link + \".\"));\nfunction logV6DeprecationWarnings(renderFuture, routerFuture) {\n if ((renderFuture == null ? void 0 : renderFuture.v7_startTransition) === undefined) {\n logDeprecation(\"v7_startTransition\", \"React Router will begin wrapping state updates in `React.startTransition` in v7\", \"https://reactrouter.com/v6/upgrading/future#v7_starttransition\");\n }\n if ((renderFuture == null ? void 0 : renderFuture.v7_relativeSplatPath) === undefined && (!routerFuture || routerFuture.v7_relativeSplatPath === undefined)) {\n logDeprecation(\"v7_relativeSplatPath\", \"Relative route resolution within Splat routes is changing in v7\", \"https://reactrouter.com/v6/upgrading/future#v7_relativesplatpath\");\n }\n if (routerFuture) {\n if (routerFuture.v7_fetcherPersist === undefined) {\n logDeprecation(\"v7_fetcherPersist\", \"The persistence behavior of fetchers is changing in v7\", \"https://reactrouter.com/v6/upgrading/future#v7_fetcherpersist\");\n }\n if (routerFuture.v7_normalizeFormMethod === undefined) {\n logDeprecation(\"v7_normalizeFormMethod\", \"Casing of `formMethod` fields is being normalized to uppercase in v7\", \"https://reactrouter.com/v6/upgrading/future#v7_normalizeformmethod\");\n }\n if (routerFuture.v7_partialHydration === undefined) {\n logDeprecation(\"v7_partialHydration\", \"`RouterProvider` hydration behavior is changing in v7\", \"https://reactrouter.com/v6/upgrading/future#v7_partialhydration\");\n }\n if (routerFuture.v7_skipActionErrorRevalidation === undefined) {\n logDeprecation(\"v7_skipActionErrorRevalidation\", \"The revalidation behavior after 4xx/5xx `action` responses is changing in v7\", \"https://reactrouter.com/v6/upgrading/future#v7_skipactionerrorrevalidation\");\n }\n }\n}\n\n/**\n Webpack + React 17 fails to compile on any of the following because webpack\n complains that `startTransition` doesn't exist in `React`:\n * import { startTransition } from \"react\"\n * import * as React from from \"react\";\n \"startTransition\" in React ? React.startTransition(() => setState()) : setState()\n * import * as React from from \"react\";\n \"startTransition\" in React ? React[\"startTransition\"](() => setState()) : setState()\n\n Moving it to a constant such as the following solves the Webpack/React 17 issue:\n * import * as React from from \"react\";\n const START_TRANSITION = \"startTransition\";\n START_TRANSITION in React ? React[START_TRANSITION](() => setState()) : setState()\n\n However, that introduces webpack/terser minification issues in production builds\n in React 18 where minification/obfuscation ends up removing the call of\n React.startTransition entirely from the first half of the ternary. Grabbing\n this exported reference once up front resolves that issue.\n\n See https://github.com/remix-run/react-router/issues/10579\n*/\nconst START_TRANSITION = \"startTransition\";\nconst startTransitionImpl = React[START_TRANSITION];\n\n/**\n * Given a Remix Router instance, render the appropriate UI\n */\nfunction RouterProvider(_ref) {\n let {\n fallbackElement,\n router,\n future\n } = _ref;\n let [state, setStateImpl] = React.useState(router.state);\n let {\n v7_startTransition\n } = future || {};\n let setState = React.useCallback(newState => {\n if (v7_startTransition && startTransitionImpl) {\n startTransitionImpl(() => setStateImpl(newState));\n } else {\n setStateImpl(newState);\n }\n }, [setStateImpl, v7_startTransition]);\n\n // Need to use a layout effect here so we are subscribed early enough to\n // pick up on any render-driven redirects/navigations (useEffect/<Navigate>)\n React.useLayoutEffect(() => router.subscribe(setState), [router, setState]);\n React.useEffect(() => {\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(fallbackElement == null || !router.future.v7_partialHydration, \"`<RouterProvider fallbackElement>` is deprecated when using \" + \"`v7_partialHydration`, use a `HydrateFallback` component instead\") : void 0;\n // Only log this once on initial mount\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n let navigator = React.useMemo(() => {\n return {\n createHref: router.createHref,\n encodeLocation: router.encodeLocation,\n go: n => router.navigate(n),\n push: (to, state, opts) => router.navigate(to, {\n state,\n preventScrollReset: opts == null ? void 0 : opts.preventScrollReset\n }),\n replace: (to, state, opts) => router.navigate(to, {\n replace: true,\n state,\n preventScrollReset: opts == null ? void 0 : opts.preventScrollReset\n })\n };\n }, [router]);\n let basename = router.basename || \"/\";\n let dataRouterContext = React.useMemo(() => ({\n router,\n navigator,\n static: false,\n basename\n }), [router, navigator, basename]);\n React.useEffect(() => logV6DeprecationWarnings(future, router.future), [router, future]);\n\n // The fragment and {null} here are important! We need them to keep React 18's\n // useId happy when we are server-rendering since we may have a <script> here\n // containing the hydrated server-side staticContext (from StaticRouterProvider).\n // useId relies on the component tree structure to generate deterministic id's\n // so we need to ensure it remains the same on the client even though\n // we don't need the <script> tag\n return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(DataRouterContext.Provider, {\n value: dataRouterContext\n }, /*#__PURE__*/React.createElement(DataRouterStateContext.Provider, {\n value: state\n }, /*#__PURE__*/React.createElement(Router, {\n basename: basename,\n location: state.location,\n navigationType: state.historyAction,\n navigator: navigator,\n future: {\n v7_relativeSplatPath: router.future.v7_relativeSplatPath\n }\n }, state.initialized || router.future.v7_partialHydration ? /*#__PURE__*/React.createElement(DataRoutes, {\n routes: router.routes,\n future: router.future,\n state: state\n }) : fallbackElement))), null);\n}\nfunction DataRoutes(_ref2) {\n let {\n routes,\n future,\n state\n } = _ref2;\n return useRoutesImpl(routes, undefined, state, future);\n}\n/**\n * A `<Router>` that stores all entries in memory.\n *\n * @see https://reactrouter.com/v6/router-components/memory-router\n */\nfunction MemoryRouter(_ref3) {\n let {\n basename,\n children,\n initialEntries,\n initialIndex,\n future\n } = _ref3;\n let historyRef = React.useRef();\n if (historyRef.current == null) {\n historyRef.current = createMemoryHistory({\n initialEntries,\n initialIndex,\n v5Compat: true\n });\n }\n let history = historyRef.current;\n let [state, setStateImpl] = React.useState({\n action: history.action,\n location: history.location\n });\n let {\n v7_startTransition\n } = future || {};\n let setState = React.useCallback(newState => {\n v7_startTransition && startTransitionImpl ? startTransitionImpl(() => setStateImpl(newState)) : setStateImpl(newState);\n }, [setStateImpl, v7_startTransition]);\n React.useLayoutEffect(() => history.listen(setState), [history, setState]);\n React.useEffect(() => logV6DeprecationWarnings(future), [future]);\n return /*#__PURE__*/React.createElement(Router, {\n basename: basename,\n children: children,\n location: state.location,\n navigationType: state.action,\n navigator: history,\n future: future\n });\n}\n/**\n * Changes the current location.\n *\n * Note: This API is mostly useful in React.Component subclasses that are not\n * able to use hooks. In functional components, we recommend you use the\n * `useNavigate` hook instead.\n *\n * @see https://reactrouter.com/v6/components/navigate\n */\nfunction Navigate(_ref4) {\n let {\n to,\n replace,\n state,\n relative\n } = _ref4;\n !useInRouterContext() ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, // TODO: This error is probably because they somehow have 2 versions of\n // the router loaded. We can help them understand how to avoid that.\n \"<Navigate> may be used only in the context of a <Router> component.\") : UNSAFE_invariant(false) : void 0;\n let {\n future,\n static: isStatic\n } = React.useContext(NavigationContext);\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(!isStatic, \"<Navigate> must not be used on the initial render in a <StaticRouter>. \" + \"This is a no-op, but you should modify your code so the <Navigate> is \" + \"only ever rendered in response to some user interaction or state change.\") : void 0;\n let {\n matches\n } = React.useContext(RouteContext);\n let {\n pathname: locationPathname\n } = useLocation();\n let navigate = useNavigate();\n\n // Resolve the path outside of the effect so that when effects run twice in\n // StrictMode they navigate to the same place\n let path = resolveTo(to, UNSAFE_getResolveToMatches(matches, future.v7_relativeSplatPath), locationPathname, relative === \"path\");\n let jsonPath = JSON.stringify(path);\n React.useEffect(() => navigate(JSON.parse(jsonPath), {\n replace,\n state,\n relative\n }), [navigate, jsonPath, relative, replace, state]);\n return null;\n}\n/**\n * Renders the child route's element, if there is one.\n *\n * @see https://reactrouter.com/v6/components/outlet\n */\nfunction Outlet(props) {\n return useOutlet(props.context);\n}\n/**\n * Declares an element that should be rendered at a certain URL path.\n *\n * @see https://reactrouter.com/v6/components/route\n */\nfunction Route(_props) {\n process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, \"A <Route> is only ever to be used as the child of <Routes> element, \" + \"never rendered directly. Please wrap your <Route> in a <Routes>.\") : UNSAFE_invariant(false) ;\n}\n/**\n * Provides location context for the rest of the app.\n *\n * Note: You usually won't render a `<Router>` directly. Instead, you'll render a\n * router that is more specific to your environment such as a `<BrowserRouter>`\n * in web browsers or a `<StaticRouter>` for server rendering.\n *\n * @see https://reactrouter.com/v6/router-components/router\n */\nfunction Router(_ref5) {\n let {\n basename: basenameProp = \"/\",\n children = null,\n location: locationProp,\n navigationType = Action.Pop,\n navigator,\n static: staticProp = false,\n future\n } = _ref5;\n !!useInRouterContext() ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, \"You cannot render a <Router> inside another <Router>.\" + \" You should never have more than one in your app.\") : UNSAFE_invariant(false) : void 0;\n\n // Preserve trailing slashes on basename, so we can let the user control\n // the enforcement of trailing slashes throughout the app\n let basename = basenameProp.replace(/^\\/*/, \"/\");\n let navigationContext = React.useMemo(() => ({\n basename,\n navigator,\n static: staticProp,\n future: _extends({\n v7_relativeSplatPath: false\n }, future)\n }), [basename, future, navigator, staticProp]);\n if (typeof locationProp === \"string\") {\n locationProp = parsePath(locationProp);\n }\n let {\n pathname = \"/\",\n search = \"\",\n hash = \"\",\n state = null,\n key = \"default\"\n } = locationProp;\n let locationContext = React.useMemo(() => {\n let trailingPathname = stripBasename(pathname, basename);\n if (trailingPathname == null) {\n return null;\n }\n return {\n location: {\n pathname: trailingPathname,\n search,\n hash,\n state,\n key\n },\n navigationType\n };\n }, [basename, pathname, search, hash, state, key, navigationType]);\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(locationContext != null, \"<Router basename=\\\"\" + basename + \"\\\"> is not able to match the URL \" + (\"\\\"\" + pathname + search + hash + \"\\\" because it does not start with the \") + \"basename, so the <Router> won't render anything.\") : void 0;\n if (locationContext == null) {\n return null;\n }\n return /*#__PURE__*/React.createElement(NavigationContext.Provider, {\n value: navigationContext\n }, /*#__PURE__*/React.createElement(LocationContext.Provider, {\n children: children,\n value: locationContext\n }));\n}\n/**\n * A container for a nested tree of `<Route>` elements that renders the branch\n * that best matches the current location.\n *\n * @see https://reactrouter.com/v6/components/routes\n */\nfunction Routes(_ref6) {\n let {\n children,\n location\n } = _ref6;\n return useRoutes(createRoutesFromChildren(children), location);\n}\n/**\n * Component to use for rendering lazily loaded data from returning defer()\n * in a loader function\n */\nfunction Await(_ref7) {\n let {\n children,\n errorElement,\n resolve\n } = _ref7;\n return /*#__PURE__*/React.createElement(AwaitErrorBoundary, {\n resolve: resolve,\n errorElement: errorElement\n }, /*#__PURE__*/React.createElement(ResolveAwait, null, children));\n}\nvar AwaitRenderStatus = /*#__PURE__*/function (AwaitRenderStatus) {\n AwaitRenderStatus[AwaitRenderStatus[\"pending\"] = 0] = \"pending\";\n AwaitRenderStatus[AwaitRenderStatus[\"success\"] = 1] = \"success\";\n AwaitRenderStatus[AwaitRenderStatus[\"error\"] = 2] = \"error\";\n return AwaitRenderStatus;\n}(AwaitRenderStatus || {});\nconst neverSettledPromise = new Promise(() => {});\nclass AwaitErrorBoundary extends React.Component {\n constructor(props) {\n super(props);\n this.state = {\n error: null\n };\n }\n static getDerivedStateFromError(error) {\n return {\n error\n };\n }\n componentDidCatch(error, errorInfo) {\n console.error(\"<Await> caught the following error during render\", error, errorInfo);\n }\n render() {\n let {\n children,\n errorElement,\n resolve\n } = this.props;\n let promise = null;\n let status = AwaitRenderStatus.pending;\n if (!(resolve instanceof Promise)) {\n // Didn't get a promise - provide as a resolved promise\n status = AwaitRenderStatus.success;\n promise = Promise.resolve();\n Object.defineProperty(promise, \"_tracked\", {\n get: () => true\n });\n Object.defineProperty(promise, \"_data\", {\n get: () => resolve\n });\n } else if (this.state.error) {\n // Caught a render error, provide it as a rejected promise\n status = AwaitRenderStatus.error;\n let renderError = this.state.error;\n promise = Promise.reject().catch(() => {}); // Avoid unhandled rejection warnings\n Object.defineProperty(promise, \"_tracked\", {\n get: () => true\n });\n Object.defineProperty(promise, \"_error\", {\n get: () => renderError\n });\n } else if (resolve._tracked) {\n // Already tracked promise - check contents\n promise = resolve;\n status = \"_error\" in promise ? AwaitRenderStatus.error : \"_data\" in promise ? AwaitRenderStatus.success : AwaitRenderStatus.pending;\n } else {\n // Raw (untracked) promise - track it\n status = AwaitRenderStatus.pending;\n Object.defineProperty(resolve, \"_tracked\", {\n get: () => true\n });\n promise = resolve.then(data => Object.defineProperty(resolve, \"_data\", {\n get: () => data\n }), error => Object.defineProperty(resolve, \"_error\", {\n get: () => error\n }));\n }\n if (status === AwaitRenderStatus.error && promise._error instanceof AbortedDeferredError) {\n // Freeze the UI by throwing a never resolved promise\n throw neverSettledPromise;\n }\n if (status === AwaitRenderStatus.error && !errorElement) {\n // No errorElement, throw to the nearest route-level error boundary\n throw promise._error;\n }\n if (status === AwaitRenderStatus.error) {\n // Render via our errorElement\n return /*#__PURE__*/React.createElement(AwaitContext.Provider, {\n value: promise,\n children: errorElement\n });\n }\n if (status === AwaitRenderStatus.success) {\n // Render children with resolved value\n return /*#__PURE__*/React.createElement(AwaitContext.Provider, {\n value: promise,\n children: children\n });\n }\n\n // Throw to the suspense boundary\n throw promise;\n }\n}\n\n/**\n * @private\n * Indirection to leverage useAsyncValue for a render-prop API on `<Await>`\n */\nfunction ResolveAwait(_ref8) {\n let {\n children\n } = _ref8;\n let data = useAsyncValue();\n let toRender = typeof children === \"function\" ? children(data) : children;\n return /*#__PURE__*/React.createElement(React.Fragment, null, toRender);\n}\n\n///////////////////////////////////////////////////////////////////////////////\n// UTILS\n///////////////////////////////////////////////////////////////////////////////\n\n/**\n * Creates a route config from a React \"children\" object, which is usually\n * either a `<Route>` element or an array of them. Used internally by\n * `<Routes>` to create a route config from its children.\n *\n * @see https://reactrouter.com/v6/utils/create-routes-from-children\n */\nfunction createRoutesFromChildren(children, parentPath) {\n if (parentPath === void 0) {\n parentPath = [];\n }\n let routes = [];\n React.Children.forEach(children, (element, index) => {\n if (! /*#__PURE__*/React.isValidElement(element)) {\n // Ignore non-elements. This allows people to more easily inline\n // conditionals in their route config.\n return;\n }\n let treePath = [...parentPath, index];\n if (element.type === React.Fragment) {\n // Transparently support React.Fragment and its children.\n routes.push.apply(routes, createRoutesFromChildren(element.props.children, treePath));\n return;\n }\n !(element.type === Route) ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, \"[\" + (typeof element.type === \"string\" ? element.type : element.type.name) + \"] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>\") : UNSAFE_invariant(false) : void 0;\n !(!element.props.index || !element.props.children) ? process.env.NODE_ENV !== \"production\" ? UNSAFE_invariant(false, \"An index route cannot have child routes.\") : UNSAFE_invariant(false) : void 0;\n let route = {\n id: element.props.id || treePath.join(\"-\"),\n caseSensitive: element.props.caseSensitive,\n element: element.props.element,\n Component: element.props.Component,\n index: element.props.index,\n path: element.props.path,\n loader: element.props.loader,\n action: element.props.action,\n errorElement: element.props.errorElement,\n ErrorBoundary: element.props.ErrorBoundary,\n hasErrorBoundary: element.props.ErrorBoundary != null || element.props.errorElement != null,\n shouldRevalidate: element.props.shouldRevalidate,\n handle: element.props.handle,\n lazy: element.props.lazy\n };\n if (element.props.children) {\n route.children = createRoutesFromChildren(element.props.children, treePath);\n }\n routes.push(route);\n });\n return routes;\n}\n\n/**\n * Renders the result of `matchRoutes()` into a React element.\n */\nfunction renderMatches(matches) {\n return _renderMatches(matches);\n}\n\nfunction mapRouteProperties(route) {\n let updates = {\n // Note: this check also occurs in createRoutesFromChildren so update\n // there if you change this -- please and thank you!\n hasErrorBoundary: route.ErrorBoundary != null || route.errorElement != null\n };\n if (route.Component) {\n if (process.env.NODE_ENV !== \"production\") {\n if (route.element) {\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(false, \"You should not include both `Component` and `element` on your route - \" + \"`Component` will be used.\") : void 0;\n }\n }\n Object.assign(updates, {\n element: /*#__PURE__*/React.createElement(route.Component),\n Component: undefined\n });\n }\n if (route.HydrateFallback) {\n if (process.env.NODE_ENV !== \"production\") {\n if (route.hydrateFallbackElement) {\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(false, \"You should not include both `HydrateFallback` and `hydrateFallbackElement` on your route - \" + \"`HydrateFallback` will be used.\") : void 0;\n }\n }\n Object.assign(updates, {\n hydrateFallbackElement: /*#__PURE__*/React.createElement(route.HydrateFallback),\n HydrateFallback: undefined\n });\n }\n if (route.ErrorBoundary) {\n if (process.env.NODE_ENV !== \"production\") {\n if (route.errorElement) {\n process.env.NODE_ENV !== \"production\" ? UNSAFE_warning(false, \"You should not include both `ErrorBoundary` and `errorElement` on your route - \" + \"`ErrorBoundary` will be used.\") : void 0;\n }\n }\n Object.assign(updates, {\n errorElement: /*#__PURE__*/React.createElement(route.ErrorBoundary),\n ErrorBoundary: undefined\n });\n }\n return updates;\n}\nfunction createMemoryRouter(routes, opts) {\n return createRouter({\n basename: opts == null ? void 0 : opts.basename,\n future: _extends({}, opts == null ? void 0 : opts.future, {\n v7_prependBasename: true\n }),\n history: createMemoryHistory({\n initialEntries: opts == null ? void 0 : opts.initialEntries,\n initialIndex: opts == null ? void 0 : opts.initialIndex\n }),\n hydrationData: opts == null ? void 0 : opts.hydrationData,\n routes,\n mapRouteProperties,\n dataStrategy: opts == null ? void 0 : opts.dataStrategy,\n patchRoutesOnNavigation: opts == null ? void 0 : opts.patchRoutesOnNavigation\n }).initialize();\n}\n\nexport { Await, MemoryRouter, Navigate, Outlet, Route, Router, RouterProvider, Routes, DataRouterContext as UNSAFE_DataRouterContext, DataRouterStateContext as UNSAFE_DataRouterStateContext, LocationContext as UNSAFE_LocationContext, NavigationContext as UNSAFE_NavigationContext, RouteContext as UNSAFE_RouteContext, logV6DeprecationWarnings as UNSAFE_logV6DeprecationWarnings, mapRouteProperties as UNSAFE_mapRouteProperties, useRouteId as UNSAFE_useRouteId, useRoutesImpl as UNSAFE_useRoutesImpl, createMemoryRouter, createRoutesFromChildren, createRoutesFromChildren as createRoutesFromElements, renderMatches, useActionData, useAsyncError, useAsyncValue, useBlocker, useHref, useInRouterContext, useLoaderData, useLocation, useMatch, useMatches, useNavigate, useNavigation, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRevalidator, useRouteError, useRouteLoaderData, useRoutes };\n//# sourceMappingURL=index.js.map\n","/**\n * FormBuilderPage - Standalone form builder page component for user-defined routing\n *\n * @deprecated Use FormBuilderView directly with your framework's param reading\n */\n\nimport { useFormNavigation } from \"@formbuilder/forms/navigation\";\nimport type React from \"react\";\nimport { useParams } from \"react-router-dom\";\nimport type { FormConfig } from \"../../../config/types\";\nimport { FormBuilderView } from \"../../../features/form-management/components/FormBuilderView/FormBuilderView\";\nimport styles from \"./FormBuilderPage.module.css\";\n\nexport interface FormBuilderPageProps {\n\t/**\n\t * Optional form configuration\n\t */\n\tconfig?: FormConfig;\n\n\t/**\n\t * Optional CSS class name\n\t */\n\tclassName?: string;\n\n\t/**\n\t * Optional inline styles\n\t */\n\tstyle?: React.CSSProperties;\n}\n\n/**\n * Standalone FormBuilderPage component for user-defined routing\n * Shows the form builder for a specific form\n *\n * @deprecated Use FormBuilderView directly with your framework's param reading\n */\nexport const FormBuilderPage: React.FC<FormBuilderPageProps> = ({\n\tconfig,\n\tclassName,\n\tstyle,\n}) => {\n\tconst params = useParams();\n\tconst { project: projectId, wizardId } = params;\n\tconst { navigateToProjects } = useFormNavigation();\n\n\t// If no project ID or wizard ID in URL, show error state\n\tif (!projectId || !wizardId) {\n\t\treturn (\n\t\t\t<div className={styles.errorContainer}>\n\t\t\t\t<div className={styles.errorContent}>\n\t\t\t\t\t<h2 className={styles.errorHeading}>\n\t\t\t\t\t\tMissing Parameters\n\t\t\t\t\t</h2>\n\t\t\t\t\t<p className={styles.errorText}>\n\t\t\t\t\t\tProject ID or Form ID is missing from the URL.\n\t\t\t\t\t</p>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={() => navigateToProjects()}\n\t\t\t\t\t\tclassName={styles.backButton}\n\t\t\t\t\t>\n\t\t\t\t\t\tBack to Projects\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<FormBuilderView\n\t\t\tprojectId={projectId}\n\t\t\tformId={wizardId}\n\t\t\tconfig={config}\n\t\t\tclassName={className}\n\t\t\tstyle={style}\n\t\t/>\n\t);\n};\n","/**\n * FormsPage - Standalone forms page component for user-defined routing\n *\n * @deprecated Use FormsView directly with your framework's param reading\n */\n\nimport { useFormNavigation } from \"@formbuilder/forms/navigation\";\nimport type React from \"react\";\nimport { useParams } from \"react-router-dom\";\nimport { FormsView } from \"../../features/form-management/components/FormsView/FormsView\";\n\nexport interface FormsPageProps {\n\t/**\n\t * Optional CSS class name\n\t */\n\tclassName?: string;\n\n\t/**\n\t * Optional inline styles\n\t */\n\tstyle?: React.CSSProperties;\n}\n\n/**\n * Standalone FormsPage component for user-defined routing\n * Shows forms within a specific project\n *\n * @deprecated Use FormsView directly with your framework's param reading\n */\nexport const FormsPage: React.FC<FormsPageProps> = ({ className, style }) => {\n\tconst params = useParams();\n\tconst projectId = params.project;\n\tconst { navigateToProjects } = useFormNavigation();\n\n\t// If no project ID in URL, redirect to projects\n\tif (!projectId) {\n\t\tnavigateToProjects();\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<FormsView projectId={projectId} className={className} style={style} />\n\t);\n};\n","/**\n * ProjectsPage - Standalone projects page component for user-defined routing\n */\n\nimport type React from \"react\";\nimport { ProjectsView } from \"../ProjectsView/ProjectsView\";\n\nexport interface ProjectsPageProps {\n\t/**\n\t * Optional CSS class name\n\t */\n\tclassName?: string;\n\n\t/**\n\t * Optional inline styles\n\t */\n\tstyle?: React.CSSProperties;\n}\n\n/**\n * Standalone ProjectsPage component for user-defined routing\n * Shows the projects overview and allows navigation to forms\n */\nexport const ProjectsPage: React.FC<ProjectsPageProps> = ({\n\tclassName,\n\tstyle,\n}) => {\n\treturn <ProjectsView className={className} style={style} />;\n};\n","\"use client\";\n\n// Main FormBuilder component and related exports\n\n// Import fonts CSS to ensure they're available when using the library\nimport \"./styles/fonts.css\";\n\nexport { isFormFieldComponent } from \"./component-registry/components\";\n// ComponentValue and renderComponent now live in @formbuilder/ui; re-exported here for backward compat\nexport type { ComponentValue } from \"@formbuilder/ui\";\nexport { renderComponent } from \"@formbuilder/ui\";\n\n// Register builder's concrete renderComponent implementation so wizard consumers work at runtime\nimport {\n\trenderComponent as builderRenderComponent,\n} from \"./component-registry/components\";\nimport { registerRenderComponent } from \"@formbuilder/ui\";\nregisterRenderComponent(builderRenderComponent);\n// Configuration system - Unified configuration types\nexport {\n\tDEFAULT_FORM_CONFIG,\n\ttype FormConfig,\n\ttype FormStorageConfig,\n\tuseFormConfiguration,\n} from \"./config\";\nexport { FlowBuilderErrorBoundary } from \"./error-boundaries\";\nexport * from \"./features/condition-editor\";\nexport * from \"./features/dialog-system\";\nexport * from \"./features/form-builder\";\nexport * from \"./features/form-management\";\n/** @deprecated Use ProjectsView, FormsView, FormBuilderView with NavigationProvider instead */\nexport type { FormExplorerProps } from \"./features/form-management/components/FormExplorer/FormExplorer\";\n/** @deprecated Use ProjectsView, FormsView, FormBuilderView with NavigationProvider instead */\nexport { FormExplorer } from \"./features/form-management/components/FormExplorer/FormExplorer\";\nexport type {\n\t/** @deprecated Use FormBuilderView directly - FormBuilderPage requires react-router-dom */\n\tFormBuilderPageProps,\n\t/** @deprecated Use FormsView directly - FormsPage requires react-router-dom */\n\tFormsPageProps,\n\tProjectsPageProps,\n} from \"./features/form-management/components/pages\";\n// Export page components for user-defined routing\nexport {\n\t/** @deprecated Use FormBuilderView directly - FormBuilderPage requires react-router-dom */\n\tFormBuilderPage,\n\t/** @deprecated Use FormsView directly - FormsPage requires react-router-dom */\n\tFormsPage,\n\tProjectsPage,\n} from \"./features/form-management/components/pages\";\nexport * from \"./features/property-editors\";\nexport * from \"./features/template-system\";\n// Shared utilities and services\nexport { TemplateStorageService } from \"./features/template-system/services/TemplateStorageService\";\nexport * from \"./features/trigger-action-system\";\nexport * from \"./features/visual-mapping\";\nexport * from \"./providers\";\n// Note: FilesystemStorageProvider removed from exports - it uses node:fs/node:path\n// Import directly from './storage/FilesystemStorageProvider' in server-side code only\n// Export storage types\nexport type {\n\tCreateFormRequest,\n\tCreateProjectRequest,\n\tFileStorageError,\n\tFormBuilderSettings,\n\tFormFile,\n\tFormMetadata,\n\tFormStorageProvider,\n\tGenericTemplate,\n\tPersonalTemplate,\n\tSharedTemplate,\n\tStorageResult,\n\tTeamTemplate,\n\tTemplateCategory,\n\tTemplateCategoryInfo,\n\tTemplateDirectory,\n\tTemplateFile,\n\tTemplateStorageConfig,\n} from \"./storage/types\";\n// export * from \"./integrations\"; // Commented out to resolve useCurrentStep conflict\n// Selective exports to avoid useCurrentStep conflict\nexport type {\n\tComponentConfig,\n\tFormSectionConfig,\n\tFormStepConfig,\n\tFormWizardConfig,\n\tStepNavigation,\n\tStepNavigationItem,\n\tStepTemplate,\n\tTemplateHistoryEntry,\n} from \"./store\";\nexport {\n\tuseCanUndo,\n\tuseCurrentSection,\n\tuseFormBuilderActions,\n\tuseFormBuilderStore,\n\tuseFormConfig,\n\tuseFormSteps,\n\tuseHasUnsavedChanges,\n\tuseIsSaving,\n\tuseLastSavedAt,\n\tuseSaveError,\n\tuseSelectedSectionId,\n\tuseSelectedStepId,\n\t// useCurrentStep excluded to avoid conflict with features/form-builder\n} from \"./store\";\nexport * from \"./utils\";\nexport {\n\tgetDatabaseConfig,\n\tresolveConfigVariables,\n} from \"./utils/configReader\";\n// Utilities\nexport {\n\ttype FormOperationsConfig,\n\tformatProjectName,\n\tgetStorageProvider,\n\tloadFormConfigFromExplorer,\n\tregisterStorageStrategy,\n\ttype StorageStrategy,\n} from \"./utils/formsExplorer\";\n"],"names":["registeredRenderer","registerRenderComponent","fn","renderComponent","props","NavigationContext","createContext","useFormNavigation","context","useContext","useFormData","projectId","formId","config","useQuery","formConfig","getFormConfig","provider","StorageProviderFactory","result","FormBuilderView","showPreview","className","style","onSave","isLoading","error","navigateToForms","handleSave","updatedConfig","formConfigData","jsx","styles","jsxs","FormBuilder","formsQueryKeys","useFormsQuery","scanFormsDirectory","useCreateFormMutation","queryClient","useQueryClient","useMutation","request","createForm","newForm","previousProjects","old","project","_err","_newForm","useDeleteFormMutation","deleteForm","form","_variables","APP_NAME","BaseHeader","Heading","BaseLayout","title","subtitle","showBackButton","onBack","backButtonText","searchSlot","primaryAction","secondaryActions","children","Button","ChevronLeft","Paragraph","action","Plus","NewFormDialog","open","onOpenChange","selectedProjectId","onFormCreated","onFormAdded","onCreateForm","createFormMutation","useForm","value","toast","resultFormId","useEffect","handleCancel","useCallback","Dialog","DialogContent","DialogHeader","DialogTitle","DialogDescription","e","field","Label","Input","Textarea","DialogFooter","SearchInput","placeholder","onSearchChange","searchValue","setSearchValue","useState","handleSearchChange","Search","ViewCard","icon","description","metadata","dropdownActions","onClick","Card","CardHeader","DropdownMenu","DropdownMenuTrigger","MoreVertical","DropdownMenuContent","DropdownMenuItem","meta","CardDescription","CardContent","RhcButton","formatDate","timestamp","FormsView","formsProp","projectNameProp","isLoadingProp","onNavigateToProjects","onRefresh","onFormDeleted","searchQuery","setSearchQuery","showNewFormDialog","setShowNewFormDialog","navigateToProjects","navigateToBuilder","internalQuery","deleteFormMutation","internalProject","p","resolvedForms","resolvedProjectName","projectFound","filteredForms","handleCreateForm","handleFormCreated","createdProjectId","f","handleDeleteForm","handleEditForm","handleFormClick","handleBackToProjects","Fragment","FileText","Settings","Trash2","ChevronRight","useProjectActions","handleCreateProject","createProject","handleDeleteProject","storageProvider","deleteResult","formsResult","projectForms","deletedCount","success","handleNavigateToProject","projectsQueryKeys","useProjectsData","NewProjectDialog","onProjectCreated","onCreateProject","dialogReducer","state","initialDialogState","ProjectsView","projectsProp","onProjectDeleted","dialogState","dispatchDialog","useReducer","deleteProject","navigateToProject","projects","handleRefresh","filteredProjects","handleProjectCreated","confirmDeleteProject","projectName","errorMessage","userMessage","handleProjectClick","GridLayout","index","GridLayoutColumn","Folder","ConfirmDialog","ProjectCard","onEditForm","onDeleteForm","isExpanded","setIsExpanded","FolderOpen","CardTitle","MoreHorizontal","Separator","useFormExplorerState","autoLoad","setState","loadProjects","prev","operationsConfig","isCancelled","initializeFormConfiguration","timeoutPromise","_","reject","connectionError","query","setSelectedProject","addProjectOptimistic","removeProjectOptimistic","addFormOptimistic","removeFormOptimistic","refreshProjectsList","clearScanCache","invalidateCache","useFormOperations","onFormLoad","onFormCreate","onFormDelete","onFormSave","onFormEdit","onProjectsRefresh","useFormConfiguration","useMemo","formTitle","finalFormId","wizardId","loadFormConfigFromExplorer","handleSaveForm","saveFormConfig","useProjectOperations","DatabaseStatusIndicator","getSyncStatus","onForceSync","onReconnect","onValidateConsistency","onResetLocalData","onReconcileConflicts","capabilities","setCapabilities","syncStatus","setSyncStatus","showDetails","setShowDetails","updateCapabilities","providerCapabilities","handleProviderReady","event","handleOnline","handleOffline","interval","currentStatus","handleForceSync","handleReconnect","handleValidateConsistency","isConsistent","handleResetLocalData","handleReconcileConflicts","getStatusConfig","formatLastSync","date","diff","getDatabaseValueClass","getPersistenceValueClass","getIntegrityValueClass","ConnectionErrorScreen","onRetry","isRetrying","setIsRetrying","handleRetry","errorInfo","WifiOff","Wifi","RefreshCw","getStatusValueClass","AlertTriangle","createProjectsView","createBuilderView","FormExplorerCore","initialView","onNavigateToForms","currentView","setCurrentView","navigationInProgress","useRef","setProviderCapabilities","showNewProjectDialog","setShowNewProjectDialog","setStorageProvider","selectedProject","navigateToView","factory","view","navigateBack","navigationContext","projectData","handleFormSave","renderView","isDatabaseSetupError","FormExplorer","themeConfig","useThemeConfig","resolvedConfig","setResolvedConfig","setIsLoading","setError","processedConfig","resolveConfigVariables","configPath","response","rawConfig","loadError","ThemeProvider","DataRouterContext","React","DataRouterStateContext","AwaitContext","LocationContext","RouteContext","RouteErrorContext","useParams","matches","routeMatch","FormBuilderPage","params","FormsPage","ProjectsPage","builderRenderComponent"],"mappings":"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","x_google_ignoreList":[25]}