@j3m-quantum/ui 1.9.1 → 1.10.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.js CHANGED
@@ -9369,36 +9369,41 @@ function getLeftStrokeStyles(state, hasRisk, isHovered) {
9369
9369
  stroke: "border-l-[3px] border-l-red-500",
9370
9370
  content: "text-foreground",
9371
9371
  progressBg: "bg-red-500",
9372
- iconColor: "text-red-600 dark:text-red-400"
9372
+ iconColor: "text-red-600 dark:text-red-400",
9373
+ cardBg: "bg-background"
9373
9374
  };
9374
9375
  }
9375
9376
  switch (state) {
9376
9377
  case "sent":
9377
9378
  return {
9378
- stroke: "border-l-[3px] border-l-green-500/50",
9379
- content: "text-muted-foreground/60",
9380
- progressBg: "bg-green-500",
9381
- iconColor: "text-green-600 dark:text-green-400"
9379
+ stroke: "border-l-[3px] border-l-green-500/40",
9380
+ content: "text-muted-foreground/50",
9381
+ progressBg: "bg-green-500/50",
9382
+ iconColor: "text-green-600/50 dark:text-green-400/50",
9383
+ cardBg: "bg-muted/30"
9382
9384
  };
9383
9385
  case "ready":
9384
9386
  return {
9385
9387
  stroke: "border-l-[3px] border-l-green-500",
9386
9388
  content: "text-foreground",
9387
9389
  progressBg: "bg-green-500",
9388
- iconColor: "text-green-600 dark:text-green-400"
9390
+ iconColor: "text-green-600 dark:text-green-400",
9391
+ cardBg: "bg-background"
9389
9392
  };
9390
9393
  default:
9391
9394
  return {
9392
9395
  stroke: isHovered ? "border-l-[3px] border-l-primary/50" : "border-l-[3px] border-l-border",
9393
9396
  content: "text-foreground",
9394
9397
  progressBg: "bg-primary",
9395
- iconColor: "text-muted-foreground"
9398
+ iconColor: "text-muted-foreground",
9399
+ cardBg: "bg-background"
9396
9400
  };
9397
9401
  }
9398
9402
  }
