@optifye/dashboard-core 6.6.10 → 6.6.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -13,7 +13,7 @@ import { noop, warning, invariant, progress, secondsToMilliseconds, milliseconds
13
13
  import { getValueTransition, hover, press, isPrimaryPointer, GroupPlaybackControls, setDragLock, supportsLinearEasing, attachTimeline, isGenerator, calcGeneratorDuration, isWaapiSupportedEasing, mapEasingToNativeEasing, maxGeneratorDuration, generateLinearEasing, isBezierDefinition } from 'motion-dom';
14
14
  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';
15
15
  import { Slot } from '@radix-ui/react-slot';
16
- import { Camera, ChevronDown, ChevronUp, Check, ShieldCheck, Star, Award, ArrowLeft, X, Coffee, Plus, Clock, Calendar, Save, Minus, ArrowDown, ArrowUp, Settings2, CheckCircle2, Search, Loader2, AlertCircle, Edit2, CheckCircle, AlertTriangle, Info, Share2, Trophy, Target, Download, User, RefreshCw, Sliders, Sparkles, TrendingDown, TrendingUp, FolderOpen, Folder, HelpCircle, Play, Activity, Layers, Filter, XCircle, ChevronLeft, ChevronRight, Sun, Moon, MousePointer, ArrowRight, MessageSquare, Trash2, Menu, Send, Copy, UserCheck, LogOut, Package, Building2, Settings, LifeBuoy, EyeOff, Eye, Zap, UserCircle } from 'lucide-react';
16
+ import { Camera, ChevronDown, ChevronUp, Check, ShieldCheck, Star, Award, ArrowLeft, X, Coffee, Plus, Clock, Calendar, Save, Minus, ArrowDown, ArrowUp, Sparkles, AlertCircle, TrendingUp, Settings2, CheckCircle2, Search, Loader2, Edit2, CheckCircle, AlertTriangle, Info, Share2, Trophy, Target, Download, User, RefreshCw, Sliders, TrendingDown, FolderOpen, Folder, HelpCircle, Play, Activity, Layers, Filter, XCircle, ChevronLeft, ChevronRight, Sun, Moon, MousePointer, ArrowRight, MessageSquare, Trash2, Menu, Send, Copy, UserCheck, LogOut, Package, Building2, Settings, LifeBuoy, EyeOff, Eye, Zap, UserCircle } from 'lucide-react';
17
17
  import { DayPicker, useNavigation as useNavigation$1 } from 'react-day-picker';
18
18
  import { XMarkIcon, ArrowRightIcon, HomeIcon, TrophyIcon, ChartBarIcon, AdjustmentsHorizontalIcon, ClockIcon, UsersIcon, CubeIcon, SparklesIcon, QuestionMarkCircleIcon, HeartIcon, UserCircleIcon, ExclamationCircleIcon, EnvelopeIcon, DocumentTextIcon, ChevronUpIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, Bars3Icon, CheckCircleIcon, ChatBubbleLeftRightIcon, ArrowLeftIcon, XCircleIcon, InformationCircleIcon } from '@heroicons/react/24/outline';
19
19
  import { CheckIcon } from '@heroicons/react/24/solid';
@@ -4014,12 +4014,8 @@ var S3ClipsSupabaseService = class {
4014
4014
  id: clip.clip_id,
4015
4015
  src: clip.playlist,
4016
4016
  // Raw playlist content
4017
- timestamp: new Date(clip.date).toLocaleTimeString("en-US", {
4018
- hour12: false,
4019
- hour: "2-digit",
4020
- minute: "2-digit",
4021
- second: "2-digit"
4022
- }),
4017
+ timestamp: clip.timestamp,
4018
+ // Use pre-formatted timestamp from API (already in 12-hour format with seconds)
4023
4019
  severity: this.getSeverityFromClipType(clip.clip_type_name),
4024
4020
  description: this.getDescriptionFromClipType(clip.clip_type_name),
4025
4021
  type: clip.clip_type_name,
@@ -6515,6 +6511,10 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId }) => {
6515
6511
  const lineIdRef = useRef(lineId);
6516
6512
  const isFetchingRef = useRef(false);
6517
6513
  const updateQueueRef = useRef(false);
6514
+ const onLineMetricsUpdateRef = useRef(onLineMetricsUpdate);
6515
+ useEffect(() => {
6516
+ onLineMetricsUpdateRef.current = onLineMetricsUpdate;
6517
+ }, [onLineMetricsUpdate]);
6518
6518
  const companySpecificMetricsTable = useMemo(
6519
6519
  () => getCompanyMetricsTableName(entityConfig.companyId, "performance_metrics"),
6520
6520
  [entityConfig.companyId]
@@ -6630,13 +6630,17 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId }) => {
6630
6630
  defaultTimezone,
6631
6631
  shiftConfig
6632
6632
  ]);
6633
+ const fetchAllMetricsRef = useRef(fetchAllMetrics);
6634
+ useEffect(() => {
6635
+ fetchAllMetricsRef.current = fetchAllMetrics;
6636
+ }, [fetchAllMetrics]);
6633
6637
  const queueUpdate = useCallback(() => {
6634
6638
  if (updateQueueRef.current || !supabase) {
6635
6639
  return;
6636
6640
  }
6637
6641
  updateQueueRef.current = true;
6638
- fetchAllMetrics();
6639
- }, [fetchAllMetrics, supabase]);
6642
+ fetchAllMetricsRef.current();
6643
+ }, [supabase]);
6640
6644
  useEffect(() => {
6641
6645
  if (lineId && supabase) {
6642
6646
  fetchAllMetrics();
@@ -6651,11 +6655,11 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId }) => {
6651
6655
  const operationalDateForSubscription = getOperationalDate(defaultTimezone);
6652
6656
  const targetLineIds = currentLineIdToUse === (entityConfig.factoryViewId || "factory") ? getConfiguredLineIds(entityConfig) : [currentLineIdToUse];
6653
6657
  if (targetLineIds.length === 0) return;
6654
- const wsMetricsFilter = `date=eq.${operationalDateForSubscription}&shift_id=eq.${currentShiftDetails.shiftId}&line_id=in.(${targetLineIds.join(",")})`;
6655
- const lineMetricsFilter = `date=eq.${operationalDateForSubscription}&shift_id=eq.${currentShiftDetails.shiftId}&line_id=in.(${targetLineIds.join(",")})`;
6658
+ const wsMetricsFilter = `line_id=in.(${targetLineIds.map((id3) => `"${id3}"`).join(",")})`;
6659
+ const lineMetricsFilter = `line_id=in.(${targetLineIds.map((id3) => `"${id3}"`).join(",")})`;
6656
6660
  const channels = [];
6657
6661
  const createSubscription = (table, filter2, channelNameBase, callback) => {
6658
- const channelName = `${channelNameBase}-${currentLineIdToUse}-${operationalDateForSubscription}-${currentShiftDetails.shiftId}`.replace(/[^a-zA-Z0-9_-]/g, "");
6662
+ const channelName = `${channelNameBase}-${Date.now()}`.replace(/[^a-zA-Z0-9_-]/g, "");
6659
6663
  const channel = supabase.channel(channelName).on(
6660
6664
  "postgres_changes",
6661
6665
  { event: "*", schema, table, filter: filter2 },
@@ -6665,40 +6669,29 @@ var useDashboardMetrics = ({ onLineMetricsUpdate, lineId }) => {
6665
6669
  callback();
6666
6670
  }
6667
6671
  }
6668
- ).subscribe((status, err) => {
6669
- if (status === REALTIME_SUBSCRIBE_STATES.CHANNEL_ERROR && err) {
6670
- console.error(`[useDashboardMetrics] Subscription error for ${table} on ${currentLineIdToUse}:`, err.message);
6671
- } else if (status === REALTIME_SUBSCRIBE_STATES.TIMED_OUT) {
6672
- console.warn(`[useDashboardMetrics] Subscription timeout for ${table} on ${currentLineIdToUse}.`);
6673
- }
6674
- });
6672
+ ).subscribe();
6675
6673
  channels.push(channel);
6676
6674
  };
6677
6675
  createSubscription(companySpecificMetricsTable, wsMetricsFilter, "dashboard-ws-metrics", queueUpdate);
6678
6676
  createSubscription(configuredLineMetricsTable, lineMetricsFilter, "dashboard-line-metrics", () => {
6679
6677
  queueUpdate();
6680
- onLineMetricsUpdate?.();
6678
+ onLineMetricsUpdateRef.current?.();
6681
6679
  });
6682
6680
  return () => {
6683
6681
  channels.forEach((channel) => {
6684
- supabase?.removeChannel(channel).catch((err) => console.error("[useDashboardMetrics] Error removing channel:", err.message));
6682
+ supabase?.removeChannel(channel);
6685
6683
  });
6686
6684
  };
6687
6685
  }, [
6688
6686
  supabase,
6689
- // fetchAllMetrics, // fetchAllMetrics is now a dependency of queueUpdate
6690
6687
  queueUpdate,
6691
- // Section 6: Add queueUpdate as dependency
6692
6688
  companySpecificMetricsTable,
6693
6689
  configuredLineMetricsTable,
6694
6690
  schema,
6695
- entityConfig,
6696
- // For companyId, factoryViewId, default/secondaryLineId
6691
+ entityConfig?.companyId,
6692
+ entityConfig?.factoryViewId,
6697
6693
  defaultTimezone,
6698
- shiftConfig,
6699
- onLineMetricsUpdate,
6700
6694
  lineId
6701
- // Add lineId from props to re-run effect if it changes, managed by lineIdRef inside effect
6702
6695
  ]);
6703
6696
  return {
6704
6697
  workspaceMetrics: metrics2?.workspaceMetrics || [],
@@ -6859,6 +6852,7 @@ var useRealtimeLineMetrics = ({
6859
6852
  const updateQueueRef = useRef(false);
6860
6853
  const isFetchingRef = useRef(false);
6861
6854
  const channelsRef = useRef([]);
6855
+ const fetchTimeoutRef = useRef(null);
6862
6856
  const currentShift = useMemo(() => getCurrentShift(dateTimeConfig.defaultTimezone || "Asia/Kolkata", shiftConfig), [dateTimeConfig.defaultTimezone, shiftConfig]);
6863
6857
  const shiftId = useMemo(
6864
6858
  () => urlShiftId !== void 0 ? urlShiftId : currentShift.shiftId,
@@ -7068,9 +7062,17 @@ var useRealtimeLineMetrics = ({
7068
7062
  }
7069
7063
  }, [supabase, date, shiftId, urlShiftId, onMetricsUpdate, entityConfig, dateTimeConfig.defaultTimezone]);
7070
7064
  const queueUpdate = useCallback(() => {
7071
- if (updateQueueRef.current) return;
7072
- updateQueueRef.current = true;
7073
- fetchData();
7065
+ console.log("[useRealtimeLineMetrics] Update queued, debouncing...");
7066
+ if (fetchTimeoutRef.current) {
7067
+ clearTimeout(fetchTimeoutRef.current);
7068
+ }
7069
+ fetchTimeoutRef.current = setTimeout(() => {
7070
+ if (updateQueueRef.current) return;
7071
+ updateQueueRef.current = true;
7072
+ console.log("[useRealtimeLineMetrics] Debounced fetch triggered");
7073
+ fetchData();
7074
+ fetchTimeoutRef.current = null;
7075
+ }, 500);
7074
7076
  }, [fetchData]);
7075
7077
  const setupSubscriptions = useCallback(() => {
7076
7078
  if (channelsRef.current.length > 0) {
@@ -7148,6 +7150,10 @@ var useRealtimeLineMetrics = ({
7148
7150
  }
7149
7151
  setupSubscriptions();
7150
7152
  return () => {
7153
+ if (fetchTimeoutRef.current) {
7154
+ clearTimeout(fetchTimeoutRef.current);
7155
+ fetchTimeoutRef.current = null;
7156
+ }
7151
7157
  if (channelsRef.current.length > 0) {
7152
7158
  channelsRef.current.forEach((channel) => {
7153
7159
  if (process.env.NODE_ENV === "development") {
@@ -8094,13 +8100,10 @@ var getWorkspaceDisplayName = (workspaceId, lineId) => {
8094
8100
  }
8095
8101
  }
8096
8102
  if (displayName) {
8097
- console.log(`getWorkspaceDisplayName(${workspaceId}, lineId: ${lineId}) -> ${displayName} (from Supabase)`);
8098
8103
  return displayName;
8099
8104
  } else {
8100
8105
  if (isInitialized) {
8101
- console.log(`getWorkspaceDisplayName(${workspaceId}, lineId: ${lineId}) -> ${workspaceId} (not found in Supabase data)`);
8102
- } else {
8103
- console.log(`getWorkspaceDisplayName(${workspaceId}, lineId: ${lineId}) -> ${workspaceId} (Supabase not initialized yet)`);
8106
+ console.warn(`getWorkspaceDisplayName(${workspaceId}, lineId: ${lineId}) -> ${workspaceId} (not found in Supabase data)`);
8104
8107
  }
8105
8108
  return workspaceId;
8106
8109
  }
@@ -8137,13 +8140,10 @@ var getShortWorkspaceDisplayName = (workspaceId, lineId) => {
8137
8140
  }
8138
8141
  }
8139
8142
  if (displayName) {
8140
- console.log(`getShortWorkspaceDisplayName(${workspaceId}, lineId: ${lineId}) -> ${displayName} (from Supabase)`);
8141
8143
  return displayName;
8142
8144
  } else {
8143
8145
  if (isInitialized) {
8144
- console.log(`getShortWorkspaceDisplayName(${workspaceId}, lineId: ${lineId}) -> ${workspaceId} (not found in Supabase data)`);
8145
- } else {
8146
- console.log(`getShortWorkspaceDisplayName(${workspaceId}, lineId: ${lineId}) -> ${workspaceId} (Supabase not initialized yet)`);
8146
+ console.warn(`getShortWorkspaceDisplayName(${workspaceId}, lineId: ${lineId}) -> ${workspaceId} (not found in Supabase data)`);
8147
8147
  }
8148
8148
  return workspaceId;
8149
8149
  }
@@ -8449,6 +8449,8 @@ var useAllWorkspaceMetrics = (options) => {
8449
8449
  const [loading, setLoading] = useState(true);
8450
8450
  const [error, setError] = useState(null);
8451
8451
  const [initialized, setInitialized] = useState(false);
8452
+ const fetchTimeoutRef = useRef(null);
8453
+ const isFetchingRef = useRef(false);
8452
8454
  const queryShiftId = useMemo(() => {
8453
8455
  const currentShift = getCurrentShift(
8454
8456
  dateTimeConfig.defaultTimezone || "Asia/Kolkata",
@@ -8467,16 +8469,15 @@ var useAllWorkspaceMetrics = (options) => {
8467
8469
  }, [entityConfig.companyId]);
8468
8470
  const schema = databaseConfig.schema ?? "public";
8469
8471
  const fetchWorkspaceMetrics = useCallback(async () => {
8472
+ if (isFetchingRef.current) {
8473
+ return;
8474
+ }
8475
+ isFetchingRef.current = true;
8470
8476
  if (!initialized) {
8471
8477
  setLoading(true);
8472
8478
  }
8473
8479
  setError(null);
8474
8480
  try {
8475
- console.log("Fetching all workspace metrics with params:", {
8476
- queryDate,
8477
- queryShiftId,
8478
- metricsTable
8479
- });
8480
8481
  const configuredLineIds = getConfiguredLineIds(entityConfig);
8481
8482
  let enabledWorkspaceIds = [];
8482
8483
  for (const lineId of configuredLineIds) {
@@ -8519,13 +8520,26 @@ var useAllWorkspaceMetrics = (options) => {
8519
8520
  efficiency: item.efficiency || 0,
8520
8521
  action_threshold: item.total_day_output || 0
8521
8522
  }));
8522
- setWorkspaces(transformedData);
8523
+ setWorkspaces((prevWorkspaces) => {
8524
+ if (prevWorkspaces.length !== transformedData.length) {
8525
+ return transformedData;
8526
+ }
8527
+ const hasChanges = transformedData.some((newWs) => {
8528
+ const prevWs = prevWorkspaces.find((w) => w.workspace_uuid === newWs.workspace_uuid);
8529
+ if (!prevWs) {
8530
+ return true;
8531
+ }
8532
+ return prevWs.efficiency !== newWs.efficiency || prevWs.action_count !== newWs.action_count || prevWs.action_threshold !== newWs.action_threshold || prevWs.avg_cycle_time !== newWs.avg_cycle_time || prevWs.workspace_name !== newWs.workspace_name;
8533
+ });
8534
+ return hasChanges ? transformedData : prevWorkspaces;
8535
+ });
8523
8536
  setInitialized(true);
8524
8537
  } catch (err) {
8525
- console.error("Error fetching all workspace metrics:", err);
8538
+ console.error("[useAllWorkspaceMetrics] Error:", err.message);
8526
8539
  setError({ message: err.message, code: err.code || "FETCH_ERROR" });
8527
8540
  } finally {
8528
8541
  setLoading(false);
8542
+ isFetchingRef.current = false;
8529
8543
  }
8530
8544
  }, [queryDate, queryShiftId, metricsTable, supabase, entityConfig.companyId]);
8531
8545
  useEffect(() => {
@@ -8533,25 +8547,37 @@ var useAllWorkspaceMetrics = (options) => {
8533
8547
  fetchWorkspaceMetrics();
8534
8548
  }
8535
8549
  const setupSubscription = () => {
8536
- const filter2 = `date=eq.${queryDate} AND shift_id=eq.${queryShiftId}`;
8537
- console.log("Setting up subscription for all workspaces with filter:", filter2);
8538
8550
  const channel2 = supabase.channel(`all-workspace-metrics-${Date.now()}`).on(
8539
8551
  "postgres_changes",
8540
8552
  {
8541
8553
  event: "*",
8542
8554
  schema,
8543
- table: metricsTable,
8544
- filter: filter2
8555
+ table: metricsTable
8545
8556
  },
8546
8557
  async (payload) => {
8547
- console.log("All workspace metrics update received:", payload);
8548
- await fetchWorkspaceMetrics();
8558
+ const data = payload.new || payload.old;
8559
+ if (data?.date !== queryDate || data?.shift_id !== queryShiftId) {
8560
+ return;
8561
+ }
8562
+ if (fetchTimeoutRef.current) {
8563
+ clearTimeout(fetchTimeoutRef.current);
8564
+ }
8565
+ fetchTimeoutRef.current = setTimeout(async () => {
8566
+ if (!isFetchingRef.current) {
8567
+ await fetchWorkspaceMetrics();
8568
+ }
8569
+ fetchTimeoutRef.current = null;
8570
+ }, 300);
8549
8571
  }
8550
8572
  ).subscribe();
8551
8573
  return channel2;
8552
8574
  };
8553
8575
  const channel = setupSubscription();
8554
8576
  return () => {
8577
+ if (fetchTimeoutRef.current) {
8578
+ clearTimeout(fetchTimeoutRef.current);
8579
+ fetchTimeoutRef.current = null;
8580
+ }
8555
8581
  if (channel) {
8556
8582
  supabase.removeChannel(channel);
8557
8583
  }
@@ -21953,7 +21979,16 @@ var VideoCard = React21__default.memo(({
21953
21979
  }
21954
21980
  );
21955
21981
  }, (prevProps, nextProps) => {
21956
- return prevProps.workspace.workspace_uuid === nextProps.workspace.workspace_uuid && prevProps.workspace.workspace_name === nextProps.workspace.workspace_name && Math.abs(prevProps.workspace.efficiency - nextProps.workspace.efficiency) < 1 && prevProps.hlsUrl === nextProps.hlsUrl && prevProps.shouldPlay === nextProps.shouldPlay && prevProps.cropping?.x === nextProps.cropping?.x && prevProps.cropping?.y === nextProps.cropping?.y && prevProps.cropping?.width === nextProps.cropping?.width && prevProps.cropping?.height === nextProps.cropping?.height;
21982
+ if (prevProps.workspace.efficiency !== nextProps.workspace.efficiency || prevProps.workspace.trend !== nextProps.workspace.trend || prevProps.workspace.performance_score !== nextProps.workspace.performance_score || prevProps.workspace.pph !== nextProps.workspace.pph) {
21983
+ return false;
21984
+ }
21985
+ if (prevProps.hlsUrl !== nextProps.hlsUrl || prevProps.shouldPlay !== nextProps.shouldPlay) {
21986
+ return false;
21987
+ }
21988
+ if (prevProps.cropping?.x !== nextProps.cropping?.x || prevProps.cropping?.y !== nextProps.cropping?.y || prevProps.cropping?.width !== nextProps.cropping?.width || prevProps.cropping?.height !== nextProps.cropping?.height) {
21989
+ return false;
21990
+ }
21991
+ return true;
21957
21992
  });
21958
21993
  VideoCard.displayName = "VideoCard";
21959
21994
  var DEFAULT_HLS_URL = "https://192.168.5.9:8443/cam1.m3u8";
@@ -22249,7 +22284,7 @@ var WorkspaceMetricCardsImpl = ({
22249
22284
  /* @__PURE__ */ jsxs(Card2, { className: "flex flex-col bg-white shadow-sm h-full min-h-[150px] sm:min-h-0", children: [
22250
22285
  /* @__PURE__ */ jsx(CardHeader2, { className: "pb-2 flex-none", children: /* @__PURE__ */ jsx(CardTitle2, { className: "text-lg text-center", children: "Cycle Time (s)" }) }),
22251
22286
  /* @__PURE__ */ jsx(CardContent2, { className: "flex-1 flex items-center justify-center py-6 sm:py-3", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
22252
- /* @__PURE__ */ jsx("p", { className: `text-5xl font-bold text-green-500`, children: workspace.avg_cycle_time.toFixed(1) }),
22287
+ /* @__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) }),
22253
22288
  /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-500 mt-2", children: [
22254
22289
  "Standard: ",
22255
22290
  workspace.ideal_cycle_time?.toFixed(1) || 0,
@@ -22961,7 +22996,8 @@ var BreakNotificationPopup = ({
22961
22996
  onDismiss,
22962
22997
  isVisible = true,
22963
22998
  className = "",
22964
- lineNames = {}
22999
+ lineNames = {},
23000
+ axelImagePath = "/axel-profile.png"
22965
23001
  }) => {
22966
23002
  const [isDismissed, setIsDismissed] = useState(false);
22967
23003
  const [currentTime, setCurrentTime] = useState(/* @__PURE__ */ new Date());
@@ -22986,6 +23022,109 @@ var BreakNotificationPopup = ({
22986
23022
  if (!isVisible || isDismissed || activeBreaks.length === 0) {
22987
23023
  return null;
22988
23024
  }
23025
+ return /* @__PURE__ */ jsx(AnimatePresence, { children: activeBreaks.map((breakItem, index) => /* @__PURE__ */ jsx(
23026
+ motion.div,
23027
+ {
23028
+ initial: { opacity: 0, x: 100, y: -20 },
23029
+ animate: { opacity: 1, x: 0, y: 0 },
23030
+ exit: { opacity: 0, x: 100, y: -20 },
23031
+ transition: { duration: 0.3, ease: "easeOut", delay: index * 0.1 },
23032
+ className: `fixed right-4 z-50 max-w-xs w-full ${className}`,
23033
+ style: { top: `${6 + index * 12}rem` },
23034
+ 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: [
23035
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start space-x-3 flex-1", children: [
23036
+ /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx(
23037
+ "img",
23038
+ {
23039
+ src: axelImagePath,
23040
+ alt: "Axel AI",
23041
+ className: "w-10 h-10 rounded-full object-cover border-2 border-gray-200 shadow-sm",
23042
+ onError: (e) => {
23043
+ const target = e.currentTarget;
23044
+ target.style.display = "none";
23045
+ const fallback = document.createElement("div");
23046
+ 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";
23047
+ fallback.textContent = "A";
23048
+ target.parentElement?.appendChild(fallback);
23049
+ }
23050
+ }
23051
+ ) }),
23052
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
23053
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-1.5", children: [
23054
+ /* @__PURE__ */ jsxs("h4", { className: "font-semibold text-sm text-gray-900", children: [
23055
+ breakItem.remarks || "Break",
23056
+ (activeBreaks.length > 1 || lineNames[breakItem.lineId]) && /* @__PURE__ */ jsxs("span", { className: "text-xs text-gray-500 ml-1", children: [
23057
+ "\u2022 ",
23058
+ lineNames[breakItem.lineId] || `Line ${breakItem.lineId.substring(0, 8)}`
23059
+ ] })
23060
+ ] }),
23061
+ /* @__PURE__ */ jsx(Coffee, { className: "w-4 h-4 text-amber-500" })
23062
+ ] }),
23063
+ /* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-600 leading-relaxed mb-2", children: [
23064
+ "Currently active from ",
23065
+ breakItem.startTime,
23066
+ " to ",
23067
+ breakItem.endTime,
23068
+ ". ",
23069
+ formatTime3(breakItem.elapsedMinutes),
23070
+ " elapsed of ",
23071
+ formatTime3(breakItem.duration),
23072
+ " total."
23073
+ ] }),
23074
+ /* @__PURE__ */ jsx("div", { className: "mt-2", children: /* @__PURE__ */ jsx("div", { className: "w-full bg-gray-200 rounded-full h-1.5", children: /* @__PURE__ */ jsx(
23075
+ "div",
23076
+ {
23077
+ className: "h-1.5 bg-blue-500 rounded-full transition-all duration-1000",
23078
+ style: {
23079
+ width: `${Math.min(100, Math.max(0, breakItem.elapsedMinutes / breakItem.duration * 100))}%`
23080
+ }
23081
+ }
23082
+ ) }) })
23083
+ ] })
23084
+ ] }),
23085
+ /* @__PURE__ */ jsx(
23086
+ "button",
23087
+ {
23088
+ onClick: handleDismiss,
23089
+ onTouchStart: () => {
23090
+ },
23091
+ className: "ml-2 text-gray-400 hover:text-gray-600 transition-colors p-2 sm:p-1 rounded-full hover:bg-gray-100 active:bg-gray-200 touch-manipulation min-h-[44px] min-w-[44px] sm:min-h-0 sm:min-w-0 flex items-center justify-center flex-shrink-0",
23092
+ "aria-label": "Dismiss notification",
23093
+ children: /* @__PURE__ */ jsx(X, { className: "w-4 h-4 sm:w-3 sm:h-3" })
23094
+ }
23095
+ )
23096
+ ] }) }) })
23097
+ },
23098
+ `${breakItem.lineId}-${breakItem.startTime}-${index}`
23099
+ )) });
23100
+ };
23101
+ var AxelNotificationPopup = ({
23102
+ suggestion,
23103
+ isVisible = true,
23104
+ onDismiss,
23105
+ className = "",
23106
+ axelImagePath = "/axel-profile.png"
23107
+ }) => {
23108
+ const [isDismissed, setIsDismissed] = useState(false);
23109
+ const handleDismiss = () => {
23110
+ setIsDismissed(true);
23111
+ onDismiss?.();
23112
+ };
23113
+ if (!isVisible || isDismissed || !suggestion) {
23114
+ return null;
23115
+ }
23116
+ const getTypeIcon = () => {
23117
+ switch (suggestion.type) {
23118
+ case "improvement":
23119
+ return /* @__PURE__ */ jsx(TrendingUp, { className: "w-4 h-4 text-blue-500" });
23120
+ case "alert":
23121
+ return /* @__PURE__ */ jsx(AlertCircle, { className: "w-4 h-4 text-amber-500" });
23122
+ case "insight":
23123
+ return /* @__PURE__ */ jsx(Sparkles, { className: "w-4 h-4 text-purple-500" });
23124
+ default:
23125
+ return /* @__PURE__ */ jsx(Sparkles, { className: "w-4 h-4 text-blue-500" });
23126
+ }
23127
+ };
22989
23128
  return /* @__PURE__ */ jsx(AnimatePresence, { children: /* @__PURE__ */ jsx(
22990
23129
  motion.div,
22991
23130
  {
@@ -22993,58 +23132,54 @@ var BreakNotificationPopup = ({
22993
23132
  animate: { opacity: 1, x: 0, y: 0 },
22994
23133
  exit: { opacity: 0, x: 100, y: -20 },
22995
23134
  transition: { duration: 0.3, ease: "easeOut" },
22996
- className: `fixed top-24 right-4 z-50 max-w-xs w-full ${className}`,
22997
- children: /* @__PURE__ */ jsx("div", { className: "bg-white text-gray-900 rounded-lg border border-gray-200 shadow-lg overflow-hidden", children: activeBreaks.map((breakItem, index) => /* @__PURE__ */ jsx(
23135
+ className: `fixed top-24 right-4 z-40 max-w-xs w-full ${className}`,
23136
+ children: /* @__PURE__ */ jsx("div", { className: "bg-white text-gray-900 rounded-lg border border-gray-200 shadow-lg overflow-hidden", children: /* @__PURE__ */ jsx(
22998
23137
  motion.div,
22999
23138
  {
23000
- initial: { opacity: 0, y: 20 },
23139
+ initial: { opacity: 0, y: 10 },
23001
23140
  animate: { opacity: 1, y: 0 },
23002
- transition: { delay: index * 0.1 },
23003
- className: `p-3 ${index > 0 ? "border-t border-gray-100" : ""}`,
23141
+ transition: { delay: 0.1 },
23142
+ className: "p-3",
23004
23143
  children: /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between", children: [
23005
- /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-3 flex-1", children: [
23006
- /* @__PURE__ */ jsx("div", { className: "w-2 h-2 bg-amber-500 rounded-full animate-pulse flex-shrink-0 mt-2" }),
23144
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start space-x-3 flex-1", children: [
23145
+ /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx(
23146
+ "img",
23147
+ {
23148
+ src: axelImagePath,
23149
+ alt: "Axel AI",
23150
+ className: "w-10 h-10 rounded-full object-cover border-2 border-gray-200 shadow-sm",
23151
+ onError: (e) => {
23152
+ const target = e.currentTarget;
23153
+ target.style.display = "none";
23154
+ const fallback = document.createElement("div");
23155
+ 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";
23156
+ fallback.textContent = "A";
23157
+ target.parentElement?.appendChild(fallback);
23158
+ }
23159
+ }
23160
+ ) }),
23007
23161
  /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
23008
- /* @__PURE__ */ jsxs("div", { className: "mb-1", children: [
23009
- /* @__PURE__ */ jsx("h4", { className: "font-semibold text-base sm:text-sm text-gray-900", children: breakItem.remarks || "Break" }),
23010
- (activeBreaks.length > 1 || lineNames[breakItem.lineId]) && /* @__PURE__ */ jsx("div", { className: "text-sm sm:text-xs text-gray-500 mt-0.5", children: lineNames[breakItem.lineId] || `Line ${breakItem.lineId.substring(0, 8)}` })
23162
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-1.5", children: [
23163
+ /* @__PURE__ */ jsx("h4", { className: "font-semibold text-sm text-gray-900", children: suggestion.title }),
23164
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1", children: getTypeIcon() })
23011
23165
  ] }),
23012
- /* @__PURE__ */ jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxs("div", { className: "text-sm sm:text-xs text-gray-600 font-medium", children: [
23013
- breakItem.startTime,
23014
- " - ",
23015
- breakItem.endTime
23016
- ] }) }),
23017
- /* @__PURE__ */ jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxs("div", { className: "text-sm sm:text-xs text-gray-500", children: [
23018
- formatTime3(breakItem.elapsedMinutes),
23019
- " / ",
23020
- formatTime3(breakItem.duration)
23021
- ] }) }),
23022
- /* @__PURE__ */ jsx("div", { className: "mt-2", children: /* @__PURE__ */ jsx("div", { className: "w-full bg-gray-200 rounded-full h-1.5", children: /* @__PURE__ */ jsx(
23023
- "div",
23024
- {
23025
- className: "h-1.5 bg-blue-500 rounded-full transition-all duration-1000",
23026
- style: {
23027
- width: `${Math.min(100, Math.max(0, breakItem.elapsedMinutes / breakItem.duration * 100))}%`
23028
- }
23029
- }
23030
- ) }) })
23166
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-600 leading-relaxed", children: suggestion.message })
23031
23167
  ] })
23032
23168
  ] }),
23033
- index === 0 && /* @__PURE__ */ jsx(
23169
+ /* @__PURE__ */ jsx(
23034
23170
  "button",
23035
23171
  {
23036
23172
  onClick: handleDismiss,
23037
23173
  onTouchStart: () => {
23038
23174
  },
23039
- className: "ml-2 text-gray-400 hover:text-gray-600 transition-colors p-2 sm:p-1 rounded-full hover:bg-gray-100 active:bg-gray-200 touch-manipulation min-h-[44px] min-w-[44px] sm:min-h-0 sm:min-w-0 flex items-center justify-center",
23175
+ className: "ml-2 text-gray-400 hover:text-gray-600 transition-colors p-2 sm:p-1 rounded-full hover:bg-gray-100 active:bg-gray-200 touch-manipulation min-h-[44px] min-w-[44px] sm:min-h-0 sm:min-w-0 flex items-center justify-center flex-shrink-0",
23040
23176
  "aria-label": "Dismiss notification",
23041
23177
  children: /* @__PURE__ */ jsx(X, { className: "w-4 h-4 sm:w-3 sm:h-3" })
23042
23178
  }
23043
23179
  )
23044
23180
  ] })
23045
- },
23046
- `${breakItem.lineId}-${breakItem.startTime}-${index}`
23047
- )) })
23181
+ }
23182
+ ) })
23048
23183
  }
