@optifye/dashboard-core 6.9.0 → 6.9.1

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.mjs CHANGED
@@ -11,7 +11,7 @@ import Hls2 from 'hls.js';
11
11
  import useSWR from 'swr';
12
12
  import { noop, warning, invariant, progress, secondsToMilliseconds, millisecondsToSeconds, memo as memo$1 } from 'motion-utils';
13
13
  import { getValueTransition, hover, press, isPrimaryPointer, GroupPlaybackControls, setDragLock, supportsLinearEasing, attachTimeline, isGenerator, calcGeneratorDuration, isWaapiSupportedEasing, mapEasingToNativeEasing, maxGeneratorDuration, generateLinearEasing, isBezierDefinition } from 'motion-dom';
14
- import { Camera, ChevronDown, ChevronUp, Check, Map as Map$1, Video, ShieldCheck, Star, Award, ArrowLeft, X, Coffee, Plus, Clock, Calendar, Save, AlertCircle, Loader2, Minus, ArrowDown, ArrowUp, Pause, Play, XCircle, ChevronLeft, ChevronRight, Sparkles, TrendingUp, Settings2, CheckCircle2, RefreshCw, TrendingDown, FolderOpen, Folder, HelpCircle, Sliders, Activity, Layers, Filter, Search, Edit2, AlertTriangle, CheckCircle, Building2, Mail, Users, User, Lock, ArrowRight, Info, Share2, Trophy, Target, Download, Sun, Moon, MousePointer, MessageSquare, Trash2, Menu, Send, Copy, UserCheck, LogOut, Package, UserPlus, Settings, LifeBuoy, EyeOff, Eye, MoreVertical, UserCog, Zap, Shield, UserCircle } from 'lucide-react';
14
+ import { Camera, ChevronDown, ChevronUp, Check, Map as Map$1, Video, ShieldCheck, Star, Award, ArrowLeft, X, Coffee, Plus, Clock, Calendar, Save, AlertCircle, Loader2, Minus, ArrowDown, ArrowUp, Pause, Play, XCircle, ChevronLeft, ChevronRight, Maximize2, Sparkles, TrendingUp, Settings2, CheckCircle2, RefreshCw, TrendingDown, FolderOpen, Folder, HelpCircle, Sliders, Activity, Layers, Filter, Search, Edit2, AlertTriangle, CheckCircle, Building2, Mail, Users, User, Lock, ArrowRight, Info, Share2, Trophy, Target, Download, Sun, Moon, MousePointer, MessageSquare, Trash2, Menu, Send, Copy, UserCheck, LogOut, Package, UserPlus, Settings, LifeBuoy, EyeOff, Eye, MoreVertical, UserCog, Zap, Shield, UserCircle } from 'lucide-react';
15
15
  import { toast } from 'sonner';
16
16
  import { BarChart as BarChart$1, CartesianGrid, XAxis, YAxis, Tooltip, Legend, Bar, LabelList, ResponsiveContainer, LineChart as LineChart$1, Line, PieChart, Pie, Cell, ReferenceLine, ComposedChart, Area, ScatterChart, Scatter } from 'recharts';
17
17
  import { Slot } from '@radix-ui/react-slot';
@@ -2763,60 +2763,135 @@ var authCoreService = {
2763
2763
  }
2764
2764
  };
2765
2765
 
2766
+ // src/lib/utils/apiClient.ts
2767
+ var ApiClient = class {
2768
+ // 5 minutes
2769
+ /**
2770
+ * Fetch with timeout, retry, and error handling
2771
+ *
2772
+ * @param url - URL to fetch
2773
+ * @param options - Fetch options plus ApiClient options
2774
+ * @returns Promise resolving to parsed JSON data
2775
+ */
2776
+ static async fetch(url, options = {}) {
2777
+ const {
2778
+ timeout = this.DEFAULT_TIMEOUT,
2779
+ retries = 1,
2780
+ retryDelay = 1e3,
2781
+ silentErrors = true,
2782
+ fallbackData = null,
2783
+ ...fetchOptions
2784
+ } = options;
2785
+ let lastError = null;
2786
+ for (let attempt = 0; attempt <= retries; attempt++) {
2787
+ const controller = new AbortController();
2788
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
2789
+ try {
2790
+ console.log(`[ApiClient] Request ${attempt > 0 ? `(retry ${attempt})` : ""}: ${url}`);
2791
+ const response = await fetch(url, {
2792
+ ...fetchOptions,
2793
+ signal: controller.signal
2794
+ });
2795
+ clearTimeout(timeoutId);
2796
+ if (!response.ok) {
2797
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
2798
+ }
2799
+ const data = await response.json();
2800
+ console.log(`[ApiClient] Success: ${url}`);
2801
+ return data;
2802
+ } catch (error) {
2803
+ clearTimeout(timeoutId);
2804
+ lastError = error;
2805
+ console.error(`[ApiClient] Error (attempt ${attempt + 1}/${retries + 1}):`, {
2806
+ url,
2807
+ error: error.message,
2808
+ isTimeout: error.name === "AbortError",
2809
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
2810
+ });
2811
+ if (attempt < retries) {
2812
+ console.log(`[ApiClient] Retrying in ${retryDelay}ms...`);
2813
+ await new Promise((resolve) => setTimeout(resolve, retryDelay));
2814
+ continue;
2815
+ }
2816
+ if (silentErrors) {
2817
+ console.warn("[ApiClient] All retries exhausted, returning fallback data");
2818
+ return fallbackData;
2819
+ } else {
2820
+ throw lastError;
2821
+ }
2822
+ }
2823
+ }
2824
+ return fallbackData;
2825
+ }
2826
+ };
2827
+ ApiClient.DEFAULT_TIMEOUT = 3e5;
2828
+
2766
2829
  // src/lib/services/authService.ts
2767
2830
  var AuthService = class {
2768
2831
  /**
2769
- * Fetch enriched user session from backend
2832
+ * Fetch enriched user session from backend with 5-minute timeout
2770
2833
  * This is your SINGLE call to get ALL auth data
2771
- *
2834
+ *
2772
2835
  * @param accessToken - JWT token from Supabase
2773
2836
  * @returns Complete user session with profile, permissions, and assignments
2774
2837
  */
2775
2838
  static async getSession(accessToken) {
2776
2839
  console.log("[AuthService] Fetching session from backend...");
2777
- const response = await fetch(`${this.backendUrl}/api/auth/session`, {
2778
- headers: {
2779
- "Authorization": `Bearer ${accessToken}`,
2780
- "Content-Type": "application/json"
2781
- }
2782
- });
2783
- if (!response.ok) {
2784
- const errorText = await response.text();
2785
- console.error("[AuthService] Session fetch failed:", response.status, errorText);
2786
- throw new Error(`Failed to fetch session: ${response.statusText}`);
2840
+ try {
2841
+ const data = await ApiClient.fetch(
2842
+ `${this.backendUrl}/api/auth/session`,
2843
+ {
2844
+ headers: {
2845
+ "Authorization": `Bearer ${accessToken}`,
2846
+ "Content-Type": "application/json"
2847
+ },
2848
+ timeout: 3e5,
2849
+ // 5 minutes
2850
+ retries: 1,
2851
+ silentErrors: false
2852
+ // We want to know about auth errors
2853
+ }
2854
+ );
2855
+ console.log("[AuthService] Session loaded:", {
2856
+ user_id: data.user_id,
2857
+ role: data.role,
2858
+ company_id: data.company_id,
2859
+ has_profile: !!data.profile,
2860
+ has_permissions: !!data.permissions
2861
+ });
2862
+ return data;
2863
+ } catch (error) {
2864
+ console.error("[AuthService] Session fetch failed:", error);
2865
+ throw error;
2787
2866
  }
2788
- const data = await response.json();
2789
- console.log("[AuthService] Session loaded:", {
2790
- user_id: data.user_id,
2791
- role: data.role,
2792
- company_id: data.company_id,
2793
- has_profile: !!data.profile,
2794
- has_permissions: !!data.permissions
2795
- });
2796
- return data;
2797
2867
  }
2798
2868
  /**
2799
- * Quick validation check without full profile fetch
2869
+ * Quick validation check without full profile fetch with timeout
2800
2870
  * Use this for lightweight auth checks
2801
- *
2871
+ *
2802
2872
  * @param accessToken - JWT token from Supabase
2803
2873
  * @returns Boolean indicating if session is valid
2804
2874
  */
2805
2875
  static async validateSession(accessToken) {
2806
2876
  try {
2807
2877
  console.log("[AuthService] Validating session...");
2808
- const response = await fetch(`${this.backendUrl}/api/auth/validate`, {
2809
- method: "POST",
2810
- headers: {
2811
- "Authorization": `Bearer ${accessToken}`,
2812
- "Content-Type": "application/json"
2878
+ const data = await ApiClient.fetch(
2879
+ `${this.backendUrl}/api/auth/validate`,
2880
+ {
2881
+ method: "POST",
2882
+ headers: {
2883
+ "Authorization": `Bearer ${accessToken}`,
2884
+ "Content-Type": "application/json"
2885
+ },
2886
+ timeout: 3e5,
2887
+ // 5 minutes
2888
+ retries: 2,
2889
+ // More retries for validation
2890
+ silentErrors: true,
2891
+ fallbackData: { valid: false, user_id: "", email: "" }
2892
+ // Safe default
2813
2893
  }
2814
- });
2815
- if (!response.ok) {
2816
- console.log("[AuthService] Session validation failed:", response.status);
2817
- return false;
2818
- }
2819
- const data = await response.json();
2894
+ );
2820
2895
  const isValid3 = data.valid === true;
2821
2896
  console.log("[AuthService] Session validation result:", isValid3);
2822
2897
  return isValid3;
@@ -2826,26 +2901,27 @@ var AuthService = class {
2826
2901
  }
2827
2902
  }
2828
2903
  /**
2829
- * Get just permissions (lightweight call)
2904
+ * Get just permissions (lightweight call) with timeout
2830
2905
  * Faster than full session fetch
2831
- *
2906
+ *
2832
2907
  * @param accessToken - JWT token from Supabase
2833
2908
  * @returns User permissions and role
2834
2909
  */
2835
2910
  static async getPermissions(accessToken) {
2836
2911
  console.log("[AuthService] Fetching permissions...");
2837
- const response = await fetch(`${this.backendUrl}/api/auth/permissions`, {
2838
- headers: {
2839
- "Authorization": `Bearer ${accessToken}`,
2840
- "Content-Type": "application/json"
2912
+ const data = await ApiClient.fetch(
2913
+ `${this.backendUrl}/api/auth/permissions`,
2914
+ {
2915
+ headers: {
2916
+ "Authorization": `Bearer ${accessToken}`,
2917
+ "Content-Type": "application/json"
2918
+ },
2919
+ timeout: 3e5,
2920
+ // 5 minutes
2921
+ retries: 1,
2922
+ silentErrors: false
2841
2923
  }
2842
- });
2843
- if (!response.ok) {
2844
- const errorText = await response.text();
2845
- console.error("[AuthService] Permissions fetch failed:", response.status, errorText);
2846
- throw new Error(`Failed to fetch permissions: ${response.statusText}`);
2847
- }
2848
- const data = await response.json();
2924
+ );
2849
2925
  console.log("[AuthService] Permissions loaded for role:", data.role);
2850
2926
  return data;
2851
2927
  }
@@ -5777,6 +5853,67 @@ var UserManagementService = class {
5777
5853
  var createUserManagementService = (supabase) => {
5778
5854
  return new UserManagementService(supabase);
5779
5855
  };
5856
+ var SupabaseContext = createContext(void 0);
5857
+ var SupabaseProvider = ({ client, children }) => {
5858
+ _setSupabaseInstance(client);
5859
+ useEffect(() => {
5860
+ _setSupabaseInstance(client);
5861
+ }, [client]);
5862
+ const contextValue = useMemo(() => ({ supabase: client }), [client]);
5863
+ return /* @__PURE__ */ jsx(SupabaseContext.Provider, { value: contextValue, children });
5864
+ };
5865
+ var useSupabase = () => {
5866
+ const context = useContext(SupabaseContext);
5867
+ if (context === void 0) {
5868
+ throw new Error("useSupabase must be used within a SupabaseProvider.");
5869
+ }
5870
+ return context.supabase;
5871
+ };
5872
+
5873
+ // src/lib/hooks/useSessionKeepAlive.ts
5874
+ var useSessionKeepAlive = (options = {}) => {
5875
+ const {
5876
+ enabled = true,
5877
+ intervalMs = 3e5
5878
+ // 5 minutes
5879
+ } = options;
5880
+ const supabase = useSupabase();
5881
+ const intervalRef = useRef(null);
5882
+ useEffect(() => {
5883
+ if (!enabled || !supabase) {
5884
+ return;
5885
+ }
5886
+ const keepAlive = async () => {
5887
+ try {
5888
+ const {
5889
+ data: { session }
5890
+ } = await supabase.auth.getSession();
5891
+ if (!session) {
5892
+ console.log("[SessionKeepAlive] No session, skipping keep-alive");
5893
+ return;
5894
+ }
5895
+ console.log("[SessionKeepAlive] Pinging backend to keep session alive");
5896
+ const isValid3 = await AuthService.validateSession(session.access_token);
5897
+ if (!isValid3) {
5898
+ console.warn("[SessionKeepAlive] Session validation failed");
5899
+ } else {
5900
+ console.log("[SessionKeepAlive] Session still valid");
5901
+ }
5902
+ } catch (error) {
5903
+ console.error("[SessionKeepAlive] Error during keep-alive:", error);
5904
+ }
5905
+ };
5906
+ const initialTimeout = setTimeout(keepAlive, 1e3);
5907
+ intervalRef.current = setInterval(keepAlive, intervalMs);
5908
+ return () => {
5909
+ clearTimeout(initialTimeout);
5910
+ if (intervalRef.current) {
5911
+ clearInterval(intervalRef.current);
5912
+ intervalRef.current = null;
5913
+ }
5914
+ };
5915
+ }, [enabled, intervalMs, supabase]);
5916
+ };
5780
5917
  var AuthContext = createContext({
5781
5918
  session: null,
5782
5919
  user: null,
@@ -5803,14 +5940,17 @@ var AuthProvider = ({ children }) => {
5803
5940
  const router = useRouter();
5804
5941
  const isFetchingRef = useRef(false);
5805
5942
  const lastProcessedSessionRef = useRef(null);
5806
- const fetchSession = useCallback(async (supabaseSession) => {
5943
+ const hasAuthenticatedRef = useRef(false);
5944
+ const fetchSession = useCallback(async (supabaseSession, isReauth = false) => {
5807
5945
  if (isFetchingRef.current) {
5808
5946
  console.log("[AuthContext] Already fetching, skipping duplicate request");
5809
5947
  return;
5810
5948
  }
5811
- console.log("[AuthContext] Fetching session from backend");
5949
+ console.log("[AuthContext] Fetching session from backend", { isReauth });
5812
5950
  isFetchingRef.current = true;
5813
- setLoading(true);
5951
+ if (!isReauth) {
5952
+ setLoading(true);
5953
+ }
5814
5954
  try {
5815
5955
  const enrichedUser = await AuthService.getSession(supabaseSession.access_token);
5816
5956
  const authUser = AuthService.toAuthUser(enrichedUser);
@@ -5818,6 +5958,7 @@ var AuthProvider = ({ children }) => {
5818
5958
  setSession(supabaseSession);
5819
5959
  setError(null);
5820
5960
  lastProcessedSessionRef.current = supabaseSession.access_token.substring(0, 20);
5961
+ hasAuthenticatedRef.current = true;
5821
5962
  if (!authUser.first_login_completed) {
5822
5963
  setShowOnboarding(true);
5823
5964
  }
@@ -5837,6 +5978,15 @@ var AuthProvider = ({ children }) => {
5837
5978
  });
5838
5979
  } catch (err) {
5839
5980
  console.error("[AuthContext] Failed to fetch session:", err);
5981
+ if (err.message?.includes("JWT expired") || err.message?.includes("invalid token") || err.message?.includes("token") || err.message?.includes("401")) {
5982
+ console.log("[AuthContext] Token expired or invalid, clearing session and redirecting to login");
5983
+ setUser(null);
5984
+ setSession(null);
5985
+ setError(new Error("Your session has expired. Please log in again."));
5986
+ await supabase.auth.signOut();
5987
+ router.replace("/login");
5988
+ return;
5989
+ }
5840
5990
  setError(err);
5841
5991
  setUser(null);
5842
5992
  if (err.message?.includes("profile")) {
@@ -5847,11 +5997,13 @@ var AuthProvider = ({ children }) => {
5847
5997
  setUser(basicUser);
5848
5998
  }
5849
5999
  } finally {
5850
- setLoading(false);
6000
+ if (!isReauth) {
6001
+ setLoading(false);
6002
+ }
5851
6003
  isFetchingRef.current = false;
5852
- console.log("[AuthContext] Loading set to false");
6004
+ console.log("[AuthContext] Loading set to false", { isReauth });
5853
6005
  }
5854
- }, []);
6006
+ }, [supabase, router]);
5855
6007
  const markFirstLoginCompleted = useCallback(async () => {
5856
6008
  if (!user?.id || !supabase) return false;
5857
6009
  try {
@@ -5883,6 +6035,7 @@ var AuthProvider = ({ children }) => {
5883
6035
  setSession(null);
5884
6036
  setError(null);
5885
6037
  setShowOnboarding(false);
6038
+ hasAuthenticatedRef.current = false;
5886
6039
  router.push("/login");
5887
6040
  } catch (err) {
5888
6041
  console.error("[AuthContext] Sign out error:", err);
@@ -5891,6 +6044,48 @@ var AuthProvider = ({ children }) => {
5891
6044
  setLoading(false);
5892
6045
  }
5893
6046
  }, [supabase, router, authConfig]);
6047
+ useSessionKeepAlive({
6048
+ enabled: !!session,
6049
+ // Only when logged in
6050
+ intervalMs: 3e5
6051
+ // 5 minutes
6052
+ });
6053
+ useEffect(() => {
6054
+ if (!session || !supabase) {
6055
+ return;
6056
+ }
6057
+ const monitorTokenExpiry = () => {
6058
+ const expiresAt = session.expires_at;
6059
+ if (!expiresAt) {
6060
+ console.warn("[AuthContext] Session has no expiry time");
6061
+ return;
6062
+ }
6063
+ const expiryTime = expiresAt * 1e3;
6064
+ const now2 = Date.now();
6065
+ const timeUntilExpiry = expiryTime - now2;
6066
+ const minutesUntilExpiry = Math.floor(timeUntilExpiry / 6e4);
6067
+ console.log(`[AuthContext] Token expires in ${minutesUntilExpiry} minutes`);
6068
+ if (minutesUntilExpiry < 5 && minutesUntilExpiry > 0) {
6069
+ console.warn("[AuthContext] Token expiring soon, attempting refresh...");
6070
+ supabase.auth.refreshSession().then(({ data, error: error2 }) => {
6071
+ if (error2) {
6072
+ console.error("[AuthContext] Token refresh failed:", error2);
6073
+ } else {
6074
+ console.log("[AuthContext] Token refreshed successfully");
6075
+ }
6076
+ });
6077
+ }
6078
+ if (timeUntilExpiry < 0) {
6079
+ console.error("[AuthContext] Token has expired, logging out");
6080
+ signOut();
6081
+ }
6082
+ };
6083
+ monitorTokenExpiry();
6084
+ const intervalId = setInterval(monitorTokenExpiry, 6e4);
6085
+ return () => {
6086
+ clearInterval(intervalId);
6087
+ };
6088
+ }, [session, supabase, signOut]);
5894
6089
  useEffect(() => {
5895
6090
  if (!supabase) {
5896
6091
  console.log("[AuthContext] No Supabase client, skipping auth initialization");
@@ -5911,7 +6106,8 @@ var AuthProvider = ({ children }) => {
5911
6106
  }
5912
6107
  if (currentSession) {
5913
6108
  console.log("[AuthContext] Found existing session, fetching user data");
5914
- await fetchSession(currentSession);
6109
+ const isReauth = hasAuthenticatedRef.current;
6110
+ await fetchSession(currentSession, isReauth);
5915
6111
  } else {
5916
6112
  console.log("[AuthContext] No session found");
5917
6113
  setLoading(false);
@@ -5943,20 +6139,27 @@ var AuthProvider = ({ children }) => {
5943
6139
  }
5944
6140
  console.log("[AuthContext] Processing auth event, fetching session");
5945
6141
  lastProcessedSessionRef.current = sessionId;
5946
- await fetchSession(currentSession);
6142
+ const isReauth = hasAuthenticatedRef.current;
6143
+ await fetchSession(currentSession, isReauth);
5947
6144
  }
5948
6145
  } else if (event === "SIGNED_OUT") {
5949
6146
  console.log("[AuthContext] User signed out");
5950
6147
  lastProcessedSessionRef.current = null;
6148
+ hasAuthenticatedRef.current = false;
5951
6149
  setUser(null);
5952
6150
  setSession(null);
5953
6151
  setError(null);
5954
6152
  setShowOnboarding(false);
5955
6153
  setLoading(false);
5956
6154
  } else if (event === "TOKEN_REFRESHED") {
5957
- console.log("[AuthContext] Token refreshed");
6155
+ console.log("[AuthContext] Token refreshed automatically");
5958
6156
  if (currentSession) {
5959
6157
  setSession(currentSession);
6158
+ const expiresAt = currentSession.expires_at;
6159
+ if (expiresAt) {
6160
+ const minutesUntilExpiry = Math.floor((expiresAt * 1e3 - Date.now()) / 6e4);
6161
+ console.log(`[AuthContext] New token expires in ${minutesUntilExpiry} minutes`);
6162
+ }
5960
6163
  }
5961
6164
  }
5962
6165
  });
@@ -5964,7 +6167,7 @@ var AuthProvider = ({ children }) => {
5964
6167
  mounted = false;
5965
6168
  subscription?.unsubscribe();
5966
6169
  };
5967
- }, [supabase, fetchSession]);
6170
+ }, [supabase]);
5968
6171
  const value = {
5969
6172
  session,
5970
6173
  user,
@@ -6012,22 +6215,6 @@ function usePageOverride(key, Default) {
6012
6215
  function useOverrides() {
6013
6216
  return useContext(DashboardOverridesContext);
6014
6217
  }
6015
- var SupabaseContext = createContext(void 0);
6016
- var SupabaseProvider = ({ client, children }) => {
6017
- _setSupabaseInstance(client);
6018
- useEffect(() => {
6019
- _setSupabaseInstance(client);
6020
- }, [client]);
6021
- const contextValue = useMemo(() => ({ supabase: client }), [client]);
6022
- return /* @__PURE__ */ jsx(SupabaseContext.Provider, { value: contextValue, children });
6023
- };
6024
- var useSupabase = () => {
6025
- const context = useContext(SupabaseContext);
6026
- if (context === void 0) {
6027
- throw new Error("useSupabase must be used within a SupabaseProvider.");
6028
- }
6029
- return context.supabase;
6030
- };
6031
6218
  var SubscriptionManagerContext = createContext({
6032
6219
  subscriptionManager: null
6033
6220
  });
@@ -10507,6 +10694,158 @@ var useWorkspaceHealthById = (workspaceId, options) => {
10507
10694
  refetch: fetchWorkspaceHealth
10508
10695
  };
10509
10696
  };
10697
+
10698
+ // src/lib/utils/relativeTime.ts
10699
+ function formatRelativeTime(timestamp) {
10700
+ if (!timestamp) return "Never";
10701
+ try {
10702
+ const now2 = /* @__PURE__ */ new Date();
10703
+ const date = typeof timestamp === "string" ? new Date(timestamp) : timestamp;
10704
+ if (isNaN(date.getTime())) return "Invalid date";
10705
+ if (date > now2) return "Just now";
10706
+ const diffMs = now2.getTime() - date.getTime();
10707
+ const diffSeconds = Math.floor(diffMs / 1e3);
10708
+ const diffMinutes = Math.floor(diffSeconds / 60);
10709
+ const diffHours = Math.floor(diffMinutes / 60);
10710
+ const diffDays = Math.floor(diffHours / 24);
10711
+ if (diffSeconds < 60) {
10712
+ return `${diffSeconds}s ago`;
10713
+ }
10714
+ if (diffMinutes < 60) {
10715
+ const remainingSeconds = diffSeconds % 60;
10716
+ if (remainingSeconds === 0) {
10717
+ return `${diffMinutes}m ago`;
10718
+ }
10719
+ return `${diffMinutes}m ${remainingSeconds}s ago`;
10720
+ }
10721
+ if (diffHours < 24) {
10722
+ const remainingMinutes = diffMinutes % 60;
10723
+ if (remainingMinutes === 0) {
10724
+ return `${diffHours}h ago`;
10725
+ }
10726
+ return `${diffHours}h ${remainingMinutes}m ago`;
10727
+ }
10728
+ return `${diffDays}d ago`;
10729
+ } catch (error) {
10730
+ console.error("[formatRelativeTime] Error formatting timestamp:", error);
10731
+ return "Unknown";
10732
+ }
10733
+ }
10734
+ function getNextUpdateInterval(timestamp) {
10735
+ if (!timestamp) return 6e4;
10736
+ try {
10737
+ const now2 = /* @__PURE__ */ new Date();
10738
+ const date = typeof timestamp === "string" ? new Date(timestamp) : timestamp;
10739
+ if (isNaN(date.getTime())) return 6e4;
10740
+ const diffMs = now2.getTime() - date.getTime();
10741
+ const diffSeconds = Math.floor(diffMs / 1e3);
10742
+ const diffMinutes = Math.floor(diffSeconds / 60);
10743
+ const diffHours = Math.floor(diffMinutes / 60);
10744
+ if (diffSeconds < 60) return 1e3;
10745
+ if (diffMinutes < 60) return 1e3;
10746
+ if (diffHours < 24) return 6e4;
10747
+ return 36e5;
10748
+ } catch (error) {
10749
+ return 6e4;
10750
+ }
10751
+ }
10752
+
10753
+ // src/lib/hooks/useWorkspaceHealthStatus.ts
10754
+ var useWorkspaceHealthStatus = (workspaceId) => {
10755
+ const supabase = useSupabase();
10756
+ const [healthData, setHealthData] = useState(null);
10757
+ const [loading, setLoading] = useState(true);
10758
+ const [error, setError] = useState(null);
10759
+ const [timeSinceUpdate, setTimeSinceUpdate] = useState("Never");
10760
+ const isFetchingRef = useRef(false);
10761
+ const updateIntervalRef = useRef(null);
10762
+ const fetchHealthStatus = useCallback(async () => {
10763
+ if (!supabase || !workspaceId || isFetchingRef.current) return;
10764
+ try {
10765
+ isFetchingRef.current = true;
10766
+ setLoading(true);
10767
+ setError(null);
10768
+ const { data, error: fetchError } = await supabase.from("workspace_health_status").select("*").eq("workspace_id", workspaceId).maybeSingle();
10769
+ if (fetchError) throw fetchError;
10770
+ if (data) {
10771
+ setHealthData(data);
10772
+ setTimeSinceUpdate(formatRelativeTime(data.last_heartbeat));
10773
+ } else {
10774
+ setHealthData(null);
10775
+ setTimeSinceUpdate("Never");
10776
+ }
10777
+ } catch (err) {
10778
+ console.error("[useWorkspaceHealthStatus] Error fetching health status:", err);
10779
+ setError({ message: err.message, code: err.code || "FETCH_ERROR" });
10780
+ setHealthData(null);
10781
+ setTimeSinceUpdate("Unknown");
10782
+ } finally {
10783
+ setLoading(false);
10784
+ isFetchingRef.current = false;
10785
+ }
10786
+ }, [supabase, workspaceId]);
10787
+ const updateDisplayTime = useCallback(() => {
10788
+ if (healthData?.last_heartbeat) {
10789
+ setTimeSinceUpdate(formatRelativeTime(healthData.last_heartbeat));
10790
+ }
10791
+ }, [healthData?.last_heartbeat]);
10792
+ useEffect(() => {
10793
+ fetchHealthStatus();
10794
+ }, [fetchHealthStatus]);
10795
+ useEffect(() => {
10796
+ if (!supabase || !workspaceId) return;
10797
+ console.log("[useWorkspaceHealthStatus] Setting up real-time subscription for workspace:", workspaceId);
10798
+ const channel = supabase.channel(`workspace-health-status-${workspaceId}`).on(
10799
+ "postgres_changes",
10800
+ {
10801
+ event: "*",
10802
+ // Listen to all events (INSERT, UPDATE, DELETE)
10803
+ schema: "public",
10804
+ table: "workspace_health_status",
10805
+ filter: `workspace_id=eq.${workspaceId}`
10806
+ },
10807
+ (payload) => {
10808
+ console.log("[useWorkspaceHealthStatus] Real-time update received:", payload);
10809
+ if (payload.new && "last_heartbeat" in payload.new) {
10810
+ const newData = payload.new;
10811
+ setHealthData(newData);
10812
+ setTimeSinceUpdate(formatRelativeTime(newData.last_heartbeat));
10813
+ } else if (payload.eventType === "DELETE") {
10814
+ setHealthData(null);
10815
+ setTimeSinceUpdate("Never");
10816
+ }
10817
+ }
10818
+ ).subscribe((status) => {
10819
+ console.log("[useWorkspaceHealthStatus] Subscription status:", status);
10820
+ });
10821
+ return () => {
10822
+ console.log("[useWorkspaceHealthStatus] Cleaning up subscription");
10823
+ supabase.removeChannel(channel);
10824
+ };
10825
+ }, [supabase, workspaceId]);
10826
+ useEffect(() => {
10827
+ if (updateIntervalRef.current) {
10828
+ clearInterval(updateIntervalRef.current);
10829
+ }
10830
+ if (!healthData?.last_heartbeat) return;
10831
+ const intervalMs = getNextUpdateInterval(healthData.last_heartbeat);
10832
+ updateIntervalRef.current = setInterval(updateDisplayTime, intervalMs);
10833
+ return () => {
10834
+ if (updateIntervalRef.current) {
10835
+ clearInterval(updateIntervalRef.current);
10836
+ }
10837
+ };
10838
+ }, [healthData?.last_heartbeat, updateDisplayTime]);
10839
+ return {
10840
+ lastHeartbeat: healthData?.last_heartbeat || null,
10841
+ timeSinceUpdate,
10842
+ isHealthy: healthData?.is_healthy ?? false,
10843
+ healthData,
10844
+ loading,
10845
+ error,
10846
+ refetch: fetchHealthStatus
10847
+ };
10848
+ };
10510
10849
  function useDateFormatter() {
10511
10850
  const { defaultTimezone, defaultLocale, dateFormatOptions, timeFormatOptions, dateTimeFormatOptions } = useDateTimeConfig();
10512
10851
  const formatDate = useCallback(
@@ -13866,7 +14205,9 @@ var createSupabaseClient = (url, key) => createClient(url, key, {
13866
14205
  autoRefreshToken: true,
13867
14206
  persistSession: true,
13868
14207
  detectSessionInUrl: true,
13869
- flowType: "pkce"
14208
+ flowType: "pkce",
14209
+ // Enable debug logging in development
14210
+ debug: process.env.NODE_ENV === "development"
13870
14211
  },
13871
14212
  db: {
13872
14213
  schema: "public"
@@ -13875,6 +14216,22 @@ var createSupabaseClient = (url, key) => createClient(url, key, {
13875
14216
  global: {
13876
14217
  headers: {
13877
14218
  "x-application-name": "optifye-dashboard"
14219
+ },
14220
+ // Add global fetch timeout (5 minutes)
14221
+ fetch: async (url2, options = {}) => {
14222
+ const controller = new AbortController();
14223
+ const timeoutId = setTimeout(() => controller.abort(), 3e5);
14224
+ try {
14225
+ const response = await fetch(url2, {
14226
+ ...options,
14227
+ signal: controller.signal
14228
+ });
14229
+ clearTimeout(timeoutId);
14230
+ return response;
14231
+ } catch (error) {
14232
+ clearTimeout(timeoutId);
14233
+ throw error;
14234
+ }
13878
14235
  }
13879
14236
  }
13880
14237
  });
@@ -13889,7 +14246,29 @@ var getAnonClient = () => {
13889
14246
  autoRefreshToken: true,
13890
14247
  persistSession: true,
13891
14248
  detectSessionInUrl: true,
13892
- flowType: "pkce"
14249
+ flowType: "pkce",
14250
+ debug: process.env.NODE_ENV === "development"
14251
+ },
14252
+ global: {
14253
+ headers: {
14254
+ "x-application-name": "optifye-dashboard"
14255
+ },
14256
+ // Add global fetch timeout (5 minutes)
14257
+ fetch: async (url2, options = {}) => {
14258
+ const controller = new AbortController();
14259
+ const timeoutId = setTimeout(() => controller.abort(), 3e5);
14260
+ try {
14261
+ const response = await fetch(url2, {
14262
+ ...options,
14263
+ signal: controller.signal
14264
+ });
14265
+ clearTimeout(timeoutId);
14266
+ return response;
14267
+ } catch (error) {
14268
+ clearTimeout(timeoutId);
14269
+ throw error;
14270
+ }
14271
+ }
13893
14272
  }
13894
14273
  });
13895
14274
  };
@@ -21253,17 +21632,33 @@ var createMotionComponent = /* @__PURE__ */ createMotionComponentFactory({
21253
21632
 
21254
21633
  // ../../node_modules/framer-motion/dist/es/render/components/motion/proxy.mjs
21255
21634
  var motion = /* @__PURE__ */ createDOMMotionComponentProxy(createMotionComponent);
21635
+
21636
+ // src/assets/optifye-logo.png
21637
+ var optifye_logo_default = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAACFIAAASwCAYAAADSLPxEAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAEyGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSfvu78nIGlkPSdXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQnPz4KPHg6eG1wbWV0YSB4bWxuczp4PSdhZG9iZTpuczptZXRhLyc+CjxyZGY6UkRGIHhtbG5zOnJkZj0naHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyc+CgogPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9JycKICB4bWxuczpBdHRyaWI9J2h0dHA6Ly9ucy5hdHRyaWJ1dGlvbi5jb20vYWRzLzEuMC8nPgogIDxBdHRyaWI6QWRzPgogICA8cmRmOlNlcT4KICAgIDxyZGY6bGkgcmRmOnBhcnNlVHlwZT0nUmVzb3VyY2UnPgogICAgIDxBdHRyaWI6Q3JlYXRlZD4yMDI1LTAyLTE5PC9BdHRyaWI6Q3JlYXRlZD4KICAgICA8QXR0cmliOkV4dElkPmEwNzgwZWVmLWUxNjItNGE4MS1iY2I0LTgxODU3M2VkMmI5YjwvQXR0cmliOkV4dElkPgogICAgIDxBdHRyaWI6RmJJZD41MjUyNjU5MTQxNzk1ODA8L0F0dHJpYjpGYklkPgogICAgIDxBdHRyaWI6VG91Y2hUeXBlPjI8L0F0dHJpYjpUb3VjaFR5cGU+CiAgICA8L3JkZjpsaT4KICAgPC9yZGY6U2VxPgogIDwvQXR0cmliOkFkcz4KIDwvcmRmOkRlc2NyaXB0aW9uPgoKIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PScnCiAgeG1sbnM6ZGM9J2h0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvJz4KICA8ZGM6dGl0bGU+CiAgIDxyZGY6QWx0PgogICAgPHJkZjpsaSB4bWw6bGFuZz0neC1kZWZhdWx0Jz5vcHRpZnllIGxvZ28gc2V4eSAoMjEzMCB4IDEyMDAgcHgpIC0gMTwvcmRmOmxpPgogICA8L3JkZjpBbHQ+CiAgPC9kYzp0aXRsZT4KIDwvcmRmOkRlc2NyaXB0aW9u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";
21638
+ var Logo = ({
21639
+ className = "",
21640
+ alt = "Optifye"
21641
+ }) => {
21642
+ return /* @__PURE__ */ jsx(
21643
+ "img",
21644
+ {
21645
+ src: optifye_logo_default,
21646
+ alt,
21647
+ className
21648
+ }
21649
+ );
21650
+ };
21256
21651
  var OptifyeLogoLoader = ({
21257
21652
  size = "md",
21258
21653
  message,
21259
21654
  className
21260
21655
  }) => {
21261
21656
  const sizeClasses = {
21262
- sm: "w-10",
21657
+ sm: "w-10 h-10",
21263
21658
  // 40px
21264
- md: "w-16",
21659
+ md: "w-16 h-16",
21265
21660
  // 64px
21266
- lg: "w-24"
21661
+ lg: "w-24 h-24"
21267
21662
  // 96px
21268
21663
  };
21269
21664
  return /* @__PURE__ */ jsxs(
@@ -21274,11 +21669,10 @@ var OptifyeLogoLoader = ({
21274
21669
  className: `flex flex-col items-center justify-center p-4 ${className || ""}`.trim(),
21275
21670
  children: [
21276
21671
  /* @__PURE__ */ jsx(
21277
- "img",
21672
+ Logo,
21278
21673
  {
21279
- src: "/optifye-logo.png",
21280
- alt: "Optifye Logo",
21281
- className: `${sizeClasses[size]} h-auto animate-pulse select-none pointer-events-none`
21674
+ className: `${sizeClasses[size]} object-contain animate-pulse select-none pointer-events-none`,
21675
+ alt: "Optifye Logo"
21282
21676
  }
21283
21677
  ),
21284
21678
  message && /* @__PURE__ */ jsx("div", { className: "mt-3 text-gray-600 text-base sm:text-sm font-medium text-center", children: message })
@@ -21290,15 +21684,65 @@ var OptifyeLogoLoader_default = OptifyeLogoLoader;
21290
21684
  var LoadingPage = ({
21291
21685
  message = "Loading Dashboard...",
21292
21686
  subMessage = "Please wait while we prepare your data",
21293
- className
21687
+ className,
21688
+ onTimeout,
21689
+ timeoutMs = 3e5
21690
+ // 5 minutes default
21294
21691
  }) => {
21295
- React23__default.useEffect(() => {
21296
- console.log("LoadingPage rendered with message:", message);
21297
- const timeout = setTimeout(() => {
21298
- console.warn("LoadingPage has been visible for more than 8 seconds. This might indicate an issue.");
21299
- }, 8e3);
21300
- return () => clearTimeout(timeout);
21301
- }, [message]);
21692
+ const [showTimeoutWarning, setShowTimeoutWarning] = useState(false);
21693
+ const [timeoutReached, setTimeoutReached] = useState(false);
21694
+ const warningTime = timeoutMs * 0.8;
21695
+ useEffect(() => {
21696
+ console.log("[LoadingPage] Rendered with message:", message);
21697
+ const warningTimer = setTimeout(() => {
21698
+ console.warn("[LoadingPage] Loading taking longer than expected");
21699
+ setShowTimeoutWarning(true);
21700
+ }, warningTime);
21701
+ const timeoutTimer = setTimeout(() => {
21702
+ console.error("[LoadingPage] Loading timeout reached after", timeoutMs, "ms");
21703
+ setTimeoutReached(true);
21704
+ if (onTimeout) {
21705
+ onTimeout();
21706
+ }
21707
+ }, timeoutMs);
21708
+ return () => {
21709
+ clearTimeout(warningTimer);
21710
+ clearTimeout(timeoutTimer);
21711
+ };
21712
+ }, [message, timeoutMs, warningTime, onTimeout]);
21713
+ const handleResetAndTryAgain = useCallback(() => {
21714
+ console.log("[LoadingPage] User initiated reset");
21715
+ const hasLocalStorage = typeof window !== "undefined" && window.localStorage;
21716
+ const hasCachedData = hasLocalStorage && localStorage.getItem("sb-zmzewpwerpaupoaoeqhh-auth-token");
21717
+ if (hasCachedData) {
21718
+ console.log("[LoadingPage] Found cached session, attempting to use it");
21719
+ window.location.reload();
21720
+ } else {
21721
+ console.log("[LoadingPage] No cached session, redirecting to login");
21722
+ if (hasLocalStorage) {
21723
+ localStorage.clear();
21724
+ sessionStorage.clear();
21725
+ }
21726
+ window.location.href = "/login";
21727
+ }
21728
+ }, []);
21729
+ if (timeoutReached) {
21730
+ return /* @__PURE__ */ jsx("div", { className: `flex h-full w-full items-center justify-center bg-slate-50 ${className || ""}`, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center space-y-6 text-center max-w-md", children: [
21731
+ /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "lg", message: "Loading Dashboard..." }),
21732
+ /* @__PURE__ */ jsxs(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, className: "space-y-2", children: [
21733
+ /* @__PURE__ */ jsx("p", { className: "text-base text-gray-600", children: "This is taking longer than usual" }),
21734
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500", children: "Your session might have timed out" })
21735
+ ] }),
21736
+ /* @__PURE__ */ jsx(
21737
+ "button",
21738
+ {
21739
+ onClick: handleResetAndTryAgain,
21740
+ className: "mt-4 px-4 py-2 text-sm text-gray-600 hover:text-gray-900 underline transition-colors",
21741
+ children: "Reset and try again"
21742
+ }
21743
+ )
21744
+ ] }) });
21745
+ }
21302
21746
  return /* @__PURE__ */ jsx("div", { className: `flex h-full w-full items-center justify-center bg-slate-50 ${className || ""}`, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center space-y-6 text-center", children: [
21303
21747
  /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "lg", message }),
21304
21748
  subMessage && /* @__PURE__ */ jsx(
@@ -21310,23 +21754,19 @@ var LoadingPage = ({
21310
21754
  transition: { delay: 0.2, duration: 0.3 },
21311
21755
  children: subMessage
21312
21756
  }
21757
+ ),
21758
+ showTimeoutWarning && !timeoutReached && /* @__PURE__ */ jsx(
21759
+ motion.p,
21760
+ {
21761
+ initial: { opacity: 0 },
21762
+ animate: { opacity: 1 },
21763
+ className: "text-sm text-gray-500 italic",
21764
+ children: "Still loading, please wait..."
21765
+ }
21313
21766
  )
21314
21767
  ] }) });
21315
21768
  };
21316
21769
  var LoadingPage_default = LoadingPage;
21317
- var AccessDeniedPage = () => /* @__PURE__ */ jsx("div", { className: "min-h-screen flex items-center justify-center bg-gray-50", children: /* @__PURE__ */ jsxs("div", { className: "max-w-md w-full bg-white shadow-lg rounded-lg p-6 text-center", children: [
21318
- /* @__PURE__ */ jsx("div", { className: "mb-4", children: /* @__PURE__ */ jsx("svg", { className: "mx-auto h-12 w-12 text-red-500", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("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.962-.833-2.732 0L4.082 15.5c-.77.833.192 2.5 1.732 2.5z" }) }) }),
21319
- /* @__PURE__ */ jsx("h1", { className: "text-xl font-semibold text-gray-900 mb-2", children: "Access Denied" }),
21320
- /* @__PURE__ */ jsx("p", { className: "text-gray-600 mb-4", children: "You do not have access to this dashboard. Please contact your administrator for assistance." }),
21321
- /* @__PURE__ */ jsx(
21322
- "button",
21323
- {
21324
- onClick: () => window.location.href = "/login",
21325
- className: "bg-blue-600 hover:bg-blue-700 text-white font-medium py-2 px-4 rounded-md transition-colors",
21326
- children: "Return to Login"
21327
- }
21328
- )
21329
- ] }) });
21330
21770
  var withAuth = (WrappedComponent2, options) => {
21331
21771
  const defaultOptions = {
21332
21772
  redirectTo: "/login",
@@ -21336,22 +21776,64 @@ var withAuth = (WrappedComponent2, options) => {
21336
21776
  const WithAuthComponent = React23.memo(function WithAuthComponent2(props) {
21337
21777
  const { session, loading, error } = useAuth();
21338
21778
  const router = useRouter();
21779
+ const [localLoading, setLocalLoading] = React23.useState(loading);
21780
+ const [loadingTimeoutReached, setLoadingTimeoutReached] = React23.useState(false);
21339
21781
  React23.useEffect(() => {
21340
21782
  if (process.env.NODE_ENV === "development" && process.env.DEBUG_AUTH === "true") {
21341
- console.log("withAuth state:", { loading, hasSession: !!session, requireAuth: defaultOptions.requireAuth });
21783
+ console.log("withAuth state:", {
21784
+ loading,
21785
+ hasSession: !!session,
21786
+ requireAuth: defaultOptions.requireAuth,
21787
+ hasError: !!error
21788
+ });
21342
21789
  }
21343
- }, [session, loading]);
21790
+ }, [session, loading, error]);
21791
+ const handleLoadingTimeout = React23.useCallback(() => {
21792
+ console.warn("[withAuth] Loading timeout reached");
21793
+ setLoadingTimeoutReached(true);
21794
+ if (typeof window !== "undefined" && localStorage.getItem("sb-zmzewpwerpaupoaoeqhh-auth-token")) {
21795
+ console.log("[withAuth] Found cached session, attempting to continue");
21796
+ setLocalLoading(false);
21797
+ } else {
21798
+ console.log("[withAuth] No cached session, redirecting to login");
21799
+ router.replace(defaultOptions.redirectTo);
21800
+ }
21801
+ }, [router]);
21344
21802
  React23.useEffect(() => {
21345
21803
  if (!loading && defaultOptions.requireAuth && !session && !error) {
21346
- console.log("Redirecting to login from withAuth");
21804
+ console.log("[withAuth] No session found, redirecting to login");
21347
21805
  router.replace(defaultOptions.redirectTo);
21348
21806
  }
21349
21807
  }, [session, loading, router, error]);
21350
- if (loading) {
21351
- return /* @__PURE__ */ jsx(LoadingPage, { message: "Authenticating..." });
21808
+ React23.useEffect(() => {
21809
+ setLocalLoading(loading);
21810
+ }, [loading]);
21811
+ if (loading || localLoading) {
21812
+ return /* @__PURE__ */ jsx(
21813
+ LoadingPage,
21814
+ {
21815
+ message: "Authenticating...",
21816
+ timeoutMs: 3e5,
21817
+ onTimeout: handleLoadingTimeout
21818
+ }
21819
+ );
21352
21820
  }
21353
- if (error && error.message.includes("You do not have access to this dashboard")) {
21354
- return /* @__PURE__ */ jsx(AccessDeniedPage, {});
21821
+ if (error) {
21822
+ console.error("[withAuth] Auth error:", {
21823
+ message: error.message,
21824
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
21825
+ });
21826
+ if (error.message.includes("You do not have access to this dashboard")) {
21827
+ return /* @__PURE__ */ jsx("div", { className: "min-h-screen flex items-center justify-center bg-slate-50", children: /* @__PURE__ */ jsxs("div", { className: "max-w-md text-center space-y-4", children: [
21828
+ /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "lg", message: "Checking Access..." }),
21829
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500", children: "Verifying your permissions" }),
21830
+ /* @__PURE__ */ jsx("a", { href: "/login", className: "text-xs text-gray-400 hover:text-gray-600 underline", children: "Return to login" })
21831
+ ] }) });
21832
+ }
21833
+ if (defaultOptions.requireAuth) {
21834
+ router.replace(defaultOptions.redirectTo);
21835
+ return null;
21836
+ }
21355
21837
  }
21356
21838
  if (defaultOptions.requireAuth && !session) {
21357
21839
  return null;
@@ -21388,7 +21870,7 @@ function withAccessControl(WrappedComponent2, options = {}) {
21388
21870
  }
21389
21871
  var LoginPage = ({
21390
21872
  onRateLimitCheck,
21391
- logoSrc = "/optifye-logo.png",
21873
+ logoSrc = optifye_logo_default,
21392
21874
  logoAlt = "Optifye",
21393
21875
  brandName = "Optifye"
21394
21876
  }) => {
@@ -24997,13 +25479,37 @@ var WhatsAppShareButton = ({
24997
25479
  }
24998
25480
  );
24999
25481
  };
25482
+ var AxelOrb = ({
25483
+ className = "",
25484
+ size = "md",
25485
+ animate = false
25486
+ }) => {
25487
+ const sizeClasses = {
25488
+ sm: "w-8 h-8",
25489
+ md: "w-10 h-10",
25490
+ lg: "w-12 h-12",
25491
+ xl: "w-16 h-16",
25492
+ "2xl": "w-20 h-20"
25493
+ };
25494
+ return /* @__PURE__ */ jsx(
25495
+ "div",
25496
+ {
25497
+ className: `${sizeClasses[size]} rounded-full ${animate ? "animate-float" : ""} ${className}`,
25498
+ style: {
25499
+ background: "linear-gradient(to top, #078DDB 0%, #65ADD6 33%, #A3D0E6 66%, #C7E2EC 100%)",
25500
+ boxShadow: "0 4px 12px rgba(7, 141, 219, 0.4), 0 0 20px rgba(7, 141, 219, 0.2)"
25501
+ },
25502
+ "aria-label": "Axel AI",
25503
+ role: "img"
25504
+ }
25505
+ );
25506
+ };
25000
25507
  var BreakNotificationPopup = ({
25001
25508
  activeBreaks,
25002
25509
  onDismiss,
25003
25510
  isVisible = true,
25004
25511
  className = "",
25005
- lineNames = {},
25006
- axelImagePath = "/axel-profile.png"
25512
+ lineNames = {}
25007
25513
  }) => {
25008
25514
  const [isDismissed, setIsDismissed] = useState(false);
25009
25515
  const [currentTime, setCurrentTime] = useState(/* @__PURE__ */ new Date());
@@ -25039,22 +25545,7 @@ var BreakNotificationPopup = ({
25039
25545
  style: { top: `${6 + index * 12}rem` },
25040
25546
  children: /* @__PURE__ */ jsx("div", { className: "bg-white text-gray-900 rounded-lg border border-gray-200 shadow-lg overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "p-3", children: /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between", children: [
25041
25547
  /* @__PURE__ */ jsxs("div", { className: "flex items-start space-x-3 flex-1", children: [
25042
- /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx(
25043
- "img",
25044
- {
25045
- src: axelImagePath,
25046
- alt: "Axel AI",
25047
- className: "w-10 h-10 rounded-full object-cover border-2 border-gray-200 shadow-sm",
25048
- onError: (e) => {
25049
- const target = e.currentTarget;
25050
- target.style.display = "none";
25051
- const fallback = document.createElement("div");
25052
- fallback.className = "w-10 h-10 rounded-full bg-blue-500 flex items-center justify-center text-white font-bold text-base shadow-sm border-2 border-gray-200";
25053
- fallback.textContent = "A";
25054
- target.parentElement?.appendChild(fallback);
25055
- }
25056
- }
25057
- ) }),
25548
+ /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx(AxelOrb, { size: "md" }) }),
25058
25549
  /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
25059
25550
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-1.5", children: [
25060
25551
  /* @__PURE__ */ jsxs("h4", { className: "font-semibold text-sm text-gray-900", children: [
@@ -25254,8 +25745,7 @@ var AxelNotificationPopup = ({
25254
25745
  suggestion,
25255
25746
  isVisible = true,
25256
25747
  onDismiss,
25257
- className = "",
25258
- axelImagePath = "/axel-profile.png"
25748
+ className = ""
25259
25749
  }) => {
25260
25750
  const [isDismissed, setIsDismissed] = useState(false);
25261
25751
  useEffect(() => {
@@ -25301,22 +25791,7 @@ var AxelNotificationPopup = ({
25301
25791
  className: "p-3",
25302
25792
  children: /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between", children: [
25303
25793
  /* @__PURE__ */ jsxs("div", { className: "flex items-start space-x-3 flex-1", children: [
25304
- /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx(
25305
- "img",
25306
- {
25307
- src: axelImagePath,
25308
- alt: "Axel AI",
25309
- className: "w-10 h-10 rounded-full object-cover border-2 border-gray-200 shadow-sm",
25310
- onError: (e) => {
25311
- const target = e.currentTarget;
25312
- target.style.display = "none";
25313
- const fallback = document.createElement("div");
25314
- fallback.className = "w-10 h-10 rounded-full bg-blue-500 flex items-center justify-center text-white font-bold text-base shadow-sm border-2 border-gray-200";
25315
- fallback.textContent = "A";
25316
- target.parentElement?.appendChild(fallback);
25317
- }
25318
- }
25319
- ) }),
25794
+ /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx(AxelOrb, { size: "md" }) }),
25320
25795
  /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
25321
25796
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-1.5", children: [
25322
25797
  /* @__PURE__ */ jsx("h4", { className: "font-semibold text-sm text-gray-900", children: suggestion.title }),
@@ -25767,6 +26242,140 @@ var TimePickerDropdown = ({
25767
26242
  ] })
25768
26243
  ] });
25769
26244
  };
26245
+ var SilentErrorBoundary = class extends React23__default.Component {
26246
+ constructor(props) {
26247
+ super(props);
26248
+ this.handleClearAndReload = () => {
26249
+ console.log("[ErrorBoundary] User initiated reset");
26250
+ if (typeof window !== "undefined") {
26251
+ try {
26252
+ localStorage.clear();
26253
+ sessionStorage.clear();
26254
+ console.log("[ErrorBoundary] Cleared all storage");
26255
+ } catch (error) {
26256
+ console.error("[ErrorBoundary] Failed to clear storage:", error);
26257
+ }
26258
+ }
26259
+ window.location.href = "/login";
26260
+ };
26261
+ this.state = {
26262
+ hasError: false,
26263
+ errorCount: 0,
26264
+ lastError: null,
26265
+ errorInfo: null
26266
+ };
26267
+ }
26268
+ static getDerivedStateFromError(error) {
26269
+ return { hasError: true };
26270
+ }
26271
+ componentDidCatch(error, errorInfo) {
26272
+ console.error("[ErrorBoundary] Caught render error:", {
26273
+ error: error.message,
26274
+ stack: error.stack,
26275
+ componentStack: errorInfo.componentStack,
26276
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
26277
+ });
26278
+ this.setState((prev) => ({
26279
+ errorCount: prev.errorCount + 1,
26280
+ lastError: error,
26281
+ errorInfo
26282
+ }));
26283
+ try {
26284
+ if (typeof window !== "undefined" && window.mixpanel) {
26285
+ window.mixpanel.track("React Render Error", {
26286
+ error: error.message,
26287
+ component: errorInfo.componentStack?.split("\n")[1] || "unknown",
26288
+ errorCount: this.state.errorCount + 1
26289
+ });
26290
+ }
26291
+ } catch (analyticsError) {
26292
+ console.warn("[ErrorBoundary] Analytics tracking failed:", analyticsError);
26293
+ }
26294
+ }
26295
+ render() {
26296
+ if (!this.state.hasError) {
26297
+ return this.props.children;
26298
+ }
26299
+ return /* @__PURE__ */ jsx("div", { className: "flex h-screen w-screen items-center justify-center bg-slate-50", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center space-y-6 text-center", children: [
26300
+ /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "lg", message: "Loading Dashboard..." }),
26301
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500", children: "Taking longer than usual..." }),
26302
+ /* @__PURE__ */ jsx("div", { className: "pt-4", children: /* @__PURE__ */ jsx(
26303
+ "a",
26304
+ {
26305
+ href: "#",
26306
+ onClick: (e) => {
26307
+ e.preventDefault();
26308
+ this.handleClearAndReload();
26309
+ },
26310
+ className: "text-xs text-gray-400 hover:text-gray-600 underline transition-colors",
26311
+ children: "Reset and try again"
26312
+ }
26313
+ ) }),
26314
+ process.env.NODE_ENV === "development" && /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-400 italic mt-4", children: "Check console for error details" })
26315
+ ] }) });
26316
+ }
26317
+ };
26318
+ var PlayPauseIndicator = ({
26319
+ show,
26320
+ isPlaying,
26321
+ duration = 600
26322
+ }) => {
26323
+ const [isVisible, setIsVisible] = useState(false);
26324
+ const [isFading, setIsFading] = useState(false);
26325
+ useEffect(() => {
26326
+ if (show) {
26327
+ setIsVisible(true);
26328
+ setIsFading(false);
26329
+ const fadeTimer = setTimeout(() => {
26330
+ setIsFading(true);
26331
+ }, 100);
26332
+ const hideTimer = setTimeout(() => {
26333
+ setIsVisible(false);
26334
+ setIsFading(false);
26335
+ }, duration);
26336
+ return () => {
26337
+ clearTimeout(fadeTimer);
26338
+ clearTimeout(hideTimer);
26339
+ };
26340
+ }
26341
+ }, [show, duration]);
26342
+ if (!isVisible) return null;
26343
+ return /* @__PURE__ */ jsx(
26344
+ "div",
26345
+ {
26346
+ className: "absolute inset-0 flex items-center justify-center pointer-events-none z-10",
26347
+ style: {
26348
+ opacity: isFading ? 0 : 1,
26349
+ transition: `opacity ${duration - 100}ms ease-out`
26350
+ },
26351
+ children: /* @__PURE__ */ jsx("div", { className: "bg-black/70 rounded-full p-6", children: isPlaying ? (
26352
+ // Play icon (triangle)
26353
+ /* @__PURE__ */ jsx(
26354
+ "svg",
26355
+ {
26356
+ xmlns: "http://www.w3.org/2000/svg",
26357
+ viewBox: "0 0 24 24",
26358
+ fill: "white",
26359
+ className: "w-16 h-16",
26360
+ children: /* @__PURE__ */ jsx("path", { d: "M8 5v14l11-7z" })
26361
+ }
26362
+ )
26363
+ ) : (
26364
+ // Pause icon (two bars)
26365
+ /* @__PURE__ */ jsx(
26366
+ "svg",
26367
+ {
26368
+ xmlns: "http://www.w3.org/2000/svg",
26369
+ viewBox: "0 0 24 24",
26370
+ fill: "white",
26371
+ className: "w-16 h-16",
26372
+ children: /* @__PURE__ */ jsx("path", { d: "M6 4h4v16H6V4zm8 0h4v16h-4V4z" })
26373
+ }
26374
+ )
26375
+ ) })
26376
+ }
26377
+ );
26378
+ };
25770
26379
  var ERROR_MAPPING = {
25771
26380
  1: {
25772
26381
  // MEDIA_ERR_ABORTED
@@ -25872,12 +26481,16 @@ var VideoPlayer = React23__default.forwardRef(({
25872
26481
  onLoadedMetadata,
25873
26482
  onLoadedData,
25874
26483
  onSeeking,
25875
- onSeeked
26484
+ onSeeked,
26485
+ onClick
25876
26486
  }, ref) => {
25877
26487
  const videoRef = useRef(null);
25878
26488
  const playerRef = useRef(null);
25879
26489
  const [isReady, setIsReady] = useState(false);
25880
26490
  const [isLoading, setIsLoading] = useState(true);
26491
+ const [showIndicator, setShowIndicator] = useState(false);
26492
+ const [indicatorIsPlaying, setIndicatorIsPlaying] = useState(false);
26493
+ const indicatorKeyRef = useRef(0);
25881
26494
  const defaultOptions = {
25882
26495
  controls: false,
25883
26496
  // Always disable Video.js controls - we use custom controls
@@ -26193,6 +26806,18 @@ var VideoPlayer = React23__default.forwardRef(({
26193
26806
  dispose,
26194
26807
  isReady
26195
26808
  }));
26809
+ const handleClickWithIndicator = useCallback(() => {
26810
+ if (!onClick || !playerRef.current) return;
26811
+ const player = playerRef.current;
26812
+ const willBePlaying = player.paused();
26813
+ setIndicatorIsPlaying(willBePlaying);
26814
+ setShowIndicator(false);
26815
+ setTimeout(() => {
26816
+ indicatorKeyRef.current += 1;
26817
+ setShowIndicator(true);
26818
+ }, 0);
26819
+ onClick();
26820
+ }, [onClick]);
26196
26821
  return /* @__PURE__ */ jsxs("div", { className: `video-player-wrapper ${className}`, style: { position: "relative", width: "100%", height: "100%" }, children: [
26197
26822
  /* @__PURE__ */ jsx(
26198
26823
  "div",
@@ -26202,7 +26827,31 @@ var VideoPlayer = React23__default.forwardRef(({
26202
26827
  "data-vjs-player": true
26203
26828
  }
26204
26829
  ),
26205
- isLoading && !externalLoadingControl && /* @__PURE__ */ jsx("div", { className: "video-player-loading", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) })
26830
+ isLoading && !externalLoadingControl && /* @__PURE__ */ jsx("div", { className: "video-player-loading", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
26831
+ onClick && /* @__PURE__ */ jsx(
26832
+ "div",
26833
+ {
26834
+ onClick: handleClickWithIndicator,
26835
+ style: {
26836
+ position: "absolute",
26837
+ top: 0,
26838
+ left: 0,
26839
+ right: 0,
26840
+ bottom: 0,
26841
+ zIndex: 1,
26842
+ cursor: "pointer"
26843
+ },
26844
+ "aria-label": "Click to play/pause"
26845
+ }
26846
+ ),
26847
+ onClick && /* @__PURE__ */ jsx(
26848
+ PlayPauseIndicator,
26849
+ {
26850
+ show: showIndicator,
26851
+ isPlaying: indicatorIsPlaying
26852
+ },
26853
+ indicatorKeyRef.current
26854
+ )
26206
26855
  ] });
26207
26856
  });
26208
26857
  VideoPlayer.displayName = "VideoPlayer";
@@ -26220,6 +26869,9 @@ var CroppedVideoPlayer = forwardRef(({
26220
26869
  const [isVideoReady, setIsVideoReady] = useState(false);
26221
26870
  const [canvasDimensions, setCanvasDimensions] = useState({ width: 0, height: 0 });
26222
26871
  const [isProcessing, setIsProcessing] = useState(false);
26872
+ const [showIndicator, setShowIndicator] = useState(false);
26873
+ const [indicatorIsPlaying, setIndicatorIsPlaying] = useState(false);
26874
+ const indicatorKeyRef = useRef(0);
26223
26875
  const stopCanvasRendering = useCallback(() => {
26224
26876
  if (animationFrameRef.current) {
26225
26877
  cancelAnimationFrame(animationFrameRef.current);
@@ -26398,14 +27050,26 @@ var CroppedVideoPlayer = forwardRef(({
26398
27050
  };
26399
27051
  }, [stopCanvasRendering]);
26400
27052
  if (!crop) {
26401
- return /* @__PURE__ */ jsx(VideoPlayer, { ref, ...videoProps });
26402
- }
27053
+ return /* @__PURE__ */ jsx(VideoPlayer, { ref, ...videoProps, onClick });
27054
+ }
27055
+ const handleClickWithIndicator = () => {
27056
+ if (!onClick || !hiddenVideoRef.current?.player) return;
27057
+ const player = hiddenVideoRef.current.player;
27058
+ const willBePlaying = player.paused();
27059
+ setIndicatorIsPlaying(willBePlaying);
27060
+ setShowIndicator(false);
27061
+ setTimeout(() => {
27062
+ indicatorKeyRef.current += 1;
27063
+ setShowIndicator(true);
27064
+ }, 0);
27065
+ onClick();
27066
+ };
26403
27067
  return /* @__PURE__ */ jsxs(
26404
27068
  "div",
26405
27069
  {
26406
27070
  ref: videoContainerRef,
26407
27071
  className: `relative w-full h-full flex items-center justify-center bg-black ${onClick ? "cursor-pointer" : ""} ${videoProps.className || ""}`,
26408
- onClick,
27072
+ onClick: handleClickWithIndicator,
26409
27073
  children: [
26410
27074
  /* @__PURE__ */ jsx("div", { className: "hidden", children: /* @__PURE__ */ jsx(
26411
27075
  VideoPlayer,
@@ -26462,7 +27126,15 @@ var CroppedVideoPlayer = forwardRef(({
26462
27126
  "Processing: ",
26463
27127
  isProcessing ? "Yes" : "No"
26464
27128
  ] })
26465
- ] })
27129
+ ] }),
27130
+ onClick && /* @__PURE__ */ jsx(
27131
+ PlayPauseIndicator,
27132
+ {
27133
+ show: showIndicator,
27134
+ isPlaying: indicatorIsPlaying
27135
+ },
27136
+ indicatorKeyRef.current
27137
+ )
26466
27138
  ]
26467
27139
  }
26468
27140
  );
@@ -28117,6 +28789,7 @@ var BottlenecksContent = ({
28117
28789
  const [metadataCache, setMetadataCache] = useState({});
28118
28790
  const [triageClips, setTriageClips] = useState([]);
28119
28791
  const [isLoadingTriageClips, setIsLoadingTriageClips] = useState(false);
28792
+ const [isFullscreen, setIsFullscreen] = useState(false);
28120
28793
  const categoryMetadataRef = useRef([]);
28121
28794
  const currentMetadataIndexRef = useRef(0);
28122
28795
  const {
@@ -29010,6 +29683,24 @@ var BottlenecksContent = ({
29010
29683
  player.pause();
29011
29684
  }
29012
29685
  };
29686
+ const toggleFullscreen = useCallback((e) => {
29687
+ e.stopPropagation();
29688
+ setIsFullscreen((prev) => !prev);
29689
+ }, []);
29690
+ const exitFullscreen = useCallback(() => {
29691
+ setIsFullscreen(false);
29692
+ }, []);
29693
+ useEffect(() => {
29694
+ const handleEscape = (e) => {
29695
+ if (e.key === "Escape" && isFullscreen) {
29696
+ exitFullscreen();
29697
+ }
29698
+ };
29699
+ if (isFullscreen) {
29700
+ window.addEventListener("keydown", handleEscape);
29701
+ return () => window.removeEventListener("keydown", handleEscape);
29702
+ }
29703
+ }, [isFullscreen, exitFullscreen]);
29013
29704
  const getClipTypeLabel = (video) => {
29014
29705
  if (!video) return "";
29015
29706
  const currentFilter = activeFilterRef.current;
@@ -29122,7 +29813,7 @@ var BottlenecksContent = ({
29122
29813
  )
29123
29814
  ] }) })
29124
29815
  ] }) }),
29125
- filteredVideos.length > 0 && currentVideo ? /* @__PURE__ */ jsx("div", { className: `p-4 ${triageMode ? "h-full" : "h-[calc(100%-4rem)]"}`, children: /* @__PURE__ */ jsx("div", { className: "relative h-full group", children: /* @__PURE__ */ jsxs("div", { className: "relative w-full h-full overflow-hidden rounded-md shadow-inner bg-gray-900", children: [
29816
+ filteredVideos.length > 0 && currentVideo && !isFullscreen ? /* @__PURE__ */ jsx("div", { className: `p-4 ${triageMode ? "h-full" : "h-[calc(100%-4rem)]"}`, children: /* @__PURE__ */ jsx("div", { className: "relative h-full group", children: /* @__PURE__ */ jsxs("div", { className: "relative w-full h-full overflow-hidden rounded-md shadow-inner bg-gray-900", children: [
29126
29817
  /* @__PURE__ */ jsx(
29127
29818
  "div",
29128
29819
  {
@@ -29222,22 +29913,24 @@ var BottlenecksContent = ({
29222
29913
  ] }) })
29223
29914
  ),
29224
29915
  /* @__PURE__ */ jsx("div", { className: "absolute bottom-0 left-0 right-0 p-3 bg-gradient-to-t from-black/70 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300 z-10", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-white", children: [
29225
- /* @__PURE__ */ jsx(
29226
- "button",
29227
- {
29228
- onClick: (e) => {
29229
- e.stopPropagation();
29230
- togglePlayback();
29231
- },
29232
- className: "p-1.5 hover:bg-white/20 rounded-full focus:outline-none focus:ring-2 focus:ring-white/50",
29233
- "aria-label": isPlaying ? "Pause" : "Play",
29234
- children: isPlaying ? /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zM7 8a1 1 0 00-1 1v2a1 1 0 102 0V9a1 1 0 00-1-1zm5 0a1 1 0 00-1 1v2a1 1 0 102 0V9a1 1 0 00-1-1z", clipRule: "evenodd" }) }) : /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8.118l-.001 3.764a1 1 0 001.555.832l3.196-1.882a1 1 0 000-1.664l-3.196-1.882z", clipRule: "evenodd" }) })
29235
- }
29236
- ),
29237
- /* @__PURE__ */ jsxs("span", { className: "text-xs font-mono px-2", children: [
29238
- formatTime2(currentTime),
29239
- " / ",
29240
- formatTime2(duration)
29916
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
29917
+ /* @__PURE__ */ jsx(
29918
+ "button",
29919
+ {
29920
+ onClick: (e) => {
29921
+ e.stopPropagation();
29922
+ togglePlayback();
29923
+ },
29924
+ className: "p-1.5 hover:bg-white/20 rounded-full focus:outline-none focus:ring-2 focus:ring-white/50",
29925
+ "aria-label": isPlaying ? "Pause" : "Play",
29926
+ children: isPlaying ? /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zM7 8a1 1 0 00-1 1v2a1 1 0 102 0V9a1 1 0 00-1-1zm5 0a1 1 0 00-1 1v2a1 1 0 102 0V9a1 1 0 00-1-1z", clipRule: "evenodd" }) }) : /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8.118l-.001 3.764a1 1 0 001.555.832l3.196-1.882a1 1 0 000-1.664l-3.196-1.882z", clipRule: "evenodd" }) })
29927
+ }
29928
+ ),
29929
+ /* @__PURE__ */ jsxs("span", { className: "text-xs font-mono px-2", children: [
29930
+ formatTime2(currentTime),
29931
+ " / ",
29932
+ formatTime2(duration)
29933
+ ] })
29241
29934
  ] }),
29242
29935
  /* @__PURE__ */ jsx(
29243
29936
  "input",
@@ -29258,6 +29951,16 @@ var BottlenecksContent = ({
29258
29951
  },
29259
29952
  "aria-label": "Seek slider"
29260
29953
  }
29954
+ ),
29955
+ /* @__PURE__ */ jsx(
29956
+ "button",
29957
+ {
29958
+ onClick: toggleFullscreen,
29959
+ className: "p-1.5 hover:bg-white/20 rounded-full focus:outline-none focus:ring-2 focus:ring-white/50",
29960
+ "aria-label": "Fullscreen",
29961
+ title: "Expand to fullscreen",
29962
+ children: /* @__PURE__ */ jsx(Maximize2, { className: "h-5 w-5" })
29963
+ }
29261
29964
  )
29262
29965
  ] }) })
29263
29966
  ] }) }) }) : (
@@ -29394,6 +30097,147 @@ var BottlenecksContent = ({
29394
30097
  )
29395
30098
  ) })
29396
30099
  ] }),
30100
+ isFullscreen && currentVideo && /* @__PURE__ */ jsxs(
30101
+ "div",
30102
+ {
30103
+ className: "fixed inset-0 z-50 bg-black flex items-center justify-center",
30104
+ style: { margin: 0 },
30105
+ children: [
30106
+ /* @__PURE__ */ jsx(
30107
+ "button",
30108
+ {
30109
+ onClick: exitFullscreen,
30110
+ className: "absolute top-4 right-4 z-50 p-2 bg-black/60 hover:bg-black/80 rounded-full text-white transition-colors focus:outline-none focus:ring-2 focus:ring-white/50",
30111
+ "aria-label": "Exit fullscreen",
30112
+ children: /* @__PURE__ */ jsx(X, { className: "h-6 w-6" })
30113
+ }
30114
+ ),
30115
+ (currentVideo.type === "cycle_completion" || currentVideo.type === "bottleneck" && currentVideo.description.toLowerCase().includes("cycle time")) && currentVideo.cycle_time_seconds || currentVideo.type === "idle_time" || currentVideo.type === "low_value" ? /* @__PURE__ */ jsx("div", { className: "absolute top-4 left-4 z-50 bg-black/60 backdrop-blur-sm px-4 py-2 rounded-lg text-white shadow-lg", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
30116
+ /* @__PURE__ */ jsx("div", { className: `flex-shrink-0 h-3 w-3 rounded-full ${currentVideo.type === "low_value" || currentVideo.type === "idle_time" ? "bg-purple-400" : isPercentileCategory(activeFilterRef.current) ? activeFilterRef.current === "fast-cycles" ? "bg-green-600" : activeFilterRef.current === "slow-cycles" ? "bg-red-700" : "bg-orange-500" : currentVideo.type === "cycle_completion" ? "bg-blue-600" : "bg-gray-500"} mr-2 animate-pulse` }),
30117
+ (currentVideo.type === "cycle_completion" || currentVideo.type === "bottleneck" && currentVideo.description.toLowerCase().includes("cycle time")) && currentVideo.cycle_time_seconds ? /* @__PURE__ */ jsxs("span", { className: "opacity-90 font-mono bg-black/30 px-2 py-1 rounded", children: [
30118
+ "Cycle time: ",
30119
+ currentVideo.cycle_time_seconds.toFixed(1),
30120
+ "s"
30121
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
30122
+ /* @__PURE__ */ jsx("span", { className: "font-medium mr-2", children: getClipTypeLabel(currentVideo) }),
30123
+ /* @__PURE__ */ jsx("span", { className: "opacity-80", children: currentVideo.description })
30124
+ ] })
30125
+ ] }) }) : /* @__PURE__ */ jsx("div", { className: "absolute top-4 right-20 z-50 bg-black/60 backdrop-blur-sm px-4 py-2 rounded-lg text-white shadow-lg", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
30126
+ /* @__PURE__ */ jsx("div", { className: `flex-shrink-0 h-3 w-3 rounded-full ${getSeverityColor(currentVideo.severity)} mr-2 animate-pulse` }),
30127
+ /* @__PURE__ */ jsx("span", { className: "font-medium mr-2", children: getClipTypeLabel(currentVideo) }),
30128
+ /* @__PURE__ */ jsx("span", { className: "opacity-80", children: currentVideo.description })
30129
+ ] }) }),
30130
+ /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center p-8", children: /* @__PURE__ */ jsxs("div", { className: "relative w-full h-full max-w-7xl group", children: [
30131
+ /* @__PURE__ */ jsx(
30132
+ "div",
30133
+ {
30134
+ className: "w-full h-full",
30135
+ style: {
30136
+ opacity: isTransitioning ? 0 : 1,
30137
+ transition: "opacity 0.1s ease-in-out"
30138
+ },
30139
+ children: /* @__PURE__ */ jsx(
30140
+ CroppedVideoPlayer,
30141
+ {
30142
+ ref: videoRef,
30143
+ src: currentVideo.src,
30144
+ poster: "",
30145
+ className: "w-full h-full",
30146
+ crop: workspaceCrop?.crop,
30147
+ onClick: togglePlayback,
30148
+ autoplay: true,
30149
+ playsInline: true,
30150
+ loop: false,
30151
+ externalLoadingControl: true,
30152
+ onReady: handleVideoReady,
30153
+ onPlay: handleVideoPlay,
30154
+ onPause: handleVideoPause,
30155
+ onTimeUpdate: handleTimeUpdate,
30156
+ onDurationChange: handleDurationChange,
30157
+ onEnded: handleVideoEnded,
30158
+ onError: handleVideoError,
30159
+ onLoadedData: handleLoadedData,
30160
+ onPlaying: handleVideoPlaying,
30161
+ onLoadingChange: handleVideoLoadingChange,
30162
+ options: {
30163
+ fluid: false,
30164
+ responsive: false,
30165
+ fill: false
30166
+ }
30167
+ }
30168
+ )
30169
+ }
30170
+ ),
30171
+ (isTransitioning || isVideoBuffering && isInitialLoading) && !error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
30172
+ !isTransitioning && isVideoBuffering && !isInitialLoading && !error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-black/60", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md", message: "Loading video..." }) }),
30173
+ /* @__PURE__ */ jsx("div", { className: "absolute bottom-0 left-0 right-0 p-4 bg-gradient-to-t from-black/70 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300 z-10", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-white", children: [
30174
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
30175
+ /* @__PURE__ */ jsx(
30176
+ "button",
30177
+ {
30178
+ onClick: (e) => {
30179
+ e.stopPropagation();
30180
+ togglePlayback();
30181
+ },
30182
+ className: "p-2 hover:bg-white/20 rounded-full focus:outline-none focus:ring-2 focus:ring-white/50",
30183
+ "aria-label": isPlaying ? "Pause" : "Play",
30184
+ children: isPlaying ? /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-6 w-6", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zM7 8a1 1 0 00-1 1v2a1 1 0 102 0V9a1 1 0 00-1-1zm5 0a1 1 0 00-1 1v2a1 1 0 102 0V9a1 1 0 00-1-1z", clipRule: "evenodd" }) }) : /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-6 w-6", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8.118l-.001 3.764a1 1 0 001.555.832l3.196-1.882a1 1 0 000-1.664l-3.196-1.882z", clipRule: "evenodd" }) })
30185
+ }
30186
+ ),
30187
+ /* @__PURE__ */ jsxs("span", { className: "text-sm font-mono px-2", children: [
30188
+ formatTime2(currentTime),
30189
+ " / ",
30190
+ formatTime2(duration)
30191
+ ] })
30192
+ ] }),
30193
+ /* @__PURE__ */ jsx(
30194
+ "input",
30195
+ {
30196
+ type: "range",
30197
+ min: "0",
30198
+ max: duration || 0,
30199
+ value: currentTime,
30200
+ onChange: (e) => {
30201
+ if (videoRef.current) {
30202
+ videoRef.current.currentTime(Number(e.target.value));
30203
+ }
30204
+ },
30205
+ className: "flex-grow mx-4 h-2.5 bg-white/30 rounded-full appearance-none cursor-pointer focus:outline-none focus:ring-2 focus:ring-white/50 touch-manipulation",
30206
+ style: {
30207
+ WebkitAppearance: "none",
30208
+ appearance: "none"
30209
+ },
30210
+ "aria-label": "Seek slider"
30211
+ }
30212
+ ),
30213
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
30214
+ /* @__PURE__ */ jsx(
30215
+ "button",
30216
+ {
30217
+ onClick: handlePrevious,
30218
+ disabled: currentMetadataIndex <= 0,
30219
+ className: `p-2 rounded-full transition-colors ${currentMetadataIndex <= 0 ? "text-gray-500 cursor-not-allowed" : "text-white hover:bg-white/20"}`,
30220
+ "aria-label": "Previous clip",
30221
+ children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-5 w-5" })
30222
+ }
30223
+ ),
30224
+ /* @__PURE__ */ jsx("span", { className: "text-sm px-3 py-1 bg-blue-600 text-white rounded-full font-medium tabular-nums", children: categoryMetadata.length > 0 ? `${currentMetadataIndex + 1} / ${categoryMetadata.length}` : "0 / 0" }),
30225
+ /* @__PURE__ */ jsx(
30226
+ "button",
30227
+ {
30228
+ onClick: handleNext,
30229
+ disabled: currentMetadataIndex >= categoryMetadata.length - 1,
30230
+ className: `p-2 rounded-full transition-colors ${currentMetadataIndex >= categoryMetadata.length - 1 ? "text-gray-500 cursor-not-allowed" : "text-white hover:bg-white/20"}`,
30231
+ "aria-label": "Next clip",
30232
+ children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-5 w-5" })
30233
+ }
30234
+ )
30235
+ ] })
30236
+ ] }) })
30237
+ ] }) })
30238
+ ]
30239
+ }
30240
+ ),
29397
30241
  !triageMode && /* @__PURE__ */ jsx(
29398
30242
  AdvancedFilterDialog,
29399
30243
  {
@@ -35731,20 +36575,7 @@ var SideNavBar = memo(({
35731
36575
  onClick: handleLogoClick,
35732
36576
  className: "mx-auto flex items-center justify-center w-full hover:opacity-80 transition-opacity focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 rounded-lg",
35733
36577
  "aria-label": "Go to home page",
35734
- children: /* @__PURE__ */ jsx(
35735
- "img",
35736
- {
35737
- src: "/optifye-logo.png",
35738
- alt: "Optifye",
35739
- className: "w-12 h-12 object-contain cursor-pointer",
35740
- onError: (e) => {
35741
- e.currentTarget.style.display = "none";
35742
- if (e.currentTarget.parentElement) {
35743
- e.currentTarget.parentElement.innerHTML = '<span class="text-blue-600 font-bold text-lg cursor-pointer">OP</span>';
35744
- }
35745
- }
35746
- }
35747
- )
36578
+ children: /* @__PURE__ */ jsx(Logo, { className: "w-12 h-12 object-contain cursor-pointer" })
35748
36579
  }
35749
36580
  ) }),
35750
36581
  /* @__PURE__ */ jsxs("div", { className: "flex-1 w-full py-6 px-4 overflow-y-auto", children: [
@@ -36122,20 +36953,7 @@ var SideNavBar = memo(({
36122
36953
  ),
36123
36954
  /* @__PURE__ */ jsxs("aside", { className: `md:hidden fixed inset-y-0 left-0 w-72 xs:w-80 bg-white shadow-2xl flex flex-col z-50 transform transition-transform duration-300 ease-in-out ${isMobileMenuOpen ? "translate-x-0" : "-translate-x-full"}`, children: [
36124
36955
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-5 py-4 border-b border-gray-200 bg-gradient-to-r from-blue-50 to-white", children: [
36125
- /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx(
36126
- "img",
36127
- {
36128
- src: "/optifye-logo.png",
36129
- alt: "Optifye",
36130
- className: "w-11 h-11 object-contain",
36131
- onError: (e) => {
36132
- e.currentTarget.style.display = "none";
36133
- if (e.currentTarget.parentElement) {
36134
- e.currentTarget.parentElement.innerHTML = '<span class="text-blue-600 font-bold text-xl">Optifye</span>';
36135
- }
36136
- }
36137
- }
36138
- ) }),
36956
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx(Logo, { className: "w-11 h-11 object-contain" }) }),
36139
36957
  /* @__PURE__ */ jsx(
36140
36958
  "button",
36141
36959
  {
@@ -36244,20 +37062,7 @@ var MainLayout = ({
36244
37062
  return /* @__PURE__ */ jsxs("div", { className: `min-h-screen ${className}`, children: [
36245
37063
  /* @__PURE__ */ jsx("header", { className: "md:hidden bg-white border-b border-gray-200 shadow-sm px-5 py-3.5 flex items-center justify-between sticky top-0 z-40", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
36246
37064
  /* @__PURE__ */ jsx(HamburgerButton, { onClick: handleMobileMenuOpen }),
36247
- /* @__PURE__ */ jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsx(
36248
- "img",
36249
- {
36250
- src: "/optifye-logo.png",
36251
- alt: "Optifye",
36252
- className: "h-9 w-9 object-contain",
36253
- onError: (e) => {
36254
- e.currentTarget.style.display = "none";
36255
- if (e.currentTarget.parentElement) {
36256
- e.currentTarget.parentElement.innerHTML = '<span class="text-blue-600 font-bold text-lg">Optifye</span>';
36257
- }
36258
- }
36259
- }
36260
- ) })
37065
+ /* @__PURE__ */ jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsx(Logo, { className: "h-9 w-9 object-contain" }) })
36261
37066
  ] }) }),
36262
37067
  /* @__PURE__ */ jsx(
36263
37068
  SideNavBar,
@@ -37867,23 +38672,29 @@ var ThreadSidebar = ({
37867
38672
  ] }) })
37868
38673
  ] });
37869
38674
  };
37870
- var axelProfilePng = "/axel-profile.png";
37871
- var ProfilePicture = React23__default.memo(({ alt = "Axel", className = "w-8 h-8 sm:w-10 sm:h-10 md:w-12 md:h-12" }) => {
37872
- return /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx("div", { className: `${className} rounded-xl overflow-hidden shadow-sm`, children: /* @__PURE__ */ jsx(
37873
- "img",
37874
- {
37875
- src: axelProfilePng,
37876
- alt,
37877
- className: "w-full h-full object-cover",
37878
- loading: "eager",
37879
- decoding: "async"
37880
- }
37881
- ) }) });
38675
+ var ProfilePicture = React23__default.memo(({
38676
+ alt = "Axel",
38677
+ className = "",
38678
+ size = "md",
38679
+ animate = false
38680
+ }) => {
38681
+ return /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx(AxelOrb, { size, animate }) });
37882
38682
  });
37883
38683
  ProfilePicture.displayName = "ProfilePicture";
37884
- var preloadImage = (src) => {
37885
- const img = new Image();
37886
- img.src = src;
38684
+ var GREETING_MESSAGES = [
38685
+ "How can I help you today?",
38686
+ "What would you like to know?",
38687
+ "Ready to optimize your operations?",
38688
+ "How can I assist you today?"
38689
+ ];
38690
+ var getDailyGreeting = () => {
38691
+ const now2 = /* @__PURE__ */ new Date();
38692
+ const startOfYear = new Date(now2.getFullYear(), 0, 0);
38693
+ const diff = now2.getTime() - startOfYear.getTime();
38694
+ const oneDay = 1e3 * 60 * 60 * 24;
38695
+ const dayOfYear = Math.floor(diff / oneDay);
38696
+ const index = dayOfYear % GREETING_MESSAGES.length;
38697
+ return GREETING_MESSAGES[index];
37887
38698
  };
37888
38699
  var AIAgentView = () => {
37889
38700
  const { navigate, pathname } = useNavigation();
@@ -37910,6 +38721,7 @@ var AIAgentView = () => {
37910
38721
  const [lastTypingTime, setLastTypingTime] = useState(null);
37911
38722
  const [characterCount, setCharacterCount] = useState(0);
37912
38723
  const typingTimeoutRef = useRef(null);
38724
+ const currentGreeting = useMemo(() => getDailyGreeting(), [greetingReset]);
37913
38725
  const isThreadLoading = (threadId) => {
37914
38726
  return threadId ? loadingThreads.has(threadId) : false;
37915
38727
  };
@@ -38063,12 +38875,11 @@ var AIAgentView = () => {
38063
38875
  }, [activeThreadId]);
38064
38876
  useEffect(() => {
38065
38877
  if (messages.length === 0 && !isTransitioning) {
38066
- const fullText = "Hi, I'm Axel - Your AI Supervisor";
38067
38878
  let index = 0;
38068
38879
  setTypedText("");
38069
38880
  const typeInterval = setInterval(() => {
38070
- if (index < fullText.length) {
38071
- setTypedText(fullText.substring(0, index + 1));
38881
+ if (index < currentGreeting.length) {
38882
+ setTypedText(currentGreeting.substring(0, index + 1));
38072
38883
  index++;
38073
38884
  } else {
38074
38885
  clearInterval(typeInterval);
@@ -38076,7 +38887,7 @@ var AIAgentView = () => {
38076
38887
  }, 50);
38077
38888
  return () => clearInterval(typeInterval);
38078
38889
  }
38079
- }, [messages.length, isTransitioning, greetingReset]);
38890
+ }, [messages.length, isTransitioning, greetingReset, currentGreeting]);
38080
38891
  useEffect(() => {
38081
38892
  if (isSidebarOpen) {
38082
38893
  setNewChatCount(0);
@@ -38102,9 +38913,6 @@ var AIAgentView = () => {
38102
38913
  localStorage.removeItem(ACTIVE_THREAD_STORAGE_KEY);
38103
38914
  textareaRef.current?.focus();
38104
38915
  };
38105
- useEffect(() => {
38106
- preloadImage(axelProfilePng);
38107
- }, []);
38108
38916
  useEffect(() => {
38109
38917
  return () => {
38110
38918
  if (typingTimeoutRef.current) {
@@ -39579,10 +40387,10 @@ var AIAgentView = () => {
39579
40387
  /* Centered welcome and input for new chat */
39580
40388
  /* @__PURE__ */ jsxs("div", { className: "w-full max-w-3xl mx-auto px-3 sm:px-4 md:px-6 flex flex-col items-center justify-center space-y-8 sm:space-y-12 -mt-8 sm:-mt-16", children: [
39581
40389
  /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
39582
- /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center mb-4 sm:mb-6 md:mb-8", children: /* @__PURE__ */ jsx(ProfilePicture, { alt: "Axel - AI Manufacturing Expert", className: "w-16 h-16 sm:w-20 sm:h-20 md:w-24 md:h-24" }) }),
40390
+ /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center mb-4 sm:mb-6 md:mb-8", children: /* @__PURE__ */ jsx(ProfilePicture, { alt: "Axel - AI Manufacturing Expert", size: "2xl", animate: true }) }),
39583
40391
  /* @__PURE__ */ jsxs("h2", { className: "text-lg sm:text-xl md:text-2xl lg:text-3xl font-semibold text-gray-900 px-2 sm:px-4", children: [
39584
40392
  typedText,
39585
- typedText.length < "Hi, I'm Axel - Your AI Supervisor".length && /* @__PURE__ */ jsx("span", { className: "animate-pulse", children: "|" })
40393
+ typedText.length < currentGreeting.length && /* @__PURE__ */ jsx("span", { className: "animate-pulse", children: "|" })
39586
40394
  ] })
39587
40395
  ] }),
39588
40396
  /* @__PURE__ */ jsx("div", { className: "w-full max-w-2xl", children: /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, children: [
@@ -42949,7 +43757,7 @@ LeaderboardDetailView.displayName = "LeaderboardDetailView";
42949
43757
  var LeaderboardDetailViewWithDisplayNames = withAllWorkspaceDisplayNames(LeaderboardDetailView);
42950
43758
  var LeaderboardDetailView_default = LeaderboardDetailViewWithDisplayNames;
42951
43759
  function LoginView({
42952
- logoSrc = "/optifye-logo.png",
43760
+ logoSrc = optifye_logo_default,
42953
43761
  logoAlt = "Optifye",
42954
43762
  brandName = "Optifye",
42955
43763
  onRateLimitCheck
@@ -46029,6 +46837,26 @@ var getInitialTab = (sourceType, defaultTab, fromMonthly, urlDate) => {
46029
46837
  }
46030
46838
  return "overview";
46031
46839
  };
46840
+ var WorkspaceHealthStatusBadge = ({
46841
+ workspaceId,
46842
+ mode = "full",
46843
+ className = "",
46844
+ showHealthDot = false
46845
+ }) => {
46846
+ const { timeSinceUpdate, isHealthy, loading, error } = useWorkspaceHealthStatus(workspaceId);
46847
+ if (loading || error) {
46848
+ return null;
46849
+ }
46850
+ return /* @__PURE__ */ jsxs("div", { className: `flex items-center gap-2 ${className}`, children: [
46851
+ showHealthDot && /* @__PURE__ */ jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsx(
46852
+ "div",
46853
+ {
46854
+ className: `h-2 w-2 rounded-full ${isHealthy ? "bg-green-500 animate-pulse" : "bg-red-500"}`
46855
+ }
46856
+ ) }),
46857
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-gray-500", children: mode === "full" ? `Last updated: ${timeSinceUpdate}` : timeSinceUpdate })
46858
+ ] });
46859
+ };
46032
46860
  var WorkspaceDetailView = ({
46033
46861
  workspaceId,
46034
46862
  date,
@@ -46124,82 +46952,6 @@ var WorkspaceDetailView = ({
46124
46952
  const workspace = isHistoricView ? historicMetrics : liveMetrics;
46125
46953
  const loading = isHistoricView ? historicLoading : liveLoading;
46126
46954
  const error = isHistoricView ? historicError : liveError;
46127
- const audioService = useAudioService();
46128
- const { latestAchievement, hasNewAchievements } = useHourlyTargetAchievements({
46129
- hourlyData: workspace?.hourly_action_counts || [],
46130
- targetThreshold: workspace?.pph_threshold || 0,
46131
- shiftStart: workspace?.shift_start || "06:00",
46132
- enabled: !isHistoricView && Boolean(workspace)
46133
- // Only for live data
46134
- });
46135
- const { latestMiss, hasNewMiss } = useHourlyTargetMisses({
46136
- hourlyData: workspace?.hourly_action_counts || [],
46137
- targetThreshold: workspace?.pph_threshold || 0,
46138
- shiftStart: workspace?.shift_start || "06:00",
46139
- enabled: !isHistoricView && Boolean(workspace)
46140
- // Only for live data
46141
- });
46142
- const [showCongratulations, setShowCongratulations] = useState(false);
46143
- const [currentAchievement, setCurrentAchievement] = useState(null);
46144
- const [showEncouragement, setShowEncouragement] = useState(false);
46145
- const [currentMiss, setCurrentMiss] = useState(null);
46146
- const [audioReady, setAudioReady] = useState(false);
46147
- useEffect(() => {
46148
- if (hasNewAchievements && latestAchievement && !isHistoricView) {
46149
- console.log("[\u{1F389} ACHIEVEMENT UNLOCKED! \u{1F389}] Target reached!", latestAchievement);
46150
- const startCelebration = async () => {
46151
- setCurrentAchievement(latestAchievement);
46152
- setShowCongratulations(true);
46153
- setTimeout(async () => {
46154
- try {
46155
- console.log("[\u{1F3B5} CELEBRATION FANFARE] Playing victory audio...");
46156
- await audioService.playCongratsSound();
46157
- console.log("[\u2705 AUDIO SUCCESS] Celebration fanfare completed!");
46158
- } catch (err) {
46159
- console.warn("[\u274C AUDIO ERROR] Failed to play congratulations sound:", err);
46160
- }
46161
- }, 300);
46162
- console.log(`[\u{1F4CA} ACHIEVEMENT ANALYTICS] Worker hit target: ${latestAchievement.currentValue}/${latestAchievement.targetValue} during ${latestAchievement.timeRange}`);
46163
- };
46164
- startCelebration();
46165
- }
46166
- }, [hasNewAchievements, latestAchievement, isHistoricView, audioService]);
46167
- useEffect(() => {
46168
- if (hasNewMiss && latestMiss && !isHistoricView) {
46169
- console.log("[\u{1F499} ENCOURAGEMENT NEEDED] Target not reached, showing support", latestMiss);
46170
- const startEncouragement = async () => {
46171
- setCurrentMiss(latestMiss);
46172
- setShowEncouragement(true);
46173
- setTimeout(async () => {
46174
- try {
46175
- console.log("[\u{1F3B5} GENTLE ENCOURAGEMENT] Playing supportive audio...");
46176
- await audioService.playEncouragementSound();
46177
- console.log("[\u2705 AUDIO SUCCESS] Encouragement audio completed!");
46178
- } catch (err) {
46179
- console.warn("[\u274C AUDIO ERROR] Failed to play encouragement sound:", err);
46180
- }
46181
- }, 300);
46182
- console.log(`[\u{1F4CA} ENCOURAGEMENT ANALYTICS] Target missed: ${latestMiss.actualValue}/${latestMiss.targetValue} (${Math.round(latestMiss.actualValue / latestMiss.targetValue * 100)}% achieved)`);
46183
- };
46184
- startEncouragement();
46185
- }
46186
- }, [hasNewMiss, latestMiss, isHistoricView, audioService]);
46187
- useEffect(() => {
46188
- const handleUserInteraction = () => {
46189
- console.log("[\u{1F50A} AUDIO ENABLED] User interaction detected - celebration sounds ready!");
46190
- audioService.markUserInteraction();
46191
- setAudioReady(true);
46192
- };
46193
- console.log("[\u{1F3A7} AUDIO SETUP] Setting up celebration audio listeners...");
46194
- document.addEventListener("click", handleUserInteraction);
46195
- document.addEventListener("touchstart", handleUserInteraction);
46196
- document.addEventListener("keydown", handleUserInteraction);
46197
- return () => {
46198
- document.removeEventListener("click", handleUserInteraction);
46199
- document.removeEventListener("touchstart", handleUserInteraction);
46200
- document.removeEventListener("keydown", handleUserInteraction);
46201
- };
46202
- }, [audioService]);
46203
46955
  useEffect(() => {
46204
46956
  if (onTabChange) {
46205
46957
  onTabChange(activeTab);
@@ -46415,113 +47167,160 @@ var WorkspaceDetailView = ({
46415
47167
  )
46416
47168
  ] });
46417
47169
  }
46418
- return /* @__PURE__ */ jsxs(
47170
+ return /* @__PURE__ */ jsx(
46419
47171
  motion.div,
46420
47172
  {
46421
47173
  className: `min-h-screen bg-slate-50 ${className}`,
46422
47174
  initial: { opacity: 1 },
46423
47175
  animate: { opacity: 1 },
46424
- children: [
46425
- /* @__PURE__ */ jsxs("div", { className: "min-h-screen w-full flex flex-col bg-slate-50", children: [
46426
- /* @__PURE__ */ jsxs("header", { className: "sticky top-0 z-10 px-3 sm:px-4 md:px-5 lg:px-6 py-2 sm:py-2.5 lg:py-3 flex flex-col shadow-sm bg-white", children: [
46427
- /* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
46428
- /* @__PURE__ */ jsx(
46429
- "button",
46430
- {
46431
- onClick: handleBackNavigation,
46432
- className: "p-2 -ml-2 rounded-full active:bg-gray-100 transition-colors",
46433
- "aria-label": "Navigate back",
46434
- children: /* @__PURE__ */ jsx(ArrowLeft, { className: "w-5 h-5 text-gray-700" })
46435
- }
46436
- ),
46437
- /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col items-center justify-center", children: [
46438
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
46439
- /* @__PURE__ */ jsx("h1", { className: "text-base font-semibold text-gray-900 truncate max-w-[220px]", children: formattedWorkspaceName }),
46440
- workspaceHealth && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1", children: /* @__PURE__ */ jsxs("div", { className: "relative flex h-2 w-2", children: [
46441
- workspaceHealth.status === "healthy" && /* @__PURE__ */ jsx("span", { className: "animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75" }),
46442
- /* @__PURE__ */ jsx("span", { className: clsx(
46443
- "relative inline-flex rounded-full h-2 w-2",
46444
- workspaceHealth.status === "healthy" ? "bg-green-500" : "bg-red-500"
46445
- ) })
46446
- ] }) })
46447
- ] }),
46448
- workspaceHealth && activeTab !== "monthly_history" && /* @__PURE__ */ jsx("span", { className: "text-[10px] text-gray-500 mt-0.5", children: workspaceHealth.timeSinceLastUpdate })
46449
- ] }),
46450
- /* @__PURE__ */ jsx("div", { className: "w-9" })
46451
- ] }) }),
46452
- /* @__PURE__ */ jsx("div", { className: "hidden sm:block", children: /* @__PURE__ */ jsxs("div", { className: "relative flex items-center", children: [
46453
- /* @__PURE__ */ jsx("div", { className: "absolute left-0 z-10", children: /* @__PURE__ */ jsx(
46454
- BackButtonMinimal,
46455
- {
46456
- onClick: handleBackNavigation,
46457
- text: previousView === "line_monthly_history" ? "Back to Line History" : returnUrl && returnUrl.includes("monthly_history") ? "Back to Line History" : returnUrl && returnUrl.includes("/kpis/") ? "Back to KPIs" : returnUrl && returnUrl.includes("/leaderboard/") ? "Back to Leaderboard" : (date || shift) && activeTab !== "monthly_history" ? "Back to Monthly History" : "Back",
46458
- size: "default",
46459
- "aria-label": "Navigate back to previous page"
46460
- }
46461
- ) }),
46462
- /* @__PURE__ */ jsx("div", { className: "absolute left-1/2 transform -translate-x-1/2 max-w-[calc(100%-200px)]", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
46463
- /* @__PURE__ */ jsx("h1", { className: "text-lg md:text-xl lg:text-2xl xl:text-3xl font-semibold text-gray-900 truncate", children: formattedWorkspaceName }),
46464
- workspaceHealth && /* @__PURE__ */ jsxs("div", { className: "relative flex h-2.5 w-2.5", children: [
46465
- /* @__PURE__ */ jsx("span", { className: clsx(
46466
- "animate-ping absolute inline-flex h-full w-full rounded-full opacity-75",
46467
- workspaceHealth.status === "healthy" ? "bg-green-400" : "bg-red-400"
46468
- ) }),
47176
+ children: /* @__PURE__ */ jsxs("div", { className: "min-h-screen w-full flex flex-col bg-slate-50", children: [
47177
+ /* @__PURE__ */ jsxs("header", { className: "sticky top-0 z-10 px-3 sm:px-4 md:px-5 lg:px-6 py-2 sm:py-2.5 lg:py-3 flex flex-col shadow-sm bg-white", children: [
47178
+ /* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
47179
+ /* @__PURE__ */ jsx(
47180
+ "button",
47181
+ {
47182
+ onClick: handleBackNavigation,
47183
+ className: "p-2 -ml-2 rounded-full active:bg-gray-100 transition-colors",
47184
+ "aria-label": "Navigate back",
47185
+ children: /* @__PURE__ */ jsx(ArrowLeft, { className: "w-5 h-5 text-gray-700" })
47186
+ }
47187
+ ),
47188
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col items-center justify-center", children: [
47189
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
47190
+ /* @__PURE__ */ jsx("h1", { className: "text-base font-semibold text-gray-900 truncate max-w-[220px]", children: formattedWorkspaceName }),
47191
+ workspaceHealth && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1", children: /* @__PURE__ */ jsxs("div", { className: "relative flex h-2 w-2", children: [
47192
+ workspaceHealth.status === "healthy" && /* @__PURE__ */ jsx("span", { className: "animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75" }),
46469
47193
  /* @__PURE__ */ jsx("span", { className: clsx(
46470
- "relative inline-flex rounded-full h-2.5 w-2.5",
47194
+ "relative inline-flex rounded-full h-2 w-2",
46471
47195
  workspaceHealth.status === "healthy" ? "bg-green-500" : "bg-red-500"
46472
47196
  ) })
46473
- ] })
46474
- ] }) }),
46475
- workspaceHealth && activeTab !== "monthly_history" && /* @__PURE__ */ jsx("div", { className: "absolute right-0 top-0 flex items-center h-8", children: /* @__PURE__ */ jsxs("span", { className: "text-xs text-gray-500", children: [
47197
+ ] }) })
47198
+ ] }),
47199
+ activeTab !== "monthly_history" && /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-0.5", children: [
47200
+ workspaceHealth && /* @__PURE__ */ jsx("span", { className: "text-[10px] text-gray-500", children: workspaceHealth.timeSinceLastUpdate }),
47201
+ /* @__PURE__ */ jsx(
47202
+ WorkspaceHealthStatusBadge,
47203
+ {
47204
+ workspaceId,
47205
+ mode: "compact",
47206
+ showHealthDot: false,
47207
+ className: "text-[10px]"
47208
+ }
47209
+ )
47210
+ ] })
47211
+ ] }),
47212
+ /* @__PURE__ */ jsx("div", { className: "w-9" })
47213
+ ] }) }),
47214
+ /* @__PURE__ */ jsx("div", { className: "hidden sm:block", children: /* @__PURE__ */ jsxs("div", { className: "relative flex items-center", children: [
47215
+ /* @__PURE__ */ jsx("div", { className: "absolute left-0 z-10", children: /* @__PURE__ */ jsx(
47216
+ BackButtonMinimal,
47217
+ {
47218
+ onClick: handleBackNavigation,
47219
+ text: previousView === "line_monthly_history" ? "Back to Line History" : returnUrl && returnUrl.includes("monthly_history") ? "Back to Line History" : returnUrl && returnUrl.includes("/kpis/") ? "Back to KPIs" : returnUrl && returnUrl.includes("/leaderboard/") ? "Back to Leaderboard" : (date || shift) && activeTab !== "monthly_history" ? "Back to Monthly History" : "Back",
47220
+ size: "default",
47221
+ "aria-label": "Navigate back to previous page"
47222
+ }
47223
+ ) }),
47224
+ /* @__PURE__ */ jsx("div", { className: "absolute left-1/2 transform -translate-x-1/2 max-w-[calc(100%-200px)]", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
47225
+ /* @__PURE__ */ jsx("h1", { className: "text-lg md:text-xl lg:text-2xl xl:text-3xl font-semibold text-gray-900 truncate", children: formattedWorkspaceName }),
47226
+ workspaceHealth && /* @__PURE__ */ jsxs("div", { className: "relative flex h-2.5 w-2.5", children: [
47227
+ /* @__PURE__ */ jsx("span", { className: clsx(
47228
+ "animate-ping absolute inline-flex h-full w-full rounded-full opacity-75",
47229
+ workspaceHealth.status === "healthy" ? "bg-green-400" : "bg-red-400"
47230
+ ) }),
47231
+ /* @__PURE__ */ jsx("span", { className: clsx(
47232
+ "relative inline-flex rounded-full h-2.5 w-2.5",
47233
+ workspaceHealth.status === "healthy" ? "bg-green-500" : "bg-red-500"
47234
+ ) })
47235
+ ] })
47236
+ ] }) }),
47237
+ activeTab !== "monthly_history" && /* @__PURE__ */ jsxs("div", { className: "absolute right-0 top-0 flex flex-col items-end gap-1", children: [
47238
+ workspaceHealth && /* @__PURE__ */ jsxs("span", { className: "text-xs text-gray-500", children: [
46476
47239
  "Last update: ",
46477
47240
  workspaceHealth.timeSinceLastUpdate
46478
- ] }) }),
46479
- /* @__PURE__ */ jsx("div", { className: "w-full h-8" })
46480
- ] }) }),
46481
- activeTab !== "monthly_history" && /* @__PURE__ */ jsxs(Fragment, { children: [
46482
- /* @__PURE__ */ jsxs("div", { className: "sm:hidden mt-3 flex items-center justify-center gap-2", children: [
46483
- /* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-gray-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: formatISTDate2(new Date(workspace.date)) }) }),
46484
- /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1 px-2.5 py-1 bg-gray-100 rounded-full", children: [
46485
- /* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: getShiftIcon(workspace.shift_type) }),
46486
- /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: workspace.shift_type })
46487
- ] }),
46488
- !date && !shift && !usingFallbackData ? /* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-green-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-green-700", children: /* @__PURE__ */ jsx(LiveTimer, {}) }) }) : date ? /* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-blue-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-blue-700", children: getDaysDifference(workspace.date, timezone, dashboardConfig?.shiftConfig?.dayShift?.startTime || "06:00") }) }) : usingFallbackData ? /* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-amber-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-amber-700", children: getDaysDifference(workspace.date, timezone, dashboardConfig?.shiftConfig?.dayShift?.startTime || "06:00") }) }) : null
46489
47241
  ] }),
46490
- /* @__PURE__ */ jsx("div", { className: "hidden sm:block mt-3 bg-blue-50 px-3 py-2 rounded-lg", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-center gap-3 md:gap-4", children: [
46491
- !date && !shift && !usingFallbackData && /* @__PURE__ */ jsxs(Fragment, { children: [
46492
- /* @__PURE__ */ jsx("div", { className: "text-base md:text-lg font-medium text-blue-600", children: /* @__PURE__ */ jsx(LiveTimer, {}) }),
46493
- /* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-300" })
46494
- ] }),
46495
- /* @__PURE__ */ jsx("span", { className: "text-sm md:text-base font-medium text-blue-600", children: formatISTDate2(new Date(workspace.date)) }),
46496
- /* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-300" }),
46497
- date && /* @__PURE__ */ jsxs(Fragment, { children: [
46498
- /* @__PURE__ */ jsx("span", { className: "px-2 py-1 text-xs font-medium bg-blue-200 text-blue-800 rounded-md", children: getDaysDifference(workspace.date, timezone, dashboardConfig?.shiftConfig?.dayShift?.startTime || "06:00") }),
46499
- /* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-300" })
46500
- ] }),
46501
- !date && !shift && usingFallbackData && /* @__PURE__ */ jsxs(Fragment, { children: [
46502
- /* @__PURE__ */ jsxs("span", { className: "px-2 py-1 text-xs font-medium bg-amber-100 text-amber-700 rounded-md", children: [
46503
- "Latest available data (",
46504
- getDaysDifference(workspace.date, timezone, dashboardConfig?.shiftConfig?.dayShift?.startTime || "06:00"),
46505
- ")"
46506
- ] }),
46507
- /* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-300" })
47242
+ /* @__PURE__ */ jsx(
47243
+ WorkspaceHealthStatusBadge,
47244
+ {
47245
+ workspaceId,
47246
+ mode: "full",
47247
+ showHealthDot: false
47248
+ }
47249
+ )
47250
+ ] }),
47251
+ /* @__PURE__ */ jsx("div", { className: "w-full h-8" })
47252
+ ] }) }),
47253
+ activeTab !== "monthly_history" && /* @__PURE__ */ jsxs(Fragment, { children: [
47254
+ /* @__PURE__ */ jsxs("div", { className: "sm:hidden mt-3 flex items-center justify-center gap-2", children: [
47255
+ /* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-gray-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: formatISTDate2(new Date(workspace.date)) }) }),
47256
+ /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1 px-2.5 py-1 bg-gray-100 rounded-full", children: [
47257
+ /* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: getShiftIcon(workspace.shift_type) }),
47258
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: workspace.shift_type })
47259
+ ] }),
47260
+ !date && !shift && !usingFallbackData ? /* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-green-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-green-700", children: /* @__PURE__ */ jsx(LiveTimer, {}) }) }) : date ? /* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-blue-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-blue-700", children: getDaysDifference(workspace.date, timezone, dashboardConfig?.shiftConfig?.dayShift?.startTime || "06:00") }) }) : usingFallbackData ? /* @__PURE__ */ jsx("div", { className: "inline-flex items-center px-2.5 py-1 bg-amber-100 rounded-full", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-amber-700", children: getDaysDifference(workspace.date, timezone, dashboardConfig?.shiftConfig?.dayShift?.startTime || "06:00") }) }) : null
47261
+ ] }),
47262
+ /* @__PURE__ */ jsx("div", { className: "hidden sm:block mt-3 bg-blue-50 px-3 py-2 rounded-lg", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-center gap-3 md:gap-4", children: [
47263
+ !date && !shift && !usingFallbackData && /* @__PURE__ */ jsxs(Fragment, { children: [
47264
+ /* @__PURE__ */ jsx("div", { className: "text-base md:text-lg font-medium text-blue-600", children: /* @__PURE__ */ jsx(LiveTimer, {}) }),
47265
+ /* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-300" })
47266
+ ] }),
47267
+ /* @__PURE__ */ jsx("span", { className: "text-sm md:text-base font-medium text-blue-600", children: formatISTDate2(new Date(workspace.date)) }),
47268
+ /* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-300" }),
47269
+ date && /* @__PURE__ */ jsxs(Fragment, { children: [
47270
+ /* @__PURE__ */ jsx("span", { className: "px-2 py-1 text-xs font-medium bg-blue-200 text-blue-800 rounded-md", children: getDaysDifference(workspace.date, timezone, dashboardConfig?.shiftConfig?.dayShift?.startTime || "06:00") }),
47271
+ /* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-300" })
47272
+ ] }),
47273
+ !date && !shift && usingFallbackData && /* @__PURE__ */ jsxs(Fragment, { children: [
47274
+ /* @__PURE__ */ jsxs("span", { className: "px-2 py-1 text-xs font-medium bg-amber-100 text-amber-700 rounded-md", children: [
47275
+ "Latest available data (",
47276
+ getDaysDifference(workspace.date, timezone, dashboardConfig?.shiftConfig?.dayShift?.startTime || "06:00"),
47277
+ ")"
46508
47278
  ] }),
46509
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
46510
- /* @__PURE__ */ jsx("div", { className: "text-blue-600", children: getShiftIcon(workspace.shift_type) }),
46511
- /* @__PURE__ */ jsxs("span", { className: "text-sm md:text-base font-medium text-blue-600", children: [
46512
- workspace.shift_type,
46513
- " Shift"
46514
- ] })
47279
+ /* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-300" })
47280
+ ] }),
47281
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
47282
+ /* @__PURE__ */ jsx("div", { className: "text-blue-600", children: getShiftIcon(workspace.shift_type) }),
47283
+ /* @__PURE__ */ jsxs("span", { className: "text-sm md:text-base font-medium text-blue-600", children: [
47284
+ workspace.shift_type,
47285
+ " Shift"
46515
47286
  ] })
46516
- ] }) })
46517
- ] }),
46518
- /* @__PURE__ */ jsxs("div", { className: "mt-2 sm:mt-1.5 lg:mt-2", children: [
46519
- /* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex bg-gray-100 rounded-lg p-0.5", children: [
47287
+ ] })
47288
+ ] }) })
47289
+ ] }),
47290
+ /* @__PURE__ */ jsxs("div", { className: "mt-2 sm:mt-1.5 lg:mt-2", children: [
47291
+ /* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex bg-gray-100 rounded-lg p-0.5", children: [
47292
+ /* @__PURE__ */ jsx(
47293
+ "button",
47294
+ {
47295
+ onClick: () => setActiveTab("overview"),
47296
+ className: `flex-1 px-2 py-1.5 text-xs font-medium rounded-md transition-all duration-200 ${activeTab === "overview" ? "bg-white text-gray-900 shadow-sm" : "text-gray-600"}`,
47297
+ children: "Efficiency"
47298
+ }
47299
+ ),
47300
+ isClipsEnabled && /* @__PURE__ */ jsx(
47301
+ "button",
47302
+ {
47303
+ onClick: () => setActiveTab("bottlenecks"),
47304
+ className: `flex-1 px-2 py-1.5 text-xs font-medium rounded-md transition-all duration-200 ${activeTab === "bottlenecks" ? "bg-white text-gray-900 shadow-sm" : "text-gray-600"}`,
47305
+ children: "Clips"
47306
+ }
47307
+ ),
47308
+ /* @__PURE__ */ jsx(
47309
+ "button",
47310
+ {
47311
+ onClick: () => setActiveTab("monthly_history"),
47312
+ className: `flex-1 px-2 py-1.5 text-xs font-medium rounded-md transition-all duration-200 ${activeTab === "monthly_history" ? "bg-white text-gray-900 shadow-sm" : "text-gray-600"}`,
47313
+ children: "History"
47314
+ }
47315
+ )
47316
+ ] }) }),
47317
+ /* @__PURE__ */ jsxs("div", { className: "hidden sm:flex items-center justify-between", children: [
47318
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5 lg:gap-2", children: [
46520
47319
  /* @__PURE__ */ jsx(
46521
47320
  "button",
46522
47321
  {
46523
47322
  onClick: () => setActiveTab("overview"),
46524
- className: `flex-1 px-2 py-1.5 text-xs font-medium rounded-md transition-all duration-200 ${activeTab === "overview" ? "bg-white text-gray-900 shadow-sm" : "text-gray-600"}`,
47323
+ className: `px-2 lg:px-3 py-1 lg:py-1.5 text-sm lg:text-base font-medium rounded-lg transition-colors whitespace-nowrap ${activeTab === "overview" ? "bg-blue-50 text-blue-600" : "text-gray-600 hover:bg-gray-50"}`,
46525
47324
  children: "Efficiency"
46526
47325
  }
46527
47326
  ),
@@ -46529,7 +47328,7 @@ var WorkspaceDetailView = ({
46529
47328
  "button",
46530
47329
  {
46531
47330
  onClick: () => setActiveTab("bottlenecks"),
46532
- className: `flex-1 px-2 py-1.5 text-xs font-medium rounded-md transition-all duration-200 ${activeTab === "bottlenecks" ? "bg-white text-gray-900 shadow-sm" : "text-gray-600"}`,
47331
+ className: `px-2 lg:px-3 py-1 lg:py-1.5 text-sm lg:text-base font-medium rounded-lg transition-colors whitespace-nowrap ${activeTab === "bottlenecks" ? "bg-blue-50 text-blue-600" : "text-gray-600 hover:bg-gray-50"}`,
46533
47332
  children: "Clips"
46534
47333
  }
46535
47334
  ),
@@ -46537,59 +47336,151 @@ var WorkspaceDetailView = ({
46537
47336
  "button",
46538
47337
  {
46539
47338
  onClick: () => setActiveTab("monthly_history"),
46540
- className: `flex-1 px-2 py-1.5 text-xs font-medium rounded-md transition-all duration-200 ${activeTab === "monthly_history" ? "bg-white text-gray-900 shadow-sm" : "text-gray-600"}`,
46541
- children: "History"
47339
+ className: `px-2 lg:px-3 py-1 lg:py-1.5 text-sm lg:text-base font-medium rounded-lg transition-colors whitespace-nowrap ${activeTab === "monthly_history" ? "bg-blue-50 text-blue-600" : "text-gray-600 hover:bg-gray-50"}`,
47340
+ children: "Monthly History"
46542
47341
  }
46543
47342
  )
46544
- ] }) }),
46545
- /* @__PURE__ */ jsxs("div", { className: "hidden sm:flex items-center justify-between", children: [
46546
- /* @__PURE__ */ jsxs("div", { className: "flex gap-1.5 lg:gap-2", children: [
46547
- /* @__PURE__ */ jsx(
46548
- "button",
46549
- {
46550
- onClick: () => setActiveTab("overview"),
46551
- className: `px-2 lg:px-3 py-1 lg:py-1.5 text-sm lg:text-base font-medium rounded-lg transition-colors whitespace-nowrap ${activeTab === "overview" ? "bg-blue-50 text-blue-600" : "text-gray-600 hover:bg-gray-50"}`,
46552
- children: "Efficiency"
46553
- }
46554
- ),
46555
- isClipsEnabled && /* @__PURE__ */ jsx(
46556
- "button",
46557
- {
46558
- onClick: () => setActiveTab("bottlenecks"),
46559
- className: `px-2 lg:px-3 py-1 lg:py-1.5 text-sm lg:text-base font-medium rounded-lg transition-colors whitespace-nowrap ${activeTab === "bottlenecks" ? "bg-blue-50 text-blue-600" : "text-gray-600 hover:bg-gray-50"}`,
46560
- children: "Clips"
46561
- }
46562
- ),
46563
- /* @__PURE__ */ jsx(
47343
+ ] }),
47344
+ activeTab === "overview" && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 lg:gap-2", children: renderHeaderActions ? renderHeaderActions(workspace) : /* @__PURE__ */ jsx(WorkspacePdfGenerator, { workspace }) }),
47345
+ activeTab === "monthly_history" && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 lg:gap-2", children: /* @__PURE__ */ jsx(
47346
+ WorkspaceMonthlyPdfGenerator,
47347
+ {
47348
+ workspaceId,
47349
+ workspaceName: workspace?.workspace_name || "",
47350
+ monthlyData,
47351
+ selectedMonth,
47352
+ selectedYear,
47353
+ selectedShift
47354
+ }
47355
+ ) })
47356
+ ] })
47357
+ ] })
47358
+ ] }),
47359
+ /* @__PURE__ */ jsxs("div", { className: "flex-grow p-1.5 sm:p-2 lg:p-4", children: [
47360
+ activeTab === "overview" && /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full lg:h-[calc(100vh-10rem)] overflow-y-auto lg:overflow-hidden", children: [
47361
+ /* @__PURE__ */ jsxs("div", { className: "block lg:hidden space-y-6 pb-6", children: [
47362
+ !shouldShowCycleTimeChart && /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-lg shadow-sm p-6", children: [
47363
+ /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-gray-700 mb-8", children: "Daily Progress" }),
47364
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col justify-center space-y-8", children: [
47365
+ /* @__PURE__ */ jsxs("div", { className: "text-center space-y-1", children: [
47366
+ /* @__PURE__ */ jsxs("p", { className: "text-7xl font-bold tracking-tight", children: [
47367
+ (workspace.total_actions / workspace.target_output * 100).toFixed(1),
47368
+ "%"
47369
+ ] }),
47370
+ /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center gap-2 text-gray-500", children: /* @__PURE__ */ jsx("span", { className: "text-base font-medium", children: "of today's target" }) })
47371
+ ] }),
47372
+ /* @__PURE__ */ jsx("div", { className: "space-y-6", children: /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
47373
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center", children: [
47374
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-600", children: "Overall Progress" }),
47375
+ /* @__PURE__ */ jsxs("p", { className: "text-lg font-semibold text-gray-700", children: [
47376
+ workspace.total_actions,
47377
+ " / ",
47378
+ workspace.target_output
47379
+ ] })
47380
+ ] }),
47381
+ /* @__PURE__ */ jsx("div", { className: "w-full bg-gray-100 rounded-full h-2.5", children: /* @__PURE__ */ jsx(
47382
+ motion.div,
47383
+ {
47384
+ initial: { width: 0 },
47385
+ animate: {
47386
+ width: `${Math.min(100, workspace.total_actions / workspace.target_output * 100)}%`
47387
+ },
47388
+ transition: {
47389
+ duration: 1,
47390
+ ease: "easeOut",
47391
+ delay: 0.2
47392
+ },
47393
+ className: "bg-green-500 h-2.5 rounded-full"
47394
+ }
47395
+ ) })
47396
+ ] }) })
47397
+ ] })
47398
+ ] }),
47399
+ /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-lg shadow-sm p-4", children: [
47400
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center mb-4", children: [
47401
+ /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-gray-700", children: shouldShowCycleTimeChart ? "Cycle Time (last 60 minutes)" : "Hourly Output" }),
47402
+ !shouldShowCycleTimeChart && /* @__PURE__ */ jsxs(
46564
47403
  "button",
46565
47404
  {
46566
- onClick: () => setActiveTab("monthly_history"),
46567
- className: `px-2 lg:px-3 py-1 lg:py-1.5 text-sm lg:text-base font-medium rounded-lg transition-colors whitespace-nowrap ${activeTab === "monthly_history" ? "bg-blue-50 text-blue-600" : "text-gray-600 hover:bg-gray-50"}`,
46568
- children: "Monthly History"
47405
+ onClick: () => setShowIdleTime(!showIdleTime),
47406
+ className: `
47407
+ flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium rounded
47408
+ transition-all duration-200 border
47409
+ ${showIdleTime ? "bg-gray-100 text-gray-700 border-gray-300 hover:bg-gray-200" : "bg-white text-gray-500 border-gray-200 hover:bg-gray-50 hover:text-gray-700"}
47410
+ `,
47411
+ "aria-label": showIdleTime ? "Hide idle time bars from chart" : "Show idle time bars on chart",
47412
+ children: [
47413
+ showIdleTime ? /* @__PURE__ */ jsx(EyeOff, { className: "w-3.5 h-3.5" }) : /* @__PURE__ */ jsx(Eye, { className: "w-3.5 h-3.5" }),
47414
+ /* @__PURE__ */ jsx("span", { children: showIdleTime ? "Hide Idle Time" : "Show Idle Time" })
47415
+ ]
46569
47416
  }
46570
47417
  )
