@structcms/admin 0.1.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/components/app/struct-cms-admin-app.tsx","../src/context/admin-context.tsx","../src/components/ui/toast.tsx","../src/lib/utils.ts","../src/context/auth-context.tsx","../src/hooks/use-api-client.ts","../src/hooks/use-admin.ts","../src/components/content/navigation-editor.tsx","../src/components/ui/button.tsx","../src/components/ui/input.tsx","../src/components/content/page-list.tsx","../src/components/ui/error-boundary.tsx","../src/components/dashboard/kpi-cards.tsx","../src/components/ui/skeleton.tsx","../src/components/dashboard/quick-actions.tsx","../src/components/dashboard/recent-pages.tsx","../src/components/dashboard/dashboard-page.tsx","../src/components/editors/page-editor.tsx","../src/lib/form-generator.tsx","../src/components/inputs/array-field.tsx","../src/components/ui/label.tsx","../src/components/inputs/image-picker.tsx","../src/components/media/media-browser.tsx","../src/components/ui/dialog.tsx","../src/components/inputs/object-field.tsx","../src/components/inputs/rich-text-editor.tsx","../src/components/inputs/string-input.tsx","../src/components/inputs/text-input.tsx","../src/components/ui/textarea.tsx","../src/components/editors/section-editor.tsx","../src/components/layout/admin-layout.tsx","../src/components/auth/login-form.tsx","../src/components/auth/protected-route.tsx","../src/components/auth/oauth-button.tsx"],"sourcesContent":["export {\n StructCMSAdminApp,\n type StructCMSAdminAppProps,\n type View,\n} from './components/app/struct-cms-admin-app';\nexport {\n AdminProvider,\n type AdminProviderProps,\n type AdminContextValue,\n} from './context/admin-context';\nexport { useAdmin } from './hooks/use-admin';\nexport {\n useApiClient,\n type ApiClient,\n type ApiResponse,\n type ApiError,\n} from './hooks/use-api-client';\nexport { StringInput, type StringInputProps } from './components/inputs/string-input';\nexport { TextInput, type TextInputProps } from './components/inputs/text-input';\nexport { RichTextEditor } from './components/inputs/rich-text-editor';\nexport type { RichTextEditorProps } from './components/inputs/rich-text-editor';\n\nexport { AuthProvider, useAuth } from './context/auth-context';\nexport type { AuthContextValue, AuthProviderProps } from './context/auth-context';\n\nexport { LoginForm, ProtectedRoute, OAuthButton } from './components/auth';\nexport type { LoginFormProps, ProtectedRouteProps, OAuthButtonProps } from './components/auth';\n\nexport { ImagePicker, type ImagePickerProps } from './components/inputs/image-picker';\nexport { ArrayField, type ArrayFieldProps } from './components/inputs/array-field';\nexport { ObjectField, type ObjectFieldProps } from './components/inputs/object-field';\nexport { Input, type InputProps } from './components/ui/input';\nexport { Textarea, type TextareaProps } from './components/ui/textarea';\nexport { Label, type LabelProps } from './components/ui/label';\nexport { Button, type ButtonProps, buttonVariants } from './components/ui/button';\nexport {\n FormGenerator,\n type FormGeneratorProps,\n resolveFieldType,\n fieldNameToLabel,\n} from './lib/form-generator';\nexport { SectionEditor, type SectionEditorProps } from './components/editors/section-editor';\nexport { PageEditor, type PageEditorProps } from './components/editors/page-editor';\nexport { PageList, type PageListProps, type PageSummary } from './components/content/page-list';\nexport {\n NavigationEditor,\n type NavigationEditorProps,\n} from './components/content/navigation-editor';\nexport {\n MediaBrowser,\n type MediaBrowserProps,\n type MediaItem,\n} from './components/media/media-browser';\nexport {\n AdminLayout,\n type AdminLayoutProps,\n type SidebarNavItem,\n} from './components/layout/admin-layout';\nexport { Skeleton, type SkeletonProps } from './components/ui/skeleton';\nexport {\n ToastProvider,\n useToast,\n type ToastProviderProps,\n type Toast,\n type ToastVariant,\n} from './components/ui/toast';\nexport { ErrorBoundary, type ErrorBoundaryProps } from './components/ui/error-boundary';\nexport { Dialog, type DialogProps } from './components/ui/dialog';\nexport { DashboardPage, type DashboardPageProps } from './components/dashboard/dashboard-page';\nexport { QuickActions, type QuickActionsProps } from './components/dashboard/quick-actions';\nexport { KpiCards, type KpiCardsProps } from './components/dashboard/kpi-cards';\nexport { RecentPages, type RecentPagesProps } from './components/dashboard/recent-pages';\nexport { cn } from './lib/utils';\n","import type { NavigationItem, Registry, SectionData } from '@structcms/core';\nimport type React from 'react';\nimport { useEffect, useState } from 'react';\nimport { AdminProvider } from '../../context/admin-context';\nimport { AuthProvider } from '../../context/auth-context';\nimport { useApiClient } from '../../hooks/use-api-client';\nimport { NavigationEditor } from '../content/navigation-editor';\nimport { PageList, type PageSummary } from '../content/page-list';\nimport { DashboardPage } from '../dashboard/dashboard-page';\nimport { PageEditor } from '../editors/page-editor';\nimport { AdminLayout, type SidebarNavItem } from '../layout/admin-layout';\nimport { MediaBrowser } from '../media/media-browser';\nimport { Skeleton } from '../ui/skeleton';\n\nexport interface StructCMSAdminAppProps {\n registry: Registry;\n apiBaseUrl?: string;\n className?: string;\n customNavItems?: SidebarNavItem[];\n renderView?: (view: View) => React.ReactNode | null;\n /**\n * If true, wraps the app in AuthProvider. When enabled, you should provide login/auth handling.\n * @default false\n */\n enableAuth?: boolean;\n /**\n * Callback when user authentication state changes\n */\n onAuthStateChange?: (user: import('../../context/auth-context').AuthContextValue['user']) => void;\n}\n\nexport type View =\n | { type: 'dashboard' }\n | { type: 'pages' }\n | { type: 'page-editor'; pageId?: string }\n | { type: 'media' }\n | { type: 'navigation' }\n | { type: 'custom'; path: string };\n\ninterface NavigationData {\n id: string;\n name: string;\n items: NavigationItem[];\n}\n\ninterface PageData {\n id: string;\n slug: string;\n title: string;\n pageType: string;\n sections: SectionData[];\n}\n\n// Custom hook for navigation data fetching\nfunction useNavigationData(currentView: View) {\n const apiClient = useApiClient();\n const [navigationData, setNavigationData] = useState<NavigationData | null>(null);\n const [navigationLoading, setNavigationLoading] = useState(false);\n const [navigationError, setNavigationError] = useState<string | null>(null);\n\n useEffect(() => {\n if (currentView.type !== 'navigation') {\n return;\n }\n\n const fetchNavigation = async () => {\n setNavigationLoading(true);\n setNavigationError(null);\n try {\n const response = await apiClient.get<NavigationData>('/navigation/main');\n if (response.error) {\n setNavigationError(response.error.message);\n } else if (response.data) {\n setNavigationData(response.data);\n }\n } catch (err) {\n setNavigationError('Failed to load navigation');\n console.error(err);\n } finally {\n setNavigationLoading(false);\n }\n };\n\n fetchNavigation();\n }, [currentView.type, apiClient]);\n\n return { navigationData, navigationLoading, navigationError, setNavigationData };\n}\n\n// Custom hook for page data fetching\nfunction usePageData(currentView: View) {\n const apiClient = useApiClient();\n const [pageData, setPageData] = useState<PageData | null>(null);\n const [pageLoading, setPageLoading] = useState(false);\n const [pageError, setPageError] = useState<string | null>(null);\n\n useEffect(() => {\n if (currentView.type !== 'page-editor') {\n return;\n }\n\n const pageId = currentView.pageId;\n if (!pageId) {\n return;\n }\n\n const fetchPage = async () => {\n setPageLoading(true);\n setPageError(null);\n try {\n const response = await apiClient.get<PageData>(`/pages/id/${pageId}`);\n if (response.error) {\n setPageError(response.error.message);\n } else if (response.data) {\n setPageData(response.data);\n }\n } catch (err) {\n setPageError('Failed to load page');\n console.error(err);\n } finally {\n setPageLoading(false);\n }\n };\n\n fetchPage();\n }, [currentView, apiClient]);\n\n return { pageData, pageLoading, pageError };\n}\n\n// Render page editor view with loading/error states\nfunction renderPageEditorView(\n currentView: View,\n pageData: PageData | null,\n pageLoading: boolean,\n pageError: string | null,\n registry: Registry,\n onSave: (sections: SectionData[]) => void\n): React.ReactNode {\n if (currentView.type !== 'page-editor') return null;\n\n if (currentView.pageId && pageLoading) {\n return (\n <div className=\"space-y-4\">\n <Skeleton className=\"h-8 w-48\" />\n <Skeleton className=\"h-64 w-full\" />\n </div>\n );\n }\n\n if (currentView.pageId && pageError) {\n return <div className=\"text-red-600\">Error: {pageError}</div>;\n }\n\n if (currentView.pageId && !pageData) {\n return <div className=\"text-gray-600\">Page not found</div>;\n }\n\n const sections = pageData?.sections ?? [];\n const allowedSections = pageData\n ? (registry.getPageType(pageData.pageType)?.allowedSections ?? [])\n : registry.getAllSections().map((s: { name: string }) => s.name);\n\n return <PageEditor sections={sections} allowedSections={allowedSections} onSave={onSave} />;\n}\n\n// Render navigation view with loading/error states\nfunction renderNavigationView(\n navigationData: NavigationData | null,\n navigationLoading: boolean,\n navigationError: string | null,\n onSave: (items: NavigationItem[]) => void\n): React.ReactNode {\n if (navigationLoading) {\n return (\n <div className=\"space-y-4\">\n <Skeleton className=\"h-8 w-48\" />\n <Skeleton className=\"h-64 w-full\" />\n </div>\n );\n }\n\n if (navigationError) {\n return <div className=\"text-red-600\">Error: {navigationError}</div>;\n }\n\n if (!navigationData) {\n return (\n <div className=\"text-gray-600\">No navigation found. Create one via the seed endpoint.</div>\n );\n }\n\n return <NavigationEditor items={navigationData.items} onSave={onSave} />;\n}\n\nfunction ViewRenderer({\n currentView,\n registry,\n customRenderView,\n onNavigate,\n onSelectPage,\n onCreatePage,\n onUploadMedia,\n}: {\n currentView: View;\n registry: Registry;\n customRenderView?: (view: View) => React.ReactNode | null;\n onNavigate: (view: View) => void;\n onSelectPage: (page: PageSummary) => void;\n onCreatePage: () => void;\n onUploadMedia: () => void;\n}) {\n const apiClient = useApiClient();\n const { navigationData, navigationLoading, navigationError, setNavigationData } =\n useNavigationData(currentView);\n const { pageData, pageLoading, pageError } = usePageData(currentView);\n\n const handleSaveNavigation = async (items: NavigationItem[]) => {\n if (!navigationData) return;\n\n try {\n const response = await apiClient.put(`/navigation/id/${navigationData.id}`, {\n items,\n });\n\n if (response.error) {\n console.error('Failed to update navigation:', response.error.message);\n } else if (response.data) {\n setNavigationData(response.data as NavigationData);\n }\n } catch (err) {\n console.error('Failed to update navigation:', err);\n }\n };\n\n const handleSavePage = async (updatedSections: SectionData[]) => {\n if (!pageData) return;\n\n try {\n const response = await apiClient.put(`/pages/id/${pageData.id}`, {\n title: pageData.title,\n sections: updatedSections,\n });\n\n if (response.error) {\n console.error('Failed to update page:', response.error.message);\n } else {\n onNavigate({ type: 'pages' });\n }\n } catch (err) {\n console.error('Failed to update page:', err);\n }\n };\n\n if (customRenderView) {\n const customView = customRenderView(currentView);\n if (customView !== null) {\n return customView;\n }\n }\n\n switch (currentView.type) {\n case 'dashboard':\n return (\n <DashboardPage\n onSelectPage={onSelectPage}\n onCreatePage={onCreatePage}\n onUploadMedia={onUploadMedia}\n />\n );\n case 'pages':\n return <PageList onSelectPage={onSelectPage} onCreatePage={onCreatePage} />;\n case 'page-editor':\n return renderPageEditorView(\n currentView,\n pageData,\n pageLoading,\n pageError,\n registry,\n handleSavePage\n );\n case 'media':\n return <MediaBrowser onSelect={() => {}} />;\n case 'navigation':\n return renderNavigationView(\n navigationData,\n navigationLoading,\n navigationError,\n handleSaveNavigation\n );\n case 'custom':\n return <div data-testid=\"custom-view\">Custom view for path: {currentView.path}</div>;\n default:\n return null;\n }\n}\n\nexport function StructCMSAdminApp({\n registry,\n apiBaseUrl = '/api/cms',\n className,\n customNavItems = [],\n renderView: customRenderView,\n enableAuth = false,\n onAuthStateChange,\n}: StructCMSAdminAppProps) {\n const [currentView, setCurrentView] = useState<View>({ type: 'dashboard' });\n\n const handleNavigate = (path: string) => {\n if (path === '/') {\n setCurrentView({ type: 'dashboard' });\n } else if (path === '/pages') {\n setCurrentView({ type: 'pages' });\n } else if (path === '/media') {\n setCurrentView({ type: 'media' });\n } else if (path === '/navigation') {\n setCurrentView({ type: 'navigation' });\n } else {\n setCurrentView({ type: 'custom', path });\n }\n };\n\n const handleNavigateToView = (view: View) => {\n setCurrentView(view);\n };\n\n const handleSelectPage = (page: PageSummary) => {\n setCurrentView({ type: 'page-editor', pageId: page.id });\n };\n\n const handleCreatePage = () => {\n setCurrentView({ type: 'page-editor' });\n };\n\n const handleUploadMedia = () => {\n setCurrentView({ type: 'media' });\n };\n\n const defaultNavItems = [\n { label: 'Dashboard', path: '/' },\n { label: 'Pages', path: '/pages' },\n { label: 'Navigation', path: '/navigation' },\n { label: 'Media', path: '/media' },\n ];\n\n const navItems = [...defaultNavItems, ...customNavItems];\n\n const appContent = (\n <AdminProvider registry={registry} apiBaseUrl={apiBaseUrl}>\n <AdminLayout className={className} navItems={navItems} onNavigate={handleNavigate}>\n <ViewRenderer\n currentView={currentView}\n registry={registry}\n customRenderView={customRenderView}\n onNavigate={handleNavigateToView}\n onSelectPage={handleSelectPage}\n onCreatePage={handleCreatePage}\n onUploadMedia={handleUploadMedia}\n />\n </AdminLayout>\n </AdminProvider>\n );\n\n if (enableAuth) {\n return (\n <AuthProvider apiBaseUrl={apiBaseUrl} onAuthStateChange={onAuthStateChange}>\n {appContent}\n </AuthProvider>\n );\n }\n\n return appContent;\n}\n","'use client';\n\nimport type { Registry } from '@structcms/core';\nimport { type ReactNode, createContext } from 'react';\nimport { ToastProvider } from '../components/ui/toast';\n\n/**\n * Configuration for the Admin context\n */\nexport interface AdminContextValue {\n registry: Registry;\n apiBaseUrl: string;\n}\n\n/**\n * Props for the AdminProvider component\n */\nexport interface AdminProviderProps {\n children: ReactNode;\n registry: Registry;\n apiBaseUrl?: string;\n}\n\nconst DEFAULT_API_BASE_URL = '/api/cms';\n\nexport const AdminContext = createContext<AdminContextValue | null>(null);\n\n/**\n * Provider component that makes registry and API configuration available to all admin components.\n *\n * @example\n * ```tsx\n * import { AdminProvider } from '@structcms/admin';\n * import { registry } from './registry';\n *\n * export default function AdminLayout({ children }) {\n * return (\n * <AdminProvider registry={registry} apiBaseUrl=\"/api/cms\">\n * {children}\n * </AdminProvider>\n * );\n * }\n * ```\n */\nexport function AdminProvider({\n children,\n registry,\n apiBaseUrl = DEFAULT_API_BASE_URL,\n}: AdminProviderProps) {\n const value: AdminContextValue = {\n registry,\n apiBaseUrl,\n };\n\n return (\n <AdminContext.Provider value={value}>\n <ToastProvider>{children}</ToastProvider>\n </AdminContext.Provider>\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport { cn } from '../../lib/utils';\n\nexport type ToastVariant = 'default' | 'success' | 'error';\n\nexport interface Toast {\n id: string;\n message: string;\n variant?: ToastVariant;\n}\n\ninterface ToastContextValue {\n toasts: Toast[];\n addToast: (message: string, variant?: ToastVariant) => void;\n removeToast: (id: string) => void;\n}\n\nconst ToastContext = React.createContext<ToastContextValue | null>(null);\n\nexport interface ToastProviderProps {\n children: React.ReactNode;\n autoDismissMs?: number;\n}\n\n/**\n * Provider for toast notifications. Wrap your app with this to enable useToast().\n *\n * @example\n * ```tsx\n * <ToastProvider>\n * <App />\n * </ToastProvider>\n * ```\n */\nfunction ToastProvider({ children, autoDismissMs = 5000 }: ToastProviderProps) {\n const [toasts, setToasts] = React.useState<Toast[]>([]);\n const counterRef = React.useRef(0);\n\n const removeToast = React.useCallback((id: string) => {\n setToasts((prev) => prev.filter((t) => t.id !== id));\n }, []);\n\n const addToast = React.useCallback(\n (message: string, variant: ToastVariant = 'default') => {\n const id = `toast-${++counterRef.current}`;\n const toast: Toast = { id, message, variant };\n setToasts((prev) => [...prev, toast]);\n\n if (autoDismissMs > 0) {\n setTimeout(() => removeToast(id), autoDismissMs);\n }\n },\n [autoDismissMs, removeToast]\n );\n\n const value = React.useMemo(\n () => ({ toasts, addToast, removeToast }),\n [toasts, addToast, removeToast]\n );\n\n return (\n <ToastContext.Provider value={value}>\n {children}\n <ToastContainer toasts={toasts} onDismiss={removeToast} />\n </ToastContext.Provider>\n );\n}\n\nToastProvider.displayName = 'ToastProvider';\n\n/**\n * Hook to trigger toast notifications. Must be used within a ToastProvider.\n *\n * @example\n * ```tsx\n * const { toast } = useToast();\n * toast('Page saved!', 'success');\n * toast('Something went wrong', 'error');\n * ```\n */\nfunction useToast() {\n const context = React.useContext(ToastContext);\n if (!context) {\n throw new Error('useToast must be used within a ToastProvider');\n }\n return {\n toast: context.addToast,\n dismiss: context.removeToast,\n toasts: context.toasts,\n };\n}\n\nconst variantStyles: Record<ToastVariant, string> = {\n default: 'bg-card border-input text-foreground',\n success: 'bg-card border-green-500 text-foreground',\n error: 'bg-card border-destructive text-foreground',\n};\n\ninterface ToastContainerProps {\n toasts: Toast[];\n onDismiss: (id: string) => void;\n}\n\nfunction ToastContainer({ toasts, onDismiss }: ToastContainerProps) {\n if (toasts.length === 0) return null;\n\n return (\n <div\n className=\"fixed bottom-4 right-4 z-50 flex flex-col gap-2 max-w-sm\"\n data-testid=\"toast-container\"\n >\n {toasts.map((toast) => (\n <div\n key={toast.id}\n className={cn(\n 'rounded-md border px-4 py-3 shadow-md flex items-center justify-between gap-2',\n variantStyles[toast.variant ?? 'default']\n )}\n role=\"alert\"\n data-testid={`toast-${toast.id}`}\n >\n <p className=\"text-sm\">{toast.message}</p>\n <button\n type=\"button\"\n className=\"text-muted-foreground hover:text-foreground text-sm\"\n onClick={() => onDismiss(toast.id)}\n data-testid={`toast-dismiss-${toast.id}`}\n >\n ✕\n </button>\n </div>\n ))}\n </div>\n );\n}\n\nexport { ToastProvider, useToast };\n","import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\n/**\n * Utility function to merge Tailwind CSS classes with clsx\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import type { AuthSession, AuthUser } from '@structcms/api';\nimport type React from 'react';\nimport { createContext, useCallback, useContext, useEffect, useState } from 'react';\n\nexport interface AuthContextValue {\n user: AuthUser | null;\n session: AuthSession | null;\n isLoading: boolean;\n isAuthenticated: boolean;\n signIn: (email: string, password: string) => Promise<void>;\n signOut: () => Promise<void>;\n refreshSession: () => Promise<void>;\n}\n\nconst AuthContext = createContext<AuthContextValue | undefined>(undefined);\n\nexport interface AuthProviderProps {\n children: React.ReactNode;\n apiBaseUrl: string;\n onAuthStateChange?: (user: AuthUser | null) => void;\n}\n\n/**\n * Get CSRF token from cookie\n */\nfunction getCsrfToken(): string | null {\n if (typeof document === 'undefined') return null;\n const match = document.cookie.match(/structcms_csrf_token=([^;]+)/);\n return match?.[1] ?? null;\n}\n\n/**\n * Create fetch options with CSRF token and credentials\n */\nfunction createFetchOptions(method: string, body?: object): RequestInit {\n const options: RequestInit = {\n method,\n credentials: 'include', // Always send cookies\n headers: {\n 'Content-Type': 'application/json',\n },\n };\n\n // Add CSRF token for non-GET requests\n if (method !== 'GET' && method !== 'HEAD') {\n const csrfToken = getCsrfToken();\n if (csrfToken) {\n (options.headers as Record<string, string>)['X-CSRF-Token'] = csrfToken;\n }\n }\n\n if (body) {\n options.body = JSON.stringify(body);\n }\n\n return options;\n}\n\nexport function AuthProvider({ children, apiBaseUrl, onAuthStateChange }: AuthProviderProps) {\n // Auth bypass only in development\n const isAuthDisabled =\n process.env.NODE_ENV === 'development' &&\n typeof window !== 'undefined' &&\n (process.env.NEXT_PUBLIC_DISABLE_AUTH === 'true' ||\n // biome-ignore lint/suspicious/noExplicitAny: Next.js internal data structure\n (window as any).__NEXT_DATA__?.props?.pageProps?.disableAuth === true);\n\n if (isAuthDisabled) {\n console.warn('⚠️ WARNING: Authentication is DISABLED. This should only be used in development!');\n }\n\n const [user, setUser] = useState<AuthUser | null>(null);\n const [session, setSession] = useState<AuthSession | null>(null);\n const [isLoading, setIsLoading] = useState(!isAuthDisabled);\n\n const clearSession = useCallback(() => {\n setUser(null);\n setSession(null);\n onAuthStateChange?.(null);\n }, [onAuthStateChange]);\n\n const tryRefreshSession = useCallback(async (): Promise<boolean> => {\n try {\n const refreshResponse = await fetch(\n `${apiBaseUrl}/auth/refresh`,\n createFetchOptions('POST')\n );\n\n if (refreshResponse.ok) {\n const data = await refreshResponse.json();\n // Session tokens are now in httpOnly cookies, we only get user data\n setSession({\n accessToken: '', // Not accessible from client\n user: data.user,\n expiresAt: data.expiresAt ? new Date(data.expiresAt) : undefined,\n });\n setUser(data.user);\n onAuthStateChange?.(data.user);\n return true;\n }\n } catch (error) {\n console.error('Failed to refresh session:', error);\n }\n return false;\n }, [apiBaseUrl, onAuthStateChange]);\n\n const loadSession = useCallback(async () => {\n if (isAuthDisabled) {\n setIsLoading(false);\n return;\n }\n\n try {\n // Verify session using httpOnly cookie\n const response = await fetch(\n `${apiBaseUrl}/auth/verify`,\n createFetchOptions('POST')\n );\n\n if (!response.ok) {\n // Try to refresh session\n const refreshed = await tryRefreshSession();\n if (!refreshed) {\n clearSession();\n }\n setIsLoading(false);\n return;\n }\n\n const userData = await response.json();\n setUser(userData);\n setSession({\n accessToken: '', // Not accessible from client\n user: userData,\n });\n onAuthStateChange?.(userData);\n } catch (error) {\n console.error('Failed to load session:', error);\n clearSession();\n } finally {\n setIsLoading(false);\n }\n }, [apiBaseUrl, onAuthStateChange, isAuthDisabled, tryRefreshSession, clearSession]);\n\n // Fetch CSRF token on mount\n useEffect(() => {\n const fetchCsrfToken = async () => {\n try {\n await fetch(`${apiBaseUrl}/auth/csrf`, {\n credentials: 'include',\n });\n } catch (error) {\n console.error('Failed to fetch CSRF token:', error);\n }\n };\n\n fetchCsrfToken();\n }, [apiBaseUrl]);\n\n useEffect(() => {\n loadSession();\n }, [loadSession]);\n\n const signIn = useCallback(\n async (email: string, password: string) => {\n setIsLoading(true);\n try {\n const response = await fetch(\n `${apiBaseUrl}/auth/signin`,\n createFetchOptions('POST', { email, password })\n );\n\n if (!response.ok) {\n const error = await response.json();\n throw new Error(error.error?.message || error.message || 'Sign in failed');\n }\n\n const data = await response.json();\n // Tokens are now in httpOnly cookies\n setSession({\n accessToken: '', // Not accessible from client\n user: data.user,\n expiresAt: data.expiresAt ? new Date(data.expiresAt) : undefined,\n });\n setUser(data.user);\n onAuthStateChange?.(data.user);\n } finally {\n setIsLoading(false);\n }\n },\n [apiBaseUrl, onAuthStateChange]\n );\n\n const signOut = useCallback(async () => {\n setIsLoading(true);\n try {\n await fetch(\n `${apiBaseUrl}/auth/signout`,\n createFetchOptions('POST')\n );\n } catch (error) {\n console.error('Sign out error:', error);\n } finally {\n clearSession();\n setIsLoading(false);\n }\n }, [apiBaseUrl, clearSession]);\n\n const refreshSession = useCallback(async () => {\n const response = await fetch(\n `${apiBaseUrl}/auth/refresh`,\n createFetchOptions('POST')\n );\n\n if (!response.ok) {\n throw new Error('Failed to refresh session');\n }\n\n const data = await response.json();\n setSession({\n accessToken: '', // Not accessible from client\n user: data.user,\n expiresAt: data.expiresAt ? new Date(data.expiresAt) : undefined,\n });\n setUser(data.user);\n onAuthStateChange?.(data.user);\n }, [apiBaseUrl, onAuthStateChange]);\n\n const value: AuthContextValue = {\n user,\n session,\n isLoading,\n isAuthenticated: isAuthDisabled || !!user,\n signIn,\n signOut,\n refreshSession,\n };\n\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\n}\n\nexport function useAuth(): AuthContextValue {\n const context = useContext(AuthContext);\n if (!context) {\n throw new Error('useAuth must be used within an AuthProvider');\n }\n return context;\n}\n","'use client';\n\nimport { useMemo } from 'react';\nimport { useAdmin } from './use-admin';\n\n/**\n * API response wrapper\n */\nexport interface ApiResponse<T> {\n data: T | null;\n error: ApiError | null;\n}\n\n/**\n * API error structure\n */\nexport interface ApiError {\n message: string;\n code?: string;\n status: number;\n}\n\n/**\n * API client interface for making requests to the CMS API\n */\nexport interface ApiClient {\n get<T>(path: string): Promise<ApiResponse<T>>;\n post<T>(path: string, body: unknown): Promise<ApiResponse<T>>;\n put<T>(path: string, body: unknown): Promise<ApiResponse<T>>;\n delete<T>(path: string): Promise<ApiResponse<T>>;\n upload<T>(path: string, body: FormData): Promise<ApiResponse<T>>;\n}\n\nasync function handleResponse<T>(response: Response): Promise<ApiResponse<T>> {\n if (!response.ok) {\n let errorMessage = 'An error occurred';\n let errorCode: string | undefined;\n\n try {\n const errorBody = (await response.json()) as {\n error?: { message?: string; code?: string };\n };\n if (errorBody.error?.message) {\n errorMessage = errorBody.error.message;\n }\n if (errorBody.error?.code) {\n errorCode = errorBody.error.code;\n }\n } catch {\n errorMessage = response.statusText || errorMessage;\n }\n\n return {\n data: null,\n error: {\n message: errorMessage,\n code: errorCode,\n status: response.status,\n },\n };\n }\n\n try {\n const data = (await response.json()) as T;\n return { data, error: null };\n } catch {\n return { data: null as T, error: null };\n }\n}\n\nfunction createApiClient(baseUrl: string): ApiClient {\n const normalizedBaseUrl = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n\n return {\n async get<T>(path: string): Promise<ApiResponse<T>> {\n const response = await fetch(`${normalizedBaseUrl}${path}`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n return handleResponse<T>(response);\n },\n\n async post<T>(path: string, body: unknown): Promise<ApiResponse<T>> {\n const response = await fetch(`${normalizedBaseUrl}${path}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(body),\n });\n return handleResponse<T>(response);\n },\n\n async put<T>(path: string, body: unknown): Promise<ApiResponse<T>> {\n const response = await fetch(`${normalizedBaseUrl}${path}`, {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(body),\n });\n return handleResponse<T>(response);\n },\n\n async delete<T>(path: string): Promise<ApiResponse<T>> {\n const response = await fetch(`${normalizedBaseUrl}${path}`, {\n method: 'DELETE',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n return handleResponse<T>(response);\n },\n\n async upload<T>(path: string, body: FormData): Promise<ApiResponse<T>> {\n const response = await fetch(`${normalizedBaseUrl}${path}`, {\n method: 'POST',\n body,\n });\n return handleResponse<T>(response);\n },\n };\n}\n\n/**\n * Hook to get an API client configured with the base URL from AdminProvider.\n * Must be used within an AdminProvider.\n *\n * @returns An API client with get, post, put, delete methods\n *\n * @example\n * ```tsx\n * function PageList() {\n * const api = useApiClient();\n *\n * async function loadPages() {\n * const { data, error } = await api.get<Page[]>('/pages');\n * if (error) {\n * console.error(error.message);\n * return;\n * }\n * setPages(data);\n * }\n * }\n * ```\n */\nexport function useApiClient(): ApiClient {\n const { apiBaseUrl } = useAdmin();\n return useMemo(() => createApiClient(apiBaseUrl), [apiBaseUrl]);\n}\n","'use client';\n\nimport { useContext } from 'react';\nimport { AdminContext, type AdminContextValue } from '../context/admin-context';\n\n/**\n * Hook to access the Admin context.\n * Must be used within an AdminProvider.\n *\n * @returns The admin context containing registry and apiBaseUrl\n * @throws Error if used outside of AdminProvider\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { registry, apiBaseUrl } = useAdmin();\n * const sections = registry.getAllSections();\n * // ...\n * }\n * ```\n */\nexport function useAdmin(): AdminContextValue {\n const context = useContext(AdminContext);\n\n if (context === null) {\n throw new Error('useAdmin must be used within an AdminProvider');\n }\n\n return context;\n}\n","'use client';\n\nimport type { NavigationItem } from '@structcms/core';\nimport * as React from 'react';\nimport { cn } from '../../lib/utils';\nimport { Button } from '../ui/button';\nimport { Input } from '../ui/input';\n\nexport interface NavigationEditorProps {\n items: NavigationItem[];\n onSave: (items: NavigationItem[]) => void;\n className?: string;\n}\n\n/**\n * Editor for navigation items with nested structure support (one level).\n *\n * @example\n * ```tsx\n * <NavigationEditor\n * items={navigation.items}\n * onSave={(items) => saveNavigation({ ...navigation, items })}\n * />\n * ```\n */\nfunction NavigationEditor({ items: initialItems, onSave, className }: NavigationEditorProps) {\n const [items, setItems] = React.useState<NavigationItem[]>(initialItems);\n\n const handleAddItem = () => {\n setItems([...items, { label: '', href: '', children: [] }]);\n };\n\n const handleRemoveItem = (index: number) => {\n const newItems = [...items];\n newItems.splice(index, 1);\n setItems(newItems);\n };\n\n const handleItemChange = (index: number, field: 'label' | 'href', value: string) => {\n const newItems = [...items];\n const item = newItems[index];\n if (item) {\n newItems[index] = { ...item, [field]: value };\n }\n setItems(newItems);\n };\n\n const handleAddChild = (parentIndex: number) => {\n const newItems = [...items];\n const parent = newItems[parentIndex];\n if (parent) {\n newItems[parentIndex] = {\n ...parent,\n children: [...(parent.children ?? []), { label: '', href: '' }],\n };\n }\n setItems(newItems);\n };\n\n const handleRemoveChild = (parentIndex: number, childIndex: number) => {\n const newItems = [...items];\n const parent = newItems[parentIndex];\n if (parent?.children) {\n const newChildren = [...parent.children];\n newChildren.splice(childIndex, 1);\n newItems[parentIndex] = { ...parent, children: newChildren };\n }\n setItems(newItems);\n };\n\n const handleChildChange = (\n parentIndex: number,\n childIndex: number,\n field: 'label' | 'href',\n value: string\n ) => {\n const newItems = [...items];\n const parent = newItems[parentIndex];\n if (parent?.children) {\n const newChildren = [...parent.children];\n const child = newChildren[childIndex];\n if (child) {\n newChildren[childIndex] = { ...child, [field]: value };\n newItems[parentIndex] = { ...parent, children: newChildren };\n }\n }\n setItems(newItems);\n };\n\n const handleSave = () => {\n onSave(items);\n };\n\n return (\n <div className={cn('space-y-4', className)} data-testid=\"navigation-editor\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-xl font-semibold\">Navigation</h2>\n </div>\n\n {items.length === 0 ? (\n <p className=\"text-sm text-muted-foreground text-center py-8\" data-testid=\"empty-state\">\n No navigation items yet.\n </p>\n ) : (\n <div className=\"space-y-3\">\n {items.map((item, index) => (\n <div\n // biome-ignore lint/suspicious/noArrayIndexKey: Navigation items have no stable IDs, order is user-controlled\n key={index}\n className=\"rounded-md border border-input bg-background p-4 space-y-3\"\n data-testid={`nav-item-${index}`}\n >\n <div className=\"flex gap-2 items-start\">\n <div className=\"flex-1 space-y-2\">\n <Input\n placeholder=\"Label\"\n value={item.label}\n onChange={(e) => handleItemChange(index, 'label', e.target.value)}\n data-testid={`nav-item-label-${index}`}\n />\n <Input\n placeholder=\"URL (e.g. /about)\"\n value={item.href}\n onChange={(e) => handleItemChange(index, 'href', e.target.value)}\n data-testid={`nav-item-href-${index}`}\n />\n </div>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => handleRemoveItem(index)}\n title=\"Remove item\"\n data-testid={`nav-item-remove-${index}`}\n >\n ✕\n </Button>\n </div>\n\n {/* Children */}\n {(item.children ?? []).length > 0 && (\n <div className=\"ml-6 space-y-2\">\n {(item.children ?? []).map((child, childIndex) => (\n <div\n // biome-ignore lint/suspicious/noArrayIndexKey: Child items have no stable IDs, order is user-controlled\n key={childIndex}\n className=\"flex gap-2 items-start rounded-md border border-input bg-muted/30 p-3\"\n data-testid={`nav-child-${index}-${childIndex}`}\n >\n <div className=\"flex-1 space-y-2\">\n <Input\n placeholder=\"Label\"\n value={child.label}\n onChange={(e) =>\n handleChildChange(index, childIndex, 'label', e.target.value)\n }\n data-testid={`nav-child-label-${index}-${childIndex}`}\n />\n <Input\n placeholder=\"URL\"\n value={child.href}\n onChange={(e) =>\n handleChildChange(index, childIndex, 'href', e.target.value)\n }\n data-testid={`nav-child-href-${index}-${childIndex}`}\n />\n </div>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => handleRemoveChild(index, childIndex)}\n title=\"Remove child\"\n data-testid={`nav-child-remove-${index}-${childIndex}`}\n >\n ✕\n </Button>\n </div>\n ))}\n </div>\n )}\n\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => handleAddChild(index)}\n data-testid={`nav-add-child-${index}`}\n >\n Add Child\n </Button>\n </div>\n ))}\n </div>\n )}\n\n <div className=\"flex gap-2 border-t border-input pt-4\">\n <Button type=\"button\" variant=\"outline\" onClick={handleAddItem} data-testid=\"nav-add-item\">\n Add Item\n </Button>\n <Button type=\"button\" onClick={handleSave} data-testid=\"nav-save\">\n Save Navigation\n </Button>\n </div>\n </div>\n );\n}\n\nNavigationEditor.displayName = 'NavigationEditor';\n\nexport { NavigationEditor };\n","import { type VariantProps, cva } from 'class-variance-authority';\nimport * as React from 'react';\nimport { cn } from '../../lib/utils';\n\nconst buttonVariants = cva(\n 'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',\n outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',\n secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n ghost: 'hover:bg-accent hover:text-accent-foreground',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-10 px-4 py-2',\n sm: 'h-9 rounded-md px-3',\n lg: 'h-11 rounded-md px-8',\n icon: 'h-10 w-10',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n }\n);\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {}\n\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, ...props }, ref) => {\n return (\n <button className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props} />\n );\n }\n);\nButton.displayName = 'Button';\n\nexport { Button, buttonVariants };\n","import * as React from 'react';\nimport { cn } from '../../lib/utils';\n\nexport interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {}\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, type, ...props }, ref) => {\n return (\n <input\n type={type}\n className={cn(\n 'flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',\n className\n )}\n ref={ref}\n {...props}\n />\n );\n }\n);\nInput.displayName = 'Input';\n\nexport { Input };\n","'use client';\n\nimport * as React from 'react';\nimport { useAdmin } from '../../hooks/use-admin';\nimport { useApiClient } from '../../hooks/use-api-client';\nimport { cn } from '../../lib/utils';\nimport { Button } from '../ui/button';\nimport { Input } from '../ui/input';\n\nexport interface PageSummary {\n id: string;\n title: string;\n slug: string;\n pageType: string;\n updatedAt?: string;\n}\n\nexport interface PageListProps {\n onSelectPage: (page: PageSummary) => void;\n onCreatePage: () => void;\n className?: string;\n}\n\n/**\n * List all pages with filter/search, link to edit each page.\n *\n * @example\n * ```tsx\n * <AdminProvider registry={registry} apiBaseUrl=\"/api/cms\">\n * <PageList\n * onSelectPage={(page) => router.push(`/admin/pages/${page.id}`)}\n * onCreatePage={() => router.push('/admin/pages/new')}\n * />\n * </AdminProvider>\n * ```\n */\nfunction PageList({ onSelectPage, onCreatePage, className }: PageListProps) {\n const api = useApiClient();\n const { registry } = useAdmin();\n const [pages, setPages] = React.useState<PageSummary[]>([]);\n const [loading, setLoading] = React.useState(true);\n const [error, setError] = React.useState<string | null>(null);\n const [search, setSearch] = React.useState('');\n const [pageTypeFilter, setPageTypeFilter] = React.useState('');\n\n const pageTypes = registry.getAllPageTypes();\n\n React.useEffect(() => {\n let cancelled = false;\n\n async function fetchPages() {\n setLoading(true);\n setError(null);\n\n const result = await api.get<PageSummary[]>('/pages');\n\n if (cancelled) return;\n\n if (result.error) {\n setError(result.error.message);\n setLoading(false);\n return;\n }\n\n setPages(result.data ?? []);\n setLoading(false);\n }\n\n void fetchPages();\n\n return () => {\n cancelled = true;\n };\n }, [api]);\n\n const filteredPages = React.useMemo(() => {\n let result = pages;\n\n if (search) {\n const lowerSearch = search.toLowerCase();\n result = result.filter(\n (page) =>\n page.title.toLowerCase().includes(lowerSearch) ||\n page.slug.toLowerCase().includes(lowerSearch)\n );\n }\n\n if (pageTypeFilter) {\n result = result.filter((page) => page.pageType === pageTypeFilter);\n }\n\n return result;\n }, [pages, search, pageTypeFilter]);\n\n return (\n <div className={cn('space-y-4', className)} data-testid=\"page-list\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-xl font-semibold\">Pages</h2>\n <Button type=\"button\" onClick={onCreatePage} data-testid=\"create-page\">\n Create New Page\n </Button>\n </div>\n\n <div className=\"flex gap-2\">\n <Input\n placeholder=\"Search by title or slug...\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"max-w-sm\"\n data-testid=\"search-input\"\n />\n {pageTypes.length > 0 && (\n <select\n value={pageTypeFilter}\n onChange={(e) => setPageTypeFilter(e.target.value)}\n className=\"flex h-10 rounded-md border border-input bg-background px-3 py-2 text-sm\"\n data-testid=\"page-type-filter\"\n >\n <option value=\"\">All Types</option>\n {pageTypes.map((pt) => (\n <option key={pt.name} value={pt.name}>\n {pt.name}\n </option>\n ))}\n </select>\n )}\n </div>\n\n {loading && (\n <p className=\"text-sm text-muted-foreground\" data-testid=\"loading\">\n Loading pages...\n </p>\n )}\n\n {error && (\n <p className=\"text-sm text-destructive\" data-testid=\"error\">\n {error}\n </p>\n )}\n\n {!loading && !error && filteredPages.length === 0 && (\n <p className=\"text-sm text-muted-foreground text-center py-8\" data-testid=\"empty-state\">\n {pages.length === 0\n ? 'No pages yet. Create your first page.'\n : 'No pages match your search.'}\n </p>\n )}\n\n {!loading && !error && filteredPages.length > 0 && (\n <div className=\"rounded-md border border-input\" data-testid=\"page-table\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b border-input bg-muted/50\">\n <th className=\"text-left p-3 font-medium\">Title</th>\n <th className=\"text-left p-3 font-medium\">Slug</th>\n <th className=\"text-left p-3 font-medium\">Type</th>\n </tr>\n </thead>\n <tbody>\n {filteredPages.map((page) => (\n <tr\n key={page.id}\n className=\"border-b border-input last:border-0 hover:bg-muted/30 cursor-pointer\"\n onClick={() => onSelectPage(page)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onSelectPage(page);\n }\n }}\n tabIndex={0}\n data-testid={`page-row-${page.id}`}\n >\n <td className=\"p-3\">{page.title}</td>\n <td className=\"p-3 text-muted-foreground\">{page.slug}</td>\n <td className=\"p-3 text-muted-foreground capitalize\">{page.pageType}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </div>\n );\n}\n\nPageList.displayName = 'PageList';\n\nexport { PageList };\n","import * as React from 'react';\nimport { cn } from '../../lib/utils';\nimport { Button } from './button';\n\nexport interface ErrorBoundaryProps {\n children: React.ReactNode;\n fallback?: React.ReactNode;\n onReset?: () => void;\n className?: string;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n}\n\n/**\n * Error boundary for catching component-level render errors.\n *\n * @example\n * ```tsx\n * <ErrorBoundary fallback={<p>Something went wrong</p>}>\n * <MyComponent />\n * </ErrorBoundary>\n * ```\n */\nclass ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false, error: null };\n }\n\n static getDerivedStateFromError(error: Error): ErrorBoundaryState {\n return { hasError: true, error };\n }\n\n handleReset = () => {\n this.setState({ hasError: false, error: null });\n this.props.onReset?.();\n };\n\n override render() {\n if (this.state.hasError) {\n if (this.props.fallback) {\n return this.props.fallback;\n }\n\n return (\n <div\n className={cn(\n 'rounded-md border border-destructive bg-destructive/10 p-4',\n this.props.className\n )}\n role=\"alert\"\n data-testid=\"error-boundary\"\n >\n <h3 className=\"text-sm font-semibold text-destructive mb-1\">Something went wrong</h3>\n <p className=\"text-sm text-muted-foreground\">\n {this.state.error?.message ?? 'An unexpected error occurred'}\n </p>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"mt-3\"\n onClick={this.handleReset}\n data-testid=\"error-boundary-retry\"\n >\n Retry\n </Button>\n </div>\n );\n }\n\n return this.props.children;\n }\n}\n\nexport { ErrorBoundary };\n","'use client';\n\nimport * as React from 'react';\nimport { useAdmin } from '../../hooks/use-admin';\nimport { useApiClient } from '../../hooks/use-api-client';\nimport { cn } from '../../lib/utils';\nimport { Button } from '../ui/button';\nimport { Skeleton } from '../ui/skeleton';\n\ninterface KpiState {\n value: number | null;\n loading: boolean;\n error: string | null;\n}\n\nexport interface KpiCardsProps {\n className?: string;\n}\n\n/**\n * Dashboard KPI cards displaying content metrics.\n *\n * Fetches pages, media, and navigation counts from the API in parallel.\n * Sections count is derived synchronously from the registry.\n *\n * @example\n * ```tsx\n * <AdminProvider registry={registry} apiBaseUrl=\"/api/cms\">\n * <KpiCards />\n * </AdminProvider>\n * ```\n */\nfunction KpiCards({ className }: KpiCardsProps) {\n const api = useApiClient();\n const { registry } = useAdmin();\n\n const [pages, setPages] = React.useState<KpiState>({ value: null, loading: true, error: null });\n const [media, setMedia] = React.useState<KpiState>({ value: null, loading: true, error: null });\n const [navigation, setNavigation] = React.useState<KpiState>({\n value: null,\n loading: true,\n error: null,\n });\n\n const sectionsCount = registry.getAllSections().length;\n\n const fetchPages = React.useCallback(\n async (signal?: { cancelled: boolean }) => {\n setPages({ value: null, loading: true, error: null });\n const result = await api.get<unknown[]>('/pages');\n if (signal?.cancelled) return;\n if (result.error) {\n setPages({ value: null, loading: false, error: result.error.message });\n } else {\n setPages({ value: result.data?.length ?? 0, loading: false, error: null });\n }\n },\n [api]\n );\n\n const fetchMedia = React.useCallback(\n async (signal?: { cancelled: boolean }) => {\n setMedia({ value: null, loading: true, error: null });\n const result = await api.get<unknown[]>('/media');\n if (signal?.cancelled) return;\n if (result.error) {\n setMedia({ value: null, loading: false, error: result.error.message });\n } else {\n setMedia({ value: result.data?.length ?? 0, loading: false, error: null });\n }\n },\n [api]\n );\n\n const fetchNavigation = React.useCallback(\n async (signal?: { cancelled: boolean }) => {\n setNavigation({ value: null, loading: true, error: null });\n const result = await api.get<unknown[]>('/navigation');\n if (signal?.cancelled) return;\n if (result.error) {\n setNavigation({ value: null, loading: false, error: result.error.message });\n } else {\n setNavigation({ value: result.data?.length ?? 0, loading: false, error: null });\n }\n },\n [api]\n );\n\n React.useEffect(() => {\n const signal = { cancelled: false };\n\n void Promise.allSettled([fetchPages(signal), fetchMedia(signal), fetchNavigation(signal)]);\n\n return () => {\n signal.cancelled = true;\n };\n }, [fetchPages, fetchMedia, fetchNavigation]);\n\n const kpis = [\n { label: 'Pages', state: pages, onRetry: () => void fetchPages(), testId: 'kpi-pages' },\n { label: 'Media Files', state: media, onRetry: () => void fetchMedia(), testId: 'kpi-media' },\n {\n label: 'Navigation Sets',\n state: navigation,\n onRetry: () => void fetchNavigation(),\n testId: 'kpi-navigation',\n },\n {\n label: 'Sections',\n state: { value: sectionsCount, loading: false, error: null } as KpiState,\n onRetry: undefined,\n testId: 'kpi-sections',\n },\n ];\n\n return (\n <div className={cn('grid grid-cols-2 gap-4 md:grid-cols-4', className)} data-testid=\"kpi-cards\">\n {kpis.map((kpi) => (\n <div\n key={kpi.testId}\n className=\"rounded-lg border border-input bg-background p-4\"\n data-testid={kpi.testId}\n >\n <p className=\"text-sm text-muted-foreground\">{kpi.label}</p>\n\n {kpi.state.loading && (\n <Skeleton className=\"mt-2 h-8 w-16\" data-testid={`${kpi.testId}-skeleton`} />\n )}\n\n {!kpi.state.loading && kpi.state.error && (\n <div className=\"mt-1\">\n <p className=\"text-sm text-destructive\" data-testid={`${kpi.testId}-error`}>\n Error loading\n </p>\n {kpi.onRetry && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"mt-2\"\n onClick={kpi.onRetry}\n data-testid={`${kpi.testId}-retry`}\n >\n Retry\n </Button>\n )}\n </div>\n )}\n\n {!kpi.state.loading && !kpi.state.error && kpi.state.value !== null && (\n <p className=\"mt-1 text-2xl font-bold\" data-testid={`${kpi.testId}-value`}>\n {kpi.state.value}\n </p>\n )}\n </div>\n ))}\n </div>\n );\n}\n\nKpiCards.displayName = 'KpiCards';\n\nexport { KpiCards };\n","import type * as React from 'react';\nimport { cn } from '../../lib/utils';\n\nexport interface SkeletonProps extends React.HTMLAttributes<HTMLDivElement> {\n width?: string | number;\n height?: string | number;\n}\n\n/**\n * Skeleton loading placeholder with pulse animation.\n *\n * @example\n * ```tsx\n * <Skeleton className=\"h-4 w-48\" />\n * <Skeleton width={200} height={20} />\n * ```\n */\nfunction Skeleton({ className, width, height, style, ...props }: SkeletonProps) {\n return (\n <div\n className={cn('animate-pulse rounded-md bg-muted', className)}\n style={{ width, height, ...style }}\n data-testid=\"skeleton\"\n {...props}\n />\n );\n}\n\nSkeleton.displayName = 'Skeleton';\n\nexport { Skeleton };\n","import { cn } from '../../lib/utils';\nimport { Button } from '../ui/button';\n\nexport interface QuickActionsProps {\n onCreatePage: () => void;\n onUploadMedia: () => void;\n className?: string;\n}\n\nexport function QuickActions({ onCreatePage, onUploadMedia, className }: QuickActionsProps) {\n return (\n <div className={cn('space-y-3', className)} data-testid=\"quick-actions\">\n <h2 className=\"text-lg font-semibold\">Quick Actions</h2>\n <div className=\"flex flex-wrap gap-3\">\n <Button\n onClick={onCreatePage}\n aria-label=\"Create New Page\"\n data-testid=\"quick-action-create-page\"\n >\n Create New Page\n </Button>\n <Button\n variant=\"outline\"\n onClick={onUploadMedia}\n aria-label=\"Upload Media\"\n data-testid=\"quick-action-upload-media\"\n >\n Upload Media\n </Button>\n </div>\n </div>\n );\n}\n","'use client';\n\nimport * as React from 'react';\nimport { useApiClient } from '../../hooks/use-api-client';\nimport { cn } from '../../lib/utils';\nimport type { PageSummary } from '../content/page-list';\nimport { Button } from '../ui/button';\nimport { Skeleton } from '../ui/skeleton';\n\nexport interface RecentPagesProps {\n onSelectPage: (page: PageSummary) => void;\n className?: string;\n}\n\nfunction formatTimestamp(dateString: string): string {\n try {\n return new Date(dateString).toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n });\n } catch {\n return dateString;\n }\n}\n\n/**\n * Displays a list of recently updated pages (max 10, sorted by updatedAt DESC).\n *\n * @example\n * ```tsx\n * <AdminProvider registry={registry} apiBaseUrl=\"/api/cms\">\n * <RecentPages onSelectPage={(page) => router.push(`/admin/pages/${page.id}`)} />\n * </AdminProvider>\n * ```\n */\nfunction RecentPages({ onSelectPage, className }: RecentPagesProps) {\n const api = useApiClient();\n const [pages, setPages] = React.useState<PageSummary[]>([]);\n const [loading, setLoading] = React.useState(true);\n const [error, setError] = React.useState(false);\n\n const fetchPages = React.useCallback(\n async (signal?: { cancelled: boolean }) => {\n setLoading(true);\n setError(false);\n\n const result = await api.get<PageSummary[]>('/pages');\n\n if (signal?.cancelled) return;\n\n if (result.error) {\n setError(true);\n setLoading(false);\n return;\n }\n\n const allPages = result.data ?? [];\n const sorted = [...allPages].sort((a, b) => {\n const dateA = a.updatedAt ? new Date(a.updatedAt).getTime() : 0;\n const dateB = b.updatedAt ? new Date(b.updatedAt).getTime() : 0;\n return dateB - dateA;\n });\n\n setPages(sorted.slice(0, 10));\n setLoading(false);\n },\n [api]\n );\n\n React.useEffect(() => {\n const signal = { cancelled: false };\n void fetchPages(signal);\n return () => {\n signal.cancelled = true;\n };\n }, [fetchPages]);\n\n return (\n <div className={cn('space-y-3', className)} data-testid=\"recent-pages\">\n <h2 className=\"text-lg font-semibold\">Recent Pages</h2>\n\n {loading && (\n <div className=\"space-y-2\" data-testid=\"recent-pages-loading\">\n {Array.from({ length: 5 }).map((_, i) => (\n // biome-ignore lint/suspicious/noArrayIndexKey: Temporary loading skeletons with no stable data\n <Skeleton key={i} className=\"h-10 w-full\" />\n ))}\n </div>\n )}\n\n {!loading && error && (\n <div data-testid=\"recent-pages-error\">\n <p className=\"text-sm text-destructive\">Unable to load recent pages</p>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"mt-2\"\n onClick={() => void fetchPages()}\n data-testid=\"recent-pages-retry\"\n >\n Retry\n </Button>\n </div>\n )}\n\n {!loading && !error && pages.length === 0 && (\n <p className=\"text-sm text-muted-foreground py-4\" data-testid=\"recent-pages-empty\">\n No pages yet.\n </p>\n )}\n\n {!loading && !error && pages.length > 0 && (\n <div className=\"rounded-md border border-input\" data-testid=\"recent-pages-list\">\n {pages.map((page) => (\n <button\n type=\"button\"\n key={page.id}\n className=\"flex items-center justify-between border-b border-input last:border-0 px-3 py-2 hover:bg-muted/30 cursor-pointer w-full text-left\"\n onClick={() => onSelectPage(page)}\n data-testid={`recent-page-${page.id}`}\n >\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-medium truncate\">{page.title}</p>\n <p className=\"text-xs text-muted-foreground truncate\">{page.slug}</p>\n </div>\n {page.updatedAt && (\n <span className=\"ml-4 text-xs text-muted-foreground whitespace-nowrap\">\n {formatTimestamp(page.updatedAt)}\n </span>\n )}\n </button>\n ))}\n </div>\n )}\n </div>\n );\n}\n\nRecentPages.displayName = 'RecentPages';\n\nexport { RecentPages };\n","'use client';\nimport { cn } from '../../lib/utils';\nimport type { PageSummary } from '../content/page-list';\nimport { ErrorBoundary } from '../ui/error-boundary';\nimport { KpiCards } from './kpi-cards';\nimport { QuickActions } from './quick-actions';\nimport { RecentPages } from './recent-pages';\n\nexport interface DashboardPageProps {\n onSelectPage: (page: PageSummary) => void;\n onCreatePage: () => void;\n onUploadMedia: () => void;\n className?: string;\n}\n\n/**\n * Main dashboard page composing KPI cards, recent pages, and quick actions.\n * This is the default admin entry point.\n *\n * @example\n * ```tsx\n * <AdminProvider registry={registry} apiBaseUrl=\"/api/cms\">\n * <DashboardPage\n * onSelectPage={(page) => router.push(`/admin/pages/${page.id}`)}\n * onCreatePage={() => router.push('/admin/pages/new')}\n * onUploadMedia={() => router.push('/admin/media')}\n * />\n * </AdminProvider>\n * ```\n */\nfunction DashboardPage({\n onSelectPage,\n onCreatePage,\n onUploadMedia,\n className,\n}: DashboardPageProps) {\n return (\n <div className={cn('space-y-6', className)} data-testid=\"dashboard-page\">\n <h1 className=\"text-2xl font-bold\">Dashboard</h1>\n\n <ErrorBoundary>\n <KpiCards />\n </ErrorBoundary>\n\n <div className=\"grid gap-6 md:grid-cols-3\">\n <div className=\"md:col-span-2\">\n <ErrorBoundary>\n <RecentPages onSelectPage={onSelectPage} />\n </ErrorBoundary>\n </div>\n\n <div>\n <ErrorBoundary>\n <QuickActions onCreatePage={onCreatePage} onUploadMedia={onUploadMedia} />\n </ErrorBoundary>\n </div>\n </div>\n </div>\n );\n}\n\nDashboardPage.displayName = 'DashboardPage';\n\nexport { DashboardPage };\n","'use client';\n\nimport type { SectionData } from '@structcms/core';\nimport * as React from 'react';\nimport { useAdmin } from '../../hooks/use-admin';\nimport { cn } from '../../lib/utils';\nimport { Button } from '../ui/button';\nimport { SectionEditor } from './section-editor';\n\nexport interface PageEditorProps {\n sections: SectionData[];\n allowedSections: string[];\n onSave: (sections: SectionData[]) => void;\n className?: string;\n}\n\n/**\n * Full page editor with multiple sections, add/remove/reorder sections.\n *\n * @example\n * ```tsx\n * <AdminProvider registry={registry} apiBaseUrl=\"/api/cms\">\n * <PageEditor\n * sections={page.sections}\n * allowedSections={['hero', 'content', 'cta']}\n * onSave={(sections) => savePage({ ...page, sections })}\n * />\n * </AdminProvider>\n * ```\n */\nfunction PageEditor({\n sections: initialSections,\n allowedSections,\n onSave,\n className,\n}: PageEditorProps) {\n const { registry } = useAdmin();\n const [sections, setSections] = React.useState<SectionData[]>(initialSections);\n const [selectedSectionType, setSelectedSectionType] = React.useState<string>(\n allowedSections[0] ?? ''\n );\n\n const handleAddSection = () => {\n if (!selectedSectionType) return;\n const newSection: SectionData = {\n type: selectedSectionType,\n data: {},\n };\n setSections([...sections, newSection]);\n };\n\n const handleRemoveSection = (index: number) => {\n const newSections = [...sections];\n newSections.splice(index, 1);\n setSections(newSections);\n };\n\n const handleMoveUp = (index: number) => {\n if (index === 0) return;\n const newSections = [...sections];\n const temp = newSections[index] as SectionData;\n newSections[index] = newSections[index - 1] as SectionData;\n newSections[index - 1] = temp;\n setSections(newSections);\n };\n\n const handleMoveDown = (index: number) => {\n if (index === sections.length - 1) return;\n const newSections = [...sections];\n const temp = newSections[index] as SectionData;\n newSections[index] = newSections[index + 1] as SectionData;\n newSections[index + 1] = temp;\n setSections(newSections);\n };\n\n const handleSectionChange = (index: number, data: Record<string, unknown>) => {\n const newSections = [...sections];\n const current = newSections[index];\n if (current) {\n newSections[index] = { ...current, data };\n }\n setSections(newSections);\n };\n\n const handleSave = () => {\n onSave(sections);\n };\n\n return (\n <div className={cn('space-y-6', className)} data-testid=\"page-editor\">\n {sections.length === 0 ? (\n <p className=\"text-sm text-muted-foreground text-center py-8\">\n No sections yet. Add a section to get started.\n </p>\n ) : (\n <div className=\"space-y-4\">\n {sections.map((section, index) => {\n const sectionDef = registry.getSection(section.type);\n const sectionLabel = sectionDef?.name ?? section.type;\n\n return (\n <div\n key={`${section.type}-${index}`}\n className=\"rounded-md border border-input bg-background p-4\"\n data-testid={`page-section-${index}`}\n >\n <div className=\"flex items-center justify-between mb-4\">\n <h3 className=\"text-sm font-semibold capitalize\">{sectionLabel}</h3>\n <div className=\"flex gap-1\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => handleMoveUp(index)}\n disabled={index === 0}\n title=\"Move up\"\n data-testid={`section-move-up-${index}`}\n >\n ↑\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => handleMoveDown(index)}\n disabled={index === sections.length - 1}\n title=\"Move down\"\n data-testid={`section-move-down-${index}`}\n >\n ↓\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => handleRemoveSection(index)}\n title=\"Remove section\"\n data-testid={`section-remove-${index}`}\n >\n ✕\n </Button>\n </div>\n </div>\n <SectionEditor\n sectionType={section.type}\n data={section.data}\n onChange={(data) => handleSectionChange(index, data)}\n submitLabel=\"Update Section\"\n />\n </div>\n );\n })}\n </div>\n )}\n\n <div className=\"flex items-center gap-2 border-t border-input pt-4\">\n <select\n value={selectedSectionType}\n onChange={(e) => setSelectedSectionType(e.target.value)}\n className=\"flex h-10 rounded-md border border-input bg-background px-3 py-2 text-sm\"\n data-testid=\"section-type-select\"\n >\n {allowedSections.map((type) => {\n const sectionDef = registry.getSection(type);\n return (\n <option key={type} value={type}>\n {sectionDef?.name ?? type}\n </option>\n );\n })}\n </select>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handleAddSection}\n data-testid=\"add-section\"\n >\n Add Section\n </Button>\n </div>\n\n <div className=\"border-t border-input pt-4\">\n <Button type=\"button\" onClick={handleSave} data-testid=\"save-page\">\n Save Page\n </Button>\n </div>\n </div>\n );\n}\n\nPageEditor.displayName = 'PageEditor';\n\nexport { PageEditor };\n","'use client';\n\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { type FieldType, getFieldMeta } from '@structcms/core';\nimport * as React from 'react';\nimport { Controller, type DefaultValues, type FieldErrors, useForm } from 'react-hook-form';\nimport type { z } from 'zod';\nimport { ArrayField } from '../components/inputs/array-field';\nimport { ImagePicker } from '../components/inputs/image-picker';\nimport { ObjectField } from '../components/inputs/object-field';\nimport { RichTextEditor } from '../components/inputs/rich-text-editor';\nimport { StringInput } from '../components/inputs/string-input';\nimport { TextInput } from '../components/inputs/text-input';\nimport { Button } from '../components/ui/button';\nimport { Input } from '../components/ui/input';\nimport { cn } from './utils';\n\n/**\n * Unwraps Zod wrappers (optional, default, nullable, etc.) to find the inner schema\n */\nfunction unwrapSchema(schema: z.ZodTypeAny): z.ZodTypeAny {\n if ('unwrap' in schema && typeof schema.unwrap === 'function') {\n return unwrapSchema(schema.unwrap() as z.ZodTypeAny);\n }\n if ('_def' in schema) {\n const def = schema._def as Record<string, unknown>;\n if ('innerType' in def && def.innerType) {\n return unwrapSchema(def.innerType as z.ZodTypeAny);\n }\n }\n return schema;\n}\n\n/**\n * Resolves the FieldType from a Zod schema by unwrapping wrappers first\n */\nfunction resolveFieldType(schema: z.ZodTypeAny): FieldType | null {\n const meta = getFieldMeta(schema);\n if (meta) return meta.fieldType;\n\n const unwrapped = unwrapSchema(schema);\n const unwrappedMeta = getFieldMeta(unwrapped);\n return unwrappedMeta?.fieldType ?? null;\n}\n\n/**\n * Converts a camelCase or snake_case field name to a human-readable label\n */\nfunction fieldNameToLabel(name: string): string {\n return name\n .replace(/([A-Z])/g, ' $1')\n .replace(/[_-]/g, ' ')\n .replace(/^\\w/, (c) => c.toUpperCase())\n .trim();\n}\n\nexport interface FormGeneratorProps<T extends z.ZodObject<z.ZodRawShape>> {\n schema: T;\n onSubmit: (data: z.infer<T>) => void;\n onChange?: (data: z.infer<T>) => void;\n defaultValues?: DefaultValues<z.infer<T>>;\n submitLabel?: string;\n className?: string;\n}\n\n/**\n * Generates a React Hook Form from a Zod schema, mapping field types to input components.\n *\n * @example\n * ```tsx\n * const schema = z.object({\n * title: fields.string().min(1),\n * description: fields.text(),\n * content: fields.richtext(),\n * });\n *\n * <FormGenerator\n * schema={schema}\n * onSubmit={(data) => console.log(data)}\n * submitLabel=\"Save\"\n * />\n * ```\n */\nfunction FormGenerator<T extends z.ZodObject<z.ZodRawShape>>({\n schema,\n onSubmit,\n onChange,\n defaultValues,\n submitLabel = 'Submit',\n className,\n}: FormGeneratorProps<T>) {\n const {\n register,\n handleSubmit,\n control,\n watch,\n formState: { errors },\n } = useForm<z.infer<T>>({\n resolver: zodResolver(schema),\n defaultValues,\n });\n\n React.useEffect(() => {\n if (!onChange) return;\n const subscription = watch((values) => {\n onChange(values as z.infer<T>);\n });\n return () => subscription.unsubscribe();\n }, [watch, onChange]);\n\n const shape = schema.shape as Record<string, z.ZodTypeAny>;\n\n const renderField = (fieldName: string, fieldSchema: z.ZodTypeAny) => {\n const fieldType = resolveFieldType(fieldSchema);\n const label = fieldNameToLabel(fieldName);\n const isRequired = !fieldSchema.isOptional();\n const fieldError = (errors as FieldErrors<Record<string, unknown>>)[fieldName];\n const errorMessage = fieldError?.message as string | undefined;\n\n switch (fieldType) {\n case 'string':\n return (\n <StringInput\n key={fieldName}\n label={label}\n required={isRequired}\n error={errorMessage}\n {...register(fieldName as Parameters<typeof register>[0])}\n />\n );\n\n case 'text':\n return (\n <TextInput\n key={fieldName}\n label={label}\n required={isRequired}\n error={errorMessage}\n {...register(fieldName as Parameters<typeof register>[0])}\n />\n );\n\n case 'richtext':\n return (\n <Controller\n key={fieldName}\n name={fieldName as Parameters<typeof register>[0]}\n control={control}\n render={({ field }) => (\n <RichTextEditor\n label={label}\n required={isRequired}\n error={errorMessage}\n value={field.value as string | undefined}\n onChange={field.onChange}\n name={field.name}\n />\n )}\n />\n );\n\n case 'image':\n return (\n <Controller\n key={fieldName}\n name={fieldName as Parameters<typeof register>[0]}\n control={control}\n render={({ field }) => (\n <ImagePicker\n label={label}\n required={isRequired}\n error={errorMessage}\n value={field.value as string | undefined}\n onChange={field.onChange}\n name={field.name}\n />\n )}\n />\n );\n\n case 'array':\n return (\n <Controller\n key={fieldName}\n name={fieldName as Parameters<typeof register>[0]}\n control={control}\n render={({ field }) => (\n <ArrayField<string>\n label={label}\n required={isRequired}\n error={errorMessage}\n value={(field.value as string[] | undefined) ?? []}\n onChange={field.onChange}\n name={field.name}\n createDefaultItem={() => ''}\n renderItem={(item, index, onItemChange) => (\n <Input\n value={item}\n onChange={(e) => onItemChange(e.target.value)}\n data-testid={`${fieldName}-item-${index}`}\n />\n )}\n />\n )}\n />\n );\n\n case 'object': {\n const innerSchema = unwrapSchema(fieldSchema);\n const innerShape =\n 'shape' in innerSchema\n ? ((innerSchema as z.ZodObject<z.ZodRawShape>).shape as Record<string, z.ZodTypeAny>)\n : null;\n\n return (\n <ObjectField key={fieldName} label={label} required={isRequired} error={errorMessage}>\n {innerShape\n ? Object.entries(innerShape).map(([subName, _subSchema]) => {\n const subFieldName = `${fieldName}.${subName}`;\n const subLabel = fieldNameToLabel(subName);\n const subError = (errors as FieldErrors<Record<string, unknown>>)[fieldName] as\n | FieldErrors<Record<string, unknown>>\n | undefined;\n const subErrorMessage = subError?.[subName]?.message as string | undefined;\n\n return (\n <StringInput\n key={subFieldName}\n label={subLabel}\n error={subErrorMessage}\n {...register(subFieldName as Parameters<typeof register>[0])}\n />\n );\n })\n : null}\n </ObjectField>\n );\n }\n\n default:\n return (\n <StringInput\n key={fieldName}\n label={label}\n required={isRequired}\n error={errorMessage}\n {...register(fieldName as Parameters<typeof register>[0])}\n />\n );\n }\n };\n\n return (\n <form\n onSubmit={handleSubmit(onSubmit)}\n className={cn('space-y-4', className)}\n data-testid=\"form-generator\"\n >\n {Object.entries(shape).map(([fieldName, fieldSchema]) => renderField(fieldName, fieldSchema))}\n {!onChange && (\n <Button type=\"submit\" data-testid=\"form-submit\">\n {submitLabel}\n </Button>\n )}\n </form>\n );\n}\n\nFormGenerator.displayName = 'FormGenerator';\n\nexport { FormGenerator, resolveFieldType, fieldNameToLabel };\n","import * as React from 'react';\nimport { cn } from '../../lib/utils';\nimport { Button } from '../ui/button';\nimport { Label } from '../ui/label';\n\nexport interface ArrayFieldProps<T> {\n label: string;\n value: T[];\n onChange: (value: T[]) => void;\n renderItem: (item: T, index: number, onChange: (item: T) => void) => React.ReactNode;\n createDefaultItem: () => T;\n error?: string;\n required?: boolean;\n className?: string;\n id?: string;\n name?: string;\n}\n\n/**\n * Component for array fields with add/remove/reorder functionality.\n *\n * @example\n * ```tsx\n * <ArrayField\n * label=\"Links\"\n * value={links}\n * onChange={setLinks}\n * createDefaultItem={() => ({ label: '', href: '' })}\n * renderItem={(item, index, onChange) => (\n * <div>\n * <input value={item.label} onChange={e => onChange({ ...item, label: e.target.value })} />\n * <input value={item.href} onChange={e => onChange({ ...item, href: e.target.value })} />\n * </div>\n * )}\n * />\n * ```\n */\nfunction ArrayFieldInner<T>(\n {\n label,\n value,\n onChange,\n renderItem,\n createDefaultItem,\n error,\n required,\n className,\n id,\n name,\n }: ArrayFieldProps<T>,\n ref: React.ForwardedRef<HTMLDivElement>\n) {\n const inputId = id || name || React.useId();\n\n const handleAdd = () => {\n onChange([...value, createDefaultItem()]);\n };\n\n const handleRemove = (index: number) => {\n const newValue = [...value];\n newValue.splice(index, 1);\n onChange(newValue);\n };\n\n const handleMoveUp = (index: number) => {\n if (index === 0) return;\n const newValue = [...value];\n const temp = newValue[index] as T;\n newValue[index] = newValue[index - 1] as T;\n newValue[index - 1] = temp;\n onChange(newValue);\n };\n\n const handleMoveDown = (index: number) => {\n if (index === value.length - 1) return;\n const newValue = [...value];\n const temp = newValue[index] as T;\n newValue[index] = newValue[index + 1] as T;\n newValue[index + 1] = temp;\n onChange(newValue);\n };\n\n const handleItemChange = (index: number, item: T) => {\n const newValue = [...value];\n newValue[index] = item;\n onChange(newValue);\n };\n\n return (\n <div ref={ref} className={cn('space-y-2', className)} data-testid=\"array-field\">\n <Label htmlFor={inputId}>\n {label}\n {required && <span className=\"text-destructive ml-1\">*</span>}\n </Label>\n <div\n className={cn(\n 'rounded-md border border-input bg-background p-4',\n error && 'border-destructive'\n )}\n >\n {value.length === 0 ? (\n <p className=\"text-sm text-muted-foreground text-center py-4\">No items yet</p>\n ) : (\n <div className=\"space-y-3\">\n {value.map((item, index) => (\n <div\n // biome-ignore lint/suspicious/noArrayIndexKey: Dynamic array items with no stable IDs\n key={index}\n className=\"flex gap-2 items-start p-3 rounded-md border border-input bg-muted/50\"\n data-testid={`array-item-${index}`}\n >\n <div className=\"flex-1\">\n {renderItem(item, index, (newItem) => handleItemChange(index, newItem))}\n </div>\n <div className=\"flex flex-col gap-1\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => handleMoveUp(index)}\n disabled={index === 0}\n title=\"Move up\"\n data-testid={`move-up-${index}`}\n >\n ↑\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => handleMoveDown(index)}\n disabled={index === value.length - 1}\n title=\"Move down\"\n data-testid={`move-down-${index}`}\n >\n ↓\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => handleRemove(index)}\n title=\"Remove\"\n data-testid={`remove-${index}`}\n >\n ✕\n </Button>\n </div>\n </div>\n ))}\n </div>\n )}\n <div className=\"mt-4\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handleAdd}\n id={inputId}\n data-testid=\"add-item\"\n >\n Add Item\n </Button>\n </div>\n </div>\n {error && (\n <p id={`${inputId}-error`} className=\"text-sm text-destructive\">\n {error}\n </p>\n )}\n </div>\n );\n}\n\nconst ArrayField = React.forwardRef(ArrayFieldInner) as <T>(\n props: ArrayFieldProps<T> & { ref?: React.ForwardedRef<HTMLDivElement> }\n) => React.ReactElement;\n\nexport { ArrayField };\n","import { type VariantProps, cva } from 'class-variance-authority';\nimport * as React from 'react';\nimport { cn } from '../../lib/utils';\n\nconst labelVariants = cva(\n 'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70'\n);\n\nexport interface LabelProps\n extends React.LabelHTMLAttributes<HTMLLabelElement>,\n VariantProps<typeof labelVariants> {}\n\nconst Label = React.forwardRef<HTMLLabelElement, LabelProps>(({ className, ...props }, ref) => (\n // biome-ignore lint/a11y/noLabelWithoutControl: Generic label component, control association handled by consumers\n <label ref={ref} className={cn(labelVariants(), className)} {...props} />\n));\nLabel.displayName = 'Label';\n\nexport { Label, labelVariants };\n","import * as React from 'react';\nimport { cn } from '../../lib/utils';\nimport { MediaBrowser, type MediaItem } from '../media/media-browser';\nimport { Button } from '../ui/button';\nimport { Dialog } from '../ui/dialog';\nimport { Label } from '../ui/label';\n\nexport interface ImagePickerProps {\n label: string;\n value?: string;\n onChange?: (value: string) => void;\n onBrowse?: () => void;\n error?: string;\n required?: boolean;\n className?: string;\n id?: string;\n name?: string;\n}\n\n/**\n * Component for image fields that opens MediaBrowser for selection.\n *\n * @example\n * ```tsx\n * <ImagePicker\n * label=\"Hero Image\"\n * value={imageUrl}\n * onChange={setImageUrl}\n * onBrowse={() => setMediaBrowserOpen(true)}\n * required\n * error={errors.image?.message}\n * />\n * ```\n */\nfunction ImagePicker({\n label,\n value,\n onChange,\n onBrowse,\n error,\n required,\n className,\n id,\n name,\n}: ImagePickerProps) {\n const inputId = id || name || React.useId();\n const [mediaBrowserOpen, setMediaBrowserOpen] = React.useState(false);\n\n const handleClear = () => {\n onChange?.('');\n };\n\n const handleBrowse = onBrowse ?? (() => setMediaBrowserOpen(true));\n\n const handleMediaSelect = (item: MediaItem) => {\n onChange?.(item.url);\n setMediaBrowserOpen(false);\n };\n\n return (\n <div className={cn('space-y-2', className)}>\n <Label htmlFor={inputId}>\n {label}\n {required && <span className=\"text-destructive ml-1\">*</span>}\n </Label>\n <div\n className={cn(\n 'rounded-md border border-input bg-background p-4',\n error && 'border-destructive'\n )}\n >\n {value ? (\n <div className=\"space-y-3\">\n <div className=\"relative aspect-video w-full max-w-xs overflow-hidden rounded-md bg-muted\">\n <img\n src={value}\n alt=\"Preview\"\n className=\"h-full w-full object-cover\"\n data-testid=\"image-preview\"\n />\n </div>\n <div className=\"flex gap-2\">\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={handleBrowse}>\n Change\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={handleClear}\n data-testid=\"clear-button\"\n >\n Clear\n </Button>\n </div>\n </div>\n ) : (\n <div className=\"flex flex-col items-center justify-center py-8 text-center\">\n <div className=\"mb-4 text-4xl text-muted-foreground\">🖼️</div>\n <p className=\"mb-4 text-sm text-muted-foreground\">No image selected</p>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={handleBrowse}\n id={inputId}\n data-testid=\"browse-button\"\n >\n Browse Media\n </Button>\n </div>\n )}\n </div>\n {error && (\n <p id={`${inputId}-error`} className=\"text-sm text-destructive\">\n {error}\n </p>\n )}\n {!onBrowse && (\n <Dialog\n open={mediaBrowserOpen}\n onClose={() => setMediaBrowserOpen(false)}\n title=\"Select Media\"\n >\n <MediaBrowser onSelect={handleMediaSelect} />\n </Dialog>\n )}\n </div>\n );\n}\n\nImagePicker.displayName = 'ImagePicker';\n\nexport { ImagePicker };\n","'use client';\n\nimport * as React from 'react';\nimport { useApiClient } from '../../hooks/use-api-client';\nimport { cn } from '../../lib/utils';\nimport { Button } from '../ui/button';\n\nexport interface MediaItem {\n id: string;\n url: string;\n filename: string;\n mimeType?: string;\n createdAt?: string;\n}\n\nexport interface MediaBrowserProps {\n onSelect?: (item: MediaItem) => void;\n className?: string;\n pageSize?: number;\n}\n\n/**\n * Browse, upload, and select media files.\n *\n * @example\n * ```tsx\n * <AdminProvider registry={registry} apiBaseUrl=\"/api/cms\">\n * <MediaBrowser onSelect={(item) => setImageUrl(item.url)} />\n * </AdminProvider>\n * ```\n */\nfunction MediaBrowser({ onSelect, className, pageSize = 12 }: MediaBrowserProps) {\n const api = useApiClient();\n const [items, setItems] = React.useState<MediaItem[]>([]);\n const [loading, setLoading] = React.useState(true);\n const [error, setError] = React.useState<string | null>(null);\n const [hasMore, setHasMore] = React.useState(false);\n const [page, setPage] = React.useState(0);\n const fileInputRef = React.useRef<HTMLInputElement>(null);\n\n const fetchMedia = React.useCallback(\n async (pageNum: number, append: boolean) => {\n setLoading(true);\n setError(null);\n\n const result = await api.get<MediaItem[]>(\n `/media?limit=${pageSize}&offset=${pageNum * pageSize}`\n );\n\n if (result.error) {\n setError(result.error.message);\n setLoading(false);\n return;\n }\n\n const newItems = result.data ?? [];\n setItems((prev) => (append ? [...prev, ...newItems] : newItems));\n setHasMore(newItems.length >= pageSize);\n setLoading(false);\n },\n [api, pageSize]\n );\n\n React.useEffect(() => {\n void fetchMedia(0, false);\n }, [fetchMedia]);\n\n const handleLoadMore = () => {\n const nextPage = page + 1;\n setPage(nextPage);\n void fetchMedia(nextPage, true);\n };\n\n const handleUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file) return;\n\n const formData = new FormData();\n formData.append('file', file);\n\n setLoading(true);\n setError(null);\n\n const result = await api.upload<MediaItem>('/media', formData);\n\n if (result.error) {\n setError(result.error.message);\n setLoading(false);\n } else {\n // Refresh the list\n setPage(0);\n await fetchMedia(0, false);\n }\n\n // Reset file input\n if (fileInputRef.current) {\n fileInputRef.current.value = '';\n }\n };\n\n const handleDelete = async (item: MediaItem) => {\n const result = await api.delete(`/media/${item.id}`);\n if (result.error) {\n setError(result.error.message);\n return;\n }\n setItems((prev) => prev.filter((i) => i.id !== item.id));\n };\n\n return (\n <div className={cn('space-y-4', className)} data-testid=\"media-browser\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-xl font-semibold\">Media</h2>\n <div>\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n className=\"hidden\"\n onChange={(e) => void handleUpload(e)}\n data-testid=\"file-input\"\n />\n <Button\n type=\"button\"\n onClick={() => fileInputRef.current?.click()}\n data-testid=\"upload-button\"\n >\n Upload\n </Button>\n </div>\n </div>\n\n {error && (\n <p className=\"text-sm text-destructive\" data-testid=\"error\">\n {error}\n </p>\n )}\n\n {!loading && items.length === 0 && !error && (\n <p className=\"text-sm text-muted-foreground text-center py-8\" data-testid=\"empty-state\">\n No media files yet. Upload your first file.\n </p>\n )}\n\n {items.length > 0 && (\n <div\n className=\"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 gap-4\"\n data-testid=\"media-grid\"\n >\n {items.map((item) => (\n <div\n key={item.id}\n className=\"group relative rounded-md border border-input bg-background overflow-hidden\"\n data-testid={`media-item-${item.id}`}\n >\n <button\n type=\"button\"\n className=\"w-full aspect-square bg-muted flex items-center justify-center overflow-hidden cursor-pointer\"\n onClick={() => onSelect?.(item)}\n data-testid={`media-select-${item.id}`}\n >\n <img src={item.url} alt={item.filename} className=\"h-full w-full object-cover\" />\n </button>\n <div className=\"p-2 flex items-center justify-between\">\n <p className=\"text-xs text-muted-foreground truncate flex-1\">{item.filename}</p>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-6 w-6\"\n onClick={() => void handleDelete(item)}\n title=\"Delete\"\n data-testid={`media-delete-${item.id}`}\n >\n ✕\n </Button>\n </div>\n </div>\n ))}\n </div>\n )}\n\n {loading && (\n <p className=\"text-sm text-muted-foreground\" data-testid=\"loading\">\n Loading media...\n </p>\n )}\n\n {hasMore && !loading && (\n <div className=\"text-center\">\n <Button type=\"button\" variant=\"outline\" onClick={handleLoadMore} data-testid=\"load-more\">\n Load More\n </Button>\n </div>\n )}\n </div>\n );\n}\n\nMediaBrowser.displayName = 'MediaBrowser';\n\nexport { MediaBrowser };\n","'use client';\n\nimport * as React from 'react';\nimport { createPortal } from 'react-dom';\nimport { cn } from '../../lib/utils';\n\nexport interface DialogProps {\n open: boolean;\n onClose: () => void;\n children: React.ReactNode;\n className?: string;\n title?: string;\n}\n\n/**\n * Minimal dialog component using React Portal.\n * Renders a modal overlay with backdrop that closes on outside click or Escape key.\n *\n * @example\n * ```tsx\n * <Dialog open={isOpen} onClose={() => setIsOpen(false)} title=\"Select Media\">\n * <MediaBrowser onSelect={handleSelect} />\n * </Dialog>\n * ```\n */\nfunction Dialog({ open, onClose, children, className, title }: DialogProps) {\n const overlayRef = React.useRef<HTMLDivElement>(null);\n\n React.useEffect(() => {\n if (!open) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n onClose();\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n document.body.style.overflow = 'hidden';\n\n return () => {\n document.removeEventListener('keydown', handleKeyDown);\n document.body.style.overflow = '';\n };\n }, [open, onClose]);\n\n const handleOverlayClick = (e: React.MouseEvent<HTMLDivElement>) => {\n if (e.target === overlayRef.current) {\n onClose();\n }\n };\n\n if (!open) return null;\n\n return createPortal(\n <div\n ref={overlayRef}\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50\"\n onClick={handleOverlayClick}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === 'Escape') {\n e.preventDefault();\n onClose();\n }\n }}\n // biome-ignore lint/a11y/useSemanticElements: Dialog overlay backdrop, not a semantic button\n role=\"button\"\n tabIndex={-1}\n data-testid=\"dialog-overlay\"\n >\n <div\n className={cn(\n 'relative mx-4 max-h-[85vh] w-full max-w-3xl overflow-auto rounded-lg border border-input bg-background p-6 shadow-lg',\n className\n )}\n // biome-ignore lint/a11y/useSemanticElements: Using div with role for flexibility, native <dialog> has styling limitations\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={title}\n data-testid=\"dialog-content\"\n >\n {title && (\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold\">{title}</h2>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-sm p-1 text-muted-foreground hover:text-foreground\"\n aria-label=\"Close\"\n data-testid=\"dialog-close\"\n >\n ✕\n </button>\n </div>\n )}\n {children}\n </div>\n </div>,\n document.body\n );\n}\n\nDialog.displayName = 'Dialog';\n\nexport { Dialog };\n","import * as React from 'react';\nimport { cn } from '../../lib/utils';\nimport { Label } from '../ui/label';\n\nexport interface ObjectFieldProps {\n label: string;\n children: React.ReactNode;\n error?: string;\n required?: boolean;\n className?: string;\n id?: string;\n name?: string;\n}\n\n/**\n * Component for nested object fields, rendering sub-form with visual grouping.\n *\n * @example\n * ```tsx\n * <ObjectField label=\"Address\" required>\n * <StringInput label=\"Street\" {...register('address.street')} />\n * <StringInput label=\"City\" {...register('address.city')} />\n * <StringInput label=\"Zip\" {...register('address.zip')} />\n * </ObjectField>\n * ```\n */\nfunction ObjectField({ label, children, error, required, className, id, name }: ObjectFieldProps) {\n const fieldId = id || name || React.useId();\n\n return (\n <div className={cn('space-y-2', className)}>\n <Label htmlFor={fieldId}>\n {label}\n {required && <span className=\"text-destructive ml-1\">*</span>}\n </Label>\n <div\n id={fieldId}\n className={cn(\n 'rounded-md border border-input bg-muted/30 p-4 space-y-4',\n error && 'border-destructive'\n )}\n // biome-ignore lint/a11y/useSemanticElements: Using div with role=\"group\" for consistent styling with other inputs\n role=\"group\"\n aria-labelledby={`${fieldId}-label`}\n aria-describedby={error ? `${fieldId}-error` : undefined}\n data-testid=\"object-field-container\"\n >\n {children}\n </div>\n {error && (\n <p id={`${fieldId}-error`} className=\"text-sm text-destructive\">\n {error}\n </p>\n )}\n </div>\n );\n}\n\nObjectField.displayName = 'ObjectField';\n\nexport { ObjectField };\n","'use client';\n\nimport Link from '@tiptap/extension-link';\nimport { EditorContent, useEditor } from '@tiptap/react';\nimport StarterKit from '@tiptap/starter-kit';\nimport * as React from 'react';\nimport { cn } from '../../lib/utils';\nimport { Label } from '../ui/label';\n\nexport interface RichTextEditorProps {\n label: string;\n value?: string;\n onChange?: (value: string) => void;\n error?: string;\n required?: boolean;\n placeholder?: string;\n className?: string;\n id?: string;\n name?: string;\n}\n\ninterface ToolbarButtonProps {\n onClick: () => void;\n isActive?: boolean;\n disabled?: boolean;\n children: React.ReactNode;\n title: string;\n}\n\nfunction ToolbarButton({ onClick, isActive, disabled, children, title }: ToolbarButtonProps) {\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled}\n title={title}\n className={cn(\n 'px-2 py-1 text-sm rounded hover:bg-accent disabled:opacity-50 disabled:cursor-not-allowed',\n isActive && 'bg-accent text-accent-foreground'\n )}\n >\n {children}\n </button>\n );\n}\n\n/**\n * WYSIWYG editor for richtext fields using TipTap.\n *\n * @example\n * ```tsx\n * <RichTextEditor\n * label=\"Content\"\n * value={content}\n * onChange={setContent}\n * required\n * error={errors.content?.message}\n * />\n * ```\n */\nfunction RichTextEditor({\n label,\n value = '',\n onChange,\n error,\n required,\n placeholder,\n className,\n id,\n name,\n}: RichTextEditorProps) {\n const inputId = id || name || React.useId();\n\n const editor = useEditor({\n extensions: [\n StarterKit.configure({\n heading: {\n levels: [1, 2, 3],\n },\n }),\n Link.extend({ name: 'customLink' }).configure({\n openOnClick: false,\n HTMLAttributes: {\n class: 'text-primary underline',\n },\n }),\n ],\n content: value,\n immediatelyRender: false,\n editorProps: {\n attributes: {\n class: 'prose prose-sm max-w-none min-h-[150px] p-3 focus:outline-none',\n 'aria-invalid': error ? 'true' : 'false',\n ...(error ? { 'aria-describedby': `${inputId}-error` } : {}),\n },\n },\n onUpdate: ({ editor: updatedEditor }) => {\n onChange?.(updatedEditor.getHTML());\n },\n });\n\n const setLink = React.useCallback(() => {\n if (!editor) return;\n\n const previousUrl = editor.getAttributes('link').href as string | undefined;\n const url = window.prompt('URL', previousUrl);\n\n if (url === null) {\n return;\n }\n\n if (url === '') {\n editor.chain().focus().extendMarkRange('link').unsetLink().run();\n return;\n }\n\n editor.chain().focus().extendMarkRange('link').setLink({ href: url }).run();\n }, [editor]);\n\n if (!editor) {\n return null;\n }\n\n return (\n <div className={cn('space-y-2', className)}>\n <Label htmlFor={inputId}>\n {label}\n {required && <span className=\"text-destructive ml-1\">*</span>}\n </Label>\n <div\n className={cn(\n 'rounded-md border border-input bg-background',\n error && 'border-destructive'\n )}\n >\n <div className=\"flex flex-wrap gap-1 border-b border-input p-2\">\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleBold().run()}\n isActive={editor.isActive('bold')}\n disabled={!editor.can().chain().focus().toggleBold().run()}\n title=\"Bold\"\n >\n <strong>B</strong>\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleItalic().run()}\n isActive={editor.isActive('italic')}\n disabled={!editor.can().chain().focus().toggleItalic().run()}\n title=\"Italic\"\n >\n <em>I</em>\n </ToolbarButton>\n <ToolbarButton onClick={setLink} isActive={editor.isActive('link')} title=\"Link\">\n 🔗\n </ToolbarButton>\n <div className=\"w-px bg-border mx-1\" />\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleHeading({ level: 1 }).run()}\n isActive={editor.isActive('heading', { level: 1 })}\n title=\"Heading 1\"\n >\n H1\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleHeading({ level: 2 }).run()}\n isActive={editor.isActive('heading', { level: 2 })}\n title=\"Heading 2\"\n >\n H2\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleHeading({ level: 3 }).run()}\n isActive={editor.isActive('heading', { level: 3 })}\n title=\"Heading 3\"\n >\n H3\n </ToolbarButton>\n <div className=\"w-px bg-border mx-1\" />\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleBulletList().run()}\n isActive={editor.isActive('bulletList')}\n title=\"Bullet List\"\n >\n •\n </ToolbarButton>\n <ToolbarButton\n onClick={() => editor.chain().focus().toggleOrderedList().run()}\n isActive={editor.isActive('orderedList')}\n title=\"Ordered List\"\n >\n 1.\n </ToolbarButton>\n </div>\n <EditorContent editor={editor} id={inputId} data-placeholder={placeholder} />\n </div>\n {error && (\n <p id={`${inputId}-error`} className=\"text-sm text-destructive\">\n {error}\n </p>\n )}\n </div>\n );\n}\n\nRichTextEditor.displayName = 'RichTextEditor';\n\nexport { RichTextEditor };\n","import * as React from 'react';\nimport { cn } from '../../lib/utils';\nimport { Input } from '../ui/input';\nimport { Label } from '../ui/label';\n\nexport interface StringInputProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {\n label: string;\n error?: string;\n}\n\n/**\n * Text input component for string fields with label, placeholder, and validation error display.\n *\n * @example\n * ```tsx\n * <StringInput\n * label=\"Title\"\n * placeholder=\"Enter title...\"\n * required\n * {...register('title')}\n * error={errors.title?.message}\n * />\n * ```\n */\nconst StringInput = React.forwardRef<HTMLInputElement, StringInputProps>(\n ({ className, label, error, required, id, ...props }, ref) => {\n const inputId = id || props.name || React.useId();\n\n return (\n <div className={cn('space-y-2', className)}>\n <Label htmlFor={inputId}>\n {label}\n {required && <span className=\"text-destructive ml-1\">*</span>}\n </Label>\n <Input\n id={inputId}\n ref={ref}\n type=\"text\"\n aria-invalid={!!error}\n aria-describedby={error ? `${inputId}-error` : undefined}\n className={cn(error && 'border-destructive')}\n {...props}\n />\n {error && (\n <p id={`${inputId}-error`} className=\"text-sm text-destructive\">\n {error}\n </p>\n )}\n </div>\n );\n }\n);\nStringInput.displayName = 'StringInput';\n\nexport { StringInput };\n","import * as React from 'react';\nimport { cn } from '../../lib/utils';\nimport { Label } from '../ui/label';\nimport { Textarea } from '../ui/textarea';\n\nexport interface TextInputProps\n extends Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, 'rows'> {\n label: string;\n error?: string;\n rows?: number;\n}\n\n/**\n * Textarea component for long text fields with label, placeholder, and validation error display.\n *\n * @example\n * ```tsx\n * <TextInput\n * label=\"Description\"\n * placeholder=\"Enter description...\"\n * rows={5}\n * required\n * {...register('description')}\n * error={errors.description?.message}\n * />\n * ```\n */\nconst TextInput = React.forwardRef<HTMLTextAreaElement, TextInputProps>(\n ({ className, label, error, required, id, rows = 3, ...props }, ref) => {\n const inputId = id || props.name || React.useId();\n\n return (\n <div className={cn('space-y-2', className)}>\n <Label htmlFor={inputId}>\n {label}\n {required && <span className=\"text-destructive ml-1\">*</span>}\n </Label>\n <Textarea\n id={inputId}\n ref={ref}\n rows={rows}\n aria-invalid={!!error}\n aria-describedby={error ? `${inputId}-error` : undefined}\n className={cn(error && 'border-destructive')}\n {...props}\n />\n {error && (\n <p id={`${inputId}-error`} className=\"text-sm text-destructive\">\n {error}\n </p>\n )}\n </div>\n );\n }\n);\nTextInput.displayName = 'TextInput';\n\nexport { TextInput };\n","import * as React from 'react';\nimport { cn } from '../../lib/utils';\n\nexport interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}\n\nconst Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(\n ({ className, ...props }, ref) => {\n return (\n <textarea\n className={cn(\n 'flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',\n className\n )}\n ref={ref}\n {...props}\n />\n );\n }\n);\nTextarea.displayName = 'Textarea';\n\nexport { Textarea };\n","'use client';\nimport type { z } from 'zod';\nimport { useAdmin } from '../../hooks/use-admin';\nimport { FormGenerator } from '../../lib/form-generator';\nimport { cn } from '../../lib/utils';\n\nexport interface SectionEditorProps {\n sectionType: string;\n data?: Record<string, unknown>;\n onChange: (data: Record<string, unknown>) => void;\n submitLabel?: string;\n className?: string;\n}\n\n/**\n * Component that renders a form for a section based on its schema from the registry.\n *\n * @example\n * ```tsx\n * <AdminProvider registry={registry} apiBaseUrl=\"/api/cms\">\n * <SectionEditor\n * sectionType=\"hero\"\n * data={{ title: 'Hello', subtitle: 'World' }}\n * onChange={(data) => console.log(data)}\n * />\n * </AdminProvider>\n * ```\n */\nfunction SectionEditor({\n sectionType,\n data,\n onChange,\n submitLabel = 'Save Section',\n className,\n}: SectionEditorProps) {\n const { registry } = useAdmin();\n\n const section = registry.getSection(sectionType);\n\n if (!section) {\n return (\n <div\n className={cn('rounded-md border border-destructive p-4', className)}\n data-testid=\"section-editor-error\"\n >\n <p className=\"text-sm text-destructive\">\n Unknown section type: <strong>{sectionType}</strong>\n </p>\n </div>\n );\n }\n\n return (\n <div className={cn('space-y-4', className)} data-testid=\"section-editor\">\n <h3 className=\"text-lg font-semibold capitalize\">{section.name}</h3>\n <FormGenerator\n schema={section.schema as z.ZodObject<z.ZodRawShape>}\n onSubmit={onChange}\n onChange={onChange}\n defaultValues={data}\n submitLabel={submitLabel}\n />\n </div>\n );\n}\n\nSectionEditor.displayName = 'SectionEditor';\n\nexport { SectionEditor };\n","'use client';\n\nimport * as React from 'react';\nimport { cn } from '../../lib/utils';\nimport { Button } from '../ui/button';\n\nexport interface SidebarNavItem {\n label: string;\n path: string;\n}\n\nconst DEFAULT_NAV_ITEMS: SidebarNavItem[] = [\n { label: 'Pages', path: '/pages' },\n { label: 'Navigation', path: '/navigation' },\n { label: 'Media', path: '/media' },\n];\n\nexport interface AdminLayoutProps {\n children: React.ReactNode;\n title?: string;\n navItems?: SidebarNavItem[];\n activePath?: string;\n onNavigate: (path: string) => void;\n className?: string;\n}\n\n/**\n * Admin layout with sidebar navigation, header, and content area.\n *\n * @example\n * ```tsx\n * <AdminLayout\n * title=\"My CMS\"\n * onNavigate={(path) => router.push(path)}\n * activePath=\"/pages\"\n * >\n * <PageList ... />\n * </AdminLayout>\n * ```\n */\nfunction AdminLayout({\n children,\n title = 'StructCMS',\n navItems = DEFAULT_NAV_ITEMS,\n activePath,\n onNavigate,\n className,\n}: AdminLayoutProps) {\n const [sidebarOpen, setSidebarOpen] = React.useState(false);\n\n return (\n <div className={cn('flex h-screen bg-background', className)} data-testid=\"admin-layout\">\n {/* Mobile overlay */}\n {sidebarOpen && (\n <div\n className=\"fixed inset-0 z-40 bg-black/50 md:hidden\"\n onClick={() => setSidebarOpen(false)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === 'Escape') {\n setSidebarOpen(false);\n }\n }}\n role=\"button\"\n tabIndex={0}\n data-testid=\"sidebar-overlay\"\n />\n )}\n\n {/* Sidebar */}\n <aside\n className={cn(\n 'fixed inset-y-0 left-0 z-50 w-64 bg-card border-r border-input transform transition-transform duration-200 md:relative md:translate-x-0',\n sidebarOpen ? 'translate-x-0' : '-translate-x-full'\n )}\n data-testid=\"sidebar\"\n >\n <div className=\"flex items-center h-14 px-4 border-b border-input\">\n <h1 className=\"text-lg font-bold\" data-testid=\"sidebar-title\">\n {title}\n </h1>\n </div>\n <nav className=\"p-2 space-y-1\" data-testid=\"sidebar-nav\">\n {navItems.map((item) => (\n <button\n key={item.path}\n type=\"button\"\n className={cn(\n 'w-full text-left px-3 py-2 rounded-md text-sm transition-colors',\n activePath === item.path ? 'bg-primary text-primary-foreground' : 'hover:bg-muted'\n )}\n onClick={() => {\n onNavigate(item.path);\n setSidebarOpen(false);\n }}\n data-testid={`nav-link-${item.path}`}\n >\n {item.label}\n </button>\n ))}\n </nav>\n </aside>\n\n {/* Main content */}\n <div className=\"flex-1 flex flex-col min-w-0\">\n {/* Header */}\n <header\n className=\"flex items-center h-14 px-4 border-b border-input bg-card\"\n data-testid=\"header\"\n >\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"md:hidden mr-2\"\n onClick={() => setSidebarOpen(!sidebarOpen)}\n data-testid=\"sidebar-toggle\"\n >\n ☰\n </Button>\n <h2 className=\"text-lg font-semibold\" data-testid=\"header-title\">\n {title}\n </h2>\n </header>\n\n {/* Content */}\n <main className=\"flex-1 overflow-auto p-6\" data-testid=\"main-content\">\n {children}\n </main>\n </div>\n </div>\n );\n}\n\nAdminLayout.displayName = 'AdminLayout';\n\nexport { AdminLayout };\n","import type React from 'react';\nimport { useState } from 'react';\nimport { useAuth } from '../../context/auth-context';\nimport { Button } from '../ui/button';\nimport { Input } from '../ui/input';\nimport { Label } from '../ui/label';\n\nexport interface LoginFormProps {\n onSuccess?: () => void;\n onError?: (error: Error) => void;\n}\n\nexport function LoginForm({ onSuccess, onError }: LoginFormProps) {\n const { signIn } = useAuth();\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [error, setError] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setError(null);\n setIsSubmitting(true);\n\n try {\n await signIn(email, password);\n onSuccess?.();\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Sign in failed';\n setError(errorMessage);\n onError?.(err instanceof Error ? err : new Error(errorMessage));\n } finally {\n setIsSubmitting(false);\n }\n };\n\n return (\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"email\">Email</Label>\n <Input\n id=\"email\"\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder=\"admin@example.com\"\n required\n disabled={isSubmitting}\n />\n </div>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"password\">Password</Label>\n <Input\n id=\"password\"\n type=\"password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n placeholder=\"••••••••\"\n required\n disabled={isSubmitting}\n />\n </div>\n\n {error && <div className=\"text-sm text-red-600 bg-red-50 p-3 rounded-md\">{error}</div>}\n\n <Button type=\"submit\" className=\"w-full\" disabled={isSubmitting}>\n {isSubmitting ? 'Signing in...' : 'Sign In'}\n </Button>\n </form>\n );\n}\n","import type React from 'react';\nimport { useAuth } from '../../context/auth-context';\n\nexport interface ProtectedRouteProps {\n children: React.ReactNode;\n fallback?: React.ReactNode;\n loadingFallback?: React.ReactNode;\n}\n\nexport function ProtectedRoute({ children, fallback, loadingFallback }: ProtectedRouteProps) {\n const { isAuthenticated, isLoading } = useAuth();\n\n // Bypass auth in test/dev mode\n const disableAuth =\n typeof process !== 'undefined' && process.env?.NEXT_PUBLIC_DISABLE_AUTH === 'true';\n if (disableAuth) {\n return <>{children}</>;\n }\n\n if (isLoading) {\n return <>{loadingFallback || <div>Loading...</div>}</>;\n }\n\n if (!isAuthenticated) {\n return <>{fallback || <div>Please sign in to access this page.</div>}</>;\n }\n\n return <>{children}</>;\n}\n","import type React from 'react';\nimport { Button } from '../ui/button';\n\nexport interface OAuthButtonProps {\n provider: 'google' | 'github' | 'gitlab' | 'azure' | 'bitbucket';\n apiBaseUrl: string;\n redirectTo?: string;\n children?: React.ReactNode;\n className?: string;\n}\n\nexport function OAuthButton({\n provider,\n apiBaseUrl,\n redirectTo,\n children,\n className,\n}: OAuthButtonProps) {\n const handleClick = async () => {\n try {\n const response = await fetch(`${apiBaseUrl}/auth/oauth`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ provider, redirectTo }),\n });\n\n if (!response.ok) {\n throw new Error('OAuth initialization failed');\n }\n\n const { url } = await response.json();\n window.location.href = url;\n } catch (error) {\n console.error('OAuth error:', error);\n }\n };\n\n const providerLabels = {\n google: 'Google',\n github: 'GitHub',\n gitlab: 'GitLab',\n azure: 'Azure',\n bitbucket: 'Bitbucket',\n };\n\n return (\n <Button type=\"button\" variant=\"outline\" onClick={handleClick} className={className}>\n {children || `Sign in with ${providerLabels[provider]}`}\n </Button>\n );\n}\n"],"mappings":"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","names":["import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_react","React","React","import_jsx_runtime","React","import_jsx_runtime","import_jsx_runtime","React","import_jsx_runtime","React","import_jsx_runtime","React","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","React","import_jsx_runtime","import_jsx_runtime","React","React","React","import_class_variance_authority","React","import_jsx_runtime","import_jsx_runtime","React","React","import_jsx_runtime","React","import_jsx_runtime","import_jsx_runtime","React","import_jsx_runtime","import_react","React","import_jsx_runtime","StarterKit","Link","React","import_jsx_runtime","React","React","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","React","import_jsx_runtime","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime"]}