@j3m-quantum/ui 1.8.0 → 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.cjs CHANGED
@@ -40,6 +40,7 @@ var PopoverPrimitive = require('@radix-ui/react-popover');
40
40
  var HoverCardPrimitive = require('@radix-ui/react-hover-card');
41
41
  var CollapsiblePrimitive = require('@radix-ui/react-collapsible');
42
42
  var ResizablePrimitive = require('react-resizable-panels');
43
+ var reactLeaflet = require('react-leaflet');
43
44
  var reactTable = require('@tanstack/react-table');
44
45
  var dateFns = require('date-fns');
45
46
 
@@ -5888,6 +5889,89 @@ var SectionFooter = React27__namespace.forwardRef(
5888
5889
  )
5889
5890
  );
5890
5891
  SectionFooter.displayName = "SectionFooter";
5892
+ function Map2({
5893
+ center,
5894
+ zoom = 13,
5895
+ className,
5896
+ children,
5897
+ ...props
5898
+ }) {
5899
+ return /* @__PURE__ */ jsxRuntime.jsx(
5900
+ reactLeaflet.MapContainer,
5901
+ {
5902
+ center,
5903
+ zoom,
5904
+ className: cn(
5905
+ "w-full rounded-lg border border-border overflow-hidden",
5906
+ "[&_.leaflet-control-zoom]:border-border",
5907
+ "[&_.leaflet-control-zoom]:rounded-md",
5908
+ "[&_.leaflet-control-zoom]:shadow-sm",
5909
+ "[&_.leaflet-control-zoom-in]:rounded-t-md",
5910
+ "[&_.leaflet-control-zoom-in]:border-b",
5911
+ "[&_.leaflet-control-zoom-in]:border-border",
5912
+ "[&_.leaflet-control-zoom-out]:rounded-b-md",
5913
+ "[&_.leaflet-popup-content-wrapper]:rounded-lg",
5914
+ "[&_.leaflet-popup-content-wrapper]:shadow-lg",
5915
+ "[&_.leaflet-popup-content-wrapper]:border",
5916
+ "[&_.leaflet-popup-content-wrapper]:border-border",
5917
+ className
5918
+ ),
5919
+ scrollWheelZoom: true,
5920
+ ...props,
5921
+ children
5922
+ }
5923
+ );
5924
+ }
5925
+ var TILE_LAYERS = {
5926
+ default: {
5927
+ url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
5928
+ attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
5929
+ },
5930
+ dark: {
5931
+ url: "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png",
5932
+ attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>'
5933
+ },
5934
+ satellite: {
5935
+ url: "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
5936
+ attribution: "&copy; Esri &mdash; Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community"
5937
+ }
5938
+ };
5939
+ function MapTileLayer({
5940
+ variant = "default",
5941
+ ...props
5942
+ }) {
5943
+ const layer = TILE_LAYERS[variant];
5944
+ return /* @__PURE__ */ jsxRuntime.jsx(
5945
+ reactLeaflet.TileLayer,
5946
+ {
5947
+ url: layer.url,
5948
+ attribution: layer.attribution,
5949
+ ...props
5950
+ }
5951
+ );
5952
+ }
5953
+ function MapMarker({
5954
+ position,
5955
+ children,
5956
+ ...props
5957
+ }) {
5958
+ return /* @__PURE__ */ jsxRuntime.jsx(reactLeaflet.Marker, { position, ...props, children });
5959
+ }
5960
+ function MapPopup({
5961
+ children,
5962
+ ...props
5963
+ }) {
5964
+ return /* @__PURE__ */ jsxRuntime.jsx(reactLeaflet.Popup, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm", children }) });
5965
+ }
5966
+ function MapTooltip({
5967
+ children,
5968
+ ...props
5969
+ }) {
5970
+ return /* @__PURE__ */ jsxRuntime.jsx(reactLeaflet.Tooltip, { ...props, children });
5971
+ }
5972
+ function MapZoomControl(props) {
5973
+ return /* @__PURE__ */ jsxRuntime.jsx(reactLeaflet.ZoomControl, { ...props });
5974
+ }
5891
5975
  function DataTableColumnHeader({
5892
5976
  column,
5893
5977
  title,
@@ -9334,36 +9418,41 @@ function getLeftStrokeStyles(state, hasRisk, isHovered) {
9334
9418
  stroke: "border-l-[3px] border-l-red-500",
9335
9419
  content: "text-foreground",
9336
9420
  progressBg: "bg-red-500",
9337
- iconColor: "text-red-600 dark:text-red-400"
9421
+ iconColor: "text-red-600 dark:text-red-400",
9422
+ cardBg: "bg-background"
9338
9423
  };
9339
9424
  }
9340
9425
  switch (state) {
9341
9426
  case "sent":
9342
9427
  return {
9343
- stroke: "border-l-[3px] border-l-green-500/50",
9344
- content: "text-muted-foreground/60",
9345
- progressBg: "bg-green-500",
9346
- iconColor: "text-green-600 dark:text-green-400"
9428
+ stroke: "border-l-[3px] border-l-green-500/40",
9429
+ content: "text-muted-foreground/50",
9430
+ progressBg: "bg-green-500/50",
9431
+ iconColor: "text-green-600/50 dark:text-green-400/50",
9432
+ cardBg: "bg-muted/30"
9347
9433
  };
9348
9434
  case "ready":
9349
9435
  return {
9350
9436
  stroke: "border-l-[3px] border-l-green-500",
9351
9437
  content: "text-foreground",
9352
9438
  progressBg: "bg-green-500",
9353
- iconColor: "text-green-600 dark:text-green-400"
9439
+ iconColor: "text-green-600 dark:text-green-400",
9440
+ cardBg: "bg-background"
9354
9441
  };
9355
9442
  default:
9356
9443
  return {
9357
9444
  stroke: isHovered ? "border-l-[3px] border-l-primary/50" : "border-l-[3px] border-l-border",
9358
9445
  content: "text-foreground",
9359
9446
  progressBg: "bg-primary",
9360
- iconColor: "text-muted-foreground"
9447
+ iconColor: "text-muted-foreground",
9448
+ cardBg: "bg-background"
9361
9449
  };
9362
9450
  }
9363
9451
  }
9364
9452
  function DeliveryBadge({
9365
9453
  delivery,
9366
9454
  onClick,
9455
+ onCommentClick,
9367
9456
  className
9368
9457
  }) {
9369
9458
  const [isHovered, setIsHovered] = React27__namespace.useState(false);
@@ -9426,70 +9515,125 @@ function DeliveryBadge({
9426
9515
  onClick?.();
9427
9516
  }
9428
9517
  };
9518
+ const handleCommentClick = (e) => {
9519
+ e.stopPropagation();
9520
+ onCommentClick?.();
9521
+ };
9522
+ const amountColorClass = React27__namespace.useMemo(() => {
9523
+ if (visualState === "sent") {
9524
+ return "text-muted-foreground/40";
9525
+ }
9526
+ if (delivery.isReadyToUnload) {
9527
+ return "text-green-600 dark:text-green-400";
9528
+ }
9529
+ if (delivery.hasProductionRisk) {
9530
+ return "text-red-600 dark:text-red-400";
9531
+ }
9532
+ return "text-muted-foreground";
9533
+ }, [visualState, delivery.isReadyToUnload, delivery.hasProductionRisk]);
9429
9534
  return /* @__PURE__ */ jsxRuntime.jsxs(
9430
- "button",
9535
+ "div",
9431
9536
  {
9432
- type: "button",
9433
- onClick: handleClick,
9434
- onKeyDown: handleKeyDown,
9435
- onMouseEnter: () => setIsHovered(true),
9436
- onMouseLeave: () => setIsHovered(false),
9437
9537
  className: cn(
9438
- // Position relative for comment dot
9538
+ // Position relative for comment button
9439
9539
  "relative",
9440
9540
  // Full-width in cell, 90° corners
9441
9541
  "w-full rounded-none",
9442
9542
  // Sizing using Quantum tokens:
9443
- // - h-[80px] card height
9444
- // - px-6 = 24px horizontal (j3m.spacing.l)
9445
- // - py-4 = 16px vertical (j3m.spacing.m)
9446
- "h-[80px] px-6 py-4",
9447
- // Layout
9448
- "flex items-center",
9449
- // Card base: white background, complete border
9450
- "bg-background border border-border",
9543
+ // - min-h-[100px] card min-height
9544
+ // - pt-4 pb-3 = vertical padding (j3m.spacing.m / j3m.spacing.s)
9545
+ // - pl-4 = left padding (j3m.spacing.m)
9546
+ // - pr-2 = minimal right padding (progress bar extends further)
9547
+ "min-h-[100px] pt-4 pb-3 pl-4 pr-2",
9548
+ // Card base: dynamic background based on state, complete border
9549
+ styles.cardBg,
9550
+ "border border-border",
9451
9551
  // Left stroke for status
9452
9552
  styles.stroke,
9453
- // Interactive states
9454
- "cursor-pointer transition-all duration-200 ease-out",
9455
- "hover:-translate-y-0.5 hover:shadow-[var(--j3m-shadow-md)]",
9456
- "active:translate-y-0 active:shadow-sm",
9457
- // Focus state
9458
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1",
9459
- // Greyed out for sent state
9460
- visualState === "sent" && "opacity-60",
9553
+ // Interactive states (reduced for sent state)
9554
+ "transition-all duration-200 ease-out",
9555
+ visualState !== "sent" && "hover:-translate-y-0.5 hover:shadow-[var(--j3m-shadow-md)]",
9461
9556
  className
9462
9557
  ),
9463
9558
  children: [
9464
- hasComments && /* @__PURE__ */ jsxRuntime.jsx(
9465
- "span",
9559
+ /* @__PURE__ */ jsxRuntime.jsx(
9560
+ Button,
9466
9561
  {
9467
- className: "absolute -top-1 -right-1 h-3 w-3 rounded-full bg-primary ring-2 ring-background",
9468
- "aria-label": "Has comments"
9562
+ type: "button",
9563
+ variant: "ghost",
9564
+ size: "icon",
9565
+ className: cn(
9566
+ "absolute top-2 right-2",
9567
+ // 44px touch target for accessibility
9568
+ "h-11 w-11",
9569
+ "rounded-full",
9570
+ hasComments && "text-primary"
9571
+ ),
9572
+ onClick: handleCommentClick,
9573
+ "aria-label": hasComments ? `${delivery.comments.length} comments` : "Add comment",
9574
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
9575
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "h-5 w-5" }),
9576
+ hasComments && /* @__PURE__ */ jsxRuntime.jsx(
9577
+ "span",
9578
+ {
9579
+ className: "absolute -top-1 -right-1 h-2.5 w-2.5 rounded-full bg-primary border-2 border-background",
9580
+ "aria-hidden": "true"
9581
+ }
9582
+ )
9583
+ ] })
9469
9584
  }
9470
9585
  ),
9471
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col justify-center gap-3 min-w-0 flex-1 overflow-hidden", children: [
9472
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 overflow-hidden", children: [
9473
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-sm font-semibold truncate", styles.content), children: prefixTitle }),
9474
- visualState === "sent" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-4 w-4 text-green-600 dark:text-green-400 shrink-0" }),
9475
- delivery.hasProductionRisk && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-4 w-4 text-red-500 shrink-0" }),
9476
- delivery.supplierName && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground truncate ml-auto", children: delivery.supplierName })
9477
- ] }),
9478
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
9479
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Factory, { className: cn("h-3.5 w-3.5 shrink-0", styles.iconColor) }),
9480
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 h-1.5 bg-black/10 dark:bg-white/10 rounded-full overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
9481
- "div",
9482
- {
9483
- className: cn("h-full rounded-full transition-all", styles.progressBg),
9484
- style: { width: `${productionProgress}%` }
9485
- }
9486
- ) }),
9487
- productionDisplay && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
9488
- "text-xs tabular-nums font-medium shrink-0",
9489
- delivery.isReadyToUnload ? "text-green-600 dark:text-green-400" : delivery.hasProductionRisk ? "text-red-600 dark:text-red-400" : "text-muted-foreground"
9490
- ), children: productionDisplay })
9491
- ] })
9492
- ] })
9586
+ /* @__PURE__ */ jsxRuntime.jsxs(
9587
+ "button",
9588
+ {
9589
+ type: "button",
9590
+ onClick: handleClick,
9591
+ onKeyDown: handleKeyDown,
9592
+ onMouseEnter: () => setIsHovered(true),
9593
+ onMouseLeave: () => setIsHovered(false),
9594
+ className: cn(
9595
+ // Full width, no background (inherits from parent)
9596
+ "w-full bg-transparent text-left",
9597
+ // Layout - vertical stack
9598
+ "flex flex-col gap-2",
9599
+ // Interactive states
9600
+ "cursor-pointer",
9601
+ "active:translate-y-0 active:shadow-sm",
9602
+ // Focus state
9603
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1"
9604
+ ),
9605
+ children: [
9606
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 overflow-hidden pr-12", children: [
9607
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-sm font-semibold truncate", styles.content), children: prefixTitle }),
9608
+ delivery.hasProductionRisk && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-4 w-4 text-red-500 shrink-0" }),
9609
+ delivery.supplierName && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
9610
+ "text-xs truncate ml-auto",
9611
+ visualState === "sent" ? "text-muted-foreground/40" : "text-muted-foreground"
9612
+ ), children: delivery.supplierName })
9613
+ ] }),
9614
+ /* @__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(
9615
+ "div",
9616
+ {
9617
+ className: cn("h-full rounded-full transition-all", styles.progressBg),
9618
+ style: { width: `${productionProgress}%` }
9619
+ }
9620
+ ) }) }),
9621
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
9622
+ productionDisplay && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
9623
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Factory, { className: cn("h-3 w-3 shrink-0", styles.iconColor) }),
9624
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
9625
+ "text-[11px] tabular-nums font-medium",
9626
+ amountColorClass
9627
+ ), children: productionDisplay })
9628
+ ] }),
9629
+ visualState === "sent" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 ml-auto", children: [
9630
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3.5 w-3.5 text-green-600/60 dark:text-green-400/60 shrink-0" }),
9631
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium text-muted-foreground/50 uppercase tracking-wide", children: "Sent" })
9632
+ ] })
9633
+ ] })
9634
+ ]
9635
+ }
9636
+ )
9493
9637
  ]
9494
9638
  }
9495
9639
  );
@@ -9499,7 +9643,7 @@ function WeeklyLoadingView({
9499
9643
  deliveries,
9500
9644
  onDeliveryClick,
9501
9645
  onWeekChange,
9502
- onDayCommentClick,
9646
+ onDeliveryCommentClick,
9503
9647
  showNavigation = true,
9504
9648
  className
9505
9649
  }) {
@@ -9530,20 +9674,6 @@ function WeeklyLoadingView({
9530
9674
  }
9531
9675
  return grouped;
9532
9676
  }, [deliveries]);
9533
- const commentCountByDay = React27__namespace.useMemo(() => {
9534
- const counts = /* @__PURE__ */ new Map();
9535
- for (let i = 1; i <= 5; i++) {
9536
- counts.set(i, 0);
9537
- }
9538
- for (const delivery of deliveries) {
9539
- const dayOfWeek = delivery.date.getDay();
9540
- if (dayOfWeek >= 1 && dayOfWeek <= 5) {
9541
- const current = counts.get(dayOfWeek) ?? 0;
9542
- counts.set(dayOfWeek, current + delivery.comments.length);
9543
- }
9544
- }
9545
- return counts;
9546
- }, [deliveries]);
9547
9677
  const totalDeliveries = deliveries.length;
9548
9678
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col", className), children: [
9549
9679
  /* @__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: [
@@ -9608,54 +9738,27 @@ function WeeklyLoadingView({
9608
9738
  ] }),
9609
9739
  /* @__PURE__ */ jsxRuntime.jsxs(ScrollArea, { className: "flex-1", children: [
9610
9740
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "hidden sm:block", children: [
9611
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-5 border-b border-border bg-muted/30", children: weekDays.map(({ date, dayOfWeek, isToday: dayIsToday }) => {
9612
- const dayCommentCount = commentCountByDay.get(dayOfWeek) ?? 0;
9613
- return /* @__PURE__ */ jsxRuntime.jsxs(
9614
- "div",
9615
- {
9616
- className: cn(
9617
- // Relative for positioning comment button
9618
- "relative",
9619
- // Compact padding: py-2 px-3 (j3m.spacing.xs / j3m.spacing.s)
9620
- "flex items-center justify-center gap-2 py-2 px-3",
9621
- dayIsToday && "bg-primary/5"
9622
- ),
9623
- children: [
9624
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
9625
- "text-xs font-medium uppercase tracking-wide",
9626
- dayIsToday ? "text-primary" : "text-muted-foreground"
9627
- ), children: getShortDayLabel(dayOfWeek) }),
9628
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
9629
- "text-base font-semibold tabular-nums",
9630
- dayIsToday ? "text-primary" : "text-foreground"
9631
- ), children: date.getDate() }),
9632
- /* @__PURE__ */ jsxRuntime.jsxs(
9633
- Button,
9634
- {
9635
- variant: "ghost",
9636
- size: "icon",
9637
- className: cn(
9638
- "absolute top-1 right-1 h-7 w-7",
9639
- dayCommentCount > 0 && "text-primary"
9640
- ),
9641
- onClick: (e) => {
9642
- e.stopPropagation();
9643
- onDayCommentClick?.(dayOfWeek, date);
9644
- },
9645
- children: [
9646
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
9647
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "h-4 w-4" }),
9648
- dayCommentCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -top-1 -right-1 h-2 w-2 rounded-full bg-primary" })
9649
- ] }),
9650
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: dayCommentCount > 0 ? `${dayCommentCount} comments on ${getShortDayLabel(dayOfWeek)}` : `Add comment for ${getShortDayLabel(dayOfWeek)}` })
9651
- ]
9652
- }
9653
- )
9654
- ]
9655
- },
9656
- dayOfWeek
9657
- );
9658
- }) }),
9741
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-5 border-b border-border bg-muted/30", children: weekDays.map(({ date, dayOfWeek, isToday: dayIsToday }) => /* @__PURE__ */ jsxRuntime.jsxs(
9742
+ "div",
9743
+ {
9744
+ className: cn(
9745
+ // Compact padding
9746
+ "flex flex-col items-center justify-center py-2 px-2",
9747
+ dayIsToday && "bg-primary/5"
9748
+ ),
9749
+ children: [
9750
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
9751
+ "text-[11px] font-semibold uppercase tracking-wide leading-none",
9752
+ dayIsToday ? "text-primary" : "text-muted-foreground"
9753
+ ), children: getShortDayLabel(dayOfWeek) }),
9754
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
9755
+ "text-lg font-medium tabular-nums leading-tight mt-0.5",
9756
+ dayIsToday ? "text-primary" : "text-foreground"
9757
+ ), children: date.getDate() })
9758
+ ]
9759
+ },
9760
+ dayOfWeek
9761
+ )) }),
9659
9762
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-5", children: weekDays.map(({ dayOfWeek, isToday: dayIsToday }) => {
9660
9763
  const dayDeliveries = deliveriesByDay.get(dayOfWeek) ?? [];
9661
9764
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -9670,7 +9773,8 @@ function WeeklyLoadingView({
9670
9773
  DeliveryBadge,
9671
9774
  {
9672
9775
  delivery,
9673
- onClick: () => onDeliveryClick?.(delivery)
9776
+ onClick: () => onDeliveryClick?.(delivery),
9777
+ onCommentClick: () => onDeliveryCommentClick?.(delivery)
9674
9778
  },
9675
9779
  delivery.id
9676
9780
  )) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-6 text-sm text-muted-foreground/40", children: "\u2014" }) })
@@ -9681,7 +9785,6 @@ function WeeklyLoadingView({
9681
9785
  ] }),
9682
9786
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sm:hidden divide-y divide-border", children: weekDays.map(({ date, dayOfWeek, isToday: dayIsToday }) => {
9683
9787
  const dayDeliveries = deliveriesByDay.get(dayOfWeek) ?? [];
9684
- const dayCommentCount = commentCountByDay.get(dayOfWeek) ?? 0;
9685
9788
  return /* @__PURE__ */ jsxRuntime.jsxs(
9686
9789
  "div",
9687
9790
  {
@@ -9690,52 +9793,31 @@ function WeeklyLoadingView({
9690
9793
  ),
9691
9794
  children: [
9692
9795
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-4 py-2", children: [
9693
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
9694
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
9695
- "text-xs font-medium uppercase",
9696
- dayIsToday ? "text-primary" : "text-muted-foreground"
9697
- ), children: getShortDayLabel(dayOfWeek) }),
9698
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
9699
- "text-base font-semibold tabular-nums",
9700
- dayIsToday ? "text-primary" : "text-foreground"
9701
- ), children: date.getDate() }),
9702
- dayIsToday && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-primary font-medium", children: "Today" })
9703
- ] }),
9704
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
9705
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: [
9706
- dayDeliveries.length,
9707
- " ",
9708
- dayDeliveries.length === 1 ? "delivery" : "deliveries"
9796
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
9797
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center min-w-[40px]", children: [
9798
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
9799
+ "text-[11px] font-semibold uppercase tracking-wide leading-none",
9800
+ dayIsToday ? "text-primary" : "text-muted-foreground"
9801
+ ), children: getShortDayLabel(dayOfWeek) }),
9802
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
9803
+ "text-lg font-medium tabular-nums leading-tight mt-0.5",
9804
+ dayIsToday ? "text-primary" : "text-foreground"
9805
+ ), children: date.getDate() })
9709
9806
  ] }),