46571
47418
  ] }),
46572
- activeTab === "overview" && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 lg:gap-2", children: renderHeaderActions ? renderHeaderActions(workspace) : /* @__PURE__ */ jsx(WorkspacePdfGenerator, { workspace }) }),
46573
- activeTab === "monthly_history" && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 lg:gap-2", children: /* @__PURE__ */ jsx(
46574
- WorkspaceMonthlyPdfGenerator,
47419
+ /* @__PURE__ */ jsx(
47420
+ "div",
46575
47421
  {
46576
- workspaceId,
46577
- workspaceName: workspace?.workspace_name || "",
46578
- monthlyData,
46579
- selectedMonth,
46580
- selectedYear,
46581
- selectedShift
47422
+ className: "h-[300px]",
47423
+ style: { minHeight: "200px", minWidth: "300px" },
47424
+ children: shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
47425
+ CycleTimeOverTimeChart,
47426
+ {
47427
+ data: workspace.hourly_action_counts || [],
47428
+ idealCycleTime: workspace.ideal_cycle_time || 0,
47429
+ shiftStart: workspace.shift_start || ""
47430
+ }
47431
+ ) : /* @__PURE__ */ jsx(
47432
+ HourlyOutputChart2,
47433
+ {
47434
+ data: workspace.hourly_action_counts || [],
47435
+ pphThreshold: workspace.pph_threshold || 0,
47436
+ shiftStart: workspace.shift_start || "",
47437
+ shiftEnd: workspace.shift_end,
47438
+ showIdleTime,
47439
+ idleTimeHourly: workspace.idle_time_hourly
47440
+ }
47441
+ )
46582
47442
  }