9399
9403
  function DeliveryBadge({
9400
9404
  delivery,
9401
9405
  onClick,
9406
+ onCommentClick,
9402
9407
  className
9403
9408
  }) {
9404
9409
  const [isHovered, setIsHovered] = React27.useState(false);
@@ -9461,70 +9466,125 @@ function DeliveryBadge({
9461
9466
  onClick?.();
9462
9467
  }
9463
9468
  };
9469
+ const handleCommentClick = (e) => {
9470
+ e.stopPropagation();
9471
+ onCommentClick?.();
9472
+ };
9473
+ const amountColorClass = React27.useMemo(() => {
9474
+ if (visualState === "sent") {
9475
+ return "text-muted-foreground/40";
9476
+ }
9477
+ if (delivery.isReadyToUnload) {
9478
+ return "text-green-600 dark:text-green-400";
9479
+ }
9480
+ if (delivery.hasProductionRisk) {
9481
+ return "text-red-600 dark:text-red-400";
9482
+ }
9483
+ return "text-muted-foreground";
9484
+ }, [visualState, delivery.isReadyToUnload, delivery.hasProductionRisk]);
9464
9485
  return /* @__PURE__ */ jsxs(
9465
- "button",
9486
+ "div",
9466
9487
  {
9467
- type: "button",
9468
- onClick: handleClick,
9469
- onKeyDown: handleKeyDown,
9470
- onMouseEnter: () => setIsHovered(true),
9471
- onMouseLeave: () => setIsHovered(false),
9472
9488
  className: cn(
9473
- // Position relative for comment dot
9489
+ // Position relative for comment button
9474
9490
  "relative",
9475
9491
  // Full-width in cell, 90° corners
9476
9492
  "w-full rounded-none",
9477
9493
  // Sizing using Quantum tokens:
9478
- // - h-[80px] card height
9479
- // - px-6 = 24px horizontal (j3m.spacing.l)
9480
- // - py-4 = 16px vertical (j3m.spacing.m)
9481
- "h-[80px] px-6 py-4",
9482
- // Layout
9483
- "flex items-center",
9484
- // Card base: white background, complete border
9485
- "bg-background border border-border",
9494
+ // - min-h-[100px] card min-height
9495
+ // - pt-4 pb-3 = vertical padding (j3m.spacing.m / j3m.spacing.s)
9496
+ // - pl-4 = left padding (j3m.spacing.m)
9497
+ // - pr-2 = minimal right padding (progress bar extends further)
9498
+ "min-h-[100px] pt-4 pb-3 pl-4 pr-2",
9499
+ // Card base: dynamic background based on state, complete border
9500
+ styles.cardBg,
9501
+ "border border-border",
9486
9502
  // Left stroke for status
9487
9503
  styles.stroke,
9488
- // Interactive states
9489
- "cursor-pointer transition-all duration-200 ease-out",
9490
- "hover:-translate-y-0.5 hover:shadow-[var(--j3m-shadow-md)]",
9491
- "active:translate-y-0 active:shadow-sm",
9492
- // Focus state
9493
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1",
9494
- // Greyed out for sent state
9495
- visualState === "sent" && "opacity-60",
9504
+ // Interactive states (reduced for sent state)
9505
+ "transition-all duration-200 ease-out",
9506
+ visualState !== "sent" && "hover:-translate-y-0.5 hover:shadow-[var(--j3m-shadow-md)]",
9496
9507
  className
9497
9508
  ),
9498
9509
  children: [
9499
- hasComments && /* @__PURE__ */ jsx(
9500
- "span",
9510
+ /* @__PURE__ */ jsx(
9511
+ Button,
9501
9512
  {
9502
- className: "absolute -top-1 -right-1 h-3 w-3 rounded-full bg-primary ring-2 ring-background",
9503
- "aria-label": "Has comments"
9513
+ type: "button",
9514
+ variant: "ghost",
9515
+ size: "icon",
9516
+ className: cn(
9517
+ "absolute top-2 right-2",
9518
+ // 44px touch target for accessibility
9519
+ "h-11 w-11",
9520
+ "rounded-full",
9521
+ hasComments && "text-primary"
9522
+ ),
9523
+ onClick: handleCommentClick,
9524
+ "aria-label": hasComments ? `${delivery.comments.length} comments` : "Add comment",
9525
+ children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
9526
+ /* @__PURE__ */ jsx(MessageSquare, { className: "h-5 w-5" }),
9527
+ hasComments && /* @__PURE__ */ jsx(
9528
+ "span",
9529
+ {
9530
+ className: "absolute -top-1 -right-1 h-2.5 w-2.5 rounded-full bg-primary border-2 border-background",
9531
+ "aria-hidden": "true"
9532
+ }
9533
+ )
9534
+ ] })
9504
9535
  }
9505
9536
  ),
9506
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col justify-center gap-3 min-w-0 flex-1 overflow-hidden", children: [
9507
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 overflow-hidden", children: [
9508
- /* @__PURE__ */ jsx("span", { className: cn("text-sm font-semibold truncate", styles.content), children: prefixTitle }),
9509
- visualState === "sent" && /* @__PURE__ */ jsx(Check, { className: "h-4 w-4 text-green-600 dark:text-green-400 shrink-0" }),
9510
- delivery.hasProductionRisk && /* @__PURE__ */ jsx(AlertTriangle, { className: "h-4 w-4 text-red-500 shrink-0" }),
9511
- delivery.supplierName && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground truncate ml-auto", children: delivery.supplierName })
9512
- ] }),
9513
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
9514
- /* @__PURE__ */ jsx(Factory, { className: cn("h-3.5 w-3.5 shrink-0", styles.iconColor) }),
9515
- /* @__PURE__ */ jsx("div", { className: "flex-1 h-1.5 bg-black/10 dark:bg-white/10 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx(
9516
- "div",
9517
- {
9518
- className: cn("h-full rounded-full transition-all", styles.progressBg),
9519
- style: { width: `${productionProgress}%` }
9520
- }
9521
- ) }),
9522
- productionDisplay && /* @__PURE__ */ jsx("span", { className: cn(
9523
- "text-xs tabular-nums font-medium shrink-0",
9524
- delivery.isReadyToUnload ? "text-green-600 dark:text-green-400" : delivery.hasProductionRisk ? "text-red-600 dark:text-red-400" : "text-muted-foreground"
9525
- ), children: productionDisplay })
9526
- ] })
9527
- ] })
9537
+ /* @__PURE__ */ jsxs(
9538
+ "button",
9539
+ {
9540
+ type: "button",
9541
+ onClick: handleClick,
9542
+ onKeyDown: handleKeyDown,
9543
+ onMouseEnter: () => setIsHovered(true),
9544
+ onMouseLeave: () => setIsHovered(false),
9545
+ className: cn(
9546
+ // Full width, no background (inherits from parent)
9547
+ "w-full bg-transparent text-left",
9548
+ // Layout - vertical stack
9549
+ "flex flex-col gap-2",
9550
+ // Interactive states
9551
+ "cursor-pointer",
9552
+ "active:translate-y-0 active:shadow-sm",
9553
+ // Focus state
9554
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1"
9555
+ ),
9556
+ children: [
9557
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 overflow-hidden pr-12", children: [
9558
+ /* @__PURE__ */ jsx("span", { className: cn("text-sm font-semibold truncate", styles.content), children: prefixTitle }),
9559
+ delivery.hasProductionRisk && /* @__PURE__ */ jsx(AlertTriangle, { className: "h-4 w-4 text-red-500 shrink-0" }),
9560
+ delivery.supplierName && /* @__PURE__ */ jsx("span", { className: cn(
9561
+ "text-xs truncate ml-auto",
9562
+ visualState === "sent" ? "text-muted-foreground/40" : "text-muted-foreground"
9563
+ ), children: delivery.supplierName })
9564
+ ] }),
9565
+ /* @__PURE__ */ jsx("div", { className: "pr-14", children: /* @__PURE__ */ jsx("div", { className: "h-2 bg-black/10 dark:bg-white/10 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx(
9566
+ "div",
9567
+ {
9568
+ className: cn("h-full rounded-full transition-all", styles.progressBg),
9569
+ style: { width: `${productionProgress}%` }
9570
+ }
9571
+ ) }) }),
9572
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
9573
+ productionDisplay && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
9574
+ /* @__PURE__ */ jsx(Factory, { className: cn("h-3 w-3 shrink-0", styles.iconColor) }),
9575
+ /* @__PURE__ */ jsx("span", { className: cn(
9576
+ "text-[11px] tabular-nums font-medium",
9577
+ amountColorClass
9578
+ ), children: productionDisplay })
9579
+ ] }),
9580
+ visualState === "sent" && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 ml-auto", children: [
9581
+ /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5 text-green-600/60 dark:text-green-400/60 shrink-0" }),
9582
+ /* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium text-muted-foreground/50 uppercase tracking-wide", children: "Sent" })
9583
+ ] })
9584
+ ] })
9585
+ ]
9586
+ }
9587
+ )
9528
9588
  ]
9529
9589
  }
9530
9590
  );
@@ -9534,7 +9594,7 @@ function WeeklyLoadingView({
9534
9594
  deliveries,
9535
9595
  onDeliveryClick,
9536
9596
  onWeekChange,
9537
- onDayCommentClick,
9597
+ onDeliveryCommentClick,
9538
9598
  showNavigation = true,
9539
9599
  className
9540
9600
  }) {
@@ -9565,20 +9625,6 @@ function WeeklyLoadingView({
9565
9625
  }
9566
9626
  return grouped;
9567
9627
  }, [deliveries]);
9568
- const commentCountByDay = React27.useMemo(() => {
9569
- const counts = /* @__PURE__ */ new Map();
9570
- for (let i = 1; i <= 5; i++) {
9571
- counts.set(i, 0);
9572
- }
9573
- for (const delivery of deliveries) {
9574
- const dayOfWeek = delivery.date.getDay();
9575
- if (dayOfWeek >= 1 && dayOfWeek <= 5) {
9576
- const current = counts.get(dayOfWeek) ?? 0;
9577
- counts.set(dayOfWeek, current + delivery.comments.length);
9578
- }
9579
- }
9580
- return counts;
9581
- }, [deliveries]);
9582
9628
  const totalDeliveries = deliveries.length;
