@jmruthers/pace-core 0.5.102 → 0.5.103

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 (141) hide show
  1. package/dist/{DataTable-DXELRJIX.js → DataTable-EEDFYMJP.js} +2 -2
  2. package/dist/{PublicLoadingSpinner-Cvgk-V0F.d.ts → PublicLoadingSpinner-48ewSMKK.d.ts} +1 -96
  3. package/dist/{chunk-7ME4Z5OY.js → chunk-5SGBVBRU.js} +12 -148
  4. package/dist/chunk-5SGBVBRU.js.map +1 -0
  5. package/dist/{chunk-EVVRUGQ2.js → chunk-62AVH7CM.js} +78 -55
  6. package/dist/{chunk-EVVRUGQ2.js.map → chunk-62AVH7CM.js.map} +1 -1
  7. package/dist/{chunk-UDWTCBSH.js → chunk-SZWCMVTQ.js} +12 -175
  8. package/dist/chunk-SZWCMVTQ.js.map +1 -0
  9. package/dist/{chunk-SZWRW5FD.js → chunk-X33A4WWI.js} +23 -3
  10. package/dist/{chunk-SZWRW5FD.js.map → chunk-X33A4WWI.js.map} +1 -1
  11. package/dist/components.d.ts +1 -1
  12. package/dist/components.js +3 -9
  13. package/dist/components.js.map +1 -1
  14. package/dist/hooks.d.ts +1 -1
  15. package/dist/hooks.js +2 -9
  16. package/dist/hooks.js.map +1 -1
  17. package/dist/index.d.ts +2 -2
  18. package/dist/index.js +4 -16
  19. package/dist/index.js.map +1 -1
  20. package/dist/types.js +3 -3
  21. package/dist/{usePublicRouteParams-BwMR2uub.d.ts → usePublicRouteParams-BiXgKiYa.d.ts} +1 -117
  22. package/dist/utils.js +1 -1
  23. package/docs/api/classes/ColumnFactory.md +1 -1
  24. package/docs/api/classes/ErrorBoundary.md +1 -1
  25. package/docs/api/classes/InvalidScopeError.md +1 -1
  26. package/docs/api/classes/MissingUserContextError.md +1 -1
  27. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  28. package/docs/api/classes/PermissionDeniedError.md +1 -1
  29. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  30. package/docs/api/classes/RBACAuditManager.md +1 -1
  31. package/docs/api/classes/RBACCache.md +1 -1
  32. package/docs/api/classes/RBACEngine.md +1 -1
  33. package/docs/api/classes/RBACError.md +1 -1
  34. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  35. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  36. package/docs/api/classes/StorageUtils.md +1 -1
  37. package/docs/api/enums/FileCategory.md +1 -1
  38. package/docs/api/interfaces/AggregateConfig.md +1 -1
  39. package/docs/api/interfaces/ButtonProps.md +1 -1
  40. package/docs/api/interfaces/CardProps.md +1 -1
  41. package/docs/api/interfaces/ColorPalette.md +1 -1
  42. package/docs/api/interfaces/ColorShade.md +1 -1
  43. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  44. package/docs/api/interfaces/DataRecord.md +1 -1
  45. package/docs/api/interfaces/DataTableAction.md +1 -1
  46. package/docs/api/interfaces/DataTableColumn.md +1 -1
  47. package/docs/api/interfaces/DataTableProps.md +1 -1
  48. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  49. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  50. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  51. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  52. package/docs/api/interfaces/FileMetadata.md +1 -1
  53. package/docs/api/interfaces/FileReference.md +1 -1
  54. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  55. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  56. package/docs/api/interfaces/FileUploadProps.md +1 -1
  57. package/docs/api/interfaces/FooterProps.md +1 -1
  58. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  59. package/docs/api/interfaces/InputProps.md +1 -1
  60. package/docs/api/interfaces/LabelProps.md +1 -1
  61. package/docs/api/interfaces/LoginFormProps.md +1 -1
  62. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  63. package/docs/api/interfaces/NavigationContextType.md +1 -1
  64. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  65. package/docs/api/interfaces/NavigationItem.md +1 -1
  66. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  67. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  68. package/docs/api/interfaces/Organisation.md +1 -1
  69. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  70. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  71. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  72. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  73. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  74. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  75. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  76. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  77. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  78. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  79. package/docs/api/interfaces/PaletteData.md +1 -1
  80. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  81. package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
  82. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  83. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  84. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  85. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  86. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  87. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  88. package/docs/api/interfaces/RBACConfig.md +1 -1
  89. package/docs/api/interfaces/RBACLogger.md +1 -1
  90. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  91. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  92. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  93. package/docs/api/interfaces/RouteConfig.md +1 -1
  94. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  95. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  96. package/docs/api/interfaces/StorageConfig.md +1 -1
  97. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  98. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  99. package/docs/api/interfaces/StorageListOptions.md +1 -1
  100. package/docs/api/interfaces/StorageListResult.md +1 -1
  101. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  102. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  103. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  104. package/docs/api/interfaces/StyleImport.md +1 -1
  105. package/docs/api/interfaces/SwitchProps.md +1 -1
  106. package/docs/api/interfaces/ToastActionElement.md +1 -1
  107. package/docs/api/interfaces/ToastProps.md +1 -1
  108. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  109. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  110. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  111. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  112. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  113. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  114. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +1 -1
  115. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
  116. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  117. package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
  118. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  119. package/docs/api/interfaces/UserEventAccess.md +1 -1
  120. package/docs/api/interfaces/UserMenuProps.md +1 -1
  121. package/docs/api/interfaces/UserProfile.md +1 -1
  122. package/docs/api/modules.md +2 -150
  123. package/docs/implementation-guides/file-reference-system.md +31 -19
  124. package/package.json +1 -1
  125. package/src/components/DataTable/components/DataTableCore.tsx +23 -13
  126. package/src/components/DataTable/hooks/useTableColumns.ts +36 -6
  127. package/src/components/PublicLayout/PublicPageHeader.tsx +1 -1
  128. package/src/components/index.ts +0 -2
  129. package/src/hooks/public/index.ts +2 -4
  130. package/src/index.ts +0 -2
  131. package/src/utils/file-reference.ts +30 -2
  132. package/src/utils/storage/README.md +22 -20
  133. package/dist/chunk-7ME4Z5OY.js.map +0 -1
  134. package/dist/chunk-UDWTCBSH.js.map +0 -1
  135. package/docs/api/interfaces/UseEventLogoOptions.md +0 -74
  136. package/docs/api/interfaces/UseEventLogoReturn.md +0 -81
  137. package/docs/api/interfaces/UsePublicEventLogoOptions.md +0 -87
  138. package/docs/api/interfaces/UsePublicEventLogoReturn.md +0 -81
  139. package/src/hooks/public/usePublicEventLogo.ts +0 -295
  140. package/src/hooks/useEventLogo.ts +0 -316
  141. /package/dist/{DataTable-DXELRJIX.js.map → DataTable-EEDFYMJP.js.map} +0 -0
