@optifye/dashboard-core 6.5.2 → 6.5.3

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, X, Coffee, Plus, ArrowLeft, Clock, Calendar, Save, Minus, ArrowDown, ArrowUp, Settings2, CheckCircle2, Search, Loader2, AlertCircle, Edit2, CheckCircle, AlertTriangle, Info, Share2, Trophy, Target, Download, User, XCircle, ChevronLeft, ChevronRight, Sun, Moon, MessageSquare, Trash2, RefreshCw, Menu, Send, Copy, UserCheck, LogOut, Package, TrendingUp, TrendingDown, Activity, Settings, LifeBuoy, EyeOff, Eye, Zap, UserCircle } from 'lucide-react';
16
+ import { Camera, ChevronDown, ChevronUp, Check, ShieldCheck, Star, Award, X, Coffee, Plus, ArrowLeft, Clock, Calendar, Save, Minus, ArrowDown, ArrowUp, Settings2, CheckCircle2, Search, Loader2, AlertCircle, Edit2, CheckCircle, AlertTriangle, Info, Share2, Trophy, Target, Download, User, XCircle, ChevronLeft, ChevronRight, Activity, Sun, Moon, MessageSquare, Trash2, RefreshCw, Menu, Send, Copy, UserCheck, LogOut, Package, TrendingUp, TrendingDown, 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, CubeIcon, SparklesIcon, QuestionMarkCircleIcon, HeartIcon, UserCircleIcon, ExclamationCircleIcon, EnvelopeIcon, DocumentTextIcon, ChevronUpIcon, ChevronDownIcon, Bars3Icon, CheckCircleIcon, ChatBubbleLeftRightIcon, XCircleIcon, InformationCircleIcon, ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/outline';
19
19
  import { CheckIcon } from '@heroicons/react/24/solid';
@@ -1875,7 +1875,29 @@ var WorkspaceHealthService = class _WorkspaceHealthService {
1875
1875
  throw error;
1876
1876
  }
1877
1877
  const processedData = (data || []).map((item) => this.processHealthStatus(item));
1878
- let filteredData = processedData;
1878
+ let uptimeMap = /* @__PURE__ */ new Map();
1879
+ if (options.companyId || data && data.length > 0) {
1880
+ const companyId = options.companyId || data[0]?.company_id;
1881
+ if (companyId) {
1882
+ try {
1883
+ uptimeMap = await this.calculateWorkspaceUptime(companyId);
1884
+ } catch (error2) {
1885
+ console.error("Error calculating uptime:", error2);
1886
+ }
1887
+ }
1888
+ }
1889
+ const dataWithUptime = processedData.map((workspace) => {
1890
+ const uptimeDetails = uptimeMap.get(workspace.workspace_id);
1891
+ if (uptimeDetails) {
1892
+ return {
1893
+ ...workspace,
1894
+ uptimePercentage: uptimeDetails.percentage,
1895
+ uptimeDetails
1896
+ };
1897
+ }
1898
+ return workspace;
1899
+ });
1900
+ let filteredData = dataWithUptime;
1879
1901
  try {
1880
1902
  const { data: enabledWorkspaces, error: workspaceError } = await supabase.from("workspaces").select("workspace_id, display_name").eq("enable", true);
1881
1903
  if (!workspaceError && enabledWorkspaces && enabledWorkspaces.length > 0) {
@@ -1951,13 +1973,31 @@ var WorkspaceHealthService = class _WorkspaceHealthService {
1951
1973
  const healthyWorkspaces = workspaces.filter((w) => w.status === "healthy").length;
1952
1974
  const unhealthyWorkspaces = workspaces.filter((w) => w.status === "unhealthy").length;
1953
1975
  const warningWorkspaces = workspaces.filter((w) => w.status === "warning").length;
1954
- const uptimePercentage = totalWorkspaces > 0 ? healthyWorkspaces / totalWorkspaces * 100 : 0;
1976
+ let uptimePercentage = 0;
1977
+ let totalDowntimeMinutes = 0;
1978
+ if (totalWorkspaces > 0) {
1979
+ const workspacesWithUptime = workspaces.filter((w) => w.uptimePercentage !== void 0 && w.uptimeDetails !== void 0);
1980
+ if (workspacesWithUptime.length > 0) {
1981
+ const totalUptime = workspacesWithUptime.reduce((sum, w) => sum + (w.uptimePercentage || 0), 0);
1982
+ uptimePercentage = totalUptime / workspacesWithUptime.length;
1983
+ totalDowntimeMinutes = workspacesWithUptime.reduce((sum, w) => {
1984
+ if (w.uptimeDetails) {
1985
+ const downtime = Math.max(0, w.uptimeDetails.expectedMinutes - w.uptimeDetails.actualMinutes);
1986
+ return sum + downtime;
1987
+ }
1988
+ return sum;
1989
+ }, 0);
1990
+ } else {
1991
+ uptimePercentage = healthyWorkspaces / totalWorkspaces * 100;
1992
+ }
1993
+ }
1955
1994
  return {
1956
1995
  totalWorkspaces,
1957
1996
  healthyWorkspaces,
1958
1997
  unhealthyWorkspaces,
1959
1998
  warningWorkspaces,
1960
1999
  uptimePercentage,
2000
+ totalDowntimeMinutes,
1961
2001
  lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
1962
2002
  };
1963
2003
  }
@@ -2037,6 +2077,155 @@ var WorkspaceHealthService = class _WorkspaceHealthService {
2037
2077
  clearCache() {
2038
2078
  this.cache.clear();
2039
2079
  }
2080
+ async calculateWorkspaceUptime(companyId) {
2081
+ const supabase = _getSupabaseInstance();
2082
+ if (!supabase) throw new Error("Supabase client not initialized");
2083
+ const dashboardConfig = _getDashboardConfigInstance();
2084
+ const timezone = dashboardConfig?.dateTimeConfig?.defaultTimezone || "UTC";
2085
+ const shiftConfig = dashboardConfig?.shiftConfig;
2086
+ const currentShiftInfo = getCurrentShift(timezone, shiftConfig);
2087
+ const currentDate = currentShiftInfo.date;
2088
+ const currentShiftId = currentShiftInfo.shiftId;
2089
+ const now2 = /* @__PURE__ */ new Date();
2090
+ const currentHour = now2.getHours();
2091
+ const currentMinute = now2.getMinutes();
2092
+ let shiftStartHour;
2093
+ let shiftEndHour;
2094
+ if (currentShiftId === 0) {
2095
+ shiftStartHour = 9;
2096
+ shiftEndHour = 18;
2097
+ } else {
2098
+ shiftStartHour = 20;
2099
+ shiftEndHour = 3;
2100
+ }
2101
+ let elapsedMinutes = 0;
2102
+ if (currentShiftId === 0) {
2103
+ if (currentHour >= shiftStartHour && currentHour < shiftEndHour) {
2104
+ elapsedMinutes = (currentHour - shiftStartHour) * 60 + currentMinute;
2105
+ } else if (currentHour >= shiftEndHour) {
2106
+ elapsedMinutes = (shiftEndHour - shiftStartHour) * 60;
2107
+ }
2108
+ } else {
2109
+ if (currentHour >= shiftStartHour) {
2110
+ elapsedMinutes = (currentHour - shiftStartHour) * 60 + currentMinute;
2111
+ } else if (currentHour < shiftEndHour) {
2112
+ elapsedMinutes = (24 - shiftStartHour + currentHour) * 60 + currentMinute;
2113
+ }
2114
+ }
2115
+ const tableName = `performance_metrics_${companyId.replace(/-/g, "_")}`;
2116
+ const query = `
2117
+ WITH workspace_uptime AS (
2118
+ SELECT
2119
+ workspace_id,
2120
+ workspace_display_name,
2121
+ idle_time_hourly,
2122
+ output_hourly,
2123
+ shift_start,
2124
+ shift_end
2125
+ FROM ${tableName}
2126
+ WHERE date = $1::date
2127
+ AND shift_id = $2
2128
+ ),
2129
+ calculated_uptime AS (
2130
+ SELECT
2131
+ workspace_id,
2132
+ workspace_display_name,
2133
+ -- Calculate actual minutes from hourly data
2134
+ (
2135
+ SELECT COALESCE(SUM(
2136
+ CASE
2137
+ WHEN jsonb_array_length(idle_time_hourly->key::text) >= 58 THEN 60
2138
+ WHEN jsonb_array_length(idle_time_hourly->key::text) > 0 THEN jsonb_array_length(idle_time_hourly->key::text)
2139
+ ELSE 0
2140
+ END
2141
+ ), 0)
2142
+ FROM jsonb_object_keys(idle_time_hourly) AS key
2143
+ WHERE key::int >= $3 AND key::int < $4
2144
+ ) +
2145
+ -- Add current hour's data if applicable
2146
+ CASE
2147
+ WHEN $4::int >= $3 AND $4::int < $5 THEN
2148
+ LEAST($6::int,
2149
+ COALESCE(jsonb_array_length(idle_time_hourly->$4::text), 0))
2150
+ ELSE 0
2151
+ END as actual_minutes
2152
+ FROM workspace_uptime
2153
+ )
2154
+ SELECT
2155
+ workspace_id,
2156
+ workspace_display_name,
2157
+ actual_minutes,
2158
+ $7::int as expected_minutes,
2159
+ ROUND(
2160
+ CASE
2161
+ WHEN $7::int > 0 THEN (actual_minutes::numeric / $7::numeric) * 100
2162
+ ELSE 100
2163
+ END, 1
2164
+ ) as uptime_percentage
2165
+ FROM calculated_uptime
2166
+ `;
2167
+ try {
2168
+ const { data, error } = await supabase.rpc("sql_query", {
2169
+ query_text: query,
2170
+ params: [
2171
+ currentDate,
2172
+ currentShiftId,
2173
+ shiftStartHour,
2174
+ currentHour,
2175
+ shiftEndHour,
2176
+ currentMinute,
2177
+ elapsedMinutes
2178
+ ]
2179
+ }).single();
2180
+ if (error) {
2181
+ const { data: queryData, error: queryError } = await supabase.from(tableName).select("workspace_id, workspace_display_name, idle_time_hourly, output_hourly").eq("date", currentDate).eq("shift_id", currentShiftId);
2182
+ if (queryError) {
2183
+ console.error("Error fetching performance metrics:", queryError);
2184
+ return /* @__PURE__ */ new Map();
2185
+ }
2186
+ const uptimeMap2 = /* @__PURE__ */ new Map();
2187
+ for (const record of queryData || []) {
2188
+ let actualMinutes = 0;
2189
+ const idleTimeHourly = record.idle_time_hourly || {};
2190
+ if (idleTimeHourly && typeof idleTimeHourly === "object") {
2191
+ for (const [hour, dataArray] of Object.entries(idleTimeHourly)) {
2192
+ const hourNum = parseInt(hour);
2193
+ if (hourNum >= shiftStartHour && hourNum < currentHour) {
2194
+ const arrayLength = Array.isArray(dataArray) ? dataArray.length : 0;
2195
+ actualMinutes += arrayLength >= 58 ? 60 : arrayLength;
2196
+ } else if (hourNum === currentHour && currentHour >= shiftStartHour) {
2197
+ const arrayLength = Array.isArray(dataArray) ? dataArray.length : 0;
2198
+ actualMinutes += Math.min(currentMinute, arrayLength);
2199
+ }
2200
+ }
2201
+ }
2202
+ const percentage = elapsedMinutes > 0 ? Math.round(actualMinutes / elapsedMinutes * 1e3) / 10 : 100;
2203
+ uptimeMap2.set(record.workspace_id, {
2204
+ expectedMinutes: elapsedMinutes,
2205
+ actualMinutes,
2206
+ percentage,
2207
+ lastCalculated: (/* @__PURE__ */ new Date()).toISOString()
2208
+ });
2209
+ }
2210
+ return uptimeMap2;
2211
+ }
2212
+ const uptimeMap = /* @__PURE__ */ new Map();
2213
+ if (Array.isArray(data)) {
2214
+ for (const record of data) {
2215
+ uptimeMap.set(record.workspace_id, {
2216
+ expectedMinutes: record.expected_minutes,
2217
+ actualMinutes: record.actual_minutes,
2218
+ percentage: record.uptime_percentage,
2219
+ lastCalculated: (/* @__PURE__ */ new Date()).toISOString()
2220
+ });
2221
+ }
2222
+ }
2223
+ return uptimeMap;
2224
+ } catch (error) {
2225
+ console.error("Error calculating workspace uptime:", error);
2226
+ return /* @__PURE__ */ new Map();
2227
+ }
2228
+ }
2040
2229
  };
2041
2230
  var workspaceHealthService = WorkspaceHealthService.getInstance();
2042
2231
 
@@ -19695,7 +19884,7 @@ var OptifyeLogoLoader = ({
19695
19884
  className: `${sizeClasses[size]} h-auto animate-pulse select-none pointer-events-none`
19696
19885
  }
19697
19886
  ),
19698
- message && /* @__PURE__ */ jsx("div", { className: "mt-3 text-gray-600 text-sm font-medium text-center", children: message })
19887
+ message && /* @__PURE__ */ jsx("div", { className: "mt-3 text-gray-600 text-base sm:text-sm font-medium text-center", children: message })
19699
19888
  ]
19700
19889
  }
19701
19890
  );
@@ -21606,8 +21795,8 @@ var VideoCard = React19__default.memo(({
21606
21795
  ] }) }),
21607
21796
  /* @__PURE__ */ jsxs("div", { className: "relative w-full h-full overflow-hidden bg-black", children: [
21608
21797
  /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-black z-0", children: /* @__PURE__ */ jsxs("div", { className: "animate-pulse flex flex-col items-center", children: [
21609
- /* @__PURE__ */ jsx(Camera, { className: `${compact ? "w-4 h-4" : "w-6 h-6"} text-gray-500` }),
21610
- /* @__PURE__ */ jsx("span", { className: `${compact ? "text-[10px]" : "text-xs"} text-gray-500 mt-1`, children: "Loading..." })
21798
+ /* @__PURE__ */ jsx(Camera, { className: `w-5 h-5 sm:${compact ? "w-4 h-4" : "w-6 h-6"} text-gray-500` }),
21799
+ /* @__PURE__ */ jsx("span", { className: `text-[11px] sm:${compact ? "text-[10px]" : "text-xs"} text-gray-500 mt-1`, children: "Loading..." })
21611
21800
  ] }) }),
21612
21801
  /* @__PURE__ */ jsxs("div", { className: "absolute inset-0 z-10", children: [
21613
21802
  /* @__PURE__ */ jsx(
@@ -21642,10 +21831,10 @@ var VideoCard = React19__default.memo(({
21642
21831
  }
21643
21832
  ) })
21644
21833
  ] }),
21645
- /* @__PURE__ */ jsxs("div", { className: `absolute bottom-0 left-0 right-0 bg-black bg-opacity-60 ${compact ? "p-1" : "p-1.5"} flex justify-between items-center z-10`, children: [
21834
+ /* @__PURE__ */ jsxs("div", { className: `absolute bottom-0 left-0 right-0 bg-black bg-opacity-60 p-1.5 sm:${compact ? "p-1" : "p-1.5"} flex justify-between items-center z-10`, children: [
21646
21835
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
21647
21836
  /* @__PURE__ */ jsx(Camera, { size: compact ? 10 : 12, className: "text-white" }),
21648
- /* @__PURE__ */ jsx("p", { className: `text-white ${compact ? "text-[10px]" : "text-xs"} font-medium tracking-wide`, children: displayName })
21837
+ /* @__PURE__ */ jsx("p", { className: `text-white text-[11px] sm:${compact ? "text-[10px]" : "text-xs"} font-medium tracking-wide`, children: displayName })
21649
21838
  ] }),
21650
21839
  /* @__PURE__ */ jsxs("div", { className: `flex items-center ${compact ? "gap-1" : "gap-1.5"}`, children: [
21651
21840
  trendInfo && /* @__PURE__ */ jsx(
@@ -21657,7 +21846,7 @@ var VideoCard = React19__default.memo(({
21657
21846
  }
21658
21847
  ),
21659
21848
  /* @__PURE__ */ jsx("div", { className: `${compact ? "w-1 h-1" : "w-1.5 h-1.5"} rounded-full bg-green-500` }),
21660
- /* @__PURE__ */ jsx("span", { className: `text-white ${compact ? "text-[10px]" : "text-xs"}`, children: "Live" })
21849
+ /* @__PURE__ */ jsx("span", { className: `text-white text-[11px] sm:${compact ? "text-[10px]" : "text-xs"}`, children: "Live" })
21661
21850
  ] })
21662
21851
  ] })
21663
21852
  ]
@@ -21867,10 +22056,10 @@ var VideoGridView = React19__default.memo(({
21867
22056
  view_type: "video_grid"
21868
22057
  });
21869
22058
  }, []);
21870
- return /* @__PURE__ */ jsx("div", { className: `relative overflow-hidden h-full w-full ${className}`, children: /* @__PURE__ */ jsx("div", { ref: containerRef, className: "h-full w-full p-2", children: /* @__PURE__ */ jsx(
22059
+ return /* @__PURE__ */ jsx("div", { className: `relative overflow-hidden h-full w-full ${className}`, children: /* @__PURE__ */ jsx("div", { ref: containerRef, className: "h-full w-full p-3 sm:p-2", children: /* @__PURE__ */ jsx(
21871
22060
  "div",
21872
22061
  {
21873
- className: "grid h-full w-full gap-2",
22062
+ className: "grid h-full w-full gap-3 sm:gap-2",
21874
22063
  style: {
21875
22064
  gridTemplateColumns: `repeat(${gridCols}, 1fr)`,
21876
22065
  gridTemplateRows: `repeat(${gridRows}, 1fr)`,
@@ -22655,15 +22844,15 @@ var BreakNotificationPopup = ({
22655
22844
  /* @__PURE__ */ jsx("div", { className: "w-2 h-2 bg-amber-500 rounded-full animate-pulse flex-shrink-0 mt-2" }),
22656
22845
  /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
22657
22846
  /* @__PURE__ */ jsxs("div", { className: "mb-1", children: [
22658
- /* @__PURE__ */ jsx("h4", { className: "font-semibold text-sm text-gray-900", children: breakItem.remarks || "Break" }),
22659
- (activeBreaks.length > 1 || lineNames[breakItem.lineId]) && /* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500 mt-0.5", children: lineNames[breakItem.lineId] || `Line ${breakItem.lineId.substring(0, 8)}` })
22847
+ /* @__PURE__ */ jsx("h4", { className: "font-semibold text-base sm:text-sm text-gray-900", children: breakItem.remarks || "Break" }),
22848
+ (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)}` })
22660
22849
  ] }),
22661
- /* @__PURE__ */ jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxs("div", { className: "text-xs text-gray-600 font-medium", children: [
22850
+ /* @__PURE__ */ jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxs("div", { className: "text-sm sm:text-xs text-gray-600 font-medium", children: [
22662
22851
  breakItem.startTime,
22663
22852
  " - ",
22664
22853
  breakItem.endTime
22665
22854
  ] }) }),
22666
- /* @__PURE__ */ jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxs("div", { className: "text-xs text-gray-500", children: [
22855
+ /* @__PURE__ */ jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxs("div", { className: "text-sm sm:text-xs text-gray-500", children: [
22667
22856
  formatTime3(breakItem.elapsedMinutes),
22668
22857
  " / ",
22669
22858
  formatTime3(breakItem.duration)
@@ -23381,7 +23570,7 @@ var TimeDisplay = ({ className, variant = "default" }) => {
23381
23570
  className: `flex items-center space-x-1.5 bg-white/60 backdrop-blur-sm px-2 py-0.5 rounded-md shadow-xs ${className || ""}`,
23382
23571
  children: [
23383
23572
  /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-3 w-3 text-[var(--primary-DEFAULT)]", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z", clipRule: "evenodd" }) }),
23384
- /* @__PURE__ */ jsxs("span", { className: "text-[11px] font-medium text-gray-800 tabular-nums tracking-tight", children: [
23573
+ /* @__PURE__ */ jsxs("span", { className: "text-xs sm:text-[11px] font-medium text-gray-800 tabular-nums tracking-tight", children: [
23385
23574
  time2,
23386
23575
  " ",
23387
23576
  timeSuffix
@@ -28057,7 +28246,7 @@ var WorkspaceGridItem = React19__default.memo(({
28057
28246
  isVeryLowEfficiency && !isInactive && /* @__PURE__ */ jsx("div", { className: "absolute -top-10 left-1/2 -translate-x-1/2 z-30", children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
28058
28247
  /* @__PURE__ */ jsx("div", { className: "absolute -inset-1 bg-red-400/50 rounded-full blur-sm animate-pulse" }),
28059
28248
  /* @__PURE__ */ jsx("div", { className: "absolute -inset-0.5 bg-red-500/30 rounded-full blur-md animate-ping [animation-duration:1.5s]" }),
28060
- /* @__PURE__ */ jsx("div", { className: "bg-[#E34329] w-9 h-9 rounded-full flex items-center justify-center text-white font-bold text-lg shadow-lg ring-2 ring-red-400/40 border border-red-400/80 animate-pulse", children: "!" })
28249
+ /* @__PURE__ */ jsx("div", { className: "bg-[#E34329] w-8 h-8 sm:w-9 sm:h-9 rounded-full flex items-center justify-center text-white font-bold text-base sm:text-lg shadow-lg ring-2 ring-red-400/40 border border-red-400/80 animate-pulse", children: "!" })
28061
28250
  ] }) }),
28062
28251
  /* @__PURE__ */ jsx(
28063
28252
  "button",
@@ -28066,14 +28255,14 @@ var WorkspaceGridItem = React19__default.memo(({
28066
28255
  className: `${styles2} ${colorClass} ${isBottleneck ? "ring-2 ring-red-500/70" : ""} ${isVeryLowEfficiency ? "ring-2 ring-red-500/50" : ""} ${isInactive ? "bg-gray-200" : ""} shadow-lg`,
28067
28256
  "aria-label": isInactive ? `Inactive workspace ${workspaceNumber}` : `View details for workspace ${workspaceNumber}`,
28068
28257
  title: isInactive ? `Inactive: ${getWorkspaceDisplayName(data.workspace_name, data.line_id)}` : getWorkspaceDisplayName(data.workspace_name, data.line_id),
28069
- children: /* @__PURE__ */ jsx("div", { className: `font-semibold tracking-wide text-[min(4vw,2rem)] uppercase ${isInactive ? "text-gray-400" : "text-white"} drop-shadow-sm`, children: workspaceNumber })
28258
+ children: /* @__PURE__ */ jsx("div", { className: `font-semibold tracking-wide text-lg sm:text-xl md:text-[min(4vw,2rem)] uppercase ${isInactive ? "text-gray-400" : "text-white"} drop-shadow-sm`, children: workspaceNumber })
28070
28259
  }
28071
28260
  ),
28072
28261
  arrow && !isInactive && /* @__PURE__ */ jsx(
28073
28262
  "div",
28074
28263
  {
28075
28264
  className: `absolute left-1/2 -translate-x-1/2 ${arrowPosition}
28076
- text-[min(3.5vw,2.25rem)] font-bold tracking-tight ${arrowColor} drop-shadow-sm`,
28265
+ text-base sm:text-lg md:text-[min(3.5vw,2.25rem)] font-bold tracking-tight ${arrowColor} drop-shadow-sm`,
28077
28266
  style: { bottom: "-2.5rem", lineHeight: 1, display: "flex", alignItems: "center", justifyContent: "center" },
28078
28267
  children: arrow
28079
28268
  }
@@ -28103,11 +28292,11 @@ var WorkspaceGrid = React19__default.memo(({
28103
28292
  }, [workspaces.length]);
28104
28293
  const { VideoGridView: VideoGridViewComponent } = useRegistry();
28105
28294
  return /* @__PURE__ */ jsxs("div", { className: `relative w-full h-full overflow-hidden ${className}`, children: [
28106
- /* @__PURE__ */ jsxs("div", { className: "absolute top-0 left-2 sm:left-4 right-2 sm:right-8 z-20", children: [
28107
- /* @__PURE__ */ jsx("div", { className: "flex flex-row items-center justify-between py-1 sm:py-1.5 gap-2", children: /* @__PURE__ */ jsx("div", { className: "hidden sm:block", children: /* @__PURE__ */ jsx(Legend6, {}) }) }),
28108
- /* @__PURE__ */ jsx("div", { className: "sm:hidden mt-1", children: /* @__PURE__ */ jsx(Legend6, {}) })
28295
+ /* @__PURE__ */ jsxs("div", { className: "absolute top-0 left-4 sm:left-4 right-4 sm:right-8 z-20", children: [
28296
+ /* @__PURE__ */ jsx("div", { className: "flex flex-row items-center justify-between py-2 sm:py-1.5 gap-2", children: /* @__PURE__ */ jsx("div", { className: "hidden sm:block", children: /* @__PURE__ */ jsx(Legend6, {}) }) }),
28297
+ /* @__PURE__ */ jsx("div", { className: "sm:hidden mt-2", children: /* @__PURE__ */ jsx(Legend6, {}) })
28109
28298
  ] }),
28110
- /* @__PURE__ */ jsx("div", { className: "absolute top-10 sm:top-16 left-0 right-0 bottom-0", children: /* @__PURE__ */ jsx(
28299
+ /* @__PURE__ */ jsx("div", { className: "absolute top-12 sm:top-16 left-0 right-0 bottom-0", children: /* @__PURE__ */ jsx(
28111
28300
  VideoGridViewComponent,
28112
28301
  {
28113
28302
  workspaces,
@@ -28322,8 +28511,8 @@ var KPICard = ({
28322
28511
  const cardClasses = clsx(
28323
28512
  // Base classes
28324
28513
  "rounded-lg transition-all duration-200",
28325
- // Sizing based on compact mode - extra compact on mobile
28326
- "p-1.5 sm:p-3 md:p-4",
28514
+ // Sizing based on compact mode - better padding on mobile
28515
+ "p-2.5 sm:p-3 md:p-4",
28327
28516
  // Variant-specific styling
28328
28517
  {
28329
28518
  "bg-white/50 backdrop-blur-sm border border-gray-200/60 shadow-sm hover:shadow-md dark:bg-gray-800/50 dark:border-gray-700/60": style.variant === "default",
@@ -28331,8 +28520,8 @@ var KPICard = ({
28331
28520
  "bg-blue-50 border border-blue-200 dark:bg-blue-900/20 dark:border-blue-800/30": style.variant === "filled",
28332
28521
  "bg-gray-50/50 dark:bg-gray-800/30": style.variant === "subtle"
28333
28522
  },
28334
- // Width for src matching - compact on mobile, flexible on small screens
28335
- !className?.includes("w-") && "w-[120px] sm:w-[180px] md:w-[220px]",
28523
+ // Width for src matching - better mobile width, flexible on small screens
28524
+ !className?.includes("w-") && "w-[110px] sm:w-[180px] md:w-[220px]",
28336
28525
  // Interactive styling if onClick is provided
28337
28526
  onClick && "cursor-pointer hover:scale-[1.01] active:scale-[0.99]",
28338
28527
  // Loading state
@@ -28351,14 +28540,14 @@ var KPICard = ({
28351
28540
  children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
28352
28541
  /* @__PURE__ */ jsx("span", { className: clsx(
28353
28542
  "font-medium text-gray-500 dark:text-gray-400",
28354
- "text-[9px] sm:text-xs md:text-sm",
28355
- "mb-0.5 sm:mb-1 md:mb-2",
28356
- "uppercase tracking-wider"
28543
+ "text-[10px] sm:text-xs md:text-sm",
28544
+ "mb-1 sm:mb-1 md:mb-2",
28545
+ "uppercase tracking-wide sm:tracking-wider"
28357
28546
  ), children: title }),
28358
28547
  /* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-0.5 sm:gap-2 flex-wrap", children: [
28359
28548
  /* @__PURE__ */ jsx("span", { className: clsx(
28360
28549
  "font-bold text-gray-900 dark:text-gray-50",
28361
- "text-sm sm:text-xl md:text-2xl"
28550
+ "text-base sm:text-xl md:text-2xl"
28362
28551
  ), children: isLoading ? "\u2014" : formattedValue }),
28363
28552
  suffix && !isLoading && /* @__PURE__ */ jsx("span", { className: clsx(
28364
28553
  "font-medium text-gray-600 dark:text-gray-300",
@@ -28533,35 +28722,46 @@ var KPISection = memo(({
28533
28722
  const outputDifference = kpis.outputProgress.current - kpis.outputProgress.idealOutput;
28534
28723
  const outputIsOnTarget = outputDifference >= 0;
28535
28724
  if (useSrcLayout) {
28536
- return /* @__PURE__ */ jsxs("div", { className: `flex gap-1 sm:gap-3 overflow-x-auto sm:overflow-visible pb-1 sm:pb-0 ${className || ""}`, children: [
28537
- /* @__PURE__ */ jsx(
28538
- KPICard,
28539
- {
28540
- title: "Underperforming",
28541
- value: "2/3",
28542
- change: 0
28543
- }
28544
- ),
28545
- /* @__PURE__ */ jsx(
28546
- KPICard,
28547
- {
28548
- title: "Efficiency",
28549
- value: kpis.efficiency.value,
28550
- change: kpis.efficiency.change,
28551
- suffix: "%"
28552
- }
28553
- ),
28554
- /* @__PURE__ */ jsx(
28555
- KPICard,
28556
- {
28557
- title: "Output Progress",
28558
- value: `${kpis.outputProgress.current}/${kpis.outputProgress.target}`,
28559
- change: kpis.outputProgress.change,
28560
- outputDifference,
28561
- showOutputDetails: true
28562
- }
28563
- )
28564
- ] });
28725
+ return /* @__PURE__ */ jsxs(
28726
+ "div",
28727
+ {
28728
+ className: `flex gap-2 sm:gap-3 overflow-x-auto sm:overflow-visible pb-2 sm:pb-0 ${className || ""}`,
28729
+ style: {
28730
+ scrollbarWidth: "none",
28731
+ msOverflowStyle: "none",
28732
+ WebkitScrollbar: { display: "none" }
28733
+ },
28734
+ children: [
28735
+ /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx(
28736
+ KPICard,
28737
+ {
28738
+ title: "Underperforming",
28739
+ value: "2/3",
28740
+ change: 0
28741
+ }
28742
+ ) }),
28743
+ /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx(
28744
+ KPICard,
28745
+ {
28746
+ title: "Efficiency",
28747
+ value: kpis.efficiency.value,
28748
+ change: kpis.efficiency.change,
28749
+ suffix: "%"
28750
+ }
28751
+ ) }),
28752
+ /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx(
28753
+ KPICard,
28754
+ {
28755
+ title: "Output Progress",
28756
+ value: `${kpis.outputProgress.current}/${kpis.outputProgress.target}`,
28757
+ change: kpis.outputProgress.change,
28758
+ outputDifference,
28759
+ showOutputDetails: true
28760
+ }
28761
+ ) })
28762
+ ]
28763
+ }
28764
+ );
28565
28765
  }
28566
28766
  const kpiCardData = [
28567
28767
  {
@@ -28694,6 +28894,19 @@ var WorkspaceHealthCard = ({
28694
28894
  const formatTimeAgo = (timeString) => {
28695
28895
  return timeString.replace("about ", "").replace(" ago", "");
28696
28896
  };
28897
+ const formatDowntime = (uptimeDetails) => {
28898
+ if (!uptimeDetails) return "";
28899
+ const downtimeMinutes = Math.max(0, uptimeDetails.expectedMinutes - uptimeDetails.actualMinutes);
28900
+ if (downtimeMinutes === 0) return "No downtime";
28901
+ if (downtimeMinutes < 1) return "< 1 min downtime";
28902
+ if (downtimeMinutes < 60) return `${downtimeMinutes} min downtime`;
28903
+ const hours = Math.floor(downtimeMinutes / 60);
28904
+ const minutes = downtimeMinutes % 60;
28905
+ if (minutes === 0) {
28906
+ return `${hours} hr downtime`;
28907
+ }
28908
+ return `${hours} hr ${minutes} min downtime`;
28909
+ };
28697
28910
  return /* @__PURE__ */ jsx(
28698
28911
  Card2,
28699
28912
  {
@@ -28727,13 +28940,32 @@ var WorkspaceHealthCard = ({
28727
28940
  /* @__PURE__ */ jsx("span", { children: config.statusText })
28728
28941
  ] })
28729
28942
  ] }),
28730
- /* @__PURE__ */ jsx("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-1", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
28731
- /* @__PURE__ */ jsx(Clock, { className: "h-3.5 w-3.5 text-gray-400" }),
28732
- /* @__PURE__ */ jsxs("span", { className: "text-sm text-gray-600 dark:text-gray-400 whitespace-nowrap", children: [
28733
- "Last seen: ",
28734
- /* @__PURE__ */ jsx("span", { className: "font-medium", children: formatTimeAgo(workspace.timeSinceLastUpdate) })
28735
- ] })
28736
- ] }) }) })
28943
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
28944
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
28945
+ /* @__PURE__ */ jsx(Clock, { className: "h-3.5 w-3.5 text-gray-400" }),
28946
+ /* @__PURE__ */ jsxs("span", { className: "text-sm text-gray-600 dark:text-gray-400 whitespace-nowrap", children: [
28947
+ "Last seen: ",
28948
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: formatTimeAgo(workspace.timeSinceLastUpdate) })
28949
+ ] })
28950
+ ] }),
28951
+ workspace.uptimePercentage !== void 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
28952
+ /* @__PURE__ */ jsx(Activity, { className: "h-3.5 w-3.5 text-gray-400" }),
28953
+ /* @__PURE__ */ jsxs("span", { className: "text-sm text-gray-600 dark:text-gray-400 whitespace-nowrap", children: [
28954
+ "Uptime today: ",
28955
+ /* @__PURE__ */ jsxs("span", { className: clsx(
28956
+ "font-medium",
28957
+ workspace.uptimePercentage >= 97 ? "text-green-600 dark:text-green-400" : workspace.uptimePercentage >= 90 ? "text-yellow-600 dark:text-yellow-400" : "text-red-600 dark:text-red-400"
28958
+ ), children: [
28959
+ workspace.uptimePercentage.toFixed(1),
28960
+ "%"
28961
+ ] })
28962
+ ] })
28963
+ ] }),
28964
+ workspace.uptimeDetails && workspace.uptimeDetails.expectedMinutes > workspace.uptimeDetails.actualMinutes && workspace.uptimePercentage !== void 0 && /* @__PURE__ */ jsx("div", { className: "flex", children: /* @__PURE__ */ jsx("span", { className: clsx(
28965
+ "inline-flex items-center px-2 py-0.5 rounded text-xs font-medium",
28966
+ workspace.uptimePercentage >= 97 ? "bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400" : workspace.uptimePercentage >= 90 ? "bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-400" : "bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400"
28967
+ ), children: formatDowntime(workspace.uptimeDetails) }) })
28968
+ ] })
28737
28969
  ] })
28738
28970
  }
28739
28971
  );
@@ -28804,6 +29036,20 @@ var CompactWorkspaceHealthCard = ({
28804
29036
  ] })
28805
29037
  ] }),
28806
29038
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
29039
+ workspace.uptimePercentage !== void 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
29040
+ /* @__PURE__ */ jsxs("p", { className: clsx(
29041
+ "text-xs font-medium",
29042
+ workspace.uptimePercentage >= 97 ? "text-green-600 dark:text-green-400" : workspace.uptimePercentage >= 90 ? "text-yellow-600 dark:text-yellow-400" : "text-red-600 dark:text-red-400"
29043
+ ), children: [
29044
+ workspace.uptimePercentage.toFixed(1),
29045
+ "%"
29046
+ ] }),
29047
+ workspace.uptimeDetails && workspace.uptimeDetails.expectedMinutes > workspace.uptimeDetails.actualMinutes && /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-400 dark:text-gray-400", children: "\u2022" }),
29048
+ workspace.uptimeDetails && workspace.uptimeDetails.expectedMinutes > workspace.uptimeDetails.actualMinutes && /* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: [
29049
+ Math.max(0, workspace.uptimeDetails.expectedMinutes - workspace.uptimeDetails.actualMinutes),
29050
+ "m down"
29051
+ ] })
29052
+ ] }),
28807
29053
  /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: workspace.timeSinceLastUpdate }),
28808
29054
  /* @__PURE__ */ jsx("div", { className: clsx("h-2 w-2 rounded-full", config.dot) })
28809
29055
  ] })
@@ -29027,18 +29273,18 @@ var DashboardHeader = memo(({ lineTitle, className = "", headerControls }) => {
29027
29273
  };
29028
29274
  return /* @__PURE__ */ jsxs("div", { className: `flex flex-row items-center justify-between w-full ${className}`, children: [
29029
29275
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
29030
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 sm:gap-2 md:gap-3", children: [
29031
- /* @__PURE__ */ jsx("h1", { className: "text-base sm:text-xl md:text-2xl lg:text-3xl font-bold text-gray-800 tracking-tight leading-none", children: lineTitle }),
29032
- /* @__PURE__ */ jsx("div", { className: "h-1 w-1 sm:h-1.5 sm:w-1.5 md:h-2 md:w-2 rounded-full bg-green-500 animate-pulse ring-1 sm:ring-2 ring-green-500/30 ring-offset-1" })
29276
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 sm:gap-2 md:gap-3", children: [
29277
+ /* @__PURE__ */ jsx("h1", { className: "text-lg sm:text-xl md:text-2xl lg:text-3xl font-bold text-gray-800 tracking-tight leading-none", children: lineTitle }),
29278
+ /* @__PURE__ */ jsx("div", { className: "h-1.5 w-1.5 sm:h-1.5 sm:w-1.5 md:h-2 md:w-2 rounded-full bg-green-500 animate-pulse ring-2 sm:ring-2 ring-green-500/30 ring-offset-1" })
29033
29279
  ] }),
29034
- /* @__PURE__ */ jsxs("div", { className: "mt-2 inline-flex items-center gap-3", children: [
29035
- /* @__PURE__ */ jsxs("div", { className: "text-sm font-medium text-gray-600", children: [
29280
+ /* @__PURE__ */ jsxs("div", { className: "mt-2 inline-flex items-center gap-2 sm:gap-3", children: [
29281
+ /* @__PURE__ */ jsxs("div", { className: "text-xs sm:text-sm font-medium text-gray-600", children: [
29036
29282
  /* @__PURE__ */ jsx(ISTTimer2, {}),
29037
29283
  " IST"
29038
29284
  ] }),
29039
29285
  /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1", children: [
29040
29286
  /* @__PURE__ */ jsx("div", { className: "text-gray-600", children: getShiftIcon() }),
29041
- /* @__PURE__ */ jsxs("span", { className: "text-sm font-medium text-gray-600", children: [
29287
+ /* @__PURE__ */ jsxs("span", { className: "text-xs sm:text-sm font-medium text-gray-600", children: [
29042
29288
  getShiftName(),
29043
29289
  " Shift"
29044
29290
  ] })
@@ -29049,9 +29295,9 @@ var DashboardHeader = memo(({ lineTitle, className = "", headerControls }) => {
29049
29295
  ] });
29050
29296
  });
29051
29297
  DashboardHeader.displayName = "DashboardHeader";
29052
- var NoWorkspaceData = memo(({ message = "No workspace data available", className = "" }) => /* @__PURE__ */ jsx("div", { className: `flex h-full items-center justify-center ${className}`, children: /* @__PURE__ */ jsx("div", { className: "rounded-lg bg-white p-4 shadow-md", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2 text-gray-500", children: [
29053
- /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z", clipRule: "evenodd" }) }),
29054
- /* @__PURE__ */ jsx("span", { children: message })
29298
+ var NoWorkspaceData = memo(({ message = "No workspace data available", className = "" }) => /* @__PURE__ */ jsx("div", { className: `flex h-full items-center justify-center ${className}`, children: /* @__PURE__ */ jsx("div", { className: "rounded-lg bg-white p-5 sm:p-4 shadow-md", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-3 sm:space-x-2 text-gray-500", children: [
29299
+ /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-6 w-6 sm:h-5 sm:w-5", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { fillRule: "evenodd", d: "M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z", clipRule: "evenodd" }) }),
29300
+ /* @__PURE__ */ jsx("span", { className: "text-base sm:text-sm", children: message })
29055
29301
  ] }) }) }));
29056
29302
  NoWorkspaceData.displayName = "NoWorkspaceData";
29057
29303
  var WorkspaceMonthlyDataFetcher = ({
@@ -29176,10 +29422,10 @@ var HamburgerButton = ({
29176
29422
  "button",
29177
29423
  {
29178
29424
  type: "button",
29179
- className: `md:hidden p-2 rounded-md text-gray-500 hover:text-gray-600 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 ${className}`,
29425
+ className: `md:hidden p-2.5 rounded-lg text-gray-600 hover:text-gray-900 hover:bg-gray-100 active:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition-colors ${className}`,
29180
29426
  onClick,
29181
29427
  "aria-label": ariaLabel,
29182
- children: /* @__PURE__ */ jsx(Bars3Icon, { className: "w-6 h-6" })
29428
+ children: /* @__PURE__ */ jsx(Bars3Icon, { className: "w-7 h-7" })
29183
29429
  }
29184
29430
  );
29185
29431
  };
@@ -29710,28 +29956,189 @@ var SideNavBar = memo(({
29710
29956
  }
29711
29957
  ) })
29712
29958
  ] });
29959
+ const MobileNavigationContent = () => {
29960
+ const isActive = (path) => {
29961
+ if (path === "/" && pathname === "/") return true;
29962
+ if (path !== "/" && pathname.startsWith(path)) return true;
29963
+ return false;
29964
+ };
29965
+ const getMobileButtonClass = (path) => {
29966
+ const active = isActive(path);
29967
+ return `w-full flex items-center gap-3 px-5 py-3.5 rounded-lg transition-colors active:scale-[0.98] ${active ? "bg-blue-50 text-blue-700" : "text-gray-700 hover:bg-gray-100 active:bg-gray-200"}`;
29968
+ };
29969
+ const getIconClass = (path) => {
29970
+ const active = isActive(path);
29971
+ return `w-7 h-7 ${active ? "text-blue-600" : "text-gray-600"}`;
29972
+ };
29973
+ const handleMobileNavClick = (handler) => {
29974
+ return () => {
29975
+ handler();
29976
+ onMobileMenuClose?.();
29977
+ };
29978
+ };
29979
+ return /* @__PURE__ */ jsxs("nav", { className: "px-5 py-6", children: [
29980
+ /* @__PURE__ */ jsxs(
29981
+ "button",
29982
+ {
29983
+ onClick: handleMobileNavClick(handleHomeClick),
29984
+ className: getMobileButtonClass("/"),
29985
+ "aria-label": "Home",
29986
+ children: [
29987
+ /* @__PURE__ */ jsx(HomeIcon, { className: getIconClass("/") }),
29988
+ /* @__PURE__ */ jsx("span", { className: "text-base font-medium", children: "Home" })
29989
+ ]
29990
+ }
29991
+ ),
29992
+ /* @__PURE__ */ jsxs("div", { className: "mt-6 space-y-2", children: [
29993
+ /* @__PURE__ */ jsxs(
29994
+ "button",
29995
+ {
29996
+ onClick: handleMobileNavClick(handleLeaderboardClick),
29997
+ className: getMobileButtonClass("/leaderboard"),
29998
+ "aria-label": "Leaderboard",
29999
+ children: [
30000
+ /* @__PURE__ */ jsx(TrophyIcon, { className: getIconClass("/leaderboard") }),
30001
+ /* @__PURE__ */ jsx("span", { className: "text-base font-medium", children: "Leaderboard" })
30002
+ ]
30003
+ }
30004
+ ),
30005
+ /* @__PURE__ */ jsxs(
30006
+ "button",
30007
+ {
30008
+ onClick: handleMobileNavClick(handleKPIsClick),
30009
+ className: getMobileButtonClass("/kpis"),
30010
+ "aria-label": "Lines",
30011
+ children: [
30012
+ /* @__PURE__ */ jsx(ChartBarIcon, { className: getIconClass("/kpis") }),
30013
+ /* @__PURE__ */ jsx("span", { className: "text-base font-medium", children: "Lines" })
30014
+ ]
30015
+ }
30016
+ ),
30017
+ /* @__PURE__ */ jsxs(
30018
+ "button",
30019
+ {
30020
+ onClick: handleMobileNavClick(handleTargetsClick),
30021
+ className: getMobileButtonClass("/targets"),
30022
+ "aria-label": "Targets",
30023
+ children: [
30024
+ /* @__PURE__ */ jsx(AdjustmentsHorizontalIcon, { className: getIconClass("/targets") }),
30025
+ /* @__PURE__ */ jsx("span", { className: "text-base font-medium", children: "Targets" })
30026
+ ]
30027
+ }
30028
+ ),
30029
+ /* @__PURE__ */ jsxs(
30030
+ "button",
30031
+ {
30032
+ onClick: handleMobileNavClick(handleShiftsClick),
30033
+ className: getMobileButtonClass("/shifts"),
30034
+ "aria-label": "Shift Management",
30035
+ children: [
30036
+ /* @__PURE__ */ jsx(ClockIcon, { className: getIconClass("/shifts") }),
30037
+ /* @__PURE__ */ jsx("span", { className: "text-base font-medium", children: "Shifts" })
30038
+ ]
30039
+ }
30040
+ ),
30041
+ skuEnabled && /* @__PURE__ */ jsxs(
30042
+ "button",
30043
+ {
30044
+ onClick: handleMobileNavClick(handleSKUsClick),
30045
+ className: getMobileButtonClass("/skus"),
30046
+ "aria-label": "SKU Management",
30047
+ children: [
30048
+ /* @__PURE__ */ jsx(CubeIcon, { className: getIconClass("/skus") }),
30049
+ /* @__PURE__ */ jsx("span", { className: "text-base font-medium", children: "SKUs" })
30050
+ ]
30051
+ }
30052
+ ),
30053
+ /* @__PURE__ */ jsxs(
30054
+ "button",
30055
+ {
30056
+ onClick: handleMobileNavClick(handleAIAgentClick),
30057
+ className: getMobileButtonClass("/ai-agent"),
30058
+ "aria-label": "AI Manufacturing Expert",
30059
+ children: [
30060
+ /* @__PURE__ */ jsx(SparklesIcon, { className: getIconClass("/ai-agent") }),
30061
+ /* @__PURE__ */ jsx("span", { className: "text-base font-medium", children: "Axel AI" })
30062
+ ]
30063
+ }
30064
+ ),
30065
+ /* @__PURE__ */ jsxs(
30066
+ "button",
30067
+ {
30068
+ onClick: handleMobileNavClick(handleHelpClick),
30069
+ className: getMobileButtonClass("/help"),
30070
+ "aria-label": "Help & Support",
30071
+ children: [
30072
+ /* @__PURE__ */ jsx(QuestionMarkCircleIcon, { className: getIconClass("/help") }),
30073
+ /* @__PURE__ */ jsx("span", { className: "text-base font-medium", children: "Help" })
30074
+ ]
30075
+ }
30076
+ ),
30077
+ /* @__PURE__ */ jsxs(
30078
+ "button",
30079
+ {
30080
+ onClick: handleMobileNavClick(handleHealthClick),
30081
+ className: getMobileButtonClass("/health"),
30082
+ "aria-label": "System Health",
30083
+ children: [
30084
+ /* @__PURE__ */ jsx(HeartIcon, { className: getIconClass("/health") }),
30085
+ /* @__PURE__ */ jsx("span", { className: "text-base font-medium", children: "System Health" })
30086
+ ]
30087
+ }
30088
+ )
30089
+ ] }),
30090
+ /* @__PURE__ */ jsx("div", { className: "mt-8 pt-6 border-t border-gray-200", children: /* @__PURE__ */ jsxs(
30091
+ "button",
30092
+ {
30093
+ onClick: handleMobileNavClick(handleProfileClick),
30094
+ className: getMobileButtonClass("/profile"),
30095
+ "aria-label": "Profile & Settings",
30096
+ children: [
30097
+ /* @__PURE__ */ jsx(UserCircleIcon, { className: getIconClass("/profile") }),
30098
+ /* @__PURE__ */ jsx("span", { className: "text-base font-medium", children: "Profile" })
30099
+ ]
30100
+ }
30101
+ ) })
30102
+ ] });
30103
+ };
29713
30104
  return /* @__PURE__ */ jsxs(Fragment, { children: [
29714
30105
  /* @__PURE__ */ jsx("aside", { className: `hidden md:flex w-20 h-screen bg-white shadow-lg border-r border-gray-100 flex-col items-center fixed ${className}`, children: /* @__PURE__ */ jsx(NavigationContent, {}) }),
29715
- isMobileMenuOpen && /* @__PURE__ */ jsxs(Fragment, { children: [
30106
+ /* @__PURE__ */ jsxs(Fragment, { children: [
29716
30107
  /* @__PURE__ */ jsx(
29717
30108
  "div",
29718
30109
  {
29719
- className: "md:hidden fixed inset-0 bg-black bg-opacity-50 z-40",
30110
+ className: `md:hidden fixed inset-0 bg-black/60 backdrop-blur-sm z-40 transition-opacity duration-300 ease-in-out ${isMobileMenuOpen ? "opacity-100 pointer-events-auto" : "opacity-0 pointer-events-none"}`,
29720
30111
  onClick: onMobileMenuClose,
29721
30112
  "aria-hidden": "true"
29722
30113
  }
29723
30114
  ),
29724
- /* @__PURE__ */ jsxs("aside", { className: "md:hidden fixed inset-y-0 left-0 w-20 bg-white shadow-lg border-r border-gray-100 flex flex-col items-center z-50", children: [
29725
- /* @__PURE__ */ jsx("div", { className: "absolute top-4 right-4", children: /* @__PURE__ */ jsx(
29726
- "button",
29727
- {
29728
- onClick: onMobileMenuClose,
29729
- className: "p-2 rounded-md text-gray-400 hover:text-gray-600 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-blue-500",
29730
- "aria-label": "Close menu",
29731
- children: /* @__PURE__ */ jsx(XMarkIcon, { className: "w-5 h-5" })
29732
- }
29733
- ) }),
29734
- /* @__PURE__ */ jsx(NavigationContent, {})
30115
+ /* @__PURE__ */ jsxs("aside", { className: `md:hidden fixed inset-y-0 left-0 w-72 xs:w-80 bg-white shadow-2xl flex flex-col z-50 transform transition-transform duration-300 ease-in-out ${isMobileMenuOpen ? "translate-x-0" : "-translate-x-full"}`, children: [
30116
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-5 py-4 border-b border-gray-200 bg-gradient-to-r from-blue-50 to-white", children: [
30117
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx(
30118
+ "img",
30119
+ {
30120
+ src: "/optifye-logo.png",
30121
+ alt: "Optifye",
30122
+ className: "w-11 h-11 object-contain",
30123
+ onError: (e) => {
30124
+ e.currentTarget.style.display = "none";
30125
+ if (e.currentTarget.parentElement) {
30126
+ e.currentTarget.parentElement.innerHTML = '<span class="text-blue-600 font-bold text-xl">Optifye</span>';
30127
+ }
30128
+ }
30129
+ }
30130
+ ) }),
30131
+ /* @__PURE__ */ jsx(
30132
+ "button",
30133
+ {
30134
+ onClick: onMobileMenuClose,
30135
+ className: "p-2.5 rounded-lg text-gray-600 hover:text-gray-900 hover:bg-gray-100 active:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-blue-500 transition-all active:scale-95",
30136
+ "aria-label": "Close menu",
30137
+ children: /* @__PURE__ */ jsx(XMarkIcon, { className: "w-7 h-7" })
30138
+ }
30139
+ )
30140
+ ] }),
30141
+ /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto", children: /* @__PURE__ */ jsx(MobileNavigationContent, {}) })
29735
30142
  ] })
29736
30143
  ] })
29737
30144
  ] });
@@ -29823,17 +30230,39 @@ var MainLayout = ({
29823
30230
  logo
29824
30231
  }) => {
29825
30232
  const router = useRouter();
30233
+ const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
30234
+ const handleMobileMenuOpen = () => setIsMobileMenuOpen(true);
30235
+ const handleMobileMenuClose = () => setIsMobileMenuOpen(false);
29826
30236
  return /* @__PURE__ */ jsxs("div", { className: `min-h-screen ${className}`, children: [
30237
+ /* @__PURE__ */ jsx("header", { className: "md:hidden bg-white border-b border-gray-200 shadow-sm px-5 py-3.5 flex items-center justify-between sticky top-0 z-40", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
30238
+ /* @__PURE__ */ jsx(HamburgerButton, { onClick: handleMobileMenuOpen }),
30239
+ /* @__PURE__ */ jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsx(
30240
+ "img",
30241
+ {
30242
+ src: "/optifye-logo.png",
30243
+ alt: "Optifye",
30244
+ className: "h-9 w-9 object-contain",
30245
+ onError: (e) => {
30246
+ e.currentTarget.style.display = "none";
30247
+ if (e.currentTarget.parentElement) {
30248
+ e.currentTarget.parentElement.innerHTML = '<span class="text-blue-600 font-bold text-lg">Optifye</span>';
30249
+ }
30250
+ }
30251
+ }
30252
+ ) })
30253
+ ] }) }),
29827
30254
  /* @__PURE__ */ jsx(
29828
30255
  SideNavBar,
29829
30256
  {
29830
30257
  navItems,
29831
30258
  currentPathname: router.pathname,
29832
30259
  currentQuery: router.query,
29833
- logo
30260
+ logo,
30261
+ isMobileMenuOpen,
30262
+ onMobileMenuClose: handleMobileMenuClose
29834
30263
  }
29835
30264
  ),
29836
- /* @__PURE__ */ jsx("main", { className: "ml-20 bg-gray-50 min-h-screen", children })
30265
+ /* @__PURE__ */ jsx("main", { className: "md:ml-20 bg-gray-50 min-h-screen transition-all duration-300", children: /* @__PURE__ */ jsx("div", { className: "h-full", children }) })
29837
30266
  ] });
29838
30267
  };
29839
30268
  var Header = ({
@@ -32843,7 +33272,7 @@ function HomeView({
32843
33272
  return null;
32844
33273
  }
32845
33274
  return /* @__PURE__ */ jsxs(Select, { onValueChange: handleLineChange, defaultValue: selectedLineId, children: [
32846
- /* @__PURE__ */ jsx(SelectTrigger, { className: "w-full sm:w-[200px] bg-white border border-gray-200 shadow-sm rounded-md h-9 text-sm", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select a line" }) }),
33275
+ /* @__PURE__ */ jsx(SelectTrigger, { className: "w-full sm:w-[200px] bg-white border border-gray-200 shadow-sm rounded-md h-11 sm:h-9 text-sm", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select a line" }) }),
32847
33276
  /* @__PURE__ */ jsx(SelectContent, { className: "z-50 bg-white shadow-lg border border-gray-200 rounded-md", children: availableLineIds.map((id3) => /* @__PURE__ */ jsx(SelectItem, { value: id3, children: lineNames[id3] || (id3 === factoryViewId ? "All Lines" : `Line ${id3.substring(0, 4)}`) }, id3)) })
32848
33277
  ] });
32849
33278
  }, [availableLineIds, handleLineChange, selectedLineId, lineNames, factoryViewId, allLineIds.length]);
@@ -32855,7 +33284,7 @@ function HomeView({
32855
33284
  if (errorMessage || displayNamesError) {
32856
33285
  return /* @__PURE__ */ jsx("div", { className: "flex h-screen items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "rounded-lg bg-white p-6 shadow-lg", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-3 text-red-500", children: [
32857
33286
  /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-6 w-6", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
32858
- /* @__PURE__ */ jsxs("span", { className: "text-lg font-medium", children: [
33287
+ /* @__PURE__ */ jsxs("span", { className: "text-base sm:text-lg font-medium", children: [
32859
33288
  "Error: ",
32860
33289
  errorMessage || displayNamesError?.message
32861
33290
  ] })
@@ -32869,7 +33298,7 @@ function HomeView({
32869
33298
  animate: { opacity: 1 },
32870
33299
  children: /* @__PURE__ */ jsxs("div", { className: "relative flex flex-1", children: [
32871
33300
  /* @__PURE__ */ jsxs("main", { className: "flex flex-1 flex-col", children: [
32872
- /* @__PURE__ */ jsx("div", { className: "sticky top-0 z-30 sm:static bg-white shadow-sm border-b border-gray-200/80", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col sm:flex-row sm:items-center sm:justify-between px-3 sm:px-6 lg:px-8 py-1.5 sm:py-2.5", children: /* @__PURE__ */ jsx(
33301
+ /* @__PURE__ */ jsx("div", { className: "relative sm:sticky sm:top-0 z-30 bg-white shadow-sm border-b border-gray-200/80", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col sm:flex-row sm:items-center sm:justify-between px-4 sm:px-6 lg:px-8 py-3 sm:py-2.5", children: /* @__PURE__ */ jsx(
32873
33302
  DashboardHeader,
32874
33303
  {
32875
33304
  lineTitle,
@@ -32878,8 +33307,8 @@ function HomeView({
32878
33307
  }
32879
33308
  ) }) }),
32880
33309
  /* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto sm:overflow-hidden relative", children: [
32881
- lineSelectorComponent && /* @__PURE__ */ jsx("div", { className: "absolute right-3 top-2 sm:right-6 sm:top-3 z-30", children: lineSelectorComponent }),
32882
- /* @__PURE__ */ jsx("div", { className: "h-full sm:h-full min-h-[calc(100vh-80px)] sm:min-h-0", children: memoizedWorkspaceMetrics.length > 0 ? /* @__PURE__ */ jsx(
33310
+ lineSelectorComponent && /* @__PURE__ */ jsx("div", { className: "absolute right-4 top-3 sm:right-6 sm:top-3 z-30", children: lineSelectorComponent }),
33311
+ /* @__PURE__ */ jsx("div", { className: "h-full sm:h-full min-h-[calc(100vh-120px)] sm:min-h-0", children: memoizedWorkspaceMetrics.length > 0 ? /* @__PURE__ */ jsx(
32883
33312
  motion.div,
32884
33313
  {
32885
33314
  initial: { opacity: 0, scale: 0.98 },
@@ -38389,8 +38818,8 @@ var WorkspaceHealthView = ({
38389
38818
  }
38390
38819
  };
38391
38820
  const getUptimeColor = (percentage) => {
38392
- if (percentage >= 99) return "text-green-600 dark:text-green-400";
38393
- if (percentage >= 95) return "text-yellow-600 dark:text-yellow-400";
38821
+ if (percentage >= 97) return "text-green-600 dark:text-green-400";
38822
+ if (percentage >= 90) return "text-yellow-600 dark:text-yellow-400";
38394
38823
  return "text-red-600 dark:text-red-400";
38395
38824
  };
38396
38825
  if (loading && !summary) {
@@ -38478,20 +38907,21 @@ var WorkspaceHealthView = ({
38478
38907
  className: "grid grid-cols-2 sm:grid-cols-2 md:grid-cols-5 gap-2 sm:gap-3 lg:gap-4",
38479
38908
  children: [
38480
38909
  /* @__PURE__ */ jsxs(Card2, { className: "col-span-2 sm:col-span-2 md:col-span-2 bg-white", children: [
38481
- /* @__PURE__ */ jsx(CardHeader2, { className: "pb-3", children: /* @__PURE__ */ jsx(CardTitle2, { className: "text-sm font-medium text-gray-500 dark:text-gray-400", children: "Overall System Status" }) }),
38910
+ /* @__PURE__ */ jsx(CardHeader2, { className: "pb-3", children: /* @__PURE__ */ jsx(CardTitle2, { className: "text-sm font-medium text-gray-500 dark:text-gray-400", children: "Overall System Uptime Today" }) }),
38482
38911
  /* @__PURE__ */ jsxs(CardContent2, { children: [
38483
38912
  /* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-2", children: [
38484
38913
  /* @__PURE__ */ jsxs("span", { className: clsx("text-3xl font-bold", getUptimeColor(summary.uptimePercentage)), children: [
38485
38914
  summary.uptimePercentage.toFixed(1),
38486
38915
  "%"
38487
38916
  ] }),
38488
- summary.uptimePercentage >= 99 ? /* @__PURE__ */ jsx(TrendingUp, { className: "h-5 w-5 text-green-500" }) : /* @__PURE__ */ jsx(TrendingDown, { className: "h-5 w-5 text-red-500" })
38917
+ summary.uptimePercentage >= 97 ? /* @__PURE__ */ jsx(TrendingUp, { className: "h-5 w-5 text-green-500" }) : summary.uptimePercentage >= 90 ? /* @__PURE__ */ jsx(Activity, { className: "h-5 w-5 text-yellow-500" }) : /* @__PURE__ */ jsx(TrendingDown, { className: "h-5 w-5 text-red-500" })
38489
38918
  ] }),
38490
- /* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: [
38919
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: "Average uptime across all workspaces" }),
38920
+ /* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: [
38491
38921
  summary.healthyWorkspaces,
38492
38922
  " of ",
38493
38923
  summary.totalWorkspaces,
38494
- " workspaces healthy"
38924
+ " workspaces online"
38495
38925
  ] })
38496
38926
  ] })
38497
38927
  ] }),