9583
9629
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col", className), children: [
9584
9630
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 border-b border-border p-4 lg:flex-row lg:items-center lg:justify-between", children: [
@@ -9643,54 +9689,27 @@ function WeeklyLoadingView({
9643
9689
  ] }),
9644
9690
  /* @__PURE__ */ jsxs(ScrollArea, { className: "flex-1", children: [
9645
9691
  /* @__PURE__ */ jsxs("div", { className: "hidden sm:block", children: [
9646
- /* @__PURE__ */ jsx("div", { className: "grid grid-cols-5 border-b border-border bg-muted/30", children: weekDays.map(({ date, dayOfWeek, isToday: dayIsToday }) => {
9647
- const dayCommentCount = commentCountByDay.get(dayOfWeek) ?? 0;
9648
- return /* @__PURE__ */ jsxs(
9649
- "div",
9650
- {
9651
- className: cn(
9652
- // Relative for positioning comment button
9653
- "relative",
9654
- // Compact padding: py-2 px-3 (j3m.spacing.xs / j3m.spacing.s)
9655
- "flex items-center justify-center gap-2 py-2 px-3",
9656
- dayIsToday && "bg-primary/5"
9657
- ),
9658
- children: [
9659
- /* @__PURE__ */ jsx("span", { className: cn(
9660
- "text-xs font-medium uppercase tracking-wide",
9661
- dayIsToday ? "text-primary" : "text-muted-foreground"
9662
- ), children: getShortDayLabel(dayOfWeek) }),
9663
- /* @__PURE__ */ jsx("span", { className: cn(
9664
- "text-base font-semibold tabular-nums",
9665
- dayIsToday ? "text-primary" : "text-foreground"
9666
- ), children: date.getDate() }),
9667
- /* @__PURE__ */ jsxs(
9668
- Button,
9669
- {
9670
- variant: "ghost",
9671
- size: "icon",
9672
- className: cn(
9673
- "absolute top-1 right-1 h-7 w-7",
9674
- dayCommentCount > 0 && "text-primary"
9675
- ),
9676
- onClick: (e) => {
9677
- e.stopPropagation();
9678
- onDayCommentClick?.(dayOfWeek, date);
9679
- },
9680
- children: [
9681
- /* @__PURE__ */ jsxs("div", { className: "relative", children: [
9682
- /* @__PURE__ */ jsx(MessageSquare, { className: "h-4 w-4" }),
9683
- dayCommentCount > 0 && /* @__PURE__ */ jsx("span", { className: "absolute -top-1 -right-1 h-2 w-2 rounded-full bg-primary" })
9684
- ] }),
9685
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: dayCommentCount > 0 ? `${dayCommentCount} comments on ${getShortDayLabel(dayOfWeek)}` : `Add comment for ${getShortDayLabel(dayOfWeek)}` })
9686
- ]
9687
- }
9688
- )
9689
- ]
9690
- },
9691
- dayOfWeek
9692
- );
9693
- }) }),
9692
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-5 border-b border-border bg-muted/30", children: weekDays.map(({ date, dayOfWeek, isToday: dayIsToday }) => /* @__PURE__ */ jsxs(
9693
+ "div",
9694
+ {
9695
+ className: cn(
9696
+ // Compact padding
9697
+ "flex flex-col items-center justify-center py-2 px-2",
9698
+ dayIsToday && "bg-primary/5"
9699
+ ),
9700
+ children: [
9701
+ /* @__PURE__ */ jsx("span", { className: cn(
9702
+ "text-[11px] font-semibold uppercase tracking-wide leading-none",
9703
+ dayIsToday ? "text-primary" : "text-muted-foreground"
9704
+ ), children: getShortDayLabel(dayOfWeek) }),
9705
+ /* @__PURE__ */ jsx("span", { className: cn(
9706
+ "text-lg font-medium tabular-nums leading-tight mt-0.5",
9707
+ dayIsToday ? "text-primary" : "text-foreground"
9708
+ ), children: date.getDate() })
9709
+ ]
9710
+ },
9711
+ dayOfWeek
9712
+ )) }),
9694
9713
  /* @__PURE__ */ jsx("div", { className: "grid grid-cols-5", children: weekDays.map(({ dayOfWeek, isToday: dayIsToday }) => {
9695
9714
  const dayDeliveries = deliveriesByDay.get(dayOfWeek) ?? [];
9696
9715
  return /* @__PURE__ */ jsx(
@@ -9705,7 +9724,8 @@ function WeeklyLoadingView({
9705
9724
  DeliveryBadge,
9706
9725
  {
9707
9726
  delivery,
9708
- onClick: () => onDeliveryClick?.(delivery)
9727
+ onClick: () => onDeliveryClick?.(delivery),
9728
+ onCommentClick: () => onDeliveryCommentClick?.(delivery)
9709
9729
  },
9710
9730
  delivery.id
9711
9731
  )) : /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-6 text-sm text-muted-foreground/40", children: "\u2014" }) })
@@ -9716,7 +9736,6 @@ function WeeklyLoadingView({
9716
9736
  ] }),
9717
9737
  /* @__PURE__ */ jsx("div", { className: "sm:hidden divide-y divide-border", children: weekDays.map(({ date, dayOfWeek, isToday: dayIsToday }) => {
9718
9738
  const dayDeliveries = deliveriesByDay.get(dayOfWeek) ?? [];
9719
- const dayCommentCount = commentCountByDay.get(dayOfWeek) ?? 0;
9720
9739
  return /* @__PURE__ */ jsxs(
9721
9740
  "div",
9722
9741
  {
@@ -9725,52 +9744,31 @@ function WeeklyLoadingView({
9725
9744
  ),
9726
9745
  children: [
9727
9746
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-4 py-2", children: [
9728
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
9729
- /* @__PURE__ */ jsx("span", { className: cn(
9730
- "text-xs font-medium uppercase",
9731
- dayIsToday ? "text-primary" : "text-muted-foreground"
9732
- ), children: getShortDayLabel(dayOfWeek) }),
9733
- /* @__PURE__ */ jsx("span", { className: cn(
9734
- "text-base font-semibold tabular-nums",
9735
- dayIsToday ? "text-primary" : "text-foreground"
9736
- ), children: date.getDate() }),
9737
- dayIsToday && /* @__PURE__ */ jsx("span", { className: "text-xs text-primary font-medium", children: "Today" })
9738
- ] }),
9739
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
9740
- /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
9741
- dayDeliveries.length,
9742
- " ",
9743
- dayDeliveries.length === 1 ? "delivery" : "deliveries"
9747
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
9748
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center min-w-[40px]", children: [
9749
+ /* @__PURE__ */ jsx("span", { className: cn(
9750
+ "text-[11px] font-semibold uppercase tracking-wide leading-none",
9751
+ dayIsToday ? "text-primary" : "text-muted-foreground"
9752
+ ), children: getShortDayLabel(dayOfWeek) }),
9753
+ /* @__PURE__ */ jsx("span", { className: cn(
9754
+ "text-lg font-medium tabular-nums leading-tight mt-0.5",
9755
+ dayIsToday ? "text-primary" : "text-foreground"
9756
+ ), children: date.getDate() })
9744
9757
  ] }),
9745
- /* @__PURE__ */ jsxs(
9746
- Button,
9747
- {
9748
- variant: "ghost",
9749
- size: "icon",
9750
- className: cn(
9751
- "h-7 w-7",
9752
- dayCommentCount > 0 && "text-primary"
9753
- ),
9754
- onClick: (e) => {
9755
- e.stopPropagation();
9756
- onDayCommentClick?.(dayOfWeek, date);
9757
- },
9758
- children: [
9759
- /* @__PURE__ */ jsxs("div", { className: "relative", children: [
9760
- /* @__PURE__ */ jsx(MessageSquare, { className: "h-4 w-4" }),
9761
- dayCommentCount > 0 && /* @__PURE__ */ jsx("span", { className: "absolute -top-1 -right-1 h-2 w-2 rounded-full bg-primary" })
9762
- ] }),
9763
- /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Comments" })
9764
- ]
9765
- }
9766
- )
9758
+ dayIsToday && /* @__PURE__ */ jsx("span", { className: "text-xs text-primary font-medium bg-primary/10 px-2 py-0.5 rounded", children: "Today" })
9759
+ ] }),
9760
+ /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
9761
+ dayDeliveries.length,
9762
+ " ",
9763
+ dayDeliveries.length === 1 ? "delivery" : "deliveries"
9767
9764
  ] })
