@jmruthers/pace-core 0.5.72 → 0.5.74

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 (151) hide show
  1. package/dist/{DataTable-RCFGXSPQ.js → DataTable-2QR5TER5.js} +7 -5
  2. package/dist/UnifiedAuthProvider-K4NRGXL4.js +14 -0
  3. package/dist/UnifiedAuthProvider-K4NRGXL4.js.map +1 -0
  4. package/dist/chunk-3SP4P7NS.js +82 -0
  5. package/dist/chunk-3SP4P7NS.js.map +1 -0
  6. package/dist/chunk-B5LK25HV.js +953 -0
  7. package/dist/chunk-B5LK25HV.js.map +1 -0
  8. package/dist/{chunk-BUM2ZPYC.js → chunk-BKVGJVUR.js} +4 -4
  9. package/dist/{chunk-WMYLD5WP.js → chunk-C5Q5LRU5.js} +57 -36
  10. package/dist/chunk-C5Q5LRU5.js.map +1 -0
  11. package/dist/{chunk-6RBH67W7.js → chunk-CDDYJCYU.js} +2 -77
  12. package/dist/chunk-CDDYJCYU.js.map +1 -0
  13. package/dist/{chunk-GDIBOLKV.js → chunk-DG5Z55HH.js} +6 -4
  14. package/dist/{chunk-GDIBOLKV.js.map → chunk-DG5Z55HH.js.map} +1 -1
  15. package/dist/{chunk-2PDTIGS4.js → chunk-H2TNUICK.js} +98 -49
  16. package/dist/chunk-H2TNUICK.js.map +1 -0
  17. package/dist/{chunk-4CET7YQI.js → chunk-IHMMNKNA.js} +11 -947
  18. package/dist/chunk-IHMMNKNA.js.map +1 -0
  19. package/dist/{chunk-C353TCFY.js → chunk-LVQ26TCN.js} +2 -2
  20. package/dist/{chunk-MTI7X73I.js → chunk-ORSMVXO2.js} +7 -5
  21. package/dist/{chunk-MTI7X73I.js.map → chunk-ORSMVXO2.js.map} +1 -1
  22. package/dist/{chunk-67FGPOHX.js → chunk-UJMCGBLS.js} +6 -4
  23. package/dist/{chunk-67FGPOHX.js.map → chunk-UJMCGBLS.js.map} +1 -1
  24. package/dist/{chunk-XC4ZCSO4.js → chunk-V6BHACCH.js} +6 -4
  25. package/dist/{chunk-XC4ZCSO4.js.map → chunk-V6BHACCH.js.map} +1 -1
  26. package/dist/components.js +9 -7
  27. package/dist/components.js.map +1 -1
  28. package/dist/hooks.js +7 -5
  29. package/dist/hooks.js.map +1 -1
  30. package/dist/index.js +19 -16
  31. package/dist/index.js.map +1 -1
  32. package/dist/providers.js +10 -7
  33. package/dist/rbac/index.js +7 -5
  34. package/dist/utils.js +8 -6
  35. package/dist/utils.js.map +1 -1
  36. package/docs/api/classes/ColumnFactory.md +1 -1
  37. package/docs/api/classes/ErrorBoundary.md +1 -1
  38. package/docs/api/classes/InvalidScopeError.md +1 -1
  39. package/docs/api/classes/MissingUserContextError.md +1 -1
  40. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  41. package/docs/api/classes/PermissionDeniedError.md +1 -1
  42. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  43. package/docs/api/classes/RBACAuditManager.md +1 -1
  44. package/docs/api/classes/RBACCache.md +1 -1
  45. package/docs/api/classes/RBACEngine.md +1 -1
  46. package/docs/api/classes/RBACError.md +1 -1
  47. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  48. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  49. package/docs/api/classes/StorageUtils.md +1 -1
  50. package/docs/api/enums/FileCategory.md +1 -1
  51. package/docs/api/interfaces/AggregateConfig.md +1 -1
  52. package/docs/api/interfaces/ButtonProps.md +1 -1
  53. package/docs/api/interfaces/CardProps.md +1 -1
  54. package/docs/api/interfaces/ColorPalette.md +1 -1
  55. package/docs/api/interfaces/ColorShade.md +1 -1
  56. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  57. package/docs/api/interfaces/DataTableAction.md +1 -1
  58. package/docs/api/interfaces/DataTableColumn.md +1 -1
  59. package/docs/api/interfaces/DataTableProps.md +1 -1
  60. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  61. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  62. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  63. package/docs/api/interfaces/EventContextType.md +1 -1
  64. package/docs/api/interfaces/EventLogoProps.md +1 -1
  65. package/docs/api/interfaces/EventProviderProps.md +1 -1
  66. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  67. package/docs/api/interfaces/FileMetadata.md +1 -1
  68. package/docs/api/interfaces/FileReference.md +1 -1
  69. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  70. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  71. package/docs/api/interfaces/FileUploadProps.md +1 -1
  72. package/docs/api/interfaces/FooterProps.md +1 -1
  73. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  74. package/docs/api/interfaces/InputProps.md +1 -1
  75. package/docs/api/interfaces/LabelProps.md +1 -1
  76. package/docs/api/interfaces/LoginFormProps.md +1 -1
  77. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  78. package/docs/api/interfaces/NavigationContextType.md +1 -1
  79. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  80. package/docs/api/interfaces/NavigationItem.md +1 -1
  81. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  82. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  83. package/docs/api/interfaces/Organisation.md +1 -1
  84. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  85. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  86. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  87. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  88. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  89. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  90. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  91. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  92. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  93. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  94. package/docs/api/interfaces/PaletteData.md +1 -1
  95. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  96. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  97. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  98. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  99. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  100. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  101. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  102. package/docs/api/interfaces/RBACConfig.md +1 -1
  103. package/docs/api/interfaces/RBACContextType.md +1 -1
  104. package/docs/api/interfaces/RBACLogger.md +1 -1
  105. package/docs/api/interfaces/RBACProviderProps.md +1 -1
  106. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  107. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  108. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  109. package/docs/api/interfaces/RouteConfig.md +1 -1
  110. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  111. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  112. package/docs/api/interfaces/StorageConfig.md +1 -1
  113. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  114. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  115. package/docs/api/interfaces/StorageListOptions.md +1 -1
  116. package/docs/api/interfaces/StorageListResult.md +1 -1
  117. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  118. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  119. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  120. package/docs/api/interfaces/StyleImport.md +1 -1
  121. package/docs/api/interfaces/SwitchProps.md +1 -1
  122. package/docs/api/interfaces/ToastActionElement.md +1 -1
  123. package/docs/api/interfaces/ToastProps.md +1 -1
  124. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  125. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  126. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  127. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  128. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  129. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  130. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  131. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  132. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  133. package/docs/api/interfaces/UserEventAccess.md +1 -1
  134. package/docs/api/interfaces/UserMenuProps.md +1 -1
  135. package/docs/api/interfaces/UserProfile.md +1 -1
  136. package/docs/api/modules.md +2 -2
  137. package/docs/implementation-guides/data-tables.md +82 -1
  138. package/package.json +1 -1
  139. package/src/components/DataTable/components/DataTableCore.tsx +37 -3
  140. package/src/components/Dialog/Dialog.tsx +2 -2
  141. package/src/components/NavigationMenu/NavigationMenu.tsx +32 -2
  142. package/src/components/PaceAppLayout/PaceAppLayout.tsx +81 -46
  143. package/src/components/Toast/Toast.test.tsx +1 -1
  144. package/src/components/Toast/Toast.tsx +1 -1
  145. package/dist/chunk-2PDTIGS4.js.map +0 -1
  146. package/dist/chunk-4CET7YQI.js.map +0 -1
  147. package/dist/chunk-6RBH67W7.js.map +0 -1
  148. package/dist/chunk-WMYLD5WP.js.map +0 -1
  149. /package/dist/{DataTable-RCFGXSPQ.js.map → DataTable-2QR5TER5.js.map} +0 -0
  150. /package/dist/{chunk-BUM2ZPYC.js.map → chunk-BKVGJVUR.js.map} +0 -0
  151. /package/dist/{chunk-C353TCFY.js.map → chunk-LVQ26TCN.js.map} +0 -0
