@jmruthers/pace-core 0.5.121 → 0.5.124
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/{AuthService-D4646R4b.d.ts → AuthService-DYuQPJj6.d.ts} +0 -9
- package/dist/{DataTable-DGZDJUYM.js → DataTable-OKDYRW2S.js} +7 -8
- package/dist/{PublicLoadingSpinner-DgDWTFqn.d.ts → PublicLoadingSpinner-CaoRbHvJ.d.ts} +30 -4
- package/dist/{UnifiedAuthProvider-UACKFATV.js → UnifiedAuthProvider-6C47WIML.js} +3 -4
- package/dist/{chunk-D6BOFXYR.js → chunk-35ZDPMBM.js} +3 -3
- package/dist/{chunk-CGURJ27Z.js → chunk-4MXVZVNS.js} +2 -2
- package/dist/{chunk-ZYJ6O5CA.js → chunk-C43QIDN3.js} +2 -2
- package/dist/{chunk-VKOCWWVY.js → chunk-CX5M4ZAG.js} +1 -6
- package/dist/{chunk-VKOCWWVY.js 3.map → chunk-CX5M4ZAG.js.map} +1 -1
- package/dist/{chunk-RIEJGKD3.js → chunk-ESJTIADP.js} +15 -6
- package/dist/{chunk-RIEJGKD3.js.map → chunk-ESJTIADP.js.map} +1 -1
- package/dist/{chunk-HFBOFZ3Z.js → chunk-GBGYYMC6.js} +317 -251
- package/dist/chunk-GBGYYMC6.js.map +1 -0
- package/dist/{chunk-SMJZMKYN.js → chunk-GEVIB2UB.js} +43 -10
- package/dist/chunk-GEVIB2UB.js.map +1 -0
- package/dist/{chunk-TDNI6ZWL.js → chunk-IJOZZOGT.js} +7 -7
- package/dist/chunk-IJOZZOGT.js.map +1 -0
- package/dist/{chunk-GZRXOUBE.js → chunk-M6DDYFUD.js} +2 -2
- package/dist/chunk-M6DDYFUD.js.map +1 -0
- package/dist/{chunk-B4GZ2BXO.js → chunk-NZGLXZGP.js} +3 -3
- package/dist/{chunk-NZ32EONV.js → chunk-QWNJCQXZ.js} +2 -2
- package/dist/{chunk-QPI2CCBA.js → chunk-VPUCTHTY.js} +149 -96
- package/dist/chunk-VPUCTHTY.js.map +1 -0
- package/dist/{chunk-FKFHZUGF.js → chunk-XN6GWKMV.js} +43 -56
- package/dist/chunk-XN6GWKMV.js.map +1 -0
- package/dist/{chunk-BHWIUEYH.js → chunk-ZBLK676C.js} +1 -61
- package/dist/chunk-ZBLK676C.js.map +1 -0
- package/dist/components.d.ts +1 -1
- package/dist/components.js +11 -11
- package/dist/{formatting-B1jSqgl-.d.ts → formatting-DFcCxUEk.d.ts} +1 -1
- package/dist/hooks.d.ts +1 -1
- package/dist/hooks.js +9 -8
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.js +19 -17
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +2 -2
- package/dist/providers.js +2 -3
- package/dist/rbac/index.js +7 -8
- package/dist/styles/index.d.ts +1 -1
- package/dist/styles/index.js +5 -3
- package/dist/theming/runtime.d.ts +73 -1
- package/dist/theming/runtime.js +5 -5
- package/dist/{usePublicRouteParams-BdF8bZgs.d.ts → usePublicRouteParams-Dyt1tzI9.d.ts} +60 -8
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +5 -5
- 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/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 +6 -6
- 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 +6 -6
- package/docs/api/classes/StorageUtils.md +1 -1
- package/docs/api/enums/FileCategory.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/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/EmptyStateConfig.md +1 -1
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/EventAppRoleData.md +1 -1
- package/docs/api/interfaces/FileDisplayProps.md +1 -1
- 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 +1 -1
- package/docs/api/interfaces/FileUploadProps.md +1 -1
- package/docs/api/interfaces/FooterProps.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/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/ProtectedRouteProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryProps.md +7 -7
- package/docs/api/interfaces/PublicErrorBoundaryState.md +5 -5
- package/docs/api/interfaces/PublicLoadingSpinnerProps.md +7 -7
- package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
- package/docs/api/interfaces/PublicPageHeaderProps.md +51 -12
- package/docs/api/interfaces/PublicPageLayoutProps.md +72 -12
- package/docs/api/interfaces/RBACConfig.md +1 -1
- package/docs/api/interfaces/RBACLogger.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/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/SwitchProps.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/UsePublicEventOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
- package/docs/api/interfaces/UsePublicFileDisplayOptions.md +1 -1
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeReturn.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 +140 -30
- package/docs/best-practices/README.md +1 -1
- package/docs/implementation-guides/datatable-filtering.md +313 -0
- package/docs/implementation-guides/datatable-rbac-usage.md +317 -0
- package/docs/implementation-guides/hierarchical-datatable.md +850 -0
- package/docs/implementation-guides/large-datasets.md +281 -0
- package/docs/implementation-guides/performance.md +403 -0
- package/docs/implementation-guides/public-pages.md +4 -4
- package/docs/migration/quick-migration-guide.md +320 -0
- package/docs/rbac/quick-start.md +16 -16
- package/docs/troubleshooting/README.md +4 -4
- package/docs/troubleshooting/cake-page-permission-guard-issue-summary.md +1 -1
- package/docs/troubleshooting/debugging.md +1117 -0
- package/docs/troubleshooting/migration.md +918 -0
- package/examples/public-pages/CorrectPublicPageImplementation.tsx +30 -30
- package/examples/public-pages/PublicEventPage.tsx +41 -41
- package/examples/public-pages/PublicPageApp.tsx +33 -33
- package/examples/public-pages/PublicPageUsageExample.tsx +30 -30
- package/package.json +4 -4
- package/src/__tests__/hooks/usePermissions.test.ts +265 -0
- package/src/components/DataTable/DataTable.test.tsx +9 -38
- package/src/components/DataTable/DataTable.tsx +0 -7
- package/src/components/DataTable/components/DataTableCore.tsx +125 -144
- package/src/components/DataTable/components/DataTableModals.tsx +25 -22
- package/src/components/DataTable/components/DataTableToolbar.tsx +14 -1
- package/src/components/DataTable/components/EditableRow.tsx +118 -42
- package/src/components/DataTable/components/UnifiedTableBody.tsx +129 -76
- package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +33 -14
- package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +17 -5
- package/src/components/DataTable/utils/exportUtils.ts +3 -2
- package/src/components/Dialog/Dialog.tsx +1 -1
- package/src/components/Dialog/README.md +24 -24
- package/src/components/Dialog/examples/BasicHtmlTest.tsx +2 -2
- package/src/components/Dialog/examples/DebugHtmlExample.tsx +6 -6
- package/src/components/Dialog/examples/HtmlDialogExample.tsx +2 -2
- package/src/components/Dialog/examples/SimpleHtmlTest.tsx +3 -3
- package/src/components/Dialog/examples/__tests__/SimpleHtmlTest.test.tsx +4 -4
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +12 -1
- package/src/components/PublicLayout/EventLogo.tsx +175 -0
- package/src/components/PublicLayout/PublicErrorBoundary.tsx +22 -18
- package/src/components/PublicLayout/PublicLoadingSpinner.tsx +22 -14
- package/src/components/PublicLayout/PublicPageHeader.tsx +133 -40
- package/src/components/PublicLayout/PublicPageLayout.tsx +75 -72
- package/src/components/PublicLayout/__tests__/PublicErrorBoundary.test.tsx +1 -1
- package/src/components/PublicLayout/__tests__/PublicLoadingSpinner.test.tsx +8 -8
- package/src/components/PublicLayout/__tests__/PublicPageHeader.test.tsx +23 -16
- package/src/components/PublicLayout/__tests__/PublicPageLayout.test.tsx +86 -14
- package/src/examples/CorrectPublicPageImplementation.tsx +30 -30
- package/src/examples/PublicEventPage.tsx +41 -41
- package/src/examples/PublicPageApp.tsx +33 -33
- package/src/examples/PublicPageUsageExample.tsx +30 -30
- package/src/hooks/__tests__/usePublicEvent.unit.test.ts +583 -0
- package/src/hooks/__tests__/usePublicRouteParams.unit.test.ts +10 -3
- package/src/hooks/index.ts +1 -1
- package/src/hooks/public/usePublicEventLogo.ts +285 -0
- package/src/hooks/public/usePublicRouteParams.ts +21 -4
- package/src/hooks/useEventTheme.test.ts +119 -43
- package/src/hooks/useEventTheme.ts +84 -55
- package/src/index.ts +3 -1
- package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +630 -0
- package/src/rbac/components/__tests__/NavigationProvider.test.tsx +667 -0
- package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +647 -0
- package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +496 -0
- package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +496 -0
- package/src/rbac/secureClient.ts +4 -2
- package/src/services/EventService.ts +0 -66
- package/src/services/__tests__/EventService.eventColours.test.ts +44 -40
- package/src/styles/index.ts +1 -1
- package/src/theming/__tests__/parseEventColours.test.ts +209 -0
- package/src/theming/parseEventColours.ts +123 -0
- package/src/theming/runtime.ts +3 -0
- package/src/types/__tests__/file-reference.test.ts +447 -0
- package/src/utils/formatDate.test.ts +11 -11
- package/src/utils/formatting.ts +3 -2
- package/dist/chunk-BDZUMRBD.js 3.map +0 -1
- package/dist/chunk-BHWIUEYH.js.map +0 -1
- package/dist/chunk-CGURJ27Z.js.map +0 -1
- package/dist/chunk-FKFHZUGF.js.map +0 -1
- package/dist/chunk-GKHF54DI 2.js +0 -619
- package/dist/chunk-GKHF54DI.js 2.map +0 -1
- package/dist/chunk-GZRXOUBE.js.map +0 -1
- package/dist/chunk-HFBOFZ3Z.js.map +0 -1
- package/dist/chunk-NZ32EONV.js.map +0 -1
- package/dist/chunk-O3NWNXDY 2.js +0 -76
- package/dist/chunk-QPI2CCBA.js.map +0 -1
- package/dist/chunk-SMJZMKYN.js.map +0 -1
- package/dist/chunk-TDNI6ZWL.js 2.map +0 -1
- package/dist/chunk-TDNI6ZWL.js.map +0 -1
- package/dist/chunk-VKOCWWVY.js.map +0 -1
- package/dist/chunk-WP5I5GLN 2.js +0 -1564
- package/dist/index 3.js +0 -856
- package/dist/providers 3.js +0 -38
- package/dist/providers.js 3.map +0 -1
- package/dist/types 3.js +0 -128
- package/dist/types.js 3.map +0 -1
- package/dist/useInactivityTracker-MRUU55XI.js 3.map +0 -1
- package/dist/utils.js 3.map +0 -1
- package/dist/validation 3.js +0 -479
- package/src/styles/semantic.css +0 -24
- /package/dist/{DataTable-DGZDJUYM.js.map → DataTable-OKDYRW2S.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-UACKFATV.js.map → UnifiedAuthProvider-6C47WIML.js.map} +0 -0
- /package/dist/{chunk-D6BOFXYR.js.map → chunk-35ZDPMBM.js.map} +0 -0
- /package/dist/{chunk-CGURJ27Z.js 2.map → chunk-4MXVZVNS.js.map} +0 -0
- /package/dist/{chunk-ZYJ6O5CA.js.map → chunk-C43QIDN3.js.map} +0 -0
- /package/dist/{chunk-B4GZ2BXO.js.map → chunk-NZGLXZGP.js.map} +0 -0
- /package/dist/{chunk-NZ32EONV.js 2.map → chunk-QWNJCQXZ.js.map} +0 -0
|
@@ -86,7 +86,7 @@ The Dialog components support rich HTML content rendering with automatic sanitiz
|
|
|
86
86
|
allowHtml={true}
|
|
87
87
|
>
|
|
88
88
|
{/* Fallback content if HTML rendering fails */}
|
|
89
|
-
<div className="text-
|
|
89
|
+
<div className="text-acc-500">
|
|
90
90
|
HTML content failed to render. This is fallback content.
|
|
91
91
|
</div>
|
|
92
92
|
</DialogBody>
|
|
@@ -100,27 +100,27 @@ The Dialog components support rich HTML content rendering with automatic sanitiz
|
|
|
100
100
|
<DialogBody
|
|
101
101
|
htmlContent={`
|
|
102
102
|
<div class="space-y-4">
|
|
103
|
-
<div class="bg-
|
|
104
|
-
<h3 class="font-semibold text-
|
|
105
|
-
<p class="text-sm text-
|
|
106
|
-
<ul class="text-sm text-
|
|
103
|
+
<div class="bg-main-50 p-4 rounded-lg">
|
|
104
|
+
<h3 class="font-semibold text-main-900 mb-2">📋 Required Format</h3>
|
|
105
|
+
<p class="text-sm text-main-800 mb-2">Your CSV file must include these columns:</p>
|
|
106
|
+
<ul class="text-sm text-main-700 list-disc list-inside ml-2">
|
|
107
107
|
<li><code>name</code> - Full name of the person</li>
|
|
108
108
|
<li><code>email</code> - Valid email address</li>
|
|
109
109
|
<li><code>phone</code> - Phone number (optional)</li>
|
|
110
110
|
</ul>
|
|
111
111
|
</div>
|
|
112
112
|
|
|
113
|
-
<div class="bg-
|
|
114
|
-
<h3 class="font-semibold text-
|
|
115
|
-
<pre class="text-xs text-
|
|
113
|
+
<div class="bg-main-50 p-4 rounded-lg">
|
|
114
|
+
<h3 class="font-semibold text-main-900 mb-2">✅ Example Data</h3>
|
|
115
|
+
<pre class="text-xs text-main-700 bg-main-50 p-2 rounded border">
|
|
116
116
|
name,email,phone
|
|
117
117
|
John Doe,john@example.com,555-0123
|
|
118
118
|
Jane Smith,jane@example.com,
|
|
119
119
|
</pre>
|
|
120
120
|
</div>
|
|
121
121
|
|
|
122
|
-
<div class="bg-
|
|
123
|
-
<p class="text-sm text-
|
|
122
|
+
<div class="bg-acc-50 p-3 rounded-lg">
|
|
123
|
+
<p class="text-sm text-acc-800">
|
|
124
124
|
<strong>⚠️ Important:</strong> Make sure your CSV file is properly formatted.
|
|
125
125
|
</p>
|
|
126
126
|
</div>
|
|
@@ -212,20 +212,20 @@ function ImportInstructionsDialog() {
|
|
|
212
212
|
|
|
213
213
|
const importInstructions = `
|
|
214
214
|
<div class="space-y-4">
|
|
215
|
-
<p class="text-sm text-
|
|
215
|
+
<p class="text-sm text-sec-600 mb-4">
|
|
216
216
|
Upload a CSV file with dish or recipe data. The system will automatically detect the format based on your column headers.
|
|
217
217
|
</p>
|
|
218
218
|
|
|
219
|
-
<div class="bg-
|
|
220
|
-
<h3 class="font-semibold text-
|
|
221
|
-
<p class="text-sm text-
|
|
219
|
+
<div class="bg-main-50 p-4 rounded-lg">
|
|
220
|
+
<h3 class="font-semibold text-main-900 mb-2">🍽️ Dish Format (3 columns)</h3>
|
|
221
|
+
<p class="text-sm text-main-800 mb-2">Perfect for importing basic dish information:</p>
|
|
222
222
|
<div class="space-y-1">
|
|
223
223
|
<p class="text-sm"><strong>Required:</strong> <code>dish_code</code>, <code>dish_name</code>, <code>mealtype_name</code></p>
|
|
224
224
|
<p class="text-sm"><strong>Optional:</strong> <code>dish_description</code></p>
|
|
225
225
|
</div>
|
|
226
226
|
<div class="mt-2">
|
|
227
|
-
<p class="text-xs text-
|
|
228
|
-
<ul class="text-xs text-
|
|
227
|
+
<p class="text-xs text-main-700"><strong>Examples:</strong></p>
|
|
228
|
+
<ul class="text-xs text-main-700 list-disc list-inside ml-2">
|
|
229
229
|
<li><code>dish_code</code>: BBQ, PC, CTY</li>
|
|
230
230
|
<li><code>dish_name</code>: BBQ hamburgers and potato salad</li>
|
|
231
231
|
<li><code>mealtype_name</code>: Breakfast, Lunch, Dinner</li>
|
|
@@ -233,16 +233,16 @@ function ImportInstructionsDialog() {
|
|
|
233
233
|
</div>
|
|
234
234
|
</div>
|
|
235
235
|
|
|
236
|
-
<div class="bg-
|
|
237
|
-
<h3 class="font-semibold text-
|
|
238
|
-
<p class="text-sm text-
|
|
236
|
+
<div class="bg-main-50 p-4 rounded-lg">
|
|
237
|
+
<h3 class="font-semibold text-main-900 mb-2">📋 Recipe Format (8 columns)</h3>
|
|
238
|
+
<p class="text-sm text-main-800 mb-2">Perfect for importing detailed recipe ingredients:</p>
|
|
239
239
|
<div class="space-y-1">
|
|
240
240
|
<p class="text-sm"><strong>Required:</strong> <code>dish_code</code>, <code>dish_name</code>, <code>mealtype_name</code>, <code>diettype_name</code>, <code>item_name</code>, <code>recipe_qtypp</code>, <code>recipe_uptake</code></p>
|
|
241
241
|
<p class="text-sm"><strong>Optional:</strong> <code>item_brand</code></p>
|
|
242
242
|
</div>
|
|
243
243
|
<div class="mt-2">
|
|
244
|
-
<p class="text-xs text-
|
|
245
|
-
<ul class="text-xs text-
|
|
244
|
+
<p class="text-xs text-main-700"><strong>Examples:</strong></p>
|
|
245
|
+
<ul class="text-xs text-main-700 list-disc list-inside ml-2">
|
|
246
246
|
<li><code>dish_code</code>: BBQ</li>
|
|
247
247
|
<li><code>dish_name</code>: BBQ hamburgers and potato salad</li>
|
|
248
248
|
<li><code>mealtype_name</code>: Dinner</li>
|
|
@@ -255,8 +255,8 @@ function ImportInstructionsDialog() {
|
|
|
255
255
|
</div>
|
|
256
256
|
</div>
|
|
257
257
|
|
|
258
|
-
<div class="bg-
|
|
259
|
-
<p class="text-sm text-
|
|
258
|
+
<div class="bg-acc-50 p-3 rounded-lg">
|
|
259
|
+
<p class="text-sm text-acc-800"><strong>⚠️ Important:</strong> Recipe imports will replace all existing recipe data for dishes in the file.</p>
|
|
260
260
|
</div>
|
|
261
261
|
</div>
|
|
262
262
|
`;
|
|
@@ -280,7 +280,7 @@ function ImportInstructionsDialog() {
|
|
|
280
280
|
logWarnings={true}
|
|
281
281
|
>
|
|
282
282
|
{/* Fallback content if HTML rendering fails */}
|
|
283
|
-
<div className="text-
|
|
283
|
+
<div className="text-acc-500">
|
|
284
284
|
HTML content failed to render. This is fallback content.
|
|
285
285
|
</div>
|
|
286
286
|
</DialogBody>
|
|
@@ -20,7 +20,7 @@ export function BasicHtmlTest() {
|
|
|
20
20
|
<h3 className="font-semibold mb-2">Test 1: Direct dangerouslySetInnerHTML</h3>
|
|
21
21
|
<div
|
|
22
22
|
dangerouslySetInnerHTML={{ __html: '<p>Hello <strong>world</strong>!</p>' }}
|
|
23
|
-
className="bg-
|
|
23
|
+
className="bg-main-50 p-2 rounded"
|
|
24
24
|
/>
|
|
25
25
|
</div>
|
|
26
26
|
|
|
@@ -38,7 +38,7 @@ export function BasicHtmlTest() {
|
|
|
38
38
|
</DialogHeader>
|
|
39
39
|
|
|
40
40
|
<DialogBody htmlContent="<p>Hello <strong>world</strong>!</p>" allowHtml={true}>
|
|
41
|
-
<div className="text-
|
|
41
|
+
<div className="text-acc-500">
|
|
42
42
|
HTML content failed to render. This is fallback content.
|
|
43
43
|
</div>
|
|
44
44
|
</DialogBody>
|
|
@@ -13,11 +13,11 @@ export function DebugHtmlExample() {
|
|
|
13
13
|
const [isOpen, setIsOpen] = useState(false);
|
|
14
14
|
|
|
15
15
|
const testHtml = `
|
|
16
|
-
<p class="text-sm text-
|
|
16
|
+
<p class="text-sm text-sec-600 mb-4">Upload a CSV file with dish or recipe data. The system will automatically detect the format based on your column headers.</p>
|
|
17
17
|
|
|
18
|
-
<div class="bg-
|
|
19
|
-
<h3 class="font-semibold text-
|
|
20
|
-
<p class="text-sm text-
|
|
18
|
+
<div class="bg-main-50 p-4 rounded-lg">
|
|
19
|
+
<h3 class="font-semibold text-main-900 mb-2">Dish Format (3 columns)</h3>
|
|
20
|
+
<p class="text-sm text-main-800 mb-2">Perfect for importing basic dish information:</p>
|
|
21
21
|
<div class="space-y-1">
|
|
22
22
|
<p class="text-sm"><strong>Required:</strong> <code>dish_code</code>, <code>dish_name</code>, <code>mealtype_name</code></p>
|
|
23
23
|
<p class="text-sm"><strong>Optional:</strong> <code>dish_description</code></p>
|
|
@@ -31,7 +31,7 @@ export function DebugHtmlExample() {
|
|
|
31
31
|
|
|
32
32
|
<div className="mb-4">
|
|
33
33
|
<h3 className="font-semibold mb-2">Raw HTML String:</h3>
|
|
34
|
-
<pre className="bg-
|
|
34
|
+
<pre className="bg-sec-100 p-2 rounded text-xs overflow-auto">
|
|
35
35
|
{testHtml}
|
|
36
36
|
</pre>
|
|
37
37
|
</div>
|
|
@@ -48,7 +48,7 @@ export function DebugHtmlExample() {
|
|
|
48
48
|
|
|
49
49
|
<DialogBody htmlContent={testHtml} allowHtml={true}>
|
|
50
50
|
{/* Fallback content if HTML rendering fails */}
|
|
51
|
-
<div className="text-
|
|
51
|
+
<div className="text-acc-500">
|
|
52
52
|
HTML content failed to render. This is fallback content.
|
|
53
53
|
</div>
|
|
54
54
|
</DialogBody>
|
|
@@ -149,8 +149,8 @@ export function HtmlDialogExample() {
|
|
|
149
149
|
<div className="space-y-4">
|
|
150
150
|
<h3 className="text-lg font-semibold">React Children Content</h3>
|
|
151
151
|
<p>This content is rendered using React children, not HTML strings.</p>
|
|
152
|
-
<div className="bg-
|
|
153
|
-
<p className="text-
|
|
152
|
+
<div className="bg-main-50 p-4 rounded-lg">
|
|
153
|
+
<p className="text-main-800">
|
|
154
154
|
You can mix HTML content (via <code>htmlContent</code> prop)
|
|
155
155
|
with React children for maximum flexibility.
|
|
156
156
|
</p>
|
|
@@ -21,14 +21,14 @@ export function SimpleHtmlTest() {
|
|
|
21
21
|
|
|
22
22
|
<div className="mb-4">
|
|
23
23
|
<h3 className="font-semibold mb-2">Test HTML:</h3>
|
|
24
|
-
<pre className="bg-
|
|
24
|
+
<pre className="bg-sec-100 p-2 rounded text-xs">
|
|
25
25
|
{simpleHtml}
|
|
26
26
|
</pre>
|
|
27
27
|
</div>
|
|
28
28
|
|
|
29
29
|
<div className="mb-4">
|
|
30
30
|
<h3 className="font-semibold mb-2">Expected Result:</h3>
|
|
31
|
-
<div className="bg-
|
|
31
|
+
<div className="bg-main-50 p-2 rounded">
|
|
32
32
|
Hello <strong>world</strong>!
|
|
33
33
|
</div>
|
|
34
34
|
</div>
|
|
@@ -44,7 +44,7 @@ export function SimpleHtmlTest() {
|
|
|
44
44
|
</DialogHeader>
|
|
45
45
|
|
|
46
46
|
<DialogBody htmlContent={simpleHtml} allowHtml={true}>
|
|
47
|
-
<div className="text-
|
|
47
|
+
<div className="text-acc-500">
|
|
48
48
|
HTML content failed to render. This is fallback content.
|
|
49
49
|
</div>
|
|
50
50
|
</DialogBody>
|
|
@@ -93,7 +93,7 @@ describe('SimpleHtmlTest Component', () => {
|
|
|
93
93
|
|
|
94
94
|
const codeBlock = screen.getByText(/Hello <strong>world<\/strong>!/).closest('pre');
|
|
95
95
|
expect(codeBlock).toBeInTheDocument();
|
|
96
|
-
expect(codeBlock?.className).toContain('bg-
|
|
96
|
+
expect(codeBlock?.className).toContain('bg-sec-100');
|
|
97
97
|
});
|
|
98
98
|
});
|
|
99
99
|
|
|
@@ -102,7 +102,7 @@ describe('SimpleHtmlTest Component', () => {
|
|
|
102
102
|
renderWithProviders(<SimpleHtmlTest />);
|
|
103
103
|
|
|
104
104
|
// Should show the expected result container with proper styling
|
|
105
|
-
const resultContainers = document.querySelectorAll('.bg-
|
|
105
|
+
const resultContainers = document.querySelectorAll('.bg-main-50');
|
|
106
106
|
expect(resultContainers.length).toBeGreaterThan(0);
|
|
107
107
|
});
|
|
108
108
|
|
|
@@ -110,11 +110,11 @@ describe('SimpleHtmlTest Component', () => {
|
|
|
110
110
|
renderWithProviders(<SimpleHtmlTest />);
|
|
111
111
|
|
|
112
112
|
// The expected result should have "Hello" text
|
|
113
|
-
const expectedResult = document.querySelector('.bg-
|
|
113
|
+
const expectedResult = document.querySelector('.bg-main-50');
|
|
114
114
|
expect(expectedResult).toBeTruthy();
|
|
115
115
|
|
|
116
116
|
// Should contain a strong element
|
|
117
|
-
const strongElements = document.querySelectorAll('.bg-
|
|
117
|
+
const strongElements = document.querySelectorAll('.bg-main-50 strong');
|
|
118
118
|
expect(strongElements.length).toBeGreaterThan(0);
|
|
119
119
|
});
|
|
120
120
|
});
|
|
@@ -772,7 +772,18 @@ export function PaceAppLayout({
|
|
|
772
772
|
<p className="text-sec-600 mb-4">
|
|
773
773
|
You don't have permission to access this page.
|
|
774
774
|
</p>
|
|
775
|
-
<
|
|
775
|
+
<div className="flex gap-2 justify-center">
|
|
776
|
+
<Button onClick={() => navigate('/')}>Go Home</Button>
|
|
777
|
+
<Button
|
|
778
|
+
variant="outline"
|
|
779
|
+
onClick={async () => {
|
|
780
|
+
await handleSignOut();
|
|
781
|
+
navigate('/login');
|
|
782
|
+
}}
|
|
783
|
+
>
|
|
784
|
+
Sign out
|
|
785
|
+
</Button>
|
|
786
|
+
</div>
|
|
776
787
|
</div>
|
|
777
788
|
</div>
|
|
778
789
|
);
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Event Logo Component
|
|
3
|
+
* @package @jmruthers/pace-core
|
|
4
|
+
* @module Components/PublicLayout
|
|
5
|
+
* @since 1.0.0
|
|
6
|
+
*
|
|
7
|
+
* A context-aware component for displaying event logos with automatic fallback to event initials.
|
|
8
|
+
* Automatically detects whether it's being used in a public or authenticated context and behaves
|
|
9
|
+
* appropriately without triggering authentication context leakage.
|
|
10
|
+
*
|
|
11
|
+
* Features:
|
|
12
|
+
* - Context-aware (works in both public and authenticated contexts)
|
|
13
|
+
* - Automatic fallback to event initials
|
|
14
|
+
* - Logo validation and error handling
|
|
15
|
+
* - Multiple size options
|
|
16
|
+
* - Responsive design
|
|
17
|
+
* - Accessibility compliant
|
|
18
|
+
* - TypeScript support
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* import { EventLogo } from '@jmruthers/pace-core';
|
|
23
|
+
*
|
|
24
|
+
* function EventHeader() {
|
|
25
|
+
* return (
|
|
26
|
+
* <EventLogo
|
|
27
|
+
* eventId={event.id}
|
|
28
|
+
* eventName={event.event_name}
|
|
29
|
+
* organisationId={event.organisation_id}
|
|
30
|
+
* size="lg"
|
|
31
|
+
* className="rounded-full"
|
|
32
|
+
* />
|
|
33
|
+
* );
|
|
34
|
+
* }
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @accessibility
|
|
38
|
+
* - WCAG 2.1 AA compliant
|
|
39
|
+
* - Proper alt text for images
|
|
40
|
+
* - Screen reader friendly fallbacks
|
|
41
|
+
* - High contrast support
|
|
42
|
+
*
|
|
43
|
+
* @dependencies
|
|
44
|
+
* - React 18+ - Component framework
|
|
45
|
+
* - FileDisplay component - Logo display and fallback handling
|
|
46
|
+
* - Tailwind CSS - Styling
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
import React from 'react';
|
|
50
|
+
import { FileDisplay } from '../FileDisplay/FileDisplay';
|
|
51
|
+
import { FileCategory } from '../../types/file-reference';
|
|
52
|
+
|
|
53
|
+
export interface EventLogoProps {
|
|
54
|
+
/** The event ID to fetch logo for */
|
|
55
|
+
eventId: string;
|
|
56
|
+
/** The event name for fallback text generation */
|
|
57
|
+
eventName: string;
|
|
58
|
+
/** The organisation ID for storage path */
|
|
59
|
+
organisationId: string;
|
|
60
|
+
/** Logo size variant */
|
|
61
|
+
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
|
|
62
|
+
/** Custom CSS classes */
|
|
63
|
+
className?: string;
|
|
64
|
+
/** Whether to show fallback text when no logo is available */
|
|
65
|
+
showFallback?: boolean;
|
|
66
|
+
/** Custom fallback text generator */
|
|
67
|
+
generateFallbackText?: (eventName: string) => string;
|
|
68
|
+
/** Whether to validate image existence (deprecated - FileDisplay handles this) */
|
|
69
|
+
validateImage?: boolean;
|
|
70
|
+
/** Custom loading component */
|
|
71
|
+
loadingComponent?: React.ComponentType;
|
|
72
|
+
/** Custom error component */
|
|
73
|
+
errorComponent?: React.ComponentType<{ error: Error }>;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Default fallback text generator
|
|
78
|
+
*/
|
|
79
|
+
function defaultGenerateFallbackText(eventName: string): string {
|
|
80
|
+
if (!eventName) return 'EV';
|
|
81
|
+
|
|
82
|
+
return eventName
|
|
83
|
+
.split(' ')
|
|
84
|
+
.map(word => word.charAt(0).toUpperCase())
|
|
85
|
+
.join('')
|
|
86
|
+
.substring(0, 3); // Max 3 characters
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Component for displaying event logos with fallback to initials
|
|
91
|
+
*
|
|
92
|
+
* This component is context-aware and automatically detects whether it's being used
|
|
93
|
+
* in a public or authenticated context. It uses FileDisplay internally to fetch and
|
|
94
|
+
* display event logos from storage, with automatic fallback to event initials if no
|
|
95
|
+
* logo is available.
|
|
96
|
+
*
|
|
97
|
+
* @param props - Logo configuration and styling
|
|
98
|
+
* @returns React element with event logo or fallback
|
|
99
|
+
*/
|
|
100
|
+
export function EventLogo({
|
|
101
|
+
eventId,
|
|
102
|
+
eventName,
|
|
103
|
+
organisationId,
|
|
104
|
+
size = 'md',
|
|
105
|
+
className = '',
|
|
106
|
+
showFallback = true,
|
|
107
|
+
generateFallbackText = defaultGenerateFallbackText,
|
|
108
|
+
validateImage = true, // Deprecated but kept for backward compatibility
|
|
109
|
+
loadingComponent: LoadingComponent,
|
|
110
|
+
errorComponent: ErrorComponent
|
|
111
|
+
}: EventLogoProps) {
|
|
112
|
+
// Adapt generateFallbackText to FileDisplay's signature
|
|
113
|
+
// FileDisplay expects (fileName?: string) => string, but we have (eventName: string) => string
|
|
114
|
+
const adaptedGenerateFallbackText = React.useCallback(
|
|
115
|
+
(fileName?: string) => {
|
|
116
|
+
// Use eventName if available, otherwise fall back to fileName
|
|
117
|
+
return generateFallbackText(eventName || fileName || '');
|
|
118
|
+
},
|
|
119
|
+
[eventName, generateFallbackText]
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
// Adapt error component to FileDisplay's signature
|
|
123
|
+
// FileDisplay expects { error: Error | string | null; retry?: () => void }
|
|
124
|
+
const adaptedErrorComponent = ErrorComponent
|
|
125
|
+
? React.useCallback(
|
|
126
|
+
({ error }: { error: Error | string | null; retry?: () => void }) => {
|
|
127
|
+
const errorObj = error instanceof Error ? error : new Error(String(error || 'Unknown error'));
|
|
128
|
+
return <ErrorComponent error={errorObj} />;
|
|
129
|
+
},
|
|
130
|
+
[ErrorComponent]
|
|
131
|
+
)
|
|
132
|
+
: undefined;
|
|
133
|
+
|
|
134
|
+
return (
|
|
135
|
+
<FileDisplay
|
|
136
|
+
table_name="event"
|
|
137
|
+
record_id={eventId}
|
|
138
|
+
organisation_id={organisationId}
|
|
139
|
+
category={FileCategory.EVENT_LOGOS}
|
|
140
|
+
displayOnly={true}
|
|
141
|
+
showFallback={showFallback}
|
|
142
|
+
fallbackSize={size}
|
|
143
|
+
className={className}
|
|
144
|
+
generateFallbackText={adaptedGenerateFallbackText}
|
|
145
|
+
loadingComponent={LoadingComponent}
|
|
146
|
+
errorComponent={adaptedErrorComponent}
|
|
147
|
+
/>
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Compact event logo for small spaces
|
|
153
|
+
*/
|
|
154
|
+
export function EventLogoCompact(props: EventLogoProps) {
|
|
155
|
+
return (
|
|
156
|
+
<EventLogo
|
|
157
|
+
{...props}
|
|
158
|
+
size="sm"
|
|
159
|
+
className={`${props.className || ''} rounded-sm`}
|
|
160
|
+
/>
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Large event logo for prominent display
|
|
166
|
+
*/
|
|
167
|
+
export function EventLogoLarge(props: EventLogoProps) {
|
|
168
|
+
return (
|
|
169
|
+
<EventLogo
|
|
170
|
+
{...props}
|
|
171
|
+
size="xl"
|
|
172
|
+
className={`${props.className || ''} rounded-lg`}
|
|
173
|
+
/>
|
|
174
|
+
);
|
|
175
|
+
}
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
*/
|
|
41
41
|
|
|
42
42
|
import React, { Component, ErrorInfo, ReactNode } from 'react';
|
|
43
|
+
import { cn } from '../../utils/cn';
|
|
43
44
|
|
|
44
45
|
export interface PublicErrorBoundaryProps {
|
|
45
46
|
/** Child components to wrap */
|
|
@@ -128,12 +129,15 @@ export class PublicErrorBoundary extends Component<PublicErrorBoundaryProps, Pub
|
|
|
128
129
|
|
|
129
130
|
// Default error UI
|
|
130
131
|
return (
|
|
131
|
-
<div className={
|
|
132
|
+
<div className={cn(
|
|
133
|
+
"min-h-screen bg-background flex items-center justify-center",
|
|
134
|
+
this.props.className
|
|
135
|
+
)}>
|
|
132
136
|
<div className="max-w-md mx-auto text-center px-4">
|
|
133
137
|
<div className="mb-6">
|
|
134
|
-
<div className="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-
|
|
138
|
+
<div className="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-acc-100 mb-4">
|
|
135
139
|
<svg
|
|
136
|
-
className="h-6 w-6 text-
|
|
140
|
+
className="h-6 w-6 text-acc-600"
|
|
137
141
|
fill="none"
|
|
138
142
|
viewBox="0 0 24 24"
|
|
139
143
|
stroke="currentColor"
|
|
@@ -146,10 +150,10 @@ export class PublicErrorBoundary extends Component<PublicErrorBoundaryProps, Pub
|
|
|
146
150
|
/>
|
|
147
151
|
</svg>
|
|
148
152
|
</div>
|
|
149
|
-
<h1 className="text-2xl font-bold text-
|
|
153
|
+
<h1 className="text-2xl font-bold text-sec-900 mb-2">
|
|
150
154
|
Something went wrong
|
|
151
155
|
</h1>
|
|
152
|
-
<p className="text-
|
|
156
|
+
<p className="text-sec-600 mb-6">
|
|
153
157
|
{this.props.customErrorMessage ||
|
|
154
158
|
'We encountered an error while loading this page. Please try again.'}
|
|
155
159
|
</p>
|
|
@@ -157,11 +161,11 @@ export class PublicErrorBoundary extends Component<PublicErrorBoundaryProps, Pub
|
|
|
157
161
|
|
|
158
162
|
{/* Error details in development */}
|
|
159
163
|
{this.props.showErrorDetails && this.state.error && (
|
|
160
|
-
<div className="mb-6 p-4 bg-
|
|
161
|
-
<h3 className="text-sm font-medium text-
|
|
164
|
+
<div className="mb-6 p-4 bg-acc-50 border border-acc-200 rounded-md text-left">
|
|
165
|
+
<h3 className="text-sm font-medium text-acc-800 mb-2">
|
|
162
166
|
Error Details (Development Only)
|
|
163
167
|
</h3>
|
|
164
|
-
<pre className="text-xs text-
|
|
168
|
+
<pre className="text-xs text-acc-700 whitespace-pre-wrap">
|
|
165
169
|
{this.state.error.toString()}
|
|
166
170
|
{this.state.errorInfo?.componentStack}
|
|
167
171
|
</pre>
|
|
@@ -172,14 +176,14 @@ export class PublicErrorBoundary extends Component<PublicErrorBoundaryProps, Pub
|
|
|
172
176
|
<div className="space-y-3">
|
|
173
177
|
<button
|
|
174
178
|
onClick={this.resetError}
|
|
175
|
-
className="w-full px-4 py-2 bg-
|
|
179
|
+
className="w-full px-4 py-2 bg-main-600 text-main-50 rounded-md hover:bg-main-700 transition-colors focus:outline-none focus:ring-2 focus:ring-main-500 focus:ring-offset-2"
|
|
176
180
|
>
|
|
177
181
|
Try Again
|
|
178
182
|
</button>
|
|
179
183
|
|
|
180
184
|
<button
|
|
181
185
|
onClick={() => window.location.reload()}
|
|
182
|
-
className="w-full px-4 py-2 bg-
|
|
186
|
+
className="w-full px-4 py-2 bg-sec-600 text-main-50 rounded-md hover:bg-sec-700 transition-colors focus:outline-none focus:ring-2 focus:ring-sec-500 focus:ring-offset-2"
|
|
183
187
|
>
|
|
184
188
|
Reload Page
|
|
185
189
|
</button>
|
|
@@ -187,7 +191,7 @@ export class PublicErrorBoundary extends Component<PublicErrorBoundaryProps, Pub
|
|
|
187
191
|
{this.props.onRecover && (
|
|
188
192
|
<button
|
|
189
193
|
onClick={this.props.onRecover}
|
|
190
|
-
className="w-full px-4 py-2 bg-
|
|
194
|
+
className="w-full px-4 py-2 bg-main-600 text-main-50 rounded-md hover:bg-main-700 transition-colors focus:outline-none focus:ring-2 focus:ring-main-500 focus:ring-offset-2"
|
|
191
195
|
>
|
|
192
196
|
Alternative Action
|
|
193
197
|
</button>
|
|
@@ -195,7 +199,7 @@ export class PublicErrorBoundary extends Component<PublicErrorBoundaryProps, Pub
|
|
|
195
199
|
</div>
|
|
196
200
|
|
|
197
201
|
{/* Help text */}
|
|
198
|
-
<div className="mt-6 text-sm text-
|
|
202
|
+
<div className="mt-6 text-sm text-sec-500">
|
|
199
203
|
<p>
|
|
200
204
|
If this problem persists, please contact support or try accessing the page later.
|
|
201
205
|
</p>
|
|
@@ -240,12 +244,12 @@ export function DefaultPublicErrorFallback({
|
|
|
240
244
|
resetError
|
|
241
245
|
}: PublicErrorBoundaryState) {
|
|
242
246
|
return (
|
|
243
|
-
<div className="min-h-screen bg-
|
|
247
|
+
<div className="min-h-screen bg-background flex items-center justify-center">
|
|
244
248
|
<div className="max-w-md mx-auto text-center px-4">
|
|
245
249
|
<div className="mb-6">
|
|
246
|
-
<div className="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-
|
|
250
|
+
<div className="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-acc-100 mb-4">
|
|
247
251
|
<svg
|
|
248
|
-
className="h-6 w-6 text-
|
|
252
|
+
className="h-6 w-6 text-acc-600"
|
|
249
253
|
fill="none"
|
|
250
254
|
viewBox="0 0 24 24"
|
|
251
255
|
stroke="currentColor"
|
|
@@ -258,17 +262,17 @@ export function DefaultPublicErrorFallback({
|
|
|
258
262
|
/>
|
|
259
263
|
</svg>
|
|
260
264
|
</div>
|
|
261
|
-
<h1 className="text-2xl font-bold text-
|
|
265
|
+
<h1 className="text-2xl font-bold text-sec-900 mb-2">
|
|
262
266
|
Page Error
|
|
263
267
|
</h1>
|
|
264
|
-
<p className="text-
|
|
268
|
+
<p className="text-sec-600 mb-6">
|
|
265
269
|
We encountered an error while loading this page.
|
|
266
270
|
</p>
|
|
267
271
|
</div>
|
|
268
272
|
|
|
269
273
|
<button
|
|
270
274
|
onClick={resetError}
|
|
271
|
-
className="w-full px-4 py-2 bg-
|
|
275
|
+
className="w-full px-4 py-2 bg-main-600 text-main-50 rounded-md hover:bg-main-700 transition-colors focus:outline-none focus:ring-2 focus:ring-main-500 focus:ring-offset-2"
|
|
272
276
|
>
|
|
273
277
|
Try Again
|
|
274
278
|
</button>
|