9768
9765
  ] }),
9769
9766
  /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-3 p-3 pt-0", children: dayDeliveries.length > 0 ? dayDeliveries.map((delivery) => /* @__PURE__ */ jsx(
9770
9767
  DeliveryBadge,
9771
9768
  {
9772
9769
  delivery,
9773
- onClick: () => onDeliveryClick?.(delivery)
9770
+ onClick: () => onDeliveryClick?.(delivery),
9771
+ onCommentClick: () => onDeliveryCommentClick?.(delivery)
9774
9772
  },
9775
9773
  delivery.id
9776
9774
  )) : /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground/40 py-4 text-center", children: "\u2014" }) })
@@ -9880,7 +9878,7 @@ function AddCommentDialog({
9880
9878
  }, [open]);
9881
9879
  return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-md", children: [
9882
9880
  /* @__PURE__ */ jsxs(DialogHeader, { children: [
9883
- /* @__PURE__ */ jsx(DialogTitle, { children: "Add pre-unloading note" }),
9881
+ /* @__PURE__ */ jsx(DialogTitle, { children: "Add pre-loading note" }),
9884
9882
  /* @__PURE__ */ jsxs(DialogDescription, { children: [
9885
9883
  "Add a note for ",
9886
9884
  /* @__PURE__ */ jsx("strong", { children: delivery.label }),
@@ -9896,7 +9894,7 @@ function AddCommentDialog({
9896
9894
  Textarea,
9897
9895
  {
9898
9896
  id: "comment-text",
9899
- placeholder: "Add a note before unloading...",
9897
+ placeholder: "Add a note before loading...",
9900
9898
  value: commentText,
9901
9899
  onChange: (e) => setCommentText(e.target.value),
9902
9900
  onKeyDown: handleKeyDown,
@@ -9951,7 +9949,7 @@ function CommentsSection({
9951
9949
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
9952
9950
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
9953
9951
  /* @__PURE__ */ jsx(MessageSquare, { className: "h-4 w-4 text-muted-foreground" }),
9954
- /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: "Notes before unloading" }),
9952
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: "Notes before loading" }),
9955
9953
  comments.length > 0 && /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-[10px] h-5", children: comments.length })
9956
9954
  ] }),
9957
9955
  /* @__PURE__ */ jsxs(
@@ -9986,7 +9984,7 @@ function CommentsSection({
9986
9984
  ] }),
9987
9985
  /* @__PURE__ */ jsx("p", { className: "text-sm", children: comment.text })
9988
9986
  ] }, comment.id)) })
9989
- ] }) : /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-dashed p-4 text-center text-sm text-muted-foreground", children: "No pre-unloading notes yet. Add notes before confirming the load." })
9987
+ ] }) : /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-dashed p-4 text-center text-sm text-muted-foreground", children: "No pre-loading notes yet. Add notes before confirming the load." })
9990
9988
  ] }),
9991
9989
  /* @__PURE__ */ jsx(
9992
9990
  AddCommentDialog,
@@ -10049,7 +10047,7 @@ function DeliveryDetailPage({
10049
10047
  const addons = delivery.elements.filter((e) => e.status === "addon");
10050
10048
  return { loaded, missing, moved, addons };
10051
10049
  }, [delivery.elements]);
10052
- const preUnloadingComments = delivery.comments.filter((c) => c.context === "pre_unloading");
10050
+ const preLoadingComments = delivery.comments.filter((c) => c.context === "pre_unloading");
10053
10051
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full", children: [
10054
10052
  /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2 px-4 py-3 border-b bg-background sticky top-0 z-10", children: /* @__PURE__ */ jsxs(
10055
10053
  Button,
@@ -10098,7 +10096,7 @@ function DeliveryDetailPage({
10098
10096
  {
10099
10097
  variant: "outline",
10100
10098
  className: "bg-green-100 dark:bg-green-900/50 border-green-300 dark:border-green-700 text-green-700 dark:text-green-300",
10101
- children: "Ready to unload"
10099
+ children: "Ready to load"
10102
10100
  }
10103
10101
  )
10104
10102
  ] })
