@j3m-quantum/ui 1.11.2 → 2.1.0

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.cjs CHANGED
@@ -123,6 +123,53 @@ function useIsMobile() {
123
123
  function cn(...inputs) {
124
124
  return tailwindMerge.twMerge(clsx.clsx(inputs));
125
125
  }
126
+ var statusCellFillClasses = {
127
+ // Green - complete/valid/ready state
128
+ complete: {
129
+ bg: "bg-green-50/50 dark:bg-green-950/30"},
130
+ ready: {
131
+ combined: "border-l-[3px] border-l-green-500 bg-green-50/50 dark:bg-green-950/30"
132
+ },
133
+ // Amber - warning/attention state
134
+ warning: {
135
+ bg: "bg-amber-50/50 dark:bg-amber-950/30"},
136
+ // Red - critical/risk state
137
+ critical: {
138
+ bg: "bg-red-50/50 dark:bg-red-950/30"},
139
+ risk: {
140
+ combined: "border-l-[3px] border-l-red-500 bg-red-50/50 dark:bg-red-950/30"
141
+ },
142
+ // Grey - normal/pending/neutral state (on track but not complete)
143
+ normal: {
144
+ combined: "border-l-[3px] border-l-muted-foreground/40 bg-muted/30 dark:bg-muted/20"
145
+ },
146
+ // Shipped - distinct muted state with green accent (greyed out + check)
147
+ shipped: {
148
+ combined: "border-l-[3px] border-l-green-500/50 bg-muted/50 dark:bg-muted/30"
149
+ }
150
+ };
151
+ var statusCellTextClasses = {
152
+ ready: {
153
+ title: "text-foreground",
154
+ subtitle: "text-green-700/80 dark:text-green-300/80",
155
+ icon: "text-green-600 dark:text-green-400"
156
+ },
157
+ risk: {
158
+ title: "text-foreground",
159
+ subtitle: "text-red-700/80 dark:text-red-300/80",
160
+ icon: "text-red-600 dark:text-red-400"
161
+ },
162
+ normal: {
163
+ title: "text-foreground",
164
+ subtitle: "text-muted-foreground",
165
+ icon: "text-muted-foreground"
166
+ },
167
+ shipped: {
168
+ title: "text-muted-foreground",
169
+ subtitle: "text-muted-foreground/70",
170
+ icon: "text-green-600/70 dark:text-green-400/70"
171
+ }
172
+ };
126
173
  var buttonVariants = classVarianceAuthority.cva(
127
174
  "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
128
175
  {
@@ -1597,6 +1644,166 @@ function FieldError({
1597
1644
  }
1598
1645
  );
1599
1646
  }
1647
+ var iconMap = {
1648
+ factory: lucideReact.Factory,
1649
+ truck: lucideReact.Truck,
1650
+ check: lucideReact.Check,
1651
+ alert: lucideReact.AlertTriangle,
1652
+ trending: lucideReact.TrendingUp
1653
+ };
1654
+ var statusColorMap = {
1655
+ normal: "text-muted-foreground",
1656
+ success: "text-green-600 dark:text-green-400",
1657
+ warning: "text-amber-600 dark:text-amber-400",
1658
+ critical: "text-red-600 dark:text-red-400"
1659
+ };
1660
+ function InsightBar({ metrics, className }) {
1661
+ return /* @__PURE__ */ jsxRuntime.jsx(
1662
+ "div",
1663
+ {
1664
+ "data-slot": "insight-bar",
1665
+ className: cn(
1666
+ "flex flex-wrap items-center gap-6 px-4 py-3",
1667
+ "border-b border-border bg-muted/20",
1668
+ className
1669
+ ),
1670
+ children: metrics.map((metric) => {
1671
+ const Icon2 = metric.icon ? iconMap[metric.icon] : null;
1672
+ const statusColor = metric.status ? statusColorMap[metric.status] : "text-foreground";
1673
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1674
+ "div",
1675
+ {
1676
+ className: "flex items-center gap-2",
1677
+ children: [
1678
+ Icon2 && /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: cn("h-4 w-4", statusColor) }),
1679
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-1.5", children: [
1680
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
1681
+ "text-lg font-semibold tabular-nums",
1682
+ statusColor
1683
+ ), children: metric.isPercentage ? `${Math.round(metric.value)}%` : metric.value.toLocaleString(void 0, { maximumFractionDigits: 1 }) }),
1684
+ metric.unit && !metric.isPercentage && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: metric.unit }),
1685
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: metric.label })
1686
+ ] })
1687
+ ]
1688
+ },
1689
+ metric.key
1690
+ );
1691
+ })
1692
+ }
1693
+ );
1694
+ }
1695
+ var iconMap2 = {
1696
+ factory: lucideReact.Factory,
1697
+ truck: lucideReact.Truck,
1698
+ check: lucideReact.Check
1699
+ };
1700
+ var statusBgMap = {
1701
+ normal: "bg-muted/30",
1702
+ complete: statusCellFillClasses.complete.bg,
1703
+ warning: statusCellFillClasses.warning.bg,
1704
+ critical: statusCellFillClasses.critical.bg
1705
+ };
1706
+ var statusTextMap = {
1707
+ normal: "text-muted-foreground",
1708
+ complete: "text-green-700 dark:text-green-300",
1709
+ warning: "text-amber-700 dark:text-amber-300",
1710
+ critical: "text-red-700 dark:text-red-300"
1711
+ };
1712
+ function ColumnSummaryCell({
1713
+ data,
1714
+ widthClass = "min-w-[120px]",
1715
+ className
1716
+ }) {
1717
+ const status = data.status || "normal";
1718
+ const bgClass = statusBgMap[status];
1719
+ const textClass = statusTextMap[status];
1720
+ const isClickable = !!data.onClick;
1721
+ const PrimaryIcon = data.primary?.icon ? iconMap2[data.primary.icon] : null;
1722
+ const SecondaryIcon = data.secondary?.icon ? iconMap2[data.secondary.icon] : null;
1723
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1724
+ "div",
1725
+ {
1726
+ role: isClickable ? "button" : void 0,
1727
+ tabIndex: isClickable ? 0 : void 0,
1728
+ onClick: data.onClick,
1729
+ onKeyDown: (e) => {
1730
+ if (isClickable && (e.key === "Enter" || e.key === " ")) {
1731
+ e.preventDefault();
1732
+ data.onClick?.();
1733
+ }
1734
+ },
1735
+ className: cn(
1736
+ // Base sizing
1737
+ widthClass,
1738
+ "flex flex-col gap-0.5 px-2 py-1.5",
1739
+ // Background based on status
1740
+ bgClass,
1741
+ // Clickable styles
1742
+ isClickable && "cursor-pointer hover:brightness-95 transition-all",
1743
+ isClickable && "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary",
1744
+ className
1745
+ ),
1746
+ children: [
1747
+ data.primary && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
1748
+ PrimaryIcon && /* @__PURE__ */ jsxRuntime.jsx(PrimaryIcon, { className: cn("h-3 w-3", textClass) }),
1749
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-xs font-medium tabular-nums", textClass), children: data.primary.value.toLocaleString(void 0, { maximumFractionDigits: 1 }) }),
1750
+ data.primary.unit && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: data.primary.unit })
1751
+ ] }),
1752
+ data.secondary && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
1753
+ SecondaryIcon && /* @__PURE__ */ jsxRuntime.jsx(SecondaryIcon, { className: cn("h-3 w-3 text-muted-foreground") }),
1754
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] text-muted-foreground tabular-nums", children: [
1755
+ data.secondary.value.toLocaleString(void 0, { maximumFractionDigits: 1 }),
1756
+ data.secondary.unit && ` ${data.secondary.unit}`
1757
+ ] })
1758
+ ] }),
1759
+ data.tertiary && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] text-muted-foreground/70 tabular-nums", children: [
1760
+ data.tertiary.value.toLocaleString(void 0, { maximumFractionDigits: 1 }),
1761
+ data.tertiary.unit && ` ${data.tertiary.unit}`
1762
+ ] }) })
1763
+ ]
1764
+ }
1765
+ );
1766
+ }
1767
+ function ColumnSummaryStrip({
1768
+ columns,
1769
+ columnWidthClass = "min-w-[120px]",
1770
+ rowHeaderLabel,
1771
+ rowHeaderWidthClass = "min-w-[200px] w-[200px]",
1772
+ className
1773
+ }) {
1774
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1775
+ "div",
1776
+ {
1777
+ "data-slot": "column-summary-strip",
1778
+ className: cn(
1779
+ "flex border-b border-border",
1780
+ className
1781
+ ),
1782
+ children: [
1783
+ rowHeaderLabel !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(
1784
+ "div",
1785
+ {
1786
+ className: cn(
1787
+ "flex items-center px-3 py-1.5",
1788
+ "bg-muted/30 border-r border-border",
1789
+ "sticky left-0 z-10",
1790
+ rowHeaderWidthClass
1791
+ ),
1792
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium text-muted-foreground uppercase tracking-wide", children: rowHeaderLabel })
1793
+ }
1794
+ ),
1795
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex", children: columns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(
1796
+ ColumnSummaryCell,
1797
+ {
1798
+ data: column,
1799
+ widthClass: columnWidthClass
1800
+ },
1801
+ column.columnKey
1802
+ )) })
1803
+ ]
1804
+ }
1805
+ );
1806
+ }
1600
1807
  var cardVariants = classVarianceAuthority.cva(
1601
1808
  "rounded-xl text-card-foreground",
1602
1809
  {
@@ -3459,6 +3666,144 @@ function CircularProgress({
3459
3666
  }
3460
3667
  );
3461
3668
  }
3669
+ function getVariantFromProgress(value) {
3670
+ if (value >= 100) return "complete";
3671
+ if (value >= 50) return "normal";
3672
+ if (value > 0) return "warning";
3673
+ return "critical";
3674
+ }
3675
+ function getStatusColors(variant) {
3676
+ switch (variant) {
3677
+ case "complete":
3678
+ return {
3679
+ track: "bg-green-500/20 dark:bg-green-500/10",
3680
+ fill: "bg-green-500",
3681
+ text: "text-green-600 dark:text-green-400",
3682
+ icon: "text-green-600 dark:text-green-400"
3683
+ };
3684
+ case "normal":
3685
+ return {
3686
+ track: "bg-green-500/20 dark:bg-green-500/10",
3687
+ fill: "bg-green-500",
3688
+ text: "text-green-600 dark:text-green-400",
3689
+ icon: "text-green-600 dark:text-green-400"
3690
+ };
3691
+ case "warning":
3692
+ return {
3693
+ track: "bg-amber-500/20 dark:bg-amber-500/10",
3694
+ fill: "bg-amber-500",
3695
+ text: "text-amber-600 dark:text-amber-400",
3696
+ icon: "text-amber-600 dark:text-amber-400"
3697
+ };
3698
+ case "critical":
3699
+ return {
3700
+ track: "bg-red-500/20 dark:bg-red-500/10",
3701
+ fill: "bg-red-500",
3702
+ text: "text-red-600 dark:text-red-400",
3703
+ icon: "text-red-600 dark:text-red-400"
3704
+ };
3705
+ }
3706
+ }
3707
+ function getSizeClasses(size) {
3708
+ switch (size) {
3709
+ case "sm":
3710
+ return {
3711
+ bar: "h-1",
3712
+ text: "text-[10px]",
3713
+ icon: "h-3 w-3",
3714
+ gap: "gap-1"
3715
+ };
3716
+ case "lg":
3717
+ return {
3718
+ bar: "h-3",
3719
+ text: "text-sm",
3720
+ icon: "h-5 w-5",
3721
+ gap: "gap-3"
3722
+ };
3723
+ default:
3724
+ return {
3725
+ bar: "h-2",
3726
+ text: "text-xs",
3727
+ icon: "h-4 w-4",
3728
+ gap: "gap-2"
3729
+ };
3730
+ }
3731
+ }
3732
+ function StatusProgress({
3733
+ className,
3734
+ value,
3735
+ currentCount,
3736
+ totalCount,
3737
+ unitLabel = "elements",
3738
+ showLabel = false,
3739
+ showCheckmark = true,
3740
+ size = "md",
3741
+ variant,
3742
+ ...props
3743
+ }) {
3744
+ const clampedValue = Math.min(100, Math.max(0, value));
3745
+ const isComplete = clampedValue >= 100;
3746
+ const resolvedVariant = variant ?? getVariantFromProgress(clampedValue);
3747
+ const colors = getStatusColors(resolvedVariant);
3748
+ const sizes = getSizeClasses(size);
3749
+ const labelText = React27__namespace.useMemo(() => {
3750
+ if (currentCount !== void 0 && totalCount !== void 0) {
3751
+ return `${currentCount} / ${totalCount} ${unitLabel}`;
3752
+ }
3753
+ return `${Math.round(clampedValue)}%`;
3754
+ }, [currentCount, totalCount, unitLabel, clampedValue]);
3755
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3756
+ "div",
3757
+ {
3758
+ "data-slot": "status-progress",
3759
+ "data-value": clampedValue,
3760
+ "data-variant": resolvedVariant,
3761
+ "data-complete": isComplete,
3762
+ className: cn("flex flex-col w-full", sizes.gap, className),
3763
+ ...props,
3764
+ children: [
3765
+ showLabel && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center justify-between", sizes.gap), children: [
3766
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("font-medium", sizes.text, colors.text), children: isComplete && showCheckmark ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-1", children: [
3767
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: cn(sizes.icon, colors.icon) }),
3768
+ "Complete"
3769
+ ] }) : labelText }),
3770
+ !isComplete && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("tabular-nums text-muted-foreground", sizes.text), children: [
3771
+ Math.round(clampedValue),
3772
+ "%"
3773
+ ] })
3774
+ ] }),
3775
+ /* @__PURE__ */ jsxRuntime.jsx(
3776
+ "div",
3777
+ {
3778
+ className: cn(
3779
+ "w-full rounded-full overflow-hidden",
3780
+ colors.track,
3781
+ sizes.bar
3782
+ ),
3783
+ role: "progressbar",
3784
+ "aria-valuenow": clampedValue,
3785
+ "aria-valuemin": 0,
3786
+ "aria-valuemax": 100,
3787
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3788
+ "div",
3789
+ {
3790
+ className: cn(
3791
+ "h-full rounded-full transition-all duration-300 ease-out",
3792
+ colors.fill
3793
+ ),
3794
+ style: { width: `${clampedValue}%` }
3795
+ }
3796
+ )
3797
+ }
3798
+ ),
3799
+ !showLabel && isComplete && showCheckmark && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center", sizes.gap), children: [
3800
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: cn(sizes.icon, colors.icon) }),
3801
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("font-medium", sizes.text, colors.text), children: "Complete" })
3802
+ ] })
3803
+ ]
3804
+ }
3805
+ );
3806
+ }
3462
3807
  function TooltipProvider({
3463
3808
  delayDuration = 0,
3464
3809
  ...props
@@ -6431,15 +6776,27 @@ function getCombinedRiskLevel(data) {
6431
6776
  if (productionStatus === "delayed" || hasDeliveryDelayed || data.hasWarning) {
6432
6777
  return "warning";
6433
6778
  }
6779
+ const productionProgress = data.production?.progress ?? data.progress ?? 0;
6780
+ const isProductionComplete = productionProgress >= 100;
6781
+ if (isProductionComplete) {
6782
+ return "complete";
6783
+ }
6434
6784
  return "normal";
6435
6785
  }
6436
- function getRowStatus(status) {
6786
+ function getRowStatus(status, progress) {
6437
6787
  if (status === "critical") return "critical";
6438
6788
  if (status === "delayed") return "warning";
6789
+ if (progress !== void 0 && progress >= 100) return "complete";
6439
6790
  return "normal";
6440
6791
  }
6441
6792
  var statusFillClasses = {
6442
6793
  normal: {
6794
+ // Grey/muted for "on track but not complete" - reduces visual noise
6795
+ border: "border-l-[3px] border-l-muted-foreground/40",
6796
+ bg: "bg-muted/30 dark:bg-muted/20"
6797
+ },
6798
+ complete: {
6799
+ // Green for "done/complete" - clear success signal
6443
6800
  border: "border-l-[3px] border-l-green-500",
6444
6801
  bg: "bg-green-50/50 dark:bg-green-950/30"
6445
6802
  },
@@ -6454,6 +6811,13 @@ var statusFillClasses = {
6454
6811
  };
6455
6812
  var statusColors = {
6456
6813
  normal: {
6814
+ // Grey/muted for "on track but not complete"
6815
+ icon: "text-muted-foreground",
6816
+ progress: "bg-muted-foreground/60",
6817
+ text: "text-muted-foreground"
6818
+ },
6819
+ complete: {
6820
+ // Green for "done/complete"
6457
6821
  icon: "text-green-600 dark:text-green-400",
6458
6822
  progress: "bg-green-500",
6459
6823
  text: "text-green-700 dark:text-green-300"
@@ -6481,19 +6845,20 @@ function WeekCell({
6481
6845
  const combinedRisk = data.type === "data" ? getCombinedRiskLevel(data) : "normal";
6482
6846
  const statusClasses = statusFillClasses[combinedRisk];
6483
6847
  const productionProgress = data.production?.progress ?? data.progress ?? 0;
6484
- const productionStatus = getRowStatus(data.production?.status);
6848
+ const productionStatus = getRowStatus(data.production?.status, productionProgress);
6485
6849
  const productionColors = statusColors[productionStatus];
6486
6850
  const deliveryCount = data.deliveries?.length ?? 0;
6487
- const worstDeliveryStatus = data.deliveries?.some((d) => d.status === "critical") ? "critical" : data.deliveries?.some((d) => d.status === "delayed") ? "warning" : "normal";
6851
+ const allDeliveriesComplete = data.deliveries?.every((d) => (d.progress ?? 0) >= 100) ?? false;
6852
+ const worstDeliveryStatus = data.deliveries?.some((d) => d.status === "critical") ? "critical" : data.deliveries?.some((d) => d.status === "delayed") ? "warning" : allDeliveriesComplete && deliveryCount > 0 ? "complete" : "normal";
6488
6853
  const deliveryColors = statusColors[worstDeliveryStatus];
6489
- const getDeliveryStatusColor = (status) => {
6490
- switch (status) {
6854
+ const getDeliveryStatusColor = (delivery) => {
6855
+ switch (delivery.status) {
6491
6856
  case "critical":
6492
6857
  return "bg-red-500";
6493
6858
  case "delayed":
6494
6859
  return "bg-amber-500";
6495
6860
  default:
6496
- return "bg-green-500";
6861
+ return (delivery.progress ?? 0) >= 100 ? "bg-green-500" : "bg-muted-foreground/60";
6497
6862
  }
6498
6863
  };
6499
6864
  const handleClick = () => {
@@ -6610,24 +6975,18 @@ function WeekCell({
6610
6975
  ] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: "\u2014" })
6611
6976
  ] }),
6612
6977
  deliveryCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
6613
- data.deliveries?.slice(0, 5).map((delivery, index) => {
6614
- const deliveryProgress = delivery.progress ?? (delivery.status === "on-time" ? 100 : delivery.status === "delayed" ? 50 : 25);
6615
- return /* @__PURE__ */ jsxRuntime.jsx(
6616
- "div",
6617
- {
6618
- className: "flex-1 max-w-[24px]",
6619
- title: delivery.label || `Delivery ${index + 1}`,
6620
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-1 bg-black/10 dark:bg-white/10 rounded-full overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
6621
- "div",
6622
- {
6623
- className: cn("h-full rounded-full transition-all", getDeliveryStatusColor(delivery.status)),
6624
- style: { width: `${deliveryProgress}%` }
6625
- }
6626
- ) })
6627
- },
6628
- delivery.id || index
6629
- );
6630
- }),
6978
+ data.deliveries?.slice(0, 5).map((delivery, index) => /* @__PURE__ */ jsxRuntime.jsx(
6979
+ "div",
6980
+ {
6981
+ className: cn(
6982
+ "flex-1 max-w-[24px] h-1.5 rounded-full",
6983
+ // Solid status color - grey=on-track, green=complete, amber=at-risk, red=critical
6984
+ getDeliveryStatusColor(delivery)
6985
+ ),
6986
+ title: delivery.label || `Delivery ${index + 1}`
6987
+ },
6988
+ delivery.id || index
6989
+ )),
6631
6990
  deliveryCount > 5 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[8px] text-muted-foreground", children: [
6632
6991
  "+",
6633
6992
  deliveryCount - 5
@@ -7241,12 +7600,95 @@ function PlanningTable({
7241
7600
  }
7242
7601
  }
7243
7602
  });
7603
+ const insightMetrics = React27__namespace.useMemo(() => {
7604
+ let totalProduced = 0;
7605
+ let totalRequired = 0;
7606
+ let totalDeliveries = 0;
7607
+ for (const supplier of suppliers) {
7608
+ for (const weekKey in supplier.weeks) {
7609
+ const weekData = supplier.weeks[weekKey];
7610
+ if (weekData.production) {
7611
+ totalProduced += weekData.production.produced;
7612
+ totalRequired += weekData.production.target;
7613
+ }
7614
+ totalDeliveries += weekData.deliveries?.length ?? 0;
7615
+ }
7616
+ }
7617
+ const productionPercent = totalRequired > 0 ? totalProduced / totalRequired * 100 : 0;
7618
+ return [
7619
+ {
7620
+ key: "produced",
7621
+ label: "produced",
7622
+ value: totalProduced,
7623
+ unit: "tons",
7624
+ icon: "factory",
7625
+ status: productionPercent >= 100 ? "success" : "normal"
7626
+ },
7627
+ {
7628
+ key: "deliveries",
7629
+ label: "planned deliveries",
7630
+ value: totalDeliveries,
7631
+ icon: "truck",
7632
+ status: "normal"
7633
+ },
7634
+ {
7635
+ key: "progress",
7636
+ label: "produced vs required",
7637
+ value: productionPercent,
7638
+ isPercentage: true,
7639
+ icon: "trending",
7640
+ status: productionPercent >= 100 ? "success" : productionPercent >= 50 ? "normal" : "warning"
7641
+ }
7642
+ ];
7643
+ }, [suppliers]);
7644
+ const columnSummaryData = React27__namespace.useMemo(() => {
7645
+ return weeks.map((week) => {
7646
+ const weekKey = getWeekKey(week.startDate);
7647
+ let producedTons = 0;
7648
+ let plannedDeliveries = 0;
7649
+ let sentDeliveries = 0;
7650
+ let hasWarning = false;
7651
+ let hasCritical = false;
7652
+ let allComplete = true;
7653
+ for (const supplier of suppliers) {
7654
+ const weekData = supplier.weeks[weekKey];
7655
+ if (weekData) {
7656
+ if (weekData.production) {
7657
+ producedTons += weekData.production.produced;
7658
+ if (weekData.production.progress !== void 0 && weekData.production.progress < 100) {
7659
+ allComplete = false;
7660
+ }
7661
+ }
7662
+ if (weekData.deliveries) {
7663
+ plannedDeliveries += weekData.deliveries.length;
7664
+ sentDeliveries += weekData.deliveries.filter(
7665
+ (d) => d.status === "on-time" && (d.progress ?? 0) >= 100
7666
+ ).length;
7667
+ }
7668
+ if (weekData.hasWarning) hasWarning = true;
7669
+ if (weekData.deliveries?.some((d) => d.status === "critical")) hasCritical = true;
7670
+ }
7671
+ }
7672
+ let status = "normal";
7673
+ if (hasCritical) status = "critical";
7674
+ else if (hasWarning) status = "warning";
7675
+ else if (allComplete && producedTons > 0) status = "complete";
7676
+ return {
7677
+ weekKey,
7678
+ producedTons,
7679
+ plannedDeliveries,
7680
+ sentDeliveries,
7681
+ status
7682
+ };
7683
+ });
7684
+ }, [weeks, suppliers]);
7244
7685
  return /* @__PURE__ */ jsxRuntime.jsxs(
7245
7686
  "div",
7246
7687
  {
7247
7688
  "data-slot": "planning-table",
7248
7689
  className: cn("flex flex-col gap-4", className),
7249
7690
  children: [
7691
+ /* @__PURE__ */ jsxRuntime.jsx(InsightBar, { metrics: insightMetrics }),
7250
7692
  showToolbar && /* @__PURE__ */ jsxRuntime.jsx(PlanningTableToolbar, { table }),
7251
7693
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl border bg-background shadow-sm overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(
7252
7694
  ScrollArea,
@@ -7255,37 +7697,80 @@ function PlanningTable({
7255
7697
  style: { maxHeight },
7256
7698
  children: [
7257
7699
  /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full border-collapse", children: [
7258
- /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "sticky top-0 z-20", children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsxRuntime.jsx(
7259
- "tr",
7260
- {
7261
- children: headerGroup.headers.map((header, index) => {
7262
- const isCurrentWeekColumn = header.id === currentWeekKey;
7700
+ /* @__PURE__ */ jsxRuntime.jsxs("thead", { className: "sticky top-0 z-20", children: [
7701
+ table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsxRuntime.jsx(
7702
+ "tr",
7703
+ {
7704
+ children: headerGroup.headers.map((header, index) => {
7705
+ const isCurrentWeekColumn = header.id === currentWeekKey;
7706
+ return /* @__PURE__ */ jsxRuntime.jsx(
7707
+ "th",
7708
+ {
7709
+ className: cn(
7710
+ "h-14 px-3 text-left align-middle font-semibold text-xs text-muted-foreground uppercase tracking-wide",
7711
+ "border-r border-b border-border last:border-r-0 bg-sidebar",
7712
+ // First column: sticky with right-edge shadow (Quantum token)
7713
+ index === 0 && stickySupplierColumn && [
7714
+ "sticky left-0 z-30 min-w-[200px]",
7715
+ "shadow-[var(--j3m-shadow-sticky-edge)]"
7716
+ ],
7717
+ index > 0 && "min-w-[140px]",
7718
+ // Current week: only highlight text/dot, not full background
7719
+ isCurrentWeekColumn && highlightCurrentWeek && "text-primary"
7720
+ ),
7721
+ children: header.isPlaceholder ? null : reactTable.flexRender(
7722
+ header.column.columnDef.header,
7723
+ header.getContext()
7724
+ )
7725
+ },
7726
+ header.id
7727
+ );
7728
+ })
7729
+ },
7730
+ headerGroup.id
7731
+ )),
7732
+ /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
7733
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: cn(
7734
+ "h-auto px-3 py-1.5 text-left align-middle",
7735
+ "border-r border-b border-border bg-muted/30",
7736
+ stickySupplierColumn && "sticky left-0 z-30 min-w-[200px]",
7737
+ stickySupplierColumn && "shadow-[var(--j3m-shadow-sticky-edge)]"
7738
+ ), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium text-muted-foreground uppercase tracking-wide", children: "Summary" }) }),
7739
+ columnSummaryData.map((summary) => {
7740
+ const statusBg = summary.status === "complete" ? "bg-green-50/50 dark:bg-green-950/30" : summary.status === "critical" ? "bg-red-50/50 dark:bg-red-950/30" : summary.status === "warning" ? "bg-amber-50/50 dark:bg-amber-950/30" : "bg-muted/30";
7741
+ const statusText = summary.status === "complete" ? "text-green-700 dark:text-green-300" : summary.status === "critical" ? "text-red-700 dark:text-red-300" : summary.status === "warning" ? "text-amber-700 dark:text-amber-300" : "text-muted-foreground";
7263
7742
  return /* @__PURE__ */ jsxRuntime.jsx(
7264
7743
  "th",
7265
7744
  {
7266
7745
  className: cn(
7267
- "h-14 px-3 text-left align-middle font-semibold text-xs text-muted-foreground uppercase tracking-wide",
7268
- "border-r border-b border-border last:border-r-0 bg-sidebar",
7269
- // First column: sticky with right-edge shadow (Quantum token)
7270
- index === 0 && stickySupplierColumn && [
7271
- "sticky left-0 z-30 min-w-[200px]",
7272
- "shadow-[var(--j3m-shadow-sticky-edge)]"
7273
- ],
7274
- index > 0 && "min-w-[140px]",
7275
- // Current week: only highlight text/dot, not full background
7276
- isCurrentWeekColumn && highlightCurrentWeek && "text-primary"
7746
+ "h-auto px-2 py-1.5 text-left align-middle",
7747
+ "border-r border-b border-border last:border-r-0 min-w-[140px]",
7748
+ statusBg
7277
7749
  ),
7278
- children: header.isPlaceholder ? null : reactTable.flexRender(
7279
- header.column.columnDef.header,
7280
- header.getContext()
7281
- )
7750
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [
7751
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
7752
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Factory, { className: cn("h-3 w-3", statusText) }),
7753
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("text-xs font-medium tabular-nums", statusText), children: [
7754
+ summary.producedTons.toLocaleString(void 0, { maximumFractionDigits: 1 }),
7755
+ " t"
7756
+ ] })
7757
+ ] }),
7758
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
7759
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: "h-3 w-3 text-muted-foreground" }),
7760
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] text-muted-foreground tabular-nums", children: [
7761
+ summary.sentDeliveries,
7762
+ "/",
7763
+ summary.plannedDeliveries,
7764
+ " sent"
7765
+ ] })
7766
+ ] })
7767
+ ] })
7282
7768
  },
7283
- header.id
7769
+ summary.weekKey
7284
7770
  );
7285
7771
  })
7286
- },
7287
- headerGroup.id
7288
- )) }),
7772
+ ] })
7773
+ ] }),
7289
7774
  /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "bg-background", children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ jsxRuntime.jsx(
7290
7775
  "tr",
7291
7776
  {
@@ -7340,10 +7825,12 @@ function PlanningTable({
7340
7825
  }
7341
7826
  );
7342
7827
  }
7343
- function getStatusBadgeVariant(status) {
7828
+ function getStatusBadgeVariant(status, isComplete) {
7829
+ if (isComplete) return "outline";
7344
7830
  switch (status) {
7345
7831
  case "on-time":
7346
7832
  return "outline";
7833
+ // Grey for on-track
7347
7834
  case "delayed":
7348
7835
  return "secondary";
7349
7836
  case "critical":
@@ -7352,19 +7839,24 @@ function getStatusBadgeVariant(status) {
7352
7839
  return "outline";
7353
7840
  }
7354
7841
  }
7355
- function getStatusBadgeClasses(status) {
7842
+ function getStatusBadgeClasses(status, isComplete) {
7843
+ if (isComplete) {
7844
+ return "border-green-500 text-green-600 bg-green-50 dark:bg-green-950/50";
7845
+ }
7356
7846
  switch (status) {
7357
7847
  case "on-time":
7358
- return "border-green-500 text-green-600 bg-green-50 dark:bg-green-950/50";
7848
+ return "border-muted-foreground/50 text-muted-foreground bg-muted/50";
7849
+ // Grey for on-track
7359
7850
  case "delayed":
7360
7851
  return "border-amber-500 text-amber-600 bg-amber-50 dark:bg-amber-950/50";
7361
7852
  case "critical":
7362
7853
  return "";
7363
7854
  default:
7364
- return "";
7855
+ return "border-muted-foreground/50 text-muted-foreground";
7365
7856
  }
7366
7857
  }
7367
- function getStatusLabel(status) {
7858
+ function getStatusLabel(status, isComplete) {
7859
+ if (isComplete) return "Complete";
7368
7860
  switch (status) {
7369
7861
  case "on-time":
7370
7862
  return "On Track";
@@ -7378,10 +7870,12 @@ function getStatusLabel(status) {
7378
7870
  return status;
7379
7871
  }
7380
7872
  }
7381
- function getProgressVariant(status) {
7873
+ function getProgressVariant(status, isComplete) {
7874
+ if (isComplete) return "success";
7382
7875
  switch (status) {
7383
7876
  case "on-time":
7384
- return "success";
7877
+ return "default";
7878
+ // Grey/default for on-track
7385
7879
  case "delayed":
7386
7880
  return "warning";
7387
7881
  case "critical":
@@ -7666,37 +8160,66 @@ function DeliveryListItem({
7666
8160
  onClick
7667
8161
  }) {
7668
8162
  const hasComments = (delivery.comments?.length ?? 0) > 0;
8163
+ const isComplete = (delivery.progress ?? 0) >= 100;
8164
+ const getCardStyles3 = () => {
8165
+ if (delivery.status === "critical") {
8166
+ return {
8167
+ card: "border-l-[3px] border-l-red-500 bg-red-50/50 dark:bg-red-950/30",
8168
+ icon: "text-red-600 dark:text-red-400",
8169
+ title: "text-foreground",
8170
+ subtitle: "text-red-700/70 dark:text-red-300/70",
8171
+ chevron: "text-red-600/60 dark:text-red-400/60"
8172
+ };
8173
+ }
8174
+ if (delivery.status === "delayed") {
8175
+ return {
8176
+ card: "border-l-[3px] border-l-amber-500 bg-amber-50/50 dark:bg-amber-950/30",
8177
+ icon: "text-amber-600 dark:text-amber-400",
8178
+ title: "text-foreground",
8179
+ subtitle: "text-amber-700/70 dark:text-amber-300/70",
8180
+ chevron: "text-amber-600/60 dark:text-amber-400/60"
8181
+ };
8182
+ }
8183
+ if (isComplete) {
8184
+ return {
8185
+ card: "border-l-[3px] border-l-green-500 bg-green-50/50 dark:bg-green-950/30",
8186
+ icon: "text-green-600 dark:text-green-400",
8187
+ title: "text-foreground",
8188
+ subtitle: "text-green-700/70 dark:text-green-300/70",
8189
+ chevron: "text-green-600/60 dark:text-green-400/60"
8190
+ };
8191
+ }
8192
+ return {
8193
+ card: "border-l-[3px] border-l-muted-foreground/40 bg-muted/30 dark:bg-muted/20",
8194
+ icon: "text-muted-foreground",
8195
+ title: "text-foreground",
8196
+ subtitle: "text-muted-foreground",
8197
+ chevron: "text-muted-foreground/60"
8198
+ };
8199
+ };
8200
+ const styles = getCardStyles3();
7669
8201
  return /* @__PURE__ */ jsxRuntime.jsxs(
7670
8202
  "button",
7671
8203
  {
7672
8204
  onClick,
7673
8205
  className: cn(
7674
8206
  "w-full flex items-center justify-between p-3 rounded-lg",
7675
- "bg-card border hover:bg-muted/50 transition-colors cursor-pointer",
7676
- "text-left"
8207
+ "transition-all duration-200 ease-out cursor-pointer text-left",
8208
+ "hover:-translate-y-0.5 hover:shadow-[var(--j3m-shadow-md)]",
8209
+ styles.card
7677
8210
  ),
7678
8211
  children: [
7679
8212
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
7680
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
7681
- "flex items-center justify-center h-8 w-8 rounded-lg",
7682
- delivery.status === "on-time" && "bg-green-100 dark:bg-green-950/50",
7683
- delivery.status === "delayed" && "bg-amber-100 dark:bg-amber-950/50",
7684
- delivery.status === "critical" && "bg-red-100 dark:bg-red-950/50"
7685
- ), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: cn(
7686
- "h-4 w-4",
7687
- delivery.status === "on-time" && "text-green-600 dark:text-green-400",
7688
- delivery.status === "delayed" && "text-amber-600 dark:text-amber-400",
7689
- delivery.status === "critical" && "text-red-600 dark:text-red-400"
7690
- ) }) }),
8213
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: cn("h-5 w-5 shrink-0", styles.icon) }),
7691
8214
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
7692
8215
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
7693
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: delivery.label || `Delivery ${index + 1}` }),
8216
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-sm font-medium", styles.title), children: delivery.label || `Delivery ${index + 1}` }),
7694
8217
  hasComments && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
7695
8218
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "h-3 w-3 text-muted-foreground" }),
7696
8219
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -top-0.5 -right-0.5 h-1.5 w-1.5 rounded-full bg-primary" })
7697
8220
  ] })
7698
8221
  ] }),
7699
- delivery.destination && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-muted-foreground", children: [
8222
+ delivery.destination && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("text-xs", styles.subtitle), children: [
7700
8223
  "\u2192 ",
7701
8224
  delivery.destination
7702
8225
  ] })
@@ -7706,12 +8229,12 @@ function DeliveryListItem({
7706
8229
  /* @__PURE__ */ jsxRuntime.jsx(
7707
8230
  Badge,
7708
8231
  {
7709
- variant: getStatusBadgeVariant(delivery.status),
7710
- className: cn("text-xs", getStatusBadgeClasses(delivery.status)),
7711
- children: getStatusLabel(delivery.status)
8232
+ variant: getStatusBadgeVariant(delivery.status, isComplete),
8233
+ className: cn("text-xs", getStatusBadgeClasses(delivery.status, isComplete)),
8234
+ children: getStatusLabel(delivery.status, isComplete)
7712
8235
  }
7713
8236
  ),
7714
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4 text-muted-foreground" })
8237
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: cn("h-4 w-4", styles.chevron) })
7715
8238
  ] })
7716
8239
  ]
7717
8240
  }
@@ -7782,9 +8305,9 @@ function DeliveryDetailsView({
7782
8305
  /* @__PURE__ */ jsxRuntime.jsx(
7783
8306
  Badge,
7784
8307
  {
7785
- variant: getStatusBadgeVariant(delivery.status),
7786
- className: cn("text-xs", getStatusBadgeClasses(delivery.status)),
7787
- children: getStatusLabel(delivery.status)
8308
+ variant: getStatusBadgeVariant(delivery.status, sentCount === totalCount && totalCount > 0),
8309
+ className: cn("text-xs", getStatusBadgeClasses(delivery.status, sentCount === totalCount && totalCount > 0)),
8310
+ children: getStatusLabel(delivery.status, sentCount === totalCount && totalCount > 0)
7788
8311
  }
7789
8312
  )
7790
8313
  ] })
@@ -7957,9 +8480,9 @@ function MainView({
7957
8480
  /* @__PURE__ */ jsxRuntime.jsx(
7958
8481
  Badge,
7959
8482
  {
7960
- variant: getStatusBadgeVariant(productionStatus),
7961
- className: cn("text-xs ml-auto", getStatusBadgeClasses(productionStatus)),
7962
- children: getStatusLabel(productionStatus)
8483
+ variant: getStatusBadgeVariant(productionStatus, isComplete),
8484
+ className: cn("text-xs ml-auto", getStatusBadgeClasses(productionStatus, isComplete)),
8485
+ children: getStatusLabel(productionStatus, isComplete)
7963
8486
  }
7964
8487
  )
7965
8488
  ] }),
@@ -7970,7 +8493,7 @@ function MainView({
7970
8493
  value: productionProgress,
7971
8494
  size: 100,
7972
8495
  strokeWidth: 10,
7973
- variant: getProgressVariant(productionStatus),
8496
+ variant: getProgressVariant(productionStatus, isComplete),
7974
8497
  showCheckmark: isComplete,
7975
8498
  children: isComplete ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center", children: [
7976
8499
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-6 w-6 text-green-600" }),
@@ -8151,46 +8674,1083 @@ function WeekDetailDialog({
8151
8674
  }
8152
8675
  ) }) });
8153
8676
  }
8154
- function RowHeaderCell({
8155
- className,
8156
- data,
8157
- showProgress = true,
8158
- ...props
8159
- }) {
8160
- const progressPercent = data.totalRequired > 0 ? Math.min(data.totalBooked / data.totalRequired * 100, 100) : 0;
8161
- return /* @__PURE__ */ jsxRuntime.jsxs(
8162
- "div",
8163
- {
8164
- "data-slot": "row-header-cell",
8165
- className: cn(
8166
- "flex flex-col justify-center gap-1.5 py-2 px-3 min-w-[200px] h-[100px] bg-background",
8167
- className
8168
- ),
8169
- ...props,
8170
- children: [
8171
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-2", children: [
8172
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
8173
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-bold leading-tight text-foreground truncate", children: data.name }),
8174
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: data.typeCode })
8175
- ] }),
8176
- /* @__PURE__ */ jsxRuntime.jsxs(
8177
- Badge,
8178
- {
8179
- variant: "outline",
8180
- className: "text-[10px] px-2 py-0.5 h-[19px] font-medium shrink-0 gap-1 bg-background border-border",
8181
- children: [
8182
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Flag, { className: "h-2.5 w-2.5" }),
8183
- "Paint"
8184
- ]
8185
- }
8186
- )
8187
- ] }),
8188
- showProgress && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
8189
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-1.5 bg-black/10 dark:bg-white/10 rounded-full overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
8190
- "div",
8191
- {
8192
- className: "h-full bg-primary rounded-full transition-all",
8193
- style: { width: `${progressPercent}%` }
8677
+ function getStatusBadgeVariant2(status, isComplete) {
8678
+ if (isComplete) return "outline";
8679
+ switch (status) {
8680
+ case "on-time":
8681
+ return "outline";
8682
+ // Grey for on-track
8683
+ case "delayed":
8684
+ return "secondary";
8685
+ case "critical":
8686
+ return "destructive";
8687
+ default:
8688
+ return "outline";
8689
+ }
8690
+ }
8691
+ function getStatusBadgeClasses2(status, isComplete) {
8692
+ if (isComplete) {
8693
+ return "border-green-500 text-green-600 bg-green-50 dark:bg-green-950/50";
8694
+ }
8695
+ switch (status) {
8696
+ case "on-time":
8697
+ return "border-muted-foreground/50 text-muted-foreground bg-muted/50";
8698
+ // Grey for on-track
8699
+ case "delayed":
8700
+ return "border-amber-500 text-amber-600 bg-amber-50 dark:bg-amber-950/50";
8701
+ case "critical":
8702
+ return "";
8703
+ default:
8704
+ return "border-muted-foreground/50 text-muted-foreground";
8705
+ }
8706
+ }
8707
+ function getStatusLabel2(status, isComplete) {
8708
+ if (isComplete) return "Complete";
8709
+ switch (status) {
8710
+ case "on-time":
8711
+ return "On Track";
8712
+ case "delayed":
8713
+ return "At Risk";
8714
+ case "critical":
8715
+ return "Critical";
8716
+ case "pending":
8717
+ return "Pending";
8718
+ default:
8719
+ return status;
8720
+ }
8721
+ }
8722
+ function getShipmentStatusBadgeClasses2(status) {
8723
+ switch (status) {
8724
+ case "sent":
8725
+ return "border-green-500 text-green-600 bg-green-50 dark:bg-green-950/50";
8726
+ case "not-sent":
8727
+ return "border-muted-foreground/50 text-muted-foreground bg-muted/50";
8728
+ case "moved":
8729
+ return "border-blue-500 text-blue-600 bg-blue-50 dark:bg-blue-950/50";
8730
+ case "addon":
8731
+ return "border-purple-500 text-purple-600 bg-purple-50 dark:bg-purple-950/50";
8732
+ case "planned":
8733
+ default:
8734
+ return "border-muted-foreground/50 text-muted-foreground";
8735
+ }
8736
+ }
8737
+ function getShipmentStatusRowBg2(status) {
8738
+ switch (status) {
8739
+ case "sent":
8740
+ return "bg-green-50/30 dark:bg-green-950/10";
8741
+ case "not-sent":
8742
+ return "bg-muted/30";
8743
+ case "moved":
8744
+ return "bg-blue-50/30 dark:bg-blue-950/10";
8745
+ case "addon":
8746
+ return "bg-purple-50/30 dark:bg-purple-950/10";
8747
+ default:
8748
+ return "";
8749
+ }
8750
+ }
8751
+ function ElementProductionDialog({
8752
+ open,
8753
+ onOpenChange,
8754
+ elements,
8755
+ onSave
8756
+ }) {
8757
+ const [searchQuery, setSearchQuery] = React27__namespace.useState("");
8758
+ const [selectedIds, setSelectedIds] = React27__namespace.useState(
8759
+ new Set(elements.filter((e) => e.isProduced).map((e) => e.id))
8760
+ );
8761
+ React27__namespace.useEffect(() => {
8762
+ if (open) {
8763
+ setSelectedIds(new Set(elements.filter((e) => e.isProduced).map((e) => e.id)));
8764
+ setSearchQuery("");
8765
+ }
8766
+ }, [open, elements]);
8767
+ const filteredElements = React27__namespace.useMemo(() => {
8768
+ if (!searchQuery.trim()) return elements;
8769
+ const query = searchQuery.toLowerCase();
8770
+ return elements.filter(
8771
+ (e) => e.name.toLowerCase().includes(query) || e.prefix?.toLowerCase().includes(query) || e.type?.toLowerCase().includes(query)
8772
+ );
8773
+ }, [elements, searchQuery]);
8774
+ React27__namespace.useMemo(() => {
8775
+ const prefixes = /* @__PURE__ */ new Set();
8776
+ elements.forEach((e) => {
8777
+ if (e.prefix) prefixes.add(e.prefix);
8778
+ });
8779
+ return Array.from(prefixes).sort();
8780
+ }, [elements]);
8781
+ const toggleElement = (id) => {
8782
+ setSelectedIds((prev) => {
8783
+ const next = new Set(prev);
8784
+ if (next.has(id)) {
8785
+ next.delete(id);
8786
+ } else {
8787
+ next.add(id);
8788
+ }
8789
+ return next;
8790
+ });
8791
+ };
8792
+ const selectAll = () => {
8793
+ setSelectedIds(new Set(filteredElements.map((e) => e.id)));
8794
+ };
8795
+ const deselectAll = () => {
8796
+ setSelectedIds(/* @__PURE__ */ new Set());
8797
+ };
8798
+ const handleSave = () => {
8799
+ onSave(Array.from(selectedIds));
8800
+ onOpenChange(false);
8801
+ };
8802
+ const selectedCount = selectedIds.size;
8803
+ const totalCount = elements.length;
8804
+ const selectedWeight = elements.filter((e) => selectedIds.has(e.id)).reduce((sum, e) => sum + (e.weight ?? 0), 0);
8805
+ const totalWeight = elements.reduce((sum, e) => sum + (e.weight ?? 0), 0);
8806
+ return /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "sm:max-w-fit max-w-[950px] w-fit max-h-[85vh] flex flex-col gap-0 p-0 overflow-hidden", children: [
8807
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { className: "w-full p-6 pb-0 shrink-0", children: [
8808
+ /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Enter production progress" }),
8809
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground", children: [
8810
+ "Mark elements as produced (",
8811
+ selectedCount,
8812
+ " / ",
8813
+ totalCount,
8814
+ " selected)"
8815
+ ] })
8816
+ ] }),
8817
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-h-0 flex flex-col p-6 pt-4 gap-4 overflow-hidden w-fit", children: [
8818
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col sm:flex-row gap-3 shrink-0", children: [
8819
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1", children: [
8820
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" }),
8821
+ /* @__PURE__ */ jsxRuntime.jsx(
8822
+ Input,
8823
+ {
8824
+ placeholder: "Search elements...",
8825
+ value: searchQuery,
8826
+ onChange: (e) => setSearchQuery(e.target.value),
8827
+ className: "pl-9 w-full"
8828
+ }
8829
+ )
8830
+ ] }),
8831
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 shrink-0", children: [
8832
+ /* @__PURE__ */ jsxRuntime.jsx(
8833
+ Button,
8834
+ {
8835
+ variant: "outline",
8836
+ size: "sm",
8837
+ onClick: selectAll,
8838
+ children: "Select all"
8839
+ }
8840
+ ),
8841
+ /* @__PURE__ */ jsxRuntime.jsx(
8842
+ Button,
8843
+ {
8844
+ variant: "outline",
8845
+ size: "sm",
8846
+ onClick: deselectAll,
8847
+ children: "Deselect all"
8848
+ }
8849
+ )
8850
+ ] })
8851
+ ] }),
8852
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-0 rounded-lg border bg-card overflow-hidden", children: filteredElements.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "h-full w-fit", children: /* @__PURE__ */ jsxRuntime.jsxs(Table, { children: [
8853
+ /* @__PURE__ */ jsxRuntime.jsx(TableHeader, { className: "sticky top-0 z-10", children: /* @__PURE__ */ jsxRuntime.jsxs(TableRow, { className: "bg-muted/50 hover:bg-muted/50", children: [
8854
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "w-[44px] bg-muted/50", children: /* @__PURE__ */ jsxRuntime.jsx(
8855
+ Checkbox,
8856
+ {
8857
+ checked: selectedIds.size === filteredElements.length && filteredElements.length > 0,
8858
+ onCheckedChange: (checked) => {
8859
+ if (checked) {
8860
+ selectAll();
8861
+ } else {
8862
+ deselectAll();
8863
+ }
8864
+ },
8865
+ "aria-label": "Select all elements"
8866
+ }
8867
+ ) }),
8868
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "bg-muted/50", children: "Element" }),
8869
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "bg-muted/50 w-[80px]", children: "Type" }),
8870
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "bg-muted/50 text-right w-[90px]", children: "Weight" }),
8871
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "bg-muted/50 text-right w-[80px]", children: "Size" }),
8872
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "bg-muted/50 text-center w-[100px]", children: "Status" })
8873
+ ] }) }),
8874
+ /* @__PURE__ */ jsxRuntime.jsx(TableBody, { children: filteredElements.map((element) => {
8875
+ const isSelected = selectedIds.has(element.id);
8876
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8877
+ TableRow,
8878
+ {
8879
+ className: cn(
8880
+ "cursor-pointer transition-colors",
8881
+ isSelected && "bg-green-50/50 dark:bg-green-950/20"
8882
+ ),
8883
+ onClick: () => toggleElement(element.id),
8884
+ children: [
8885
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { className: "w-[44px]", children: /* @__PURE__ */ jsxRuntime.jsx(
8886
+ Checkbox,
8887
+ {
8888
+ checked: isSelected,
8889
+ onCheckedChange: () => toggleElement(element.id),
8890
+ onClick: (e) => e.stopPropagation(),
8891
+ "aria-label": `Mark ${element.name} as produced`
8892
+ }
8893
+ ) }),
8894
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
8895
+ element.prefix && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "outline", className: "text-[10px] h-5 shrink-0 font-mono", children: element.prefix }),
8896
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: element.name })
8897
+ ] }) }),
8898
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { className: "text-muted-foreground w-[80px]", children: element.type || "\u2014" }),
8899
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { className: "text-right tabular-nums text-muted-foreground w-[90px]", children: element.weight != null ? `${element.weight.toLocaleString()} kg` : "\u2014" }),
8900
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { className: "text-right tabular-nums text-muted-foreground w-[80px]", children: element.size != null ? `${element.size.toLocaleString()} ${element.sizeUnit || "sqm"}` : "\u2014" }),
8901
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { className: "text-center w-[100px]", children: isSelected ? /* @__PURE__ */ jsxRuntime.jsxs(
8902
+ Badge,
8903
+ {
8904
+ variant: "outline",
8905
+ className: "border-green-500 text-green-600 bg-green-50 dark:bg-green-950/50",
8906
+ children: [
8907
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3 w-3 mr-1" }),
8908
+ "Produced"
8909
+ ]
8910
+ }
8911
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
8912
+ Badge,
8913
+ {
8914
+ variant: "outline",
8915
+ className: "border-muted-foreground/50 text-muted-foreground",
8916
+ children: "Not produced"
8917
+ }
8918
+ ) })
8919
+ ]
8920
+ },
8921
+ element.id
8922
+ );
8923
+ }) })
8924
+ ] }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center h-full min-h-[200px] text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-12", children: [
8925
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Package, { className: "h-10 w-10 mx-auto mb-3 opacity-50" }),
8926
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium", children: "No elements found" }),
8927
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground mt-1", children: "Try adjusting your search" })
8928
+ ] }) }) })
8929
+ ] }),
8930
+ /* @__PURE__ */ jsxRuntime.jsx(DialogFooter, { className: "w-full p-6 pt-4 border-t shrink-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between w-full gap-4", children: [
8931
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 text-sm text-muted-foreground", children: [
8932
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
8933
+ selectedCount,
8934
+ " / ",
8935
+ totalCount,
8936
+ " elements"
8937
+ ] }),
8938
+ totalWeight > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
8939
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u2022" }),
8940
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "tabular-nums font-medium text-foreground", children: [
8941
+ (selectedWeight / 1e3).toLocaleString(void 0, { maximumFractionDigits: 1 }),
8942
+ " / ",
8943
+ (totalWeight / 1e3).toLocaleString(void 0, { maximumFractionDigits: 1 }),
8944
+ " ton"
8945
+ ] })
8946
+ ] })
8947
+ ] }),
8948
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
8949
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), children: "Cancel" }),
8950
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handleSave, children: "Save progress" })
8951
+ ] })
8952
+ ] }) })
8953
+ ] }) });
8954
+ }
8955
+ function DeliveryCommentPopover2({
8956
+ comments = [],
8957
+ onAddComment,
8958
+ deliveryLabel
8959
+ }) {
8960
+ const [open, setOpen] = React27__namespace.useState(false);
8961
+ const [newCommentText, setNewCommentText] = React27__namespace.useState("");
8962
+ const [viewCommentsOpen, setViewCommentsOpen] = React27__namespace.useState(true);
8963
+ const [showAddForm, setShowAddForm] = React27__namespace.useState(false);
8964
+ const handleSubmit = () => {
8965
+ if (newCommentText.trim() && onAddComment) {
8966
+ onAddComment(newCommentText.trim());
8967
+ setNewCommentText("");
8968
+ setShowAddForm(false);
8969
+ setViewCommentsOpen(true);
8970
+ }
8971
+ };
8972
+ const handleKeyDown = (e) => {
8973
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
8974
+ e.preventDefault();
8975
+ handleSubmit();
8976
+ }
8977
+ if (e.key === "Escape") {
8978
+ setShowAddForm(false);
8979
+ setNewCommentText("");
8980
+ }
8981
+ };
8982
+ const formatDate3 = (date) => {
8983
+ return new Intl.DateTimeFormat("en-US", {
8984
+ month: "short",
8985
+ day: "numeric",
8986
+ hour: "numeric",
8987
+ minute: "2-digit"
8988
+ }).format(date);
8989
+ };
8990
+ React27__namespace.useEffect(() => {
8991
+ if (!open) {
8992
+ setShowAddForm(false);
8993
+ setNewCommentText("");
8994
+ }
8995
+ }, [open]);
8996
+ return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange: setOpen, children: [
8997
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(CommentButton, { size: "sm", commentCount: comments.length }) }),
8998
+ /* @__PURE__ */ jsxRuntime.jsxs(
8999
+ PopoverContent,
9000
+ {
9001
+ className: "w-80 p-0 z-[100]",
9002
+ align: "end",
9003
+ sideOffset: 8,
9004
+ collisionPadding: 16,
9005
+ children: [
9006
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 py-3 border-b border-border", children: [
9007
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-sm font-semibold", children: "Comments" }),
9008
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: deliveryLabel })
9009
+ ] }),
9010
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-2 space-y-2 h-fit overflow-y-auto", children: [
9011
+ /* @__PURE__ */ jsxRuntime.jsxs(Collapsible, { open: viewCommentsOpen, onOpenChange: setViewCommentsOpen, children: [
9012
+ /* @__PURE__ */ jsxRuntime.jsx(CollapsibleTrigger2, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: "ghost", size: "sm", className: "w-full justify-between h-8 px-2", children: [
9013
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs font-medium", children: [
9014
+ "Comments ",
9015
+ comments.length > 0 && `(${comments.length})`
9016
+ ] }),
9017
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: cn(
9018
+ "h-4 w-4 transition-transform duration-200",
9019
+ viewCommentsOpen && "rotate-180"
9020
+ ) })
9021
+ ] }) }),
9022
+ /* @__PURE__ */ jsxRuntime.jsx(CollapsibleContent2, { className: "space-y-2 pt-2", children: comments.length > 0 ? comments.map((comment) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg bg-muted/50 p-3 space-y-2", children: [
9023
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
9024
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium", children: comment.author }),
9025
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: formatDate3(comment.createdAt) })
9026
+ ] }),
9027
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-foreground", children: comment.text })
9028
+ ] }, comment.id)) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground text-center py-2", children: "No comments yet" }) })
9029
+ ] }),
9030
+ /* @__PURE__ */ jsxRuntime.jsx(Separator, { className: "my-2" }),
9031
+ !showAddForm ? /* @__PURE__ */ jsxRuntime.jsxs(
9032
+ Button,
9033
+ {
9034
+ variant: "outline",
9035
+ size: "sm",
9036
+ className: "w-full justify-center gap-2 h-8",
9037
+ onClick: () => setShowAddForm(true),
9038
+ children: [
9039
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3.5 w-3.5" }),
9040
+ "Add comment"
9041
+ ]
9042
+ }
9043
+ ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(
9044
+ "space-y-3 p-3 rounded-lg border border-border bg-muted/30",
9045
+ "animate-in fade-in-0 slide-in-from-top-2 duration-200"
9046
+ ), children: [
9047
+ /* @__PURE__ */ jsxRuntime.jsx(
9048
+ Textarea,
9049
+ {
9050
+ placeholder: "Type your comment...",
9051
+ value: newCommentText,
9052
+ onChange: (e) => setNewCommentText(e.target.value),
9053
+ onKeyDown: handleKeyDown,
9054
+ className: "min-h-[80px] text-sm resize-none",
9055
+ autoFocus: true
9056
+ }
9057
+ ),
9058
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
9059
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: "\u2318+Enter to send \xB7 Esc to cancel" }),
9060
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
9061
+ /* @__PURE__ */ jsxRuntime.jsx(
9062
+ Button,
9063
+ {
9064
+ variant: "ghost",
9065
+ size: "sm",
9066
+ className: "h-7",
9067
+ onClick: () => {
9068
+ setShowAddForm(false);
9069
+ setNewCommentText("");
9070
+ },
9071
+ children: "Cancel"
9072
+ }
9073
+ ),
9074
+ /* @__PURE__ */ jsxRuntime.jsxs(
9075
+ Button,
9076
+ {
9077
+ size: "sm",
9078
+ className: "h-7 gap-1",
9079
+ onClick: handleSubmit,
9080
+ disabled: !newCommentText.trim(),
9081
+ children: [
9082
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "h-3 w-3" }),
9083
+ "Save"
9084
+ ]
9085
+ }
9086
+ )
9087
+ ] })
9088
+ ] })
9089
+ ] })
9090
+ ] })
9091
+ ]
9092
+ }
9093
+ )
9094
+ ] });
9095
+ }
9096
+ function ProductionCommentSection2({
9097
+ comments = [],
9098
+ onAddComment
9099
+ }) {
9100
+ const [showAddForm, setShowAddForm] = React27__namespace.useState(false);
9101
+ const [newComment, setNewComment] = React27__namespace.useState("");
9102
+ const handleSubmit = () => {
9103
+ if (newComment.trim() && onAddComment) {
9104
+ onAddComment(newComment.trim());
9105
+ setNewComment("");
9106
+ setShowAddForm(false);
9107
+ }
9108
+ };
9109
+ const handleKeyDown = (e) => {
9110
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
9111
+ e.preventDefault();
9112
+ handleSubmit();
9113
+ }
9114
+ if (e.key === "Escape") {
9115
+ setShowAddForm(false);
9116
+ setNewComment("");
9117
+ }
9118
+ };
9119
+ const formatDate3 = (date) => {
9120
+ return new Intl.DateTimeFormat("en-US", {
9121
+ month: "short",
9122
+ day: "numeric",
9123
+ hour: "numeric",
9124
+ minute: "2-digit"
9125
+ }).format(date);
9126
+ };
9127
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
9128
+ comments.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: comments.map((comment) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg bg-muted/50 p-2.5 space-y-1", children: [
9129
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
9130
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium", children: comment.author }),
9131
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: formatDate3(comment.createdAt) })
9132
+ ] }),
9133
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-foreground", children: comment.text })
9134
+ ] }, comment.id)) }),
9135
+ !showAddForm ? /* @__PURE__ */ jsxRuntime.jsxs(
9136
+ Button,
9137
+ {
9138
+ variant: "ghost",
9139
+ size: "sm",
9140
+ className: "w-full justify-start gap-2 h-8 text-muted-foreground",
9141
+ onClick: () => setShowAddForm(true),
9142
+ children: [
9143
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "h-3.5 w-3.5" }),
9144
+ comments.length > 0 ? "Add another comment" : "Add a comment..."
9145
+ ]
9146
+ }
9147
+ ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 animate-in fade-in-0 slide-in-from-top-2 duration-200", children: [
9148
+ /* @__PURE__ */ jsxRuntime.jsx(
9149
+ Textarea,
9150
+ {
9151
+ placeholder: "Add a comment...",
9152
+ value: newComment,
9153
+ onChange: (e) => setNewComment(e.target.value),
9154
+ onKeyDown: handleKeyDown,
9155
+ className: "min-h-[60px] text-sm resize-none",
9156
+ autoFocus: true
9157
+ }
9158
+ ),
9159
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
9160
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: "\u2318+Enter to send" }),
9161
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
9162
+ /* @__PURE__ */ jsxRuntime.jsx(
9163
+ Button,
9164
+ {
9165
+ variant: "ghost",
9166
+ size: "sm",
9167
+ className: "h-7",
9168
+ onClick: () => {
9169
+ setShowAddForm(false);
9170
+ setNewComment("");
9171
+ },
9172
+ children: "Cancel"
9173
+ }
9174
+ ),
9175
+ /* @__PURE__ */ jsxRuntime.jsxs(
9176
+ Button,
9177
+ {
9178
+ size: "sm",
9179
+ className: "h-7 gap-1",
9180
+ onClick: handleSubmit,
9181
+ disabled: !newComment.trim(),
9182
+ children: [
9183
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "h-3 w-3" }),
9184
+ "Save"
9185
+ ]
9186
+ }
9187
+ )
9188
+ ] })
9189
+ ] })
9190
+ ] })
9191
+ ] });
9192
+ }
9193
+ function DeliveryListItem2({
9194
+ delivery,
9195
+ index,
9196
+ onClick
9197
+ }) {
9198
+ const hasComments = (delivery.comments?.length ?? 0) > 0;
9199
+ const isComplete = (delivery.progress ?? 0) >= 100;
9200
+ const getCardStyles3 = () => {
9201
+ if (delivery.status === "critical") {
9202
+ return {
9203
+ card: "border-l-[3px] border-l-red-500 bg-red-50/50 dark:bg-red-950/30",
9204
+ icon: "text-red-600 dark:text-red-400",
9205
+ title: "text-foreground",
9206
+ subtitle: "text-red-700/70 dark:text-red-300/70",
9207
+ chevron: "text-red-600/60 dark:text-red-400/60"
9208
+ };
9209
+ }
9210
+ if (delivery.status === "delayed") {
9211
+ return {
9212
+ card: "border-l-[3px] border-l-amber-500 bg-amber-50/50 dark:bg-amber-950/30",
9213
+ icon: "text-amber-600 dark:text-amber-400",
9214
+ title: "text-foreground",
9215
+ subtitle: "text-amber-700/70 dark:text-amber-300/70",
9216
+ chevron: "text-amber-600/60 dark:text-amber-400/60"
9217
+ };
9218
+ }
9219
+ if (isComplete) {
9220
+ return {
9221
+ card: "border-l-[3px] border-l-green-500 bg-green-50/50 dark:bg-green-950/30",
9222
+ icon: "text-green-600 dark:text-green-400",
9223
+ title: "text-foreground",
9224
+ subtitle: "text-green-700/70 dark:text-green-300/70",
9225
+ chevron: "text-green-600/60 dark:text-green-400/60"
9226
+ };
9227
+ }
9228
+ return {
9229
+ card: "border-l-[3px] border-l-muted-foreground/40 bg-muted/30 dark:bg-muted/20",
9230
+ icon: "text-muted-foreground",
9231
+ title: "text-foreground",
9232
+ subtitle: "text-muted-foreground",
9233
+ chevron: "text-muted-foreground/60"
9234
+ };
9235
+ };
9236
+ const styles = getCardStyles3();
9237
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9238
+ "button",
9239
+ {
9240
+ onClick,
9241
+ className: cn(
9242
+ "w-full flex items-center justify-between p-3 rounded-lg",
9243
+ "transition-all duration-200 ease-out cursor-pointer text-left",
9244
+ "hover:-translate-y-0.5 hover:shadow-[var(--j3m-shadow-md)]",
9245
+ styles.card
9246
+ ),
9247
+ children: [
9248
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
9249
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: cn("h-5 w-5 shrink-0", styles.icon) }),
9250
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
9251
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
9252
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-sm font-medium", styles.title), children: delivery.label || `Delivery ${index + 1}` }),
9253
+ hasComments && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
9254
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "h-3 w-3 text-muted-foreground" }),
9255
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -top-0.5 -right-0.5 h-1.5 w-1.5 rounded-full bg-primary" })
9256
+ ] })
9257
+ ] }),
9258
+ delivery.destination && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("text-xs", styles.subtitle), children: [
9259
+ "\u2192 ",
9260
+ delivery.destination
9261
+ ] })
9262
+ ] })
9263
+ ] }),
9264
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
9265
+ /* @__PURE__ */ jsxRuntime.jsx(
9266
+ Badge,
9267
+ {
9268
+ variant: getStatusBadgeVariant2(delivery.status, isComplete),
9269
+ className: cn("text-xs", getStatusBadgeClasses2(delivery.status, isComplete)),
9270
+ children: getStatusLabel2(delivery.status, isComplete)
9271
+ }
9272
+ ),
9273
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: cn("h-4 w-4", styles.chevron) })
9274
+ ] })
9275
+ ]
9276
+ }
9277
+ );
9278
+ }
9279
+ function DeliveryDetailsView2({
9280
+ delivery,
9281
+ week,
9282
+ onBack,
9283
+ onAddComment
9284
+ }) {
9285
+ const elements = delivery.elements ?? [];
9286
+ const categorizedElements = React27__namespace.useMemo(() => {
9287
+ const sent = [];
9288
+ const notSent = [];
9289
+ const moved = [];
9290
+ const addons = [];
9291
+ elements.forEach((element) => {
9292
+ const status = getElementShipmentStatus(element, delivery.id);
9293
+ switch (status) {
9294
+ case "sent":
9295
+ sent.push(element);
9296
+ break;
9297
+ case "not-sent":
9298
+ notSent.push(element);
9299
+ break;
9300
+ case "moved":
9301
+ moved.push(element);
9302
+ break;
9303
+ case "addon":
9304
+ addons.push(element);
9305
+ break;
9306
+ default:
9307
+ notSent.push(element);
9308
+ }
9309
+ });
9310
+ return { sent, notSent, moved, addons };
9311
+ }, [elements, delivery.id]);
9312
+ const totalCount = elements.length;
9313
+ const sentCount = categorizedElements.sent.length;
9314
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col h-full animate-in slide-in-from-right-4 duration-200", children: [
9315
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2 px-4 py-3 border-b", children: /* @__PURE__ */ jsxRuntime.jsxs(
9316
+ Button,
9317
+ {
9318
+ variant: "ghost",
9319
+ size: "sm",
9320
+ className: "gap-1 -ml-2",
9321
+ onClick: onBack,
9322
+ children: [
9323
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "h-4 w-4" }),
9324
+ "Back"
9325
+ ]
9326
+ }
9327
+ ) }),
9328
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 py-4 space-y-2", children: [
9329
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
9330
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold", children: delivery.label || "Delivery Details" }),
9331
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
9332
+ /* @__PURE__ */ jsxRuntime.jsx(
9333
+ DeliveryCommentPopover2,
9334
+ {
9335
+ comments: delivery.comments,
9336
+ onAddComment,
9337
+ deliveryLabel: delivery.label || "Delivery"
9338
+ }
9339
+ ),
9340
+ /* @__PURE__ */ jsxRuntime.jsx(
9341
+ Badge,
9342
+ {
9343
+ variant: getStatusBadgeVariant2(delivery.status, sentCount === totalCount && totalCount > 0),
9344
+ className: cn("text-xs", getStatusBadgeClasses2(delivery.status, sentCount === totalCount && totalCount > 0)),
9345
+ children: getStatusLabel2(delivery.status, sentCount === totalCount && totalCount > 0)
9346
+ }
9347
+ )
9348
+ ] })
9349
+ ] }),
9350
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 text-sm text-muted-foreground", children: [
9351
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
9352
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Calendar, { className: "h-3.5 w-3.5" }),
9353
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
9354
+ week.label,
9355
+ " \u2022 ",
9356
+ week.dateRange
9357
+ ] })
9358
+ ] }),
9359
+ delivery.destination && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
9360
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: "h-3.5 w-3.5" }),
9361
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
9362
+ "\u2192 ",
9363
+ delivery.destination
9364
+ ] })
9365
+ ] })
9366
+ ] })
9367
+ ] }),
9368
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "flex-1 px-4 pb-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
9369
+ totalCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg bg-muted/50 p-4 space-y-3", children: [
9370
+ /* @__PURE__ */ jsxRuntime.jsx(
9371
+ StatusProgress,
9372
+ {
9373
+ value: totalCount > 0 ? sentCount / totalCount * 100 : 0,
9374
+ currentCount: sentCount,
9375
+ totalCount,
9376
+ unitLabel: "shipped",
9377
+ showLabel: true,
9378
+ showCheckmark: true,
9379
+ size: "md"
9380
+ }
9381
+ ),
9382
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 flex-wrap", children: [
9383
+ categorizedElements.sent.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [
9384
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircle2, { className: "h-3 w-3 text-green-600" }),
9385
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-green-700 dark:text-green-300", children: [
9386
+ categorizedElements.sent.length,
9387
+ " Sent"
9388
+ ] })
9389
+ ] }),
9390
+ categorizedElements.notSent.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [
9391
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XCircle, { className: "h-3 w-3 text-muted-foreground" }),
9392
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground", children: [
9393
+ categorizedElements.notSent.length,
9394
+ " Missing"
9395
+ ] })
9396
+ ] }),
9397
+ categorizedElements.moved.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [
9398
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowRight, { className: "h-3 w-3 text-blue-600" }),
9399
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-blue-700 dark:text-blue-300", children: [
9400
+ categorizedElements.moved.length,
9401
+ " Moved"
9402
+ ] })
9403
+ ] }),
9404
+ categorizedElements.addons.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [
9405
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3 w-3 text-purple-600" }),
9406
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-purple-700 dark:text-purple-300", children: [
9407
+ categorizedElements.addons.length,
9408
+ " Add-on"
9409
+ ] })
9410
+ ] })
9411
+ ] })
9412
+ ] }),
9413
+ elements.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
9414
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "Elements" }),
9415
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(Table, { children: [
9416
+ /* @__PURE__ */ jsxRuntime.jsx(TableHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(TableRow, { className: "bg-sidebar hover:bg-sidebar", children: [
9417
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "font-semibold", children: "Prefix" }),
9418
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "font-semibold", children: "Type" }),
9419
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "font-semibold text-right", children: "Weight" }),
9420
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "font-semibold text-center", children: "Status" })
9421
+ ] }) }),
9422
+ /* @__PURE__ */ jsxRuntime.jsx(TableBody, { children: elements.map((element) => {
9423
+ const shipmentStatus = getElementShipmentStatus(element, delivery.id);
9424
+ const statusLabel = getShipmentStatusLabel(shipmentStatus);
9425
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9426
+ TableRow,
9427
+ {
9428
+ className: getShipmentStatusRowBg2(shipmentStatus),
9429
+ children: [
9430
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { className: "font-medium", children: element.prefix || "\u2014" }),
9431
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { children: element.type || element.name || "\u2014" }),
9432
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { className: "text-right tabular-nums", children: element.weight ? `${element.weight} ${element.weightUnit || "kg"}` : "\u2014" }),
9433
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-1", children: [
9434
+ /* @__PURE__ */ jsxRuntime.jsx(
9435
+ Badge,
9436
+ {
9437
+ variant: "outline",
9438
+ className: cn("text-[10px] h-5", getShipmentStatusBadgeClasses2(shipmentStatus)),
9439
+ children: statusLabel
9440
+ }
9441
+ ),
9442
+ shipmentStatus === "moved" && element.actualDeliveryLabel && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[9px] text-blue-600 dark:text-blue-400", children: [
9443
+ "\u2192 ",
9444
+ element.actualDeliveryLabel
9445
+ ] }),
9446
+ shipmentStatus === "addon" && element.originalDeliveryLabel && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[9px] text-purple-600 dark:text-purple-400", children: [
9447
+ "from ",
9448
+ element.originalDeliveryLabel
9449
+ ] })
9450
+ ] }) })
9451
+ ]
9452
+ },
9453
+ element.id
9454
+ );
9455
+ }) })
9456
+ ] }) })
9457
+ ] }),
9458
+ elements.length === 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-8 text-muted-foreground", children: [
9459
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Package, { className: "h-8 w-8 mx-auto mb-2 opacity-50" }),
9460
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm", children: "No elements in this delivery" })
9461
+ ] })
9462
+ ] }) })
9463
+ ] });
9464
+ }
9465
+ function MainView2({
9466
+ supplier,
9467
+ week,
9468
+ data,
9469
+ productionElements,
9470
+ previousProducedCount,
9471
+ onOpenProductionDialog,
9472
+ onSelectDelivery,
9473
+ onAddProductionComment
9474
+ }) {
9475
+ const production = data?.production;
9476
+ const producedCount = productionElements.filter((e) => e.isProduced).length;
9477
+ const totalCount = productionElements.length;
9478
+ const productionProgress = totalCount > 0 ? Math.round(producedCount / totalCount * 100) : 0;
9479
+ const isComplete = productionProgress >= 100;
9480
+ const hasProductionComments = (production?.comments?.length ?? 0) > 0;
9481
+ const showPreviousProgress = !isComplete && previousProducedCount !== void 0 && previousProducedCount !== producedCount;
9482
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "animate-in fade-in-0 duration-200", children: [
9483
+ /* @__PURE__ */ jsxRuntime.jsxs(SheetHeader, { className: "px-4 pt-4 pb-3 border-b", children: [
9484
+ /* @__PURE__ */ jsxRuntime.jsxs(SheetTitle, { className: "flex items-center gap-2", children: [
9485
+ supplier.name,
9486
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "secondary", className: "text-xs font-normal", children: supplier.badgeType })
9487
+ ] }),
9488
+ /* @__PURE__ */ jsxRuntime.jsxs(SheetDescription, { className: "flex items-center gap-2", children: [
9489
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Calendar, { className: "h-4 w-4" }),
9490
+ week.label,
9491
+ " \u2022 ",
9492
+ week.dateRange
9493
+ ] })
9494
+ ] }),
9495
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "flex-1 px-4 pb-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6 pt-4", children: [
9496
+ data.type !== "empty" && /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-4", children: [
9497
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
9498
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Factory, { className: "h-4 w-4 text-muted-foreground" }),
9499
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold", children: "Production" })
9500
+ ] }),
9501
+ totalCount > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
9502
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center py-4", children: [
9503
+ /* @__PURE__ */ jsxRuntime.jsx(
9504
+ CircularProgress,
9505
+ {
9506
+ value: productionProgress,
9507
+ size: 88,
9508
+ strokeWidth: 8,
9509
+ variant: productionProgress >= 100 ? "success" : productionProgress >= 50 ? "success" : productionProgress > 0 ? "warning" : "destructive",
9510
+ showCheckmark: true,
9511
+ children: productionProgress < 100 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-lg font-bold tabular-nums", children: [
9512
+ Math.round(productionProgress),
9513
+ "%"
9514
+ ] })
9515
+ }
9516
+ ),
9517
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 text-center", children: [
9518
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm font-semibold text-foreground", children: [
9519
+ producedCount,
9520
+ " / ",
9521
+ totalCount,
9522
+ " elements"
9523
+ ] }),
9524
+ showPreviousProgress && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-muted-foreground mt-1", children: [
9525
+ "Previously: ",
9526
+ previousProducedCount,
9527
+ " / ",
9528
+ totalCount
9529
+ ] })
9530
+ ] })
9531
+ ] }),
9532
+ /* @__PURE__ */ jsxRuntime.jsx(
9533
+ Button,
9534
+ {
9535
+ className: "w-full",
9536
+ onClick: onOpenProductionDialog,
9537
+ children: "Enter production progress"
9538
+ }
9539
+ )
9540
+ ] }) : (
9541
+ /* No elements - show placeholder with button still available */
9542
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
9543
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-6 text-muted-foreground bg-muted/30 rounded-lg", children: [
9544
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Package, { className: "h-8 w-8 mx-auto mb-2 opacity-50" }),
9545
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm", children: "No elements to track" })
9546
+ ] }),
9547
+ /* @__PURE__ */ jsxRuntime.jsx(
9548
+ Button,
9549
+ {
9550
+ className: "w-full",
9551
+ variant: "outline",
9552
+ onClick: onOpenProductionDialog,
9553
+ children: "Enter production progress"
9554
+ }
9555
+ )
9556
+ ] })
9557
+ ),
9558
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
9559
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
9560
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Comments" }),
9561
+ hasProductionComments && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] text-muted-foreground", children: [
9562
+ "(",
9563
+ production?.comments?.length,
9564
+ ")"
9565
+ ] })
9566
+ ] }),
9567
+ /* @__PURE__ */ jsxRuntime.jsx(
9568
+ ProductionCommentSection2,
9569
+ {
9570
+ comments: production?.comments,
9571
+ onAddComment: onAddProductionComment
9572
+ }
9573
+ )
9574
+ ] })
9575
+ ] }),
9576
+ data.deliveries && data.deliveries.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-4", children: [
9577
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
9578
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: "h-4 w-4 text-muted-foreground" }),
9579
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold", children: "Deliveries" }),
9580
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground ml-auto", children: [
9581
+ data.deliveries.length,
9582
+ " scheduled"
9583
+ ] })
9584
+ ] }),
9585
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: data.deliveries.map((delivery, index) => /* @__PURE__ */ jsxRuntime.jsx(
9586
+ DeliveryListItem2,
9587
+ {
9588
+ delivery,
9589
+ index,
9590
+ onClick: () => onSelectDelivery(delivery)
9591
+ },
9592
+ delivery.id
9593
+ )) })
9594
+ ] }),
9595
+ data.type === "no-logistics" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-muted-foreground p-3 bg-muted/50 rounded-lg", children: [
9596
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: "h-4 w-4" }),
9597
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: "No logistics scheduled for this week" })
9598
+ ] }),
9599
+ data.hasWarning && data.warningMessage && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2 rounded-lg bg-amber-50 dark:bg-amber-950/50 p-3 text-amber-700 dark:text-amber-300", children: [
9600
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-4 w-4 mt-0.5 shrink-0" }),
9601
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm", children: data.warningMessage })
9602
+ ] }),
9603
+ data.notes && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
9604
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "Notes" }),
9605
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm", children: data.notes })
9606
+ ] })
9607
+ ] }) })
9608
+ ] });
9609
+ }
9610
+ function WeekDetailSheet({
9611
+ open,
9612
+ onOpenChange,
9613
+ supplier,
9614
+ week,
9615
+ data,
9616
+ onProductionUpdate,
9617
+ onAddProductionComment,
9618
+ onAddDeliveryComment
9619
+ }) {
9620
+ const [selectedDelivery, setSelectedDelivery] = React27__namespace.useState(null);
9621
+ const [productionDialogOpen, setProductionDialogOpen] = React27__namespace.useState(false);
9622
+ const [previousProducedCount, setPreviousProducedCount] = React27__namespace.useState(void 0);
9623
+ const productionElements = React27__namespace.useMemo(() => {
9624
+ if (!data?.deliveries) return [];
9625
+ const elements = [];
9626
+ const seenIds = /* @__PURE__ */ new Set();
9627
+ data.deliveries.forEach((delivery) => {
9628
+ delivery.elements?.forEach((element) => {
9629
+ if (!seenIds.has(element.id)) {
9630
+ seenIds.add(element.id);
9631
+ elements.push({
9632
+ id: element.id,
9633
+ name: element.name,
9634
+ prefix: element.prefix,
9635
+ type: element.type,
9636
+ weight: element.weight,
9637
+ size: element.sizeSqm,
9638
+ sizeUnit: "sqm",
9639
+ isProduced: element.isProduced
9640
+ });
9641
+ }
9642
+ });
9643
+ });
9644
+ return elements;
9645
+ }, [data?.deliveries]);
9646
+ const currentProducedCount = productionElements.filter((e) => e.isProduced).length;
9647
+ React27__namespace.useEffect(() => {
9648
+ if (open && data?.deliveries) {
9649
+ setPreviousProducedCount(currentProducedCount);
9650
+ }
9651
+ }, [open]);
9652
+ React27__namespace.useEffect(() => {
9653
+ if (!open) {
9654
+ setSelectedDelivery(null);
9655
+ setProductionDialogOpen(false);
9656
+ setPreviousProducedCount(void 0);
9657
+ }
9658
+ }, [open]);
9659
+ const handleProductionSave = (producedIds) => {
9660
+ if (!supplier || !week || !onProductionUpdate) return;
9661
+ const weekKey = `${week.year}-W${week.weekNumber.toString().padStart(2, "0")}`;
9662
+ onProductionUpdate(supplier.id, weekKey, producedIds);
9663
+ setPreviousProducedCount(producedIds.length);
9664
+ };
9665
+ if (!supplier || !week || !data) {
9666
+ return null;
9667
+ }
9668
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9669
+ /* @__PURE__ */ jsxRuntime.jsx(Sheet, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsx(
9670
+ SheetContent,
9671
+ {
9672
+ side: "right",
9673
+ className: "w-full sm:max-w-lg p-0 overflow-hidden",
9674
+ children: selectedDelivery ? /* @__PURE__ */ jsxRuntime.jsx(
9675
+ DeliveryDetailsView2,
9676
+ {
9677
+ delivery: selectedDelivery,
9678
+ week,
9679
+ onBack: () => setSelectedDelivery(null),
9680
+ onAddComment: onAddDeliveryComment ? (text) => {
9681
+ const weekKey = `${week.year}-W${week.weekNumber.toString().padStart(2, "0")}`;
9682
+ onAddDeliveryComment(supplier.id, weekKey, selectedDelivery.id, text);
9683
+ } : void 0
9684
+ }
9685
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
9686
+ MainView2,
9687
+ {
9688
+ supplier,
9689
+ week,
9690
+ data,
9691
+ productionElements,
9692
+ previousProducedCount,
9693
+ onOpenProductionDialog: () => setProductionDialogOpen(true),
9694
+ onSelectDelivery: setSelectedDelivery,
9695
+ onAddProductionComment: onAddProductionComment ? (text) => {
9696
+ const weekKey = `${week.year}-W${week.weekNumber.toString().padStart(2, "0")}`;
9697
+ onAddProductionComment(supplier.id, weekKey, text);
9698
+ } : void 0
9699
+ }
9700
+ )
9701
+ }
9702
+ ) }),
9703
+ /* @__PURE__ */ jsxRuntime.jsx(
9704
+ ElementProductionDialog,
9705
+ {
9706
+ open: productionDialogOpen,
9707
+ onOpenChange: setProductionDialogOpen,
9708
+ elements: productionElements,
9709
+ onSave: handleProductionSave
9710
+ }
9711
+ )
9712
+ ] });
9713
+ }
9714
+ function RowHeaderCell({
9715
+ className,
9716
+ data,
9717
+ showProgress = true,
9718
+ ...props
9719
+ }) {
9720
+ const progressPercent = data.totalRequired > 0 ? Math.min(data.totalBooked / data.totalRequired * 100, 100) : 0;
9721
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9722
+ "div",
9723
+ {
9724
+ "data-slot": "row-header-cell",
9725
+ className: cn(
9726
+ "flex flex-col justify-center gap-1.5 py-2 px-3 min-w-[200px] h-[100px] bg-background",
9727
+ className
9728
+ ),
9729
+ ...props,
9730
+ children: [
9731
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-2", children: [
9732
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
9733
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-bold leading-tight text-foreground truncate", children: data.name }),
9734
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: data.typeCode })
9735
+ ] }),
9736
+ /* @__PURE__ */ jsxRuntime.jsxs(
9737
+ Badge,
9738
+ {
9739
+ variant: "outline",
9740
+ className: "text-[10px] px-2 py-0.5 h-[19px] font-medium shrink-0 gap-1 bg-background border-border",
9741
+ children: [
9742
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Flag, { className: "h-2.5 w-2.5" }),
9743
+ "Paint"
9744
+ ]
9745
+ }
9746
+ )
9747
+ ] }),
9748
+ showProgress && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
9749
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-1.5 bg-black/10 dark:bg-white/10 rounded-full overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
9750
+ "div",
9751
+ {
9752
+ className: "h-full bg-primary rounded-full transition-all",
9753
+ style: { width: `${progressPercent}%` }
8194
9754
  }
