@jmruthers/pace-core 0.5.13 → 0.5.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/dist/{DataTable-NNCMQSDG.js → DataTable-RICY7YDA.js} +3 -3
  2. package/dist/{chunk-AMOT5ZSZ.js → chunk-F6IHN3DC.js} +57 -17
  3. package/dist/chunk-F6IHN3DC.js.map +1 -0
  4. package/dist/{chunk-BUWLPWDA.js → chunk-JPXJGMOO.js} +2 -2
  5. package/dist/{chunk-PILT65PA.js → chunk-JZCNOXSG.js} +2 -2
  6. package/dist/{chunk-5E3YF7HA.js → chunk-MQGGT7FF.js} +35 -31
  7. package/dist/{chunk-5E3YF7HA.js.map → chunk-MQGGT7FF.js.map} +1 -1
  8. package/dist/components.js +3 -3
  9. package/dist/index.js +4 -4
  10. package/dist/rbac/index.js +2 -2
  11. package/dist/utils.js +1 -1
  12. package/docs/api/classes/ErrorBoundary.md +1 -1
  13. package/docs/api/classes/InvalidScopeError.md +1 -1
  14. package/docs/api/classes/MissingUserContextError.md +1 -1
  15. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  16. package/docs/api/classes/PermissionDeniedError.md +1 -1
  17. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  18. package/docs/api/classes/RBACAuditManager.md +1 -1
  19. package/docs/api/classes/RBACCache.md +1 -1
  20. package/docs/api/classes/RBACEngine.md +1 -1
  21. package/docs/api/classes/RBACError.md +1 -1
  22. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  23. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  24. package/docs/api/interfaces/AggregateConfig.md +1 -1
  25. package/docs/api/interfaces/ButtonProps.md +1 -1
  26. package/docs/api/interfaces/CardProps.md +1 -1
  27. package/docs/api/interfaces/ColorPalette.md +1 -1
  28. package/docs/api/interfaces/ColorShade.md +1 -1
  29. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  30. package/docs/api/interfaces/DataTableAction.md +1 -1
  31. package/docs/api/interfaces/DataTableColumn.md +1 -1
  32. package/docs/api/interfaces/DataTableProps.md +1 -1
  33. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  34. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  35. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  36. package/docs/api/interfaces/EventContextType.md +1 -1
  37. package/docs/api/interfaces/EventLogoProps.md +1 -1
  38. package/docs/api/interfaces/EventProviderProps.md +1 -1
  39. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  40. package/docs/api/interfaces/FileUploadProps.md +1 -1
  41. package/docs/api/interfaces/FooterProps.md +1 -1
  42. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  43. package/docs/api/interfaces/InputProps.md +1 -1
  44. package/docs/api/interfaces/LabelProps.md +1 -1
  45. package/docs/api/interfaces/LoginFormProps.md +1 -1
  46. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  47. package/docs/api/interfaces/NavigationContextType.md +1 -1
  48. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  49. package/docs/api/interfaces/NavigationItem.md +1 -1
  50. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  51. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  52. package/docs/api/interfaces/Organisation.md +1 -1
  53. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  54. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  55. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  56. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  57. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  58. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  59. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  60. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  61. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  62. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  63. package/docs/api/interfaces/PaletteData.md +1 -1
  64. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  65. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  66. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  67. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  68. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  69. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  70. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  71. package/docs/api/interfaces/RBACConfig.md +1 -1
  72. package/docs/api/interfaces/RBACContextType.md +1 -1
  73. package/docs/api/interfaces/RBACLogger.md +1 -1
  74. package/docs/api/interfaces/RBACProviderProps.md +1 -1
  75. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  76. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  77. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  78. package/docs/api/interfaces/RouteConfig.md +1 -1
  79. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  80. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  81. package/docs/api/interfaces/StorageConfig.md +1 -1
  82. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  83. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  84. package/docs/api/interfaces/StorageListOptions.md +1 -1
  85. package/docs/api/interfaces/StorageListResult.md +1 -1
  86. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  87. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  88. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  89. package/docs/api/interfaces/StyleImport.md +1 -1
  90. package/docs/api/interfaces/ToastActionElement.md +1 -1
  91. package/docs/api/interfaces/ToastProps.md +1 -1
  92. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  93. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  94. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  95. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  96. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  97. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  98. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  99. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  100. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  101. package/docs/api/interfaces/UserEventAccess.md +1 -1
  102. package/docs/api/interfaces/UserMenuProps.md +1 -1
  103. package/docs/api/interfaces/UserProfile.md +1 -1
  104. package/docs/api/modules.md +8 -8
  105. package/package.json +1 -1
  106. package/src/rbac/components/PagePermissionGuard.tsx +21 -13
  107. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +478 -0
  108. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +157 -0
  109. package/src/rbac/hooks/useCan.test.ts +1 -1
  110. package/src/rbac/hooks/usePermissions.test.ts +5 -8
  111. package/src/rbac/hooks/usePermissions.ts +74 -22
  112. package/dist/chunk-AMOT5ZSZ.js.map +0 -1
  113. /package/dist/{DataTable-NNCMQSDG.js.map → DataTable-RICY7YDA.js.map} +0 -0
  114. /package/dist/{chunk-BUWLPWDA.js.map → chunk-JPXJGMOO.js.map} +0 -0
  115. /package/dist/{chunk-PILT65PA.js.map → chunk-JZCNOXSG.js.map} +0 -0
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / StorageListOptions
1
+ [@jmruthers/pace-core - v0.5.15](../README.md) / [Exports](../modules.md) / StorageListOptions
2
2
 
3
3
  # Interface: StorageListOptions
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / StorageListResult
1
+ [@jmruthers/pace-core - v0.5.15](../README.md) / [Exports](../modules.md) / StorageListResult
2
2
 
3
3
  # Interface: StorageListResult
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / StorageUploadOptions
1
+ [@jmruthers/pace-core - v0.5.15](../README.md) / [Exports](../modules.md) / StorageUploadOptions
2
2
 
3
3
  # Interface: StorageUploadOptions
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / StorageUploadResult
1
+ [@jmruthers/pace-core - v0.5.15](../README.md) / [Exports](../modules.md) / StorageUploadResult
2
2
 
3
3
  # Interface: StorageUploadResult
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / StorageUrlOptions
1
+ [@jmruthers/pace-core - v0.5.15](../README.md) / [Exports](../modules.md) / StorageUrlOptions
2
2
 
3
3
  # Interface: StorageUrlOptions
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / StyleImport
1
+ [@jmruthers/pace-core - v0.5.15](../README.md) / [Exports](../modules.md) / StyleImport
2
2
 
3
3
  # Interface: StyleImport
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / ToastActionElement
1
+ [@jmruthers/pace-core - v0.5.15](../README.md) / [Exports](../modules.md) / ToastActionElement
2
2
 
3
3
  # Interface: ToastActionElement
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / ToastProps
1
+ [@jmruthers/pace-core - v0.5.15](../README.md) / [Exports](../modules.md) / ToastProps
2
2
 
3
3
  # Interface: ToastProps
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / UnifiedAuthContextType
1
+ [@jmruthers/pace-core - v0.5.15](../README.md) / [Exports](../modules.md) / UnifiedAuthContextType
2
2
 
3
3
  # Interface: UnifiedAuthContextType
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / UnifiedAuthProviderProps
1
+ [@jmruthers/pace-core - v0.5.15](../README.md) / [Exports](../modules.md) / UnifiedAuthProviderProps
2
2
 
3
3
  # Interface: UnifiedAuthProviderProps
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / UseInactivityTrackerOptions
1
+ [@jmruthers/pace-core - v0.5.15](../README.md) / [Exports](../modules.md) / UseInactivityTrackerOptions
2
2
 
3
3
  # Interface: UseInactivityTrackerOptions
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / UseInactivityTrackerReturn
1
+ [@jmruthers/pace-core - v0.5.15](../README.md) / [Exports](../modules.md) / UseInactivityTrackerReturn
2
2
 
3
3
  # Interface: UseInactivityTrackerReturn
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / UsePublicEventLogoOptions
1
+ [@jmruthers/pace-core - v0.5.15](../README.md) / [Exports](../modules.md) / UsePublicEventLogoOptions
2
2
 
3
3
  # Interface: UsePublicEventLogoOptions
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / UsePublicEventLogoReturn
1
+ [@jmruthers/pace-core - v0.5.15](../README.md) / [Exports](../modules.md) / UsePublicEventLogoReturn
2
2
 
3
3
  # Interface: UsePublicEventLogoReturn
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / UsePublicEventOptions
1
+ [@jmruthers/pace-core - v0.5.15](../README.md) / [Exports](../modules.md) / UsePublicEventOptions
2
2
 
3
3
  # Interface: UsePublicEventOptions
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / UsePublicEventReturn
1
+ [@jmruthers/pace-core - v0.5.15](../README.md) / [Exports](../modules.md) / UsePublicEventReturn
2
2
 
3
3
  # Interface: UsePublicEventReturn
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / UsePublicRouteParamsReturn
1
+ [@jmruthers/pace-core - v0.5.15](../README.md) / [Exports](../modules.md) / UsePublicRouteParamsReturn
2
2
 