9710
- /* @__PURE__ */ jsxRuntime.jsxs(
9711
- Button,
9712
- {
9713
- variant: "ghost",
9714
- size: "icon",
9715
- className: cn(
9716
- "h-7 w-7",
9717
- dayCommentCount > 0 && "text-primary"
9718
- ),
9719
- onClick: (e) => {
9720
- e.stopPropagation();
9721
- onDayCommentClick?.(dayOfWeek, date);
9722
- },
9723
- children: [
9724
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
9725
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "h-4 w-4" }),
9726
- dayCommentCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -top-1 -right-1 h-2 w-2 rounded-full bg-primary" })
9727
- ] }),
9728
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Comments" })
9729
- ]
9730
- }
9731
- )
9807
+ dayIsToday && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-primary font-medium bg-primary/10 px-2 py-0.5 rounded", children: "Today" })
9808
+ ] }),
9809
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: [
9810
+ dayDeliveries.length,
9811
+ " ",
9812
+ dayDeliveries.length === 1 ? "delivery" : "deliveries"
9732
9813
  ] })
9733
9814
  ] }),
9734
9815
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-3 p-3 pt-0", children: dayDeliveries.length > 0 ? dayDeliveries.map((delivery) => /* @__PURE__ */ jsxRuntime.jsx(
9735
9816
  DeliveryBadge,
9736
9817
  {
9737
9818
  delivery,
9738
- onClick: () => onDeliveryClick?.(delivery)
9819
+ onClick: () => onDeliveryClick?.(delivery),
9820
+ onCommentClick: () => onDeliveryCommentClick?.(delivery)
9739
9821
  },
9740
9822
  delivery.id
9741
9823
  )) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-muted-foreground/40 py-4 text-center", children: "\u2014" }) })
@@ -9845,7 +9927,7 @@ function AddCommentDialog({
9845
9927
  }, [open]);
9846
9928
  return /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "sm:max-w-md", children: [
9847
9929
  /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { children: [
9848
- /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Add pre-unloading note" }),
9930
+ /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Add pre-loading note" }),
9849
9931
  /* @__PURE__ */ jsxRuntime.jsxs(DialogDescription, { children: [
9850
9932
  "Add a note for ",
9851
9933
  /* @__PURE__ */ jsxRuntime.jsx("strong", { children: delivery.label }),
@@ -9861,7 +9943,7 @@ function AddCommentDialog({
9861
9943
  Textarea,
9862
9944
  {
9863
9945
  id: "comment-text",
9864
- placeholder: "Add a note before unloading...",
9946
+ placeholder: "Add a note before loading...",
9865
9947
  value: commentText,
9866
9948
  onChange: (e) => setCommentText(e.target.value),
9867
9949
  onKeyDown: handleKeyDown,
@@ -9916,7 +9998,7 @@ function CommentsSection({
9916
9998
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
9917
9999
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
9918
10000
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "h-4 w-4 text-muted-foreground" }),
9919
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold", children: "Notes before unloading" }),
10001
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold", children: "Notes before loading" }),
9920
10002
  comments.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "secondary", className: "text-[10px] h-5", children: comments.length })
9921
10003
  ] }),
9922
10004
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -9951,7 +10033,7 @@ function CommentsSection({
9951
10033
  ] }),
9952
10034
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm", children: comment.text })
9953
10035
  ] }, comment.id)) })
