@optifye/dashboard-core 6.5.1 → 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 +19 -1
- package/dist/index.d.ts +19 -1
- package/dist/index.js +625 -132
- package/dist/index.mjs +626 -133
- package/package.json +1 -1
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,
|
|
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
|
|
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
|
-
|
|
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
|
|
|
@@ -4122,6 +4311,23 @@ var S3ClipsAPIClient = class {
|
|
|
4122
4311
|
};
|
|
4123
4312
|
});
|
|
4124
4313
|
}
|
|
4314
|
+
/**
|
|
4315
|
+
* Batch fetch multiple videos in parallel
|
|
4316
|
+
*/
|
|
4317
|
+
async batchFetchVideos(workspaceId, date, shiftId, requests) {
|
|
4318
|
+
const batchKey = `batch:${workspaceId}:${date}:${shiftId}:${requests.length}`;
|
|
4319
|
+
return this.deduplicate(batchKey, async () => {
|
|
4320
|
+
const response = await this.fetchWithAuth("/api/clips/batch", {
|
|
4321
|
+
workspaceId,
|
|
4322
|
+
date,
|
|
4323
|
+
shift: shiftId.toString(),
|
|
4324
|
+
requests,
|
|
4325
|
+
sopCategories: this.sopCategories
|
|
4326
|
+
});
|
|
4327
|
+
console.log(`[S3ClipsAPIClient] Batch fetched ${response.videos.length} videos in ${response.performance.duration}ms`);
|
|
4328
|
+
return response.videos;
|
|
4329
|
+
});
|
|
4330
|
+
}
|
|
4125
4331
|
/**
|
|
4126
4332
|
* Convert S3 URI to CloudFront URL
|
|
4127
4333
|
* In the API client, URLs are already signed from the server
|
|
@@ -4405,6 +4611,23 @@ var S3ClipsService = class {
|
|
|
4405
4611
|
);
|
|
4406
4612
|
return result.videos;
|
|
4407
4613
|
}
|
|
4614
|
+
/**
|
|
4615
|
+
* Batch fetch multiple videos in parallel
|
|
4616
|
+
*/
|
|
4617
|
+
async batchFetchVideos(workspaceId, date, shiftId, requests) {
|
|
4618
|
+
try {
|
|
4619
|
+
const results = await this.apiClient.batchFetchVideos(
|
|
4620
|
+
workspaceId,
|
|
4621
|
+
date,
|
|
4622
|
+
shiftId,
|
|
4623
|
+
requests
|
|
4624
|
+
);
|
|
4625
|
+
return results.map((r2) => r2.video).filter((v) => v !== null);
|
|
4626
|
+
} catch (error) {
|
|
4627
|
+
console.error("[S3ClipsService] Error batch fetching videos:", error);
|
|
4628
|
+
return [];
|
|
4629
|
+
}
|
|
4630
|
+
}
|
|
4408
4631
|
/**
|
|
4409
4632
|
* Get videos page using pagination API
|
|
4410
4633
|
*/
|
|
@@ -19661,7 +19884,7 @@ var OptifyeLogoLoader = ({
|
|
|
19661
19884
|
className: `${sizeClasses[size]} h-auto animate-pulse select-none pointer-events-none`
|
|
19662
19885
|
}
|
|
19663
19886
|
),
|
|
19664
|
-
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 })
|
|
19665
19888
|
]
|
|
19666
19889
|
}
|
|
19667
19890
|
);
|
|
@@ -21572,8 +21795,8 @@ var VideoCard = React19__default.memo(({
|
|
|
21572
21795
|
] }) }),
|
|
21573
21796
|
/* @__PURE__ */ jsxs("div", { className: "relative w-full h-full overflow-hidden bg-black", children: [
|
|
21574
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: [
|
|
21575
|
-
/* @__PURE__ */ jsx(Camera, { className:
|
|
21576
|
-
/* @__PURE__ */ jsx("span", { className:
|
|
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..." })
|
|
21577
21800
|
] }) }),
|
|
21578
21801
|
/* @__PURE__ */ jsxs("div", { className: "absolute inset-0 z-10", children: [
|
|
21579
21802
|
/* @__PURE__ */ jsx(
|
|
@@ -21608,10 +21831,10 @@ var VideoCard = React19__default.memo(({
|
|
|
21608
21831
|
}
|
|
21609
21832
|
) })
|
|
21610
21833
|
] }),
|
|
21611
|
-
/* @__PURE__ */ jsxs("div", { className: `absolute bottom-0 left-0 right-0 bg-black bg-opacity-60
|
|
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: [
|
|
21612
21835
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
21613
21836
|
/* @__PURE__ */ jsx(Camera, { size: compact ? 10 : 12, className: "text-white" }),
|
|
21614
|
-
/* @__PURE__ */ jsx("p", { className: `text-white
|
|
21837
|
+
/* @__PURE__ */ jsx("p", { className: `text-white text-[11px] sm:${compact ? "text-[10px]" : "text-xs"} font-medium tracking-wide`, children: displayName })
|
|
21615
21838
|
] }),
|
|
21616
21839
|
/* @__PURE__ */ jsxs("div", { className: `flex items-center ${compact ? "gap-1" : "gap-1.5"}`, children: [
|
|
21617
21840
|
trendInfo && /* @__PURE__ */ jsx(
|
|
@@ -21623,7 +21846,7 @@ var VideoCard = React19__default.memo(({
|
|
|
21623
21846
|
}
|
|
21624
21847
|
),
|
|
21625
21848
|
/* @__PURE__ */ jsx("div", { className: `${compact ? "w-1 h-1" : "w-1.5 h-1.5"} rounded-full bg-green-500` }),
|
|
21626
|
-
/* @__PURE__ */ jsx("span", { className: `text-white
|
|
21849
|
+
/* @__PURE__ */ jsx("span", { className: `text-white text-[11px] sm:${compact ? "text-[10px]" : "text-xs"}`, children: "Live" })
|
|
21627
21850
|
] })
|
|
21628
21851
|
] })
|
|
21629
21852
|
]
|
|
@@ -21833,10 +22056,10 @@ var VideoGridView = React19__default.memo(({
|
|
|
21833
22056
|
view_type: "video_grid"
|
|
21834
22057
|
});
|
|
21835
22058
|
}, []);
|
|
21836
|
-
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(
|
|
21837
22060
|
"div",
|
|
21838
22061
|
{
|
|
21839
|
-
className: "grid h-full w-full gap-2",
|
|
22062
|
+
className: "grid h-full w-full gap-3 sm:gap-2",
|
|
21840
22063
|
style: {
|
|
21841
22064
|
gridTemplateColumns: `repeat(${gridCols}, 1fr)`,
|
|
21842
22065
|
gridTemplateRows: `repeat(${gridRows}, 1fr)`,
|
|
@@ -22621,15 +22844,15 @@ var BreakNotificationPopup = ({
|
|
|
22621
22844
|
/* @__PURE__ */ jsx("div", { className: "w-2 h-2 bg-amber-500 rounded-full animate-pulse flex-shrink-0 mt-2" }),
|
|
22622
22845
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
22623
22846
|
/* @__PURE__ */ jsxs("div", { className: "mb-1", children: [
|
|
22624
|
-
/* @__PURE__ */ jsx("h4", { className: "font-semibold text-sm text-gray-900", children: breakItem.remarks || "Break" }),
|
|
22625
|
-
(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)}` })
|
|
22626
22849
|
] }),
|
|
22627
|
-
/* @__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: [
|
|
22628
22851
|
breakItem.startTime,
|
|
22629
22852
|
" - ",
|
|
22630
22853
|
breakItem.endTime
|
|
22631
22854
|
] }) }),
|
|
22632
|
-
/* @__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: [
|
|
22633
22856
|
formatTime3(breakItem.elapsedMinutes),
|
|
22634
22857
|
" / ",
|
|
22635
22858
|
formatTime3(breakItem.duration)
|
|
@@ -23347,7 +23570,7 @@ var TimeDisplay = ({ className, variant = "default" }) => {
|
|
|
23347
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 || ""}`,
|
|
23348
23571
|
children: [
|
|
23349
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" }) }),
|
|
23350
|
-
/* @__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: [
|
|
23351
23574
|
time2,
|
|
23352
23575
|
" ",
|
|
23353
23576
|
timeSuffix
|
|
@@ -26994,44 +27217,73 @@ var BottlenecksContent = ({
|
|
|
26994
27217
|
if (indicesToLoad.length === 0) return;
|
|
26995
27218
|
console.log(`[ensureVideosLoaded] Preloading ${indicesToLoad.length} videos around index ${centerIndex}: [${indicesToLoad.join(", ")}]`);
|
|
26996
27219
|
indicesToLoad.forEach((idx) => loadingVideosRef.current.add(idx));
|
|
26997
|
-
const
|
|
26998
|
-
|
|
26999
|
-
|
|
27000
|
-
|
|
27001
|
-
|
|
27002
|
-
|
|
27003
|
-
|
|
27220
|
+
const operationalDate = date || getOperationalDate();
|
|
27221
|
+
const shiftStr = effectiveShift;
|
|
27222
|
+
console.log(`[ensureVideosLoaded] Batch fetching ${indicesToLoad.length} videos in parallel`);
|
|
27223
|
+
try {
|
|
27224
|
+
const batchRequests = indicesToLoad.map((index) => ({
|
|
27225
|
+
category: effectiveFilter,
|
|
27226
|
+
index,
|
|
27227
|
+
includeMetadata: false
|
|
27228
|
+
// No metadata during bulk preloading
|
|
27229
|
+
}));
|
|
27230
|
+
const videos = await s3ClipsService.batchFetchVideos(
|
|
27231
|
+
workspaceId,
|
|
27232
|
+
operationalDate,
|
|
27233
|
+
shiftStr,
|
|
27234
|
+
batchRequests
|
|
27235
|
+
);
|
|
27236
|
+
if (videos.length > 0 && isMountedRef.current) {
|
|
27237
|
+
videos.forEach((video, idx) => {
|
|
27238
|
+
if (video) {
|
|
27239
|
+
setAllVideos((prev) => {
|
|
27240
|
+
const exists = prev.some((v) => v.id === video.id);
|
|
27241
|
+
if (!exists) {
|
|
27242
|
+
return [...prev, video];
|
|
27243
|
+
}
|
|
27244
|
+
return prev;
|
|
27245
|
+
});
|
|
27246
|
+
const originalIndex = indicesToLoad[idx];
|
|
27247
|
+
loadedIndices.add(originalIndex);
|
|
27248
|
+
preloadVideoUrl(video.src);
|
|
27249
|
+
}
|
|
27250
|
+
});
|
|
27251
|
+
console.log(`[ensureVideosLoaded] Successfully loaded ${videos.length} videos in batch`);
|
|
27252
|
+
}
|
|
27253
|
+
} catch (error2) {
|
|
27254
|
+
console.error("[ensureVideosLoaded] Batch fetch failed:", error2);
|
|
27255
|
+
const loadPromises = indicesToLoad.map(async (index) => {
|
|
27256
|
+
try {
|
|
27257
|
+
const video = await s3ClipsService.getClipByIndex(
|
|
27004
27258
|
workspaceId,
|
|
27005
27259
|
operationalDate,
|
|
27006
27260
|
shiftStr,
|
|
27007
27261
|
effectiveFilter,
|
|
27008
27262
|
index,
|
|
27009
27263
|
true,
|
|
27010
|
-
// includeCycleTime
|
|
27264
|
+
// includeCycleTime
|
|
27011
27265
|
false
|
|
27012
|
-
// includeMetadata
|
|
27266
|
+
// includeMetadata
|
|
27013
27267
|
);
|
|
27268
|
+
if (video && isMountedRef.current) {
|
|
27269
|
+
setAllVideos((prev) => {
|
|
27270
|
+
const exists = prev.some((v) => v.id === video.id);
|
|
27271
|
+
if (!exists) {
|
|
27272
|
+
return [...prev, video];
|
|
27273
|
+
}
|
|
27274
|
+
return prev;
|
|
27275
|
+
});
|
|
27276
|
+
loadedIndices.add(index);
|
|
27277
|
+
preloadVideoUrl(video.src);
|
|
27278
|
+
}
|
|
27279
|
+
} catch (err) {
|
|
27280
|
+
console.warn(`[ensureVideosLoaded] Failed to load video at index ${index}:`, err);
|
|
27014
27281
|
}
|
|
27015
|
-
|
|
27016
|
-
|
|
27017
|
-
|
|
27018
|
-
|
|
27019
|
-
|
|
27020
|
-
}
|
|
27021
|
-
return prev;
|
|
27022
|
-
});
|
|
27023
|
-
loadedIndices.add(index);
|
|
27024
|
-
preloadVideoUrl(video.src);
|
|
27025
|
-
}
|
|
27026
|
-
} catch (error2) {
|
|
27027
|
-
console.warn(`[ensureVideosLoaded] Failed to load video at index ${index}:`, error2);
|
|
27028
|
-
} finally {
|
|
27029
|
-
loadingVideosRef.current.delete(index);
|
|
27030
|
-
}
|
|
27031
|
-
});
|
|
27032
|
-
Promise.all(loadPromises).catch((err) => {
|
|
27033
|
-
console.warn("[ensureVideosLoaded] Some videos failed to preload:", err);
|
|
27034
|
-
});
|
|
27282
|
+
});
|
|
27283
|
+
await Promise.all(loadPromises);
|
|
27284
|
+
} finally {
|
|
27285
|
+
indicesToLoad.forEach((idx) => loadingVideosRef.current.delete(idx));
|
|
27286
|
+
}
|
|
27035
27287
|
}, [s3ClipsService, workspaceId, clipCounts, sopCategories, date, effectiveShift]);
|
|
27036
27288
|
const loadFirstVideoForCategory = useCallback(async (category) => {
|
|
27037
27289
|
if (!workspaceId || !s3ClipsService || !isMountedRef.current) return;
|
|
@@ -27994,7 +28246,7 @@ var WorkspaceGridItem = React19__default.memo(({
|
|
|
27994
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: [
|
|
27995
28247
|
/* @__PURE__ */ jsx("div", { className: "absolute -inset-1 bg-red-400/50 rounded-full blur-sm animate-pulse" }),
|
|
27996
28248
|
/* @__PURE__ */ jsx("div", { className: "absolute -inset-0.5 bg-red-500/30 rounded-full blur-md animate-ping [animation-duration:1.5s]" }),
|
|
27997
|
-
/* @__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: "!" })
|
|
27998
28250
|
] }) }),
|
|
27999
28251
|
/* @__PURE__ */ jsx(
|
|
28000
28252
|
"button",
|
|
@@ -28003,14 +28255,14 @@ var WorkspaceGridItem = React19__default.memo(({
|
|
|
28003
28255
|
className: `${styles2} ${colorClass} ${isBottleneck ? "ring-2 ring-red-500/70" : ""} ${isVeryLowEfficiency ? "ring-2 ring-red-500/50" : ""} ${isInactive ? "bg-gray-200" : ""} shadow-lg`,
|
|
28004
28256
|
"aria-label": isInactive ? `Inactive workspace ${workspaceNumber}` : `View details for workspace ${workspaceNumber}`,
|
|
28005
28257
|
title: isInactive ? `Inactive: ${getWorkspaceDisplayName(data.workspace_name, data.line_id)}` : getWorkspaceDisplayName(data.workspace_name, data.line_id),
|
|
28006
|
-
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 })
|
|
28007
28259
|
}
|
|
28008
28260
|
),
|
|
28009
28261
|
arrow && !isInactive && /* @__PURE__ */ jsx(
|
|
28010
28262
|
"div",
|
|
28011
28263
|
{
|
|
28012
28264
|
className: `absolute left-1/2 -translate-x-1/2 ${arrowPosition}
|
|
28013
|
-
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`,
|
|
28014
28266
|
style: { bottom: "-2.5rem", lineHeight: 1, display: "flex", alignItems: "center", justifyContent: "center" },
|
|
28015
28267
|
children: arrow
|
|
28016
28268
|
}
|
|
@@ -28040,11 +28292,11 @@ var WorkspaceGrid = React19__default.memo(({
|
|
|
28040
28292
|
}, [workspaces.length]);
|
|
28041
28293
|
const { VideoGridView: VideoGridViewComponent } = useRegistry();
|
|
28042
28294
|
return /* @__PURE__ */ jsxs("div", { className: `relative w-full h-full overflow-hidden ${className}`, children: [
|
|
28043
|
-
/* @__PURE__ */ jsxs("div", { className: "absolute top-0 left-
|
|
28044
|
-
/* @__PURE__ */ jsx("div", { className: "flex flex-row items-center justify-between py-
|
|
28045
|
-
/* @__PURE__ */ jsx("div", { className: "sm:hidden mt-
|
|
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, {}) })
|
|
28046
28298
|
] }),
|
|
28047
|
-
/* @__PURE__ */ jsx("div", { className: "absolute top-
|
|
28299
|
+
/* @__PURE__ */ jsx("div", { className: "absolute top-12 sm:top-16 left-0 right-0 bottom-0", children: /* @__PURE__ */ jsx(
|
|
28048
28300
|
VideoGridViewComponent,
|
|
28049
28301
|
{
|
|
28050
28302
|
workspaces,
|
|
@@ -28259,8 +28511,8 @@ var KPICard = ({
|
|
|
28259
28511
|
const cardClasses = clsx(
|
|
28260
28512
|
// Base classes
|
|
28261
28513
|
"rounded-lg transition-all duration-200",
|
|
28262
|
-
// Sizing based on compact mode -
|
|
28263
|
-
"p-
|
|
28514
|
+
// Sizing based on compact mode - better padding on mobile
|
|
28515
|
+
"p-2.5 sm:p-3 md:p-4",
|
|
28264
28516
|
// Variant-specific styling
|
|
28265
28517
|
{
|
|
28266
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",
|
|
@@ -28268,8 +28520,8 @@ var KPICard = ({
|
|
|
28268
28520
|
"bg-blue-50 border border-blue-200 dark:bg-blue-900/20 dark:border-blue-800/30": style.variant === "filled",
|
|
28269
28521
|
"bg-gray-50/50 dark:bg-gray-800/30": style.variant === "subtle"
|
|
28270
28522
|
},
|
|
28271
|
-
// Width for src matching -
|
|
28272
|
-
!className?.includes("w-") && "w-[
|
|
28523
|
+
// Width for src matching - better mobile width, flexible on small screens
|
|
28524
|
+
!className?.includes("w-") && "w-[110px] sm:w-[180px] md:w-[220px]",
|
|
28273
28525
|
// Interactive styling if onClick is provided
|
|
28274
28526
|
onClick && "cursor-pointer hover:scale-[1.01] active:scale-[0.99]",
|
|
28275
28527
|
// Loading state
|
|
@@ -28288,14 +28540,14 @@ var KPICard = ({
|
|
|
28288
28540
|
children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
28289
28541
|
/* @__PURE__ */ jsx("span", { className: clsx(
|
|
28290
28542
|
"font-medium text-gray-500 dark:text-gray-400",
|
|
28291
|
-
"text-[
|
|
28292
|
-
"mb-
|
|
28293
|
-
"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"
|
|
28294
28546
|
), children: title }),
|
|
28295
28547
|
/* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-0.5 sm:gap-2 flex-wrap", children: [
|
|
28296
28548
|
/* @__PURE__ */ jsx("span", { className: clsx(
|
|
28297
28549
|
"font-bold text-gray-900 dark:text-gray-50",
|
|
28298
|
-
"text-
|
|
28550
|
+
"text-base sm:text-xl md:text-2xl"
|
|
28299
28551
|
), children: isLoading ? "\u2014" : formattedValue }),
|
|
28300
28552
|
suffix && !isLoading && /* @__PURE__ */ jsx("span", { className: clsx(
|
|
28301
28553
|
"font-medium text-gray-600 dark:text-gray-300",
|
|
@@ -28470,35 +28722,46 @@ var KPISection = memo(({
|
|
|
28470
28722
|
const outputDifference = kpis.outputProgress.current - kpis.outputProgress.idealOutput;
|
|
28471
28723
|
const outputIsOnTarget = outputDifference >= 0;
|
|
28472
28724
|
if (useSrcLayout) {
|
|
28473
|
-
return /* @__PURE__ */ jsxs(
|
|
28474
|
-
|
|
28475
|
-
|
|
28476
|
-
{
|
|
28477
|
-
|
|
28478
|
-
|
|
28479
|
-
|
|
28480
|
-
|
|
28481
|
-
|
|
28482
|
-
|
|
28483
|
-
|
|
28484
|
-
|
|
28485
|
-
|
|
28486
|
-
|
|
28487
|
-
|
|
28488
|
-
|
|
28489
|
-
|
|
28490
|
-
|
|
28491
|
-
|
|
28492
|
-
|
|
28493
|
-
|
|
28494
|
-
|
|
28495
|
-
|
|
28496
|
-
|
|
28497
|
-
|
|
28498
|
-
|
|
28499
|
-
|
|
28500
|
-
|
|
28501
|
-
|
|
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
|
+
);
|
|
28502
28765
|
}
|
|
28503
28766
|
const kpiCardData = [
|
|
28504
28767
|
{
|
|
@@ -28631,6 +28894,19 @@ var WorkspaceHealthCard = ({
|
|
|
28631
28894
|
const formatTimeAgo = (timeString) => {
|
|
28632
28895
|
return timeString.replace("about ", "").replace(" ago", "");
|
|
28633
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
|
+
};
|
|
28634
28910
|
return /* @__PURE__ */ jsx(
|
|
28635
28911
|
Card2,
|
|
28636
28912
|
{
|
|
@@ -28664,13 +28940,32 @@ var WorkspaceHealthCard = ({
|
|
|
28664
28940
|
/* @__PURE__ */ jsx("span", { children: config.statusText })
|
|
28665
28941
|
] })
|
|
28666
28942
|
] }),
|
|
28667
|
-
/* @__PURE__ */
|
|
28668
|
-
/* @__PURE__ */
|
|
28669
|
-
|
|
28670
|
-
"
|
|
28671
|
-
|
|
28672
|
-
|
|
28673
|
-
|
|
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
|
+
] })
|
|
28674
28969
|
] })
|
|
28675
28970
|
}
|
|
28676
28971
|
);
|
|
@@ -28741,6 +29036,20 @@ var CompactWorkspaceHealthCard = ({
|
|
|
28741
29036
|
] })
|
|
28742
29037
|
] }),
|
|
28743
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
|
+
] }),
|
|
28744
29053
|
/* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: workspace.timeSinceLastUpdate }),
|
|
28745
29054
|
/* @__PURE__ */ jsx("div", { className: clsx("h-2 w-2 rounded-full", config.dot) })
|
|
28746
29055
|
] })
|
|
@@ -28964,18 +29273,18 @@ var DashboardHeader = memo(({ lineTitle, className = "", headerControls }) => {
|
|
|
28964
29273
|
};
|
|
28965
29274
|
return /* @__PURE__ */ jsxs("div", { className: `flex flex-row items-center justify-between w-full ${className}`, children: [
|
|
28966
29275
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
28967
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-
|
|
28968
|
-
/* @__PURE__ */ jsx("h1", { className: "text-
|
|
28969
|
-
/* @__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-
|
|
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" })
|
|
28970
29279
|
] }),
|
|
28971
|
-
/* @__PURE__ */ jsxs("div", { className: "mt-2 inline-flex items-center gap-3", children: [
|
|
28972
|
-
/* @__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: [
|
|
28973
29282
|
/* @__PURE__ */ jsx(ISTTimer2, {}),
|
|
28974
29283
|
" IST"
|
|
28975
29284
|
] }),
|
|
28976
29285
|
/* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1", children: [
|
|
28977
29286
|
/* @__PURE__ */ jsx("div", { className: "text-gray-600", children: getShiftIcon() }),
|
|
28978
|
-
/* @__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: [
|
|
28979
29288
|
getShiftName(),
|
|
28980
29289
|
" Shift"
|
|
28981
29290
|
] })
|
|
@@ -28986,9 +29295,9 @@ var DashboardHeader = memo(({ lineTitle, className = "", headerControls }) => {
|
|
|
28986
29295
|
] });
|
|
28987
29296
|
});
|
|
28988
29297
|
DashboardHeader.displayName = "DashboardHeader";
|
|
28989
|
-
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: [
|
|
28990
|
-
/* @__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" }) }),
|
|
28991
|
-
/* @__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 })
|
|
28992
29301
|
] }) }) }));
|
|
28993
29302
|
NoWorkspaceData.displayName = "NoWorkspaceData";
|
|
28994
29303
|
var WorkspaceMonthlyDataFetcher = ({
|
|
@@ -29113,10 +29422,10 @@ var HamburgerButton = ({
|
|
|
29113
29422
|
"button",
|
|
29114
29423
|
{
|
|
29115
29424
|
type: "button",
|
|
29116
|
-
className: `md:hidden p-2 rounded-
|
|
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}`,
|
|
29117
29426
|
onClick,
|
|
29118
29427
|
"aria-label": ariaLabel,
|
|
29119
|
-
children: /* @__PURE__ */ jsx(Bars3Icon, { className: "w-
|
|
29428
|
+
children: /* @__PURE__ */ jsx(Bars3Icon, { className: "w-7 h-7" })
|
|
29120
29429
|
}
|
|
29121
29430
|
);
|
|
29122
29431
|
};
|
|
@@ -29647,28 +29956,189 @@ var SideNavBar = memo(({
|
|
|
29647
29956
|
}
|
|
29648
29957
|
) })
|
|
29649
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
|
+
};
|
|
29650
30104
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
29651
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, {}) }),
|
|
29652
|
-
|
|
30106
|
+
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
29653
30107
|
/* @__PURE__ */ jsx(
|
|
29654
30108
|
"div",
|
|
29655
30109
|
{
|
|
29656
|
-
className:
|
|
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"}`,
|
|
29657
30111
|
onClick: onMobileMenuClose,
|
|
29658
30112
|
"aria-hidden": "true"
|
|
29659
30113
|
}
|
|
29660
30114
|
),
|
|
29661
|
-
/* @__PURE__ */ jsxs("aside", { className:
|
|
29662
|
-
/* @__PURE__ */
|
|
29663
|
-
"
|
|
29664
|
-
|
|
29665
|
-
|
|
29666
|
-
|
|
29667
|
-
|
|
29668
|
-
|
|
29669
|
-
|
|
29670
|
-
|
|
29671
|
-
|
|
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, {}) })
|
|
29672
30142
|
] })
|
|
29673
30143
|
] })
|
|
29674
30144
|
] });
|
|
@@ -29760,17 +30230,39 @@ var MainLayout = ({
|
|
|
29760
30230
|
logo
|
|
29761
30231
|
}) => {
|
|
29762
30232
|
const router = useRouter();
|
|
30233
|
+
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
|
30234
|
+
const handleMobileMenuOpen = () => setIsMobileMenuOpen(true);
|
|
30235
|
+
const handleMobileMenuClose = () => setIsMobileMenuOpen(false);
|
|
29763
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
|
+
] }) }),
|
|
29764
30254
|
/* @__PURE__ */ jsx(
|
|
29765
30255
|
SideNavBar,
|
|
29766
30256
|
{
|
|
29767
30257
|
navItems,
|
|
29768
30258
|
currentPathname: router.pathname,
|
|
29769
30259
|
currentQuery: router.query,
|
|
29770
|
-
logo
|
|
30260
|
+
logo,
|
|
30261
|
+
isMobileMenuOpen,
|
|
30262
|
+
onMobileMenuClose: handleMobileMenuClose
|
|
29771
30263
|
}
|
|
29772
30264
|
),
|
|
29773
|
-
/* @__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 }) })
|
|
29774
30266
|
] });
|
|
29775
30267
|
};
|
|
29776
30268
|
var Header = ({
|
|
@@ -32780,7 +33272,7 @@ function HomeView({
|
|
|
32780
33272
|
return null;
|
|
32781
33273
|
}
|
|
32782
33274
|
return /* @__PURE__ */ jsxs(Select, { onValueChange: handleLineChange, defaultValue: selectedLineId, children: [
|
|
32783
|
-
/* @__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" }) }),
|
|
32784
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)) })
|
|
32785
33277
|
] });
|
|
32786
33278
|
}, [availableLineIds, handleLineChange, selectedLineId, lineNames, factoryViewId, allLineIds.length]);
|
|
@@ -32792,7 +33284,7 @@ function HomeView({
|
|
|
32792
33284
|
if (errorMessage || displayNamesError) {
|
|
32793
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: [
|
|
32794
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" }) }),
|
|
32795
|
-
/* @__PURE__ */ jsxs("span", { className: "text-lg font-medium", children: [
|
|
33287
|
+
/* @__PURE__ */ jsxs("span", { className: "text-base sm:text-lg font-medium", children: [
|
|
32796
33288
|
"Error: ",
|
|
32797
33289
|
errorMessage || displayNamesError?.message
|
|
32798
33290
|
] })
|
|
@@ -32806,7 +33298,7 @@ function HomeView({
|
|
|
32806
33298
|
animate: { opacity: 1 },
|
|
32807
33299
|
children: /* @__PURE__ */ jsxs("div", { className: "relative flex flex-1", children: [
|
|
32808
33300
|
/* @__PURE__ */ jsxs("main", { className: "flex flex-1 flex-col", children: [
|
|
32809
|
-
/* @__PURE__ */ jsx("div", { className: "sticky top-0 z-30
|
|
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(
|
|
32810
33302
|
DashboardHeader,
|
|
32811
33303
|
{
|
|
32812
33304
|
lineTitle,
|
|
@@ -32815,8 +33307,8 @@ function HomeView({
|
|
|
32815
33307
|
}
|
|
32816
33308
|
) }) }),
|
|
32817
33309
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto sm:overflow-hidden relative", children: [
|
|
32818
|
-
lineSelectorComponent && /* @__PURE__ */ jsx("div", { className: "absolute right-
|
|
32819
|
-
/* @__PURE__ */ jsx("div", { className: "h-full sm:h-full min-h-[calc(100vh-
|
|
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(
|
|
32820
33312
|
motion.div,
|
|
32821
33313
|
{
|
|
32822
33314
|
initial: { opacity: 0, scale: 0.98 },
|
|
@@ -38326,8 +38818,8 @@ var WorkspaceHealthView = ({
|
|
|
38326
38818
|
}
|
|
38327
38819
|
};
|
|
38328
38820
|
const getUptimeColor = (percentage) => {
|
|
38329
|
-
if (percentage >=
|
|
38330
|
-
if (percentage >=
|
|
38821
|
+
if (percentage >= 97) return "text-green-600 dark:text-green-400";
|
|
38822
|
+
if (percentage >= 90) return "text-yellow-600 dark:text-yellow-400";
|
|
38331
38823
|
return "text-red-600 dark:text-red-400";
|
|
38332
38824
|
};
|
|
38333
38825
|
if (loading && !summary) {
|
|
@@ -38415,20 +38907,21 @@ var WorkspaceHealthView = ({
|
|
|
38415
38907
|
className: "grid grid-cols-2 sm:grid-cols-2 md:grid-cols-5 gap-2 sm:gap-3 lg:gap-4",
|
|
38416
38908
|
children: [
|
|
38417
38909
|
/* @__PURE__ */ jsxs(Card2, { className: "col-span-2 sm:col-span-2 md:col-span-2 bg-white", children: [
|
|
38418
|
-
/* @__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
|
|
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" }) }),
|
|
38419
38911
|
/* @__PURE__ */ jsxs(CardContent2, { children: [
|
|
38420
38912
|
/* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-2", children: [
|
|
38421
38913
|
/* @__PURE__ */ jsxs("span", { className: clsx("text-3xl font-bold", getUptimeColor(summary.uptimePercentage)), children: [
|
|
38422
38914
|
summary.uptimePercentage.toFixed(1),
|
|
38423
38915
|
"%"
|
|
38424
38916
|
] }),
|
|
38425
|
-
summary.uptimePercentage >=
|
|
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" })
|
|
38426
38918
|
] }),
|
|
38427
|
-
/* @__PURE__ */
|
|
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: [
|
|
38428
38921
|
summary.healthyWorkspaces,
|
|
38429
38922
|
" of ",
|
|
38430
38923
|
summary.totalWorkspaces,
|
|
38431
|
-
" workspaces
|
|
38924
|
+
" workspaces online"
|
|
38432
38925
|
] })
|
|
38433
38926
|
] })
|
|
38434
38927
|
] }),
|