3
3
  # Interface: UsePublicRouteParamsReturn
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / UserEventAccess
1
+ [@jmruthers/pace-core - v0.5.15](../README.md) / [Exports](../modules.md) / UserEventAccess
2
2
 
3
3
  # Interface: UserEventAccess
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / UserMenuProps
1
+ [@jmruthers/pace-core - v0.5.15](../README.md) / [Exports](../modules.md) / UserMenuProps
2
2
 
3
3
  # Interface: UserMenuProps
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / UserProfile
1
+ [@jmruthers/pace-core - v0.5.15](../README.md) / [Exports](../modules.md) / UserProfile
2
2
 
3
3
  # Interface: UserProfile
4
4
 
@@ -1,6 +1,6 @@
1
- [@jmruthers/pace-core - v0.5.13](README.md) / Exports
1
+ [@jmruthers/pace-core - v0.5.15](README.md) / Exports
2
2
 
3
- # @jmruthers/pace-core - v0.5.13
3
+ # @jmruthers/pace-core - v0.5.15
4
4
 
5
5
  **`File`**
6
6
 
@@ -5434,7 +5434,7 @@ function MyComponent() {
5434
5434
 
5435
5435
  #### Defined in
5436
5436
 
5437
- [packages/core/src/rbac/hooks/usePermissions.ts:123](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L123)
5437
+ [packages/core/src/rbac/hooks/usePermissions.ts:175](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L175)
5438
5438
 
5439
5439
  ___
5440
5440
 
@@ -5484,7 +5484,7 @@ function MyComponent() {
5484
5484
 
5485
5485
  #### Defined in
5486
5486
 
5487
- [packages/core/src/rbac/hooks/usePermissions.ts:202](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L202)
5487
+ [packages/core/src/rbac/hooks/usePermissions.ts:254](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L254)
5488
5488
 
5489
5489
  ___
5490
5490
 
@@ -5541,7 +5541,7 @@ function MyComponent() {
5541
5541
 
5542
5542
  #### Defined in
5543
5543
 
5544
- [packages/core/src/rbac/hooks/usePermissions.ts:276](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L276)
5544
+ [packages/core/src/rbac/hooks/usePermissions.ts:328](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L328)
5545
5545
 
5546
5546
  ___
5547
5547
 
@@ -5592,7 +5592,7 @@ function MyComponent() {
5592
5592
 
5593
5593
  #### Defined in
5594
5594
 
5595
- [packages/core/src/rbac/hooks/usePermissions.ts:358](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L358)
5595
+ [packages/core/src/rbac/hooks/usePermissions.ts:410](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L410)
5596
5596
 
5597
5597
  ___
5598
5598
 
@@ -5643,7 +5643,7 @@ function MyComponent() {
5643
5643
 
5644
5644
  #### Defined in
5645
5645
 
5646
- [packages/core/src/rbac/hooks/usePermissions.ts:443](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L443)
5646
+ [packages/core/src/rbac/hooks/usePermissions.ts:495](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L495)
5647
5647
 
5648
5648
  ___
5649
5649
 
@@ -5694,7 +5694,7 @@ function MyComponent() {
5694
5694
 
5695
5695
  #### Defined in
5696
5696
 
5697
- [packages/core/src/rbac/hooks/usePermissions.ts:527](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L527)
5697
+ [packages/core/src/rbac/hooks/usePermissions.ts:579](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/hooks/usePermissions.ts#L579)
5698
5698
 
5699
5699
  ___
5700
5700
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jmruthers/pace-core",
3
- "version": "0.5.13",
3
+ "version": "0.5.15",
4
4
  "description": "Clean, modern React component library with Tailwind v4 styling and native utilities",
5
5
  "private": false,
6
6
  "publishConfig": {
@@ -67,7 +67,7 @@
67
67
  * - RBAC types - Type definitions
68
68
  */
69
69
 
70
- import React, { useMemo, useCallback, useEffect, useState } from 'react';
70
+ import React, { useMemo, useCallback, useEffect, useState, useRef } from 'react';
71
71
  import { useCan } from '../hooks';
72
72
  import { useUnifiedAuth } from '../../providers/UnifiedAuthProvider';
73
73
  import { UUID, Permission, Scope } from '../types';
@@ -132,6 +132,10 @@ export function PagePermissionGuard({
132
132
  const [hasChecked, setHasChecked] = useState(false);
133
133
  const [checkError, setCheckError] = useState<Error | null>(null);
134
134
  const [resolvedScope, setResolvedScope] = useState<Scope | null>(null);
135
+
136
+ // Use ref to avoid infinite re-renders from supabase dependency
137
+ const supabaseRef = useRef(supabase);
138
+ supabaseRef.current = supabase;
135
139
 
136
140
  // Resolve scope - either use provided scope or resolve from context
137
141
  useEffect(() => {
@@ -145,12 +149,12 @@ export function PagePermissionGuard({
145
149
  let appId: string | undefined = undefined;
146
150
 
147
151
  // Try to resolve from database
148
- if (supabase) {
152
+ if (supabaseRef.current) {
149
153
  const appName = getCurrentAppName();
150
154
  if (appName) {
151
155
  try {
152
156
  console.log('[PagePermissionGuard] Resolving app name to ID:', appName);
153
- const { data: app, error } = await supabase
157
+ const { data: app, error } = await supabaseRef.current
154
158
  .from('rbac_apps')
155
159
  .select('id, name, is_active')
156
160
  .eq('name', appName)
@@ -160,7 +164,7 @@ export function PagePermissionGuard({
160
164
  if (error) {
161
165
  console.error('[PagePermissionGuard] Database error resolving app ID:', error);
162
166
  // Check if app exists but is inactive
163
- const { data: inactiveApp } = await supabase
167
+ const { data: inactiveApp } = await supabaseRef.current
164
168
  .from('rbac_apps')
165
169
  .select('id, name, is_active')
166
170
  .eq('name', appName)
@@ -256,9 +260,9 @@ export function PagePermissionGuard({
256
260
  }
257
261
 
258
262
  // If we only have event, resolve organisation from event
259
- if (selectedEventId && supabase) {
263
+ if (selectedEventId && supabaseRef.current) {
260
264
  try {
261
- const eventScope = await createScopeFromEvent(supabase, selectedEventId);
265
+ const eventScope = await createScopeFromEvent(supabaseRef.current, selectedEventId);
262
266
  if (!eventScope) {
263
267
  setCheckError(new Error('Could not resolve organization from event context'));
264
268
  setResolvedScope(null); // Ensure we don't proceed with incomplete scope
@@ -283,7 +287,7 @@ export function PagePermissionGuard({
283
287
  };
284
288
 
285
289
  resolveScope();
286
- }, [scope, selectedOrganisationId, selectedEventId, supabase]);
290
+ }, [scope, selectedOrganisationId, selectedEventId]);
287
291
 
288
292
  // Determine the page ID for permission checking
289
293
  const effectivePageId = useMemo((): string => {
@@ -315,7 +319,7 @@ export function PagePermissionGuard({
315
319
 
316
320
  // Use a stable scope object to prevent unnecessary re-renders
317
321
  const scopeForUseCan = useMemo(() => {
318
- return shouldCheckPermissions ? resolvedScope : { organisationId: 'loading', appId: 'loading', eventId: undefined };
322
+ return shouldCheckPermissions ? resolvedScope : { organisationId: '', appId: '', eventId: undefined };
319
323
  }, [shouldCheckPermissions, resolvedScope]);
320
324
 
321
325
  const { can, isLoading: canIsLoading, error: canError } = useCan(
@@ -392,27 +396,31 @@ export function PagePermissionGuard({
392
396
  willShowLoading: isLoading || !resolvedScope,
393
397
  willShowError: !!checkError,
394
398
  willShowAccessDenied: !can,
395
- willShowContent: !isLoading && !!resolvedScope && !checkError && can
399
+ willShowContent: !isLoading && !!resolvedScope && !checkError && can,
400
+ scopeKey: resolvedScope ? `${resolvedScope.organisationId}-${resolvedScope.eventId}-${resolvedScope.appId}` : 'no-scope'
396
401
  });
397
402
 
403
+ // Create a key to force re-render when scope changes
404
+ const scopeKey = resolvedScope ? `${resolvedScope.organisationId}-${resolvedScope.eventId}-${resolvedScope.appId}` : 'no-scope';
405
+
398
406
  // Show loading state
399
407
  if (isLoading || !resolvedScope) {
400
- return <>{loading}</>;
408
+ return <div key={`loading-${scopeKey}`}>{loading}</div>;
401
409
  }
402
410
 
403
411
  // Show error state
404
412
  if (checkError) {
405
413
  console.error(`[PagePermissionGuard] Permission check failed for page ${pageName}:`, checkError);
406
- return <>{fallback}</>;
414
+ return <div key={`error-${scopeKey}`}>{fallback}</div>;
407
415
  }
408
416
 
409
417
  // Show access denied
410
418
  if (!can) {
411
- return <>{fallback}</>;
419
+ return <div key={`denied-${scopeKey}`}>{fallback}</div>;
412
420
  }
413
421
 
414
422
  // Show protected content
415
- return <>{children}</>;
423
+ return <div key={`content-${scopeKey}`}>{children}</div>;
416
424
  }
417
425
 
418
426
  /**