@@ -10189,13 +10187,13 @@ function DeliveryDetailPage({
10189
10187
  ] })
10190
10188
  ] })
10191
10189
  ] }),
10192
- delivery.elements.length > 0 && /* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
10190
+ (elementsByStatus.loaded.length > 0 || elementsByStatus.missing.length > 0 || elementsByStatus.moved.length > 0) && /* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
10193
10191
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
10194
10192
  /* @__PURE__ */ jsx(Package, { className: "h-4 w-4 text-muted-foreground" }),
10195
- /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: "Elements to Unload" }),
10193
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: "What should be packed" }),
10196
10194
  /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground ml-auto", children: [
10197
- delivery.elements.length,
10198
- " total"
10195
+ elementsByStatus.loaded.length + elementsByStatus.missing.length + elementsByStatus.moved.length,
10196
+ " items"
10199
10197
  ] })
10200
10198
  ] }),
10201
10199
  /* @__PURE__ */ jsx("div", { className: "rounded-lg border overflow-hidden", children: /* @__PURE__ */ jsxs(Table, { children: [
@@ -10206,7 +10204,7 @@ function DeliveryDetailPage({
10206
10204
  /* @__PURE__ */ jsx(TableHead, { className: "font-semibold text-right", children: "Size (m\xB2)" }),
10207
10205
  /* @__PURE__ */ jsx(TableHead, { className: "font-semibold text-center", children: "Status" })
10208
10206
  ] }) }),
10209
- /* @__PURE__ */ jsx(TableBody, { children: delivery.elements.map((element) => /* @__PURE__ */ jsxs(
10207
+ /* @__PURE__ */ jsx(TableBody, { children: [...elementsByStatus.loaded, ...elementsByStatus.missing, ...elementsByStatus.moved].map((element) => /* @__PURE__ */ jsxs(
10210
10208
  TableRow,
10211
10209
  {
10212
10210
  className: getElementRowBg(element.status),
@@ -10234,10 +10232,6 @@ function DeliveryDetailPage({
10234
10232
  element.status === "moved" && element.actualDeliveryLabel && /* @__PURE__ */ jsxs("span", { className: "text-[9px] text-blue-600 dark:text-blue-400", children: [
10235
10233
  "\u2192 ",
10236
10234
  element.actualDeliveryLabel
10237
- ] }),
10238
- element.status === "addon" && element.originalDeliveryLabel && /* @__PURE__ */ jsxs("span", { className: "text-[9px] text-purple-600 dark:text-purple-400", children: [
10239
- "from ",
10240
- element.originalDeliveryLabel
10241
10235
  ] })
10242
10236
  ] }) })
10243
10237
  ]
@@ -10246,10 +10240,48 @@ function DeliveryDetailPage({
10246
10240
  )) })
10247
10241
  ] }) })
10248
10242
  ] }),
10243
+ elementsByStatus.addons.length > 0 && /* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
10244
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
10245
+ /* @__PURE__ */ jsx(Plus, { className: "h-4 w-4 text-purple-600 dark:text-purple-400" }),
10246
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: "Extra items (moved to this delivery)" }),
10247
+ /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground ml-auto", children: [
10248
+ elementsByStatus.addons.length,
10249
+ " items"
10250
+ ] })
10251
+ ] }),
10252
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "These items were originally planned for other deliveries but have been moved to this one." }),
10253
+ /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-purple-200 dark:border-purple-800 overflow-hidden", children: /* @__PURE__ */ jsxs(Table, { children: [
10254
+ /* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsxs(TableRow, { className: "bg-purple-50/50 dark:bg-purple-950/30 hover:bg-purple-50/50 dark:hover:bg-purple-950/30", children: [
10255
+ /* @__PURE__ */ jsx(TableHead, { className: "font-semibold", children: "Prefix" }),
10256
+ /* @__PURE__ */ jsx(TableHead, { className: "font-semibold", children: "Type" }),
10257
+ /* @__PURE__ */ jsx(TableHead, { className: "font-semibold text-right", children: "Weight" }),
10258
+ /* @__PURE__ */ jsx(TableHead, { className: "font-semibold text-right", children: "Size (m\xB2)" }),
10259
+ /* @__PURE__ */ jsx(TableHead, { className: "font-semibold", children: "Moved from" })
10260
+ ] }) }),
10261
+ /* @__PURE__ */ jsx(TableBody, { children: elementsByStatus.addons.map((element) => /* @__PURE__ */ jsxs(
10262
+ TableRow,
10263
+ {
10264
+ className: "bg-purple-50/30 dark:bg-purple-950/10",
10265
+ children: [
10266
+ /* @__PURE__ */ jsx(TableCell, { className: "font-medium", children: element.prefix }),
10267
+ /* @__PURE__ */ jsx(TableCell, { children: element.type }),
10268
+ /* @__PURE__ */ jsx(TableCell, { className: "text-right tabular-nums", children: element.weight ? /* @__PURE__ */ jsxs("span", { children: [
10269
+ element.weight,
10270
+ " ",
10271
+ element.weightUnit || "kg"
10272
+ ] }) : "\u2014" }),
10273
+ /* @__PURE__ */ jsx(TableCell, { className: "text-right tabular-nums", children: element.sizeSqm ?? "\u2014" }),
10274
+ /* @__PURE__ */ jsx(TableCell, { children: element.originalDeliveryLabel ? /* @__PURE__ */ jsx("span", { className: "text-sm text-purple-600 dark:text-purple-400", children: element.originalDeliveryLabel }) : /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "\u2014" }) })
10275
+ ]
10276
+ },
10277
+ element.id
10278
+ )) })
10279
+ ] }) })
10280
+ ] }),
10249
10281
  /* @__PURE__ */ jsx(
10250
10282
  CommentsSection,
10251
10283
  {
10252
- comments: preUnloadingComments,
10284
+ comments: preLoadingComments,
10253
10285
  delivery,
10254
10286
  weekId: week.weekKey,
10255
10287
  onAddComment
@@ -10286,6 +10318,9 @@ function SupplierWeeklyLoading({
10286
10318
  }) {
10287
10319
  const [selectedDelivery, setSelectedDelivery] = React27.useState(null);
10288
10320
  const [sheetOpen, setSheetOpen] = React27.useState(false);
10321
+ const [commentDelivery, setCommentDelivery] = React27.useState(null);
10322
+ const [commentDialogOpen, setCommentDialogOpen] = React27.useState(false);
10323
+ const [commentText, setCommentText] = React27.useState("");
10289
10324
  const handleDeliveryClick = (delivery) => {
10290
10325
  setSelectedDelivery(delivery);
10291
10326
  setSheetOpen(true);
@@ -10296,6 +10331,38 @@ function SupplierWeeklyLoading({
10296
10331
  setTimeout(() => setSelectedDelivery(null), 200);
10297
10332
  onBack?.();
10298
10333
  };
10334
+ const handleDeliveryCommentClick = (delivery) => {
10335
+ setCommentDelivery(delivery);
10336
+ setCommentDialogOpen(true);
10337
+ };
10338
+ const handleCommentDialogClose = () => {
10339
+ setCommentDialogOpen(false);
10340
+ setCommentText("");
10341
+ setTimeout(() => setCommentDelivery(null), 200);
10342
+ };
10343
+ const handleCommentSubmit = () => {
10344
+ if (commentText.trim() && commentDelivery && onAddComment) {
10345
+ onAddComment({
10346
+ author: "Current User",
10347
+ // Would come from auth context in real app
10348
+ text: commentText.trim(),
10349
+ context: "pre_unloading",
10350
+ weekId: week.weekKey,
10351
+ deliveryId: commentDelivery.id,
10352
+ supplierId: commentDelivery.supplierId,
10353
+ supplierName: commentDelivery.supplierName,
10354
+ prefixId: commentDelivery.prefixScope,
10355
+ prefixName: commentDelivery.prefixScope
10356
+ });
10357
+ handleCommentDialogClose();
10358
+ }
10359
+ };
10360
+ const handleCommentKeyDown = (e) => {
10361
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
10362
+ e.preventDefault();
10363
+ handleCommentSubmit();
10364
+ }
10365
+ };
10299
10366
  const Wrapper = bordered ? Card : "div";
10300
10367
  const Content14 = bordered ? CardContent : "div";
10301
10368
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -10314,6 +10381,7 @@ function SupplierWeeklyLoading({
10314
10381
  week,
10315
10382
  deliveries,
10316
10383
  onDeliveryClick: handleDeliveryClick,
10384
+ onDeliveryCommentClick: handleDeliveryCommentClick,
10317
10385
  onWeekChange,
10318
10386
  showNavigation
10319
10387
  }
@@ -10342,7 +10410,58 @@ function SupplierWeeklyLoading({
10342
10410
  )
10343
10411
  ]
10344
10412
  }
10345
- ) })
10413
+ ) }),
10414
+ /* @__PURE__ */ jsx(Dialog, { open: commentDialogOpen, onOpenChange: (open) => !open && handleCommentDialogClose(), children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-md", children: [
10415
+ /* @__PURE__ */ jsxs(DialogHeader, { children: [
10416
+ /* @__PURE__ */ jsx(DialogTitle, { children: "Add pre-loading note" }),
10417
+ /* @__PURE__ */ jsxs(DialogDescription, { children: [
10418
+ "Add a note for ",
10419
+ /* @__PURE__ */ jsx("strong", { children: commentDelivery?.label }),
10420
+ " (",
10421
+ commentDelivery?.supplierName,
10422
+ commentDelivery?.prefixScope && ` \u2022 ${commentDelivery.prefixScope}`,
10423
+ ")."
10424
+ ] })
10425
+ ] }),
10426
+ /* @__PURE__ */ jsx("div", { className: "space-y-4 py-2", children: /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
10427
+ /* @__PURE__ */ jsx(Label2, { htmlFor: "card-comment-text", className: "text-sm font-medium", children: "Note" }),
10428
+ /* @__PURE__ */ jsx(
10429
+ Textarea,
10430
+ {
10431
+ id: "card-comment-text",
10432
+ placeholder: "Add a note before loading...",
10433
+ value: commentText,
10434
+ onChange: (e) => setCommentText(e.target.value),
10435
+ onKeyDown: handleCommentKeyDown,
10436
+ className: "min-h-[120px] text-base resize-none",
10437
+ autoFocus: true
10438
+ }
10439
+ ),
10440
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "\u2318+Enter to save" })
10441
+ ] }) }),
10442
+ /* @__PURE__ */ jsxs(DialogFooter, { className: "gap-2 sm:gap-0", children: [
10443
+ /* @__PURE__ */ jsx(
10444
+ Button,
10445
+ {
10446
+ variant: "ghost",
10447
+ onClick: handleCommentDialogClose,
10448
+ children: "Cancel"
10449
+ }
10450
+ ),
10451
+ /* @__PURE__ */ jsxs(
10452
+ Button,
10453
+ {
10454
+ onClick: handleCommentSubmit,
10455
+ disabled: !commentText.trim(),
10456
+ className: "gap-1.5",
10457
+ children: [
10458
+ /* @__PURE__ */ jsx(Send, { className: "h-4 w-4" }),
10459
+ "Save note"
10460
+ ]
10461
+ }
10462
+ )
10463
+ ] })
10464
+ ] }) })
10346
10465
  ] });
10347
10466
  }
10348
10467
  function getStatusBadgeVariant3(status) {