@jmruthers/pace-core 0.5.60 → 0.5.62
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/README.md +2 -2
- package/dist/{DataTable-5M6MV2VY.js → DataTable-7BER7PDS.js} +6 -6
- package/dist/{DataTable-DqDDvBfI.d.ts → DataTable-D15XipLZ.d.ts} +7 -0
- package/dist/{PublicLoadingSpinner-SL8WaQN7.d.ts → PublicLoadingSpinner-CXJ-W9wZ.d.ts} +3 -27
- package/dist/{chunk-SFMRBGGK.js → chunk-2LPYEFXI.js} +136 -137
- package/dist/chunk-2LPYEFXI.js.map +1 -0
- package/dist/{chunk-XMTHMOOM.js → chunk-BTCA3ENN.js} +4 -4
- package/dist/{chunk-ESXTFEE6.js → chunk-C7GUF747.js} +3 -3
- package/dist/{chunk-W7PPXKTZ.js → chunk-CKNY7HYS.js} +2 -2
- package/dist/{chunk-5MLDIGHB.js → chunk-FVDOEGGG.js} +3 -3
- package/dist/{chunk-NQ4TOOO6.js → chunk-L3RV2ALE.js} +1 -1
- package/dist/chunk-L3RV2ALE.js.map +1 -0
- package/dist/{chunk-NMNDTCOR.js → chunk-QVEOQVD4.js} +3 -3
- package/dist/{chunk-XDXG6QVH.js → chunk-S66AJVI2.js} +13 -6
- package/dist/chunk-S66AJVI2.js.map +1 -0
- package/dist/{chunk-E4FPK232.js → chunk-T2MQY57J.js} +2 -2
- package/dist/{chunk-ITPVFKDH.js → chunk-T6HVDA24.js} +129 -12
- package/dist/chunk-T6HVDA24.js.map +1 -0
- package/dist/{chunk-STT7INZR.js → chunk-ULBI5JGB.js} +2 -1
- package/dist/{chunk-CGSYCF2W.js → chunk-VTJ5HCZB.js} +2 -2
- package/dist/components.d.ts +81 -4
- package/dist/components.js +258 -11
- package/dist/components.js.map +1 -1
- package/dist/hooks.d.ts +2 -61
- package/dist/hooks.js +31 -146
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.js +14 -14
- package/dist/index.js.map +1 -1
- package/dist/providers.js +4 -4
- package/dist/rbac/index.js +6 -6
- package/dist/styles/index.d.ts +1 -1
- package/dist/styles/index.js +1 -1
- package/dist/types.js +1 -1
- package/dist/useToast-Bm6TnSK-.d.ts +63 -0
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +1 -1
- package/docs/README.md +1 -1
- package/docs/api/README.md +2 -2
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/InvalidScopeError.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/PublicErrorBoundary.md +1 -1
- package/docs/api/classes/RBACAuditManager.md +1 -1
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +1 -1
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +1 -1
- package/docs/api/classes/SecureSupabaseClient.md +1 -1
- package/docs/api/classes/StorageUtils.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +1 -1
- package/docs/api/interfaces/ButtonProps.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/DataAccessRecord.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 +44 -18
- package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
- package/docs/api/interfaces/EmptyStateConfig.md +1 -1
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/EventContextType.md +1 -1
- package/docs/api/interfaces/EventLogoProps.md +1 -1
- package/docs/api/interfaces/EventProviderProps.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadProps.md +1 -1
- package/docs/api/interfaces/FooterProps.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/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 +1 -1
- package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
- package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
- 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/RBACConfig.md +1 -1
- package/docs/api/interfaces/RBACContextType.md +1 -1
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RBACProviderProps.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +1 -1
- package/docs/api/interfaces/RouteConfig.md +1 -1
- package/docs/api/interfaces/SecureDataContextType.md +1 -1
- package/docs/api/interfaces/SecureDataProviderProps.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/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/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
- 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/UsePublicRouteParamsReturn.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 +38 -53
- package/docs/architecture/README.md +1 -3
- package/docs/consuming-app-example.md +3 -3
- package/docs/consuming-app-vite-config.md +1 -1
- package/docs/documentation-style-checklist.md +2 -2
- package/docs/getting-started/examples/basic-auth-app.md +2 -2
- package/docs/getting-started/installation.md +2 -2
- package/docs/getting-started/quick-start.md +1 -1
- package/docs/implementation-guides/data-tables.md +67 -0
- package/docs/migration/README.md +6 -6
- package/docs/migration/quick-migration-guide.md +3 -3
- package/docs/migration/v0.4.15-tailwind-scanning.md +1 -1
- package/docs/migration/v0.4.16-css-first-approach.md +1 -1
- package/docs/migration/v0.4.17-source-path-fix.md +4 -4
- package/docs/migration-guide.md +2 -2
- package/docs/quick-reference.md +4 -4
- package/docs/styles/README.md +3 -3
- package/docs/troubleshooting/README.md +2 -2
- package/docs/troubleshooting/common-issues.md +1 -1
- package/docs/troubleshooting/styling-issues.md +2 -2
- package/docs/troubleshooting/tailwind-content-scanning.md +2 -2
- package/docs/usage.md +2 -2
- package/package.json +2 -6
- package/src/components/DataTable/DataTable.tsx +13 -0
- package/src/components/DataTable/__tests__/DataTable.default-state.test.tsx +414 -0
- package/src/components/DataTable/components/DataTableCore.tsx +19 -2
- package/src/components/DataTable/types.ts +9 -0
- package/src/components/Dialog/examples/__tests__/SmartDialogExample.unit.test.tsx +151 -0
- package/src/components/Dialog/utils/__tests__/safeHtml.unit.test.ts +611 -0
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.accessibility.test.tsx +287 -0
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.integration.test.tsx +861 -0
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.performance.test.tsx +628 -0
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +777 -0
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.unit.test.tsx +901 -0
- package/src/components/Toast/Toast.test.tsx +51 -21
- package/src/components/Toast/Toast.tsx +13 -35
- package/src/components/Toast/index.ts +2 -1
- package/src/components/index.ts +15 -1
- package/src/hooks/useFileReference.ts +37 -0
- package/src/index.ts +1 -1
- package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +1 -1
- package/src/rbac/__tests__/rbac-engine-simplified.test.ts +1 -1
- package/src/styles/core.css +32 -37
- package/src/styles/index.ts +1 -1
- package/dist/chunk-ITPVFKDH.js.map +0 -1
- package/dist/chunk-NQ4TOOO6.js.map +0 -1
- package/dist/chunk-SFMRBGGK.js.map +0 -1
- package/dist/chunk-XDXG6QVH.js.map +0 -1
- package/dist/styles/core.css +0 -242
- package/dist/styles/fonts/georama-italic.woff2 +0 -0
- package/dist/styles/fonts/georama.woff2 +0 -0
- package/dist/styles/fonts/open-sans-italic.woff2 +0 -0
- package/dist/styles/fonts/open-sans.woff2 +0 -0
- package/dist/styles/fonts/reddit-mono.woff2 +0 -0
- /package/dist/{DataTable-5M6MV2VY.js.map → DataTable-7BER7PDS.js.map} +0 -0
- /package/dist/{chunk-XMTHMOOM.js.map → chunk-BTCA3ENN.js.map} +0 -0
- /package/dist/{chunk-ESXTFEE6.js.map → chunk-C7GUF747.js.map} +0 -0
- /package/dist/{chunk-W7PPXKTZ.js.map → chunk-CKNY7HYS.js.map} +0 -0
- /package/dist/{chunk-5MLDIGHB.js.map → chunk-FVDOEGGG.js.map} +0 -0
- /package/dist/{chunk-NMNDTCOR.js.map → chunk-QVEOQVD4.js.map} +0 -0
- /package/dist/{chunk-E4FPK232.js.map → chunk-T2MQY57J.js.map} +0 -0
- /package/dist/{chunk-STT7INZR.js.map → chunk-ULBI5JGB.js.map} +0 -0
- /package/dist/{chunk-CGSYCF2W.js.map → chunk-VTJ5HCZB.js.map} +0 -0
|
@@ -16,24 +16,15 @@ import {
|
|
|
16
16
|
ToastViewport,
|
|
17
17
|
ToastProvider,
|
|
18
18
|
Toaster,
|
|
19
|
-
useToast,
|
|
20
19
|
ToastProps
|
|
21
20
|
} from './Toast';
|
|
21
|
+
import { useToast, reset } from '../../hooks/useToast';
|
|
22
22
|
import { renderWithProviders } from '../../__tests__/helpers/test-utils';
|
|
23
23
|
|
|
24
|
-
// Mock console methods to avoid noise in tests
|
|
25
|
-
const originalConsoleLog = console.log;
|
|
26
|
-
|
|
27
24
|
describe('Toast Component System', () => {
|
|
28
25
|
beforeEach(() => {
|
|
29
26
|
vi.clearAllMocks();
|
|
30
|
-
//
|
|
31
|
-
console.log = vi.fn();
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
afterEach(() => {
|
|
35
|
-
// Restore console methods
|
|
36
|
-
console.log = originalConsoleLog;
|
|
27
|
+
reset(); // Reset toast state between tests
|
|
37
28
|
});
|
|
38
29
|
|
|
39
30
|
// ToastProvider component tests
|
|
@@ -126,6 +117,30 @@ describe('Toast Component System', () => {
|
|
|
126
117
|
|
|
127
118
|
expect(screen.getByTestId('toast-viewport')).toBeInTheDocument();
|
|
128
119
|
});
|
|
120
|
+
|
|
121
|
+
it('renders toasts when they exist in state', () => {
|
|
122
|
+
// Create a test component that adds a toast
|
|
123
|
+
function TestComponent() {
|
|
124
|
+
const { toast } = useToast();
|
|
125
|
+
|
|
126
|
+
React.useEffect(() => {
|
|
127
|
+
toast({
|
|
128
|
+
title: 'Test Toast',
|
|
129
|
+
description: 'This is a test toast'
|
|
130
|
+
});
|
|
131
|
+
}, [toast]);
|
|
132
|
+
|
|
133
|
+
return <Toaster />;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
renderWithProviders(<TestComponent />);
|
|
137
|
+
|
|
138
|
+
// Wait for the toast to appear
|
|
139
|
+
waitFor(() => {
|
|
140
|
+
expect(screen.getByText('Test Toast')).toBeInTheDocument();
|
|
141
|
+
expect(screen.getByText('This is a test toast')).toBeInTheDocument();
|
|
142
|
+
});
|
|
143
|
+
});
|
|
129
144
|
});
|
|
130
145
|
|
|
131
146
|
// useToast hook tests
|
|
@@ -148,42 +163,57 @@ describe('Toast Component System', () => {
|
|
|
148
163
|
expect(screen.getByText('Dismiss')).toBeInTheDocument();
|
|
149
164
|
});
|
|
150
165
|
|
|
151
|
-
it('
|
|
166
|
+
it('adds toast to state when triggered', async () => {
|
|
152
167
|
const user = userEvent.setup();
|
|
153
168
|
|
|
154
169
|
function TestComponent() {
|
|
155
|
-
const { toast } = useToast();
|
|
170
|
+
const { toast, toasts } = useToast();
|
|
156
171
|
|
|
157
172
|
return (
|
|
158
|
-
<
|
|
173
|
+
<div>
|
|
174
|
+
<button onClick={() => toast({ title: 'Test Toast' })}>Show Toast</button>
|
|
175
|
+
<div data-testid="toast-count">{toasts.length}</div>
|
|
176
|
+
</div>
|
|
159
177
|
);
|
|
160
178
|
}
|
|
161
179
|
|
|
162
180
|
renderWithProviders(<TestComponent />);
|
|
163
181
|
|
|
182
|
+
expect(screen.getByTestId('toast-count')).toHaveTextContent('0');
|
|
183
|
+
|
|
164
184
|
const button = screen.getByText('Show Toast');
|
|
165
185
|
await user.click(button);
|
|
166
186
|
|
|
167
|
-
expect(
|
|
187
|
+
expect(screen.getByTestId('toast-count')).toHaveTextContent('1');
|
|
168
188
|
});
|
|
169
189
|
|
|
170
|
-
it('
|
|
190
|
+
it('dismisses toast when dismiss is called', async () => {
|
|
171
191
|
const user = userEvent.setup();
|
|
172
192
|
|
|
173
193
|
function TestComponent() {
|
|
174
|
-
const { dismiss } = useToast();
|
|
194
|
+
const { toast, dismiss, toasts } = useToast();
|
|
175
195
|
|
|
176
196
|
return (
|
|
177
|
-
<
|
|
197
|
+
<div>
|
|
198
|
+
<button onClick={() => toast({ title: 'Test Toast' })}>Show Toast</button>
|
|
199
|
+
<button onClick={() => dismiss()}>Dismiss</button>
|
|
200
|
+
<div data-testid="toast-count">{toasts.length}</div>
|
|
201
|
+
</div>
|
|
178
202
|
);
|
|
179
203
|
}
|
|
180
204
|
|
|
181
205
|
renderWithProviders(<TestComponent />);
|
|
182
206
|
|
|
183
|
-
const
|
|
184
|
-
await user.click(
|
|
207
|
+
const showButton = screen.getByText('Show Toast');
|
|
208
|
+
await user.click(showButton);
|
|
209
|
+
|
|
210
|
+
expect(screen.getByTestId('toast-count')).toHaveTextContent('1');
|
|
211
|
+
|
|
212
|
+
const dismissButton = screen.getByText('Dismiss');
|
|
213
|
+
await user.click(dismissButton);
|
|
185
214
|
|
|
186
|
-
|
|
215
|
+
// Toast should be marked as closed but still in array
|
|
216
|
+
expect(screen.getByTestId('toast-count')).toHaveTextContent('1');
|
|
187
217
|
});
|
|
188
218
|
});
|
|
189
219
|
|
|
@@ -89,6 +89,7 @@ import * as React from "react"
|
|
|
89
89
|
import * as ToastPrimitives from "@radix-ui/react-toast"
|
|
90
90
|
import { X } from "lucide-react"
|
|
91
91
|
import { cn } from "../../utils/cn"
|
|
92
|
+
import { useToast } from "../../hooks/useToast"
|
|
92
93
|
|
|
93
94
|
const ToastProvider = ToastPrimitives.Provider
|
|
94
95
|
|
|
@@ -268,45 +269,12 @@ export interface ToastProps extends React.ComponentPropsWithoutRef<typeof ToastP
|
|
|
268
269
|
|
|
269
270
|
export interface ToastActionElement extends React.ReactElement<typeof ToastAction> {}
|
|
270
271
|
|
|
271
|
-
// Simple useToast hook
|
|
272
|
-
/**
|
|
273
|
-
* useToast hook
|
|
274
|
-
* Hook for managing toast notifications
|
|
275
|
-
*
|
|
276
|
-
* @returns Object with toast and dismiss functions
|
|
277
|
-
*
|
|
278
|
-
* @example
|
|
279
|
-
* ```tsx
|
|
280
|
-
* const { toast, dismiss } = useToast();
|
|
281
|
-
*
|
|
282
|
-
* // Show a toast
|
|
283
|
-
* toast({
|
|
284
|
-
* title: "Success!",
|
|
285
|
-
* description: "Your changes have been saved."
|
|
286
|
-
* });
|
|
287
|
-
*
|
|
288
|
-
* // Dismiss all toasts
|
|
289
|
-
* dismiss();
|
|
290
|
-
* ```
|
|
291
|
-
*/
|
|
292
|
-
export function useToast() {
|
|
293
|
-
return {
|
|
294
|
-
toast: (props: any) => {
|
|
295
|
-
console.log('Toast:', props);
|
|
296
|
-
},
|
|
297
|
-
dismiss: () => {
|
|
298
|
-
console.log('Toast dismissed');
|
|
299
|
-
}
|
|
300
|
-
};
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
// Simple Toaster component
|
|
304
272
|
/**
|
|
305
273
|
* Toaster component
|
|
306
|
-
* Container component that
|
|
274
|
+
* Container component that renders actual toast notifications
|
|
307
275
|
* Should be placed at the root of your application
|
|
308
276
|
*
|
|
309
|
-
* @returns JSX.Element - The toast provider with viewport
|
|
277
|
+
* @returns JSX.Element - The toast provider with viewport and rendered toasts
|
|
310
278
|
*
|
|
311
279
|
* @example
|
|
312
280
|
* ```tsx
|
|
@@ -321,9 +289,19 @@ export function useToast() {
|
|
|
321
289
|
* ```
|
|
322
290
|
*/
|
|
323
291
|
export function Toaster() {
|
|
292
|
+
const { toasts } = useToast();
|
|
293
|
+
|
|
324
294
|
return (
|
|
325
295
|
<ToastProvider data-testid="toast-provider">
|
|
326
296
|
<ToastViewport />
|
|
297
|
+
{toasts.map((toast: any) => (
|
|
298
|
+
<Toast key={toast.id} {...toast}>
|
|
299
|
+
{toast.title && <ToastTitle>{toast.title}</ToastTitle>}
|
|
300
|
+
{toast.description && <ToastDescription>{toast.description}</ToastDescription>}
|
|
301
|
+
{toast.action && toast.action}
|
|
302
|
+
<ToastClose onClick={toast.dismiss} />
|
|
303
|
+
</Toast>
|
|
304
|
+
))}
|
|
327
305
|
</ToastProvider>
|
|
328
306
|
);
|
|
329
307
|
}
|
package/src/components/index.ts
CHANGED
|
@@ -119,7 +119,6 @@ export {
|
|
|
119
119
|
ToastTitle,
|
|
120
120
|
ToastDescription,
|
|
121
121
|
ToastClose,
|
|
122
|
-
useToast,
|
|
123
122
|
} from './Toast';
|
|
124
123
|
export type { ToastActionElement, ToastProps } from './Toast';
|
|
125
124
|
|
|
@@ -238,6 +237,16 @@ export { PasswordResetForm } from './PasswordReset';
|
|
|
238
237
|
export { FileUpload } from './FileUpload';
|
|
239
238
|
export type { FileUploadProps } from './FileUpload';
|
|
240
239
|
|
|
240
|
+
export { FileDisplay } from './FileDisplay';
|
|
241
|
+
export type { FileDisplayProps } from './FileDisplay';
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
// ============================================================================
|
|
245
|
+
// TYPES
|
|
246
|
+
// ============================================================================
|
|
247
|
+
|
|
248
|
+
export { FileCategory } from '../types/file-reference';
|
|
249
|
+
export type { FileReference, FileMetadata, FileUploadOptions } from '../types/file-reference';
|
|
241
250
|
|
|
242
251
|
// ============================================================================
|
|
243
252
|
// HOOKS
|
|
@@ -246,6 +255,11 @@ export type { FileUploadProps } from './FileUpload';
|
|
|
246
255
|
export { useStorage, useFileUpload } from '../hooks/useStorage';
|
|
247
256
|
export type { UseStorageOptions, UseStorageReturn } from '../hooks/useStorage';
|
|
248
257
|
|
|
258
|
+
export { useFileReference, useFileReferenceForRecord } from '../hooks/useFileReference';
|
|
259
|
+
export type { UseFileReferenceOptions, UseFileReferenceReturn, UseFileReferenceForRecordReturn } from '../hooks/useFileReference';
|
|
260
|
+
|
|
261
|
+
export { useToast } from '../hooks/useToast';
|
|
262
|
+
|
|
249
263
|
// RBAC Components - Use the new RBAC system
|
|
250
264
|
// For RBAC functionality, import from @jmruthers/pace-core/rbac
|
|
251
265
|
// export { PermissionGuard, AccessLevelGuard } from '@jmruthers/pace-core/rbac';
|
|
@@ -230,3 +230,40 @@ export function useFileReferenceForRecord(
|
|
|
230
230
|
clearError
|
|
231
231
|
};
|
|
232
232
|
}
|
|
233
|
+
|
|
234
|
+
// Type definitions for the hooks
|
|
235
|
+
export type UseFileReferenceOptions = {
|
|
236
|
+
table_name: string;
|
|
237
|
+
record_id: string;
|
|
238
|
+
organisation_id: string;
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
export type UseFileReferenceReturn = {
|
|
242
|
+
isLoading: boolean;
|
|
243
|
+
error: string | null;
|
|
244
|
+
uploadFile: (options: FileUploadOptions, file: File) => Promise<FileUploadResult | null>;
|
|
245
|
+
getFileReference: (table_name: string, record_id: string, organisation_id: string) => Promise<FileReference | null>;
|
|
246
|
+
getFileUrl: (table_name: string, record_id: string, organisation_id: string) => Promise<string | null>;
|
|
247
|
+
getSignedUrl: (table_name: string, record_id: string, organisation_id: string, expires_in?: number) => Promise<string | null>;
|
|
248
|
+
updateFileReference: (id: string, updates: Partial<FileReference>) => Promise<FileReference | null>;
|
|
249
|
+
deleteFileReference: (table_name: string, record_id: string, organisation_id: string, delete_file?: boolean) => Promise<boolean>;
|
|
250
|
+
listFileReferences: (table_name: string, record_id: string, organisation_id: string) => Promise<FileReference[]>;
|
|
251
|
+
getFileCount: (table_name: string, record_id: string, organisation_id: string) => Promise<number>;
|
|
252
|
+
clearError: () => void;
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
export type UseFileReferenceForRecordReturn = {
|
|
256
|
+
isLoading: boolean;
|
|
257
|
+
error: string | null;
|
|
258
|
+
fileUrl: string | null;
|
|
259
|
+
fileReference: FileReference | null;
|
|
260
|
+
fileReferences: FileReference[];
|
|
261
|
+
fileCount: number;
|
|
262
|
+
loadFileReference: () => Promise<FileReference | null>;
|
|
263
|
+
loadFileUrl: () => Promise<string | null>;
|
|
264
|
+
loadFileReferences: () => Promise<FileReference[]>;
|
|
265
|
+
loadFileCount: () => Promise<number>;
|
|
266
|
+
deleteFile: (delete_file?: boolean) => Promise<boolean>;
|
|
267
|
+
updateFileReference: (id: string, updates: Partial<FileReference>) => Promise<FileReference | null>;
|
|
268
|
+
clearError: () => void;
|
|
269
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -105,8 +105,8 @@ export {
|
|
|
105
105
|
ToastTitle,
|
|
106
106
|
ToastDescription,
|
|
107
107
|
ToastClose,
|
|
108
|
-
useToast,
|
|
109
108
|
} from './components/Toast/Toast';
|
|
109
|
+
export { useToast } from './hooks/useToast';
|
|
110
110
|
export type { ToastActionElement, ToastProps } from './components/Toast/Toast';
|
|
111
111
|
|
|
112
112
|
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider, TooltipRoot } from './components/Tooltip/Tooltip';
|
|
@@ -205,7 +205,7 @@ describe('RBACEngine - Core Logic Tests', () => {
|
|
|
205
205
|
return Promise.resolve({
|
|
206
206
|
data: [
|
|
207
207
|
{
|
|
208
|
-
permission_type: 'read',
|
|
208
|
+
permission_type: 'read:page.organisation',
|
|
209
209
|
role_name: 'org_admin',
|
|
210
210
|
has_permission: true,
|
|
211
211
|
granted_at: '2023-01-01T00:00:00Z'
|
|
@@ -93,7 +93,7 @@ describe('RBACEngine - Simplified Tests', () => {
|
|
|
93
93
|
if (funcName === 'rbac_permissions_get') {
|
|
94
94
|
return Promise.resolve({
|
|
95
95
|
data: [{
|
|
96
|
-
permission_type: 'read',
|
|
96
|
+
permission_type: 'read:page.users',
|
|
97
97
|
resource_name: 'users',
|
|
98
98
|
role_name: 'org_admin',
|
|
99
99
|
has_permission: true,
|
package/src/styles/core.css
CHANGED
|
@@ -1,39 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
/* core.css export config to incliude in node_modules\@jmruthers\pace-core\package.json
|
|
2
|
+
"./styles/core.css": "./src/styles/core.css",
|
|
3
|
+
*/
|
|
2
4
|
|
|
3
5
|
@theme {
|
|
4
|
-
/* reset all color variables and fonts */
|
|
5
|
-
--color-*: initial;
|
|
6
6
|
--font-sans: "Open Sans", sans-serif;
|
|
7
7
|
--font-serif: "Open Sans", sans-serif;
|
|
8
8
|
--font-mono: "Reddit Mono", monospace;
|
|
9
9
|
}
|
|
10
|
-
@theme static {
|
|
11
|
-
--app-width: 90rem;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
@theme inline {
|
|
15
|
-
/* Semantic token mapping */
|
|
16
|
-
--color-border: var(--color-main-500);
|
|
17
|
-
--color-input: var(--color-sec-200);
|
|
18
|
-
--color-ring: var(--color-main-950);
|
|
19
|
-
--color-background: var(--color-main-50);
|
|
20
|
-
--color-foreground: var(--color-main-950);
|
|
21
|
-
--color-primary: var(--color-main-600);
|
|
22
|
-
--color-primary-foreground: var(--color-main-50);
|
|
23
|
-
--color-secondary: var(--color-sec-400);
|
|
24
|
-
--color-secondary-foreground: var(--color-main-950);
|
|
25
|
-
--color-destructive: var(--color-acc-700);
|
|
26
|
-
--color-destructive-foreground: var(--color-main-50);
|
|
27
|
-
--color-muted: var(--color-sec-100);
|
|
28
|
-
--color-muted-foreground: var(--color-main-700);
|
|
29
|
-
--color-accent: var(--color-acc-400);
|
|
30
|
-
--color-accent-foreground: var(--color-main-950);
|
|
31
|
-
--color-popover: var(--color-main-50);
|
|
32
|
-
--color-popover-foreground: var(--color-main-950);
|
|
33
|
-
--color-card: var(--color-main-50);
|
|
34
|
-
--color-card-foreground: var(--color-main-950);
|
|
35
|
-
|
|
36
|
-
}
|
|
37
10
|
|
|
38
11
|
@layer base {
|
|
39
12
|
|
|
@@ -48,7 +21,6 @@
|
|
|
48
21
|
color: var(--color-foreground);
|
|
49
22
|
}
|
|
50
23
|
|
|
51
|
-
/* Font definitions - Loading from consuming app's public directory with system font fallbacks */
|
|
52
24
|
/* Font definitions */
|
|
53
25
|
@font-face {
|
|
54
26
|
font-family: "Georama";
|
|
@@ -90,10 +62,6 @@
|
|
|
90
62
|
src: url("/fonts/reddit-mono.woff2") format("woff2");
|
|
91
63
|
}
|
|
92
64
|
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
@layer components {
|
|
96
|
-
|
|
97
65
|
/* Elements */
|
|
98
66
|
h1,
|
|
99
67
|
h2,
|
|
@@ -230,13 +198,40 @@
|
|
|
230
198
|
font-size: 0.875em;
|
|
231
199
|
color: var(--color-main-500);
|
|
232
200
|
}
|
|
233
|
-
|
|
201
|
+
|
|
234
202
|
.appGradient {
|
|
235
203
|
background: linear-gradient(145deg, var(--color-main-100) 10%, var(--color-main-200) 30%, var(--color-main-200) 70%, var(--color-main-300) 90%);
|
|
236
204
|
background-attachment: fixed;
|
|
237
205
|
}
|
|
238
206
|
}
|
|
239
207
|
|
|
240
|
-
@
|
|
208
|
+
@theme inline {
|
|
209
|
+
/* Semantic token mapping */
|
|
210
|
+
--color-border: var(--color-main-500);
|
|
211
|
+
--color-input: var(--color-sec-200);
|
|
212
|
+
--color-ring: var(--color-main-950);
|
|
213
|
+
--color-background: var(--color-main-50);
|
|
214
|
+
--color-foreground: var(--color-main-950);
|
|
215
|
+
--color-primary: var(--color-main-600);
|
|
216
|
+
--color-primary-foreground: var(--color-main-50);
|
|
217
|
+
--color-secondary: var(--color-sec-400);
|
|
218
|
+
--color-secondary-foreground: var(--color-main-950);
|
|
219
|
+
--color-destructive: var(--color-acc-700);
|
|
220
|
+
--color-destructive-foreground: var(--color-main-50);
|
|
221
|
+
--color-muted: var(--color-sec-100);
|
|
222
|
+
--color-muted-foreground: var(--color-main-700);
|
|
223
|
+
--color-accent: var(--color-acc-400);
|
|
224
|
+
--color-accent-foreground: var(--color-main-950);
|
|
225
|
+
--color-popover: var(--color-main-50);
|
|
226
|
+
--color-popover-foreground: var(--color-main-950);
|
|
227
|
+
--color-card: var(--color-main-50);
|
|
228
|
+
--color-card-foreground: var(--color-main-950);
|
|
229
|
+
}
|
|
241
230
|
|
|
231
|
+
@layer components {
|
|
232
|
+
/* Custom component styles go here */
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
@layer utilities {
|
|
236
|
+
/* Custom utility styles go here */
|
|
242
237
|
}
|
package/src/styles/index.ts
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/PublicLayout/PublicErrorBoundary.tsx","../src/components/PublicLayout/PublicPageProvider.tsx","../src/hooks/useAppConfig.ts","../src/hooks/public/usePublicEventLogo.ts"],"sourcesContent":["/**\n * @file Public Error Boundary Component\n * @package @jmruthers/pace-core\n * @module Components/PublicLayout\n * @since 1.0.0\n *\n * An error boundary component specifically designed for public pages.\n * Provides graceful error handling and recovery for public content.\n *\n * Features:\n * - Graceful error handling\n * - User-friendly error messages\n * - Recovery mechanisms\n * - Accessibility compliant\n * - TypeScript support\n *\n * @example\n * ```tsx\n * import { PublicErrorBoundary } from '@jmruthers/pace-core';\n *\n * function PublicEventPage() {\n * return (\n * <PublicErrorBoundary>\n * <PublicPageContent />\n * </PublicErrorBoundary>\n * );\n * }\n * ```\n *\n * @accessibility\n * - WCAG 2.1 AA compliant\n * - Screen reader friendly error messages\n * - Keyboard accessible recovery actions\n * - High contrast support\n *\n * @dependencies\n * - React 18+ - Component framework\n * - Error boundary patterns\n * - Tailwind CSS - Styling\n */\n\nimport React, { Component, ErrorInfo, ReactNode } from 'react';\n\nexport interface PublicErrorBoundaryProps {\n /** Child components to wrap */\n children: ReactNode;\n /** Custom error fallback component */\n fallback?: React.ComponentType<PublicErrorBoundaryState>;\n /** Custom CSS classes for error display */\n className?: string;\n /** Whether to show error details in development */\n showErrorDetails?: boolean;\n /** Custom error message */\n customErrorMessage?: string;\n /** Custom recovery action */\n onRecover?: () => void;\n}\n\nexport interface PublicErrorBoundaryState {\n /** Whether an error has occurred */\n hasError: boolean;\n /** The error that occurred */\n error: Error | null;\n /** Error information */\n errorInfo: ErrorInfo | null;\n /** Function to reset the error state */\n resetError: () => void;\n}\n\n/**\n * Error boundary component for public pages\n * \n * This component catches JavaScript errors anywhere in the child component tree,\n * logs those errors, and displays a fallback UI instead of the component tree that crashed.\n * \n * @param props - Error boundary configuration\n * @returns React element with error boundary wrapper\n */\nexport class PublicErrorBoundary extends Component<PublicErrorBoundaryProps, PublicErrorBoundaryState> {\n constructor(props: PublicErrorBoundaryProps) {\n super(props);\n this.state = {\n hasError: false,\n error: null,\n errorInfo: null,\n resetError: this.resetError.bind(this)\n };\n }\n\n static getDerivedStateFromError(error: Error): Partial<PublicErrorBoundaryState> {\n // Update state so the next render will show the fallback UI\n return {\n hasError: true,\n error\n };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\n // Log the error to console in development\n if (import.meta.env.MODE === 'development') {\n console.error('PublicErrorBoundary caught an error:', error, errorInfo);\n }\n\n // Update state with error info\n this.setState({\n error,\n errorInfo\n });\n\n // You can also log the error to an error reporting service here\n // Example: logErrorToService(error, errorInfo);\n }\n\n resetError = () => {\n this.setState({\n hasError: false,\n error: null,\n errorInfo: null\n });\n };\n\n render() {\n if (this.state.hasError) {\n // Custom fallback component\n if (this.props.fallback) {\n return <this.props.fallback {...this.state} />;\n }\n\n // Default error UI\n return (\n <div className={`min-h-screen bg-white flex items-center justify-center ${this.props.className || ''}`}>\n <div className=\"max-w-md mx-auto text-center px-4\">\n <div className=\"mb-6\">\n <div className=\"mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-red-100 mb-4\">\n <svg\n className=\"h-6 w-6 text-red-600\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z\"\n />\n </svg>\n </div>\n <h1 className=\"text-2xl font-bold text-gray-900 mb-2\">\n Something went wrong\n </h1>\n <p className=\"text-gray-600 mb-6\">\n {this.props.customErrorMessage || \n 'We encountered an error while loading this page. Please try again.'}\n </p>\n </div>\n\n {/* Error details in development */}\n {this.props.showErrorDetails && this.state.error && (\n <div className=\"mb-6 p-4 bg-red-50 border border-red-200 rounded-md text-left\">\n <h3 className=\"text-sm font-medium text-red-800 mb-2\">\n Error Details (Development Only)\n </h3>\n <pre className=\"text-xs text-red-700 whitespace-pre-wrap\">\n {this.state.error.toString()}\n {this.state.errorInfo?.componentStack}\n </pre>\n </div>\n )}\n\n {/* Recovery actions */}\n <div className=\"space-y-3\">\n <button\n onClick={this.resetError}\n className=\"w-full px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2\"\n >\n Try Again\n </button>\n \n <button\n onClick={() => window.location.reload()}\n className=\"w-full px-4 py-2 bg-gray-600 text-white rounded-md hover:bg-gray-700 transition-colors focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2\"\n >\n Reload Page\n </button>\n\n {this.props.onRecover && (\n <button\n onClick={this.props.onRecover}\n className=\"w-full px-4 py-2 bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors focus:outline-none focus:ring-2 focus:ring-green-500 focus:ring-offset-2\"\n >\n Alternative Action\n </button>\n )}\n </div>\n\n {/* Help text */}\n <div className=\"mt-6 text-sm text-gray-500\">\n <p>\n If this problem persists, please contact support or try accessing the page later.\n </p>\n </div>\n </div>\n </div>\n );\n }\n\n return this.props.children;\n }\n}\n\n/**\n * Hook for accessing error boundary state\n * Useful for components that need to know if they're inside an error boundary\n */\nexport function useErrorBoundary() {\n const [error, setError] = React.useState<Error | null>(null);\n\n const resetError = React.useCallback(() => {\n setError(null);\n }, []);\n\n const captureError = React.useCallback((error: Error) => {\n setError(error);\n }, []);\n\n React.useEffect(() => {\n if (error) {\n throw error;\n }\n }, [error]);\n\n return { captureError, resetError };\n}\n\n/**\n * Default error fallback component\n */\nexport function DefaultPublicErrorFallback({ \n error, \n resetError \n}: PublicErrorBoundaryState) {\n return (\n <div className=\"min-h-screen bg-white flex items-center justify-center\">\n <div className=\"max-w-md mx-auto text-center px-4\">\n <div className=\"mb-6\">\n <div className=\"mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-red-100 mb-4\">\n <svg\n className=\"h-6 w-6 text-red-600\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z\"\n />\n </svg>\n </div>\n <h1 className=\"text-2xl font-bold text-gray-900 mb-2\">\n Page Error\n </h1>\n <p className=\"text-gray-600 mb-6\">\n We encountered an error while loading this page.\n </p>\n </div>\n\n <button\n onClick={resetError}\n className=\"w-full px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2\"\n >\n Try Again\n </button>\n </div>\n </div>\n );\n}\n","/**\n * @file Public Page Provider\n * @package @jmruthers/pace-core\n * @module Components/PublicLayout\n * @since 1.0.0\n *\n * A completely isolated provider for public pages that doesn't trigger\n * any authentication context. This ensures public pages work independently\n * of the main application's authentication system.\n *\n * Features:\n * - No authentication required\n * - No organisation context\n * - No event context\n * - Completely isolated from main app context\n * - Environment variable access for public data\n * - Error boundary integration\n *\n * @example\n * ```tsx\n * import { PublicPageProvider } from '@jmruthers/pace-core';\n * \n * function PublicApp() {\n * return (\n * <PublicPageProvider>\n * <Routes>\n * <Route path=\"/events/:eventCode/recipe-grid-report\" element={<PublicRecipePage />} />\n * </Routes>\n * </PublicPageProvider>\n * );\n * }\n * ```\n */\n\nimport React, { createContext, useContext, ReactNode, useMemo } from 'react';\nimport { createClient } from '@supabase/supabase-js';\nimport type { Database } from '../../types/database';\nimport { PublicErrorBoundary } from './PublicErrorBoundary';\n\ninterface PublicPageContextType {\n isPublicPage: true;\n supabase: ReturnType<typeof createClient<Database>> | null;\n environment: {\n supabaseUrl: string | null;\n supabaseKey: string | null;\n };\n}\n\nconst PublicPageContext = createContext<PublicPageContextType | undefined>(undefined);\n\nexport interface PublicPageProviderProps {\n children: ReactNode;\n}\n\n/**\n * Provider for public pages that completely isolates them from authentication context\n * \n * This provider:\n * - Does not initialize any authentication providers\n * - Provides environment variables for public data access\n * - Includes error boundary for graceful error handling\n * - Is completely separate from the main app context\n */\nexport function PublicPageProvider({ children }: PublicPageProviderProps) {\n // Get environment variables for public data access\n // Handle both Vite (import.meta.env) and Node.js (process.env) environments\n const getEnvVar = (key: string): string | undefined => {\n // Check Vite environment first (browser)\n if (typeof import.meta !== 'undefined' && (import.meta as any).env) {\n return (import.meta as any).env[key];\n }\n // Check Node.js environment (server-side)\n if (typeof import.meta !== 'undefined' && import.meta.env) {\n return import.meta.env[key];\n }\n return undefined;\n };\n\n const supabaseUrl = getEnvVar('VITE_SUPABASE_URL') || \n getEnvVar('NEXT_PUBLIC_SUPABASE_URL') || \n null;\n \n const supabaseKey = getEnvVar('VITE_SUPABASE_ANON_KEY') || \n getEnvVar('NEXT_PUBLIC_SUPABASE_ANON_KEY') || \n null;\n\n // Create Supabase client if environment variables are available\n const supabase = useMemo(() => {\n if (!supabaseUrl || !supabaseKey) {\n console.warn('[PublicPageProvider] Missing Supabase environment variables. Please ensure VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY are set in your environment.');\n return null;\n }\n return createClient<Database>(supabaseUrl, supabaseKey);\n }, [supabaseUrl, supabaseKey]);\n\n const contextValue: PublicPageContextType = {\n isPublicPage: true,\n supabase,\n environment: {\n supabaseUrl,\n supabaseKey\n }\n };\n\n return (\n <PublicPageContext.Provider value={contextValue}>\n <PublicErrorBoundary>\n {children}\n </PublicErrorBoundary>\n </PublicPageContext.Provider>\n );\n}\n\n/**\n * Hook to access public page context\n * \n * @returns Public page context with environment variables\n */\nexport function usePublicPageContext(): PublicPageContextType {\n const context = useContext(PublicPageContext);\n \n if (!context) {\n throw new Error('usePublicPageContext must be used within a PublicPageProvider');\n }\n \n return context;\n}\n\n/**\n * Hook to check if we're in a public page context\n * \n * @returns True if we're in a public page context\n */\nexport function useIsPublicPage(): boolean {\n const context = useContext(PublicPageContext);\n return context !== undefined;\n}\n","/**\n * @file useAppConfig Hook\n * @package @jmruthers/pace-core\n * @module Hooks/useAppConfig\n * @since 0.4.0\n *\n * Hook for accessing app configuration like direct access support and event requirements.\n * This is a convenience hook that extracts app config from the UnifiedAuthProvider.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n * const { supportsDirectAccess, requiresEvent, isLoading } = useAppConfig();\n * \n * if (isLoading) return <div>Loading...</div>;\n * \n * return (\n * <div>\n * {supportsDirectAccess && (\n * <div>This app supports direct access!</div>\n * )}\n * {requiresEvent && (\n * <EventSelector />\n * )}\n * </div>\n * );\n * }\n * ```\n */\n\nimport { useMemo } from 'react';\nimport { useUnifiedAuth } from '../providers/UnifiedAuthProvider';\nimport { useIsPublicPage } from '../components/PublicLayout/PublicPageProvider';\n\nexport interface UseAppConfigReturn {\n supportsDirectAccess: boolean;\n requiresEvent: boolean;\n isLoading: boolean;\n appName: string;\n}\n\n/**\n * Hook to access app configuration\n * Works in both authenticated and public contexts\n * @returns App configuration and loading state\n */\nexport function useAppConfig(): UseAppConfigReturn {\n // Check if we're in a public page context first\n const isPublicPage = useIsPublicPage();\n \n if (isPublicPage) {\n // For public pages, try to get app name from environment variables\n const getAppName = (): string => {\n // Check Vite environment first (browser)\n if (typeof import.meta !== 'undefined' && (import.meta as any).env) {\n return (import.meta as any).env.VITE_APP_NAME || \n (import.meta as any).env.NEXT_PUBLIC_APP_NAME || \n 'PACE';\n }\n // Check Node.js environment (server-side)\n if (typeof import.meta !== 'undefined' && import.meta.env) {\n return import.meta.env.VITE_APP_NAME || \n import.meta.env.NEXT_PUBLIC_APP_NAME || \n 'PACE';\n }\n return 'PACE';\n };\n \n return useMemo(() => ({\n supportsDirectAccess: false, // Public pages don't support direct access\n requiresEvent: true, // Public pages always require an event\n isLoading: false,\n appName: getAppName()\n }), []);\n }\n \n // For authenticated pages, use UnifiedAuthProvider\n try {\n const { appConfig, appName } = useUnifiedAuth();\n return useMemo(() => ({\n supportsDirectAccess: !(appConfig?.requires_event ?? true),\n requiresEvent: appConfig?.requires_event ?? true,\n isLoading: appConfig === null,\n appName\n }), [appConfig?.requires_event, appName]);\n } catch (error) {\n // Fallback if UnifiedAuthProvider is not available\n return useMemo(() => ({\n supportsDirectAccess: false,\n requiresEvent: true,\n isLoading: false,\n appName: 'PACE'\n }), []);\n }\n} ","/**\n * @file Public Event Logo Hook\n * @package @jmruthers/pace-core\n * @module Hooks/Public\n * @since 1.0.0\n *\n * A React hook for accessing public event logo URLs without authentication.\n * Provides logo URLs with fallback handling for public pages.\n *\n * Features:\n * - No authentication required\n * - Automatic fallback to event initials\n * - Caching for performance\n * - Error handling and loading states\n * - TypeScript support\n * - Image validation\n *\n * @example\n * ```tsx\n * import { usePublicEventLogo } from '@jmruthers/pace-core';\n *\n * function EventHeader() {\n * const { logoUrl, fallbackText, isLoading, error } = usePublicEventLogo(\n * eventId, \n * eventName, \n * organisationId\n * );\n *\n * if (isLoading) return <div>Loading logo...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n *\n * return (\n * <div>\n * {logoUrl ? (\n * <img src={logoUrl} alt={`${eventName} logo`} />\n * ) : (\n * <div className=\"logo-fallback\">{fallbackText}</div>\n * )}\n * </div>\n * );\n * }\n * ```\n *\n * @accessibility\n * - No direct accessibility concerns (hook)\n * - Enables accessible logo display with proper alt text\n * - Supports screen reader friendly fallbacks\n *\n * @security\n * - Only returns public-safe logo URLs\n * - Validates image existence before returning URL\n * - No sensitive information exposed\n * - Rate limiting applied at storage level\n *\n * @performance\n * - Built-in caching with TTL\n * - Image validation and optimization\n * - Minimal re-renders with stable references\n * - Lazy loading support\n *\n * @dependencies\n * - React 18+ - Hooks and effects\n * - @supabase/supabase-js - Storage integration\n * - Event types - Type definitions\n */\n\nimport { useState, useEffect, useCallback, useMemo } from 'react';\nimport type { SupabaseClient } from '@supabase/supabase-js';\nimport type { Database } from '../../types/database';\n\n// Simple in-memory cache for public data\nconst publicDataCache = new Map<string, { data: any; timestamp: number; ttl: number }>();\n\nexport interface UsePublicEventLogoReturn {\n /** The logo URL if available, null if not found or error */\n logoUrl: string | null;\n /** Fallback text (event initials) if no logo is available */\n fallbackText: string;\n /** Whether the logo is currently loading */\n isLoading: boolean;\n /** Any error that occurred during loading */\n error: Error | null;\n /** Function to manually refetch the logo */\n refetch: () => Promise<void>;\n}\n\nexport interface UsePublicEventLogoOptions {\n /** Cache TTL in milliseconds (default: 30 minutes) */\n cacheTtl?: number;\n /** Whether to enable caching (default: true) */\n enableCache?: boolean;\n /** Whether to validate image existence (default: true) */\n validateImage?: boolean;\n /** Custom fallback text generator */\n generateFallbackText?: (eventName: string) => string;\n /** Supabase client instance (required) */\n supabase: SupabaseClient<Database>;\n}\n\n/**\n * Generate fallback text from event name (first letter of each word)\n */\nfunction defaultGenerateFallbackText(eventName: string): string {\n if (!eventName) return 'EV';\n \n return eventName\n .split(' ')\n .map(word => word.charAt(0).toUpperCase())\n .join('')\n .substring(0, 3); // Max 3 characters\n}\n\n/**\n * Hook for accessing public event logo URLs\n * \n * This hook provides access to event logo URLs without requiring\n * authentication. It includes fallback handling and image validation.\n * \n * @param eventId - The event ID to fetch logo for\n * @param eventName - The event name for fallback text generation\n * @param organisationId - The organisation ID for storage path\n * @param options - Configuration options for caching and behavior\n * @returns Object containing logo URL, fallback text, loading state, error, and refetch function\n */\nexport function usePublicEventLogo(\n eventId: string | undefined,\n eventName: string | undefined,\n organisationId: string | undefined,\n options: UsePublicEventLogoOptions\n): UsePublicEventLogoReturn {\n const {\n cacheTtl = 30 * 60 * 1000, // 30 minutes\n enableCache = true,\n validateImage = true,\n generateFallbackText = defaultGenerateFallbackText,\n supabase\n } = options;\n\n const [logoUrl, setLogoUrl] = useState<string | null>(null);\n const [isLoading, setIsLoading] = useState<boolean>(false);\n const [error, setError] = useState<Error | null>(null);\n\n // Generate fallback text\n const fallbackText = useMemo(() => {\n return eventName ? generateFallbackText(eventName) : 'EV';\n }, [eventName, generateFallbackText]);\n\n const fetchLogo = useCallback(async (): Promise<void> => {\n if (!eventId || !organisationId || !supabase) {\n setLogoUrl(null);\n setIsLoading(false);\n return;\n }\n\n // Validate UUID format for organisationId to prevent database errors\n const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n if (!uuidRegex.test(organisationId)) {\n console.warn('[usePublicEventLogo] Invalid organisationId format (not a valid UUID):', organisationId);\n // Don't return early - let the database handle the validation\n // This allows for more graceful error handling\n }\n\n // Check cache first\n const cacheKey = `public_logo_${eventId}_${organisationId}`;\n if (enableCache) {\n const cached = publicDataCache.get(cacheKey);\n if (cached && Date.now() - cached.timestamp < cached.ttl) {\n setLogoUrl(cached.data);\n setIsLoading(false);\n setError(null);\n return;\n }\n }\n\n try {\n setIsLoading(true);\n setError(null);\n\n // Call the public logo RPC function\n const { data, error: rpcError } = await (supabase as any).rpc('get_public_event_logo', {\n event_id_param: eventId,\n organisation_id_param: organisationId\n });\n\n if (rpcError) {\n throw new Error(rpcError.message || 'Failed to fetch logo');\n }\n\n if (!data || data.length === 0 || !data[0] || !data[0].logo_url) {\n setLogoUrl(null);\n return;\n }\n\n const logoUrl = data[0].logo_url;\n\n // Validate image existence if requested\n if (validateImage) {\n try {\n const response = await fetch(logoUrl, { method: 'HEAD' });\n if (!response.ok) {\n console.warn('[usePublicEventLogo] Logo URL not accessible:', logoUrl);\n setLogoUrl(null);\n return;\n }\n } catch (fetchError) {\n console.warn('[usePublicEventLogo] Error validating logo URL:', fetchError);\n setLogoUrl(null);\n return;\n }\n }\n\n setLogoUrl(logoUrl);\n\n // Cache the result\n if (enableCache) {\n publicDataCache.set(cacheKey, {\n data: logoUrl,\n timestamp: Date.now(),\n ttl: cacheTtl\n });\n }\n\n } catch (err) {\n console.error('[usePublicEventLogo] Error fetching logo:', err);\n const error = err instanceof Error ? err : new Error('Unknown error occurred');\n setError(error);\n setLogoUrl(null);\n } finally {\n setIsLoading(false);\n }\n }, [eventId, organisationId, supabase, cacheTtl, enableCache, validateImage]);\n\n // Fetch logo when parameters change\n useEffect(() => {\n if (eventId && organisationId) {\n fetchLogo();\n } else {\n setLogoUrl(null);\n setIsLoading(false);\n setError(null);\n }\n }, [fetchLogo, eventId, organisationId]);\n\n const refetch = useCallback(async (): Promise<void> => {\n if (!eventId || !organisationId) return;\n \n // Clear cache for this logo\n if (enableCache) {\n const cacheKey = `public_logo_${eventId}_${organisationId}`;\n publicDataCache.delete(cacheKey);\n }\n await fetchLogo();\n }, [fetchLogo, eventId, organisationId, enableCache]);\n\n return {\n logoUrl,\n fallbackText,\n isLoading,\n error,\n refetch\n };\n}\n\n/**\n * Clear all cached public logo data\n * Useful for testing or when you need to force refresh all data\n */\nexport function clearPublicLogoCache(): void {\n for (const [key] of publicDataCache) {\n if (key.startsWith('public_logo_')) {\n publicDataCache.delete(key);\n }\n }\n}\n\n/**\n * Get cache statistics for debugging\n */\nexport function getPublicLogoCacheStats(): { size: number; keys: string[] } {\n const keys = Array.from(publicDataCache.keys()).filter(key => key.startsWith('public_logo_'));\n return {\n size: keys.length,\n keys\n };\n}\n"],"mappings":"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","names":["error","jsx","useMemo","useMemo","useMemo","logoUrl","error"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/styles/index.ts"],"sourcesContent":["/**\n * @file Styles Index\n * @package @jmruthers/pace-core\n * @module Styles\n * @since 2.0.0\n * \n * Central export for all pace-core styles.\n * This file provides easy access to all CSS files for consuming applications.\n * \n * @example\n * ```tsx\n * // Import the core CSS file\n * import '@jmruthers/pace-core/styles/core.css';\n * ```\n * \n * @example\n * ```tsx\n * // Import theming runtime\n * import { applyPalette, clearPalette } from '@jmruthers/pace-core/theming/runtime';\n * ```\n */\n\n// Note: CSS files are available at runtime via package exports\n// Import them using the individual file paths\n\n// Type definitions for style imports\nexport interface StyleImport {\n default: string;\n}\n\n// Style configuration\nexport const styleConfig = {\n core: {\n path: './core.css',\n description: 'Complete CSS foundation including base styles, theme mappings, fonts, resets, and neutral tokens'\n }\n} as const;\n\n// Helper function to get style paths\nexport function getStylePath(style: keyof typeof styleConfig): string {\n return styleConfig[style].path;\n}\n\n// Helper function to get all style paths\nexport function getAllStylePaths(): string[] {\n return Object.values(styleConfig).map(config => config.path);\n}\n\n// Re-export theming runtime for convenience\nexport { applyPalette, clearPalette, generateSSRThemeCSS, isDynamicThemingActive, getCurrentThemeData } from '../theming/runtime';\nexport type { PaletteData, ColorPalette, ColorShade } from '../theming/runtime';\n"],"mappings":";AA+BO,IAAM,cAAc;AAAA,EACzB,MAAM;AAAA,IACJ,MAAM;AAAA,IACN,aAAa;AAAA,EACf;AACF;AAGO,SAAS,aAAa,OAAyC;AACpE,SAAO,YAAY,KAAK,EAAE;AAC5B;AAGO,SAAS,mBAA6B;AAC3C,SAAO,OAAO,OAAO,WAAW,EAAE,IAAI,YAAU,OAAO,IAAI;AAC7D;","names":[]}
|