@optifye/dashboard-core 6.10.11 → 6.10.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -17,7 +17,7 @@ import { BarChart as BarChart$1, CartesianGrid, XAxis, YAxis, ReferenceLine, Too
17
17
  import { Slot } from '@radix-ui/react-slot';
18
18
  import * as SelectPrimitive from '@radix-ui/react-select';
19
19
  import { DayPicker, useNavigation as useNavigation$1 } from 'react-day-picker';
20
- import { XMarkIcon, ArrowRightIcon, HomeIcon, TrophyIcon, ChartBarIcon, LightBulbIcon, AdjustmentsHorizontalIcon, ClockIcon, UsersIcon, TicketIcon, CubeIcon, SparklesIcon, QuestionMarkCircleIcon, HeartIcon, UserCircleIcon, ExclamationCircleIcon, EnvelopeIcon, DocumentTextIcon, ChevronUpIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, Bars3Icon, CheckCircleIcon, ChatBubbleLeftRightIcon, ArrowLeftIcon, XCircleIcon, PlayCircleIcon, InformationCircleIcon } from '@heroicons/react/24/outline';
20
+ import { XMarkIcon, ArrowRightIcon, HomeIcon, TrophyIcon, ChartBarIcon, LightBulbIcon, AdjustmentsHorizontalIcon, ClockIcon, UsersIcon, TicketIcon, CubeIcon, SparklesIcon, QuestionMarkCircleIcon, HeartIcon, UserCircleIcon, ExclamationCircleIcon, EnvelopeIcon, DocumentTextIcon, ChevronUpIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, Bars3Icon, CheckCircleIcon, ChatBubbleLeftRightIcon, ArrowLeftIcon, XCircleIcon, CalendarIcon, InformationCircleIcon, PlayCircleIcon } from '@heroicons/react/24/outline';
21
21
  import { CheckIcon } from '@heroicons/react/24/solid';
22
22
  import html2canvas from 'html2canvas';
23
23
  import jsPDF, { jsPDF as jsPDF$1 } from 'jspdf';
@@ -529,6 +529,84 @@ function getCurrentTimeInZone(timezone, formatString) {
529
529
  }
530
530
  return now2;
531
531
  }
532
+ var pad2 = (value) => String(value).padStart(2, "0");
533
+ var buildDateKey = (year, monthIndex, day) => {
534
+ return `${year}-${pad2(monthIndex + 1)}-${pad2(day)}`;
535
+ };
536
+ var getDateKeyFromDate = (date) => {
537
+ return date.toISOString().split("T")[0];
538
+ };
539
+ var parseDateKeyToDate = (dateKey) => {
540
+ const [year, month, day] = dateKey.split("-").map(Number);
541
+ return new Date(year, month - 1, day);
542
+ };
543
+ var formatDateKeyForDisplay = (dateKey, formatStr = "MMM d, yyyy") => {
544
+ return format(parseDateKeyToDate(dateKey), formatStr);
545
+ };
546
+ var getMonthKeyBounds = (year, monthIndex) => {
547
+ const startKey = buildDateKey(year, monthIndex, 1);
548
+ const lastDay = new Date(year, monthIndex + 1, 0).getDate();
549
+ const endKey = buildDateKey(year, monthIndex, lastDay);
550
+ return { startKey, endKey };
551
+ };
552
+ var normalizeDateKeyRange = (startKey, endKey, minKey, maxKey) => {
553
+ const clampedStart = startKey < minKey ? minKey : startKey > maxKey ? maxKey : startKey;
554
+ const clampedEnd = endKey < minKey ? minKey : endKey > maxKey ? maxKey : endKey;
555
+ if (clampedStart <= clampedEnd) {
556
+ return { startKey: clampedStart, endKey: clampedEnd };
557
+ }
558
+ return { startKey: clampedEnd, endKey: clampedStart };
559
+ };
560
+ var isFullMonthRange = (range, year, monthIndex) => {
561
+ const bounds = getMonthKeyBounds(year, monthIndex);
562
+ return range.startKey === bounds.startKey && range.endKey === bounds.endKey;
563
+ };
564
+ var getMonthWeekRanges = (year, monthIndex, timezone, maxKey) => {
565
+ const totalDays = new Date(year, monthIndex + 1, 0).getDate();
566
+ const ranges = [];
567
+ let currentStartDay = 1;
568
+ for (let day = 1; day <= totalDays; day += 1) {
569
+ const zonedDate = toZonedTime(new Date(year, monthIndex, day), timezone);
570
+ const dayOfWeek = zonedDate.getDay();
571
+ const isEndOfWeek = dayOfWeek === 0 || day === totalDays;
572
+ if (isEndOfWeek) {
573
+ const startKey = buildDateKey(year, monthIndex, currentStartDay);
574
+ const endKey = buildDateKey(year, monthIndex, day);
575
+ if (maxKey && startKey > maxKey) {
576
+ break;
577
+ }
578
+ const clampedEndKey = maxKey && endKey > maxKey ? maxKey : endKey;
579
+ if (clampedEndKey < startKey) {
580
+ break;
581
+ }
582
+ const labelStart = formatDateKeyForDisplay(startKey, "MMM d");
583
+ const labelEnd = formatDateKeyForDisplay(clampedEndKey, "MMM d");
584
+ ranges.push({
585
+ startKey,
586
+ endKey: clampedEndKey,
587
+ label: `Week of ${labelStart} - ${labelEnd}`
588
+ });
589
+ currentStartDay = day + 1;
590
+ }
591
+ }
592
+ return ranges;
593
+ };
594
+ var formatRangeLabel = (range, fullMonthLabel) => {
595
+ if (!range.startKey || !range.endKey) return fullMonthLabel;
596
+ if (range.startKey === range.endKey) {
597
+ return formatDateKeyForDisplay(range.startKey, "MMM d, yyyy");
598
+ }
599
+ const startLabel = formatDateKeyForDisplay(range.startKey, "MMM d");
600
+ const endLabel = formatDateKeyForDisplay(range.endKey, "MMM d, yyyy");
601
+ return `${startLabel} - ${endLabel}`;
602
+ };
603
+ var filterDataByDateKeyRange = (data, range) => {
604
+ if (!range.startKey || !range.endKey) return data;
605
+ return (data || []).filter((item) => {
606
+ const dateKey = typeof item.date === "string" ? item.date : getDateKeyFromDate(item.date);
607
+ return dateKey >= range.startKey && dateKey <= range.endKey;
608
+ });
609
+ };
532
610
 
533
611
  // src/lib/utils/shifts.ts
534
612
  var DEFAULT_DAY_SHIFT_START = "06:00";
@@ -1501,7 +1579,7 @@ var dashboardService = {
1501
1579
  throw err;
1502
1580
  }
1503
1581
  },
1504
- async getUnderperformingWorkspaces(lineIdInput, monthInput, yearInput, shiftIds) {
1582
+ async getUnderperformingWorkspaces(lineIdInput, monthInput, yearInput, shiftIds, startDate, endDate) {
1505
1583
  _getSupabaseInstance();
1506
1584
  const config = _getDashboardConfigInstance();
1507
1585
  const entityConfig = config.entityConfig ?? DEFAULT_ENTITY_CONFIG;
@@ -1528,7 +1606,9 @@ var dashboardService = {
1528
1606
  year: currentYear,
1529
1607
  companyId,
1530
1608
  metricsTable,
1531
- shifts: dynamicShiftIds
1609
+ shifts: dynamicShiftIds,
1610
+ ...startDate ? { start_date: startDate } : {},
1611
+ ...endDate ? { end_date: endDate } : {}
1532
1612
  };
1533
1613
  const response = await fetch(fullFunctionUrl, {
1534
1614
  method: "POST",
@@ -29117,6 +29197,8 @@ var ERROR_MAPPING = {
29117
29197
  };
29118
29198
  var CLIP_ID_COMMENT_REGEX = /#\s*Clip ID:\s*([a-f0-9-]+)/i;
29119
29199
  var PLAYLIST_PROXY_REGEX = /\/api\/clips\/playlist\/([a-f0-9-]+)/i;
29200
+ var REMUX_URL_COMMENT_REGEX = /#\s*Remux URL:\s*([^\s]+)/i;
29201
+ var REMUXING_ENABLED_REGEX = /#\s*Remuxing:\s*enabled/i;
29120
29202
  var R2_FALLBACK_DETAILS = /* @__PURE__ */ new Set([
29121
29203
  "fragLoadError",
29122
29204
  "fragLoadHTTPError",
@@ -29132,6 +29214,13 @@ var extractClipIdFromSource = (source) => {
29132
29214
  if (urlMatch) return urlMatch[1];
29133
29215
  return null;
29134
29216
  };
29217
+ var extractRemuxUrl = (source) => {
29218
+ if (!source) return null;
29219
+ if (!REMUXING_ENABLED_REGEX.test(source)) return null;
29220
+ const remuxMatch = source.match(REMUX_URL_COMMENT_REGEX);
29221
+ if (remuxMatch) return remuxMatch[1];
29222
+ return null;
29223
+ };
29135
29224
  var ensureClipIdComment = (playlist, clipId) => {
29136
29225
  if (!playlist || playlist.includes(`# Clip ID: ${clipId}`) || CLIP_ID_COMMENT_REGEX.test(playlist)) {
29137
29226
  return playlist;
@@ -29460,7 +29549,50 @@ var HlsVideoPlayer = forwardRef(({
29460
29549
  if (effectiveSrc.startsWith("#EXTM3U")) {
29461
29550
  const safariMode = isSafari();
29462
29551
  const browserName = getBrowserName();
29463
- if (safariMode) {
29552
+ const remuxUrl = extractRemuxUrl(effectiveSrc);
29553
+ if (remuxUrl) {
29554
+ console.log(`[HlsVideoPlayer] Remuxing enabled - using remux playlist URL: ${remuxUrl}`);
29555
+ if (safariMode) {
29556
+ video.src = remuxUrl;
29557
+ } else if (Hls3.isSupported()) {
29558
+ const hls = new Hls3(mergedHlsConfig);
29559
+ hlsRef.current = hls;
29560
+ hls.on(Events.MANIFEST_PARSED, () => {
29561
+ console.log("[HlsVideoPlayer] Remuxed manifest parsed, ready to play");
29562
+ setIsReady(true);
29563
+ eventCallbacksRef.current.onReady?.(player);
29564
+ });
29565
+ hls.on(Events.ERROR, (_event, data) => {
29566
+ console.error("[HlsVideoPlayer] HLS.js error (remuxing):", data);
29567
+ if (data.fatal) {
29568
+ let errorInfo;
29569
+ switch (data.type) {
29570
+ case ErrorTypes.NETWORK_ERROR:
29571
+ errorInfo = ERROR_MAPPING.networkError;
29572
+ hls.startLoad();
29573
+ break;
29574
+ case ErrorTypes.MEDIA_ERROR:
29575
+ errorInfo = ERROR_MAPPING.mediaError;
29576
+ hls.recoverMediaError();
29577
+ break;
29578
+ default:
29579
+ errorInfo = ERROR_MAPPING.otherError;
29580
+ break;
29581
+ }
29582
+ errorInfo.details = data.details;
29583
+ eventCallbacksRef.current.onError?.(player, errorInfo);
29584
+ }
29585
+ });
29586
+ hls.on(Events.FRAG_LOADED, () => {
29587
+ setIsLoading(false);
29588
+ eventCallbacksRef.current.onLoadingChange?.(false);
29589
+ });
29590
+ hls.loadSource(remuxUrl);
29591
+ hls.attachMedia(video);
29592
+ } else {
29593
+ video.src = remuxUrl;
29594
+ }
29595
+ } else if (safariMode) {
29464
29596
  const clipIdMatch = effectiveSrc.match(/# Clip ID: ([a-f0-9-]+)/i);
29465
29597
  if (clipIdMatch) {
29466
29598
  const proxyUrl = `/api/clips/playlist/${clipIdMatch[1]}`;
@@ -36399,6 +36531,8 @@ var LineHistoryCalendar = ({
36399
36531
  year,
36400
36532
  lineId,
36401
36533
  selectedShiftId,
36534
+ rangeStart,
36535
+ rangeEnd,
36402
36536
  onDateSelect,
36403
36537
  className = ""
36404
36538
  }) => {
@@ -36409,6 +36543,7 @@ var LineHistoryCalendar = ({
36409
36543
  const currentTimeInZone = getCurrentTimeInZone(configuredTimezone);
36410
36544
  return typeof currentTimeInZone === "string" ? new Date(currentTimeInZone) : currentTimeInZone;
36411
36545
  }, [configuredTimezone]);
36546
+ const monthBounds = useMemo(() => getMonthKeyBounds(year, month), [year, month]);
36412
36547
  const calendarData = useMemo(() => {
36413
36548
  const startOfMonth = toZonedTime(new Date(year, month, 1), configuredTimezone);
36414
36549
  const endOfMonth = toZonedTime(new Date(year, month + 1, 0), configuredTimezone);
@@ -36490,6 +36625,10 @@ var LineHistoryCalendar = ({
36490
36625
  const isFuture = isFutureDate(day.date instanceof Date ? day.date : new Date(day.date));
36491
36626
  const hasData = hasRealData(shiftData);
36492
36627
  const dateObj = day.date instanceof Date ? day.date : new Date(day.date);
36628
+ const dateKey = `${dateObj.getFullYear()}-${String(dateObj.getMonth() + 1).padStart(2, "0")}-${String(dateObj.getDate()).padStart(2, "0")}`;
36629
+ const showRange = rangeStart && rangeEnd ? !(rangeStart === monthBounds.startKey && rangeEnd === monthBounds.endKey) : false;
36630
+ const inRange = showRange ? dateKey >= rangeStart && dateKey <= rangeEnd : false;
36631
+ const isRangeEdge = inRange && (dateKey === rangeStart || dateKey === rangeEnd);
36493
36632
  return /* @__PURE__ */ jsx(
36494
36633
  "div",
36495
36634
  {
@@ -36510,7 +36649,15 @@ var LineHistoryCalendar = ({
36510
36649
  underperforming_workspaces: shiftData.underperforming_workspaces || 0,
36511
36650
  total_workspaces: shiftData.total_workspaces || 0
36512
36651
  });
36513
- const returnTo = `/kpis/${lineId}?tab=monthly_history&month=${month2}&year=${year2}`;
36652
+ const params = new URLSearchParams();
36653
+ params.set("tab", "monthly_history");
36654
+ params.set("month", month2.toString());
36655
+ params.set("year", year2.toString());
36656
+ if (rangeStart && rangeEnd && !(rangeStart === monthBounds.startKey && rangeEnd === monthBounds.endKey)) {
36657
+ params.set("rangeStart", rangeStart);
36658
+ params.set("rangeEnd", rangeEnd);
36659
+ }
36660
+ const returnTo = `/kpis/${lineId}?${params.toString()}`;
36514
36661
  if (onDateSelect) {
36515
36662
  onDateSelect(date, selectedShiftId);
36516
36663
  } else {
@@ -36523,8 +36670,14 @@ var LineHistoryCalendar = ({
36523
36670
  rounded-lg h-full p-2 relative
36524
36671
  ${isToday2 ? "ring-2 ring-blue-500 dark:ring-blue-400 ring-offset-2 dark:ring-offset-gray-800 shadow-md" : ""}
36525
36672
  `, children: [
36673
+ inRange && /* @__PURE__ */ jsx(
36674
+ "div",
36675
+ {
36676
+ className: `absolute inset-0 rounded-lg pointer-events-none ${isRangeEdge ? "ring-2 ring-blue-500" : "ring-2 ring-blue-200"}`
36677
+ }
36678
+ ),
36526
36679
  /* @__PURE__ */ jsx("div", { className: `
36527
- text-base font-medium ${hasData ? "text-white" : "text-gray-500"} flex items-center
36680
+ text-base font-medium ${hasData ? "text-white" : "text-gray-500"} flex items-center relative z-10
36528
36681
  ${isToday2 ? "bg-blue-500 dark:bg-blue-600 rounded-full w-7 h-7 justify-center" : ""}
36529
36682
  `, children: dateObj.getDate() }),
36530
36683
  !isFuture && hasData && renderStats(shiftData, dateObj)
@@ -36702,6 +36855,183 @@ var IdleTimeReasonChart = ({
36702
36855
  ] });
36703
36856
  };
36704
36857
  var IdleTimeReasonChart_default = IdleTimeReasonChart;
36858
+ var MonthlyRangeFilter = ({
36859
+ month,
36860
+ year,
36861
+ timezone,
36862
+ value,
36863
+ onChange,
36864
+ className
36865
+ }) => {
36866
+ const monthBounds = useMemo(() => getMonthKeyBounds(year, month), [year, month]);
36867
+ const weekRanges = useMemo(() => getMonthWeekRanges(year, month, timezone), [year, month, timezone]);
36868
+ const normalizedRange = useMemo(() => {
36869
+ return normalizeDateKeyRange(value.startKey, value.endKey, monthBounds.startKey, monthBounds.endKey);
36870
+ }, [value.startKey, value.endKey, monthBounds.startKey, monthBounds.endKey]);
36871
+ const monthLabel = useMemo(() => {
36872
+ return new Date(year, month).toLocaleString("default", { month: "long", year: "numeric" });
36873
+ }, [year, month]);
36874
+ const presetOptions = useMemo(() => {
36875
+ const fullMonthRangeLabel = `${formatDateKeyForDisplay(monthBounds.startKey, "MMM d")} - ${formatDateKeyForDisplay(monthBounds.endKey, "MMM d")}`;
36876
+ const presets = [
36877
+ {
36878
+ id: "full-month",
36879
+ label: "Full month",
36880
+ rangeLabel: fullMonthRangeLabel,
36881
+ startKey: monthBounds.startKey,
36882
+ endKey: monthBounds.endKey
36883
+ }
36884
+ ];
36885
+ weekRanges.forEach((range, index) => {
36886
+ const rangeLabel = `${formatDateKeyForDisplay(range.startKey, "MMM d")} - ${formatDateKeyForDisplay(range.endKey, "MMM d")}`;
36887
+ presets.push({
36888
+ id: `week-${index + 1}`,
36889
+ label: `Week ${index + 1}`,
36890
+ rangeLabel,
36891
+ startKey: range.startKey,
36892
+ endKey: range.endKey
36893
+ });
36894
+ });
36895
+ return presets;
36896
+ }, [monthBounds.startKey, monthBounds.endKey, weekRanges]);
36897
+ const activePreset = useMemo(() => {
36898
+ return presetOptions.find(
36899
+ (preset) => preset.startKey === normalizedRange.startKey && preset.endKey === normalizedRange.endKey
36900
+ );
36901
+ }, [presetOptions, normalizedRange.startKey, normalizedRange.endKey]);
36902
+ const displayLabel = useMemo(() => {
36903
+ if (activePreset) return activePreset.label;
36904
+ return "Custom range";
36905
+ }, [activePreset]);
36906
+ const fullMonthLabel = useMemo(() => {
36907
+ const startLabel = formatDateKeyForDisplay(monthBounds.startKey, "MMM d");
36908
+ const endLabel = formatDateKeyForDisplay(monthBounds.endKey, "MMM d, yyyy");
36909
+ return `${startLabel} - ${endLabel}`;
36910
+ }, [monthBounds.startKey, monthBounds.endKey]);
36911
+ const displayRange = useMemo(() => {
36912
+ return formatRangeLabel(normalizedRange, fullMonthLabel);
36913
+ }, [normalizedRange, fullMonthLabel]);
36914
+ const [customStart, setCustomStart] = useState(normalizedRange.startKey);
36915
+ const [customEnd, setCustomEnd] = useState(normalizedRange.endKey);
36916
+ const [isOpen, setIsOpen] = useState(false);
36917
+ const dropdownRef = useRef(null);
36918
+ useEffect(() => {
36919
+ setCustomStart(normalizedRange.startKey);
36920
+ setCustomEnd(normalizedRange.endKey);
36921
+ }, [normalizedRange.startKey, normalizedRange.endKey]);
36922
+ useEffect(() => {
36923
+ const handleClickOutside = (event) => {
36924
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
36925
+ setIsOpen(false);
36926
+ }
36927
+ };
36928
+ document.addEventListener("mousedown", handleClickOutside);
36929
+ return () => document.removeEventListener("mousedown", handleClickOutside);
36930
+ }, []);
36931
+ const handlePresetSelect = (startKey, endKey) => {
36932
+ const normalized = normalizeDateKeyRange(startKey, endKey, monthBounds.startKey, monthBounds.endKey);
36933
+ onChange(normalized);
36934
+ setIsOpen(false);
36935
+ };
36936
+ const handleCustomApply = () => {
36937
+ if (!customStart || !customEnd) return;
36938
+ const normalized = normalizeDateKeyRange(customStart, customEnd, monthBounds.startKey, monthBounds.endKey);
36939
+ onChange(normalized);
36940
+ setIsOpen(false);
36941
+ };
36942
+ return /* @__PURE__ */ jsxs("div", { className: `relative ${className ?? ""}`, ref: dropdownRef, children: [
36943
+ /* @__PURE__ */ jsxs(
36944
+ "button",
36945
+ {
36946
+ type: "button",
36947
+ onClick: () => setIsOpen((prev) => !prev),
36948
+ className: "flex items-center gap-3 rounded-lg border border-slate-200 bg-white px-3 py-2 text-left shadow-sm transition-colors hover:border-slate-300 focus:outline-none focus:ring-2 focus:ring-blue-500",
36949
+ children: [
36950
+ /* @__PURE__ */ jsx(CalendarIcon, { className: "h-4 w-4 text-slate-500" }),
36951
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
36952
+ /* @__PURE__ */ jsx("span", { className: "text-[11px] uppercase tracking-[0.2em] text-slate-500", children: displayLabel }),
36953
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-slate-900", children: displayRange })
36954
+ ] }),
36955
+ /* @__PURE__ */ jsx(
36956
+ ChevronDownIcon,
36957
+ {
36958
+ className: `ml-2 h-4 w-4 text-slate-400 transition-transform ${isOpen ? "rotate-180" : ""}`
36959
+ }
36960
+ )
36961
+ ]
36962
+ }
36963
+ ),
36964
+ isOpen && /* @__PURE__ */ jsx("div", { className: "absolute right-0 z-50 mt-2 w-80 rounded-lg border border-slate-200 bg-white shadow-lg", children: /* @__PURE__ */ jsxs("div", { className: "p-3", children: [
36965
+ /* @__PURE__ */ jsx("div", { className: "text-[11px] uppercase tracking-[0.18em] text-slate-500", children: "Weeks" }),
36966
+ /* @__PURE__ */ jsx("div", { className: "mt-2 space-y-1", children: presetOptions.map((preset) => {
36967
+ const isActive = preset.startKey === normalizedRange.startKey && preset.endKey === normalizedRange.endKey;
36968
+ return /* @__PURE__ */ jsxs(
36969
+ "button",
36970
+ {
36971
+ type: "button",
36972
+ onClick: () => handlePresetSelect(preset.startKey, preset.endKey),
36973
+ className: `flex w-full items-center justify-between rounded-md px-2 py-2 text-left text-sm transition-colors ${isActive ? "bg-blue-50 text-blue-700" : "text-slate-700 hover:bg-slate-50"}`,
36974
+ children: [
36975
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: preset.label }),
36976
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-slate-500", children: preset.rangeLabel })
36977
+ ]
36978
+ },
36979
+ preset.id
36980
+ );
36981
+ }) }),
36982
+ /* @__PURE__ */ jsxs("div", { className: "mt-3 border-t border-slate-200 pt-3", children: [
36983
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
36984
+ /* @__PURE__ */ jsx("div", { className: "text-[11px] uppercase tracking-[0.18em] text-slate-500", children: "Custom range" }),
36985
+ !activePreset && /* @__PURE__ */ jsx("span", { className: "rounded-full border border-blue-100 bg-blue-50 px-2 py-0.5 text-[10px] uppercase tracking-wide text-blue-700", children: "Selected" })
36986
+ ] }),
36987
+ /* @__PURE__ */ jsxs("div", { className: "mt-2 grid grid-cols-1 gap-2 sm:grid-cols-2", children: [
36988
+ /* @__PURE__ */ jsxs("div", { children: [
36989
+ /* @__PURE__ */ jsx("label", { className: "block text-[11px] font-medium text-slate-600", children: "Start" }),
36990
+ /* @__PURE__ */ jsx(
36991
+ "input",
36992
+ {
36993
+ type: "date",
36994
+ value: customStart,
36995
+ onChange: (event) => setCustomStart(event.target.value),
36996
+ min: monthBounds.startKey,
36997
+ max: monthBounds.endKey,
36998
+ className: "mt-1 w-full rounded-md border border-slate-200 bg-white px-2 py-2 text-sm text-slate-700 focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200"
36999
+ }
37000
+ )
37001
+ ] }),
37002
+ /* @__PURE__ */ jsxs("div", { children: [
37003
+ /* @__PURE__ */ jsx("label", { className: "block text-[11px] font-medium text-slate-600", children: "End" }),
37004
+ /* @__PURE__ */ jsx(
37005
+ "input",
37006
+ {
37007
+ type: "date",
37008
+ value: customEnd,
37009
+ onChange: (event) => setCustomEnd(event.target.value),
37010
+ min: monthBounds.startKey,
37011
+ max: monthBounds.endKey,
37012
+ className: "mt-1 w-full rounded-md border border-slate-200 bg-white px-2 py-2 text-sm text-slate-700 focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200"
37013
+ }
37014
+ )
37015
+ ] })
37016
+ ] }),
37017
+ /* @__PURE__ */ jsx(
37018
+ "button",
37019
+ {
37020
+ type: "button",
37021
+ onClick: handleCustomApply,
37022
+ className: "mt-3 w-full rounded-md bg-blue-600 px-3 py-2 text-sm font-semibold text-white transition-colors hover:bg-blue-700",
37023
+ children: "Apply range"
37024
+ }
37025
+ )
37026
+ ] }),
37027
+ /* @__PURE__ */ jsxs("div", { className: "mt-3 text-xs text-slate-400", children: [
37028
+ "Month: ",
37029
+ monthLabel
37030
+ ] })
37031
+ ] }) })
37032
+ ] });
37033
+ };
37034
+ var MonthlyRangeFilter_default = MonthlyRangeFilter;
36705
37035
  var DEFAULT_PERFORMANCE_DATA = {
36706
37036
  avg_efficiency: 0,
36707
37037
  underperforming_workspaces: 0,
@@ -36719,10 +37049,15 @@ var LineMonthlyHistory = ({
36719
37049
  month,
36720
37050
  year,
36721
37051
  monthlyData = [],
37052
+ analysisData,
37053
+ rangeStart,
37054
+ rangeEnd,
37055
+ timezone,
36722
37056
  underperformingWorkspaces = {},
36723
37057
  lineId,
36724
37058
  selectedShiftId = 0,
36725
37059
  onShiftChange,
37060
+ onRangeChange,
36726
37061
  availableShifts,
36727
37062
  onWorkspaceSelect,
36728
37063
  onCalendarDateSelect,
@@ -36731,17 +37066,26 @@ var LineMonthlyHistory = ({
36731
37066
  className
36732
37067
  }) => {
36733
37068
  const navigation = useNavigation();
36734
- const chartKey = useMemo(() => `${lineId}-${month}-${year}-${selectedShiftId}`, [lineId, month, year, selectedShiftId]);
36735
- const startDate = useMemo(() => {
36736
- const m = String(month + 1).padStart(2, "0");
36737
- return `${year}-${m}-01`;
36738
- }, [month, year]);
36739
- const endDate = useMemo(() => {
36740
- const lastDay = new Date(year, month + 1, 0).getDate();
36741
- const m = String(month + 1).padStart(2, "0");
36742
- const d = String(lastDay).padStart(2, "0");
36743
- return `${year}-${m}-${d}`;
36744
- }, [month, year]);
37069
+ const chartKey = useMemo(() => `${lineId}-${month}-${year}-${selectedShiftId}-${rangeStart}-${rangeEnd}`, [lineId, month, year, selectedShiftId, rangeStart, rangeEnd]);
37070
+ const monthBounds = useMemo(() => getMonthKeyBounds(year, month), [year, month]);
37071
+ const normalizedRange = useMemo(() => {
37072
+ const startKey = rangeStart || monthBounds.startKey;
37073
+ const endKey = rangeEnd || monthBounds.endKey;
37074
+ return normalizeDateKeyRange(startKey, endKey, monthBounds.startKey, monthBounds.endKey);
37075
+ }, [rangeStart, rangeEnd, monthBounds.startKey, monthBounds.endKey]);
37076
+ const isFullRange = useMemo(() => isFullMonthRange(normalizedRange, year, month), [normalizedRange, year, month]);
37077
+ const monthLabel = useMemo(() => new Date(year, month).toLocaleString("default", { month: "long" }), [year, month]);
37078
+ const rangeLabel = useMemo(() => {
37079
+ return isFullRange ? monthLabel : formatRangeLabel(normalizedRange, monthLabel);
37080
+ }, [isFullRange, normalizedRange, monthLabel]);
37081
+ const analysisMonthlyData = useMemo(() => {
37082
+ if (analysisData) {
37083
+ return analysisData;
37084
+ }
37085
+ return filterDataByDateKeyRange(monthlyData, normalizedRange);
37086
+ }, [analysisData, monthlyData, normalizedRange]);
37087
+ const startDate = normalizedRange.startKey;
37088
+ const endDate = normalizedRange.endKey;
36745
37089
  const {
36746
37090
  chartData: idleReasonsChartData,
36747
37091
  isLoading: idleReasonsLoading,
@@ -36762,7 +37106,7 @@ var LineMonthlyHistory = ({
36762
37106
  }
36763
37107
  ) });
36764
37108
  }
36765
- const averages = (monthlyData || []).reduce(
37109
+ const averages = (analysisMonthlyData || []).reduce(
36766
37110
  (acc, day) => {
36767
37111
  const shiftData = getShiftData2(day, selectedShiftId);
36768
37112
  if (!shiftData || shiftData?.avg_efficiency < 10) {
@@ -36822,7 +37166,15 @@ var LineMonthlyHistory = ({
36822
37166
  )) });
36823
37167
  };
36824
37168
  const handleWorkspaceClick = (workspace) => {
36825
- const returnToUrl = `/kpis/${lineId}?tab=monthly_history&month=${month}&year=${year}`;
37169
+ const params = new URLSearchParams();
37170
+ params.set("tab", "monthly_history");
37171
+ params.set("month", month.toString());
37172
+ params.set("year", year.toString());
37173
+ if (!isFullRange) {
37174
+ params.set("rangeStart", normalizedRange.startKey);
37175
+ params.set("rangeEnd", normalizedRange.endKey);
37176
+ }
37177
+ const returnToUrl = `/kpis/${lineId}?${params.toString()}`;
36826
37178
  if (onWorkspaceSelect) {
36827
37179
  onWorkspaceSelect(workspace.workspace_uuid, {
36828
37180
  sourceType: "lineMonthlyHistory",
@@ -36842,18 +37194,31 @@ var LineMonthlyHistory = ({
36842
37194
  });
36843
37195
  };
36844
37196
  return /* @__PURE__ */ jsxs("div", { className: clsx("flex flex-col gap-2 min-h-0 overflow-y-auto pb-6", className), children: [
36845
- /* @__PURE__ */ jsx("div", { className: "flex justify-center mb-4", children: /* @__PURE__ */ jsx("div", { className: "flex gap-1 border border-gray-200 rounded-lg p-1 bg-gray-50", children: (availableShifts && availableShifts.length > 0 ? availableShifts : [
36846
- { id: 0, name: "Day Shift" },
36847
- { id: 1, name: "Night Shift" }
36848
- ]).sort((a, b) => a.id - b.id).map((shift) => /* @__PURE__ */ jsx(
36849
- "button",
36850
- {
36851
- onClick: () => onShiftChange?.(shift.id),
36852
- className: `px-4 py-2 text-sm font-medium rounded-md transition-all duration-200 ${selectedShiftId === shift.id ? "bg-white text-blue-600 shadow-sm ring-1 ring-gray-200" : "text-gray-600 hover:text-gray-900 hover:bg-gray-100"}`,
36853
- children: shift.name
36854
- },
36855
- shift.id
36856
- )) }) }),
37197
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-3 sm:items-center mb-4", children: [
37198
+ /* @__PURE__ */ jsx("div", { className: "hidden sm:block" }),
37199
+ /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx("div", { className: "flex gap-1 border border-gray-200 rounded-lg p-1 bg-gray-50", children: (availableShifts && availableShifts.length > 0 ? availableShifts : [
37200
+ { id: 0, name: "Day Shift" },
37201
+ { id: 1, name: "Night Shift" }
37202
+ ]).sort((a, b) => a.id - b.id).map((shift) => /* @__PURE__ */ jsx(
37203
+ "button",
37204
+ {
37205
+ onClick: () => onShiftChange?.(shift.id),
37206
+ className: `px-4 py-2 text-sm font-medium rounded-md transition-all duration-200 ${selectedShiftId === shift.id ? "bg-white text-blue-600 shadow-sm ring-1 ring-gray-200" : "text-gray-600 hover:text-gray-900 hover:bg-gray-100"}`,
37207
+ children: shift.name
37208
+ },
37209
+ shift.id
37210
+ )) }) }),
37211
+ /* @__PURE__ */ jsx("div", { className: "flex justify-center sm:justify-end", children: /* @__PURE__ */ jsx(
37212
+ MonthlyRangeFilter_default,
37213
+ {
37214
+ month,
37215
+ year,
37216
+ timezone,
37217
+ value: normalizedRange,
37218
+ onChange: (nextRange) => onRangeChange?.(nextRange)
37219
+ }
37220
+ ) })
37221
+ ] }),
36857
37222
  /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-6 mt-6", children: [
36858
37223
  /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6", children: [
36859
37224
  /* @__PURE__ */ jsxs("div", { className: "flex justify-center items-center mb-6 space-x-4", children: [
@@ -36916,6 +37281,8 @@ var LineMonthlyHistory = ({
36916
37281
  year,
36917
37282
  lineId,
36918
37283
  selectedShiftId,
37284
+ rangeStart: normalizedRange.startKey,
37285
+ rangeEnd: normalizedRange.endKey,
36919
37286
  onDateSelect: onCalendarDateSelect
36920
37287
  }
36921
37288
  )
@@ -36926,7 +37293,7 @@ var LineMonthlyHistory = ({
36926
37293
  /* @__PURE__ */ jsx("h3", { className: "text-base font-semibold text-gray-700 mb-1 text-center", children: "Efficiency" }),
36927
37294
  /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-500 mb-4 text-center", children: [
36928
37295
  "Cumulative for ",
36929
- new Date(year, month).toLocaleString("default", { month: "long" })
37296
+ rangeLabel
36930
37297
  ] }),
36931
37298
  /* @__PURE__ */ jsxs("div", { className: "text-4xl font-bold text-center text-gray-900", children: [
36932
37299
  avgEfficiency.toFixed(1),
@@ -36937,7 +37304,7 @@ var LineMonthlyHistory = ({
36937
37304
  /* @__PURE__ */ jsx("h3", { className: "text-base font-semibold text-gray-700 mb-1 text-center", children: "Avg. Underperforming" }),
36938
37305
  /* @__PURE__ */ jsxs("p", { className: "text-sm text-gray-500 mb-4 text-center", children: [
36939
37306
  "Cumulative for ",
36940
- new Date(year, month).toLocaleString("default", { month: "long" })
37307
+ rangeLabel
36941
37308
  ] }),
36942
37309
  /* @__PURE__ */ jsxs("div", { className: "text-4xl font-bold text-center text-gray-900", children: [
36943
37310
  avgUnderperforming.toFixed(1),
@@ -37016,9 +37383,12 @@ var LineMonthlyPdfGenerator = ({
37016
37383
  lineId,
37017
37384
  lineName,
37018
37385
  monthlyData,
37386
+ analysisData,
37019
37387
  underperformingWorkspaces,
37020
37388
  selectedMonth,
37021
37389
  selectedYear,
37390
+ rangeStart,
37391
+ rangeEnd,
37022
37392
  selectedShiftId,
37023
37393
  availableShifts,
37024
37394
  className
@@ -37027,12 +37397,41 @@ var LineMonthlyPdfGenerator = ({
37027
37397
  const generatePDF = async () => {
37028
37398
  setIsGenerating(true);
37029
37399
  try {
37400
+ const monthBounds = getMonthKeyBounds(selectedYear, selectedMonth);
37401
+ const requestedRange = {
37402
+ startKey: rangeStart || monthBounds.startKey,
37403
+ endKey: rangeEnd || monthBounds.endKey
37404
+ };
37405
+ const normalizedRange = normalizeDateKeyRange(
37406
+ requestedRange.startKey,
37407
+ requestedRange.endKey,
37408
+ monthBounds.startKey,
37409
+ monthBounds.endKey
37410
+ );
37411
+ const fullRange = isFullMonthRange(normalizedRange, selectedYear, selectedMonth);
37412
+ const reportStartDate = parseDateKeyToDate(normalizedRange.startKey);
37413
+ const reportEndDate = parseDateKeyToDate(normalizedRange.endKey);
37414
+ const reportStartStr = reportStartDate.toLocaleDateString("en-IN", {
37415
+ day: "2-digit",
37416
+ month: "short",
37417
+ year: "numeric",
37418
+ timeZone: "Asia/Kolkata"
37419
+ });
37420
+ const reportEndStr = reportEndDate.toLocaleDateString("en-IN", {
37421
+ day: "2-digit",
37422
+ month: "short",
37423
+ year: "numeric",
37424
+ timeZone: "Asia/Kolkata"
37425
+ });
37030
37426
  trackCoreEvent("Line Monthly PDF Export Clicked", {
37031
37427
  line_id: lineId,
37032
37428
  line_name: lineName,
37033
37429
  month: selectedMonth,
37034
37430
  year: selectedYear,
37035
- shift_id: selectedShiftId
37431
+ shift_id: selectedShiftId,
37432
+ range_start: normalizedRange.startKey,
37433
+ range_end: normalizedRange.endKey,
37434
+ is_full_month: fullRange
37036
37435
  });
37037
37436
  const doc = new jsPDF$1();
37038
37437
  doc.setFontSize(14);
@@ -37065,28 +37464,15 @@ var LineMonthlyPdfGenerator = ({
37065
37464
  const shiftType = getShiftDisplayName(selectedShiftId, availableShifts);
37066
37465
  doc.text(`${monthName}`, 20, 55);
37067
37466
  doc.text(`${shiftType}`, 20, 63);
37068
- const startDate = new Date(selectedYear, selectedMonth, 1);
37069
- const endDate = new Date(selectedYear, selectedMonth + 1, 0);
37070
- const startDateStr = startDate.toLocaleDateString("en-IN", {
37071
- day: "2-digit",
37072
- month: "short",
37073
- year: "numeric",
37074
- timeZone: "Asia/Kolkata"
37075
- });
37076
- const endDateStr = endDate.toLocaleDateString("en-IN", {
37077
- day: "2-digit",
37078
- month: "short",
37079
- year: "numeric",
37080
- timeZone: "Asia/Kolkata"
37081
- });
37082
37467
  doc.setFontSize(12);
37083
37468
  doc.setTextColor(80, 80, 80);
37084
- doc.text(`Report Period: ${startDateStr} - ${endDateStr}`, 20, 71);
37469
+ doc.text(`Report Period: ${reportStartStr} - ${reportEndStr}`, 20, 71);
37085
37470
  doc.setTextColor(0, 0, 0);
37086
37471
  doc.setDrawColor(180, 180, 180);
37087
37472
  doc.setLineWidth(0.8);
37088
37473
  doc.line(20, 85, 190, 85);
37089
- const validDays = monthlyData.filter((day) => {
37474
+ const reportData = analysisData ? analysisData : filterDataByDateKeyRange(monthlyData, normalizedRange);
37475
+ const validDays = reportData.filter((day) => {
37090
37476
  const date = new Date(day.date);
37091
37477
  return date.getMonth() === selectedMonth && date.getFullYear() === selectedYear;
37092
37478
  });
@@ -38435,27 +38821,36 @@ var CustomTooltip2 = ({ active, payload, label }) => {
38435
38821
  };
38436
38822
  var WorkspaceMonthlyHistory = ({
38437
38823
  data,
38824
+ analysisData,
38438
38825
  month,
38439
38826
  year,
38440
38827
  workspaceId,
38828
+ rangeStart,
38829
+ rangeEnd,
38830
+ timezone,
38441
38831
  selectedShiftId = 0,
38442
38832
  onDateSelect,
38443
38833
  onMonthNavigate,
38444
38834
  onShiftChange,
38835
+ onRangeChange,
38445
38836
  availableShifts,
38446
38837
  monthlyDataLoading = false,
38447
38838
  className = ""
38448
38839
  }) => {
38449
- const startDate = useMemo(() => {
38450
- const monthString = String(month + 1).padStart(2, "0");
38451
- return `${year}-${monthString}-01`;
38452
- }, [month, year]);
38453
- const endDate = useMemo(() => {
38454
- const lastDay = new Date(year, month + 1, 0).getDate();
38455
- const monthString = String(month + 1).padStart(2, "0");
38456
- const dayString = String(lastDay).padStart(2, "0");
38457
- return `${year}-${monthString}-${dayString}`;
38458
- }, [month, year]);
38840
+ const monthBounds = useMemo(() => getMonthKeyBounds(year, month), [year, month]);
38841
+ const normalizedRange = useMemo(() => {
38842
+ const startKey = rangeStart || monthBounds.startKey;
38843
+ const endKey = rangeEnd || monthBounds.endKey;
38844
+ return normalizeDateKeyRange(startKey, endKey, monthBounds.startKey, monthBounds.endKey);
38845
+ }, [rangeStart, rangeEnd, monthBounds.startKey, monthBounds.endKey]);
38846
+ const analysisMonthlyData = useMemo(() => {
38847
+ if (analysisData) {
38848
+ return analysisData;
38849
+ }
38850
+ return filterDataByDateKeyRange(data, normalizedRange);
38851
+ }, [analysisData, data, normalizedRange]);
38852
+ const startDate = normalizedRange.startKey;
38853
+ const endDate = normalizedRange.endKey;
38459
38854
  const {
38460
38855
  chartData: idleReasonsChartData,
38461
38856
  isLoading: idleReasonsLoading,
@@ -38465,19 +38860,25 @@ var WorkspaceMonthlyHistory = ({
38465
38860
  startDate,
38466
38861
  endDate,
38467
38862
  shiftId: selectedShiftId,
38468
- enabled: data.length > 0
38863
+ enabled: analysisMonthlyData.length > 0
38469
38864
  });
38470
38865
  const hasRealData = (shift) => {
38471
38866
  if (shift.hasData !== void 0) return shift.hasData;
38472
38867
  return shift.efficiency > 0 || shift.output > 0 || shift.cycleTime > 0 || shift.pph > 0 || shift.idealOutput > 0 || shift.idleTime > 0;
38473
38868
  };
38474
38869
  const chartData = useMemo(() => {
38475
- const daysInMonth = new Date(year, month + 1, 0).getDate();
38870
+ const rangeStartDate = parseDateKeyToDate(normalizedRange.startKey);
38871
+ const rangeEndDate = parseDateKeyToDate(normalizedRange.endKey);
38872
+ const dayNumbers = [];
38873
+ for (let d = new Date(rangeStartDate); d <= rangeEndDate; d.setDate(d.getDate() + 1)) {
38874
+ dayNumbers.push(d.getDate());
38875
+ }
38476
38876
  const dailyData = [];
38477
38877
  let maxOutput = 0;
38478
38878
  let lastSetTarget = 0;
38479
- for (let day = daysInMonth; day >= 1; day--) {
38480
- const dayData = data.find((d) => {
38879
+ for (let i = dayNumbers.length - 1; i >= 0; i--) {
38880
+ const day = dayNumbers[i];
38881
+ const dayData = analysisMonthlyData.find((d) => {
38481
38882
  const date = new Date(d.date);
38482
38883
  return date.getDate() === day;
38483
38884
  });
@@ -38488,8 +38889,8 @@ var WorkspaceMonthlyHistory = ({
38488
38889
  break;
38489
38890
  }
38490
38891
  }
38491
- for (let day = 1; day <= daysInMonth; day++) {
38492
- const dayData = data.find((d) => {
38892
+ for (const day of dayNumbers) {
38893
+ const dayData = analysisMonthlyData.find((d) => {
38493
38894
  const date = new Date(d.date);
38494
38895
  return date.getDate() === day;
38495
38896
  });
@@ -38515,7 +38916,7 @@ var WorkspaceMonthlyHistory = ({
38515
38916
  const calculatedMax = Math.max(maxOutput, lastSetTarget);
38516
38917
  const yAxisMax = calculatedMax > 0 ? calculatedMax * 1.1 : 100;
38517
38918
  return { data: dailyData, maxOutput, lastSetTarget, yAxisMax };
38518
- }, [data, month, year, selectedShiftId]);
38919
+ }, [analysisMonthlyData, normalizedRange.startKey, normalizedRange.endKey, selectedShiftId]);
38519
38920
  const yAxisTicks = useMemo(() => {
38520
38921
  const max = chartData.yAxisMax;
38521
38922
  const target = chartData.lastSetTarget;
@@ -38538,7 +38939,7 @@ var WorkspaceMonthlyHistory = ({
38538
38939
  return Array.from(new Set(ticks)).filter((v) => v >= 0 && v <= max).sort((a, b) => a - b);
38539
38940
  }, [chartData.yAxisMax, chartData.lastSetTarget]);
38540
38941
  const pieChartData = useMemo(() => {
38541
- const validShifts = data.map((d) => getShiftData(d, selectedShiftId)).filter(hasRealData);
38942
+ const validShifts = analysisMonthlyData.map((d) => getShiftData(d, selectedShiftId)).filter(hasRealData);
38542
38943
  if (validShifts.length === 0) return [];
38543
38944
  const totalIdleTime = validShifts.reduce((sum, shift) => sum + shift.idleTime, 0);
38544
38945
  const totalShiftTime = validShifts.length * 8 * 3600;
@@ -38547,9 +38948,9 @@ var WorkspaceMonthlyHistory = ({
38547
38948
  { name: "Productive", value: Math.round(activeTime / totalShiftTime * 100) },
38548
38949
  { name: "Idle", value: Math.round(totalIdleTime / totalShiftTime * 100) }
38549
38950
  ];
38550
- }, [data, selectedShiftId]);
38951
+ }, [analysisMonthlyData, selectedShiftId]);
38551
38952
  const metrics2 = useMemo(() => {
38552
- const validShifts = data.map((d) => getShiftData(d, selectedShiftId)).filter(hasRealData);
38953
+ const validShifts = analysisMonthlyData.map((d) => getShiftData(d, selectedShiftId)).filter(hasRealData);
38553
38954
  if (validShifts.length === 0) return null;
38554
38955
  const totalEfficiency = validShifts.reduce((sum, shift) => sum + shift.efficiency, 0);
38555
38956
  const totalCycleTime = validShifts.reduce((sum, shift) => sum + shift.cycleTime, 0);
@@ -38569,7 +38970,7 @@ var WorkspaceMonthlyHistory = ({
38569
38970
  totalOutput,
38570
38971
  avgIdleTime: Math.round(totalIdleTime / validShifts.length)
38571
38972
  };
38572
- }, [data, selectedShiftId]);
38973
+ }, [analysisMonthlyData, selectedShiftId]);
38573
38974
  const calendarData = useMemo(() => {
38574
38975
  const startOfMonth = new Date(year, month, 1);
38575
38976
  const endOfMonth = new Date(year, month + 1, 0);
@@ -38609,7 +39010,7 @@ var WorkspaceMonthlyHistory = ({
38609
39010
  onShiftChange(shiftId);
38610
39011
  }
38611
39012
  }, [workspaceId, onShiftChange]);
38612
- const chartKey = useMemo(() => `${workspaceId}-${month}-${year}-${selectedShiftId}`, [workspaceId, month, year, selectedShiftId]);
39013
+ const chartKey = useMemo(() => `${workspaceId}-${month}-${year}-${selectedShiftId}-${normalizedRange.startKey}-${normalizedRange.endKey}`, [workspaceId, month, year, selectedShiftId, normalizedRange.startKey, normalizedRange.endKey]);
38613
39014
  if (monthlyDataLoading) {
38614
39015
  return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-[calc(100vh-10rem)]", children: /* @__PURE__ */ jsx(
38615
39016
  OptifyeLogoLoader_default,
@@ -38620,18 +39021,31 @@ var WorkspaceMonthlyHistory = ({
38620
39021
  ) });
38621
39022
  }
38622
39023
  return /* @__PURE__ */ jsxs("div", { className: `flex flex-col gap-2 min-h-0 overflow-y-auto pb-6 ${className}`, children: [
38623
- /* @__PURE__ */ jsx("div", { className: "flex justify-center mb-4", children: /* @__PURE__ */ jsx("div", { className: "flex gap-1 border border-gray-200 rounded-lg p-1 bg-gray-50", children: (availableShifts && availableShifts.length > 0 ? availableShifts : [
38624
- { id: 0, name: "Day Shift" },
38625
- { id: 1, name: "Night Shift" }
38626
- ]).sort((a, b) => a.id - b.id).map((shift) => /* @__PURE__ */ jsx(
38627
- "button",
38628
- {
38629
- onClick: () => handleShiftChange(shift.id),
38630
- className: `px-4 py-2 text-sm font-medium rounded-md transition-all duration-200 ${selectedShiftId === shift.id ? "bg-white text-blue-600 shadow-sm ring-1 ring-gray-200" : "text-gray-600 hover:text-gray-900 hover:bg-gray-100"}`,
38631
- children: shift.name
38632
- },
38633
- shift.id
38634
- )) }) }),
39024
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-3 sm:items-center mb-4", children: [
39025
+ /* @__PURE__ */ jsx("div", { className: "hidden sm:block" }),
39026
+ /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx("div", { className: "flex gap-1 border border-gray-200 rounded-lg p-1 bg-gray-50", children: (availableShifts && availableShifts.length > 0 ? availableShifts : [
39027
+ { id: 0, name: "Day Shift" },
39028
+ { id: 1, name: "Night Shift" }
39029
+ ]).sort((a, b) => a.id - b.id).map((shift) => /* @__PURE__ */ jsx(
39030
+ "button",
39031
+ {
39032
+ onClick: () => handleShiftChange(shift.id),
39033
+ className: `px-4 py-2 text-sm font-medium rounded-md transition-all duration-200 ${selectedShiftId === shift.id ? "bg-white text-blue-600 shadow-sm ring-1 ring-gray-200" : "text-gray-600 hover:text-gray-900 hover:bg-gray-100"}`,
39034
+ children: shift.name
39035
+ },
39036
+ shift.id
39037
+ )) }) }),
39038
+ /* @__PURE__ */ jsx("div", { className: "flex justify-center sm:justify-end", children: /* @__PURE__ */ jsx(
39039
+ MonthlyRangeFilter_default,
39040
+ {
39041
+ month,
39042
+ year,
39043
+ timezone,
39044
+ value: normalizedRange,
39045
+ onChange: (nextRange) => onRangeChange?.(nextRange)
39046
+ }
39047
+ ) })
39048
+ ] }),
38635
39049
  /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-6 mt-6", children: [
38636
39050
  /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-xl shadow-sm border border-gray-100 p-6", children: [
38637
39051
  /* @__PURE__ */ jsxs("div", { className: "flex justify-center items-center mb-6 space-x-4", children: [
@@ -38699,6 +39113,10 @@ var WorkspaceMonthlyHistory = ({
38699
39113
  const hasData = shiftData ? hasRealData(shiftData) : false;
38700
39114
  const isToday2 = (/* @__PURE__ */ new Date()).getDate() === dayNumber && (/* @__PURE__ */ new Date()).getMonth() === month && (/* @__PURE__ */ new Date()).getFullYear() === year;
38701
39115
  const isFuture = new Date(year, month, dayNumber) > /* @__PURE__ */ new Date();
39116
+ const dateKey = `${year}-${String(month + 1).padStart(2, "0")}-${String(dayNumber).padStart(2, "0")}`;
39117
+ const showRange = normalizedRange.startKey && normalizedRange.endKey ? !(normalizedRange.startKey === monthBounds.startKey && normalizedRange.endKey === monthBounds.endKey) : false;
39118
+ const inRange = showRange ? dateKey >= normalizedRange.startKey && dateKey <= normalizedRange.endKey : false;
39119
+ const isRangeEdge = inRange && (dateKey === normalizedRange.startKey || dateKey === normalizedRange.endKey);
38702
39120
  const getPerformanceColor = () => {
38703
39121
  if (isFuture) return "bg-gray-200 dark:bg-gray-700";
38704
39122
  if (!hasData || !shiftData) return "bg-gray-300 dark:bg-gray-600";
@@ -38714,8 +39132,14 @@ var WorkspaceMonthlyHistory = ({
38714
39132
  rounded-lg h-full p-2 relative
38715
39133
  ${isToday2 ? "ring-2 ring-blue-500 dark:ring-blue-400 ring-offset-2 dark:ring-offset-gray-800 shadow-md" : ""}
38716
39134
  `, children: [
39135
+ inRange && /* @__PURE__ */ jsx(
39136
+ "div",
39137
+ {
39138
+ className: `absolute inset-0 rounded-lg pointer-events-none ${isRangeEdge ? "ring-2 ring-blue-500" : "ring-2 ring-blue-200"}`
39139
+ }
39140
+ ),
38717
39141
  /* @__PURE__ */ jsx("div", { className: `
38718
- text-base font-medium ${hasData && !isFuture ? "text-white" : "text-gray-500"} flex items-center
39142
+ text-base font-medium ${hasData && !isFuture ? "text-white" : "text-gray-500"} flex items-center relative z-10
38719
39143
  ${isToday2 ? "bg-blue-500 dark:bg-blue-600 rounded-full w-7 h-7 justify-center" : ""}
38720
39144
  `, children: dayNumber }),
38721
39145
  !isFuture && hasData && shiftData && /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-black/80 rounded-lg p-2 text-white opacity-0 group-hover:opacity-100 transition-opacity", children: /* @__PURE__ */ jsxs("div", { className: "text-xs space-y-1", children: [
@@ -39259,8 +39683,11 @@ var WorkspaceMonthlyPdfGenerator = ({
39259
39683
  workspaceId,
39260
39684
  workspaceName,
39261
39685
  monthlyData,
39686
+ analysisData,
39262
39687
  selectedMonth,
39263
39688
  selectedYear,
39689
+ rangeStart,
39690
+ rangeEnd,
39264
39691
  selectedShiftId,
39265
39692
  availableShifts,
39266
39693
  className
@@ -39269,12 +39696,41 @@ var WorkspaceMonthlyPdfGenerator = ({
39269
39696
  const generatePDF = async () => {
39270
39697
  setIsGenerating(true);
39271
39698
  try {
39699
+ const monthBounds = getMonthKeyBounds(selectedYear, selectedMonth);
39700
+ const requestedRange = {
39701
+ startKey: rangeStart || monthBounds.startKey,
39702
+ endKey: rangeEnd || monthBounds.endKey
39703
+ };
39704
+ const normalizedRange = normalizeDateKeyRange(
39705
+ requestedRange.startKey,
39706
+ requestedRange.endKey,
39707
+ monthBounds.startKey,
39708
+ monthBounds.endKey
39709
+ );
39710
+ const fullRange = isFullMonthRange(normalizedRange, selectedYear, selectedMonth);
39711
+ const reportStartDate = parseDateKeyToDate(normalizedRange.startKey);
39712
+ const reportEndDate = parseDateKeyToDate(normalizedRange.endKey);
39713
+ const reportStartStr = reportStartDate.toLocaleDateString("en-IN", {
39714
+ day: "2-digit",
39715
+ month: "short",
39716
+ year: "numeric",
39717
+ timeZone: "Asia/Kolkata"
39718
+ });
39719
+ const reportEndStr = reportEndDate.toLocaleDateString("en-IN", {
39720
+ day: "2-digit",
39721
+ month: "short",
39722
+ year: "numeric",
39723
+ timeZone: "Asia/Kolkata"
39724
+ });
39272
39725
  trackCoreEvent("Workspace Monthly PDF Export Clicked", {
39273
39726
  workspace_id: workspaceId,
39274
39727
  workspace_name: workspaceName,
39275
39728
  month: selectedMonth,
39276
39729
  year: selectedYear,
39277
- shift_id: selectedShiftId
39730
+ shift_id: selectedShiftId,
39731
+ range_start: normalizedRange.startKey,
39732
+ range_end: normalizedRange.endKey,
39733
+ is_full_month: fullRange
39278
39734
  });
39279
39735
  const doc = new jsPDF$1();
39280
39736
  doc.setFontSize(14);
@@ -39311,28 +39767,15 @@ var WorkspaceMonthlyPdfGenerator = ({
39311
39767
  const shiftType = getShiftDisplayName2(selectedShiftId, availableShifts);
39312
39768
  doc.text(`${monthName}`, 20, 65);
39313
39769
  doc.text(`${shiftType}`, 20, 73);
39314
- const startDate = new Date(selectedYear, selectedMonth, 1);
39315
- const endDate = new Date(selectedYear, selectedMonth + 1, 0);
39316
- const startDateStr = startDate.toLocaleDateString("en-IN", {
39317
- day: "2-digit",
39318
- month: "short",
39319
- year: "numeric",
39320
- timeZone: "Asia/Kolkata"
39321
- });
39322
- const endDateStr = endDate.toLocaleDateString("en-IN", {
39323
- day: "2-digit",
39324
- month: "short",
39325
- year: "numeric",
39326
- timeZone: "Asia/Kolkata"
39327
- });
39328
39770
  doc.setFontSize(12);
39329
39771
  doc.setTextColor(80, 80, 80);
39330
- doc.text(`Report Period: ${startDateStr} - ${endDateStr}`, 20, 81);
39772
+ doc.text(`Report Period: ${reportStartStr} - ${reportEndStr}`, 20, 81);
39331
39773
  doc.setTextColor(0, 0, 0);
39332
39774
  doc.setDrawColor(180, 180, 180);
39333
39775
  doc.setLineWidth(0.8);
39334
39776
  doc.line(20, 90, 190, 90);
39335
- const validDays = monthlyData.filter((day) => {
39777
+ const reportData = analysisData ? analysisData : filterDataByDateKeyRange(monthlyData, normalizedRange);
39778
+ const validDays = reportData.filter((day) => {
39336
39779
  const date = new Date(day.date);
39337
39780
  return date.getMonth() === selectedMonth && date.getFullYear() === selectedYear;
39338
39781
  });
@@ -50101,6 +50544,8 @@ var KPIDetailView = ({
50101
50544
  tab: urlTab,
50102
50545
  month: urlMonth,
50103
50546
  year: urlYear,
50547
+ rangeStart: urlRangeStart,
50548
+ rangeEnd: urlRangeEnd,
50104
50549
  companyId,
50105
50550
  navigate,
50106
50551
  className,
@@ -50127,6 +50572,9 @@ var KPIDetailView = ({
50127
50572
  }
50128
50573
  return (/* @__PURE__ */ new Date()).getFullYear();
50129
50574
  });
50575
+ const monthBounds = useMemo(() => getMonthKeyBounds(currentYear, currentMonth), [currentYear, currentMonth]);
50576
+ const [rangeStart, setRangeStart] = useState(monthBounds.startKey);
50577
+ const [rangeEnd, setRangeEnd] = useState(monthBounds.endKey);
50130
50578
  const [monthlyData, setMonthlyData] = useState([]);
50131
50579
  const [underperformingWorkspaces, setUnderperformingWorkspaces] = useState({});
50132
50580
  const [selectedShiftId, setSelectedShiftId] = useState(0);
@@ -50143,6 +50591,18 @@ var KPIDetailView = ({
50143
50591
  }
50144
50592
  return void 0;
50145
50593
  }, [urlShift]);
50594
+ const range = useMemo(() => ({ startKey: rangeStart, endKey: rangeEnd }), [rangeStart, rangeEnd]);
50595
+ const isFullRange = useMemo(() => isFullMonthRange(range, currentYear, currentMonth), [range, currentYear, currentMonth]);
50596
+ useEffect(() => {
50597
+ const normalized = normalizeDateKeyRange(
50598
+ typeof urlRangeStart === "string" ? urlRangeStart : monthBounds.startKey,
50599
+ typeof urlRangeEnd === "string" ? urlRangeEnd : monthBounds.endKey,
50600
+ monthBounds.startKey,
50601
+ monthBounds.endKey
50602
+ );
50603
+ setRangeStart(normalized.startKey);
50604
+ setRangeEnd(normalized.endKey);
50605
+ }, [urlRangeStart, urlRangeEnd, monthBounds.startKey, monthBounds.endKey]);
50146
50606
  const supabase = useSupabase();
50147
50607
  const dashboardConfig = useDashboardConfig();
50148
50608
  const configuredTimezone = timezone || dashboardConfig.dateTimeConfig?.defaultTimezone || "UTC";
@@ -50242,8 +50702,10 @@ var KPIDetailView = ({
50242
50702
  lineId,
50243
50703
  currentMonth,
50244
50704
  currentYear,
50245
- shiftConfig?.shifts?.map((s) => s.shiftId)
50705
+ shiftConfig?.shifts?.map((s) => s.shiftId),
50246
50706
  // Pass dynamic shift IDs
50707
+ isFullRange ? void 0 : range.startKey,
50708
+ isFullRange ? void 0 : range.endKey
50247
50709
  )
50248
50710
  ]).then(([monthlyMetrics, underperformingData]) => {
50249
50711
  console.log("Fetched monthly metrics data:", monthlyMetrics);
@@ -50305,7 +50767,10 @@ var KPIDetailView = ({
50305
50767
  setMonthlyDataLoading(false);
50306
50768
  });
50307
50769
  }
50308
- }, [activeTab, lineId, currentMonth, currentYear, supabase, dashboardConfig, shiftConfig]);
50770
+ }, [activeTab, lineId, currentMonth, currentYear, supabase, dashboardConfig, shiftConfig, range.startKey, range.endKey, isFullRange]);
50771
+ const analysisMonthlyData = useMemo(() => {
50772
+ return filterDataByDateKeyRange(monthlyData, range);
50773
+ }, [monthlyData, range]);
50309
50774
  const lineInfo = useMemo(() => {
50310
50775
  if (!metrics2 || !lineDetails || !lineDetails.factory) {
50311
50776
  return null;
@@ -50532,6 +50997,21 @@ var KPIDetailView = ({
50532
50997
  const url = `/kpis/${lineId}?tab=overview&month=${currentMonth}&year=${currentYear}`;
50533
50998
  handleNavigate(url, { shallow: true });
50534
50999
  }, [lineId, currentMonth, currentYear, handleNavigate]);
51000
+ const buildMonthlyHistoryUrl = useCallback((month, year, rangeOverride) => {
51001
+ const bounds = getMonthKeyBounds(year, month);
51002
+ const activeRange = rangeOverride || range;
51003
+ const normalized = normalizeDateKeyRange(activeRange.startKey, activeRange.endKey, bounds.startKey, bounds.endKey);
51004
+ const fullRange = isFullMonthRange(normalized, year, month);
51005
+ const params = new URLSearchParams();
51006
+ params.set("tab", "monthly_history");
51007
+ params.set("month", month.toString());
51008
+ params.set("year", year.toString());
51009
+ if (!fullRange) {
51010
+ params.set("rangeStart", normalized.startKey);
51011
+ params.set("rangeEnd", normalized.endKey);
51012
+ }
51013
+ return `/kpis/${lineId}?${params.toString()}`;
51014
+ }, [lineId, range]);
50535
51015
  const handleMonthlyHistoryClick = useCallback(() => {
50536
51016
  trackCoreEvent("Monthly History Viewed", {
50537
51017
  source: "line_kpi",
@@ -50539,9 +51019,9 @@ var KPIDetailView = ({
50539
51019
  line_name: lineInfo?.line_name
50540
51020
  });
50541
51021
  setActiveTab("monthly_history");
50542
- const url = `/kpis/${lineId}?tab=monthly_history&month=${currentMonth}&year=${currentYear}`;
51022
+ const url = buildMonthlyHistoryUrl(currentMonth, currentYear);
50543
51023
  handleNavigate(url, { shallow: true });
50544
- }, [lineInfo, lineId, currentMonth, currentYear, handleNavigate]);
51024
+ }, [lineInfo, currentMonth, currentYear, handleNavigate, buildMonthlyHistoryUrl]);
50545
51025
  const handleBackClick = useCallback(() => {
50546
51026
  if (!urlDate && !urlShift) {
50547
51027
  trackCoreEvent("Dashboard Viewed", {
@@ -50555,10 +51035,16 @@ var KPIDetailView = ({
50555
51035
  } else if (backLinkUrl) {
50556
51036
  handleNavigate(backLinkUrl);
50557
51037
  } else {
50558
- const backUrl = urlDate || urlShift ? urlMonth && urlYear ? `/kpis/${lineId}?tab=monthly_history&month=${urlMonth}&year=${urlYear}` : `/kpis/${lineId}?tab=monthly_history&month=${currentMonth}&year=${currentYear}` : "/kpis";
51038
+ const targetMonth = urlMonth && typeof urlMonth === "string" ? parseInt(urlMonth, 10) : currentMonth;
51039
+ const targetYear = urlYear && typeof urlYear === "string" ? parseInt(urlYear, 10) : currentYear;
51040
+ const backRange = {
51041
+ startKey: typeof urlRangeStart === "string" ? urlRangeStart : range.startKey,
51042
+ endKey: typeof urlRangeEnd === "string" ? urlRangeEnd : range.endKey
51043
+ };
51044
+ const backUrl = urlDate || urlShift ? buildMonthlyHistoryUrl(targetMonth, targetYear, backRange) : "/kpis";
50559
51045
  handleNavigate(backUrl);
50560
51046
  }
50561
- }, [urlDate, urlShift, lineInfo, onBackClick, backLinkUrl, handleNavigate, urlMonth, urlYear, lineId, currentMonth, currentYear]);
51047
+ }, [urlDate, urlShift, lineInfo, onBackClick, backLinkUrl, handleNavigate, urlMonth, urlYear, currentMonth, currentYear, urlRangeStart, urlRangeEnd, range, buildMonthlyHistoryUrl]);
50562
51048
  const handleCalendarMonthChange = useCallback((newMonth, newYear) => {
50563
51049
  let validMonth = newMonth;
50564
51050
  let validYear = newYear;
@@ -50579,10 +51065,18 @@ var KPIDetailView = ({
50579
51065
  if (validYear > istYear || validYear === istYear && validMonth > istMonth) {
50580
51066
  return;
50581
51067
  }
51068
+ const nextBounds = getMonthKeyBounds(validYear, validMonth);
50582
51069
  setCurrentMonth(validMonth);
50583
51070
  setCurrentYear(validYear);
50584
- handleNavigate(`/kpis/${lineId}?tab=monthly_history&month=${validMonth}&year=${validYear}`, { shallow: true });
50585
- }, [currentMonth, currentYear, configuredTimezone, handleNavigate, lineId]);
51071
+ setRangeStart(nextBounds.startKey);
51072
+ setRangeEnd(nextBounds.endKey);
51073
+ handleNavigate(buildMonthlyHistoryUrl(validMonth, validYear, nextBounds), { shallow: true });
51074
+ }, [configuredTimezone, handleNavigate, lineId, buildMonthlyHistoryUrl]);
51075
+ const handleRangeChange = useCallback((nextRange) => {
51076
+ setRangeStart(nextRange.startKey);
51077
+ setRangeEnd(nextRange.endKey);
51078
+ handleNavigate(buildMonthlyHistoryUrl(currentMonth, currentYear, nextRange), { shallow: true });
51079
+ }, [currentMonth, currentYear, handleNavigate, buildMonthlyHistoryUrl]);
50586
51080
  if ((lineMetricsLoading || workspacesLoading || isShiftConfigLoading) && !lineInfo && !metrics2) {
50587
51081
  return /* @__PURE__ */ jsx(LoadingPage, { message: "Loading line metrics..." });
50588
51082
  }
@@ -50763,9 +51257,12 @@ var KPIDetailView = ({
50763
51257
  lineId,
50764
51258
  lineName: lineInfo?.line_name || "Line",
50765
51259
  monthlyData,
51260
+ analysisData: analysisMonthlyData,
50766
51261
  underperformingWorkspaces,
50767
51262
  selectedMonth: currentMonth,
50768
51263
  selectedYear: currentYear,
51264
+ rangeStart,
51265
+ rangeEnd,
50769
51266
  selectedShiftId
50770
51267
  }
50771
51268
  )
@@ -50814,10 +51311,15 @@ var KPIDetailView = ({
50814
51311
  lineId,
50815
51312
  underperformingWorkspaces,
50816
51313
  monthlyData,
51314
+ analysisData: analysisMonthlyData,
50817
51315
  month: currentMonth,
50818
51316
  year: currentYear,
51317
+ rangeStart,
51318
+ rangeEnd,
51319
+ timezone: configuredTimezone,
50819
51320
  selectedShiftId,
50820
51321
  onShiftChange: setSelectedShiftId,
51322
+ onRangeChange: handleRangeChange,
50821
51323
  availableShifts: shiftConfig?.shifts?.map((s) => ({ id: s.shiftId, name: s.shiftName })),
50822
51324
  onCalendarMonthChange: (date) => handleCalendarMonthChange(date.getMonth(), date.getFullYear()),
50823
51325
  isLoading: monthlyDataLoading
@@ -54526,6 +55028,8 @@ var WorkspaceDetailView = ({
54526
55028
  lineId,
54527
55029
  defaultTab,
54528
55030
  returnUrl,
55031
+ rangeStart: urlRangeStart,
55032
+ rangeEnd: urlRangeEnd,
54529
55033
  lineIds = { line1: "", line2: "" },
54530
55034
  selectedLineId,
54531
55035
  onNavigate,
@@ -54552,12 +55056,27 @@ var WorkspaceDetailView = ({
54552
55056
  const today = new Date((/* @__PURE__ */ new Date()).toLocaleString("en-US", { timeZone: timezone }));
54553
55057
  const [selectedMonth, setSelectedMonth] = useState(today.getMonth());
54554
55058
  const [selectedYear, setSelectedYear] = useState(today.getFullYear());
55059
+ const monthBounds = useMemo(() => getMonthKeyBounds(selectedYear, selectedMonth), [selectedYear, selectedMonth]);
55060
+ const [rangeStart, setRangeStart] = useState(monthBounds.startKey);
55061
+ const [rangeEnd, setRangeEnd] = useState(monthBounds.endKey);
54555
55062
  const [selectedShift, setSelectedShift] = useState(0);
54556
55063
  useEffect(() => {
54557
55064
  if (parsedShiftId !== void 0) {
54558
55065
  setSelectedShift(parsedShiftId);
54559
55066
  }
54560
55067
  }, [parsedShiftId]);
55068
+ const range = useMemo(() => ({ startKey: rangeStart, endKey: rangeEnd }), [rangeStart, rangeEnd]);
55069
+ const isFullRange = useMemo(() => isFullMonthRange(range, selectedYear, selectedMonth), [range, selectedYear, selectedMonth]);
55070
+ useEffect(() => {
55071
+ const normalized = normalizeDateKeyRange(
55072
+ typeof urlRangeStart === "string" ? urlRangeStart : monthBounds.startKey,
55073
+ typeof urlRangeEnd === "string" ? urlRangeEnd : monthBounds.endKey,
55074
+ monthBounds.startKey,
55075
+ monthBounds.endKey
55076
+ );
55077
+ setRangeStart(normalized.startKey);
55078
+ setRangeEnd(normalized.endKey);
55079
+ }, [urlRangeStart, urlRangeEnd, monthBounds.startKey, monthBounds.endKey]);
54561
55080
  const isHistoricView = Boolean(date && parsedShiftId !== void 0);
54562
55081
  const initialTab = getInitialTab(sourceType, defaultTab, fromMonthly, date);
54563
55082
  const [activeTab, setActiveTab] = useState(initialTab);
@@ -54780,6 +55299,9 @@ var WorkspaceDetailView = ({
54780
55299
  });
54781
55300
  }
54782
55301
  }, [activeTab, workspaceId, selectedMonth, selectedYear, supabase, dashboardConfig, handleMonthlyDataLoaded]);
55302
+ const analysisMonthlyData = useMemo(() => {
55303
+ return filterDataByDateKeyRange(monthlyData, range);
55304
+ }, [monthlyData, range]);
54783
55305
  const formattedWorkspaceName = displayName || formatWorkspaceName3(workspace?.workspace_name || "", effectiveLineId);
54784
55306
  const shouldShowCycleTimeChart = showCycleTimeChart ?? formattedWorkspaceName.startsWith("FINAL ASSY");
54785
55307
  const handleBackNavigation = () => {
@@ -54801,6 +55323,10 @@ var WorkspaceDetailView = ({
54801
55323
  const params = new URLSearchParams();
54802
55324
  params.set("fromMonthly", "true");
54803
55325
  params.set("shift", selectedShift.toString());
55326
+ if (!isFullRange) {
55327
+ params.set("rangeStart", range.startKey);
55328
+ params.set("rangeEnd", range.endKey);
55329
+ }
54804
55330
  if (effectiveLineId) {
54805
55331
  params.set("lineId", effectiveLineId);
54806
55332
  }
@@ -54813,6 +55339,10 @@ var WorkspaceDetailView = ({
54813
55339
  const params = new URLSearchParams();
54814
55340
  params.set("fromMonthly", "true");
54815
55341
  params.set("shift", selectedShift.toString());
55342
+ if (!isFullRange) {
55343
+ params.set("rangeStart", range.startKey);
55344
+ params.set("rangeEnd", range.endKey);
55345
+ }
54816
55346
  if (effectiveLineId) {
54817
55347
  params.set("lineId", effectiveLineId);
54818
55348
  }
@@ -55082,8 +55612,11 @@ var WorkspaceDetailView = ({
55082
55612
  workspaceId,
55083
55613
  workspaceName: workspace?.workspace_name || "",
55084
55614
  monthlyData,
55615
+ analysisData: analysisMonthlyData,
55085
55616
  selectedMonth,
55086
55617
  selectedYear,
55618
+ rangeStart,
55619
+ rangeEnd,
55087
55620
  selectedShiftId: selectedShift
55088
55621
  }
55089
55622
  ) })
@@ -55356,10 +55889,14 @@ var WorkspaceDetailView = ({
55356
55889
  WorkspaceMonthlyHistory,
55357
55890
  {
55358
55891
  data: monthlyData,
55892
+ analysisData: analysisMonthlyData,
55359
55893
  month: selectedMonth,
55360
55894
  year: selectedYear,
55361
55895
  workspaceId,
55362
55896
  selectedShiftId: selectedShift,
55897
+ rangeStart,
55898
+ rangeEnd,
55899
+ timezone,
55363
55900
  monthlyDataLoading,
55364
55901
  availableShifts: shiftConfig?.shifts?.map((s) => ({ id: s.shiftId, name: s.shiftName })),
55365
55902
  onDateSelect: (selectedDate, shiftId) => {
@@ -55370,6 +55907,10 @@ var WorkspaceDetailView = ({
55370
55907
  params.set("date", selectedDate);
55371
55908
  params.set("shift", shiftId.toString());
55372
55909
  params.set("fromMonthly", "true");
55910
+ if (!isFullRange) {
55911
+ params.set("rangeStart", range.startKey);
55912
+ params.set("rangeEnd", range.endKey);
55913
+ }
55373
55914
  if (effectiveLineId) {
55374
55915
  params.set("lineId", effectiveLineId);
55375
55916
  }
@@ -55379,8 +55920,15 @@ var WorkspaceDetailView = ({
55379
55920
  onMonthNavigate: (newMonth, newYear) => {
55380
55921
  setSelectedMonth(newMonth);
55381
55922
  setSelectedYear(newYear);
55923
+ const nextBounds = getMonthKeyBounds(newYear, newMonth);
55924
+ setRangeStart(nextBounds.startKey);
55925
+ setRangeEnd(nextBounds.endKey);
55382
55926
  },
55383
55927
  onShiftChange: setSelectedShift,
55928
+ onRangeChange: (nextRange) => {
55929
+ setRangeStart(nextRange.startKey);
55930
+ setRangeEnd(nextRange.endKey);
55931
+ },
55384
55932
  className: "w-full"
55385
55933
  }
55386
55934
  )
@@ -58070,12 +58618,13 @@ function shuffleArray(array) {
58070
58618
  }
58071
58619
  return shuffled;
58072
58620
  }
58073
- var CATEGORY_OPTIONS = [
58074
- { id: "all", label: "All" },
58075
- { id: "cycle_time", label: "Cycle Time" },
58076
- { id: "efficiency", label: "Efficiency" },
58077
- { id: "downtime", label: "Downtime" }
58078
- ];
58621
+ var buildInitials = (name) => {
58622
+ const parts = name.trim().split(/\s+/).filter(Boolean);
58623
+ if (parts.length === 0) return "NA";
58624
+ const first = parts[0]?.[0] || "";
58625
+ const second = parts.length > 1 ? parts[1]?.[0] || "" : "";
58626
+ return `${first}${second}`.toUpperCase();
58627
+ };
58079
58628
  var ClipVideoCarousel = ({ clips, clipsService }) => {
58080
58629
  const [currentIndex, setCurrentIndex] = useState(0);
58081
58630
  const [videos, setVideos] = useState([]);
@@ -58324,6 +58873,77 @@ var TableEvidence = ({ columns, rows }) => {
58324
58873
  /* @__PURE__ */ jsx("tbody", { children: rows.map((row, idx) => /* @__PURE__ */ jsx("tr", { className: "border-b border-gray-100 last:border-b-0", children: columns.map((col) => /* @__PURE__ */ jsx("td", { className: "px-3 py-2 text-gray-700 whitespace-nowrap", children: formatValue(row[col]) }, col)) }, idx)) })
58325
58874
  ] }) }) });
58326
58875
  };
58876
+ var EvidenceCarousel = ({ evidence, clipsService }) => {
58877
+ const [currentIndex, setCurrentIndex] = useState(0);
58878
+ const nextEvidence = () => {
58879
+ setCurrentIndex((prev) => (prev + 1) % evidence.length);
58880
+ };
58881
+ const prevEvidence = () => {
58882
+ setCurrentIndex((prev) => (prev - 1 + evidence.length) % evidence.length);
58883
+ };
58884
+ const ev = evidence[currentIndex];
58885
+ const isVideo = ev.type === "video_gallery";
58886
+ const isChart = ev.type === "bar_chart" || ev.type === "timeseries" || ev.type === "pie_chart";
58887
+ const title = ev.title || "Evidence";
58888
+ const clips = Array.isArray(ev.clips) ? ev.clips : [];
58889
+ const clipCount = clips.length;
58890
+ return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
58891
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between mb-2", children: [
58892
+ /* @__PURE__ */ jsxs("h4", { className: "text-xs font-semibold text-gray-500 uppercase tracking-wider flex items-center gap-2", children: [
58893
+ isVideo ? /* @__PURE__ */ jsx(PlayCircleIcon, { className: "w-4 h-4" }) : isChart ? /* @__PURE__ */ jsx(ChartBarIcon, { className: "w-4 h-4" }) : /* @__PURE__ */ jsx(ChartBarIcon, { className: "w-4 h-4" }),
58894
+ title
58895
+ ] }),
58896
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
58897
+ isVideo && clipCount > 1 && /* @__PURE__ */ jsxs("span", { className: "text-[10px] font-medium text-gray-500 bg-gray-100 px-1.5 py-0.5 rounded", children: [
58898
+ clipCount,
58899
+ " clips"
58900
+ ] }),
58901
+ evidence.length > 1 && /* @__PURE__ */ jsxs("span", { className: "text-[10px] font-medium text-gray-500 bg-gray-200 px-1.5 py-0.5 rounded", children: [
58902
+ currentIndex + 1,
58903
+ " / ",
58904
+ evidence.length
58905
+ ] })
58906
+ ] })
58907
+ ] }),
58908
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
58909
+ ev.type === "video_gallery" && /* @__PURE__ */ jsx(ClipVideoCarousel, { clips, clipsService }),
58910
+ ev.type === "bar_chart" && (Array.isArray(ev.x) && Array.isArray(ev.y) || Array.isArray(ev.data) && Array.isArray(ev.series)) && /* @__PURE__ */ jsx(
58911
+ BarChartEvidence,
58912
+ {
58913
+ x: ev.x,
58914
+ y: ev.y,
58915
+ data: ev.data,
58916
+ series: ev.series,
58917
+ unit: ev.unit,
58918
+ referenceLines: Array.isArray(ev.reference_lines) ? ev.reference_lines : void 0
58919
+ }
58920
+ ),
58921
+ ev.type === "pie_chart" && Array.isArray(ev.data) && /* @__PURE__ */ jsx(PieChartEvidence, { data: ev.data }),
58922
+ ev.type === "timeseries" && Array.isArray(ev.x) && Array.isArray(ev.y) && /* @__PURE__ */ jsx(LineChartEvidence, { x: ev.x, y: ev.y, unit: ev.unit }),
58923
+ ev.type === "table" && Array.isArray(ev.columns) && Array.isArray(ev.rows) && /* @__PURE__ */ jsx(TableEvidence, { columns: ev.columns, rows: ev.rows })
58924
+ ] }),
58925
+ evidence.length > 1 && /* @__PURE__ */ jsxs(Fragment, { children: [
58926
+ /* @__PURE__ */ jsx(
58927
+ "button",
58928
+ {
58929
+ onClick: prevEvidence,
58930
+ className: "absolute left-0 top-1/2 -translate-y-1/2 -translate-x-3 p-1.5 rounded-full bg-white border border-gray-200 shadow-sm hover:bg-gray-50 text-gray-600 transition-all z-10",
58931
+ "aria-label": "Previous evidence",
58932
+ children: /* @__PURE__ */ jsx(ChevronLeftIcon, { className: "w-4 h-4" })
58933
+ }
58934
+ ),
58935
+ /* @__PURE__ */ jsx(
58936
+ "button",
58937
+ {
58938
+ onClick: nextEvidence,
58939
+ className: "absolute right-0 top-1/2 -translate-y-1/2 translate-x-3 p-1.5 rounded-full bg-white border border-gray-200 shadow-sm hover:bg-gray-50 text-gray-600 transition-all z-10",
58940
+ "aria-label": "Next evidence",
58941
+ children: /* @__PURE__ */ jsx(ChevronRightIcon, { className: "w-4 h-4" })
58942
+ }
58943
+ )
58944
+ ] })
58945
+ ] });
58946
+ };
58327
58947
  var ImprovementCenterView = () => {
58328
58948
  const { navigate } = useNavigation();
58329
58949
  const supabase = useSupabase();
@@ -58331,12 +58951,16 @@ var ImprovementCenterView = () => {
58331
58951
  const dashboardConfig = useDashboardConfig();
58332
58952
  const entityConfig = useEntityConfig();
58333
58953
  const [currentDate, setCurrentDate] = useState(/* @__PURE__ */ new Date());
58334
- const [selectedCategory, setSelectedCategory] = useState("all");
58335
58954
  const [selectedLineId, setSelectedLineId] = useState("all");
58336
58955
  const [selectedStatus, setSelectedStatus] = useState("all");
58956
+ const [selectedShift, setSelectedShift] = useState("all");
58957
+ const [selectedWeeksRange, setSelectedWeeksRange] = useState("all");
58958
+ const [selectedMemberId, setSelectedMemberId] = useState("all");
58337
58959
  const [recommendations, setRecommendations] = useState([]);
58338
58960
  const [isLoading, setIsLoading] = useState(false);
58339
58961
  const [loadError, setLoadError] = useState(null);
58962
+ const [teamMembers, setTeamMembers] = useState([]);
58963
+ const [companyLines, setCompanyLines] = useState([]);
58340
58964
  const computeWeeksOpen = (firstSeenAt) => {
58341
58965
  if (!firstSeenAt) return void 0;
58342
58966
  const firstSeen = new Date(firstSeenAt);
@@ -58349,11 +58973,50 @@ var ImprovementCenterView = () => {
58349
58973
  return entityConfig.lines || entityConfig.lineNames || {};
58350
58974
  }, [entityConfig.lines, entityConfig.lineNames]);
58351
58975
  const configuredLineIds = useMemo(() => Object.keys(configuredLines), [configuredLines]);
58352
- const { accessibleLineIds } = useUserLineAccess(configuredLineIds);
58976
+ const companyLineIds = useMemo(() => companyLines.map((line) => line.id), [companyLines]);
58977
+ const assignedLineIds = useMemo(() => {
58978
+ if (!user) return [];
58979
+ if (user.role_level !== "supervisor") return [];
58980
+ const lines = user.properties?.line_id || user.properties?.line_ids || [];
58981
+ return Array.isArray(lines) ? lines : [];
58982
+ }, [user]);
58983
+ const assignedFactoryIds = useMemo(() => {
58984
+ if (!user) return [];
58985
+ if (user.role_level !== "plant_head") return [];
58986
+ const factories = user.properties?.factory_id || user.properties?.factory_ids || [];
58987
+ return Array.isArray(factories) ? factories : [];
58988
+ }, [user]);
58989
+ const plantHeadLineIds = useMemo(() => {
58990
+ if (user?.role_level !== "plant_head" || companyLines.length === 0) return [];
58991
+ const factorySet = new Set(assignedFactoryIds);
58992
+ return companyLines.filter((line) => line.factoryId === void 0 || line.factoryId === null || factorySet.has(line.factoryId)).map((line) => line.id);
58993
+ }, [assignedFactoryIds, companyLines, user?.role_level]);
58353
58994
  const scopeLineIds = useMemo(() => {
58354
- return accessibleLineIds.length > 0 ? accessibleLineIds : configuredLineIds;
58355
- }, [accessibleLineIds, configuredLineIds]);
58995
+ if (user?.role_level === "supervisor") {
58996
+ return assignedLineIds;
58997
+ }
58998
+ if (user?.role_level === "plant_head") {
58999
+ if (plantHeadLineIds.length > 0) return plantHeadLineIds;
59000
+ return companyLineIds.length > 0 ? companyLineIds : configuredLineIds;
59001
+ }
59002
+ if (companyLineIds.length > 0) return companyLineIds;
59003
+ return configuredLineIds;
59004
+ }, [
59005
+ assignedLineIds,
59006
+ companyLineIds,
59007
+ configuredLineIds,
59008
+ plantHeadLineIds,
59009
+ user?.role_level
59010
+ ]);
58356
59011
  const scopeLineIdsKey = useMemo(() => scopeLineIds.join(","), [scopeLineIds]);
59012
+ const lineNameById = useMemo(() => {
59013
+ const map = /* @__PURE__ */ new Map();
59014
+ companyLines.forEach((line) => map.set(line.id, line.name));
59015
+ Object.entries(configuredLines).forEach(([id3, name]) => {
59016
+ if (!map.has(id3)) map.set(id3, name);
59017
+ });
59018
+ return map;
59019
+ }, [companyLines, configuredLines]);
58357
59020
  const companyId = user?.company_id || entityConfig.companyId;
58358
59021
  const clipsService = useMemo(() => {
58359
59022
  try {
@@ -58362,6 +59025,58 @@ var ImprovementCenterView = () => {
58362
59025
  return null;
58363
59026
  }
58364
59027
  }, [dashboardConfig]);
59028
+ useEffect(() => {
59029
+ let cancelled = false;
59030
+ const loadTeamMembers = async () => {
59031
+ if (!supabase || !companyId) return;
59032
+ try {
59033
+ const userService2 = createUserManagementService(supabase);
59034
+ const supervisors = await userService2.getCompanyUsers(companyId, "supervisor");
59035
+ if (cancelled) return;
59036
+ const members = supervisors.map((user2) => {
59037
+ const rawName = user2.properties?.full_name || user2.email?.split("@")[0] || "Unknown";
59038
+ return {
59039
+ id: user2.user_id,
59040
+ name: rawName,
59041
+ role: user2.role_level,
59042
+ initials: buildInitials(rawName),
59043
+ email: user2.email
59044
+ };
59045
+ });
59046
+ members.sort((a, b) => a.name.localeCompare(b.name));
59047
+ setTeamMembers(members);
59048
+ } catch (error) {
59049
+ if (!cancelled) {
59050
+ console.error("[ImprovementCenterView] Failed to load supervisors", error);
59051
+ setTeamMembers([]);
59052
+ }
59053
+ }
59054
+ };
59055
+ loadTeamMembers();
59056
+ return () => {
59057
+ cancelled = true;
59058
+ };
59059
+ }, [supabase, companyId]);
59060
+ useEffect(() => {
59061
+ let cancelled = false;
59062
+ const loadLines = async () => {
59063
+ if (!supabase || !companyId) return;
59064
+ try {
59065
+ const linesService2 = new LinesService(supabase);
59066
+ const lines = await linesService2.getLinesByCompanyId(companyId);
59067
+ if (!cancelled) setCompanyLines(lines);
59068
+ } catch (error) {
59069
+ if (!cancelled) {
59070
+ console.error("[ImprovementCenterView] Failed to load lines", error);
59071
+ setCompanyLines([]);
59072
+ }
59073
+ }
59074
+ };
59075
+ loadLines();
59076
+ return () => {
59077
+ cancelled = true;
59078
+ };
59079
+ }, [supabase, companyId]);
58365
59080
  const nextMonth = () => {
58366
59081
  setCurrentDate(new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 1));
58367
59082
  };
@@ -58394,11 +59109,16 @@ var ImprovementCenterView = () => {
58394
59109
  const res = await fetchBackendJson(supabase, `/api/improvement-center/recommendations?${params.toString()}`);
58395
59110
  if (cancelled) return;
58396
59111
  let recs = res.recommendations || [];
58397
- recs = recs.map((r2) => ({
58398
- ...r2,
58399
- ticket_status: r2.issue_status === "resolved" ? "solved" : "active",
58400
- weeks_open: typeof r2.weeks_open === "number" ? r2.weeks_open : computeWeeksOpen(r2.first_seen_at) ?? 1
58401
- }));
59112
+ recs = recs.map((r2) => {
59113
+ const assignedUserIds = Array.isArray(r2.assigned_user_ids) ? r2.assigned_user_ids : r2.assigned_to_user_id ? [r2.assigned_to_user_id] : [];
59114
+ return {
59115
+ ...r2,
59116
+ ticket_status: r2.issue_status === "resolved" ? "solved" : "active",
59117
+ weeks_open: typeof r2.weeks_open === "number" ? r2.weeks_open : computeWeeksOpen(r2.first_seen_at) ?? 1,
59118
+ assigned_to_user_id: assignedUserIds[0],
59119
+ assigned_user_ids: assignedUserIds
59120
+ };
59121
+ });
58402
59122
  const allowed = new Set(scopeLineIds);
58403
59123
  setRecommendations(recs.filter((r2) => !r2.line_id || allowed.has(r2.line_id)));
58404
59124
  } catch (err) {
@@ -58414,37 +59134,80 @@ var ImprovementCenterView = () => {
58414
59134
  cancelled = true;
58415
59135
  };
58416
59136
  }, [supabase, companyId, scopeLineIdsKey, currentDate]);
59137
+ const teamMembersById = useMemo(() => {
59138
+ return new Map(teamMembers.map((member) => [member.id, member]));
59139
+ }, [teamMembers]);
58417
59140
  const filteredRecommendations = useMemo(() => {
58418
59141
  return recommendations.filter((rec) => {
58419
- if (selectedCategory !== "all" && rec.type !== selectedCategory) return false;
58420
59142
  if (selectedLineId !== "all" && rec.line_id !== selectedLineId) return false;
58421
59143
  if (selectedStatus === "resolved" && rec.ticket_status !== "solved") return false;
58422
59144
  if (selectedStatus === "unresolved" && rec.ticket_status === "solved") return false;
59145
+ if (selectedShift !== "all" && (rec.shift_label || `Shift ${rec.shift_id}`) !== selectedShift) return false;
59146
+ if (selectedWeeksRange !== "all") {
59147
+ const weeks = rec.weeks_open || 0;
59148
+ if (selectedWeeksRange === "1" && weeks !== 1) return false;
59149
+ if (selectedWeeksRange === "2" && weeks !== 2) return false;
59150
+ if (selectedWeeksRange === "3+" && weeks < 3) return false;
59151
+ }
59152
+ if (selectedMemberId !== "all" && !(rec.assigned_user_ids?.includes(selectedMemberId) || rec.assigned_to_user_id === selectedMemberId)) return false;
58423
59153
  return true;
58424
59154
  }).sort((a, b) => (b.weeks_open || 0) - (a.weeks_open || 0));
58425
- }, [recommendations, selectedCategory, selectedLineId, selectedStatus]);
59155
+ }, [recommendations, selectedLineId, selectedStatus, selectedShift, selectedWeeksRange, selectedMemberId]);
58426
59156
  const stats = useMemo(() => {
58427
- const total = recommendations.length;
58428
- const resolved = recommendations.filter((r2) => r2.ticket_status === "solved").length;
59157
+ const baseFiltered = recommendations.filter((rec) => {
59158
+ if (selectedLineId !== "all" && rec.line_id !== selectedLineId) return false;
59159
+ if (selectedShift !== "all" && (rec.shift_label || `Shift ${rec.shift_id}`) !== selectedShift) return false;
59160
+ if (selectedWeeksRange !== "all") {
59161
+ const weeks = rec.weeks_open || 0;
59162
+ if (selectedWeeksRange === "1" && weeks !== 1) return false;
59163
+ if (selectedWeeksRange === "2" && weeks !== 2) return false;
59164
+ if (selectedWeeksRange === "3+" && weeks < 3) return false;
59165
+ }
59166
+ if (selectedMemberId !== "all" && !(rec.assigned_user_ids?.includes(selectedMemberId) || rec.assigned_to_user_id === selectedMemberId)) return false;
59167
+ return true;
59168
+ });
59169
+ const total = baseFiltered.length;
59170
+ const resolved = baseFiltered.filter((r2) => r2.ticket_status === "solved").length;
58429
59171
  return {
58430
59172
  all: total,
58431
59173
  resolved,
58432
59174
  unresolved: total - resolved
58433
59175
  };
58434
- }, [recommendations]);
59176
+ }, [recommendations, selectedLineId, selectedShift, selectedWeeksRange, selectedMemberId]);
58435
59177
  const clearFilters = () => {
58436
- setSelectedCategory("all");
58437
59178
  setSelectedLineId("all");
58438
59179
  setSelectedStatus("all");
58439
- };
59180
+ setSelectedShift("all");
59181
+ setSelectedWeeksRange("all");
59182
+ setSelectedMemberId("all");
59183
+ };
59184
+ const shiftOptions = useMemo(() => {
59185
+ const shifts = /* @__PURE__ */ new Set();
59186
+ recommendations.forEach((r2) => {
59187
+ const label = r2.shift_label || (r2.shift_id !== void 0 ? `Shift ${r2.shift_id}` : null);
59188
+ if (label) shifts.add(label);
59189
+ });
59190
+ return ["all", ...Array.from(shifts)];
59191
+ }, [recommendations]);
59192
+ const weekOptions = [
59193
+ { id: "all", label: "Any Duration" },
59194
+ { id: "1", label: "1 Week" },
59195
+ { id: "2", label: "2 Weeks" },
59196
+ { id: "3+", label: "3+ Weeks" }
59197
+ ];
58440
59198
  const lineOptions = useMemo(() => {
58441
59199
  const options = [{ id: "all", label: "All Lines" }];
58442
59200
  scopeLineIds.forEach((lineId) => {
58443
- const lineName = configuredLines[lineId] || lineId;
59201
+ const lineName = lineNameById.get(lineId) || lineId;
58444
59202
  options.push({ id: lineId, label: lineName });
58445
59203
  });
58446
59204
  return options;
58447
- }, [scopeLineIds, configuredLines]);
59205
+ }, [scopeLineIds, lineNameById]);
59206
+ useEffect(() => {
59207
+ if (selectedLineId !== "all" && !scopeLineIds.includes(selectedLineId)) {
59208
+ setSelectedLineId("all");
59209
+ }
59210
+ }, [scopeLineIds, selectedLineId]);
58448
59211
  return /* @__PURE__ */ jsxs("div", { className: "min-h-screen bg-gray-50 flex flex-col", children: [
58449
59212
  /* @__PURE__ */ jsx("header", { className: "sticky top-0 z-10 bg-white border-b border-gray-200 flex-shrink-0", children: /* @__PURE__ */ jsx("div", { className: "px-4 sm:px-6 lg:px-8 py-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
58450
59213
  /* @__PURE__ */ jsx("div", { className: "flex items-center gap-4 min-w-[120px]", children: /* @__PURE__ */ jsx(
@@ -58519,15 +59282,41 @@ var ImprovementCenterView = () => {
58519
59282
  }
58520
59283
  )
58521
59284
  ] }),
58522
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 w-full md:w-auto", children: [
59285
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2 w-full md:w-auto", children: [
59286
+ /* @__PURE__ */ jsxs(
59287
+ "select",
59288
+ {
59289
+ value: selectedShift,
59290
+ onChange: (e) => setSelectedShift(e.target.value),
59291
+ className: "flex-1 md:flex-none appearance-none pl-3 pr-8 py-1.5 text-sm border border-gray-300 rounded-lg bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500 cursor-pointer text-gray-700 shadow-sm",
59292
+ style: { backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e")`, backgroundPosition: `right 0.5rem center`, backgroundRepeat: `no-repeat`, backgroundSize: `1.5em 1.5em` },
59293
+ children: [
59294
+ /* @__PURE__ */ jsx("option", { value: "all", children: "All Shifts" }),
59295
+ shiftOptions.filter((s) => s !== "all").map((shift) => /* @__PURE__ */ jsx("option", { value: shift, children: shift }, shift))
59296
+ ]
59297
+ }
59298
+ ),
58523
59299
  /* @__PURE__ */ jsx(
58524
59300
  "select",
58525
59301
  {
58526
- value: selectedCategory,
58527
- onChange: (e) => setSelectedCategory(e.target.value),
58528
- className: "w-full md:w-auto appearance-none pl-3 pr-8 py-1.5 text-sm border border-gray-300 rounded-lg bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500 cursor-pointer text-gray-700 shadow-sm",
59302
+ value: selectedWeeksRange,
59303
+ onChange: (e) => setSelectedWeeksRange(e.target.value),
59304
+ className: "flex-1 md:flex-none appearance-none pl-3 pr-8 py-1.5 text-sm border border-gray-300 rounded-lg bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500 cursor-pointer text-gray-700 shadow-sm",
59305
+ style: { backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e")`, backgroundPosition: `right 0.5rem center`, backgroundRepeat: `no-repeat`, backgroundSize: `1.5em 1.5em` },
59306
+ children: weekOptions.map((opt) => /* @__PURE__ */ jsx("option", { value: opt.id, children: opt.label }, opt.id))
59307
+ }
59308
+ ),
59309
+ /* @__PURE__ */ jsxs(
59310
+ "select",
59311
+ {
59312
+ value: selectedMemberId,
59313
+ onChange: (e) => setSelectedMemberId(e.target.value),
59314
+ className: "flex-1 md:flex-none appearance-none pl-3 pr-8 py-1.5 text-sm border border-gray-300 rounded-lg bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500 cursor-pointer text-gray-700 shadow-sm",
58529
59315
  style: { backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e")`, backgroundPosition: `right 0.5rem center`, backgroundRepeat: `no-repeat`, backgroundSize: `1.5em 1.5em` },
58530
- children: CATEGORY_OPTIONS.map((opt) => /* @__PURE__ */ jsx("option", { value: opt.id, children: opt.label }, opt.id))
59316
+ children: [
59317
+ /* @__PURE__ */ jsx("option", { value: "all", children: "All Members" }),
59318
+ teamMembers.map((member) => /* @__PURE__ */ jsx("option", { value: member.id, children: member.name }, member.id))
59319
+ ]
58531
59320
  }
58532
59321
  ),
58533
59322
  /* @__PURE__ */ jsx(
@@ -58535,7 +59324,7 @@ var ImprovementCenterView = () => {
58535
59324
  {
58536
59325
  value: selectedLineId,
58537
59326
  onChange: (e) => setSelectedLineId(e.target.value),
58538
- className: "w-full md:w-auto appearance-none pl-3 pr-8 py-1.5 text-sm border border-gray-300 rounded-lg bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500 cursor-pointer text-gray-700 shadow-sm",
59327
+ className: "flex-1 md:flex-none appearance-none pl-3 pr-8 py-1.5 text-sm border border-gray-300 rounded-lg bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500 cursor-pointer text-gray-700 shadow-sm",
58539
59328
  style: { backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e")`, backgroundPosition: `right 0.5rem center`, backgroundRepeat: `no-repeat`, backgroundSize: `1.5em 1.5em` },
58540
59329
  children: lineOptions.map((opt) => /* @__PURE__ */ jsx("option", { value: opt.id, children: opt.label }, opt.id))
58541
59330
  }
@@ -58550,29 +59339,47 @@ var ImprovementCenterView = () => {
58550
59339
  animate: { opacity: 1, y: 0 },
58551
59340
  transition: { delay: index * 0.1 },
58552
59341
  className: `bg-white rounded-xl shadow-sm border overflow-hidden ${rec.ticket_status === "solved" ? "border-green-200" : "border-gray-200"}`,
58553
- children: /* @__PURE__ */ jsx("div", { className: "p-6", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col md:flex-row gap-6", children: [
59342
+ children: /* @__PURE__ */ jsx("div", { className: "p-6 relative", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col md:flex-row gap-6", children: [
58554
59343
  /* @__PURE__ */ jsxs("div", { className: "flex-1 space-y-4", children: [
58555
59344
  /* @__PURE__ */ jsx("div", { className: "flex items-start justify-between", children: /* @__PURE__ */ jsxs("div", { className: "space-y-3 w-full", children: [
58556
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
58557
- /* @__PURE__ */ jsx("span", { className: `inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${rec.type === "cycle_time" ? "bg-blue-100 text-blue-800" : rec.type === "efficiency" ? "bg-orange-100 text-orange-800" : "bg-gray-100 text-gray-800"}`, children: rec.type.replace("_", " ").toUpperCase() }),
58558
- (rec.shift_label || rec.shift_id !== void 0) && /* @__PURE__ */ jsx("span", { className: "inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-700", children: rec.shift_label || `Shift ${rec.shift_id}` }),
58559
- rec.ticket_status === "solved" ? /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800", children: [
59345
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
59346
+ rec.ticket_status === "solved" ? /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium bg-emerald-50 text-emerald-700 border border-emerald-100", children: [
58560
59347
  /* @__PURE__ */ jsx(CheckCircleIcon, { className: "w-3.5 h-3.5" }),
58561
59348
  "Resolved"
58562
- ] }) : /* @__PURE__ */ jsxs("span", { className: `inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium border ${(rec.weeks_open || 0) > 2 ? "bg-red-50 text-red-700 border-red-200" : "bg-amber-50 text-amber-700 border-amber-200"}`, children: [
59349
+ ] }) : /* @__PURE__ */ jsxs("span", { className: `inline-flex items-center gap-1.5 px-2.5 py-0.5 rounded-full text-xs font-medium border ${(rec.weeks_open || 0) > 2 ? "bg-red-50 text-red-700 border-red-100" : "bg-amber-50 text-amber-700 border-amber-100"}`, children: [
58563
59350
  /* @__PURE__ */ jsx(ClockIcon, { className: "w-3.5 h-3.5" }),
58564
59351
  "Open for ",
58565
59352
  rec.weeks_open || 1,
58566
59353
  " week",
58567
59354
  (rec.weeks_open || 1) !== 1 ? "s" : ""
59355
+ ] }),
59356
+ rec.assigned_user_ids && rec.assigned_user_ids.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
59357
+ /* @__PURE__ */ jsx("div", { className: "h-3 w-px bg-gray-200" }),
59358
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-3", children: rec.assigned_user_ids.map((uid) => {
59359
+ const user2 = teamMembersById.get(uid);
59360
+ if (!user2) {
59361
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
59362
+ /* @__PURE__ */ jsx("div", { className: "w-5 h-5 rounded-full bg-gray-100 text-gray-500 flex items-center justify-center text-[9px] font-bold border border-gray-200", children: "??" }),
59363
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-500", children: "Unknown" })
59364
+ ] }, uid);
59365
+ }
59366
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
59367
+ /* @__PURE__ */ jsx("div", { className: "w-5 h-5 rounded-full bg-gray-100 text-gray-600 flex items-center justify-center text-[9px] font-bold border border-gray-200", children: user2.initials }),
59368
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-gray-600", children: user2.name })
59369
+ ] }, user2.id);
59370
+ }) })
58568
59371
  ] })
58569
59372
  ] }),
58570
59373
  /* @__PURE__ */ jsxs("div", { children: [
58571
- /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-gray-900", children: rec.title }),
58572
- /* @__PURE__ */ jsxs("p", { className: "text-sm font-medium text-gray-500 mt-1", children: [
59374
+ /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-gray-900 pr-12", children: rec.title }),
59375
+ /* @__PURE__ */ jsxs("p", { className: "text-sm font-medium text-gray-500 mt-1 flex items-center gap-2", children: [
58573
59376
  rec.location,
58574
59377
  " \u2022 ",
58575
- rec.line
59378
+ rec.line,
59379
+ (rec.shift_label || rec.shift_id !== void 0) && /* @__PURE__ */ jsxs(Fragment, { children: [
59380
+ /* @__PURE__ */ jsx("span", { children: "\u2022" }),
59381
+ /* @__PURE__ */ jsx("span", { className: "uppercase tracking-wide text-xs pt-0.5 text-gray-500 font-medium", children: rec.shift_label || `Shift ${rec.shift_id}` })
59382
+ ] })
58576
59383
  ] })
58577
59384
  ] })
58578
59385
  ] }) }),
@@ -58583,40 +59390,14 @@ var ImprovementCenterView = () => {
58583
59390
  rec.impact
58584
59391
  ] }) })
58585
59392
  ] }),
58586
- /* @__PURE__ */ jsx("div", { className: "w-full md:w-1/2 lg:w-5/12 bg-gray-50 rounded-lg p-4 border border-gray-100", children: Array.isArray(rec.evidence) && rec.evidence.length > 0 ? /* @__PURE__ */ jsx("div", { className: "space-y-4", children: rec.evidence.map((ev, idx) => {
58587
- const isVideo = ev.type === "video_gallery";
58588
- const isChart = ev.type === "bar_chart" || ev.type === "timeseries" || ev.type === "pie_chart";
58589
- const title = ev.title || "Evidence";
58590
- const clips = Array.isArray(ev.clips) ? ev.clips : [];
58591
- const clipCount = clips.length;
58592
- return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
58593
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
58594
- /* @__PURE__ */ jsxs("h4", { className: "text-xs font-semibold text-gray-500 uppercase tracking-wider flex items-center gap-2", children: [
58595
- isVideo ? /* @__PURE__ */ jsx(PlayCircleIcon, { className: "w-4 h-4" }) : isChart ? /* @__PURE__ */ jsx(ChartBarIcon, { className: "w-4 h-4" }) : /* @__PURE__ */ jsx(ChartBarIcon, { className: "w-4 h-4" }),
58596
- title
58597
- ] }),
58598
- isVideo && clipCount > 1 && /* @__PURE__ */ jsxs("span", { className: "text-[10px] font-medium text-gray-500 bg-gray-100 px-1.5 py-0.5 rounded", children: [
58599
- clipCount,
58600
- " clips"
58601
- ] })
58602
- ] }),
58603
- ev.type === "video_gallery" && /* @__PURE__ */ jsx(ClipVideoCarousel, { clips, clipsService }),
58604
- ev.type === "bar_chart" && (Array.isArray(ev.x) && Array.isArray(ev.y) || Array.isArray(ev.data) && Array.isArray(ev.series)) && /* @__PURE__ */ jsx(
58605
- BarChartEvidence,
58606
- {
58607
- x: ev.x,
58608
- y: ev.y,
58609
- data: ev.data,
58610
- series: ev.series,
58611
- unit: ev.unit,
58612
- referenceLines: Array.isArray(ev.reference_lines) ? ev.reference_lines : void 0
58613
- }
58614
- ),
58615
- ev.type === "pie_chart" && Array.isArray(ev.data) && /* @__PURE__ */ jsx(PieChartEvidence, { data: ev.data }),
58616
- ev.type === "timeseries" && Array.isArray(ev.x) && Array.isArray(ev.y) && /* @__PURE__ */ jsx(LineChartEvidence, { x: ev.x, y: ev.y, unit: ev.unit }),
58617
- ev.type === "table" && Array.isArray(ev.columns) && Array.isArray(ev.rows) && /* @__PURE__ */ jsx(TableEvidence, { columns: ev.columns, rows: ev.rows })
58618
- ] }, `${rec.id}-ev-${idx}`);
58619
- }) }) : /* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children: isLoading ? "Loading evidence\u2026" : loadError ? loadError : "No evidence available" }) })
59393
+ /* @__PURE__ */ jsx("div", { className: "w-full md:w-1/2 lg:w-5/12 bg-gray-50 rounded-lg p-4 border border-gray-100", children: Array.isArray(rec.evidence) && rec.evidence.length > 0 ? /* @__PURE__ */ jsx(
59394
+ EvidenceCarousel,
59395
+ {
59396
+ evidence: rec.evidence,
59397
+ recId: rec.id,
59398
+ clipsService
59399
+ }
59400
+ ) : /* @__PURE__ */ jsx("div", { className: "text-xs text-gray-500", children: isLoading ? "Loading evidence\u2026" : loadError ? loadError : "No evidence available" }) })
58620
59401
  ] }) })
58621
59402
  },
58622
59403
  rec.id
@@ -58625,8 +59406,8 @@ var ImprovementCenterView = () => {
58625
59406
  /* @__PURE__ */ jsxs("div", { className: "text-center py-16 bg-white rounded-xl border border-gray-200 shadow-sm", children: [
58626
59407
  /* @__PURE__ */ jsx("div", { className: "mx-auto flex items-center justify-center w-16 h-16 rounded-full bg-green-50 mb-4", children: /* @__PURE__ */ jsx(CheckCircleIcon, { className: "w-8 h-8 text-green-500" }) }),
58627
59408
  /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-gray-900", children: "No tickets found" }),
58628
- /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-gray-500 max-w-md mx-auto", children: selectedCategory !== "all" || selectedLineId !== "all" || selectedStatus !== "all" ? "Try adjusting your filters to see more results." : "All monitored long-term patterns were evaluated and remained within limits. This is a success state!" }),
58629
- (selectedCategory !== "all" || selectedLineId !== "all" || selectedStatus !== "all") && /* @__PURE__ */ jsx(
59409
+ /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-gray-500 max-w-md mx-auto", children: selectedLineId !== "all" || selectedStatus !== "all" || selectedShift !== "all" || selectedWeeksRange !== "all" || selectedMemberId !== "all" ? "Try adjusting your filters to see more results." : "All monitored long-term patterns were evaluated and remained within limits. This is a success state!" }),
59410
+ (selectedLineId !== "all" || selectedStatus !== "all" || selectedShift !== "all" || selectedWeeksRange !== "all" || selectedMemberId !== "all") && /* @__PURE__ */ jsx(
58630
59411
  "button",
58631
59412
  {
58632
59413
  onClick: clearFilters,
@@ -59097,4 +59878,4 @@ var streamProxyConfig = {
59097
59878
  }
59098
59879
  };
59099
59880
 
59100
- export { ACTION_NAMES, AIAgentView_default as AIAgentView, AcceptInvite, AcceptInviteView_default as AcceptInviteView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthService, AuthenticatedBottleneckClipsView, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedTicketsView, AuthenticatedWorkspaceHealthView, AxelNotificationPopup, AxelOrb, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, BottleneckClipsModal, BottleneckClipsView_default as BottleneckClipsView, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, ChangeRoleDialog, ClipFilterProvider, CompactWorkspaceHealthCard, ConfirmRemoveUserDialog, CongratulationsOverlay, CroppedHlsVideoPlayer, CroppedVideoPlayer, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_HOME_VIEW_CONFIG, DEFAULT_MAP_VIEW_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_SHIFT_DATA, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, DetailedHealthStatus, DiagnosisVideoModal, EmptyStateMessage, EncouragementOverlay, FactoryAssignmentDropdown, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthDateShiftSelector, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HlsVideoPlayer, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, ISTTimer_default as ISTTimer, ImprovementCenterView_default as ImprovementCenterView, InlineEditableText, InteractiveOnboardingTour, InvitationService, InvitationsTable, InviteUserDialog, 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, LineAssignmentDropdown, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LinesService, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, Logo, MainLayout, MapGridView, MetricCard_default as MetricCard, MinimalOnboardingPopup, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PlayPauseIndicator, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, RegistryProvider, RoleBadge, S3ClipsSupabaseService as S3ClipsService, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SessionTracker, SessionTrackingContext, SessionTrackingProvider, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SignupWithInvitation, SilentErrorBoundary, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, TeamManagementView_default as TeamManagementView, TeamUsagePdfGenerator, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TicketsView_default as TicketsView, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UserManagementService, UserManagementTable, UserService, UserUsageDetailModal, UserUsageStats, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, aggregateKPIsFromLineMetricsRows, apiUtils, areAllLinesOnSameShift, authCoreService, authOTPService, authRateLimitService, buildKPIsFromLineMetricsRow, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearWorkspaceDisplayNamesCache, cn, createDefaultKPIs, createInvitationService, createLinesService, createSessionTracker, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserManagementService, createUserService, dashboardService, deleteThread, fetchIdleTimeReasons, forceRefreshWorkspaceDisplayNames, formatDateInZone, formatDateTimeInZone, formatDuration, formatISTDate, formatIdleTime, formatReasonLabel, formatRelativeTime, formatTimeInZone, fromUrlFriendlyName, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAllWorkspaceDisplayNamesSnapshot, getAnonClient, getAvailableShiftIds, getBrowserName, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentShiftForLine, getCurrentTimeInZone, getDashboardHeaderTimeInZone, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getNextUpdateInterval, getOperationalDate, getReasonColor, getS3SignedUrl, getS3VideoSrc, getShiftData, getShiftNameById, getShortShiftName, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUniformShiftGroup, getUserThreads, getUserThreadsPaginated, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, groupLinesByShift, hasAnyShiftData, identifyCoreUser, initializeCoreMixpanel, isLegacyConfiguration, isPrefetchError, isSafari, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, optifyeAgentClient, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, subscribeWorkspaceDisplayNames, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, transformToChartData, updateThreadTitle, upsertWorkspaceDisplayNameInCache, useAccessControl, useActiveBreaks, useActiveLineId, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useAxelNotifications, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useCompanyUsersUsage, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useDynamicShiftConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHasLineAccess, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useIdleTimeReasons, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineShiftConfig, useLineSupervisor, useLineWorkspaceMetrics, useLines, useMessages, useMetrics, useMultiLineShiftConfigs, useNavigation, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useSessionKeepAlive, useSessionTracking, useSessionTrackingContext, useShiftConfig, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useSupervisorsByLineIds, useTargets, useTeamManagementPermissions, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useUserLineAccess, useUserUsage, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealthById, useWorkspaceHealthStatus, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, useWorkspaceUptimeTimeline, userService, videoPrefetchManager, videoPreloader, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };
59881
+ export { ACTION_NAMES, AIAgentView_default as AIAgentView, AcceptInvite, AcceptInviteView_default as AcceptInviteView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthService, AuthenticatedBottleneckClipsView, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedTicketsView, AuthenticatedWorkspaceHealthView, AxelNotificationPopup, AxelOrb, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, BottleneckClipsModal, BottleneckClipsView_default as BottleneckClipsView, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, ChangeRoleDialog, ClipFilterProvider, CompactWorkspaceHealthCard, ConfirmRemoveUserDialog, CongratulationsOverlay, CroppedHlsVideoPlayer, CroppedVideoPlayer, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_HOME_VIEW_CONFIG, DEFAULT_MAP_VIEW_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_SHIFT_DATA, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, DetailedHealthStatus, DiagnosisVideoModal, EmptyStateMessage, EncouragementOverlay, FactoryAssignmentDropdown, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthDateShiftSelector, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HlsVideoPlayer, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, ISTTimer_default as ISTTimer, ImprovementCenterView_default as ImprovementCenterView, InlineEditableText, InteractiveOnboardingTour, InvitationService, InvitationsTable, InviteUserDialog, 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, LineAssignmentDropdown, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LinesService, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, Logo, MainLayout, MapGridView, MetricCard_default as MetricCard, MinimalOnboardingPopup, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PlayPauseIndicator, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, RegistryProvider, RoleBadge, S3ClipsSupabaseService as S3ClipsService, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SessionTracker, SessionTrackingContext, SessionTrackingProvider, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SignupWithInvitation, SilentErrorBoundary, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, TeamManagementView_default as TeamManagementView, TeamUsagePdfGenerator, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TicketsView_default as TicketsView, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UserManagementService, UserManagementTable, UserService, UserUsageDetailModal, UserUsageStats, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, aggregateKPIsFromLineMetricsRows, apiUtils, areAllLinesOnSameShift, authCoreService, authOTPService, authRateLimitService, buildDateKey, buildKPIsFromLineMetricsRow, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearWorkspaceDisplayNamesCache, cn, createDefaultKPIs, createInvitationService, createLinesService, createSessionTracker, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserManagementService, createUserService, dashboardService, deleteThread, fetchIdleTimeReasons, filterDataByDateKeyRange, forceRefreshWorkspaceDisplayNames, formatDateInZone, formatDateKeyForDisplay, formatDateTimeInZone, formatDuration, formatISTDate, formatIdleTime, formatRangeLabel, formatReasonLabel, formatRelativeTime, formatTimeInZone, fromUrlFriendlyName, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAllWorkspaceDisplayNamesSnapshot, getAnonClient, getAvailableShiftIds, getBrowserName, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentShiftForLine, getCurrentTimeInZone, getDashboardHeaderTimeInZone, getDateKeyFromDate, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getMonthKeyBounds, getMonthWeekRanges, getNextUpdateInterval, getOperationalDate, getReasonColor, getS3SignedUrl, getS3VideoSrc, getShiftData, getShiftNameById, getShortShiftName, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUniformShiftGroup, getUserThreads, getUserThreadsPaginated, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, groupLinesByShift, hasAnyShiftData, identifyCoreUser, initializeCoreMixpanel, isFullMonthRange, isLegacyConfiguration, isPrefetchError, isSafari, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, normalizeDateKeyRange, optifyeAgentClient, parseDateKeyToDate, parseS3Uri, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, s3VideoPreloader, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, subscribeWorkspaceDisplayNames, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, transformToChartData, updateThreadTitle, upsertWorkspaceDisplayNameInCache, useAccessControl, useActiveBreaks, useActiveLineId, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useAxelNotifications, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useCompanyUsersUsage, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useDynamicShiftConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHasLineAccess, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useIdleTimeReasons, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineShiftConfig, useLineSupervisor, useLineWorkspaceMetrics, useLines, useMessages, useMetrics, useMultiLineShiftConfigs, useNavigation, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useSessionKeepAlive, useSessionTracking, useSessionTrackingContext, useShiftConfig, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useSupervisorsByLineIds, useTargets, useTeamManagementPermissions, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useUserLineAccess, useUserUsage, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealthById, useWorkspaceHealthStatus, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, useWorkspaceUptimeTimeline, userService, videoPrefetchManager, videoPreloader, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };