@optifye/dashboard-core 6.11.21 → 6.11.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2232,6 +2232,61 @@ var clearAuthSnapshot = () => {
2232
2232
  safeStorageRemoveItem(AUTH_SNAPSHOT_STORAGE_KEY);
2233
2233
  };
2234
2234
 
2235
+ // src/lib/auth/authAuditLog.ts
2236
+ var TAB_ID = typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID().slice(0, 8) : Math.random().toString(36).slice(2, 10);
2237
+ var FLUSH_INTERVAL_MS = 3e4;
2238
+ var MAX_QUEUE_SIZE = 50;
2239
+ var queue = [];
2240
+ var flushTimer = null;
2241
+ var apiBaseUrl = "";
2242
+ var getAccessToken = null;
2243
+ var initAuthAuditLog = (baseUrl, tokenGetter) => {
2244
+ apiBaseUrl = baseUrl;
2245
+ getAccessToken = tokenGetter;
2246
+ if (typeof window === "undefined") return;
2247
+ if (!flushTimer) {
2248
+ flushTimer = setInterval(flushAuthAuditLog, FLUSH_INTERVAL_MS);
2249
+ window.addEventListener("visibilitychange", () => {
2250
+ if (document.visibilityState === "hidden") {
2251
+ void flushAuthAuditLog();
2252
+ }
2253
+ });
2254
+ }
2255
+ };
2256
+ var logAuthEvent = (eventType, details = {}) => {
2257
+ queue.push({
2258
+ event_type: eventType,
2259
+ tab_id: TAB_ID,
2260
+ details: {
2261
+ ...details,
2262
+ ts: (/* @__PURE__ */ new Date()).toISOString()
2263
+ }
2264
+ });
2265
+ if (queue.length >= MAX_QUEUE_SIZE) {
2266
+ void flushAuthAuditLog();
2267
+ }
2268
+ };
2269
+ var flushAuthAuditLog = async () => {
2270
+ if (queue.length === 0 || !apiBaseUrl || !getAccessToken) return;
2271
+ const events = queue.splice(0, MAX_QUEUE_SIZE);
2272
+ try {
2273
+ const token = await getAccessToken();
2274
+ if (!token) return;
2275
+ const body = JSON.stringify({ events });
2276
+ const url = `${apiBaseUrl}/api/auth/audit`;
2277
+ await fetch(url, {
2278
+ method: "POST",
2279
+ headers: {
2280
+ "Content-Type": "application/json",
2281
+ Authorization: `Bearer ${token}`
2282
+ },
2283
+ body,
2284
+ keepalive: document.visibilityState === "hidden"
2285
+ });
2286
+ } catch {
2287
+ }
2288
+ };
2289
+
2235
2290
  // src/lib/auth/session.ts
2236
2291
  var DEFAULT_MIN_VALIDITY_MS = 6e4;
2237
2292
  var refreshPromises = /* @__PURE__ */ new WeakMap();
@@ -2241,6 +2296,24 @@ var isInvalidRefreshTokenError = (error) => {
2241
2296
  if (!message.includes("refresh token")) return false;
2242
2297
  return message.includes("invalid") || message.includes("not found") || message.includes("revoked");
2243
2298
  };