@@ -6,15 +6,8 @@ import {
6
6
  DebugLogger,
7
7
  cn,
8
8
  init_cn,
9
- init_debugLogger,
10
- init_organisationContext,
11
- setOrganisationContext
12
- } from "./chunk-6RBH67W7.js";
13
- import {
14
- applyPalette,
15
- clearPalette,
16
- init_runtime
17
- } from "./chunk-SMJZMKYN.js";
9
+ init_debugLogger
10
+ } from "./chunk-CDDYJCYU.js";
18
11
  import {
19
12
  __commonJS,
20
13
  __esm,
@@ -1708,10 +1701,10 @@ var require_lodash = __commonJS({
1708
1701
  })();
1709
1702
  var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout, ctxNow = Date2 && Date2.now !== root.Date.now && Date2.now, ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout;
1710
1703
  var nativeCeil = Math2.ceil, nativeFloor = Math2.floor, nativeGetSymbols = Object2.getOwnPropertySymbols, nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined2, nativeIsFinite = context.isFinite, nativeJoin = arrayProto.join, nativeKeys = overArg(Object2.keys, Object2), nativeMax = Math2.max, nativeMin = Math2.min, nativeNow = Date2.now, nativeParseInt = context.parseInt, nativeRandom = Math2.random, nativeReverse = arrayProto.reverse;
1711
- var DataView = getNative(context, "DataView"), Map2 = getNative(context, "Map"), Promise2 = getNative(context, "Promise"), Set = getNative(context, "Set"), WeakMap = getNative(context, "WeakMap"), nativeCreate = getNative(Object2, "create");
1704
+ var DataView = getNative(context, "DataView"), Map = getNative(context, "Map"), Promise2 = getNative(context, "Promise"), Set = getNative(context, "Set"), WeakMap = getNative(context, "WeakMap"), nativeCreate = getNative(Object2, "create");
1712
1705
  var metaMap = WeakMap && new WeakMap();
1713
1706
  var realNames = {};
1714
- var dataViewCtorString = toSource(DataView), mapCtorString = toSource(Map2), promiseCtorString = toSource(Promise2), setCtorString = toSource(Set), weakMapCtorString = toSource(WeakMap);
1707
+ var dataViewCtorString = toSource(DataView), mapCtorString = toSource(Map), promiseCtorString = toSource(Promise2), setCtorString = toSource(Set), weakMapCtorString = toSource(WeakMap);
1715
1708
  var symbolProto = Symbol ? Symbol.prototype : undefined2, symbolValueOf = symbolProto ? symbolProto.valueOf : undefined2, symbolToString = symbolProto ? symbolProto.toString : undefined2;
1716
1709
  function lodash(value) {
1717
1710
  if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
@@ -1956,7 +1949,7 @@ var require_lodash = __commonJS({
1956
1949
  this.size = 0;
1957
1950
  this.__data__ = {
1958
1951
  "hash": new Hash(),
1959
- "map": new (Map2 || ListCache)(),
1952
+ "map": new (Map || ListCache)(),
1960
1953
  "string": new Hash()
1961
1954
  };
1962
1955
  }
@@ -2021,7 +2014,7 @@ var require_lodash = __commonJS({
2021
2014
  var data = this.__data__;
2022
2015
  if (data instanceof ListCache) {
2023
2016
  var pairs = data.__data__;
2024
- if (!Map2 || pairs.length < LARGE_ARRAY_SIZE - 1) {
2017
+ if (!Map || pairs.length < LARGE_ARRAY_SIZE - 1) {
2025
2018
  pairs.push([key, value]);
2026
2019
  this.size = ++data.size;
2027
2020
  return this;
@@ -3765,7 +3758,7 @@ var require_lodash = __commonJS({
3765
3758
  return result2;
3766
3759
  };
3767
3760
  var getTag = baseGetTag;
3768
- if (DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag || Map2 && getTag(new Map2()) != mapTag || Promise2 && getTag(Promise2.resolve()) != promiseTag || Set && getTag(new Set()) != setTag || WeakMap && getTag(new WeakMap()) != weakMapTag) {
3761
+ if (DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag || Map && getTag(new Map()) != mapTag || Promise2 && getTag(Promise2.resolve()) != promiseTag || Set && getTag(new Set()) != setTag || WeakMap && getTag(new WeakMap()) != weakMapTag) {
3769
3762
  getTag = function(value) {
3770
3763
  var result2 = baseGetTag(value), Ctor = result2 == objectTag ? value.constructor : undefined2, ctorString = Ctor ? toSource(Ctor) : "";
3771
3764
  if (ctorString) {
@@ -6500,7 +6493,7 @@ var init_Dialog = __esm({
6500
6493
  {
6501
6494
  ref,
6502
6495
  className: cn(
6503
- "fixed inset-0 z-50 bg-main-950/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
6496
+ "fixed inset-0 z-50 bg-black/50 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
6504
6497
  className
6505
6498
  ),
6506
6499
  ...props
@@ -6629,7 +6622,7 @@ var init_Dialog = __esm({
6629
6622
  onEscapeKeyDown: preventCloseOnEscape ? handleEscapeKeyDown : void 0,
6630
6623
  onPointerDownOutside: handlePointerDownOutside,
6631
6624
  className: cn(
6632
- "fixed left-[50%] top-[50%] z-50 w-full translate-x-[-50%] translate-y-[-50%] border bg-background shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
6625
+ "fixed left-[50%] top-[50%] z-[51] w-full translate-x-[-50%] translate-y-[-50%] border bg-background shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
6633
6626
  // Reset native dialog styles that interfere with our custom styling
6634
6627
  "m-0 p-0 max-w-none max-h-none w-auto h-auto border-0 bg-transparent outline-none",
6635
6628
  // Apply our custom styling
@@ -7274,7 +7267,6 @@ function UnifiedAuthProvider({
7274
7267
  var UnifiedAuthContext, useUnifiedAuth;
7275
7268
  var init_UnifiedAuthProvider = __esm({
7276
7269
  "src/providers/UnifiedAuthProvider.tsx"() {
7277
- "use strict";
7278
7270
  init_AuthProvider();
7279
7271
  init_RBACProvider();
7280
7272
  init_InactivityProvider();
@@ -7289,926 +7281,6 @@ var init_UnifiedAuthProvider = __esm({
7289
7281
  }
7290
7282
  });
7291
7283
 
7292
- // src/providers/OrganisationProvider.tsx
7293
- var OrganisationProvider_exports = {};
7294
- __export(OrganisationProvider_exports, {
7295
- OrganisationProvider: () => OrganisationProvider,
7296
- useOrganisations: () => useOrganisations
7297
- });
7298
- import { createContext as createContext5, useContext as useContext5, useState as useState7, useEffect as useEffect7, useCallback as useCallback7, useMemo as useMemo6, useRef as useRef2 } from "react";
7299
- import { useNavigate } from "react-router-dom";
7300
- import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
7301
- function OrganisationProvider({ children }) {
7302
- const [selectedOrganisation, setSelectedOrganisation] = useState7(null);
7303
- const [organisations, setOrganisations] = useState7([]);
7304
- const [userMemberships, setUserMemberships] = useState7([]);
7305
- const [roleMapState, setRoleMapState] = useState7(/* @__PURE__ */ new Map());
7306
- const [isLoading, setIsLoading] = useState7(true);
7307
- const [error, setError] = useState7(null);
7308
- const [isContextReady, setIsContextReady] = useState7(false);
7309
- const [retryCount, setRetryCount] = useState7(0);
7310
- const isLoadingRef = useRef2(false);
7311
- const lastLoadTimeRef = useRef2(0);
7312
- const hasFailedRef = useRef2(false);
7313
- const abortControllerRef = useRef2(null);
7314
- const { user, session, supabase, signOut } = useUnifiedAuth();
7315
- let navigate = null;
7316
- try {
7317
- navigate = useNavigate();
7318
- } catch (error2) {
7319
- navigate = null;
7320
- }
7321
- const clearAllCachedData = useCallback7(() => {
7322
- localStorage.removeItem(STORAGE_KEYS2.SELECTED_ORGANISATION);
7323
- localStorage.removeItem(STORAGE_KEYS2.ORGANISATION_CONTEXT);
7324
- setSelectedOrganisation(null);
7325
- setOrganisations([]);
7326
- setUserMemberships([]);
7327
- setRoleMapState(/* @__PURE__ */ new Map());
7328
- setError(null);
7329
- setRetryCount(0);
7330
- setIsContextReady(false);
7331
- }, []);
7332
- const setDatabaseOrganisationContext = useCallback7(async (organisation) => {
7333
- if (!supabase || !session) {
7334
- console.warn("[OrganisationProvider] No Supabase client or session available for setting organisation context");
7335
- setIsContextReady(false);
7336
- return;
7337
- }
7338
- try {
7339
- await setOrganisationContext(supabase, organisation.id);
7340
- DebugLogger.log("OrganisationProvider", "Database organisation context set to:", organisation.display_name);
7341
- setIsContextReady(true);
7342
- } catch (error2) {
7343
- console.error("[OrganisationProvider] Failed to set database organisation context:", error2);
7344
- setIsContextReady(false);
7345
- }
7346
- }, [supabase, session]);
7347
- useEffect7(() => {
7348
- if (selectedOrganisation && supabase && session) {
7349
- setIsContextReady(false);
7350
- (async () => {
7351
- await setDatabaseOrganisationContext(selectedOrganisation);
7352
- })();
7353
- } else {
7354
- setIsContextReady(false);
7355
- }
7356
- }, [selectedOrganisation, setDatabaseOrganisationContext, supabase, session]);
7357
- const loadUserOrganisations = useCallback7(async () => {
7358
- const callId = Math.random().toString(36).substr(2, 9);
7359
- console.log(`[OrganisationProvider] Starting loadUserOrganisations call ${callId}`);
7360
- if (!user || !session || !supabase) {
7361
- DebugLogger.log("OrganisationProvider", "Clearing organisation state - no user, session, or supabase client");
7362
- setSelectedOrganisation(null);
7363
- setOrganisations([]);
7364
- setUserMemberships([]);
7365
- setIsLoading(false);
7366
- setError(null);
7367
- return;
7368
- }
7369
- if (isLoadingRef.current) {
7370
- console.log("OrganisationProvider", "Already loading, skipping duplicate load");
7371
- return;
7372
- }
7373
- const now = Date.now();
7374
- if (now - lastLoadTimeRef.current < 2e3) {
7375
- console.log("OrganisationProvider", "Too soon since last load, skipping");
7376
- return;
7377
- }
7378
- if (abortControllerRef.current) {
7379
- abortControllerRef.current.abort();
7380
- }
7381
- abortControllerRef.current = new AbortController();
7382
- const abortSignal = abortControllerRef.current.signal;
7383
- lastLoadTimeRef.current = now;
7384
- isLoadingRef.current = true;
7385
- setIsLoading(true);
7386
- setError(null);
7387
- try {
7388
- DebugLogger.log("OrganisationProvider", "Loading organisations for user:", user.id);
7389
- console.log("[OrganisationProvider] Supabase client ready:", {
7390
- isConnected: !!supabase,
7391
- hasAuth: !!supabase.auth,
7392
- hasRpc: !!supabase.rpc
7393
- });
7394
- let memberships, membershipError;
7395
- try {
7396
- console.log("[OrganisationProvider] Making RPC call to data_user_organisation_roles_get...");
7397
- const timeoutPromise = new Promise((_, reject) => {
7398
- const timeoutId = setTimeout(() => reject(new Error("RPC call timeout after 10 seconds")), 1e4);
7399
- abortSignal.addEventListener("abort", () => {
7400
- clearTimeout(timeoutId);
7401
- reject(new Error("Request aborted"));
7402
- });
7403
- });
7404
- const rpcPromise = supabase.rpc("data_user_organisation_roles_get", {
7405
- p_user_id: user.id,
7406
- p_organisation_id: null
7407
- });
7408
- if (abortSignal.aborted) {
7409
- throw new Error("Request aborted");
7410
- }
7411
- const result = await Promise.race([rpcPromise, timeoutPromise]);
7412
- console.log("[OrganisationProvider] RPC call completed:", {
7413
- hasData: !!result.data,
7414
- hasError: !!result.error,
7415
- dataLength: result.data?.length || 0,
7416
- errorMessage: result.error?.message || "No error"
7417
- });
7418
- memberships = result.data?.filter(
7419
- (role) => ["org_admin", "leader", "member"].includes(role.role)
7420
- ) || [];
7421
- membershipError = result.error;
7422
- } catch (queryError) {
7423
- membershipError = queryError;
7424
- }
7425
- if (membershipError) {
7426
- console.error("[OrganisationProvider] Error loading memberships:", membershipError);
7427
- if (membershipError.message?.includes("timeout")) {
7428
- console.log("[OrganisationProvider] RPC timed out, trying direct database query as fallback...");
7429
- try {
7430
- if (abortSignal.aborted) {
7431
- throw new Error("Request aborted");
7432
- }
7433
- const { data: fallbackData, error: fallbackError } = await supabase.from("rbac_organisation_roles").select(`
7434
- id,
7435
- user_id,
7436
- organisation_id,
7437
- role,
7438
- status,
7439
- granted_at,
7440
- granted_by,
7441
- revoked_at,
7442
- revoked_by,
7443
- notes,
7444
- created_at,
7445
- updated_at,
7446
- organisations!inner(
7447
- id,
7448
- name,
7449
- display_name,
7450
- subscription_tier,
7451
- settings,
7452
- is_active,
7453
- parent_id,
7454
- created_at,
7455
- updated_at
7456
- )
7457
- `).eq("user_id", user.id).eq("status", "active").is("revoked_at", null).in("role", ["org_admin", "leader", "member"]);
7458
- if (fallbackError) {
7459
- console.error("[OrganisationProvider] Fallback query also failed:", fallbackError);
7460
- throw membershipError;
7461
- }
7462
- console.log("[OrganisationProvider] Fallback query successful, got", fallbackData?.length || 0, "memberships");
7463
- memberships = fallbackData || [];
7464
- membershipError = null;
7465
- } catch (fallbackErr) {
7466
- console.error("[OrganisationProvider] Fallback query failed:", fallbackErr);
7467
- throw membershipError;
7468
- }
7469
- } else {
7470
- throw membershipError;
7471
- }
7472
- }
7473
- DebugLogger.log("OrganisationProvider", "Raw memberships data:", memberships);
7474
- if (!memberships || memberships.length === 0) {
7475
- throw new Error("User has no active organisation memberships");
7476
- }
7477
- console.log("[OrganisationProvider] All memberships data:", memberships);
7478
- memberships.forEach((membership, index) => {
7479
- console.log(`[OrganisationProvider] Membership ${index}:`, {
7480
- organisation_id: membership.organisation_id,
7481
- type: typeof membership.organisation_id,
7482
- length: membership.organisation_id ? membership.organisation_id.length : "null/undefined",
7483
- trimmed: membership.organisation_id ? membership.organisation_id.trim() : "null/undefined"
7484
- });
7485
- if (!membership.organisation_id || membership.organisation_id.trim() === "") {
7486
- console.warn(`[OrganisationProvider] Membership ${index} has invalid organisation_id:`, membership);
7487
- }
7488
- });
7489
- const organisationIds = memberships.map((m) => m.organisation_id).filter((id) => {
7490
- if (!id || typeof id !== "string") {
7491
- console.warn("[OrganisationProvider] Invalid organisation ID (not string):", id);
7492
- return false;
7493
- }
7494
- const trimmedId = id.trim();
7495
- if (trimmedId === "") {
7496
- console.warn("[OrganisationProvider] Empty organisation ID found");
7497
- return false;
7498
- }
7499
- const isValidUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(trimmedId);
7500
- if (!isValidUuid) {
7501
- console.warn("[OrganisationProvider] Invalid UUID format:", trimmedId);
7502
- }
7503
- return isValidUuid;
7504
- });
7505
- if (organisationIds.length === 0) {
7506
- console.warn("[OrganisationProvider] No valid organisation IDs found in memberships:", memberships);
7507
- throw new Error("No valid organisation IDs found in memberships");
7508
- }
7509
- DebugLogger.log("OrganisationProvider", "Valid organisation IDs:", organisationIds);
7510
- console.log("[OrganisationProvider] Raw organisation IDs before cleaning:", organisationIds);
7511
- console.log("[OrganisationProvider] Raw organisation IDs types:", organisationIds.map((id) => typeof id));
7512
- console.log("[OrganisationProvider] Raw organisation IDs lengths:", organisationIds.map((id) => id ? id.length : "null/undefined"));
7513
- const cleanOrganisationIds = organisationIds.filter((id) => {
7514
- const isValid = id && typeof id === "string" && id.trim() !== "";
7515
- if (!isValid) {
7516
- console.warn("[OrganisationProvider] Filtering out invalid ID:", { id, type: typeof id, length: id ? id.length : "null/undefined" });
7517
- }
7518
- return isValid;
7519
- }).map((id) => id.trim());
7520
- console.log("[OrganisationProvider] Clean organisation IDs after filtering:", cleanOrganisationIds);
7521
- if (cleanOrganisationIds.length === 0) {
7522
- console.warn("[OrganisationProvider] No clean organisation IDs after filtering:", organisationIds);
7523
- throw new Error("No valid organisation IDs found after cleaning");
7524
- }
7525
- DebugLogger.log("OrganisationProvider", "Clean organisation IDs for query:", cleanOrganisationIds);
7526
- const finalOrganisationIds = cleanOrganisationIds.filter((id) => {
7527
- const isEmpty = !id || id.trim() === "";
7528
- if (isEmpty) {
7529
- console.error("[OrganisationProvider] CRITICAL: Empty string found in final array:", { id, type: typeof id });
7530
- }
7531
- return !isEmpty;
7532
- });
7533
- if (finalOrganisationIds.length !== cleanOrganisationIds.length) {
7534
- console.error("[OrganisationProvider] CRITICAL: Empty strings were filtered out in final validation!");
7535
- console.error("Original:", cleanOrganisationIds);
7536
- console.error("Final:", finalOrganisationIds);
7537
- }
7538
- console.log("[OrganisationProvider] FINAL QUERY ARRAY:", {
7539
- array: finalOrganisationIds,
7540
- length: finalOrganisationIds.length,
7541
- types: finalOrganisationIds.map((id) => typeof id),
7542
- hasEmpty: finalOrganisationIds.some((id) => !id || id.trim() === ""),
7543
- stringified: JSON.stringify(finalOrganisationIds)
7544
- });
7545
- if (finalOrganisationIds.some((id) => !id || id.trim() === "")) {
7546
- console.error("[OrganisationProvider] ABORTING QUERY - Empty string detected in final array!");
7547
- throw new Error("Empty string detected in organisation IDs array - aborting query");
7548
- }
7549
- const safeOrganisationIds = [...finalOrganisationIds].filter((id) => {
7550
- const isValid = id && typeof id === "string" && id.trim() !== "";
7551
- if (!isValid) {
7552
- console.error("[OrganisationProvider] SAFETY FILTER: Removing invalid ID:", { id, type: typeof id });
7553
- }
7554
- return isValid;
7555
- });
7556
- console.log("[OrganisationProvider] SAFE ARRAY FOR QUERY:", {
7557
- original: finalOrganisationIds,
7558
- safe: safeOrganisationIds,
7559
- lengths: { original: finalOrganisationIds.length, safe: safeOrganisationIds.length }
7560
- });
7561
- console.log("[OrganisationProvider] Using direct table query with manual filtering");
7562
- if (abortSignal.aborted) {
7563
- throw new Error("Request aborted");
7564
- }
7565
- const { data: allOrganisations, error: orgError } = await supabase.from("organisations").select("id, name, display_name, subscription_tier, settings, is_active, parent_id, created_at, updated_at");
7566
- if (orgError) {
7567
- console.error("[OrganisationProvider] Error loading organisations:", orgError);
7568
- throw orgError;
7569
- }
7570
- const organisations2 = allOrganisations?.filter(
7571
- (org) => safeOrganisationIds.includes(org.id)
7572
- ) || [];
7573
- const roleMap = /* @__PURE__ */ new Map();
7574
- memberships?.forEach((membership) => {
7575
- roleMap.set(membership.organisation_id, membership.role);
7576
- });
7577
- const orgs = organisations2;
7578
- const activeOrgs = orgs.filter((org) => org.is_active);
7579
- if (activeOrgs.length === 0) {
7580
- throw new Error("User has no access to active organisations");
7581
- }
7582
- DebugLogger.log("OrganisationProvider", "Active organisations:", activeOrgs);
7583
- setOrganisations(activeOrgs);
7584
- setUserMemberships(memberships);
7585
- setRoleMapState(roleMap);
7586
- let initialOrg = null;
7587
- try {
7588
- const persistedOrgString = localStorage.getItem(STORAGE_KEYS2.SELECTED_ORGANISATION);
7589
- if (persistedOrgString) {
7590
- const persistedOrg = JSON.parse(persistedOrgString);
7591
- if (persistedOrg.id && typeof persistedOrg.id === "string" && persistedOrg.id.trim() !== "") {
7592
- const validPersistedOrg = activeOrgs.find((org) => org.id === persistedOrg.id);
7593
- if (validPersistedOrg) {
7594
- initialOrg = validPersistedOrg;
7595
- DebugLogger.log("OrganisationProvider", "Restored persisted organisation:", initialOrg.display_name);
7596
- } else {
7597
- console.warn("[OrganisationProvider] Persisted organisation not found in active orgs, clearing cache");
7598
- localStorage.removeItem(STORAGE_KEYS2.SELECTED_ORGANISATION);
7599
- }
7600
- } else {
7601
- console.warn("[OrganisationProvider] Invalid persisted organisation ID, clearing cache");
7602
- localStorage.removeItem(STORAGE_KEYS2.SELECTED_ORGANISATION);
7603
- }
7604
- }
7605
- } catch (storageError) {
7606
- console.warn("[OrganisationProvider] Failed to restore persisted organisation:", storageError);
7607
- localStorage.removeItem(STORAGE_KEYS2.SELECTED_ORGANISATION);
7608
- }
7609
- if (!initialOrg) {
7610
- const adminMembership = memberships.find((m) => m.role === "org_admin");
7611
- if (adminMembership) {
7612
- const foundOrg = organisations2.find((org) => org.id === adminMembership.organisation_id);
7613
- if (foundOrg) {
7614
- initialOrg = foundOrg;
7615
- DebugLogger.log("OrganisationProvider", "Selected org_admin organisation:", initialOrg.display_name);
7616
- }
7617
- }
7618
- }
7619
- if (!initialOrg) {
7620
- initialOrg = activeOrgs[0];
7621
- DebugLogger.log("OrganisationProvider", "Selected first organisation:", initialOrg.display_name);
7622
- }
7623
- if (!initialOrg) {
7624
- throw new Error("No valid organisation found for user");
7625
- }
7626
- setSelectedOrganisation(initialOrg);
7627
- localStorage.setItem(STORAGE_KEYS2.SELECTED_ORGANISATION, JSON.stringify(initialOrg));
7628
- DebugLogger.log("OrganisationProvider", "Organisation context established:", {
7629
- selectedOrganisation: initialOrg.display_name,
7630
- totalOrganisations: activeOrgs.length,
7631
- userRole: roleMap.get(initialOrg.id)
7632
- });
7633
- setRetryCount(0);
7634
- hasFailedRef.current = false;
7635
- } catch (err) {
7636
- console.error("[OrganisationProvider] Failed to load organisations:", err);
7637
- setError(err);
7638
- setRetryCount((prev) => prev + 1);
7639
- hasFailedRef.current = true;
7640
- clearAllCachedData();
7641
- } finally {
7642
- isLoadingRef.current = false;
7643
- setIsLoading(false);
7644
- abortControllerRef.current = null;
7645
- }
7646
- }, [user, session, supabase, clearAllCachedData]);
7647
- useEffect7(() => {
7648
- if (user && session && supabase && !isLoading && !isLoadingRef.current) {
7649
- if (retryCount >= 3 || hasFailedRef.current) {
7650
- console.error("[OrganisationProvider] Max retry count reached or failed flag set, stopping organisation loading");
7651
- setError(new Error("Failed to load organisations after multiple attempts"));
7652
- setIsLoading(false);
7653
- return;
7654
- }
7655
- if (retryCount > 0 && Date.now() - lastLoadTimeRef.current < 5e3) {
7656
- console.log("[OrganisationProvider] Circuit breaker active - too soon since last attempt");
7657
- return;
7658
- }
7659
- console.log("[OrganisationProvider] Authentication stable, loading organizations... (retry:", retryCount, ")");
7660
- loadUserOrganisations();
7661
- } else if (!user && !session) {
7662
- console.log("[OrganisationProvider] No authentication, clearing organization state");
7663
- setSelectedOrganisation(null);
7664
- setOrganisations([]);
7665
- setUserMemberships([]);
7666
- setRoleMapState(/* @__PURE__ */ new Map());
7667
- setIsLoading(false);
7668
- setError(null);
7669
- setRetryCount(0);
7670
- isLoadingRef.current = false;
7671
- hasFailedRef.current = false;
7672
- localStorage.removeItem(STORAGE_KEYS2.SELECTED_ORGANISATION);
7673
- localStorage.removeItem(STORAGE_KEYS2.ORGANISATION_CONTEXT);
7674
- }
7675
- }, [user, session, supabase, loadUserOrganisations]);
7676
- useEffect7(() => {
7677
- return () => {
7678
- isLoadingRef.current = false;
7679
- hasFailedRef.current = false;
7680
- lastLoadTimeRef.current = 0;
7681
- if (abortControllerRef.current) {
7682
- abortControllerRef.current.abort();
7683
- abortControllerRef.current = null;
7684
- }
7685
- };
7686
- }, []);
7687
- const handleLogoutAndRedirect = useCallback7(async () => {
7688
- try {
7689
- await signOut();
7690
- if (navigate) {
7691
- navigate("/login", { replace: true });
7692
- } else {
7693
- window.location.href = "/login";
7694
- }
7695
- } catch (error2) {
7696
- console.error("[OrganisationProvider] Error during logout:", error2);
7697
- if (navigate) {
7698
- navigate("/login", { replace: true });
7699
- } else {
7700
- window.location.href = "/login";
7701
- }
7702
- }
7703
- }, [signOut, navigate]);
7704
- const ensureOrganisationContext = useCallback7(() => {
7705
- if (!selectedOrganisation) {
7706
- throw new Error("Organisation context is required but not available");
7707
- }
7708
- return selectedOrganisation;
7709
- }, [selectedOrganisation]);
7710
- const getUserRole = useCallback7((orgId) => {
7711
- const targetOrgId = orgId || selectedOrganisation?.id;
7712
- if (!targetOrgId) return "no_access";
7713
- return roleMapState.get(targetOrgId) || "no_access";
7714
- }, [roleMapState, selectedOrganisation]);
7715
- const validateOrganisationAccess = useCallback7((orgId) => {
7716
- return userMemberships.some(
7717
- (m) => m.organisation_id === orgId && m.status === "active" && m.revoked_at === null
7718
- );
7719
- }, [userMemberships]);
7720
- const switchOrganisation = useCallback7(async (orgId) => {
7721
- DebugLogger.log("OrganisationProvider", "Switching to organisation:", orgId);
7722
- if (!validateOrganisationAccess(orgId)) {
7723
- throw new Error(`User does not have access to organisation ${orgId}`);
7724
- }
7725
- const targetOrg = organisations.find((org) => org.id === orgId);
7726
- if (!targetOrg) {
7727
- throw new Error(`Organisation ${orgId} not found in user's organisations`);
7728
- }
7729
- setSelectedOrganisation(targetOrg);
7730
- localStorage.setItem(STORAGE_KEYS2.SELECTED_ORGANISATION, JSON.stringify(targetOrg));
7731
- await setDatabaseOrganisationContext(targetOrg);
7732
- DebugLogger.log("OrganisationProvider", "Switched to organisation:", targetOrg.display_name);
7733
- }, [organisations, validateOrganisationAccess, setDatabaseOrganisationContext]);
7734
- const refreshOrganisations = useCallback7(async () => {
7735
- if (!user || !session || !supabase) return;
7736
- setIsLoading(true);
7737
- }, [user, session, supabase]);
7738
- const getPrimaryOrganisation = useCallback7(() => {
7739
- const rolePriority = ["org_admin", "leader", "member"];
7740
- for (const role of rolePriority) {
7741
- const membership = userMemberships.find((m) => m.role === role);
7742
- if (membership) {
7743
- return organisations.find((org) => org.id === membership.organisation_id) || null;
7744
- }
7745
- }
7746
- return null;
7747
- }, [userMemberships, organisations]);
7748
- const isOrganisationSecure = useCallback7(() => {
7749
- return !!(selectedOrganisation && user);
7750
- }, [selectedOrganisation, user]);
7751
- const buildOrganisationHierarchy = useCallback7((orgs) => {
7752
- const orgMap = /* @__PURE__ */ new Map();
7753
- orgs.forEach((org) => orgMap.set(org.id, org));
7754
- const roots = [];
7755
- orgs.forEach((org) => {
7756
- if (!org.parent_id) {
7757
- roots.push({
7758
- organisation: org,
7759
- children: [],
7760
- depth: 0
7761
- });
7762
- }
7763
- });
7764
- return roots;
7765
- }, []);
7766
- const hasValidOrganisationContext = useMemo6(() => {
7767
- return !!(selectedOrganisation && !isLoading && !error && isContextReady);
7768
- }, [selectedOrganisation, isLoading, error, isContextReady]);
7769
- const contextValue = useMemo6(() => {
7770
- if (!selectedOrganisation) {
7771
- const placeholderOrg = {
7772
- id: "",
7773
- name: "",
7774
- display_name: "",
7775
- subscription_tier: "standard",
7776
- settings: {},
7777
- is_active: false,
7778
- created_at: "",
7779
- updated_at: ""
7780
- };
7781
- return {
7782
- selectedOrganisation: placeholderOrg,
7783
- organisations: [],
7784
- userMemberships: [],
7785
- isLoading,
7786
- error,
7787
- hasValidOrganisationContext: false,
7788
- setSelectedOrganisation: () => {
7789
- },
7790
- switchOrganisation: async () => {
7791
- },
7792
- getUserRole: () => "no_access",
7793
- validateOrganisationAccess: () => false,
7794
- refreshOrganisations: async () => {
7795
- },
7796
- ensureOrganisationContext: () => {
7797
- throw new Error("No organisation context");
7798
- },
7799
- isOrganisationSecure: () => false,
7800
- getPrimaryOrganisation: () => null
7801
- };
7802
- }
7803
- return {
7804
- selectedOrganisation,
7805
- organisations,
7806
- userMemberships,
7807
- isLoading,
7808
- error,
7809
- hasValidOrganisationContext,
7810
- setSelectedOrganisation,
7811
- switchOrganisation,
7812
- getUserRole,
7813
- validateOrganisationAccess,
7814
- refreshOrganisations,
7815
- ensureOrganisationContext,
7816
- isOrganisationSecure,
7817
- getPrimaryOrganisation
7818
- };
7819
- }, [
7820
- selectedOrganisation,
7821
- organisations,
7822
- userMemberships,
7823
- isLoading,
7824
- error,
7825
- hasValidOrganisationContext,
7826
- switchOrganisation,
7827
- getUserRole,
7828
- validateOrganisationAccess,
7829
- refreshOrganisations,
7830
- ensureOrganisationContext,
7831
- isOrganisationSecure,
7832
- getPrimaryOrganisation
7833
- ]);
7834
- if (isLoading || selectedOrganisation && !isContextReady) {
7835
- return /* @__PURE__ */ jsx9("div", { className: "organisation-loading", role: "status", "aria-label": "Loading organisation context", children: /* @__PURE__ */ jsx9("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs5("div", { className: "text-center", children: [
7836
- /* @__PURE__ */ jsx9("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-primary mx-auto mb-4" }),
7837
- /* @__PURE__ */ jsx9("p", { className: "text-muted-foreground", children: isLoading ? "Loading organisation context..." : "Setting up organisation context..." })
7838
- ] }) }) });
7839
- }
7840
- if (error || user && !selectedOrganisation) {
7841
- return /* @__PURE__ */ jsx9("div", { className: "organisation-error", role: "alert", children: /* @__PURE__ */ jsx9("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs5("div", { className: "text-center max-w-md mx-auto p-6", children: [
7842
- /* @__PURE__ */ jsx9("div", { className: "text-destructive mb-4", children: /* @__PURE__ */ jsx9("svg", { className: "h-12 w-12 mx-auto", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx9("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.732-.833-2.464 0L4.35 16.5c-.77.833.192 2.5 1.732 2.5z" }) }) }),
7843
- /* @__PURE__ */ jsx9("h2", { className: "text-xl font-semibold text-foreground mb-2", children: "Organisation Access Required" }),
7844
- /* @__PURE__ */ jsx9("p", { className: "text-muted-foreground mb-4", children: error?.message || "No valid organisation context available. Please contact your administrator to be added to an organisation." }),
7845
- /* @__PURE__ */ jsx9(
7846
- "button",
7847
- {
7848
- onClick: handleLogoutAndRedirect,
7849
- className: "px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90",
7850
- children: "Sign Out"
7851
- }
7852
- )
7853
- ] }) }) });
7854
- }
7855
- return /* @__PURE__ */ jsx9(OrganisationContext.Provider, { value: contextValue, children });
7856
- }
7857
- var OrganisationContext, STORAGE_KEYS2, useOrganisations;
7858
- var init_OrganisationProvider = __esm({
7859
- "src/providers/OrganisationProvider.tsx"() {
7860
- "use strict";
7861
- init_UnifiedAuthProvider();
7862
- init_organisationContext();
7863
- init_debugLogger();
7864
- OrganisationContext = createContext5(void 0);
7865
- STORAGE_KEYS2 = {
7866
- SELECTED_ORGANISATION: "pace-core-selected-organisation",
7867
- ORGANISATION_CONTEXT: "pace-core-organisation-context"
7868
- };
7869
- useOrganisations = () => {
7870
- const context = useContext5(OrganisationContext);
7871
- if (!context) {
7872
- throw new Error("useOrganisations must be used within an OrganisationProvider");
7873
- }
7874
- return context;
7875
- };
7876
- }
7877
- });
7878
-
7879
- // src/providers/EventProvider.tsx
7880
- var EventProvider_exports = {};
7881
- __export(EventProvider_exports, {
7882
- EventProvider: () => EventProvider,
7883
- useEvents: () => useEvents
7884
- });
7885
- import {
7886
- createContext as createContext6,
7887
- useContext as useContext6,
7888
- useState as useState8,
7889
- useEffect as useEffect8,
7890
- useLayoutEffect,
7891
- useCallback as useCallback8,
7892
- useRef as useRef3,
7893
- useMemo as useMemo7
7894
- } from "react";
7895
- import { jsx as jsx10 } from "react/jsx-runtime";
7896
- function getNextEventByDate(events) {
7897
- if (!events || events.length === 0) {
7898
- return null;
7899
- }
7900
- const now = /* @__PURE__ */ new Date();
7901
- const futureEvents = events.filter((event) => {
7902
- if (!event.event_date) return false;
7903
- const eventDate = new Date(event.event_date);
7904
- return eventDate >= now;
7905
- });
7906
- if (futureEvents.length === 0) {
7907
- return null;
7908
- }
7909
- const sortedFutureEvents = futureEvents.sort((a, b) => {
7910
- const dateA = new Date(a.event_date);
7911
- const dateB = new Date(b.event_date);
7912
- return dateA.getTime() - dateB.getTime();
7913
- });
7914
- return sortedFutureEvents[0];
7915
- }
7916
- function EventProvider({ children }) {
7917
- const [events, setEvents] = useState8([]);
7918
- const [selectedEvent, setSelectedEventState] = useState8(null);
7919
- const [isLoading, setIsLoading] = useState8(true);
7920
- const [error, setError] = useState8(null);
7921
- const { user, session, supabase, appName, setSelectedEventId } = useUnifiedAuth();
7922
- const isInitializedRef = useRef3(false);
7923
- const isFetchingRef = useRef3(false);
7924
- const hasAutoSelectedRef = useRef3(false);
7925
- const userClearedEventRef = useRef3(false);
7926
- const setSelectedEventIdRef = useRef3(setSelectedEventId);
7927
- let selectedOrganisation = null;
7928
- let ensureOrganisationContext = null;
7929
- try {
7930
- const orgContext = useOrganisations();
7931
- selectedOrganisation = orgContext.selectedOrganisation;
7932
- ensureOrganisationContext = orgContext.ensureOrganisationContext;
7933
- } catch (error2) {
7934
- console.warn("[EventProvider] Organisation context not available:", error2);
7935
- }
7936
- const loadPersistedEvent = useCallback8(async (events2) => {
7937
- try {
7938
- let persistedEventId = sessionStorage.getItem("pace-core-selected-event");
7939
- if (!persistedEventId) {
7940
- persistedEventId = localStorage.getItem("pace-core-selected-event");
7941
- if (persistedEventId) {
7942
- sessionStorage.setItem("pace-core-selected-event", persistedEventId);
7943
- }
7944
- }
7945
- if (persistedEventId && events2.length > 0) {
7946
- const persistedEvent = events2.find((event) => event.event_id === persistedEventId);
7947
- if (persistedEvent) {
7948
- DebugLogger.log("EventProvider", "Restoring persisted event:", persistedEvent.event_name);
7949
- setSelectedEventState(persistedEvent);
7950
- setSelectedEventId(persistedEventId);
7951
- return true;
7952
- } else {
7953
- DebugLogger.log("EventProvider", "Persisted event not found in current events, clearing storage");
7954
- sessionStorage.removeItem("pace-core-selected-event");
7955
- localStorage.removeItem("pace-core-selected-event");
7956
- }
7957
- }
7958
- } catch (error2) {
7959
- console.warn("[EventProvider] Failed to load persisted event:", error2);
7960
- }
7961
- return false;
7962
- }, [setSelectedEventId]);
7963
- const persistEventSelection = useCallback8((eventId) => {
7964
- try {
7965
- sessionStorage.setItem("pace-core-selected-event", eventId);
7966
- localStorage.setItem("pace-core-selected-event", eventId);
7967
- } catch (error2) {
7968
- console.warn("[EventProvider] Failed to persist event selection:", error2);
7969
- }
7970
- }, []);
7971
- const autoSelectNextEvent = useCallback8((events2) => {
7972
- const nextEvent = getNextEventByDate(events2);
7973
- if (nextEvent) {
7974
- DebugLogger.log("EventProvider", "Auto-selecting next event:", nextEvent.event_name);
7975
- setSelectedEventState(nextEvent);
7976
- setSelectedEventId(nextEvent.event_id);
7977
- persistEventSelection(nextEvent.event_id);
7978
- }
7979
- }, [setSelectedEventId, persistEventSelection]);
7980
- const fetchEvents = useCallback8(async () => {
7981
- if (!user || !session || !supabase || !appName || !selectedOrganisation) {
7982
- DebugLogger.log("EventProvider", "Missing required dependencies, skipping fetch");
7983
- setIsLoading(false);
7984
- return;
7985
- }
7986
- if (isFetchingRef.current) {
7987
- DebugLogger.log("EventProvider", "Already fetching events, skipping");
7988
- return;
7989
- }
7990
- DebugLogger.log("EventProvider", "User and organisation found, fetching events for:", {
7991
- userId: user.id,
7992
- appName,
7993
- organisationId: selectedOrganisation.id,
7994
- organisationName: selectedOrganisation.display_name
7995
- });
7996
- isFetchingRef.current = true;
7997
- let isMounted = true;
7998
- try {
7999
- if (ensureOrganisationContext) {
8000
- await ensureOrganisationContext();
8001
- await setOrganisationContext(supabase, selectedOrganisation.id);
8002
- }
8003
- DebugLogger.log("EventProvider", "Calling data_user_events_get RPC with:", {
8004
- user_id: user.id,
8005
- organisation_id: selectedOrganisation.id,
8006
- app_name: appName
8007
- });
8008
- const { data, error: rpcError } = await supabase.rpc("data_user_events_get", {
8009
- p_user_id: user.id,
8010
- p_organisation_id: selectedOrganisation.id,
8011
- p_app_name: appName
8012
- });
8013
- DebugLogger.log("EventProvider", "RPC response:", {
8014
- data,
8015
- error: rpcError,
8016
- dataLength: data?.length || 0,
8017
- organisationId: selectedOrganisation.id
8018
- });
8019
- if (rpcError) {
8020
- throw new Error(rpcError.message || "Failed to fetch events");
8021
- }
8022
- if (isMounted) {
8023
- const eventsData = data || [];
8024
- console.log("[EventProvider] Loaded events:", eventsData.map((event) => ({
8025
- eventId: event.event_id,
8026
- eventName: event.event_name,
8027
- organisationId: event.organisation_id,
8028
- selectedOrganisationId: selectedOrganisation?.id
8029
- })));
8030
- const transformedEvents = eventsData.map((event) => ({
8031
- id: event.event_id,
8032
- // Use event_id as the primary id
8033
- event_id: event.event_id,
8034
- event_name: event.event_name,
8035
- event_date: event.event_date,
8036
- event_venue: event.event_venue,
8037
- event_participants: event.event_participants,
8038
- event_colours: event.event_colours,
8039
- event_logo: "",
8040
- // No logo field in event table
8041
- organisation_id: event.organisation_id,
8042
- is_visible: event.is_visible,
8043
- // Legacy compatibility
8044
- name: event.event_name,
8045
- start_date: event.event_date
8046
- }));
8047
- setEvents(transformedEvents);
8048
- setError(null);
8049
- hasAutoSelectedRef.current = false;
8050
- const persistedEventLoaded = await loadPersistedEvent(transformedEvents);
8051
- if (!persistedEventLoaded) {
8052
- const nextEvent = getNextEventByDate(transformedEvents);
8053
- if (nextEvent) {
8054
- DebugLogger.log("EventProvider", "Auto-selecting next event after no persisted event found:", nextEvent.event_name);
8055
- hasAutoSelectedRef.current = true;
8056
- setSelectedEventState(nextEvent);
8057
- setSelectedEventIdRef.current(nextEvent.event_id);
8058
- persistEventSelection(nextEvent.event_id);
8059
- }
8060
- }
8061
- }
8062
- } catch (err) {
8063
- console.error("[EventProvider] Error fetching events:", err);
8064
- const _error = err instanceof Error ? err : new Error("Unknown error occurred");
8065
- if (isMounted) {
8066
- setError(_error);
8067
- setEvents([]);
8068
- }
8069
- } finally {
8070
- if (isMounted) {
8071
- setIsLoading(false);
8072
- }
8073
- isFetchingRef.current = false;
8074
- }
8075
- return () => {
8076
- isMounted = false;
8077
- };
8078
- }, [user, session, supabase, appName, selectedOrganisation, ensureOrganisationContext, loadPersistedEvent, autoSelectNextEvent]);
8079
- useEffect8(() => {
8080
- if (!isInitializedRef.current) {
8081
- isInitializedRef.current = true;
8082
- fetchEvents();
8083
- }
8084
- }, [fetchEvents]);
8085
- useEffect8(() => {
8086
- setSelectedEventIdRef.current = setSelectedEventId;
8087
- }, [setSelectedEventId]);
8088
- useLayoutEffect(() => {
8089
- if (events.length > 0 && !selectedEvent && !hasAutoSelectedRef.current && !userClearedEventRef.current) {
8090
- const nextEvent = getNextEventByDate(events);
8091
- if (nextEvent) {
8092
- DebugLogger.log("EventProvider", "Auto-selecting next event:", nextEvent.event_name);
8093
- hasAutoSelectedRef.current = true;
8094
- setSelectedEventState(nextEvent);
8095
- setSelectedEventIdRef.current(nextEvent.event_id);
8096
- persistEventSelection(nextEvent.event_id);
8097
- }
8098
- }
8099
- }, [events, selectedEvent]);
8100
- useEffect8(() => {
8101
- console.log("[EventProvider] Event theming useEffect triggered, selectedEvent:", selectedEvent?.event_name, selectedEvent?.event_colours);
8102
- if (!selectedEvent) {
8103
- console.log("[EventProvider] No selected event, clearing palette");
8104
- clearPalette();
8105
- return;
8106
- }
8107
- const eventColours = selectedEvent.event_colours;
8108
- console.log("[EventProvider] Event colours:", eventColours);
8109
- console.log("[EventProvider] Event colours keys:", Object.keys(eventColours || {}));
8110
- if (!eventColours || typeof eventColours !== "object") {
8111
- console.log("[EventProvider] No valid event_colours, clearing palette");
8112
- clearPalette();
8113
- return;
8114
- }
8115
- const evMainPalette = eventColours["ev-main"] || eventColours.main || {};
8116
- const evSecPalette = eventColours["ev-sec"] || eventColours.sec || {};
8117
- const evAccPalette = eventColours["ev-acc"] || eventColours.acc || {};
8118
- console.log("[EventProvider] Mapped palettes:", {
8119
- "ev-main": Object.keys(evMainPalette),
8120
- "ev-sec": Object.keys(evSecPalette),
8121
- "ev-acc": Object.keys(evAccPalette)
8122
- });
8123
- const fullPalette = {
8124
- main: evMainPalette,
8125
- sec: evSecPalette,
8126
- acc: evAccPalette
8127
- };
8128
- if (!fullPalette.main && !fullPalette.sec && !fullPalette.acc) {
8129
- console.log("[EventProvider] No valid palettes found in event_colours, clearing palette");
8130
- clearPalette();
8131
- return;
8132
- }
8133
- console.log("[EventProvider] Applying full palette:", fullPalette);
8134
- try {
8135
- applyPalette(fullPalette);
8136
- console.log("[EventProvider] Palette applied successfully");
8137
- } catch (error2) {
8138
- console.error("[EventProvider] Failed to apply event palette:", error2);
8139
- }
8140
- }, [selectedEvent]);
8141
- const setSelectedEvent = useCallback8((event) => {
8142
- if (event) {
8143
- try {
8144
- console.log("[EventProvider] Event selection validation:", {
8145
- eventId: event.event_id,
8146
- eventName: event.event_name,
8147
- eventOrganisationId: event.organisation_id,
8148
- selectedOrganisationId: selectedOrganisation?.id,
8149
- selectedOrganisationName: selectedOrganisation?.display_name,
8150
- match: event.organisation_id === selectedOrganisation?.id
8151
- });
8152
- if (selectedOrganisation && event.organisation_id !== selectedOrganisation.id) {
8153
- console.error("[EventProvider] Event organisation_id does not match selected organisation", {
8154
- eventOrganisationId: event.organisation_id,
8155
- selectedOrganisationId: selectedOrganisation.id,
8156
- eventName: event.event_name
8157
- });
8158
- return;
8159
- }
8160
- } catch (error2) {
8161
- console.error("[EventProvider] Error during event validation:", error2);
8162
- }
8163
- setSelectedEventState(event);
8164
- setSelectedEventId(event.event_id);
8165
- persistEventSelection(event.event_id);
8166
- userClearedEventRef.current = false;
8167
- } else {
8168
- setSelectedEventState(null);
8169
- setSelectedEventId(null);
8170
- sessionStorage.removeItem("pace-core-selected-event");
8171
- localStorage.removeItem("pace-core-selected-event");
8172
- hasAutoSelectedRef.current = false;
8173
- userClearedEventRef.current = true;
8174
- }
8175
- }, [selectedOrganisation, setSelectedEventId, persistEventSelection]);
8176
- const refreshEvents = useCallback8(async () => {
8177
- isInitializedRef.current = false;
8178
- isFetchingRef.current = false;
8179
- userClearedEventRef.current = false;
8180
- await fetchEvents();
8181
- }, [fetchEvents]);
8182
- const contextValue = useMemo7(() => ({
8183
- events,
8184
- selectedEvent,
8185
- isLoading,
8186
- error,
8187
- setSelectedEvent,
8188
- refreshEvents
8189
- }), [events, selectedEvent, isLoading, error, setSelectedEvent, refreshEvents]);
8190
- return /* @__PURE__ */ jsx10(EventContext.Provider, { value: contextValue, children });
8191
- }
8192
- var EventContext, useEvents;
8193
- var init_EventProvider = __esm({
8194
- "src/providers/EventProvider.tsx"() {
8195
- "use strict";
8196
- init_UnifiedAuthProvider();
8197
- init_OrganisationProvider();
8198
- init_organisationContext();
8199
- init_debugLogger();
8200
- init_runtime();
8201
- EventContext = createContext6(void 0);
8202
- useEvents = () => {
8203
- const context = useContext6(EventContext);
8204
- if (context === void 0) {
8205
- throw new Error("useEvents must be used within an EventProvider");
8206
- }
8207
- return context;
8208
- };
8209
- }
8210
- });
8211
-
8212
7284
  export {
8213
7285
  AuthProvider,
8214
7286
  useAuth,
@@ -8247,15 +7319,7 @@ export {
8247
7319
  useUnifiedAuth,
8248
7320
  UnifiedAuthProvider,
8249
7321
  UnifiedAuthProvider_exports,
8250
- init_UnifiedAuthProvider,
8251
- OrganisationProvider,
8252
- useOrganisations,
8253
- OrganisationProvider_exports,
8254
- init_OrganisationProvider,
8255
- useEvents,
8256
- EventProvider,
8257
- EventProvider_exports,
8258
- init_EventProvider
7322
+ init_UnifiedAuthProvider
8259
7323
  };
8260
7324
  /*! Bundled license information:
8261
7325
 
@@ -8269,4 +7333,4 @@ lodash/lodash.js:
8269
7333
  * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
8270
7334
  *)
8271
7335
  */
8272
- //# sourceMappingURL=chunk-4CET7YQI.js.map
7336
+ //# sourceMappingURL=chunk-IHMMNKNA.js.map