8195
9755
  ) }),
8196
9756
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] font-medium text-primary", children: [
@@ -8853,6 +10413,84 @@ function CalibrationTable({
8853
10413
  () => prefixes.map((p) => ({ id: p.id, name: p.name })),
8854
10414
  [prefixes]
8855
10415
  );
10416
+ const insightMetrics = React27__namespace.useMemo(() => {
10417
+ let totalCalibrated = 0;
10418
+ let totalRequired = 0;
10419
+ for (const prefix of prefixes) {
10420
+ for (const weekKey in prefix.weeks) {
10421
+ const cell = prefix.weeks[weekKey];
10422
+ if (cell.planned > 0) {
10423
+ totalRequired += cell.planned;
10424
+ totalCalibrated += cell.entered ?? 0;
10425
+ }
10426
+ }
10427
+ }
10428
+ const completeness = totalRequired > 0 ? totalCalibrated / totalRequired * 100 : 0;
10429
+ const remaining = Math.max(0, totalRequired - totalCalibrated);
10430
+ return [
10431
+ {
10432
+ key: "calibrated",
10433
+ label: "calibrated",
10434
+ value: totalCalibrated,
10435
+ unit: "tons",
10436
+ icon: "factory",
10437
+ status: completeness >= 100 ? "success" : "normal"
10438
+ },
10439
+ {
10440
+ key: "remaining",
10441
+ label: "remaining",
10442
+ value: remaining,
10443
+ unit: "tons",
10444
+ icon: "factory",
10445
+ status: remaining > 0 ? "warning" : "success"
10446
+ },
10447
+ {
10448
+ key: "completeness",
10449
+ label: "complete",
10450
+ value: completeness,
10451
+ isPercentage: true,
10452
+ icon: "trending",
10453
+ status: completeness >= 100 ? "success" : completeness >= 50 ? "normal" : "warning"
10454
+ }
10455
+ ];
10456
+ }, [prefixes]);
10457
+ const columnSummaryData = React27__namespace.useMemo(() => {
10458
+ return weeks.map((week) => {
10459
+ const weekKey = getWeekKey(week.startDate);
10460
+ let calibratedTons = 0;
10461
+ let requiredTons = 0;
10462
+ let hasShortfall = false;
10463
+ let allValid = true;
10464
+ for (const prefix of prefixes) {
10465
+ const cell = prefix.weeks[weekKey];
10466
+ if (cell) {
10467
+ requiredTons += cell.planned;
10468
+ calibratedTons += cell.entered ?? 0;
10469
+ if (cell.status === "shortfall") hasShortfall = true;
10470
+ if (cell.status !== "valid" && cell.planned > 0) allValid = false;
10471
+ }
10472
+ }
10473
+ let status2 = "normal";
10474
+ if (hasShortfall) {
10475
+ status2 = "critical";
10476
+ } else if (allValid && requiredTons > 0) {
10477
+ status2 = "complete";
10478
+ }
10479
+ return {
10480
+ columnKey: weekKey,
10481
+ primary: {
10482
+ value: calibratedTons,
10483
+ unit: "t",
10484
+ icon: "factory"
10485
+ },
10486
+ secondary: {
10487
+ value: requiredTons,
10488
+ unit: "t req"
10489
+ },
10490
+ status: status2
10491
+ };
10492
+ });
10493
+ }, [weeks, prefixes]);
8856
10494
  return /* @__PURE__ */ jsxRuntime.jsxs(
8857
10495
  "div",
8858
10496
  {
@@ -8863,6 +10501,7 @@ function CalibrationTable({
8863
10501
  /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-semibold tracking-tight", children: "Weekly Production Calibration" }),
8864
10502
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: "Review required weekly production and confirm achievable output at the selected checkpoint." })
8865
10503
  ] }) }),
10504
+ /* @__PURE__ */ jsxRuntime.jsx(InsightBar, { metrics: insightMetrics }),
8866
10505
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
8867
10506
  showToolbar && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
8868
10507
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -8895,36 +10534,74 @@ function CalibrationTable({
8895
10534
  style: { maxHeight },
8896
10535
  children: [
8897
10536
  /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full border-collapse", children: [
8898
- /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "sticky top-0 z-20", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
8899
- /* @__PURE__ */ jsxRuntime.jsx("th", { className: cn(
8900
- "h-14 px-3 text-left align-middle font-semibold text-xs text-muted-foreground uppercase tracking-wide",
8901
- "border-r border-b border-border bg-sidebar",
8902
- stickyRowHeader && "sticky left-0 z-30 min-w-[200px]",
8903
- // Right shadow using Quantum token
8904
- stickyRowHeader && "shadow-[var(--j3m-shadow-sticky-edge)]"
8905
- ), children: "Supplier / Scope" }),
8906
- weeks.map((week) => {
8907
- const weekKey = getWeekKey(week.startDate);
8908
- const weekComments = getWeekComments(weekKey);
8909
- return /* @__PURE__ */ jsxRuntime.jsx(
8910
- "th",
8911
- {
8912
- className: "h-14 px-2 text-left align-middle border-r border-b border-border last:border-r-0 min-w-[220px] bg-sidebar",
8913
- children: /* @__PURE__ */ jsxRuntime.jsx(
8914
- CalibrationWeekHeader,
8915
- {
8916
- week,
8917
- comments: weekComments,
8918
- showCommentButton: true,
8919
- availablePrefixes,
8920
- onAddComment: (text, prefixId, prefixName) => handleAddWeekComment(weekKey, text, prefixId)
8921
- }
8922
- )
8923
- },
8924
- weekKey
8925
- );
8926
- })
8927
- ] }) }),
10537
+ /* @__PURE__ */ jsxRuntime.jsxs("thead", { className: "sticky top-0 z-20", children: [
10538
+ /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
10539
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: cn(
10540
+ "h-14 px-3 text-left align-middle font-semibold text-xs text-muted-foreground uppercase tracking-wide",
10541
+ "border-r border-b border-border bg-sidebar",
10542
+ stickyRowHeader && "sticky left-0 z-30 min-w-[200px]",
10543
+ // Right shadow using Quantum token
10544
+ stickyRowHeader && "shadow-[var(--j3m-shadow-sticky-edge)]"
10545
+ ), children: "Supplier / Scope" }),
10546
+ weeks.map((week) => {
10547
+ const weekKey = getWeekKey(week.startDate);
10548
+ const weekComments = getWeekComments(weekKey);
10549
+ return /* @__PURE__ */ jsxRuntime.jsx(
10550
+ "th",
10551
+ {
10552
+ className: "h-14 px-2 text-left align-middle border-r border-b border-border last:border-r-0 min-w-[220px] bg-sidebar",
10553
+ children: /* @__PURE__ */ jsxRuntime.jsx(
10554
+ CalibrationWeekHeader,
10555
+ {
10556
+ week,
10557
+ comments: weekComments,
10558
+ showCommentButton: true,
10559
+ availablePrefixes,
10560
+ onAddComment: (text, prefixId, prefixName) => handleAddWeekComment(weekKey, text, prefixId)
10561
+ }
10562
+ )
10563
+ },
10564
+ weekKey
10565
+ );
10566
+ })
10567
+ ] }),
10568
+ /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
10569
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: cn(
10570
+ "h-auto px-3 py-1.5 text-left align-middle",
10571
+ "border-r border-b border-border bg-muted/30",
10572
+ stickyRowHeader && "sticky left-0 z-30 min-w-[200px]",
10573
+ stickyRowHeader && "shadow-[var(--j3m-shadow-sticky-edge)]"
10574
+ ), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium text-muted-foreground uppercase tracking-wide", children: "Summary" }) }),
10575
+ columnSummaryData.map((summary) => {
10576
+ const statusBg = summary.status === "complete" ? "bg-green-50/50 dark:bg-green-950/30" : summary.status === "critical" ? "bg-red-50/50 dark:bg-red-950/30" : "bg-muted/30";
10577
+ const statusText = summary.status === "complete" ? "text-green-700 dark:text-green-300" : summary.status === "critical" ? "text-red-700 dark:text-red-300" : "text-muted-foreground";
10578
+ return /* @__PURE__ */ jsxRuntime.jsx(
10579
+ "th",
10580
+ {
10581
+ className: cn(
10582
+ "h-auto px-2 py-1.5 text-left align-middle",
10583
+ "border-r border-b border-border last:border-r-0 min-w-[220px]",
10584
+ statusBg
10585
+ ),
10586
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [
10587
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
10588
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Factory, { className: cn("h-3 w-3", statusText) }),
10589
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("text-xs font-medium tabular-nums", statusText), children: [
10590
+ summary.primary?.value.toLocaleString(void 0, { maximumFractionDigits: 1 }),
10591
+ " t"
10592
+ ] })
10593
+ ] }),
10594
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] text-muted-foreground tabular-nums", children: [
10595
+ summary.secondary?.value.toLocaleString(void 0, { maximumFractionDigits: 1 }),
10596
+ " t req"
10597
+ ] })
10598
+ ] })
10599
+ },
10600
+ summary.columnKey
10601
+ );
10602
+ })
10603
+ ] })
10604
+ ] }),
8928
10605
  /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "bg-background", children: paginatedPrefixes.length > 0 ? paginatedPrefixes.map((prefix) => {
8929
10606
  const sortedWeekKeys = weeks.map((w) => getWeekKey(w.startDate));
8930
10607
  let hasDeficit = false;
@@ -9423,40 +11100,40 @@ function groupDeliveriesByPrefixAndDay(deliveries) {
9423
11100
  }
9424
11101
  return grouped;
9425
11102
  }
9426
- function getLeftStrokeStyles(state, hasRisk, isHovered) {
11103
+ function getCardStyles(state, hasRisk) {
9427
11104
  if (hasRisk) {
9428
11105
  return {
9429
- stroke: "border-l-[3px] border-l-red-500",
9430
- content: "text-foreground",
9431
- progressBg: "bg-red-500",
9432
- iconColor: "text-red-600 dark:text-red-400",
9433
- cardBg: "bg-background"
11106
+ fill: statusCellFillClasses.risk.combined,
11107
+ titleColor: statusCellTextClasses.risk.title,
11108
+ subtitleColor: statusCellTextClasses.risk.subtitle,
11109
+ iconColor: statusCellTextClasses.risk.icon,
11110
+ opacity: ""
9434
11111
  };
9435
11112
  }
9436
11113
  switch (state) {
9437
11114
  case "sent":
9438
11115
  return {
9439
- stroke: "border-l-[3px] border-l-green-500/40",
9440
- content: "text-muted-foreground/50",
9441
- progressBg: "bg-green-500/50",
9442
- iconColor: "text-green-600/50 dark:text-green-400/50",
9443
- cardBg: "bg-muted/30"
11116
+ fill: statusCellFillClasses.shipped.combined,
11117
+ titleColor: statusCellTextClasses.shipped.title,
11118
+ subtitleColor: statusCellTextClasses.shipped.subtitle,
11119
+ iconColor: statusCellTextClasses.shipped.icon,
11120
+ opacity: "opacity-75"
9444
11121
  };
9445
11122
  case "ready":
9446
11123
  return {
9447
- stroke: "border-l-[3px] border-l-green-500",
9448
- content: "text-foreground",
9449
- progressBg: "bg-green-500",
9450
- iconColor: "text-green-600 dark:text-green-400",
9451
- cardBg: "bg-background"
11124
+ fill: statusCellFillClasses.ready.combined,
11125
+ titleColor: statusCellTextClasses.ready.title,
11126
+ subtitleColor: statusCellTextClasses.ready.subtitle,
11127
+ iconColor: statusCellTextClasses.ready.icon,
11128
+ opacity: ""
9452
11129
  };
9453
11130
  default:
9454
11131
  return {
9455
- stroke: isHovered ? "border-l-[3px] border-l-primary/50" : "border-l-[3px] border-l-border",
9456
- content: "text-foreground",
9457
- progressBg: "bg-primary",
9458
- iconColor: "text-muted-foreground",
9459
- cardBg: "bg-background"
11132
+ fill: statusCellFillClasses.normal.combined,
11133
+ titleColor: statusCellTextClasses.normal.title,
11134
+ subtitleColor: statusCellTextClasses.normal.subtitle,
11135
+ iconColor: statusCellTextClasses.normal.icon,
11136
+ opacity: ""
9460
11137
  };
9461
11138
  }
9462
11139
  }
@@ -9466,55 +11143,10 @@ function DeliveryBadge({
9466
11143
  onCommentClick,
9467
11144
  className
9468
11145
  }) {
9469
- const [isHovered, setIsHovered] = React27__namespace.useState(false);
9470
11146
  const hasComments = delivery.comments.length > 0;
9471
11147
  const visualState = getDeliveryVisualState(delivery);
9472
- const styles = getLeftStrokeStyles(visualState, delivery.hasProductionRisk ?? false, isHovered);
9473
- const prefixTitle = React27__namespace.useMemo(() => {
9474
- const prefixSet = /* @__PURE__ */ new Set();
9475
- if (delivery.elements && delivery.elements.length > 0) {
9476
- for (const element of delivery.elements) {
9477
- if (element.prefix) {
9478
- prefixSet.add(element.prefix);
9479
- }
9480
- }
9481
- }
9482
- if (prefixSet.size === 0 && delivery.prefixScope) {
9483
- prefixSet.add(delivery.prefixScope);
9484
- }
9485
- const prefixes = Array.from(prefixSet);
9486
- if (prefixes.length === 0) {
9487
- return delivery.label;
9488
- }
9489
- if (prefixes.length > 3) {
9490
- return `${prefixes.slice(0, 3).join(" \xB7 ")} \xB7 +${prefixes.length - 3}`;
9491
- }
9492
- return prefixes.join(" \xB7 ");
9493
- }, [delivery]);
9494
- const productionProgress = React27__namespace.useMemo(() => {
9495
- if (delivery.producedTons !== void 0 && delivery.totalTons !== void 0 && delivery.totalTons > 0) {
9496
- return Math.min(delivery.producedTons / delivery.totalTons * 100, 100);
9497
- }
9498
- if (delivery.producedCount !== void 0 && delivery.totalCount !== void 0 && delivery.totalCount > 0) {
9499
- return Math.min(delivery.producedCount / delivery.totalCount * 100, 100);
9500
- }
9501
- if (delivery.loadedCount !== void 0 && delivery.totalCount !== void 0 && delivery.totalCount > 0) {
9502
- return Math.min(delivery.loadedCount / delivery.totalCount * 100, 100);
9503
- }
9504
- return 0;
9505
- }, [delivery]);
9506
- const productionDisplay = React27__namespace.useMemo(() => {
9507
- if (delivery.producedTons !== void 0 && delivery.totalTons !== void 0) {
9508
- return `${delivery.producedTons}/${delivery.totalTons}t`;
9509
- }
9510
- if (delivery.producedCount !== void 0 && delivery.totalCount !== void 0) {
9511
- return `${delivery.producedCount}/${delivery.totalCount}`;
9512
- }
9513
- if (delivery.loadedCount !== void 0 && delivery.totalCount !== void 0) {
9514
- return `${delivery.loadedCount}/${delivery.totalCount}`;
9515
- }
9516
- return null;
9517
- }, [delivery]);
11148
+ const styles = getCardStyles(visualState, delivery.hasProductionRisk ?? false);
11149
+ const projectName = delivery.destination || delivery.label;
9518
11150
  const handleClick = (e) => {
9519
11151
  e.stopPropagation();
9520
11152
  onClick?.();
@@ -9530,38 +11162,22 @@ function DeliveryBadge({
9530
11162
  e.stopPropagation();
9531
11163
  onCommentClick?.();
9532
11164
  };
9533
- const amountColorClass = React27__namespace.useMemo(() => {
9534
- if (visualState === "sent") {
9535
- return "text-muted-foreground/40";
9536
- }
9537
- if (delivery.isReadyToUnload) {
9538
- return "text-green-600 dark:text-green-400";
9539
- }
9540
- if (delivery.hasProductionRisk) {
9541
- return "text-red-600 dark:text-red-400";
9542
- }
9543
- return "text-muted-foreground";
9544
- }, [visualState, delivery.isReadyToUnload, delivery.hasProductionRisk]);
9545
11165
  return /* @__PURE__ */ jsxRuntime.jsxs(
9546
11166
  "div",
9547
11167
  {
9548
11168
  className: cn(
9549
11169
  // Position relative for comment button
9550
11170
  "relative",
9551
- // Full-width in cell, 90° corners
9552
- "w-full rounded-none",
9553
- // Sizing using Quantum tokens:
9554
- // - min-h-[100px] card min-height
9555
- // - pt-4 pb-3 = vertical padding (j3m.spacing.m / j3m.spacing.s)
9556
- // - pl-4 = left padding (j3m.spacing.m)
9557
- // - pr-2 = minimal right padding (progress bar extends further)
9558
- "min-h-[100px] pt-4 pb-3 pl-4 pr-2",
9559
- // Card base: dynamic background based on state, complete border
9560
- styles.cardBg,
9561
- "border border-border",
9562
- // Left stroke for status
9563
- styles.stroke,
9564
- // Interactive states (reduced for sent state)
11171
+ // Full-width in cell, small radius (matching planning cards)
11172
+ "w-full rounded-lg",
11173
+ // Compact sizing - min-h-[72px], p-4 (j3m.spacing.m)
11174
+ "min-h-[72px] p-4",
11175
+ // FULL-CARD STATUS FILL - uses shared calibration/planning tokens
11176
+ // This is the key change: status fill on outermost container
11177
+ styles.fill,
11178
+ // Opacity for shipped state
11179
+ styles.opacity,
11180
+ // Interactive states (disabled hover lift for shipped)
9565
11181
  "transition-all duration-200 ease-out",
9566
11182
  visualState !== "sent" && "hover:-translate-y-0.5 hover:shadow-[var(--j3m-shadow-md)]",
9567
11183
  className
@@ -9574,10 +11190,12 @@ function DeliveryBadge({
9574
11190
  variant: "ghost",
9575
11191
  size: "icon",
9576
11192
  className: cn(
9577
- "absolute top-2 right-2",
11193
+ "absolute top-1.5 right-1.5",
9578
11194
  // 44px touch target for accessibility
9579
11195
  "h-11 w-11",
9580
11196
  "rounded-full",
11197
+ // Subtle background for visibility on colored fills
11198
+ "bg-background/50 hover:bg-background/80",
9581
11199
  hasComments && "text-primary"
9582
11200
  ),
9583
11201
  onClick: handleCommentClick,
@@ -9600,13 +11218,11 @@ function DeliveryBadge({
9600
11218
  type: "button",
9601
11219
  onClick: handleClick,
9602
11220
  onKeyDown: handleKeyDown,
9603
- onMouseEnter: () => setIsHovered(true),
9604
- onMouseLeave: () => setIsHovered(false),
9605
11221
  className: cn(
9606
11222
  // Full width, no background (inherits from parent)
9607
11223
  "w-full bg-transparent text-left",
9608
11224
  // Layout - vertical stack
9609
- "flex flex-col gap-2",
11225
+ "flex flex-col justify-between h-full min-h-[40px]",
9610
11226
  // Interactive states
9611
11227
  "cursor-pointer",
9612
11228
  "active:translate-y-0 active:shadow-sm",
@@ -9614,33 +11230,20 @@ function DeliveryBadge({
9614
11230
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1"
9615
11231
  ),
9616
11232
  children: [
9617
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 overflow-hidden pr-12", children: [
9618
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-sm font-semibold truncate", styles.content), children: prefixTitle }),
9619
- delivery.hasProductionRisk && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-4 w-4 text-red-500 shrink-0" }),
9620
- delivery.supplierName && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
9621
- "text-xs truncate ml-auto",
9622
- visualState === "sent" ? "text-muted-foreground/40" : "text-muted-foreground"
9623
- ), children: delivery.supplierName })
11233
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2 pr-12", children: [
11234
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
11235
+ "text-sm font-semibold leading-tight line-clamp-2",
11236
+ styles.titleColor
11237
+ ), children: projectName }),
11238
+ delivery.hasProductionRisk && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: cn("h-4 w-4 shrink-0 mt-0.5", styles.iconColor) })
9624
11239
  ] }),
9625
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pr-14", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2 bg-black/10 dark:bg-white/10 rounded-full overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
9626
- "div",
9627
- {
9628
- className: cn("h-full rounded-full transition-all", styles.progressBg),
9629
- style: { width: `${productionProgress}%` }
9630
- }
9631
- ) }) }),
9632
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
9633
- productionDisplay && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
9634
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Factory, { className: cn("h-3 w-3 shrink-0", styles.iconColor) }),
9635
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
9636
- "text-[11px] tabular-nums font-medium",
9637
- amountColorClass
9638
- ), children: productionDisplay })
11240
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 mt-2", children: [
11241
+ visualState === "sent" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
11242
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: cn("h-3.5 w-3.5 shrink-0", styles.iconColor) }),
11243
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-[10px] font-medium uppercase tracking-wide", styles.subtitleColor), children: "Shipped" })
9639
11244
  ] }),
9640
- visualState === "sent" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 ml-auto", children: [
9641
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3.5 w-3.5 text-green-600/60 dark:text-green-400/60 shrink-0" }),
9642
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium text-muted-foreground/50 uppercase tracking-wide", children: "Sent" })
9643
- ] })
11245
+ visualState === "ready" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-[10px] font-semibold uppercase tracking-wide", styles.subtitleColor), children: "Ready" }),
11246
+ delivery.hasProductionRisk && visualState !== "sent" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-[10px] font-semibold uppercase tracking-wide", styles.subtitleColor), children: "At Risk" })
9644
11247
  ] })
9645
11248
  ]
9646
11249
  }
@@ -9649,6 +11252,62 @@ function DeliveryBadge({
9649
11252
  }
9650
11253
  );
9651
11254
  }
11255
+ function isShippedDelivery(delivery) {
11256
+ return delivery.status === "shipped" || delivery.status === "delivered";
11257
+ }
11258
+ function ShippedDeliveriesToggle({
11259
+ shippedDeliveries,
11260
+ isOpen,
11261
+ onToggle,
11262
+ onDeliveryClick,
11263
+ onDeliveryCommentClick
11264
+ }) {
11265
+ if (shippedDeliveries.length === 0) return null;
11266
+ return /* @__PURE__ */ jsxRuntime.jsxs(Collapsible, { open: isOpen, onOpenChange: onToggle, children: [
11267
+ /* @__PURE__ */ jsxRuntime.jsx(CollapsibleTrigger2, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
11268
+ "button",
11269
+ {
11270
+ type: "button",
11271
+ className: cn(
11272
+ "w-full flex items-center justify-between gap-2",
11273
+ "min-h-[44px] px-3 py-2",
11274
+ "rounded-md",
11275
+ "text-xs text-muted-foreground",
11276
+ "hover:bg-muted/50 transition-colors",
11277
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary"
11278
+ ),
11279
+ children: [
11280
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
11281
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3.5 w-3.5 text-green-600 dark:text-green-400" }),
11282
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
11283
+ "Shipped (",
11284
+ shippedDeliveries.length,
11285
+ ")"
11286
+ ] })
11287
+ ] }),
11288
+ /* @__PURE__ */ jsxRuntime.jsx(
11289
+ lucideReact.ChevronDown,
11290
+ {
11291
+ className: cn(
11292
+ "h-4 w-4 transition-transform duration-200",
11293
+ isOpen && "rotate-180"
11294
+ )
11295
+ }
11296
+ )
11297
+ ]
11298
+ }
11299
+ ) }),
11300
+ /* @__PURE__ */ jsxRuntime.jsx(CollapsibleContent2, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-3 pt-2", children: shippedDeliveries.map((delivery) => /* @__PURE__ */ jsxRuntime.jsx(
11301
+ DeliveryBadge,
11302
+ {
11303
+ delivery,
11304
+ onClick: () => onDeliveryClick?.(delivery),
11305
+ onCommentClick: () => onDeliveryCommentClick?.(delivery)
11306
+ },
11307
+ delivery.id
11308
+ )) }) })
11309
+ ] });
11310
+ }
9652
11311
  function WeeklyLoadingView({
9653
11312
  week,
9654
11313
  deliveries,
@@ -9658,6 +11317,24 @@ function WeeklyLoadingView({
9658
11317
  showNavigation = true,
9659
11318
  className
9660
11319
  }) {
11320
+ const [shippedOpenState, setShippedOpenState] = React27__namespace.useState({
11321
+ 1: false,
11322
+ // Monday
11323
+ 2: false,
11324
+ // Tuesday
11325
+ 3: false,
11326
+ // Wednesday
11327
+ 4: false,
11328
+ // Thursday
11329
+ 5: false
11330
+ // Friday
11331
+ });
11332
+ const toggleShippedForDay = (dayOfWeek) => {
11333
+ setShippedOpenState((prev) => ({
11334
+ ...prev,
11335
+ [dayOfWeek]: !prev[dayOfWeek]
11336
+ }));
11337
+ };
9661
11338
  const weekDays = React27__namespace.useMemo(() => {
9662
11339
  const days = [];
9663
11340
  for (let i = 0; i < 5; i++) {
@@ -9673,19 +11350,36 @@ function WeeklyLoadingView({
9673
11350
  const deliveriesByDay = React27__namespace.useMemo(() => {
9674
11351
  const grouped = /* @__PURE__ */ new Map();
9675
11352
  for (let i = 1; i <= 5; i++) {
9676
- grouped.set(i, []);
11353
+ grouped.set(i, { pending: [], shipped: [] });
9677
11354
  }
9678
11355
  for (const delivery of deliveries) {
9679
11356
  const dayOfWeek = delivery.date.getDay();
9680
11357
  if (dayOfWeek >= 1 && dayOfWeek <= 5) {
9681
- const dayDeliveries = grouped.get(dayOfWeek) ?? [];
9682
- dayDeliveries.push(delivery);
9683
- grouped.set(dayOfWeek, dayDeliveries);
11358
+ const dayData = grouped.get(dayOfWeek);
11359
+ if (isShippedDelivery(delivery)) {
11360
+ dayData.shipped.push(delivery);
11361
+ } else {
11362
+ dayData.pending.push(delivery);
11363
+ }
9684
11364
  }
9685
11365
  }
9686
11366
  return grouped;
9687
11367
  }, [deliveries]);
9688
- const totalDeliveries = deliveries.length;
11368
+ const totalPendingDeliveries = deliveries.filter((d) => !isShippedDelivery(d)).length;
11369
+ const totalShippedDeliveries = deliveries.filter((d) => isShippedDelivery(d)).length;
11370
+ const daySummaryData = React27__namespace.useMemo(() => {
11371
+ const summaries = /* @__PURE__ */ new Map();
11372
+ for (let i = 1; i <= 5; i++) {
11373
+ const dayData = deliveriesByDay.get(i) ?? { pending: [], shipped: [] };
11374
+ const allDayDeliveries = [...dayData.pending, ...dayData.shipped];
11375
+ summaries.set(i, {
11376
+ deliveries: allDayDeliveries.length,
11377
+ tonsRequired: allDayDeliveries.reduce((sum, d) => sum + (d.totalTons ?? 0), 0),
11378
+ tonsProduced: allDayDeliveries.reduce((sum, d) => sum + (d.producedTons ?? 0), 0)
11379
+ });
11380
+ }
11381
+ return summaries;
11382
+ }, [deliveriesByDay]);
9689
11383
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col", className), children: [
9690
11384
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4 border-b border-border p-4 lg:flex-row lg:items-center lg:justify-between", children: [
9691
11385
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
@@ -9702,9 +11396,9 @@ function WeeklyLoadingView({
9702
11396
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
9703
11397
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: week.dateRange }),
9704
11398
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: [
9705
- totalDeliveries,
9706
- " ",
9707
- totalDeliveries === 1 ? "delivery" : "deliveries"
11399
+ totalPendingDeliveries,
11400
+ " pending",
11401
+ totalShippedDeliveries > 0 && `, ${totalShippedDeliveries} shipped`
9708
11402
  ] })
9709
11403
  ] })
9710
11404
  ] }),
@@ -9770,9 +11464,48 @@ function WeeklyLoadingView({
9770
11464
  },
9771
11465
  dayOfWeek
9772
11466
  )) }),
11467
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-5 border-b border-border", children: weekDays.map(({ dayOfWeek, isToday: dayIsToday }) => {
11468
+ const summary = daySummaryData.get(dayOfWeek) ?? { deliveries: 0, tonsRequired: 0, tonsProduced: 0 };
11469
+ const productionComplete = summary.tonsRequired > 0 && summary.tonsProduced >= summary.tonsRequired;
11470
+ return /* @__PURE__ */ jsxRuntime.jsxs(
11471
+ "div",
11472
+ {
11473
+ className: cn(
11474
+ "flex flex-col gap-0.5 py-1.5 px-2",
11475
+ productionComplete ? "bg-green-50/50 dark:bg-green-950/30" : "bg-muted/20",
11476
+ dayIsToday && "bg-primary/5"
11477
+ ),
11478
+ children: [
11479
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
11480
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: "h-3 w-3 text-muted-foreground" }),
11481
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium tabular-nums text-muted-foreground", children: summary.deliveries })
11482
+ ] }),
11483
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
11484
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Factory, { className: cn(
11485
+ "h-3 w-3",
11486
+ productionComplete ? "text-green-600 dark:text-green-400" : "text-muted-foreground"
11487
+ ) }),
11488
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn(
11489
+ "text-[10px] tabular-nums",
11490
+ productionComplete ? "text-green-700 dark:text-green-300" : "text-muted-foreground"
11491
+ ), children: [
11492
+ summary.tonsProduced.toLocaleString(void 0, { maximumFractionDigits: 1 }),
11493
+ "/",
11494
+ summary.tonsRequired.toLocaleString(void 0, { maximumFractionDigits: 1 }),
11495
+ " t"
11496
+ ] })
11497
+ ] })
11498
+ ]
11499
+ },
11500
+ dayOfWeek
11501
+ );
11502
+ }) }),
9773
11503
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-5", children: weekDays.map(({ dayOfWeek, isToday: dayIsToday }) => {
9774
- const dayDeliveries = deliveriesByDay.get(dayOfWeek) ?? [];
9775
- return /* @__PURE__ */ jsxRuntime.jsx(
11504
+ const dayData = deliveriesByDay.get(dayOfWeek) ?? { pending: [], shipped: [] };
11505
+ const hasPending = dayData.pending.length > 0;
11506
+ const hasShipped = dayData.shipped.length > 0;
11507
+ const isEmpty = !hasPending && !hasShipped;
11508
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9776
11509
  "div",
9777
11510
  {
9778
11511
  className: cn(
@@ -9780,22 +11513,39 @@ function WeeklyLoadingView({
9780
11513
  "flex flex-col p-3",
9781
11514
  dayIsToday && "bg-primary/5"
9782
11515
  ),
9783
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-3", children: dayDeliveries.length > 0 ? dayDeliveries.map((delivery) => /* @__PURE__ */ jsxRuntime.jsx(
9784
- DeliveryBadge,
9785
- {
9786
- delivery,
9787
- onClick: () => onDeliveryClick?.(delivery),
9788
- onCommentClick: () => onDeliveryCommentClick?.(delivery)
9789
- },
9790
- delivery.id
9791
- )) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-6 text-sm text-muted-foreground/40", children: "\u2014" }) })
11516
+ children: [
11517
+ hasPending && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-3", children: dayData.pending.map((delivery) => /* @__PURE__ */ jsxRuntime.jsx(
11518
+ DeliveryBadge,
11519
+ {
11520
+ delivery,
11521
+ onClick: () => onDeliveryClick?.(delivery),
11522
+ onCommentClick: () => onDeliveryCommentClick?.(delivery)
11523
+ },
11524
+ delivery.id
11525
+ )) }),
11526
+ hasShipped && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(hasPending && "mt-3"), children: /* @__PURE__ */ jsxRuntime.jsx(
11527
+ ShippedDeliveriesToggle,
11528
+ {
11529
+ shippedDeliveries: dayData.shipped,
11530
+ isOpen: shippedOpenState[dayOfWeek] ?? false,
11531
+ onToggle: () => toggleShippedForDay(dayOfWeek),
11532
+ onDeliveryClick,
11533
+ onDeliveryCommentClick
11534
+ }
11535
+ ) }),
11536
+ isEmpty && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-6 text-sm text-muted-foreground/40", children: "\u2014" })
11537
+ ]
9792
11538
  },
9793
11539
  dayOfWeek
9794
11540
  );
9795
11541
  }) })
9796
11542
  ] }),
9797
11543
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sm:hidden divide-y divide-border", children: weekDays.map(({ date, dayOfWeek, isToday: dayIsToday }) => {
9798
- const dayDeliveries = deliveriesByDay.get(dayOfWeek) ?? [];
11544
+ const dayData = deliveriesByDay.get(dayOfWeek) ?? { pending: [], shipped: [] };
11545
+ const hasPending = dayData.pending.length > 0;
11546
+ const hasShipped = dayData.shipped.length > 0;
11547
+ const isEmpty = !hasPending && !hasShipped;
11548
+ dayData.pending.length + dayData.shipped.length;
9799
11549
  return /* @__PURE__ */ jsxRuntime.jsxs(
9800
11550
  "div",
9801
11551
  {
@@ -9818,20 +11568,33 @@ function WeeklyLoadingView({
9818
11568
  dayIsToday && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-primary font-medium bg-primary/10 px-2 py-0.5 rounded", children: "Today" })
9819
11569
  ] }),
9820
11570
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: [
9821
- dayDeliveries.length,
9822
- " ",
9823
- dayDeliveries.length === 1 ? "delivery" : "deliveries"
11571
+ dayData.pending.length,
11572
+ " pending",
11573
+ hasShipped && `, ${dayData.shipped.length} shipped`
9824
11574
  ] })
9825
11575
  ] }),
9826
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-3 p-3 pt-0", children: dayDeliveries.length > 0 ? dayDeliveries.map((delivery) => /* @__PURE__ */ jsxRuntime.jsx(
9827
- DeliveryBadge,
9828
- {
9829
- delivery,
9830
- onClick: () => onDeliveryClick?.(delivery),
9831
- onCommentClick: () => onDeliveryCommentClick?.(delivery)
9832
- },
9833
- delivery.id
9834
- )) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-muted-foreground/40 py-4 text-center", children: "\u2014" }) })
11576
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 p-3 pt-0", children: [
11577
+ hasPending && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-3", children: dayData.pending.map((delivery) => /* @__PURE__ */ jsxRuntime.jsx(
11578
+ DeliveryBadge,
11579
+ {
11580
+ delivery,
11581
+ onClick: () => onDeliveryClick?.(delivery),
11582
+ onCommentClick: () => onDeliveryCommentClick?.(delivery)
11583
+ },
11584
+ delivery.id
11585
+ )) }),
11586
+ hasShipped && /* @__PURE__ */ jsxRuntime.jsx(
11587
+ ShippedDeliveriesToggle,
11588
+ {
11589
+ shippedDeliveries: dayData.shipped,
11590
+ isOpen: shippedOpenState[dayOfWeek] ?? false,
11591
+ onToggle: () => toggleShippedForDay(dayOfWeek),
11592
+ onDeliveryClick,
11593
+ onDeliveryCommentClick
11594
+ }
11595
+ ),
11596
+ isEmpty && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-muted-foreground/40 py-4 text-center", children: "\u2014" })
11597
+ ] })
9835
11598
  ]
9836
11599
  },
9837
11600
  dayOfWeek
@@ -9840,36 +11603,63 @@ function WeeklyLoadingView({
9840
11603
  ] })
9841
11604
  ] });
9842
11605
  }
9843
- function getStatusBadgeVariant2(status) {
9844
- switch (status) {
9845
- case "shipped":
9846
- case "delivered":
9847
- return "default";
9848
- case "loaded":
9849
- case "in_progress":
9850
- return "secondary";
9851
- case "cancelled":
9852
- return "destructive";
9853
- case "planned":
9854
- default:
9855
- return "outline";
11606
+ function getTimelineState(delivery) {
11607
+ const isShipped = delivery.status === "shipped" || delivery.status === "delivered";
11608
+ const isReady = delivery.isReadyToUnload ?? false;
11609
+ const hasProductionData = delivery.producedCount !== void 0 || delivery.producedTons !== void 0;
11610
+ if (isShipped) {
11611
+ return {
11612
+ currentStep: "delivery",
11613
+ documentState: "completed",
11614
+ productionState: "completed",
11615
+ deliveryState: "completed",
11616
+ isReady: true,
11617
+ currentStepLabel: "Delivery",
11618
+ reason: "Delivery completed"
11619
+ };
9856
11620
  }
9857
- }
9858
- function getStatusBadgeClasses2(status) {
9859
- switch (status) {
9860
- case "shipped":
9861
- case "delivered":
9862
- return "border-green-500 text-green-600 bg-green-50 dark:bg-green-950/50";
9863
- case "loaded":
9864
- return "border-blue-500 text-blue-600 bg-blue-50 dark:bg-blue-950/50";
9865
- case "in_progress":
9866
- return "border-amber-500 text-amber-600 bg-amber-50 dark:bg-amber-950/50";
9867
- case "cancelled":
9868
- return "";
9869
- case "planned":
9870
- default:
9871
- return "border-muted-foreground/50 text-muted-foreground";
11621
+ if (isReady) {
11622
+ return {
11623
+ currentStep: "delivery",
11624
+ documentState: "completed",
11625
+ productionState: "completed",
11626
+ deliveryState: "current",
11627
+ isReady: true,
11628
+ currentStepLabel: "Delivery",
11629
+ reason: "All prerequisites complete"
11630
+ };
11631
+ }
11632
+ if (hasProductionData) {
11633
+ return {
11634
+ currentStep: "production",
11635
+ documentState: "completed",
11636
+ productionState: "current",
11637
+ deliveryState: "upcoming",
11638
+ isReady: false,
11639
+ currentStepLabel: "Production",
11640
+ reason: delivery.hasProductionRisk ? delivery.riskReason || "Production delay risk" : "Not all items have been produced"
11641
+ };
11642
+ }
11643
+ if (delivery.status === "planned") {
11644
+ return {
11645
+ currentStep: "document",
11646
+ documentState: "current",
11647
+ productionState: "upcoming",
11648
+ deliveryState: "upcoming",
11649
+ isReady: false,
11650
+ currentStepLabel: "Document",
11651
+ reason: "Waiting for document approval"
11652
+ };
9872
11653
  }
11654
+ return {
11655
+ currentStep: "production",
11656
+ documentState: "completed",
11657
+ productionState: "current",
11658
+ deliveryState: "upcoming",
11659
+ isReady: false,
11660
+ currentStepLabel: "Production",
11661
+ reason: "Production status pending"
11662
+ };
9873
11663
  }
9874
11664
  function getElementStatusBadgeClasses(status) {
9875
11665
  switch (status) {
@@ -9885,6 +11675,166 @@ function getElementStatusBadgeClasses(status) {
9885
11675
  return "border-muted-foreground/50 text-muted-foreground";
9886
11676
  }
9887
11677
  }
11678
+ var TIMELINE_STEPS = [
11679
+ { id: "document", label: "Document", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "h-4 w-4" }) },
11680
+ { id: "production", label: "Production", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Factory, { className: "h-4 w-4" }) },
11681
+ { id: "delivery", label: "Delivery", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: "h-4 w-4" }) }
11682
+ ];
11683
+ function getStepStyles(state) {
11684
+ switch (state) {
11685
+ case "completed":
11686
+ return {
11687
+ dot: "bg-green-500/20 border-green-500",
11688
+ icon: "text-green-600 dark:text-green-400",
11689
+ label: "text-muted-foreground",
11690
+ line: "bg-green-500"
11691
+ };
11692
+ case "current":
11693
+ return {
11694
+ dot: "bg-primary/20 border-primary",
11695
+ icon: "text-primary",
11696
+ label: "text-foreground font-semibold",
11697
+ line: "bg-border"
11698
+ };
11699
+ case "upcoming":
11700
+ default:
11701
+ return {
11702
+ dot: "bg-muted border-border",
11703
+ icon: "text-muted-foreground/50",
11704
+ label: "text-muted-foreground/50",
11705
+ line: "bg-border"
11706
+ };
11707
+ }
11708
+ }
11709
+ function DeliveryTimeline({ timelineState }) {
11710
+ const getStateForStep = (stepId) => {
11711
+ switch (stepId) {
11712
+ case "document":
11713
+ return timelineState.documentState;
11714
+ case "production":
11715
+ return timelineState.productionState;
11716
+ case "delivery":
11717
+ return timelineState.deliveryState;
11718
+ }
11719
+ };
11720
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-between w-full", children: TIMELINE_STEPS.map((step, index) => {
11721
+ const state = getStateForStep(step.id);
11722
+ const styles = getStepStyles(state);
11723
+ const isLast = index === TIMELINE_STEPS.length - 1;
11724
+ return /* @__PURE__ */ jsxRuntime.jsxs(React27__namespace.Fragment, { children: [
11725
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-2", children: [
11726
+ /* @__PURE__ */ jsxRuntime.jsx(
11727
+ "div",
11728
+ {
11729
+ className: cn(
11730
+ "flex items-center justify-center",
11731
+ "h-10 w-10 rounded-full border-2",
11732
+ "transition-colors duration-200",
11733
+ styles.dot
11734
+ ),
11735
+ children: state === "completed" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: cn("h-4 w-4", styles.icon) }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles.icon, children: step.icon })
11736
+ }
11737
+ ),
11738
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-xs", styles.label), children: step.label })
11739
+ ] }),
11740
+ !isLast && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 mx-2 mb-6", children: /* @__PURE__ */ jsxRuntime.jsx(
11741
+ "div",
11742
+ {
11743
+ className: cn(
11744
+ "h-0.5 w-full rounded-full",
11745
+ styles.line
11746
+ )
11747
+ }
11748
+ ) })
11749
+ ] }, step.id);
11750
+ }) });
11751
+ }
11752
+ function PackingStatusBadge({
11753
+ timelineState,
11754
+ hasRisk
11755
+ }) {
11756
+ const getPackingStatus = () => {
11757
+ if (timelineState.isReady) {
11758
+ return {
11759
+ label: "Ready",
11760
+ className: "bg-green-100 dark:bg-green-900/50 text-green-700 dark:text-green-300 border-green-200 dark:border-green-800"
11761
+ };
11762
+ }
11763
+ if (hasRisk) {
11764
+ return {
11765
+ label: "At risk",
11766
+ className: "bg-red-100 dark:bg-red-900/50 text-red-700 dark:text-red-300 border-red-200 dark:border-red-800"
11767
+ };
11768
+ }
11769
+ switch (timelineState.currentStep) {
11770
+ case "document":
11771
+ return {
11772
+ label: "Pending approval",
11773
+ className: "bg-muted text-muted-foreground border-border"
11774
+ };
11775
+ case "production":
11776
+ return {
11777
+ label: "In production",
11778
+ className: "bg-amber-100 dark:bg-amber-900/50 text-amber-700 dark:text-amber-300 border-amber-200 dark:border-amber-800"
11779
+ };
11780
+ default:
11781
+ return {
11782
+ label: "Not ready",
11783
+ className: "bg-muted text-muted-foreground border-border"
11784
+ };
11785
+ }
11786
+ };
11787
+ const status = getPackingStatus();
11788
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
11789
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "Packing status:" }),
11790
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
11791
+ "inline-flex items-center px-2 py-0.5 rounded text-xs font-medium border",
11792
+ status.className
11793
+ ), children: status.label })
11794
+ ] });
11795
+ }
11796
+ function ReadinessMessage({
11797
+ timelineState,
11798
+ hasRisk
11799
+ }) {
11800
+ if (timelineState.isReady && timelineState.deliveryState === "completed") {
11801
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg bg-green-50/50 dark:bg-green-950/20 border border-green-200 dark:border-green-800/50 p-3", children: [
11802
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
11803
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-4 w-4 text-green-600 dark:text-green-400 shrink-0" }),
11804
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-green-700 dark:text-green-300", children: "Shipped" })
11805
+ ] }),
11806
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-green-600/80 dark:text-green-400/80 mt-1 ml-6", children: "Delivery has been completed." })
11807
+ ] });
11808
+ }
11809
+ if (timelineState.isReady) {
11810
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg bg-green-50/50 dark:bg-green-950/20 border border-green-200 dark:border-green-800/50 p-3", children: [
11811
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
11812
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-4 w-4 text-green-600 dark:text-green-400 shrink-0" }),
11813
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-green-700 dark:text-green-300", children: "Ready" })
11814
+ ] }),
11815
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-green-600/80 dark:text-green-400/80 mt-1 ml-6", children: "All prerequisites are complete." })
11816
+ ] });
11817
+ }
11818
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
11819
+ "rounded-lg p-3 border",
11820
+ hasRisk ? "bg-red-50/50 dark:bg-red-950/20 border-red-200 dark:border-red-800/50" : "bg-muted/50 border-border"
11821
+ ), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [
11822
+ hasRisk ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-4 w-4 text-red-500 shrink-0 mt-0.5" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-4 rounded-full bg-primary/20 border border-primary shrink-0 mt-0.5" }),
11823
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11824
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn(
11825
+ "text-sm font-medium",
11826
+ hasRisk ? "text-red-700 dark:text-red-300" : "text-foreground"
11827
+ ), children: [
11828
+ "Currently in: ",
11829
+ timelineState.currentStepLabel
11830
+ ] }),
11831
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn(
11832
+ "text-xs mt-0.5",
11833
+ hasRisk ? "text-red-600/80 dark:text-red-400/80" : "text-muted-foreground"
11834
+ ), children: timelineState.reason })
11835
+ ] })
11836
+ ] }) });
11837
+ }
9888
11838
  function getElementRowBg(status) {
9889
11839
  switch (status) {
9890
11840
  case "loaded":
@@ -10058,31 +12008,6 @@ function CommentsSection({
10058
12008
  )
10059
12009
  ] });
10060
12010
  }
10061
- function getDeliveryHeaderStyles(state, hasRisk) {
10062
- if (hasRisk) {
10063
- return {
10064
- iconBg: "bg-red-100 dark:bg-red-950/50",
10065
- iconColor: "text-red-600 dark:text-red-400"
10066
- };
10067
- }
10068
- switch (state) {
10069
- case "sent":
10070
- return {
10071
- iconBg: "bg-green-100 dark:bg-green-950/50",
10072
- iconColor: "text-green-600 dark:text-green-400"
10073
- };
10074
- case "ready":
10075
- return {
10076
- iconBg: "bg-green-100 dark:bg-green-950/50",
10077
- iconColor: "text-green-600 dark:text-green-400"
10078
- };
10079
- default:
10080
- return {
10081
- iconBg: "bg-muted",
10082
- iconColor: "text-muted-foreground"
10083
- };
10084
- }
10085
- }
10086
12011
  function DeliveryDetailPage({
10087
12012
  delivery,
10088
12013
  week,
@@ -10093,13 +12018,7 @@ function DeliveryDetailPage({
10093
12018
  onAddComment,
10094
12019
  onConfirmLoad
10095
12020
  }) {
10096
- const visualState = getDeliveryVisualState(delivery);
10097
- const headerStyles = getDeliveryHeaderStyles(visualState, delivery.hasProductionRisk ?? false);
10098
- const loadedCount = delivery.loadedCount ?? delivery.elements.filter((e) => e.status === "loaded").length;
10099
- const totalCount = delivery.totalCount ?? delivery.elements.length;
10100
- const loadedPercent = totalCount > 0 ? Math.round(loadedCount / totalCount * 100) : 0;
10101
- const producedCount = delivery.producedCount ?? loadedCount;
10102
- const producedPercent = totalCount > 0 ? Math.round(producedCount / totalCount * 100) : 0;
12021
+ const timelineState = getTimelineState(delivery);
10103
12022
  const elementsByStatus = React27__namespace.useMemo(() => {
10104
12023
  const loaded = delivery.elements.filter((e) => e.status === "loaded");
10105
12024
  const missing = delivery.elements.filter((e) => e.status === "missing");
@@ -10108,6 +12027,7 @@ function DeliveryDetailPage({
10108
12027
  return { loaded, missing, moved, addons };
10109
12028
  }, [delivery.elements]);
10110
12029
  const preLoadingComments = delivery.comments.filter((c) => c.context === "pre_unloading");
12030
+ const projectName = delivery.destination || delivery.label;
10111
12031
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col h-full", children: [
10112
12032
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2 px-4 py-3 border-b bg-background sticky top-0 z-10", children: /* @__PURE__ */ jsxRuntime.jsxs(
10113
12033
  Button,
@@ -10123,129 +12043,39 @@ function DeliveryDetailPage({
10123
12043
  }
10124
12044
  ) }),
10125
12045
  /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "flex-1", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 pb-6 space-y-6", children: [
10126
- /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "pt-4 space-y-4", children: [
12046
+ /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "pt-4 space-y-3", children: [
10127
12047
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
10128
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3", children: [
10129
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
10130
- "flex items-center justify-center h-12 w-12 rounded-xl shrink-0",
10131
- headerStyles.iconBg
10132
- ), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: cn("h-6 w-6", headerStyles.iconColor) }) }),
10133
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
10134
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
10135
- /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-lg font-semibold", children: delivery.label }),
10136
- visualState === "sent" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-5 w-5 text-green-600 dark:text-green-400" }),
10137
- delivery.hasProductionRisk && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-5 w-5 text-red-500" })
10138
- ] }),
10139
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground", children: [
10140
- delivery.supplierName,
10141
- delivery.prefixScope && ` \u2022 ${delivery.prefixScope}`
10142
- ] })
10143
- ] })
10144
- ] }),
10145
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-end gap-1.5", children: [
10146
- /* @__PURE__ */ jsxRuntime.jsx(
10147
- Badge,
10148
- {
10149
- variant: getStatusBadgeVariant2(delivery.status),
10150
- className: cn("shrink-0", getStatusBadgeClasses2(delivery.status)),
10151
- children: getLoadingDeliveryStatusLabel(delivery.status)
10152
- }
10153
- ),
10154
- delivery.isReadyToUnload && /* @__PURE__ */ jsxRuntime.jsx(
10155
- Badge,
10156
- {
10157
- variant: "outline",
10158
- className: "bg-green-100 dark:bg-green-900/50 border-green-300 dark:border-green-700 text-green-700 dark:text-green-300",
10159
- children: "Ready to load"
10160
- }
10161
- )
10162
- ] })
12048
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-bold leading-tight line-clamp-2", children: projectName }),
12049
+ delivery.hasProductionRisk && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-5 w-5 text-red-500 shrink-0 mt-0.5" })
10163
12050
  ] }),
10164
- delivery.hasProductionRisk && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border-l-2 border-l-red-500 bg-red-50/50 dark:bg-red-950/30 p-3", children: [
10165
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
10166
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-4 w-4 text-red-600 dark:text-red-400 shrink-0" }),
10167
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-red-700 dark:text-red-400", children: "Production delay risk" })
12051
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-x-4 gap-y-1 text-sm text-muted-foreground", children: [
12052
+ delivery.location && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
12053
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MapPin, { className: "h-3.5 w-3.5 shrink-0" }),
12054
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: delivery.location })
10168
12055
  ] }),
10169
- delivery.riskReason && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-red-600 dark:text-red-400 mt-1 ml-6", children: delivery.riskReason })
10170
- ] }),
10171
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-4 text-sm text-muted-foreground", children: [
10172
12056
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
10173
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Calendar, { className: "h-4 w-4" }),
10174
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: delivery.date.toLocaleDateString("en-US", {
10175
- weekday: "short",
10176
- month: "short",
10177
- day: "numeric"
10178
- }) })
10179
- ] }),
10180
- delivery.destination && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
10181
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MapPin, { className: "h-4 w-4" }),
10182
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: delivery.destination })
10183
- ] })
10184
- ] }),
10185
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg bg-muted/50 p-4 space-y-3", children: [
10186
- (delivery.producedCount !== void 0 || delivery.producedTons !== void 0) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
10187
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
10188
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "Production" }),
10189
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn(
10190
- "text-sm font-semibold tabular-nums",
10191
- delivery.isReadyToUnload ? "text-green-600 dark:text-green-400" : delivery.hasProductionRisk ? "text-red-600 dark:text-red-400" : ""
10192
- ), children: [
10193
- delivery.producedTons !== void 0 && delivery.totalTons !== void 0 ? `${delivery.producedTons} / ${delivery.totalTons} tons` : `Produced ${producedCount} / ${totalCount}`,
10194
- delivery.isReadyToUnload && " \u2713"
10195
- ] })
10196
- ] }),
10197
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2 bg-black/10 dark:bg-white/10 rounded-full overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
10198
- "div",
10199
- {
10200
- className: cn(
10201
- "h-full rounded-full transition-all",
10202
- delivery.isReadyToUnload ? "bg-green-500" : delivery.hasProductionRisk ? "bg-red-500" : "bg-amber-500"
10203
- ),
10204
- style: { width: `${producedPercent}%` }
10205
- }
10206
- ) })
10207
- ] }),
10208
- /* @__PURE__ */ jsxRuntime.jsx(Separator, { className: "my-2" }),
10209
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
10210
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
10211
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "Loading Progress" }),
10212
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm font-semibold tabular-nums", children: [
10213
- "Loaded ",
10214
- loadedCount,
10215
- " / ",
10216
- totalCount
10217
- ] })
10218
- ] }),
10219
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2 bg-black/10 dark:bg-white/10 rounded-full overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
10220
- "div",
10221
- {
10222
- className: cn(
10223
- "h-full rounded-full transition-all",
10224
- loadedPercent === 100 ? "bg-green-500" : "bg-primary"
10225
- ),
10226
- style: { width: `${loadedPercent}%` }
10227
- }
10228
- ) }),
10229
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 flex-wrap text-xs", children: [
10230
- elementsByStatus.loaded.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-green-600 dark:text-green-400", children: [
10231
- elementsByStatus.loaded.length,
10232
- " Loaded"
10233
- ] }),
10234
- elementsByStatus.missing.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground", children: [
10235
- elementsByStatus.missing.length,
10236
- " Missing"
10237
- ] }),
10238
- elementsByStatus.moved.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-blue-600 dark:text-blue-400", children: [
10239
- elementsByStatus.moved.length,
10240
- " Moved"
10241
- ] }),
10242
- elementsByStatus.addons.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-purple-600 dark:text-purple-400", children: [
10243
- elementsByStatus.addons.length,
10244
- " Add-on"
10245
- ] })
12057
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Calendar, { className: "h-3.5 w-3.5 shrink-0" }),
12058
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
12059
+ "Expected on site: ",
12060
+ delivery.date.toLocaleDateString("en-US", {
12061
+ day: "numeric",
12062
+ month: "short",
12063
+ year: "numeric"
12064
+ })
10246
12065
  ] })
10247
12066
  ] })
10248
- ] })
12067
+ ] }),
12068
+ /* @__PURE__ */ jsxRuntime.jsx(PackingStatusBadge, { timelineState, hasRisk: delivery.hasProductionRisk ?? false })
12069
+ ] }),
12070
+ /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-4", children: [
12071
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-2", children: /* @__PURE__ */ jsxRuntime.jsx(DeliveryTimeline, { timelineState }) }),
12072
+ /* @__PURE__ */ jsxRuntime.jsx(
12073
+ ReadinessMessage,
12074
+ {
12075
+ timelineState,
12076
+ hasRisk: delivery.hasProductionRisk ?? false
12077
+ }
12078
+ )
10249
12079
  ] }),
10250
12080
  (elementsByStatus.loaded.length > 0 || elementsByStatus.missing.length > 0 || elementsByStatus.moved.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-3", children: [
10251
12081
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
@@ -10423,31 +12253,74 @@ function SupplierWeeklyLoading({
10423
12253
  handleCommentSubmit();
10424
12254
  }
10425
12255
  };
12256
+ const insightMetrics = React27__namespace.useMemo(() => {
12257
+ const totalDeliveries = deliveries.length;
12258
+ const readyDeliveries = deliveries.filter((d) => d.isReadyToUnload).length;
12259
+ deliveries.filter(
12260
+ (d) => d.status === "shipped" || d.status === "delivered"
12261
+ ).length;
12262
+ const totalTonsRequired = deliveries.reduce((sum, d) => sum + (d.totalTons ?? 0), 0);
12263
+ const producedTons = deliveries.reduce((sum, d) => sum + (d.producedTons ?? 0), 0);
12264
+ return [
12265
+ {
12266
+ key: "deliveries",
12267
+ label: "deliveries",
12268
+ value: totalDeliveries,
12269
+ icon: "truck",
12270
+ status: "normal"
12271
+ },
12272
+ {
12273
+ key: "ready",
12274
+ label: "ready",
12275
+ value: readyDeliveries,
12276
+ icon: "check",
12277
+ status: readyDeliveries > 0 ? "success" : "normal"
12278
+ },
12279
+ {
12280
+ key: "required",
12281
+ label: "tons required",
12282
+ value: totalTonsRequired,
12283
+ unit: "t",
12284
+ icon: "factory",
12285
+ status: "normal"
12286
+ },
12287
+ {
12288
+ key: "produced",
12289
+ label: "tons produced",
12290
+ value: producedTons,
12291
+ unit: "t",
12292
+ icon: "factory",
12293
+ status: producedTons >= totalTonsRequired ? "success" : producedTons >= totalTonsRequired * 0.5 ? "normal" : "warning"
12294
+ }
12295
+ ];
12296
+ }, [deliveries]);
10426
12297
  const Wrapper = bordered ? Card : "div";
10427
12298
  const Content14 = bordered ? CardContent : "div";
10428
12299
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10429
- /* @__PURE__ */ jsxRuntime.jsx(
10430
- Wrapper,
10431
- {
10432
- className: cn(
10433
- "flex flex-col overflow-hidden",
10434
- // Removed fixed min-height - content-driven sizing
10435
- !bordered && "border border-border bg-card rounded-lg",
10436
- className
10437
- ),
10438
- children: /* @__PURE__ */ jsxRuntime.jsx(Content14, { className: cn("flex-1 overflow-hidden p-0", !bordered && ""), children: /* @__PURE__ */ jsxRuntime.jsx(
10439
- WeeklyLoadingView,
10440
- {
10441
- week,
10442
- deliveries,
10443
- onDeliveryClick: handleDeliveryClick,
10444
- onDeliveryCommentClick: handleDeliveryCommentClick,
10445
- onWeekChange,
10446
- showNavigation
10447
- }
10448
- ) })
10449
- }
10450
- ),
12300
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-0", className), children: [
12301
+ /* @__PURE__ */ jsxRuntime.jsx(InsightBar, { metrics: insightMetrics, className: "rounded-t-lg border border-b-0" }),
12302
+ /* @__PURE__ */ jsxRuntime.jsx(
12303
+ Wrapper,
12304
+ {
12305
+ className: cn(
12306
+ "flex flex-col overflow-hidden rounded-t-none",
12307
+ // Removed fixed min-height - content-driven sizing
12308
+ !bordered && "border border-border bg-card rounded-lg rounded-t-none"
12309
+ ),
12310
+ children: /* @__PURE__ */ jsxRuntime.jsx(Content14, { className: cn("flex-1 overflow-hidden p-0", !bordered && ""), children: /* @__PURE__ */ jsxRuntime.jsx(
12311
+ WeeklyLoadingView,
12312
+ {
12313
+ week,
12314
+ deliveries,
12315
+ onDeliveryClick: handleDeliveryClick,
12316
+ onDeliveryCommentClick: handleDeliveryCommentClick,
12317
+ onWeekChange,
12318
+ showNavigation
12319
+ }
12320
+ ) })
12321
+ }
12322
+ )
12323
+ ] }),
10451
12324
  /* @__PURE__ */ jsxRuntime.jsx(Sheet, { open: sheetOpen, onOpenChange: (open) => !open && handleSheetClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(
10452
12325
  SheetContent,
10453
12326
  {
@@ -10524,59 +12397,40 @@ function SupplierWeeklyLoading({
10524
12397
  ] }) })
10525
12398
  ] });
10526
12399
  }
10527
- function getStatusBadgeVariant3(status) {
10528
- switch (status) {
10529
- case "shipped":
10530
- case "delivered":
10531
- return "default";
10532
- case "loaded":
10533
- case "in_progress":
10534
- return "secondary";
10535
- case "cancelled":
10536
- return "destructive";
10537
- case "planned":
10538
- default:
10539
- return "outline";
10540
- }
10541
- }
10542
- function getStatusBadgeClasses3(status) {
10543
- switch (status) {
10544
- case "shipped":
10545
- case "delivered":
10546
- return "border-green-500 text-green-600 bg-green-50 dark:bg-green-950/50";
10547
- case "loaded":
10548
- return "border-blue-500 text-blue-600 bg-blue-50 dark:bg-blue-950/50";
10549
- case "in_progress":
10550
- return "border-amber-500 text-amber-600 bg-amber-50 dark:bg-amber-950/50";
10551
- case "cancelled":
10552
- return "";
10553
- case "planned":
10554
- default:
10555
- return "border-muted-foreground/50 text-muted-foreground";
10556
- }
10557
- }
10558
- function getLeftStrokeStyles2(state, hasRisk, isHovered) {
12400
+ function getCardStyles2(state, hasRisk) {
10559
12401
  if (hasRisk) {
10560
12402
  return {
10561
- stroke: "border-l-2 border-l-red-500",
10562
- iconColor: "text-muted-foreground"
12403
+ fill: statusCellFillClasses.risk.combined,
12404
+ titleColor: statusCellTextClasses.risk.title,
12405
+ subtitleColor: statusCellTextClasses.risk.subtitle,
12406
+ iconColor: statusCellTextClasses.risk.icon,
12407
+ opacity: ""
10563
12408
  };
10564
12409
  }
10565
12410
  switch (state) {
10566
12411
  case "sent":
10567
12412
  return {
10568
- stroke: "border-l-2 border-l-green-500/50",
10569
- iconColor: "text-muted-foreground/40"
12413
+ fill: statusCellFillClasses.shipped.combined,
12414
+ titleColor: statusCellTextClasses.shipped.title,
12415
+ subtitleColor: statusCellTextClasses.shipped.subtitle,
12416
+ iconColor: statusCellTextClasses.shipped.icon,
12417
+ opacity: "opacity-75"
10570
12418
  };
10571
12419
  case "ready":
10572
12420
  return {
10573
- stroke: "border-l-2 border-l-green-500",
10574
- iconColor: "text-muted-foreground"
12421
+ fill: statusCellFillClasses.ready.combined,
12422
+ titleColor: statusCellTextClasses.ready.title,
12423
+ subtitleColor: statusCellTextClasses.ready.subtitle,
12424
+ iconColor: statusCellTextClasses.ready.icon,
12425
+ opacity: ""
10575
12426
  };
10576
12427
  default:
10577
12428
  return {
10578
- stroke: isHovered ? "border-l-2 border-l-border" : "border-l-2 border-l-transparent",
10579
- iconColor: "text-muted-foreground"
12429
+ fill: statusCellFillClasses.normal.combined,
12430
+ titleColor: statusCellTextClasses.normal.title,
12431
+ subtitleColor: statusCellTextClasses.normal.subtitle,
12432
+ iconColor: statusCellTextClasses.normal.icon,
12433
+ opacity: ""
10580
12434
  };
10581
12435
  }
10582
12436
  }
@@ -10585,22 +12439,10 @@ function DeliveryCard({
10585
12439
  onTap,
10586
12440
  className
10587
12441
  }) {
10588
- const [isHovered, setIsHovered] = React27__namespace.useState(false);
10589
12442
  const hasComments = delivery.comments.length > 0;
10590
12443
  const visualState = getDeliveryVisualState(delivery);
10591
- const styles = getLeftStrokeStyles2(visualState, delivery.hasProductionRisk ?? false, isHovered);
10592
- const productionDisplay = React27__namespace.useMemo(() => {
10593
- if (delivery.producedTons !== void 0 && delivery.totalTons !== void 0) {
10594
- return `${delivery.producedTons} / ${delivery.totalTons}t produced`;
10595
- }
10596
- if (delivery.producedCount !== void 0 && delivery.totalCount !== void 0) {
10597
- return `${delivery.producedCount} / ${delivery.totalCount} produced`;
10598
- }
10599
- if (delivery.loadedCount !== void 0 && delivery.totalCount !== void 0) {
10600
- return `Loaded ${delivery.loadedCount} / ${delivery.totalCount}`;
10601
- }
10602
- return null;
10603
- }, [delivery]);
12444
+ const styles = getCardStyles2(visualState, delivery.hasProductionRisk ?? false);
12445
+ const projectName = delivery.destination || delivery.label;
10604
12446
  const handleClick = () => {
10605
12447
  onTap?.();
10606
12448
  };
@@ -10617,76 +12459,47 @@ function DeliveryCard({
10617
12459
  tabIndex: 0,
10618
12460
  onClick: handleClick,
10619
12461
  onKeyDown: handleKeyDown,
10620
- onMouseEnter: () => setIsHovered(true),
10621
- onMouseLeave: () => setIsHovered(false),
10622
12462
  className: cn(
10623
- // Full-width, 90° corners (j3m.radius.none)
10624
- "w-full rounded-none",
12463
+ // Full-width, small radius (matching planning table cards)
12464
+ "w-full rounded-lg",
10625
12465
  // Touch-friendly sizing - 56px min-height for iPad
10626
12466
  "min-h-[56px] p-4",
10627
- // Card styling: white background, standard border
10628
- "bg-background border border-border",
10629
- // Left stroke for status (j3m.stroke.m = 2px)
10630
- styles.stroke,
10631
- // Hover/tap state - lift effect like Calibration
12467
+ // FULL-CARD STATUS FILL - uses shared calibration/planning tokens
12468
+ // This is the key change: status fill on outermost container
12469
+ styles.fill,
12470
+ // Opacity for shipped state
12471
+ styles.opacity,
12472
+ // Hover/tap state - lift effect (disabled for shipped)
10632
12473
  "cursor-pointer transition-all duration-200 ease-out",
10633
- "hover:-translate-y-0.5 hover:shadow-[var(--j3m-shadow-md)]",
12474
+ visualState !== "sent" && "hover:-translate-y-0.5 hover:shadow-[var(--j3m-shadow-md)]",
10634
12475
  "active:translate-y-0 active:shadow-sm",
10635
12476
  // Focus state
10636
12477
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary",
10637
- // Greyed out for sent state
10638
- visualState === "sent" && "opacity-60",
10639
12478
  className
10640
12479
  ),
10641
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3", children: [
10642
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-3 min-w-0 flex-1", children: [
10643
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
10644
- "flex items-center justify-center h-10 w-10 rounded-md shrink-0 bg-muted/50"
10645
- ), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: cn("h-5 w-5", styles.iconColor) }) }),
10646
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 min-w-0", children: [
10647
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
10648
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold truncate", children: delivery.label }),
10649
- visualState === "sent" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-4 w-4 text-green-600 dark:text-green-400 shrink-0" }),
10650
- visualState === "ready" && /* @__PURE__ */ jsxRuntime.jsx(
10651
- Badge,
10652
- {
10653
- variant: "outline",
10654
- className: "text-[9px] px-1.5 py-0 h-4 bg-green-100 dark:bg-green-900/50 border-green-300 dark:border-green-700 text-green-700 dark:text-green-300",
10655
- children: "Ready"
10656
- }
10657
- ),
10658
- delivery.hasProductionRisk && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-4 w-4 text-red-500 shrink-0" }),
10659
- hasComments && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative shrink-0", children: [
10660
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "h-3.5 w-3.5 text-muted-foreground" }),
10661
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -top-0.5 -right-0.5 h-2 w-2 rounded-full bg-primary" })
10662
- ] })
10663
- ] }),
10664
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground truncate", children: [
10665
- delivery.supplierName,
10666
- delivery.prefixScope && ` \u2022 ${delivery.prefixScope}`
10667
- ] }),
10668
- productionDisplay && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [
10669
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Package, { className: "h-3 w-3 text-muted-foreground" }),
10670
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn(
10671
- delivery.isReadyToUnload ? "text-green-600 dark:text-green-400 font-medium" : delivery.hasProductionRisk ? "text-red-600 dark:text-red-400" : "text-muted-foreground"
10672
- ), children: [
10673
- delivery.isReadyToUnload ? "\u2713 " : "",
10674
- productionDisplay
10675
- ] })
12480
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3", children: [
12481
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 min-w-0 flex-1", children: [
12482
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
12483
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
12484
+ "text-sm font-semibold truncate",
12485
+ styles.titleColor
12486
+ ), children: projectName }),
12487
+ delivery.hasProductionRisk && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: cn("h-4 w-4 shrink-0", styles.iconColor) }),
12488
+ hasComments && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative shrink-0 p-0.5 rounded bg-background/50", children: [
12489
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "h-3.5 w-3.5 text-muted-foreground" }),
12490
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -top-0.5 -right-0.5 h-2 w-2 rounded-full bg-primary" })
10676
12491
  ] })
12492
+ ] }),
12493
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
12494
+ visualState === "sent" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
12495
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: cn("h-3.5 w-3.5 shrink-0", styles.iconColor) }),
12496
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-[10px] font-medium uppercase tracking-wide", styles.subtitleColor), children: "Shipped" })
12497
+ ] }),
12498
+ visualState === "ready" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-[10px] font-semibold uppercase tracking-wide", styles.subtitleColor), children: "Ready" }),
12499
+ delivery.hasProductionRisk && visualState !== "sent" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-[10px] font-semibold uppercase tracking-wide", styles.subtitleColor), children: "At Risk" })
10677
12500
  ] })
10678
12501
  ] }),
10679
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 shrink-0", children: [
10680
- /* @__PURE__ */ jsxRuntime.jsx(
10681
- Badge,
10682
- {
10683
- variant: getStatusBadgeVariant3(delivery.status),
10684
- className: cn("text-[10px] h-5", getStatusBadgeClasses3(delivery.status)),
10685
- children: getLoadingDeliveryStatusLabel(delivery.status)
10686
- }
10687
- ),
10688
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4 text-muted-foreground" })
10689
- ] })
12502
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: cn("h-4 w-4 shrink-0", styles.iconColor) })
10690
12503
  ] })
10691
12504
  }
10692
12505
  );
@@ -13911,7 +15724,7 @@ var GanttContentHeader = ({
13911
15724
  return /* @__PURE__ */ jsxRuntime.jsxs(
13912
15725
  "div",
13913
15726
  {
13914
- className: "sticky top-0 z-20 grid w-full shrink-0 bg-background/95 backdrop-blur-sm",
15727
+ className: "sticky top-0 z-20 grid w-full shrink-0 bg-muted/80 backdrop-blur-sm",
13915
15728
  style: { height: "var(--gantt-header-height)" },
13916
15729
  children: [
13917
15730
  /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -14108,7 +15921,7 @@ var GanttSidebarHeader = ({
14108
15921
  }) => /* @__PURE__ */ jsxRuntime.jsxs(
14109
15922
  "div",
14110
15923
  {
14111
- className: "sticky top-0 z-10 flex shrink-0 items-end justify-between gap-2.5 border-border/50 border-b bg-background/95 px-2.5 py-2 font-medium text-muted-foreground text-xs backdrop-blur-sm",
15924
+ className: "sticky top-0 z-40 flex shrink-0 items-end justify-between gap-2.5 border-border/50 border-b bg-muted/80 px-2.5 py-2 font-medium text-muted-foreground text-xs backdrop-blur-sm",
14112
15925
  style: { height: "var(--gantt-header-height)" },
14113
15926
  children: [
14114
15927
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "flex-1 truncate text-left", children: title }),
@@ -14172,11 +15985,12 @@ var GanttGroupSummaryBar = React27.memo(({
14172
15985
  children: /* @__PURE__ */ jsxRuntime.jsx(
14173
15986
  "div",
14174
15987
  {
14175
- className: "h-full w-full rounded-sm border border-border/60 bg-muted/40 shadow-sm",
15988
+ className: "relative h-full w-full rounded-sm border border-border/60 bg-muted/40 shadow-sm overflow-hidden",
14176
15989
  style: {
14177
15990
  // Subtle gradient for depth
14178
15991
  background: "linear-gradient(180deg, hsl(var(--muted) / 0.5) 0%, hsl(var(--muted) / 0.3) 100%)"
14179
- }
15992
+ },
15993
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center px-2", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-[10px] font-medium text-muted-foreground", children: group.title }) })
14180
15994
  }
14181
15995
  )
14182
15996
  }
@@ -14208,7 +16022,7 @@ var GanttCollapsibleSidebarGroup = ({
14208
16022
  /* @__PURE__ */ jsxRuntime.jsx(CollapsibleTrigger2, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
14209
16023
  "button",
14210
16024
  {
14211
- className: "flex w-full items-center gap-2 px-2.5 py-2 text-left font-medium text-xs hover:bg-muted/30 border-b border-border/50 bg-background",
16025
+ className: "flex w-full items-center gap-2 px-2.5 py-2 text-left font-medium text-xs hover:bg-muted/70 border-b border-border/50 bg-muted/40",
14212
16026
  style: { height: "var(--gantt-row-height)" },
14213
16027
  type: "button",
14214
16028
  children: [
@@ -14250,7 +16064,7 @@ var GanttCollapsibleTimelineGroup = ({
14250
16064
  /* @__PURE__ */ jsxRuntime.jsx(
14251
16065
  "div",
14252
16066
  {
14253
- className: "relative w-full border-b border-border/50",
16067
+ className: "relative w-full border-b border-border/50 bg-muted/20",
14254
16068
  style: { height: "var(--gantt-row-height)" },
14255
16069
  children: /* @__PURE__ */ jsxRuntime.jsx(GanttGroupSummaryBar, { group })
14256
16070
  }
@@ -14268,7 +16082,7 @@ var GanttSidebarGroup = ({
14268
16082
  /* @__PURE__ */ jsxRuntime.jsx(
14269
16083
  "p",
14270
16084
  {
14271
- className: "w-full truncate px-2.5 py-2 text-left font-medium text-muted-foreground text-xs border-b border-border/50 bg-background",
16085
+ className: "w-full truncate px-2.5 py-2 text-left font-medium text-muted-foreground text-xs border-b border-border/50 bg-muted/40",
14272
16086
  style: { height: "var(--gantt-row-height)" },
14273
16087
  children: name
14274
16088
  }
@@ -14282,7 +16096,7 @@ var GanttSidebar = ({
14282
16096
  "div",
14283
16097
  {
14284
16098
  className: cn(
14285
- "sticky left-0 z-30 h-max min-h-full border-border/50 border-r bg-background",
16099
+ "sticky left-0 z-30 h-max min-h-full border-border/50 border-r bg-muted/50",
14286
16100
  className
14287
16101
  ),
14288
16102
  style: { width: "var(--gantt-sidebar-width)" },
@@ -15446,6 +17260,8 @@ exports.CircularProgress = CircularProgress;
15446
17260
  exports.Collapsible = Collapsible;
15447
17261
  exports.CollapsibleContent = CollapsibleContent2;
15448
17262
  exports.CollapsibleTrigger = CollapsibleTrigger2;
17263
+ exports.ColumnSummaryCell = ColumnSummaryCell;
17264
+ exports.ColumnSummaryStrip = ColumnSummaryStrip;
15449
17265
  exports.Command = Command;
15450
17266
  exports.CommandDialog = CommandDialog;
15451
17267
  exports.CommandEmpty = CommandEmpty;
@@ -15585,6 +17401,7 @@ exports.InputGroupButton = InputGroupButton;
15585
17401
  exports.InputGroupInput = InputGroupInput;
15586
17402
  exports.InputGroupText = InputGroupText;
15587
17403
  exports.InputGroupTextarea = InputGroupTextarea;
17404
+ exports.InsightBar = InsightBar;
15588
17405
  exports.Item = Item6;
15589
17406
  exports.ItemActions = ItemActions;
15590
17407
  exports.ItemContent = ItemContent;
@@ -15732,6 +17549,7 @@ exports.SiteHeader = SiteHeader;
15732
17549
  exports.Skeleton = Skeleton;
15733
17550
  exports.Slider = Slider;
15734
17551
  exports.Spinner = Spinner;
17552
+ exports.StatusProgress = StatusProgress;
15735
17553
  exports.SubmitCalibrationBar = SubmitCalibrationBar;
15736
17554
  exports.SupplierCell = SupplierCell;
15737
17555
  exports.SupplierWeeklyLoading = SupplierWeeklyLoading;
@@ -15767,6 +17585,7 @@ exports.UserAvatarsDropdown = UserAvatarsDropdown;
15767
17585
  exports.VIEW_LABELS = VIEW_LABELS;
15768
17586
  exports.WeekCell = WeekCell;
15769
17587
  exports.WeekDetailDialog = WeekDetailDialog;
17588
+ exports.WeekDetailSheet = WeekDetailSheet;
15770
17589
  exports.WeekHeader = WeekHeader;
15771
17590
  exports.WeekView = WeekView;
15772
17591
  exports.WeeklyLoadingView = WeeklyLoadingView;