@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.css +25 -27
- package/dist/index.d.mts +175 -12
- package/dist/index.d.ts +175 -12
- package/dist/index.js +1660 -841
- package/dist/index.mjs +1654 -843
- package/package.json +1 -1
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
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
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
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
"
|
|
2812
|
-
|
|
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
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
21672
|
+
Logo,
|
|
21278
21673
|
{
|
|
21279
|
-
|
|
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
|
-
|
|
21296
|
-
|
|
21297
|
-
|
|
21298
|
-
|
|
21299
|
-
|
|
21300
|
-
|
|
21301
|
-
|
|
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:", {
|
|
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("
|
|
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
|
-
|
|
21351
|
-
|
|
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
|
|
21354
|
-
|
|
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 =
|
|
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__ */
|
|
29226
|
-
|
|
29227
|
-
|
|
29228
|
-
|
|
29229
|
-
e
|
|
29230
|
-
|
|
29231
|
-
|
|
29232
|
-
|
|
29233
|
-
|
|
29234
|
-
|
|
29235
|
-
|
|
29236
|
-
|
|
29237
|
-
|
|
29238
|
-
|
|
29239
|
-
|
|
29240
|
-
|
|
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
|
|
37871
|
-
|
|
37872
|
-
|
|
37873
|
-
|
|
37874
|
-
|
|
37875
|
-
|
|
37876
|
-
|
|
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
|
|
37885
|
-
|
|
37886
|
-
|
|
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 <
|
|
38071
|
-
setTypedText(
|
|
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",
|
|
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 <
|
|
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 =
|
|
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__ */
|
|
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("
|
|
46426
|
-
/* @__PURE__ */
|
|
46427
|
-
/* @__PURE__ */ jsx(
|
|
46428
|
-
|
|
46429
|
-
|
|
46430
|
-
|
|
46431
|
-
|
|
46432
|
-
|
|
46433
|
-
|
|
46434
|
-
|
|
46435
|
-
|
|
46436
|
-
|
|
46437
|
-
/* @__PURE__ */ jsxs("div", { className: "flex
|
|
46438
|
-
/* @__PURE__ */
|
|
46439
|
-
|
|
46440
|
-
workspaceHealth && /* @__PURE__ */ jsx("
|
|
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
|
|
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
|
-
|
|
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(
|
|
46491
|
-
|
|
46492
|
-
|
|
46493
|
-
|
|
46494
|
-
|
|
46495
|
-
|
|
46496
|
-
|
|
46497
|
-
|
|
46498
|
-
|
|
46499
|
-
|
|
46500
|
-
|
|
46501
|
-
|
|
46502
|
-
|
|
46503
|
-
|
|
46504
|
-
|
|
46505
|
-
|
|
46506
|
-
|
|
46507
|
-
|
|
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__ */
|
|
46510
|
-
|
|
46511
|
-
|
|
46512
|
-
|
|
46513
|
-
|
|
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
|
-
|
|
46519
|
-
|
|
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: `
|
|
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: `
|
|
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: `
|
|
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__ */
|
|
46546
|
-
|
|
46547
|
-
|
|
46548
|
-
|
|
46549
|
-
|
|
46550
|
-
|
|
46551
|
-
|
|
46552
|
-
|
|
46553
|
-
|
|
46554
|
-
|
|
46555
|
-
|
|
46556
|
-
|
|
46557
|
-
|
|
46558
|
-
|
|
46559
|
-
|
|
46560
|
-
|
|
46561
|
-
|
|
46562
|
-
|
|
46563
|
-
|
|
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: () =>
|
|
46567
|
-
className: `
|
|
46568
|
-
|
|
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
|
-
|
|
46573
|
-
|
|
46574
|
-
WorkspaceMonthlyPdfGenerator,
|
|
47419
|
+
/* @__PURE__ */ jsx(
|
|
47420
|
+
"div",
|
|
46575
47421
|
{
|
|
46576
|
-
|
|
46577
|
-
|
|
46578
|
-
|
|
46579
|
-
|
|
46580
|
-
|
|
46581
|
-
|
|
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
|
-
|
|
46588
|
-
|
|
46589
|
-
|
|
46590
|
-
|
|
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:
|
|
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
|
-
|
|
46636
|
-
|
|
46637
|
-
|
|
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-[
|
|
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: "
|
|
46708
|
-
/* @__PURE__ */ jsxs(
|
|
46709
|
-
|
|
46710
|
-
|
|
46711
|
-
/* @__PURE__ */ jsxs("
|
|
46712
|
-
|
|
46713
|
-
|
|
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
|
-
|
|
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
|
-
|
|
46794
|
-
/* @__PURE__ */
|
|
46795
|
-
|
|
46796
|
-
/* @__PURE__ */ jsx(
|
|
46797
|
-
|
|
46798
|
-
|
|
46799
|
-
|
|
46800
|
-
|
|
46801
|
-
|
|
46802
|
-
|
|
46803
|
-
|
|
46804
|
-
|
|
46805
|
-
|
|
46806
|
-
|
|
46807
|
-
|
|
46808
|
-
|
|
46809
|
-
|
|
46810
|
-
|
|
46811
|
-
|
|
46812
|
-
|
|
46813
|
-
|
|
46814
|
-
|
|
46815
|
-
|
|
46816
|
-
|
|
46817
|
-
|
|
46818
|
-
|
|
46819
|
-
|
|
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
|
-
|
|
46880
|
-
|
|
46881
|
-
|
|
46882
|
-
|
|
46883
|
-
className: "h-[calc(100vh-10rem)]"
|
|
47605
|
+
selectedMonth,
|
|
47606
|
+
selectedYear,
|
|
47607
|
+
onDataLoaded: handleMonthlyDataLoaded,
|
|
47608
|
+
onLoadingChange: setMonthlyDataLoading
|
|
46884
47609
|
}
|
|
46885
|
-
)
|
|
46886
|
-
|
|
46887
|
-
|
|
46888
|
-
|
|
46889
|
-
|
|
46890
|
-
|
|
46891
|
-
|
|
46892
|
-
|
|
46893
|
-
|
|
46894
|
-
|
|
46895
|
-
|
|
46896
|
-
|
|
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
|
-
|
|
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
|
-
|
|
48034
|
-
|
|
48035
|
-
|
|
48036
|
-
|
|
48037
|
-
|
|
48038
|
-
|
|
48039
|
-
|
|
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(
|
|
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-
|
|
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 &&
|
|
48127
|
-
/* @__PURE__ */ jsxs(
|
|
48128
|
-
/* @__PURE__ */
|
|
48129
|
-
|
|
48130
|
-
|
|
48131
|
-
|
|
48132
|
-
|
|
48133
|
-
|
|
48134
|
-
|
|
48135
|
-
|
|
48136
|
-
|
|
48137
|
-
|
|
48138
|
-
|
|
48139
|
-
|
|
48140
|
-
|
|
48141
|
-
|
|
48142
|
-
|
|
48143
|
-
|
|
48144
|
-
|
|
48145
|
-
|
|
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
|
-
|
|
48190
|
-
|
|
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(
|
|
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-
|
|
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 &&
|
|
48299
|
-
/* @__PURE__ */ jsxs(
|
|
48300
|
-
/* @__PURE__ */
|
|
48301
|
-
|
|
48302
|
-
|
|
48303
|
-
|
|
48304
|
-
|
|
48305
|
-
|
|
48306
|
-
|
|
48307
|
-
|
|
48308
|
-
|
|
48309
|
-
|
|
48310
|
-
|
|
48311
|
-
|
|
48312
|
-
|
|
48313
|
-
|
|
48314
|
-
|
|
48315
|
-
|
|
48316
|
-
|
|
48317
|
-
|
|
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
|
-
|
|
48359
|
-
|
|
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
|
|
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
|
|
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
|
|
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 };
|