9954
- ] }) : /* @__PURE__ */ jsxRuntime.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." })
10036
+ ] }) : /* @__PURE__ */ jsxRuntime.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." })
9955
10037
  ] }),
9956
10038
  /* @__PURE__ */ jsxRuntime.jsx(
9957
10039
  AddCommentDialog,
@@ -10014,7 +10096,7 @@ function DeliveryDetailPage({
10014
10096
  const addons = delivery.elements.filter((e) => e.status === "addon");
10015
10097
  return { loaded, missing, moved, addons };
10016
10098
  }, [delivery.elements]);
10017
- const preUnloadingComments = delivery.comments.filter((c) => c.context === "pre_unloading");
10099
+ const preLoadingComments = delivery.comments.filter((c) => c.context === "pre_unloading");
10018
10100
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col h-full", children: [
10019
10101
  /* @__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(
10020
10102
  Button,
@@ -10063,7 +10145,7 @@ function DeliveryDetailPage({
10063
10145
  {
10064
10146
  variant: "outline",
10065
10147
  className: "bg-green-100 dark:bg-green-900/50 border-green-300 dark:border-green-700 text-green-700 dark:text-green-300",
10066
- children: "Ready to unload"
10148
+ children: "Ready to load"
10067
10149
  }
10068
10150
  )
10069
10151
  ] })
@@ -10154,13 +10236,13 @@ function DeliveryDetailPage({
10154
10236
  ] })
10155
10237
  ] })
10156
10238
  ] }),
10157
- delivery.elements.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-3", children: [
10239
+ (elementsByStatus.loaded.length > 0 || elementsByStatus.missing.length > 0 || elementsByStatus.moved.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-3", children: [
10158
10240
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
10159
10241
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Package, { className: "h-4 w-4 text-muted-foreground" }),
10160
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold", children: "Elements to Unload" }),
10242
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold", children: "What should be packed" }),
10161
10243
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground ml-auto", children: [
10162
- delivery.elements.length,
10163
- " total"
10244
+ elementsByStatus.loaded.length + elementsByStatus.missing.length + elementsByStatus.moved.length,
10245
+ " items"
10164
10246
  ] })
10165
10247
  ] }),
10166
10248
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(Table, { children: [
@@ -10171,7 +10253,7 @@ function DeliveryDetailPage({
10171
10253
  /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "font-semibold text-right", children: "Size (m\xB2)" }),
10172
10254
  /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "font-semibold text-center", children: "Status" })
10173
10255
  ] }) }),
10174
- /* @__PURE__ */ jsxRuntime.jsx(TableBody, { children: delivery.elements.map((element) => /* @__PURE__ */ jsxRuntime.jsxs(
10256
+ /* @__PURE__ */ jsxRuntime.jsx(TableBody, { children: [...elementsByStatus.loaded, ...elementsByStatus.missing, ...elementsByStatus.moved].map((element) => /* @__PURE__ */ jsxRuntime.jsxs(
10175
10257
  TableRow,
10176
10258
  {
10177
10259
  className: getElementRowBg(element.status),
@@ -10199,10 +10281,6 @@ function DeliveryDetailPage({
10199
10281
  element.status === "moved" && element.actualDeliveryLabel && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[9px] text-blue-600 dark:text-blue-400", children: [
10200
10282
  "\u2192 ",
10201
10283
  element.actualDeliveryLabel
10202
- ] }),
10203
- element.status === "addon" && element.originalDeliveryLabel && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[9px] text-purple-600 dark:text-purple-400", children: [
10204
- "from ",
10205
- element.originalDeliveryLabel
10206
10284
  ] })
10207
10285
  ] }) })
10208
10286
  ]