2299
+ var getSessionFromStorage = () => {
2300
+ if (typeof window === "undefined") return null;
2301
+ try {
2302
+ for (let i = 0; i < localStorage.length; i++) {
2303
+ const key = localStorage.key(i);
2304
+ if (key?.startsWith("sb-") && key?.endsWith("-auth-token")) {
2305
+ const raw = localStorage.getItem(key);
2306
+ if (!raw) continue;
2307
+ const parsed = JSON.parse(raw);
2308
+ if (parsed?.access_token && parsed?.refresh_token && parsed?.expires_at) {
2309
+ return parsed;
2310
+ }
2311
+ }
2312
+ }
2313
+ } catch {
2314
+ }
2315
+ return null;
2316
+ };
2244
2317
  var isSessionValid = (session, minValidityMs = 0) => {
2245
2318
  if (!session) return false;
2246
2319
  if (!session.expires_at) return true;
@@ -2297,6 +2370,18 @@ var refreshSessionSingleFlight = async (supabase) => {
2297
2370
  }
2298
2371
  const invalidRefreshToken = isInvalidRefreshTokenError(refreshError);
2299
2372
  if (invalidRefreshToken) {
2373
+ const storedSession = getSessionFromStorage();
2374
+ if (storedSession && isSessionValid(storedSession, 0)) {
2375
+ console.log("[Auth] Recovered session from localStorage after invalid refresh token (another tab refreshed)");
2376
+ try {
2377
+ await supabase.auth.setSession({
2378
+ access_token: storedSession.access_token,
2379
+ refresh_token: storedSession.refresh_token
2380
+ });
2381
+ } catch {
2382
+ }
2383
+ return { session: storedSession, error: null, invalidRefreshToken: false };
2384
+ }
2300
2385
  try {
2301
2386
  await supabase.auth.signOut({ scope: "local" });
2302
2387
  } catch (error) {
@@ -6606,7 +6691,17 @@ function captureSentryException(error, extras) {
6606
6691
  }
6607
6692
 
6608
6693
  // src/lib/services/mixpanelService.ts
6694
+ var ROOT_DASHBOARD_EVENT_NAMES = {
6695
+ operations_overview: "Operations Overview Page Clicked",
6696
+ monitor: "Live Monitor Clicked"
6697
+ };
6698
+ var MIXPANEL_EVENT_NAME_ALIASES = {
6699
+ "Operations Overview clicked": ROOT_DASHBOARD_EVENT_NAMES.operations_overview,
6700
+ "monitor page clicked": ROOT_DASHBOARD_EVENT_NAMES.monitor
6701
+ };
6702
+ var MAX_QUEUED_MIXPANEL_ACTIONS = 200;
6609
6703
  var isMixpanelInitialized = false;
6704
+ var queuedMixpanelActions = [];
6610
6705
  var currentUserProperties;
6611
6706
  var MIXPANEL_WARNING_RATE_LIMIT = {
6612
6707
  windowMs: 10 * 60 * 1e3,
@@ -6634,6 +6729,52 @@ var reportMixpanelError = (key, error, extras) => {
6634
6729
  if (!shouldReportMixpanel(key, true)) return;
6635
6730
  captureSentryException(error, { ...baseMixpanelExtras(), ...extras });
6636
6731
  };
6732
+ var normalizeCoreEventName = (eventName) => {
6733
+ const canonicalName = MIXPANEL_EVENT_NAME_ALIASES[eventName] || eventName;
6734
+ if (canonicalName !== eventName) {
6735
+ reportMixpanelWarning(`event_alias:${eventName}`, "Mixpanel event alias rewritten to canonical name", {
6736
+ operation: "track_event",
6737
+ originalEventName: eventName,
6738
+ canonicalEventName: canonicalName
6739
+ });
6740
+ }
6741
+ return canonicalName;
6742
+ };
6743
+ var queueMixpanelAction = (action) => {
6744
+ if (queuedMixpanelActions.length >= MAX_QUEUED_MIXPANEL_ACTIONS) {
6745
+ queuedMixpanelActions.shift();
6746
+ reportMixpanelWarning("queue_overflow", "Mixpanel queue overflow, dropping oldest queued action", {
6747
+ operation: "queue",
6748
+ maxQueuedActions: MAX_QUEUED_MIXPANEL_ACTIONS
6749
+ });
6750
+ }
6751
+ queuedMixpanelActions.push(action);
6752
+ };
6753
+ var flushQueuedMixpanelActions = () => {
6754
+ if (!isMixpanelInitialized || queuedMixpanelActions.length === 0) return;
6755
+ const pendingActions = queuedMixpanelActions.splice(0, queuedMixpanelActions.length);
6756
+ pendingActions.forEach((action) => {
6757
+ try {
6758
+ if (action.type === "identify") {
6759
+ mixpanel__default.default.identify(action.userId);
6760
+ if (action.userProperties) {
6761
+ mixpanel__default.default.people.set(action.userProperties);
6762
+ }
6763
+ return;
6764
+ }
6765
+ if (action.type === "page_view") {
6766
+ mixpanel__default.default.track("Page View", { page: action.pageName, ...action.properties || {} });
6767
+ return;
6768
+ }
6769
+ mixpanel__default.default.track(action.eventName, action.properties || {});
6770
+ } catch (err) {
6771
+ reportMixpanelError("flush_queued_action_failed", err, {
6772
+ operation: "flush_queue",
6773
+ actionType: action.type
6774
+ });
6775
+ }
6776
+ });
6777
+ };
6637
6778
  var initializeCoreMixpanel = (token, debugOrOptions, trackPageViewArg) => {
6638
6779
  if (!token) {
6639
6780
  console.warn("Mixpanel token not provided for initialization. Mixpanel will not be enabled.");
@@ -6691,6 +6832,7 @@ var initializeCoreMixpanel = (token, debugOrOptions, trackPageViewArg) => {
6691
6832
  try {
6692
6833
  mixpanel__default.default.init(token, initOptions);
6693
6834
  isMixpanelInitialized = true;
6835
+ flushQueuedMixpanelActions();
6694
6836
  } catch (err) {
6695
6837
  reportMixpanelError("init_failed", err, {
6696
6838
  operation: "init",
@@ -6706,7 +6848,12 @@ var initializeCoreMixpanel = (token, debugOrOptions, trackPageViewArg) => {
6706
6848
  };
6707
6849
  var trackCorePageView = (pageName, properties) => {
6708
6850
  if (!isMixpanelInitialized) {
6709
- reportMixpanelWarning("track_pageview_not_initialized", "Mixpanel not initialized: page view dropped", {
6851
+ queueMixpanelAction({
6852
+ type: "page_view",
6853
+ pageName,
6854
+ properties
6855
+ });
6856
+ reportMixpanelWarning("track_pageview_queued", "Mixpanel not initialized yet: page view queued", {
6710
6857
  operation: "track_pageview",
6711
6858
  pageName
6712
6859
  });
@@ -6722,10 +6869,20 @@ var trackCorePageView = (pageName, properties) => {
6722
6869
  }
6723
6870
  };
6724
6871
  var trackCoreEvent = (eventName, properties) => {
6872
+ const normalizedEventName = normalizeCoreEventName(eventName);
6725
6873
  if (!isMixpanelInitialized) {
6726
- reportMixpanelWarning("track_event_not_initialized", "Mixpanel not initialized: event dropped", {
6874
+ const mergedProps2 = {
6875
+ ...currentUserProperties || {},
6876
+ ...properties || {}
6877
+ };
6878
+ queueMixpanelAction({
6879
+ type: "track",
6880
+ eventName: normalizedEventName,
6881
+ properties: mergedProps2
6882
+ });
6883
+ reportMixpanelWarning("track_event_queued", "Mixpanel not initialized yet: event queued", {
6727
6884
  operation: "track_event",
6728
- eventName
6885
+ eventName: normalizedEventName
6729
6886
  });
6730
6887
  return;
6731
6888
  }
@@ -6736,11 +6893,11 @@ var trackCoreEvent = (eventName, properties) => {
6736
6893
  ...properties || {}
6737
6894
  };
6738
6895
  try {
6739
- mixpanel__default.default.track(eventName, mergedProps);
6896
+ mixpanel__default.default.track(normalizedEventName, mergedProps);
6740
6897
  } catch (err) {
6741
6898
  reportMixpanelError("track_event_failed", err, {
6742
6899
  operation: "track_event",
6743
- eventName
6900
+ eventName: normalizedEventName
6744
6901
  });
6745
6902
  }
6746
6903
  };
@@ -6791,8 +6948,14 @@ var getCoreSessionReplayUrl = () => {
6791
6948
  return null;
6792
6949
  };
6793
6950
  var identifyCoreUser = (userId, userProperties) => {
6951
+ currentUserProperties = userProperties ? { ...userProperties } : void 0;
6794
6952
  if (!isMixpanelInitialized) {
6795
- reportMixpanelWarning("identify_not_initialized", "Mixpanel not initialized: identify dropped", {
6953
+ queueMixpanelAction({
6954
+ type: "identify",
6955
+ userId,
6956
+ userProperties: currentUserProperties
6957
+ });
6958
+ reportMixpanelWarning("identify_queued", "Mixpanel not initialized yet: identify queued", {
6796
6959
  operation: "identify",
6797
6960
  userIdPresent: Boolean(userId),
6798
6961
  hasUserProperties: Boolean(userProperties)
@@ -6812,17 +6975,20 @@ var identifyCoreUser = (userId, userProperties) => {
6812
6975
  });
6813
6976
  return;
6814
6977
  }
6815
- currentUserProperties = { ...userProperties };
6978
+ currentUserProperties = userProperties ? { ...userProperties } : void 0;
6816
6979
  };
6817
6980
  var resetCoreMixpanel = () => {
6818
- if (!isMixpanelInitialized) return;
6819
- try {
6820
- mixpanel__default.default.reset();
6821
- } catch (err) {
6822
- reportMixpanelError("reset_failed", err, {
6823
- operation: "reset"
6824
- });
6981
+ if (isMixpanelInitialized) {
6982
+ try {
6983
+ mixpanel__default.default.reset();
6984
+ } catch (err) {
6985
+ reportMixpanelError("reset_failed", err, {
6986
+ operation: "reset"
6987
+ });
6988
+ }
6825
6989
  }
6990
+ currentUserProperties = void 0;
6991
+ queuedMixpanelActions.splice(0, queuedMixpanelActions.length);
6826
6992
  };
6827
6993
 
6828
6994
  // src/lib/services/sseClient.ts
@@ -10379,6 +10545,15 @@ var AuthProvider = ({ children }) => {
10379
10545
  const [error, setError] = React142.useState(null);
10380
10546
  const [authStatus, setAuthStatus] = React142.useState("loading");
10381
10547
  const [showOnboarding, setShowOnboarding] = React142.useState(false);
10548
+ const auditInitRef = React142.useRef(false);
10549
+ if (!auditInitRef.current && typeof window !== "undefined") {
10550
+ const backendUrl = process.env.NEXT_PUBLIC_BACKEND_URL || "http://localhost:8000";
10551
+ initAuthAuditLog(backendUrl, async () => {
10552
+ const { data: { session: s } } = await supabase.auth.getSession();
10553
+ return s?.access_token ?? null;
10554
+ });
10555
+ auditInitRef.current = true;
10556
+ }
10382
10557
  const isFetchingRef = React142.useRef(false);
10383
10558
  const lastProcessedSessionRef = React142.useRef(null);
10384
10559
  const hasAuthenticatedRef = React142.useRef(false);
@@ -10542,6 +10717,7 @@ var AuthProvider = ({ children }) => {
10542
10717
  resetRecoveryState();
10543
10718
  if (refreshResult.invalidRefreshToken) {
10544
10719
  console.warn("[AuthContext] Refresh token invalid, redirecting to login");
10720
+ logAuthEvent("forced_logout", { reason: "invalid_refresh_token", trigger: "fetchSession" });
10545
10721
  setAuthStatus("failed");
10546
10722
  clearSessionState();
10547
10723
  await handleAuthRequired(supabase, "session_expired");
@@ -10641,6 +10817,7 @@ var AuthProvider = ({ children }) => {
10641
10817
  const signOut = React142.useCallback(async () => {
10642
10818
  try {
10643
10819
  console.log("[AuthContext] Signing out");
10820
+ logAuthEvent("sign_out_initiated", { trigger: "user_action" });
10644
10821
  setAuthStatus("loading");
10645
10822
  resetRecoveryState();
10646
10823
  clearAuthSnapshot();
@@ -10665,6 +10842,22 @@ var AuthProvider = ({ children }) => {
10665
10842
  return;
10666
10843
  }
10667
10844
  const monitorTokenExpiry = async () => {
10845
+ const storedSession = getSessionFromStorage();
10846
+ if (storedSession && isSessionValid(storedSession, 5 * 60 * 1e3)) {
10847
+ if (storedSession.access_token !== session.access_token) {
10848
+ console.log("[AuthContext] Adopting session refreshed by another tab");
10849
+ logAuthEvent("cross_tab_refresh_adopted", { source: "monitorTokenExpiry" });
10850
+ setTrackedSession(storedSession);
10851
+ try {
10852
+ await supabase.auth.setSession({
10853
+ access_token: storedSession.access_token,
10854
+ refresh_token: storedSession.refresh_token
10855
+ });
10856
+ } catch {
10857
+ }
10858
+ }
10859
+ return;
10860
+ }
10668
10861
  const expiresAt = session.expires_at;
10669
10862
  if (!expiresAt) {
10670
10863
  console.warn("[AuthContext] Session has no expiry time");
@@ -10677,13 +10870,16 @@ var AuthProvider = ({ children }) => {
10677
10870
  console.log(`[AuthContext] Token expires in ${minutesUntilExpiry} minutes`);
10678
10871
  if (minutesUntilExpiry < 5 && timeUntilExpiry > 0) {
10679
10872
  console.warn("[AuthContext] Token expiring soon, attempting refresh...");
10873
+ logAuthEvent("token_refresh_started", { reason: "expiring_soon", minutesUntilExpiry });
10680
10874
  const refreshResult = await refreshSessionSingleFlight(supabase);
10681
10875
  if (isSessionValid(refreshResult.session, 0)) {
10682
10876
  setTrackedSession(refreshResult.session);
10877
+ logAuthEvent("token_refresh_succeeded", { expiresAt: refreshResult.session?.expires_at });
10683
10878
  console.log("[AuthContext] Token refreshed successfully");
10684
10879
  return;
10685
10880
  }
10686
10881
  if (refreshResult.invalidRefreshToken) {
10882
+ logAuthEvent("token_refresh_failed", { reason: "invalid_refresh_token", trigger: "proactive" });
10687
10883
  clearAuthSnapshot();
10688
10884
  resetRecoveryState();
10689
10885
  console.error("[AuthContext] Refresh token invalid during proactive refresh");
@@ -10692,13 +10888,16 @@ var AuthProvider = ({ children }) => {
10692
10888
  }
10693
10889
  if (timeUntilExpiry <= 0) {
10694
10890
  console.warn("[AuthContext] Token has expired, attempting refresh...");
10891
+ logAuthEvent("token_refresh_started", { reason: "expired", minutesUntilExpiry });
10695
10892
  const refreshResult = await refreshSessionSingleFlight(supabase);
10696
10893
  if (isSessionValid(refreshResult.session, 0)) {
10697
10894
  setTrackedSession(refreshResult.session);
10895
+ logAuthEvent("token_refresh_succeeded", { expiresAt: refreshResult.session?.expires_at });
10698
10896
  console.log("[AuthContext] Token refreshed after expiry");
10699
10897
  return;
10700
10898
  }
10701
10899
  if (refreshResult.invalidRefreshToken) {
10900
+ logAuthEvent("token_refresh_failed", { reason: "invalid_refresh_token", trigger: "expired" });
10702
10901
  clearAuthSnapshot();
10703
10902
  resetRecoveryState();
10704
10903
  console.error("[AuthContext] Refresh token invalid after expiry");
@@ -10750,6 +10949,29 @@ var AuthProvider = ({ children }) => {
10750
10949
  window.addEventListener("rbac:refresh-scope", handleScopeRefresh);
10751
10950
  return () => window.removeEventListener("rbac:refresh-scope", handleScopeRefresh);
10752
10951
  }, [fetchSession, session]);
10952
+ React142.useEffect(() => {
10953
+ if (typeof window === "undefined") return;
10954
+ const handleStorageChange = (e) => {
10955
+ if (!e.key?.startsWith("sb-") || !e.key?.endsWith("-auth-token")) return;
10956
+ if (!e.newValue || !session) return;
10957
+ try {
10958
+ const stored = JSON.parse(e.newValue);
10959
+ if (stored?.access_token && stored?.refresh_token && stored?.expires_at && stored.access_token !== session.access_token) {
10960
+ console.log("[AuthContext] Cross-tab token update detected, syncing session");
10961
+ logAuthEvent("cross_tab_refresh_adopted", { source: "storage_event" });
10962
+ setTrackedSession(stored);
10963
+ supabase.auth.setSession({
10964
+ access_token: stored.access_token,
10965
+ refresh_token: stored.refresh_token
10966
+ }).catch(() => {
10967
+ });
10968
+ }
10969
+ } catch {
10970
+ }
10971
+ };
10972
+ window.addEventListener("storage", handleStorageChange);
10973
+ return () => window.removeEventListener("storage", handleStorageChange);
10974
+ }, [session, setTrackedSession, supabase]);
10753
10975
  React142.useEffect(() => {
10754
10976
  if (typeof window === "undefined" || authStatus !== "recovering") {
10755
10977
  return;
@@ -10841,6 +11063,7 @@ var AuthProvider = ({ children }) => {
10841
11063
  }
10842
11064
  if (event === "SIGNED_OUT") {
10843
11065
  console.log("[AuthContext] User signed out");
11066
+ logAuthEvent("signed_out", { trigger: "auth_state_change" });
10844
11067
  resetRecoveryState();
10845
11068
  clearAuthSnapshot();
10846
11069
  clearSessionState();
@@ -11117,7 +11340,7 @@ function useSessionTracking(options = {}) {
11117
11340
  const trackerRef = React142.useRef(null);
11118
11341
  const isTrackingRef = React142.useRef(false);
11119
11342
  const initRef = React142.useRef(false);
11120
- const getAccessToken = React142.useCallback(async () => {
11343
+ const getAccessToken2 = React142.useCallback(async () => {
11121
11344
  return session?.access_token || null;
11122
11345
  }, [session?.access_token]);
11123
11346
  React142.useEffect(() => {
@@ -11125,14 +11348,14 @@ function useSessionTracking(options = {}) {
11125
11348
  return;
11126
11349
  }
11127
11350
  initRef.current = true;
11128
- const apiBaseUrl = config?.apiBaseUrl || process.env.NEXT_PUBLIC_API_BASE_URL || "";
11129
- if (!apiBaseUrl) {
11351
+ const apiBaseUrl2 = config?.apiBaseUrl || process.env.NEXT_PUBLIC_API_BASE_URL || "";
11352
+ if (!apiBaseUrl2) {
11130
11353
  console.warn("[useSessionTracking] No API base URL configured, session tracking disabled");
11131
11354
  return;
11132
11355
  }
11133
11356
  const tracker = createSessionTracker({
11134
- apiBaseUrl,
11135
- getAccessToken,
11357
+ apiBaseUrl: apiBaseUrl2,
11358
+ getAccessToken: getAccessToken2,
11136
11359
  onSessionStart: (sessionId) => {
11137
11360
  isTrackingRef.current = true;
11138
11361
  onSessionStart?.(sessionId);
@@ -11153,7 +11376,7 @@ function useSessionTracking(options = {}) {
11153
11376
  initRef.current = false;
11154
11377
  isTrackingRef.current = false;
11155
11378
  };
11156
- }, [enabled, isAuthenticated, user?.id, session?.access_token, config?.apiBaseUrl, getAccessToken, onSessionStart, onSessionEnd, user]);
11379
+ }, [enabled, isAuthenticated, user?.id, session?.access_token, config?.apiBaseUrl, getAccessToken2, onSessionStart, onSessionEnd, user]);
11157
11380
  React142.useEffect(() => {
11158
11381
  if (!isAuthenticated && trackerRef.current && isTrackingRef.current) {
11159
11382
  trackerRef.current.endSession("logout");
@@ -19734,9 +19957,9 @@ function useUserUsage(userId, options = {}) {
19734
19957
  const [data, setData] = React142.useState(null);
19735
19958
  const [isLoading, setIsLoading] = React142.useState(true);
19736
19959
  const [error, setError] = React142.useState(null);
19737
- const apiBaseUrl = config?.apiBaseUrl || process.env.NEXT_PUBLIC_API_BASE_URL || "";
19960
+ const apiBaseUrl2 = config?.apiBaseUrl || process.env.NEXT_PUBLIC_API_BASE_URL || "";
19738
19961
  const fetchData = React142.useCallback(async () => {
19739
- if (!userId || !apiBaseUrl || !session?.access_token) {
19962
+ if (!userId || !apiBaseUrl2 || !session?.access_token) {
19740
19963
  setIsLoading(false);
19741
19964
  return;
19742
19965
  }
@@ -19746,7 +19969,7 @@ function useUserUsage(userId, options = {}) {
19746
19969
  const params = new URLSearchParams();
19747
19970
  if (startDate) params.append("start_date", startDate);
19748
19971
  if (endDate) params.append("end_date", endDate);
19749
- const url = `${apiBaseUrl}/api/usage/user/${userId}${params.toString() ? `?${params}` : ""}`;
19972
+ const url = `${apiBaseUrl2}/api/usage/user/${userId}${params.toString() ? `?${params}` : ""}`;
19750
19973
  const response = await fetch(url, {
19751
19974
  headers: {
19752
19975
  "Authorization": `Bearer ${session.access_token}`
@@ -19764,7 +19987,7 @@ function useUserUsage(userId, options = {}) {
19764
19987
  } finally {
19765
19988
  setIsLoading(false);
19766
19989
  }
19767
- }, [userId, apiBaseUrl, session?.access_token, startDate, endDate]);
19990
+ }, [userId, apiBaseUrl2, session?.access_token, startDate, endDate]);
19768
19991
  React142.useEffect(() => {
19769
19992
  if (enabled) {
19770
19993
  fetchData();
@@ -19786,12 +20009,12 @@ function useCompanyUsersUsage(companyId, options = {}) {
19786
20009
  const [isLoading, setIsLoading] = React142.useState(true);
19787
20010
  const [isTodayLoading, setIsTodayLoading] = React142.useState(true);
19788
20011
  const [error, setError] = React142.useState(null);
19789
- const apiBaseUrl = config?.apiBaseUrl || process.env.NEXT_PUBLIC_BACKEND_URL || "";
20012
+ const apiBaseUrl2 = config?.apiBaseUrl || process.env.NEXT_PUBLIC_BACKEND_URL || "";
19790
20013
  const userRole = user?.role || user?.role_level;
19791
20014
  const canAccess = userRole === "owner" || userRole === "optifye";
19792
- const isEnabled = enabled && canAccess && !!apiBaseUrl;
20015
+ const isEnabled = enabled && canAccess && !!apiBaseUrl2;
19793
20016
  const fetchOwnerReport = React142.useCallback(async () => {
19794
- if (!apiBaseUrl || !session?.access_token || !canAccess || !isEnabled) {
20017
+ if (!apiBaseUrl2 || !session?.access_token || !canAccess || !isEnabled) {
19795
20018
  setIsLoading(false);
19796
20019
  return;
19797
20020
  }
@@ -19806,7 +20029,7 @@ function useCompanyUsersUsage(companyId, options = {}) {
19806
20029
  if (startDate) params.append("start_date", startDate);
19807
20030
  if (endDate) params.append("end_date", endDate);
19808
20031
  if (roleFilter) params.append("role_filter", roleFilter);
19809
- const url = `${apiBaseUrl}/api/usage/owner-report${params.toString() ? `?${params}` : ""}`;
20032
+ const url = `${apiBaseUrl2}/api/usage/owner-report${params.toString() ? `?${params}` : ""}`;
19810
20033
  const response = await fetch(url, {
19811
20034
  headers: {
19812
20035
  "Authorization": `Bearer ${session.access_token}`
@@ -19824,15 +20047,15 @@ function useCompanyUsersUsage(companyId, options = {}) {
19824
20047
  } finally {
19825
20048
  setIsLoading(false);
19826
20049
  }
19827
- }, [apiBaseUrl, session?.access_token, canAccess, isEnabled, startDate, endDate, roleFilter]);
20050
+ }, [apiBaseUrl2, session?.access_token, canAccess, isEnabled, startDate, endDate, roleFilter]);
19828
20051
  const fetchTodayUsage = React142.useCallback(async () => {
19829
- if (!apiBaseUrl || !session?.access_token || !canAccess || !isEnabled) {
20052
+ if (!apiBaseUrl2 || !session?.access_token || !canAccess || !isEnabled) {
19830
20053
  setIsTodayLoading(false);
19831
20054
  return;
19832
20055
  }
19833
20056
  setIsTodayLoading(true);
19834
20057
  try {
19835
- const url = `${apiBaseUrl}/api/usage/today`;
20058
+ const url = `${apiBaseUrl2}/api/usage/today`;
19836
20059
  const response = await fetch(url, {
19837
20060
  headers: {
19838
20061
  "Authorization": `Bearer ${session.access_token}`
@@ -19848,7 +20071,7 @@ function useCompanyUsersUsage(companyId, options = {}) {
19848
20071
  } finally {
19849
20072
  setIsTodayLoading(false);
19850
20073
  }
19851
- }, [apiBaseUrl, session?.access_token, canAccess, isEnabled]);
20074
+ }, [apiBaseUrl2, session?.access_token, canAccess, isEnabled]);
19852
20075
  const fetchAll = React142.useCallback(async () => {
19853
20076
  await Promise.all([
19854
20077
  fetchOwnerReport(),
@@ -19918,9 +20141,9 @@ function useCompanyClipsCost() {
19918
20141
  const hasFetchedOnceRef = React142.useRef(false);
19919
20142
  const canViewClipsCost = user?.role_level === "owner" || user?.role_level === "optifye";
19920
20143
  const companyId = user?.properties?.company_id || user?.company_id || entityConfig.companyId;
19921
- const apiBaseUrl = config?.apiBaseUrl || process.env.NEXT_PUBLIC_API_BASE_URL || "";
20144
+ const apiBaseUrl2 = config?.apiBaseUrl || process.env.NEXT_PUBLIC_API_BASE_URL || "";
19922
20145
  const fetchData = React142.useCallback(async () => {
19923
- if (!canViewClipsCost || !companyId || !supabase || !apiBaseUrl || !session?.access_token) {
20146
+ if (!canViewClipsCost || !companyId || !supabase || !apiBaseUrl2 || !session?.access_token) {
19924
20147
  setIsLoading(false);
19925
20148
  setData(null);
19926
20149
  hasFetchedOnceRef.current = false;
@@ -19932,7 +20155,7 @@ function useCompanyClipsCost() {
19932
20155
  setError(null);
19933
20156
  try {
19934
20157
  const [statsResponse, linesResult] = await Promise.all([
19935
- fetch(`${apiBaseUrl}/api/classification/company-stats?company_id=${encodeURIComponent(companyId)}`, {
20158
+ fetch(`${apiBaseUrl2}/api/classification/company-stats?company_id=${encodeURIComponent(companyId)}`, {
19936
20159
  headers: {
19937
20160
  "Authorization": `Bearer ${session.access_token}`
19938
20161
  }
@@ -19967,7 +20190,7 @@ function useCompanyClipsCost() {
19967
20190
  hasFetchedOnceRef.current = true;
19968
20191
  setIsLoading(false);
19969
20192
  }
19970
- }, [canViewClipsCost, companyId, supabase, apiBaseUrl, session?.access_token]);
20193
+ }, [canViewClipsCost, companyId, supabase, apiBaseUrl2, session?.access_token]);
19971
20194
  React142.useEffect(() => {
19972
20195
  fetchData();
19973
20196
  }, [fetchData]);
@@ -23503,11 +23726,11 @@ function createRenderStep(runNextFrame) {
23503
23726
  */
23504
23727
  schedule: (callback, keepAlive = false, immediate = false) => {
23505
23728
  const addToCurrentFrame = immediate && isProcessing;
23506
- const queue = addToCurrentFrame ? thisFrame : nextFrame;
23729
+ const queue2 = addToCurrentFrame ? thisFrame : nextFrame;
23507
23730
  if (keepAlive)
23508
23731
  toKeepAlive.add(callback);
23509
- if (!queue.has(callback))
23510
- queue.add(callback);
23732
+ if (!queue2.has(callback))
23733
+ queue2.add(callback);
23511
23734
  return callback;
23512
23735
  },
23513
23736
  /**
@@ -52675,7 +52898,7 @@ var SideNavBar = React142.memo(({
52675
52898
  transition-all duration-200 ease-out focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2`;
52676
52899
  }, [pathname]);
52677
52900
  const buildDashboardSurfaceTrackingEvent = React142.useCallback((source, destinationPath, dashboardSurface) => ({
52678
- name: dashboardSurface === "operations_overview" ? "Operations Overview clicked" : "monitor page clicked",
52901
+ name: ROOT_DASHBOARD_EVENT_NAMES[dashboardSurface],
52679
52902
  properties: {
52680
52903
  source,
52681
52904
  destination_path: destinationPath,
@@ -53956,7 +54179,7 @@ var AwardNotificationManager = () => {
53956
54179
  const supabase = useSupabase();
53957
54180
  const { user } = useAuth();
53958
54181
  const router$1 = router.useRouter();
53959
- const [queue, setQueue] = React142.useState([]);
54182
+ const [queue2, setQueue] = React142.useState([]);
53960
54183
  const [activeNotification, setActiveNotification] = React142.useState(null);
53961
54184
  const lastUserIdRef = React142.useRef(null);
53962
54185
  React142.useEffect(() => {
@@ -53977,10 +54200,10 @@ var AwardNotificationManager = () => {
53977
54200
  loadNotifications();
53978
54201
  }, [user, supabase]);
53979
54202
  React142.useEffect(() => {
53980
- if (!activeNotification && queue.length > 0) {
53981
- setActiveNotification(queue[0]);
54203
+ if (!activeNotification && queue2.length > 0) {
54204
+ setActiveNotification(queue2[0]);
53982
54205
  }
53983
- }, [queue, activeNotification]);
54206
+ }, [queue2, activeNotification]);
53984
54207
  const dismissActive = async () => {
53985
54208
  if (!activeNotification) return;
53986
54209
  if (!activeNotification.id.startsWith("mock-")) {
@@ -79730,6 +79953,7 @@ exports.PrefetchEvents = PrefetchEvents;
79730
79953
  exports.PrefetchStatus = PrefetchStatus;
79731
79954
  exports.PrefetchTimeoutError = PrefetchTimeoutError;
79732
79955
  exports.ProfileView = ProfileView_default;
79956
+ exports.ROOT_DASHBOARD_EVENT_NAMES = ROOT_DASHBOARD_EVENT_NAMES;
79733
79957
  exports.RegistryProvider = RegistryProvider;
79734
79958
  exports.RoleBadge = RoleBadge;
79735
79959
  exports.S3ClipsService = S3ClipsSupabaseService;