23049
23184
  ) });
23050
23185
  };
@@ -25875,12 +26010,6 @@ var WorkspaceHistoryCalendar = ({
25875
26010
  ] })
25876
26011
  ] });
25877
26012
  };
25878
-
25879
- // src/lib/constants/design-tokens.ts
25880
- var designTokens = {
25881
- // Typography scale with clear hierarchy
25882
- typography: {
25883
- body: "text-sm text-gray-600"}};
25884
26013
  var WEEKDAYS3 = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
25885
26014
  var getOrdinal = (n) => {
25886
26015
  const suffix = ["th", "st", "nd", "rd"];
@@ -25929,8 +26058,19 @@ var WorkspaceMonthlyHistory = ({
25929
26058
  const daysInMonth = new Date(year, month + 1, 0).getDate();
25930
26059
  const dailyData = [];
25931
26060
  let maxOutput = 0;
25932
- let totalIdealOutput = 0;
25933
- let validDaysCount = 0;
26061
+ let lastSetTarget = 0;
26062
+ for (let day = daysInMonth; day >= 1; day--) {
26063
+ const dayData = data.find((d) => {
26064
+ const date = new Date(d.date);
26065
+ return date.getDate() === day;
26066
+ });
26067
+ const shiftData = dayData ? selectedShift === "day" ? dayData.dayShift : dayData.nightShift : null;
26068
+ const idealOutput = shiftData ? shiftData.idealOutput : 0;
26069
+ if (idealOutput > 0) {
26070
+ lastSetTarget = idealOutput;
26071
+ break;
26072
+ }
26073
+ }
25934
26074
  for (let day = 1; day <= daysInMonth; day++) {
25935
26075
  const dayData = data.find((d) => {
25936
26076
  const date = new Date(d.date);
@@ -25940,11 +26080,7 @@ var WorkspaceMonthlyHistory = ({
25940
26080
  const output = shiftData && hasRealData(shiftData) ? shiftData.output : 0;
25941
26081
  const idealOutput = shiftData ? shiftData.idealOutput : 0;
25942
26082
  if (output > maxOutput) maxOutput = output;
25943
- if (idealOutput > 0) {
25944
- totalIdealOutput += idealOutput;
25945
- validDaysCount++;
25946
- }
25947
- const color2 = output >= idealOutput ? "#00AB45" : "#E34329";
26083
+ const color2 = output >= lastSetTarget ? "#00AB45" : "#E34329";
25948
26084
  dailyData.push({
25949
26085
  hour: getOrdinal(day),
25950
26086
  // Using ordinal format (1st, 2nd, 3rd, etc.)
@@ -25959,14 +26095,13 @@ var WorkspaceMonthlyHistory = ({
25959
26095
  // Not used but keeps structure consistent
25960
26096
  });
25961
26097
  }
25962
- const avgIdealOutput = validDaysCount > 0 ? totalIdealOutput / validDaysCount : 0;
25963
- const calculatedMax = Math.max(maxOutput, avgIdealOutput);
26098
+ const calculatedMax = Math.max(maxOutput, lastSetTarget);
25964
26099
  const yAxisMax = calculatedMax > 0 ? calculatedMax * 1.1 : 100;
25965
- return { data: dailyData, maxOutput, avgIdealOutput, yAxisMax };
26100
+ return { data: dailyData, maxOutput, lastSetTarget, yAxisMax };
25966
26101
  }, [data, month, year, selectedShift]);
25967
26102
  const yAxisTicks = useMemo(() => {
25968
26103
  const max = chartData.yAxisMax;
25969
- const target = chartData.avgIdealOutput;
26104
+ const target = chartData.lastSetTarget;
25970
26105
  if (!max || max <= 0) return void 0;
25971
26106
  const desiredIntervals = 4;
25972
26107
  const roughStep = max / desiredIntervals;
@@ -25984,7 +26119,7 @@ var WorkspaceMonthlyHistory = ({
25984
26119
  ticks.push(Math.round(target));
25985
26120
  }
25986
26121
  return Array.from(new Set(ticks)).filter((v) => v >= 0 && v <= max).sort((a, b) => a - b);
25987
- }, [chartData.yAxisMax, chartData.avgIdealOutput]);
26122
+ }, [chartData.yAxisMax, chartData.lastSetTarget]);
25988
26123
  const pieChartData = useMemo(() => {
25989
26124
  const validShifts = data.map((d) => selectedShift === "day" ? d.dayShift : d.nightShift).filter(hasRealData);
25990
26125
  if (validShifts.length === 0) return [];
@@ -26058,10 +26193,13 @@ var WorkspaceMonthlyHistory = ({
26058
26193
  }
26059
26194
  }, [workspaceId, onShiftChange]);
26060
26195
  if (monthlyDataLoading) {
26061
- return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-[calc(100vh-10rem)]", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center space-y-4", children: [
26062
- /* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsx("div", { className: "h-12 w-12 animate-spin rounded-full border-4 border-blue-200", children: /* @__PURE__ */ jsx("div", { className: "absolute inset-0 rounded-full border-4 border-blue-600 border-t-transparent" }) }) }),
26063
- /* @__PURE__ */ jsx("p", { className: designTokens.typography.body + " font-medium", children: "Loading monthly performance data..." })
26064
- ] }) });
26196
+ return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-[calc(100vh-10rem)]", children: /* @__PURE__ */ jsx(
26197
+ OptifyeLogoLoader_default,
26198
+ {
26199
+ size: "lg",
26200
+ message: "Loading monthly performance data..."
26201
+ }
26202
+ ) });
26065
26203
  }
26066
26204
  return /* @__PURE__ */ jsxs("div", { className: `flex flex-col gap-2 min-h-0 overflow-y-auto pb-6 ${className}`, children: [
26067
26205
  /* @__PURE__ */ jsx("div", { className: "flex justify-center mb-4", children: /* @__PURE__ */ jsxs("div", { className: "flex gap-1 border border-gray-200 rounded-lg p-1 bg-gray-50", children: [
@@ -26296,7 +26434,7 @@ var WorkspaceMonthlyHistory = ({
26296
26434
  tick: (props) => {
26297
26435
  const { x, y, payload } = props;
26298
26436
  const value = Math.round(payload.value);
26299
- const targetValue = Math.round(chartData.avgIdealOutput);
26437
+ const targetValue = Math.round(chartData.lastSetTarget);
26300
26438
  const isTarget = Math.abs(value - targetValue) < 1 && targetValue > 0;
26301
26439
  return /* @__PURE__ */ jsx(
26302
26440
  "text",
@@ -26320,10 +26458,10 @@ var WorkspaceMonthlyHistory = ({
26320
26458
  content: CustomTooltip
26321
26459
  }
26322
26460
  ),
26323
- chartData.avgIdealOutput > 0 && /* @__PURE__ */ jsx(
26461
+ chartData.lastSetTarget > 0 && /* @__PURE__ */ jsx(
26324
26462
  ReferenceLine,
26325
26463
  {
26326
- y: chartData.avgIdealOutput,
26464
+ y: chartData.lastSetTarget,
26327
26465
  stroke: "#E34329",
26328
26466
  strokeDasharray: "5 5",
26329
26467
  strokeWidth: 2
@@ -26381,11 +26519,11 @@ var WorkspaceMonthlyHistory = ({
26381
26519
  ]
26382
26520
  }
26383
26521
  ) }) }),
26384
- /* @__PURE__ */ jsx("div", { className: "flex justify-center items-center gap-6 mt-3", children: chartData.avgIdealOutput > 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
26522
+ /* @__PURE__ */ jsx("div", { className: "flex justify-center items-center gap-6 mt-3", children: chartData.lastSetTarget > 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
26385
26523
  /* @__PURE__ */ jsx("div", { className: "w-12 h-0.5 border-t-2 border-dashed", style: { borderColor: "#E34329" } }),
26386
26524
  /* @__PURE__ */ jsxs("span", { className: "text-xs text-gray-600", children: [
26387
26525
  "Target: ",
26388
- Math.round(chartData.avgIdealOutput),
26526
+ Math.round(chartData.lastSetTarget),
26389
26527
  " units/day"
26390
26528
  ] })
26391
26529
  ] }) })
@@ -26498,7 +26636,7 @@ var WorkspacePdfGenerator = ({ workspace, className }) => {
26498
26636
  doc.roundedRect(22, y - 7, 165, 12, 2, 2, "S");
26499
26637
  };
26500
26638
  doc.setFillColor(245, 245, 245);
26501
- doc.roundedRect(15, 95, 180, 70, 3, 3, "F");
26639
+ doc.roundedRect(15, 95, 180, 60, 3, 3, "F");
26502
26640
  doc.setFontSize(18);
26503
26641
  doc.setFont("helvetica", "bold");
26504
26642
  doc.setTextColor(40, 40, 40);
@@ -26527,34 +26665,29 @@ var WorkspacePdfGenerator = ({ workspace, className }) => {
26527
26665
  doc.text("PPH (Pieces Per Hour):", 25, kpiStartY + kpiSpacing * 3);
26528
26666
  doc.setFont("helvetica", "bold");
26529
26667
  doc.text(`${workspace.avg_pph.toFixed(1)} (Standard: ${workspace.pph_threshold.toFixed(1)})`, 120, kpiStartY + kpiSpacing * 3);
26530
- createKPIBox(kpiStartY + kpiSpacing * 4);
26531
- doc.setFont("helvetica", "normal");
26532
- doc.text("Rank:", 25, kpiStartY + kpiSpacing * 4);
26533
- doc.setFont("helvetica", "bold");
26534
- doc.text(`${workspace.workspace_rank} of ${workspace.total_workspaces}`, 120, kpiStartY + kpiSpacing * 4);
26535
26668
  doc.setDrawColor(180, 180, 180);
26536
26669
  doc.setLineWidth(0.8);
26537
- doc.line(20, 180, 190, 180);
26670
+ doc.line(20, 170, 190, 170);
26538
26671
  doc.setFillColor(245, 245, 245);
26539
- doc.roundedRect(15, 185, 180, 85, 3, 3, "F");
26672
+ doc.roundedRect(15, 175, 180, 85, 3, 3, "F");
26540
26673
  doc.setFontSize(18);
26541
26674
  doc.setFont("helvetica", "bold");
26542
26675
  doc.setTextColor(40, 40, 40);
26543
- doc.text("Hourly Performance", 20, 195);
26676
+ doc.text("Hourly Performance", 20, 185);
26544
26677
  doc.setTextColor(0, 0, 0);
26545
26678
  doc.setFontSize(11);
26546
26679
  doc.setFont("helvetica", "bold");
26547
26680
  doc.setFillColor(245, 245, 245);
26548
- doc.roundedRect(20, 187, 170, 8, 1, 1, "F");
26549
- doc.text("Time Range", 25, 192);
26550
- doc.text("Output", 95, 192);
26551
- doc.text("Target", 135, 192);
26552
- doc.text("Status", 170, 192);
26681
+ doc.roundedRect(20, 177, 170, 8, 1, 1, "F");
26682
+ doc.text("Time Range", 25, 182);
26683
+ doc.text("Output", 95, 182);
26684
+ doc.text("Target", 135, 182);
26685
+ doc.text("Status", 170, 182);
26553
26686
  doc.setLineWidth(0.2);
26554
26687
  doc.setDrawColor(220, 220, 220);
26555
- doc.line(20, 195, 190, 195);
26688
+ doc.line(20, 185, 190, 185);
26556
26689
  doc.setFont("helvetica", "normal");
26557
- let yPos = 201;
26690
+ let yPos = 191;
26558
26691
  const hourlyData = workspace.hourly_action_counts || [];
26559
26692
  const hourlyTarget = workspace.pph_threshold;
26560
26693
  hourlyData.forEach((output, index) => {
@@ -27231,6 +27364,36 @@ var TimePickerDropdown = ({
27231
27364
  ] })
27232
27365
  ] });
27233
27366
  };
27367
+ var ERROR_MAPPING = {
27368
+ 1: {
27369
+ // MEDIA_ERR_ABORTED
27370
+ code: 1,
27371
+ type: "recoverable" /* RECOVERABLE */,
27372
+ message: "Video loading was interrupted",
27373
+ canRetry: true
27374
+ },
27375
+ 2: {
27376
+ // MEDIA_ERR_NETWORK
27377
+ code: 2,
27378
+ type: "recoverable" /* RECOVERABLE */,
27379
+ message: "Network error - please check your internet connection",
27380
+ canRetry: true
27381
+ },
27382
+ 3: {
27383
+ // MEDIA_ERR_DECODE
27384
+ code: 3,
27385
+ type: "non_recoverable" /* NON_RECOVERABLE */,
27386
+ message: "Stream corrupted due to internet connection",
27387
+ canRetry: false
27388
+ },
27389
+ 4: {
27390
+ // MEDIA_ERR_SRC_NOT_SUPPORTED
27391
+ code: 4,
27392
+ type: "non_recoverable" /* NON_RECOVERABLE */,
27393
+ message: "Video format not supported by your browser. Please use Google Chrome.",
27394
+ canRetry: false
27395
+ }
27396
+ };
27234
27397
  var videoPlayerStyles = `
27235
27398
  .video-player-container {
27236
27399
  width: 100%;
@@ -27461,8 +27624,21 @@ var VideoPlayer = React21__default.forwardRef(({
27461
27624
  player.on("seeked", () => onSeeked?.(player));
27462
27625
  player.on("error", () => {
27463
27626
  const error = player.error();
27464
- console.error("Video.js error:", error);
27465
- onError?.(player, error);
27627
+ const errorCode = error?.code ?? 0;
27628
+ const errorInfo = ERROR_MAPPING[errorCode] || {
27629
+ code: errorCode || 0,
27630
+ type: "non_recoverable" /* NON_RECOVERABLE */,
27631
+ message: "Unknown playback error occurred",
27632
+ canRetry: false
27633
+ };
27634
+ console.error("[VideoPlayer] Video.js error:", {
27635
+ code: errorCode,
27636
+ type: errorInfo.type,
27637
+ message: errorInfo.message,
27638
+ canRetry: errorInfo.canRetry,
27639
+ originalError: error
27640
+ });
27641
+ onError?.(player, errorInfo);
27466
27642
  });
27467
27643
  if (src) {
27468
27644
  const isHLS = src.endsWith(".m3u8") || src.startsWith("#EXTM3U");
@@ -28305,7 +28481,10 @@ var FilterDialogTrigger = ({
28305
28481
  }
28306
28482
  );
28307
28483
  };
28308
- var getSeverityIcon = (severity) => {
28484
+ var getSeverityIcon = (severity, categoryId) => {
28485
+ if (categoryId === "idle_time" || categoryId === "low_value" || categoryId === "longest-idles") {
28486
+ return /* @__PURE__ */ jsx(AlertTriangle, { className: "h-3 w-3 text-red-500" });
28487
+ }
28309
28488
  switch (severity) {
28310
28489
  case "high":
28311
28490
  return /* @__PURE__ */ jsx(AlertTriangle, { className: "h-3 w-3 text-red-500" });
@@ -28532,17 +28711,17 @@ var FileManagerFilters = ({
28532
28711
  const colorClasses = getColorClasses(category.color);
28533
28712
  const clipNodes = filteredClips.map((clip, index) => {
28534
28713
  const timeString = new Date(clip.clip_timestamp).toLocaleTimeString("en-US", {
28535
- hour12: false,
28536
- hour: "2-digit",
28714
+ hour12: true,
28715
+ hour: "numeric",
28537
28716
  minute: "2-digit",
28538
28717
  timeZone: timezone
28539
28718
  // Use database timezone for display
28540
28719
  });
28541
28720
  return {
28542
28721
  id: clip.id,
28543
- label: `${timeString} - ${clip.description}${clip.duration && category.id !== "idle_time" ? ` (${clip.duration.toFixed(1)}s)` : ""}`,
28722
+ label: `${timeString}${clip.duration && category.id !== "idle_time" ? ` - (${clip.duration.toFixed(1)}s)` : ""}`,
28544
28723
  type: "video",
28545
- icon: getSeverityIcon(clip.severity),
28724
+ icon: getSeverityIcon(clip.severity, category.id),
28546
28725
  timestamp: clip.clip_timestamp,
28547
28726
  severity: clip.severity,
28548
28727
  clipId: clip.clipId,
@@ -28582,9 +28761,9 @@ var FileManagerFilters = ({
28582
28761
  children: (percentileClips["fast-cycles"] || []).map((clip, index) => ({
28583
28762
  id: clip.id,
28584
28763
  // Remove prefix to match currentVideoId
28585
- label: `${clip.timestamp} - ${clip.description}${clip.cycle_time_seconds ? ` (${clip.cycle_time_seconds.toFixed(1)}s)` : ""}`,
28764
+ label: `${clip.timestamp}${clip.cycle_time_seconds ? ` - (${clip.cycle_time_seconds.toFixed(1)}s)` : ""}`,
28586
28765
  type: "video",
28587
- icon: getSeverityIcon(clip.severity),
28766
+ icon: getSeverityIcon(clip.severity, "fast-cycles"),
28588
28767
  timestamp: clip.creation_timestamp,
28589
28768
  severity: clip.severity,
28590
28769
  clipId: clip.id,
@@ -28605,9 +28784,9 @@ var FileManagerFilters = ({
28605
28784
  children: (percentileClips["slow-cycles"] || []).map((clip, index) => ({
28606
28785
  id: clip.id,
28607
28786
  // Remove prefix to match currentVideoId
28608
- label: `${clip.timestamp} - ${clip.description}${clip.cycle_time_seconds ? ` (${clip.cycle_time_seconds.toFixed(1)}s)` : ""}`,
28787
+ label: `${clip.timestamp}${clip.cycle_time_seconds ? ` - (${clip.cycle_time_seconds.toFixed(1)}s)` : ""}`,
28609
28788
  type: "video",
28610
- icon: getSeverityIcon(clip.severity),
28789
+ icon: getSeverityIcon(clip.severity, "slow-cycles"),
28611
28790
  timestamp: clip.creation_timestamp,
28612
28791
  severity: clip.severity,
28613
28792
  clipId: clip.id,
@@ -28628,9 +28807,9 @@ var FileManagerFilters = ({
28628
28807
  isPercentile: true,
28629
28808
  children: (percentileClips['idle-times'] || []).map((clip, index) => ({
28630
28809
  id: clip.id, // Remove prefix to match currentVideoId
28631
- label: `${clip.timestamp} - ${clip.description}${clip.cycle_time_seconds ? ` (${clip.cycle_time_seconds.toFixed(1)}s)` : ''}`,
28810
+ label: `${clip.timestamp}${clip.cycle_time_seconds ? ` - (${clip.cycle_time_seconds.toFixed(1)}s)` : ''}`,
28632
28811
  type: 'video' as const,
28633
- icon: getSeverityIcon(clip.severity),
28812
+ icon: getSeverityIcon(clip.severity, 'longest-idles'),
28634
28813
  timestamp: clip.creation_timestamp,
28635
28814
  severity: clip.severity,
28636
28815
  clipId: clip.id,
@@ -28640,7 +28819,7 @@ var FileManagerFilters = ({
28640
28819
  ];
28641
28820
  percentileCategories.forEach((category) => {
28642
28821
  if (category.count > 0 && shouldShowCategory(category.id)) {
28643
- tree.unshift(category);
28822
+ tree.push(category);
28644
28823
  }
28645
28824
  });
28646
28825
  return tree;
@@ -28685,7 +28864,7 @@ var FileManagerFilters = ({
28685
28864
  /* @__PURE__ */ jsxs(
28686
28865
  "div",
28687
28866
  {
28688
- className: `flex items-center cursor-pointer transition-all duration-300 ease-out group relative overflow-hidden ${node.type === "category" && depth === 0 ? `py-3 px-4 rounded-2xl hover:bg-gradient-to-r hover:from-slate-50 hover:to-blue-50/30 hover:shadow-lg hover:shadow-blue-100/20 hover:scale-[1.02] hover:-translate-y-0.5 ${isActive ? "bg-gradient-to-r from-blue-50 via-blue-50/80 to-indigo-50/60 border border-blue-200/50 shadow-lg shadow-blue-100/30 scale-[1.02]" : "border border-transparent"}` : `py-2 px-3 rounded-xl hover:bg-gradient-to-r hover:from-slate-50 hover:to-slate-50/50 hover:shadow-sm ${isActive ? "bg-gradient-to-r from-blue-50/80 to-blue-50/40 border border-blue-200/30 shadow-sm" : "border border-transparent"} ${isCurrentVideo ? "bg-gradient-to-r from-emerald-50 to-green-50/60 border border-emerald-200/50 shadow-md shadow-emerald-100/20" : ""}`} ${node.type === "video" ? "ml-6" : ""}`,
28867
+ className: `flex items-center cursor-pointer transition-all duration-300 ease-out group relative overflow-hidden ${node.type === "category" && depth === 0 ? `py-3 px-4 rounded-2xl hover:bg-gradient-to-r hover:from-slate-50 hover:to-blue-50/30 hover:shadow-lg hover:shadow-blue-100/20 hover:scale-[1.02] hover:-translate-y-0.5 ${isActive ? "bg-gradient-to-r from-blue-50 via-blue-50/80 to-indigo-50/60 border border-blue-200/50 shadow-lg shadow-blue-100/30 scale-[1.02]" : "border border-transparent"}` : `py-2 px-3 rounded-xl hover:bg-gradient-to-r hover:from-slate-50 hover:to-slate-50/50 hover:shadow-sm ${isActive ? "bg-gradient-to-r from-blue-50/80 to-blue-50/40 border border-blue-200/30 shadow-sm" : "border border-transparent"} ${isCurrentVideo ? "bg-gradient-to-r from-blue-50 to-blue-50/60 border border-blue-200/50 shadow-md shadow-blue-100/20" : ""}`} ${node.type === "video" ? "ml-6" : ""}`,
28689
28868
  onClick: () => handleNodeClick(node),
28690
28869
  children: [
28691
28870
  hasChildren && /* @__PURE__ */ jsx(
@@ -28702,13 +28881,10 @@ var FileManagerFilters = ({
28702
28881
  /* @__PURE__ */ jsx("div", { className: `flex-shrink-0 mr-3 ${node.type === "category" || node.type === "percentile-category" ? "p-2 rounded-lg shadow-sm group-hover:scale-110 transition-transform duration-200" : "p-0.5"} ${colorClasses && (node.type === "category" || node.type === "percentile-category") ? `${colorClasses.bg} border border-white/60` : ""}`, children: node.icon }),
28703
28882
  /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0 flex items-center justify-between", children: [
28704
28883
  /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
28705
- /* @__PURE__ */ jsx("div", { className: `font-semibold tracking-tight ${node.type === "category" || node.type === "percentile-category" ? "text-slate-800 text-sm" : "text-slate-700 text-xs"} ${isCurrentVideo ? "text-emerald-700 font-bold" : ""} group-hover:text-slate-900 transition-colors duration-200`, children: node.label }),
28884
+ /* @__PURE__ */ jsx("div", { className: `font-semibold tracking-tight ${node.type === "category" || node.type === "percentile-category" ? "text-slate-800 text-sm" : "text-slate-700 text-xs"} ${isCurrentVideo ? "text-blue-700 font-bold" : ""} group-hover:text-slate-900 transition-colors duration-200`, children: node.label }),
28706
28885
  node.type === "category" && categories.find((c) => c.id === node.id)?.description && /* @__PURE__ */ jsx("div", { className: "text-xs text-slate-500 mt-0.5 font-normal", children: categories.find((c) => c.id === node.id)?.description }),
28707
28886
  node.type === "percentile-category" && node.subtitle && /* @__PURE__ */ jsx("div", { className: "text-xs text-slate-500 mt-0.5 font-normal", children: node.subtitle }),
28708
- node.type === "video" && node.severity && /* @__PURE__ */ jsx("div", { className: "text-xs text-slate-500 capitalize mt-0.5 font-medium", children: /* @__PURE__ */ jsxs("span", { className: `inline-flex items-center px-1.5 py-0.5 rounded-md text-xs font-medium ${node.severity === "high" ? "bg-red-100 text-red-700" : node.severity === "medium" ? "bg-yellow-100 text-yellow-700" : "bg-green-100 text-green-700"}`, children: [
28709
- node.severity,
28710
- " priority"
28711
- ] }) })
28887
+ node.type === "video" && node.severity && /* @__PURE__ */ jsx("div", { className: "text-xs text-slate-500 capitalize mt-0.5 font-medium", children: /* @__PURE__ */ jsx("span", { className: `inline-flex items-center px-1.5 py-0.5 rounded-md text-xs font-medium ${node.categoryId === "idle_time" || node.categoryId === "low_value" ? "bg-red-100 text-red-700" : node.severity === "high" ? "bg-red-100 text-red-700" : node.severity === "medium" ? "bg-yellow-100 text-yellow-700" : "bg-green-100 text-green-700"}`, children: node.categoryId === "idle_time" || node.categoryId === "low_value" ? "Idle" : node.severity === "low" ? "Fast" : node.severity === "medium" ? "Average" : "Slow" }) })
28712
28888
  ] }),
28713
28889
  node.count !== void 0 && (node.type === "category" || node.type === "percentile-category") && /* @__PURE__ */ jsx("div", { className: "flex items-center ml-2", children: /* @__PURE__ */ jsx("span", { className: `px-2.5 py-1 text-sm font-bold rounded-lg shadow-sm border backdrop-blur-sm flex-shrink-0 group-hover:scale-105 transition-all duration-200 ${colorClasses ? `${colorClasses.bg} ${colorClasses.text} ${colorClasses.border} bg-opacity-80` : "bg-slate-100/80 text-slate-700 border-slate-200/60"}`, children: node.count }) })
28714
28890
  ] })
@@ -29357,7 +29533,12 @@ var BottlenecksContent = ({
29357
29533
  } catch (err) {
29358
29534
  console.error("[BottlenecksContent] Error fetching clip counts:", err);
29359
29535
  if (isMountedRef.current) {
29360
- setError("Failed to load clip counts. Please try again.");
29536
+ setError({
29537
+ type: "fatal",
29538
+ message: "Failed to load clip counts. Please try again.",
29539
+ canSkip: false,
29540
+ canRetry: true
29541
+ });
29361
29542
  setIsLoading(false);
29362
29543
  }
29363
29544
  } finally {
@@ -29441,7 +29622,12 @@ var BottlenecksContent = ({
29441
29622
  } catch (err) {
29442
29623
  console.error("Error loading first video for category:", err);
29443
29624
  if (isMountedRef.current) {
29444
- setError("Failed to load clips. Please try again.");
29625
+ setError({
29626
+ type: "fatal",
29627
+ message: "Failed to load clips. Please try again.",
29628
+ canSkip: false,
29629
+ canRetry: true
29630
+ });
29445
29631
  setIsCategoryLoading(false);
29446
29632
  }
29447
29633
  } finally {
@@ -29723,7 +29909,12 @@ var BottlenecksContent = ({
29723
29909
  } catch (error2) {
29724
29910
  console.error(`[BottlenecksContent] Error loading clip by ID (${clipId}):`, error2);
29725
29911
  if (isMountedRef.current) {
29726
- setError("Failed to load selected clip. Please try again.");
29912
+ setError({
29913
+ type: "fatal",
29914
+ message: "Failed to load selected clip. Please try again.",
29915
+ canSkip: true,
29916
+ canRetry: true
29917
+ });
29727
29918
  clearLoadingState();
29728
29919
  }
29729
29920
  }
@@ -29746,7 +29937,12 @@ var BottlenecksContent = ({
29746
29937
  }
29747
29938
  } catch (error2) {
29748
29939
  console.error(`[BottlenecksContent] Error in legacy loadAndPlayClip:`, error2);
29749
- setError("Failed to load selected clip. Please try again.");
29940
+ setError({
29941
+ type: "fatal",
29942
+ message: "Failed to load selected clip. Please try again.",
29943
+ canSkip: true,
29944
+ canRetry: true
29945
+ });
29750
29946
  setIsNavigating(false);
29751
29947
  }
29752
29948
  }, [workspaceId, s3ClipsService, date, effectiveShift, loadAndPlayClipById]);
@@ -29786,7 +29982,12 @@ var BottlenecksContent = ({
29786
29982
  }
29787
29983
  } catch (error2) {
29788
29984
  console.error(`[handleNext] Error navigating:`, error2);
29789
- setError("Failed to navigate to next clip");
29985
+ setError({
29986
+ type: "fatal",
29987
+ message: "Failed to navigate to next clip",
29988
+ canSkip: true,
29989
+ canRetry: true
29990
+ });
29790
29991
  clearLoadingState();
29791
29992
  }
29792
29993
  }, [clearLoadingState, s3ClipsService]);
@@ -29822,7 +30023,12 @@ var BottlenecksContent = ({
29822
30023
  }
29823
30024
  } catch (error2) {
29824
30025
  console.error(`[handlePrevious] Error navigating:`, error2);
29825
- setError("Failed to navigate to previous clip");
30026
+ setError({
30027
+ type: "fatal",
30028
+ message: "Failed to navigate to previous clip",
30029
+ canSkip: true,
30030
+ canRetry: true
30031
+ });
29826
30032
  clearLoadingState();
29827
30033
  }
29828
30034
  }, [clearLoadingState, s3ClipsService]);
@@ -29835,7 +30041,7 @@ var BottlenecksContent = ({
29835
30041
  const handleVideoReady = useCallback((player) => {
29836
30042
  console.log("Video.js player ready - NOT clearing loading (wait for playing event)");
29837
30043
  videoRetryCountRef.current = 0;
29838
- if (error?.includes("Retrying")) {
30044
+ if (error?.isRetrying) {
29839
30045
  setError(null);
29840
30046
  }
29841
30047
  }, [error]);
@@ -29880,20 +30086,53 @@ var BottlenecksContent = ({
29880
30086
  }, [clearLoadingState]);
29881
30087
  const handleVideoLoadingChange = useCallback((isLoading2) => {
29882
30088
  console.log(`[BottlenecksContent] Video loading state changed: ${isLoading2}`);
30089
+ if (error && error.type === "fatal") {
30090
+ console.log(`[BottlenecksContent] Ignoring loading state change - fatal error is showing`);
30091
+ return;
30092
+ }
29883
30093
  setIsVideoBuffering(isLoading2);
29884
- }, []);
30094
+ }, [error]);
29885
30095
  const handleVideoEnded = useCallback((player) => {
29886
30096
  handleNext();
29887
30097
  }, [handleNext]);
29888
30098
  const videoRetryCountRef = useRef(0);
29889
- const handleVideoError = useCallback((player, error2) => {
29890
- console.error("Video.js error:", error2);
30099
+ const handleVideoError = useCallback((player, errorInfo) => {
30100
+ console.error("[BottlenecksContent] Video.js error:", errorInfo);
29891
30101
  setIsPlaying(false);
30102
+ setIsVideoBuffering(false);
30103
+ const errorCode = errorInfo?.code || 0;
30104
+ const canRetry = errorInfo?.canRetry ?? false;
30105
+ const errorMessage = errorInfo?.message || "Unknown error";
30106
+ console.log(`[Video Error] Code: ${errorCode}, Can Retry: ${canRetry}, Message: ${errorMessage}`);
30107
+ if (!canRetry) {
30108
+ console.log("[Video Error] Non-recoverable error - showing error overlay immediately");
30109
+ setError({
30110
+ type: "fatal",
30111
+ code: errorCode,
30112
+ message: errorMessage,
30113
+ canSkip: true,
30114
+ canRetry: false
30115
+ });
30116
+ clearLoadingState();
30117
+ videoRetryCountRef.current = 0;
30118
+ trackCoreEvent("clips_video_error_non_recoverable", {
30119
+ workspaceId,
30120
+ category: activeFilterRef.current,
30121
+ videoId: currentVideo?.id,
30122
+ errorCode,
30123
+ errorMessage
30124
+ });
30125
+ return;
30126
+ }
29892
30127
  if (videoRetryCountRef.current < 3 && currentVideo) {
29893
30128
  videoRetryCountRef.current++;
29894
30129
  const retryDelay = 1e3 * videoRetryCountRef.current;
29895
- console.log(`[Video Error] Retrying... Attempt ${videoRetryCountRef.current}/3 in ${retryDelay}ms`);
29896
- setError(`Retrying... (${videoRetryCountRef.current}/3)`);
30130
+ console.log(`[Video Error] Recoverable error - Retrying... Attempt ${videoRetryCountRef.current}/3 in ${retryDelay}ms`);
30131
+ setError({
30132
+ type: "retrying",
30133
+ message: `Retrying... (${videoRetryCountRef.current}/3)`,
30134
+ isRetrying: true
30135
+ });
29897
30136
  setTimeout(() => {
29898
30137
  if (videoRef.current && currentVideo && isMountedRef.current) {
29899
30138
  setError(null);
@@ -29901,16 +30140,26 @@ var BottlenecksContent = ({
29901
30140
  }
29902
30141
  }, retryDelay);
29903
30142
  } else {
29904
- setError("Video failed to load after 3 attempts. The stream may be corrupted.");
30143
+ console.log("[Video Error] Retries exhausted - showing final error overlay");
30144
+ setError({
30145
+ type: "fatal",
30146
+ code: errorCode,
30147
+ message: errorMessage,
30148
+ canSkip: true,
30149
+ canRetry: true
30150
+ // Allow manual retry for network errors
30151
+ });
29905
30152
  videoRetryCountRef.current = 0;
29906
30153
  trackCoreEvent("clips_video_error_final", {
29907
30154
  workspaceId,
29908
30155
  category: activeFilterRef.current,
29909
30156
  videoId: currentVideo?.id,
29910
- attempts: videoRetryCountRef.current
30157
+ errorCode,
30158
+ errorMessage,
30159
+ attempts: 3
29911
30160
  });
29912
30161
  }
29913
- }, [currentVideo, workspaceId]);
30162
+ }, [currentVideo, workspaceId, clearLoadingState]);
29914
30163
  useEffect(() => {
29915
30164
  isMountedRef.current = true;
29916
30165
  return () => {
@@ -29928,9 +30177,13 @@ var BottlenecksContent = ({
29928
30177
  }, [s3ClipsService]);
29929
30178
  useEffect(() => {
29930
30179
  if (filteredVideos.length > 0 && currentIndex < filteredVideos.length) {
30180
+ if (error && error.type === "fatal") {
30181
+ console.log("[BottlenecksContent] Not clearing fatal error on video change - let user handle it");
30182
+ return;
30183
+ }
29931
30184
  setError(null);
29932
30185
  }
29933
- }, [currentIndex, filteredVideos]);
30186
+ }, [currentIndex, filteredVideos, error]);
29934
30187
  useEffect(() => {
29935
30188
  if (!isTransitioning && pendingVideo) {
29936
30189
  const timer = setTimeout(() => {
@@ -30005,11 +30258,11 @@ var BottlenecksContent = ({
30005
30258
  if ((isLoading || clipTypesLoading) && allVideos.length === 0 && Object.keys(mergedCounts).length === 0) {
30006
30259
  return /* @__PURE__ */ jsx("div", { className: "flex-grow p-4 flex items-center justify-center h-[calc(100vh-12rem)]", children: /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "lg", message: "Loading clips..." }) });
30007
30260
  }
30008
- if (error || clipTypesError) {
30261
+ if (error && error.type === "fatal" && !hasInitialLoad || clipTypesError) {
30009
30262
  return /* @__PURE__ */ jsxs("div", { className: "flex-grow p-4 flex flex-col items-center justify-center h-[calc(100vh-12rem)] text-center", children: [
30010
30263
  /* @__PURE__ */ jsx(XCircle, { className: "w-12 h-12 text-red-400 mb-3" }),
30011
30264
  /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-red-700 mb-1", children: "Error Loading Clips" }),
30012
- /* @__PURE__ */ jsx("p", { className: "text-gray-600 max-w-md", children: error || clipTypesError })
30265
+ /* @__PURE__ */ jsx("p", { className: "text-gray-600 max-w-md", children: error?.message || clipTypesError })
30013
30266
  ] });
30014
30267
  }
30015
30268
  const categoriesToShow = clipTypes.length > 0 ? clipTypes : [];
@@ -30056,7 +30309,7 @@ var BottlenecksContent = ({
30056
30309
  ),
30057
30310
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-1", children: [
30058
30311
  /* @__PURE__ */ jsx("span", { className: "text-sm px-2 py-1 bg-blue-50 text-blue-700 rounded-full font-medium tabular-nums", children: categoryMetadata.length > 0 ? `${currentMetadataIndex + 1} / ${categoryMetadata.length}` : "0 / 0" }),
30059
- error && /* @__PURE__ */ jsx("span", { className: "text-xs text-red-600 font-medium", children: error })
30312
+ error && error.type === "retrying" && /* @__PURE__ */ jsx("span", { className: "text-xs text-orange-600 font-medium", children: error.message })
30060
30313
  ] }),
30061
30314
  /* @__PURE__ */ jsx(
30062
30315
  "button",
@@ -30070,7 +30323,6 @@ var BottlenecksContent = ({
30070
30323
  )
30071
30324
  ] })
30072
30325
  ] }) }),
30073
- /* Show video if we have filtered videos and current video, or show loading */
30074
30326
  filteredVideos.length > 0 && currentVideo ? /* @__PURE__ */ jsx("div", { className: "p-4 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: [
30075
30327
  /* @__PURE__ */ jsx(
30076
30328
  CroppedVideoPlayer,
@@ -30102,30 +30354,44 @@ var BottlenecksContent = ({
30102
30354
  }
30103
30355
  }
30104
30356
  ),
30105
- (isTransitioning || isVideoBuffering && isInitialLoading) && /* @__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..." }) }),
30106
- !isTransitioning && isVideoBuffering && !isInitialLoading && /* @__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..." }) }),
30107
- error && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-black/80 text-white p-4", children: /* @__PURE__ */ jsxs("div", { className: "text-center max-w-md", children: [
30357
+ (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..." }) }),
30358
+ !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..." }) }),
30359
+ error && error.type === "retrying" && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-40 flex items-center justify-center bg-black/60", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
30360
+ /* @__PURE__ */ jsx(OptifyeLogoLoader_default, { size: "md" }),
30361
+ /* @__PURE__ */ jsx("p", { className: "text-white text-sm mt-4 font-medium", children: error.message })
30362
+ ] }) }),
30363
+ error && error.type === "fatal" && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-50 flex items-center justify-center bg-black/90 text-white p-4", children: /* @__PURE__ */ jsxs("div", { className: "text-center max-w-md", children: [
30108
30364
  /* @__PURE__ */ jsx("svg", { className: "w-16 h-16 mx-auto mb-4 text-red-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.732-.833-2.5 0L4.268 16.5c-.77.833.192 2.5 1.732 2.5z" }) }),
30109
- /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold mb-2", children: "Video Stream Error" }),
30110
- /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-300 mb-4", children: "The video stream appears to be corrupted or unavailable. This may be due to:" }),
30111
- /* @__PURE__ */ jsxs("ul", { className: "text-sm text-gray-300 text-left space-y-1 mb-4", children: [
30112
- /* @__PURE__ */ jsx("li", { children: "\u2022 Incomplete video encoding" }),
30113
- /* @__PURE__ */ jsx("li", { children: "\u2022 Network connectivity issues" }),
30114
- /* @__PURE__ */ jsx("li", { children: "\u2022 Server processing errors" })
30115
- ] }),
30116
- /* @__PURE__ */ jsx(
30117
- "button",
30118
- {
30119
- onClick: () => {
30120
- setError(null);
30121
- if (videoRef.current) {
30122
- videoRef.current.dispose();
30123
- }
30124
- },
30125
- className: "px-4 py-2 bg-blue-600 hover:bg-blue-700 rounded text-sm font-medium",
30126
- children: "Retry"
30127
- }
30128
- )
30365
+ /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold mb-2", children: error.code === 3 ? "Stream Corrupted" : error.code === 4 ? "Format Not Supported" : error.code === 2 ? "Network Error" : error.code === 1 ? "Loading Interrupted" : "Playback Error" }),
30366
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-300 mb-6", children: error.message }),
30367
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-3 justify-center", children: [
30368
+ error.canSkip && /* @__PURE__ */ jsx(
30369
+ "button",
30370
+ {
30371
+ onClick: () => {
30372
+ setError(null);
30373
+ videoRetryCountRef.current = 0;
30374
+ handleNext();
30375
+ },
30376
+ className: "px-5 py-2.5 bg-blue-600 hover:bg-blue-700 rounded-md text-sm font-medium transition-colors",
30377
+ children: "Skip to Next Clip"
30378
+ }
30379
+ ),
30380
+ error.canRetry && /* @__PURE__ */ jsx(
30381
+ "button",
30382
+ {
30383
+ onClick: () => {
30384
+ setError(null);
30385
+ videoRetryCountRef.current = 0;
30386
+ if (videoRef.current) {
30387
+ videoRef.current.dispose();
30388
+ }
30389
+ },
30390
+ className: "px-5 py-2.5 bg-gray-600 hover:bg-gray-700 rounded-md text-sm font-medium transition-colors",
30391
+ children: "Retry"
30392
+ }
30393
+ )
30394
+ ] })
30129
30395
  ] }) }),
30130
30396
  (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-3 left-3 z-10 bg-black/60 backdrop-blur-sm px-3 py-1.5 rounded-lg text-white shadow-lg text-xs", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
30131
30397
  /* @__PURE__ */ jsx("div", { className: `flex-shrink-0 h-2.5 w-2.5 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` }),
@@ -36859,6 +37125,8 @@ function HomeView({
36859
37125
  const [errorMessage, setErrorMessage] = useState(null);
36860
37126
  const [displayNamesInitialized, setDisplayNamesInitialized] = useState(false);
36861
37127
  const [hasInitialDataLoaded, setHasInitialDataLoaded] = useState(false);
37128
+ const [axelSuggestion, setAxelSuggestion] = useState(null);
37129
+ const [showAxelNotification, setShowAxelNotification] = useState(false);
36862
37130
  const dashboardConfig = useDashboardConfig();
36863
37131
  const timezone = useAppTimezone();
36864
37132
  useEffect(() => {
@@ -36933,12 +37201,7 @@ function HomeView({
36933
37201
  }, []);
36934
37202
  const handleWorkspaceHoverEnd = useCallback((workspaceId) => {
36935
37203
  }, []);
36936
- const memoizedWorkspaceMetrics = useMemo(() => workspaceMetrics, [
36937
- // Only update reference if meaningful properties change
36938
- workspaceMetrics.length,
36939
- // Use stable string representation instead of spreading array
36940
- JSON.stringify(workspaceMetrics.map((w) => `${w.workspace_uuid}-${Math.round(w.efficiency)}-${w.trend}`))
36941
- ]);
37204
+ const memoizedWorkspaceMetrics = workspaceMetrics;
36942
37205
  const memoizedKPIs = useMemo(() => kpis, [
36943
37206
  // Only update reference when values change by at least 1%
36944
37207
  kpis?.efficiency?.value ? Math.round(kpis.efficiency.value) : null,
@@ -36966,6 +37229,9 @@ function HomeView({
36966
37229
  setIsChangingFilter(true);
36967
37230
  setSelectedLineId(value);
36968
37231
  }, []);
37232
+ const handleDismissAxelNotification = useCallback(() => {
37233
+ setShowAxelNotification(false);
37234
+ }, []);
36969
37235
  useEffect(() => {
36970
37236
  if (!metricsLoading && !kpisLoading && isChangingFilter) {
36971
37237
  if (workspaceMetrics.length > 0 || selectedLineId === factoryViewId) {
@@ -37077,6 +37343,14 @@ function HomeView({
37077
37343
  lineNames,
37078
37344
  isVisible: !breaksLoading && !breaksError
37079
37345
  }
37346
+ ),
37347
+ /* @__PURE__ */ jsx(
37348
+ AxelNotificationPopup,
37349
+ {
37350
+ suggestion: axelSuggestion,
37351
+ isVisible: showAxelNotification,
37352
+ onDismiss: handleDismissAxelNotification
37353
+ }
37080
37354
  )
37081
37355
  ] })
37082
37356
  }
@@ -38510,7 +38784,7 @@ var KPIsOverviewView = ({
38510
38784
  var KPIsOverviewView_default = KPIsOverviewView;
38511
38785
  var IsolatedTimer = memo(() => {
38512
38786
  return /* @__PURE__ */ jsx(ISTTimer_default, {});
38513
- }, () => true);
38787
+ });
38514
38788
  IsolatedTimer.displayName = "IsolatedTimer";
38515
38789
  var HeaderRibbon = memo(({
38516
38790
  currentDate,
@@ -38518,42 +38792,49 @@ var HeaderRibbon = memo(({
38518
38792
  shiftId,
38519
38793
  getShiftIcon,
38520
38794
  getShiftName
38521
- }) => /* @__PURE__ */ jsxs(Fragment, { children: [
38522
- /* @__PURE__ */ jsxs("div", { className: "sm:hidden mt-3 flex items-center justify-center gap-2", children: [
38523
- /* @__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: currentMobileDate }) }),
38524
- /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1 px-2.5 py-1 bg-gray-100 rounded-full", children: [
38525
- /* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: getShiftIcon(shiftId) }),
38526
- /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: getShiftName(shiftId) })
38795
+ }) => {
38796
+ const shiftIcon = useMemo(() => getShiftIcon(shiftId), [getShiftIcon, shiftId]);
38797
+ const shiftName = useMemo(() => getShiftName(shiftId), [getShiftName, shiftId]);
38798
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
38799
+ /* @__PURE__ */ jsxs("div", { className: "sm:hidden mt-3 flex items-center justify-center gap-2", children: [
38800
+ /* @__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: currentMobileDate }) }),
38801
+ /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1 px-2.5 py-1 bg-gray-100 rounded-full", children: [
38802
+ /* @__PURE__ */ jsx("div", { className: "text-gray-700 scale-90", children: shiftIcon }),
38803
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-700", children: shiftName })
38804
+ ] }),
38805
+ /* @__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(IsolatedTimer, {}) }) })
38527
38806
  ] }),
38528
- /* @__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(IsolatedTimer, {}) }) })
38529
- ] }),
38530
- /* @__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: [
38531
- /* @__PURE__ */ jsx("div", { className: "text-base md:text-lg font-medium text-blue-600", children: /* @__PURE__ */ jsx(IsolatedTimer, {}) }),
38532
- /* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-300" }),
38533
- /* @__PURE__ */ jsx("span", { className: "text-sm md:text-base font-medium text-blue-600", children: currentDate }),
38534
- /* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-300" }),
38535
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
38536
- /* @__PURE__ */ jsx("div", { className: "text-blue-600", children: getShiftIcon(shiftId) }),
38537
- /* @__PURE__ */ jsxs("span", { className: "text-sm md:text-base font-medium text-blue-600", children: [
38538
- getShiftName(shiftId),
38539
- " Shift"
38807
+ /* @__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: [
38808
+ /* @__PURE__ */ jsx("div", { className: "text-base md:text-lg font-medium text-blue-600", children: /* @__PURE__ */ jsx(IsolatedTimer, {}) }),
38809
+ /* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-300" }),
38810
+ /* @__PURE__ */ jsx("span", { className: "text-sm md:text-base font-medium text-blue-600", children: currentDate }),
38811
+ /* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-blue-300" }),
38812
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
38813
+ /* @__PURE__ */ jsx("div", { className: "text-blue-600", children: shiftIcon }),
38814
+ /* @__PURE__ */ jsxs("span", { className: "text-sm md:text-base font-medium text-blue-600", children: [
38815
+ shiftName,
38816
+ " Shift"
38817
+ ] })
38540
38818
  ] })
38541
- ] })
38542
- ] }) })
38543
- ] }));
38819
+ ] }) })
38820
+ ] });
38821
+ });
38544
38822
  HeaderRibbon.displayName = "HeaderRibbon";
38545
38823
  var MobileWorkspaceCard = memo(({
38546
38824
  workspace,
38547
38825
  rank,
38548
38826
  cardClass,
38549
38827
  onWorkspaceClick,
38550
- getMedalIcon,
38551
- getLineName
38828
+ getMedalIcon
38552
38829
  }) => /* @__PURE__ */ jsxs(
38553
38830
  "div",
38554
38831
  {
38555
38832
  onClick: () => onWorkspaceClick(workspace, rank),
38556
- className: `${cardClass} p-3 rounded-lg border shadow-sm active:scale-[0.98] transition-all cursor-pointer`,
38833
+ className: `${cardClass} p-3 rounded-lg border shadow-sm active:scale-[0.98] transition-all duration-300 cursor-pointer`,
38834
+ style: {
38835
+ willChange: "opacity, transform",
38836
+ animation: "fadeIn 0.3s ease-in-out"
38837
+ },
38557
38838
  children: [
38558
38839
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-2", children: [
38559
38840
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
@@ -38565,8 +38846,8 @@ var MobileWorkspaceCard = memo(({
38565
38846
  getMedalIcon(rank)
38566
38847
  ] }),
38567
38848
  /* @__PURE__ */ jsxs("div", { children: [
38568
- /* @__PURE__ */ jsx("div", { className: "font-semibold text-gray-900", children: getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id) }),
38569
- /* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children: getLineName(workspace.line_id) })
38849
+ /* @__PURE__ */ jsx("div", { className: "font-semibold text-gray-900", children: workspace.displayName }),
38850
+ /* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children: workspace.lineName })
38570
38851
  ] })
38571
38852
  ] }),
38572
38853
  /* @__PURE__ */ jsxs("div", { className: "text-right", children: [
@@ -38596,27 +38877,32 @@ var MobileWorkspaceCard = memo(({
38596
38877
  ] })
38597
38878
  ]
38598
38879
  }
38599
- ));
38880
+ ), (prevProps, nextProps) => {
38881
+ return prevProps.rank === nextProps.rank && prevProps.cardClass === nextProps.cardClass && prevProps.workspace.workspace_uuid === nextProps.workspace.workspace_uuid && prevProps.workspace.efficiency === nextProps.workspace.efficiency && prevProps.workspace.action_count === nextProps.workspace.action_count && prevProps.workspace.action_threshold === nextProps.workspace.action_threshold && prevProps.workspace.avg_cycle_time === nextProps.workspace.avg_cycle_time && prevProps.workspace.displayName === nextProps.workspace.displayName && prevProps.workspace.lineName === nextProps.workspace.lineName && prevProps.onWorkspaceClick === nextProps.onWorkspaceClick && prevProps.getMedalIcon === nextProps.getMedalIcon;
38882
+ });
38600
38883
  MobileWorkspaceCard.displayName = "MobileWorkspaceCard";
38601
38884
  var DesktopWorkspaceRow = memo(({
38602
38885
  workspace,
38603
38886
  index,
38604
38887
  rowClass,
38605
38888
  onWorkspaceClick,
38606
- getMedalIcon,
38607
- getLineName
38889
+ getMedalIcon
38608
38890
  }) => /* @__PURE__ */ jsxs(
38609
38891
  "tr",
38610
38892
  {
38611
38893
  onClick: () => onWorkspaceClick(workspace, index + 1),
38612
- className: `${rowClass} hover:bg-gray-50/90 transition-colors cursor-pointer group`,
38894
+ className: `${rowClass} hover:bg-gray-50/90 transition-all duration-300 cursor-pointer group`,
38895
+ style: {
38896
+ willChange: "opacity, background-color",
38897
+ animation: "fadeIn 0.3s ease-in-out"
38898
+ },
38613
38899
  children: [
38614
38900
  /* @__PURE__ */ jsx("td", { className: "px-3 py-2.5 sm:p-4 text-sm sm:text-base whitespace-nowrap group-hover:font-medium", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
38615
38901
  /* @__PURE__ */ jsx("span", { children: index + 1 }),
38616
38902
  getMedalIcon(index + 1)
38617
38903
  ] }) }),
38618
- /* @__PURE__ */ jsx("td", { className: "px-3 py-2.5 sm:p-4 text-sm sm:text-base whitespace-nowrap", children: /* @__PURE__ */ jsx("div", { className: "font-medium", children: getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id) }) }),
38619
- /* @__PURE__ */ jsx("td", { className: "px-3 py-2.5 sm:p-4 text-sm sm:text-base whitespace-nowrap", children: /* @__PURE__ */ jsx("div", { className: "font-medium", children: getLineName(workspace.line_id) }) }),
38904
+ /* @__PURE__ */ jsx("td", { className: "px-3 py-2.5 sm:p-4 text-sm sm:text-base whitespace-nowrap", children: /* @__PURE__ */ jsx("div", { className: "font-medium", children: workspace.displayName }) }),
38905
+ /* @__PURE__ */ jsx("td", { className: "px-3 py-2.5 sm:p-4 text-sm sm:text-base whitespace-nowrap", children: /* @__PURE__ */ jsx("div", { className: "font-medium", children: workspace.lineName }) }),
38620
38906
  /* @__PURE__ */ jsxs("td", { className: "px-3 py-2.5 sm:p-4 text-sm sm:text-base font-medium whitespace-nowrap", children: [
38621
38907
  (workspace.efficiency || 0).toFixed(1),
38622
38908
  "%"
@@ -38634,7 +38920,9 @@ var DesktopWorkspaceRow = memo(({
38634
38920
  ] })
38635
38921
  ]
38636
38922
  }
38637
- ));
38923
+ ), (prevProps, nextProps) => {
38924
+ return prevProps.index === nextProps.index && prevProps.rowClass === nextProps.rowClass && prevProps.workspace.workspace_uuid === nextProps.workspace.workspace_uuid && prevProps.workspace.efficiency === nextProps.workspace.efficiency && prevProps.workspace.action_count === nextProps.workspace.action_count && prevProps.workspace.action_threshold === nextProps.workspace.action_threshold && prevProps.workspace.avg_cycle_time === nextProps.workspace.avg_cycle_time && prevProps.workspace.displayName === nextProps.workspace.displayName && prevProps.workspace.lineName === nextProps.workspace.lineName && prevProps.onWorkspaceClick === nextProps.onWorkspaceClick && prevProps.getMedalIcon === nextProps.getMedalIcon;
38925
+ });
38638
38926
  DesktopWorkspaceRow.displayName = "DesktopWorkspaceRow";
38639
38927
  var LeaderboardDetailView = memo(({
38640
38928
  lineId,
@@ -38650,6 +38938,13 @@ var LeaderboardDetailView = memo(({
38650
38938
  const navigation = useNavigation();
38651
38939
  const entityConfig = useEntityConfig();
38652
38940
  const [sortAscending, setSortAscending] = useState(false);
38941
+ const [isMobile, setIsMobile] = useState(false);
38942
+ React21__default.useEffect(() => {
38943
+ const checkMobile = () => setIsMobile(window.innerWidth < 640);
38944
+ checkMobile();
38945
+ window.addEventListener("resize", checkMobile);
38946
+ return () => window.removeEventListener("resize", checkMobile);
38947
+ }, []);
38653
38948
  const configuredLineNames = useMemo(() => {
38654
38949
  return getAllLineDisplayNames(entityConfig);
38655
38950
  }, [entityConfig]);
@@ -38667,18 +38962,10 @@ var LeaderboardDetailView = memo(({
38667
38962
  const handleSortToggle = useCallback(() => {
38668
38963
  setSortAscending(!sortAscending);
38669
38964
  }, [sortAscending]);
38670
- const realtimeMetricsParams = useMemo(() => ({
38671
- lineId: lineId || "",
38672
- date,
38673
- shiftId: typeof shift === "number" ? shift : typeof shift === "string" ? parseInt(shift) : void 0
38674
- }), [lineId, date, shift]);
38675
- const {
38676
- metrics: metrics2,
38677
- lineDetails,
38678
- loading: metricsLoading,
38679
- error: metricsError,
38680
- refreshMetrics
38681
- } = useRealtimeLineMetrics(realtimeMetricsParams);
38965
+ const shiftId = useMemo(
38966
+ () => typeof shift === "number" ? shift : typeof shift === "string" ? parseInt(shift) : void 0,
38967
+ [shift]
38968
+ );
38682
38969
  const {
38683
38970
  workspaces,
38684
38971
  loading: workspacesLoading,
@@ -38688,12 +38975,12 @@ var LeaderboardDetailView = memo(({
38688
38975
  initialDate: date,
38689
38976
  initialShiftId: typeof shift === "number" ? shift : typeof shift === "string" ? parseInt(shift) : void 0
38690
38977
  });
38691
- const getShiftName = useCallback((shiftId) => {
38692
- if (shiftId === void 0) return "Day";
38693
- return shiftId === 0 ? "Day" : "Night";
38978
+ const getShiftName = useCallback((shiftId2) => {
38979
+ if (shiftId2 === void 0) return "Day";
38980
+ return shiftId2 === 0 ? "Day" : "Night";
38694
38981
  }, []);
38695
- const getShiftIcon = useCallback((shiftId) => {
38696
- const shift2 = getShiftName(shiftId);
38982
+ const getShiftIcon = useCallback((shiftId2) => {
38983
+ const shift2 = getShiftName(shiftId2);
38697
38984
  if (shift2 === "Day") {
38698
38985
  return /* @__PURE__ */ jsx("svg", { className: "w-4 h-4", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" }) });
38699
38986
  } else {
@@ -38735,17 +39022,18 @@ var LeaderboardDetailView = memo(({
38735
39022
  return null;
38736
39023
  }
38737
39024
  }, [sortAscending]);
39025
+ const workspacesLength = useMemo(() => workspaces?.length || 0, [workspaces?.length]);
38738
39026
  const handleWorkspaceClick = useCallback((workspace, rank) => {
38739
39027
  trackCoreEvent("Workspace from Leaderboard Clicked", {
38740
39028
  workspace_name: workspace.workspace_name,
38741
39029
  workspace_id: workspace.workspace_uuid,
38742
39030
  rank,
38743
- total_workspaces: workspaces?.length || 0,
39031
+ total_workspaces: workspacesLength,
38744
39032
  efficiency: workspace.efficiency,
38745
39033
  action_count: workspace.action_count,
38746
39034
  action_threshold: workspace.action_threshold
38747
39035
  });
38748
- const displayName = getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id);
39036
+ const displayName = workspace.displayName || getWorkspaceDisplayName(workspace.workspace_name, workspace.line_id);
38749
39037
  const navParams = workspace.workspace_uuid ? getWorkspaceNavigationParams(workspace.workspace_uuid, displayName, workspace.line_id) : "";
38750
39038
  const returnToParam = `&returnTo=${encodeURIComponent(`/leaderboard`)}`;
38751
39039
  if (onWorkspaceClick) {
@@ -38753,20 +39041,33 @@ var LeaderboardDetailView = memo(({
38753
39041
  } else {
38754
39042
  navigation.navigate(`/workspace/${workspace.workspace_uuid}${navParams}${returnToParam}`);
38755
39043
  }
38756
- }, [onWorkspaceClick, navigation, lineId, workspaces?.length]);
38757
- const sortedWorkspaces = useMemo(() => {
39044
+ }, [onWorkspaceClick, navigation, lineId, workspacesLength]);
39045
+ const workspaceDisplayData = useMemo(() => {
38758
39046
  if (!workspaces) return [];
38759
- return [...workspaces].sort((a, b) => {
39047
+ return workspaces.map((ws) => ({
39048
+ ...ws,
39049
+ displayName: getWorkspaceDisplayName(ws.workspace_name, ws.line_id),
39050
+ lineName: getLineName(ws.line_id)
39051
+ }));
39052
+ }, [workspaces, getLineName]);
39053
+ const sortedWorkspaces = useMemo(() => {
39054
+ return [...workspaceDisplayData].sort((a, b) => {
38760
39055
  const effA = a.efficiency || 0;
38761
39056
  const effB = b.efficiency || 0;
38762
39057
  return sortAscending ? effA - effB : effB - effA;
38763
39058
  });
38764
- }, [workspaces, sortAscending]);
38765
- const loading = useMemo(() => metricsLoading || workspacesLoading, [metricsLoading, workspacesLoading]);
38766
- const error = useMemo(() => metricsError || workspacesError, [metricsError, workspacesError]);
38767
- const currentDateFormatted = useMemo(() => formatDate(/* @__PURE__ */ new Date()), [formatDate]);
38768
- const currentMobileDateFormatted = useMemo(() => formatMobileDate(/* @__PURE__ */ new Date()), [formatMobileDate]);
38769
- if (loading) {
39059
+ }, [workspaceDisplayData, sortAscending]);
39060
+ const loading = workspacesLoading;
39061
+ const error = workspacesError;
39062
+ const currentDateFormatted = useMemo(() => {
39063
+ const dateStr = (/* @__PURE__ */ new Date()).toDateString();
39064
+ return formatDate(new Date(dateStr));
39065
+ }, [formatDate, date]);
39066
+ const currentMobileDateFormatted = useMemo(() => {
39067
+ const dateStr = (/* @__PURE__ */ new Date()).toDateString();
39068
+ return formatMobileDate(new Date(dateStr));
39069
+ }, [formatMobileDate, date]);
39070
+ if (loading && (!workspaces || workspaces.length === 0)) {
38770
39071
  return /* @__PURE__ */ jsx("div", { className: `h-[calc(100vh-64px)] flex items-center justify-center bg-slate-50 ${className}`, children: /* @__PURE__ */ jsx("div", { className: "text-xl text-gray-600", children: "Loading workspaces..." }) });
38771
39072
  }
38772
39073
  if (error) {
@@ -38775,7 +39076,7 @@ var LeaderboardDetailView = memo(({
38775
39076
  error.message
38776
39077
  ] }) });
38777
39078
  }
38778
- return /* @__PURE__ */ jsxs("div", { className: `min-h-screen bg-slate-50 flex flex-col ${className}`, children: [
39079
+ return /* @__PURE__ */ jsxs("div", { className: `min-h-screen bg-slate-50 flex flex-col ${className}`, style: { willChange: "contents" }, children: [
38779
39080
  /* @__PURE__ */ jsx("div", { className: "sticky top-0 z-20 bg-white shadow-sm border-b border-gray-200/80", children: /* @__PURE__ */ jsxs("div", { className: "px-3 sm:px-6 md:px-8 py-2 sm:py-2.5", children: [
38780
39081
  /* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center", children: [
38781
39082
  /* @__PURE__ */ jsx(
@@ -38867,31 +39168,30 @@ var LeaderboardDetailView = memo(({
38867
39168
  {
38868
39169
  currentDate: currentDateFormatted,
38869
39170
  currentMobileDate: currentMobileDateFormatted,
38870
- shiftId: metrics2?.shift_id,
39171
+ shiftId,
38871
39172
  getShiftIcon,
38872
39173
  getShiftName
38873
39174
  }
38874
39175
  )
38875
39176
  ] }) }),
38876
- /* @__PURE__ */ jsxs("div", { className: "flex-1 w-full mx-auto p-3 sm:p-4 md:p-6", children: [
38877
- /* @__PURE__ */ jsx("div", { className: "sm:hidden space-y-3", children: sortedWorkspaces.map((ws, index) => {
38878
- const rank = index + 1;
38879
- const isTopThree = index < 3;
38880
- const cardClass = sortAscending ? isTopThree ? "bg-red-50/90 border-red-200" : "bg-white" : isTopThree ? "bg-green-50/90 border-green-200" : "bg-white";
38881
- return /* @__PURE__ */ jsx(
38882
- MobileWorkspaceCard,
38883
- {
38884
- workspace: ws,
38885
- rank,
38886
- cardClass,
38887
- onWorkspaceClick: handleWorkspaceClick,
38888
- getMedalIcon,
38889
- getLineName
38890
- },
38891
- ws.workspace_uuid
38892
- );
38893
- }) }),
38894
- /* @__PURE__ */ jsx("div", { className: "hidden sm:block bg-white rounded-lg shadow-md overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "overflow-auto", children: /* @__PURE__ */ jsxs("table", { className: "w-full border-collapse table-auto", children: [
39177
+ /* @__PURE__ */ jsx("div", { className: "flex-1 w-full mx-auto p-3 sm:p-4 md:p-6", children: isMobile ? /* @__PURE__ */ jsx("div", { className: "space-y-3", children: sortedWorkspaces.map((ws, index) => {
39178
+ const rank = index + 1;
39179
+ const isTopThree = index < 3;
39180
+ const cardClass = sortAscending ? isTopThree ? "bg-red-50/90 border-red-200" : "bg-white" : isTopThree ? "bg-green-50/90 border-green-200" : "bg-white";
39181
+ return /* @__PURE__ */ jsx(
39182
+ MobileWorkspaceCard,
39183
+ {
39184
+ workspace: ws,
39185
+ rank,
39186
+ cardClass,
39187
+ onWorkspaceClick: handleWorkspaceClick,
39188
+ getMedalIcon
39189
+ },
39190
+ ws.workspace_uuid
39191
+ );
39192
+ }) }) : (
39193
+ /* Desktop table view - only render on desktop */
39194
+ /* @__PURE__ */ jsx("div", { className: "bg-white rounded-lg shadow-md overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "overflow-auto", children: /* @__PURE__ */ jsxs("table", { className: "w-full border-collapse table-auto", children: [
38895
39195
  /* @__PURE__ */ jsx("thead", { className: "bg-gray-50 border-b border-gray-200 sticky top-0 z-10", children: /* @__PURE__ */ jsxs("tr", { children: [
38896
39196
  /* @__PURE__ */ jsx("th", { className: "px-3 py-2.5 sm:p-4 text-left text-xs sm:text-sm font-semibold text-gray-600 whitespace-nowrap", children: "Rank" }),
38897
39197
  /* @__PURE__ */ jsx("th", { className: "px-3 py-2.5 sm:p-4 text-left text-xs sm:text-sm font-semibold text-gray-600 whitespace-nowrap", children: "Workspace" }),
@@ -38910,17 +39210,16 @@ var LeaderboardDetailView = memo(({
38910
39210
  index,
38911
39211
  rowClass,
38912
39212
  onWorkspaceClick: handleWorkspaceClick,
38913
- getMedalIcon,
38914
- getLineName
39213
+ getMedalIcon
38915
39214
  },
38916
39215
  ws.workspace_uuid
38917
39216
  );
38918
39217
  }) })
38919
39218
  ] }) }) })
38920
- ] })
39219
+ ) })
38921
39220
  ] });
38922
39221
  }, (prevProps, nextProps) => {
38923
- return prevProps.lineId === nextProps.lineId && prevProps.date === nextProps.date && prevProps.shift === nextProps.shift && prevProps.line1Id === nextProps.line1Id && prevProps.line2Id === nextProps.line2Id && JSON.stringify(prevProps.lineNames) === JSON.stringify(nextProps.lineNames) && prevProps.className === nextProps.className && prevProps.onBackClick === nextProps.onBackClick && prevProps.onWorkspaceClick === nextProps.onWorkspaceClick;
39222
+ return prevProps.lineId === nextProps.lineId && prevProps.date === nextProps.date && prevProps.shift === nextProps.shift && prevProps.line1Id === nextProps.line1Id && prevProps.line2Id === nextProps.line2Id && JSON.stringify(prevProps.lineNames) === JSON.stringify(nextProps.lineNames) && prevProps.className === nextProps.className;
38924
39223
  });
38925
39224
  LeaderboardDetailView.displayName = "LeaderboardDetailView";
38926
39225
  var LeaderboardDetailViewWithDisplayNames = withAllWorkspaceDisplayNames(LeaderboardDetailView);
@@ -40029,16 +40328,8 @@ var ACTION_NAMES = {
40029
40328
  // src/views/TargetsView.utils.ts
40030
40329
  var calculatePPH = (cycleTime, breaks = [], shiftHours = 0) => {
40031
40330
  if (cycleTime === "" || cycleTime === 0) return "";
40032
- const basicPPH = 3600 / cycleTime;
40033
- if (breaks.length === 0 || shiftHours === 0) {
40034
- return Number(basicPPH.toFixed(1));
40035
- }
40036
- const safeBreaks = Array.isArray(breaks) ? breaks : [];
40037
- const totalBreakMinutes = safeBreaks.reduce((total, breakItem) => total + breakItem.duration, 0);
40038
- const totalBreakHours = totalBreakMinutes / 60;
40039
- const realWorkHours = shiftHours - totalBreakHours;
40040
- const effectivePPH = basicPPH * (realWorkHours / shiftHours);
40041
- return Number(effectivePPH.toFixed(1));
40331
+ const pph = 3600 / cycleTime;
40332
+ return Number(pph.toFixed(1));
40042
40333
  };
40043
40334
  var calculateDayOutput = (pph, shiftHours, breaks = []) => {
40044
40335
  if (pph === "") return "";
@@ -42634,7 +42925,7 @@ var WorkspaceDetailView = ({
42634
42925
  /* @__PURE__ */ jsxs(Card2, { children: [
42635
42926
  /* @__PURE__ */ jsx(CardHeader2, { className: "pb-2 flex-none", children: /* @__PURE__ */ jsx(CardTitle2, { className: "text-lg text-center", children: "Cycle Time (s)" }) }),
42636
42927
  /* @__PURE__ */ jsx(CardContent2, { className: "flex-1 flex items-center justify-center py-6", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
42637
- /* @__PURE__ */ jsx("p", { className: `text-5xl font-bold text-green-500`, children: workspace.avg_cycle_time.toFixed(1) }),
42928
+ /* @__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) }),
42638
42929
  /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-500 mt-2", children: [
42639
42930
  "Standard: ",
42640
42931
  workspace.ideal_cycle_time?.toFixed(1) || 0,
@@ -42754,7 +43045,7 @@ var WorkspaceDetailView = ({
42754
43045
  /* @__PURE__ */ jsxs(Card2, { children: [
42755
43046
  /* @__PURE__ */ jsx(CardHeader2, { className: "pb-2 flex-none", children: /* @__PURE__ */ jsx(CardTitle2, { className: "text-lg text-center", children: "Cycle Time (s)" }) }),
42756
43047
  /* @__PURE__ */ jsx(CardContent2, { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
42757
- /* @__PURE__ */ jsx("p", { className: `text-5xl font-bold text-green-500`, children: workspace.avg_cycle_time.toFixed(1) }),
43048
+ /* @__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) }),
42758
43049
  /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-500 mt-2", children: [
42759
43050
  "Standard: ",
42760
43051
  workspace.ideal_cycle_time?.toFixed(1) || 0,
@@ -44080,4 +44371,4 @@ function shuffleArray(array) {
44080
44371
  return shuffled;
44081
44372
  }
44082
44373
 
44083
- export { ACTION_NAMES, AIAgentView_default as AIAgentView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedWorkspaceHealthView, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, 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_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, 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, 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, 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, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, 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, createLinesService, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserService, dashboardService, deleteThread, forceRefreshWorkspaceDisplayNames, formatDateInZone, formatDateTimeInZone, formatISTDate, formatIdleTime, formatTimeInZone, fromUrlFriendlyName, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAnonClient, 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, 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, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineWorkspaceMetrics, useMessages, useMetrics, useNavigation, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useShiftConfig, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useTargets, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealth, useWorkspaceHealthById, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, userService, videoPrefetchManager, videoPreloader, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };
44374
+ export { ACTION_NAMES, AIAgentView_default as AIAgentView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedWorkspaceHealthView, AxelNotificationPopup, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, 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_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, 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, 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, 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, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, 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, createLinesService, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserService, dashboardService, deleteThread, forceRefreshWorkspaceDisplayNames, formatDateInZone, formatDateTimeInZone, formatISTDate, formatIdleTime, formatTimeInZone, fromUrlFriendlyName, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAnonClient, 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, 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, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineWorkspaceMetrics, useMessages, useMetrics, useNavigation, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useShiftConfig, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useTargets, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealth, useWorkspaceHealthById, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, userService, videoPrefetchManager, videoPreloader, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };