@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.css +73 -23
- package/dist/index.d.mts +11 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +533 -103
- package/dist/index.mjs +534 -104
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1905,7 +1905,29 @@ var WorkspaceHealthService = class _WorkspaceHealthService {
|
|
|
1905
1905
|
throw error;
|
|
1906
1906
|
}
|
|
1907
1907
|
const processedData = (data || []).map((item) => this.processHealthStatus(item));
|
|
1908
|
-
let
|
|
1908
|
+
let uptimeMap = /* @__PURE__ */ new Map();
|
|
1909
|
+
if (options.companyId || data && data.length > 0) {
|
|
1910
|
+
const companyId = options.companyId || data[0]?.company_id;
|
|
1911
|
+
if (companyId) {
|
|
1912
|
+
try {
|
|
1913
|
+
uptimeMap = await this.calculateWorkspaceUptime(companyId);
|
|
1914
|
+
} catch (error2) {
|
|
1915
|
+
console.error("Error calculating uptime:", error2);
|
|
1916
|
+
}
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
const dataWithUptime = processedData.map((workspace) => {
|
|
1920
|
+
const uptimeDetails = uptimeMap.get(workspace.workspace_id);
|
|
1921
|
+
if (uptimeDetails) {
|
|
1922
|
+
return {
|
|
1923
|
+
...workspace,
|
|
1924
|
+
uptimePercentage: uptimeDetails.percentage,
|
|
1925
|
+
uptimeDetails
|
|
1926
|
+
};
|
|
1927
|
+
}
|
|
1928
|
+
return workspace;
|
|
1929
|
+
});
|
|
1930
|
+
let filteredData = dataWithUptime;
|
|
1909
1931
|
try {
|
|
1910
1932
|
const { data: enabledWorkspaces, error: workspaceError } = await supabase.from("workspaces").select("workspace_id, display_name").eq("enable", true);
|
|
1911
1933
|
if (!workspaceError && enabledWorkspaces && enabledWorkspaces.length > 0) {
|
|
@@ -1981,13 +2003,31 @@ var WorkspaceHealthService = class _WorkspaceHealthService {
|
|
|
1981
2003
|
const healthyWorkspaces = workspaces.filter((w) => w.status === "healthy").length;
|
|
1982
2004
|
const unhealthyWorkspaces = workspaces.filter((w) => w.status === "unhealthy").length;
|
|
1983
2005
|
const warningWorkspaces = workspaces.filter((w) => w.status === "warning").length;
|
|
1984
|
-
|
|
2006
|
+
let uptimePercentage = 0;
|
|
2007
|
+
let totalDowntimeMinutes = 0;
|
|
2008
|
+
if (totalWorkspaces > 0) {
|
|
2009
|
+
const workspacesWithUptime = workspaces.filter((w) => w.uptimePercentage !== void 0 && w.uptimeDetails !== void 0);
|
|
2010
|
+
if (workspacesWithUptime.length > 0) {
|
|
2011
|
+
const totalUptime = workspacesWithUptime.reduce((sum, w) => sum + (w.uptimePercentage || 0), 0);
|
|
2012
|
+
uptimePercentage = totalUptime / workspacesWithUptime.length;
|
|
2013
|
+
totalDowntimeMinutes = workspacesWithUptime.reduce((sum, w) => {
|
|
2014
|
+
if (w.uptimeDetails) {
|
|
2015
|
+
const downtime = Math.max(0, w.uptimeDetails.expectedMinutes - w.uptimeDetails.actualMinutes);
|
|
2016
|
+
return sum + downtime;
|
|
2017
|
+
}
|
|
2018
|
+
return sum;
|
|
2019
|
+
}, 0);
|
|
2020
|
+
} else {
|
|
2021
|
+
uptimePercentage = healthyWorkspaces / totalWorkspaces * 100;
|
|
2022
|
+
}
|
|
2023
|
+
}
|
|
1985
2024
|
return {
|
|
1986
2025
|
totalWorkspaces,
|
|
1987
2026
|
healthyWorkspaces,
|
|
1988
2027
|
unhealthyWorkspaces,
|
|
1989
2028
|
warningWorkspaces,
|
|
1990
2029
|
uptimePercentage,
|
|
2030
|
+
totalDowntimeMinutes,
|
|
1991
2031
|
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
1992
2032
|
};
|
|
1993
2033
|
}
|
|
@@ -2067,6 +2107,155 @@ var WorkspaceHealthService = class _WorkspaceHealthService {
|
|
|
2067
2107
|
clearCache() {
|
|
2068
2108
|
this.cache.clear();
|
|
2069
2109
|
}
|
|
2110
|
+
async calculateWorkspaceUptime(companyId) {
|
|
2111
|
+
const supabase = _getSupabaseInstance();
|
|
2112
|
+
if (!supabase) throw new Error("Supabase client not initialized");
|
|
2113
|
+
const dashboardConfig = _getDashboardConfigInstance();
|
|
2114
|
+
const timezone = dashboardConfig?.dateTimeConfig?.defaultTimezone || "UTC";
|
|
2115
|
+
const shiftConfig = dashboardConfig?.shiftConfig;
|
|
2116
|
+
const currentShiftInfo = getCurrentShift(timezone, shiftConfig);
|
|
2117
|
+
const currentDate = currentShiftInfo.date;
|
|
2118
|
+
const currentShiftId = currentShiftInfo.shiftId;
|
|
2119
|
+
const now2 = /* @__PURE__ */ new Date();
|
|
2120
|
+
const currentHour = now2.getHours();
|
|
2121
|
+
const currentMinute = now2.getMinutes();
|
|
2122
|
+
let shiftStartHour;
|
|
2123
|
+
let shiftEndHour;
|
|
2124
|
+
if (currentShiftId === 0) {
|
|
2125
|
+
shiftStartHour = 9;
|
|
2126
|
+
shiftEndHour = 18;
|
|
2127
|
+
} else {
|
|
2128
|
+
shiftStartHour = 20;
|
|
2129
|
+
shiftEndHour = 3;
|
|
2130
|
+
}
|
|
2131
|
+
let elapsedMinutes = 0;
|
|
2132
|
+
if (currentShiftId === 0) {
|
|
2133
|
+
if (currentHour >= shiftStartHour && currentHour < shiftEndHour) {
|
|
2134
|
+
elapsedMinutes = (currentHour - shiftStartHour) * 60 + currentMinute;
|
|
2135
|
+
} else if (currentHour >= shiftEndHour) {
|
|
2136
|
+
elapsedMinutes = (shiftEndHour - shiftStartHour) * 60;
|
|
2137
|
+
}
|
|
2138
|
+
} else {
|
|
2139
|
+
if (currentHour >= shiftStartHour) {
|
|
2140
|
+
elapsedMinutes = (currentHour - shiftStartHour) * 60 + currentMinute;
|
|
2141
|
+
} else if (currentHour < shiftEndHour) {
|
|
2142
|
+
elapsedMinutes = (24 - shiftStartHour + currentHour) * 60 + currentMinute;
|
|
2143
|
+
}
|
|
2144
|
+
}
|
|
2145
|
+
const tableName = `performance_metrics_${companyId.replace(/-/g, "_")}`;
|
|
2146
|
+
const query = `
|
|
2147
|
+
WITH workspace_uptime AS (
|
|
2148
|
+
SELECT
|
|
2149
|
+
workspace_id,
|
|
2150
|
+
workspace_display_name,
|
|
2151
|
+
idle_time_hourly,
|
|
2152
|
+
output_hourly,
|
|
2153
|
+
shift_start,
|
|
2154
|
+
shift_end
|
|
2155
|
+
FROM ${tableName}
|
|
2156
|
+
WHERE date = $1::date
|
|
2157
|
+
AND shift_id = $2
|
|
2158
|
+
),
|
|
2159
|
+
calculated_uptime AS (
|
|
2160
|
+
SELECT
|
|
2161
|
+
workspace_id,
|
|
2162
|
+
workspace_display_name,
|
|
2163
|
+
-- Calculate actual minutes from hourly data
|
|
2164
|
+
(
|
|
2165
|
+
SELECT COALESCE(SUM(
|
|
2166
|
+
CASE
|
|
2167
|
+
WHEN jsonb_array_length(idle_time_hourly->key::text) >= 58 THEN 60
|
|
2168
|
+
WHEN jsonb_array_length(idle_time_hourly->key::text) > 0 THEN jsonb_array_length(idle_time_hourly->key::text)
|
|
2169
|
+
ELSE 0
|
|
2170
|
+
END
|
|
2171
|
+
), 0)
|
|
2172
|
+
FROM jsonb_object_keys(idle_time_hourly) AS key
|
|
2173
|
+
WHERE key::int >= $3 AND key::int < $4
|
|
2174
|
+
) +
|
|
2175
|
+
-- Add current hour's data if applicable
|
|
2176
|
+
CASE
|
|
2177
|
+
WHEN $4::int >= $3 AND $4::int < $5 THEN
|
|
2178
|
+
LEAST($6::int,
|
|
2179
|
+
COALESCE(jsonb_array_length(idle_time_hourly->$4::text), 0))
|
|
2180
|
+
ELSE 0
|
|
2181
|
+
END as actual_minutes
|
|
2182
|
+
FROM workspace_uptime
|
|
2183
|
+
)
|
|
2184
|
+
SELECT
|
|
2185
|
+
workspace_id,
|
|
2186
|
+
workspace_display_name,
|
|
2187
|
+
actual_minutes,
|
|
2188
|
+
$7::int as expected_minutes,
|
|
2189
|
+
ROUND(
|
|
2190
|
+
CASE
|
|
2191
|
+
WHEN $7::int > 0 THEN (actual_minutes::numeric / $7::numeric) * 100
|
|
2192
|
+
ELSE 100
|
|
2193
|
+
END, 1
|
|
2194
|
+
) as uptime_percentage
|
|
2195
|
+
FROM calculated_uptime
|
|
2196
|
+
`;
|
|
2197
|
+
try {
|
|
2198
|
+
const { data, error } = await supabase.rpc("sql_query", {
|
|
2199
|
+
query_text: query,
|
|
2200
|
+
params: [
|
|
2201
|
+
currentDate,
|
|
2202
|
+
currentShiftId,
|
|
2203
|
+
shiftStartHour,
|
|
2204
|
+
currentHour,
|
|
2205
|
+
shiftEndHour,
|
|
2206
|
+
currentMinute,
|
|
2207
|
+
elapsedMinutes
|
|
2208
|
+
]
|
|
2209
|
+
}).single();
|
|
2210
|
+
if (error) {
|
|
2211
|
+
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);
|
|
2212
|
+
if (queryError) {
|
|
2213
|
+
console.error("Error fetching performance metrics:", queryError);
|
|
2214
|
+
return /* @__PURE__ */ new Map();
|
|
2215
|
+
}
|
|
2216
|
+
const uptimeMap2 = /* @__PURE__ */ new Map();
|
|
2217
|
+
for (const record of queryData || []) {
|
|
2218
|
+
let actualMinutes = 0;
|
|
2219
|
+
const idleTimeHourly = record.idle_time_hourly || {};
|
|
2220
|
+
if (idleTimeHourly && typeof idleTimeHourly === "object") {
|
|
2221
|
+
for (const [hour, dataArray] of Object.entries(idleTimeHourly)) {
|
|
2222
|
+
const hourNum = parseInt(hour);
|
|
2223
|
+
if (hourNum >= shiftStartHour && hourNum < currentHour) {
|
|
2224
|
+
const arrayLength = Array.isArray(dataArray) ? dataArray.length : 0;
|
|
2225
|
+
actualMinutes += arrayLength >= 58 ? 60 : arrayLength;
|
|
2226
|
+
} else if (hourNum === currentHour && currentHour >= shiftStartHour) {
|
|
2227
|
+
const arrayLength = Array.isArray(dataArray) ? dataArray.length : 0;
|
|
2228
|
+
actualMinutes += Math.min(currentMinute, arrayLength);
|
|
2229
|
+
}
|
|
2230
|
+
}
|
|
2231
|
+
}
|
|
2232
|
+
const percentage = elapsedMinutes > 0 ? Math.round(actualMinutes / elapsedMinutes * 1e3) / 10 : 100;
|
|
2233
|
+
uptimeMap2.set(record.workspace_id, {
|
|
2234
|
+
expectedMinutes: elapsedMinutes,
|
|
2235
|
+
actualMinutes,
|
|
2236
|
+
percentage,
|
|
2237
|
+
lastCalculated: (/* @__PURE__ */ new Date()).toISOString()
|
|
2238
|
+
});
|
|
2239
|
+
}
|
|
2240
|
+
return uptimeMap2;
|
|
2241
|
+
}
|
|
2242
|
+
const uptimeMap = /* @__PURE__ */ new Map();
|
|
2243
|
+
if (Array.isArray(data)) {
|
|
2244
|
+
for (const record of data) {
|
|
2245
|
+
uptimeMap.set(record.workspace_id, {
|
|
2246
|
+
expectedMinutes: record.expected_minutes,
|
|
2247
|
+
actualMinutes: record.actual_minutes,
|
|
2248
|
+
percentage: record.uptime_percentage,
|
|
2249
|
+
lastCalculated: (/* @__PURE__ */ new Date()).toISOString()
|
|
2250
|
+
});
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
return uptimeMap;
|
|
2254
|
+
} catch (error) {
|
|
2255
|
+
console.error("Error calculating workspace uptime:", error);
|
|
2256
|
+
return /* @__PURE__ */ new Map();
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
2070
2259
|
};
|
|
2071
2260
|
var workspaceHealthService = WorkspaceHealthService.getInstance();
|
|
2072
2261
|
|
|
@@ -19725,7 +19914,7 @@ var OptifyeLogoLoader = ({
|
|
|
19725
19914
|
className: `${sizeClasses[size]} h-auto animate-pulse select-none pointer-events-none`
|
|
19726
19915
|
}
|
|
19727
19916
|
),
|
|
19728
|
-
message && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 text-gray-600 text-sm font-medium text-center", children: message })
|
|
19917
|
+
message && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 text-gray-600 text-base sm:text-sm font-medium text-center", children: message })
|
|
19729
19918
|
]
|
|
19730
19919
|
}
|
|
19731
19920
|
);
|
|
@@ -21636,8 +21825,8 @@ var VideoCard = React19__namespace.default.memo(({
|
|
|
21636
21825
|
] }) }),
|
|
21637
21826
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full h-full overflow-hidden bg-black", children: [
|
|
21638
21827
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-black z-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "animate-pulse flex flex-col items-center", children: [
|
|
21639
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Camera, { className:
|
|
21640
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className:
|
|
21828
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Camera, { className: `w-5 h-5 sm:${compact ? "w-4 h-4" : "w-6 h-6"} text-gray-500` }),
|
|
21829
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `text-[11px] sm:${compact ? "text-[10px]" : "text-xs"} text-gray-500 mt-1`, children: "Loading..." })
|
|
21641
21830
|
] }) }),
|
|
21642
21831
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-0 z-10", children: [
|
|
21643
21832
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -21672,10 +21861,10 @@ var VideoCard = React19__namespace.default.memo(({
|
|
|
21672
21861
|
}
|
|
21673
21862
|
) })
|
|
21674
21863
|
] }),
|
|
21675
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `absolute bottom-0 left-0 right-0 bg-black bg-opacity-60
|
|
21864
|
+
/* @__PURE__ */ jsxRuntime.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: [
|
|
21676
21865
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
21677
21866
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Camera, { size: compact ? 10 : 12, className: "text-white" }),
|
|
21678
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: `text-white
|
|
21867
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: `text-white text-[11px] sm:${compact ? "text-[10px]" : "text-xs"} font-medium tracking-wide`, children: displayName })
|
|
21679
21868
|
] }),
|
|
21680
21869
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex items-center ${compact ? "gap-1" : "gap-1.5"}`, children: [
|
|
21681
21870
|
trendInfo && /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -21687,7 +21876,7 @@ var VideoCard = React19__namespace.default.memo(({
|
|
|
21687
21876
|
}
|
|
21688
21877
|
),
|
|
21689
21878
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: `${compact ? "w-1 h-1" : "w-1.5 h-1.5"} rounded-full bg-green-500` }),
|
|
21690
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `text-white
|
|
21879
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `text-white text-[11px] sm:${compact ? "text-[10px]" : "text-xs"}`, children: "Live" })
|
|
21691
21880
|
] })
|
|
21692
21881
|
] })
|
|
21693
21882
|
]
|
|
@@ -21897,10 +22086,10 @@ var VideoGridView = React19__namespace.default.memo(({
|
|
|
21897
22086
|
view_type: "video_grid"
|
|
21898
22087
|
});
|
|
21899
22088
|
}, []);
|
|
21900
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `relative overflow-hidden h-full w-full ${className}`, children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, className: "h-full w-full p-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
22089
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `relative overflow-hidden h-full w-full ${className}`, children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, className: "h-full w-full p-3 sm:p-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
21901
22090
|
"div",
|
|
21902
22091
|
{
|
|
21903
|
-
className: "grid h-full w-full gap-2",
|
|
22092
|
+
className: "grid h-full w-full gap-3 sm:gap-2",
|
|
21904
22093
|
style: {
|
|
21905
22094
|
gridTemplateColumns: `repeat(${gridCols}, 1fr)`,
|
|
21906
22095
|
gridTemplateRows: `repeat(${gridRows}, 1fr)`,
|
|
@@ -22685,15 +22874,15 @@ var BreakNotificationPopup = ({
|
|
|
22685
22874
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-2 h-2 bg-amber-500 rounded-full animate-pulse flex-shrink-0 mt-2" }),
|
|
22686
22875
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
22687
22876
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1", children: [
|
|
22688
|
-
/* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-semibold text-sm text-gray-900", children: breakItem.remarks || "Break" }),
|
|
22689
|
-
(activeBreaks.length > 1 || lineNames[breakItem.lineId]) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-gray-500 mt-0.5", children: lineNames[breakItem.lineId] || `Line ${breakItem.lineId.substring(0, 8)}` })
|
|
22877
|
+
/* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-semibold text-base sm:text-sm text-gray-900", children: breakItem.remarks || "Break" }),
|
|
22878
|
+
(activeBreaks.length > 1 || lineNames[breakItem.lineId]) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm sm:text-xs text-gray-500 mt-0.5", children: lineNames[breakItem.lineId] || `Line ${breakItem.lineId.substring(0, 8)}` })
|
|
22690
22879
|
] }),
|
|
22691
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-gray-600 font-medium", children: [
|
|
22880
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm sm:text-xs text-gray-600 font-medium", children: [
|
|
22692
22881
|
breakItem.startTime,
|
|
22693
22882
|
" - ",
|
|
22694
22883
|
breakItem.endTime
|
|
22695
22884
|
] }) }),
|
|
22696
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-gray-500", children: [
|
|
22885
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm sm:text-xs text-gray-500", children: [
|
|
22697
22886
|
formatTime3(breakItem.elapsedMinutes),
|
|
22698
22887
|
" / ",
|
|
22699
22888
|
formatTime3(breakItem.duration)
|
|
@@ -23411,7 +23600,7 @@ var TimeDisplay = ({ className, variant = "default" }) => {
|
|
|
23411
23600
|
className: `flex items-center space-x-1.5 bg-white/60 backdrop-blur-sm px-2 py-0.5 rounded-md shadow-xs ${className || ""}`,
|
|
23412
23601
|
children: [
|
|
23413
23602
|
/* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.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" }) }),
|
|
23414
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[11px] font-medium text-gray-800 tabular-nums tracking-tight", children: [
|
|
23603
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs sm:text-[11px] font-medium text-gray-800 tabular-nums tracking-tight", children: [
|
|
23415
23604
|
time2,
|
|
23416
23605
|
" ",
|
|
23417
23606
|
timeSuffix
|
|
@@ -28087,7 +28276,7 @@ var WorkspaceGridItem = React19__namespace.default.memo(({
|
|
|
28087
28276
|
isVeryLowEfficiency && !isInactive && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -top-10 left-1/2 -translate-x-1/2 z-30", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
|
|
28088
28277
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -inset-1 bg-red-400/50 rounded-full blur-sm animate-pulse" }),
|
|
28089
28278
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute -inset-0.5 bg-red-500/30 rounded-full blur-md animate-ping [animation-duration:1.5s]" }),
|
|
28090
|
-
/* @__PURE__ */ jsxRuntime.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: "!" })
|
|
28279
|
+
/* @__PURE__ */ jsxRuntime.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: "!" })
|
|
28091
28280
|
] }) }),
|
|
28092
28281
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
28093
28282
|
"button",
|
|
@@ -28096,14 +28285,14 @@ var WorkspaceGridItem = React19__namespace.default.memo(({
|
|
|
28096
28285
|
className: `${styles2} ${colorClass} ${isBottleneck ? "ring-2 ring-red-500/70" : ""} ${isVeryLowEfficiency ? "ring-2 ring-red-500/50" : ""} ${isInactive ? "bg-gray-200" : ""} shadow-lg`,
|
|
28097
28286
|
"aria-label": isInactive ? `Inactive workspace ${workspaceNumber}` : `View details for workspace ${workspaceNumber}`,
|
|
28098
28287
|
title: isInactive ? `Inactive: ${getWorkspaceDisplayName(data.workspace_name, data.line_id)}` : getWorkspaceDisplayName(data.workspace_name, data.line_id),
|
|
28099
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: `font-semibold tracking-wide text-[min(4vw,2rem)] uppercase ${isInactive ? "text-gray-400" : "text-white"} drop-shadow-sm`, children: workspaceNumber })
|
|
28288
|
+
children: /* @__PURE__ */ jsxRuntime.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 })
|
|
28100
28289
|
}
|
|
28101
28290
|
),
|
|
28102
28291
|
arrow && !isInactive && /* @__PURE__ */ jsxRuntime.jsx(
|
|
28103
28292
|
"div",
|
|
28104
28293
|
{
|
|
28105
28294
|
className: `absolute left-1/2 -translate-x-1/2 ${arrowPosition}
|
|
28106
|
-
text-[min(3.5vw,2.25rem)] font-bold tracking-tight ${arrowColor} drop-shadow-sm`,
|
|
28295
|
+
text-base sm:text-lg md:text-[min(3.5vw,2.25rem)] font-bold tracking-tight ${arrowColor} drop-shadow-sm`,
|
|
28107
28296
|
style: { bottom: "-2.5rem", lineHeight: 1, display: "flex", alignItems: "center", justifyContent: "center" },
|
|
28108
28297
|
children: arrow
|
|
28109
28298
|
}
|
|
@@ -28133,11 +28322,11 @@ var WorkspaceGrid = React19__namespace.default.memo(({
|
|
|
28133
28322
|
}, [workspaces.length]);
|
|
28134
28323
|
const { VideoGridView: VideoGridViewComponent } = useRegistry();
|
|
28135
28324
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `relative w-full h-full overflow-hidden ${className}`, children: [
|
|
28136
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute top-0 left-
|
|
28137
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-row items-center justify-between py-
|
|
28138
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "sm:hidden mt-
|
|
28325
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute top-0 left-4 sm:left-4 right-4 sm:right-8 z-20", children: [
|
|
28326
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-row items-center justify-between py-2 sm:py-1.5 gap-2", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden sm:block", children: /* @__PURE__ */ jsxRuntime.jsx(Legend6, {}) }) }),
|
|
28327
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "sm:hidden mt-2", children: /* @__PURE__ */ jsxRuntime.jsx(Legend6, {}) })
|
|
28139
28328
|
] }),
|
|
28140
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-
|
|
28329
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-12 sm:top-16 left-0 right-0 bottom-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
28141
28330
|
VideoGridViewComponent,
|
|
28142
28331
|
{
|
|
28143
28332
|
workspaces,
|
|
@@ -28352,8 +28541,8 @@ var KPICard = ({
|
|
|
28352
28541
|
const cardClasses = clsx(
|
|
28353
28542
|
// Base classes
|
|
28354
28543
|
"rounded-lg transition-all duration-200",
|
|
28355
|
-
// Sizing based on compact mode -
|
|
28356
|
-
"p-
|
|
28544
|
+
// Sizing based on compact mode - better padding on mobile
|
|
28545
|
+
"p-2.5 sm:p-3 md:p-4",
|
|
28357
28546
|
// Variant-specific styling
|
|
28358
28547
|
{
|
|
28359
28548
|
"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",
|
|
@@ -28361,8 +28550,8 @@ var KPICard = ({
|
|
|
28361
28550
|
"bg-blue-50 border border-blue-200 dark:bg-blue-900/20 dark:border-blue-800/30": style.variant === "filled",
|
|
28362
28551
|
"bg-gray-50/50 dark:bg-gray-800/30": style.variant === "subtle"
|
|
28363
28552
|
},
|
|
28364
|
-
// Width for src matching -
|
|
28365
|
-
!className?.includes("w-") && "w-[
|
|
28553
|
+
// Width for src matching - better mobile width, flexible on small screens
|
|
28554
|
+
!className?.includes("w-") && "w-[110px] sm:w-[180px] md:w-[220px]",
|
|
28366
28555
|
// Interactive styling if onClick is provided
|
|
28367
28556
|
onClick && "cursor-pointer hover:scale-[1.01] active:scale-[0.99]",
|
|
28368
28557
|
// Loading state
|
|
@@ -28381,14 +28570,14 @@ var KPICard = ({
|
|
|
28381
28570
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
|
|
28382
28571
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: clsx(
|
|
28383
28572
|
"font-medium text-gray-500 dark:text-gray-400",
|
|
28384
|
-
"text-[
|
|
28385
|
-
"mb-
|
|
28386
|
-
"uppercase tracking-wider"
|
|
28573
|
+
"text-[10px] sm:text-xs md:text-sm",
|
|
28574
|
+
"mb-1 sm:mb-1 md:mb-2",
|
|
28575
|
+
"uppercase tracking-wide sm:tracking-wider"
|
|
28387
28576
|
), children: title }),
|
|
28388
28577
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-0.5 sm:gap-2 flex-wrap", children: [
|
|
28389
28578
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: clsx(
|
|
28390
28579
|
"font-bold text-gray-900 dark:text-gray-50",
|
|
28391
|
-
"text-
|
|
28580
|
+
"text-base sm:text-xl md:text-2xl"
|
|
28392
28581
|
), children: isLoading ? "\u2014" : formattedValue }),
|
|
28393
28582
|
suffix && !isLoading && /* @__PURE__ */ jsxRuntime.jsx("span", { className: clsx(
|
|
28394
28583
|
"font-medium text-gray-600 dark:text-gray-300",
|
|
@@ -28563,35 +28752,46 @@ var KPISection = React19.memo(({
|
|
|
28563
28752
|
const outputDifference = kpis.outputProgress.current - kpis.outputProgress.idealOutput;
|
|
28564
28753
|
const outputIsOnTarget = outputDifference >= 0;
|
|
28565
28754
|
if (useSrcLayout) {
|
|
28566
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
28567
|
-
|
|
28568
|
-
|
|
28569
|
-
{
|
|
28570
|
-
|
|
28571
|
-
|
|
28572
|
-
|
|
28573
|
-
|
|
28574
|
-
|
|
28575
|
-
|
|
28576
|
-
|
|
28577
|
-
|
|
28578
|
-
|
|
28579
|
-
|
|
28580
|
-
|
|
28581
|
-
|
|
28582
|
-
|
|
28583
|
-
|
|
28584
|
-
|
|
28585
|
-
|
|
28586
|
-
|
|
28587
|
-
|
|
28588
|
-
|
|
28589
|
-
|
|
28590
|
-
|
|
28591
|
-
|
|
28592
|
-
|
|
28593
|
-
|
|
28594
|
-
|
|
28755
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
28756
|
+
"div",
|
|
28757
|
+
{
|
|
28758
|
+
className: `flex gap-2 sm:gap-3 overflow-x-auto sm:overflow-visible pb-2 sm:pb-0 ${className || ""}`,
|
|
28759
|
+
style: {
|
|
28760
|
+
scrollbarWidth: "none",
|
|
28761
|
+
msOverflowStyle: "none",
|
|
28762
|
+
WebkitScrollbar: { display: "none" }
|
|
28763
|
+
},
|
|
28764
|
+
children: [
|
|
28765
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
28766
|
+
KPICard,
|
|
28767
|
+
{
|
|
28768
|
+
title: "Underperforming",
|
|
28769
|
+
value: "2/3",
|
|
28770
|
+
change: 0
|
|
28771
|
+
}
|
|
28772
|
+
) }),
|
|
28773
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
28774
|
+
KPICard,
|
|
28775
|
+
{
|
|
28776
|
+
title: "Efficiency",
|
|
28777
|
+
value: kpis.efficiency.value,
|
|
28778
|
+
change: kpis.efficiency.change,
|
|
28779
|
+
suffix: "%"
|
|
28780
|
+
}
|
|
28781
|
+
) }),
|
|
28782
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
28783
|
+
KPICard,
|
|
28784
|
+
{
|
|
28785
|
+
title: "Output Progress",
|
|
28786
|
+
value: `${kpis.outputProgress.current}/${kpis.outputProgress.target}`,
|
|
28787
|
+
change: kpis.outputProgress.change,
|
|
28788
|
+
outputDifference,
|
|
28789
|
+
showOutputDetails: true
|
|
28790
|
+
}
|
|
28791
|
+
) })
|
|
28792
|
+
]
|
|
28793
|
+
}
|
|
28794
|
+
);
|
|
28595
28795
|
}
|
|
28596
28796
|
const kpiCardData = [
|
|
28597
28797
|
{
|
|
@@ -28724,6 +28924,19 @@ var WorkspaceHealthCard = ({
|
|
|
28724
28924
|
const formatTimeAgo = (timeString) => {
|
|
28725
28925
|
return timeString.replace("about ", "").replace(" ago", "");
|
|
28726
28926
|
};
|
|
28927
|
+
const formatDowntime = (uptimeDetails) => {
|
|
28928
|
+
if (!uptimeDetails) return "";
|
|
28929
|
+
const downtimeMinutes = Math.max(0, uptimeDetails.expectedMinutes - uptimeDetails.actualMinutes);
|
|
28930
|
+
if (downtimeMinutes === 0) return "No downtime";
|
|
28931
|
+
if (downtimeMinutes < 1) return "< 1 min downtime";
|
|
28932
|
+
if (downtimeMinutes < 60) return `${downtimeMinutes} min downtime`;
|
|
28933
|
+
const hours = Math.floor(downtimeMinutes / 60);
|
|
28934
|
+
const minutes = downtimeMinutes % 60;
|
|
28935
|
+
if (minutes === 0) {
|
|
28936
|
+
return `${hours} hr downtime`;
|
|
28937
|
+
}
|
|
28938
|
+
return `${hours} hr ${minutes} min downtime`;
|
|
28939
|
+
};
|
|
28727
28940
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
28728
28941
|
Card2,
|
|
28729
28942
|
{
|
|
@@ -28757,13 +28970,32 @@ var WorkspaceHealthCard = ({
|
|
|
28757
28970
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: config.statusText })
|
|
28758
28971
|
] })
|
|
28759
28972
|
] }),
|
|
28760
|
-
/* @__PURE__ */ jsxRuntime.
|
|
28761
|
-
/* @__PURE__ */ jsxRuntime.
|
|
28762
|
-
|
|
28763
|
-
"
|
|
28764
|
-
|
|
28765
|
-
|
|
28766
|
-
|
|
28973
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
28974
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
28975
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { className: "h-3.5 w-3.5 text-gray-400" }),
|
|
28976
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-gray-600 dark:text-gray-400 whitespace-nowrap", children: [
|
|
28977
|
+
"Last seen: ",
|
|
28978
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: formatTimeAgo(workspace.timeSinceLastUpdate) })
|
|
28979
|
+
] })
|
|
28980
|
+
] }),
|
|
28981
|
+
workspace.uptimePercentage !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
28982
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Activity, { className: "h-3.5 w-3.5 text-gray-400" }),
|
|
28983
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-gray-600 dark:text-gray-400 whitespace-nowrap", children: [
|
|
28984
|
+
"Uptime today: ",
|
|
28985
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: clsx(
|
|
28986
|
+
"font-medium",
|
|
28987
|
+
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"
|
|
28988
|
+
), children: [
|
|
28989
|
+
workspace.uptimePercentage.toFixed(1),
|
|
28990
|
+
"%"
|
|
28991
|
+
] })
|
|
28992
|
+
] })
|
|
28993
|
+
] }),
|
|
28994
|
+
workspace.uptimeDetails && workspace.uptimeDetails.expectedMinutes > workspace.uptimeDetails.actualMinutes && workspace.uptimePercentage !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: clsx(
|
|
28995
|
+
"inline-flex items-center px-2 py-0.5 rounded text-xs font-medium",
|
|
28996
|
+
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"
|
|
28997
|
+
), children: formatDowntime(workspace.uptimeDetails) }) })
|
|
28998
|
+
] })
|
|
28767
28999
|
] })
|
|
28768
29000
|
}
|
|
28769
29001
|
);
|
|
@@ -28834,6 +29066,20 @@ var CompactWorkspaceHealthCard = ({
|
|
|
28834
29066
|
] })
|
|
28835
29067
|
] }),
|
|
28836
29068
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
29069
|
+
workspace.uptimePercentage !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
29070
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: clsx(
|
|
29071
|
+
"text-xs font-medium",
|
|
29072
|
+
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"
|
|
29073
|
+
), children: [
|
|
29074
|
+
workspace.uptimePercentage.toFixed(1),
|
|
29075
|
+
"%"
|
|
29076
|
+
] }),
|
|
29077
|
+
workspace.uptimeDetails && workspace.uptimeDetails.expectedMinutes > workspace.uptimeDetails.actualMinutes && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-400 dark:text-gray-400", children: "\u2022" }),
|
|
29078
|
+
workspace.uptimeDetails && workspace.uptimeDetails.expectedMinutes > workspace.uptimeDetails.actualMinutes && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: [
|
|
29079
|
+
Math.max(0, workspace.uptimeDetails.expectedMinutes - workspace.uptimeDetails.actualMinutes),
|
|
29080
|
+
"m down"
|
|
29081
|
+
] })
|
|
29082
|
+
] }),
|
|
28837
29083
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: workspace.timeSinceLastUpdate }),
|
|
28838
29084
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx("h-2 w-2 rounded-full", config.dot) })
|
|
28839
29085
|
] })
|
|
@@ -29057,18 +29303,18 @@ var DashboardHeader = React19.memo(({ lineTitle, className = "", headerControls
|
|
|
29057
29303
|
};
|
|
29058
29304
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-row items-center justify-between w-full ${className}`, children: [
|
|
29059
29305
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
|
|
29060
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-
|
|
29061
|
-
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-
|
|
29062
|
-
/* @__PURE__ */ jsxRuntime.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-
|
|
29306
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 sm:gap-2 md:gap-3", children: [
|
|
29307
|
+
/* @__PURE__ */ jsxRuntime.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 }),
|
|
29308
|
+
/* @__PURE__ */ jsxRuntime.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" })
|
|
29063
29309
|
] }),
|
|
29064
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 inline-flex items-center gap-3", children: [
|
|
29065
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm font-medium text-gray-600", children: [
|
|
29310
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 inline-flex items-center gap-2 sm:gap-3", children: [
|
|
29311
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs sm:text-sm font-medium text-gray-600", children: [
|
|
29066
29312
|
/* @__PURE__ */ jsxRuntime.jsx(ISTTimer2, {}),
|
|
29067
29313
|
" IST"
|
|
29068
29314
|
] }),
|
|
29069
29315
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inline-flex items-center gap-1", children: [
|
|
29070
29316
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-gray-600", children: getShiftIcon() }),
|
|
29071
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm font-medium text-gray-600", children: [
|
|
29317
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs sm:text-sm font-medium text-gray-600", children: [
|
|
29072
29318
|
getShiftName(),
|
|
29073
29319
|
" Shift"
|
|
29074
29320
|
] })
|
|
@@ -29079,9 +29325,9 @@ var DashboardHeader = React19.memo(({ lineTitle, className = "", headerControls
|
|
|
29079
29325
|
] });
|
|
29080
29326
|
});
|
|
29081
29327
|
DashboardHeader.displayName = "DashboardHeader";
|
|
29082
|
-
var NoWorkspaceData = React19.memo(({ message = "No workspace data available", className = "" }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex h-full items-center justify-center ${className}`, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg bg-white p-4 shadow-md", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2 text-gray-500", children: [
|
|
29083
|
-
/* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", className: "h-5 w-5", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.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" }) }),
|
|
29084
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { children: message })
|
|
29328
|
+
var NoWorkspaceData = React19.memo(({ message = "No workspace data available", className = "" }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex h-full items-center justify-center ${className}`, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg bg-white p-5 sm:p-4 shadow-md", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-3 sm:space-x-2 text-gray-500", children: [
|
|
29329
|
+
/* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.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" }) }),
|
|
29330
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-base sm:text-sm", children: message })
|
|
29085
29331
|
] }) }) }));
|
|
29086
29332
|
NoWorkspaceData.displayName = "NoWorkspaceData";
|
|
29087
29333
|
var WorkspaceMonthlyDataFetcher = ({
|
|
@@ -29206,10 +29452,10 @@ var HamburgerButton = ({
|
|
|
29206
29452
|
"button",
|
|
29207
29453
|
{
|
|
29208
29454
|
type: "button",
|
|
29209
|
-
className: `md:hidden p-2 rounded-
|
|
29455
|
+
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}`,
|
|
29210
29456
|
onClick,
|
|
29211
29457
|
"aria-label": ariaLabel,
|
|
29212
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(outline.Bars3Icon, { className: "w-
|
|
29458
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(outline.Bars3Icon, { className: "w-7 h-7" })
|
|
29213
29459
|
}
|
|
29214
29460
|
);
|
|
29215
29461
|
};
|
|
@@ -29740,28 +29986,189 @@ var SideNavBar = React19.memo(({
|
|
|
29740
29986
|
}
|
|
29741
29987
|
) })
|
|
29742
29988
|
] });
|
|
29989
|
+
const MobileNavigationContent = () => {
|
|
29990
|
+
const isActive = (path) => {
|
|
29991
|
+
if (path === "/" && pathname === "/") return true;
|
|
29992
|
+
if (path !== "/" && pathname.startsWith(path)) return true;
|
|
29993
|
+
return false;
|
|
29994
|
+
};
|
|
29995
|
+
const getMobileButtonClass = (path) => {
|
|
29996
|
+
const active = isActive(path);
|
|
29997
|
+
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"}`;
|
|
29998
|
+
};
|
|
29999
|
+
const getIconClass = (path) => {
|
|
30000
|
+
const active = isActive(path);
|
|
30001
|
+
return `w-7 h-7 ${active ? "text-blue-600" : "text-gray-600"}`;
|
|
30002
|
+
};
|
|
30003
|
+
const handleMobileNavClick = (handler) => {
|
|
30004
|
+
return () => {
|
|
30005
|
+
handler();
|
|
30006
|
+
onMobileMenuClose?.();
|
|
30007
|
+
};
|
|
30008
|
+
};
|
|
30009
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("nav", { className: "px-5 py-6", children: [
|
|
30010
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
30011
|
+
"button",
|
|
30012
|
+
{
|
|
30013
|
+
onClick: handleMobileNavClick(handleHomeClick),
|
|
30014
|
+
className: getMobileButtonClass("/"),
|
|
30015
|
+
"aria-label": "Home",
|
|
30016
|
+
children: [
|
|
30017
|
+
/* @__PURE__ */ jsxRuntime.jsx(outline.HomeIcon, { className: getIconClass("/") }),
|
|
30018
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-base font-medium", children: "Home" })
|
|
30019
|
+
]
|
|
30020
|
+
}
|
|
30021
|
+
),
|
|
30022
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-6 space-y-2", children: [
|
|
30023
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
30024
|
+
"button",
|
|
30025
|
+
{
|
|
30026
|
+
onClick: handleMobileNavClick(handleLeaderboardClick),
|
|
30027
|
+
className: getMobileButtonClass("/leaderboard"),
|
|
30028
|
+
"aria-label": "Leaderboard",
|
|
30029
|
+
children: [
|
|
30030
|
+
/* @__PURE__ */ jsxRuntime.jsx(outline.TrophyIcon, { className: getIconClass("/leaderboard") }),
|
|
30031
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-base font-medium", children: "Leaderboard" })
|
|
30032
|
+
]
|
|
30033
|
+
}
|
|
30034
|
+
),
|
|
30035
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
30036
|
+
"button",
|
|
30037
|
+
{
|
|
30038
|
+
onClick: handleMobileNavClick(handleKPIsClick),
|
|
30039
|
+
className: getMobileButtonClass("/kpis"),
|
|
30040
|
+
"aria-label": "Lines",
|
|
30041
|
+
children: [
|
|
30042
|
+
/* @__PURE__ */ jsxRuntime.jsx(outline.ChartBarIcon, { className: getIconClass("/kpis") }),
|
|
30043
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-base font-medium", children: "Lines" })
|
|
30044
|
+
]
|
|
30045
|
+
}
|
|
30046
|
+
),
|
|
30047
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
30048
|
+
"button",
|
|
30049
|
+
{
|
|
30050
|
+
onClick: handleMobileNavClick(handleTargetsClick),
|
|
30051
|
+
className: getMobileButtonClass("/targets"),
|
|
30052
|
+
"aria-label": "Targets",
|
|
30053
|
+
children: [
|
|
30054
|
+
/* @__PURE__ */ jsxRuntime.jsx(outline.AdjustmentsHorizontalIcon, { className: getIconClass("/targets") }),
|
|
30055
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-base font-medium", children: "Targets" })
|
|
30056
|
+
]
|
|
30057
|
+
}
|
|
30058
|
+
),
|
|
30059
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
30060
|
+
"button",
|
|
30061
|
+
{
|
|
30062
|
+
onClick: handleMobileNavClick(handleShiftsClick),
|
|
30063
|
+
className: getMobileButtonClass("/shifts"),
|
|
30064
|
+
"aria-label": "Shift Management",
|
|
30065
|
+
children: [
|
|
30066
|
+
/* @__PURE__ */ jsxRuntime.jsx(outline.ClockIcon, { className: getIconClass("/shifts") }),
|
|
30067
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-base font-medium", children: "Shifts" })
|
|
30068
|
+
]
|
|
30069
|
+
}
|
|
30070
|
+
),
|
|
30071
|
+
skuEnabled && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
30072
|
+
"button",
|
|
30073
|
+
{
|
|
30074
|
+
onClick: handleMobileNavClick(handleSKUsClick),
|
|
30075
|
+
className: getMobileButtonClass("/skus"),
|
|
30076
|
+
"aria-label": "SKU Management",
|
|
30077
|
+
children: [
|
|
30078
|
+
/* @__PURE__ */ jsxRuntime.jsx(outline.CubeIcon, { className: getIconClass("/skus") }),
|
|
30079
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-base font-medium", children: "SKUs" })
|
|
30080
|
+
]
|
|
30081
|
+
}
|
|
30082
|
+
),
|
|
30083
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
30084
|
+
"button",
|
|
30085
|
+
{
|
|
30086
|
+
onClick: handleMobileNavClick(handleAIAgentClick),
|
|
30087
|
+
className: getMobileButtonClass("/ai-agent"),
|
|
30088
|
+
"aria-label": "AI Manufacturing Expert",
|
|
30089
|
+
children: [
|
|
30090
|
+
/* @__PURE__ */ jsxRuntime.jsx(outline.SparklesIcon, { className: getIconClass("/ai-agent") }),
|
|
30091
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-base font-medium", children: "Axel AI" })
|
|
30092
|
+
]
|
|
30093
|
+
}
|
|
30094
|
+
),
|
|
30095
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
30096
|
+
"button",
|
|
30097
|
+
{
|
|
30098
|
+
onClick: handleMobileNavClick(handleHelpClick),
|
|
30099
|
+
className: getMobileButtonClass("/help"),
|
|
30100
|
+
"aria-label": "Help & Support",
|
|
30101
|
+
children: [
|
|
30102
|
+
/* @__PURE__ */ jsxRuntime.jsx(outline.QuestionMarkCircleIcon, { className: getIconClass("/help") }),
|
|
30103
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-base font-medium", children: "Help" })
|
|
30104
|
+
]
|
|
30105
|
+
}
|
|
30106
|
+
),
|
|
30107
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
30108
|
+
"button",
|
|
30109
|
+
{
|
|
30110
|
+
onClick: handleMobileNavClick(handleHealthClick),
|
|
30111
|
+
className: getMobileButtonClass("/health"),
|
|
30112
|
+
"aria-label": "System Health",
|
|
30113
|
+
children: [
|
|
30114
|
+
/* @__PURE__ */ jsxRuntime.jsx(outline.HeartIcon, { className: getIconClass("/health") }),
|
|
30115
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-base font-medium", children: "System Health" })
|
|
30116
|
+
]
|
|
30117
|
+
}
|
|
30118
|
+
)
|
|
30119
|
+
] }),
|
|
30120
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-8 pt-6 border-t border-gray-200", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
30121
|
+
"button",
|
|
30122
|
+
{
|
|
30123
|
+
onClick: handleMobileNavClick(handleProfileClick),
|
|
30124
|
+
className: getMobileButtonClass("/profile"),
|
|
30125
|
+
"aria-label": "Profile & Settings",
|
|
30126
|
+
children: [
|
|
30127
|
+
/* @__PURE__ */ jsxRuntime.jsx(outline.UserCircleIcon, { className: getIconClass("/profile") }),
|
|
30128
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-base font-medium", children: "Profile" })
|
|
30129
|
+
]
|
|
30130
|
+
}
|
|
30131
|
+
) })
|
|
30132
|
+
] });
|
|
30133
|
+
};
|
|
29743
30134
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
29744
30135
|
/* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx(NavigationContent, {}) }),
|
|
29745
|
-
|
|
30136
|
+
/* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
29746
30137
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
29747
30138
|
"div",
|
|
29748
30139
|
{
|
|
29749
|
-
className:
|
|
30140
|
+
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"}`,
|
|
29750
30141
|
onClick: onMobileMenuClose,
|
|
29751
30142
|
"aria-hidden": "true"
|
|
29752
30143
|
}
|
|
29753
30144
|
),
|
|
29754
|
-
/* @__PURE__ */ jsxRuntime.jsxs("aside", { className:
|
|
29755
|
-
/* @__PURE__ */ jsxRuntime.
|
|
29756
|
-
"
|
|
29757
|
-
|
|
29758
|
-
|
|
29759
|
-
|
|
29760
|
-
|
|
29761
|
-
|
|
29762
|
-
|
|
29763
|
-
|
|
29764
|
-
|
|
30145
|
+
/* @__PURE__ */ jsxRuntime.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: [
|
|
30146
|
+
/* @__PURE__ */ jsxRuntime.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: [
|
|
30147
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
30148
|
+
"img",
|
|
30149
|
+
{
|
|
30150
|
+
src: "/optifye-logo.png",
|
|
30151
|
+
alt: "Optifye",
|
|
30152
|
+
className: "w-11 h-11 object-contain",
|
|
30153
|
+
onError: (e) => {
|
|
30154
|
+
e.currentTarget.style.display = "none";
|
|
30155
|
+
if (e.currentTarget.parentElement) {
|
|
30156
|
+
e.currentTarget.parentElement.innerHTML = '<span class="text-blue-600 font-bold text-xl">Optifye</span>';
|
|
30157
|
+
}
|
|
30158
|
+
}
|
|
30159
|
+
}
|
|
30160
|
+
) }),
|
|
30161
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
30162
|
+
"button",
|
|
30163
|
+
{
|
|
30164
|
+
onClick: onMobileMenuClose,
|
|
30165
|
+
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",
|
|
30166
|
+
"aria-label": "Close menu",
|
|
30167
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(outline.XMarkIcon, { className: "w-7 h-7" })
|
|
30168
|
+
}
|
|
30169
|
+
)
|
|
30170
|
+
] }),
|
|
30171
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(MobileNavigationContent, {}) })
|
|
29765
30172
|
] })
|
|
29766
30173
|
] })
|
|
29767
30174
|
] });
|
|
@@ -29853,17 +30260,39 @@ var MainLayout = ({
|
|
|
29853
30260
|
logo
|
|
29854
30261
|
}) => {
|
|
29855
30262
|
const router$1 = router.useRouter();
|
|
30263
|
+
const [isMobileMenuOpen, setIsMobileMenuOpen] = React19.useState(false);
|
|
30264
|
+
const handleMobileMenuOpen = () => setIsMobileMenuOpen(true);
|
|
30265
|
+
const handleMobileMenuClose = () => setIsMobileMenuOpen(false);
|
|
29856
30266
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `min-h-screen ${className}`, children: [
|
|
30267
|
+
/* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
30268
|
+
/* @__PURE__ */ jsxRuntime.jsx(HamburgerButton, { onClick: handleMobileMenuOpen }),
|
|
30269
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
30270
|
+
"img",
|
|
30271
|
+
{
|
|
30272
|
+
src: "/optifye-logo.png",
|
|
30273
|
+
alt: "Optifye",
|
|
30274
|
+
className: "h-9 w-9 object-contain",
|
|
30275
|
+
onError: (e) => {
|
|
30276
|
+
e.currentTarget.style.display = "none";
|
|
30277
|
+
if (e.currentTarget.parentElement) {
|
|
30278
|
+
e.currentTarget.parentElement.innerHTML = '<span class="text-blue-600 font-bold text-lg">Optifye</span>';
|
|
30279
|
+
}
|
|
30280
|
+
}
|
|
30281
|
+
}
|
|
30282
|
+
) })
|
|
30283
|
+
] }) }),
|
|
29857
30284
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
29858
30285
|
SideNavBar,
|
|
29859
30286
|
{
|
|
29860
30287
|
navItems,
|
|
29861
30288
|
currentPathname: router$1.pathname,
|
|
29862
30289
|
currentQuery: router$1.query,
|
|
29863
|
-
logo
|
|
30290
|
+
logo,
|
|
30291
|
+
isMobileMenuOpen,
|
|
30292
|
+
onMobileMenuClose: handleMobileMenuClose
|
|
29864
30293
|
}
|
|
29865
30294
|
),
|
|
29866
|
-
/* @__PURE__ */ jsxRuntime.jsx("main", { className: "ml-20 bg-gray-50 min-h-screen", children })
|
|
30295
|
+
/* @__PURE__ */ jsxRuntime.jsx("main", { className: "md:ml-20 bg-gray-50 min-h-screen transition-all duration-300", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full", children }) })
|
|
29867
30296
|
] });
|
|
29868
30297
|
};
|
|
29869
30298
|
var Header = ({
|
|
@@ -32873,7 +33302,7 @@ function HomeView({
|
|
|
32873
33302
|
return null;
|
|
32874
33303
|
}
|
|
32875
33304
|
return /* @__PURE__ */ jsxRuntime.jsxs(Select, { onValueChange: handleLineChange, defaultValue: selectedLineId, children: [
|
|
32876
|
-
/* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "w-full sm:w-[200px] bg-white border border-gray-200 shadow-sm rounded-md h-9 text-sm", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: "Select a line" }) }),
|
|
33305
|
+
/* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx(SelectValue, { placeholder: "Select a line" }) }),
|
|
32877
33306
|
/* @__PURE__ */ jsxRuntime.jsx(SelectContent, { className: "z-50 bg-white shadow-lg border border-gray-200 rounded-md", children: availableLineIds.map((id3) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: id3, children: lineNames[id3] || (id3 === factoryViewId ? "All Lines" : `Line ${id3.substring(0, 4)}`) }, id3)) })
|
|
32878
33307
|
] });
|
|
32879
33308
|
}, [availableLineIds, handleLineChange, selectedLineId, lineNames, factoryViewId, allLineIds.length]);
|
|
@@ -32885,7 +33314,7 @@ function HomeView({
|
|
|
32885
33314
|
if (errorMessage || displayNamesError) {
|
|
32886
33315
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-screen items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg bg-white p-6 shadow-lg", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-3 text-red-500", children: [
|
|
32887
33316
|
/* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
|
|
32888
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-lg font-medium", children: [
|
|
33317
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-base sm:text-lg font-medium", children: [
|
|
32889
33318
|
"Error: ",
|
|
32890
33319
|
errorMessage || displayNamesError?.message
|
|
32891
33320
|
] })
|
|
@@ -32899,7 +33328,7 @@ function HomeView({
|
|
|
32899
33328
|
animate: { opacity: 1 },
|
|
32900
33329
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex flex-1", children: [
|
|
32901
33330
|
/* @__PURE__ */ jsxRuntime.jsxs("main", { className: "flex flex-1 flex-col", children: [
|
|
32902
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-0 z-30
|
|
33331
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative sm:sticky sm:top-0 z-30 bg-white shadow-sm border-b border-gray-200/80", children: /* @__PURE__ */ jsxRuntime.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__ */ jsxRuntime.jsx(
|
|
32903
33332
|
DashboardHeader,
|
|
32904
33333
|
{
|
|
32905
33334
|
lineTitle,
|
|
@@ -32908,8 +33337,8 @@ function HomeView({
|
|
|
32908
33337
|
}
|
|
32909
33338
|
) }) }),
|
|
32910
33339
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto sm:overflow-hidden relative", children: [
|
|
32911
|
-
lineSelectorComponent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-
|
|
32912
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full sm:h-full min-h-[calc(100vh-
|
|
33340
|
+
lineSelectorComponent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-4 top-3 sm:right-6 sm:top-3 z-30", children: lineSelectorComponent }),
|
|
33341
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full sm:h-full min-h-[calc(100vh-120px)] sm:min-h-0", children: memoizedWorkspaceMetrics.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
32913
33342
|
motion.div,
|
|
32914
33343
|
{
|
|
32915
33344
|
initial: { opacity: 0, scale: 0.98 },
|
|
@@ -38419,8 +38848,8 @@ var WorkspaceHealthView = ({
|
|
|
38419
38848
|
}
|
|
38420
38849
|
};
|
|
38421
38850
|
const getUptimeColor = (percentage) => {
|
|
38422
|
-
if (percentage >=
|
|
38423
|
-
if (percentage >=
|
|
38851
|
+
if (percentage >= 97) return "text-green-600 dark:text-green-400";
|
|
38852
|
+
if (percentage >= 90) return "text-yellow-600 dark:text-yellow-400";
|
|
38424
38853
|
return "text-red-600 dark:text-red-400";
|
|
38425
38854
|
};
|
|
38426
38855
|
if (loading && !summary) {
|
|
@@ -38508,20 +38937,21 @@ var WorkspaceHealthView = ({
|
|
|
38508
38937
|
className: "grid grid-cols-2 sm:grid-cols-2 md:grid-cols-5 gap-2 sm:gap-3 lg:gap-4",
|
|
38509
38938
|
children: [
|
|
38510
38939
|
/* @__PURE__ */ jsxRuntime.jsxs(Card2, { className: "col-span-2 sm:col-span-2 md:col-span-2 bg-white", children: [
|
|
38511
|
-
/* @__PURE__ */ jsxRuntime.jsx(CardHeader2, { className: "pb-3", children: /* @__PURE__ */ jsxRuntime.jsx(CardTitle2, { className: "text-sm font-medium text-gray-500 dark:text-gray-400", children: "Overall System
|
|
38940
|
+
/* @__PURE__ */ jsxRuntime.jsx(CardHeader2, { className: "pb-3", children: /* @__PURE__ */ jsxRuntime.jsx(CardTitle2, { className: "text-sm font-medium text-gray-500 dark:text-gray-400", children: "Overall System Uptime Today" }) }),
|
|
38512
38941
|
/* @__PURE__ */ jsxRuntime.jsxs(CardContent2, { children: [
|
|
38513
38942
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-2", children: [
|
|
38514
38943
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: clsx("text-3xl font-bold", getUptimeColor(summary.uptimePercentage)), children: [
|
|
38515
38944
|
summary.uptimePercentage.toFixed(1),
|
|
38516
38945
|
"%"
|
|
38517
38946
|
] }),
|
|
38518
|
-
summary.uptimePercentage >=
|
|
38947
|
+
summary.uptimePercentage >= 97 ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.TrendingUp, { className: "h-5 w-5 text-green-500" }) : summary.uptimePercentage >= 90 ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Activity, { className: "h-5 w-5 text-yellow-500" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.TrendingDown, { className: "h-5 w-5 text-red-500" })
|
|
38519
38948
|
] }),
|
|
38520
|
-
/* @__PURE__ */ jsxRuntime.
|
|
38949
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mt-1", children: "Average uptime across all workspaces" }),
|
|
38950
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: [
|
|
38521
38951
|
summary.healthyWorkspaces,
|
|
38522
38952
|
" of ",
|
|
38523
38953
|
summary.totalWorkspaces,
|
|
38524
|
-
" workspaces
|
|
38954
|
+
" workspaces online"
|
|
38525
38955
|
] })
|
|
38526
38956
|
] })
|
|
38527
38957
|
] }),
|