@jmruthers/pace-core 0.6.6 → 0.6.7
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/{scripts/audit/audit-dependencies.cjs → audit-tool/00-dependencies.cjs} +12 -13
- package/audit-tool/audits/01-pace-core-compliance.cjs +556 -0
- package/audit-tool/audits/02-project-structure.cjs +255 -0
- package/audit-tool/audits/03-architecture.cjs +196 -0
- package/audit-tool/audits/04-code-quality.cjs +149 -0
- package/audit-tool/audits/05-styling.cjs +224 -0
- package/audit-tool/audits/06-security-rbac.cjs +544 -0
- package/audit-tool/audits/07-api-tech-stack.cjs +301 -0
- package/audit-tool/audits/08-testing-documentation.cjs +202 -0
- package/audit-tool/audits/09-operations.cjs +208 -0
- package/audit-tool/index.cjs +291 -0
- package/audit-tool/utils/code-utils.cjs +218 -0
- package/audit-tool/utils/file-utils.cjs +230 -0
- package/audit-tool/utils/report-utils.cjs +241 -0
- package/cursor-rules/00-standards-overview.mdc +156 -0
- package/cursor-rules/{00-pace-core-compliance.mdc → 01-pace-core-compliance.mdc} +187 -34
- package/cursor-rules/02-project-structure.mdc +37 -5
- package/cursor-rules/{03-solid-principles.mdc → 03-architecture.mdc} +125 -11
- package/cursor-rules/04-code-quality.mdc +419 -0
- package/cursor-rules/{08-markup-quality.mdc → 05-styling.mdc} +55 -10
- package/cursor-rules/{09-rbac-compliance.mdc → 06-security-rbac.mdc} +62 -6
- package/cursor-rules/07-api-tech-stack.mdc +377 -0
- package/cursor-rules/08-testing-documentation.mdc +324 -0
- package/cursor-rules/09-operations.mdc +365 -0
- package/dist/DataTable-7PMH7XN7.js +15 -0
- package/dist/{DataTable-2N_tqbfq.d.ts → DataTable-DRUIgtUH.d.ts} +1 -1
- package/dist/{PublicPageProvider-BBH6Vqg7.d.ts → PublicPageProvider-DlsCaR5v.d.ts} +26 -16
- package/dist/{chunk-FENMYN2U.js → chunk-5X4QLXRG.js} +1 -3
- package/dist/{chunk-4T7OBVTU.js → chunk-6F3IILHI.js} +1 -1
- package/dist/{chunk-SD6WQY43.js → chunk-7ILTDCL2.js} +9 -1
- package/dist/{chunk-3QC3KRHK.js → chunk-A3W6LW53.js} +16 -1
- package/dist/{chunk-7TYHROIV.js → chunk-BM4CQ5P3.js} +50 -8
- package/dist/{chunk-2HGJFNAH.js → chunk-FEJLJNWA.js} +1 -15
- package/dist/{chunk-OHIK3MIO.js → chunk-GHYHJTYV.js} +2 -2
- package/dist/{chunk-UIYSCEV7.js → chunk-IUBRCBSY.js} +1 -1
- package/dist/{chunk-LAZMKTTF.js → chunk-JGWDVX64.js} +281 -347
- package/dist/{chunk-MAGBIDNS.js → chunk-L4XMVJKY.js} +2 -2
- package/dist/{chunk-A55DK444.js → chunk-OJ4SKRSV.js} +1 -7
- package/dist/{chunk-ZS5VO5JB.js → chunk-Q7Q7V5NV.js} +406 -451
- package/dist/{chunk-3O3WHILE.js → chunk-VBCS3DUA.js} +236 -60
- package/dist/{chunk-BVP2BCJF.js → chunk-ZKAWKYT4.js} +8 -8
- package/dist/components.d.ts +5 -4
- package/dist/components.js +27 -32
- package/dist/eslint-rules/index.cjs +22 -9
- package/{src/eslint-rules/rules/compliance.cjs → dist/eslint-rules/rules/01-pace-core-compliance.cjs} +184 -23
- package/dist/eslint-rules/rules/04-code-quality.cjs +290 -0
- package/dist/eslint-rules/rules/05-styling.cjs +61 -0
- package/dist/eslint-rules/rules/{rbac.cjs → 06-security-rbac.cjs} +26 -10
- package/dist/eslint-rules/rules/07-api-tech-stack.cjs +263 -0
- package/dist/eslint-rules/rules/08-testing.cjs +94 -0
- package/dist/hooks.d.ts +5 -5
- package/dist/hooks.js +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +18 -17
- package/dist/rbac/index.js +6 -6
- package/dist/theming/runtime.d.ts +14 -1
- package/dist/theming/runtime.js +1 -1
- package/dist/{types-B-K_5VnO.d.ts → types-DXstZpNI.d.ts} +0 -17
- package/dist/{usePublicRouteParams-COZ28Mvq.d.ts → usePublicRouteParams-MamNgwqe.d.ts} +19 -19
- package/dist/utils.d.ts +2 -2
- package/dist/utils.js +8 -8
- package/docs/README.md +1 -1
- package/docs/api/modules.md +47 -31
- package/docs/api-reference/components.md +18 -20
- package/docs/api-reference/hooks.md +80 -80
- package/docs/api-reference/types.md +1 -1
- package/docs/api-reference/utilities.md +1 -1
- package/docs/architecture/README.md +1 -1
- package/docs/core-concepts/events.md +3 -3
- package/docs/core-concepts/organisations.md +6 -6
- package/docs/core-concepts/permissions.md +6 -6
- package/docs/documentation-index.md +12 -18
- package/docs/getting-started/documentation-index.md +1 -1
- package/docs/getting-started/examples/README.md +4 -4
- package/docs/getting-started/examples/full-featured-app.md +1 -1
- package/docs/getting-started/faq.md +2 -2
- package/docs/getting-started/quick-reference.md +4 -4
- package/docs/implementation-guides/authentication.md +15 -15
- package/docs/implementation-guides/component-styling.md +1 -1
- package/docs/implementation-guides/data-tables.md +126 -33
- package/docs/implementation-guides/datatable-rbac-usage.md +1 -1
- package/docs/implementation-guides/dynamic-colors.md +3 -3
- package/docs/implementation-guides/file-upload-storage.md +2 -2
- package/docs/implementation-guides/hierarchical-datatable.md +40 -60
- package/docs/implementation-guides/inactivity-tracking.md +3 -3
- package/docs/implementation-guides/large-datasets.md +3 -2
- package/docs/implementation-guides/organisation-security.md +2 -2
- package/docs/implementation-guides/performance.md +2 -2
- package/docs/implementation-guides/permission-enforcement.md +1 -1
- package/docs/migration/V0.3.44_organisation-context-timing-fix.md +1 -1
- package/docs/migration/V0.4.0_rbac-migration.md +6 -6
- package/docs/rbac/README.md +5 -5
- package/docs/rbac/advanced-patterns.md +6 -6
- package/docs/rbac/api-reference.md +20 -20
- package/docs/rbac/event-based-apps.md +3 -3
- package/docs/rbac/examples.md +41 -41
- package/docs/rbac/getting-started.md +37 -37
- package/docs/rbac/performance.md +1 -1
- package/docs/rbac/quick-start.md +52 -52
- package/docs/rbac/secure-client-protection.md +1 -1
- package/docs/rbac/troubleshooting.md +1 -1
- package/docs/security/README.md +5 -5
- package/docs/standards/0-standards-overview.md +220 -0
- package/docs/standards/{00-pace-core-compliance.md → 1-pace-core-compliance-standards.md} +204 -185
- package/docs/standards/{02-project-structure.md → 2-project-structure-standards.md} +11 -47
- package/docs/standards/3-architecture-standards.md +606 -0
- package/docs/standards/4-code-quality-standards.md +728 -0
- package/docs/standards/{08-markup-quality.md → 5-styling-standards.md} +12 -9
- package/docs/standards/{09-rbac-compliance.md → 6-security-rbac-standards.md} +126 -18
- package/docs/standards/7-api-tech-stack-standards.md +662 -0
- package/docs/standards/8-testing-documentation-standards.md +401 -0
- package/docs/standards/9-operations-standards.md +1102 -0
- package/docs/standards/README.md +203 -104
- package/docs/troubleshooting/README.md +4 -4
- package/docs/troubleshooting/common-issues.md +2 -2
- package/docs/troubleshooting/debugging.md +9 -9
- package/docs/troubleshooting/migration.md +4 -4
- package/eslint-config-pace-core.cjs +21 -10
- package/package.json +6 -5
- package/scripts/install-cursor-rules.cjs +11 -243
- package/scripts/install-eslint-config.cjs +284 -0
- package/src/__tests__/helpers/__tests__/component-test-utils.test.tsx +2 -2
- package/src/__tests__/helpers/__tests__/test-providers.test.tsx +2 -2
- package/src/__tests__/helpers/__tests__/test-utils.test.tsx +10 -10
- package/src/__tests__/integration/UserProfile.test.tsx +14 -14
- package/src/__tests__/rbac/PagePermissionGuard.test.tsx +6 -6
- package/src/__tests__/templates/accessibility.test.template.tsx +9 -9
- package/src/__tests__/templates/component.test.template.tsx +18 -15
- package/src/components/Calendar/Calendar.tsx +201 -47
- package/src/components/ContextSelector/ContextSelector.tsx +137 -153
- package/src/components/DataTable/AUDIT_REPORT.md +293 -0
- package/src/components/DataTable/__tests__/DataTableCore.test.tsx +10 -2
- package/src/components/DataTable/__tests__/a11y.basic.test.tsx +10 -4
- package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +9 -9
- package/src/components/DataTable/components/ColumnFilter.tsx +63 -74
- package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +43 -41
- package/src/components/DataTable/components/DataTableErrorBoundary.tsx +9 -11
- package/src/components/DataTable/components/DataTableLayout.tsx +5 -16
- package/src/components/DataTable/components/EditableRow.tsx +5 -7
- package/src/components/DataTable/components/EmptyState.tsx +10 -9
- package/src/components/DataTable/components/FilterRow.tsx +2 -4
- package/src/components/DataTable/components/ImportModal.tsx +124 -126
- package/src/components/DataTable/components/LoadingState.tsx +5 -6
- package/src/components/DataTable/components/SortIndicator.tsx +50 -0
- package/src/components/DataTable/components/__tests__/COVERAGE_NOTE.md +4 -4
- package/src/components/DataTable/components/__tests__/ColumnFilter.test.tsx +23 -82
- package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.test.tsx +37 -9
- package/src/components/DataTable/components/__tests__/EmptyState.test.tsx +7 -4
- package/src/components/DataTable/components/__tests__/FilterRow.test.tsx +12 -4
- package/src/components/DataTable/components/__tests__/LoadingState.test.tsx +41 -27
- package/src/components/DataTable/components/index.ts +2 -1
- package/src/components/DataTable/types.ts +0 -18
- package/src/components/DataTable/utils/a11yUtils.ts +17 -0
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +2 -1
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +11 -15
- package/src/components/DateTimeField/DateTimeField.tsx +7 -8
- package/src/components/Dialog/Dialog.test.tsx +1 -0
- package/src/components/Dialog/Dialog.tsx +25 -8
- package/src/components/ErrorBoundary/ErrorBoundary.tsx +77 -79
- package/src/components/FileUpload/FileUpload.test.tsx +52 -14
- package/src/components/FileUpload/FileUpload.tsx +112 -130
- package/src/components/Progress/Progress.tsx +2 -4
- package/src/components/ProtectedRoute/ProtectedRoute.tsx +8 -8
- package/src/components/Select/Select.tsx +86 -77
- package/src/components/Select/types.ts +3 -0
- package/src/hooks/__tests__/ServiceHooks.test.tsx +16 -16
- package/src/hooks/__tests__/hooks.integration.test.tsx +49 -49
- package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +97 -97
- package/src/hooks/public/usePublicEvent.ts +5 -5
- package/src/hooks/public/usePublicEventLogo.ts +5 -5
- package/src/hooks/public/usePublicFileDisplay.ts +2 -2
- package/src/hooks/public/usePublicRouteParams.ts +5 -5
- package/src/hooks/useAppConfig.ts +2 -2
- package/src/hooks/useEventTheme.test.ts +7 -7
- package/src/hooks/useEventTheme.ts +1 -4
- package/src/hooks/useFileDisplay.ts +2 -2
- package/src/providers/UnifiedAuthProvider.smoke.test.tsx +21 -21
- package/src/providers/__tests__/AuthProvider.test.tsx +21 -21
- package/src/providers/__tests__/EventProvider.test.tsx +61 -61
- package/src/providers/__tests__/InactivityProvider.test.tsx +56 -56
- package/src/providers/__tests__/OrganisationProvider.test.tsx +75 -75
- package/src/providers/__tests__/ProviderLifecycle.test.tsx +37 -37
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +103 -103
- package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +7 -7
- package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +10 -10
- package/src/styles/core.css +7 -0
- package/src/theming/__tests__/parseEventColours.test.ts +9 -3
- package/src/theming/parseEventColours.ts +22 -10
- package/src/utils/__tests__/lazyLoad.unit.test.tsx +42 -39
- package/src/utils/storage/README.md +1 -1
- package/cursor-rules/01-standards-compliance.mdc +0 -285
- package/cursor-rules/04-testing-standards.mdc +0 -270
- package/cursor-rules/05-bug-reports-and-features.mdc +0 -248
- package/cursor-rules/06-code-quality.mdc +0 -311
- package/cursor-rules/07-tech-stack-compliance.mdc +0 -216
- package/cursor-rules/10-error-handling-patterns.mdc +0 -179
- package/cursor-rules/11-performance-optimization.mdc +0 -169
- package/cursor-rules/12-ci-cd-integration.mdc +0 -150
- package/dist/DataTable-LRJL4IRV.js +0 -15
- package/dist/eslint-rules/rules/compliance.cjs +0 -348
- package/dist/eslint-rules/rules/components.cjs +0 -113
- package/dist/eslint-rules/rules/imports.cjs +0 -102
- package/docs/best-practices/README.md +0 -472
- package/docs/best-practices/accessibility.md +0 -604
- package/docs/best-practices/common-patterns.md +0 -516
- package/docs/best-practices/deployment.md +0 -1103
- package/docs/best-practices/performance.md +0 -1328
- package/docs/best-practices/security.md +0 -940
- package/docs/best-practices/testing.md +0 -1034
- package/docs/rbac/compliance/compliance-guide.md +0 -544
- package/docs/standards/01-standards-compliance.md +0 -188
- package/docs/standards/03-solid-principles.md +0 -39
- package/docs/standards/04-testing-standards.md +0 -36
- package/docs/standards/05-bug-reports-and-features.md +0 -27
- package/docs/standards/06-code-quality.md +0 -34
- package/docs/standards/07-tech-stack-compliance.md +0 -30
- package/docs/standards/10-error-handling-patterns.md +0 -401
- package/docs/standards/11-performance-optimization.md +0 -348
- package/docs/standards/12-ci-cd-integration.md +0 -370
- package/docs/standards/ALIGNMENT_REVIEW_SUMMARY.md +0 -192
- package/scripts/audit/audit-compliance.cjs +0 -1295
- package/scripts/audit/audit-components.cjs +0 -260
- package/scripts/audit/audit-rbac.cjs +0 -954
- package/scripts/audit/audit-standards.cjs +0 -1268
- package/scripts/audit/index.cjs +0 -1927
- package/src/components/DataTable/components/DataTableBody.tsx +0 -478
- package/src/components/DataTable/components/DraggableColumnHeader.tsx +0 -156
- package/src/components/DataTable/components/ExpandButton.tsx +0 -113
- package/src/components/DataTable/components/GroupHeader.tsx +0 -54
- package/src/components/DataTable/components/ViewRowModal.tsx +0 -68
- package/src/components/DataTable/components/VirtualizedDataTable.tsx +0 -525
- package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +0 -462
- package/src/components/DataTable/components/__tests__/GroupHeader.test.tsx +0 -393
- package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +0 -476
- package/src/components/DataTable/components/__tests__/VirtualizedDataTable.test.tsx +0 -128
- package/src/components/DataTable/core/DataTableContext.tsx +0 -216
- package/src/components/DataTable/core/__tests__/DataTableContext.test.tsx +0 -136
- package/src/components/DataTable/hooks/__tests__/useColumnReordering.test.ts +0 -570
- package/src/components/DataTable/hooks/useColumnReordering.ts +0 -123
- package/src/components/DataTable/utils/debugTools.ts +0 -514
- package/src/eslint-rules/index.cjs +0 -22
- package/src/eslint-rules/rules/components.cjs +0 -113
- package/src/eslint-rules/rules/imports.cjs +0 -102
- package/src/eslint-rules/rules/rbac.cjs +0 -790
- package/src/eslint-rules/utils/helpers.cjs +0 -42
- package/src/eslint-rules/utils/manifest-loader.cjs +0 -75
|
@@ -111,11 +111,11 @@ function App() {
|
|
|
111
111
|
handleSignOutNow,
|
|
112
112
|
} = useUnifiedAuth();
|
|
113
113
|
|
|
114
|
-
if (isLoading) return <
|
|
115
|
-
if (authError) return <
|
|
114
|
+
if (isLoading) return <p>Loading...</p>;
|
|
115
|
+
if (authError) return <p>Error: {authError.message}</p>;
|
|
116
116
|
|
|
117
117
|
return (
|
|
118
|
-
<
|
|
118
|
+
<main>
|
|
119
119
|
{user ? (
|
|
120
120
|
<>
|
|
121
121
|
<p>Welcome, {user.email}</p>
|
|
@@ -129,7 +129,7 @@ function App() {
|
|
|
129
129
|
) : (
|
|
130
130
|
<LoginForm onSignIn={signIn} />
|
|
131
131
|
)}
|
|
132
|
-
</
|
|
132
|
+
</main>
|
|
133
133
|
);
|
|
134
134
|
}
|
|
135
135
|
```
|
|
@@ -220,22 +220,22 @@ function EventManager() {
|
|
|
220
220
|
hasAccess,
|
|
221
221
|
} = useEvents();
|
|
222
222
|
|
|
223
|
-
if (loading) return <
|
|
223
|
+
if (loading) return <p>Loading events...</p>;
|
|
224
224
|
|
|
225
225
|
return (
|
|
226
|
-
<
|
|
226
|
+
<section>
|
|
227
227
|
<h2>Available Events</h2>
|
|
228
228
|
{events.map(event => (
|
|
229
|
-
<
|
|
229
|
+
<section key={event.id}>
|
|
230
230
|
<span>{event.name}</span>
|
|
231
231
|
{hasAccess(event.id) && (
|
|
232
232
|
<button onClick={() => setSelectedEvent(event)}>
|
|
233
233
|
Select
|
|
234
234
|
</button>
|
|
235
235
|
)}
|
|
236
|
-
</
|
|
236
|
+
</section>
|
|
237
237
|
))}
|
|
238
|
-
</
|
|
238
|
+
</section>
|
|
239
239
|
);
|
|
240
240
|
}
|
|
241
241
|
```
|
|
@@ -281,9 +281,9 @@ function UserActions({ userId, scope }) {
|
|
|
281
281
|
}, [hasPermission, isLoading, userId, scope]);
|
|
282
282
|
|
|
283
283
|
return (
|
|
284
|
-
<
|
|
284
|
+
<section>
|
|
285
285
|
{canEdit && <EditButton />}
|
|
286
|
-
</
|
|
286
|
+
</section>
|
|
287
287
|
);
|
|
288
288
|
}
|
|
289
289
|
```
|
|
@@ -312,18 +312,18 @@ function PermissionDisplay({ userId, scope }) {
|
|
|
312
312
|
scope
|
|
313
313
|
});
|
|
314
314
|
|
|
315
|
-
if (isLoading) return <
|
|
316
|
-
if (error) return <
|
|
315
|
+
if (isLoading) return <p>Loading permissions...</p>;
|
|
316
|
+
if (error) return <p>Error: {error.message}</p>;
|
|
317
317
|
|
|
318
318
|
return (
|
|
319
|
-
<
|
|
319
|
+
<section>
|
|
320
320
|
<h3>User Permissions</h3>
|
|
321
321
|
{Object.entries(permissions).map(([pageId, operations]) => (
|
|
322
|
-
<
|
|
322
|
+
<p key={pageId}>
|
|
323
323
|
<strong>{pageId}:</strong> {operations.join(', ')}
|
|
324
|
-
</
|
|
324
|
+
</p>
|
|
325
325
|
))}
|
|
326
|
-
</
|
|
326
|
+
</section>
|
|
327
327
|
);
|
|
328
328
|
}
|
|
329
329
|
```
|
|
@@ -352,13 +352,13 @@ function AccessLevelDisplay({ userId, scope }) {
|
|
|
352
352
|
scope
|
|
353
353
|
});
|
|
354
354
|
|
|
355
|
-
if (isLoading) return <
|
|
356
|
-
if (error) return <
|
|
355
|
+
if (isLoading) return <p>Loading access level...</p>;
|
|
356
|
+
if (error) return <p>Error: {error.message}</p>;
|
|
357
357
|
|
|
358
358
|
return (
|
|
359
|
-
<
|
|
359
|
+
<section>
|
|
360
360
|
<p>Access Level: {accessLevel || 'None'}</p>
|
|
361
|
-
</
|
|
361
|
+
</section>
|
|
362
362
|
);
|
|
363
363
|
}
|
|
364
364
|
```
|
|
@@ -406,10 +406,10 @@ function NotificationExample() {
|
|
|
406
406
|
};
|
|
407
407
|
|
|
408
408
|
return (
|
|
409
|
-
<
|
|
409
|
+
<section>
|
|
410
410
|
<button onClick={handleSuccess}>Show Success</button>
|
|
411
411
|
<button onClick={handleError}>Show Error</button>
|
|
412
|
-
</
|
|
412
|
+
</section>
|
|
413
413
|
);
|
|
414
414
|
}
|
|
415
415
|
```
|
|
@@ -460,23 +460,23 @@ function UserForm() {
|
|
|
460
460
|
|
|
461
461
|
return (
|
|
462
462
|
<form onSubmit={handleSubmit(onSubmit)}>
|
|
463
|
-
<
|
|
463
|
+
<section>
|
|
464
464
|
<label>Name</label>
|
|
465
465
|
<input {...register('name')} />
|
|
466
466
|
{errors.name && <span>{errors.name.message}</span>}
|
|
467
|
-
</
|
|
467
|
+
</section>
|
|
468
468
|
|
|
469
|
-
<
|
|
469
|
+
<section>
|
|
470
470
|
<label>Email</label>
|
|
471
471
|
<input type="email" {...register('email')} />
|
|
472
472
|
{errors.email && <span>{errors.email.message}</span>}
|
|
473
|
-
</
|
|
473
|
+
</section>
|
|
474
474
|
|
|
475
|
-
<
|
|
475
|
+
<section>
|
|
476
476
|
<label>Age</label>
|
|
477
477
|
<input type="number" {...register('age')} />
|
|
478
478
|
{errors.age && <span>{errors.age.message}</span>}
|
|
479
|
-
</
|
|
479
|
+
</section>
|
|
480
480
|
|
|
481
481
|
<button type="submit" disabled={isSubmitting}>
|
|
482
482
|
{isSubmitting ? 'Submitting...' : 'Submit'}
|
|
@@ -654,18 +654,18 @@ function Dropdown() {
|
|
|
654
654
|
useClickOutside(dropdownRef, () => setIsOpen(false));
|
|
655
655
|
|
|
656
656
|
return (
|
|
657
|
-
<
|
|
657
|
+
<nav ref={dropdownRef}>
|
|
658
658
|
<button onClick={() => setIsOpen(!isOpen)}>
|
|
659
659
|
Toggle Dropdown
|
|
660
660
|
</button>
|
|
661
661
|
{isOpen && (
|
|
662
|
-
<
|
|
663
|
-
<
|
|
664
|
-
<
|
|
665
|
-
<
|
|
666
|
-
</
|
|
662
|
+
<section className="dropdown-content">
|
|
663
|
+
<button>Option 1</button>
|
|
664
|
+
<button>Option 2</button>
|
|
665
|
+
<button>Option 3</button>
|
|
666
|
+
</section>
|
|
667
667
|
)}
|
|
668
|
-
</
|
|
668
|
+
</nav>
|
|
669
669
|
);
|
|
670
670
|
}
|
|
671
671
|
```
|
|
@@ -696,11 +696,11 @@ function PerformanceDashboard() {
|
|
|
696
696
|
const metrics = usePerformanceMonitor();
|
|
697
697
|
|
|
698
698
|
return (
|
|
699
|
-
<
|
|
699
|
+
<section>
|
|
700
700
|
<p>Render time: {metrics.renderTime}ms</p>
|
|
701
701
|
<p>Memory usage: {metrics.memoryUsage}MB</p>
|
|
702
702
|
<p>Components: {metrics.componentCount}</p>
|
|
703
|
-
</
|
|
703
|
+
</section>
|
|
704
704
|
);
|
|
705
705
|
}
|
|
706
706
|
```
|
|
@@ -829,7 +829,7 @@ function PublicEventPage() {
|
|
|
829
829
|
console.log('Event Code:', eventCode);
|
|
830
830
|
console.log('Report ID:', reportId);
|
|
831
831
|
|
|
832
|
-
return <
|
|
832
|
+
return <p>Event: {eventCode}</p>;
|
|
833
833
|
}
|
|
834
834
|
```
|
|
835
835
|
|
|
@@ -856,11 +856,11 @@ function PublicEventPage() {
|
|
|
856
856
|
const { eventCode } = usePublicRouteParams({ fetchEventData: false });
|
|
857
857
|
const { event, isLoading, error, refetch } = usePublicEvent(eventCode || '');
|
|
858
858
|
|
|
859
|
-
if (isLoading) return <
|
|
860
|
-
if (error) return <
|
|
861
|
-
if (!event) return <
|
|
862
|
-
|
|
863
|
-
return <
|
|
859
|
+
if (isLoading) return <p>Loading...</p>;
|
|
860
|
+
if (error) return <p>Error: {error.message}</p>;
|
|
861
|
+
if (!event) return <p>Event not found</p>;
|
|
862
|
+
|
|
863
|
+
return <p>Event: {event.event_name}</p>;
|
|
864
864
|
}
|
|
865
865
|
```
|
|
866
866
|
|
|
@@ -880,10 +880,10 @@ function MyComponent() {
|
|
|
880
880
|
const isPublicPage = useIsPublicPage();
|
|
881
881
|
|
|
882
882
|
if (isPublicPage) {
|
|
883
|
-
return <
|
|
883
|
+
return <section>This is a public page</section>;
|
|
884
884
|
}
|
|
885
885
|
|
|
886
|
-
return <
|
|
886
|
+
return <section>This is an authenticated page</section>;
|
|
887
887
|
}
|
|
888
888
|
```
|
|
889
889
|
|
|
@@ -912,7 +912,7 @@ function PublicComponent() {
|
|
|
912
912
|
|
|
913
913
|
console.log('Supabase URL:', environment.supabaseUrl);
|
|
914
914
|
|
|
915
|
-
return <
|
|
915
|
+
return <section>Public component</section>;
|
|
916
916
|
}
|
|
917
917
|
```
|
|
918
918
|
|
|
@@ -973,16 +973,16 @@ function MyComponent() {
|
|
|
973
973
|
});
|
|
974
974
|
|
|
975
975
|
return (
|
|
976
|
-
<
|
|
976
|
+
<section>
|
|
977
977
|
<p>Idle: {isIdle ? 'Yes' : 'No'}</p>
|
|
978
978
|
<p>Time remaining: {Math.floor(timeRemaining / 1000)}s</p>
|
|
979
979
|
{showWarning && (
|
|
980
|
-
<
|
|
980
|
+
<section>
|
|
981
981
|
<p>You will be signed out soon due to inactivity.</p>
|
|
982
982
|
<button onClick={resetActivity}>Stay Active</button>
|
|
983
|
-
</
|
|
983
|
+
</section>
|
|
984
984
|
)}
|
|
985
|
-
</
|
|
985
|
+
</section>
|
|
986
986
|
);
|
|
987
987
|
}
|
|
988
988
|
```
|
|
@@ -1050,10 +1050,10 @@ function SecureComponent() {
|
|
|
1050
1050
|
};
|
|
1051
1051
|
|
|
1052
1052
|
return (
|
|
1053
|
-
<
|
|
1053
|
+
<section>
|
|
1054
1054
|
<p>Super Admin: {superAdminContext.isSuperAdmin ? 'Yes' : 'No'}</p>
|
|
1055
1055
|
<button onClick={handleSecureAction}>Perform Secure Action</button>
|
|
1056
|
-
</
|
|
1056
|
+
</section>
|
|
1057
1057
|
);
|
|
1058
1058
|
}
|
|
1059
1059
|
```
|
|
@@ -1105,15 +1105,15 @@ function FileUpload() {
|
|
|
1105
1105
|
};
|
|
1106
1106
|
|
|
1107
1107
|
return (
|
|
1108
|
-
<
|
|
1108
|
+
<section>
|
|
1109
1109
|
<input
|
|
1110
1110
|
type="file"
|
|
1111
1111
|
onChange={(e) => e.target.files?.[0] && handleFileUpload(e.target.files[0])}
|
|
1112
1112
|
disabled={isLoading}
|
|
1113
1113
|
/>
|
|
1114
|
-
{isLoading && <
|
|
1115
|
-
{error && <
|
|
1116
|
-
</
|
|
1114
|
+
{isLoading && <p>Uploading...</p>}
|
|
1115
|
+
{error && <p>Error: {error.message}</p>}
|
|
1116
|
+
</section>
|
|
1117
1117
|
);
|
|
1118
1118
|
}
|
|
1119
1119
|
```
|
|
@@ -1160,30 +1160,30 @@ function FileUploadWithProgress() {
|
|
|
1160
1160
|
};
|
|
1161
1161
|
|
|
1162
1162
|
return (
|
|
1163
|
-
<
|
|
1163
|
+
<section>
|
|
1164
1164
|
<input
|
|
1165
1165
|
type="file"
|
|
1166
1166
|
onChange={(e) => e.target.files?.[0] && handleFileUpload(e.target.files[0])}
|
|
1167
1167
|
disabled={isUploading}
|
|
1168
1168
|
/>
|
|
1169
1169
|
{isUploading && (
|
|
1170
|
-
<
|
|
1171
|
-
<
|
|
1172
|
-
<
|
|
1173
|
-
<
|
|
1170
|
+
<section>
|
|
1171
|
+
<p>Uploading... {uploadProgress}%</p>
|
|
1172
|
+
<section className="w-full bg-sec-200 rounded-full h-2" role="progressbar" aria-valuenow={uploadProgress} aria-valuemin={0} aria-valuemax={100}>
|
|
1173
|
+
<section
|
|
1174
1174
|
className="bg-main-600 h-2 rounded-full transition-all duration-300"
|
|
1175
1175
|
style={{ width: `${uploadProgress}%` }}
|
|
1176
1176
|
/>
|
|
1177
|
-
</
|
|
1178
|
-
</
|
|
1177
|
+
</section>
|
|
1178
|
+
</section>
|
|
1179
1179
|
)}
|
|
1180
1180
|
{error && (
|
|
1181
|
-
<
|
|
1182
|
-
<
|
|
1181
|
+
<section>
|
|
1182
|
+
<p>Error: {error.message}</p>
|
|
1183
1183
|
<button onClick={reset}>Try Again</button>
|
|
1184
|
-
</
|
|
1184
|
+
</section>
|
|
1185
1185
|
)}
|
|
1186
|
-
</
|
|
1186
|
+
</section>
|
|
1187
1187
|
);
|
|
1188
1188
|
}
|
|
1189
1189
|
```
|
|
@@ -1235,12 +1235,12 @@ function AppSettings() {
|
|
|
1235
1235
|
});
|
|
1236
1236
|
};
|
|
1237
1237
|
|
|
1238
|
-
if (isLoading) return <
|
|
1239
|
-
if (error) return <
|
|
1240
|
-
if (!config) return <
|
|
1238
|
+
if (isLoading) return <p>Loading configuration...</p>;
|
|
1239
|
+
if (error) return <p>Error: {error.message}</p>;
|
|
1240
|
+
if (!config) return <p>No configuration available</p>;
|
|
1241
1241
|
|
|
1242
1242
|
return (
|
|
1243
|
-
<
|
|
1243
|
+
<section>
|
|
1244
1244
|
<h2>App Configuration</h2>
|
|
1245
1245
|
<p>App Name: {config.appName}</p>
|
|
1246
1246
|
<p>Version: {config.version}</p>
|
|
@@ -1257,7 +1257,7 @@ function AppSettings() {
|
|
|
1257
1257
|
{name}
|
|
1258
1258
|
</label>
|
|
1259
1259
|
))}
|
|
1260
|
-
</
|
|
1260
|
+
</section>
|
|
1261
1261
|
);
|
|
1262
1262
|
}
|
|
1263
1263
|
```
|
|
@@ -1295,9 +1295,9 @@ function Modal({ children, onClose }) {
|
|
|
1295
1295
|
});
|
|
1296
1296
|
|
|
1297
1297
|
return (
|
|
1298
|
-
<
|
|
1298
|
+
<section ref={containerRef}>
|
|
1299
1299
|
{children}
|
|
1300
|
-
</
|
|
1300
|
+
</section>
|
|
1301
1301
|
);
|
|
1302
1302
|
}
|
|
1303
1303
|
```
|
|
@@ -1333,9 +1333,9 @@ function Dialog({ isOpen, children, onClose }) {
|
|
|
1333
1333
|
if (!isOpen) return null;
|
|
1334
1334
|
|
|
1335
1335
|
return (
|
|
1336
|
-
<
|
|
1336
|
+
<section ref={containerRef}>
|
|
1337
1337
|
{children}
|
|
1338
|
-
</
|
|
1338
|
+
</section>
|
|
1339
1339
|
);
|
|
1340
1340
|
}
|
|
1341
1341
|
```
|
|
@@ -1391,9 +1391,9 @@ function ResponsiveLayout({ children }) {
|
|
|
1391
1391
|
const isMobile = useIsMobile();
|
|
1392
1392
|
|
|
1393
1393
|
return (
|
|
1394
|
-
<
|
|
1394
|
+
<section className={isMobile ? 'mobile' : 'desktop'}>
|
|
1395
1395
|
{children}
|
|
1396
|
-
</
|
|
1396
|
+
</section>
|
|
1397
1397
|
);
|
|
1398
1398
|
}
|
|
1399
1399
|
```
|
|
@@ -1491,7 +1491,7 @@ import { usePerformanceMonitor } from '@jmruthers/pace-core';
|
|
|
1491
1491
|
function PerformanceDashboard() {
|
|
1492
1492
|
const metrics = usePerformanceMonitor();
|
|
1493
1493
|
|
|
1494
|
-
return <
|
|
1494
|
+
return <p>Render time: {metrics.renderTime}ms</p>;
|
|
1495
1495
|
}
|
|
1496
1496
|
```
|
|
1497
1497
|
|
|
@@ -1048,7 +1048,7 @@ All types in `@jmruthers/pace-core` are designed to provide:
|
|
|
1048
1048
|
- **Generic Support**: Flexible types that work with your data
|
|
1049
1049
|
- **Strict Mode**: Compatible with TypeScript strict mode
|
|
1050
1050
|
|
|
1051
|
-
For more information about using types effectively, see the [
|
|
1051
|
+
For more information about using types effectively, see the [Code Quality Standards](../standards/4-code-quality-standards.md) (TypeScript rules).
|
|
1052
1052
|
|
|
1053
1053
|
## ♿ Accessibility
|
|
1054
1054
|
|
|
@@ -1204,7 +1204,7 @@ export {
|
|
|
1204
1204
|
- Validate input parameters
|
|
1205
1205
|
- Return consistent types
|
|
1206
1206
|
|
|
1207
|
-
For more information about using utilities effectively, see the [
|
|
1207
|
+
For more information about using utilities effectively, see the [Code Quality Standards](../standards/4-code-quality-standards.md) and [Architecture Standards](../standards/3-architecture-standards.md).
|
|
1208
1208
|
|
|
1209
1209
|
## ♿ Accessibility
|
|
1210
1210
|
|
|
@@ -125,7 +125,7 @@ ComponentName/
|
|
|
125
125
|
|
|
126
126
|
### Component Design Patterns
|
|
127
127
|
|
|
128
|
-
1. **Compound Components**: Components that work together (e.g., DataTable + DataTableToolbar +
|
|
128
|
+
1. **Compound Components**: Components that work together (e.g., DataTable + DataTableToolbar + UnifiedTableBody)
|
|
129
129
|
2. **Render Props**: Flexible rendering patterns for complex components
|
|
130
130
|
3. **Controlled/Uncontrolled**: Support for both controlled and uncontrolled usage
|
|
131
131
|
4. **Composition**: Components that can be composed together
|
|
@@ -273,7 +273,7 @@ function EventScopedData() {
|
|
|
273
273
|
}, [selectedEvent]);
|
|
274
274
|
|
|
275
275
|
if (!selectedEvent) {
|
|
276
|
-
return <
|
|
276
|
+
return <p>Please select an event</p>;
|
|
277
277
|
}
|
|
278
278
|
|
|
279
279
|
if (loading) {
|
|
@@ -585,10 +585,10 @@ function EventScopedComponent() {
|
|
|
585
585
|
const { selectedEvent } = useEvents();
|
|
586
586
|
|
|
587
587
|
if (!selectedEvent) {
|
|
588
|
-
return <
|
|
588
|
+
return <p>Please select an event</p>;
|
|
589
589
|
}
|
|
590
590
|
|
|
591
|
-
return <
|
|
591
|
+
return <section>Content for {selectedEvent.event_name}</section>;
|
|
592
592
|
}
|
|
593
593
|
|
|
594
594
|
// ❌ Avoid - No event context check
|
|
@@ -514,8 +514,8 @@ function OrganisationAwareComponent() {
|
|
|
514
514
|
updateOrganisationSettings,
|
|
515
515
|
} = useOrganisation();
|
|
516
516
|
|
|
517
|
-
if (loading) return <
|
|
518
|
-
if (error) return <
|
|
517
|
+
if (loading) return <p>Loading...</p>;
|
|
518
|
+
if (error) return <p>Error: {error}</p>;
|
|
519
519
|
|
|
520
520
|
return (
|
|
521
521
|
<div>
|
|
@@ -563,10 +563,10 @@ function ProtectedComponent() {
|
|
|
563
563
|
);
|
|
564
564
|
|
|
565
565
|
if (!hasAccess) {
|
|
566
|
-
return <
|
|
566
|
+
return <p>Access denied</p>;
|
|
567
567
|
}
|
|
568
568
|
|
|
569
|
-
return <
|
|
569
|
+
return <section>Protected content</section>;
|
|
570
570
|
}
|
|
571
571
|
```
|
|
572
572
|
|
|
@@ -598,10 +598,10 @@ function DataComponent() {
|
|
|
598
598
|
const { currentOrganisation } = useOrganisation();
|
|
599
599
|
|
|
600
600
|
if (!currentOrganisation) {
|
|
601
|
-
return <
|
|
601
|
+
return <p>Please select an organisation</p>;
|
|
602
602
|
}
|
|
603
603
|
|
|
604
|
-
return <
|
|
604
|
+
return <section>Organisation data</section>;
|
|
605
605
|
}
|
|
606
606
|
```
|
|
607
607
|
|
|
@@ -210,8 +210,8 @@ import { usePagePermission } from '@jmruthers/pace-core';
|
|
|
210
210
|
function AdminDashboard() {
|
|
211
211
|
const { hasAccess, loading } = usePagePermission('admin');
|
|
212
212
|
|
|
213
|
-
if (loading) return <
|
|
214
|
-
if (!hasAccess) return <
|
|
213
|
+
if (loading) return <p>Checking permissions...</p>;
|
|
214
|
+
if (!hasAccess) return <p>Access denied</p>;
|
|
215
215
|
|
|
216
216
|
return (
|
|
217
217
|
<div>
|
|
@@ -305,7 +305,7 @@ function ProtectedComponent({ children, permission }) {
|
|
|
305
305
|
permission
|
|
306
306
|
);
|
|
307
307
|
|
|
308
|
-
if (isLoading) return <
|
|
308
|
+
if (isLoading) return <p>Checking permissions...</p>;
|
|
309
309
|
if (!can) return null; // Or return an access denied component
|
|
310
310
|
|
|
311
311
|
return children;
|
|
@@ -488,7 +488,7 @@ function withPermission(permission: string) {
|
|
|
488
488
|
permission
|
|
489
489
|
);
|
|
490
490
|
|
|
491
|
-
if (isLoading) return <
|
|
491
|
+
if (isLoading) return <p>Checking permissions...</p>;
|
|
492
492
|
if (!can) return null;
|
|
493
493
|
|
|
494
494
|
return <Component {...props} />;
|
|
@@ -547,7 +547,7 @@ function PermissionAwareComponent() {
|
|
|
547
547
|
);
|
|
548
548
|
|
|
549
549
|
if (isLoading) {
|
|
550
|
-
return <
|
|
550
|
+
return <p>Loading permissions...</p>;
|
|
551
551
|
}
|
|
552
552
|
|
|
553
553
|
return (
|
|
@@ -714,7 +714,7 @@ function FeatureFlag({ permission, children }) {
|
|
|
714
714
|
permission
|
|
715
715
|
);
|
|
716
716
|
|
|
717
|
-
if (isLoading) return <
|
|
717
|
+
if (isLoading) return <p>Checking permissions...</p>;
|
|
718
718
|
if (!can) return null;
|
|
719
719
|
|
|
720
720
|
return children;
|
|
@@ -109,30 +109,24 @@ This index mirrors the folder layout in `packages/core/docs/` so teams can quick
|
|
|
109
109
|
- [RBAC security architecture](./architecture/rbac-security-architecture.md)
|
|
110
110
|
- [Database schema requirements](./architecture/database-schema-requirements.md)
|
|
111
111
|
|
|
112
|
-
##
|
|
113
|
-
|
|
114
|
-
- [Overview](./
|
|
115
|
-
- [
|
|
116
|
-
- [
|
|
117
|
-
- [
|
|
118
|
-
- [
|
|
119
|
-
- [
|
|
120
|
-
- [
|
|
112
|
+
## Standards
|
|
113
|
+
|
|
114
|
+
- [Standards Overview](./standards/0-standards-overview.md) – Complete standards system
|
|
115
|
+
- [pace-core Compliance](./standards/1-pace-core-compliance-standards.md) – Using pace-core correctly
|
|
116
|
+
- [Project Structure](./standards/2-project-structure-standards.md) – Code organization
|
|
117
|
+
- [Architecture](./standards/3-architecture-standards.md) – SOLID principles and design
|
|
118
|
+
- [Code Quality](./standards/4-code-quality-standards.md) – TypeScript, accessibility, and code style
|
|
119
|
+
- [Styling](./standards/5-styling-standards.md) – CSS architecture and Tailwind v4
|
|
120
|
+
- [Security & RBAC](./standards/6-security-rbac-standards.md) – RLS policies and RBAC
|
|
121
|
+
- [API & Tech Stack](./standards/7-api-tech-stack-standards.md) – Required technologies and API design
|
|
122
|
+
- [Testing & Documentation](./standards/8-testing-documentation-standards.md) – Testing strategy and docs
|
|
123
|
+
- [Operations](./standards/9-operations-standards.md) – Error handling, performance, CI/CD
|
|
121
124
|
|
|
122
125
|
## Security
|
|
123
126
|
|
|
124
127
|
- [Security posture](./security/README.md)
|
|
125
128
|
- [Security checklist](./security/checklist.md)
|
|
126
129
|
|
|
127
|
-
## Development standards
|
|
128
|
-
|
|
129
|
-
- [Standards overview](./standards/README.md) – Development standards for the project
|
|
130
|
-
- [Architecture Standard](./standards/01-architecture-standard.md) – Core architectural principles
|
|
131
|
-
- [API & RPC Standard](./standards/02-api-and-rpc-standard.md) – API design patterns and database function standards
|
|
132
|
-
- [Component Standard](./standards/03-component-standard.md) – React component development guidelines
|
|
133
|
-
- [Code Style Standard](./standards/04-code-style-standard.md) – Code style and TypeScript conventions
|
|
134
|
-
- [Security Standard](./standards/05-security-standard.md) – Security requirements and best practices
|
|
135
|
-
- [Testing & Documentation Standard](./standards/06-testing-and-docs-standard.md) – Testing strategy and documentation requirements
|
|
136
130
|
|
|
137
131
|
## Meta & maintenance
|
|
138
132
|
|
|
@@ -30,7 +30,7 @@ Follow this checklist after installing `@jmruthers/pace-core`. Each step points
|
|
|
30
30
|
|
|
31
31
|
- ✅ Apply the design system tokens → [Styling usage](../styles/usage.md)
|
|
32
32
|
- ✅ Run the test playbook → [Testing overview](../testing/README.md)
|
|
33
|
-
- ✅ Prepare for production → [
|
|
33
|
+
- ✅ Prepare for production → [Operations Standards](../standards/9-operations-standards.md#cicd-integration) (deployment)
|
|
34
34
|
- ✅ Review security posture → [Security checklist](../security/checklist.md)
|
|
35
35
|
|
|
36
36
|
## Need help?
|
|
@@ -677,8 +677,8 @@ export function MealsPage() {
|
|
|
677
677
|
}
|
|
678
678
|
};
|
|
679
679
|
|
|
680
|
-
if (loading) return <
|
|
681
|
-
if (error) return <
|
|
680
|
+
if (loading) return <p>Loading meals...</p>;
|
|
681
|
+
if (error) return <p>Error: {error}</p>;
|
|
682
682
|
|
|
683
683
|
return (
|
|
684
684
|
<div className="p-6">
|
|
@@ -919,7 +919,7 @@ All examples are designed to be easily customizable:
|
|
|
919
919
|
3. **Examples** → Choose an example above
|
|
920
920
|
4. **Core Concepts** → [Understand the Fundamentals](../core-concepts/)
|
|
921
921
|
5. **Implementation** → [Advanced Patterns](../implementation-guides/)
|
|
922
|
-
6. **Production** → [
|
|
922
|
+
6. **Production** → [Standards](../standards/) - Development standards and best practices
|
|
923
923
|
|
|
924
924
|
## 🆘 Need Help?
|
|
925
925
|
|
|
@@ -932,4 +932,4 @@ All examples are designed to be easily customizable:
|
|
|
932
932
|
- [Authentication Implementation Guide](../implementation-guides/authentication.md) - Complete authentication setup
|
|
933
933
|
- [Data Tables Guide](../implementation-guides/data-tables.md) - Advanced data management
|
|
934
934
|
- [API Reference](../api-reference/) - Complete component documentation
|
|
935
|
-
- [
|
|
935
|
+
- [Standards](../standards/) - Development standards and production guidelines
|
|
@@ -615,4 +615,4 @@ REACT_APP_SUPABASE_ANON_KEY=your-anon-key-here
|
|
|
615
615
|
- **[Core Concepts](../core-concepts/)** - Understand authentication and RBAC
|
|
616
616
|
- **[Implementation Guides](../implementation-guides/)** - Advanced patterns
|
|
617
617
|
- **[API Reference](../api-reference/)** - All components and hooks
|
|
618
|
-
- **[
|
|
618
|
+
- **[Standards](../standards/)** - Development standards and production deployment
|
|
@@ -222,7 +222,7 @@ function MyComponent() {
|
|
|
222
222
|
}
|
|
223
223
|
}, [hasPermission, organisationId]);
|
|
224
224
|
|
|
225
|
-
if (isLoading) return <
|
|
225
|
+
if (isLoading) return <p>Loading...</p>;
|
|
226
226
|
|
|
227
227
|
return <DataTable data={data} />;
|
|
228
228
|
}
|
|
@@ -281,7 +281,7 @@ See [Public Pages Guide](./implementation-guides/public-pages.md).
|
|
|
281
281
|
3. Use React.memo for expensive components
|
|
282
282
|
4. Optimize data table rendering
|
|
283
283
|
|
|
284
|
-
See [Performance
|
|
284
|
+
See [Performance Optimization](../standards/9-operations-standards.md#performance-optimization).
|
|
285
285
|
|
|
286
286
|
## Still Have Questions?
|
|
287
287
|
|