@jmruthers/pace-core 0.5.185 → 0.5.187
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{DataTable-Z9NLVJh0.d.ts → DataTable-IVYljGJ6.d.ts} +1 -1
- package/dist/{DataTable-IX2NBUTP.js → DataTable-K3RJRSOX.js} +7 -7
- package/dist/{PublicPageProvider-BABf6JCh.d.ts → PublicPageProvider-DrLDztHt.d.ts} +214 -107
- package/dist/{UnifiedAuthProvider-A4BCQRJY.js → UnifiedAuthProvider-B76OWOAT.js} +2 -2
- package/dist/{api-BMFCXVQX.js → api-YP7XD5L6.js} +3 -3
- package/dist/{audit-WRS3KJKI.js → audit-B5P6FFIR.js} +2 -2
- package/dist/{chunk-445GEP27.js → chunk-3IC5WCMO.js} +33 -8
- package/dist/chunk-3IC5WCMO.js.map +1 -0
- package/dist/{chunk-OKI34GZD.js → chunk-3NFNJOO7.js} +8 -8
- package/dist/chunk-3NFNJOO7.js.map +1 -0
- package/dist/{chunk-FSFQFJCU.js → chunk-63FOKYGO.js} +174 -6
- package/dist/chunk-63FOKYGO.js.map +1 -0
- package/dist/{chunk-MX3EIJGQ.js → chunk-C4OYJOV4.js} +631 -97
- package/dist/chunk-C4OYJOV4.js.map +1 -0
- package/dist/{chunk-HGPQUCBC.js → chunk-FMTK4XNN.js} +3 -3
- package/dist/{chunk-U6WNSFX5.js → chunk-HEHYGYOX.js} +279 -44
- package/dist/chunk-HEHYGYOX.js.map +1 -0
- package/dist/{chunk-XAUHJD3L.js → chunk-K2JGDXGU.js} +2 -2
- package/dist/{chunk-HC67NW5K.js → chunk-LBBUPSSC.js} +863 -552
- package/dist/chunk-LBBUPSSC.js.map +1 -0
- package/dist/{chunk-IXSNYUCT.js → chunk-SAUPYVLF.js} +1 -1
- package/dist/chunk-SAUPYVLF.js.map +1 -0
- package/dist/{chunk-AISXLWGZ.js → chunk-T6ZJVI3A.js} +27 -23
- package/dist/chunk-T6ZJVI3A.js.map +1 -0
- package/dist/{chunk-STTZQK2I.js → chunk-ULX5FYEM.js} +9 -7
- package/dist/chunk-ULX5FYEM.js.map +1 -0
- package/dist/{chunk-FXFJRTKI.js → chunk-WK2Y6TGA.js} +3 -3
- package/dist/chunk-WK2Y6TGA.js.map +1 -0
- package/dist/chunk-YHCN776L.js +447 -0
- package/dist/chunk-YHCN776L.js.map +1 -0
- package/dist/components.d.ts +4 -4
- package/dist/components.js +12 -10
- package/dist/components.js.map +1 -1
- package/dist/{database.generated-CBmg2950.d.ts → database.generated-DI89OQeI.d.ts} +63 -9
- package/dist/{file-reference-BjR39ktt.d.ts → file-reference-D037xOFK.d.ts} +3 -1
- package/dist/hooks.d.ts +265 -6
- package/dist/hooks.js +148 -49
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +25 -10
- package/dist/index.js +65 -30
- package/dist/index.js.map +1 -1
- package/dist/providers.js +1 -1
- package/dist/rbac/index.d.ts +125 -8
- package/dist/rbac/index.js +27 -7
- package/dist/{types-DUyCRSTj.d.ts → types-Bwgl--Xo.d.ts} +162 -1
- package/dist/types.d.ts +2 -2
- package/dist/types.js +1 -1
- package/dist/{usePublicRouteParams-CvnC3d-e.d.ts → usePublicRouteParams-CTDELQ7H.d.ts} +3 -3
- package/dist/utils.d.ts +214 -4
- package/dist/utils.js +22 -2
- package/dist/utils.js.map +1 -1
- package/docs/api/classes/ColumnFactory.md +1 -1
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/InvalidScopeError.md +1 -1
- package/docs/api/classes/Logger.md +1 -1
- package/docs/api/classes/MissingUserContextError.md +1 -1
- package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
- package/docs/api/classes/PermissionDeniedError.md +1 -1
- package/docs/api/classes/RBACAuditManager.md +21 -17
- package/docs/api/classes/RBACCache.md +31 -23
- package/docs/api/classes/RBACEngine.md +6 -6
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +1 -1
- package/docs/api/classes/SecureSupabaseClient.md +5 -5
- package/docs/api/classes/StorageUtils.md +1 -1
- package/docs/api/enums/FileCategory.md +1 -1
- package/docs/api/enums/LogLevel.md +1 -1
- package/docs/api/enums/RBACErrorCode.md +1 -1
- package/docs/api/enums/RPCFunction.md +1 -1
- package/docs/api/interfaces/AddressFieldProps.md +241 -0
- package/docs/api/interfaces/AddressFieldRef.md +94 -0
- package/docs/api/interfaces/AggregateConfig.md +1 -1
- package/docs/api/interfaces/AutocompleteOptions.md +75 -0
- package/docs/api/interfaces/BadgeProps.md +1 -1
- package/docs/api/interfaces/ButtonProps.md +1 -1
- package/docs/api/interfaces/CalendarProps.md +1 -1
- package/docs/api/interfaces/CardProps.md +1 -1
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +1 -1
- package/docs/api/interfaces/ComplianceResult.md +1 -1
- package/docs/api/interfaces/DataAccessRecord.md +1 -1
- package/docs/api/interfaces/DataRecord.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +1 -1
- package/docs/api/interfaces/DataTableColumn.md +1 -1
- package/docs/api/interfaces/DataTableProps.md +1 -1
- package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
- package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
- package/docs/api/interfaces/DatabaseIssue.md +1 -1
- package/docs/api/interfaces/EmptyStateConfig.md +1 -1
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/EventAppRoleData.md +1 -1
- package/docs/api/interfaces/ExportColumn.md +1 -1
- package/docs/api/interfaces/ExportOptions.md +1 -1
- package/docs/api/interfaces/FileDisplayProps.md +15 -15
- package/docs/api/interfaces/FileMetadata.md +1 -1
- package/docs/api/interfaces/FileReference.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadOptions.md +33 -9
- package/docs/api/interfaces/FileUploadProps.md +36 -14
- package/docs/api/interfaces/FooterProps.md +1 -1
- package/docs/api/interfaces/FormFieldProps.md +1 -1
- package/docs/api/interfaces/FormProps.md +1 -1
- package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
- package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
- package/docs/api/interfaces/InputProps.md +1 -1
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoggerConfig.md +1 -1
- package/docs/api/interfaces/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
- package/docs/api/interfaces/NavigationContextType.md +1 -1
- package/docs/api/interfaces/NavigationGuardProps.md +1 -1
- package/docs/api/interfaces/NavigationItem.md +1 -1
- package/docs/api/interfaces/NavigationMenuProps.md +1 -1
- package/docs/api/interfaces/NavigationProviderProps.md +1 -1
- package/docs/api/interfaces/Organisation.md +1 -1
- package/docs/api/interfaces/OrganisationContextType.md +1 -1
- package/docs/api/interfaces/OrganisationMembership.md +1 -1
- package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
- package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
- package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
- package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
- package/docs/api/interfaces/PageAccessRecord.md +1 -1
- package/docs/api/interfaces/PagePermissionContextType.md +1 -1
- package/docs/api/interfaces/PagePermissionGuardProps.md +11 -11
- package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/ParsedAddress.md +120 -0
- package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
- package/docs/api/interfaces/ProgressProps.md +1 -1
- package/docs/api/interfaces/ProtectedRouteProps.md +6 -6
- package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
- package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
- package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
- package/docs/api/interfaces/QuickFix.md +1 -1
- package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
- package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
- package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
- package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
- package/docs/api/interfaces/RBACConfig.md +27 -4
- package/docs/api/interfaces/RBACContext.md +1 -1
- package/docs/api/interfaces/RBACLogger.md +5 -5
- package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
- package/docs/api/interfaces/RBACPerformanceMetrics.md +138 -0
- package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
- package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
- package/docs/api/interfaces/RBACResult.md +1 -1
- package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
- package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
- package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
- package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
- package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
- package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
- package/docs/api/interfaces/RBACRolesListParams.md +1 -1
- package/docs/api/interfaces/RBACRolesListResult.md +1 -1
- package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
- package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
- package/docs/api/interfaces/ResourcePermissions.md +1 -1
- package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RoleManagementResult.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +1 -1
- package/docs/api/interfaces/RouteConfig.md +1 -1
- package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
- package/docs/api/interfaces/SecureDataContextType.md +1 -1
- package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
- package/docs/api/interfaces/SessionRestorationLoaderProps.md +1 -1
- package/docs/api/interfaces/SetupIssue.md +1 -1
- package/docs/api/interfaces/StorageConfig.md +1 -1
- package/docs/api/interfaces/StorageFileInfo.md +1 -1
- package/docs/api/interfaces/StorageFileMetadata.md +1 -1
- package/docs/api/interfaces/StorageListOptions.md +1 -1
- package/docs/api/interfaces/StorageListResult.md +1 -1
- package/docs/api/interfaces/StorageUploadOptions.md +1 -1
- package/docs/api/interfaces/StorageUploadResult.md +1 -1
- package/docs/api/interfaces/StorageUrlOptions.md +1 -1
- package/docs/api/interfaces/StyleImport.md +1 -1
- package/docs/api/interfaces/SwitchProps.md +1 -1
- package/docs/api/interfaces/TabsContentProps.md +1 -1
- package/docs/api/interfaces/TabsListProps.md +1 -1
- package/docs/api/interfaces/TabsProps.md +1 -1
- package/docs/api/interfaces/TabsTriggerProps.md +1 -1
- package/docs/api/interfaces/TextareaProps.md +1 -1
- package/docs/api/interfaces/ToastActionElement.md +1 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
- package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
- package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +2 -2
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
- package/docs/api/interfaces/UsePublicFileDisplayOptions.md +2 -2
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeOptions.md +2 -2
- package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
- package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
- package/docs/api/interfaces/UserEventAccess.md +1 -1
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +328 -69
- package/docs/api-reference/components.md +26 -12
- package/docs/best-practices/performance.md +11 -0
- package/docs/implementation-guides/file-reference-system.md +24 -2
- package/docs/implementation-guides/file-upload-storage.md +38 -1
- package/docs/rbac/README.md +2 -1
- package/docs/rbac/api-reference.md +11 -0
- package/docs/rbac/performance.md +320 -0
- package/docs/standards/01-architecture-standard.md +5 -0
- package/docs/standards/05-security-standard.md +12 -0
- package/package.json +1 -1
- package/scripts/check-pace-core-compliance.js +512 -0
- package/src/components/AddressField/AddressField.test.tsx +411 -0
- package/src/components/AddressField/AddressField.tsx +323 -0
- package/src/components/AddressField/README.md +336 -0
- package/src/components/AddressField/index.ts +10 -0
- package/src/components/AddressField/types.ts +65 -0
- package/src/components/FileDisplay/FileDisplay.test.tsx +454 -0
- package/src/components/FileDisplay/FileDisplay.tsx +28 -1
- package/src/components/FileUpload/FileUpload.test.tsx +2 -0
- package/src/components/FileUpload/FileUpload.tsx +7 -1
- package/src/components/Header/Header.tsx +2 -5
- package/src/components/ProtectedRoute/ProtectedRoute.tsx +134 -1
- package/src/components/index.ts +2 -0
- package/src/hooks/__tests__/useFileDisplay.unit.test.ts +30 -5
- package/src/hooks/__tests__/useOrganisationSecurity.unit.test.tsx +11 -10
- package/src/hooks/__tests__/usePublicFileDisplay.test.ts +31 -6
- package/src/hooks/index.ts +9 -0
- package/src/hooks/public/usePublicFileDisplay.ts +8 -10
- package/src/hooks/useAddressAutocomplete.test.ts +318 -0
- package/src/hooks/useAddressAutocomplete.ts +268 -0
- package/src/hooks/useFileDisplay.ts +3 -15
- package/src/hooks/useFileReference.test.ts +21 -3
- package/src/hooks/useFileReference.ts +3 -24
- package/src/hooks/useFileUrlCache.ts +246 -0
- package/src/hooks/useInactivityTracker.ts +31 -20
- package/src/hooks/useOrganisationSecurity.test.ts +10 -7
- package/src/hooks/useOrganisationSecurity.ts +3 -3
- package/src/hooks/usePreventTabReload.ts +106 -0
- package/src/hooks/useQueryCache.ts +315 -0
- package/src/hooks/useSecureDataAccess.ts +2 -2
- package/src/index.ts +2 -0
- package/src/providers/services/EventServiceProvider.tsx +4 -1
- package/src/rbac/__tests__/rbac-role-isolation.test.ts +456 -0
- package/src/rbac/api.test.ts +21 -6
- package/src/rbac/api.ts +32 -11
- package/src/rbac/audit-batched.ts +223 -0
- package/src/rbac/audit-enhanced.ts +2 -2
- package/src/rbac/audit.test.ts +6 -5
- package/src/rbac/audit.ts +34 -6
- package/src/rbac/cache-invalidation.ts +63 -12
- package/src/rbac/cache.test.ts +2 -2
- package/src/rbac/cache.ts +61 -14
- package/src/rbac/components/PagePermissionGuard.tsx +19 -10
- package/src/rbac/components/__tests__/PagePermissionGuard.performance.test.tsx +248 -0
- package/src/rbac/config.ts +9 -0
- package/src/rbac/engine.ts +2 -21
- package/src/rbac/hooks/usePermissions.ts +21 -5
- package/src/rbac/index.ts +19 -0
- package/src/rbac/performance.ts +210 -0
- package/src/rbac/request-deduplication.ts +87 -0
- package/src/rbac/utils/deep-equal.ts +93 -0
- package/src/styles/core.css +5 -5
- package/src/types/database.generated.ts +63 -9
- package/src/types/file-reference.ts +3 -1
- package/src/utils/file-reference/__tests__/file-reference.test.ts +89 -8
- package/src/utils/file-reference/index.ts +56 -17
- package/src/utils/google-places/googlePlacesUtils.test.ts +403 -0
- package/src/utils/google-places/googlePlacesUtils.ts +475 -0
- package/src/utils/google-places/index.ts +26 -0
- package/src/utils/google-places/loadGoogleMapsScript.ts +207 -0
- package/src/utils/google-places/types.ts +94 -0
- package/src/utils/index.ts +23 -0
- package/src/utils/request-deduplication.ts +165 -0
- package/src/utils/security/secureDataAccess.ts +1 -1
- package/src/utils/storage/helpers.ts +211 -4
- package/dist/chunk-445GEP27.js.map +0 -1
- package/dist/chunk-AISXLWGZ.js.map +0 -1
- package/dist/chunk-FMUCXFII.js +0 -76
- package/dist/chunk-FMUCXFII.js.map +0 -1
- package/dist/chunk-FSFQFJCU.js.map +0 -1
- package/dist/chunk-FXFJRTKI.js.map +0 -1
- package/dist/chunk-HC67NW5K.js.map +0 -1
- package/dist/chunk-IXSNYUCT.js.map +0 -1
- package/dist/chunk-MX3EIJGQ.js.map +0 -1
- package/dist/chunk-OKI34GZD.js.map +0 -1
- package/dist/chunk-STTZQK2I.js.map +0 -1
- package/dist/chunk-U6WNSFX5.js.map +0 -1
- /package/dist/{DataTable-IX2NBUTP.js.map → DataTable-K3RJRSOX.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-A4BCQRJY.js.map → UnifiedAuthProvider-B76OWOAT.js.map} +0 -0
- /package/dist/{api-BMFCXVQX.js.map → api-YP7XD5L6.js.map} +0 -0
- /package/dist/{audit-WRS3KJKI.js.map → audit-B5P6FFIR.js.map} +0 -0
- /package/dist/{chunk-HGPQUCBC.js.map → chunk-FMTK4XNN.js.map} +0 -0
- /package/dist/{chunk-XAUHJD3L.js.map → chunk-K2JGDXGU.js.map} +0 -0
package/dist/components.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/DateTimeField/DateTimeField.tsx","../src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx"],"sourcesContent":["/**\n * @file DateTimeField Component\n * @package @jmruthers/pace-core\n * @module Components/DateTimeField\n * @since 0.1.0\n *\n * Form input component for datetime values with timezone support.\n * Handles UTC ↔ timezone conversion automatically.\n *\n * Features:\n * - Automatic UTC ↔ timezone conversion\n * - Prevents unwanted conversions during user editing\n * - Shows timezone information when not UTC\n * - Supports both ISO string and Date object values\n * - Uses native datetime-local input type\n * - Accessible form field with proper labels\n *\n * @example\n * ```tsx\n * import { DateTimeField } from '@jmruthers/pace-core/components';\n * import { useState } from 'react';\n *\n * function EventForm() {\n * const [startTime, setStartTime] = useState<string>();\n *\n * return (\n * <DateTimeField\n * label=\"Start Time\"\n * value={startTime}\n * onChange={setStartTime}\n * timezone=\"America/New_York\"\n * required\n * />\n * );\n * }\n * ```\n *\n * @accessibility\n * - Proper label association with htmlFor\n * - Required field indicators\n * - Screen reader friendly\n * - Keyboard navigation support\n * - Focus management\n */\n\nimport * as React from 'react';\nimport { format, parse } from 'date-fns';\nimport { Label } from '../Label';\nimport { Input } from '../Input';\nimport { cn } from '../../utils/core/cn';\nimport { toZonedTime, fromZonedTime, getUserTimeZone } from '../../utils/timezone';\n\n/**\n * Props for the DateTimeField component\n */\nexport interface DateTimeFieldProps {\n /**\n * Field label\n */\n label: string;\n /**\n * UTC date value (ISO string, Date object, or undefined)\n */\n value: string | Date | undefined;\n /**\n * Change handler that receives UTC value (ISO string or Date object)\n */\n onChange: (value: string | Date | undefined) => void;\n /**\n * Target timezone for display (default: 'UTC')\n */\n timezone?: string;\n /**\n * Whether the field is required\n */\n required?: boolean;\n /**\n * Additional CSS classes\n */\n className?: string;\n /**\n * If true, onChange returns Date object instead of ISO string\n */\n returnAsDate?: boolean;\n /**\n * Input id (auto-generated if not provided)\n */\n id?: string;\n /**\n * Helper text to display below the label\n */\n helperText?: string;\n /**\n * Error message to display\n */\n error?: string;\n}\n\n/**\n * DateTimeField component\n * Form input for datetime values with automatic timezone conversion\n *\n * @param props - DateTimeField configuration\n * @returns JSX.Element - The rendered datetime field\n */\nexport function DateTimeField({\n label,\n value,\n onChange,\n timezone = 'UTC',\n required = false,\n className,\n returnAsDate = false,\n id,\n helperText,\n error\n}: DateTimeFieldProps) {\n const [isEditing, setIsEditing] = React.useState(false);\n const inputRef = React.useRef<HTMLInputElement>(null);\n const fieldId = id || `datetime-field-${React.useId()}`;\n\n // Convert UTC value to timezone for display\n const getDisplayValue = React.useCallback((): string => {\n if (!value) {\n return '';\n }\n\n try {\n let dateObj: Date;\n if (typeof value === 'string') {\n dateObj = new Date(value);\n } else {\n dateObj = value;\n }\n\n if (!dateObj || isNaN(dateObj.getTime())) {\n return '';\n }\n\n // Convert UTC to timezone\n const zonedDate = toZonedTime(dateObj, timezone);\n\n // Format for datetime-local input (YYYY-MM-DDTHH:mm)\n return format(zonedDate, \"yyyy-MM-dd'T'HH:mm\");\n } catch {\n return '';\n }\n }, [value, timezone]);\n\n const displayValue = isEditing ? undefined : getDisplayValue();\n\n // Handle input change\n const handleChange = React.useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n setIsEditing(true);\n const inputValue = e.target.value;\n\n if (!inputValue) {\n onChange(undefined);\n return;\n }\n\n try {\n // Parse the datetime-local value (in timezone)\n const localDate = parse(inputValue, \"yyyy-MM-dd'T'HH:mm\", new Date());\n\n if (isNaN(localDate.getTime())) {\n onChange(undefined);\n return;\n }\n\n // Convert from timezone to UTC\n const utcDate = fromZonedTime(localDate, timezone);\n\n // Return as ISO string or Date object\n if (returnAsDate) {\n onChange(utcDate);\n } else {\n onChange(utcDate.toISOString());\n }\n } catch {\n onChange(undefined);\n }\n }, [timezone, returnAsDate, onChange]);\n\n // Handle blur to stop editing mode\n const handleBlur = React.useCallback(() => {\n setIsEditing(false);\n }, []);\n\n // Get timezone display text\n const getTimezoneDisplay = React.useCallback((): string => {\n if (timezone === 'UTC') {\n return '';\n }\n\n const userTz = getUserTimeZone();\n if (timezone === userTz) {\n return 'Local';\n }\n\n return timezone;\n }, [timezone]);\n\n const timezoneDisplay = getTimezoneDisplay();\n\n return (\n <div className={cn('space-y-2', className)}>\n <Label htmlFor={fieldId} required={required} helperText={helperText} error={error}>\n {label}\n </Label>\n <div className=\"relative\">\n <Input\n ref={inputRef}\n id={fieldId}\n type=\"datetime-local\"\n value={displayValue}\n onChange={handleChange}\n onBlur={handleBlur}\n required={required}\n error={!!error}\n className=\"w-full\"\n />\n {timezoneDisplay && (\n <span className=\"absolute right-3 top-1/2 -translate-y-1/2 text-sm text-muted-foreground pointer-events-none\">\n {timezoneDisplay}\n </span>\n )}\n </div>\n </div>\n );\n}\n\n","/**\n * @file DatePickerWithTimezone Component\n * @package @jmruthers/pace-core\n * @module Components/DatePickerWithTimezone\n * @since 0.1.0\n *\n * Date picker component that displays timezone information alongside the calendar.\n * Provides a calendar interface with timezone context for date selection.\n *\n * Features:\n * - Calendar date selection\n * - Timezone display (shows \"Local\" when matches user timezone)\n * - Optional \"Done\" button\n * - Accessible date selection\n * - Keyboard navigation support\n *\n * @example\n * ```tsx\n * import { DatePickerWithTimezone } from '@jmruthers/pace-core/components';\n * import { useState } from 'react';\n *\n * function DateSelector() {\n * const [date, setDate] = useState<Date>();\n *\n * return (\n * <DatePickerWithTimezone\n * selected={date}\n * onSelect={setDate}\n * timezone=\"America/New_York\"\n * onDone={() => console.log('Date selected')}\n * />\n * );\n * }\n * ```\n *\n * @accessibility\n * - WCAG 2.1 AA compliant\n * - Keyboard navigation support\n * - Screen reader friendly\n * - Focus management\n * - Proper ARIA attributes\n */\n\nimport * as React from 'react';\nimport { Calendar } from '../Calendar';\nimport { Button } from '../Button';\nimport { Clock } from 'lucide-react';\nimport { getUserTimeZone } from '../../utils/timezone';\nimport { cn } from '../../utils/core/cn';\n\n/**\n * Props for the DatePickerWithTimezone component\n */\nexport interface DatePickerWithTimezoneProps {\n /**\n * Currently selected date\n */\n selected?: Date;\n /**\n * Date selection handler\n */\n onSelect: (date: Date | undefined) => void;\n /**\n * Optional callback when \"Done\" button is clicked\n */\n onDone?: () => void;\n /**\n * Timezone to display (defaults to user's timezone)\n */\n timezone?: string;\n /**\n * Additional CSS classes\n */\n className?: string;\n}\n\n/**\n * DatePickerWithTimezone component\n * Date picker with timezone information display\n *\n * @param props - DatePickerWithTimezone configuration\n * @returns JSX.Element - The rendered date picker with timezone\n */\nexport function DatePickerWithTimezone({\n selected,\n onSelect,\n onDone,\n timezone,\n className\n}: DatePickerWithTimezoneProps) {\n const userTimezone = getUserTimeZone();\n const displayTimezone = timezone || userTimezone;\n const timezoneDisplay = displayTimezone === userTimezone ? 'Local' : displayTimezone;\n\n return (\n <div className={cn('flex flex-col', className)}>\n <div className=\"p-3\">\n <Calendar\n mode=\"single\"\n selected={selected}\n onSelect={onSelect}\n initialFocus\n captionLayout=\"dropdown-buttons\"\n fromYear={1900}\n toYear={2100}\n className=\"p-0\"\n />\n </div>\n\n <div className=\"flex items-center justify-between border-t border-border px-3 py-2\">\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <Clock className=\"h-4 w-4\" aria-hidden=\"true\" />\n <span>\n Timezone: <span aria-label={`Timezone ${timezoneDisplay}`}>{timezoneDisplay}</span>\n </span>\n </div>\n {onDone && (\n <Button onClick={onDone} size=\"sm\" className=\"h-8\">\n Done\n </Button>\n )}\n </div>\n </div>\n );\n}\n\n"],"mappings":"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","names":["jsx","jsxs"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/DateTimeField/DateTimeField.tsx","../src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx"],"sourcesContent":["/**\n * @file DateTimeField Component\n * @package @jmruthers/pace-core\n * @module Components/DateTimeField\n * @since 0.1.0\n *\n * Form input component for datetime values with timezone support.\n * Handles UTC ↔ timezone conversion automatically.\n *\n * Features:\n * - Automatic UTC ↔ timezone conversion\n * - Prevents unwanted conversions during user editing\n * - Shows timezone information when not UTC\n * - Supports both ISO string and Date object values\n * - Uses native datetime-local input type\n * - Accessible form field with proper labels\n *\n * @example\n * ```tsx\n * import { DateTimeField } from '@jmruthers/pace-core/components';\n * import { useState } from 'react';\n *\n * function EventForm() {\n * const [startTime, setStartTime] = useState<string>();\n *\n * return (\n * <DateTimeField\n * label=\"Start Time\"\n * value={startTime}\n * onChange={setStartTime}\n * timezone=\"America/New_York\"\n * required\n * />\n * );\n * }\n * ```\n *\n * @accessibility\n * - Proper label association with htmlFor\n * - Required field indicators\n * - Screen reader friendly\n * - Keyboard navigation support\n * - Focus management\n */\n\nimport * as React from 'react';\nimport { format, parse } from 'date-fns';\nimport { Label } from '../Label';\nimport { Input } from '../Input';\nimport { cn } from '../../utils/core/cn';\nimport { toZonedTime, fromZonedTime, getUserTimeZone } from '../../utils/timezone';\n\n/**\n * Props for the DateTimeField component\n */\nexport interface DateTimeFieldProps {\n /**\n * Field label\n */\n label: string;\n /**\n * UTC date value (ISO string, Date object, or undefined)\n */\n value: string | Date | undefined;\n /**\n * Change handler that receives UTC value (ISO string or Date object)\n */\n onChange: (value: string | Date | undefined) => void;\n /**\n * Target timezone for display (default: 'UTC')\n */\n timezone?: string;\n /**\n * Whether the field is required\n */\n required?: boolean;\n /**\n * Additional CSS classes\n */\n className?: string;\n /**\n * If true, onChange returns Date object instead of ISO string\n */\n returnAsDate?: boolean;\n /**\n * Input id (auto-generated if not provided)\n */\n id?: string;\n /**\n * Helper text to display below the label\n */\n helperText?: string;\n /**\n * Error message to display\n */\n error?: string;\n}\n\n/**\n * DateTimeField component\n * Form input for datetime values with automatic timezone conversion\n *\n * @param props - DateTimeField configuration\n * @returns JSX.Element - The rendered datetime field\n */\nexport function DateTimeField({\n label,\n value,\n onChange,\n timezone = 'UTC',\n required = false,\n className,\n returnAsDate = false,\n id,\n helperText,\n error\n}: DateTimeFieldProps) {\n const [isEditing, setIsEditing] = React.useState(false);\n const inputRef = React.useRef<HTMLInputElement>(null);\n const fieldId = id || `datetime-field-${React.useId()}`;\n\n // Convert UTC value to timezone for display\n const getDisplayValue = React.useCallback((): string => {\n if (!value) {\n return '';\n }\n\n try {\n let dateObj: Date;\n if (typeof value === 'string') {\n dateObj = new Date(value);\n } else {\n dateObj = value;\n }\n\n if (!dateObj || isNaN(dateObj.getTime())) {\n return '';\n }\n\n // Convert UTC to timezone\n const zonedDate = toZonedTime(dateObj, timezone);\n\n // Format for datetime-local input (YYYY-MM-DDTHH:mm)\n return format(zonedDate, \"yyyy-MM-dd'T'HH:mm\");\n } catch {\n return '';\n }\n }, [value, timezone]);\n\n const displayValue = isEditing ? undefined : getDisplayValue();\n\n // Handle input change\n const handleChange = React.useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n setIsEditing(true);\n const inputValue = e.target.value;\n\n if (!inputValue) {\n onChange(undefined);\n return;\n }\n\n try {\n // Parse the datetime-local value (in timezone)\n const localDate = parse(inputValue, \"yyyy-MM-dd'T'HH:mm\", new Date());\n\n if (isNaN(localDate.getTime())) {\n onChange(undefined);\n return;\n }\n\n // Convert from timezone to UTC\n const utcDate = fromZonedTime(localDate, timezone);\n\n // Return as ISO string or Date object\n if (returnAsDate) {\n onChange(utcDate);\n } else {\n onChange(utcDate.toISOString());\n }\n } catch {\n onChange(undefined);\n }\n }, [timezone, returnAsDate, onChange]);\n\n // Handle blur to stop editing mode\n const handleBlur = React.useCallback(() => {\n setIsEditing(false);\n }, []);\n\n // Get timezone display text\n const getTimezoneDisplay = React.useCallback((): string => {\n if (timezone === 'UTC') {\n return '';\n }\n\n const userTz = getUserTimeZone();\n if (timezone === userTz) {\n return 'Local';\n }\n\n return timezone;\n }, [timezone]);\n\n const timezoneDisplay = getTimezoneDisplay();\n\n return (\n <div className={cn('space-y-2', className)}>\n <Label htmlFor={fieldId} required={required} helperText={helperText} error={error}>\n {label}\n </Label>\n <div className=\"relative\">\n <Input\n ref={inputRef}\n id={fieldId}\n type=\"datetime-local\"\n value={displayValue}\n onChange={handleChange}\n onBlur={handleBlur}\n required={required}\n error={!!error}\n className=\"w-full\"\n />\n {timezoneDisplay && (\n <span className=\"absolute right-3 top-1/2 -translate-y-1/2 text-sm text-muted-foreground pointer-events-none\">\n {timezoneDisplay}\n </span>\n )}\n </div>\n </div>\n );\n}\n\n","/**\n * @file DatePickerWithTimezone Component\n * @package @jmruthers/pace-core\n * @module Components/DatePickerWithTimezone\n * @since 0.1.0\n *\n * Date picker component that displays timezone information alongside the calendar.\n * Provides a calendar interface with timezone context for date selection.\n *\n * Features:\n * - Calendar date selection\n * - Timezone display (shows \"Local\" when matches user timezone)\n * - Optional \"Done\" button\n * - Accessible date selection\n * - Keyboard navigation support\n *\n * @example\n * ```tsx\n * import { DatePickerWithTimezone } from '@jmruthers/pace-core/components';\n * import { useState } from 'react';\n *\n * function DateSelector() {\n * const [date, setDate] = useState<Date>();\n *\n * return (\n * <DatePickerWithTimezone\n * selected={date}\n * onSelect={setDate}\n * timezone=\"America/New_York\"\n * onDone={() => console.log('Date selected')}\n * />\n * );\n * }\n * ```\n *\n * @accessibility\n * - WCAG 2.1 AA compliant\n * - Keyboard navigation support\n * - Screen reader friendly\n * - Focus management\n * - Proper ARIA attributes\n */\n\nimport * as React from 'react';\nimport { Calendar } from '../Calendar';\nimport { Button } from '../Button';\nimport { Clock } from 'lucide-react';\nimport { getUserTimeZone } from '../../utils/timezone';\nimport { cn } from '../../utils/core/cn';\n\n/**\n * Props for the DatePickerWithTimezone component\n */\nexport interface DatePickerWithTimezoneProps {\n /**\n * Currently selected date\n */\n selected?: Date;\n /**\n * Date selection handler\n */\n onSelect: (date: Date | undefined) => void;\n /**\n * Optional callback when \"Done\" button is clicked\n */\n onDone?: () => void;\n /**\n * Timezone to display (defaults to user's timezone)\n */\n timezone?: string;\n /**\n * Additional CSS classes\n */\n className?: string;\n}\n\n/**\n * DatePickerWithTimezone component\n * Date picker with timezone information display\n *\n * @param props - DatePickerWithTimezone configuration\n * @returns JSX.Element - The rendered date picker with timezone\n */\nexport function DatePickerWithTimezone({\n selected,\n onSelect,\n onDone,\n timezone,\n className\n}: DatePickerWithTimezoneProps) {\n const userTimezone = getUserTimeZone();\n const displayTimezone = timezone || userTimezone;\n const timezoneDisplay = displayTimezone === userTimezone ? 'Local' : displayTimezone;\n\n return (\n <div className={cn('flex flex-col', className)}>\n <div className=\"p-3\">\n <Calendar\n mode=\"single\"\n selected={selected}\n onSelect={onSelect}\n initialFocus\n captionLayout=\"dropdown-buttons\"\n fromYear={1900}\n toYear={2100}\n className=\"p-0\"\n />\n </div>\n\n <div className=\"flex items-center justify-between border-t border-border px-3 py-2\">\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <Clock className=\"h-4 w-4\" aria-hidden=\"true\" />\n <span>\n Timezone: <span aria-label={`Timezone ${timezoneDisplay}`}>{timezoneDisplay}</span>\n </span>\n </div>\n {onDone && (\n <Button onClick={onDone} size=\"sm\" className=\"h-8\">\n Done\n </Button>\n )}\n </div>\n </div>\n );\n}\n\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,YAAY,WAAW;AACvB,SAAS,QAAQ,aAAa;AAiKxB,cAGA,YAHA;AAtGC,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,WAAW;AAAA,EACX;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AACF,GAAuB;AACrB,QAAM,CAAC,WAAW,YAAY,IAAU,eAAS,KAAK;AACtD,QAAM,WAAiB,aAAyB,IAAI;AACpD,QAAM,UAAU,MAAM,kBAAwB,YAAM,CAAC;AAGrD,QAAM,kBAAwB,kBAAY,MAAc;AACtD,QAAI,CAAC,OAAO;AACV,aAAO;AAAA,IACT;AAEA,QAAI;AACF,UAAI;AACJ,UAAI,OAAO,UAAU,UAAU;AAC7B,kBAAU,IAAI,KAAK,KAAK;AAAA,MAC1B,OAAO;AACL,kBAAU;AAAA,MACZ;AAEA,UAAI,CAAC,WAAW,MAAM,QAAQ,QAAQ,CAAC,GAAG;AACxC,eAAO;AAAA,MACT;AAGA,YAAM,YAAY,YAAY,SAAS,QAAQ;AAG/C,aAAO,OAAO,WAAW,oBAAoB;AAAA,IAC/C,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF,GAAG,CAAC,OAAO,QAAQ,CAAC;AAEpB,QAAM,eAAe,YAAY,SAAY,gBAAgB;AAG7D,QAAM,eAAqB,kBAAY,CAAC,MAA2C;AACjF,iBAAa,IAAI;AACjB,UAAM,aAAa,EAAE,OAAO;AAE5B,QAAI,CAAC,YAAY;AACf,eAAS,MAAS;AAClB;AAAA,IACF;AAEA,QAAI;AAEF,YAAM,YAAY,MAAM,YAAY,sBAAsB,oBAAI,KAAK,CAAC;AAEpE,UAAI,MAAM,UAAU,QAAQ,CAAC,GAAG;AAC9B,iBAAS,MAAS;AAClB;AAAA,MACF;AAGA,YAAM,UAAU,cAAc,WAAW,QAAQ;AAGjD,UAAI,cAAc;AAChB,iBAAS,OAAO;AAAA,MAClB,OAAO;AACL,iBAAS,QAAQ,YAAY,CAAC;AAAA,MAChC;AAAA,IACF,QAAQ;AACN,eAAS,MAAS;AAAA,IACpB;AAAA,EACF,GAAG,CAAC,UAAU,cAAc,QAAQ,CAAC;AAGrC,QAAM,aAAmB,kBAAY,MAAM;AACzC,iBAAa,KAAK;AAAA,EACpB,GAAG,CAAC,CAAC;AAGL,QAAM,qBAA2B,kBAAY,MAAc;AACzD,QAAI,aAAa,OAAO;AACtB,aAAO;AAAA,IACT;AAEA,UAAM,SAAS,gBAAgB;AAC/B,QAAI,aAAa,QAAQ;AACvB,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,CAAC;AAEb,QAAM,kBAAkB,mBAAmB;AAE3C,SACE,qBAAC,SAAI,WAAW,GAAG,aAAa,SAAS,GACvC;AAAA,wBAAC,SAAM,SAAS,SAAS,UAAoB,YAAwB,OAClE,iBACH;AAAA,IACA,qBAAC,SAAI,WAAU,YACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,KAAK;AAAA,UACL,IAAI;AAAA,UACJ,MAAK;AAAA,UACL,OAAO;AAAA,UACP,UAAU;AAAA,UACV,QAAQ;AAAA,UACR;AAAA,UACA,OAAO,CAAC,CAAC;AAAA,UACT,WAAU;AAAA;AAAA,MACZ;AAAA,MACC,mBACC,oBAAC,UAAK,WAAU,+FACb,2BACH;AAAA,OAEJ;AAAA,KACF;AAEJ;;;ACxLA,SAAS,aAAa;AAmDd,gBAAAA,MAeE,QAAAC,aAfF;AAdD,SAAS,uBAAuB;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAgC;AAC9B,QAAM,eAAe,gBAAgB;AACrC,QAAM,kBAAkB,YAAY;AACpC,QAAM,kBAAkB,oBAAoB,eAAe,UAAU;AAErE,SACE,gBAAAA,MAAC,SAAI,WAAW,GAAG,iBAAiB,SAAS,GAC3C;AAAA,oBAAAD,KAAC,SAAI,WAAU,OACb,0BAAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA,cAAY;AAAA,QACZ,eAAc;AAAA,QACd,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,WAAU;AAAA;AAAA,IACZ,GACF;AAAA,IAEA,gBAAAC,MAAC,SAAI,WAAU,sEACb;AAAA,sBAAAA,MAAC,SAAI,WAAU,yDACb;AAAA,wBAAAD,KAAC,SAAM,WAAU,WAAU,eAAY,QAAO;AAAA,QAC9C,gBAAAC,MAAC,UAAK;AAAA;AAAA,UACM,gBAAAD,KAAC,UAAK,cAAY,YAAY,eAAe,IAAK,2BAAgB;AAAA,WAC9E;AAAA,SACF;AAAA,MACC,UACC,gBAAAA,KAAC,UAAO,SAAS,QAAQ,MAAK,MAAK,WAAU,OAAM,kBAEnD;AAAA,OAEJ;AAAA,KACF;AAEJ;","names":["jsx","jsxs"]}
|
|
@@ -3307,13 +3307,13 @@ type Database = {
|
|
|
3307
3307
|
}
|
|
3308
3308
|
];
|
|
3309
3309
|
};
|
|
3310
|
-
|
|
3310
|
+
pace_identification: {
|
|
3311
3311
|
Row: {
|
|
3312
3312
|
created_at: string | null;
|
|
3313
3313
|
document_number: string | null;
|
|
3314
|
-
document_type: string;
|
|
3315
3314
|
expiry_date: string | null;
|
|
3316
3315
|
id: string;
|
|
3316
|
+
identification_type_id: number | null;
|
|
3317
3317
|
issue_city: string | null;
|
|
3318
3318
|
issue_country: string | null;
|
|
3319
3319
|
issue_date: string | null;
|
|
@@ -3326,9 +3326,9 @@ type Database = {
|
|
|
3326
3326
|
Insert: {
|
|
3327
3327
|
created_at?: string | null;
|
|
3328
3328
|
document_number?: string | null;
|
|
3329
|
-
document_type: string;
|
|
3330
3329
|
expiry_date?: string | null;
|
|
3331
3330
|
id?: string;
|
|
3331
|
+
identification_type_id?: number | null;
|
|
3332
3332
|
issue_city?: string | null;
|
|
3333
3333
|
issue_country?: string | null;
|
|
3334
3334
|
issue_date?: string | null;
|
|
@@ -3341,9 +3341,9 @@ type Database = {
|
|
|
3341
3341
|
Update: {
|
|
3342
3342
|
created_at?: string | null;
|
|
3343
3343
|
document_number?: string | null;
|
|
3344
|
-
document_type?: string;
|
|
3345
3344
|
expiry_date?: string | null;
|
|
3346
3345
|
id?: string;
|
|
3346
|
+
identification_type_id?: number | null;
|
|
3347
3347
|
issue_city?: string | null;
|
|
3348
3348
|
issue_country?: string | null;
|
|
3349
3349
|
issue_date?: string | null;
|
|
@@ -3355,14 +3355,21 @@ type Database = {
|
|
|
3355
3355
|
};
|
|
3356
3356
|
Relationships: [
|
|
3357
3357
|
{
|
|
3358
|
-
foreignKeyName: "
|
|
3358
|
+
foreignKeyName: "fk_pace_identification_organisation_id";
|
|
3359
3359
|
columns: ["organisation_id"];
|
|
3360
3360
|
isOneToOne: false;
|
|
3361
3361
|
referencedRelation: "organisations";
|
|
3362
3362
|
referencedColumns: ["id"];
|
|
3363
3363
|
},
|
|
3364
3364
|
{
|
|
3365
|
-
foreignKeyName: "
|
|
3365
|
+
foreignKeyName: "fk_pace_identification_type_id";
|
|
3366
|
+
columns: ["identification_type_id"];
|
|
3367
|
+
isOneToOne: false;
|
|
3368
|
+
referencedRelation: "pace_identification_type";
|
|
3369
|
+
referencedColumns: ["id"];
|
|
3370
|
+
},
|
|
3371
|
+
{
|
|
3372
|
+
foreignKeyName: "pace_identification_member_id_fkey";
|
|
3366
3373
|
columns: ["member_id"];
|
|
3367
3374
|
isOneToOne: false;
|
|
3368
3375
|
referencedRelation: "pace_member";
|
|
@@ -3370,6 +3377,53 @@ type Database = {
|
|
|
3370
3377
|
}
|
|
3371
3378
|
];
|
|
3372
3379
|
};
|
|
3380
|
+
pace_identification_type: {
|
|
3381
|
+
Row: {
|
|
3382
|
+
created_at: string | null;
|
|
3383
|
+
created_by: string | null;
|
|
3384
|
+
description: string | null;
|
|
3385
|
+
id: number;
|
|
3386
|
+
is_active: boolean | null;
|
|
3387
|
+
name: string;
|
|
3388
|
+
organisation_id: string;
|
|
3389
|
+
sort_order: number | null;
|
|
3390
|
+
updated_at: string | null;
|
|
3391
|
+
updated_by: string | null;
|
|
3392
|
+
};
|
|
3393
|
+
Insert: {
|
|
3394
|
+
created_at?: string | null;
|
|
3395
|
+
created_by?: string | null;
|
|
3396
|
+
description?: string | null;
|
|
3397
|
+
id?: never;
|
|
3398
|
+
is_active?: boolean | null;
|
|
3399
|
+
name: string;
|
|
3400
|
+
organisation_id: string;
|
|
3401
|
+
sort_order?: number | null;
|
|
3402
|
+
updated_at?: string | null;
|
|
3403
|
+
updated_by?: string | null;
|
|
3404
|
+
};
|
|
3405
|
+
Update: {
|
|
3406
|
+
created_at?: string | null;
|
|
3407
|
+
created_by?: string | null;
|
|
3408
|
+
description?: string | null;
|
|
3409
|
+
id?: never;
|
|
3410
|
+
is_active?: boolean | null;
|
|
3411
|
+
name?: string;
|
|
3412
|
+
organisation_id?: string;
|
|
3413
|
+
sort_order?: number | null;
|
|
3414
|
+
updated_at?: string | null;
|
|
3415
|
+
updated_by?: string | null;
|
|
3416
|
+
};
|
|
3417
|
+
Relationships: [
|
|
3418
|
+
{
|
|
3419
|
+
foreignKeyName: "pace_identification_type_organisation_id_fkey";
|
|
3420
|
+
columns: ["organisation_id"];
|
|
3421
|
+
isOneToOne: false;
|
|
3422
|
+
referencedRelation: "organisations";
|
|
3423
|
+
referencedColumns: ["id"];
|
|
3424
|
+
}
|
|
3425
|
+
];
|
|
3426
|
+
};
|
|
3373
3427
|
pace_member: {
|
|
3374
3428
|
Row: {
|
|
3375
3429
|
address_id: string | null;
|
|
@@ -3839,7 +3893,7 @@ type Database = {
|
|
|
3839
3893
|
}
|
|
3840
3894
|
];
|
|
3841
3895
|
};
|
|
3842
|
-
|
|
3896
|
+
pace_qualification: {
|
|
3843
3897
|
Row: {
|
|
3844
3898
|
created_at: string | null;
|
|
3845
3899
|
credential_id: string | null;
|
|
@@ -3881,14 +3935,14 @@ type Database = {
|
|
|
3881
3935
|
};
|
|
3882
3936
|
Relationships: [
|
|
3883
3937
|
{
|
|
3884
|
-
foreignKeyName: "
|
|
3938
|
+
foreignKeyName: "fk_pace_qualification_organisation_id";
|
|
3885
3939
|
columns: ["organisation_id"];
|
|
3886
3940
|
isOneToOne: false;
|
|
3887
3941
|
referencedRelation: "organisations";
|
|
3888
3942
|
referencedColumns: ["id"];
|
|
3889
3943
|
},
|
|
3890
3944
|
{
|
|
3891
|
-
foreignKeyName: "
|
|
3945
|
+
foreignKeyName: "pace_qualification_member_id_fkey";
|
|
3892
3946
|
columns: ["member_id"];
|
|
3893
3947
|
isOneToOne: false;
|
|
3894
3948
|
referencedRelation: "pace_member";
|
|
@@ -47,6 +47,7 @@ declare enum FileCategory {
|
|
|
47
47
|
* Options for uploading a file with a file reference
|
|
48
48
|
* @property pageContext - The page context where the file upload occurs (e.g., 'configuration', 'forms', 'applications')
|
|
49
49
|
* Used for context-aware permission checks. Required to check appropriate page-level permissions.
|
|
50
|
+
* @property event_id - Optional event ID for event-scoped permission checks. Required for event-based apps.
|
|
50
51
|
*/
|
|
51
52
|
interface FileUploadOptions {
|
|
52
53
|
table_name: string;
|
|
@@ -54,7 +55,9 @@ interface FileUploadOptions {
|
|
|
54
55
|
organisation_id: string;
|
|
55
56
|
app_id: AppId;
|
|
56
57
|
category: FileCategory;
|
|
58
|
+
folder: string;
|
|
57
59
|
pageContext: string;
|
|
60
|
+
event_id?: string;
|
|
58
61
|
is_public?: boolean;
|
|
59
62
|
custom_metadata?: Record<string, unknown>;
|
|
60
63
|
}
|
|
@@ -73,7 +76,6 @@ interface FileReferenceService {
|
|
|
73
76
|
}
|
|
74
77
|
interface StorageUploadOptions {
|
|
75
78
|
orgId: string;
|
|
76
|
-
category: FileCategory;
|
|
77
79
|
isPublic?: boolean;
|
|
78
80
|
customPath?: string;
|
|
79
81
|
}
|
package/dist/hooks.d.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
export { u as useToast } from './useToast-C8gR5ir4.js';
|
|
2
|
-
import {
|
|
3
|
-
export { O as OrganisationSecurityHook,
|
|
2
|
+
import { a as StorageUploadOptions, c as StorageUploadResult, e as StorageListOptions, f as StorageListResult, m as StorageFileInfo } from './usePublicRouteParams-CTDELQ7H.js';
|
|
3
|
+
export { O as OrganisationSecurityHook, K as UseAppConfigReturn, U as UseFormDialogOptions, h as UseFormDialogReturn, J as UseOrganisationPermissionsReturn, H as UsePublicEventLogoOptions, G as UsePublicEventLogoReturn, C as UsePublicEventOptions, B as UsePublicEventReturn, E as UsePublicFileDisplayOptions, D as UsePublicFileDisplayReturn, I as UsePublicRouteParamsReturn, o as clearPublicEventCache, r as clearPublicFileDisplayCache, v as clearPublicLogoCache, A as extractEventCodeFromPath, z as generatePublicRoutePath, p as getPublicEventCacheStats, s as getPublicFileDisplayCacheStats, w as getPublicLogoCacheStats, k as useAppConfig, l as useEventTheme, g as useFormDialog, i as useOrganisationPermissions, j as useOrganisationSecurity, n as usePublicEvent, y as usePublicEventCode, t as usePublicEventLogo, q as usePublicFileDisplay, x as usePublicRouteParams, u as useZodForm } from './usePublicRouteParams-CTDELQ7H.js';
|
|
4
4
|
import * as React$1 from 'react';
|
|
5
5
|
import { SortingState, ColumnFiltersState, ExpandedState } from '@tanstack/react-table';
|
|
6
|
+
import { d as DataRecord, g as PerformanceConfig, S as ServerSideConfig, C as ChunkingConfig, i as SearchIndexConfig, h as PaginationMode, k as ServerSideParams, l as ServerSideResponse, A as AutocompleteOptions, m as GooglePlaceAutocompletePrediction, P as ParsedAddress } from './types-Bwgl--Xo.js';
|
|
6
7
|
export { u as useComponentPerformance } from './useComponentPerformance-DE9l5RkL.js';
|
|
7
|
-
import { c as DataRecord, P as PerformanceConfig, S as ServerSideConfig, C as ChunkingConfig, g as SearchIndexConfig, f as PaginationMode, i as ServerSideParams, j as ServerSideResponse } from './types-DUyCRSTj.js';
|
|
8
8
|
import { SupabaseClient } from '@supabase/supabase-js';
|
|
9
|
-
import {
|
|
9
|
+
import { D as Database } from './database.generated-DI89OQeI.js';
|
|
10
|
+
import { F as FileCategory, a as FileReference } from './file-reference-D037xOFK.js';
|
|
10
11
|
import 'react-hook-form';
|
|
11
12
|
import 'zod';
|
|
12
13
|
import './event-CW5YB_2p.js';
|
|
13
14
|
import './core-CUElvH_C.js';
|
|
14
|
-
import './database.generated-CBmg2950.js';
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* @file Error Handling Stubs
|
|
@@ -227,6 +227,64 @@ declare function useDataTableState(options: UseDataTableStateOptions): {
|
|
|
227
227
|
};
|
|
228
228
|
};
|
|
229
229
|
|
|
230
|
+
/**
|
|
231
|
+
* @file Address Autocomplete Hook
|
|
232
|
+
* @package @jmruthers/pace-core
|
|
233
|
+
* @module Hooks/AddressAutocomplete
|
|
234
|
+
* @since 0.1.0
|
|
235
|
+
*
|
|
236
|
+
* Hook for managing Google Places API autocomplete functionality.
|
|
237
|
+
* Provides debounced input, caching, and address selection.
|
|
238
|
+
*/
|
|
239
|
+
|
|
240
|
+
interface UseAddressAutocompleteOptions {
|
|
241
|
+
/** Google Places API options */
|
|
242
|
+
autocompleteOptions?: AutocompleteOptions;
|
|
243
|
+
/** Debounce delay in milliseconds (default: 300) */
|
|
244
|
+
debounceDelay?: number;
|
|
245
|
+
/** Enable caching (default: true) */
|
|
246
|
+
cacheEnabled?: boolean;
|
|
247
|
+
/** Cache TTL configuration */
|
|
248
|
+
cacheTTL?: {
|
|
249
|
+
/** Autocomplete cache TTL in seconds (default: 3600 = 1 hour) */
|
|
250
|
+
autocomplete?: number;
|
|
251
|
+
/** Place details cache TTL in seconds (default: 86400 = 24 hours) */
|
|
252
|
+
placeDetails?: number;
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
interface UseAddressAutocompleteReturn {
|
|
256
|
+
/** Array of autocomplete suggestions */
|
|
257
|
+
suggestions: GooglePlaceAutocompletePrediction[];
|
|
258
|
+
/** Loading state */
|
|
259
|
+
isLoading: boolean;
|
|
260
|
+
/** Error state */
|
|
261
|
+
error: Error | null;
|
|
262
|
+
/** Select an address by place_id */
|
|
263
|
+
selectAddress: (placeId: string) => Promise<ParsedAddress | null>;
|
|
264
|
+
/** Get address by place_id (uses cache) */
|
|
265
|
+
getAddressByPlaceId: (placeId: string) => Promise<ParsedAddress | null>;
|
|
266
|
+
/** Clear suggestions */
|
|
267
|
+
clearSuggestions: () => void;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Hook for Google Places API autocomplete with caching
|
|
271
|
+
*
|
|
272
|
+
* @param apiKey - Google Places API key
|
|
273
|
+
* @param inputValue - Current input value
|
|
274
|
+
* @param options - Hook configuration options
|
|
275
|
+
* @returns Autocomplete state and functions
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* ```tsx
|
|
279
|
+
* const { suggestions, isLoading, selectAddress } = useAddressAutocomplete(
|
|
280
|
+
* apiKey,
|
|
281
|
+
* inputValue,
|
|
282
|
+
* { debounceDelay: 300, cacheEnabled: true }
|
|
283
|
+
* );
|
|
284
|
+
* ```
|
|
285
|
+
*/
|
|
286
|
+
declare function useAddressAutocomplete(apiKey: string, inputValue: string, options?: UseAddressAutocompleteOptions): UseAddressAutocompleteReturn;
|
|
287
|
+
|
|
230
288
|
/**
|
|
231
289
|
* @file useSecureDataAccess Hook
|
|
232
290
|
* @package @jmruthers/pace-core
|
|
@@ -359,6 +417,86 @@ declare function usePerformanceMonitor(componentName: string, enabled?: boolean,
|
|
|
359
417
|
endMeasurement: () => void;
|
|
360
418
|
};
|
|
361
419
|
|
|
420
|
+
/**
|
|
421
|
+
* Query Result Caching Hook
|
|
422
|
+
* @package @jmruthers/pace-core
|
|
423
|
+
* @module Hooks/QueryCache
|
|
424
|
+
* @since 2.0.0
|
|
425
|
+
*
|
|
426
|
+
* Provides in-memory caching for frequently accessed data to eliminate duplicate queries.
|
|
427
|
+
* Useful for caching user profiles, app pages, and other relatively static data.
|
|
428
|
+
*/
|
|
429
|
+
|
|
430
|
+
interface UseQueryCacheOptions {
|
|
431
|
+
/** Time to live in seconds (default: 300 = 5 minutes) */
|
|
432
|
+
ttl?: number;
|
|
433
|
+
/** Whether to enable caching (default: true) */
|
|
434
|
+
enabled?: boolean;
|
|
435
|
+
}
|
|
436
|
+
interface UseQueryCacheReturn {
|
|
437
|
+
/** Get cached query result or fetch if not cached */
|
|
438
|
+
getCachedQuery: <T>(table: string, filterKey: string, filterValue: string, fetchFn: () => Promise<T>, options?: UseQueryCacheOptions) => Promise<T>;
|
|
439
|
+
/** Invalidate a specific cached query */
|
|
440
|
+
invalidateQuery: (table: string, filterKey: string, filterValue: string) => void;
|
|
441
|
+
/** Clear all cached queries */
|
|
442
|
+
clearCache: () => void;
|
|
443
|
+
/** Get cache statistics */
|
|
444
|
+
getCacheStats: () => {
|
|
445
|
+
size: number;
|
|
446
|
+
keys: string[];
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Hook for query result caching
|
|
451
|
+
*
|
|
452
|
+
* Provides caching for frequently accessed data to eliminate duplicate queries.
|
|
453
|
+
* Automatically handles cache expiration and cleanup.
|
|
454
|
+
*
|
|
455
|
+
* @param supabase - Supabase client (optional, can be passed in fetchFn)
|
|
456
|
+
* @returns Query cache utilities
|
|
457
|
+
*
|
|
458
|
+
* @example
|
|
459
|
+
* ```tsx
|
|
460
|
+
* const { getCachedQuery } = useQueryCache(supabase);
|
|
461
|
+
*
|
|
462
|
+
* const person = await getCachedQuery(
|
|
463
|
+
* 'pace_person',
|
|
464
|
+
* 'user_id',
|
|
465
|
+
* userId,
|
|
466
|
+
* async () => {
|
|
467
|
+
* const { data } = await supabase
|
|
468
|
+
* .from('pace_person')
|
|
469
|
+
* .select('id, first_name, last_name, email')
|
|
470
|
+
* .eq('user_id', userId)
|
|
471
|
+
* .single();
|
|
472
|
+
* return data;
|
|
473
|
+
* },
|
|
474
|
+
* { ttl: 300 } // 5 minutes
|
|
475
|
+
* );
|
|
476
|
+
* ```
|
|
477
|
+
*/
|
|
478
|
+
declare function useQueryCache(supabase?: SupabaseClient<Database>): UseQueryCacheReturn;
|
|
479
|
+
/**
|
|
480
|
+
* Pre-configured cache helpers for common queries
|
|
481
|
+
*/
|
|
482
|
+
declare const queryCacheHelpers: {
|
|
483
|
+
/**
|
|
484
|
+
* Cache pace_person queries by user_id
|
|
485
|
+
* TTL: 5 minutes
|
|
486
|
+
*/
|
|
487
|
+
pacePersonByUserId: <T>(supabase: SupabaseClient<Database>, userId: string, fetchFn: () => Promise<T>) => Promise<T>;
|
|
488
|
+
/**
|
|
489
|
+
* Cache pace_member queries by person_id
|
|
490
|
+
* TTL: 5 minutes
|
|
491
|
+
*/
|
|
492
|
+
paceMemberByPersonId: <T>(supabase: SupabaseClient<Database>, personId: string, fetchFn: () => Promise<T>) => Promise<T>;
|
|
493
|
+
/**
|
|
494
|
+
* Cache rbac_app_pages queries by app_id
|
|
495
|
+
* TTL: 15 minutes (app pages are relatively static)
|
|
496
|
+
*/
|
|
497
|
+
rbacAppPagesByAppId: <T>(supabase: SupabaseClient<Database>, appId: string, fetchFn: () => Promise<T>) => Promise<T>;
|
|
498
|
+
};
|
|
499
|
+
|
|
362
500
|
/**
|
|
363
501
|
* @file File Display Hook (Authenticated)
|
|
364
502
|
* @package @jmruthers/pace-core
|
|
@@ -459,6 +597,83 @@ declare function getFileDisplayCacheStats(): {
|
|
|
459
597
|
*/
|
|
460
598
|
declare function invalidateFileDisplayCache(table_name: string, record_id: string, organisation_id: string, category?: FileCategory): void;
|
|
461
599
|
|
|
600
|
+
/**
|
|
601
|
+
* @file File URL Cache Hook
|
|
602
|
+
* @package @jmruthers/pace-core
|
|
603
|
+
* @module Hooks
|
|
604
|
+
*
|
|
605
|
+
* Centralized caching hook for file URLs to prevent duplicate requests
|
|
606
|
+
* and improve performance across components.
|
|
607
|
+
*
|
|
608
|
+
* Features:
|
|
609
|
+
* - TTL-based caching matching signed URL expiration (3600s)
|
|
610
|
+
* - Automatic cache cleanup
|
|
611
|
+
* - Supports both public and signed URLs
|
|
612
|
+
* - Thread-safe cache operations
|
|
613
|
+
*
|
|
614
|
+
* @example
|
|
615
|
+
* ```tsx
|
|
616
|
+
* import { useFileUrlCache } from '@jmruthers/pace-core';
|
|
617
|
+
*
|
|
618
|
+
* function MyComponent() {
|
|
619
|
+
* const { getUrl, setUrl, clearCache } = useFileUrlCache();
|
|
620
|
+
*
|
|
621
|
+
* const url = await getUrl(fileReference, supabase, organisationId);
|
|
622
|
+
* return <img src={url} alt="File" />;
|
|
623
|
+
* }
|
|
624
|
+
* ```
|
|
625
|
+
*/
|
|
626
|
+
|
|
627
|
+
interface UseFileUrlCacheReturn {
|
|
628
|
+
/**
|
|
629
|
+
* Get URL for a file reference, using cache if available
|
|
630
|
+
* @param fileReference - File reference to get URL for
|
|
631
|
+
* @param supabase - Supabase client instance
|
|
632
|
+
* @param organisationId - Organisation ID for signed URLs
|
|
633
|
+
* @param ttl - Time to live in milliseconds (default: 3600000 = 1 hour)
|
|
634
|
+
* @returns Promise resolving to URL string or null
|
|
635
|
+
*/
|
|
636
|
+
getUrl: (fileReference: FileReference, supabase: SupabaseClient, organisationId: string, ttl?: number) => Promise<string | null>;
|
|
637
|
+
/**
|
|
638
|
+
* Set URL in cache
|
|
639
|
+
* @param fileReference - File reference
|
|
640
|
+
* @param url - URL to cache
|
|
641
|
+
* @param ttl - Time to live in milliseconds (default: 3600000 = 1 hour)
|
|
642
|
+
*/
|
|
643
|
+
setUrl: (fileReference: FileReference, url: string, ttl?: number) => void;
|
|
644
|
+
/**
|
|
645
|
+
* Get URL from cache without generating if missing
|
|
646
|
+
* @param fileReference - File reference
|
|
647
|
+
* @returns Cached URL or null if not in cache or expired
|
|
648
|
+
*/
|
|
649
|
+
getCachedUrl: (fileReference: FileReference) => string | null;
|
|
650
|
+
/**
|
|
651
|
+
* Clear cache for a specific file reference
|
|
652
|
+
* @param fileReference - File reference to clear
|
|
653
|
+
*/
|
|
654
|
+
clearFile: (fileReference: FileReference) => void;
|
|
655
|
+
/**
|
|
656
|
+
* Clear all cached URLs
|
|
657
|
+
*/
|
|
658
|
+
clearCache: () => void;
|
|
659
|
+
/**
|
|
660
|
+
* Get cache statistics
|
|
661
|
+
*/
|
|
662
|
+
getCacheStats: () => {
|
|
663
|
+
size: number;
|
|
664
|
+
maxSize: number;
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* Hook for centralized file URL caching
|
|
669
|
+
*
|
|
670
|
+
* This hook provides a shared cache for file URLs across all components,
|
|
671
|
+
* preventing duplicate requests for the same file.
|
|
672
|
+
*
|
|
673
|
+
* @returns Cache operations and utilities
|
|
674
|
+
*/
|
|
675
|
+
declare function useFileUrlCache(): UseFileUrlCacheReturn;
|
|
676
|
+
|
|
462
677
|
/**
|
|
463
678
|
* React hook for storage operations
|
|
464
679
|
*/
|
|
@@ -505,4 +720,48 @@ declare function useFileUpload({ supabase, appName, orgId }: UseStorageOptions):
|
|
|
505
720
|
uploadError: string | null;
|
|
506
721
|
};
|
|
507
722
|
|
|
508
|
-
|
|
723
|
+
/**
|
|
724
|
+
* @file usePreventTabReload Hook
|
|
725
|
+
* @package @jmruthers/pace-core
|
|
726
|
+
* @module Hooks
|
|
727
|
+
* @since 0.6.0
|
|
728
|
+
*
|
|
729
|
+
* Prevents full page reloads when switching browser tabs.
|
|
730
|
+
* Handles browser back-forward cache (bfcache) restoration and tab visibility changes.
|
|
731
|
+
*/
|
|
732
|
+
interface UsePreventTabReloadOptions {
|
|
733
|
+
/**
|
|
734
|
+
* Whether to enable the prevention logic
|
|
735
|
+
* @default true
|
|
736
|
+
*/
|
|
737
|
+
enabled?: boolean;
|
|
738
|
+
/**
|
|
739
|
+
* Grace period in milliseconds to wait after tab becomes visible
|
|
740
|
+
* before allowing any potential reloads
|
|
741
|
+
* @default 2000
|
|
742
|
+
*/
|
|
743
|
+
gracePeriodMs?: number;
|
|
744
|
+
}
|
|
745
|
+
/**
|
|
746
|
+
* Hook to prevent full page reloads when switching browser tabs.
|
|
747
|
+
*
|
|
748
|
+
* This hook handles:
|
|
749
|
+
* - Browser back-forward cache (bfcache) restoration
|
|
750
|
+
* - Tab visibility changes
|
|
751
|
+
* - Prevents unwanted page reloads when returning to a tab
|
|
752
|
+
*
|
|
753
|
+
* @param options - Configuration options
|
|
754
|
+
*
|
|
755
|
+
* @example
|
|
756
|
+
* ```tsx
|
|
757
|
+
* import { usePreventTabReload } from '@jmruthers/pace-core';
|
|
758
|
+
*
|
|
759
|
+
* function MyComponent() {
|
|
760
|
+
* usePreventTabReload();
|
|
761
|
+
* // Component code...
|
|
762
|
+
* }
|
|
763
|
+
* ```
|
|
764
|
+
*/
|
|
765
|
+
declare function usePreventTabReload(options?: UsePreventTabReloadOptions): void;
|
|
766
|
+
|
|
767
|
+
export { type SecureDataAccessReturn, type UseAddressAutocompleteOptions, type UseAddressAutocompleteReturn, type UseDataTablePerformanceOptions, type UseDataTablePerformanceReturn, type UseFileDisplayOptions, type UseFileDisplayReturn, type UseFileUrlCacheReturn, type UsePreventTabReloadOptions, type UseQueryCacheOptions, type UseQueryCacheReturn, type UseStorageOptions, type UseStorageReturn, clearFileDisplayCache, getFileDisplayCacheStats, invalidateFileDisplayCache, queryCacheHelpers, useAddressAutocomplete, useDataTablePerformance, useDataTableState, useDebounce, useFileDisplay, useFileUpload, useFileUrlCache, useFocusManagement, useFocusTrap, useIsMobile, useKeyboardShortcuts, usePerformanceMonitor, usePreventTabReload, useQueryCache, useSecureDataAccess, useStorage };
|