@optifye/dashboard-core 6.0.3 → 6.0.4
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 +3702 -0
- package/dist/index.d.mts +258 -10
- package/dist/index.d.ts +258 -10
- package/dist/index.js +2460 -816
- package/dist/index.mjs +1842 -211
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
1
|
+
import * as React19 from 'react';
|
|
2
|
+
import React19__default, { createContext, useRef, useCallback, useState, useMemo, useEffect, memo, useContext, useLayoutEffect, useId, Children, isValidElement, useInsertionEffect, forwardRef, Fragment as Fragment$1, createElement, Component } from 'react';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
import { useRouter } from 'next/router';
|
|
5
5
|
import { toZonedTime, formatInTimeZone } from 'date-fns-tz';
|
|
@@ -10,15 +10,15 @@ import Hls2 from 'hls.js';
|
|
|
10
10
|
import useSWR from 'swr';
|
|
11
11
|
import { noop, warning, invariant, progress, secondsToMilliseconds, millisecondsToSeconds, memo as memo$1 } from 'motion-utils';
|
|
12
12
|
import { getValueTransition, hover, press, isPrimaryPointer, GroupPlaybackControls, setDragLock, supportsLinearEasing, attachTimeline, isGenerator, calcGeneratorDuration, isWaapiSupportedEasing, mapEasingToNativeEasing, maxGeneratorDuration, generateLinearEasing, isBezierDefinition } from 'motion-dom';
|
|
13
|
-
import {
|
|
13
|
+
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';
|
|
14
14
|
import { Slot } from '@radix-ui/react-slot';
|
|
15
|
-
import { Camera, ChevronDown, ChevronUp, Check, ShieldCheck, Star, Award, X, Coffee, Plus, Clock, Minus, ArrowDown, ArrowUp, Search, CheckCircle, AlertTriangle, Info, Share2, Download, User, XCircle, ChevronLeft, ChevronRight, AlertCircle, Sun, Moon, MessageSquare, Trash2, ArrowLeft, RefreshCw, Menu, Send, Copy, Edit2, UserCheck, Save, LogOut, Calendar, Settings, LifeBuoy, Loader2, ArrowLeftIcon as ArrowLeftIcon$1, Settings2, CheckCircle2, EyeOff, Eye, Zap, UserCircle } from 'lucide-react';
|
|
15
|
+
import { Camera, ChevronDown, ChevronUp, Check, ShieldCheck, Star, Award, X, Coffee, Plus, Clock, Minus, ArrowDown, ArrowUp, Search, CheckCircle, AlertTriangle, Info, Share2, Download, User, XCircle, ChevronLeft, ChevronRight, AlertCircle, Sun, Moon, MessageSquare, Trash2, ArrowLeft, RefreshCw, Menu, Send, Copy, Edit2, UserCheck, Save, LogOut, Calendar, Package, Settings, LifeBuoy, Loader2, ArrowLeftIcon as ArrowLeftIcon$1, Settings2, CheckCircle2, EyeOff, Eye, Zap, UserCircle } from 'lucide-react';
|
|
16
16
|
import { DayPicker, useNavigation as useNavigation$1 } from 'react-day-picker';
|
|
17
17
|
import html2canvas from 'html2canvas';
|
|
18
18
|
import jsPDF, { jsPDF as jsPDF$1 } from 'jspdf';
|
|
19
19
|
import * as SelectPrimitive from '@radix-ui/react-select';
|
|
20
20
|
import { S3Client, ListObjectsV2Command, GetObjectCommand } from '@aws-sdk/client-s3';
|
|
21
|
-
import { HomeIcon, TrophyIcon, ChartBarIcon, AdjustmentsHorizontalIcon, ClockIcon, SparklesIcon, QuestionMarkCircleIcon, UserCircleIcon, ArrowRightIcon, ArrowLeftIcon, ChatBubbleLeftRightIcon, CheckCircleIcon, ExclamationCircleIcon, DocumentTextIcon, EnvelopeIcon, InformationCircleIcon, ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/outline';
|
|
21
|
+
import { HomeIcon, TrophyIcon, ChartBarIcon, AdjustmentsHorizontalIcon, ClockIcon, CubeIcon, SparklesIcon, QuestionMarkCircleIcon, UserCircleIcon, ArrowRightIcon, ArrowLeftIcon, ChatBubbleLeftRightIcon, CheckCircleIcon, ExclamationCircleIcon, DocumentTextIcon, EnvelopeIcon, InformationCircleIcon, ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/24/outline';
|
|
22
22
|
import { Readable } from 'stream';
|
|
23
23
|
import { toast } from 'sonner';
|
|
24
24
|
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
|
@@ -205,14 +205,14 @@ var _getDashboardConfigInstance = () => {
|
|
|
205
205
|
}
|
|
206
206
|
return dashboardConfigInstance;
|
|
207
207
|
};
|
|
208
|
-
var DashboardConfigContext =
|
|
208
|
+
var DashboardConfigContext = React19.createContext(void 0);
|
|
209
209
|
var DashboardProvider = ({ config: userProvidedConfig, children }) => {
|
|
210
|
-
const fullConfig =
|
|
210
|
+
const fullConfig = React19.useMemo(() => mergeWithDefaultConfig(userProvidedConfig), [userProvidedConfig]);
|
|
211
211
|
_setDashboardConfigInstance(fullConfig);
|
|
212
|
-
|
|
212
|
+
React19.useEffect(() => {
|
|
213
213
|
_setDashboardConfigInstance(fullConfig);
|
|
214
214
|
}, [fullConfig]);
|
|
215
|
-
|
|
215
|
+
React19.useEffect(() => {
|
|
216
216
|
if (!fullConfig.theme) return;
|
|
217
217
|
const styleId = "dashboard-core-theme-vars";
|
|
218
218
|
let styleEl = document.getElementById(styleId);
|
|
@@ -238,7 +238,7 @@ var DashboardProvider = ({ config: userProvidedConfig, children }) => {
|
|
|
238
238
|
return /* @__PURE__ */ jsx(DashboardConfigContext.Provider, { value: fullConfig, children });
|
|
239
239
|
};
|
|
240
240
|
var useDashboardConfig = () => {
|
|
241
|
-
const ctx =
|
|
241
|
+
const ctx = React19.useContext(DashboardConfigContext);
|
|
242
242
|
if (!ctx) throw new Error("useDashboardConfig must be used within a DashboardProvider");
|
|
243
243
|
return ctx;
|
|
244
244
|
};
|
|
@@ -331,6 +331,56 @@ var actionService = {
|
|
|
331
331
|
return data || [];
|
|
332
332
|
}
|
|
333
333
|
};
|
|
334
|
+
function createMemoizedFunction(fn, getCacheKey) {
|
|
335
|
+
const cache = /* @__PURE__ */ new Map();
|
|
336
|
+
const CACHE_DURATION3 = 5 * 60 * 1e3;
|
|
337
|
+
return (...args) => {
|
|
338
|
+
const key = getCacheKey(...args);
|
|
339
|
+
const cached = cache.get(key);
|
|
340
|
+
if (cached && Date.now() - cached.timestamp < CACHE_DURATION3) {
|
|
341
|
+
return cached.result;
|
|
342
|
+
}
|
|
343
|
+
const result = fn(...args);
|
|
344
|
+
cache.set(key, { result, timestamp: Date.now() });
|
|
345
|
+
if (cache.size > 100) {
|
|
346
|
+
const firstKey = cache.keys().next().value;
|
|
347
|
+
if (firstKey) cache.delete(firstKey);
|
|
348
|
+
}
|
|
349
|
+
return result;
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
var memoizedEfficiencyFilter = createMemoizedFunction(
|
|
353
|
+
(data, minEfficiency, maxEfficiency) => {
|
|
354
|
+
return data.filter((item) => {
|
|
355
|
+
const eff = item.efficiency ?? 0;
|
|
356
|
+
return eff >= minEfficiency && (maxEfficiency === void 0 || eff < maxEfficiency);
|
|
357
|
+
});
|
|
358
|
+
},
|
|
359
|
+
(data, min, max = void 0) => `${data.length}-${min}-${max}`
|
|
360
|
+
);
|
|
361
|
+
var memoizedAverageEfficiency = createMemoizedFunction(
|
|
362
|
+
(data, minThreshold = 10) => {
|
|
363
|
+
const validItems = data.filter((item) => (item.efficiency ?? 0) >= minThreshold);
|
|
364
|
+
if (validItems.length === 0) return 0;
|
|
365
|
+
const sum = validItems.reduce((acc, item) => acc + (item.efficiency ?? 0), 0);
|
|
366
|
+
return sum / validItems.length;
|
|
367
|
+
},
|
|
368
|
+
(data, threshold) => `${data.length}-${threshold}`
|
|
369
|
+
);
|
|
370
|
+
var memoizedOutputArrayAggregation = createMemoizedFunction(
|
|
371
|
+
(arrays) => {
|
|
372
|
+
if (arrays.length === 0) return [];
|
|
373
|
+
const maxLength = Math.max(...arrays.map((arr) => arr.length));
|
|
374
|
+
const result = new Array(maxLength).fill(0);
|
|
375
|
+
for (const arr of arrays) {
|
|
376
|
+
for (let i = 0; i < arr.length; i++) {
|
|
377
|
+
result[i] += arr[i];
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return result;
|
|
381
|
+
},
|
|
382
|
+
(arrays) => arrays.map((arr) => arr.length).join("-")
|
|
383
|
+
);
|
|
334
384
|
var getOperationalDate = (timezone = "Asia/Kolkata", date = /* @__PURE__ */ new Date(), shiftStartTime = "06:00") => {
|
|
335
385
|
const zonedDate = toZonedTime(date, timezone);
|
|
336
386
|
const hours = zonedDate.getHours();
|
|
@@ -468,22 +518,32 @@ var dashboardService = {
|
|
|
468
518
|
if (!defaultLineId || !secondaryLineId || !companyId) {
|
|
469
519
|
throw new Error("Factory View requires defaultLineId, secondaryLineId, and companyId to be configured.");
|
|
470
520
|
}
|
|
471
|
-
const
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
521
|
+
const [lineResult, metricsResult, performanceResult] = await Promise.all([
|
|
522
|
+
// Get Line 1's info for general factory details
|
|
523
|
+
supabase.from(linesTable).select(`
|
|
524
|
+
id,
|
|
525
|
+
line_name,
|
|
526
|
+
factory_id,
|
|
527
|
+
factories!lines_factory_id_fkey(factory_name),
|
|
528
|
+
company_id,
|
|
529
|
+
companies!lines_company_id_fkey(company_name:name)
|
|
530
|
+
`).eq("id", defaultLineId).maybeSingle(),
|
|
531
|
+
// Get metrics from line_metrics table for both lines
|
|
532
|
+
supabase.from(lineMetricsTable).select("*").in("line_id", [defaultLineId, secondaryLineId]).eq("shift_id", shiftId).eq("date", date),
|
|
533
|
+
// Get performance data from the dynamic metrics table for both lines
|
|
534
|
+
supabase.from(metricsTable).select("efficiency").in("line_id", [defaultLineId, secondaryLineId]).eq("shift_id", shiftId).eq("date", date)
|
|
535
|
+
]);
|
|
536
|
+
if (lineResult.error) throw lineResult.error;
|
|
537
|
+
if (!lineResult.data) throw new Error(`Configured default line (${defaultLineId}) not found`);
|
|
538
|
+
if (metricsResult.error) throw metricsResult.error;
|
|
539
|
+
if (performanceResult.error) throw performanceResult.error;
|
|
540
|
+
const lineData2 = lineResult.data;
|
|
541
|
+
const metricsData = metricsResult.data;
|
|
542
|
+
const performanceData2 = performanceResult.data;
|
|
543
|
+
const underperformingWorkspaces2 = memoizedEfficiencyFilter(performanceData2 || [], 10, 70);
|
|
544
|
+
const validWorkspaces2 = memoizedEfficiencyFilter(performanceData2 || [], 10);
|
|
545
|
+
const underperformingCount2 = underperformingWorkspaces2.length;
|
|
546
|
+
validWorkspaces2.length;
|
|
487
547
|
const combinedMetrics = (metricsData || []).reduce((acc, m) => {
|
|
488
548
|
acc.avg_efficiency += m.efficiency ?? 0;
|
|
489
549
|
acc.current_output += m.current_output ?? 0;
|
|
@@ -503,13 +563,13 @@ var dashboardService = {
|
|
|
503
563
|
shift_id: shiftId,
|
|
504
564
|
date,
|
|
505
565
|
metrics: {
|
|
506
|
-
avg_efficiency: (performanceData2
|
|
507
|
-
// Use
|
|
566
|
+
avg_efficiency: memoizedAverageEfficiency(performanceData2 || [], 10),
|
|
567
|
+
// Use memoized calculation for efficiency
|
|
508
568
|
avg_cycle_time: 0,
|
|
509
569
|
// Needs calculation logic if required for factory view
|
|
510
570
|
current_output: combinedMetrics.current_output,
|
|
511
571
|
ideal_output: combinedMetrics.ideal_output,
|
|
512
|
-
total_workspaces:
|
|
572
|
+
total_workspaces: 0,
|
|
513
573
|
// SRC ALIGNMENT: Use hardcoded 44 for factory view total_workspaces
|
|
514
574
|
underperforming_workspaces: underperformingCount2,
|
|
515
575
|
underperforming_workspace_names: [],
|
|
@@ -547,9 +607,11 @@ var dashboardService = {
|
|
|
547
607
|
}
|
|
548
608
|
const { data: performanceData, error: performanceError } = await supabase.from(metricsTable).select("efficiency").eq("line_id", lineId).eq("shift_id", shiftId).eq("date", date);
|
|
549
609
|
if (performanceError) throw performanceError;
|
|
550
|
-
const
|
|
551
|
-
const
|
|
552
|
-
const
|
|
610
|
+
const underperformingWorkspaces = memoizedEfficiencyFilter(performanceData || [], 10, 70);
|
|
611
|
+
const validWorkspaces = memoizedEfficiencyFilter(performanceData || [], 10);
|
|
612
|
+
const underperformingCount = underperformingWorkspaces.length;
|
|
613
|
+
validWorkspaces.length;
|
|
614
|
+
const avgEfficiencyFromPerf = memoizedAverageEfficiency(performanceData || [], 10);
|
|
553
615
|
const useFallbackMetrics = !metricsFromDb;
|
|
554
616
|
let metricsForReturn;
|
|
555
617
|
if (useFallbackMetrics) {
|
|
@@ -867,19 +929,26 @@ var dashboardService = {
|
|
|
867
929
|
if (!defaultLineId || !companyId) {
|
|
868
930
|
throw new Error("Factory View requires at least defaultLineId and companyId to be configured.");
|
|
869
931
|
}
|
|
870
|
-
const
|
|
871
|
-
|
|
872
|
-
|
|
932
|
+
const lineIdsToQuery = [defaultLineId, secondaryLineId].filter((id3) => id3 !== void 0 && id3 !== null);
|
|
933
|
+
const [line1Result, metricsResult2, performanceResult2] = await Promise.all([
|
|
934
|
+
supabase.from(linesTable).select("id, line_name, factory_id, factories!lines_factory_id_fkey(factory_name), company_id, companies!lines_company_id_fkey(company_name:name)").eq("id", defaultLineId).single(),
|
|
935
|
+
supabase.from(lineMetricsTable).select("*").in("line_id", lineIdsToQuery).eq("shift_id", queryShiftId).eq("date", queryDate),
|
|
936
|
+
supabase.from(metricsTable).select("efficiency").in("line_id", lineIdsToQuery).eq("shift_id", queryShiftId).eq("date", queryDate)
|
|
937
|
+
]);
|
|
938
|
+
if (line1Result.error) throw line1Result.error;
|
|
939
|
+
if (!line1Result.data) {
|
|
873
940
|
throw new Error(`Default line ${defaultLineId} for Factory View not found.`);
|
|
874
941
|
}
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
const
|
|
879
|
-
|
|
880
|
-
const
|
|
881
|
-
const
|
|
882
|
-
const
|
|
942
|
+
if (metricsResult2.error) throw metricsResult2.error;
|
|
943
|
+
if (performanceResult2.error) throw performanceResult2.error;
|
|
944
|
+
const line1Data = line1Result.data;
|
|
945
|
+
const metricsData = metricsResult2.data;
|
|
946
|
+
const performanceData2 = performanceResult2.data;
|
|
947
|
+
const underperformingWorkspaces2 = memoizedEfficiencyFilter(performanceData2 || [], 10, 70);
|
|
948
|
+
const validWorkspaces2 = memoizedEfficiencyFilter(performanceData2 || [], 10);
|
|
949
|
+
const underperformingCount2 = underperformingWorkspaces2.length;
|
|
950
|
+
const totalValidWorkspaces2 = validWorkspaces2.length;
|
|
951
|
+
const avgEfficiencyFromPerf2 = memoizedAverageEfficiency(performanceData2 || [], 10);
|
|
883
952
|
const initialAccumulator = {
|
|
884
953
|
avg_cycle_time: 0,
|
|
885
954
|
current_output: 0,
|
|
@@ -887,7 +956,8 @@ var dashboardService = {
|
|
|
887
956
|
line_threshold: 0,
|
|
888
957
|
threshold_pph: 0,
|
|
889
958
|
total_workspaces: 0,
|
|
890
|
-
output_array: []
|
|
959
|
+
output_array: [],
|
|
960
|
+
outputArrays: []
|
|
891
961
|
};
|
|
892
962
|
const combinedMetricsData = (metricsData || []).reduce((acc, m) => {
|
|
893
963
|
acc.avg_cycle_time += m.avg_cycle_time ?? 0;
|
|
@@ -897,14 +967,7 @@ var dashboardService = {
|
|
|
897
967
|
acc.threshold_pph += m.threshold_pph ?? 0;
|
|
898
968
|
acc.total_workspaces += m.total_workspaces ?? 0;
|
|
899
969
|
if (m.output_array && m.output_array.length > 0) {
|
|
900
|
-
|
|
901
|
-
if (!acc.output_array || acc.output_array.length === 0) acc.output_array = [...currentMOutputArray];
|
|
902
|
-
else {
|
|
903
|
-
acc.output_array = acc.output_array.map((val, i) => val + (currentMOutputArray[i] ?? 0));
|
|
904
|
-
if (currentMOutputArray.length > acc.output_array.length) {
|
|
905
|
-
acc.output_array.push(...currentMOutputArray.slice(acc.output_array.length));
|
|
906
|
-
}
|
|
907
|
-
}
|
|
970
|
+
acc.outputArrays.push(m.output_array);
|
|
908
971
|
}
|
|
909
972
|
return acc;
|
|
910
973
|
}, initialAccumulator);
|
|
@@ -925,7 +988,7 @@ var dashboardService = {
|
|
|
925
988
|
avg_cycle_time: combinedMetricsData.avg_cycle_time / numLines,
|
|
926
989
|
current_output: combinedMetricsData.current_output,
|
|
927
990
|
ideal_output: combinedMetricsData.ideal_output,
|
|
928
|
-
total_workspaces: combinedMetricsData.total_workspaces ||
|
|
991
|
+
total_workspaces: combinedMetricsData.total_workspaces || 0,
|
|
929
992
|
// Use combined or default
|
|
930
993
|
underperforming_workspaces: underperformingCount2,
|
|
931
994
|
line_threshold: combinedMetricsData.line_threshold,
|
|
@@ -933,7 +996,7 @@ var dashboardService = {
|
|
|
933
996
|
shift_start: metricsData?.[0]?.shift_start || shiftConfig.dayShift?.startTime || "06:00",
|
|
934
997
|
shift_end: metricsData?.[0]?.shift_end || shiftConfig.dayShift?.endTime || "18:00",
|
|
935
998
|
last_updated: (/* @__PURE__ */ new Date()).toISOString(),
|
|
936
|
-
output_array: combinedMetricsData.
|
|
999
|
+
output_array: combinedMetricsData.outputArrays.length > 0 ? memoizedOutputArrayAggregation(combinedMetricsData.outputArrays) : [],
|
|
937
1000
|
underperforming_workspace_names: [],
|
|
938
1001
|
underperforming_workspace_uuids: [],
|
|
939
1002
|
poorest_performing_workspaces: []
|
|
@@ -943,18 +1006,25 @@ var dashboardService = {
|
|
|
943
1006
|
if (!companyId) {
|
|
944
1007
|
throw new Error("Company ID must be configured for detailed line requests.");
|
|
945
1008
|
}
|
|
946
|
-
const
|
|
947
|
-
|
|
948
|
-
|
|
1009
|
+
const [lineResult, metricsResult, performanceResult] = await Promise.all([
|
|
1010
|
+
supabase.from(linesTable).select("id, line_name, factory_id, factories!lines_factory_id_fkey(factory_name), company_id, companies!lines_company_id_fkey(company_name:name)").eq("id", lineIdToQuery).single(),
|
|
1011
|
+
supabase.from(lineMetricsTable).select("*").eq("line_id", lineIdToQuery).eq("shift_id", queryShiftId).eq("date", queryDate).maybeSingle(),
|
|
1012
|
+
supabase.from(metricsTable).select("efficiency").eq("line_id", lineIdToQuery).eq("shift_id", queryShiftId).eq("date", queryDate)
|
|
1013
|
+
]);
|
|
1014
|
+
if (lineResult.error) throw lineResult.error;
|
|
1015
|
+
if (!lineResult.data) {
|
|
949
1016
|
throw new Error(`Line ${lineIdToQuery} not found.`);
|
|
950
1017
|
}
|
|
951
|
-
|
|
952
|
-
if (
|
|
953
|
-
const
|
|
954
|
-
|
|
955
|
-
const
|
|
956
|
-
const
|
|
957
|
-
const
|
|
1018
|
+
if (metricsResult.error) throw metricsResult.error;
|
|
1019
|
+
if (performanceResult.error) throw performanceResult.error;
|
|
1020
|
+
const lineData = lineResult.data;
|
|
1021
|
+
const metrics2 = metricsResult.data;
|
|
1022
|
+
const performanceData = performanceResult.data;
|
|
1023
|
+
const underperformingWorkspaces = memoizedEfficiencyFilter(performanceData || [], 10, 70);
|
|
1024
|
+
const validWorkspaces = memoizedEfficiencyFilter(performanceData || [], 10);
|
|
1025
|
+
const underperformingCount = underperformingWorkspaces.length;
|
|
1026
|
+
const totalValidWorkspaces = validWorkspaces.length;
|
|
1027
|
+
const avgEfficiencyFromPerf = memoizedAverageEfficiency(performanceData || [], 10);
|
|
958
1028
|
return {
|
|
959
1029
|
line_id: lineData.id,
|
|
960
1030
|
line_name: lineData.line_name,
|
|
@@ -1641,6 +1711,128 @@ var workspaceService = {
|
|
|
1641
1711
|
}
|
|
1642
1712
|
};
|
|
1643
1713
|
|
|
1714
|
+
// src/lib/services/skuService.ts
|
|
1715
|
+
var getTable4 = (dbConfig, tableName) => {
|
|
1716
|
+
const globalConfig = _getDashboardConfigInstance();
|
|
1717
|
+
const defaults2 = globalConfig?.databaseConfig?.tables;
|
|
1718
|
+
const userValue = dbConfig?.tables?.[tableName];
|
|
1719
|
+
const hardcodedDefaults = {
|
|
1720
|
+
skus: "skus"
|
|
1721
|
+
};
|
|
1722
|
+
return userValue ?? defaults2?.[tableName] ?? hardcodedDefaults[tableName];
|
|
1723
|
+
};
|
|
1724
|
+
var skuService = {
|
|
1725
|
+
/**
|
|
1726
|
+
* Fetch all active SKUs for a company
|
|
1727
|
+
*/
|
|
1728
|
+
async getSKUs(companyId) {
|
|
1729
|
+
const supabase = _getSupabaseInstance();
|
|
1730
|
+
if (!supabase) throw new Error("Supabase client not initialized");
|
|
1731
|
+
const config = _getDashboardConfigInstance();
|
|
1732
|
+
const dbConfig = config?.databaseConfig;
|
|
1733
|
+
const skusTable = getTable4(dbConfig, "skus");
|
|
1734
|
+
const { data, error } = await supabase.from(skusTable).select("*").eq("company_id", companyId).eq("is_active", true).order("created_at", { ascending: false });
|
|
1735
|
+
if (error) {
|
|
1736
|
+
console.error(`Error fetching SKUs from ${skusTable}:`, error);
|
|
1737
|
+
throw error;
|
|
1738
|
+
}
|
|
1739
|
+
return data || [];
|
|
1740
|
+
},
|
|
1741
|
+
/**
|
|
1742
|
+
* Get a single SKU by ID
|
|
1743
|
+
*/
|
|
1744
|
+
async getSKU(skuId) {
|
|
1745
|
+
const supabase = _getSupabaseInstance();
|
|
1746
|
+
if (!supabase) throw new Error("Supabase client not initialized");
|
|
1747
|
+
const config = _getDashboardConfigInstance();
|
|
1748
|
+
const dbConfig = config?.databaseConfig;
|
|
1749
|
+
const skusTable = getTable4(dbConfig, "skus");
|
|
1750
|
+
const { data, error } = await supabase.from(skusTable).select("*").eq("id", skuId).single();
|
|
1751
|
+
if (error) {
|
|
1752
|
+
console.error(`Error fetching SKU from ${skusTable}:`, error);
|
|
1753
|
+
throw error;
|
|
1754
|
+
}
|
|
1755
|
+
return data;
|
|
1756
|
+
},
|
|
1757
|
+
/**
|
|
1758
|
+
* Create a new SKU
|
|
1759
|
+
*/
|
|
1760
|
+
async createSKU(skuData) {
|
|
1761
|
+
const supabase = _getSupabaseInstance();
|
|
1762
|
+
if (!supabase) throw new Error("Supabase client not initialized");
|
|
1763
|
+
const config = _getDashboardConfigInstance();
|
|
1764
|
+
const dbConfig = config?.databaseConfig;
|
|
1765
|
+
const skusTable = getTable4(dbConfig, "skus");
|
|
1766
|
+
const { data, error } = await supabase.from(skusTable).insert([{
|
|
1767
|
+
...skuData,
|
|
1768
|
+
attributes: skuData.attributes || {},
|
|
1769
|
+
is_active: skuData.is_active ?? true
|
|
1770
|
+
}]).select("*").single();
|
|
1771
|
+
if (error) {
|
|
1772
|
+
console.error(`Error creating SKU in ${skusTable}:`, error);
|
|
1773
|
+
throw error;
|
|
1774
|
+
}
|
|
1775
|
+
return data;
|
|
1776
|
+
},
|
|
1777
|
+
/**
|
|
1778
|
+
* Update an existing SKU
|
|
1779
|
+
*/
|
|
1780
|
+
async updateSKU(skuId, updates) {
|
|
1781
|
+
const supabase = _getSupabaseInstance();
|
|
1782
|
+
if (!supabase) throw new Error("Supabase client not initialized");
|
|
1783
|
+
const config = _getDashboardConfigInstance();
|
|
1784
|
+
const dbConfig = config?.databaseConfig;
|
|
1785
|
+
const skusTable = getTable4(dbConfig, "skus");
|
|
1786
|
+
const { data, error } = await supabase.from(skusTable).update({
|
|
1787
|
+
...updates,
|
|
1788
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1789
|
+
}).eq("id", skuId).select("*").single();
|
|
1790
|
+
if (error) {
|
|
1791
|
+
console.error(`Error updating SKU in ${skusTable}:`, error);
|
|
1792
|
+
throw error;
|
|
1793
|
+
}
|
|
1794
|
+
return data;
|
|
1795
|
+
},
|
|
1796
|
+
/**
|
|
1797
|
+
* Soft delete a SKU (set is_active to false)
|
|
1798
|
+
*/
|
|
1799
|
+
async deleteSKU(skuId) {
|
|
1800
|
+
const supabase = _getSupabaseInstance();
|
|
1801
|
+
if (!supabase) throw new Error("Supabase client not initialized");
|
|
1802
|
+
const config = _getDashboardConfigInstance();
|
|
1803
|
+
const dbConfig = config?.databaseConfig;
|
|
1804
|
+
const skusTable = getTable4(dbConfig, "skus");
|
|
1805
|
+
const { error } = await supabase.from(skusTable).update({
|
|
1806
|
+
is_active: false,
|
|
1807
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
1808
|
+
}).eq("id", skuId);
|
|
1809
|
+
if (error) {
|
|
1810
|
+
console.error(`Error deleting SKU from ${skusTable}:`, error);
|
|
1811
|
+
throw error;
|
|
1812
|
+
}
|
|
1813
|
+
},
|
|
1814
|
+
/**
|
|
1815
|
+
* Check if a SKU ID already exists for a company
|
|
1816
|
+
*/
|
|
1817
|
+
async checkSKUExists(companyId, skuId, excludeId) {
|
|
1818
|
+
const supabase = _getSupabaseInstance();
|
|
1819
|
+
if (!supabase) throw new Error("Supabase client not initialized");
|
|
1820
|
+
const config = _getDashboardConfigInstance();
|
|
1821
|
+
const dbConfig = config?.databaseConfig;
|
|
1822
|
+
const skusTable = getTable4(dbConfig, "skus");
|
|
1823
|
+
let query = supabase.from(skusTable).select("id").eq("company_id", companyId).eq("sku_id", skuId).eq("is_active", true);
|
|
1824
|
+
if (excludeId) {
|
|
1825
|
+
query = query.neq("id", excludeId);
|
|
1826
|
+
}
|
|
1827
|
+
const { data, error } = await query;
|
|
1828
|
+
if (error) {
|
|
1829
|
+
console.error(`Error checking SKU existence in ${skusTable}:`, error);
|
|
1830
|
+
throw error;
|
|
1831
|
+
}
|
|
1832
|
+
return data && data.length > 0 || false;
|
|
1833
|
+
}
|
|
1834
|
+
};
|
|
1835
|
+
|
|
1644
1836
|
// src/lib/services/authCoreService.ts
|
|
1645
1837
|
var AUTH_ERROR_MESSAGES = {
|
|
1646
1838
|
"Invalid login credentials": "Invalid email or password",
|
|
@@ -2070,6 +2262,349 @@ async function deleteThread(threadId) {
|
|
|
2070
2262
|
const { error } = await supabase.schema("ai").from("chat_threads").delete().eq("id", threadId);
|
|
2071
2263
|
if (error) throw error;
|
|
2072
2264
|
}
|
|
2265
|
+
|
|
2266
|
+
// src/lib/services/cacheService.ts
|
|
2267
|
+
var CacheService = class {
|
|
2268
|
+
constructor() {
|
|
2269
|
+
this.memoryCache = /* @__PURE__ */ new Map();
|
|
2270
|
+
this.DEFAULT_DURATION = 5 * 60 * 1e3;
|
|
2271
|
+
}
|
|
2272
|
+
// 5 minutes
|
|
2273
|
+
/**
|
|
2274
|
+
* Generate a cache key from multiple parts
|
|
2275
|
+
*/
|
|
2276
|
+
generateKey(...parts) {
|
|
2277
|
+
return parts.filter((p) => p !== void 0 && p !== null).join(":");
|
|
2278
|
+
}
|
|
2279
|
+
/**
|
|
2280
|
+
* Get item from cache
|
|
2281
|
+
*/
|
|
2282
|
+
get(key, options) {
|
|
2283
|
+
const storage = options?.storage || "memory";
|
|
2284
|
+
try {
|
|
2285
|
+
let cacheItem = null;
|
|
2286
|
+
if (storage === "memory") {
|
|
2287
|
+
cacheItem = this.memoryCache.get(key) || null;
|
|
2288
|
+
} else if (storage === "localStorage" || storage === "sessionStorage") {
|
|
2289
|
+
const stored = window[storage].getItem(key);
|
|
2290
|
+
if (stored) {
|
|
2291
|
+
cacheItem = JSON.parse(stored);
|
|
2292
|
+
}
|
|
2293
|
+
}
|
|
2294
|
+
if (!cacheItem) {
|
|
2295
|
+
return null;
|
|
2296
|
+
}
|
|
2297
|
+
if (Date.now() > cacheItem.expiresAt) {
|
|
2298
|
+
this.delete(key, options);
|
|
2299
|
+
return null;
|
|
2300
|
+
}
|
|
2301
|
+
return cacheItem.data;
|
|
2302
|
+
} catch (error) {
|
|
2303
|
+
console.error(`Error getting cache item ${key}:`, error);
|
|
2304
|
+
return null;
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
/**
|
|
2308
|
+
* Set item in cache
|
|
2309
|
+
*/
|
|
2310
|
+
set(key, data, options) {
|
|
2311
|
+
const storage = options?.storage || "memory";
|
|
2312
|
+
const duration = options?.duration || this.DEFAULT_DURATION;
|
|
2313
|
+
const cacheItem = {
|
|
2314
|
+
data,
|
|
2315
|
+
timestamp: Date.now(),
|
|
2316
|
+
expiresAt: Date.now() + duration
|
|
2317
|
+
};
|
|
2318
|
+
try {
|
|
2319
|
+
if (storage === "memory") {
|
|
2320
|
+
this.memoryCache.set(key, cacheItem);
|
|
2321
|
+
if (this.memoryCache.size > 100) {
|
|
2322
|
+
const firstKey = this.memoryCache.keys().next().value;
|
|
2323
|
+
if (firstKey) {
|
|
2324
|
+
this.memoryCache.delete(firstKey);
|
|
2325
|
+
}
|
|
2326
|
+
}
|
|
2327
|
+
} else if (storage === "localStorage" || storage === "sessionStorage") {
|
|
2328
|
+
window[storage].setItem(key, JSON.stringify(cacheItem));
|
|
2329
|
+
}
|
|
2330
|
+
} catch (error) {
|
|
2331
|
+
console.error(`Error setting cache item ${key}:`, error);
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
2334
|
+
/**
|
|
2335
|
+
* Delete item from cache
|
|
2336
|
+
*/
|
|
2337
|
+
delete(key, options) {
|
|
2338
|
+
const storage = options?.storage || "memory";
|
|
2339
|
+
try {
|
|
2340
|
+
if (storage === "memory") {
|
|
2341
|
+
this.memoryCache.delete(key);
|
|
2342
|
+
} else if (storage === "localStorage" || storage === "sessionStorage") {
|
|
2343
|
+
window[storage].removeItem(key);
|
|
2344
|
+
}
|
|
2345
|
+
} catch (error) {
|
|
2346
|
+
console.error(`Error deleting cache item ${key}:`, error);
|
|
2347
|
+
}
|
|
2348
|
+
}
|
|
2349
|
+
/**
|
|
2350
|
+
* Clear all items from cache
|
|
2351
|
+
*/
|
|
2352
|
+
clear(options) {
|
|
2353
|
+
const storage = options?.storage || "memory";
|
|
2354
|
+
try {
|
|
2355
|
+
if (storage === "memory") {
|
|
2356
|
+
this.memoryCache.clear();
|
|
2357
|
+
} else if (storage === "localStorage" || storage === "sessionStorage") {
|
|
2358
|
+
const keys = Object.keys(window[storage]);
|
|
2359
|
+
keys.forEach((key) => {
|
|
2360
|
+
try {
|
|
2361
|
+
const item = window[storage].getItem(key);
|
|
2362
|
+
if (item) {
|
|
2363
|
+
const parsed = JSON.parse(item);
|
|
2364
|
+
if (parsed.timestamp && parsed.expiresAt && parsed.data !== void 0) {
|
|
2365
|
+
window[storage].removeItem(key);
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2368
|
+
} catch {
|
|
2369
|
+
}
|
|
2370
|
+
});
|
|
2371
|
+
}
|
|
2372
|
+
} catch (error) {
|
|
2373
|
+
console.error("Error clearing cache:", error);
|
|
2374
|
+
}
|
|
2375
|
+
}
|
|
2376
|
+
/**
|
|
2377
|
+
* Get or set item in cache with a factory function
|
|
2378
|
+
*/
|
|
2379
|
+
async getOrSet(key, factory, options) {
|
|
2380
|
+
const cached = this.get(key, options);
|
|
2381
|
+
if (cached !== null) {
|
|
2382
|
+
return cached;
|
|
2383
|
+
}
|
|
2384
|
+
const data = await factory();
|
|
2385
|
+
this.set(key, data, options);
|
|
2386
|
+
return data;
|
|
2387
|
+
}
|
|
2388
|
+
/**
|
|
2389
|
+
* Invalidate cache entries matching a pattern
|
|
2390
|
+
*/
|
|
2391
|
+
invalidatePattern(pattern, options) {
|
|
2392
|
+
const storage = options?.storage || "memory";
|
|
2393
|
+
const regex = typeof pattern === "string" ? new RegExp(pattern) : pattern;
|
|
2394
|
+
try {
|
|
2395
|
+
if (storage === "memory") {
|
|
2396
|
+
const keysToDelete = [];
|
|
2397
|
+
this.memoryCache.forEach((_, key) => {
|
|
2398
|
+
if (regex.test(key)) {
|
|
2399
|
+
keysToDelete.push(key);
|
|
2400
|
+
}
|
|
2401
|
+
});
|
|
2402
|
+
keysToDelete.forEach((key) => this.memoryCache.delete(key));
|
|
2403
|
+
} else if (storage === "localStorage" || storage === "sessionStorage") {
|
|
2404
|
+
const keys = Object.keys(window[storage]);
|
|
2405
|
+
keys.forEach((key) => {
|
|
2406
|
+
if (regex.test(key)) {
|
|
2407
|
+
window[storage].removeItem(key);
|
|
2408
|
+
}
|
|
2409
|
+
});
|
|
2410
|
+
}
|
|
2411
|
+
} catch (error) {
|
|
2412
|
+
console.error("Error invalidating cache pattern:", error);
|
|
2413
|
+
}
|
|
2414
|
+
}
|
|
2415
|
+
/**
|
|
2416
|
+
* Clean up expired items
|
|
2417
|
+
*/
|
|
2418
|
+
cleanup(options) {
|
|
2419
|
+
const storage = options?.storage || "memory";
|
|
2420
|
+
const now2 = Date.now();
|
|
2421
|
+
try {
|
|
2422
|
+
if (storage === "memory") {
|
|
2423
|
+
const keysToDelete = [];
|
|
2424
|
+
this.memoryCache.forEach((item, key) => {
|
|
2425
|
+
if (now2 > item.expiresAt) {
|
|
2426
|
+
keysToDelete.push(key);
|
|
2427
|
+
}
|
|
2428
|
+
});
|
|
2429
|
+
keysToDelete.forEach((key) => this.memoryCache.delete(key));
|
|
2430
|
+
} else if (storage === "localStorage" || storage === "sessionStorage") {
|
|
2431
|
+
const keys = Object.keys(window[storage]);
|
|
2432
|
+
keys.forEach((key) => {
|
|
2433
|
+
try {
|
|
2434
|
+
const item = window[storage].getItem(key);
|
|
2435
|
+
if (item) {
|
|
2436
|
+
const parsed = JSON.parse(item);
|
|
2437
|
+
if (parsed.expiresAt && now2 > parsed.expiresAt) {
|
|
2438
|
+
window[storage].removeItem(key);
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2441
|
+
} catch {
|
|
2442
|
+
}
|
|
2443
|
+
});
|
|
2444
|
+
}
|
|
2445
|
+
} catch (error) {
|
|
2446
|
+
console.error("Error cleaning up cache:", error);
|
|
2447
|
+
}
|
|
2448
|
+
}
|
|
2449
|
+
};
|
|
2450
|
+
var cacheService = new CacheService();
|
|
2451
|
+
if (typeof window !== "undefined") {
|
|
2452
|
+
setInterval(() => {
|
|
2453
|
+
cacheService.cleanup({ storage: "localStorage" });
|
|
2454
|
+
cacheService.cleanup({ storage: "sessionStorage" });
|
|
2455
|
+
cacheService.cleanup({ storage: "memory" });
|
|
2456
|
+
}, 60 * 1e3);
|
|
2457
|
+
}
|
|
2458
|
+
|
|
2459
|
+
// src/lib/services/subscriptionManager.ts
|
|
2460
|
+
var SubscriptionManager = class {
|
|
2461
|
+
constructor(supabase) {
|
|
2462
|
+
this.subscriptions = /* @__PURE__ */ new Map();
|
|
2463
|
+
this.debounceTimers = /* @__PURE__ */ new Map();
|
|
2464
|
+
this.supabase = supabase;
|
|
2465
|
+
}
|
|
2466
|
+
/**
|
|
2467
|
+
* Generate a unique key for a subscription configuration
|
|
2468
|
+
*/
|
|
2469
|
+
generateKey(config) {
|
|
2470
|
+
const { table, schema = "public", event = "*", filter: filter2 = "" } = config;
|
|
2471
|
+
return `${schema}:${table}:${event}:${filter2}`;
|
|
2472
|
+
}
|
|
2473
|
+
/**
|
|
2474
|
+
* Subscribe to real-time changes with automatic deduplication
|
|
2475
|
+
*/
|
|
2476
|
+
subscribe(config) {
|
|
2477
|
+
const key = this.generateKey(config);
|
|
2478
|
+
const existing = this.subscriptions.get(key);
|
|
2479
|
+
if (existing) {
|
|
2480
|
+
existing.configs.push(config);
|
|
2481
|
+
existing.refCount++;
|
|
2482
|
+
console.log(`[SubscriptionManager] Reusing existing subscription for ${key}, refCount: ${existing.refCount}`);
|
|
2483
|
+
return () => this.unsubscribe(key, config.callback);
|
|
2484
|
+
}
|
|
2485
|
+
const channelName = `subscription-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
2486
|
+
const channel = this.supabase.channel(channelName);
|
|
2487
|
+
channel.on(
|
|
2488
|
+
"postgres_changes",
|
|
2489
|
+
{
|
|
2490
|
+
event: config.event || "*",
|
|
2491
|
+
schema: config.schema || "public",
|
|
2492
|
+
table: config.table,
|
|
2493
|
+
...config.filter && { filter: config.filter }
|
|
2494
|
+
},
|
|
2495
|
+
(payload) => {
|
|
2496
|
+
this.debouncedCallback(key, () => {
|
|
2497
|
+
const subscription = this.subscriptions.get(key);
|
|
2498
|
+
if (subscription) {
|
|
2499
|
+
subscription.configs.forEach((cfg) => {
|
|
2500
|
+
try {
|
|
2501
|
+
cfg.callback(payload);
|
|
2502
|
+
} catch (error) {
|
|
2503
|
+
console.error("[SubscriptionManager] Error in callback:", error);
|
|
2504
|
+
}
|
|
2505
|
+
});
|
|
2506
|
+
}
|
|
2507
|
+
});
|
|
2508
|
+
}
|
|
2509
|
+
);
|
|
2510
|
+
channel.subscribe((status) => {
|
|
2511
|
+
console.log(`[SubscriptionManager] Subscription status for ${key}:`, status);
|
|
2512
|
+
});
|
|
2513
|
+
this.subscriptions.set(key, {
|
|
2514
|
+
channel,
|
|
2515
|
+
configs: [config],
|
|
2516
|
+
refCount: 1
|
|
2517
|
+
});
|
|
2518
|
+
console.log(`[SubscriptionManager] Created new subscription for ${key}`);
|
|
2519
|
+
return () => this.unsubscribe(key, config.callback);
|
|
2520
|
+
}
|
|
2521
|
+
/**
|
|
2522
|
+
* Debounce callbacks to prevent excessive updates
|
|
2523
|
+
*/
|
|
2524
|
+
debouncedCallback(key, callback, delay2 = 500) {
|
|
2525
|
+
const existingTimer = this.debounceTimers.get(key);
|
|
2526
|
+
if (existingTimer) {
|
|
2527
|
+
clearTimeout(existingTimer);
|
|
2528
|
+
}
|
|
2529
|
+
const timer = setTimeout(() => {
|
|
2530
|
+
callback();
|
|
2531
|
+
this.debounceTimers.delete(key);
|
|
2532
|
+
}, delay2);
|
|
2533
|
+
this.debounceTimers.set(key, timer);
|
|
2534
|
+
}
|
|
2535
|
+
/**
|
|
2536
|
+
* Unsubscribe from a specific subscription
|
|
2537
|
+
*/
|
|
2538
|
+
unsubscribe(key, callback) {
|
|
2539
|
+
const subscription = this.subscriptions.get(key);
|
|
2540
|
+
if (!subscription) {
|
|
2541
|
+
console.warn(`[SubscriptionManager] No subscription found for key: ${key}`);
|
|
2542
|
+
return;
|
|
2543
|
+
}
|
|
2544
|
+
subscription.configs = subscription.configs.filter((cfg) => cfg.callback !== callback);
|
|
2545
|
+
subscription.refCount--;
|
|
2546
|
+
console.log(`[SubscriptionManager] Unsubscribed from ${key}, refCount: ${subscription.refCount}`);
|
|
2547
|
+
if (subscription.refCount <= 0) {
|
|
2548
|
+
this.supabase.removeChannel(subscription.channel);
|
|
2549
|
+
this.subscriptions.delete(key);
|
|
2550
|
+
const timer = this.debounceTimers.get(key);
|
|
2551
|
+
if (timer) {
|
|
2552
|
+
clearTimeout(timer);
|
|
2553
|
+
this.debounceTimers.delete(key);
|
|
2554
|
+
}
|
|
2555
|
+
console.log(`[SubscriptionManager] Removed subscription for ${key}`);
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
/**
|
|
2559
|
+
* Subscribe to multiple tables with a single callback
|
|
2560
|
+
*/
|
|
2561
|
+
subscribeMultiple(configs, callback) {
|
|
2562
|
+
const unsubscribeFunctions = configs.map(
|
|
2563
|
+
(config) => this.subscribe({ ...config, callback })
|
|
2564
|
+
);
|
|
2565
|
+
return () => {
|
|
2566
|
+
unsubscribeFunctions.forEach((fn) => fn());
|
|
2567
|
+
};
|
|
2568
|
+
}
|
|
2569
|
+
/**
|
|
2570
|
+
* Get current subscription statistics
|
|
2571
|
+
*/
|
|
2572
|
+
getStats() {
|
|
2573
|
+
let totalCallbacks = 0;
|
|
2574
|
+
this.subscriptions.forEach((sub) => {
|
|
2575
|
+
totalCallbacks += sub.configs.length;
|
|
2576
|
+
});
|
|
2577
|
+
return {
|
|
2578
|
+
totalSubscriptions: this.subscriptions.size,
|
|
2579
|
+
totalCallbacks
|
|
2580
|
+
};
|
|
2581
|
+
}
|
|
2582
|
+
/**
|
|
2583
|
+
* Clean up all subscriptions
|
|
2584
|
+
*/
|
|
2585
|
+
cleanup() {
|
|
2586
|
+
this.debounceTimers.forEach((timer) => clearTimeout(timer));
|
|
2587
|
+
this.debounceTimers.clear();
|
|
2588
|
+
this.subscriptions.forEach((subscription) => {
|
|
2589
|
+
this.supabase.removeChannel(subscription.channel);
|
|
2590
|
+
});
|
|
2591
|
+
this.subscriptions.clear();
|
|
2592
|
+
console.log("[SubscriptionManager] All subscriptions cleaned up");
|
|
2593
|
+
}
|
|
2594
|
+
};
|
|
2595
|
+
var managerInstance = null;
|
|
2596
|
+
function getSubscriptionManager(supabase) {
|
|
2597
|
+
if (!managerInstance) {
|
|
2598
|
+
managerInstance = new SubscriptionManager(supabase);
|
|
2599
|
+
}
|
|
2600
|
+
return managerInstance;
|
|
2601
|
+
}
|
|
2602
|
+
function resetSubscriptionManager() {
|
|
2603
|
+
if (managerInstance) {
|
|
2604
|
+
managerInstance.cleanup();
|
|
2605
|
+
managerInstance = null;
|
|
2606
|
+
}
|
|
2607
|
+
}
|
|
2073
2608
|
var AuthContext = createContext({
|
|
2074
2609
|
session: null,
|
|
2075
2610
|
user: null,
|
|
@@ -2289,6 +2824,36 @@ var useSupabase = () => {
|
|
|
2289
2824
|
}
|
|
2290
2825
|
return context.supabase;
|
|
2291
2826
|
};
|
|
2827
|
+
var SubscriptionManagerContext = createContext({
|
|
2828
|
+
subscriptionManager: null
|
|
2829
|
+
});
|
|
2830
|
+
var SubscriptionManagerProvider = ({ children }) => {
|
|
2831
|
+
const supabase = useSupabase();
|
|
2832
|
+
const subscriptionManager = useMemo(() => {
|
|
2833
|
+
if (!supabase) return null;
|
|
2834
|
+
return getSubscriptionManager(supabase);
|
|
2835
|
+
}, [supabase]);
|
|
2836
|
+
useEffect(() => {
|
|
2837
|
+
return () => {
|
|
2838
|
+
if (subscriptionManager) {
|
|
2839
|
+
console.log("[SubscriptionManagerProvider] Cleaning up subscriptions");
|
|
2840
|
+
subscriptionManager.cleanup();
|
|
2841
|
+
}
|
|
2842
|
+
};
|
|
2843
|
+
}, [subscriptionManager]);
|
|
2844
|
+
return /* @__PURE__ */ jsx(SubscriptionManagerContext.Provider, { value: { subscriptionManager }, children });
|
|
2845
|
+
};
|
|
2846
|
+
var useSubscriptionManager = () => {
|
|
2847
|
+
const { subscriptionManager } = useContext(SubscriptionManagerContext);
|
|
2848
|
+
if (!subscriptionManager) {
|
|
2849
|
+
throw new Error("useSubscriptionManager must be used within a SubscriptionManagerProvider");
|
|
2850
|
+
}
|
|
2851
|
+
return subscriptionManager;
|
|
2852
|
+
};
|
|
2853
|
+
var useSubscriptionManagerSafe = () => {
|
|
2854
|
+
const { subscriptionManager } = useContext(SubscriptionManagerContext);
|
|
2855
|
+
return subscriptionManager;
|
|
2856
|
+
};
|
|
2292
2857
|
var DEFAULT_COMPANY_ID = "default-company-id";
|
|
2293
2858
|
var useWorkspaceMetrics = (workspaceId) => {
|
|
2294
2859
|
const supabase = useSupabase();
|
|
@@ -2545,7 +3110,7 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
|
|
|
2545
3110
|
const defaultTimezone = dateTimeConfig.defaultTimezone;
|
|
2546
3111
|
const workspaceMetricsBaseTable = databaseConfig.tables?.workspaces ?? "workspace_metrics";
|
|
2547
3112
|
const workspaceActionsTable = databaseConfig.tables?.actions ?? "workspace_actions";
|
|
2548
|
-
const fetchMetrics = useCallback(async () => {
|
|
3113
|
+
const fetchMetrics = useCallback(async (skipCache = false) => {
|
|
2549
3114
|
if (!workspaceId || isFetchingRef.current) return;
|
|
2550
3115
|
try {
|
|
2551
3116
|
isFetchingRef.current = true;
|
|
@@ -2554,6 +3119,28 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
|
|
|
2554
3119
|
const queryShiftId = shiftId !== void 0 ? shiftId : currentShift.shiftId;
|
|
2555
3120
|
console.log("[useWorkspaceDetailedMetrics] Using shift ID:", queryShiftId, "from input shift:", shiftId);
|
|
2556
3121
|
console.log("[useWorkspaceDetailedMetrics] Using date:", queryDate, "from input date:", date);
|
|
3122
|
+
const cacheKey = cacheService.generateKey(
|
|
3123
|
+
"workspace-detailed-metrics",
|
|
3124
|
+
workspaceId,
|
|
3125
|
+
queryDate,
|
|
3126
|
+
queryShiftId,
|
|
3127
|
+
companyId
|
|
3128
|
+
);
|
|
3129
|
+
if (!skipCache) {
|
|
3130
|
+
const cachedData = cacheService.get(cacheKey, {
|
|
3131
|
+
storage: "memory",
|
|
3132
|
+
duration: 5 * 60 * 1e3
|
|
3133
|
+
// 5 minutes
|
|
3134
|
+
});
|
|
3135
|
+
if (cachedData) {
|
|
3136
|
+
console.log("[useWorkspaceDetailedMetrics] Using cached data for:", cacheKey);
|
|
3137
|
+
setMetrics(cachedData);
|
|
3138
|
+
setIsLoading(false);
|
|
3139
|
+
updateQueueRef.current = false;
|
|
3140
|
+
isFetchingRef.current = false;
|
|
3141
|
+
return;
|
|
3142
|
+
}
|
|
3143
|
+
}
|
|
2557
3144
|
console.log(`[useWorkspaceDetailedMetrics] Querying ${metricsTable} for workspace: ${workspaceId}, date: ${queryDate}, shift: ${queryShiftId}`);
|
|
2558
3145
|
const { data, error: fetchError } = await supabase.from(metricsTable).select("*").eq("workspace_id", workspaceId).eq("date", queryDate).eq("shift_id", queryShiftId).maybeSingle();
|
|
2559
3146
|
if (fetchError) throw fetchError;
|
|
@@ -2656,6 +3243,18 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
|
|
|
2656
3243
|
setIsLoading(false);
|
|
2657
3244
|
updateQueueRef.current = false;
|
|
2658
3245
|
isFetchingRef.current = false;
|
|
3246
|
+
const fallbackCacheKey = cacheService.generateKey(
|
|
3247
|
+
"workspace-detailed-metrics",
|
|
3248
|
+
workspaceId,
|
|
3249
|
+
recentData.date,
|
|
3250
|
+
recentData.shift_id,
|
|
3251
|
+
companyId
|
|
3252
|
+
);
|
|
3253
|
+
cacheService.set(fallbackCacheKey, transformedData2, {
|
|
3254
|
+
storage: "memory",
|
|
3255
|
+
duration: 2 * 60 * 1e3
|
|
3256
|
+
// 2 minutes for fallback data
|
|
3257
|
+
});
|
|
2659
3258
|
return;
|
|
2660
3259
|
} else {
|
|
2661
3260
|
console.warn("[useWorkspaceDetailedMetrics] No data found for workspace:", workspaceId, "at all");
|
|
@@ -2769,6 +3368,11 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
|
|
|
2769
3368
|
...data.sop_check !== void 0 && { sop_check: data.sop_check }
|
|
2770
3369
|
};
|
|
2771
3370
|
setMetrics(transformedData);
|
|
3371
|
+
cacheService.set(cacheKey, transformedData, {
|
|
3372
|
+
storage: "memory",
|
|
3373
|
+
duration: 5 * 60 * 1e3
|
|
3374
|
+
// 5 minutes
|
|
3375
|
+
});
|
|
2772
3376
|
} catch (err) {
|
|
2773
3377
|
console.error("Error fetching workspace metrics:", err);
|
|
2774
3378
|
setError({ message: err.message, code: err.code });
|
|
@@ -2803,7 +3407,7 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
|
|
|
2803
3407
|
},
|
|
2804
3408
|
async (payload) => {
|
|
2805
3409
|
console.log(`Received ${metricsTablePrefix} update:`, payload);
|
|
2806
|
-
await fetchMetrics();
|
|
3410
|
+
await fetchMetrics(true);
|
|
2807
3411
|
}
|
|
2808
3412
|
).subscribe((status) => {
|
|
2809
3413
|
console.log(`Workspace detailed metrics subscription status:`, status);
|
|
@@ -2837,6 +3441,14 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
|
|
|
2837
3441
|
matches: payloadData?.date === operationalDate && payloadData?.shift_id === queryShiftId
|
|
2838
3442
|
});
|
|
2839
3443
|
if (payloadData?.date === operationalDate && payloadData?.shift_id === queryShiftId) {
|
|
3444
|
+
const cacheKey = cacheService.generateKey(
|
|
3445
|
+
"workspace-detailed-metrics",
|
|
3446
|
+
workspaceId,
|
|
3447
|
+
operationalDate,
|
|
3448
|
+
queryShiftId,
|
|
3449
|
+
companyId
|
|
3450
|
+
);
|
|
3451
|
+
cacheService.delete(cacheKey, { storage: "memory" });
|
|
2840
3452
|
queueUpdate();
|
|
2841
3453
|
}
|
|
2842
3454
|
}
|
|
@@ -2862,6 +3474,14 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
|
|
|
2862
3474
|
matches: payloadData?.date === operationalDate && payloadData?.shift_id === queryShiftId
|
|
2863
3475
|
});
|
|
2864
3476
|
if (payloadData?.date === operationalDate && payloadData?.shift_id === queryShiftId) {
|
|
3477
|
+
const cacheKey = cacheService.generateKey(
|
|
3478
|
+
"workspace-detailed-metrics",
|
|
3479
|
+
workspaceId,
|
|
3480
|
+
operationalDate,
|
|
3481
|
+
queryShiftId,
|
|
3482
|
+
companyId
|
|
3483
|
+
);
|
|
3484
|
+
cacheService.delete(cacheKey, { storage: "memory" });
|
|
2865
3485
|
queueUpdate();
|
|
2866
3486
|
}
|
|
2867
3487
|
}
|
|
@@ -2887,6 +3507,14 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
|
|
|
2887
3507
|
matches: payloadData?.date === operationalDate && payloadData?.shift_id === queryShiftId
|
|
2888
3508
|
});
|
|
2889
3509
|
if (payloadData?.date === operationalDate && payloadData?.shift_id === queryShiftId) {
|
|
3510
|
+
const cacheKey = cacheService.generateKey(
|
|
3511
|
+
"workspace-detailed-metrics",
|
|
3512
|
+
workspaceId,
|
|
3513
|
+
operationalDate,
|
|
3514
|
+
queryShiftId,
|
|
3515
|
+
companyId
|
|
3516
|
+
);
|
|
3517
|
+
cacheService.delete(cacheKey, { storage: "memory" });
|
|
2890
3518
|
queueUpdate();
|
|
2891
3519
|
}
|
|
2892
3520
|
}
|
|
@@ -2913,7 +3541,8 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId) => {
|
|
|
2913
3541
|
metrics: metrics2,
|
|
2914
3542
|
isLoading,
|
|
2915
3543
|
error,
|
|
2916
|
-
refetch: fetchMetrics
|
|
3544
|
+
refetch: () => fetchMetrics(true)
|
|
3545
|
+
// Force refresh without cache
|
|
2917
3546
|
};
|
|
2918
3547
|
};
|
|
2919
3548
|
var useLineWorkspaceMetrics = (lineId, options) => {
|
|
@@ -5130,19 +5759,39 @@ var useActiveBreaks = (lineIds) => {
|
|
|
5130
5759
|
let breaks = [];
|
|
5131
5760
|
if (activeShift.breaks) {
|
|
5132
5761
|
if (Array.isArray(activeShift.breaks)) {
|
|
5133
|
-
breaks = activeShift.breaks.map((breakItem) =>
|
|
5134
|
-
startTime
|
|
5135
|
-
endTime
|
|
5136
|
-
duration
|
|
5137
|
-
|
|
5138
|
-
|
|
5762
|
+
breaks = activeShift.breaks.map((breakItem) => {
|
|
5763
|
+
const startTime = breakItem.start || breakItem.startTime || "00:00";
|
|
5764
|
+
const endTime = breakItem.end || breakItem.endTime || "00:00";
|
|
5765
|
+
let duration = breakItem.duration || 0;
|
|
5766
|
+
if (!duration || duration === 0) {
|
|
5767
|
+
const startMinutes = parseTimeToMinutes2(startTime);
|
|
5768
|
+
const endMinutes = parseTimeToMinutes2(endTime);
|
|
5769
|
+
duration = endMinutes < startMinutes ? endMinutes + 24 * 60 - startMinutes : endMinutes - startMinutes;
|
|
5770
|
+
}
|
|
5771
|
+
return {
|
|
5772
|
+
startTime,
|
|
5773
|
+
endTime,
|
|
5774
|
+
duration,
|
|
5775
|
+
remarks: breakItem.remarks || breakItem.name || ""
|
|
5776
|
+
};
|
|
5777
|
+
});
|
|
5139
5778
|
} else if (activeShift.breaks.breaks && Array.isArray(activeShift.breaks.breaks)) {
|
|
5140
|
-
breaks = activeShift.breaks.breaks.map((breakItem) =>
|
|
5141
|
-
startTime
|
|
5142
|
-
endTime
|
|
5143
|
-
duration
|
|
5144
|
-
|
|
5145
|
-
|
|
5779
|
+
breaks = activeShift.breaks.breaks.map((breakItem) => {
|
|
5780
|
+
const startTime = breakItem.start || breakItem.startTime || "00:00";
|
|
5781
|
+
const endTime = breakItem.end || breakItem.endTime || "00:00";
|
|
5782
|
+
let duration = breakItem.duration || 0;
|
|
5783
|
+
if (!duration || duration === 0) {
|
|
5784
|
+
const startMinutes = parseTimeToMinutes2(startTime);
|
|
5785
|
+
const endMinutes = parseTimeToMinutes2(endTime);
|
|
5786
|
+
duration = endMinutes < startMinutes ? endMinutes + 24 * 60 - startMinutes : endMinutes - startMinutes;
|
|
5787
|
+
}
|
|
5788
|
+
return {
|
|
5789
|
+
startTime,
|
|
5790
|
+
endTime,
|
|
5791
|
+
duration,
|
|
5792
|
+
remarks: breakItem.remarks || breakItem.name || ""
|
|
5793
|
+
};
|
|
5794
|
+
});
|
|
5146
5795
|
}
|
|
5147
5796
|
}
|
|
5148
5797
|
for (const breakItem of breaks) {
|
|
@@ -5204,12 +5853,32 @@ var useAllWorkspaceMetrics = (options) => {
|
|
|
5204
5853
|
return `${metricsTablePrefix}_${companyId.replace(/-/g, "_")}`;
|
|
5205
5854
|
}, [entityConfig.companyId]);
|
|
5206
5855
|
const schema = databaseConfig.schema ?? "public";
|
|
5207
|
-
const fetchWorkspaceMetrics = useCallback(async () => {
|
|
5856
|
+
const fetchWorkspaceMetrics = useCallback(async (skipCache = false) => {
|
|
5208
5857
|
if (!initialized) {
|
|
5209
5858
|
setLoading(true);
|
|
5210
5859
|
}
|
|
5211
5860
|
setError(null);
|
|
5212
5861
|
try {
|
|
5862
|
+
const cacheKey = cacheService.generateKey(
|
|
5863
|
+
"all-workspace-metrics",
|
|
5864
|
+
entityConfig.companyId,
|
|
5865
|
+
queryDate,
|
|
5866
|
+
queryShiftId
|
|
5867
|
+
);
|
|
5868
|
+
if (!skipCache && !loading) {
|
|
5869
|
+
const cachedData = cacheService.get(cacheKey, {
|
|
5870
|
+
storage: "memory",
|
|
5871
|
+
duration: 5 * 60 * 1e3
|
|
5872
|
+
// 5 minutes
|
|
5873
|
+
});
|
|
5874
|
+
if (cachedData) {
|
|
5875
|
+
console.log("[useAllWorkspaceMetrics] Using cached data for:", cacheKey);
|
|
5876
|
+
setWorkspaces(cachedData);
|
|
5877
|
+
setInitialized(true);
|
|
5878
|
+
setLoading(false);
|
|
5879
|
+
return;
|
|
5880
|
+
}
|
|
5881
|
+
}
|
|
5213
5882
|
console.log("Fetching all workspace metrics with params:", {
|
|
5214
5883
|
queryDate,
|
|
5215
5884
|
queryShiftId,
|
|
@@ -5246,6 +5915,11 @@ var useAllWorkspaceMetrics = (options) => {
|
|
|
5246
5915
|
}));
|
|
5247
5916
|
setWorkspaces(transformedData);
|
|
5248
5917
|
setInitialized(true);
|
|
5918
|
+
cacheService.set(cacheKey, transformedData, {
|
|
5919
|
+
storage: "memory",
|
|
5920
|
+
duration: 5 * 60 * 1e3
|
|
5921
|
+
// 5 minutes
|
|
5922
|
+
});
|
|
5249
5923
|
} catch (err) {
|
|
5250
5924
|
console.error("Error fetching all workspace metrics:", err);
|
|
5251
5925
|
setError({ message: err.message, code: err.code || "FETCH_ERROR" });
|
|
@@ -5270,7 +5944,14 @@ var useAllWorkspaceMetrics = (options) => {
|
|
|
5270
5944
|
},
|
|
5271
5945
|
async (payload) => {
|
|
5272
5946
|
console.log("All workspace metrics update received:", payload);
|
|
5273
|
-
|
|
5947
|
+
const cacheKey = cacheService.generateKey(
|
|
5948
|
+
"all-workspace-metrics",
|
|
5949
|
+
entityConfig.companyId,
|
|
5950
|
+
queryDate,
|
|
5951
|
+
queryShiftId
|
|
5952
|
+
);
|
|
5953
|
+
cacheService.delete(cacheKey, { storage: "memory" });
|
|
5954
|
+
await fetchWorkspaceMetrics(true);
|
|
5274
5955
|
}
|
|
5275
5956
|
).subscribe();
|
|
5276
5957
|
return channel2;
|
|
@@ -5281,16 +5962,80 @@ var useAllWorkspaceMetrics = (options) => {
|
|
|
5281
5962
|
supabase.removeChannel(channel);
|
|
5282
5963
|
}
|
|
5283
5964
|
};
|
|
5284
|
-
}, [queryDate, queryShiftId, metricsTable, fetchWorkspaceMetrics, initialized, supabase, schema]);
|
|
5965
|
+
}, [queryDate, queryShiftId, metricsTable, fetchWorkspaceMetrics, initialized, supabase, schema, entityConfig.companyId]);
|
|
5285
5966
|
useEffect(() => {
|
|
5286
5967
|
setInitialized(false);
|
|
5287
5968
|
}, [queryDate, queryShiftId]);
|
|
5288
|
-
const refreshWorkspaces = fetchWorkspaceMetrics;
|
|
5969
|
+
const refreshWorkspaces = useCallback(() => fetchWorkspaceMetrics(true), [fetchWorkspaceMetrics]);
|
|
5289
5970
|
return useMemo(
|
|
5290
5971
|
() => ({ workspaces, loading, error, refreshWorkspaces }),
|
|
5291
5972
|
[workspaces, loading, error, refreshWorkspaces]
|
|
5292
5973
|
);
|
|
5293
5974
|
};
|
|
5975
|
+
var useSKUs = (companyId) => {
|
|
5976
|
+
const [skus, setSKUs] = useState([]);
|
|
5977
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
5978
|
+
const [error, setError] = useState(null);
|
|
5979
|
+
const supabase = useSupabase();
|
|
5980
|
+
const config = useDashboardConfig();
|
|
5981
|
+
const dbConfig = config?.databaseConfig;
|
|
5982
|
+
const skusTable = dbConfig?.tables?.skus || "skus";
|
|
5983
|
+
const fetchSKUs = useCallback(async () => {
|
|
5984
|
+
if (!companyId) {
|
|
5985
|
+
setIsLoading(false);
|
|
5986
|
+
return;
|
|
5987
|
+
}
|
|
5988
|
+
try {
|
|
5989
|
+
setIsLoading(true);
|
|
5990
|
+
setError(null);
|
|
5991
|
+
const data = await skuService.getSKUs(companyId);
|
|
5992
|
+
setSKUs(data);
|
|
5993
|
+
} catch (err) {
|
|
5994
|
+
setError(err instanceof Error ? err : new Error("Failed to fetch SKUs"));
|
|
5995
|
+
console.error("Error fetching SKUs:", err);
|
|
5996
|
+
} finally {
|
|
5997
|
+
setIsLoading(false);
|
|
5998
|
+
}
|
|
5999
|
+
}, [companyId]);
|
|
6000
|
+
useEffect(() => {
|
|
6001
|
+
fetchSKUs();
|
|
6002
|
+
}, [fetchSKUs]);
|
|
6003
|
+
useEffect(() => {
|
|
6004
|
+
if (!supabase || !companyId) return;
|
|
6005
|
+
const channel = supabase.channel(`skus:${companyId}`).on(
|
|
6006
|
+
"postgres_changes",
|
|
6007
|
+
{
|
|
6008
|
+
event: "*",
|
|
6009
|
+
schema: dbConfig?.schema || "public",
|
|
6010
|
+
table: skusTable,
|
|
6011
|
+
filter: `company_id=eq.${companyId}`
|
|
6012
|
+
},
|
|
6013
|
+
(payload) => {
|
|
6014
|
+
console.log("SKU change received:", payload);
|
|
6015
|
+
if (payload.eventType === "INSERT") {
|
|
6016
|
+
setSKUs((prev) => [...prev, payload.new]);
|
|
6017
|
+
} else if (payload.eventType === "UPDATE") {
|
|
6018
|
+
setSKUs(
|
|
6019
|
+
(prev) => prev.map(
|
|
6020
|
+
(sku) => sku.id === payload.new.id ? payload.new : sku
|
|
6021
|
+
)
|
|
6022
|
+
);
|
|
6023
|
+
} else if (payload.eventType === "DELETE") {
|
|
6024
|
+
setSKUs((prev) => prev.filter((sku) => sku.id !== payload.old.id));
|
|
6025
|
+
}
|
|
6026
|
+
}
|
|
6027
|
+
).subscribe();
|
|
6028
|
+
return () => {
|
|
6029
|
+
supabase.removeChannel(channel);
|
|
6030
|
+
};
|
|
6031
|
+
}, [supabase, companyId, dbConfig?.schema, skusTable]);
|
|
6032
|
+
return {
|
|
6033
|
+
skus,
|
|
6034
|
+
isLoading,
|
|
6035
|
+
error,
|
|
6036
|
+
refetch: fetchSKUs
|
|
6037
|
+
};
|
|
6038
|
+
};
|
|
5294
6039
|
var MAX_RETRIES = 10;
|
|
5295
6040
|
var RETRY_DELAY = 500;
|
|
5296
6041
|
function useNavigation(customNavigate) {
|
|
@@ -8522,7 +9267,7 @@ var MotionConfigContext = createContext({
|
|
|
8522
9267
|
});
|
|
8523
9268
|
|
|
8524
9269
|
// ../../node_modules/framer-motion/dist/es/components/AnimatePresence/PopChild.mjs
|
|
8525
|
-
var PopChildMeasure = class extends
|
|
9270
|
+
var PopChildMeasure = class extends React19.Component {
|
|
8526
9271
|
getSnapshotBeforeUpdate(prevProps) {
|
|
8527
9272
|
const element = this.props.childRef.current;
|
|
8528
9273
|
if (element && prevProps.isPresent && !this.props.isPresent) {
|
|
@@ -8577,7 +9322,7 @@ function PopChild({ children, isPresent }) {
|
|
|
8577
9322
|
document.head.removeChild(style);
|
|
8578
9323
|
};
|
|
8579
9324
|
}, [isPresent]);
|
|
8580
|
-
return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children:
|
|
9325
|
+
return jsx(PopChildMeasure, { isPresent, childRef: ref, sizeRef: size, children: React19.cloneElement(children, { ref }) });
|
|
8581
9326
|
}
|
|
8582
9327
|
|
|
8583
9328
|
// ../../node_modules/framer-motion/dist/es/components/AnimatePresence/PresenceChild.mjs
|
|
@@ -8614,7 +9359,7 @@ var PresenceChild = ({ children, initial, isPresent, onExitComplete, custom, pre
|
|
|
8614
9359
|
useMemo(() => {
|
|
8615
9360
|
presenceChildren.forEach((_, key) => presenceChildren.set(key, false));
|
|
8616
9361
|
}, [isPresent]);
|
|
8617
|
-
|
|
9362
|
+
React19.useEffect(() => {
|
|
8618
9363
|
!isPresent && !presenceChildren.size && onExitComplete && onExitComplete();
|
|
8619
9364
|
}, [isPresent]);
|
|
8620
9365
|
if (mode === "popLayout") {
|
|
@@ -10021,7 +10766,7 @@ function removeItem(arr, item) {
|
|
|
10021
10766
|
}
|
|
10022
10767
|
|
|
10023
10768
|
// ../../node_modules/framer-motion/dist/es/utils/subscription-manager.mjs
|
|
10024
|
-
var
|
|
10769
|
+
var SubscriptionManager3 = class {
|
|
10025
10770
|
constructor() {
|
|
10026
10771
|
this.subscriptions = [];
|
|
10027
10772
|
}
|
|
@@ -10150,7 +10895,7 @@ var MotionValue = class {
|
|
|
10150
10895
|
}
|
|
10151
10896
|
on(eventName, callback) {
|
|
10152
10897
|
if (!this.events[eventName]) {
|
|
10153
|
-
this.events[eventName] = new
|
|
10898
|
+
this.events[eventName] = new SubscriptionManager3();
|
|
10154
10899
|
}
|
|
10155
10900
|
const unsubscribe = this.events[eventName].add(callback);
|
|
10156
10901
|
if (eventName === "change") {
|
|
@@ -14144,7 +14889,7 @@ function createProjectionNode2({ attachResizeListener, defaultParent, measureScr
|
|
|
14144
14889
|
}
|
|
14145
14890
|
addEventListener(name, handler) {
|
|
14146
14891
|
if (!this.eventHandlers.has(name)) {
|
|
14147
|
-
this.eventHandlers.set(name, new
|
|
14892
|
+
this.eventHandlers.set(name, new SubscriptionManager3());
|
|
14148
14893
|
}
|
|
14149
14894
|
return this.eventHandlers.get(name).add(handler);
|
|
14150
14895
|
}
|
|
@@ -15734,7 +16479,7 @@ var VisualElement = class {
|
|
|
15734
16479
|
}
|
|
15735
16480
|
on(eventName, callback) {
|
|
15736
16481
|
if (!this.events[eventName]) {
|
|
15737
|
-
this.events[eventName] = new
|
|
16482
|
+
this.events[eventName] = new SubscriptionManager3();
|
|
15738
16483
|
}
|
|
15739
16484
|
return this.events[eventName].add(callback);
|
|
15740
16485
|
}
|
|
@@ -15883,7 +16628,7 @@ var LoadingPage = ({
|
|
|
15883
16628
|
subMessage = "Please wait while we prepare your data",
|
|
15884
16629
|
className
|
|
15885
16630
|
}) => {
|
|
15886
|
-
|
|
16631
|
+
React19__default.useEffect(() => {
|
|
15887
16632
|
console.log("LoadingPage rendered with message:", message);
|
|
15888
16633
|
const timeout = setTimeout(() => {
|
|
15889
16634
|
console.warn("LoadingPage has been visible for more than 8 seconds. This might indicate an issue.");
|
|
@@ -15926,10 +16671,10 @@ var withAuth = (WrappedComponent2, options) => {
|
|
|
15926
16671
|
return function WithAuthComponent(props) {
|
|
15927
16672
|
const { session, loading } = useAuth();
|
|
15928
16673
|
const router = useRouter();
|
|
15929
|
-
|
|
16674
|
+
React19.useEffect(() => {
|
|
15930
16675
|
console.log("withAuth state:", { loading, hasSession: !!session, requireAuth: defaultOptions.requireAuth });
|
|
15931
16676
|
}, [session, loading]);
|
|
15932
|
-
|
|
16677
|
+
React19.useEffect(() => {
|
|
15933
16678
|
if (!loading && defaultOptions.requireAuth && !session) {
|
|
15934
16679
|
console.log("Redirecting to login from withAuth");
|
|
15935
16680
|
router.replace(defaultOptions.redirectTo);
|
|
@@ -16257,7 +17002,7 @@ var DebugAuth = () => {
|
|
|
16257
17002
|
] }) });
|
|
16258
17003
|
};
|
|
16259
17004
|
var DEFAULT_BAR_RADIUS = [4, 4, 0, 0];
|
|
16260
|
-
var
|
|
17005
|
+
var BarChartComponent = ({
|
|
16261
17006
|
data,
|
|
16262
17007
|
bars,
|
|
16263
17008
|
xAxisDataKey = "name",
|
|
@@ -16345,7 +17090,35 @@ var BarChart = ({
|
|
|
16345
17090
|
}
|
|
16346
17091
|
return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: chartContent });
|
|
16347
17092
|
};
|
|
16348
|
-
var
|
|
17093
|
+
var BarChart = React19__default.memo(BarChartComponent, (prevProps, nextProps) => {
|
|
17094
|
+
if (prevProps.xAxisDataKey !== nextProps.xAxisDataKey || prevProps.xAxisLabel !== nextProps.xAxisLabel || prevProps.yAxisLabel !== nextProps.yAxisLabel || prevProps.yAxisUnit !== nextProps.yAxisUnit || prevProps.layout !== nextProps.layout || prevProps.className !== nextProps.className || prevProps.showGrid !== nextProps.showGrid || prevProps.showLegend !== nextProps.showLegend || prevProps.showTooltip !== nextProps.showTooltip || prevProps.responsive !== nextProps.responsive || prevProps.aspect !== nextProps.aspect) {
|
|
17095
|
+
return false;
|
|
17096
|
+
}
|
|
17097
|
+
if (prevProps.data.length !== nextProps.data.length) {
|
|
17098
|
+
return false;
|
|
17099
|
+
}
|
|
17100
|
+
if (!prevProps.data.every((item, idx) => {
|
|
17101
|
+
const nextItem = nextProps.data[idx];
|
|
17102
|
+
return Object.keys(item).every((key) => item[key] === nextItem[key]);
|
|
17103
|
+
})) {
|
|
17104
|
+
return false;
|
|
17105
|
+
}
|
|
17106
|
+
if (prevProps.bars.length !== nextProps.bars.length) {
|
|
17107
|
+
return false;
|
|
17108
|
+
}
|
|
17109
|
+
if (!prevProps.bars.every((bar, idx) => {
|
|
17110
|
+
const nextBar = nextProps.bars[idx];
|
|
17111
|
+
return bar.dataKey === nextBar.dataKey && bar.name === nextBar.name && bar.fill === nextBar.fill && JSON.stringify(bar.radius) === JSON.stringify(nextBar.radius) && bar.labelList === nextBar.labelList;
|
|
17112
|
+
})) {
|
|
17113
|
+
return false;
|
|
17114
|
+
}
|
|
17115
|
+
if (prevProps.tooltipFormatter !== nextProps.tooltipFormatter || JSON.stringify(prevProps.legendPayload) !== JSON.stringify(nextProps.legendPayload)) {
|
|
17116
|
+
return false;
|
|
17117
|
+
}
|
|
17118
|
+
return true;
|
|
17119
|
+
});
|
|
17120
|
+
BarChart.displayName = "BarChart";
|
|
17121
|
+
var LineChartComponent = ({
|
|
16349
17122
|
data,
|
|
16350
17123
|
lines,
|
|
16351
17124
|
xAxisDataKey = "name",
|
|
@@ -16436,7 +17209,35 @@ var LineChart = ({
|
|
|
16436
17209
|
}
|
|
16437
17210
|
return /* @__PURE__ */ jsx("div", { className: clsx("w-full", className), children: chartContent });
|
|
16438
17211
|
};
|
|
16439
|
-
var
|
|
17212
|
+
var LineChart = React19__default.memo(LineChartComponent, (prevProps, nextProps) => {
|
|
17213
|
+
if (prevProps.xAxisDataKey !== nextProps.xAxisDataKey || prevProps.xAxisLabel !== nextProps.xAxisLabel || prevProps.yAxisLabel !== nextProps.yAxisLabel || prevProps.yAxisUnit !== nextProps.yAxisUnit || prevProps.className !== nextProps.className || prevProps.showGrid !== nextProps.showGrid || prevProps.showLegend !== nextProps.showLegend || prevProps.showTooltip !== nextProps.showTooltip || prevProps.responsive !== nextProps.responsive || prevProps.aspect !== nextProps.aspect || JSON.stringify(prevProps.yAxisDomain) !== JSON.stringify(nextProps.yAxisDomain)) {
|
|
17214
|
+
return false;
|
|
17215
|
+
}
|
|
17216
|
+
if (prevProps.data.length !== nextProps.data.length) {
|
|
17217
|
+
return false;
|
|
17218
|
+
}
|
|
17219
|
+
if (!prevProps.data.every((item, idx) => {
|
|
17220
|
+
const nextItem = nextProps.data[idx];
|
|
17221
|
+
return Object.keys(item).every((key) => item[key] === nextItem[key]);
|
|
17222
|
+
})) {
|
|
17223
|
+
return false;
|
|
17224
|
+
}
|
|
17225
|
+
if (prevProps.lines.length !== nextProps.lines.length) {
|
|
17226
|
+
return false;
|
|
17227
|
+
}
|
|
17228
|
+
if (!prevProps.lines.every((line, idx) => {
|
|
17229
|
+
const nextLine = nextProps.lines[idx];
|
|
17230
|
+
return line.dataKey === nextLine.dataKey && line.name === nextLine.name && line.stroke === nextLine.stroke && line.strokeWidth === nextLine.strokeWidth && line.type === nextLine.type && JSON.stringify(line.dot) === JSON.stringify(nextLine.dot) && JSON.stringify(line.activeDot) === JSON.stringify(nextLine.activeDot) && line.labelList === nextLine.labelList;
|
|
17231
|
+
})) {
|
|
17232
|
+
return false;
|
|
17233
|
+
}
|
|
17234
|
+
if (prevProps.tooltipFormatter !== nextProps.tooltipFormatter || prevProps.xAxisTickFormatter !== nextProps.xAxisTickFormatter || JSON.stringify(prevProps.legendPayload) !== JSON.stringify(nextProps.legendPayload)) {
|
|
17235
|
+
return false;
|
|
17236
|
+
}
|
|
17237
|
+
return true;
|
|
17238
|
+
});
|
|
17239
|
+
LineChart.displayName = "LineChart";
|
|
17240
|
+
var OutputProgressChartComponent = ({
|
|
16440
17241
|
currentOutput,
|
|
16441
17242
|
targetOutput,
|
|
16442
17243
|
className = ""
|
|
@@ -16485,6 +17286,8 @@ var OutputProgressChart = ({
|
|
|
16485
17286
|
] }) })
|
|
16486
17287
|
] }) });
|
|
16487
17288
|
};
|
|
17289
|
+
var OutputProgressChart = React19__default.memo(OutputProgressChartComponent);
|
|
17290
|
+
OutputProgressChart.displayName = "OutputProgressChart";
|
|
16488
17291
|
var LargeOutputProgressChart = ({
|
|
16489
17292
|
currentOutput,
|
|
16490
17293
|
targetOutput,
|
|
@@ -16534,7 +17337,7 @@ var LargeOutputProgressChart = ({
|
|
|
16534
17337
|
] }) })
|
|
16535
17338
|
] }) });
|
|
16536
17339
|
};
|
|
16537
|
-
var
|
|
17340
|
+
var CycleTimeChartComponent = ({
|
|
16538
17341
|
data = [],
|
|
16539
17342
|
className = ""
|
|
16540
17343
|
}) => {
|
|
@@ -16599,6 +17402,25 @@ var CycleTimeChart = ({
|
|
|
16599
17402
|
}
|
|
16600
17403
|
) }) });
|
|
16601
17404
|
};
|
|
17405
|
+
var CycleTimeChart = React19__default.memo(CycleTimeChartComponent, (prevProps, nextProps) => {
|
|
17406
|
+
if (prevProps.className !== nextProps.className) {
|
|
17407
|
+
return false;
|
|
17408
|
+
}
|
|
17409
|
+
if (!prevProps.data && !nextProps.data) {
|
|
17410
|
+
return true;
|
|
17411
|
+
}
|
|
17412
|
+
if (!prevProps.data || !nextProps.data) {
|
|
17413
|
+
return false;
|
|
17414
|
+
}
|
|
17415
|
+
if (prevProps.data.length !== nextProps.data.length) {
|
|
17416
|
+
return false;
|
|
17417
|
+
}
|
|
17418
|
+
return prevProps.data.every((item, index) => {
|
|
17419
|
+
const nextItem = nextProps.data[index];
|
|
17420
|
+
return item.time === nextItem.time && item.value === nextItem.value;
|
|
17421
|
+
});
|
|
17422
|
+
});
|
|
17423
|
+
CycleTimeChart.displayName = "CycleTimeChart";
|
|
16602
17424
|
var CycleTimeOverTimeChart = ({
|
|
16603
17425
|
data,
|
|
16604
17426
|
idealCycleTime,
|
|
@@ -16616,10 +17438,10 @@ var CycleTimeOverTimeChart = ({
|
|
|
16616
17438
|
};
|
|
16617
17439
|
const displayData = getDisplayData(data);
|
|
16618
17440
|
const DURATION = displayData.length;
|
|
16619
|
-
const [animatedData, setAnimatedData] =
|
|
16620
|
-
const prevDataRef =
|
|
16621
|
-
const animationFrameRef =
|
|
16622
|
-
const animateToNewData =
|
|
17441
|
+
const [animatedData, setAnimatedData] = React19__default.useState(Array(DURATION).fill(0));
|
|
17442
|
+
const prevDataRef = React19__default.useRef(Array(DURATION).fill(0));
|
|
17443
|
+
const animationFrameRef = React19__default.useRef(null);
|
|
17444
|
+
const animateToNewData = React19__default.useCallback((targetData) => {
|
|
16623
17445
|
const startData = [...prevDataRef.current];
|
|
16624
17446
|
const startTime = performance.now();
|
|
16625
17447
|
const duration = 1200;
|
|
@@ -16649,7 +17471,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
16649
17471
|
}
|
|
16650
17472
|
animationFrameRef.current = requestAnimationFrame(animate);
|
|
16651
17473
|
}, []);
|
|
16652
|
-
|
|
17474
|
+
React19__default.useEffect(() => {
|
|
16653
17475
|
if (JSON.stringify(data) !== JSON.stringify(prevDataRef.current)) {
|
|
16654
17476
|
const processedData = getDisplayData(data);
|
|
16655
17477
|
animateToNewData(processedData);
|
|
@@ -16873,7 +17695,7 @@ var CycleTimeOverTimeChart = ({
|
|
|
16873
17695
|
renderLegend()
|
|
16874
17696
|
] });
|
|
16875
17697
|
};
|
|
16876
|
-
var Card =
|
|
17698
|
+
var Card = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
16877
17699
|
"div",
|
|
16878
17700
|
{
|
|
16879
17701
|
ref,
|
|
@@ -16885,7 +17707,7 @@ var Card = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
16885
17707
|
}
|
|
16886
17708
|
));
|
|
16887
17709
|
Card.displayName = "Card";
|
|
16888
|
-
var CardHeader =
|
|
17710
|
+
var CardHeader = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
16889
17711
|
"div",
|
|
16890
17712
|
{
|
|
16891
17713
|
ref,
|
|
@@ -16894,7 +17716,7 @@ var CardHeader = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
16894
17716
|
}
|
|
16895
17717
|
));
|
|
16896
17718
|
CardHeader.displayName = "CardHeader";
|
|
16897
|
-
var CardTitle =
|
|
17719
|
+
var CardTitle = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
16898
17720
|
"h3",
|
|
16899
17721
|
{
|
|
16900
17722
|
ref,
|
|
@@ -16906,7 +17728,7 @@ var CardTitle = React14.forwardRef(({ className, ...props }, ref) => /* @__PURE_
|
|
|
16906
17728
|
}
|
|
16907
17729
|
));
|
|
16908
17730
|
CardTitle.displayName = "CardTitle";
|
|
16909
|
-
var CardDescription =
|
|
17731
|
+
var CardDescription = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
16910
17732
|
"p",
|
|
16911
17733
|
{
|
|
16912
17734
|
ref,
|
|
@@ -16915,9 +17737,9 @@ var CardDescription = React14.forwardRef(({ className, ...props }, ref) => /* @_
|
|
|
16915
17737
|
}
|
|
16916
17738
|
));
|
|
16917
17739
|
CardDescription.displayName = "CardDescription";
|
|
16918
|
-
var CardContent =
|
|
17740
|
+
var CardContent = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-0", className), ...props }));
|
|
16919
17741
|
CardContent.displayName = "CardContent";
|
|
16920
|
-
var CardFooter =
|
|
17742
|
+
var CardFooter = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
16921
17743
|
"div",
|
|
16922
17744
|
{
|
|
16923
17745
|
ref,
|
|
@@ -16993,7 +17815,7 @@ var buttonVariants = cva(
|
|
|
16993
17815
|
}
|
|
16994
17816
|
}
|
|
16995
17817
|
);
|
|
16996
|
-
var Button =
|
|
17818
|
+
var Button = React19.forwardRef(
|
|
16997
17819
|
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
16998
17820
|
const Comp = asChild ? Slot : "button";
|
|
16999
17821
|
return /* @__PURE__ */ jsx(
|
|
@@ -17007,7 +17829,7 @@ var Button = React14.forwardRef(
|
|
|
17007
17829
|
}
|
|
17008
17830
|
);
|
|
17009
17831
|
Button.displayName = "Button";
|
|
17010
|
-
var
|
|
17832
|
+
var HourlyOutputChartComponent = ({
|
|
17011
17833
|
data,
|
|
17012
17834
|
pphThreshold,
|
|
17013
17835
|
shiftStart,
|
|
@@ -17024,17 +17846,17 @@ var HourlyOutputChart = ({
|
|
|
17024
17846
|
};
|
|
17025
17847
|
const shiftStartTime = getTimeFromTimeString(shiftStart);
|
|
17026
17848
|
const SHIFT_DURATION = 11;
|
|
17027
|
-
const [animatedData, setAnimatedData] =
|
|
17028
|
-
const prevDataRef =
|
|
17029
|
-
const animationFrameRef =
|
|
17030
|
-
const [idleBarState, setIdleBarState] =
|
|
17849
|
+
const [animatedData, setAnimatedData] = React19__default.useState(Array(SHIFT_DURATION).fill(0));
|
|
17850
|
+
const prevDataRef = React19__default.useRef(Array(SHIFT_DURATION).fill(0));
|
|
17851
|
+
const animationFrameRef = React19__default.useRef(null);
|
|
17852
|
+
const [idleBarState, setIdleBarState] = React19__default.useState({
|
|
17031
17853
|
visible: showIdleTime,
|
|
17032
17854
|
key: 0,
|
|
17033
17855
|
shouldAnimate: false
|
|
17034
17856
|
});
|
|
17035
|
-
const prevShowIdleTimeRef =
|
|
17036
|
-
const stateUpdateTimeoutRef =
|
|
17037
|
-
|
|
17857
|
+
const prevShowIdleTimeRef = React19__default.useRef(showIdleTime);
|
|
17858
|
+
const stateUpdateTimeoutRef = React19__default.useRef(null);
|
|
17859
|
+
React19__default.useEffect(() => {
|
|
17038
17860
|
if (stateUpdateTimeoutRef.current) {
|
|
17039
17861
|
clearTimeout(stateUpdateTimeoutRef.current);
|
|
17040
17862
|
}
|
|
@@ -17059,7 +17881,7 @@ var HourlyOutputChart = ({
|
|
|
17059
17881
|
}
|
|
17060
17882
|
};
|
|
17061
17883
|
}, [showIdleTime]);
|
|
17062
|
-
const animateToNewData =
|
|
17884
|
+
const animateToNewData = React19__default.useCallback((targetData) => {
|
|
17063
17885
|
const startData = [...prevDataRef.current];
|
|
17064
17886
|
const startTime = performance.now();
|
|
17065
17887
|
const duration = 1200;
|
|
@@ -17089,7 +17911,7 @@ var HourlyOutputChart = ({
|
|
|
17089
17911
|
}
|
|
17090
17912
|
animationFrameRef.current = requestAnimationFrame(animate);
|
|
17091
17913
|
}, []);
|
|
17092
|
-
|
|
17914
|
+
React19__default.useEffect(() => {
|
|
17093
17915
|
if (JSON.stringify(data) !== JSON.stringify(prevDataRef.current)) {
|
|
17094
17916
|
const shiftData = data.slice(0, SHIFT_DURATION);
|
|
17095
17917
|
animateToNewData(shiftData);
|
|
@@ -17100,7 +17922,7 @@ var HourlyOutputChart = ({
|
|
|
17100
17922
|
}
|
|
17101
17923
|
};
|
|
17102
17924
|
}, [data, animateToNewData]);
|
|
17103
|
-
const formatHour =
|
|
17925
|
+
const formatHour = React19__default.useCallback((hourIndex) => {
|
|
17104
17926
|
const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
|
|
17105
17927
|
const startHour = Math.floor(startDecimalHour) % 24;
|
|
17106
17928
|
const startMinute = Math.round(startDecimalHour % 1 * 60);
|
|
@@ -17117,7 +17939,7 @@ var HourlyOutputChart = ({
|
|
|
17117
17939
|
};
|
|
17118
17940
|
return `${formatTime2(startHour, startMinute)}-${formatTime2(endHour, endMinute)}`;
|
|
17119
17941
|
}, [shiftStartTime.decimalHour]);
|
|
17120
|
-
const formatTimeRange =
|
|
17942
|
+
const formatTimeRange = React19__default.useCallback((hourIndex) => {
|
|
17121
17943
|
const startDecimalHour = shiftStartTime.decimalHour + hourIndex;
|
|
17122
17944
|
const startHour = Math.floor(startDecimalHour) % 24;
|
|
17123
17945
|
const startMinute = Math.round(startDecimalHour % 1 * 60);
|
|
@@ -17131,7 +17953,7 @@ var HourlyOutputChart = ({
|
|
|
17131
17953
|
};
|
|
17132
17954
|
return `${formatTime2(startHour, startMinute)} - ${formatTime2(endHour, endMinute)}`;
|
|
17133
17955
|
}, [shiftStartTime.decimalHour]);
|
|
17134
|
-
const chartData =
|
|
17956
|
+
const chartData = React19__default.useMemo(() => {
|
|
17135
17957
|
return Array.from({ length: SHIFT_DURATION }, (_, i) => {
|
|
17136
17958
|
const actualHour = (shiftStartTime.hour + i) % 24;
|
|
17137
17959
|
const idleArray = idleTimeHourly?.[actualHour.toString()] || [];
|
|
@@ -17148,7 +17970,7 @@ var HourlyOutputChart = ({
|
|
|
17148
17970
|
};
|
|
17149
17971
|
});
|
|
17150
17972
|
}, [animatedData, data, pphThreshold, idleTimeHourly, shiftStartTime.hour, formatHour, formatTimeRange]);
|
|
17151
|
-
const IdleBar =
|
|
17973
|
+
const IdleBar = React19__default.useMemo(() => {
|
|
17152
17974
|
if (!idleBarState.visible) return null;
|
|
17153
17975
|
return /* @__PURE__ */ jsx(
|
|
17154
17976
|
Bar,
|
|
@@ -17465,6 +18287,33 @@ var HourlyOutputChart = ({
|
|
|
17465
18287
|
renderLegend()
|
|
17466
18288
|
] });
|
|
17467
18289
|
};
|
|
18290
|
+
var HourlyOutputChart = React19__default.memo(HourlyOutputChartComponent, (prevProps, nextProps) => {
|
|
18291
|
+
if (prevProps.pphThreshold !== nextProps.pphThreshold || prevProps.shiftStart !== nextProps.shiftStart || prevProps.showIdleTime !== nextProps.showIdleTime || prevProps.className !== nextProps.className) {
|
|
18292
|
+
return false;
|
|
18293
|
+
}
|
|
18294
|
+
if (prevProps.data.length !== nextProps.data.length) {
|
|
18295
|
+
return false;
|
|
18296
|
+
}
|
|
18297
|
+
if (!prevProps.data.every((val, idx) => val === nextProps.data[idx])) {
|
|
18298
|
+
return false;
|
|
18299
|
+
}
|
|
18300
|
+
const prevIdle = prevProps.idleTimeHourly || {};
|
|
18301
|
+
const nextIdle = nextProps.idleTimeHourly || {};
|
|
18302
|
+
const prevKeys = Object.keys(prevIdle);
|
|
18303
|
+
const nextKeys = Object.keys(nextIdle);
|
|
18304
|
+
if (prevKeys.length !== nextKeys.length) {
|
|
18305
|
+
return false;
|
|
18306
|
+
}
|
|
18307
|
+
for (const key of prevKeys) {
|
|
18308
|
+
if (!nextIdle[key]) return false;
|
|
18309
|
+
const prevArray = prevIdle[key];
|
|
18310
|
+
const nextArray = nextIdle[key];
|
|
18311
|
+
if (prevArray.length !== nextArray.length) return false;
|
|
18312
|
+
if (!prevArray.every((val, idx) => val === nextArray[idx])) return false;
|
|
18313
|
+
}
|
|
18314
|
+
return true;
|
|
18315
|
+
});
|
|
18316
|
+
HourlyOutputChart.displayName = "HourlyOutputChart";
|
|
17468
18317
|
function getTrendArrowAndColor(trend) {
|
|
17469
18318
|
if (trend > 0) {
|
|
17470
18319
|
return { arrow: "\u2191", color: "text-green-400" };
|
|
@@ -17474,7 +18323,7 @@ function getTrendArrowAndColor(trend) {
|
|
|
17474
18323
|
return { arrow: "\u2192", color: "text-gray-400" };
|
|
17475
18324
|
}
|
|
17476
18325
|
}
|
|
17477
|
-
var VideoCard =
|
|
18326
|
+
var VideoCard = React19__default.memo(({
|
|
17478
18327
|
workspace,
|
|
17479
18328
|
hlsUrl,
|
|
17480
18329
|
shouldPlay,
|
|
@@ -17617,7 +18466,7 @@ var VideoCard = React14__default.memo(({
|
|
|
17617
18466
|
});
|
|
17618
18467
|
VideoCard.displayName = "VideoCard";
|
|
17619
18468
|
var DEFAULT_HLS_URL = "https://192.168.5.9:8443/cam1.m3u8";
|
|
17620
|
-
var VideoGridView =
|
|
18469
|
+
var VideoGridView = React19__default.memo(({
|
|
17621
18470
|
workspaces,
|
|
17622
18471
|
selectedLine,
|
|
17623
18472
|
className = "",
|
|
@@ -18419,7 +19268,7 @@ var EmptyStateMessage = ({
|
|
|
18419
19268
|
iconClassName
|
|
18420
19269
|
}) => {
|
|
18421
19270
|
let IconContent = null;
|
|
18422
|
-
if (
|
|
19271
|
+
if (React19__default.isValidElement(iconType)) {
|
|
18423
19272
|
IconContent = iconType;
|
|
18424
19273
|
} else if (typeof iconType === "string") {
|
|
18425
19274
|
const MappedIcon = IconMap[iconType];
|
|
@@ -18552,7 +19401,10 @@ var BreakNotificationPopup = ({
|
|
|
18552
19401
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-3 flex-1", children: [
|
|
18553
19402
|
/* @__PURE__ */ jsx("div", { className: "w-2 h-2 bg-amber-500 rounded-full animate-pulse flex-shrink-0 mt-2" }),
|
|
18554
19403
|
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
18555
|
-
/* @__PURE__ */
|
|
19404
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-1", children: [
|
|
19405
|
+
/* @__PURE__ */ jsx("h4", { className: "font-semibold text-sm text-gray-900", children: breakItem.remarks || "Break" }),
|
|
19406
|
+
(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)}` })
|
|
19407
|
+
] }),
|
|
18556
19408
|
/* @__PURE__ */ jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxs("div", { className: "text-xs text-gray-600 font-medium", children: [
|
|
18557
19409
|
breakItem.startTime,
|
|
18558
19410
|
" - ",
|
|
@@ -18561,8 +19413,7 @@ var BreakNotificationPopup = ({
|
|
|
18561
19413
|
/* @__PURE__ */ jsx("div", { className: "mb-2", children: /* @__PURE__ */ jsxs("div", { className: "text-xs text-gray-500", children: [
|
|
18562
19414
|
formatTime2(breakItem.elapsedMinutes),
|
|
18563
19415
|
" / ",
|
|
18564
|
-
breakItem.duration
|
|
18565
|
-
" min"
|
|
19416
|
+
formatTime2(breakItem.duration)
|
|
18566
19417
|
] }) }),
|
|
18567
19418
|
/* @__PURE__ */ jsx("div", { className: "mt-2", children: /* @__PURE__ */ jsx("div", { className: "w-full bg-gray-200 rounded-full h-1.5", children: /* @__PURE__ */ jsx(
|
|
18568
19419
|
"div",
|
|
@@ -21001,7 +21852,7 @@ function Skeleton({ className, ...props }) {
|
|
|
21001
21852
|
var Select = SelectPrimitive.Root;
|
|
21002
21853
|
var SelectGroup = SelectPrimitive.Group;
|
|
21003
21854
|
var SelectValue = SelectPrimitive.Value;
|
|
21004
|
-
var SelectTrigger =
|
|
21855
|
+
var SelectTrigger = React19.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
21005
21856
|
SelectPrimitive.Trigger,
|
|
21006
21857
|
{
|
|
21007
21858
|
ref,
|
|
@@ -21017,7 +21868,7 @@ var SelectTrigger = React14.forwardRef(({ className, children, ...props }, ref)
|
|
|
21017
21868
|
}
|
|
21018
21869
|
));
|
|
21019
21870
|
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
|
|
21020
|
-
var SelectScrollUpButton =
|
|
21871
|
+
var SelectScrollUpButton = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
21021
21872
|
SelectPrimitive.ScrollUpButton,
|
|
21022
21873
|
{
|
|
21023
21874
|
ref,
|
|
@@ -21027,7 +21878,7 @@ var SelectScrollUpButton = React14.forwardRef(({ className, ...props }, ref) =>
|
|
|
21027
21878
|
}
|
|
21028
21879
|
));
|
|
21029
21880
|
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
|
|
21030
|
-
var SelectScrollDownButton =
|
|
21881
|
+
var SelectScrollDownButton = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
21031
21882
|
SelectPrimitive.ScrollDownButton,
|
|
21032
21883
|
{
|
|
21033
21884
|
ref,
|
|
@@ -21037,7 +21888,7 @@ var SelectScrollDownButton = React14.forwardRef(({ className, ...props }, ref) =
|
|
|
21037
21888
|
}
|
|
21038
21889
|
));
|
|
21039
21890
|
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
|
|
21040
|
-
var SelectContent =
|
|
21891
|
+
var SelectContent = React19.forwardRef(({ className, children, position = "popper", ...props }, ref) => /* @__PURE__ */ jsx(SelectPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
|
|
21041
21892
|
SelectPrimitive.Content,
|
|
21042
21893
|
{
|
|
21043
21894
|
ref,
|
|
@@ -21065,7 +21916,7 @@ var SelectContent = React14.forwardRef(({ className, children, position = "poppe
|
|
|
21065
21916
|
}
|
|
21066
21917
|
) }));
|
|
21067
21918
|
SelectContent.displayName = SelectPrimitive.Content.displayName;
|
|
21068
|
-
var SelectLabel =
|
|
21919
|
+
var SelectLabel = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
21069
21920
|
SelectPrimitive.Label,
|
|
21070
21921
|
{
|
|
21071
21922
|
ref,
|
|
@@ -21074,7 +21925,7 @@ var SelectLabel = React14.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
21074
21925
|
}
|
|
21075
21926
|
));
|
|
21076
21927
|
SelectLabel.displayName = SelectPrimitive.Label.displayName;
|
|
21077
|
-
var SelectItem =
|
|
21928
|
+
var SelectItem = React19.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
21078
21929
|
SelectPrimitive.Item,
|
|
21079
21930
|
{
|
|
21080
21931
|
ref,
|
|
@@ -21090,7 +21941,7 @@ var SelectItem = React14.forwardRef(({ className, children, ...props }, ref) =>
|
|
|
21090
21941
|
}
|
|
21091
21942
|
));
|
|
21092
21943
|
SelectItem.displayName = SelectPrimitive.Item.displayName;
|
|
21093
|
-
var SelectSeparator =
|
|
21944
|
+
var SelectSeparator = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
21094
21945
|
SelectPrimitive.Separator,
|
|
21095
21946
|
{
|
|
21096
21947
|
ref,
|
|
@@ -21965,7 +22816,7 @@ var BottlenecksContent = ({
|
|
|
21965
22816
|
className
|
|
21966
22817
|
}) => {
|
|
21967
22818
|
const dashboardConfig = useDashboardConfig();
|
|
21968
|
-
const sopCategories =
|
|
22819
|
+
const sopCategories = React19__default.useMemo(() => {
|
|
21969
22820
|
const sopConfig = dashboardConfig?.s3Config?.sopCategories;
|
|
21970
22821
|
if (!sopConfig) return null;
|
|
21971
22822
|
if (sopConfig.workspaceOverrides && sopConfig.workspaceOverrides[workspaceId]) {
|
|
@@ -22944,7 +23795,7 @@ var arePropsEqual = (prevProps, nextProps) => {
|
|
|
22944
23795
|
return prevProps.data.efficiency === nextProps.data.efficiency && prevProps.data.trend_score === nextProps.data.trend_score && prevProps.data.workspace_id === nextProps.data.workspace_id && prevProps.data.workspace_name === nextProps.data.workspace_name && prevProps.isBottleneck === nextProps.isBottleneck && prevProps.isLowEfficiency === nextProps.isLowEfficiency && prevProps.isVeryLowEfficiency === nextProps.isVeryLowEfficiency && // Position doesn't need deep equality check as it's generally static
|
|
22945
23796
|
prevProps.position.id === nextProps.position.id;
|
|
22946
23797
|
};
|
|
22947
|
-
var WorkspaceGridItem =
|
|
23798
|
+
var WorkspaceGridItem = React19__default.memo(({
|
|
22948
23799
|
data,
|
|
22949
23800
|
position,
|
|
22950
23801
|
isBottleneck = false,
|
|
@@ -23037,7 +23888,7 @@ var WorkspaceGridItem = React14__default.memo(({
|
|
|
23037
23888
|
);
|
|
23038
23889
|
}, arePropsEqual);
|
|
23039
23890
|
WorkspaceGridItem.displayName = "WorkspaceGridItem";
|
|
23040
|
-
var WorkspaceGrid =
|
|
23891
|
+
var WorkspaceGrid = React19__default.memo(({
|
|
23041
23892
|
workspaces,
|
|
23042
23893
|
isPdfMode = false,
|
|
23043
23894
|
customWorkspacePositions,
|
|
@@ -23227,7 +24078,7 @@ var KPICard = ({
|
|
|
23227
24078
|
}) => {
|
|
23228
24079
|
useThemeConfig();
|
|
23229
24080
|
const { formatNumber } = useFormatNumber();
|
|
23230
|
-
const trendInfo =
|
|
24081
|
+
const trendInfo = React19__default.useMemo(() => {
|
|
23231
24082
|
let trendValue = trend || "neutral";
|
|
23232
24083
|
if (change !== void 0 && trend === void 0) {
|
|
23233
24084
|
trendValue = change > 0 ? "up" : change < 0 ? "down" : "neutral";
|
|
@@ -23250,7 +24101,7 @@ var KPICard = ({
|
|
|
23250
24101
|
const shouldShowTrend = !(change === 0 && trend === void 0);
|
|
23251
24102
|
return { trendValue, Icon: Icon2, colorClass, shouldShowTrend };
|
|
23252
24103
|
}, [trend, change]);
|
|
23253
|
-
const formattedValue =
|
|
24104
|
+
const formattedValue = React19__default.useMemo(() => {
|
|
23254
24105
|
if (title === "Quality Compliance" && typeof value === "number") {
|
|
23255
24106
|
return value.toFixed(1);
|
|
23256
24107
|
}
|
|
@@ -23264,7 +24115,7 @@ var KPICard = ({
|
|
|
23264
24115
|
}
|
|
23265
24116
|
return value;
|
|
23266
24117
|
}, [value, title]);
|
|
23267
|
-
const formattedChange =
|
|
24118
|
+
const formattedChange = React19__default.useMemo(() => {
|
|
23268
24119
|
if (change === void 0 || change === 0) return null;
|
|
23269
24120
|
const absChange = Math.abs(change);
|
|
23270
24121
|
return formatNumber(absChange, { minimumFractionDigits: 0, maximumFractionDigits: 1 });
|
|
@@ -23751,7 +24602,7 @@ var Breadcrumbs = ({ items }) => {
|
|
|
23751
24602
|
}
|
|
23752
24603
|
}
|
|
23753
24604
|
};
|
|
23754
|
-
return /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: "mb-1 flex items-center space-x-1 text-xs font-medium text-gray-500 dark:text-gray-400", children: items.map((item, index) => /* @__PURE__ */ jsxs(
|
|
24605
|
+
return /* @__PURE__ */ jsx("nav", { "aria-label": "Breadcrumb", className: "mb-1 flex items-center space-x-1 text-xs font-medium text-gray-500 dark:text-gray-400", children: items.map((item, index) => /* @__PURE__ */ jsxs(React19__default.Fragment, { children: [
|
|
23755
24606
|
index > 0 && /* @__PURE__ */ jsx(ChevronRight, { className: "h-3 w-3 text-gray-400 dark:text-gray-500" }),
|
|
23756
24607
|
/* @__PURE__ */ jsxs(
|
|
23757
24608
|
"span",
|
|
@@ -23943,7 +24794,9 @@ var SideNavBar = memo(({
|
|
|
23943
24794
|
const router = useRouter();
|
|
23944
24795
|
const { navigate } = useNavigation();
|
|
23945
24796
|
const entityConfig = useEntityConfig();
|
|
24797
|
+
const dashboardConfig = useDashboardConfig();
|
|
23946
24798
|
const lineId = entityConfig.defaultLineId || LINE_1_UUID;
|
|
24799
|
+
const skuEnabled = dashboardConfig?.skuConfig?.enabled || false;
|
|
23947
24800
|
const pathname = propPathname || router.pathname;
|
|
23948
24801
|
const getButtonClasses = useCallback((path) => {
|
|
23949
24802
|
const isActive = pathname === path || pathname.startsWith(path + "/");
|
|
@@ -24018,6 +24871,14 @@ var SideNavBar = memo(({
|
|
|
24018
24871
|
}
|
|
24019
24872
|
}
|
|
24020
24873
|
}), [navigate]);
|
|
24874
|
+
const handleSKUsClick = useCallback(() => navigate("/skus", {
|
|
24875
|
+
trackingEvent: {
|
|
24876
|
+
name: "SKU Management Page Clicked",
|
|
24877
|
+
properties: {
|
|
24878
|
+
source: "side_nav"
|
|
24879
|
+
}
|
|
24880
|
+
}
|
|
24881
|
+
}), [navigate]);
|
|
24021
24882
|
const homeButtonClasses = useMemo(() => getButtonClasses("/"), [getButtonClasses, pathname]);
|
|
24022
24883
|
const leaderboardButtonClasses = useMemo(() => getButtonClasses("/leaderboard"), [getButtonClasses, pathname]);
|
|
24023
24884
|
const kpisButtonClasses = useMemo(() => getButtonClasses("/kpis"), [getButtonClasses, pathname]);
|
|
@@ -24026,6 +24887,7 @@ var SideNavBar = memo(({
|
|
|
24026
24887
|
const aiAgentButtonClasses = useMemo(() => getButtonClasses("/ai-agent"), [getButtonClasses, pathname]);
|
|
24027
24888
|
const profileButtonClasses = useMemo(() => getButtonClasses("/profile"), [getButtonClasses, pathname]);
|
|
24028
24889
|
const helpButtonClasses = useMemo(() => getButtonClasses("/help"), [getButtonClasses, pathname]);
|
|
24890
|
+
const skusButtonClasses = useMemo(() => getButtonClasses("/skus"), [getButtonClasses, pathname]);
|
|
24029
24891
|
return /* @__PURE__ */ jsxs("aside", { className: `w-20 h-screen bg-white shadow-lg border-r border-gray-100 flex flex-col items-center fixed ${className}`, children: [
|
|
24030
24892
|
/* @__PURE__ */ jsx("div", { className: "w-full py-6 px-4 flex-shrink-0", children: /* @__PURE__ */ jsx(
|
|
24031
24893
|
"button",
|
|
@@ -24126,6 +24988,21 @@ var SideNavBar = memo(({
|
|
|
24126
24988
|
]
|
|
24127
24989
|
}
|
|
24128
24990
|
),
|
|
24991
|
+
skuEnabled && /* @__PURE__ */ jsxs(
|
|
24992
|
+
"button",
|
|
24993
|
+
{
|
|
24994
|
+
onClick: handleSKUsClick,
|
|
24995
|
+
className: skusButtonClasses,
|
|
24996
|
+
"aria-label": "SKU Management",
|
|
24997
|
+
tabIndex: 0,
|
|
24998
|
+
role: "tab",
|
|
24999
|
+
"aria-selected": pathname === "/skus" || pathname.startsWith("/skus/"),
|
|
25000
|
+
children: [
|
|
25001
|
+
/* @__PURE__ */ jsx(CubeIcon, { className: "w-5 h-5 mb-1" }),
|
|
25002
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium leading-tight", children: "SKUs" })
|
|
25003
|
+
]
|
|
25004
|
+
}
|
|
25005
|
+
),
|
|
24129
25006
|
/* @__PURE__ */ jsxs(
|
|
24130
25007
|
"button",
|
|
24131
25008
|
{
|
|
@@ -24310,6 +25187,103 @@ var Header = ({
|
|
|
24310
25187
|
] })
|
|
24311
25188
|
] }) });
|
|
24312
25189
|
};
|
|
25190
|
+
var LoadingState = ({
|
|
25191
|
+
message = "Loading...",
|
|
25192
|
+
subMessage,
|
|
25193
|
+
size = "lg",
|
|
25194
|
+
className = ""
|
|
25195
|
+
}) => {
|
|
25196
|
+
return /* @__PURE__ */ jsx("div", { className: `flex h-full w-full items-center justify-center bg-gray-50/50 ${className}`, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center space-y-4 text-center", children: [
|
|
25197
|
+
/* @__PURE__ */ jsx(LoadingSpinner_default, { size }),
|
|
25198
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
25199
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-medium text-gray-900", children: message }),
|
|
25200
|
+
subMessage && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-gray-600", children: subMessage })
|
|
25201
|
+
] })
|
|
25202
|
+
] }) });
|
|
25203
|
+
};
|
|
25204
|
+
var LoadingSkeleton = ({
|
|
25205
|
+
type,
|
|
25206
|
+
count = 1,
|
|
25207
|
+
className = "",
|
|
25208
|
+
showLoadingIndicator = true
|
|
25209
|
+
}) => {
|
|
25210
|
+
const renderSkeleton = () => {
|
|
25211
|
+
switch (type) {
|
|
25212
|
+
case "card":
|
|
25213
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-3 p-4 border rounded-lg relative", children: [
|
|
25214
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-3/4" }),
|
|
25215
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-1/2" }),
|
|
25216
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-full" }),
|
|
25217
|
+
showLoadingIndicator && /* @__PURE__ */ jsx("div", { className: "absolute top-2 right-2", children: /* @__PURE__ */ jsxs("div", { className: "flex space-x-1", children: [
|
|
25218
|
+
/* @__PURE__ */ jsx("div", { className: "w-1.5 h-1.5 bg-blue-500 rounded-full animate-bounce", style: { animationDelay: "0ms" } }),
|
|
25219
|
+
/* @__PURE__ */ jsx("div", { className: "w-1.5 h-1.5 bg-blue-500 rounded-full animate-bounce", style: { animationDelay: "150ms" } }),
|
|
25220
|
+
/* @__PURE__ */ jsx("div", { className: "w-1.5 h-1.5 bg-blue-500 rounded-full animate-bounce", style: { animationDelay: "300ms" } })
|
|
25221
|
+
] }) })
|
|
25222
|
+
] });
|
|
25223
|
+
case "chart":
|
|
25224
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-3 p-4 relative", children: [
|
|
25225
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-6 w-1/3" }),
|
|
25226
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
25227
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-64 w-full" }),
|
|
25228
|
+
showLoadingIndicator && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "bg-white/80 rounded-lg p-3 shadow-sm", children: /* @__PURE__ */ jsxs("svg", { className: "animate-spin h-6 w-6 text-blue-500", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
|
|
25229
|
+
/* @__PURE__ */ jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
25230
|
+
/* @__PURE__ */ jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
|
|
25231
|
+
] }) }) })
|
|
25232
|
+
] })
|
|
25233
|
+
] });
|
|
25234
|
+
case "table":
|
|
25235
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
25236
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-full" }),
|
|
25237
|
+
[...Array(5)].map((_, i) => /* @__PURE__ */ jsx(Skeleton, { className: "h-12 w-full" }, i))
|
|
25238
|
+
] });
|
|
25239
|
+
case "list":
|
|
25240
|
+
return /* @__PURE__ */ jsx("div", { className: "space-y-2", children: [...Array(5)].map((_, i) => /* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-3", children: [
|
|
25241
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-10 w-10 rounded-full" }),
|
|
25242
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-2", children: [
|
|
25243
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-3/4" }),
|
|
25244
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-1/2" })
|
|
25245
|
+
] })
|
|
25246
|
+
] }, i)) });
|
|
25247
|
+
case "kpi":
|
|
25248
|
+
return /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4", children: [...Array(4)].map((_, i) => /* @__PURE__ */ jsxs("div", { className: "p-4 border rounded-lg space-y-2", children: [
|
|
25249
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-2/3" }),
|
|
25250
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-1/2" }),
|
|
25251
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-full" })
|
|
25252
|
+
] }, i)) });
|
|
25253
|
+
case "workspace-card":
|
|
25254
|
+
return /* @__PURE__ */ jsxs("div", { className: "p-4 border rounded-lg space-y-3", children: [
|
|
25255
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-between items-start", children: [
|
|
25256
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-1/3" }),
|
|
25257
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-5 w-16" })
|
|
25258
|
+
] }),
|
|
25259
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-32 w-full" }),
|
|
25260
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
25261
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-full" }),
|
|
25262
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-8 w-full" })
|
|
25263
|
+
] })
|
|
25264
|
+
] });
|
|
25265
|
+
case "video-grid":
|
|
25266
|
+
return /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4", children: [...Array(6)].map((_, i) => /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
25267
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-48 w-full rounded-lg" }),
|
|
25268
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-4 w-3/4" }),
|
|
25269
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "h-3 w-1/2" })
|
|
25270
|
+
] }, i)) });
|
|
25271
|
+
default:
|
|
25272
|
+
return /* @__PURE__ */ jsx(Skeleton, { className: "h-20 w-full" });
|
|
25273
|
+
}
|
|
25274
|
+
};
|
|
25275
|
+
return /* @__PURE__ */ jsx("div", { className, children: [...Array(count)].map((_, index) => /* @__PURE__ */ jsx("div", { children: renderSkeleton() }, index)) });
|
|
25276
|
+
};
|
|
25277
|
+
var LoadingInline = ({
|
|
25278
|
+
message,
|
|
25279
|
+
size = "sm",
|
|
25280
|
+
className = ""
|
|
25281
|
+
}) => {
|
|
25282
|
+
return /* @__PURE__ */ jsxs("div", { className: `inline-flex items-center space-x-2 ${className}`, children: [
|
|
25283
|
+
/* @__PURE__ */ jsx(LoadingSpinner_default, { size }),
|
|
25284
|
+
message && /* @__PURE__ */ jsx("span", { className: "text-sm text-gray-600", children: message })
|
|
25285
|
+
] });
|
|
25286
|
+
};
|
|
24313
25287
|
var DEFAULT_HLS_CONFIG = {
|
|
24314
25288
|
maxBufferLength: 15,
|
|
24315
25289
|
// Moderate buffer length for faster startup
|
|
@@ -24569,7 +25543,7 @@ var ThreadSidebar = ({
|
|
|
24569
25543
|
] });
|
|
24570
25544
|
};
|
|
24571
25545
|
var axelProfilePng = "/axel-profile.png";
|
|
24572
|
-
var ProfilePicture =
|
|
25546
|
+
var ProfilePicture = React19__default.memo(({ alt = "Axel", className = "w-12 h-12" }) => {
|
|
24573
25547
|
return /* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx("div", { className: `${className} rounded-xl overflow-hidden shadow-sm`, children: /* @__PURE__ */ jsx(
|
|
24574
25548
|
"img",
|
|
24575
25549
|
{
|
|
@@ -24687,6 +25661,7 @@ var AIAgentView = () => {
|
|
|
24687
25661
|
const textareaRef = useRef(null);
|
|
24688
25662
|
const messagesEndRef = useRef(null);
|
|
24689
25663
|
const containerRef = useRef(null);
|
|
25664
|
+
const renderedContentCache = useRef(/* @__PURE__ */ new Map());
|
|
24690
25665
|
const { createThread, mutate: mutateThreads } = useThreads();
|
|
24691
25666
|
const { messages, addMessage, setMessages } = useMessages(activeThreadId);
|
|
24692
25667
|
const agnoApiUrl = config.endpoints?.agnoApiUrl || "https://optifye-agent-production.up.railway.app";
|
|
@@ -25172,6 +26147,10 @@ var AIAgentView = () => {
|
|
|
25172
26147
|
});
|
|
25173
26148
|
}
|
|
25174
26149
|
const renderAssistantContent = (content) => {
|
|
26150
|
+
const cached = renderedContentCache.current.get(content);
|
|
26151
|
+
if (cached) {
|
|
26152
|
+
return cached;
|
|
26153
|
+
}
|
|
25175
26154
|
const parseChartPatterns = (text) => {
|
|
25176
26155
|
const chartElements = [];
|
|
25177
26156
|
let lastIndex = 0;
|
|
@@ -26036,16 +27015,20 @@ var AIAgentView = () => {
|
|
|
26036
27015
|
}
|
|
26037
27016
|
};
|
|
26038
27017
|
const chartContent = parseChartPatterns(content);
|
|
27018
|
+
let finalNode;
|
|
26039
27019
|
if (chartContent) {
|
|
26040
|
-
|
|
27020
|
+
finalNode = /* @__PURE__ */ jsx("div", { className: "formatted-content", children: chartContent });
|
|
27021
|
+
} else {
|
|
27022
|
+
finalNode = /* @__PURE__ */ jsx(
|
|
27023
|
+
"div",
|
|
27024
|
+
{
|
|
27025
|
+
className: "formatted-content",
|
|
27026
|
+
dangerouslySetInnerHTML: { __html: formatMessage(content) }
|
|
27027
|
+
}
|
|
27028
|
+
);
|
|
26041
27029
|
}
|
|
26042
|
-
|
|
26043
|
-
|
|
26044
|
-
{
|
|
26045
|
-
className: "formatted-content",
|
|
26046
|
-
dangerouslySetInnerHTML: { __html: formatMessage(content) }
|
|
26047
|
-
}
|
|
26048
|
-
);
|
|
27030
|
+
renderedContentCache.current.set(content, finalNode);
|
|
27031
|
+
return finalNode;
|
|
26049
27032
|
};
|
|
26050
27033
|
return /* @__PURE__ */ jsxs("div", { className: "flex h-screen bg-white", children: [
|
|
26051
27034
|
/* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: {
|
|
@@ -27287,8 +28270,6 @@ var HelpView = ({
|
|
|
27287
28270
|
var AuthenticatedHelpView = withAuth(HelpView);
|
|
27288
28271
|
var HelpView_default = HelpView;
|
|
27289
28272
|
var KPISection2 = KPISection;
|
|
27290
|
-
var LoadingPageCmp = LoadingPage_default;
|
|
27291
|
-
var LoadingOverlayCmp = LoadingOverlay_default;
|
|
27292
28273
|
function HomeView({
|
|
27293
28274
|
defaultLineId,
|
|
27294
28275
|
factoryViewId,
|
|
@@ -27307,6 +28288,7 @@ function HomeView({
|
|
|
27307
28288
|
const [isChangingFilter, setIsChangingFilter] = useState(false);
|
|
27308
28289
|
const [errorMessage, setErrorMessage] = useState(null);
|
|
27309
28290
|
const [displayNamesInitialized, setDisplayNamesInitialized] = useState(false);
|
|
28291
|
+
const [hasInitialDataLoaded, setHasInitialDataLoaded] = useState(false);
|
|
27310
28292
|
useEffect(() => {
|
|
27311
28293
|
const initDisplayNames = async () => {
|
|
27312
28294
|
try {
|
|
@@ -27357,17 +28339,17 @@ function HomeView({
|
|
|
27357
28339
|
lineId: selectedLineId,
|
|
27358
28340
|
onLineMetricsUpdate
|
|
27359
28341
|
});
|
|
27360
|
-
const lineIdsForBreaks = useMemo(() => {
|
|
27361
|
-
if (selectedLineId === factoryViewId) {
|
|
27362
|
-
return allLineIds;
|
|
27363
|
-
}
|
|
27364
|
-
return [selectedLineId];
|
|
27365
|
-
}, [selectedLineId, factoryViewId, allLineIds]);
|
|
27366
28342
|
const {
|
|
27367
|
-
activeBreaks,
|
|
28343
|
+
activeBreaks: allActiveBreaks,
|
|
27368
28344
|
isLoading: breaksLoading,
|
|
27369
28345
|
error: breaksError
|
|
27370
|
-
} = useActiveBreaks(
|
|
28346
|
+
} = useActiveBreaks(allLineIds);
|
|
28347
|
+
const activeBreaks = useMemo(() => {
|
|
28348
|
+
if (selectedLineId === factoryViewId) {
|
|
28349
|
+
return allActiveBreaks;
|
|
28350
|
+
}
|
|
28351
|
+
return allActiveBreaks.filter((breakItem) => breakItem.lineId === selectedLineId);
|
|
28352
|
+
}, [allActiveBreaks, selectedLineId, factoryViewId]);
|
|
27371
28353
|
const memoizedWorkspaceMetrics = useMemo(() => workspaceMetrics, [
|
|
27372
28354
|
// Only update reference if meaningful properties change
|
|
27373
28355
|
workspaceMetrics.length,
|
|
@@ -27407,6 +28389,11 @@ function HomeView({
|
|
|
27407
28389
|
}
|
|
27408
28390
|
}
|
|
27409
28391
|
}, [metricsLoading, kpisLoading, workspaceMetrics, isChangingFilter, selectedLineId, factoryViewId]);
|
|
28392
|
+
useEffect(() => {
|
|
28393
|
+
if (!metricsLoading && !kpisLoading && !hasInitialDataLoaded) {
|
|
28394
|
+
setHasInitialDataLoaded(true);
|
|
28395
|
+
}
|
|
28396
|
+
}, [metricsLoading, kpisLoading, hasInitialDataLoaded]);
|
|
27410
28397
|
const lineTitle = useMemo(() => {
|
|
27411
28398
|
return factoryName;
|
|
27412
28399
|
}, [factoryName]);
|
|
@@ -27419,9 +28406,56 @@ function HomeView({
|
|
|
27419
28406
|
/* @__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)) })
|
|
27420
28407
|
] });
|
|
27421
28408
|
}, [availableLineIds, handleLineChange, selectedLineId, lineNames, factoryViewId, allLineIds.length]);
|
|
27422
|
-
const
|
|
27423
|
-
|
|
27424
|
-
|
|
28409
|
+
const isInitialLoading = !isHydrated || !displayNamesInitialized && displayNamesLoading;
|
|
28410
|
+
const isDataLoading = metricsLoading || kpisLoading;
|
|
28411
|
+
if (isInitialLoading) {
|
|
28412
|
+
return /* @__PURE__ */ jsx("div", { className: "min-h-screen bg-gradient-to-br from-slate-50 via-blue-50 to-slate-50 flex items-center justify-center", children: /* @__PURE__ */ jsx(
|
|
28413
|
+
motion.div,
|
|
28414
|
+
{
|
|
28415
|
+
className: "text-center",
|
|
28416
|
+
initial: { opacity: 0, scale: 0.9 },
|
|
28417
|
+
animate: { opacity: 1, scale: 1 },
|
|
28418
|
+
transition: { duration: 0.5 },
|
|
28419
|
+
children: /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-2xl shadow-2xl p-12 max-w-md mx-auto", children: [
|
|
28420
|
+
/* @__PURE__ */ jsx("div", { className: "relative mb-8", children: /* @__PURE__ */ jsxs("div", { className: "w-24 h-24 mx-auto", children: [
|
|
28421
|
+
/* @__PURE__ */ jsxs("svg", { className: "animate-spin", viewBox: "0 0 100 100", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
28422
|
+
/* @__PURE__ */ jsx("circle", { cx: "50", cy: "50", r: "45", fill: "none", stroke: "#e5e7eb", strokeWidth: "8" }),
|
|
28423
|
+
/* @__PURE__ */ jsx(
|
|
28424
|
+
"circle",
|
|
28425
|
+
{
|
|
28426
|
+
cx: "50",
|
|
28427
|
+
cy: "50",
|
|
28428
|
+
r: "45",
|
|
28429
|
+
fill: "none",
|
|
28430
|
+
stroke: "#3b82f6",
|
|
28431
|
+
strokeWidth: "8",
|
|
28432
|
+
strokeDasharray: "150 283",
|
|
28433
|
+
strokeLinecap: "round",
|
|
28434
|
+
className: "transform -rotate-90 origin-center"
|
|
28435
|
+
}
|
|
28436
|
+
)
|
|
28437
|
+
] }),
|
|
28438
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsx("div", { className: "w-16 h-16 bg-gradient-to-br from-blue-500 to-blue-600 rounded-full animate-pulse" }) })
|
|
28439
|
+
] }) }),
|
|
28440
|
+
/* @__PURE__ */ jsx("h2", { className: "text-2xl font-bold text-gray-800 mb-2", children: "Loading Dashboard" }),
|
|
28441
|
+
/* @__PURE__ */ jsx("p", { className: "text-gray-600 mb-6", children: "Initializing your workspace..." }),
|
|
28442
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
28443
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center space-x-2 text-sm text-gray-500", children: [
|
|
28444
|
+
/* @__PURE__ */ jsx("div", { className: "w-2 h-2 bg-blue-500 rounded-full animate-pulse" }),
|
|
28445
|
+
/* @__PURE__ */ jsx("span", { children: "Connecting to services" })
|
|
28446
|
+
] }),
|
|
28447
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center space-x-2 text-sm text-gray-500", children: [
|
|
28448
|
+
/* @__PURE__ */ jsx("div", { className: "w-2 h-2 bg-blue-500 rounded-full animate-pulse", style: { animationDelay: "0.2s" } }),
|
|
28449
|
+
/* @__PURE__ */ jsx("span", { children: "Loading workspace configurations" })
|
|
28450
|
+
] }),
|
|
28451
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center space-x-2 text-sm text-gray-500", children: [
|
|
28452
|
+
/* @__PURE__ */ jsx("div", { className: "w-2 h-2 bg-blue-500 rounded-full animate-pulse", style: { animationDelay: "0.4s" } }),
|
|
28453
|
+
/* @__PURE__ */ jsx("span", { children: "Preparing dashboard view" })
|
|
28454
|
+
] })
|
|
28455
|
+
] })
|
|
28456
|
+
] })
|
|
28457
|
+
}
|
|
28458
|
+
) });
|
|
27425
28459
|
}
|
|
27426
28460
|
if (errorMessage || displayNamesError) {
|
|
27427
28461
|
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: [
|
|
@@ -27432,52 +28466,64 @@ function HomeView({
|
|
|
27432
28466
|
] })
|
|
27433
28467
|
] }) }) });
|
|
27434
28468
|
}
|
|
27435
|
-
|
|
27436
|
-
return /* @__PURE__ */ jsx("div", { className: "min-h-screen bg-slate-50", children: /* @__PURE__ */ jsx(LoadingPageCmp, { message: "Loading metrics..." }) });
|
|
27437
|
-
}
|
|
27438
|
-
return /* @__PURE__ */ jsxs(
|
|
28469
|
+
return /* @__PURE__ */ jsx(
|
|
27439
28470
|
motion.div,
|
|
27440
28471
|
{
|
|
27441
28472
|
className: "flex min-h-screen bg-slate-50",
|
|
27442
28473
|
initial: { opacity: 1 },
|
|
27443
28474
|
animate: { opacity: 1 },
|
|
27444
|
-
children: [
|
|
27445
|
-
/* @__PURE__ */
|
|
27446
|
-
|
|
27447
|
-
|
|
27448
|
-
/* @__PURE__ */ jsx("div", { className: "sticky top-0 z-30 sm:static bg-white shadow-sm border-b border-gray-200/80", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col sm:flex-row sm:items-center sm:justify-between px-3 sm:px-6 lg:px-8 py-1.5 sm:py-2.5", children: /* @__PURE__ */ jsx(
|
|
27449
|
-
DashboardHeader,
|
|
27450
|
-
{
|
|
27451
|
-
lineTitle,
|
|
27452
|
-
className: "w-full",
|
|
27453
|
-
headerControls: memoizedKPIs ? /* @__PURE__ */ jsx(KPISection2, { kpis: memoizedKPIs, className: "w-full sm:w-auto" }) : null
|
|
27454
|
-
}
|
|
27455
|
-
) }) }),
|
|
27456
|
-
/* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto sm:overflow-hidden relative", children: [
|
|
27457
|
-
lineSelectorComponent && /* @__PURE__ */ jsx("div", { className: "absolute right-3 top-2 sm:right-6 sm:top-3 z-30", children: lineSelectorComponent }),
|
|
27458
|
-
memoizedWorkspaceMetrics.length > 0 ? /* @__PURE__ */ jsx("div", { className: "h-full sm:h-full min-h-[calc(100vh-80px)] sm:min-h-0", children: React14__default.createElement(WorkspaceGrid, {
|
|
27459
|
-
workspaces: memoizedWorkspaceMetrics,
|
|
27460
|
-
lineNames,
|
|
27461
|
-
factoryView: factoryViewId,
|
|
27462
|
-
videoSources,
|
|
27463
|
-
className: "h-full"
|
|
27464
|
-
}) }) : /* @__PURE__ */ jsx(NoWorkspaceData, { message: "No workspace data available. Select another line or check configurations." })
|
|
27465
|
-
] })
|
|
27466
|
-
] }),
|
|
27467
|
-
/* @__PURE__ */ jsx(
|
|
27468
|
-
BreakNotificationPopup,
|
|
28475
|
+
children: /* @__PURE__ */ jsxs("div", { className: "relative flex flex-1", children: [
|
|
28476
|
+
/* @__PURE__ */ jsxs("main", { className: "flex flex-1 flex-col", children: [
|
|
28477
|
+
/* @__PURE__ */ jsx("div", { className: "sticky top-0 z-30 sm:static bg-white shadow-sm border-b border-gray-200/80", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col sm:flex-row sm:items-center sm:justify-between px-3 sm:px-6 lg:px-8 py-1.5 sm:py-2.5", children: /* @__PURE__ */ jsx(
|
|
28478
|
+
DashboardHeader,
|
|
27469
28479
|
{
|
|
27470
|
-
|
|
27471
|
-
|
|
27472
|
-
|
|
28480
|
+
lineTitle,
|
|
28481
|
+
className: "w-full",
|
|
28482
|
+
headerControls: memoizedKPIs ? /* @__PURE__ */ jsx(KPISection2, { kpis: memoizedKPIs, className: "w-full sm:w-auto" }) : null
|
|
27473
28483
|
}
|
|
27474
|
-
)
|
|
27475
|
-
|
|
27476
|
-
|
|
28484
|
+
) }) }),
|
|
28485
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto sm:overflow-hidden relative", children: [
|
|
28486
|
+
lineSelectorComponent && /* @__PURE__ */ jsx("div", { className: "absolute right-3 top-2 sm:right-6 sm:top-3 z-30", children: lineSelectorComponent }),
|
|
28487
|
+
/* @__PURE__ */ jsx("div", { className: "h-full sm:h-full min-h-[calc(100vh-80px)] sm:min-h-0", children: isDataLoading && hasInitialDataLoaded && memoizedWorkspaceMetrics.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-3 sm:px-6 lg:px-8 py-4", children: /* @__PURE__ */ jsx(LoadingSkeleton, { type: "workspace-card", count: 8, className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4" }) }) : memoizedWorkspaceMetrics.length > 0 ? /* @__PURE__ */ jsx(
|
|
28488
|
+
motion.div,
|
|
28489
|
+
{
|
|
28490
|
+
initial: { opacity: 0, scale: 0.98 },
|
|
28491
|
+
animate: { opacity: 1, scale: 1 },
|
|
28492
|
+
transition: { duration: 0.3 },
|
|
28493
|
+
className: "h-full",
|
|
28494
|
+
children: React19__default.createElement(WorkspaceGrid, {
|
|
28495
|
+
workspaces: memoizedWorkspaceMetrics,
|
|
28496
|
+
lineNames,
|
|
28497
|
+
factoryView: factoryViewId,
|
|
28498
|
+
videoSources,
|
|
28499
|
+
className: "h-full"
|
|
28500
|
+
})
|
|
28501
|
+
},
|
|
28502
|
+
selectedLineId
|
|
28503
|
+
) : /* @__PURE__ */ jsx(
|
|
28504
|
+
motion.div,
|
|
28505
|
+
{
|
|
28506
|
+
initial: { opacity: 0 },
|
|
28507
|
+
animate: { opacity: 1 },
|
|
28508
|
+
transition: { duration: 0.3 },
|
|
28509
|
+
children: /* @__PURE__ */ jsx(NoWorkspaceData, { message: "No workspace data available. Select another line or check configurations." })
|
|
28510
|
+
}
|
|
28511
|
+
) })
|
|
28512
|
+
] })
|
|
28513
|
+
] }),
|
|
28514
|
+
/* @__PURE__ */ jsx(
|
|
28515
|
+
BreakNotificationPopup,
|
|
28516
|
+
{
|
|
28517
|
+
activeBreaks,
|
|
28518
|
+
lineNames,
|
|
28519
|
+
isVisible: !breaksLoading && !breaksError
|
|
28520
|
+
}
|
|
28521
|
+
)
|
|
28522
|
+
] })
|
|
27477
28523
|
}
|
|
27478
28524
|
);
|
|
27479
28525
|
}
|
|
27480
|
-
var AuthenticatedHomeView = withAuth(
|
|
28526
|
+
var AuthenticatedHomeView = withAuth(React19__default.memo(HomeView));
|
|
27481
28527
|
var HomeView_default = HomeView;
|
|
27482
28528
|
|
|
27483
28529
|
// src/views/kpi-detail-view.types.ts
|
|
@@ -28310,7 +29356,7 @@ var LineCard = ({ line, onClick }) => {
|
|
|
28310
29356
|
const { kpis, isLoading, error } = useLineKPIs({ lineId: line.id });
|
|
28311
29357
|
const shiftConfig = useShiftConfig();
|
|
28312
29358
|
const dateTimeConfig = useDateTimeConfig();
|
|
28313
|
-
const isOnTrack =
|
|
29359
|
+
const isOnTrack = React19__default.useMemo(() => {
|
|
28314
29360
|
if (!kpis) return null;
|
|
28315
29361
|
const currentTime = /* @__PURE__ */ new Date();
|
|
28316
29362
|
const timezone = dateTimeConfig.defaultTimezone || "Asia/Kolkata";
|
|
@@ -30335,7 +31381,7 @@ var BulkConfigureModal = ({
|
|
|
30335
31381
|
},
|
|
30336
31382
|
className: "w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm\n shadow-sm focus:border-blue-500 focus:ring-blue-500 \n transition-all duration-200 hover:border-blue-400",
|
|
30337
31383
|
min: "0",
|
|
30338
|
-
step: "
|
|
31384
|
+
step: "0.01",
|
|
30339
31385
|
placeholder: "Enter cycle time"
|
|
30340
31386
|
}
|
|
30341
31387
|
),
|
|
@@ -30456,6 +31502,343 @@ var BulkConfigureModal = ({
|
|
|
30456
31502
|
);
|
|
30457
31503
|
};
|
|
30458
31504
|
var BulkConfigureModal_default = BulkConfigureModal;
|
|
31505
|
+
var SKUModal = ({
|
|
31506
|
+
isOpen,
|
|
31507
|
+
onClose,
|
|
31508
|
+
onSave,
|
|
31509
|
+
editingSKU
|
|
31510
|
+
}) => {
|
|
31511
|
+
const config = useDashboardConfig();
|
|
31512
|
+
const defaultProductionTarget = config?.skuConfig?.defaultProductionTarget || 1e3;
|
|
31513
|
+
const [formData, setFormData] = useState({
|
|
31514
|
+
sku_id: "",
|
|
31515
|
+
production_target: defaultProductionTarget,
|
|
31516
|
+
attributes: {}
|
|
31517
|
+
});
|
|
31518
|
+
const [isSaving, setIsSaving] = useState(false);
|
|
31519
|
+
const [error, setError] = useState(null);
|
|
31520
|
+
useEffect(() => {
|
|
31521
|
+
if (editingSKU) {
|
|
31522
|
+
setFormData({
|
|
31523
|
+
sku_id: editingSKU.sku_id,
|
|
31524
|
+
production_target: editingSKU.production_target,
|
|
31525
|
+
attributes: editingSKU.attributes || {}
|
|
31526
|
+
});
|
|
31527
|
+
} else {
|
|
31528
|
+
setFormData({
|
|
31529
|
+
sku_id: "",
|
|
31530
|
+
production_target: defaultProductionTarget,
|
|
31531
|
+
attributes: {}
|
|
31532
|
+
});
|
|
31533
|
+
}
|
|
31534
|
+
setError(null);
|
|
31535
|
+
}, [editingSKU, defaultProductionTarget]);
|
|
31536
|
+
const handleSubmit = async (e) => {
|
|
31537
|
+
e.preventDefault();
|
|
31538
|
+
setError(null);
|
|
31539
|
+
if (!formData.sku_id.trim()) {
|
|
31540
|
+
setError("SKU ID is required");
|
|
31541
|
+
return;
|
|
31542
|
+
}
|
|
31543
|
+
if (formData.production_target <= 0) {
|
|
31544
|
+
setError("Production target must be greater than 0");
|
|
31545
|
+
return;
|
|
31546
|
+
}
|
|
31547
|
+
setIsSaving(true);
|
|
31548
|
+
try {
|
|
31549
|
+
const skuData = {
|
|
31550
|
+
sku_id: formData.sku_id.trim(),
|
|
31551
|
+
production_target: formData.production_target,
|
|
31552
|
+
attributes: formData.attributes,
|
|
31553
|
+
company_id: config?.entityConfig?.companyId || ""
|
|
31554
|
+
};
|
|
31555
|
+
await onSave(skuData);
|
|
31556
|
+
onClose();
|
|
31557
|
+
} catch (err) {
|
|
31558
|
+
setError(err instanceof Error ? err.message : "Failed to save SKU");
|
|
31559
|
+
} finally {
|
|
31560
|
+
setIsSaving(false);
|
|
31561
|
+
}
|
|
31562
|
+
};
|
|
31563
|
+
if (!isOpen) return null;
|
|
31564
|
+
return /* @__PURE__ */ jsx("div", { className: "fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50 p-4", children: /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-xl shadow-2xl max-w-md w-full transform transition-all", children: [
|
|
31565
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between p-6 border-b border-gray-200", children: [
|
|
31566
|
+
/* @__PURE__ */ jsx("h2", { className: "text-xl font-semibold text-gray-900", children: editingSKU ? "Edit SKU" : "Add New SKU" }),
|
|
31567
|
+
/* @__PURE__ */ jsx(
|
|
31568
|
+
"button",
|
|
31569
|
+
{
|
|
31570
|
+
onClick: onClose,
|
|
31571
|
+
className: "text-gray-400 hover:text-gray-600 transition-colors p-1 hover:bg-gray-100 rounded-lg",
|
|
31572
|
+
disabled: isSaving,
|
|
31573
|
+
children: /* @__PURE__ */ jsx(X, { className: "w-5 h-5" })
|
|
31574
|
+
}
|
|
31575
|
+
)
|
|
31576
|
+
] }),
|
|
31577
|
+
/* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "p-6", children: [
|
|
31578
|
+
error && /* @__PURE__ */ jsx("div", { className: "mb-4 p-3 bg-red-50 border border-red-200 text-red-700 rounded-lg text-sm", children: error }),
|
|
31579
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-5", children: [
|
|
31580
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
31581
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: "sku_id", className: "block text-sm font-medium text-gray-700 mb-2", children: [
|
|
31582
|
+
"SKU ID ",
|
|
31583
|
+
/* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
|
|
31584
|
+
] }),
|
|
31585
|
+
/* @__PURE__ */ jsx(
|
|
31586
|
+
"input",
|
|
31587
|
+
{
|
|
31588
|
+
type: "text",
|
|
31589
|
+
id: "sku_id",
|
|
31590
|
+
value: formData.sku_id,
|
|
31591
|
+
onChange: (e) => setFormData({ ...formData, sku_id: e.target.value }),
|
|
31592
|
+
className: "w-full px-4 py-2.5 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200",
|
|
31593
|
+
placeholder: "Enter SKU ID",
|
|
31594
|
+
disabled: isSaving || !!editingSKU,
|
|
31595
|
+
required: true
|
|
31596
|
+
}
|
|
31597
|
+
)
|
|
31598
|
+
] }),
|
|
31599
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
31600
|
+
/* @__PURE__ */ jsxs("label", { htmlFor: "production_target", className: "block text-sm font-medium text-gray-700 mb-2", children: [
|
|
31601
|
+
"Production Target ",
|
|
31602
|
+
/* @__PURE__ */ jsx("span", { className: "text-red-500", children: "*" })
|
|
31603
|
+
] }),
|
|
31604
|
+
/* @__PURE__ */ jsx(
|
|
31605
|
+
"input",
|
|
31606
|
+
{
|
|
31607
|
+
type: "number",
|
|
31608
|
+
id: "production_target",
|
|
31609
|
+
value: formData.production_target,
|
|
31610
|
+
onChange: (e) => setFormData({ ...formData, production_target: parseInt(e.target.value) || 0 }),
|
|
31611
|
+
className: "w-full px-4 py-2.5 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200",
|
|
31612
|
+
placeholder: "Enter production target",
|
|
31613
|
+
min: "1",
|
|
31614
|
+
disabled: isSaving,
|
|
31615
|
+
required: true
|
|
31616
|
+
}
|
|
31617
|
+
),
|
|
31618
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1.5 text-sm text-gray-500", children: "Units per day for this SKU" })
|
|
31619
|
+
] }),
|
|
31620
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
31621
|
+
/* @__PURE__ */ jsx("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Additional Attributes (Optional)" }),
|
|
31622
|
+
/* @__PURE__ */ jsx(
|
|
31623
|
+
"textarea",
|
|
31624
|
+
{
|
|
31625
|
+
value: JSON.stringify(formData.attributes, null, 2),
|
|
31626
|
+
onChange: (e) => {
|
|
31627
|
+
try {
|
|
31628
|
+
const parsed = JSON.parse(e.target.value);
|
|
31629
|
+
setFormData({ ...formData, attributes: parsed });
|
|
31630
|
+
} catch {
|
|
31631
|
+
}
|
|
31632
|
+
},
|
|
31633
|
+
className: "w-full px-4 py-2.5 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent font-mono text-sm transition-all duration-200",
|
|
31634
|
+
rows: 4,
|
|
31635
|
+
placeholder: '{"color": "red", "size": "large"}',
|
|
31636
|
+
disabled: isSaving
|
|
31637
|
+
}
|
|
31638
|
+
),
|
|
31639
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1.5 text-sm text-gray-500", children: "Enter valid JSON for additional SKU attributes" })
|
|
31640
|
+
] })
|
|
31641
|
+
] }),
|
|
31642
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-end space-x-3 mt-6 pt-4 border-t border-gray-200", children: [
|
|
31643
|
+
/* @__PURE__ */ jsx(
|
|
31644
|
+
"button",
|
|
31645
|
+
{
|
|
31646
|
+
type: "button",
|
|
31647
|
+
onClick: onClose,
|
|
31648
|
+
className: "px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 transition-all duration-200",
|
|
31649
|
+
disabled: isSaving,
|
|
31650
|
+
children: "Cancel"
|
|
31651
|
+
}
|
|
31652
|
+
),
|
|
31653
|
+
/* @__PURE__ */ jsx(
|
|
31654
|
+
"button",
|
|
31655
|
+
{
|
|
31656
|
+
type: "submit",
|
|
31657
|
+
className: "px-4 py-2 text-sm font-medium text-white bg-blue-600 border border-transparent rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-200 shadow-sm",
|
|
31658
|
+
disabled: isSaving,
|
|
31659
|
+
children: isSaving ? "Saving..." : editingSKU ? "Update" : "Create"
|
|
31660
|
+
}
|
|
31661
|
+
)
|
|
31662
|
+
] })
|
|
31663
|
+
] })
|
|
31664
|
+
] }) });
|
|
31665
|
+
};
|
|
31666
|
+
var SKUSelector = ({
|
|
31667
|
+
onSelect,
|
|
31668
|
+
selectedSKU,
|
|
31669
|
+
availableSKUs,
|
|
31670
|
+
className = "",
|
|
31671
|
+
lineId,
|
|
31672
|
+
disabled = false,
|
|
31673
|
+
required = false
|
|
31674
|
+
}) => {
|
|
31675
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
31676
|
+
const [searchTerm, setSearchTerm] = useState("");
|
|
31677
|
+
const dropdownRef = useRef(null);
|
|
31678
|
+
useEffect(() => {
|
|
31679
|
+
const handleClickOutside = (event) => {
|
|
31680
|
+
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
31681
|
+
setIsOpen(false);
|
|
31682
|
+
}
|
|
31683
|
+
};
|
|
31684
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
31685
|
+
return () => {
|
|
31686
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
31687
|
+
};
|
|
31688
|
+
}, []);
|
|
31689
|
+
const filteredSKUs = availableSKUs.filter(
|
|
31690
|
+
(sku) => sku.sku_id.toLowerCase().includes(searchTerm.toLowerCase()) || JSON.stringify(sku.attributes).toLowerCase().includes(searchTerm.toLowerCase())
|
|
31691
|
+
);
|
|
31692
|
+
const handleSelect = (sku) => {
|
|
31693
|
+
onSelect(sku);
|
|
31694
|
+
setIsOpen(false);
|
|
31695
|
+
setSearchTerm("");
|
|
31696
|
+
};
|
|
31697
|
+
return /* @__PURE__ */ jsxs("div", { className: `relative ${className}`, ref: dropdownRef, children: [
|
|
31698
|
+
/* @__PURE__ */ jsx(
|
|
31699
|
+
"button",
|
|
31700
|
+
{
|
|
31701
|
+
type: "button",
|
|
31702
|
+
onClick: () => !disabled && setIsOpen(!isOpen),
|
|
31703
|
+
className: `
|
|
31704
|
+
w-full px-3 py-2 text-left bg-white border rounded-md shadow-sm
|
|
31705
|
+
${disabled ? "bg-gray-100 cursor-not-allowed" : "hover:bg-gray-50 cursor-pointer"}
|
|
31706
|
+
${required && !selectedSKU ? "border-red-300" : "border-gray-300"}
|
|
31707
|
+
focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500
|
|
31708
|
+
`,
|
|
31709
|
+
disabled,
|
|
31710
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
31711
|
+
/* @__PURE__ */ jsx("span", { className: selectedSKU ? "text-gray-900" : "text-gray-500", children: selectedSKU ? /* @__PURE__ */ jsxs("div", { children: [
|
|
31712
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: selectedSKU.sku_id }),
|
|
31713
|
+
/* @__PURE__ */ jsxs("span", { className: "text-sm text-gray-500 ml-2", children: [
|
|
31714
|
+
"(Target: ",
|
|
31715
|
+
selectedSKU.production_target,
|
|
31716
|
+
" units/day)"
|
|
31717
|
+
] })
|
|
31718
|
+
] }) : "Select SKU" }),
|
|
31719
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: `w-4 h-4 text-gray-400 transition-transform ${isOpen ? "rotate-180" : ""}` })
|
|
31720
|
+
] })
|
|
31721
|
+
}
|
|
31722
|
+
),
|
|
31723
|
+
isOpen && /* @__PURE__ */ jsxs("div", { className: "absolute z-10 w-full mt-1 bg-white border border-gray-300 rounded-md shadow-lg", children: [
|
|
31724
|
+
/* @__PURE__ */ jsx("div", { className: "p-2 border-b", children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
31725
|
+
/* @__PURE__ */ jsx(Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-gray-400" }),
|
|
31726
|
+
/* @__PURE__ */ jsx(
|
|
31727
|
+
"input",
|
|
31728
|
+
{
|
|
31729
|
+
type: "text",
|
|
31730
|
+
value: searchTerm,
|
|
31731
|
+
onChange: (e) => setSearchTerm(e.target.value),
|
|
31732
|
+
placeholder: "Search SKUs...",
|
|
31733
|
+
className: "w-full pl-9 pr-3 py-2 text-sm border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500",
|
|
31734
|
+
onClick: (e) => e.stopPropagation()
|
|
31735
|
+
}
|
|
31736
|
+
)
|
|
31737
|
+
] }) }),
|
|
31738
|
+
/* @__PURE__ */ jsxs("div", { className: "max-h-60 overflow-y-auto", children: [
|
|
31739
|
+
!required && /* @__PURE__ */ jsx(
|
|
31740
|
+
"button",
|
|
31741
|
+
{
|
|
31742
|
+
onClick: () => handleSelect(null),
|
|
31743
|
+
className: "w-full px-3 py-2 text-left text-sm hover:bg-gray-100 focus:outline-none focus:bg-gray-100",
|
|
31744
|
+
children: /* @__PURE__ */ jsx("span", { className: "text-gray-500", children: "No SKU" })
|
|
31745
|
+
}
|
|
31746
|
+
),
|
|
31747
|
+
filteredSKUs.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-3 py-2 text-sm text-gray-500", children: "No SKUs found" }) : filteredSKUs.map((sku) => /* @__PURE__ */ jsx(
|
|
31748
|
+
"button",
|
|
31749
|
+
{
|
|
31750
|
+
onClick: () => handleSelect(sku),
|
|
31751
|
+
className: `
|
|
31752
|
+
w-full px-3 py-2 text-left text-sm hover:bg-gray-100 focus:outline-none focus:bg-gray-100
|
|
31753
|
+
${selectedSKU?.id === sku.id ? "bg-blue-50" : ""}
|
|
31754
|
+
`,
|
|
31755
|
+
children: /* @__PURE__ */ jsxs("div", { children: [
|
|
31756
|
+
/* @__PURE__ */ jsx("div", { className: "font-medium", children: sku.sku_id }),
|
|
31757
|
+
/* @__PURE__ */ jsxs("div", { className: "text-xs text-gray-500", children: [
|
|
31758
|
+
"Target: ",
|
|
31759
|
+
sku.production_target,
|
|
31760
|
+
" units/day",
|
|
31761
|
+
Object.keys(sku.attributes || {}).length > 0 && /* @__PURE__ */ jsxs("span", { className: "ml-2", children: [
|
|
31762
|
+
"\u2022 ",
|
|
31763
|
+
Object.entries(sku.attributes).map(([key, value]) => `${key}: ${value}`).join(", ")
|
|
31764
|
+
] })
|
|
31765
|
+
] })
|
|
31766
|
+
] })
|
|
31767
|
+
},
|
|
31768
|
+
sku.id
|
|
31769
|
+
))
|
|
31770
|
+
] })
|
|
31771
|
+
] })
|
|
31772
|
+
] });
|
|
31773
|
+
};
|
|
31774
|
+
var SKUList = ({
|
|
31775
|
+
skus,
|
|
31776
|
+
onEdit,
|
|
31777
|
+
onDelete,
|
|
31778
|
+
isLoading = false
|
|
31779
|
+
}) => {
|
|
31780
|
+
if (isLoading) {
|
|
31781
|
+
return /* @__PURE__ */ jsx("div", { className: "bg-white rounded-xl shadow-sm border border-gray-200 p-8", children: /* @__PURE__ */ jsxs("div", { className: "flex justify-center items-center", children: [
|
|
31782
|
+
/* @__PURE__ */ jsx("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600" }),
|
|
31783
|
+
/* @__PURE__ */ jsx("span", { className: "ml-3 text-gray-600", children: "Loading SKUs..." })
|
|
31784
|
+
] }) });
|
|
31785
|
+
}
|
|
31786
|
+
if (skus.length === 0) {
|
|
31787
|
+
return /* @__PURE__ */ jsx("div", { className: "bg-white rounded-xl shadow-sm border border-gray-200 p-12", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
31788
|
+
/* @__PURE__ */ jsx(Package, { className: "mx-auto h-12 w-12 text-gray-400" }),
|
|
31789
|
+
/* @__PURE__ */ jsx("h3", { className: "mt-2 text-lg font-medium text-gray-900", children: "No SKUs found" }),
|
|
31790
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-gray-500", children: "Get started by creating a new SKU for production planning." })
|
|
31791
|
+
] }) });
|
|
31792
|
+
}
|
|
31793
|
+
return /* @__PURE__ */ jsx("div", { className: "bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "overflow-x-auto", children: /* @__PURE__ */ jsxs("table", { className: "min-w-full divide-y divide-gray-200", children: [
|
|
31794
|
+
/* @__PURE__ */ jsx("thead", { className: "bg-gray-50", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
31795
|
+
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider", children: "SKU ID" }),
|
|
31796
|
+
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider", children: "Production Target" }),
|
|
31797
|
+
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider", children: "Attributes" }),
|
|
31798
|
+
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider", children: "Status" }),
|
|
31799
|
+
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider", children: "Created" }),
|
|
31800
|
+
/* @__PURE__ */ jsx("th", { scope: "col", className: "relative px-6 py-3", children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Actions" }) })
|
|
31801
|
+
] }) }),
|
|
31802
|
+
/* @__PURE__ */ jsx("tbody", { className: "bg-white divide-y divide-gray-200", children: skus.map((sku) => /* @__PURE__ */ jsxs("tr", { className: "hover:bg-gray-50 transition-colors duration-150", children: [
|
|
31803
|
+
/* @__PURE__ */ jsx("td", { className: "px-6 py-4 whitespace-nowrap", children: /* @__PURE__ */ jsx("div", { className: "text-sm font-semibold text-gray-900", children: sku.sku_id }) }),
|
|
31804
|
+
/* @__PURE__ */ jsx("td", { className: "px-6 py-4 whitespace-nowrap", children: /* @__PURE__ */ jsxs("div", { className: "text-sm font-medium text-gray-700", children: [
|
|
31805
|
+
sku.production_target.toLocaleString(),
|
|
31806
|
+
" units/day"
|
|
31807
|
+
] }) }),
|
|
31808
|
+
/* @__PURE__ */ jsx("td", { className: "px-6 py-4", children: /* @__PURE__ */ jsx("div", { className: "text-sm text-gray-500", children: Object.keys(sku.attributes || {}).length === 0 ? /* @__PURE__ */ jsx("span", { className: "text-gray-400", children: "No attributes" }) : /* @__PURE__ */ jsx("div", { className: "max-w-xs truncate", children: Object.entries(sku.attributes).map(([key, value], index) => /* @__PURE__ */ jsxs("span", { children: [
|
|
31809
|
+
index > 0 && ", ",
|
|
31810
|
+
/* @__PURE__ */ jsxs("span", { className: "font-medium", children: [
|
|
31811
|
+
key,
|
|
31812
|
+
":"
|
|
31813
|
+
] }),
|
|
31814
|
+
" ",
|
|
31815
|
+
String(value)
|
|
31816
|
+
] }, key)) }) }) }),
|
|
31817
|
+
/* @__PURE__ */ jsx("td", { className: "px-6 py-4 whitespace-nowrap", children: /* @__PURE__ */ jsx("span", { className: `inline-flex px-2 py-1 text-xs font-semibold rounded-full ${sku.is_active ? "bg-green-100 text-green-800" : "bg-gray-100 text-gray-800"}`, children: sku.is_active ? "Active" : "Inactive" }) }),
|
|
31818
|
+
/* @__PURE__ */ jsx("td", { className: "px-6 py-4 whitespace-nowrap text-sm text-gray-500", children: new Date(sku.created_at).toLocaleDateString() }),
|
|
31819
|
+
/* @__PURE__ */ jsxs("td", { className: "px-6 py-4 whitespace-nowrap text-right text-sm font-medium", children: [
|
|
31820
|
+
/* @__PURE__ */ jsx(
|
|
31821
|
+
"button",
|
|
31822
|
+
{
|
|
31823
|
+
onClick: () => onEdit(sku),
|
|
31824
|
+
className: "text-blue-600 hover:text-blue-800 mr-3 transition-colors duration-150 p-1 hover:bg-blue-50 rounded",
|
|
31825
|
+
title: "Edit SKU",
|
|
31826
|
+
children: /* @__PURE__ */ jsx(Edit2, { className: "w-4 h-4" })
|
|
31827
|
+
}
|
|
31828
|
+
),
|
|
31829
|
+
/* @__PURE__ */ jsx(
|
|
31830
|
+
"button",
|
|
31831
|
+
{
|
|
31832
|
+
onClick: () => onDelete(sku),
|
|
31833
|
+
className: "text-red-600 hover:text-red-800 transition-colors duration-150 p-1 hover:bg-red-50 rounded",
|
|
31834
|
+
title: "Delete SKU",
|
|
31835
|
+
children: /* @__PURE__ */ jsx(Trash2, { className: "w-4 h-4" })
|
|
31836
|
+
}
|
|
31837
|
+
)
|
|
31838
|
+
] })
|
|
31839
|
+
] }, sku.id)) })
|
|
31840
|
+
] }) }) });
|
|
31841
|
+
};
|
|
30459
31842
|
var TargetsViewUI = ({
|
|
30460
31843
|
isLoading,
|
|
30461
31844
|
lineWorkspaces,
|
|
@@ -30474,7 +31857,12 @@ var TargetsViewUI = ({
|
|
|
30474
31857
|
onShiftChange,
|
|
30475
31858
|
onSaveLine,
|
|
30476
31859
|
onToggleBulkConfigure,
|
|
30477
|
-
onBulkConfigure
|
|
31860
|
+
onBulkConfigure,
|
|
31861
|
+
// SKU props
|
|
31862
|
+
skuEnabled = false,
|
|
31863
|
+
skus = [],
|
|
31864
|
+
onUpdateSelectedSKU,
|
|
31865
|
+
skuRequired = false
|
|
30478
31866
|
}) => {
|
|
30479
31867
|
if (isLoading) {
|
|
30480
31868
|
return /* @__PURE__ */ jsx("div", { className: "flex h-screen bg-gray-50", children: /* @__PURE__ */ jsx("div", { className: "flex-1 flex items-center justify-center", children: /* @__PURE__ */ jsx(Loader2, { className: "w-8 h-8 animate-spin text-blue-600" }) }) });
|
|
@@ -30590,6 +31978,26 @@ var TargetsViewUI = ({
|
|
|
30590
31978
|
] })
|
|
30591
31979
|
] }) }),
|
|
30592
31980
|
line.isOpen && /* @__PURE__ */ jsxs("div", { id: `line-${lineId}-content`, className: "border-t border-gray-200", children: [
|
|
31981
|
+
skuEnabled && /* @__PURE__ */ jsx("div", { className: "px-6 py-4 border-b border-gray-200 bg-gray-50/50", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
|
|
31982
|
+
/* @__PURE__ */ jsx("label", { htmlFor: `sku-${lineId}`, className: "text-sm font-medium text-gray-700", children: "Select SKU:" }),
|
|
31983
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 max-w-md", children: /* @__PURE__ */ jsx(
|
|
31984
|
+
SKUSelector,
|
|
31985
|
+
{
|
|
31986
|
+
onSelect: (sku) => onUpdateSelectedSKU?.(lineId, sku),
|
|
31987
|
+
selectedSKU: line.selectedSKU || null,
|
|
31988
|
+
availableSKUs: skus,
|
|
31989
|
+
lineId,
|
|
31990
|
+
required: skuRequired,
|
|
31991
|
+
className: "w-full"
|
|
31992
|
+
}
|
|
31993
|
+
) }),
|
|
31994
|
+
line.selectedSKU && /* @__PURE__ */ jsxs("div", { className: "text-sm text-gray-600", children: [
|
|
31995
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "Production Target:" }),
|
|
31996
|
+
" ",
|
|
31997
|
+
line.selectedSKU.production_target.toLocaleString(),
|
|
31998
|
+
" units/day"
|
|
31999
|
+
] })
|
|
32000
|
+
] }) }),
|
|
30593
32001
|
/* @__PURE__ */ jsx("div", { className: "px-6 py-3 bg-gray-50 border-b border-gray-200", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-12 gap-6 text-sm font-medium text-gray-600", children: [
|
|
30594
32002
|
/* @__PURE__ */ jsx("div", { className: "col-span-2", children: "Workspace" }),
|
|
30595
32003
|
/* @__PURE__ */ jsx("div", { className: "col-span-2", children: "Action Type" }),
|
|
@@ -30636,7 +32044,7 @@ var TargetsViewUI = ({
|
|
|
30636
32044
|
onChange: (e) => onUpdateWorkspaceTarget(lineId, workspace.id, "targetCycleTime", Number(e.target.value) || ""),
|
|
30637
32045
|
className: "block w-full rounded-lg border border-gray-300 bg-white px-3 py-2 text-sm\n shadow-sm focus:border-blue-500 focus:ring-blue-500 \n transition-all duration-200 hover:border-gray-400",
|
|
30638
32046
|
min: "0",
|
|
30639
|
-
step: "
|
|
32047
|
+
step: "0.01",
|
|
30640
32048
|
placeholder: "Enter cycle time"
|
|
30641
32049
|
}
|
|
30642
32050
|
) }),
|
|
@@ -30727,6 +32135,9 @@ var TargetsView = ({
|
|
|
30727
32135
|
const supabase = useSupabase();
|
|
30728
32136
|
const auth = useAuth();
|
|
30729
32137
|
userId || auth?.user?.id;
|
|
32138
|
+
const dashboardConfig = useDashboardConfig();
|
|
32139
|
+
const { skus, isLoading: skusLoading } = useSKUs(companyId);
|
|
32140
|
+
const skuEnabled = dashboardConfig?.skuConfig?.enabled || false;
|
|
30730
32141
|
useEffect(() => {
|
|
30731
32142
|
const fetchLineDetails = async () => {
|
|
30732
32143
|
if (!supabase || lineIds.length === 0) return;
|
|
@@ -31094,6 +32505,41 @@ var TargetsView = ({
|
|
|
31094
32505
|
}
|
|
31095
32506
|
}));
|
|
31096
32507
|
};
|
|
32508
|
+
const updateSelectedSKU = (lineId, sku) => {
|
|
32509
|
+
setLineWorkspaces((prev) => ({
|
|
32510
|
+
...prev,
|
|
32511
|
+
[lineId]: {
|
|
32512
|
+
...prev[lineId],
|
|
32513
|
+
selectedSKU: sku,
|
|
32514
|
+
productId: sku?.sku_id || prev[lineId].productId
|
|
32515
|
+
// Update productId with SKU ID
|
|
32516
|
+
}
|
|
32517
|
+
}));
|
|
32518
|
+
if (sku && sku.production_target > 0) {
|
|
32519
|
+
const lineData = lineWorkspaces[lineId];
|
|
32520
|
+
const workspaceCount = lineData.workspaces.length;
|
|
32521
|
+
if (workspaceCount > 0) {
|
|
32522
|
+
const targetPerWorkspace = Math.floor(sku.production_target / workspaceCount);
|
|
32523
|
+
const pphPerWorkspace = calculatePPH(
|
|
32524
|
+
lineData.shiftHours > 0 ? lineData.shiftHours * 3600 / targetPerWorkspace : 0,
|
|
32525
|
+
lineData.breaks,
|
|
32526
|
+
lineData.shiftHours
|
|
32527
|
+
);
|
|
32528
|
+
setLineWorkspaces((prev) => ({
|
|
32529
|
+
...prev,
|
|
32530
|
+
[lineId]: {
|
|
32531
|
+
...prev[lineId],
|
|
32532
|
+
workspaces: prev[lineId].workspaces.map((ws) => ({
|
|
32533
|
+
...ws,
|
|
32534
|
+
targetDayOutput: targetPerWorkspace,
|
|
32535
|
+
targetPPH: pphPerWorkspace,
|
|
32536
|
+
targetCycleTime: lineData.shiftHours > 0 ? parseFloat((lineData.shiftHours * 3600 / targetPerWorkspace).toFixed(2)) : ""
|
|
32537
|
+
}))
|
|
32538
|
+
}
|
|
32539
|
+
}));
|
|
32540
|
+
}
|
|
32541
|
+
}
|
|
32542
|
+
};
|
|
31097
32543
|
const updateWorkspaceTarget = (lineId, workspaceId, field, value) => {
|
|
31098
32544
|
setLineWorkspaces((prev) => {
|
|
31099
32545
|
const shiftHours = prev[lineId].shiftHours;
|
|
@@ -31226,6 +32672,11 @@ var TargetsView = ({
|
|
|
31226
32672
|
return;
|
|
31227
32673
|
}
|
|
31228
32674
|
console.log(`[handleSaveLine] factoryId for ${lineId}: ${lineDataToSave.factoryId}`);
|
|
32675
|
+
if (skuEnabled && dashboardConfig?.skuConfig?.requireSKUSelection && !lineDataToSave.selectedSKU) {
|
|
32676
|
+
console.log(`[handleSaveLine] Exiting: SKU selection required but not selected for lineId: ${lineId}`);
|
|
32677
|
+
toast.error("Please select a SKU before saving.");
|
|
32678
|
+
return;
|
|
32679
|
+
}
|
|
31229
32680
|
const currentFactoryId = lineDataToSave.factoryId;
|
|
31230
32681
|
const currentDate = getOperationalDate();
|
|
31231
32682
|
console.log(`[handleSaveLine] currentDate: ${currentDate}, selectedShift: ${selectedShift}`);
|
|
@@ -31239,8 +32690,9 @@ var TargetsView = ({
|
|
|
31239
32690
|
ideal_cycle_time: Number(ws.targetCycleTime) || 0,
|
|
31240
32691
|
total_day_output: Number(ws.targetDayOutput) || 0,
|
|
31241
32692
|
action_name: ws.actionType === "assembly" ? ACTION_NAMES.ASSEMBLY : ACTION_NAMES.PACKAGING,
|
|
31242
|
-
updated_by: currentEffectiveUserId
|
|
32693
|
+
updated_by: currentEffectiveUserId,
|
|
31243
32694
|
// Use the potentially hardcoded ID
|
|
32695
|
+
...skuEnabled && lineDataToSave.selectedSKU ? { sku_id: lineDataToSave.selectedSKU.id } : {}
|
|
31244
32696
|
}));
|
|
31245
32697
|
console.log(`[handleSaveLine] workspaceThresholdUpdates for ${lineId}:`, workspaceThresholdUpdates);
|
|
31246
32698
|
await workspaceService.updateActionThresholds(workspaceThresholdUpdates);
|
|
@@ -31252,7 +32704,8 @@ var TargetsView = ({
|
|
|
31252
32704
|
shift_id: selectedShift,
|
|
31253
32705
|
product_code: lineDataToSave.productId,
|
|
31254
32706
|
threshold_day_output: lineDataToSave.workspaces.reduce((acc, ws) => acc + (Number(ws.targetDayOutput) || 0), 0),
|
|
31255
|
-
threshold_pph: lineDataToSave.workspaces.reduce((acc, ws) => acc + (Number(ws.targetPPH) || 0), 0)
|
|
32707
|
+
threshold_pph: lineDataToSave.workspaces.reduce((acc, ws) => acc + (Number(ws.targetPPH) || 0), 0),
|
|
32708
|
+
...skuEnabled && lineDataToSave.selectedSKU ? { sku_id: lineDataToSave.selectedSKU.id } : {}
|
|
31256
32709
|
};
|
|
31257
32710
|
console.log(`[handleSaveLine] lineThresholdData for upsert on ${lineId}:`, lineThresholdData);
|
|
31258
32711
|
const { error: lineUpsertError } = await supabase.from("line_thresholds").upsert(lineThresholdData, { onConflict: "factory_id,line_id,date,shift_id" });
|
|
@@ -31347,7 +32800,7 @@ var TargetsView = ({
|
|
|
31347
32800
|
return /* @__PURE__ */ jsx(
|
|
31348
32801
|
TargetsViewUI_default,
|
|
31349
32802
|
{
|
|
31350
|
-
isLoading,
|
|
32803
|
+
isLoading: isLoading || skusLoading,
|
|
31351
32804
|
lineWorkspaces,
|
|
31352
32805
|
lineNames,
|
|
31353
32806
|
savingLines,
|
|
@@ -31364,7 +32817,11 @@ var TargetsView = ({
|
|
|
31364
32817
|
onShiftChange: handleShiftChange,
|
|
31365
32818
|
onSaveLine: handleSaveLine,
|
|
31366
32819
|
onToggleBulkConfigure: handleToggleBulkConfigure,
|
|
31367
|
-
onBulkConfigure: handleBulkConfigure
|
|
32820
|
+
onBulkConfigure: handleBulkConfigure,
|
|
32821
|
+
skuEnabled,
|
|
32822
|
+
skus,
|
|
32823
|
+
onUpdateSelectedSKU: updateSelectedSKU,
|
|
32824
|
+
skuRequired: dashboardConfig?.skuConfig?.requireSKUSelection || false
|
|
31368
32825
|
}
|
|
31369
32826
|
);
|
|
31370
32827
|
};
|
|
@@ -31623,7 +33080,43 @@ var WorkspaceDetailView = ({
|
|
|
31623
33080
|
}
|
|
31624
33081
|
};
|
|
31625
33082
|
if (loading) {
|
|
31626
|
-
return /* @__PURE__ */ jsx(
|
|
33083
|
+
return /* @__PURE__ */ jsx(
|
|
33084
|
+
motion.div,
|
|
33085
|
+
{
|
|
33086
|
+
className: "min-h-screen bg-slate-50",
|
|
33087
|
+
initial: { opacity: 0 },
|
|
33088
|
+
animate: { opacity: 1 },
|
|
33089
|
+
transition: { duration: 0.3 },
|
|
33090
|
+
children: /* @__PURE__ */ jsxs("div", { className: "min-h-screen w-full flex flex-col bg-slate-50", children: [
|
|
33091
|
+
/* @__PURE__ */ jsx("header", { className: "sticky top-0 z-10 px-2 sm:px-2.5 lg:px-3 py-1.5 sm:py-2 lg:py-3 flex flex-col shadow-sm bg-white", children: /* @__PURE__ */ jsxs("div", { className: "relative flex items-center", children: [
|
|
33092
|
+
/* @__PURE__ */ jsx("div", { className: "absolute left-0 animate-pulse", children: /* @__PURE__ */ jsx("div", { className: "h-8 w-20 bg-gray-200 rounded" }) }),
|
|
33093
|
+
/* @__PURE__ */ jsx("div", { className: "absolute left-1/2 transform -translate-x-1/2 animate-pulse", children: /* @__PURE__ */ jsx("div", { className: "h-6 w-40 bg-gray-200 rounded" }) }),
|
|
33094
|
+
/* @__PURE__ */ jsx("div", { className: "w-full h-8" })
|
|
33095
|
+
] }) }),
|
|
33096
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 p-4 sm:p-6 lg:p-8", children: [
|
|
33097
|
+
/* @__PURE__ */ jsx("div", { className: "mb-6", children: /* @__PURE__ */ jsxs("div", { className: "flex space-x-4 justify-center animate-pulse", children: [
|
|
33098
|
+
/* @__PURE__ */ jsx("div", { className: "h-10 w-32 bg-gray-200 rounded-lg" }),
|
|
33099
|
+
/* @__PURE__ */ jsx("div", { className: "h-10 w-32 bg-gray-200 rounded-lg" }),
|
|
33100
|
+
/* @__PURE__ */ jsx("div", { className: "h-10 w-32 bg-gray-200 rounded-lg" })
|
|
33101
|
+
] }) }),
|
|
33102
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4 mb-6", children: [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsx("div", { className: "bg-white rounded-lg p-4 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "animate-pulse", children: [
|
|
33103
|
+
/* @__PURE__ */ jsx("div", { className: "h-4 w-20 bg-gray-200 rounded mb-2" }),
|
|
33104
|
+
/* @__PURE__ */ jsx("div", { className: "h-8 w-16 bg-gray-200 rounded" })
|
|
33105
|
+
] }) }, i)) }),
|
|
33106
|
+
/* @__PURE__ */ jsx("div", { className: "bg-white rounded-lg p-6 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "animate-pulse", children: [
|
|
33107
|
+
/* @__PURE__ */ jsx("div", { className: "h-6 w-40 bg-gray-200 rounded mb-4" }),
|
|
33108
|
+
/* @__PURE__ */ jsx("div", { className: "h-64 bg-gray-100 rounded relative overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "bg-white/80 rounded-lg p-4 shadow-sm", children: [
|
|
33109
|
+
/* @__PURE__ */ jsxs("svg", { className: "animate-spin h-8 w-8 text-blue-500", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
|
|
33110
|
+
/* @__PURE__ */ jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
33111
|
+
/* @__PURE__ */ jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
|
|
33112
|
+
] }),
|
|
33113
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-gray-600 mt-2", children: "Loading chart data..." })
|
|
33114
|
+
] }) }) })
|
|
33115
|
+
] }) })
|
|
33116
|
+
] })
|
|
33117
|
+
] })
|
|
33118
|
+
}
|
|
33119
|
+
);
|
|
31627
33120
|
}
|
|
31628
33121
|
if (error) {
|
|
31629
33122
|
return /* @__PURE__ */ jsxs("div", { className: "min-h-screen p-8 bg-slate-50", children: [
|
|
@@ -32063,6 +33556,144 @@ var WorkspaceDetailView = ({
|
|
|
32063
33556
|
};
|
|
32064
33557
|
var WrappedComponent = withAuth(WorkspaceDetailView);
|
|
32065
33558
|
var WorkspaceDetailView_default = WrappedComponent;
|
|
33559
|
+
var SKUManagementView = () => {
|
|
33560
|
+
const config = useDashboardConfig();
|
|
33561
|
+
const companyId = config?.entityConfig?.companyId || "";
|
|
33562
|
+
const router = useRouter();
|
|
33563
|
+
const { skus, isLoading, error, refetch } = useSKUs(companyId);
|
|
33564
|
+
const [isModalOpen, setIsModalOpen] = useState(false);
|
|
33565
|
+
const [editingSKU, setEditingSKU] = useState(null);
|
|
33566
|
+
const [deleteConfirmSKU, setDeleteConfirmSKU] = useState(null);
|
|
33567
|
+
useEffect(() => {
|
|
33568
|
+
trackCoreEvent("SKU Management Page Viewed");
|
|
33569
|
+
}, []);
|
|
33570
|
+
const handleCreateOrUpdate = async (skuData) => {
|
|
33571
|
+
try {
|
|
33572
|
+
if (editingSKU) {
|
|
33573
|
+
await skuService.updateSKU(editingSKU.id, {
|
|
33574
|
+
production_target: skuData.production_target,
|
|
33575
|
+
attributes: skuData.attributes
|
|
33576
|
+
});
|
|
33577
|
+
trackCoreEvent("SKU Updated", {
|
|
33578
|
+
sku_id: editingSKU.sku_id,
|
|
33579
|
+
production_target: skuData.production_target
|
|
33580
|
+
});
|
|
33581
|
+
} else {
|
|
33582
|
+
const exists = await skuService.checkSKUExists(companyId, skuData.sku_id);
|
|
33583
|
+
if (exists) {
|
|
33584
|
+
throw new Error("SKU ID already exists");
|
|
33585
|
+
}
|
|
33586
|
+
await skuService.createSKU(skuData);
|
|
33587
|
+
trackCoreEvent("SKU Created", {
|
|
33588
|
+
sku_id: skuData.sku_id,
|
|
33589
|
+
production_target: skuData.production_target
|
|
33590
|
+
});
|
|
33591
|
+
}
|
|
33592
|
+
setIsModalOpen(false);
|
|
33593
|
+
setEditingSKU(null);
|
|
33594
|
+
refetch();
|
|
33595
|
+
} catch (error2) {
|
|
33596
|
+
console.error("Error saving SKU:", error2);
|
|
33597
|
+
throw error2;
|
|
33598
|
+
}
|
|
33599
|
+
};
|
|
33600
|
+
const handleEdit = (sku) => {
|
|
33601
|
+
setEditingSKU(sku);
|
|
33602
|
+
setIsModalOpen(true);
|
|
33603
|
+
};
|
|
33604
|
+
const handleDelete = async (sku) => {
|
|
33605
|
+
if (deleteConfirmSKU?.id === sku.id) {
|
|
33606
|
+
try {
|
|
33607
|
+
await skuService.deleteSKU(sku.id);
|
|
33608
|
+
trackCoreEvent("SKU Deleted", { sku_id: sku.sku_id });
|
|
33609
|
+
setDeleteConfirmSKU(null);
|
|
33610
|
+
refetch();
|
|
33611
|
+
} catch (error2) {
|
|
33612
|
+
console.error("Error deleting SKU:", error2);
|
|
33613
|
+
}
|
|
33614
|
+
} else {
|
|
33615
|
+
setDeleteConfirmSKU(sku);
|
|
33616
|
+
setTimeout(() => setDeleteConfirmSKU(null), 3e3);
|
|
33617
|
+
}
|
|
33618
|
+
};
|
|
33619
|
+
const handleAddNew = () => {
|
|
33620
|
+
setEditingSKU(null);
|
|
33621
|
+
setIsModalOpen(true);
|
|
33622
|
+
};
|
|
33623
|
+
const handleBack = () => {
|
|
33624
|
+
router.push("/");
|
|
33625
|
+
};
|
|
33626
|
+
if (!config?.skuConfig?.enabled) {
|
|
33627
|
+
return /* @__PURE__ */ jsx("div", { className: "min-h-screen bg-slate-50 flex items-center justify-center", children: /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
|
|
33628
|
+
/* @__PURE__ */ jsx(Package, { className: "mx-auto h-12 w-12 text-gray-400" }),
|
|
33629
|
+
/* @__PURE__ */ jsx("h3", { className: "mt-2 text-sm font-medium text-gray-900", children: "SKU Management Disabled" }),
|
|
33630
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-gray-500", children: "SKU management is not enabled for this workspace." })
|
|
33631
|
+
] }) });
|
|
33632
|
+
}
|
|
33633
|
+
return /* @__PURE__ */ jsxs("div", { className: "min-h-screen bg-slate-50", children: [
|
|
33634
|
+
/* @__PURE__ */ jsx("div", { className: "sticky top-0 z-10 bg-white border-b border-gray-200/80 shadow-sm", children: /* @__PURE__ */ jsx("div", { className: "px-4 sm:px-8 py-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center relative", children: [
|
|
33635
|
+
/* @__PURE__ */ jsxs(
|
|
33636
|
+
"button",
|
|
33637
|
+
{
|
|
33638
|
+
onClick: handleBack,
|
|
33639
|
+
className: "absolute left-0 flex items-center gap-2 text-gray-600 hover:text-gray-900 transition-colors",
|
|
33640
|
+
children: [
|
|
33641
|
+
/* @__PURE__ */ jsx(ArrowLeft, { className: "h-5 w-5" }),
|
|
33642
|
+
/* @__PURE__ */ jsx("span", { children: "Back" })
|
|
33643
|
+
]
|
|
33644
|
+
}
|
|
33645
|
+
),
|
|
33646
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 text-center mx-auto", children: [
|
|
33647
|
+
/* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold text-gray-900", children: "SKU Management" }),
|
|
33648
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-gray-500", children: "Manage Stock Keeping Units (SKUs) for production planning" })
|
|
33649
|
+
] }),
|
|
33650
|
+
/* @__PURE__ */ jsxs(
|
|
33651
|
+
"button",
|
|
33652
|
+
{
|
|
33653
|
+
onClick: handleAddNew,
|
|
33654
|
+
className: "absolute right-0 inline-flex items-center px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-all duration-200 shadow-sm",
|
|
33655
|
+
children: [
|
|
33656
|
+
/* @__PURE__ */ jsx(Plus, { className: "w-4 h-4 mr-2" }),
|
|
33657
|
+
"Add SKU"
|
|
33658
|
+
]
|
|
33659
|
+
}
|
|
33660
|
+
)
|
|
33661
|
+
] }) }) }),
|
|
33662
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-auto", children: /* @__PURE__ */ jsxs("div", { className: "px-4 sm:px-8 py-6", children: [
|
|
33663
|
+
/* @__PURE__ */ jsx("div", { className: "mb-6 bg-gradient-to-r from-blue-50 to-blue-50/50 p-4 rounded-xl border border-blue-100", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-blue-700 font-medium", children: "Create and manage SKUs with production targets. These will be available for selection in the production targets page." }) }),
|
|
33664
|
+
error ? /* @__PURE__ */ jsxs("div", { className: "bg-red-50 border border-red-200 text-red-700 p-4 rounded-lg", children: [
|
|
33665
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: "Error loading SKUs" }),
|
|
33666
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm mt-1", children: error.message })
|
|
33667
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
33668
|
+
/* @__PURE__ */ jsx(
|
|
33669
|
+
SKUList,
|
|
33670
|
+
{
|
|
33671
|
+
skus,
|
|
33672
|
+
onEdit: handleEdit,
|
|
33673
|
+
onDelete: handleDelete,
|
|
33674
|
+
isLoading
|
|
33675
|
+
}
|
|
33676
|
+
),
|
|
33677
|
+
deleteConfirmSKU && /* @__PURE__ */ jsx("div", { className: "mt-4 bg-yellow-50 border border-yellow-200 text-yellow-800 p-4 rounded-lg", children: /* @__PURE__ */ jsxs("p", { className: "text-sm", children: [
|
|
33678
|
+
"Click delete again to confirm deletion of SKU: ",
|
|
33679
|
+
/* @__PURE__ */ jsx("strong", { children: deleteConfirmSKU.sku_id })
|
|
33680
|
+
] }) })
|
|
33681
|
+
] })
|
|
33682
|
+
] }) }),
|
|
33683
|
+
/* @__PURE__ */ jsx(
|
|
33684
|
+
SKUModal,
|
|
33685
|
+
{
|
|
33686
|
+
isOpen: isModalOpen,
|
|
33687
|
+
onClose: () => {
|
|
33688
|
+
setIsModalOpen(false);
|
|
33689
|
+
setEditingSKU(null);
|
|
33690
|
+
},
|
|
33691
|
+
onSave: handleCreateOrUpdate,
|
|
33692
|
+
editingSKU
|
|
33693
|
+
}
|
|
33694
|
+
)
|
|
33695
|
+
] });
|
|
33696
|
+
};
|
|
32066
33697
|
var S3Service = class {
|
|
32067
33698
|
constructor(config) {
|
|
32068
33699
|
this.s3Client = null;
|
|
@@ -32301,4 +33932,4 @@ var S3Service = class {
|
|
|
32301
33932
|
}
|
|
32302
33933
|
};
|
|
32303
33934
|
|
|
32304
|
-
export { ACTION_NAMES, AIAgentView_default as AIAgentView, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedTargetsView, BarChart, BaseHistoryCalendar, BottlenecksContent, BreakNotificationPopup, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, EmptyStateMessage, FactoryView_default as FactoryView, GaugeChart, GridComponentsPlaceholder, Header, HelpView_default as HelpView, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, ISTTimer_default as ISTTimer, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend6 as Legend, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LiveTimer, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSpinner_default as LoadingSpinner, LoginPage, LoginView_default as LoginView, MainLayout, MetricCard_default as MetricCard, NoWorkspaceData, OptifyeAgentClient, OutputProgressChart, PageHeader, PieChart4 as PieChart, ProfileView_default as ProfileView, RegistryProvider, S3Service, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SingleVideoStream_default as SingleVideoStream, Skeleton, SlackAPI, SupabaseProvider, TargetWorkspaceGrid, TargetsView_default as TargetsView, ThreadSidebar, TimeDisplay_default as TimeDisplay, TimePickerDropdown, VideoCard, VideoGridView, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, apiUtils, authCoreService, authOTPService, authRateLimitService, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearWorkspaceDisplayNamesCache, cn, createStreamProxyHandler, createSupabaseClient, createThrottledReload, dashboardService, deleteThread, forceRefreshWorkspaceDisplayNames, formatDateInZone, formatDateTimeInZone, formatISTDate, formatIdleTime, formatTimeInZone, fromUrlFriendlyName, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAnonClient, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getCurrentShift, getCurrentTimeInZone, getDashboardHeaderTimeInZone, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultTabForWorkspace, getManufacturingInsights, getMetricsTablePrefix, getOperationalDate, getS3SignedUrl, getS3VideoSrc, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getThreadMessages, getUserThreads, getUserThreadsPaginated, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, identifyCoreUser, initializeCoreMixpanel, isTransitionPeriod, isValidLineInfoPayload, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, mergeWithDefaultConfig, optifyeAgentClient, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, s3VideoPreloader, storeWorkspaceMapping, streamProxyConfig, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, updateThreadTitle, useActiveBreaks, useAllWorkspaceMetrics, useAnalyticsConfig, useAuth, useAuthConfig, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineWorkspaceMetrics, useMessages, useMetrics, useNavigation, useOverrides, usePageOverride, useRealtimeLineMetrics, useRegistry, useShiftConfig, useShifts, useSupabase, useSupabaseClient, useTargets, useTheme, useThemeConfig, useThreads, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, videoPreloader, whatsappService, withAuth, withRegistry, workspaceService };
|
|
33935
|
+
export { ACTION_NAMES, AIAgentView_default as AIAgentView, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedTargetsView, BarChart, BaseHistoryCalendar, BottlenecksContent, BreakNotificationPopup, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, EmptyStateMessage, FactoryView_default as FactoryView, GaugeChart, GridComponentsPlaceholder, Header, HelpView_default as HelpView, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, ISTTimer_default as ISTTimer, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend6 as Legend, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingSpinner_default as LoadingSpinner, LoadingState, LoginPage, LoginView_default as LoginView, MainLayout, MetricCard_default as MetricCard, NoWorkspaceData, OptifyeAgentClient, OutputProgressChart, PageHeader, PieChart4 as PieChart, ProfileView_default as ProfileView, RegistryProvider, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SingleVideoStream_default as SingleVideoStream, Skeleton, SlackAPI, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, TargetWorkspaceGrid, TargetsView_default as TargetsView, ThreadSidebar, TimeDisplay_default as TimeDisplay, TimePickerDropdown, VideoCard, VideoGridView, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, apiUtils, authCoreService, authOTPService, authRateLimitService, cacheService, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearWorkspaceDisplayNamesCache, cn, createStreamProxyHandler, createSupabaseClient, createThrottledReload, dashboardService, deleteThread, forceRefreshWorkspaceDisplayNames, formatDateInZone, formatDateTimeInZone, formatISTDate, formatIdleTime, formatTimeInZone, fromUrlFriendlyName, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAnonClient, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getCurrentShift, getCurrentTimeInZone, getDashboardHeaderTimeInZone, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultTabForWorkspace, getManufacturingInsights, getMetricsTablePrefix, getOperationalDate, getS3SignedUrl, getS3VideoSrc, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUserThreads, getUserThreadsPaginated, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, identifyCoreUser, initializeCoreMixpanel, isTransitionPeriod, isValidLineInfoPayload, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, mergeWithDefaultConfig, optifyeAgentClient, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetSubscriptionManager, s3VideoPreloader, skuService, storeWorkspaceMapping, streamProxyConfig, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, updateThreadTitle, useActiveBreaks, useAllWorkspaceMetrics, useAnalyticsConfig, useAuth, useAuthConfig, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineWorkspaceMetrics, useMessages, useMetrics, useNavigation, useOverrides, usePageOverride, useRealtimeLineMetrics, useRegistry, useSKUs, useShiftConfig, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useTargets, useTheme, useThemeConfig, useThreads, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, videoPreloader, whatsappService, withAuth, withRegistry, workspaceService };
|