@@ -1,74 +0,0 @@
1
- [@jmruthers/pace-core - v0.5.102](../README.md) / [Exports](../modules.md) / UseEventLogoOptions
2
-
3
- # Interface: UseEventLogoOptions
4
-
5
- ## Table of contents
6
-
7
- ### Properties
8
-
9
- - [cacheTtl](UseEventLogoOptions.md#cachettl)
10
- - [enableCache](UseEventLogoOptions.md#enablecache)
11
- - [validateImage](UseEventLogoOptions.md#validateimage)
12
- - [generateFallbackText](UseEventLogoOptions.md#generatefallbacktext)
13
-
14
- ## Properties
15
-
16
- ### cacheTtl
17
-
18
- • `Optional` **cacheTtl**: `number`
19
-
20
- Cache TTL in milliseconds (default: 30 minutes)
21
-
22
- #### Defined in
23
-
24
- [packages/core/src/hooks/useEventLogo.ts:67](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/useEventLogo.ts#L67)
25
-
26
- ___
27
-
28
- ### enableCache
29
-
30
- • `Optional` **enableCache**: `boolean`
31
-
32
- Whether to enable caching (default: true)
33
-
34
- #### Defined in
35
-
36
- [packages/core/src/hooks/useEventLogo.ts:69](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/useEventLogo.ts#L69)
37
-
38
- ___
39
-
40
- ### validateImage
41
-
42
- • `Optional` **validateImage**: `boolean`
43
-
44
- Whether to validate image existence (default: true)
45
-
46
- #### Defined in
47
-
48
- [packages/core/src/hooks/useEventLogo.ts:71](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/useEventLogo.ts#L71)
49
-
50
- ___
51
-
52
- ### generateFallbackText
53
-
54
- • `Optional` **generateFallbackText**: (`eventName`: `string`) => `string`
55
-
56
- Custom fallback text generator
57
-
58
- #### Type declaration
59
-
60
- ▸ (`eventName`): `string`
61
-
62
- ##### Parameters
63
-
64
- | Name | Type |
65
- | :------ | :------ |
66
- | `eventName` | `string` |
67
-
68
- ##### Returns
69
-
70
- `string`
71
-
72
- #### Defined in
73
-
74
- [packages/core/src/hooks/useEventLogo.ts:73](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/useEventLogo.ts#L73)
@@ -1,81 +0,0 @@
1
- [@jmruthers/pace-core - v0.5.102](../README.md) / [Exports](../modules.md) / UseEventLogoReturn
2
-
3
- # Interface: UseEventLogoReturn
4
-
5
- ## Table of contents
6
-
7
- ### Properties
8
-
9
- - [logoUrl](UseEventLogoReturn.md#logourl)
10
- - [fallbackText](UseEventLogoReturn.md#fallbacktext)
11
- - [isLoading](UseEventLogoReturn.md#isloading)
12
- - [error](UseEventLogoReturn.md#error)
13
- - [refetch](UseEventLogoReturn.md#refetch)
14
-
15
- ## Properties
16
-
17
- ### logoUrl
18
-
19
- • **logoUrl**: ``null`` \| `string`
20
-
21
- The logo URL if available, null if not found or error
22
-
23
- #### Defined in
24
-
25
- [packages/core/src/hooks/useEventLogo.ts:54](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/useEventLogo.ts#L54)
26
-
27
- ___
28
-
29
- ### fallbackText
30
-
31
- • **fallbackText**: `string`
32
-
33
- Fallback text (event initials) if no logo is available
34
-
35
- #### Defined in
36
-
37
- [packages/core/src/hooks/useEventLogo.ts:56](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/useEventLogo.ts#L56)
38
-
39
- ___
40
-
41
- ### isLoading
42
-
43
- • **isLoading**: `boolean`
44
-
45
- Whether the logo is currently loading
46
-
47
- #### Defined in
48
-
49
- [packages/core/src/hooks/useEventLogo.ts:58](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/useEventLogo.ts#L58)
50
-
51
- ___
52
-
53
- ### error
54
-
55
- • **error**: ``null`` \| `Error`
56
-
57
- Any error that occurred during loading
58
-
59
- #### Defined in
60
-
61
- [packages/core/src/hooks/useEventLogo.ts:60](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/useEventLogo.ts#L60)
62
-
63
- ___
64
-
65
- ### refetch
66
-
67
- • **refetch**: () => `Promise`\<`void`\>
68
-
69
- Function to manually refetch the logo
70
-
71
- #### Type declaration
72
-
73
- ▸ (): `Promise`\<`void`\>
74
-
75
- ##### Returns
76
-
77
- `Promise`\<`void`\>
78
-
79
- #### Defined in
80
-
81
- [packages/core/src/hooks/useEventLogo.ts:62](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/useEventLogo.ts#L62)
@@ -1,87 +0,0 @@
1
- [@jmruthers/pace-core - v0.5.102](../README.md) / [Exports](../modules.md) / UsePublicEventLogoOptions
2
-
3
- # Interface: UsePublicEventLogoOptions
4
-
5
- ## Table of contents
6
-
7
- ### Properties
8
-
9
- - [cacheTtl](UsePublicEventLogoOptions.md#cachettl)
10
- - [enableCache](UsePublicEventLogoOptions.md#enablecache)
11
- - [validateImage](UsePublicEventLogoOptions.md#validateimage)
12
- - [generateFallbackText](UsePublicEventLogoOptions.md#generatefallbacktext)
13
- - [supabase](UsePublicEventLogoOptions.md#supabase)
14
-
15
- ## Properties
16
-
17
- ### cacheTtl
18
-
19
- • `Optional` **cacheTtl**: `number`
20
-
21
- Cache TTL in milliseconds (default: 30 minutes)
22
-
23
- #### Defined in
24
-
25
- [packages/core/src/hooks/public/usePublicEventLogo.ts:91](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicEventLogo.ts#L91)
26
-
27
- ___
28
-
29
- ### enableCache
30
-
31
- • `Optional` **enableCache**: `boolean`
32
-
33
- Whether to enable caching (default: true)
34
-
35
- #### Defined in
36
-
37
- [packages/core/src/hooks/public/usePublicEventLogo.ts:93](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicEventLogo.ts#L93)
38
-
39
- ___
40
-
41
- ### validateImage
42
-
43
- • `Optional` **validateImage**: `boolean`
44
-
45
- Whether to validate image existence (default: true)
46
-
47
- #### Defined in
48
-
49
- [packages/core/src/hooks/public/usePublicEventLogo.ts:95](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicEventLogo.ts#L95)
50
-
51
- ___
52
-
53
- ### generateFallbackText
54
-
55
- • `Optional` **generateFallbackText**: (`eventName`: `string`) => `string`
56
-
57
- Custom fallback text generator
58
-
59
- #### Type declaration
60
-
61
- ▸ (`eventName`): `string`
62
-
63
- ##### Parameters
64
-
65
- | Name | Type |
66
- | :------ | :------ |
67
- | `eventName` | `string` |
68
-
69
- ##### Returns
70
-
71
- `string`
72
-
73
- #### Defined in
74
-
75
- [packages/core/src/hooks/public/usePublicEventLogo.ts:97](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicEventLogo.ts#L97)
76
-
77
- ___
78
-
79
- ### supabase
80
-
81
- • **supabase**: `default`\<`Database`, ``"public"``, ``"public"``, `never`, {}\>
82
-
83
- Supabase client instance (required)
84
-
85
- #### Defined in
86
-
87
- [packages/core/src/hooks/public/usePublicEventLogo.ts:99](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicEventLogo.ts#L99)
@@ -1,81 +0,0 @@
1
- [@jmruthers/pace-core - v0.5.102](../README.md) / [Exports](../modules.md) / UsePublicEventLogoReturn
2
-
3
- # Interface: UsePublicEventLogoReturn
4
-
5
- ## Table of contents
6
-
7
- ### Properties
8
-
9
- - [logoUrl](UsePublicEventLogoReturn.md#logourl)
10
- - [fallbackText](UsePublicEventLogoReturn.md#fallbacktext)
11
- - [isLoading](UsePublicEventLogoReturn.md#isloading)
12
- - [error](UsePublicEventLogoReturn.md#error)
13
- - [refetch](UsePublicEventLogoReturn.md#refetch)
14
-
15
- ## Properties
16
-
17
- ### logoUrl
18
-
19
- • **logoUrl**: ``null`` \| `string`
20
-
21
- The logo URL if available, null if not found or error
22
-
23
- #### Defined in
24
-
25
- [packages/core/src/hooks/public/usePublicEventLogo.ts:78](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicEventLogo.ts#L78)
26
-
27
- ___
28
-
29
- ### fallbackText
30
-
31
- • **fallbackText**: `string`
32
-
33
- Fallback text (event initials) if no logo is available
34
-
35
- #### Defined in
36
-
37
- [packages/core/src/hooks/public/usePublicEventLogo.ts:80](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicEventLogo.ts#L80)
38
-
39
- ___
40
-
41
- ### isLoading
42
-
43
- • **isLoading**: `boolean`
44
-
45
- Whether the logo is currently loading
46
-
47
- #### Defined in
48
-
49
- [packages/core/src/hooks/public/usePublicEventLogo.ts:82](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicEventLogo.ts#L82)
50
-
51
- ___
52
-
53
- ### error
54
-
55
- • **error**: ``null`` \| `Error`
56
-
57
- Any error that occurred during loading
58
-
59
- #### Defined in
60
-
61
- [packages/core/src/hooks/public/usePublicEventLogo.ts:84](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicEventLogo.ts#L84)
62
-
63
- ___
64
-
65
- ### refetch
66
-
67
- • **refetch**: () => `Promise`\<`void`\>
68
-
69
- Function to manually refetch the logo
70
-
71
- #### Type declaration
72
-
73
- ▸ (): `Promise`\<`void`\>
74
-
75
- ##### Returns
76
-
77
- `Promise`\<`void`\>
78
-
79
- #### Defined in
80
-
81
- [packages/core/src/hooks/public/usePublicEventLogo.ts:86](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicEventLogo.ts#L86)
@@ -1,295 +0,0 @@
1
- /**
2
- * @file Public Event Logo Hook
3
- * @package @jmruthers/pace-core
4
- * @module Hooks/Public
5
- * @since 1.0.0
6
- *
7
- * A React hook for accessing public event logo URLs without authentication.
8
- * Provides logo URLs with fallback handling for public pages.
9
- *
10
- * Features:
11
- * - No authentication required
12
- * - Automatic fallback to event initials
13
- * - Caching for performance
14
- * - Error handling and loading states
15
- * - TypeScript support
16
- * - Image validation
17
- *
18
- * @example
19
- * ```tsx
20
- * import { usePublicEventLogo } from '@jmruthers/pace-core';
21
- *
22
- * function EventHeader() {
23
- * const { logoUrl, fallbackText, isLoading, error } = usePublicEventLogo(
24
- * eventId,
25
- * eventName,
26
- * organisationId
27
- * );
28
- *
29
- * if (isLoading) return <div>Loading logo...</div>;
30
- * if (error) return <div>Error: {error.message}</div>;
31
- *
32
- * return (
33
- * <div>
34
- * {logoUrl ? (
35
- * <img src={logoUrl} alt={`${eventName} logo`} />
36
- * ) : (
37
- * <div className="logo-fallback">{fallbackText}</div>
38
- * )}
39
- * </div>
40
- * );
41
- * }
42
- * ```
43
- *
44
- * @accessibility
45
- * - No direct accessibility concerns (hook)
46
- * - Enables accessible logo display with proper alt text
47
- * - Supports screen reader friendly fallbacks
48
- *
49
- * @security
50
- * - Only returns public-safe logo URLs
51
- * - Validates image existence before returning URL
52
- * - No sensitive information exposed
53
- * - Rate limiting applied at storage level
54
- *
55
- * @performance
56
- * - Built-in caching with TTL
57
- * - Image validation and optimization
58
- * - Minimal re-renders with stable references
59
- * - Lazy loading support
60
- *
61
- * @dependencies
62
- * - React 18+ - Hooks and effects
63
- * - @supabase/supabase-js - Storage integration
64
- * - Event types - Type definitions
65
- */
66
-
67
- import { useState, useEffect, useCallback, useMemo } from 'react';
68
- import type { SupabaseClient } from '@supabase/supabase-js';
69
- import type { Database } from '../../types/database';
70
- import { getPublicUrl } from '../../utils/storage/helpers';
71
- import { FileCategory } from '../../types/file-reference';
72
-
73
- // Simple in-memory cache for public data
74
- const publicDataCache = new Map<string, { data: any; timestamp: number; ttl: number }>();
75
-
76
- export interface UsePublicEventLogoReturn {
77
- /** The logo URL if available, null if not found or error */
78
- logoUrl: string | null;
79
- /** Fallback text (event initials) if no logo is available */
80
- fallbackText: string;
81
- /** Whether the logo is currently loading */
82
- isLoading: boolean;
83
- /** Any error that occurred during loading */
84
- error: Error | null;
85
- /** Function to manually refetch the logo */
86
- refetch: () => Promise<void>;
87
- }
88
-
89
- export interface UsePublicEventLogoOptions {
90
- /** Cache TTL in milliseconds (default: 30 minutes) */
91
- cacheTtl?: number;
92
- /** Whether to enable caching (default: true) */
93
- enableCache?: boolean;
94
- /** Whether to validate image existence (default: true) */
95
- validateImage?: boolean;
96
- /** Custom fallback text generator */
97
- generateFallbackText?: (eventName: string) => string;
98
- /** Supabase client instance (required) */
99
- supabase: SupabaseClient<Database>;
100
- }
101
-
102
- /**
103
- * Generate fallback text from event name (first letter of each word)
104
- */
105
- function defaultGenerateFallbackText(eventName: string): string {
106
- if (!eventName) return 'EV';
107
-
108
- return eventName
109
- .split(' ')
110
- .map(word => word.charAt(0).toUpperCase())
111
- .join('')
112
- .substring(0, 3); // Max 3 characters
113
- }
114
-
115
- /**
116
- * Hook for accessing public event logo URLs
117
- *
118
- * This hook provides access to event logo URLs without requiring
119
- * authentication. It includes fallback handling and image validation.
120
- *
121
- * @param eventId - The event ID to fetch logo for
122
- * @param eventName - The event name for fallback text generation
123
- * @param organisationId - The organisation ID for storage path
124
- * @param options - Configuration options for caching and behavior
125
- * @returns Object containing logo URL, fallback text, loading state, error, and refetch function
126
- */
127
- export function usePublicEventLogo(
128
- eventId: string | undefined,
129
- eventName: string | undefined,
130
- organisationId: string | undefined,
131
- options: UsePublicEventLogoOptions
132
- ): UsePublicEventLogoReturn {
133
- const {
134
- cacheTtl = 30 * 60 * 1000, // 30 minutes
135
- enableCache = true,
136
- validateImage = true,
137
- generateFallbackText = defaultGenerateFallbackText,
138
- supabase
139
- } = options;
140
-
141
- const [logoUrl, setLogoUrl] = useState<string | null>(null);
142
- const [isLoading, setIsLoading] = useState<boolean>(false);
143
- const [error, setError] = useState<Error | null>(null);
144
-
145
- // Generate fallback text
146
- const fallbackText = useMemo(() => {
147
- return eventName ? generateFallbackText(eventName) : 'EV';
148
- }, [eventName, generateFallbackText]);
149
-
150
- const fetchLogo = useCallback(async (): Promise<void> => {
151
- if (!eventId || !organisationId || !supabase) {
152
- setLogoUrl(null);
153
- setIsLoading(false);
154
- return;
155
- }
156
-
157
- // Validate UUID format for organisationId to prevent database errors
158
- const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
159
- if (!uuidRegex.test(organisationId)) {
160
- console.warn('[usePublicEventLogo] Invalid organisationId format (not a valid UUID):', organisationId);
161
- // Don't return early - let the database handle the validation
162
- // This allows for more graceful error handling
163
- }
164
-
165
- // Check cache first
166
- const cacheKey = `public_logo_${eventId}_${organisationId}`;
167
- if (enableCache) {
168
- const cached = publicDataCache.get(cacheKey);
169
- if (cached && Date.now() - cached.timestamp < cached.ttl) {
170
- setLogoUrl(cached.data);
171
- setIsLoading(false);
172
- setError(null);
173
- return;
174
- }
175
- }
176
-
177
- try {
178
- setIsLoading(true);
179
- setError(null);
180
-
181
- // Get event logo from file_references using new RPC function
182
- const { data, error: rpcError } = await (supabase as any)
183
- .rpc('data_file_reference_by_category_list', {
184
- p_table_name: 'event',
185
- p_record_id: eventId,
186
- p_category: FileCategory.EVENT_LOGOS,
187
- p_organisation_id: organisationId
188
- });
189
-
190
- if (rpcError) {
191
- throw new Error(rpcError.message || 'Failed to fetch logo');
192
- }
193
-
194
- if (!data || data.length === 0 || !data[0]?.file_path) {
195
- setLogoUrl(null);
196
- return;
197
- }
198
-
199
- // Get the file path from the RPC response
200
- const logoPath = data[0].file_path;
201
- const isPublic = data[0].is_public ?? true; // Event logos should be public
202
-
203
- // Generate public URL using bucket-aware helper (public-files bucket for public files)
204
- const logoUrl = getPublicUrl(supabase, logoPath, isPublic);
205
-
206
- // Validate image existence if requested
207
- if (validateImage) {
208
- try {
209
- const response = await fetch(logoUrl, { method: 'HEAD' });
210
- if (!response.ok) {
211
- console.warn('[usePublicEventLogo] Logo URL not accessible:', logoUrl);
212
- setLogoUrl(null);
213
- return;
214
- }
215
- } catch (fetchError) {
216
- console.warn('[usePublicEventLogo] Error validating logo URL:', fetchError);
217
- setLogoUrl(null);
218
- return;
219
- }
220
- }
221
-
222
- setLogoUrl(logoUrl);
223
-
224
- // Cache the result
225
- if (enableCache) {
226
- publicDataCache.set(cacheKey, {
227
- data: logoUrl,
228
- timestamp: Date.now(),
229
- ttl: cacheTtl
230
- });
231
- }
232
-
233
- } catch (err) {
234
- console.error('[usePublicEventLogo] Error fetching logo:', err);
235
- const error = err instanceof Error ? err : new Error('Unknown error occurred');
236
- setError(error);
237
- setLogoUrl(null);
238
- } finally {
239
- setIsLoading(false);
240
- }
241
- }, [eventId, organisationId, supabase, cacheTtl, enableCache, validateImage]);
242
-
243
- // Fetch logo when parameters change
244
- useEffect(() => {
245
- if (eventId && organisationId) {
246
- fetchLogo();
247
- } else {
248
- setLogoUrl(null);
249
- setIsLoading(false);
250
- setError(null);
251
- }
252
- }, [fetchLogo, eventId, organisationId]);
253
-
254
- const refetch = useCallback(async (): Promise<void> => {
255
- if (!eventId || !organisationId) return;
256
-
257
- // Clear cache for this logo
258
- if (enableCache) {
259
- const cacheKey = `public_logo_${eventId}_${organisationId}`;
260
- publicDataCache.delete(cacheKey);
261
- }
262
- await fetchLogo();
263
- }, [fetchLogo, eventId, organisationId, enableCache]);
264
-
265
- return {
266
- logoUrl,
267
- fallbackText,
268
- isLoading,
269
- error,
270
- refetch
271
- };
272
- }
273
-
274
- /**
275
- * Clear all cached public logo data
276
- * Useful for testing or when you need to force refresh all data
277
- */
278
- export function clearPublicLogoCache(): void {
279
- for (const [key] of publicDataCache) {
280
- if (key.startsWith('public_logo_')) {
281
- publicDataCache.delete(key);
282
- }
283
- }
284
- }
285
-
286
- /**
287
- * Get cache statistics for debugging
288
- */
289
- export function getPublicLogoCacheStats(): { size: number; keys: string[] } {
290
- const keys = Array.from(publicDataCache.keys()).filter(key => key.startsWith('public_logo_'));
291
- return {
292
- size: keys.length,
293
- keys
294
- };
295
- }