46583
- ) })
46584
- ] })
46585
- ] })
46586
- ] }),
46587
- /* @__PURE__ */ jsxs("div", { className: "flex-grow p-1.5 sm:p-2 lg:p-4", children: [
46588
- activeTab === "overview" && /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full lg:h-[calc(100vh-10rem)] overflow-y-auto lg:overflow-hidden", children: [
46589
- /* @__PURE__ */ jsxs("div", { className: "block lg:hidden space-y-6 pb-6", children: [
46590
- !shouldShowCycleTimeChart && /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-lg shadow-sm p-6", children: [
47443
+ )
47444
+ ] }),
47445
+ shouldShowCycleTimeChart ? /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
47446
+ /* @__PURE__ */ jsxs(Card2, { children: [
47447
+ /* @__PURE__ */ jsx(CardHeader2, { className: "pb-2 flex-none", children: /* @__PURE__ */ jsx(CardTitle2, { className: "text-lg text-center", children: "Efficiency" }) }),
47448
+ /* @__PURE__ */ jsx(CardContent2, { className: "flex-1 flex items-center justify-center py-6", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
47449
+ /* @__PURE__ */ jsxs("p", { className: `text-5xl font-bold ${(workspace.avg_efficiency || 0) >= 80 ? "text-green-500" : "text-red-500"}`, children: [
47450
+ (workspace.avg_efficiency || 0).toFixed(1),
47451
+ "%"
47452
+ ] }),
47453
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 mt-2", children: "Target: 80%" })
47454
+ ] }) })
47455
+ ] }),
47456
+ /* @__PURE__ */ jsxs(Card2, { children: [
47457
+ /* @__PURE__ */ jsx(CardHeader2, { className: "pb-2 flex-none", children: /* @__PURE__ */ jsx(CardTitle2, { className: "text-lg text-center", children: "Cycle Time (s)" }) }),
47458
+ /* @__PURE__ */ jsx(CardContent2, { className: "flex-1 flex items-center justify-center py-6", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
47459
+ /* @__PURE__ */ jsx("p", { className: `text-5xl font-bold ${workspace.avg_cycle_time > (workspace.ideal_cycle_time || 0) ? "text-red-500" : "text-green-500"}`, children: workspace.avg_cycle_time.toFixed(1) }),
47460
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-500 mt-2", children: [
47461
+ "Standard: ",
47462
+ workspace.ideal_cycle_time?.toFixed(1) || 0,
47463
+ "s"
47464
+ ] })
47465
+ ] }) })
47466
+ ] }),
47467
+ /* @__PURE__ */ jsxs(Card2, { children: [
47468
+ /* @__PURE__ */ jsx(CardHeader2, { className: "pb-2 flex-none", children: /* @__PURE__ */ jsx(CardTitle2, { className: "text-lg text-center", children: "Idle Time" }) }),
47469
+ /* @__PURE__ */ jsx(CardContent2, { className: "flex-1 flex items-center justify-center py-6", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
47470
+ /* @__PURE__ */ jsx("p", { className: `text-4xl font-bold ${!workspace.idle_time || workspace.idle_time <= 0 ? "text-green-500" : workspace.idle_time <= 300 ? "text-yellow-500" : (
47471
+ // 5 minutes or less
47472
+ "text-red-500"
47473
+ )}`, children: formatIdleTime(workspace.idle_time) }),
47474
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 mt-2", children: "Total idle time" })
47475
+ ] }) })
47476
+ ] })
47477
+ ] }) : /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(WorkspaceMetricCards, { workspace, className: "flex-1" }) })
47478
+ ] }),
47479
+ /* @__PURE__ */ jsxs("div", { className: "hidden lg:flex lg:flex-col lg:h-full", children: [
47480
+ /* @__PURE__ */ jsxs("div", { className: "h-[60%] grid grid-cols-1 lg:grid-cols-5 gap-3 mb-3", children: [
47481
+ !shouldShowCycleTimeChart && /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-lg shadow-sm p-6 lg:col-span-2", children: [
46591
47482
  /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-gray-700 mb-8", children: "Daily Progress" }),
46592
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col justify-center space-y-8", children: [
47483
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-[calc(100%-6rem)] justify-center space-y-8", children: [
46593
47484
  /* @__PURE__ */ jsxs("div", { className: "text-center space-y-1", children: [
46594
47485
  /* @__PURE__ */ jsxs("p", { className: "text-7xl font-bold tracking-tight", children: [
46595
47486
  (workspace.total_actions / workspace.target_output * 100).toFixed(1),
@@ -46624,7 +47515,7 @@ var WorkspaceDetailView = ({
46624
47515
  ] }) })
46625
47516
  ] })
46626
47517
  ] }),
46627
- /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-lg shadow-sm p-4", children: [
47518
+ /* @__PURE__ */ jsxs("div", { className: `bg-white rounded-lg shadow-sm p-4 ${shouldShowCycleTimeChart ? "lg:col-span-5" : "lg:col-span-3"}`, children: [
46628
47519
  /* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center mb-4", children: [
46629
47520
  /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-gray-700", children: shouldShowCycleTimeChart ? "Cycle Time (last 60 minutes)" : "Hourly Output" }),
46630
47521
  !shouldShowCycleTimeChart && /* @__PURE__ */ jsxs(
@@ -46632,10 +47523,10 @@ var WorkspaceDetailView = ({
46632
47523
  {
46633
47524
  onClick: () => setShowIdleTime(!showIdleTime),
46634
47525
  className: `
46635
- flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium rounded
46636
- transition-all duration-200 border
46637
- ${showIdleTime ? "bg-gray-100 text-gray-700 border-gray-300 hover:bg-gray-200" : "bg-white text-gray-500 border-gray-200 hover:bg-gray-50 hover:text-gray-700"}
46638
- `,
47526
+ flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium rounded
47527
+ transition-all duration-200 border
47528
+ ${showIdleTime ? "bg-gray-100 text-gray-700 border-gray-300 hover:bg-gray-200" : "bg-white text-gray-500 border-gray-200 hover:bg-gray-50 hover:text-gray-700"}
47529
+ `,
46639
47530
  "aria-label": showIdleTime ? "Hide idle time bars from chart" : "Show idle time bars on chart",
46640
47531
  children: [
46641
47532
  showIdleTime ? /* @__PURE__ */ jsx(EyeOff, { className: "w-3.5 h-3.5" }) : /* @__PURE__ */ jsx(Eye, { className: "w-3.5 h-3.5" }),
@@ -46647,7 +47538,7 @@ var WorkspaceDetailView = ({
46647
47538
  /* @__PURE__ */ jsx(
46648
47539
  "div",
46649
47540
  {
46650
- className: "h-[300px]",
47541
+ className: "h-[calc(100%-3rem)]",
46651
47542
  style: { minHeight: "200px", minWidth: "300px" },
46652
47543
  children: shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
46653
47544
  CycleTimeOverTimeChart,
@@ -46669,248 +47560,103 @@ var WorkspaceDetailView = ({
46669
47560
  )
46670
47561
  }
46671
47562
  )
46672
- ] }),
46673
- shouldShowCycleTimeChart ? /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
46674
- /* @__PURE__ */ jsxs(Card2, { children: [
46675
- /* @__PURE__ */ jsx(CardHeader2, { className: "pb-2 flex-none", children: /* @__PURE__ */ jsx(CardTitle2, { className: "text-lg text-center", children: "Efficiency" }) }),
46676
- /* @__PURE__ */ jsx(CardContent2, { className: "flex-1 flex items-center justify-center py-6", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
46677
- /* @__PURE__ */ jsxs("p", { className: `text-5xl font-bold ${(workspace.avg_efficiency || 0) >= 80 ? "text-green-500" : "text-red-500"}`, children: [
46678
- (workspace.avg_efficiency || 0).toFixed(1),
46679
- "%"
46680
- ] }),
46681
- /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 mt-2", children: "Target: 80%" })
46682
- ] }) })
46683
- ] }),
46684
- /* @__PURE__ */ jsxs(Card2, { children: [
46685
- /* @__PURE__ */ jsx(CardHeader2, { className: "pb-2 flex-none", children: /* @__PURE__ */ jsx(CardTitle2, { className: "text-lg text-center", children: "Cycle Time (s)" }) }),
46686
- /* @__PURE__ */ jsx(CardContent2, { className: "flex-1 flex items-center justify-center py-6", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
46687
- /* @__PURE__ */ jsx("p", { className: `text-5xl font-bold ${workspace.avg_cycle_time > (workspace.ideal_cycle_time || 0) ? "text-red-500" : "text-green-500"}`, children: workspace.avg_cycle_time.toFixed(1) }),
46688
- /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-500 mt-2", children: [
46689
- "Standard: ",
46690
- workspace.ideal_cycle_time?.toFixed(1) || 0,
46691
- "s"
46692
- ] })
46693
- ] }) })
46694
- ] }),
46695
- /* @__PURE__ */ jsxs(Card2, { children: [
46696
- /* @__PURE__ */ jsx(CardHeader2, { className: "pb-2 flex-none", children: /* @__PURE__ */ jsx(CardTitle2, { className: "text-lg text-center", children: "Idle Time" }) }),
46697
- /* @__PURE__ */ jsx(CardContent2, { className: "flex-1 flex items-center justify-center py-6", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
46698
- /* @__PURE__ */ jsx("p", { className: `text-4xl font-bold ${!workspace.idle_time || workspace.idle_time <= 0 ? "text-green-500" : workspace.idle_time <= 300 ? "text-yellow-500" : (
46699
- // 5 minutes or less
46700
- "text-red-500"
46701
- )}`, children: formatIdleTime(workspace.idle_time) }),
46702
- /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 mt-2", children: "Total idle time" })
46703
- ] }) })
46704
- ] })
46705
- ] }) : /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(WorkspaceMetricCards, { workspace, className: "flex-1" }) })
47563
+ ] })
46706
47564
  ] }),
46707
- /* @__PURE__ */ jsxs("div", { className: "hidden lg:flex lg:flex-col lg:h-full", children: [
46708
- /* @__PURE__ */ jsxs("div", { className: "h-[60%] grid grid-cols-1 lg:grid-cols-5 gap-3 mb-3", children: [
46709
- !shouldShowCycleTimeChart && /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-lg shadow-sm p-6 lg:col-span-2", children: [
46710
- /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-gray-700 mb-8", children: "Daily Progress" }),
46711
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-[calc(100%-6rem)] justify-center space-y-8", children: [
46712
- /* @__PURE__ */ jsxs("div", { className: "text-center space-y-1", children: [
46713
- /* @__PURE__ */ jsxs("p", { className: "text-7xl font-bold tracking-tight", children: [
46714
- (workspace.total_actions / workspace.target_output * 100).toFixed(1),
46715
- "%"
46716
- ] }),
46717
- /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center gap-2 text-gray-500", children: /* @__PURE__ */ jsx("span", { className: "text-base font-medium", children: "of today's target" }) })
46718
- ] }),
46719
- /* @__PURE__ */ jsx("div", { className: "space-y-6", children: /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
46720
- /* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center", children: [
46721
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-600", children: "Overall Progress" }),
46722
- /* @__PURE__ */ jsxs("p", { className: "text-lg font-semibold text-gray-700", children: [
46723
- workspace.total_actions,
46724
- " / ",
46725
- workspace.target_output
46726
- ] })
46727
- ] }),
46728
- /* @__PURE__ */ jsx("div", { className: "w-full bg-gray-100 rounded-full h-2.5", children: /* @__PURE__ */ jsx(
46729
- motion.div,
46730
- {
46731
- initial: { width: 0 },
46732
- animate: {
46733
- width: `${Math.min(100, workspace.total_actions / workspace.target_output * 100)}%`
46734
- },
46735
- transition: {
46736
- duration: 1,
46737
- ease: "easeOut",
46738
- delay: 0.2
46739
- },
46740
- className: "bg-green-500 h-2.5 rounded-full"
46741
- }
46742
- ) })
46743
- ] }) })
46744
- ] })
46745
- ] }),
46746
- /* @__PURE__ */ jsxs("div", { className: `bg-white rounded-lg shadow-sm p-4 ${shouldShowCycleTimeChart ? "lg:col-span-5" : "lg:col-span-3"}`, children: [
46747
- /* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center mb-4", children: [
46748
- /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-gray-700", children: shouldShowCycleTimeChart ? "Cycle Time (last 60 minutes)" : "Hourly Output" }),
46749
- !shouldShowCycleTimeChart && /* @__PURE__ */ jsxs(
46750
- "button",
46751
- {
46752
- onClick: () => setShowIdleTime(!showIdleTime),
46753
- className: `
46754
- flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium rounded
46755
- transition-all duration-200 border
46756
- ${showIdleTime ? "bg-gray-100 text-gray-700 border-gray-300 hover:bg-gray-200" : "bg-white text-gray-500 border-gray-200 hover:bg-gray-50 hover:text-gray-700"}
46757
- `,
46758
- "aria-label": showIdleTime ? "Hide idle time bars from chart" : "Show idle time bars on chart",
46759
- children: [
46760
- showIdleTime ? /* @__PURE__ */ jsx(EyeOff, { className: "w-3.5 h-3.5" }) : /* @__PURE__ */ jsx(Eye, { className: "w-3.5 h-3.5" }),
46761
- /* @__PURE__ */ jsx("span", { children: showIdleTime ? "Hide Idle Time" : "Show Idle Time" })
46762
- ]
46763
- }
46764
- )
47565
+ shouldShowCycleTimeChart ? /* @__PURE__ */ jsxs("div", { className: "h-[40%] grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3", children: [
47566
+ /* @__PURE__ */ jsxs(Card2, { children: [
47567
+ /* @__PURE__ */ jsx(CardHeader2, { className: "pb-2 flex-none", children: /* @__PURE__ */ jsx(CardTitle2, { className: "text-lg text-center", children: "Efficiency" }) }),
47568
+ /* @__PURE__ */ jsx(CardContent2, { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
47569
+ /* @__PURE__ */ jsxs("p", { className: `text-5xl font-bold ${(workspace.avg_efficiency || 0) >= 80 ? "text-green-500" : "text-red-500"}`, children: [
47570
+ (workspace.avg_efficiency || 0).toFixed(1),
47571
+ "%"
46765
47572
  ] }),
46766
- /* @__PURE__ */ jsx(
46767
- "div",
46768
- {
46769
- className: "h-[calc(100%-3rem)]",
46770
- style: { minHeight: "200px", minWidth: "300px" },
46771
- children: shouldShowCycleTimeChart ? /* @__PURE__ */ jsx(
46772
- CycleTimeOverTimeChart,
46773
- {
46774
- data: workspace.hourly_action_counts || [],
46775
- idealCycleTime: workspace.ideal_cycle_time || 0,
46776
- shiftStart: workspace.shift_start || ""
46777
- }
46778
- ) : /* @__PURE__ */ jsx(
46779
- HourlyOutputChart2,
46780
- {
46781
- data: workspace.hourly_action_counts || [],
46782
- pphThreshold: workspace.pph_threshold || 0,
46783
- shiftStart: workspace.shift_start || "",
46784
- shiftEnd: workspace.shift_end,
46785
- showIdleTime,
46786
- idleTimeHourly: workspace.idle_time_hourly
46787
- }
46788
- )
46789
- }
46790
- )
46791
- ] })
47573
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 mt-2", children: "Target: 80%" })
47574
+ ] }) })
46792
47575
  ] }),
46793
- shouldShowCycleTimeChart ? /* @__PURE__ */ jsxs("div", { className: "h-[40%] grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3", children: [
46794
- /* @__PURE__ */ jsxs(Card2, { children: [
46795
- /* @__PURE__ */ jsx(CardHeader2, { className: "pb-2 flex-none", children: /* @__PURE__ */ jsx(CardTitle2, { className: "text-lg text-center", children: "Efficiency" }) }),
46796
- /* @__PURE__ */ jsx(CardContent2, { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
46797
- /* @__PURE__ */ jsxs("p", { className: `text-5xl font-bold ${(workspace.avg_efficiency || 0) >= 80 ? "text-green-500" : "text-red-500"}`, children: [
46798
- (workspace.avg_efficiency || 0).toFixed(1),
46799
- "%"
46800
- ] }),
46801
- /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 mt-2", children: "Target: 80%" })
46802
- ] }) })
46803
- ] }),
46804
- /* @__PURE__ */ jsxs(Card2, { children: [
46805
- /* @__PURE__ */ jsx(CardHeader2, { className: "pb-2 flex-none", children: /* @__PURE__ */ jsx(CardTitle2, { className: "text-lg text-center", children: "Cycle Time (s)" }) }),
46806
- /* @__PURE__ */ jsx(CardContent2, { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
46807
- /* @__PURE__ */ jsx("p", { className: `text-5xl font-bold ${workspace.avg_cycle_time > (workspace.ideal_cycle_time || 0) ? "text-red-500" : "text-green-500"}`, children: workspace.avg_cycle_time.toFixed(1) }),
46808
- /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-500 mt-2", children: [
46809
- "Standard: ",
46810
- workspace.ideal_cycle_time?.toFixed(1) || 0,
46811
- "s"
46812
- ] })
46813
- ] }) })
46814
- ] }),
46815
- /* @__PURE__ */ jsxs(Card2, { children: [
46816
- /* @__PURE__ */ jsx(CardHeader2, { className: "pb-2 flex-none", children: /* @__PURE__ */ jsx(CardTitle2, { className: "text-lg text-center", children: "Idle Time" }) }),
46817
- /* @__PURE__ */ jsx(CardContent2, { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
46818
- /* @__PURE__ */ jsx("p", { className: `text-4xl font-bold ${!workspace.idle_time || workspace.idle_time <= 0 ? "text-green-500" : workspace.idle_time <= 300 ? "text-yellow-500" : (
46819
- // 5 minutes or less
46820
- "text-red-500"
46821
- )}`, children: formatIdleTime(workspace.idle_time) }),
46822
- /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 mt-2", children: "Total idle time" })
46823
- ] }) })
46824
- ] })
46825
- ] }) : /* @__PURE__ */ jsx("div", { className: "h-[40%] flex", children: /* @__PURE__ */ jsx(WorkspaceMetricCards, { workspace, className: "flex-1" }) })
46826
- ] })
46827
- ] }),
46828
- activeTab === "monthly_history" && /* @__PURE__ */ jsxs("div", { className: "h-[calc(100vh-10rem)] overflow-y-auto px-2 sm:px-4 lg:px-0", children: [
46829
- workspaceId && activeTab === "monthly_history" && /* @__PURE__ */ jsx(
46830
- WorkspaceMonthlyDataFetcher,
46831
- {
46832
- workspaceId,
46833
- selectedMonth,
46834
- selectedYear,
46835
- onDataLoaded: handleMonthlyDataLoaded,
46836
- onLoadingChange: setMonthlyDataLoading
46837
- }
46838
- ),
46839
- usingFallbackData && !date && !shift && /* @__PURE__ */ jsx("div", { className: "mb-3 sm:mb-4 bg-amber-50 border border-amber-200 rounded-lg px-3 sm:px-4 py-2 sm:py-3 text-amber-800", children: /* @__PURE__ */ jsxs("p", { className: "text-xs sm:text-sm font-medium flex items-center", children: [
46840
- /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-4 w-4 sm:h-5 sm:w-5 mr-2", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z", clipRule: "evenodd" }) }),
46841
- "No current data available for today. Showing monthly history instead."
46842
- ] }) }),
46843
- /* @__PURE__ */ jsx(
46844
- WorkspaceMonthlyHistory,
46845
- {
46846
- data: monthlyData,
46847
- month: selectedMonth,
46848
- year: selectedYear,
46849
- workspaceId,
46850
- selectedShift,
46851
- monthlyDataLoading,
46852
- onDateSelect: (selectedDate, shift2) => {
46853
- if (onDateSelect) {
46854
- onDateSelect(selectedDate, shift2);
46855
- } else if (onNavigate) {
46856
- const params = new URLSearchParams();
46857
- params.set("date", selectedDate);
46858
- params.set("shift", shift2 === "day" ? "0" : "1");
46859
- params.set("fromMonthly", "true");
46860
- if (effectiveLineId) {
46861
- params.set("lineId", effectiveLineId);
46862
- }
46863
- onNavigate(`/workspace/${workspaceId}?${params.toString()}`);
46864
- }
46865
- },
46866
- onMonthNavigate: (newMonth, newYear) => {
46867
- setSelectedMonth(newMonth);
46868
- setSelectedYear(newYear);
46869
- },
46870
- onShiftChange: setSelectedShift,
46871
- className: "w-full"
46872
- }
46873
- )
46874
- ] }),
46875
- activeTab === "bottlenecks" && /* @__PURE__ */ jsx(ClipFilterProvider, { children: /* @__PURE__ */ jsx(
46876
- BottlenecksContent,
47576
+ /* @__PURE__ */ jsxs(Card2, { children: [
47577
+ /* @__PURE__ */ jsx(CardHeader2, { className: "pb-2 flex-none", children: /* @__PURE__ */ jsx(CardTitle2, { className: "text-lg text-center", children: "Cycle Time (s)" }) }),
47578
+ /* @__PURE__ */ jsx(CardContent2, { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
47579
+ /* @__PURE__ */ jsx("p", { className: `text-5xl font-bold ${workspace.avg_cycle_time > (workspace.ideal_cycle_time || 0) ? "text-red-500" : "text-green-500"}`, children: workspace.avg_cycle_time.toFixed(1) }),
47580
+ /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-500 mt-2", children: [
47581
+ "Standard: ",
47582
+ workspace.ideal_cycle_time?.toFixed(1) || 0,
47583
+ "s"
47584
+ ] })
47585
+ ] }) })
47586
+ ] }),
47587
+ /* @__PURE__ */ jsxs(Card2, { children: [
47588
+ /* @__PURE__ */ jsx(CardHeader2, { className: "pb-2 flex-none", children: /* @__PURE__ */ jsx(CardTitle2, { className: "text-lg text-center", children: "Idle Time" }) }),
47589
+ /* @__PURE__ */ jsx(CardContent2, { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
47590
+ /* @__PURE__ */ jsx("p", { className: `text-4xl font-bold ${!workspace.idle_time || workspace.idle_time <= 0 ? "text-green-500" : workspace.idle_time <= 300 ? "text-yellow-500" : (
47591
+ // 5 minutes or less
47592
+ "text-red-500"
47593
+ )}`, children: formatIdleTime(workspace.idle_time) }),
47594
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 mt-2", children: "Total idle time" })
47595
+ ] }) })
47596
+ ] })
47597
+ ] }) : /* @__PURE__ */ jsx("div", { className: "h-[40%] flex", children: /* @__PURE__ */ jsx(WorkspaceMetricCards, { workspace, className: "flex-1" }) })
47598
+ ] })
47599
+ ] }),
47600
+ activeTab === "monthly_history" && /* @__PURE__ */ jsxs("div", { className: "h-[calc(100vh-10rem)] overflow-y-auto px-2 sm:px-4 lg:px-0", children: [
47601
+ workspaceId && activeTab === "monthly_history" && /* @__PURE__ */ jsx(
47602
+ WorkspaceMonthlyDataFetcher,
46877
47603
  {
46878
47604
  workspaceId,
46879
- workspaceName: formattedWorkspaceName,
46880
- date,
46881
- shift,
46882
- totalOutput: workspace?.total_actions,
46883
- className: "h-[calc(100vh-10rem)]"
47605
+ selectedMonth,
47606
+ selectedYear,
47607
+ onDataLoaded: handleMonthlyDataLoaded,
47608
+ onLoadingChange: setMonthlyDataLoading
46884
47609
  }
46885
- ) })
46886
- ] })
46887
- ] }),
46888
- /* @__PURE__ */ jsx(
46889
- CongratulationsOverlay,
46890
- {
46891
- achievement: currentAchievement,
46892
- isVisible: showCongratulations,
46893
- duration: 6e4,
46894
- onDismiss: () => {
46895
- setShowCongratulations(false);
46896
- setCurrentAchievement(null);
47610
+ ),
47611
+ usingFallbackData && !date && !shift && /* @__PURE__ */ jsx("div", { className: "mb-3 sm:mb-4 bg-amber-50 border border-amber-200 rounded-lg px-3 sm:px-4 py-2 sm:py-3 text-amber-800", children: /* @__PURE__ */ jsxs("p", { className: "text-xs sm:text-sm font-medium flex items-center", children: [
47612
+ /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-4 w-4 sm:h-5 sm:w-5 mr-2", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z", clipRule: "evenodd" }) }),
47613
+ "No current data available for today. Showing monthly history instead."
47614
+ ] }) }),
47615
+ /* @__PURE__ */ jsx(
47616
+ WorkspaceMonthlyHistory,
47617
+ {
47618
+ data: monthlyData,
47619
+ month: selectedMonth,
47620
+ year: selectedYear,
47621
+ workspaceId,
47622
+ selectedShift,
47623
+ monthlyDataLoading,
47624
+ onDateSelect: (selectedDate, shift2) => {
47625
+ if (onDateSelect) {
47626
+ onDateSelect(selectedDate, shift2);
47627
+ } else if (onNavigate) {
47628
+ const params = new URLSearchParams();
47629
+ params.set("date", selectedDate);
47630
+ params.set("shift", shift2 === "day" ? "0" : "1");
47631
+ params.set("fromMonthly", "true");
47632
+ if (effectiveLineId) {
47633
+ params.set("lineId", effectiveLineId);
47634
+ }
47635
+ onNavigate(`/workspace/${workspaceId}?${params.toString()}`);
47636
+ }
47637
+ },
47638
+ onMonthNavigate: (newMonth, newYear) => {
47639
+ setSelectedMonth(newMonth);
47640
+ setSelectedYear(newYear);
47641
+ },
47642
+ onShiftChange: setSelectedShift,
47643
+ className: "w-full"
47644
+ }
47645
+ )
47646
+ ] }),
47647
+ activeTab === "bottlenecks" && /* @__PURE__ */ jsx(ClipFilterProvider, { children: /* @__PURE__ */ jsx(
47648
+ BottlenecksContent,
47649
+ {
47650
+ workspaceId,
47651
+ workspaceName: formattedWorkspaceName,
47652
+ date,
47653
+ shift,
47654
+ totalOutput: workspace?.total_actions,
47655
+ className: "h-[calc(100vh-10rem)]"
46897
47656
  }
46898
- }
46899
- ),
46900
- /* @__PURE__ */ jsx(
46901
- EncouragementOverlay,
46902
- {
46903
- isVisible: showEncouragement,
46904
- onClose: () => {
46905
- setShowEncouragement(false);
46906
- setCurrentMiss(null);
46907
- },
46908
- targetValue: currentMiss?.targetValue || 0,
46909
- actualValue: currentMiss?.actualValue || 0,
46910
- metricName: currentMiss?.metricName || "Target"
46911
- }
46912
- )
46913
- ]
47657
+ ) })
47658
+ ] })
47659
+ ] })
46914
47660
  }
46915
47661
  );
46916
47662
  };
@@ -48025,21 +48771,36 @@ var LineAssignmentDropdown = ({
48025
48771
  const [isOpen, setIsOpen] = useState(false);
48026
48772
  const [selectedIds, setSelectedIds] = useState(currentLineIds);
48027
48773
  const [isSaving, setIsSaving] = useState(false);
48774
+ const [position, setPosition] = useState({ top: 0, left: 0, width: 0 });
48775
+ const buttonRef = useRef(null);
48028
48776
  const dropdownRef = useRef(null);
48029
48777
  useEffect(() => {
48030
48778
  setSelectedIds(currentLineIds);
48031
48779
  }, [currentLineIds]);
48032
48780
  useEffect(() => {
48033
- console.log("[LineAssignmentDropdown] Available lines updated:", {
48034
- userId,
48035
- count: availableLines.length,
48036
- lines: availableLines,
48037
- hasCompanyId: availableLines.every((l) => l.company_id)
48038
- });
48039
- }, [availableLines, userId]);
48781
+ const updatePosition = () => {
48782
+ if (isOpen && buttonRef.current) {
48783
+ const rect = buttonRef.current.getBoundingClientRect();
48784
+ setPosition({
48785
+ top: rect.bottom,
48786
+ left: rect.left,
48787
+ width: rect.width
48788
+ });
48789
+ }
48790
+ };
48791
+ if (isOpen) {
48792
+ updatePosition();
48793
+ window.addEventListener("scroll", updatePosition, true);
48794
+ window.addEventListener("resize", updatePosition);
48795
+ }
48796
+ return () => {
48797
+ window.removeEventListener("scroll", updatePosition, true);
48798
+ window.removeEventListener("resize", updatePosition);
48799
+ };
48800
+ }, [isOpen]);
48040
48801
  useEffect(() => {
48041
48802
  const handleClickOutside = (event) => {
48042
- if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
48803
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target) && buttonRef.current && !buttonRef.current.contains(event.target)) {
48043
48804
  setIsOpen(false);
48044
48805
  setSelectedIds(currentLineIds);
48045
48806
  }
@@ -48105,94 +48866,106 @@ var LineAssignmentDropdown = ({
48105
48866
  if (!canEdit) {
48106
48867
  return /* @__PURE__ */ jsx("div", { className: "text-sm", children: getDisplayText() });
48107
48868
  }
48108
- return /* @__PURE__ */ jsxs("div", { className: "relative", ref: dropdownRef, children: [
48869
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
48109
48870
  /* @__PURE__ */ jsxs(
48110
48871
  "button",
48111
48872
  {
48873
+ ref: buttonRef,
48112
48874
  onClick: () => setIsOpen(!isOpen),
48113
48875
  className: cn(
48114
- "flex items-center gap-2 px-3 py-1.5 text-sm border rounded-lg transition-colors",
48876
+ "flex items-center gap-2 px-3 py-2 text-sm border rounded-lg transition-colors min-w-[200px]",
48115
48877
  currentLineIds.length === 0 ? "border-blue-300 bg-blue-50 hover:bg-blue-100" : "border-gray-300 bg-white hover:bg-gray-50"
48116
48878
  ),
48117
48879
  children: [
48118
48880
  /* @__PURE__ */ jsx("span", { className: "flex-1 text-left", children: getDisplayText() }),
48119
48881
  /* @__PURE__ */ jsx(ChevronDown, { className: cn(
48120
- "w-4 h-4 text-gray-400 transition-transform",
48882
+ "w-4 h-4 text-gray-400 transition-transform flex-shrink-0",
48121
48883
  isOpen && "rotate-180"
48122
48884
  ) })
48123
48885
  ]
48124
48886
  }
48125
48887
  ),
48126
- isOpen && /* @__PURE__ */ jsxs("div", { className: "absolute z-[10000] mt-2 w-72 bg-white rounded-lg shadow-lg border border-gray-200 left-0", children: [
48127
- /* @__PURE__ */ jsxs("div", { className: "px-4 py-3 border-b border-gray-200", children: [
48128
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
48129
- /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900", children: "Assign Lines" }),
48130
- /* @__PURE__ */ jsx(
48131
- "button",
48132
- {
48133
- onClick: handleCancel,
48134
- className: "text-gray-400 hover:text-gray-600",
48135
- children: /* @__PURE__ */ jsx(X, { className: "w-4 h-4" })
48136
- }
48137
- )
48138
- ] }),
48139
- /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 mt-1", children: "Select one or more lines to assign" })
48140
- ] }),
48141
- /* @__PURE__ */ jsx("div", { className: "max-h-64 overflow-y-auto", children: availableLines.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "px-4 py-8 text-center", children: [
48142
- /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 mb-2", children: "No lines available" }),
48143
- /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-400", children: "Check console (F12) for filtering details" })
48144
- ] }) : /* @__PURE__ */ jsx("div", { className: "py-2", children: availableLines.map((line) => /* @__PURE__ */ jsxs(
48145
- "label",
48146
- {
48147
- className: "flex items-center gap-3 px-4 py-2.5 hover:bg-gray-50 cursor-pointer transition-colors",
48148
- children: [
48149
- /* @__PURE__ */ jsx(
48150
- "input",
48151
- {
48152
- type: "checkbox",
48153
- checked: selectedIds.includes(line.id),
48154
- onChange: () => handleToggleLine(line.id),
48155
- className: "h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"
48156
- }
48157
- ),
48158
- /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-900", children: line.line_name }) }),
48159
- selectedIds.includes(line.id) && /* @__PURE__ */ jsx(Check, { className: "w-4 h-4 text-blue-600" })
48160
- ]
48161
- },
48162
- line.id
48163
- )) }) }),
48164
- /* @__PURE__ */ jsxs("div", { className: "px-4 py-3 border-t border-gray-200 bg-gray-50 flex items-center justify-between", children: [
48165
- /* @__PURE__ */ jsxs("span", { className: "text-xs text-gray-600", children: [
48166
- selectedIds.length,
48167
- " selected"
48168
- ] }),
48169
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
48170
- /* @__PURE__ */ jsx(
48171
- "button",
48172
- {
48173
- onClick: handleCancel,
48174
- className: "px-3 py-1.5 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors",
48175
- children: "Cancel"
48176
- }
48177
- ),
48178
- /* @__PURE__ */ jsx(
48179
- "button",
48180
- {
48181
- onClick: handleSave,
48182
- disabled: !hasChanges || isSaving,
48183
- className: "px-3 py-1.5 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors",
48184
- children: isSaving ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
48185
- /* @__PURE__ */ jsxs("svg", { className: "animate-spin h-3 w-3", viewBox: "0 0 24 24", children: [
48186
- /* @__PURE__ */ jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4", fill: "none" }),
48187
- /* @__PURE__ */ jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
48888
+ isOpen && createPortal(
48889
+ /* @__PURE__ */ jsxs(Fragment, { children: [
48890
+ /* @__PURE__ */ jsx("div", { className: "fixed inset-0 z-[9998]" }),
48891
+ /* @__PURE__ */ jsxs(
48892
+ "div",
48893
+ {
48894
+ ref: dropdownRef,
48895
+ className: "fixed z-[9999] bg-white rounded-lg shadow-2xl border border-gray-200",
48896
+ style: {
48897
+ top: `${position.top + 4}px`,
48898
+ left: `${position.left}px`,
48899
+ minWidth: `${Math.max(position.width, 300)}px`,
48900
+ maxWidth: "400px",
48901
+ maxHeight: "calc(100vh - 100px)"
48902
+ },
48903
+ children: [
48904
+ /* @__PURE__ */ jsx("div", { className: "px-4 py-3 border-b border-gray-200 bg-gray-50", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
48905
+ /* @__PURE__ */ jsxs("div", { children: [
48906
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900", children: "Assign Lines" }),
48907
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 mt-0.5", children: "Select one or more lines" })
48188
48908
  ] }),
48189
- "Saving..."
48190
- ] }) : "Save"
48191
- }
48192
- )
48193
- ] })
48194
- ] })
48195
- ] })
48909
+ /* @__PURE__ */ jsx(
48910
+ "button",
48911
+ {
48912
+ onClick: handleCancel,
48913
+ className: "text-gray-400 hover:text-gray-600 transition-colors",
48914
+ children: /* @__PURE__ */ jsx(X, { className: "w-4 h-4" })
48915
+ }
48916
+ )
48917
+ ] }) }),
48918
+ /* @__PURE__ */ jsx("div", { className: "max-h-80 overflow-y-auto", children: availableLines.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-4 py-8 text-center", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500", children: "No lines available" }) }) : /* @__PURE__ */ jsx("div", { className: "py-1", children: availableLines.map((line) => /* @__PURE__ */ jsxs(
48919
+ "label",
48920
+ {
48921
+ className: "flex items-center gap-3 px-4 py-2.5 hover:bg-gray-50 cursor-pointer transition-colors",
48922
+ children: [
48923
+ /* @__PURE__ */ jsx(
48924
+ "input",
48925
+ {
48926
+ type: "checkbox",
48927
+ checked: selectedIds.includes(line.id),
48928
+ onChange: () => handleToggleLine(line.id),
48929
+ className: "h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"
48930
+ }
48931
+ ),
48932
+ /* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-900 truncate", children: line.line_name }) }),
48933
+ selectedIds.includes(line.id) && /* @__PURE__ */ jsx(Check, { className: "w-4 h-4 text-blue-600 flex-shrink-0" })
48934
+ ]
48935
+ },
48936
+ line.id
48937
+ )) }) }),
48938
+ /* @__PURE__ */ jsxs("div", { className: "px-4 py-3 border-t border-gray-200 bg-gray-50 flex items-center justify-between", children: [
48939
+ /* @__PURE__ */ jsxs("span", { className: "text-xs text-gray-600", children: [
48940
+ selectedIds.length,
48941
+ " selected"
48942
+ ] }),
48943
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
48944
+ /* @__PURE__ */ jsx(
48945
+ "button",
48946
+ {
48947
+ onClick: handleCancel,
48948
+ className: "px-3 py-1.5 text-xs font-medium text-gray-700 bg-white border border-gray-300 rounded hover:bg-gray-50 transition-colors",
48949
+ children: "Cancel"
48950
+ }
48951
+ ),
48952
+ /* @__PURE__ */ jsx(
48953
+ "button",
48954
+ {
48955
+ onClick: handleSave,
48956
+ disabled: !hasChanges || isSaving,
48957
+ className: "px-3 py-1.5 text-xs font-medium text-white bg-blue-600 rounded hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors",
48958
+ children: isSaving ? "Saving..." : "Save"
48959
+ }
48960
+ )
48961
+ ] })
48962
+ ] })
48963
+ ]
48964
+ }
48965
+ )
48966
+ ] }),
48967
+ document.body
48968
+ )
48196
48969
  ] });
48197
48970
  };
48198
48971
  var FactoryAssignmentDropdown = ({
@@ -48205,13 +48978,36 @@ var FactoryAssignmentDropdown = ({
48205
48978
  const [isOpen, setIsOpen] = useState(false);
48206
48979
  const [selectedIds, setSelectedIds] = useState(currentFactoryIds);
48207
48980
  const [isSaving, setIsSaving] = useState(false);
48981
+ const [position, setPosition] = useState({ top: 0, left: 0, width: 0 });
48982
+ const buttonRef = useRef(null);
48208
48983
  const dropdownRef = useRef(null);
48209
48984
  useEffect(() => {
48210
48985
  setSelectedIds(currentFactoryIds);
48211
48986
  }, [currentFactoryIds]);
48987
+ useEffect(() => {
48988
+ const updatePosition = () => {
48989
+ if (isOpen && buttonRef.current) {
48990
+ const rect = buttonRef.current.getBoundingClientRect();
48991
+ setPosition({
48992
+ top: rect.bottom,
48993
+ left: rect.left,
48994
+ width: rect.width
48995
+ });
48996
+ }
48997
+ };
48998
+ if (isOpen) {
48999
+ updatePosition();
49000
+ window.addEventListener("scroll", updatePosition, true);
49001
+ window.addEventListener("resize", updatePosition);
49002
+ }
49003
+ return () => {
49004
+ window.removeEventListener("scroll", updatePosition, true);
49005
+ window.removeEventListener("resize", updatePosition);
49006
+ };
49007
+ }, [isOpen]);
48212
49008
  useEffect(() => {
48213
49009
  const handleClickOutside = (event) => {
48214
- if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
49010
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target) && buttonRef.current && !buttonRef.current.contains(event.target)) {
48215
49011
  setIsOpen(false);
48216
49012
  setSelectedIds(currentFactoryIds);
48217
49013
  }
@@ -48277,91 +49073,106 @@ var FactoryAssignmentDropdown = ({
48277
49073
  if (!canEdit) {
48278
49074
  return /* @__PURE__ */ jsx("div", { className: "text-sm", children: getDisplayText() });
48279
49075
  }
48280
- return /* @__PURE__ */ jsxs("div", { className: "relative", ref: dropdownRef, children: [
49076
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
48281
49077
  /* @__PURE__ */ jsxs(
48282
49078
  "button",
48283
49079
  {
49080
+ ref: buttonRef,
48284
49081
  onClick: () => setIsOpen(!isOpen),
48285
49082
  className: cn(
48286
- "flex items-center gap-2 px-3 py-1.5 text-sm border rounded-lg transition-colors",
49083
+ "flex items-center gap-2 px-3 py-2 text-sm border rounded-lg transition-colors min-w-[200px]",
48287
49084
  currentFactoryIds.length === 0 ? "border-blue-300 bg-blue-50 hover:bg-blue-100" : "border-gray-300 bg-white hover:bg-gray-50"
48288
49085
  ),
48289
49086
  children: [
48290
49087
  /* @__PURE__ */ jsx("span", { className: "flex-1 text-left", children: getDisplayText() }),
48291
49088
  /* @__PURE__ */ jsx(ChevronDown, { className: cn(
48292
- "w-4 h-4 text-gray-400 transition-transform",
49089
+ "w-4 h-4 text-gray-400 transition-transform flex-shrink-0",
48293
49090
  isOpen && "rotate-180"
48294
49091
  ) })
48295
49092
  ]
48296
49093
  }
48297
49094
  ),
48298
- isOpen && /* @__PURE__ */ jsxs("div", { className: "absolute z-[10000] mt-2 w-72 bg-white rounded-lg shadow-lg border border-gray-200 left-0", children: [
48299
- /* @__PURE__ */ jsxs("div", { className: "px-4 py-3 border-b border-gray-200", children: [
48300
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
48301
- /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900", children: "Assign Factories" }),
48302
- /* @__PURE__ */ jsx(
48303
- "button",
48304
- {
48305
- onClick: handleCancel,
48306
- className: "text-gray-400 hover:text-gray-600",
48307
- children: /* @__PURE__ */ jsx(X, { className: "w-4 h-4" })
48308
- }
48309
- )
48310
- ] }),
48311
- /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 mt-1", children: "Select one or more factories to assign" })
48312
- ] }),
48313
- /* @__PURE__ */ jsx("div", { className: "max-h-64 overflow-y-auto", children: availableFactories.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-4 py-8 text-center text-sm text-gray-500", children: "No factories available" }) : /* @__PURE__ */ jsx("div", { className: "py-2", children: availableFactories.map((factory) => /* @__PURE__ */ jsxs(
48314
- "label",
48315
- {
48316
- className: "flex items-center gap-3 px-4 py-2.5 hover:bg-gray-50 cursor-pointer transition-colors",
48317
- children: [
48318
- /* @__PURE__ */ jsx(
48319
- "input",
48320
- {
48321
- type: "checkbox",
48322
- checked: selectedIds.includes(factory.id),
48323
- onChange: () => handleToggleFactory(factory.id),
48324
- className: "h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"
48325
- }
48326
- ),
48327
- /* @__PURE__ */ jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-900", children: factory.factory_name }) }),
48328
- selectedIds.includes(factory.id) && /* @__PURE__ */ jsx(Check, { className: "w-4 h-4 text-blue-600" })
48329
- ]
48330
- },
48331
- factory.id
48332
- )) }) }),
48333
- /* @__PURE__ */ jsxs("div", { className: "px-4 py-3 border-t border-gray-200 bg-gray-50 flex items-center justify-between", children: [
48334
- /* @__PURE__ */ jsxs("span", { className: "text-xs text-gray-600", children: [
48335
- selectedIds.length,
48336
- " selected"
48337
- ] }),
48338
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
48339
- /* @__PURE__ */ jsx(
48340
- "button",
48341
- {
48342
- onClick: handleCancel,
48343
- className: "px-3 py-1.5 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors",
48344
- children: "Cancel"
48345
- }
48346
- ),
48347
- /* @__PURE__ */ jsx(
48348
- "button",
48349
- {
48350
- onClick: handleSave,
48351
- disabled: !hasChanges || isSaving,
48352
- className: "px-3 py-1.5 text-sm font-medium text-white bg-blue-600 rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors",
48353
- children: isSaving ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
48354
- /* @__PURE__ */ jsxs("svg", { className: "animate-spin h-3 w-3", viewBox: "0 0 24 24", children: [
48355
- /* @__PURE__ */ jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4", fill: "none" }),
48356
- /* @__PURE__ */ jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
49095
+ isOpen && createPortal(
49096
+ /* @__PURE__ */ jsxs(Fragment, { children: [
49097
+ /* @__PURE__ */ jsx("div", { className: "fixed inset-0 z-[9998]" }),
49098
+ /* @__PURE__ */ jsxs(
49099
+ "div",
49100
+ {
49101
+ ref: dropdownRef,
49102
+ className: "fixed z-[9999] bg-white rounded-lg shadow-2xl border border-gray-200",
49103
+ style: {
49104
+ top: `${position.top + 4}px`,
49105
+ left: `${position.left}px`,
49106
+ minWidth: `${Math.max(position.width, 300)}px`,
49107
+ maxWidth: "400px",
49108
+ maxHeight: "calc(100vh - 100px)"
49109
+ },
49110
+ children: [
49111
+ /* @__PURE__ */ jsx("div", { className: "px-4 py-3 border-b border-gray-200 bg-gray-50", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
49112
+ /* @__PURE__ */ jsxs("div", { children: [
49113
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900", children: "Assign Factories" }),
49114
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 mt-0.5", children: "Select one or more factories" })
48357
49115
  ] }),
48358
- "Saving..."
48359
- ] }) : "Save"
48360
- }
48361
- )
48362
- ] })
48363
- ] })
48364
- ] })
49116
+ /* @__PURE__ */ jsx(
49117
+ "button",
49118
+ {
49119
+ onClick: handleCancel,
49120
+ className: "text-gray-400 hover:text-gray-600 transition-colors",
49121
+ children: /* @__PURE__ */ jsx(X, { className: "w-4 h-4" })
49122
+ }
49123
+ )
49124
+ ] }) }),
49125
+ /* @__PURE__ */ jsx("div", { className: "max-h-80 overflow-y-auto", children: availableFactories.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-4 py-8 text-center", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500", children: "No factories available" }) }) : /* @__PURE__ */ jsx("div", { className: "py-1", children: availableFactories.map((factory) => /* @__PURE__ */ jsxs(
49126
+ "label",
49127
+ {
49128
+ className: "flex items-center gap-3 px-4 py-2.5 hover:bg-gray-50 cursor-pointer transition-colors",
49129
+ children: [
49130
+ /* @__PURE__ */ jsx(
49131
+ "input",
49132
+ {
49133
+ type: "checkbox",
49134
+ checked: selectedIds.includes(factory.id),
49135
+ onChange: () => handleToggleFactory(factory.id),
49136
+ className: "h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"
49137
+ }
49138
+ ),
49139
+ /* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-gray-900 truncate", children: factory.factory_name }) }),
49140
+ selectedIds.includes(factory.id) && /* @__PURE__ */ jsx(Check, { className: "w-4 h-4 text-blue-600 flex-shrink-0" })
49141
+ ]
49142
+ },
49143
+ factory.id
49144
+ )) }) }),
49145
+ /* @__PURE__ */ jsxs("div", { className: "px-4 py-3 border-t border-gray-200 bg-gray-50 flex items-center justify-between", children: [
49146
+ /* @__PURE__ */ jsxs("span", { className: "text-xs text-gray-600", children: [
49147
+ selectedIds.length,
49148
+ " selected"
49149
+ ] }),
49150
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
49151
+ /* @__PURE__ */ jsx(
49152
+ "button",
49153
+ {
49154
+ onClick: handleCancel,
49155
+ className: "px-3 py-1.5 text-xs font-medium text-gray-700 bg-white border border-gray-300 rounded hover:bg-gray-50 transition-colors",
49156
+ children: "Cancel"
49157
+ }
49158
+ ),
49159
+ /* @__PURE__ */ jsx(
49160
+ "button",
49161
+ {
49162
+ onClick: handleSave,
49163
+ disabled: !hasChanges || isSaving,
49164
+ className: "px-3 py-1.5 text-xs font-medium text-white bg-blue-600 rounded hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors",
49165
+ children: isSaving ? "Saving..." : "Save"
49166
+ }
49167
+ )
49168
+ ] })
49169
+ ] })
49170
+ ]
49171
+ }
49172
+ )
49173
+ ] }),
49174
+ document.body
49175
+ )
48365
49176
  ] });
48366
49177
  };
48367
49178
  var UserManagementTable = ({
@@ -48513,7 +49324,7 @@ var UserManagementTable = ({
48513
49324
  }
48514
49325
  )
48515
49326
  ] }),
48516
- /* @__PURE__ */ jsx("div", { className: "bg-white rounded-lg border border-gray-200 overflow-x-auto", children: /* @__PURE__ */ jsx("div", { className: "overflow-visible relative", children: /* @__PURE__ */ jsxs("table", { className: "min-w-full divide-y divide-gray-200", children: [
49327
+ /* @__PURE__ */ jsx("div", { className: "bg-white rounded-lg border border-gray-200", children: /* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs("table", { className: "min-w-full divide-y divide-gray-200", children: [
48517
49328
  /* @__PURE__ */ jsx("thead", { className: "bg-gray-50", children: /* @__PURE__ */ jsxs("tr", { children: [
48518
49329
  /* @__PURE__ */ jsx(
48519
49330
  "th",
@@ -48582,7 +49393,7 @@ var UserManagementTable = ({
48582
49393
  ] })
48583
49394
  ] }) }),
48584
49395
  /* @__PURE__ */ jsx("td", { className: "px-6 py-4 whitespace-nowrap", children: /* @__PURE__ */ jsx(RoleBadge, { role: user.role_level, size: "sm" }) }),
48585
- /* @__PURE__ */ jsx("td", { className: "px-6 py-4 relative overflow-visible z-10", children: user.role_level === "supervisor" ? /* @__PURE__ */ jsx(
49396
+ /* @__PURE__ */ jsx("td", { className: "px-6 py-4", children: user.role_level === "supervisor" ? /* @__PURE__ */ jsx(
48586
49397
  LineAssignmentDropdown,
48587
49398
  {
48588
49399
  userId: user.user_id,
@@ -48624,7 +49435,7 @@ var UserManagementTable = ({
48624
49435
  }
48625
49436
  ) : /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-900", children: formatAssignments(user) }) }),
48626
49437
  /* @__PURE__ */ jsx("td", { className: "px-6 py-4 whitespace-nowrap", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500", children: formatDate(user.created_at) }) }),
48627
- /* @__PURE__ */ jsx("td", { className: "px-6 py-4 whitespace-nowrap text-right relative overflow-visible", children: hasActions && /* @__PURE__ */ jsxs("div", { className: "relative overflow-visible", children: [
49438
+ /* @__PURE__ */ jsx("td", { className: "px-6 py-4 whitespace-nowrap text-right", children: hasActions && /* @__PURE__ */ jsxs("div", { className: "relative", children: [
48628
49439
  /* @__PURE__ */ jsx(
48629
49440
  "button",
48630
49441
  {
@@ -50986,4 +51797,4 @@ function shuffleArray(array) {
50986
51797
  return shuffled;
50987
51798
  }
50988
51799
 
50989
- export { ACTION_NAMES, AIAgentView_default as AIAgentView, AcceptInvite, AcceptInviteView_default as AcceptInviteView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthService, AuthenticatedBottleneckClipsView, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedTicketsView, AuthenticatedWorkspaceHealthView, AxelNotificationPopup, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, BottleneckClipsModal, BottleneckClipsView_default as BottleneckClipsView, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, ClipFilterProvider, CompactWorkspaceHealthCard, CongratulationsOverlay, CroppedVideoPlayer, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_MAP_VIEW_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, DetailedHealthStatus, DiagnosisVideoModal, EmptyStateMessage, EncouragementOverlay, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, ISTTimer_default as ISTTimer, InlineEditableText, InteractiveOnboardingTour, InvitationService, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend6 as Legend, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LinesService, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, MainLayout, MapGridView, MetricCard_default as MetricCard, MinimalOnboardingPopup, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, RegistryProvider, S3ClipsSupabaseService as S3ClipsService, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SignupWithInvitation, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, TeamManagementView_default as TeamManagementView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TicketsView_default as TicketsView, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UserManagementService, UserService, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, apiUtils, authCoreService, authOTPService, authRateLimitService, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearWorkspaceDisplayNamesCache, cn, createInvitationService, createLinesService, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserManagementService, createUserService, dashboardService, deleteThread, forceRefreshWorkspaceDisplayNames, formatDateInZone, formatDateTimeInZone, formatISTDate, formatIdleTime, formatTimeInZone, fromUrlFriendlyName, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAnonClient, getBrowserName, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentTimeInZone, getDashboardHeaderTimeInZone, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getOperationalDate, getS3SignedUrl, getS3VideoSrc, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUserThreads, getUserThreadsPaginated, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, identifyCoreUser, initializeCoreMixpanel, isLegacyConfiguration, isPrefetchError, isSafari, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, optifyeAgentClient, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, updateThreadTitle, useAccessControl, useActiveBreaks, useActiveLineId, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useAxelNotifications, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useDynamicShiftConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHasLineAccess, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineShiftConfig, useLineSupervisor, useLineWorkspaceMetrics, useMessages, useMetrics, useNavigation, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useShiftConfig, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useTargets, useTeamManagementPermissions, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useUserLineAccess, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealthById, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, userService, videoPrefetchManager, videoPreloader, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };
51800
+ export { ACTION_NAMES, AIAgentView_default as AIAgentView, AcceptInvite, AcceptInviteView_default as AcceptInviteView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthService, AuthenticatedBottleneckClipsView, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedTicketsView, AuthenticatedWorkspaceHealthView, AxelNotificationPopup, AxelOrb, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, BottleneckClipsModal, BottleneckClipsView_default as BottleneckClipsView, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, ClipFilterProvider, CompactWorkspaceHealthCard, CongratulationsOverlay, CroppedVideoPlayer, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_MAP_VIEW_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, DetailedHealthStatus, DiagnosisVideoModal, EmptyStateMessage, EncouragementOverlay, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, ISTTimer_default as ISTTimer, InlineEditableText, InteractiveOnboardingTour, InvitationService, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend6 as Legend, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LinesService, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, Logo, MainLayout, MapGridView, MetricCard_default as MetricCard, MinimalOnboardingPopup, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PlayPauseIndicator, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, RegistryProvider, S3ClipsSupabaseService as S3ClipsService, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SignupWithInvitation, SilentErrorBoundary, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, TeamManagementView_default as TeamManagementView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TicketsView_default as TicketsView, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UserManagementService, UserService, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, apiUtils, authCoreService, authOTPService, authRateLimitService, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearWorkspaceDisplayNamesCache, cn, createInvitationService, createLinesService, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserManagementService, createUserService, dashboardService, deleteThread, forceRefreshWorkspaceDisplayNames, formatDateInZone, formatDateTimeInZone, formatISTDate, formatIdleTime, formatRelativeTime, formatTimeInZone, fromUrlFriendlyName, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAnonClient, getBrowserName, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentTimeInZone, getDashboardHeaderTimeInZone, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getNextUpdateInterval, getOperationalDate, getS3SignedUrl, getS3VideoSrc, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUserThreads, getUserThreadsPaginated, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, identifyCoreUser, initializeCoreMixpanel, isLegacyConfiguration, isPrefetchError, isSafari, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, optifyeAgentClient, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, updateThreadTitle, useAccessControl, useActiveBreaks, useActiveLineId, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useAxelNotifications, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useDynamicShiftConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHasLineAccess, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineShiftConfig, useLineSupervisor, useLineWorkspaceMetrics, useMessages, useMetrics, useNavigation, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useSessionKeepAlive, useShiftConfig, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useTargets, useTeamManagementPermissions, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useUserLineAccess, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealthById, useWorkspaceHealthStatus, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, userService, videoPrefetchManager, videoPreloader, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };