@jmruthers/pace-core 0.5.61 → 0.5.63

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/dist/{DataTable-5M6MV2VY.js → DataTable-7BER7PDS.js} +6 -6
  2. package/dist/{DataTable-DqDDvBfI.d.ts → DataTable-D15XipLZ.d.ts} +7 -0
  3. package/dist/{PublicLoadingSpinner-CrMOrhNz.d.ts → PublicLoadingSpinner-CXJ-W9wZ.d.ts} +2 -2
  4. package/dist/{chunk-44SAHU2N.js → chunk-2LPYEFXI.js} +5 -5
  5. package/dist/chunk-4BWGRQBG.js +74 -0
  6. package/dist/chunk-4BWGRQBG.js.map +1 -0
  7. package/dist/{chunk-XMTHMOOM.js → chunk-BTCA3ENN.js} +4 -4
  8. package/dist/{chunk-ESXTFEE6.js → chunk-C7GUF747.js} +3 -3
  9. package/dist/{chunk-W7PPXKTZ.js → chunk-CKNY7HYS.js} +2 -2
  10. package/dist/{chunk-5MLDIGHB.js → chunk-FVDOEGGG.js} +3 -3
  11. package/dist/{chunk-HFDYTSAP.js → chunk-QVEOQVD4.js} +3 -3
  12. package/dist/{chunk-XDXG6QVH.js → chunk-S66AJVI2.js} +13 -6
  13. package/dist/chunk-S66AJVI2.js.map +1 -0
  14. package/dist/{chunk-E4FPK232.js → chunk-T2MQY57J.js} +2 -2
  15. package/dist/{chunk-4ULBJNIT.js → chunk-T6HVDA24.js} +2 -2
  16. package/dist/{chunk-STT7INZR.js → chunk-ULBI5JGB.js} +2 -1
  17. package/dist/{chunk-CGSYCF2W.js → chunk-VTJ5HCZB.js} +2 -2
  18. package/dist/components.d.ts +82 -5
  19. package/dist/components.js +258 -9
  20. package/dist/components.js.map +1 -1
  21. package/dist/{appConfig-DjpeG6P-.d.ts → formatting-BfDeV-ja.d.ts} +29 -1
  22. package/dist/hooks.d.ts +3 -2
  23. package/dist/hooks.js +5 -5
  24. package/dist/index.d.ts +8 -11
  25. package/dist/index.js +25 -14
  26. package/dist/index.js.map +1 -1
  27. package/dist/{organisation-DD0yBbGU.d.ts → organisation-t-vvQC3g.d.ts} +1 -1
  28. package/dist/providers.d.ts +2 -2
  29. package/dist/providers.js +4 -4
  30. package/dist/rbac/index.js +6 -6
  31. package/dist/types.js +1 -1
  32. package/dist/{usePublicRouteParams-Cu6oKazv.d.ts → usePublicRouteParams-CdoFxnJK.d.ts} +2 -63
  33. package/dist/useToast-Bm6TnSK-.d.ts +63 -0
  34. package/dist/utils.d.ts +3 -31
  35. package/dist/utils.js +8 -41
  36. package/dist/utils.js.map +1 -1
  37. package/docs/api/classes/ErrorBoundary.md +1 -1
  38. package/docs/api/classes/InvalidScopeError.md +1 -1
  39. package/docs/api/classes/MissingUserContextError.md +1 -1
  40. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  41. package/docs/api/classes/PermissionDeniedError.md +1 -1
  42. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  43. package/docs/api/classes/RBACAuditManager.md +1 -1
  44. package/docs/api/classes/RBACCache.md +1 -1
  45. package/docs/api/classes/RBACEngine.md +1 -1
  46. package/docs/api/classes/RBACError.md +1 -1
  47. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  48. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  49. package/docs/api/classes/StorageUtils.md +1 -1
  50. package/docs/api/interfaces/AggregateConfig.md +1 -1
  51. package/docs/api/interfaces/ButtonProps.md +1 -1
  52. package/docs/api/interfaces/CardProps.md +1 -1
  53. package/docs/api/interfaces/ColorPalette.md +1 -1
  54. package/docs/api/interfaces/ColorShade.md +1 -1
  55. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  56. package/docs/api/interfaces/DataTableAction.md +1 -1
  57. package/docs/api/interfaces/DataTableColumn.md +1 -1
  58. package/docs/api/interfaces/DataTableProps.md +44 -18
  59. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  60. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  61. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  62. package/docs/api/interfaces/EventContextType.md +1 -1
  63. package/docs/api/interfaces/EventLogoProps.md +1 -1
  64. package/docs/api/interfaces/EventProviderProps.md +1 -1
  65. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  66. package/docs/api/interfaces/FileUploadProps.md +1 -1
  67. package/docs/api/interfaces/FooterProps.md +1 -1
  68. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  69. package/docs/api/interfaces/InputProps.md +1 -1
  70. package/docs/api/interfaces/LabelProps.md +1 -1
  71. package/docs/api/interfaces/LoginFormProps.md +1 -1
  72. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  73. package/docs/api/interfaces/NavigationContextType.md +1 -1
  74. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  75. package/docs/api/interfaces/NavigationItem.md +1 -1
  76. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  77. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  78. package/docs/api/interfaces/Organisation.md +1 -1
  79. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  80. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  81. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  82. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  83. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  84. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  85. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  86. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  87. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  88. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  89. package/docs/api/interfaces/PaletteData.md +1 -1
  90. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  91. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  92. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  93. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  94. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  95. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  96. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  97. package/docs/api/interfaces/RBACConfig.md +1 -1
  98. package/docs/api/interfaces/RBACContextType.md +1 -1
  99. package/docs/api/interfaces/RBACLogger.md +1 -1
  100. package/docs/api/interfaces/RBACProviderProps.md +1 -1
  101. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  102. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  103. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  104. package/docs/api/interfaces/RouteConfig.md +1 -1
  105. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  106. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  107. package/docs/api/interfaces/StorageConfig.md +1 -1
  108. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  109. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  110. package/docs/api/interfaces/StorageListOptions.md +1 -1
  111. package/docs/api/interfaces/StorageListResult.md +1 -1
  112. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  113. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  114. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  115. package/docs/api/interfaces/StyleImport.md +1 -1
  116. package/docs/api/interfaces/ToastActionElement.md +1 -1
  117. package/docs/api/interfaces/ToastProps.md +1 -1
  118. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  119. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  120. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  121. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  122. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  123. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  124. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  125. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  126. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  127. package/docs/api/interfaces/UserEventAccess.md +1 -1
  128. package/docs/api/interfaces/UserMenuProps.md +1 -1
  129. package/docs/api/interfaces/UserProfile.md +1 -1
  130. package/docs/api/modules.md +148 -26
  131. package/docs/implementation-guides/data-tables.md +67 -0
  132. package/package.json +1 -1
  133. package/src/components/DataTable/DataTable.tsx +13 -0
  134. package/src/components/DataTable/__tests__/DataTable.default-state.test.tsx +414 -0
  135. package/src/components/DataTable/components/DataTableCore.tsx +19 -2
  136. package/src/components/DataTable/types.ts +9 -0
  137. package/src/components/Dialog/examples/__tests__/SmartDialogExample.unit.test.tsx +151 -0
  138. package/src/components/Dialog/utils/__tests__/safeHtml.unit.test.ts +611 -0
  139. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.accessibility.test.tsx +287 -0
  140. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.integration.test.tsx +861 -0
  141. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.performance.test.tsx +628 -0
  142. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +777 -0
  143. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.unit.test.tsx +901 -0
  144. package/src/components/Toast/index.ts +2 -0
  145. package/src/components/index.ts +15 -0
  146. package/src/hooks/__tests__/useApiFetch.unit.test.ts +1 -1
  147. package/src/hooks/useFileReference.ts +37 -0
  148. package/src/index.ts +10 -0
  149. package/src/styles/base.css +208 -0
  150. package/src/styles/semantic.css +24 -0
  151. package/dist/chunk-W66AZIOH.js +0 -29
  152. package/dist/chunk-W66AZIOH.js.map +0 -1
  153. package/dist/chunk-XDXG6QVH.js.map +0 -1
  154. /package/dist/{DataTable-5M6MV2VY.js.map → DataTable-7BER7PDS.js.map} +0 -0
  155. /package/dist/{chunk-44SAHU2N.js.map → chunk-2LPYEFXI.js.map} +0 -0
  156. /package/dist/{chunk-XMTHMOOM.js.map → chunk-BTCA3ENN.js.map} +0 -0
  157. /package/dist/{chunk-ESXTFEE6.js.map → chunk-C7GUF747.js.map} +0 -0
  158. /package/dist/{chunk-W7PPXKTZ.js.map → chunk-CKNY7HYS.js.map} +0 -0
  159. /package/dist/{chunk-5MLDIGHB.js.map → chunk-FVDOEGGG.js.map} +0 -0
  160. /package/dist/{chunk-HFDYTSAP.js.map → chunk-QVEOQVD4.js.map} +0 -0
  161. /package/dist/{chunk-E4FPK232.js.map → chunk-T2MQY57J.js.map} +0 -0
  162. /package/dist/{chunk-4ULBJNIT.js.map → chunk-T6HVDA24.js.map} +0 -0
  163. /package/dist/{chunk-STT7INZR.js.map → chunk-ULBI5JGB.js.map} +0 -0
  164. /package/dist/{chunk-CGSYCF2W.js.map → chunk-VTJ5HCZB.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/index.ts","../src/components/Form/FormField.tsx","../src/components/Form/FormErrorSummary.tsx","../src/components/Form/FormLiveRegion.tsx","../src/components/Form/FormFieldset.tsx","../src/components/SuperAdminGuard.tsx","../src/components/FileUpload.tsx","../src/hooks/useFileReference.ts","../src/utils/file-reference.ts"],"sourcesContent":["/**\n * @file Complete Components Library Export\n * @package @jmruthers/pace-core\n * @module Components\n * @since 0.1.0\n * \n * This file exports ALL components, providers, and utilities in the PACE Core library.\n * Use this import path when you need access to specialized components not included in the main export.\n * \n * @example\n * // Complete library access\n * import { Dialog, NavigationMenu } from '@jmruthers/pace-core/components';\n * \n * // For common components, prefer the main export:\n * import { Button, Card } from '@jmruthers/pace-core';\n */\n\n// ============================================================================\n// AUTHENTICATION & AUTHORIZATION\n// ============================================================================\n\n// Unified auth provider (replaces individual providers)\nexport { UnifiedAuthProvider, useUnifiedAuth } from '../providers/UnifiedAuthProvider';\nexport type { UnifiedAuthProviderProps, UnifiedAuthContextType } from '../providers/UnifiedAuthProvider';\n\n// ============================================================================\n// BASIC UI COMPONENTS\n// ============================================================================\n\nexport { Button } from './Button';\nexport type { ButtonProps } from './Button';\n\nexport { \n Card, \n CardHeader, \n CardFooter, \n CardTitle, \n CardDescription, \n CardContent,\n CardActions\n} from './Card';\nexport type { CardProps, CardActionsProps } from './Card';\n\nexport { Input } from './Input';\nexport type { InputProps } from './Input';\nexport { Label } from './Label';\nexport type { LabelProps } from './Label';\n\nexport { Alert, AlertTitle, AlertDescription } from './Alert';\nexport { Avatar, AvatarImage, AvatarFallback } from './Avatar';\n\nexport { Checkbox } from './Checkbox';\nexport { Progress } from './Progress';\n\n// Table components\nexport {\n Table,\n TableHeader,\n TableBody,\n TableCaption,\n TableCell,\n TableFooter,\n TableHead,\n TableRow,\n} from './Table/Table';\n\n// ============================================================================\n// ADVANCED UI COMPONENTS\n// ============================================================================\n\n// Dialog exports\nexport {\n Dialog,\n DialogPortal,\n DialogOverlay,\n DialogTrigger,\n DialogClose,\n DialogContent,\n DialogHeader,\n DialogBody,\n DialogFooter,\n DialogTitle,\n DialogDescription,\n} from './Dialog/Dialog';\nexport type {\n DialogProps,\n DialogTriggerProps,\n DialogContentProps,\n DialogOverlayProps,\n DialogHeaderProps,\n DialogFooterProps,\n DialogTitleProps,\n DialogDescriptionProps,\n DialogSize\n} from './Dialog/Dialog';\n\n// Dropdown Menu exports\n// DropdownMenu components have been merged into Select components\n\n// Select exports (includes all dropdown functionality)\nexport {\n Select,\n SelectGroup,\n SelectValue,\n SelectTrigger,\n SelectContent,\n SelectLabel,\n SelectItem,\n SelectSeparator,\n} from './Select';\n\n// Toast exports\nexport {\n Toast,\n Toaster,\n ToastAction,\n ToastProvider,\n ToastViewport,\n ToastTitle,\n ToastDescription,\n ToastClose,\n} from './Toast';\nexport type { ToastActionElement, ToastProps } from './Toast';\n\n// Tooltip exports\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider, TooltipRoot } from './Tooltip';\n\n// ============================================================================\n// DATA DISPLAY COMPONENTS\n// ============================================================================\n\nexport {\n DataTable,\n type DataTableProps,\n type DataTableColumn,\n type DataTableAction,\n type DataTableToolbarButton,\n type AggregateConfig,\n type EmptyStateConfig,\n type GetRowId\n} from './DataTable';\n\n// Re-export types from DataTable types\nexport type { DataRecord } from './DataTable/types';\n\n// ============================================================================\n// FORM COMPONENTS\n// ============================================================================\n\nexport { \n Form, \n FormField, \n FormErrorSummary, \n FormLiveRegion, \n FormFieldset \n} from './Form';\nexport type { \n FormProps, \n FormFieldProps, \n FormErrorSummaryProps, \n FormLiveRegionProps, \n FormFieldsetProps \n} from './Form';\n\n// LoginForm - ensure it's exported\nexport { LoginForm } from './LoginForm';\nexport type { LoginFormProps } from './LoginForm';\n\n// ============================================================================\n// LAYOUT COMPONENTS\n// ============================================================================\n\nexport { Header } from './Header';\nexport { Footer } from './Footer';\nexport type { FooterProps } from './Footer';\n\n// Public Layout Components\nexport * from './PublicLayout';\n\n// ============================================================================\n// SECURITY COMPONENTS\n// ============================================================================\n\n// Super Admin Guard components\nexport { \n SuperAdminGuard, \n SuperAdminBadge, \n SuperAdminDebugPanel \n} from './SuperAdminGuard';\nexport type { SuperAdminGuardProps } from './SuperAdminGuard';\n\n// Removed: Protected and AdminGuard components (unused)\n\n// ============================================================================\n// NAVIGATION COMPONENTS\n// ============================================================================\n\nexport {\n NavigationMenu,\n} from './NavigationMenu';\nexport type { NavigationMenuProps, NavigationItem } from './NavigationMenu';\n\nexport { OrganisationSelector } from './OrganisationSelector';\nexport type { OrganisationSelectorProps } from './OrganisationSelector';\n\nexport { UserMenu } from './UserMenu';\n\n// Reusable Page/Layout Components\nexport * from './PaceAppLayout';\nexport * from './PaceLoginPage';\n\n// ============================================================================\n// UTILITY COMPONENTS\n// ============================================================================\n\nexport { ErrorBoundary } from './ErrorBoundary';\nexport type { ErrorBoundaryProps, ErrorBoundaryState } from './ErrorBoundary';\nexport { LoadingSpinner } from './LoadingSpinner';\n\n// ============================================================================\n// EVENT MANAGEMENT\n// ============================================================================\n\nexport { EventSelector } from './EventSelector';\n\n// ============================================================================\n// AUTHENTICATION FORMS\n// ============================================================================\n\n// Password Component exports\nexport { PasswordResetForm } from './PasswordReset';\n\n// ============================================================================\n// STORAGE COMPONENTS\n// ============================================================================\n\nexport { FileUpload } from './FileUpload';\nexport type { FileUploadProps } from './FileUpload';\n\n\n// ============================================================================\n// HOOKS\n// ============================================================================\n\nexport { useStorage, useFileUpload } from '../hooks/useStorage';\nexport type { UseStorageOptions, UseStorageReturn } from '../hooks/useStorage';\n\n// RBAC Components - Use the new RBAC system\n// For RBAC functionality, import from @jmruthers/pace-core/rbac\n// export { PermissionGuard, AccessLevelGuard } from '@jmruthers/pace-core/rbac';\n","/**\n * @file FormField Component\n * @package @jmruthers/pace-core\n * @module Components/Form\n * @since 0.1.0\n *\n * A flexible form field component that integrates with React Hook Form and provides\n * built-in validation, error handling, and accessibility features.\n *\n * Features:\n * - React Hook Form integration with Controller\n * - Built-in validation with error display\n * - Accessible labels and error messages\n * - Custom render function support\n * - TypeScript support with generic field paths\n * - Consistent styling with error states\n * - Test ID support for testing\n * - Flexible input types and props\n *\n * @example\n * ```tsx\n * // Basic text field\n * <FormField\n * name=\"username\"\n * label=\"Username\"\n * placeholder=\"Enter your username\"\n * validation={{ required: true }}\n * />\n * \n * // Email field with custom validation\n * <FormField\n * name=\"email\"\n * label=\"Email Address\"\n * type=\"email\"\n * validation={{\n * required: true,\n * pattern: {\n * value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}$/i,\n * message: \"Invalid email address\"\n * }\n * }}\n * />\n * \n * // Custom render function\n * <FormField\n * name=\"avatar\"\n * label=\"Profile Picture\"\n * render={({ field }) => (\n * <input\n * {...field}\n * type=\"file\"\n * accept=\"image/*\"\n * className=\"file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-sec-50 file:text-sec-700 hover:file:bg-sec-100\"\n * />\n * )}\n * />\n * \n * // With test ID for testing\n * <FormField\n * name=\"password\"\n * label=\"Password\"\n * type=\"password\"\n * data-testid=\"password-field\"\n * validation={{\n * required: true,\n * minLength: {\n * value: 8,\n * message: \"Password must be at least 8 characters\"\n * }\n * }}\n * />\n * ```\n *\n * @accessibility\n * - Proper label association with htmlFor\n * - Error messages with role=\"alert\"\n * - Required field indicators\n * - Focus management\n * - Screen reader friendly error announcements\n * - Keyboard navigation support\n *\n * @dependencies\n * - react-hook-form - Form integration\n * - React 18+ - Hooks and context\n * - Tailwind CSS - Styling\n */\n\nimport React from 'react';\nimport { useFormContext, Controller, FieldPath, FieldValues } from 'react-hook-form';\nimport { cn } from '../../utils/cn';\nimport { Label } from '../Label';\n\nexport interface FormFieldProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>\n> {\n /**\n * Field name\n */\n name: TName;\n \n /**\n * Field label\n */\n label?: string;\n \n /**\n * Field type\n */\n type?: string;\n \n /**\n * Placeholder text\n */\n placeholder?: string;\n \n /**\n * Additional props for the input\n */\n inputProps?: React.InputHTMLAttributes<HTMLInputElement>;\n \n /**\n * Validation rules\n */\n validation?: {\n required?: boolean;\n pattern?: {\n value: RegExp;\n message: string;\n };\n minLength?: {\n value: number;\n message: string;\n };\n maxLength?: {\n value: number;\n message: string;\n };\n };\n \n /**\n * Custom render function\n */\n render?: ({ field }: { field: any }) => React.ReactElement;\n \n /**\n * Test ID\n */\n 'data-testid'?: string;\n \n /**\n * Class name\n */\n className?: string;\n}\n\n/**\n * FormField component for React Hook Form integration\n * \n * @template TFieldValues - The type of form field values\n * @template TName - The type of the field name (must be a valid field path)\n * @param props - Form field configuration and validation\n * @returns JSX.Element - The rendered form field with validation\n * \n * @example\n * ```tsx\n * <FormField\n * name=\"email\"\n * label=\"Email\"\n * type=\"email\"\n * validation={{\n * required: true,\n * pattern: {\n * value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}$/i,\n * message: \"Please enter a valid email address\"\n * }\n * }}\n * />\n * ```\n */\nexport function FormField<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>\n>({\n name,\n label,\n type = \"text\",\n placeholder,\n inputProps,\n validation,\n render,\n 'data-testid': testId,\n className,\n}: FormFieldProps<TFieldValues, TName>) {\n const { control, formState: { errors } } = useFormContext<TFieldValues>();\n const fieldError = errors[name];\n\n // Safely extract error message\n const errorMessage = fieldError && typeof fieldError === 'object' && 'message' in fieldError \n ? String(fieldError.message) \n : undefined;\n\n return (\n <div className={cn(\"space-y-2\", className)}>\n {label && (\n <Label htmlFor={name}>\n {label}\n {validation?.required && (\n <span className=\"text-destructive ml-1\" aria-label=\"required\">\n *\n </span>\n )}\n </Label>\n )}\n \n <Controller\n name={name}\n control={control}\n rules={validation}\n render={({ field }) => {\n if (render) {\n return render({ field });\n }\n \n return (\n <input\n {...field}\n id={name}\n type={type}\n placeholder={placeholder}\n data-testid={testId}\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 fieldError && \"border-destructive focus-visible:ring-destructive\"\n )}\n {...inputProps}\n />\n );\n }}\n />\n \n {errorMessage && (\n <p className=\"text-destructive\" role=\"alert\">\n {errorMessage}\n </p>\n )}\n </div>\n );\n}\n","\n/**\n * @file FormErrorSummary Component\n * @package @jmruthers/pace-core\n * @module Components/Form\n * @since 0.1.0\n *\n * A form error summary component that displays validation errors in a user-friendly format.\n * Provides a centralized location for users to see all form errors at once.\n *\n * Features:\n * - Displays all form errors in one place\n * - Configurable error display format\n * - Optional field name display\n * - Accessible error presentation\n * - Consistent styling with Alert component\n * - Automatic error filtering\n * - Responsive design\n *\n * @example\n * ```tsx\n * // Basic error summary\n * <FormErrorSummary errors={formErrors} />\n * \n * // With custom title\n * <FormErrorSummary \n * errors={formErrors}\n * title=\"Please correct the following issues:\"\n * />\n * \n * // Show field names with errors\n * <FormErrorSummary \n * errors={formErrors}\n * showFieldNames={true}\n * />\n * \n * // In a form with React Hook Form\n * const { formState: { errors } } = useForm();\n * \n * <Form onSubmit={handleSubmit}>\n * <FormField name=\"email\" label=\"Email\" />\n * <FormField name=\"password\" label=\"Password\" />\n * <FormErrorSummary errors={errors} />\n * <Button type=\"submit\">Submit</Button>\n * </Form>\n * ```\n *\n * @accessibility\n * - Uses Alert component for consistent accessibility\n * - Proper heading hierarchy with h3\n * - List structure for error items\n * - Screen reader friendly error announcements\n * - High contrast support via Alert component\n *\n * @dependencies\n * - Alert component for consistent styling\n * - React 18+ - Component framework\n * - Tailwind CSS - Styling\n */\n\nimport { Alert } from '../Alert';\n\nexport interface FormErrorSummaryProps {\n /** Form validation errors object */\n errors?: Record<string, any>;\n /** Title displayed above the error list */\n title?: string;\n /** Whether to show field names alongside error messages */\n showFieldNames?: boolean;\n}\n\n/**\n * FormErrorSummary component for displaying form validation errors\n * \n * This component provides a user-friendly way to display all form errors\n * in one centralized location, improving the user experience by making\n * it clear what needs to be fixed.\n * \n * @param props - Component configuration\n * @param props.errors - Form validation errors object\n * @param props.title - Title displayed above the error list\n * @param props.showFieldNames - Whether to show field names with errors\n * @returns JSX.Element - The rendered error summary or null if no errors\n */\nexport function FormErrorSummary({ \n errors = {}, \n title = \"Please fix the following errors:\",\n showFieldNames = false \n}: FormErrorSummaryProps) {\n const errorEntries = Object.entries(errors).filter(([, value]) => Boolean(value));\n\n if (errorEntries.length === 0) {\n return null;\n }\n\n return (\n <Alert variant=\"destructive\" className=\"mb-4\">\n <div>\n <h3>{title}</h3>\n <ul className=\"list-disc list-inside space-y-1\">\n {errorEntries.map(([field, error], index) => {\n const message = typeof error === 'object' && error.message ? error.message : String(error);\n return (\n <li key={index} className=\"text-sm\">\n {showFieldNames ? `${field}: ${message}` : message}\n </li>\n );\n })}\n </ul>\n </div>\n </Alert>\n );\n}\n","/**\n * @file FormLiveRegion Component\n * @package @jmruthers/pace-core\n * @module Components/Form\n * @since 0.1.0\n *\n * An accessible live region component for form validation announcements.\n * Provides real-time feedback to screen readers about form validation states\n * and error messages, improving accessibility for users with assistive technologies.\n *\n * Features:\n * - Real-time form validation announcements\n * - Configurable politeness levels (polite/assertive)\n * - Customizable delay timing\n * - Field-level and form-level announcements\n * - Success message customization\n * - Automatic error counting and field identification\n * - Accessibility compliant with ARIA live regions\n * - Integration with React Hook Form\n *\n * @example\n * ```tsx\n * // Basic live region\n * const { control, formState } = useForm();\n * \n * <Form onSubmit={handleSubmit}>\n * <FormField name=\"email\" label=\"Email\" />\n * <FormField name=\"password\" label=\"Password\" />\n * <FormLiveRegion form={{ control, formState }} />\n * <Button type=\"submit\">Submit</Button>\n * </Form>\n * \n * // With custom configuration\n * <FormLiveRegion\n * form={{ control, formState }}\n * politeness=\"assertive\"\n * delay={1000}\n * successMessage=\"Your form was submitted successfully!\"\n * enableFieldAnnouncements={true}\n * />\n * \n * // In a complex form\n * function ComplexForm() {\n * const methods = useForm({\n * defaultValues: { name: '', email: '', message: '' }\n * });\n * \n * return (\n * <FormProvider {...methods}>\n * <form onSubmit={methods.handleSubmit(onSubmit)}>\n * <FormField name=\"name\" label=\"Name\" />\n * <FormField name=\"email\" label=\"Email\" />\n * <FormField name=\"message\" label=\"Message\" />\n * <FormLiveRegion \n * form={methods}\n * politeness=\"polite\"\n * delay={300}\n * />\n * <Button type=\"submit\">Send Message</Button>\n * </form>\n * </FormProvider>\n * );\n * }\n * ```\n *\n * @accessibility\n * - ARIA live region for screen reader announcements\n * - Configurable politeness levels for different message types\n * - Automatic error counting and field identification\n * - Non-intrusive validation feedback\n * - WCAG 2.1 AA compliant\n * - Screen reader friendly error announcements\n *\n * @dependencies\n * - react-hook-form - Form state management\n * - React 18+ - Hooks and effects\n * - Tailwind CSS - Styling\n */\n\nimport React, { useEffect, useState } from 'react';\nimport { UseFormReturn, FieldValues } from 'react-hook-form';\nimport { cn } from '../../utils/cn';\n\n/**\n * Props for the FormLiveRegion component\n */\nexport interface FormLiveRegionProps<T extends FieldValues> {\n /** React Hook Form instance */\n form: UseFormReturn<T>;\n /** ARIA live region politeness level */\n politeness?: 'polite' | 'assertive';\n /** Delay before announcing messages (in ms) */\n delay?: number;\n /** Custom success message */\n successMessage?: string;\n /** Custom class name */\n className?: string;\n /** Enable field-level validation announcements */\n enableFieldAnnouncements?: boolean;\n}\n\n/**\n * FormLiveRegion component for accessible form validation announcements\n */\nexport function FormLiveRegion<T extends FieldValues>({\n form,\n politeness = 'polite',\n delay = 500,\n successMessage = 'Form submitted successfully',\n className,\n enableFieldAnnouncements = true\n}: FormLiveRegionProps<T>): React.ReactElement {\n const [message, setMessage] = useState<string>('');\n const { formState } = form;\n\n // Handle form-level announcements\n useEffect(() => {\n let timeoutId: NodeJS.Timeout;\n\n if (formState.isSubmitting) {\n setMessage('Submitting form...');\n } else if (formState.isSubmitSuccessful) {\n timeoutId = setTimeout(() => {\n setMessage(successMessage);\n }, delay);\n } else if (formState.errors && Object.keys(formState.errors).length > 0) {\n const errorCount = Object.keys(formState.errors).length;\n const errorFields = Object.keys(formState.errors).join(', ');\n setMessage(`Form has ${errorCount} error${errorCount === 1 ? '' : 's'} in: ${errorFields}`);\n } else if (formState.isValid && formState.isDirty) {\n setMessage('Form is valid');\n } else {\n setMessage('');\n }\n\n return () => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n };\n }, [formState, delay, successMessage]);\n\n // Handle field-level announcements\n useEffect(() => {\n if (!enableFieldAnnouncements) return;\n\n let timeoutId: NodeJS.Timeout;\n \n const fieldErrors = formState.errors;\n const touchedFields = formState.touchedFields;\n \n // Find newly touched fields with errors\n const newErrors = Object.keys(fieldErrors).filter(field => {\n // Type-safe access to touchedFields\n const touchedField = touchedFields as Record<string, boolean>;\n return touchedField[field] && fieldErrors[field as keyof typeof fieldErrors];\n });\n\n if (newErrors.length > 0) {\n timeoutId = setTimeout(() => {\n const errorField = newErrors[0];\n const errorData = fieldErrors[errorField as keyof typeof fieldErrors];\n const errorMessage = errorData?.message;\n if (errorMessage) {\n setMessage(`${errorField}: ${errorMessage}`);\n }\n }, delay);\n }\n\n return () => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n };\n }, [formState.errors, formState.touchedFields, enableFieldAnnouncements, delay]);\n\n if (!message) {\n return <></>;\n }\n\n return (\n <div\n role=\"status\"\n aria-live={politeness}\n aria-atomic=\"true\"\n className={cn('sr-only', className)}\n style={{\n position: 'absolute',\n left: '-10000px',\n width: '1px',\n height: '1px',\n overflow: 'hidden'\n }}\n >\n {message}\n </div>\n );\n}\n","/**\n * @file FormFieldset Component\n * @package @jmruthers/pace-core\n * @module Components/Form\n * @since 0.1.0\n *\n * A form fieldset component that groups related form fields together with a legend\n * and optional description. Provides semantic structure and accessibility for form sections.\n *\n * Features:\n * - Semantic fieldset grouping for related form fields\n * - Accessible legend with required indicator\n * - Optional description text with proper ARIA association\n * - Consistent styling with design system\n * - Forwarded ref support\n * - Customizable styling via className\n * - Required field indication\n * - Responsive design\n *\n * @example\n * ```tsx\n * // Basic fieldset\n * <FormFieldset legend=\"Personal Information\">\n * <FormField name=\"firstName\" label=\"First Name\" />\n * <FormField name=\"lastName\" label=\"Last Name\" />\n * <FormField name=\"email\" label=\"Email\" />\n * </FormFieldset>\n * \n * // Fieldset with description\n * <FormFieldset \n * legend=\"Contact Details\" \n * description=\"We'll use this information to contact you about your order\"\n * >\n * <FormField name=\"phone\" label=\"Phone Number\" />\n * <FormField name=\"address\" label=\"Address\" />\n * </FormFieldset>\n * \n * // Required fieldset\n * <FormFieldset \n * legend=\"Account Settings\" \n * required={true}\n * description=\"These settings are required for account creation\"\n * >\n * <FormField name=\"username\" label=\"Username\" required />\n * <FormField name=\"password\" label=\"Password\" type=\"password\" required />\n * </FormFieldset>\n * \n * // With custom styling\n * <FormFieldset \n * legend=\"Preferences\"\n * className=\"bg-sec-50 border-sec-200\"\n * >\n * <FormField name=\"newsletter\" label=\"Subscribe to newsletter\" type=\"checkbox\" />\n * <FormField name=\"notifications\" label=\"Enable notifications\" type=\"checkbox\" />\n * </FormFieldset>\n * ```\n *\n * @accessibility\n * - Proper semantic HTML with fieldset and legend\n * - ARIA describedby association for descriptions\n * - Required field indication with asterisk\n * - Screen reader friendly structure\n * - Keyboard navigation support\n * - WCAG 2.1 AA compliant\n *\n * @dependencies\n * - React 18+ - Component framework and hooks\n * - Tailwind CSS - Styling\n * - cn utility - Class name merging\n */\n\nimport React from 'react';\nimport { cn } from '../../utils/cn';\n\nexport interface FormFieldsetProps extends React.FieldsetHTMLAttributes<HTMLFieldSetElement> {\n /** The legend text for the fieldset */\n legend: string;\n /** Optional description text below the legend */\n description?: string;\n /** Whether the fieldset contains required fields */\n required?: boolean;\n /** Form fields to group within the fieldset */\n children: React.ReactNode;\n}\n\n/**\n * FormFieldset component for grouping related form fields\n * \n * This component provides semantic grouping for form fields with proper\n * accessibility support and consistent styling. Use it to organize\n * related form inputs into logical sections.\n * \n * @param props - Component configuration\n * @param props.legend - The legend text for the fieldset\n * @param props.description - Optional description text\n * @param props.required - Whether the fieldset contains required fields\n * @param props.children - Form fields to group\n * @param ref - Forwarded ref to the fieldset element\n * @returns JSX.Element - The rendered fieldset with legend and fields\n */\nexport const FormFieldset = React.forwardRef<HTMLFieldSetElement, FormFieldsetProps>(\n ({ legend, description, required, className, children, ...props }, ref) => {\n const descriptionId = React.useId();\n \n return (\n <fieldset\n ref={ref}\n className={cn(\"space-y-4 border border-input rounded-lg p-4\", className)}\n aria-describedby={description ? descriptionId : undefined}\n {...props}\n >\n <legend className=\"px-2\">\n {legend}\n {required && <span className=\"text-destructive ml-1\">*</span>}\n </legend>\n {description && (\n <p id={descriptionId} className=\"text-muted-foreground\">\n {description}\n </p>\n )}\n {children}\n </fieldset>\n );\n }\n);\n\nFormFieldset.displayName = \"FormFieldset\";\n","/**\n * Super Admin Guard Component\n * @package @jmruthers/pace-core\n * @module Components/SuperAdminGuard\n * @since 1.0.0\n * \n * A reusable component for protecting content that should only be visible to super admins.\n */\n\nimport React from 'react';\nimport { useRBAC } from '../rbac/hooks/useRBAC';\n\nexport interface SuperAdminGuardProps {\n children: React.ReactNode;\n fallback?: React.ReactNode;\n showDebugInfo?: boolean;\n}\n\n/**\n * Super Admin Guard Component\n * \n * Renders children only if the current user is a super admin.\n * Provides a fallback for non-super admin users.\n * \n * @param children - Content to render for super admins\n * @param fallback - Content to render for non-super admins (optional)\n * @param showDebugInfo - Whether to show debug information (optional)\n */\nexport function SuperAdminGuard({ \n children, \n fallback = null, \n showDebugInfo = false \n}: SuperAdminGuardProps) {\n const { isSuperAdmin, hasGlobalPermission, isLoading } = useRBAC();\n\n // Show loading state\n if (isLoading) {\n return (\n <div className=\"super-admin-guard-loading\">\n <div className=\"loading-spinner\" />\n <span>Checking permissions...</span>\n </div>\n );\n }\n\n // Show debug info if enabled\n if (showDebugInfo) {\n console.log('[SuperAdminGuard] Debug Info:', {\n isSuperAdmin,\n isLoading\n });\n }\n\n // Render children for super admins\n if (isSuperAdmin) {\n return (\n <div className=\"super-admin-content\">\n {children}\n </div>\n );\n }\n\n // Render fallback for non-super admins\n return (\n <div className=\"super-admin-fallback\">\n {fallback}\n </div>\n );\n}\n\n/**\n * Super Admin Badge Component\n * \n * Shows a visual indicator when the current user is a super admin.\n */\nexport function SuperAdminBadge() {\n const { isSuperAdmin } = useRBAC();\n\n if (!isSuperAdmin) {\n return null;\n }\n\n return (\n <div className=\"super-admin-badge\">\n <span className=\"badge-text\">SUPER ADMIN</span>\n </div>\n );\n}\n\n/**\n * Super Admin Debug Panel\n * \n * Shows debug information about the current user's permissions.\n * Only visible to super admins and in development mode.\n */\nexport function SuperAdminDebugPanel() {\n const { isSuperAdmin, isLoading } = useRBAC();\n\n // Only show in development or for super admins\n if (import.meta.env.MODE !== 'development' && !isSuperAdmin) {\n return null;\n }\n\n return (\n <div className=\"super-admin-debug-panel\">\n <h4>Super Admin Debug Info</h4>\n <div className=\"debug-info\">\n <p><strong>Is Super Admin:</strong> {isSuperAdmin ? 'Yes' : 'No'}</p>\n <p><strong>Is Loading:</strong> {isLoading ? 'Yes' : 'No'}</p>\n <p><strong>Environment:</strong> {import.meta.env.MODE}</p>\n </div>\n </div>\n );\n}\n\nexport default SuperAdminGuard;\n","// File Upload Component\n// Provides a file upload interface using the file reference system\n\nimport React, { useState, useCallback, useRef } from 'react';\nimport { SupabaseClient } from '@supabase/supabase-js';\nimport { FileCategory } from '../types/file-reference';\nimport { useFileReference } from '../hooks/useFileReference';\n\nexport interface FileUploadProps {\n supabase: SupabaseClient;\n table_name: string;\n record_id: string;\n organisation_id: string;\n app_id: string;\n category: FileCategory;\n accept?: string;\n maxSize?: number;\n multiple?: boolean;\n disabled?: boolean;\n className?: string;\n onUploadSuccess?: (result: any) => void;\n onUploadError?: (error: string) => void;\n children?: React.ReactNode;\n}\n\nexport function FileUpload({\n supabase,\n table_name,\n record_id,\n organisation_id,\n app_id,\n category,\n accept = '*/*',\n maxSize = 10 * 1024 * 1024, // 10MB default\n multiple = false,\n disabled = false,\n className = '',\n onUploadSuccess,\n onUploadError,\n children\n}: FileUploadProps) {\n const [isDragging, setIsDragging] = useState(false);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const { uploadFile, isLoading, error } = useFileReference(supabase);\n\n const handleFileSelect = useCallback(async (files: FileList | null) => {\n if (!files || files.length === 0) return;\n\n const fileArray = Array.from(files);\n \n // Validate file sizes\n const oversizedFiles = fileArray.filter(file => file.size > maxSize);\n if (oversizedFiles.length > 0) {\n const errorMessage = `Files exceed maximum size of ${Math.round(maxSize / 1024 / 1024)}MB: ${oversizedFiles.map(f => f.name).join(', ')}`;\n onUploadError?.(errorMessage);\n return;\n }\n\n // Upload files\n for (const file of fileArray) {\n try {\n const result = await uploadFile({\n table_name,\n record_id,\n organisation_id,\n app_id,\n category,\n is_public: false\n }, file);\n\n if (result) {\n onUploadSuccess?.(result);\n } else {\n onUploadError?.('Upload failed');\n }\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Upload failed';\n onUploadError?.(errorMessage);\n }\n }\n }, [uploadFile, table_name, record_id, organisation_id, app_id, category, maxSize, onUploadSuccess, onUploadError]);\n\n const handleDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n if (!disabled) {\n setIsDragging(true);\n }\n }, [disabled]);\n\n const handleDragLeave = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(false);\n }, []);\n\n const handleDrop = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(false);\n \n if (disabled) return;\n \n const files = e.dataTransfer.files;\n handleFileSelect(files);\n }, [disabled, handleFileSelect]);\n\n const handleFileInputChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n handleFileSelect(e.target.files);\n // Reset input value to allow re-uploading the same file\n if (e.target) {\n e.target.value = '';\n }\n }, [handleFileSelect]);\n\n const handleClick = useCallback(() => {\n if (!disabled && fileInputRef.current) {\n fileInputRef.current.click();\n }\n }, [disabled]);\n\n const dragClasses = isDragging ? 'border-main-500 bg-main-50' : 'border-sec-300 hover:border-sec-400';\n const disabledClasses = disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer hover:bg-sec-50';\n\n return (\n <div\n className={`relative border-2 border-dashed rounded-lg p-6 text-center transition-colors ${dragClasses} ${disabledClasses} ${className}`}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n onClick={handleClick}\n >\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n onChange={handleFileInputChange}\n className=\"hidden\"\n disabled={disabled}\n />\n \n {children || (\n <div className=\"space-y-2\">\n <div className=\"text-sec-600\">\n {isDragging ? (\n 'Drop files here...'\n ) : (\n <>\n <span className=\"font-medium\">Click to upload</span>\n {' '}or drag and drop\n </>\n )}\n </div>\n <div className=\"text-sm text-sec-500\">\n {accept !== '*/*' && `Accepted formats: ${accept}`}\n {maxSize && ` • Max size: ${Math.round(maxSize / 1024 / 1024)}MB`}\n {multiple && ' • Multiple files allowed'}\n </div>\n </div>\n )}\n \n {isLoading && (\n <div className=\"absolute inset-0 bg-white bg-opacity-75 flex items-center justify-center\">\n <div className=\"animate-spin rounded-full h-8 w-8 border-b-2 border-main-500\"></div>\n </div>\n )}\n \n {error && (\n <div className=\"mt-2 text-sm text-acc-600\">\n {error}\n </div>\n )}\n </div>\n );\n}\n","// File Reference React Hooks\n// Provides React hooks for managing file references\n\nimport { useState, useCallback } from 'react';\nimport { SupabaseClient } from '@supabase/supabase-js';\nimport { \n FileReference, \n FileUploadOptions, \n FileReferenceService,\n FileUploadResult \n} from '../types/file-reference';\nimport { createFileReferenceService, uploadFileWithReference } from '../utils/file-reference';\n\nexport function useFileReference(supabase: SupabaseClient) {\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const service = createFileReferenceService(supabase);\n\n const uploadFile = useCallback(async (options: FileUploadOptions, file: File): Promise<FileUploadResult | null> => {\n setIsLoading(true);\n setError(null);\n \n try {\n const result = await uploadFileWithReference(supabase, options, file);\n return result;\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Upload failed';\n setError(errorMessage);\n return null;\n } finally {\n setIsLoading(false);\n }\n }, [supabase]);\n\n const getFileReference = useCallback(async (table_name: string, record_id: string, organisation_id: string): Promise<FileReference | null> => {\n setIsLoading(true);\n setError(null);\n \n try {\n return await service.getFileReference(table_name, record_id, organisation_id);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Failed to get file reference';\n setError(errorMessage);\n return null;\n } finally {\n setIsLoading(false);\n }\n }, [service]);\n\n const getFileUrl = useCallback(async (table_name: string, record_id: string, organisation_id: string): Promise<string | null> => {\n setIsLoading(true);\n setError(null);\n \n try {\n return await service.getFileUrl(table_name, record_id, organisation_id);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Failed to get file URL';\n setError(errorMessage);\n return null;\n } finally {\n setIsLoading(false);\n }\n }, [service]);\n\n const getSignedUrl = useCallback(async (table_name: string, record_id: string, organisation_id: string, expires_in?: number): Promise<string | null> => {\n setIsLoading(true);\n setError(null);\n \n try {\n return await service.getSignedUrl(table_name, record_id, organisation_id, expires_in);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Failed to get signed URL';\n setError(errorMessage);\n return null;\n } finally {\n setIsLoading(false);\n }\n }, [service]);\n\n const updateFileReference = useCallback(async (id: string, updates: Partial<FileReference>): Promise<FileReference | null> => {\n setIsLoading(true);\n setError(null);\n \n try {\n return await service.updateFileReference(id, updates);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Failed to update file reference';\n setError(errorMessage);\n return null;\n } finally {\n setIsLoading(false);\n }\n }, [service]);\n\n const deleteFileReference = useCallback(async (table_name: string, record_id: string, organisation_id: string, delete_file?: boolean): Promise<boolean> => {\n setIsLoading(true);\n setError(null);\n \n try {\n return await service.deleteFileReference(table_name, record_id, organisation_id, delete_file);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Failed to delete file reference';\n setError(errorMessage);\n return false;\n } finally {\n setIsLoading(false);\n }\n }, [service]);\n\n const listFileReferences = useCallback(async (table_name: string, record_id: string, organisation_id: string): Promise<FileReference[]> => {\n setIsLoading(true);\n setError(null);\n \n try {\n return await service.listFileReferences(table_name, record_id, organisation_id);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Failed to list file references';\n setError(errorMessage);\n return [];\n } finally {\n setIsLoading(false);\n }\n }, [service]);\n\n const getFileCount = useCallback(async (table_name: string, record_id: string, organisation_id: string): Promise<number> => {\n setIsLoading(true);\n setError(null);\n \n try {\n return await service.getFileCount(table_name, record_id, organisation_id);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Failed to get file count';\n setError(errorMessage);\n return 0;\n } finally {\n setIsLoading(false);\n }\n }, [service]);\n\n const clearError = useCallback(() => {\n setError(null);\n }, []);\n\n return {\n isLoading,\n error,\n uploadFile,\n getFileReference,\n getFileUrl,\n getSignedUrl,\n updateFileReference,\n deleteFileReference,\n listFileReferences,\n getFileCount,\n clearError\n };\n}\n\nexport function useFileReferenceForRecord(\n supabase: SupabaseClient,\n table_name: string,\n record_id: string,\n organisation_id: string\n) {\n const {\n isLoading,\n error,\n getFileUrl,\n getFileReference,\n updateFileReference,\n deleteFileReference,\n listFileReferences,\n getFileCount,\n clearError\n } = useFileReference(supabase);\n\n const [fileUrl, setFileUrl] = useState<string | null>(null);\n const [fileReference, setFileReference] = useState<FileReference | null>(null);\n const [fileReferences, setFileReferences] = useState<FileReference[]>([]);\n const [fileCount, setFileCount] = useState<number>(0);\n\n const loadFileReference = useCallback(async () => {\n const reference = await getFileReference(table_name, record_id, organisation_id);\n setFileReference(reference);\n return reference;\n }, [getFileReference, table_name, record_id, organisation_id]);\n\n const loadFileUrl = useCallback(async () => {\n const url = await getFileUrl(table_name, record_id, organisation_id);\n setFileUrl(url);\n return url;\n }, [getFileUrl, table_name, record_id, organisation_id]);\n\n const loadFileReferences = useCallback(async () => {\n const references = await listFileReferences(table_name, record_id, organisation_id);\n setFileReferences(references);\n return references;\n }, [listFileReferences, table_name, record_id, organisation_id]);\n\n const loadFileCount = useCallback(async () => {\n const count = await getFileCount(table_name, record_id, organisation_id);\n setFileCount(count);\n return count;\n }, [getFileCount, table_name, record_id, organisation_id]);\n\n const deleteFile = useCallback(async (delete_file?: boolean) => {\n const success = await deleteFileReference(table_name, record_id, organisation_id, delete_file);\n if (success) {\n setFileReference(null);\n setFileUrl(null);\n await loadFileCount();\n }\n return success;\n }, [deleteFileReference, table_name, record_id, organisation_id, loadFileCount]);\n\n return {\n isLoading,\n error,\n fileUrl,\n fileReference,\n fileReferences,\n fileCount,\n loadFileReference,\n loadFileUrl,\n loadFileReferences,\n loadFileCount,\n deleteFile,\n updateFileReference,\n clearError\n };\n}\n","// File Reference Service\n// Provides CRUD operations for the centralized file reference system\n\nimport { SupabaseClient } from '@supabase/supabase-js';\nimport { \n FileReference, \n FileUploadOptions, \n FileReferenceService, \n FileUploadResult,\n FileCategory \n} from '../types/file-reference';\nimport { generateFilePath, uploadFile, getPublicUrl, getSignedUrl, deleteFile, extractFileMetadata } from './storage/helpers';\n\nexport class FileReferenceServiceImpl implements FileReferenceService {\n constructor(private supabase: SupabaseClient) {}\n\n async createFileReference(options: FileUploadOptions, file: File): Promise<FileReference> {\n try {\n // Generate file path\n const filePath = generateFilePath({\n appName: 'file-reference',\n orgId: options.organisation_id,\n isPublic: options.is_public || false\n }, file.name);\n\n // Upload file to storage\n const uploadResult = await uploadFile(this.supabase, file, {\n appName: 'file-reference',\n orgId: options.organisation_id,\n isPublic: options.is_public || false,\n customPath: filePath\n });\n if (!uploadResult.success) {\n throw new Error(`Failed to upload file: ${uploadResult.error}`);\n }\n\n // Extract file metadata\n const metadata = await extractFileMetadata(file, {\n appName: 'file-reference',\n orgId: options.organisation_id,\n isPublic: options.is_public || false\n }, 'system');\n\n // Create file reference in database\n const { data, error } = await this.supabase\n .rpc('insert_file_reference', {\n p_table_name: options.table_name,\n p_record_id: options.record_id,\n p_file_path: filePath,\n p_organisation_id: options.organisation_id,\n p_app_id: options.app_id,\n p_file_metadata: {\n fileName: file.name,\n fileType: file.type,\n fileSize: file.size,\n category: options.category,\n ...metadata,\n ...options.custom_metadata\n },\n p_is_public: options.is_public || false\n });\n\n if (error) {\n // Clean up uploaded file if database insert fails\n await deleteFile(this.supabase, filePath);\n throw new Error(`Failed to create file reference: ${error.message}`);\n }\n\n // Get the created file reference\n const { data: fileRef, error: fetchError } = await this.supabase\n .from('file_references')\n .select('*')\n .eq('id', data)\n .single();\n\n if (fetchError || !fileRef) {\n throw new Error(`Failed to fetch created file reference: ${fetchError?.message}`);\n }\n\n return fileRef as FileReference;\n } catch (error) {\n console.error('Error creating file reference:', error);\n throw error;\n }\n }\n\n async getFileReference(table_name: string, record_id: string, organisation_id: string): Promise<FileReference | null> {\n try {\n const { data, error } = await this.supabase\n .from('file_references')\n .select('*')\n .eq('table_name', table_name)\n .eq('record_id', record_id)\n .eq('organisation_id', organisation_id)\n .single();\n\n if (error) {\n if (error.code === 'PGRST116') {\n return null; // No rows found\n }\n throw new Error(`Failed to get file reference: ${error.message}`);\n }\n\n return data as FileReference;\n } catch (error) {\n console.error('Error getting file reference:', error);\n throw error;\n }\n }\n\n async getFileUrl(table_name: string, record_id: string, organisation_id: string): Promise<string | null> {\n try {\n const { data, error } = await this.supabase\n .rpc('get_file_url', {\n p_table_name: table_name,\n p_record_id: record_id,\n p_organisation_id: organisation_id\n });\n\n if (error) {\n throw new Error(`Failed to get file URL: ${error.message}`);\n }\n\n return data;\n } catch (error) {\n console.error('Error getting file URL:', error);\n throw error;\n }\n }\n\n async getSignedUrl(table_name: string, record_id: string, organisation_id: string, expires_in: number = 3600): Promise<string | null> {\n try {\n const { data, error } = await this.supabase\n .rpc('get_file_signed_url', {\n p_table_name: table_name,\n p_record_id: record_id,\n p_organisation_id: organisation_id,\n p_expires_in: expires_in\n });\n\n if (error) {\n throw new Error(`Failed to get signed URL: ${error.message}`);\n }\n\n return data;\n } catch (error) {\n console.error('Error getting signed URL:', error);\n throw error;\n }\n }\n\n async updateFileReference(id: string, updates: Partial<FileReference>): Promise<FileReference> {\n try {\n const { data, error } = await this.supabase\n .from('file_references')\n .update(updates)\n .eq('id', id)\n .select()\n .single();\n\n if (error) {\n throw new Error(`Failed to update file reference: ${error.message}`);\n }\n\n return data as FileReference;\n } catch (error) {\n console.error('Error updating file reference:', error);\n throw error;\n }\n }\n\n async deleteFileReference(table_name: string, record_id: string, organisation_id: string, delete_file: boolean = false): Promise<boolean> {\n try {\n const { error } = await this.supabase\n .rpc('delete_file_reference', {\n p_table_name: table_name,\n p_record_id: record_id,\n p_organisation_id: organisation_id,\n p_delete_file: delete_file\n });\n\n if (error) {\n throw new Error(`Failed to delete file reference: ${error.message}`);\n }\n\n return true;\n } catch (error) {\n console.error('Error deleting file reference:', error);\n throw error;\n }\n }\n\n async listFileReferences(table_name: string, record_id: string, organisation_id: string): Promise<FileReference[]> {\n try {\n const { data, error } = await this.supabase\n .rpc('get_record_files', {\n p_table_name: table_name,\n p_record_id: record_id,\n p_organisation_id: organisation_id\n });\n\n if (error) {\n throw new Error(`Failed to list file references: ${error.message}`);\n }\n\n return data as FileReference[];\n } catch (error) {\n console.error('Error listing file references:', error);\n throw error;\n }\n }\n\n async getFileCount(table_name: string, record_id: string, organisation_id: string): Promise<number> {\n try {\n const { data, error } = await this.supabase\n .rpc('get_record_file_count', {\n p_table_name: table_name,\n p_record_id: record_id,\n p_organisation_id: organisation_id\n });\n\n if (error) {\n throw new Error(`Failed to get file count: ${error.message}`);\n }\n\n return data || 0;\n } catch (error) {\n console.error('Error getting file count:', error);\n throw error;\n }\n }\n}\n\n// Factory function to create file reference service\nexport function createFileReferenceService(supabase: SupabaseClient): FileReferenceService {\n return new FileReferenceServiceImpl(supabase);\n}\n\n// Helper function to upload file and create reference in one operation\nexport async function uploadFileWithReference(\n supabase: SupabaseClient,\n options: FileUploadOptions,\n file: File\n): Promise<FileUploadResult> {\n const service = createFileReferenceService(supabase);\n const fileReference = await service.createFileReference(options, file);\n \n const fileUrl = options.is_public \n ? getPublicUrl(supabase, fileReference.file_path)\n : await getSignedUrl(supabase, fileReference.file_path, { \n appName: 'file-reference',\n orgId: options.organisation_id,\n expiresIn: 3600 \n });\n\n const urlString = typeof fileUrl === 'string' ? fileUrl : fileUrl?.url || '';\n\n return {\n file_reference: fileReference,\n file_url: urlString,\n signed_url: options.is_public ? undefined : urlString || undefined\n };\n}\n"],"mappings":"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","names":["jsx","jsxs","jsx","React","jsx","jsxs","jsx","jsxs","useState","useCallback","useState","useState","uploadFile","getSignedUrl","Fragment","jsx","jsxs","useState","uploadFile","useCallback"]}
1
+ {"version":3,"sources":["../src/components/index.ts","../src/components/Form/FormField.tsx","../src/components/Form/FormErrorSummary.tsx","../src/components/Form/FormLiveRegion.tsx","../src/components/Form/FormFieldset.tsx","../src/components/SuperAdminGuard.tsx","../src/components/FileUpload.tsx","../src/hooks/useFileReference.ts","../src/utils/file-reference.ts","../src/components/FileDisplay.tsx"],"sourcesContent":["/**\n * @file Complete Components Library Export\n * @package @jmruthers/pace-core\n * @module Components\n * @since 0.1.0\n * \n * This file exports ALL components, providers, and utilities in the PACE Core library.\n * Use this import path when you need access to specialized components not included in the main export.\n * \n * @example\n * // Complete library access\n * import { Dialog, NavigationMenu } from '@jmruthers/pace-core/components';\n * \n * // For common components, prefer the main export:\n * import { Button, Card } from '@jmruthers/pace-core';\n */\n\n// ============================================================================\n// AUTHENTICATION & AUTHORIZATION\n// ============================================================================\n\n// Unified auth provider (replaces individual providers)\nexport { UnifiedAuthProvider, useUnifiedAuth } from '../providers/UnifiedAuthProvider';\nexport type { UnifiedAuthProviderProps, UnifiedAuthContextType } from '../providers/UnifiedAuthProvider';\n\n// ============================================================================\n// BASIC UI COMPONENTS\n// ============================================================================\n\nexport { Button } from './Button';\nexport type { ButtonProps } from './Button';\n\nexport { \n Card, \n CardHeader, \n CardFooter, \n CardTitle, \n CardDescription, \n CardContent,\n CardActions\n} from './Card';\nexport type { CardProps, CardActionsProps } from './Card';\n\nexport { Input } from './Input';\nexport type { InputProps } from './Input';\nexport { Label } from './Label';\nexport type { LabelProps } from './Label';\n\nexport { Alert, AlertTitle, AlertDescription } from './Alert';\nexport { Avatar, AvatarImage, AvatarFallback } from './Avatar';\n\nexport { Checkbox } from './Checkbox';\nexport { Progress } from './Progress';\n\n// Table components\nexport {\n Table,\n TableHeader,\n TableBody,\n TableCaption,\n TableCell,\n TableFooter,\n TableHead,\n TableRow,\n} from './Table/Table';\n\n// ============================================================================\n// ADVANCED UI COMPONENTS\n// ============================================================================\n\n// Dialog exports\nexport {\n Dialog,\n DialogPortal,\n DialogOverlay,\n DialogTrigger,\n DialogClose,\n DialogContent,\n DialogHeader,\n DialogBody,\n DialogFooter,\n DialogTitle,\n DialogDescription,\n} from './Dialog/Dialog';\nexport type {\n DialogProps,\n DialogTriggerProps,\n DialogContentProps,\n DialogOverlayProps,\n DialogHeaderProps,\n DialogFooterProps,\n DialogTitleProps,\n DialogDescriptionProps,\n DialogSize\n} from './Dialog/Dialog';\n\n// Dropdown Menu exports\n// DropdownMenu components have been merged into Select components\n\n// Select exports (includes all dropdown functionality)\nexport {\n Select,\n SelectGroup,\n SelectValue,\n SelectTrigger,\n SelectContent,\n SelectLabel,\n SelectItem,\n SelectSeparator,\n} from './Select';\n\n// Toast exports\nexport {\n Toast,\n Toaster,\n ToastAction,\n ToastProvider,\n ToastViewport,\n ToastTitle,\n ToastDescription,\n ToastClose,\n} from './Toast';\nexport type { ToastActionElement, ToastProps } from './Toast';\n\n// Tooltip exports\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider, TooltipRoot } from './Tooltip';\n\n// ============================================================================\n// DATA DISPLAY COMPONENTS\n// ============================================================================\n\nexport {\n DataTable,\n type DataTableProps,\n type DataTableColumn,\n type DataTableAction,\n type DataTableToolbarButton,\n type AggregateConfig,\n type EmptyStateConfig,\n type GetRowId\n} from './DataTable';\n\n// Re-export types from DataTable types\nexport type { DataRecord } from './DataTable/types';\n\n// ============================================================================\n// FORM COMPONENTS\n// ============================================================================\n\nexport { \n Form, \n FormField, \n FormErrorSummary, \n FormLiveRegion, \n FormFieldset \n} from './Form';\nexport type { \n FormProps, \n FormFieldProps, \n FormErrorSummaryProps, \n FormLiveRegionProps, \n FormFieldsetProps \n} from './Form';\n\n// LoginForm - ensure it's exported\nexport { LoginForm } from './LoginForm';\nexport type { LoginFormProps } from './LoginForm';\n\n// ============================================================================\n// LAYOUT COMPONENTS\n// ============================================================================\n\nexport { Header } from './Header';\nexport { Footer } from './Footer';\nexport type { FooterProps } from './Footer';\n\n// Public Layout Components\nexport * from './PublicLayout';\n\n// ============================================================================\n// SECURITY COMPONENTS\n// ============================================================================\n\n// Super Admin Guard components\nexport { \n SuperAdminGuard, \n SuperAdminBadge, \n SuperAdminDebugPanel \n} from './SuperAdminGuard';\nexport type { SuperAdminGuardProps } from './SuperAdminGuard';\n\n// Removed: Protected and AdminGuard components (unused)\n\n// ============================================================================\n// NAVIGATION COMPONENTS\n// ============================================================================\n\nexport {\n NavigationMenu,\n} from './NavigationMenu';\nexport type { NavigationMenuProps, NavigationItem } from './NavigationMenu';\n\nexport { OrganisationSelector } from './OrganisationSelector';\nexport type { OrganisationSelectorProps } from './OrganisationSelector';\n\nexport { UserMenu } from './UserMenu';\n\n// Reusable Page/Layout Components\nexport * from './PaceAppLayout';\nexport * from './PaceLoginPage';\n\n// ============================================================================\n// UTILITY COMPONENTS\n// ============================================================================\n\nexport { ErrorBoundary } from './ErrorBoundary';\nexport type { ErrorBoundaryProps, ErrorBoundaryState } from './ErrorBoundary';\nexport { LoadingSpinner } from './LoadingSpinner';\n\n// ============================================================================\n// EVENT MANAGEMENT\n// ============================================================================\n\nexport { EventSelector } from './EventSelector';\n\n// ============================================================================\n// AUTHENTICATION FORMS\n// ============================================================================\n\n// Password Component exports\nexport { PasswordResetForm } from './PasswordReset';\n\n// ============================================================================\n// STORAGE COMPONENTS\n// ============================================================================\n\nexport { FileUpload } from './FileUpload';\nexport type { FileUploadProps } from './FileUpload';\n\nexport { FileDisplay } from './FileDisplay';\nexport type { FileDisplayProps } from './FileDisplay';\n\n\n// ============================================================================\n// TYPES\n// ============================================================================\n\nexport { FileCategory } from '../types/file-reference';\nexport type { FileReference, FileMetadata, FileUploadOptions } from '../types/file-reference';\n\n// ============================================================================\n// HOOKS\n// ============================================================================\n\nexport { useStorage, useFileUpload } from '../hooks/useStorage';\nexport type { UseStorageOptions, UseStorageReturn } from '../hooks/useStorage';\n\nexport { useFileReference, useFileReferenceForRecord } from '../hooks/useFileReference';\nexport type { UseFileReferenceOptions, UseFileReferenceReturn, UseFileReferenceForRecordReturn } from '../hooks/useFileReference';\n\nexport { useToast } from '../hooks/useToast';\n\n// RBAC Components - Use the new RBAC system\n// For RBAC functionality, import from @jmruthers/pace-core/rbac\n// export { PermissionGuard, AccessLevelGuard } from '@jmruthers/pace-core/rbac';\n","/**\n * @file FormField Component\n * @package @jmruthers/pace-core\n * @module Components/Form\n * @since 0.1.0\n *\n * A flexible form field component that integrates with React Hook Form and provides\n * built-in validation, error handling, and accessibility features.\n *\n * Features:\n * - React Hook Form integration with Controller\n * - Built-in validation with error display\n * - Accessible labels and error messages\n * - Custom render function support\n * - TypeScript support with generic field paths\n * - Consistent styling with error states\n * - Test ID support for testing\n * - Flexible input types and props\n *\n * @example\n * ```tsx\n * // Basic text field\n * <FormField\n * name=\"username\"\n * label=\"Username\"\n * placeholder=\"Enter your username\"\n * validation={{ required: true }}\n * />\n * \n * // Email field with custom validation\n * <FormField\n * name=\"email\"\n * label=\"Email Address\"\n * type=\"email\"\n * validation={{\n * required: true,\n * pattern: {\n * value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}$/i,\n * message: \"Invalid email address\"\n * }\n * }}\n * />\n * \n * // Custom render function\n * <FormField\n * name=\"avatar\"\n * label=\"Profile Picture\"\n * render={({ field }) => (\n * <input\n * {...field}\n * type=\"file\"\n * accept=\"image/*\"\n * className=\"file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-sec-50 file:text-sec-700 hover:file:bg-sec-100\"\n * />\n * )}\n * />\n * \n * // With test ID for testing\n * <FormField\n * name=\"password\"\n * label=\"Password\"\n * type=\"password\"\n * data-testid=\"password-field\"\n * validation={{\n * required: true,\n * minLength: {\n * value: 8,\n * message: \"Password must be at least 8 characters\"\n * }\n * }}\n * />\n * ```\n *\n * @accessibility\n * - Proper label association with htmlFor\n * - Error messages with role=\"alert\"\n * - Required field indicators\n * - Focus management\n * - Screen reader friendly error announcements\n * - Keyboard navigation support\n *\n * @dependencies\n * - react-hook-form - Form integration\n * - React 18+ - Hooks and context\n * - Tailwind CSS - Styling\n */\n\nimport React from 'react';\nimport { useFormContext, Controller, FieldPath, FieldValues } from 'react-hook-form';\nimport { cn } from '../../utils/cn';\nimport { Label } from '../Label';\n\nexport interface FormFieldProps<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>\n> {\n /**\n * Field name\n */\n name: TName;\n \n /**\n * Field label\n */\n label?: string;\n \n /**\n * Field type\n */\n type?: string;\n \n /**\n * Placeholder text\n */\n placeholder?: string;\n \n /**\n * Additional props for the input\n */\n inputProps?: React.InputHTMLAttributes<HTMLInputElement>;\n \n /**\n * Validation rules\n */\n validation?: {\n required?: boolean;\n pattern?: {\n value: RegExp;\n message: string;\n };\n minLength?: {\n value: number;\n message: string;\n };\n maxLength?: {\n value: number;\n message: string;\n };\n };\n \n /**\n * Custom render function\n */\n render?: ({ field }: { field: any }) => React.ReactElement;\n \n /**\n * Test ID\n */\n 'data-testid'?: string;\n \n /**\n * Class name\n */\n className?: string;\n}\n\n/**\n * FormField component for React Hook Form integration\n * \n * @template TFieldValues - The type of form field values\n * @template TName - The type of the field name (must be a valid field path)\n * @param props - Form field configuration and validation\n * @returns JSX.Element - The rendered form field with validation\n * \n * @example\n * ```tsx\n * <FormField\n * name=\"email\"\n * label=\"Email\"\n * type=\"email\"\n * validation={{\n * required: true,\n * pattern: {\n * value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}$/i,\n * message: \"Please enter a valid email address\"\n * }\n * }}\n * />\n * ```\n */\nexport function FormField<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>\n>({\n name,\n label,\n type = \"text\",\n placeholder,\n inputProps,\n validation,\n render,\n 'data-testid': testId,\n className,\n}: FormFieldProps<TFieldValues, TName>) {\n const { control, formState: { errors } } = useFormContext<TFieldValues>();\n const fieldError = errors[name];\n\n // Safely extract error message\n const errorMessage = fieldError && typeof fieldError === 'object' && 'message' in fieldError \n ? String(fieldError.message) \n : undefined;\n\n return (\n <div className={cn(\"space-y-2\", className)}>\n {label && (\n <Label htmlFor={name}>\n {label}\n {validation?.required && (\n <span className=\"text-destructive ml-1\" aria-label=\"required\">\n *\n </span>\n )}\n </Label>\n )}\n \n <Controller\n name={name}\n control={control}\n rules={validation}\n render={({ field }) => {\n if (render) {\n return render({ field });\n }\n \n return (\n <input\n {...field}\n id={name}\n type={type}\n placeholder={placeholder}\n data-testid={testId}\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 fieldError && \"border-destructive focus-visible:ring-destructive\"\n )}\n {...inputProps}\n />\n );\n }}\n />\n \n {errorMessage && (\n <p className=\"text-destructive\" role=\"alert\">\n {errorMessage}\n </p>\n )}\n </div>\n );\n}\n","\n/**\n * @file FormErrorSummary Component\n * @package @jmruthers/pace-core\n * @module Components/Form\n * @since 0.1.0\n *\n * A form error summary component that displays validation errors in a user-friendly format.\n * Provides a centralized location for users to see all form errors at once.\n *\n * Features:\n * - Displays all form errors in one place\n * - Configurable error display format\n * - Optional field name display\n * - Accessible error presentation\n * - Consistent styling with Alert component\n * - Automatic error filtering\n * - Responsive design\n *\n * @example\n * ```tsx\n * // Basic error summary\n * <FormErrorSummary errors={formErrors} />\n * \n * // With custom title\n * <FormErrorSummary \n * errors={formErrors}\n * title=\"Please correct the following issues:\"\n * />\n * \n * // Show field names with errors\n * <FormErrorSummary \n * errors={formErrors}\n * showFieldNames={true}\n * />\n * \n * // In a form with React Hook Form\n * const { formState: { errors } } = useForm();\n * \n * <Form onSubmit={handleSubmit}>\n * <FormField name=\"email\" label=\"Email\" />\n * <FormField name=\"password\" label=\"Password\" />\n * <FormErrorSummary errors={errors} />\n * <Button type=\"submit\">Submit</Button>\n * </Form>\n * ```\n *\n * @accessibility\n * - Uses Alert component for consistent accessibility\n * - Proper heading hierarchy with h3\n * - List structure for error items\n * - Screen reader friendly error announcements\n * - High contrast support via Alert component\n *\n * @dependencies\n * - Alert component for consistent styling\n * - React 18+ - Component framework\n * - Tailwind CSS - Styling\n */\n\nimport { Alert } from '../Alert';\n\nexport interface FormErrorSummaryProps {\n /** Form validation errors object */\n errors?: Record<string, any>;\n /** Title displayed above the error list */\n title?: string;\n /** Whether to show field names alongside error messages */\n showFieldNames?: boolean;\n}\n\n/**\n * FormErrorSummary component for displaying form validation errors\n * \n * This component provides a user-friendly way to display all form errors\n * in one centralized location, improving the user experience by making\n * it clear what needs to be fixed.\n * \n * @param props - Component configuration\n * @param props.errors - Form validation errors object\n * @param props.title - Title displayed above the error list\n * @param props.showFieldNames - Whether to show field names with errors\n * @returns JSX.Element - The rendered error summary or null if no errors\n */\nexport function FormErrorSummary({ \n errors = {}, \n title = \"Please fix the following errors:\",\n showFieldNames = false \n}: FormErrorSummaryProps) {\n const errorEntries = Object.entries(errors).filter(([, value]) => Boolean(value));\n\n if (errorEntries.length === 0) {\n return null;\n }\n\n return (\n <Alert variant=\"destructive\" className=\"mb-4\">\n <div>\n <h3>{title}</h3>\n <ul className=\"list-disc list-inside space-y-1\">\n {errorEntries.map(([field, error], index) => {\n const message = typeof error === 'object' && error.message ? error.message : String(error);\n return (\n <li key={index} className=\"text-sm\">\n {showFieldNames ? `${field}: ${message}` : message}\n </li>\n );\n })}\n </ul>\n </div>\n </Alert>\n );\n}\n","/**\n * @file FormLiveRegion Component\n * @package @jmruthers/pace-core\n * @module Components/Form\n * @since 0.1.0\n *\n * An accessible live region component for form validation announcements.\n * Provides real-time feedback to screen readers about form validation states\n * and error messages, improving accessibility for users with assistive technologies.\n *\n * Features:\n * - Real-time form validation announcements\n * - Configurable politeness levels (polite/assertive)\n * - Customizable delay timing\n * - Field-level and form-level announcements\n * - Success message customization\n * - Automatic error counting and field identification\n * - Accessibility compliant with ARIA live regions\n * - Integration with React Hook Form\n *\n * @example\n * ```tsx\n * // Basic live region\n * const { control, formState } = useForm();\n * \n * <Form onSubmit={handleSubmit}>\n * <FormField name=\"email\" label=\"Email\" />\n * <FormField name=\"password\" label=\"Password\" />\n * <FormLiveRegion form={{ control, formState }} />\n * <Button type=\"submit\">Submit</Button>\n * </Form>\n * \n * // With custom configuration\n * <FormLiveRegion\n * form={{ control, formState }}\n * politeness=\"assertive\"\n * delay={1000}\n * successMessage=\"Your form was submitted successfully!\"\n * enableFieldAnnouncements={true}\n * />\n * \n * // In a complex form\n * function ComplexForm() {\n * const methods = useForm({\n * defaultValues: { name: '', email: '', message: '' }\n * });\n * \n * return (\n * <FormProvider {...methods}>\n * <form onSubmit={methods.handleSubmit(onSubmit)}>\n * <FormField name=\"name\" label=\"Name\" />\n * <FormField name=\"email\" label=\"Email\" />\n * <FormField name=\"message\" label=\"Message\" />\n * <FormLiveRegion \n * form={methods}\n * politeness=\"polite\"\n * delay={300}\n * />\n * <Button type=\"submit\">Send Message</Button>\n * </form>\n * </FormProvider>\n * );\n * }\n * ```\n *\n * @accessibility\n * - ARIA live region for screen reader announcements\n * - Configurable politeness levels for different message types\n * - Automatic error counting and field identification\n * - Non-intrusive validation feedback\n * - WCAG 2.1 AA compliant\n * - Screen reader friendly error announcements\n *\n * @dependencies\n * - react-hook-form - Form state management\n * - React 18+ - Hooks and effects\n * - Tailwind CSS - Styling\n */\n\nimport React, { useEffect, useState } from 'react';\nimport { UseFormReturn, FieldValues } from 'react-hook-form';\nimport { cn } from '../../utils/cn';\n\n/**\n * Props for the FormLiveRegion component\n */\nexport interface FormLiveRegionProps<T extends FieldValues> {\n /** React Hook Form instance */\n form: UseFormReturn<T>;\n /** ARIA live region politeness level */\n politeness?: 'polite' | 'assertive';\n /** Delay before announcing messages (in ms) */\n delay?: number;\n /** Custom success message */\n successMessage?: string;\n /** Custom class name */\n className?: string;\n /** Enable field-level validation announcements */\n enableFieldAnnouncements?: boolean;\n}\n\n/**\n * FormLiveRegion component for accessible form validation announcements\n */\nexport function FormLiveRegion<T extends FieldValues>({\n form,\n politeness = 'polite',\n delay = 500,\n successMessage = 'Form submitted successfully',\n className,\n enableFieldAnnouncements = true\n}: FormLiveRegionProps<T>): React.ReactElement {\n const [message, setMessage] = useState<string>('');\n const { formState } = form;\n\n // Handle form-level announcements\n useEffect(() => {\n let timeoutId: NodeJS.Timeout;\n\n if (formState.isSubmitting) {\n setMessage('Submitting form...');\n } else if (formState.isSubmitSuccessful) {\n timeoutId = setTimeout(() => {\n setMessage(successMessage);\n }, delay);\n } else if (formState.errors && Object.keys(formState.errors).length > 0) {\n const errorCount = Object.keys(formState.errors).length;\n const errorFields = Object.keys(formState.errors).join(', ');\n setMessage(`Form has ${errorCount} error${errorCount === 1 ? '' : 's'} in: ${errorFields}`);\n } else if (formState.isValid && formState.isDirty) {\n setMessage('Form is valid');\n } else {\n setMessage('');\n }\n\n return () => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n };\n }, [formState, delay, successMessage]);\n\n // Handle field-level announcements\n useEffect(() => {\n if (!enableFieldAnnouncements) return;\n\n let timeoutId: NodeJS.Timeout;\n \n const fieldErrors = formState.errors;\n const touchedFields = formState.touchedFields;\n \n // Find newly touched fields with errors\n const newErrors = Object.keys(fieldErrors).filter(field => {\n // Type-safe access to touchedFields\n const touchedField = touchedFields as Record<string, boolean>;\n return touchedField[field] && fieldErrors[field as keyof typeof fieldErrors];\n });\n\n if (newErrors.length > 0) {\n timeoutId = setTimeout(() => {\n const errorField = newErrors[0];\n const errorData = fieldErrors[errorField as keyof typeof fieldErrors];\n const errorMessage = errorData?.message;\n if (errorMessage) {\n setMessage(`${errorField}: ${errorMessage}`);\n }\n }, delay);\n }\n\n return () => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n };\n }, [formState.errors, formState.touchedFields, enableFieldAnnouncements, delay]);\n\n if (!message) {\n return <></>;\n }\n\n return (\n <div\n role=\"status\"\n aria-live={politeness}\n aria-atomic=\"true\"\n className={cn('sr-only', className)}\n style={{\n position: 'absolute',\n left: '-10000px',\n width: '1px',\n height: '1px',\n overflow: 'hidden'\n }}\n >\n {message}\n </div>\n );\n}\n","/**\n * @file FormFieldset Component\n * @package @jmruthers/pace-core\n * @module Components/Form\n * @since 0.1.0\n *\n * A form fieldset component that groups related form fields together with a legend\n * and optional description. Provides semantic structure and accessibility for form sections.\n *\n * Features:\n * - Semantic fieldset grouping for related form fields\n * - Accessible legend with required indicator\n * - Optional description text with proper ARIA association\n * - Consistent styling with design system\n * - Forwarded ref support\n * - Customizable styling via className\n * - Required field indication\n * - Responsive design\n *\n * @example\n * ```tsx\n * // Basic fieldset\n * <FormFieldset legend=\"Personal Information\">\n * <FormField name=\"firstName\" label=\"First Name\" />\n * <FormField name=\"lastName\" label=\"Last Name\" />\n * <FormField name=\"email\" label=\"Email\" />\n * </FormFieldset>\n * \n * // Fieldset with description\n * <FormFieldset \n * legend=\"Contact Details\" \n * description=\"We'll use this information to contact you about your order\"\n * >\n * <FormField name=\"phone\" label=\"Phone Number\" />\n * <FormField name=\"address\" label=\"Address\" />\n * </FormFieldset>\n * \n * // Required fieldset\n * <FormFieldset \n * legend=\"Account Settings\" \n * required={true}\n * description=\"These settings are required for account creation\"\n * >\n * <FormField name=\"username\" label=\"Username\" required />\n * <FormField name=\"password\" label=\"Password\" type=\"password\" required />\n * </FormFieldset>\n * \n * // With custom styling\n * <FormFieldset \n * legend=\"Preferences\"\n * className=\"bg-sec-50 border-sec-200\"\n * >\n * <FormField name=\"newsletter\" label=\"Subscribe to newsletter\" type=\"checkbox\" />\n * <FormField name=\"notifications\" label=\"Enable notifications\" type=\"checkbox\" />\n * </FormFieldset>\n * ```\n *\n * @accessibility\n * - Proper semantic HTML with fieldset and legend\n * - ARIA describedby association for descriptions\n * - Required field indication with asterisk\n * - Screen reader friendly structure\n * - Keyboard navigation support\n * - WCAG 2.1 AA compliant\n *\n * @dependencies\n * - React 18+ - Component framework and hooks\n * - Tailwind CSS - Styling\n * - cn utility - Class name merging\n */\n\nimport React from 'react';\nimport { cn } from '../../utils/cn';\n\nexport interface FormFieldsetProps extends React.FieldsetHTMLAttributes<HTMLFieldSetElement> {\n /** The legend text for the fieldset */\n legend: string;\n /** Optional description text below the legend */\n description?: string;\n /** Whether the fieldset contains required fields */\n required?: boolean;\n /** Form fields to group within the fieldset */\n children: React.ReactNode;\n}\n\n/**\n * FormFieldset component for grouping related form fields\n * \n * This component provides semantic grouping for form fields with proper\n * accessibility support and consistent styling. Use it to organize\n * related form inputs into logical sections.\n * \n * @param props - Component configuration\n * @param props.legend - The legend text for the fieldset\n * @param props.description - Optional description text\n * @param props.required - Whether the fieldset contains required fields\n * @param props.children - Form fields to group\n * @param ref - Forwarded ref to the fieldset element\n * @returns JSX.Element - The rendered fieldset with legend and fields\n */\nexport const FormFieldset = React.forwardRef<HTMLFieldSetElement, FormFieldsetProps>(\n ({ legend, description, required, className, children, ...props }, ref) => {\n const descriptionId = React.useId();\n \n return (\n <fieldset\n ref={ref}\n className={cn(\"space-y-4 border border-input rounded-lg p-4\", className)}\n aria-describedby={description ? descriptionId : undefined}\n {...props}\n >\n <legend className=\"px-2\">\n {legend}\n {required && <span className=\"text-destructive ml-1\">*</span>}\n </legend>\n {description && (\n <p id={descriptionId} className=\"text-muted-foreground\">\n {description}\n </p>\n )}\n {children}\n </fieldset>\n );\n }\n);\n\nFormFieldset.displayName = \"FormFieldset\";\n","/**\n * Super Admin Guard Component\n * @package @jmruthers/pace-core\n * @module Components/SuperAdminGuard\n * @since 1.0.0\n * \n * A reusable component for protecting content that should only be visible to super admins.\n */\n\nimport React from 'react';\nimport { useRBAC } from '../rbac/hooks/useRBAC';\n\nexport interface SuperAdminGuardProps {\n children: React.ReactNode;\n fallback?: React.ReactNode;\n showDebugInfo?: boolean;\n}\n\n/**\n * Super Admin Guard Component\n * \n * Renders children only if the current user is a super admin.\n * Provides a fallback for non-super admin users.\n * \n * @param children - Content to render for super admins\n * @param fallback - Content to render for non-super admins (optional)\n * @param showDebugInfo - Whether to show debug information (optional)\n */\nexport function SuperAdminGuard({ \n children, \n fallback = null, \n showDebugInfo = false \n}: SuperAdminGuardProps) {\n const { isSuperAdmin, hasGlobalPermission, isLoading } = useRBAC();\n\n // Show loading state\n if (isLoading) {\n return (\n <div className=\"super-admin-guard-loading\">\n <div className=\"loading-spinner\" />\n <span>Checking permissions...</span>\n </div>\n );\n }\n\n // Show debug info if enabled\n if (showDebugInfo) {\n console.log('[SuperAdminGuard] Debug Info:', {\n isSuperAdmin,\n isLoading\n });\n }\n\n // Render children for super admins\n if (isSuperAdmin) {\n return (\n <div className=\"super-admin-content\">\n {children}\n </div>\n );\n }\n\n // Render fallback for non-super admins\n return (\n <div className=\"super-admin-fallback\">\n {fallback}\n </div>\n );\n}\n\n/**\n * Super Admin Badge Component\n * \n * Shows a visual indicator when the current user is a super admin.\n */\nexport function SuperAdminBadge() {\n const { isSuperAdmin } = useRBAC();\n\n if (!isSuperAdmin) {\n return null;\n }\n\n return (\n <div className=\"super-admin-badge\">\n <span className=\"badge-text\">SUPER ADMIN</span>\n </div>\n );\n}\n\n/**\n * Super Admin Debug Panel\n * \n * Shows debug information about the current user's permissions.\n * Only visible to super admins and in development mode.\n */\nexport function SuperAdminDebugPanel() {\n const { isSuperAdmin, isLoading } = useRBAC();\n\n // Only show in development or for super admins\n if (import.meta.env.MODE !== 'development' && !isSuperAdmin) {\n return null;\n }\n\n return (\n <div className=\"super-admin-debug-panel\">\n <h4>Super Admin Debug Info</h4>\n <div className=\"debug-info\">\n <p><strong>Is Super Admin:</strong> {isSuperAdmin ? 'Yes' : 'No'}</p>\n <p><strong>Is Loading:</strong> {isLoading ? 'Yes' : 'No'}</p>\n <p><strong>Environment:</strong> {import.meta.env.MODE}</p>\n </div>\n </div>\n );\n}\n\nexport default SuperAdminGuard;\n","// File Upload Component\n// Provides a file upload interface using the file reference system\n\nimport React, { useState, useCallback, useRef } from 'react';\nimport { SupabaseClient } from '@supabase/supabase-js';\nimport { FileCategory } from '../types/file-reference';\nimport { useFileReference } from '../hooks/useFileReference';\n\nexport interface FileUploadProps {\n supabase: SupabaseClient;\n table_name: string;\n record_id: string;\n organisation_id: string;\n app_id: string;\n category: FileCategory;\n accept?: string;\n maxSize?: number;\n multiple?: boolean;\n disabled?: boolean;\n className?: string;\n onUploadSuccess?: (result: any) => void;\n onUploadError?: (error: string) => void;\n children?: React.ReactNode;\n}\n\nexport function FileUpload({\n supabase,\n table_name,\n record_id,\n organisation_id,\n app_id,\n category,\n accept = '*/*',\n maxSize = 10 * 1024 * 1024, // 10MB default\n multiple = false,\n disabled = false,\n className = '',\n onUploadSuccess,\n onUploadError,\n children\n}: FileUploadProps) {\n const [isDragging, setIsDragging] = useState(false);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const { uploadFile, isLoading, error } = useFileReference(supabase);\n\n const handleFileSelect = useCallback(async (files: FileList | null) => {\n if (!files || files.length === 0) return;\n\n const fileArray = Array.from(files);\n \n // Validate file sizes\n const oversizedFiles = fileArray.filter(file => file.size > maxSize);\n if (oversizedFiles.length > 0) {\n const errorMessage = `Files exceed maximum size of ${Math.round(maxSize / 1024 / 1024)}MB: ${oversizedFiles.map(f => f.name).join(', ')}`;\n onUploadError?.(errorMessage);\n return;\n }\n\n // Upload files\n for (const file of fileArray) {\n try {\n const result = await uploadFile({\n table_name,\n record_id,\n organisation_id,\n app_id,\n category,\n is_public: false\n }, file);\n\n if (result) {\n onUploadSuccess?.(result);\n } else {\n onUploadError?.('Upload failed');\n }\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Upload failed';\n onUploadError?.(errorMessage);\n }\n }\n }, [uploadFile, table_name, record_id, organisation_id, app_id, category, maxSize, onUploadSuccess, onUploadError]);\n\n const handleDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n if (!disabled) {\n setIsDragging(true);\n }\n }, [disabled]);\n\n const handleDragLeave = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(false);\n }, []);\n\n const handleDrop = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragging(false);\n \n if (disabled) return;\n \n const files = e.dataTransfer.files;\n handleFileSelect(files);\n }, [disabled, handleFileSelect]);\n\n const handleFileInputChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n handleFileSelect(e.target.files);\n // Reset input value to allow re-uploading the same file\n if (e.target) {\n e.target.value = '';\n }\n }, [handleFileSelect]);\n\n const handleClick = useCallback(() => {\n if (!disabled && fileInputRef.current) {\n fileInputRef.current.click();\n }\n }, [disabled]);\n\n const dragClasses = isDragging ? 'border-main-500 bg-main-50' : 'border-sec-300 hover:border-sec-400';\n const disabledClasses = disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer hover:bg-sec-50';\n\n return (\n <div\n className={`relative border-2 border-dashed rounded-lg p-6 text-center transition-colors ${dragClasses} ${disabledClasses} ${className}`}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n onClick={handleClick}\n >\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n onChange={handleFileInputChange}\n className=\"hidden\"\n disabled={disabled}\n />\n \n {children || (\n <div className=\"space-y-2\">\n <div className=\"text-sec-600\">\n {isDragging ? (\n 'Drop files here...'\n ) : (\n <>\n <span className=\"font-medium\">Click to upload</span>\n {' '}or drag and drop\n </>\n )}\n </div>\n <div className=\"text-sm text-sec-500\">\n {accept !== '*/*' && `Accepted formats: ${accept}`}\n {maxSize && ` • Max size: ${Math.round(maxSize / 1024 / 1024)}MB`}\n {multiple && ' • Multiple files allowed'}\n </div>\n </div>\n )}\n \n {isLoading && (\n <div className=\"absolute inset-0 bg-white bg-opacity-75 flex items-center justify-center\">\n <div className=\"animate-spin rounded-full h-8 w-8 border-b-2 border-main-500\"></div>\n </div>\n )}\n \n {error && (\n <div className=\"mt-2 text-sm text-acc-600\">\n {error}\n </div>\n )}\n </div>\n );\n}\n","// File Reference React Hooks\n// Provides React hooks for managing file references\n\nimport { useState, useCallback } from 'react';\nimport { SupabaseClient } from '@supabase/supabase-js';\nimport { \n FileReference, \n FileUploadOptions, \n FileReferenceService,\n FileUploadResult \n} from '../types/file-reference';\nimport { createFileReferenceService, uploadFileWithReference } from '../utils/file-reference';\n\nexport function useFileReference(supabase: SupabaseClient) {\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const service = createFileReferenceService(supabase);\n\n const uploadFile = useCallback(async (options: FileUploadOptions, file: File): Promise<FileUploadResult | null> => {\n setIsLoading(true);\n setError(null);\n \n try {\n const result = await uploadFileWithReference(supabase, options, file);\n return result;\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Upload failed';\n setError(errorMessage);\n return null;\n } finally {\n setIsLoading(false);\n }\n }, [supabase]);\n\n const getFileReference = useCallback(async (table_name: string, record_id: string, organisation_id: string): Promise<FileReference | null> => {\n setIsLoading(true);\n setError(null);\n \n try {\n return await service.getFileReference(table_name, record_id, organisation_id);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Failed to get file reference';\n setError(errorMessage);\n return null;\n } finally {\n setIsLoading(false);\n }\n }, [service]);\n\n const getFileUrl = useCallback(async (table_name: string, record_id: string, organisation_id: string): Promise<string | null> => {\n setIsLoading(true);\n setError(null);\n \n try {\n return await service.getFileUrl(table_name, record_id, organisation_id);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Failed to get file URL';\n setError(errorMessage);\n return null;\n } finally {\n setIsLoading(false);\n }\n }, [service]);\n\n const getSignedUrl = useCallback(async (table_name: string, record_id: string, organisation_id: string, expires_in?: number): Promise<string | null> => {\n setIsLoading(true);\n setError(null);\n \n try {\n return await service.getSignedUrl(table_name, record_id, organisation_id, expires_in);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Failed to get signed URL';\n setError(errorMessage);\n return null;\n } finally {\n setIsLoading(false);\n }\n }, [service]);\n\n const updateFileReference = useCallback(async (id: string, updates: Partial<FileReference>): Promise<FileReference | null> => {\n setIsLoading(true);\n setError(null);\n \n try {\n return await service.updateFileReference(id, updates);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Failed to update file reference';\n setError(errorMessage);\n return null;\n } finally {\n setIsLoading(false);\n }\n }, [service]);\n\n const deleteFileReference = useCallback(async (table_name: string, record_id: string, organisation_id: string, delete_file?: boolean): Promise<boolean> => {\n setIsLoading(true);\n setError(null);\n \n try {\n return await service.deleteFileReference(table_name, record_id, organisation_id, delete_file);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Failed to delete file reference';\n setError(errorMessage);\n return false;\n } finally {\n setIsLoading(false);\n }\n }, [service]);\n\n const listFileReferences = useCallback(async (table_name: string, record_id: string, organisation_id: string): Promise<FileReference[]> => {\n setIsLoading(true);\n setError(null);\n \n try {\n return await service.listFileReferences(table_name, record_id, organisation_id);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Failed to list file references';\n setError(errorMessage);\n return [];\n } finally {\n setIsLoading(false);\n }\n }, [service]);\n\n const getFileCount = useCallback(async (table_name: string, record_id: string, organisation_id: string): Promise<number> => {\n setIsLoading(true);\n setError(null);\n \n try {\n return await service.getFileCount(table_name, record_id, organisation_id);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Failed to get file count';\n setError(errorMessage);\n return 0;\n } finally {\n setIsLoading(false);\n }\n }, [service]);\n\n const clearError = useCallback(() => {\n setError(null);\n }, []);\n\n return {\n isLoading,\n error,\n uploadFile,\n getFileReference,\n getFileUrl,\n getSignedUrl,\n updateFileReference,\n deleteFileReference,\n listFileReferences,\n getFileCount,\n clearError\n };\n}\n\nexport function useFileReferenceForRecord(\n supabase: SupabaseClient,\n table_name: string,\n record_id: string,\n organisation_id: string\n) {\n const {\n isLoading,\n error,\n getFileUrl,\n getFileReference,\n updateFileReference,\n deleteFileReference,\n listFileReferences,\n getFileCount,\n clearError\n } = useFileReference(supabase);\n\n const [fileUrl, setFileUrl] = useState<string | null>(null);\n const [fileReference, setFileReference] = useState<FileReference | null>(null);\n const [fileReferences, setFileReferences] = useState<FileReference[]>([]);\n const [fileCount, setFileCount] = useState<number>(0);\n\n const loadFileReference = useCallback(async () => {\n const reference = await getFileReference(table_name, record_id, organisation_id);\n setFileReference(reference);\n return reference;\n }, [getFileReference, table_name, record_id, organisation_id]);\n\n const loadFileUrl = useCallback(async () => {\n const url = await getFileUrl(table_name, record_id, organisation_id);\n setFileUrl(url);\n return url;\n }, [getFileUrl, table_name, record_id, organisation_id]);\n\n const loadFileReferences = useCallback(async () => {\n const references = await listFileReferences(table_name, record_id, organisation_id);\n setFileReferences(references);\n return references;\n }, [listFileReferences, table_name, record_id, organisation_id]);\n\n const loadFileCount = useCallback(async () => {\n const count = await getFileCount(table_name, record_id, organisation_id);\n setFileCount(count);\n return count;\n }, [getFileCount, table_name, record_id, organisation_id]);\n\n const deleteFile = useCallback(async (delete_file?: boolean) => {\n const success = await deleteFileReference(table_name, record_id, organisation_id, delete_file);\n if (success) {\n setFileReference(null);\n setFileUrl(null);\n await loadFileCount();\n }\n return success;\n }, [deleteFileReference, table_name, record_id, organisation_id, loadFileCount]);\n\n return {\n isLoading,\n error,\n fileUrl,\n fileReference,\n fileReferences,\n fileCount,\n loadFileReference,\n loadFileUrl,\n loadFileReferences,\n loadFileCount,\n deleteFile,\n updateFileReference,\n clearError\n };\n}\n\n// Type definitions for the hooks\nexport type UseFileReferenceOptions = {\n table_name: string;\n record_id: string;\n organisation_id: string;\n};\n\nexport type UseFileReferenceReturn = {\n isLoading: boolean;\n error: string | null;\n uploadFile: (options: FileUploadOptions, file: File) => Promise<FileUploadResult | null>;\n getFileReference: (table_name: string, record_id: string, organisation_id: string) => Promise<FileReference | null>;\n getFileUrl: (table_name: string, record_id: string, organisation_id: string) => Promise<string | null>;\n getSignedUrl: (table_name: string, record_id: string, organisation_id: string, expires_in?: number) => Promise<string | null>;\n updateFileReference: (id: string, updates: Partial<FileReference>) => Promise<FileReference | null>;\n deleteFileReference: (table_name: string, record_id: string, organisation_id: string, delete_file?: boolean) => Promise<boolean>;\n listFileReferences: (table_name: string, record_id: string, organisation_id: string) => Promise<FileReference[]>;\n getFileCount: (table_name: string, record_id: string, organisation_id: string) => Promise<number>;\n clearError: () => void;\n};\n\nexport type UseFileReferenceForRecordReturn = {\n isLoading: boolean;\n error: string | null;\n fileUrl: string | null;\n fileReference: FileReference | null;\n fileReferences: FileReference[];\n fileCount: number;\n loadFileReference: () => Promise<FileReference | null>;\n loadFileUrl: () => Promise<string | null>;\n loadFileReferences: () => Promise<FileReference[]>;\n loadFileCount: () => Promise<number>;\n deleteFile: (delete_file?: boolean) => Promise<boolean>;\n updateFileReference: (id: string, updates: Partial<FileReference>) => Promise<FileReference | null>;\n clearError: () => void;\n};\n","// File Reference Service\n// Provides CRUD operations for the centralized file reference system\n\nimport { SupabaseClient } from '@supabase/supabase-js';\nimport { \n FileReference, \n FileUploadOptions, \n FileReferenceService, \n FileUploadResult,\n FileCategory \n} from '../types/file-reference';\nimport { generateFilePath, uploadFile, getPublicUrl, getSignedUrl, deleteFile, extractFileMetadata } from './storage/helpers';\n\nexport class FileReferenceServiceImpl implements FileReferenceService {\n constructor(private supabase: SupabaseClient) {}\n\n async createFileReference(options: FileUploadOptions, file: File): Promise<FileReference> {\n try {\n // Generate file path\n const filePath = generateFilePath({\n appName: 'file-reference',\n orgId: options.organisation_id,\n isPublic: options.is_public || false\n }, file.name);\n\n // Upload file to storage\n const uploadResult = await uploadFile(this.supabase, file, {\n appName: 'file-reference',\n orgId: options.organisation_id,\n isPublic: options.is_public || false,\n customPath: filePath\n });\n if (!uploadResult.success) {\n throw new Error(`Failed to upload file: ${uploadResult.error}`);\n }\n\n // Extract file metadata\n const metadata = await extractFileMetadata(file, {\n appName: 'file-reference',\n orgId: options.organisation_id,\n isPublic: options.is_public || false\n }, 'system');\n\n // Create file reference in database\n const { data, error } = await this.supabase\n .rpc('insert_file_reference', {\n p_table_name: options.table_name,\n p_record_id: options.record_id,\n p_file_path: filePath,\n p_organisation_id: options.organisation_id,\n p_app_id: options.app_id,\n p_file_metadata: {\n fileName: file.name,\n fileType: file.type,\n fileSize: file.size,\n category: options.category,\n ...metadata,\n ...options.custom_metadata\n },\n p_is_public: options.is_public || false\n });\n\n if (error) {\n // Clean up uploaded file if database insert fails\n await deleteFile(this.supabase, filePath);\n throw new Error(`Failed to create file reference: ${error.message}`);\n }\n\n // Get the created file reference\n const { data: fileRef, error: fetchError } = await this.supabase\n .from('file_references')\n .select('*')\n .eq('id', data)\n .single();\n\n if (fetchError || !fileRef) {\n throw new Error(`Failed to fetch created file reference: ${fetchError?.message}`);\n }\n\n return fileRef as FileReference;\n } catch (error) {\n console.error('Error creating file reference:', error);\n throw error;\n }\n }\n\n async getFileReference(table_name: string, record_id: string, organisation_id: string): Promise<FileReference | null> {\n try {\n const { data, error } = await this.supabase\n .from('file_references')\n .select('*')\n .eq('table_name', table_name)\n .eq('record_id', record_id)\n .eq('organisation_id', organisation_id)\n .single();\n\n if (error) {\n if (error.code === 'PGRST116') {\n return null; // No rows found\n }\n throw new Error(`Failed to get file reference: ${error.message}`);\n }\n\n return data as FileReference;\n } catch (error) {\n console.error('Error getting file reference:', error);\n throw error;\n }\n }\n\n async getFileUrl(table_name: string, record_id: string, organisation_id: string): Promise<string | null> {\n try {\n const { data, error } = await this.supabase\n .rpc('get_file_url', {\n p_table_name: table_name,\n p_record_id: record_id,\n p_organisation_id: organisation_id\n });\n\n if (error) {\n throw new Error(`Failed to get file URL: ${error.message}`);\n }\n\n return data;\n } catch (error) {\n console.error('Error getting file URL:', error);\n throw error;\n }\n }\n\n async getSignedUrl(table_name: string, record_id: string, organisation_id: string, expires_in: number = 3600): Promise<string | null> {\n try {\n const { data, error } = await this.supabase\n .rpc('get_file_signed_url', {\n p_table_name: table_name,\n p_record_id: record_id,\n p_organisation_id: organisation_id,\n p_expires_in: expires_in\n });\n\n if (error) {\n throw new Error(`Failed to get signed URL: ${error.message}`);\n }\n\n return data;\n } catch (error) {\n console.error('Error getting signed URL:', error);\n throw error;\n }\n }\n\n async updateFileReference(id: string, updates: Partial<FileReference>): Promise<FileReference> {\n try {\n const { data, error } = await this.supabase\n .from('file_references')\n .update(updates)\n .eq('id', id)\n .select()\n .single();\n\n if (error) {\n throw new Error(`Failed to update file reference: ${error.message}`);\n }\n\n return data as FileReference;\n } catch (error) {\n console.error('Error updating file reference:', error);\n throw error;\n }\n }\n\n async deleteFileReference(table_name: string, record_id: string, organisation_id: string, delete_file: boolean = false): Promise<boolean> {\n try {\n const { error } = await this.supabase\n .rpc('delete_file_reference', {\n p_table_name: table_name,\n p_record_id: record_id,\n p_organisation_id: organisation_id,\n p_delete_file: delete_file\n });\n\n if (error) {\n throw new Error(`Failed to delete file reference: ${error.message}`);\n }\n\n return true;\n } catch (error) {\n console.error('Error deleting file reference:', error);\n throw error;\n }\n }\n\n async listFileReferences(table_name: string, record_id: string, organisation_id: string): Promise<FileReference[]> {\n try {\n const { data, error } = await this.supabase\n .rpc('get_record_files', {\n p_table_name: table_name,\n p_record_id: record_id,\n p_organisation_id: organisation_id\n });\n\n if (error) {\n throw new Error(`Failed to list file references: ${error.message}`);\n }\n\n return data as FileReference[];\n } catch (error) {\n console.error('Error listing file references:', error);\n throw error;\n }\n }\n\n async getFileCount(table_name: string, record_id: string, organisation_id: string): Promise<number> {\n try {\n const { data, error } = await this.supabase\n .rpc('get_record_file_count', {\n p_table_name: table_name,\n p_record_id: record_id,\n p_organisation_id: organisation_id\n });\n\n if (error) {\n throw new Error(`Failed to get file count: ${error.message}`);\n }\n\n return data || 0;\n } catch (error) {\n console.error('Error getting file count:', error);\n throw error;\n }\n }\n}\n\n// Factory function to create file reference service\nexport function createFileReferenceService(supabase: SupabaseClient): FileReferenceService {\n return new FileReferenceServiceImpl(supabase);\n}\n\n// Helper function to upload file and create reference in one operation\nexport async function uploadFileWithReference(\n supabase: SupabaseClient,\n options: FileUploadOptions,\n file: File\n): Promise<FileUploadResult> {\n const service = createFileReferenceService(supabase);\n const fileReference = await service.createFileReference(options, file);\n \n const fileUrl = options.is_public \n ? getPublicUrl(supabase, fileReference.file_path)\n : await getSignedUrl(supabase, fileReference.file_path, { \n appName: 'file-reference',\n orgId: options.organisation_id,\n expiresIn: 3600 \n });\n\n const urlString = typeof fileUrl === 'string' ? fileUrl : fileUrl?.url || '';\n\n return {\n file_reference: fileReference,\n file_url: urlString,\n signed_url: options.is_public ? undefined : urlString || undefined\n };\n}\n","// File Display Component\n// Provides a file display interface using the file reference system\n\nimport React, { useState, useEffect } from 'react';\nimport { SupabaseClient } from '@supabase/supabase-js';\nimport { FileReference, FileCategory } from '../types/file-reference';\nimport { useFileReferenceForRecord } from '../hooks/useFileReference';\n\nexport interface FileDisplayProps {\n supabase: SupabaseClient;\n table_name: string;\n record_id: string;\n organisation_id: string;\n category?: FileCategory;\n showUpload?: boolean;\n showDelete?: boolean;\n className?: string;\n children?: React.ReactNode;\n}\n\nexport function FileDisplay({\n supabase,\n table_name,\n record_id,\n organisation_id,\n category,\n showUpload = false,\n showDelete = false,\n className = '',\n children\n}: FileDisplayProps) {\n const {\n isLoading,\n error,\n fileUrl,\n fileReference,\n fileReferences,\n fileCount,\n loadFileReference,\n loadFileUrl,\n loadFileReferences,\n loadFileCount,\n deleteFile,\n clearError\n } = useFileReferenceForRecord(supabase, table_name, record_id, organisation_id);\n\n const [imageError, setImageError] = useState(false);\n\n // Load file data on mount\n useEffect(() => {\n loadFileCount();\n if (category) {\n loadFileReference();\n } else {\n loadFileReferences();\n }\n }, [loadFileCount, loadFileReference, loadFileReferences, category]);\n\n // Load file URL when file reference is available\n useEffect(() => {\n if (fileReference) {\n loadFileUrl();\n }\n }, [fileReference, loadFileUrl]);\n\n const handleDelete = async () => {\n if (window.confirm('Are you sure you want to delete this file?')) {\n const success = await deleteFile(true);\n if (success) {\n setImageError(false);\n }\n }\n };\n\n const handleImageError = () => {\n setImageError(true);\n };\n\n const getFileIcon = (fileType: string) => {\n if (fileType.startsWith('image/')) return '🖼️';\n if (fileType.startsWith('video/')) return '🎥';\n if (fileType.startsWith('audio/')) return '🎵';\n if (fileType.includes('pdf')) return '📄';\n if (fileType.includes('word')) return '📝';\n if (fileType.includes('excel') || fileType.includes('spreadsheet')) return '📊';\n if (fileType.includes('powerpoint') || fileType.includes('presentation')) return '📊';\n return '📁';\n };\n\n const formatFileSize = (bytes: number) => {\n if (bytes === 0) return '0 Bytes';\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n };\n\n if (isLoading) {\n return (\n <div className={`flex items-center justify-center p-4 ${className}`}>\n <div className=\"animate-spin rounded-full h-8 w-8 border-b-2 border-main-500\"></div>\n </div>\n );\n }\n\n if (error) {\n return (\n <div className={`p-4 bg-acc-50 border border-acc-200 rounded-lg ${className}`}>\n <div className=\"text-acc-600\">\n Error loading file: {error}\n </div>\n <button\n onClick={clearError}\n className=\"mt-2 text-sm text-acc-700 hover:text-acc-800 underline\"\n >\n Try again\n </button>\n </div>\n );\n }\n\n if (fileCount === 0) {\n return (\n <div className={`text-sec-500 text-center p-4 ${className}`}>\n No files found\n {children}\n </div>\n );\n }\n\n // Single file display (when category is specified)\n if (category && fileReference) {\n const isImage = fileReference.file_metadata.fileType?.startsWith('image/');\n \n return (\n <div className={`space-y-2 ${className}`}>\n {isImage && fileUrl && !imageError ? (\n <div className=\"relative\">\n <img\n src={fileUrl}\n alt={fileReference.file_metadata.fileName || 'File'}\n className=\"max-w-full h-auto rounded-lg border border-sec-200\"\n onError={handleImageError}\n />\n {showDelete && (\n <button\n onClick={handleDelete}\n className=\"absolute top-2 right-2 bg-acc-500 text-white rounded-full w-6 h-6 flex items-center justify-center text-sm hover:bg-acc-600\"\n title=\"Delete file\"\n >\n ×\n </button>\n )}\n </div>\n ) : (\n <div className=\"flex items-center space-x-3 p-3 bg-sec-50 rounded-lg border border-sec-200\">\n <span className=\"text-2xl\">\n {getFileIcon(fileReference.file_metadata.fileType || '')}\n </span>\n <div className=\"flex-1 min-w-0\">\n <div className=\"font-medium text-sec-900 truncate\">\n {fileReference.file_metadata.fileName || 'Unknown file'}\n </div>\n <div className=\"text-sm text-sec-500\">\n {fileReference.file_metadata.fileSize && formatFileSize(fileReference.file_metadata.fileSize)}\n {fileReference.file_metadata.fileType && ` • ${fileReference.file_metadata.fileType}`}\n </div>\n </div>\n {showDelete && (\n <button\n onClick={handleDelete}\n className=\"text-acc-500 hover:text-acc-700 p-1\"\n title=\"Delete file\"\n >\n ×\n </button>\n )}\n </div>\n )}\n {children}\n </div>\n );\n }\n\n // Multiple files display\n return (\n <div className={`space-y-2 ${className}`}>\n {fileReferences.map((fileRef) => {\n const isImage = fileRef.file_metadata.fileType?.startsWith('image/');\n const fileUrl = fileRef.is_public \n ? `https://your-supabase-url.supabase.co/storage/v1/object/public/files/${fileRef.file_path}`\n : null; // Would need to get signed URL for private files\n \n return (\n <div key={fileRef.id} className=\"flex items-center space-x-3 p-3 bg-sec-50 rounded-lg border border-sec-200\">\n {isImage && fileUrl ? (\n <img\n src={fileUrl}\n alt={fileRef.file_metadata.fileName || 'File'}\n className=\"w-12 h-12 object-cover rounded\"\n onError={handleImageError}\n />\n ) : (\n <span className=\"text-2xl\">\n {getFileIcon(fileRef.file_metadata.fileType || '')}\n </span>\n )}\n <div className=\"flex-1 min-w-0\">\n <div className=\"font-medium text-sec-900 truncate\">\n {fileRef.file_metadata.fileName || 'Unknown file'}\n </div>\n <div className=\"text-sm text-sec-500\">\n {fileRef.file_metadata.fileSize && formatFileSize(fileRef.file_metadata.fileSize)}\n {fileRef.file_metadata.fileType && ` • ${fileRef.file_metadata.fileType}`}\n {fileRef.file_metadata.category && ` • ${fileRef.file_metadata.category}`}\n </div>\n </div>\n {showDelete && (\n <button\n onClick={() => deleteFile(true)}\n className=\"text-acc-500 hover:text-acc-700 p-1\"\n title=\"Delete file\"\n >\n ×\n </button>\n )}\n </div>\n );\n })}\n {children}\n </div>\n );\n}\n"],"mappings":"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","names":["jsx","jsxs","jsx","React","jsx","jsxs","jsx","jsxs","useState","useCallback","useState","useState","uploadFile","getSignedUrl","deleteFile","Fragment","jsx","jsxs","useState","uploadFile","useCallback","useState","useEffect","jsx","jsxs","deleteFile","useState","useEffect","fileUrl"]}
@@ -76,4 +76,32 @@ declare function getCurrentAppName(): string;
76
76
  */
77
77
  declare function getCurrentAppId(): string;
78
78
 
79
- export { type AppConfig as A, type SecureDataAccess as S, cn as a, getCurrentAppName as b, createSecureDataAccess as c, getCurrentAppId as d, getAppConfig as g, setAppConfig as s };
79
+ /**
80
+ * Utility functions for formatting data in the application
81
+ */
82
+ /**
83
+ * Format a date as a readable string
84
+ */
85
+ declare function formatDate(date: Date | string | number): string;
86
+ /**
87
+ * Format a number as a currency
88
+ */
89
+ declare function formatCurrency(value: number, currencyCode?: string, locale?: string): string;
90
+ /**
91
+ * Format a number with custom options
92
+ */
93
+ declare function formatNumber(value: number, options?: Intl.NumberFormatOptions, locale?: string): string;
94
+ /**
95
+ * Format a number as a percentage
96
+ */
97
+ declare function formatPercent(value: number, locale?: string, decimals?: number): string;
98
+ /**
99
+ * Format a large number with abbreviations (K, M, B)
100
+ */
101
+ declare function formatCompactNumber(value: number, locale?: string): string;
102
+ /**
103
+ * Format a file size in bytes to a human-readable string
104
+ */
105
+ declare function formatFileSize(bytes: number): string;
106
+
107
+ export { type AppConfig as A, type SecureDataAccess as S, cn as a, getCurrentAppName as b, createSecureDataAccess as c, getCurrentAppId as d, formatCurrency as e, formatDate as f, getAppConfig as g, formatNumber as h, formatPercent as i, formatCompactNumber as j, formatFileSize as k, setAppConfig as s };
package/dist/hooks.d.ts CHANGED
@@ -1,11 +1,12 @@
1
- export { O as OrganisationSecurityHook, s as UseAppConfigReturn, r as UseOrganisationPermissionsReturn, p as UsePublicEventLogoOptions, o as UsePublicEventLogoReturn, n as UsePublicEventOptions, U as UsePublicEventReturn, q as UsePublicRouteParamsReturn, e as clearPublicEventCache, h as clearPublicLogoCache, m as extractEventCodeFromPath, l as generatePublicRoutePath, g as getPublicEventCacheStats, i as getPublicLogoCacheStats, c as useAppConfig, a as useOrganisationPermissions, b as useOrganisationSecurity, d as usePublicEvent, k as usePublicEventCode, f as usePublicEventLogo, j as usePublicRouteParams, u as useToast } from './usePublicRouteParams-Cu6oKazv.js';
1
+ export { u as useToast } from './useToast-Bm6TnSK-.js';
2
2
  import * as React$1 from 'react';
3
3
  import { SortingState, ColumnFiltersState, ExpandedState } from '@tanstack/react-table';
4
+ export { O as OrganisationSecurityHook, r as UseAppConfigReturn, q as UseOrganisationPermissionsReturn, o as UsePublicEventLogoOptions, n as UsePublicEventLogoReturn, m as UsePublicEventOptions, U as UsePublicEventReturn, p as UsePublicRouteParamsReturn, d as clearPublicEventCache, f as clearPublicLogoCache, l as extractEventCodeFromPath, k as generatePublicRoutePath, g as getPublicEventCacheStats, h as getPublicLogoCacheStats, b as useAppConfig, u as useOrganisationPermissions, a as useOrganisationSecurity, c as usePublicEvent, j as usePublicEventCode, e as usePublicEventLogo, i as usePublicRouteParams } from './usePublicRouteParams-CdoFxnJK.js';
4
5
  import * as react_hook_form from 'react-hook-form';
5
6
  import { z } from 'zod';
6
7
  export { u as useComponentPerformance } from './useComponentPerformance-DE9l5RkL.js';
7
8
  import { d as PaginationMode, D as DataRecord, P as PerformanceConfig, S as ServerSideConfig, C as ChunkingConfig, e as SearchIndexConfig, h as ServerSideParams, i as ServerSideResponse } from './types-E5WSpEtz.js';
8
- import './organisation-DD0yBbGU.js';
9
+ import './organisation-t-vvQC3g.js';
9
10
  import './unified-CMPjE_fv.js';
10
11
  import '@supabase/supabase-js';
11
12
  import './database-C3Szpi5J.js';
package/dist/hooks.js CHANGED
@@ -8,22 +8,22 @@ import {
8
8
  usePublicEvent,
9
9
  usePublicEventCode,
10
10
  usePublicRouteParams
11
- } from "./chunk-HFDYTSAP.js";
11
+ } from "./chunk-QVEOQVD4.js";
12
12
  import {
13
13
  useSecureDataAccess
14
- } from "./chunk-W7PPXKTZ.js";
14
+ } from "./chunk-CKNY7HYS.js";
15
15
  import {
16
16
  clearPublicLogoCache,
17
17
  getPublicLogoCacheStats,
18
18
  useAppConfig,
19
19
  usePublicEventLogo,
20
20
  useToast
21
- } from "./chunk-4ULBJNIT.js";
21
+ } from "./chunk-T6HVDA24.js";
22
22
  import {
23
23
  useDataTablePerformance
24
24
  } from "./chunk-YNUBMSMV.js";
25
- import "./chunk-E4FPK232.js";
26
- import "./chunk-STT7INZR.js";
25
+ import "./chunk-T2MQY57J.js";
26
+ import "./chunk-ULBI5JGB.js";
27
27
  import {
28
28
  useComponentPerformance
29
29
  } from "./chunk-66C4BSAY.js";
package/dist/index.d.ts CHANGED
@@ -1,15 +1,16 @@
1
1
  export { b as UnifiedAuthContextType, U as UnifiedAuthProvider, a as UnifiedAuthProviderProps, u as useUnifiedAuth } from './UnifiedAuthProvider-CQNiemcB.js';
2
2
  export { EventContextType, EventProvider, EventProviderProps, OrganisationProvider, useEvents, useOrganisations } from './providers.js';
3
- export { O as Organisation, b as OrganisationContextType, a as OrganisationMembership, c as OrganisationProviderProps, d as OrganisationSecurityError, U as UserProfile } from './organisation-DD0yBbGU.js';
3
+ export { b as Organisation, d as OrganisationContextType, c as OrganisationMembership, e as OrganisationProviderProps, f as OrganisationSecurityError, U as UserProfile } from './organisation-t-vvQC3g.js';
4
4
  import * as react_jsx_runtime from 'react/jsx-runtime';
5
5
  export { ALL_PERMISSIONS, AccessLevel, AccessLevelGuard, AllPermissions, CACHE_PATTERNS, DataAccessRecord, EVENT_APP_PERMISSIONS, EnhancedNavigationMenu, EnhancedNavigationMenuProps, EventAppRole, GLOBAL_PERMISSIONS, GlobalRole, InvalidScopeError, LogLevel, MissingUserContextError, NavigationAccessRecord, NavigationContextType, NavigationGuard, NavigationGuardProps, NavigationProvider, NavigationProviderProps, ORGANISATION_PERMISSIONS, Operation, OrganisationContextRequiredError, OrganisationRole, PAGE_PERMISSIONS, PageAccessRecord, PagePermissionContextType, PagePermissionGuard, PagePermissionGuardProps, PagePermissionProvider, PagePermissionProviderProps, Permission, PermissionCheck, PermissionDeniedError, PermissionEnforcer, PermissionEnforcerProps, PermissionGuard, PermissionMap, RBACAuditManager, RBACCache, RBACConfig, RBACEngine, RBACError, RBACLogger, RBACNotInitializedError, RoleBasedRouter, RoleBasedRouterContextType, RoleBasedRouterProps, RouteAccessRecord, RouteConfig, Scope, SecureDataContextType, SecureDataProvider, SecureDataProviderProps, SecureSupabaseClient, UUID, createAuditManager, createRBACConfig, createRBACEngine, createRBACExpressMiddleware, createRBACMiddleware, createSecureClient, emitAuditEvent, fromSupabaseClient, getAccessLevel, getGlobalAuditManager, getPermissionMap, getPermissionsForRole, getRBACConfig, getRBACLogger, hasAllPermissions, hasAnyPermission, hasAnyPermissionCached, hasPermission, hasPermissionCached, isDebugMode, isDevelopmentMode, isPermitted, isPermittedCached, isValidPermission, rbacCache, setGlobalAuditManager, setupRBAC, useAccessLevel, useCachedPermissions, useCan, useHasAllPermissions, useHasAnyPermission, useMultiplePermissions, useNavigationPermissions, usePagePermissions, usePermissions, useRBAC, useRoleBasedRouter, useSecureData, withAccessLevelGuard, withPermissionGuard, withRoleGuard } from './rbac/index.js';
6
6
  export { R as RBACContextType, a as RBACProvider, b as RBACProviderProps, U as UserEventAccess, u as useRBACProvider } from './RBACProvider-BO4ilsQB.js';
7
- import { b9 as FileSizeLimits, ba as StorageConfig, bb as StorageUploadOptions, bc as StorageFileMetadata, bd as StorageUploadResult, be as StorageUrlOptions, bf as StorageListOptions, bg as StorageListResult } from './PublicLoadingSpinner-CrMOrhNz.js';
8
- export { A as Alert, m as AlertDescription, l as AlertTitle, n as Avatar, p as AvatarFallback, o as AvatarImage, B as Button, a as ButtonProps, C as Card, g as CardActions, f as CardContent, e as CardDescription, c as CardFooter, b as CardHeader, h as CardProps, d as CardTitle, q as Checkbox, aW as DefaultPublicErrorFallback, D as Dialog, J as DialogBody, F as DialogClose, G as DialogContent, N as DialogDescription, K as DialogFooter, H as DialogHeader, z as DialogOverlay, y as DialogPortal, M as DialogTitle, E as DialogTrigger, ax as ErrorBoundary, aR as EventLogo, aS as EventLogoCompact, aT as EventLogoLarge, b1 as EventLogoProps, aB as EventSelector, ap as Footer, aq as FooterProps, ak as Form, ao as Header, I as Input, j as InputProps, L as Label, k as LabelProps, aA as LoadingSpinner, am as LoginForm, an as LoginFormProps, at as NavigationItem, ar as NavigationMenu, as as NavigationMenuProps, au as OrganisationSelector, b6 as PaceAppLayout, b5 as PaceAppLayoutProps, b8 as PaceLoginPage, b7 as PaceLoginPageProps, aC as PasswordResetForm, P as Progress, aU as PublicErrorBoundary, b2 as PublicErrorBoundaryProps, b3 as PublicErrorBoundaryState, aZ as PublicLoadingSkeleton, aX as PublicLoadingSpinner, aY as PublicLoadingSpinnerFullPage, b4 as PublicLoadingSpinnerProps, aQ as PublicPageContextChecker, aO as PublicPageDebugger, aP as PublicPageDiagnostic, aN as PublicPageFooter, b0 as PublicPageFooterProps, aJ as PublicPageHeader, a$ as PublicPageHeaderProps, aH as PublicPageLayout, a_ as PublicPageLayoutProps, aK as PublicPageProvider, Z as Select, a1 as SelectContent, _ as SelectGroup, a3 as SelectItem, a2 as SelectLabel, a4 as SelectSeparator, a0 as SelectTrigger, $ as SelectValue, bi as StorageFileInfo, T as Table, s as TableBody, t as TableCaption, u as TableCell, v as TableFooter, w as TableHead, r as TableHeader, x as TableRow, a5 as Toast, a7 as ToastAction, ad as ToastActionElement, ac as ToastClose, ab as ToastDescription, ae as ToastProps, a8 as ToastProvider, aa as ToastTitle, a9 as ToastViewport, a6 as Toaster, af as Tooltip, ah as TooltipContent, ai as TooltipProvider, aj as TooltipRoot, ag as TooltipTrigger, aw as UserMenu, bh as UserMenuProps, aV as useErrorBoundary, aE as useFileUpload, aM as useIsPublicPage, aI as usePublicPageContext, aL as usePublicPageProviderContext, aD as useStorage } from './PublicLoadingSpinner-CrMOrhNz.js';
9
- export { p as UsePublicEventLogoOptions, o as UsePublicEventLogoReturn, n as UsePublicEventOptions, U as UsePublicEventReturn, q as UsePublicRouteParamsReturn, e as clearPublicEventCache, h as clearPublicLogoCache, m as extractEventCodeFromPath, l as generatePublicRoutePath, g as getPublicEventCacheStats, i as getPublicLogoCacheStats, c as useAppConfig, a as useOrganisationPermissions, b as useOrganisationSecurity, d as usePublicEvent, k as usePublicEventCode, f as usePublicEventLogo, j as usePublicRouteParams, u as useToast } from './usePublicRouteParams-Cu6oKazv.js';
10
- export { D as DataTable, a as DataTableProps } from './DataTable-DqDDvBfI.js';
7
+ import { F as FileSizeLimits, S as StorageConfig, a as StorageUploadOptions, b as StorageFileMetadata, c as StorageUploadResult, d as StorageUrlOptions, e as StorageListOptions, f as StorageListResult } from './PublicLoadingSpinner-CXJ-W9wZ.js';
8
+ export { A as Alert, r as AlertDescription, q as AlertTitle, s as Avatar, u as AvatarFallback, t as AvatarImage, B as Button, g as ButtonProps, C as Card, m as CardActions, l as CardContent, k as CardDescription, i as CardFooter, h as CardHeader, n as CardProps, j as CardTitle, v as Checkbox, aU as DefaultPublicErrorFallback, D as Dialog, H as DialogBody, z as DialogClose, E as DialogContent, M as DialogDescription, J as DialogFooter, G as DialogHeader, x as DialogOverlay, w as DialogPortal, K as DialogTitle, y as DialogTrigger, ap as ErrorBoundary, aP as EventLogo, aQ as EventLogoCompact, aR as EventLogoLarge, a$ as EventLogoProps, ar as EventSelector, ae as Footer, af as FooterProps, aa as Form, ad as Header, I as Input, o as InputProps, L as Label, p as LabelProps, aq as LoadingSpinner, ab as LoginForm, ac as LoginFormProps, ai as NavigationItem, ag as NavigationMenu, ah as NavigationMenuProps, as as OrganisationSelector, al as PaceAppLayout, am as PaceAppLayoutProps, an as PaceLoginPage, ao as PaceLoginPageProps, at as PasswordResetForm, P as Progress, aS as PublicErrorBoundary, b0 as PublicErrorBoundaryProps, b1 as PublicErrorBoundaryState, aX as PublicLoadingSkeleton, aV as PublicLoadingSpinner, aW as PublicLoadingSpinnerFullPage, b2 as PublicLoadingSpinnerProps, aO as PublicPageContextChecker, aM as PublicPageDebugger, aN as PublicPageDiagnostic, aL as PublicPageFooter, a_ as PublicPageFooterProps, aH as PublicPageHeader, aZ as PublicPageHeaderProps, aF as PublicPageLayout, aY as PublicPageLayoutProps, aI as PublicPageProvider, N as Select, T as SelectContent, O as SelectGroup, V as SelectItem, U as SelectLabel, W as SelectSeparator, R as SelectTrigger, Q as SelectValue, aE as StorageFileInfo, aw as Table, ay as TableBody, az as TableCaption, aA as TableCell, aB as TableFooter, aC as TableHead, ax as TableHeader, aD as TableRow, X as Toast, Z as ToastAction, a3 as ToastActionElement, a2 as ToastClose, a1 as ToastDescription, a4 as ToastProps, _ as ToastProvider, a0 as ToastTitle, $ as ToastViewport, Y as Toaster, a5 as Tooltip, a7 as TooltipContent, a8 as TooltipProvider, a9 as TooltipRoot, a6 as TooltipTrigger, aj as UserMenu, ak as UserMenuProps, aT as useErrorBoundary, av as useFileUpload, aK as useIsPublicPage, aG as usePublicPageContext, aJ as usePublicPageProviderContext, au as useStorage } from './PublicLoadingSpinner-CXJ-W9wZ.js';
9
+ export { u as useToast } from './useToast-Bm6TnSK-.js';
10
+ export { D as DataTable, a as DataTableProps } from './DataTable-D15XipLZ.js';
11
11
  export { A as AggregateConfig, D as DataRecord, f as DataTableAction, a as DataTableColumn, g as DataTableToolbarButton, E as EmptyStateConfig, G as GetRowId } from './types-E5WSpEtz.js';
12
- export { a as cn, c as createSecureDataAccess, g as getAppConfig, d as getCurrentAppId, b as getCurrentAppName, s as setAppConfig } from './appConfig-DjpeG6P-.js';
12
+ export { o as UsePublicEventLogoOptions, n as UsePublicEventLogoReturn, m as UsePublicEventOptions, U as UsePublicEventReturn, p as UsePublicRouteParamsReturn, d as clearPublicEventCache, f as clearPublicLogoCache, l as extractEventCodeFromPath, k as generatePublicRoutePath, g as getPublicEventCacheStats, h as getPublicLogoCacheStats, b as useAppConfig, u as useOrganisationPermissions, a as useOrganisationSecurity, c as usePublicEvent, j as usePublicEventCode, e as usePublicEventLogo, i as usePublicRouteParams } from './usePublicRouteParams-CdoFxnJK.js';
13
+ export { a as cn, c as createSecureDataAccess, j as formatCompactNumber, e as formatCurrency, f as formatDate, k as formatFileSize, h as formatNumber, i as formatPercent, g as getAppConfig, d as getCurrentAppId, b as getCurrentAppName, s as setAppConfig } from './formatting-BfDeV-ja.js';
13
14
  import React__default from 'react';
14
15
  import { SupabaseClient } from '@supabase/supabase-js';
15
16
  export { StyleImport, getAllStylePaths, getStylePath, styleConfig } from './styles/index.js';
@@ -345,10 +346,6 @@ declare function validateFileSize(file: File): {
345
346
  isValid: boolean;
346
347
  error?: string;
347
348
  };
348
- /**
349
- * Get human-readable file size
350
- */
351
- declare function formatFileSize(bytes: number): string;
352
349
 
353
350
  /**
354
351
  * Storage helper functions for pace-core
@@ -424,4 +421,4 @@ declare class StorageUtils {
424
421
  static archiveFile: typeof archiveFile;
425
422
  }
426
423
 
427
- export { APP_PATH_MAPPING, DEFAULT_FILE_SIZE_LIMIT, FILE_SIZE_LIMITS, FileSizeLimits, FileUpload, type FileUploadProps, InactivityWarningModal, type InactivityWarningModalProps, PasswordChangeForm, STORAGE_CONFIG, StorageConfig, StorageFileMetadata, StorageListOptions, StorageListResult, StorageUploadOptions, StorageUploadResult, StorageUrlOptions, StorageUtils, type UseInactivityTrackerOptions, type UseInactivityTrackerReturn, archiveFile, deleteFile, extractFileMetadata, formatFileSize, generateFilePath, generateUniqueFileName, getFileSizeLimit, getPublicUrl, getSignedUrl, listFiles, uploadFile, useInactivityTracker, validateFileSize };
424
+ export { APP_PATH_MAPPING, DEFAULT_FILE_SIZE_LIMIT, FILE_SIZE_LIMITS, FileSizeLimits, FileUpload, type FileUploadProps, InactivityWarningModal, type InactivityWarningModalProps, PasswordChangeForm, STORAGE_CONFIG, StorageConfig, StorageFileMetadata, StorageListOptions, StorageListResult, StorageUploadOptions, StorageUploadResult, StorageUrlOptions, StorageUtils, type UseInactivityTrackerOptions, type UseInactivityTrackerReturn, archiveFile, deleteFile, extractFileMetadata, generateFilePath, generateUniqueFileName, getFileSizeLimit, getPublicUrl, getSignedUrl, listFiles, uploadFile, useInactivityTracker, validateFileSize };