@@ -10211,10 +10289,48 @@ function DeliveryDetailPage({
10211
10289
  )) })
10212
10290
  ] }) })
10213
10291
  ] }),
10292
+ elementsByStatus.addons.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-3", children: [
10293
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
10294
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4 text-purple-600 dark:text-purple-400" }),
10295
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold", children: "Extra items (moved to this delivery)" }),
10296
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground ml-auto", children: [
10297
+ elementsByStatus.addons.length,
10298
+ " items"
10299
+ ] })
10300
+ ] }),
10301
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "These items were originally planned for other deliveries but have been moved to this one." }),
10302
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-purple-200 dark:border-purple-800 overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(Table, { children: [
10303
+ /* @__PURE__ */ jsxRuntime.jsx(TableHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(TableRow, { className: "bg-purple-50/50 dark:bg-purple-950/30 hover:bg-purple-50/50 dark:hover:bg-purple-950/30", children: [
10304
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "font-semibold", children: "Prefix" }),
10305
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "font-semibold", children: "Type" }),
10306
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "font-semibold text-right", children: "Weight" }),
10307
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "font-semibold text-right", children: "Size (m\xB2)" }),
10308
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "font-semibold", children: "Moved from" })
10309
+ ] }) }),
10310
+ /* @__PURE__ */ jsxRuntime.jsx(TableBody, { children: elementsByStatus.addons.map((element) => /* @__PURE__ */ jsxRuntime.jsxs(
10311
+ TableRow,
10312
+ {
10313
+ className: "bg-purple-50/30 dark:bg-purple-950/10",
10314
+ children: [
10315
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { className: "font-medium", children: element.prefix }),
10316
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { children: element.type }),
10317
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { className: "text-right tabular-nums", children: element.weight ? /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
10318
+ element.weight,
10319
+ " ",
10320
+ element.weightUnit || "kg"
10321
+ ] }) : "\u2014" }),
10322
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { className: "text-right tabular-nums", children: element.sizeSqm ?? "\u2014" }),
10323
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { children: element.originalDeliveryLabel ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-purple-600 dark:text-purple-400", children: element.originalDeliveryLabel }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "\u2014" }) })
10324
+ ]
10325
+ },
10326
+ element.id
10327
+ )) })
10328
+ ] }) })
10329
+ ] }),
10214
10330
  /* @__PURE__ */ jsxRuntime.jsx(
10215
10331
  CommentsSection,
10216
10332
  {
10217
- comments: preUnloadingComments,
10333
+ comments: preLoadingComments,
10218
10334
  delivery,
10219
10335
  weekId: week.weekKey,
10220
10336
  onAddComment
@@ -10251,6 +10367,9 @@ function SupplierWeeklyLoading({
10251
10367
  }) {
10252
10368
  const [selectedDelivery, setSelectedDelivery] = React27__namespace.useState(null);
10253
10369
  const [sheetOpen, setSheetOpen] = React27__namespace.useState(false);
10370
+ const [commentDelivery, setCommentDelivery] = React27__namespace.useState(null);
10371
+ const [commentDialogOpen, setCommentDialogOpen] = React27__namespace.useState(false);
10372
+ const [commentText, setCommentText] = React27__namespace.useState("");
10254
10373
  const handleDeliveryClick = (delivery) => {
10255
10374
  setSelectedDelivery(delivery);
10256
10375
  setSheetOpen(true);
@@ -10261,6 +10380,38 @@ function SupplierWeeklyLoading({
10261
10380
  setTimeout(() => setSelectedDelivery(null), 200);
10262
10381
  onBack?.();
10263
10382
  };
10383
+ const handleDeliveryCommentClick = (delivery) => {
10384
+ setCommentDelivery(delivery);
10385
+ setCommentDialogOpen(true);
10386
+ };
10387
+ const handleCommentDialogClose = () => {
10388
+ setCommentDialogOpen(false);
10389
+ setCommentText("");
10390
+ setTimeout(() => setCommentDelivery(null), 200);
10391
+ };
10392
+ const handleCommentSubmit = () => {
10393
+ if (commentText.trim() && commentDelivery && onAddComment) {
10394
+ onAddComment({
10395
+ author: "Current User",
10396
+ // Would come from auth context in real app
10397
+ text: commentText.trim(),
10398
+ context: "pre_unloading",
10399
+ weekId: week.weekKey,
10400
+ deliveryId: commentDelivery.id,
10401
+ supplierId: commentDelivery.supplierId,
10402
+ supplierName: commentDelivery.supplierName,
10403
+ prefixId: commentDelivery.prefixScope,
10404
+ prefixName: commentDelivery.prefixScope
10405
+ });
10406
+ handleCommentDialogClose();
10407
+ }
10408
+ };
10409
+ const handleCommentKeyDown = (e) => {
10410
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
10411
+ e.preventDefault();
10412
+ handleCommentSubmit();
10413
+ }
10414
+ };
10264
10415
  const Wrapper = bordered ? Card : "div";
10265
10416
  const Content14 = bordered ? CardContent : "div";
10266
10417
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -10279,6 +10430,7 @@ function SupplierWeeklyLoading({
10279
10430
  week,
10280
10431
  deliveries,
10281
10432
  onDeliveryClick: handleDeliveryClick,
10433
+ onDeliveryCommentClick: handleDeliveryCommentClick,
10282
10434
  onWeekChange,
10283
10435
  showNavigation
10284
10436
  }
@@ -10307,7 +10459,58 @@ function SupplierWeeklyLoading({
10307
10459
  )
10308
10460
  ]
10309
10461
  }
10310
- ) })
10462
+ ) }),
10463
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: commentDialogOpen, onOpenChange: (open) => !open && handleCommentDialogClose(), children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "sm:max-w-md", children: [
10464
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { children: [
10465
+ /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Add pre-loading note" }),
10466
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogDescription, { children: [
10467
+ "Add a note for ",
10468
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { children: commentDelivery?.label }),
10469
+ " (",
10470
+ commentDelivery?.supplierName,
10471
+ commentDelivery?.prefixScope && ` \u2022 ${commentDelivery.prefixScope}`,
10472
+ ")."
10473
+ ] })
10474
+ ] }),
10475
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-4 py-2", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
10476
+ /* @__PURE__ */ jsxRuntime.jsx(Label2, { htmlFor: "card-comment-text", className: "text-sm font-medium", children: "Note" }),
10477
+ /* @__PURE__ */ jsxRuntime.jsx(
10478
+ Textarea,
10479
+ {
10480
+ id: "card-comment-text",
10481
+ placeholder: "Add a note before loading...",
10482
+ value: commentText,
10483
+ onChange: (e) => setCommentText(e.target.value),
10484
+ onKeyDown: handleCommentKeyDown,
10485
+ className: "min-h-[120px] text-base resize-none",
10486
+ autoFocus: true
10487
+ }
10488
+ ),
10489
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "\u2318+Enter to save" })
10490
+ ] }) }),
10491
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogFooter, { className: "gap-2 sm:gap-0", children: [
10492
+ /* @__PURE__ */ jsxRuntime.jsx(
10493
+ Button,
10494
+ {
10495
+ variant: "ghost",
10496
+ onClick: handleCommentDialogClose,
10497
+ children: "Cancel"
10498
+ }
10499
+ ),
10500
+ /* @__PURE__ */ jsxRuntime.jsxs(
10501
+ Button,
10502
+ {
10503
+ onClick: handleCommentSubmit,
10504
+ disabled: !commentText.trim(),
10505
+ className: "gap-1.5",
10506
+ children: [
10507
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "h-4 w-4" }),
10508
+ "Save note"
10509
+ ]
10510
+ }
10511
+ )
10512
+ ] })
10513
+ ] }) })
10311
10514
  ] });
10312
10515
  }
10313
10516
  function getStatusBadgeVariant3(status) {
@@ -13797,6 +14000,12 @@ exports.ItemTitle = ItemTitle;
13797
14000
  exports.Kbd = Kbd;
13798
14001
  exports.KbdGroup = KbdGroup;
13799
14002
  exports.Label = Label2;
14003
+ exports.Map = Map2;
14004
+ exports.MapMarker = MapMarker;
14005
+ exports.MapPopup = MapPopup;
14006
+ exports.MapTileLayer = MapTileLayer;
14007
+ exports.MapTooltip = MapTooltip;
14008
+ exports.MapZoomControl = MapZoomControl;
13800
14009
  exports.Menubar = Menubar;
13801
14010
  exports.MenubarCheckboxItem = MenubarCheckboxItem;
13802
14011
  exports.MenubarContent = MenubarContent;