@j3m-quantum/ui 1.11.1 → 1.12.1

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
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var React27 = require('react');
3
+ var React29 = require('react');
4
4
  var reactSlot = require('@radix-ui/react-slot');
5
5
  var classVarianceAuthority = require('class-variance-authority');
6
6
  var clsx = require('clsx');
@@ -73,7 +73,7 @@ function _interopNamespace(e) {
73
73
  return Object.freeze(n);
74
74
  }
75
75
 
76
- var React27__namespace = /*#__PURE__*/_interopNamespace(React27);
76
+ var React29__namespace = /*#__PURE__*/_interopNamespace(React29);
77
77
  var SeparatorPrimitive__namespace = /*#__PURE__*/_interopNamespace(SeparatorPrimitive);
78
78
  var CheckboxPrimitive__namespace = /*#__PURE__*/_interopNamespace(CheckboxPrimitive);
79
79
  var RadioGroupPrimitive__namespace = /*#__PURE__*/_interopNamespace(RadioGroupPrimitive);
@@ -108,8 +108,8 @@ var tunnel__default = /*#__PURE__*/_interopDefault(tunnel);
108
108
  // src/hooks/use-mobile.ts
109
109
  var MOBILE_BREAKPOINT = 768;
110
110
  function useIsMobile() {
111
- const [isMobile, setIsMobile] = React27__namespace.useState(void 0);
112
- React27__namespace.useEffect(() => {
111
+ const [isMobile, setIsMobile] = React29__namespace.useState(void 0);
112
+ React29__namespace.useEffect(() => {
113
113
  const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
114
114
  const onChange = () => {
115
115
  setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
@@ -150,7 +150,7 @@ var buttonVariants = classVarianceAuthority.cva(
150
150
  }
151
151
  }
152
152
  );
153
- var Button = React27__namespace.forwardRef(
153
+ var Button = React29__namespace.forwardRef(
154
154
  ({ className, variant, size, asChild = false, ...props }, ref) => {
155
155
  const Comp = asChild ? reactSlot.Slot : "button";
156
156
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -514,7 +514,7 @@ function Slider({
514
514
  max = 100,
515
515
  ...props
516
516
  }) {
517
- const _values = React27__namespace.useMemo(
517
+ const _values = React29__namespace.useMemo(
518
518
  () => Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min, max],
519
519
  [value, defaultValue, min, max]
520
520
  );
@@ -800,7 +800,7 @@ function Toggle({
800
800
  }
801
801
  );
802
802
  }
803
- var ToggleGroupContext = React27__namespace.createContext({
803
+ var ToggleGroupContext = React29__namespace.createContext({
804
804
  size: "default",
805
805
  variant: "default",
806
806
  spacing: 0
@@ -837,7 +837,7 @@ function ToggleGroupItem({
837
837
  size,
838
838
  ...props
839
839
  }) {
840
- const context = React27__namespace.useContext(ToggleGroupContext);
840
+ const context = React29__namespace.useContext(ToggleGroupContext);
841
841
  return /* @__PURE__ */ jsxRuntime.jsx(
842
842
  ToggleGroupPrimitive__namespace.Item,
843
843
  {
@@ -867,7 +867,7 @@ function ThemeSwitch({
867
867
  className,
868
868
  size = "default"
869
869
  }) {
870
- const [isChecked, setIsChecked] = React27__namespace.useState(defaultChecked);
870
+ const [isChecked, setIsChecked] = React29__namespace.useState(defaultChecked);
871
871
  const isControlled = checked !== void 0;
872
872
  const currentChecked = isControlled ? checked : isChecked;
873
873
  const handleClick = () => {
@@ -1287,7 +1287,7 @@ function Label2({
1287
1287
  );
1288
1288
  }
1289
1289
  var Form = reactHookForm.FormProvider;
1290
- var FormFieldContext = React27__namespace.createContext(
1290
+ var FormFieldContext = React29__namespace.createContext(
1291
1291
  {}
1292
1292
  );
1293
1293
  var FormField = ({
@@ -1296,8 +1296,8 @@ var FormField = ({
1296
1296
  return /* @__PURE__ */ jsxRuntime.jsx(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsxRuntime.jsx(reactHookForm.Controller, { ...props }) });
1297
1297
  };
1298
1298
  var useFormField = () => {
1299
- const fieldContext = React27__namespace.useContext(FormFieldContext);
1300
- const itemContext = React27__namespace.useContext(FormItemContext);
1299
+ const fieldContext = React29__namespace.useContext(FormFieldContext);
1300
+ const itemContext = React29__namespace.useContext(FormItemContext);
1301
1301
  const { getFieldState } = reactHookForm.useFormContext();
1302
1302
  const formState = reactHookForm.useFormState({ name: fieldContext.name });
1303
1303
  const fieldState = getFieldState(fieldContext.name, formState);
@@ -1314,11 +1314,11 @@ var useFormField = () => {
1314
1314
  ...fieldState
1315
1315
  };
1316
1316
  };
1317
- var FormItemContext = React27__namespace.createContext(
1317
+ var FormItemContext = React29__namespace.createContext(
1318
1318
  {}
1319
1319
  );
1320
1320
  function FormItem({ className, ...props }) {
1321
- const id = React27__namespace.useId();
1321
+ const id = React29__namespace.useId();
1322
1322
  return /* @__PURE__ */ jsxRuntime.jsx(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsxRuntime.jsx(
1323
1323
  "div",
1324
1324
  {
@@ -1566,7 +1566,7 @@ function FieldError({
1566
1566
  errors,
1567
1567
  ...props
1568
1568
  }) {
1569
- const content = React27.useMemo(() => {
1569
+ const content = React29.useMemo(() => {
1570
1570
  if (children) {
1571
1571
  return children;
1572
1572
  }
@@ -2420,8 +2420,8 @@ function CalendarDayButton({
2420
2420
  modifiers,
2421
2421
  ...props
2422
2422
  }) {
2423
- const ref = React27__namespace.useRef(null);
2424
- React27__namespace.useEffect(() => {
2423
+ const ref = React29__namespace.useRef(null);
2424
+ React29__namespace.useEffect(() => {
2425
2425
  if (modifiers.focused) ref.current?.focus();
2426
2426
  }, [modifiers.focused]);
2427
2427
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -2442,9 +2442,9 @@ function CalendarDayButton({
2442
2442
  }
2443
2443
  );
2444
2444
  }
2445
- var CarouselContext = React27__namespace.createContext(null);
2445
+ var CarouselContext = React29__namespace.createContext(null);
2446
2446
  function useCarousel() {
2447
- const context = React27__namespace.useContext(CarouselContext);
2447
+ const context = React29__namespace.useContext(CarouselContext);
2448
2448
  if (!context) {
2449
2449
  throw new Error("useCarousel must be used within a <Carousel />");
2450
2450
  }
@@ -2466,20 +2466,20 @@ function Carousel({
2466
2466
  },
2467
2467
  plugins
2468
2468
  );
2469
- const [canScrollPrev, setCanScrollPrev] = React27__namespace.useState(false);
2470
- const [canScrollNext, setCanScrollNext] = React27__namespace.useState(false);
2471
- const onSelect = React27__namespace.useCallback((api2) => {
2469
+ const [canScrollPrev, setCanScrollPrev] = React29__namespace.useState(false);
2470
+ const [canScrollNext, setCanScrollNext] = React29__namespace.useState(false);
2471
+ const onSelect = React29__namespace.useCallback((api2) => {
2472
2472
  if (!api2) return;
2473
2473
  setCanScrollPrev(api2.canScrollPrev());
2474
2474
  setCanScrollNext(api2.canScrollNext());
2475
2475
  }, []);
2476
- const scrollPrev = React27__namespace.useCallback(() => {
2476
+ const scrollPrev = React29__namespace.useCallback(() => {
2477
2477
  api?.scrollPrev();
2478
2478
  }, [api]);
2479
- const scrollNext = React27__namespace.useCallback(() => {
2479
+ const scrollNext = React29__namespace.useCallback(() => {
2480
2480
  api?.scrollNext();
2481
2481
  }, [api]);
2482
- const handleKeyDown = React27__namespace.useCallback(
2482
+ const handleKeyDown = React29__namespace.useCallback(
2483
2483
  (event) => {
2484
2484
  if (event.key === "ArrowLeft") {
2485
2485
  event.preventDefault();
@@ -2491,11 +2491,11 @@ function Carousel({
2491
2491
  },
2492
2492
  [scrollPrev, scrollNext]
2493
2493
  );
2494
- React27__namespace.useEffect(() => {
2494
+ React29__namespace.useEffect(() => {
2495
2495
  if (!api || !setApi) return;
2496
2496
  setApi(api);
2497
2497
  }, [api, setApi]);
2498
- React27__namespace.useEffect(() => {
2498
+ React29__namespace.useEffect(() => {
2499
2499
  if (!api) return;
2500
2500
  onSelect(api);
2501
2501
  api.on("reInit", onSelect);
@@ -2628,9 +2628,9 @@ function CarouselNext({
2628
2628
  );
2629
2629
  }
2630
2630
  var THEMES = { light: "", dark: ".dark" };
2631
- var ChartContext = React27__namespace.createContext(null);
2631
+ var ChartContext = React29__namespace.createContext(null);
2632
2632
  function useChart() {
2633
- const context = React27__namespace.useContext(ChartContext);
2633
+ const context = React29__namespace.useContext(ChartContext);
2634
2634
  if (!context) {
2635
2635
  throw new Error("useChart must be used within a <ChartContainer />");
2636
2636
  }
@@ -2643,7 +2643,7 @@ function ChartContainer({
2643
2643
  config,
2644
2644
  ...props
2645
2645
  }) {
2646
- const uniqueId = React27__namespace.useId();
2646
+ const uniqueId = React29__namespace.useId();
2647
2647
  const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`;
2648
2648
  return /* @__PURE__ */ jsxRuntime.jsx(ChartContext.Provider, { value: { config }, children: /* @__PURE__ */ jsxRuntime.jsxs(
2649
2649
  "div",
@@ -2704,7 +2704,7 @@ function ChartTooltipContent({
2704
2704
  labelKey
2705
2705
  }) {
2706
2706
  const { config } = useChart();
2707
- const tooltipLabel = React27__namespace.useMemo(() => {
2707
+ const tooltipLabel = React29__namespace.useMemo(() => {
2708
2708
  if (hideLabel || !payload?.length) {
2709
2709
  return null;
2710
2710
  }
@@ -3459,6 +3459,144 @@ function CircularProgress({
3459
3459
  }
3460
3460
  );
3461
3461
  }
3462
+ function getVariantFromProgress(value) {
3463
+ if (value >= 100) return "complete";
3464
+ if (value >= 50) return "normal";
3465
+ if (value > 0) return "warning";
3466
+ return "critical";
3467
+ }
3468
+ function getStatusColors(variant) {
3469
+ switch (variant) {
3470
+ case "complete":
3471
+ return {
3472
+ track: "bg-green-500/20 dark:bg-green-500/10",
3473
+ fill: "bg-green-500",
3474
+ text: "text-green-600 dark:text-green-400",
3475
+ icon: "text-green-600 dark:text-green-400"
3476
+ };
3477
+ case "normal":
3478
+ return {
3479
+ track: "bg-green-500/20 dark:bg-green-500/10",
3480
+ fill: "bg-green-500",
3481
+ text: "text-green-600 dark:text-green-400",
3482
+ icon: "text-green-600 dark:text-green-400"
3483
+ };
3484
+ case "warning":
3485
+ return {
3486
+ track: "bg-amber-500/20 dark:bg-amber-500/10",
3487
+ fill: "bg-amber-500",
3488
+ text: "text-amber-600 dark:text-amber-400",
3489
+ icon: "text-amber-600 dark:text-amber-400"
3490
+ };
3491
+ case "critical":
3492
+ return {
3493
+ track: "bg-red-500/20 dark:bg-red-500/10",
3494
+ fill: "bg-red-500",
3495
+ text: "text-red-600 dark:text-red-400",
3496
+ icon: "text-red-600 dark:text-red-400"
3497
+ };
3498
+ }
3499
+ }
3500
+ function getSizeClasses(size) {
3501
+ switch (size) {
3502
+ case "sm":
3503
+ return {
3504
+ bar: "h-1",
3505
+ text: "text-[10px]",
3506
+ icon: "h-3 w-3",
3507
+ gap: "gap-1"
3508
+ };
3509
+ case "lg":
3510
+ return {
3511
+ bar: "h-3",
3512
+ text: "text-sm",
3513
+ icon: "h-5 w-5",
3514
+ gap: "gap-3"
3515
+ };
3516
+ default:
3517
+ return {
3518
+ bar: "h-2",
3519
+ text: "text-xs",
3520
+ icon: "h-4 w-4",
3521
+ gap: "gap-2"
3522
+ };
3523
+ }
3524
+ }
3525
+ function StatusProgress({
3526
+ className,
3527
+ value,
3528
+ currentCount,
3529
+ totalCount,
3530
+ unitLabel = "elements",
3531
+ showLabel = false,
3532
+ showCheckmark = true,
3533
+ size = "md",
3534
+ variant,
3535
+ ...props
3536
+ }) {
3537
+ const clampedValue = Math.min(100, Math.max(0, value));
3538
+ const isComplete = clampedValue >= 100;
3539
+ const resolvedVariant = variant ?? getVariantFromProgress(clampedValue);
3540
+ const colors = getStatusColors(resolvedVariant);
3541
+ const sizes = getSizeClasses(size);
3542
+ const labelText = React29__namespace.useMemo(() => {
3543
+ if (currentCount !== void 0 && totalCount !== void 0) {
3544
+ return `${currentCount} / ${totalCount} ${unitLabel}`;
3545
+ }
3546
+ return `${Math.round(clampedValue)}%`;
3547
+ }, [currentCount, totalCount, unitLabel, clampedValue]);
3548
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3549
+ "div",
3550
+ {
3551
+ "data-slot": "status-progress",
3552
+ "data-value": clampedValue,
3553
+ "data-variant": resolvedVariant,
3554
+ "data-complete": isComplete,
3555
+ className: cn("flex flex-col w-full", sizes.gap, className),
3556
+ ...props,
3557
+ children: [
3558
+ showLabel && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center justify-between", sizes.gap), children: [
3559
+ /* @__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: [
3560
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: cn(sizes.icon, colors.icon) }),
3561
+ "Complete"
3562
+ ] }) : labelText }),
3563
+ !isComplete && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("tabular-nums text-muted-foreground", sizes.text), children: [
3564
+ Math.round(clampedValue),
3565
+ "%"
3566
+ ] })
3567
+ ] }),
3568
+ /* @__PURE__ */ jsxRuntime.jsx(
3569
+ "div",
3570
+ {
3571
+ className: cn(
3572
+ "w-full rounded-full overflow-hidden",
3573
+ colors.track,
3574
+ sizes.bar
3575
+ ),
3576
+ role: "progressbar",
3577
+ "aria-valuenow": clampedValue,
3578
+ "aria-valuemin": 0,
3579
+ "aria-valuemax": 100,
3580
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3581
+ "div",
3582
+ {
3583
+ className: cn(
3584
+ "h-full rounded-full transition-all duration-300 ease-out",
3585
+ colors.fill
3586
+ ),
3587
+ style: { width: `${clampedValue}%` }
3588
+ }
3589
+ )
3590
+ }
3591
+ ),
3592
+ !showLabel && isComplete && showCheckmark && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex items-center", sizes.gap), children: [
3593
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: cn(sizes.icon, colors.icon) }),
3594
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("font-medium", sizes.text, colors.text), children: "Complete" })
3595
+ ] })
3596
+ ]
3597
+ }
3598
+ );
3599
+ }
3462
3600
  function TooltipProvider({
3463
3601
  delayDuration = 0,
3464
3602
  ...props
@@ -3506,8 +3644,8 @@ function TooltipContent({
3506
3644
  ) });
3507
3645
  }
3508
3646
  function useDetectTheme() {
3509
- const [theme, setTheme] = React27__namespace.useState("light");
3510
- React27__namespace.useEffect(() => {
3647
+ const [theme, setTheme] = React29__namespace.useState("light");
3648
+ React29__namespace.useEffect(() => {
3511
3649
  const isDark = document.documentElement.classList.contains("dark");
3512
3650
  setTheme(isDark ? "dark" : "light");
3513
3651
  const observer = new MutationObserver((mutations) => {
@@ -4156,7 +4294,7 @@ function CommandShortcut({
4156
4294
  }
4157
4295
  );
4158
4296
  }
4159
- var SearchTrigger = React27__namespace.forwardRef(
4297
+ var SearchTrigger = React29__namespace.forwardRef(
4160
4298
  ({
4161
4299
  className,
4162
4300
  placeholder = "Search...",
@@ -4192,7 +4330,7 @@ var SearchTrigger = React27__namespace.forwardRef(
4192
4330
  );
4193
4331
  SearchTrigger.displayName = "SearchTrigger";
4194
4332
  function useSearchShortcut(onOpen, key = "k") {
4195
- React27__namespace.useEffect(() => {
4333
+ React29__namespace.useEffect(() => {
4196
4334
  const down = (e) => {
4197
4335
  if (e.key.toLowerCase() === key.toLowerCase() && (e.metaKey || e.ctrlKey)) {
4198
4336
  e.preventDefault();
@@ -5167,9 +5305,9 @@ var SIDEBAR_WIDTH = "16rem";
5167
5305
  var SIDEBAR_WIDTH_MOBILE = "18rem";
5168
5306
  var SIDEBAR_WIDTH_ICON = "3rem";
5169
5307
  var SIDEBAR_KEYBOARD_SHORTCUT = "b";
5170
- var SidebarContext = React27__namespace.createContext(null);
5308
+ var SidebarContext = React29__namespace.createContext(null);
5171
5309
  function useSidebar() {
5172
- const context = React27__namespace.useContext(SidebarContext);
5310
+ const context = React29__namespace.useContext(SidebarContext);
5173
5311
  if (!context) {
5174
5312
  throw new Error("useSidebar must be used within a SidebarProvider.");
5175
5313
  }
@@ -5185,10 +5323,10 @@ function SidebarProvider({
5185
5323
  ...props
5186
5324
  }) {
5187
5325
  const isMobile = useIsMobile();
5188
- const [openMobile, setOpenMobile] = React27__namespace.useState(false);
5189
- const [_open, _setOpen] = React27__namespace.useState(defaultOpen);
5326
+ const [openMobile, setOpenMobile] = React29__namespace.useState(false);
5327
+ const [_open, _setOpen] = React29__namespace.useState(defaultOpen);
5190
5328
  const open = openProp ?? _open;
5191
- const setOpen = React27__namespace.useCallback(
5329
+ const setOpen = React29__namespace.useCallback(
5192
5330
  (value) => {
5193
5331
  const openState = typeof value === "function" ? value(open) : value;
5194
5332
  if (setOpenProp) {
@@ -5200,10 +5338,10 @@ function SidebarProvider({
5200
5338
  },
5201
5339
  [setOpenProp, open]
5202
5340
  );
5203
- const toggleSidebar = React27__namespace.useCallback(() => {
5341
+ const toggleSidebar = React29__namespace.useCallback(() => {
5204
5342
  return isMobile ? setOpenMobile((open2) => !open2) : setOpen((open2) => !open2);
5205
5343
  }, [isMobile, setOpen, setOpenMobile]);
5206
- React27__namespace.useEffect(() => {
5344
+ React29__namespace.useEffect(() => {
5207
5345
  const handleKeyDown = (event) => {
5208
5346
  if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
5209
5347
  event.preventDefault();
@@ -5214,7 +5352,7 @@ function SidebarProvider({
5214
5352
  return () => window.removeEventListener("keydown", handleKeyDown);
5215
5353
  }, [toggleSidebar]);
5216
5354
  const state = open ? "expanded" : "collapsed";
5217
- const contextValue = React27__namespace.useMemo(
5355
+ const contextValue = React29__namespace.useMemo(
5218
5356
  () => ({
5219
5357
  state,
5220
5358
  open,
@@ -5672,7 +5810,7 @@ function SidebarMenuSkeleton({
5672
5810
  showIcon = false,
5673
5811
  ...props
5674
5812
  }) {
5675
- const width = React27__namespace.useMemo(() => {
5813
+ const width = React29__namespace.useMemo(() => {
5676
5814
  return `${Math.floor(Math.random() * 40) + 50}%`;
5677
5815
  }, []);
5678
5816
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -5815,7 +5953,7 @@ var sectionVariants = classVarianceAuthority.cva(
5815
5953
  }
5816
5954
  );
5817
5955
  var isGlassVariant = (variant) => variant?.startsWith("glass-") ?? false;
5818
- var Section = React27__namespace.forwardRef(
5956
+ var Section = React29__namespace.forwardRef(
5819
5957
  ({ className, variant, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
5820
5958
  "section",
5821
5959
  {
@@ -5827,7 +5965,7 @@ var Section = React27__namespace.forwardRef(
5827
5965
  )
5828
5966
  );
5829
5967
  Section.displayName = "Section";
5830
- var SectionHeader = React27__namespace.forwardRef(
5968
+ var SectionHeader = React29__namespace.forwardRef(
5831
5969
  ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
5832
5970
  "div",
5833
5971
  {
@@ -5842,7 +5980,7 @@ var SectionHeader = React27__namespace.forwardRef(
5842
5980
  )
5843
5981
  );
5844
5982
  SectionHeader.displayName = "SectionHeader";
5845
- var SectionTitle = React27__namespace.forwardRef(
5983
+ var SectionTitle = React29__namespace.forwardRef(
5846
5984
  ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
5847
5985
  "h2",
5848
5986
  {
@@ -5856,7 +5994,7 @@ var SectionTitle = React27__namespace.forwardRef(
5856
5994
  )
5857
5995
  );
5858
5996
  SectionTitle.displayName = "SectionTitle";
5859
- var SectionDescription = React27__namespace.forwardRef(
5997
+ var SectionDescription = React29__namespace.forwardRef(
5860
5998
  ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
5861
5999
  "p",
5862
6000
  {
@@ -5870,7 +6008,7 @@ var SectionDescription = React27__namespace.forwardRef(
5870
6008
  )
5871
6009
  );
5872
6010
  SectionDescription.displayName = "SectionDescription";
5873
- var SectionContent = React27__namespace.forwardRef(
6011
+ var SectionContent = React29__namespace.forwardRef(
5874
6012
  ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
5875
6013
  "div",
5876
6014
  {
@@ -5884,7 +6022,7 @@ var SectionContent = React27__namespace.forwardRef(
5884
6022
  )
5885
6023
  );
5886
6024
  SectionContent.displayName = "SectionContent";
5887
- var SectionFooter = React27__namespace.forwardRef(
6025
+ var SectionFooter = React29__namespace.forwardRef(
5888
6026
  ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
5889
6027
  "div",
5890
6028
  {
@@ -6192,7 +6330,7 @@ function SiteHeader({
6192
6330
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-[var(--header-height,3.5rem)] w-full items-center gap-[var(--j3m-spacing-s)] px-[var(--j3m-spacing-m)]", children: [
6193
6331
  trigger,
6194
6332
  trigger && /* @__PURE__ */ jsxRuntime.jsx(Separator, { orientation: "vertical", className: "mr-[var(--j3m-spacing-s)] h-4" }),
6195
- /* @__PURE__ */ jsxRuntime.jsx(Breadcrumb, { className: "hidden sm:block", children: /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbList, { children: breadcrumbs.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs(React27__namespace.Fragment, { children: [
6333
+ /* @__PURE__ */ jsxRuntime.jsx(Breadcrumb, { className: "hidden sm:block", children: /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbList, { children: breadcrumbs.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs(React29__namespace.Fragment, { children: [
6196
6334
  index > 0 && /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbSeparator, {}),
6197
6335
  /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbItem, { children: item.href ? /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbLink, { href: item.href, children: item.label }) : /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbPage, { children: item.label }) })
6198
6336
  ] }, index)) }) }),
@@ -6431,15 +6569,27 @@ function getCombinedRiskLevel(data) {
6431
6569
  if (productionStatus === "delayed" || hasDeliveryDelayed || data.hasWarning) {
6432
6570
  return "warning";
6433
6571
  }
6572
+ const productionProgress = data.production?.progress ?? data.progress ?? 0;
6573
+ const isProductionComplete = productionProgress >= 100;
6574
+ if (isProductionComplete) {
6575
+ return "complete";
6576
+ }
6434
6577
  return "normal";
6435
6578
  }
6436
- function getRowStatus(status) {
6579
+ function getRowStatus(status, progress) {
6437
6580
  if (status === "critical") return "critical";
6438
6581
  if (status === "delayed") return "warning";
6582
+ if (progress !== void 0 && progress >= 100) return "complete";
6439
6583
  return "normal";
6440
6584
  }
6441
6585
  var statusFillClasses = {
6442
6586
  normal: {
6587
+ // Grey/muted for "on track but not complete" - reduces visual noise
6588
+ border: "border-l-[3px] border-l-muted-foreground/40",
6589
+ bg: "bg-muted/30 dark:bg-muted/20"
6590
+ },
6591
+ complete: {
6592
+ // Green for "done/complete" - clear success signal
6443
6593
  border: "border-l-[3px] border-l-green-500",
6444
6594
  bg: "bg-green-50/50 dark:bg-green-950/30"
6445
6595
  },
@@ -6454,6 +6604,13 @@ var statusFillClasses = {
6454
6604
  };
6455
6605
  var statusColors = {
6456
6606
  normal: {
6607
+ // Grey/muted for "on track but not complete"
6608
+ icon: "text-muted-foreground",
6609
+ progress: "bg-muted-foreground/60",
6610
+ text: "text-muted-foreground"
6611
+ },
6612
+ complete: {
6613
+ // Green for "done/complete"
6457
6614
  icon: "text-green-600 dark:text-green-400",
6458
6615
  progress: "bg-green-500",
6459
6616
  text: "text-green-700 dark:text-green-300"
@@ -6481,19 +6638,20 @@ function WeekCell({
6481
6638
  const combinedRisk = data.type === "data" ? getCombinedRiskLevel(data) : "normal";
6482
6639
  const statusClasses = statusFillClasses[combinedRisk];
6483
6640
  const productionProgress = data.production?.progress ?? data.progress ?? 0;
6484
- const productionStatus = getRowStatus(data.production?.status);
6641
+ const productionStatus = getRowStatus(data.production?.status, productionProgress);
6485
6642
  const productionColors = statusColors[productionStatus];
6486
6643
  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";
6644
+ const allDeliveriesComplete = data.deliveries?.every((d) => (d.progress ?? 0) >= 100) ?? false;
6645
+ const worstDeliveryStatus = data.deliveries?.some((d) => d.status === "critical") ? "critical" : data.deliveries?.some((d) => d.status === "delayed") ? "warning" : allDeliveriesComplete && deliveryCount > 0 ? "complete" : "normal";
6488
6646
  const deliveryColors = statusColors[worstDeliveryStatus];
6489
- const getDeliveryStatusColor = (status) => {
6490
- switch (status) {
6647
+ const getDeliveryStatusColor = (delivery) => {
6648
+ switch (delivery.status) {
6491
6649
  case "critical":
6492
6650
  return "bg-red-500";
6493
6651
  case "delayed":
6494
6652
  return "bg-amber-500";
6495
6653
  default:
6496
- return "bg-green-500";
6654
+ return (delivery.progress ?? 0) >= 100 ? "bg-green-500" : "bg-muted-foreground/60";
6497
6655
  }
6498
6656
  };
6499
6657
  const handleClick = () => {
@@ -6610,24 +6768,18 @@ function WeekCell({
6610
6768
  ] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: "\u2014" })
6611
6769
  ] }),
6612
6770
  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
- }),
6771
+ data.deliveries?.slice(0, 5).map((delivery, index) => /* @__PURE__ */ jsxRuntime.jsx(
6772
+ "div",
6773
+ {
6774
+ className: cn(
6775
+ "flex-1 max-w-[24px] h-1.5 rounded-full",
6776
+ // Solid status color - grey=on-track, green=complete, amber=at-risk, red=critical
6777
+ getDeliveryStatusColor(delivery)
6778
+ ),
6779
+ title: delivery.label || `Delivery ${index + 1}`
6780
+ },
6781
+ delivery.id || index
6782
+ )),
6631
6783
  deliveryCount > 5 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[8px] text-muted-foreground", children: [
6632
6784
  "+",
6633
6785
  deliveryCount - 5
@@ -6799,11 +6951,11 @@ function PlanningWeekCommentPopover({
6799
6951
  open,
6800
6952
  onOpenChange
6801
6953
  }) {
6802
- const [newCommentText, setNewCommentText] = React27__namespace.useState("");
6803
- const [selectedLocationId, setSelectedLocationId] = React27__namespace.useState("");
6804
- const [viewCommentsOpen, setViewCommentsOpen] = React27__namespace.useState(true);
6805
- const [showAddForm, setShowAddForm] = React27__namespace.useState(false);
6806
- const selectedLocation = React27__namespace.useMemo(() => {
6954
+ const [newCommentText, setNewCommentText] = React29__namespace.useState("");
6955
+ const [selectedLocationId, setSelectedLocationId] = React29__namespace.useState("");
6956
+ const [viewCommentsOpen, setViewCommentsOpen] = React29__namespace.useState(true);
6957
+ const [showAddForm, setShowAddForm] = React29__namespace.useState(false);
6958
+ const selectedLocation = React29__namespace.useMemo(() => {
6807
6959
  return locationOptions.find((opt) => opt.id === selectedLocationId);
6808
6960
  }, [locationOptions, selectedLocationId]);
6809
6961
  const handleSubmit = () => {
@@ -6847,8 +6999,8 @@ function PlanningWeekCommentPopover({
6847
6999
  minute: "2-digit"
6848
7000
  }).format(date);
6849
7001
  };
6850
- const prevOpenRef = React27__namespace.useRef(open);
6851
- React27__namespace.useEffect(() => {
7002
+ const prevOpenRef = React29__namespace.useRef(open);
7003
+ React29__namespace.useEffect(() => {
6852
7004
  const wasOpen = prevOpenRef.current;
6853
7005
  prevOpenRef.current = open;
6854
7006
  if (wasOpen && !open) {
@@ -7202,22 +7354,22 @@ function PlanningTable({
7202
7354
  stickySupplierColumn = true,
7203
7355
  maxHeight = "600px"
7204
7356
  } = config;
7205
- const weeks = React27__namespace.useMemo(
7357
+ const weeks = React29__namespace.useMemo(
7206
7358
  () => generateWeeks(startDate, weekCount),
7207
7359
  [startDate, weekCount]
7208
7360
  );
7209
- const currentWeekKey = React27__namespace.useMemo(() => {
7361
+ const currentWeekKey = React29__namespace.useMemo(() => {
7210
7362
  const currentWeek = weeks.find((w) => w.isCurrentWeek);
7211
7363
  return currentWeek ? getWeekKey(currentWeek.startDate) : null;
7212
7364
  }, [weeks]);
7213
- const columns = React27__namespace.useMemo(
7365
+ const columns = React29__namespace.useMemo(
7214
7366
  () => generateColumns(weeks, config, suppliers),
7215
7367
  [weeks, config, suppliers]
7216
7368
  );
7217
- const [sorting, setSorting] = React27__namespace.useState([]);
7218
- const [columnFilters, setColumnFilters] = React27__namespace.useState([]);
7219
- const [columnVisibility, setColumnVisibility] = React27__namespace.useState({});
7220
- const [rowSelection, setRowSelection] = React27__namespace.useState({});
7369
+ const [sorting, setSorting] = React29__namespace.useState([]);
7370
+ const [columnFilters, setColumnFilters] = React29__namespace.useState([]);
7371
+ const [columnVisibility, setColumnVisibility] = React29__namespace.useState({});
7372
+ const [rowSelection, setRowSelection] = React29__namespace.useState({});
7221
7373
  const table = reactTable.useReactTable({
7222
7374
  data: suppliers,
7223
7375
  columns,
@@ -7340,10 +7492,12 @@ function PlanningTable({
7340
7492
  }
7341
7493
  );
7342
7494
  }
7343
- function getStatusBadgeVariant(status) {
7495
+ function getStatusBadgeVariant(status, isComplete) {
7496
+ if (isComplete) return "outline";
7344
7497
  switch (status) {
7345
7498
  case "on-time":
7346
7499
  return "outline";
7500
+ // Grey for on-track
7347
7501
  case "delayed":
7348
7502
  return "secondary";
7349
7503
  case "critical":
@@ -7352,19 +7506,24 @@ function getStatusBadgeVariant(status) {
7352
7506
  return "outline";
7353
7507
  }
7354
7508
  }
7355
- function getStatusBadgeClasses(status) {
7509
+ function getStatusBadgeClasses(status, isComplete) {
7510
+ if (isComplete) {
7511
+ return "border-green-500 text-green-600 bg-green-50 dark:bg-green-950/50";
7512
+ }
7356
7513
  switch (status) {
7357
7514
  case "on-time":
7358
- return "border-green-500 text-green-600 bg-green-50 dark:bg-green-950/50";
7515
+ return "border-muted-foreground/50 text-muted-foreground bg-muted/50";
7516
+ // Grey for on-track
7359
7517
  case "delayed":
7360
7518
  return "border-amber-500 text-amber-600 bg-amber-50 dark:bg-amber-950/50";
7361
7519
  case "critical":
7362
7520
  return "";
7363
7521
  default:
7364
- return "";
7522
+ return "border-muted-foreground/50 text-muted-foreground";
7365
7523
  }
7366
7524
  }
7367
- function getStatusLabel(status) {
7525
+ function getStatusLabel(status, isComplete) {
7526
+ if (isComplete) return "Complete";
7368
7527
  switch (status) {
7369
7528
  case "on-time":
7370
7529
  return "On Track";
@@ -7378,10 +7537,12 @@ function getStatusLabel(status) {
7378
7537
  return status;
7379
7538
  }
7380
7539
  }
7381
- function getProgressVariant(status) {
7540
+ function getProgressVariant(status, isComplete) {
7541
+ if (isComplete) return "success";
7382
7542
  switch (status) {
7383
7543
  case "on-time":
7384
- return "success";
7544
+ return "default";
7545
+ // Grey/default for on-track
7385
7546
  case "delayed":
7386
7547
  return "warning";
7387
7548
  case "critical":
@@ -7424,10 +7585,10 @@ function DeliveryCommentPopover({
7424
7585
  onAddComment,
7425
7586
  deliveryLabel
7426
7587
  }) {
7427
- const [open, setOpen] = React27__namespace.useState(false);
7428
- const [newCommentText, setNewCommentText] = React27__namespace.useState("");
7429
- const [viewCommentsOpen, setViewCommentsOpen] = React27__namespace.useState(true);
7430
- const [showAddForm, setShowAddForm] = React27__namespace.useState(false);
7588
+ const [open, setOpen] = React29__namespace.useState(false);
7589
+ const [newCommentText, setNewCommentText] = React29__namespace.useState("");
7590
+ const [viewCommentsOpen, setViewCommentsOpen] = React29__namespace.useState(true);
7591
+ const [showAddForm, setShowAddForm] = React29__namespace.useState(false);
7431
7592
  const handleSubmit = () => {
7432
7593
  if (newCommentText.trim() && onAddComment) {
7433
7594
  onAddComment(newCommentText.trim());
@@ -7454,8 +7615,8 @@ function DeliveryCommentPopover({
7454
7615
  minute: "2-digit"
7455
7616
  }).format(date);
7456
7617
  };
7457
- const prevOpenRef = React27__namespace.useRef(open);
7458
- React27__namespace.useEffect(() => {
7618
+ const prevOpenRef = React29__namespace.useRef(open);
7619
+ React29__namespace.useEffect(() => {
7459
7620
  const wasOpen = prevOpenRef.current;
7460
7621
  prevOpenRef.current = open;
7461
7622
  if (wasOpen && !open) {
@@ -7567,8 +7728,8 @@ function ProductionCommentSection({
7567
7728
  comments = [],
7568
7729
  onAddComment
7569
7730
  }) {
7570
- const [showAddForm, setShowAddForm] = React27__namespace.useState(false);
7571
- const [newComment, setNewComment] = React27__namespace.useState("");
7731
+ const [showAddForm, setShowAddForm] = React29__namespace.useState(false);
7732
+ const [newComment, setNewComment] = React29__namespace.useState("");
7572
7733
  const handleSubmit = () => {
7573
7734
  if (newComment.trim() && onAddComment) {
7574
7735
  onAddComment(newComment.trim());
@@ -7666,6 +7827,20 @@ function DeliveryListItem({
7666
7827
  onClick
7667
7828
  }) {
7668
7829
  const hasComments = (delivery.comments?.length ?? 0) > 0;
7830
+ const isComplete = (delivery.progress ?? 0) >= 100;
7831
+ const getIconStyles = () => {
7832
+ if (delivery.status === "critical") {
7833
+ return { bg: "bg-red-100 dark:bg-red-950/50", icon: "text-red-600 dark:text-red-400" };
7834
+ }
7835
+ if (delivery.status === "delayed") {
7836
+ return { bg: "bg-amber-100 dark:bg-amber-950/50", icon: "text-amber-600 dark:text-amber-400" };
7837
+ }
7838
+ if (isComplete) {
7839
+ return { bg: "bg-green-100 dark:bg-green-950/50", icon: "text-green-600 dark:text-green-400" };
7840
+ }
7841
+ return { bg: "bg-muted", icon: "text-muted-foreground" };
7842
+ };
7843
+ const iconStyles = getIconStyles();
7669
7844
  return /* @__PURE__ */ jsxRuntime.jsxs(
7670
7845
  "button",
7671
7846
  {
@@ -7679,15 +7854,8 @@ function DeliveryListItem({
7679
7854
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
7680
7855
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
7681
7856
  "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
- ) }) }),
7857
+ iconStyles.bg
7858
+ ), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: cn("h-4 w-4", iconStyles.icon) }) }),
7691
7859
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
7692
7860
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
7693
7861
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: delivery.label || `Delivery ${index + 1}` }),
@@ -7706,9 +7874,9 @@ function DeliveryListItem({
7706
7874
  /* @__PURE__ */ jsxRuntime.jsx(
7707
7875
  Badge,
7708
7876
  {
7709
- variant: getStatusBadgeVariant(delivery.status),
7710
- className: cn("text-xs", getStatusBadgeClasses(delivery.status)),
7711
- children: getStatusLabel(delivery.status)
7877
+ variant: getStatusBadgeVariant(delivery.status, isComplete),
7878
+ className: cn("text-xs", getStatusBadgeClasses(delivery.status, isComplete)),
7879
+ children: getStatusLabel(delivery.status, isComplete)
7712
7880
  }
7713
7881
  ),
7714
7882
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4 text-muted-foreground" })
@@ -7724,7 +7892,7 @@ function DeliveryDetailsView({
7724
7892
  onAddComment
7725
7893
  }) {
7726
7894
  const elements = delivery.elements ?? [];
7727
- const categorizedElements = React27__namespace.useMemo(() => {
7895
+ const categorizedElements = React29__namespace.useMemo(() => {
7728
7896
  const sent = [];
7729
7897
  const notSent = [];
7730
7898
  const moved = [];
@@ -7782,9 +7950,9 @@ function DeliveryDetailsView({
7782
7950
  /* @__PURE__ */ jsxRuntime.jsx(
7783
7951
  Badge,
7784
7952
  {
7785
- variant: getStatusBadgeVariant(delivery.status),
7786
- className: cn("text-xs", getStatusBadgeClasses(delivery.status)),
7787
- children: getStatusLabel(delivery.status)
7953
+ variant: getStatusBadgeVariant(delivery.status, sentCount === totalCount && totalCount > 0),
7954
+ className: cn("text-xs", getStatusBadgeClasses(delivery.status, sentCount === totalCount && totalCount > 0)),
7955
+ children: getStatusLabel(delivery.status, sentCount === totalCount && totalCount > 0)
7788
7956
  }
7789
7957
  )
7790
7958
  ] })
@@ -7957,9 +8125,9 @@ function MainView({
7957
8125
  /* @__PURE__ */ jsxRuntime.jsx(
7958
8126
  Badge,
7959
8127
  {
7960
- variant: getStatusBadgeVariant(productionStatus),
7961
- className: cn("text-xs ml-auto", getStatusBadgeClasses(productionStatus)),
7962
- children: getStatusLabel(productionStatus)
8128
+ variant: getStatusBadgeVariant(productionStatus, isComplete),
8129
+ className: cn("text-xs ml-auto", getStatusBadgeClasses(productionStatus, isComplete)),
8130
+ children: getStatusLabel(productionStatus, isComplete)
7963
8131
  }
7964
8132
  )
7965
8133
  ] }),
@@ -7970,7 +8138,7 @@ function MainView({
7970
8138
  value: productionProgress,
7971
8139
  size: 100,
7972
8140
  strokeWidth: 10,
7973
- variant: getProgressVariant(productionStatus),
8141
+ variant: getProgressVariant(productionStatus, isComplete),
7974
8142
  showCheckmark: isComplete,
7975
8143
  children: isComplete ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center", children: [
7976
8144
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-6 w-6 text-green-600" }),
@@ -8092,15 +8260,15 @@ function WeekDetailDialog({
8092
8260
  }) {
8093
8261
  const production = data?.production;
8094
8262
  const initialProduced = production?.produced ?? 0;
8095
- const [producedValue, setProducedValue] = React27__namespace.useState(initialProduced.toString());
8096
- const [hasChanges, setHasChanges] = React27__namespace.useState(false);
8097
- const [selectedDelivery, setSelectedDelivery] = React27__namespace.useState(null);
8098
- React27__namespace.useEffect(() => {
8263
+ const [producedValue, setProducedValue] = React29__namespace.useState(initialProduced.toString());
8264
+ const [hasChanges, setHasChanges] = React29__namespace.useState(false);
8265
+ const [selectedDelivery, setSelectedDelivery] = React29__namespace.useState(null);
8266
+ React29__namespace.useEffect(() => {
8099
8267
  const newProduced = data?.production?.produced ?? 0;
8100
8268
  setProducedValue(newProduced.toString());
8101
8269
  setHasChanges(false);
8102
8270
  }, [data]);
8103
- React27__namespace.useEffect(() => {
8271
+ React29__namespace.useEffect(() => {
8104
8272
  if (!open) {
8105
8273
  setSelectedDelivery(null);
8106
8274
  }
@@ -8151,59 +8319,1074 @@ function WeekDetailDialog({
8151
8319
  }
8152
8320
  ) }) });
8153
8321
  }
8154
- function RowHeaderCell({
8155
- className,
8156
- data,
8157
- showProgress = true,
8158
- ...props
8322
+ function getStatusBadgeVariant2(status, isComplete) {
8323
+ if (isComplete) return "outline";
8324
+ switch (status) {
8325
+ case "on-time":
8326
+ return "outline";
8327
+ // Grey for on-track
8328
+ case "delayed":
8329
+ return "secondary";
8330
+ case "critical":
8331
+ return "destructive";
8332
+ default:
8333
+ return "outline";
8334
+ }
8335
+ }
8336
+ function getStatusBadgeClasses2(status, isComplete) {
8337
+ if (isComplete) {
8338
+ return "border-green-500 text-green-600 bg-green-50 dark:bg-green-950/50";
8339
+ }
8340
+ switch (status) {
8341
+ case "on-time":
8342
+ return "border-muted-foreground/50 text-muted-foreground bg-muted/50";
8343
+ // Grey for on-track
8344
+ case "delayed":
8345
+ return "border-amber-500 text-amber-600 bg-amber-50 dark:bg-amber-950/50";
8346
+ case "critical":
8347
+ return "";
8348
+ default:
8349
+ return "border-muted-foreground/50 text-muted-foreground";
8350
+ }
8351
+ }
8352
+ function getStatusLabel2(status, isComplete) {
8353
+ if (isComplete) return "Complete";
8354
+ switch (status) {
8355
+ case "on-time":
8356
+ return "On Track";
8357
+ case "delayed":
8358
+ return "At Risk";
8359
+ case "critical":
8360
+ return "Critical";
8361
+ case "pending":
8362
+ return "Pending";
8363
+ default:
8364
+ return status;
8365
+ }
8366
+ }
8367
+ function getShipmentStatusBadgeClasses2(status) {
8368
+ switch (status) {
8369
+ case "sent":
8370
+ return "border-green-500 text-green-600 bg-green-50 dark:bg-green-950/50";
8371
+ case "not-sent":
8372
+ return "border-muted-foreground/50 text-muted-foreground bg-muted/50";
8373
+ case "moved":
8374
+ return "border-blue-500 text-blue-600 bg-blue-50 dark:bg-blue-950/50";
8375
+ case "addon":
8376
+ return "border-purple-500 text-purple-600 bg-purple-50 dark:bg-purple-950/50";
8377
+ case "planned":
8378
+ default:
8379
+ return "border-muted-foreground/50 text-muted-foreground";
8380
+ }
8381
+ }
8382
+ function getShipmentStatusRowBg2(status) {
8383
+ switch (status) {
8384
+ case "sent":
8385
+ return "bg-green-50/30 dark:bg-green-950/10";
8386
+ case "not-sent":
8387
+ return "bg-muted/30";
8388
+ case "moved":
8389
+ return "bg-blue-50/30 dark:bg-blue-950/10";
8390
+ case "addon":
8391
+ return "bg-purple-50/30 dark:bg-purple-950/10";
8392
+ default:
8393
+ return "";
8394
+ }
8395
+ }
8396
+ function ElementProductionDialog({
8397
+ open,
8398
+ onOpenChange,
8399
+ elements,
8400
+ onSave
8159
8401
  }) {
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,
8402
+ const [searchQuery, setSearchQuery] = React29__namespace.useState("");
8403
+ const [selectedIds, setSelectedIds] = React29__namespace.useState(
8404
+ new Set(elements.filter((e) => e.isProduced).map((e) => e.id))
8405
+ );
8406
+ React29__namespace.useEffect(() => {
8407
+ if (open) {
8408
+ setSelectedIds(new Set(elements.filter((e) => e.isProduced).map((e) => e.id)));
8409
+ setSearchQuery("");
8410
+ }
8411
+ }, [open, elements]);
8412
+ const filteredElements = React29__namespace.useMemo(() => {
8413
+ if (!searchQuery.trim()) return elements;
8414
+ const query = searchQuery.toLowerCase();
8415
+ return elements.filter(
8416
+ (e) => e.name.toLowerCase().includes(query) || e.prefix?.toLowerCase().includes(query) || e.type?.toLowerCase().includes(query)
8417
+ );
8418
+ }, [elements, searchQuery]);
8419
+ React29__namespace.useMemo(() => {
8420
+ const prefixes = /* @__PURE__ */ new Set();
8421
+ elements.forEach((e) => {
8422
+ if (e.prefix) prefixes.add(e.prefix);
8423
+ });
8424
+ return Array.from(prefixes).sort();
8425
+ }, [elements]);
8426
+ const toggleElement = (id) => {
8427
+ setSelectedIds((prev) => {
8428
+ const next = new Set(prev);
8429
+ if (next.has(id)) {
8430
+ next.delete(id);
8431
+ } else {
8432
+ next.add(id);
8433
+ }
8434
+ return next;
8435
+ });
8436
+ };
8437
+ const selectAll = () => {
8438
+ setSelectedIds(new Set(filteredElements.map((e) => e.id)));
8439
+ };
8440
+ const deselectAll = () => {
8441
+ setSelectedIds(/* @__PURE__ */ new Set());
8442
+ };
8443
+ const handleSave = () => {
8444
+ onSave(Array.from(selectedIds));
8445
+ onOpenChange(false);
8446
+ };
8447
+ const selectedCount = selectedIds.size;
8448
+ const totalCount = elements.length;
8449
+ const selectedWeight = elements.filter((e) => selectedIds.has(e.id)).reduce((sum, e) => sum + (e.weight ?? 0), 0);
8450
+ const totalWeight = elements.reduce((sum, e) => sum + (e.weight ?? 0), 0);
8451
+ 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: [
8452
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { className: "w-full p-6 pb-0 shrink-0", children: [
8453
+ /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Enter production progress" }),
8454
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground", children: [
8455
+ "Mark elements as produced (",
8456
+ selectedCount,
8457
+ " / ",
8458
+ totalCount,
8459
+ " selected)"
8460
+ ] })
8461
+ ] }),
8462
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-h-0 flex flex-col p-6 pt-4 gap-4 overflow-hidden w-fit", children: [
8463
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col sm:flex-row gap-3 shrink-0", children: [
8464
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1", children: [
8465
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" }),
8466
+ /* @__PURE__ */ jsxRuntime.jsx(
8467
+ Input,
8178
8468
  {
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
- ]
8469
+ placeholder: "Search elements...",
8470
+ value: searchQuery,
8471
+ onChange: (e) => setSearchQuery(e.target.value),
8472
+ className: "pl-9 w-full"
8185
8473
  }
8186
8474
  )
8187
8475
  ] }),
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",
8476
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 shrink-0", children: [
8477
+ /* @__PURE__ */ jsxRuntime.jsx(
8478
+ Button,
8191
8479
  {
8192
- className: "h-full bg-primary rounded-full transition-all",
8193
- style: { width: `${progressPercent}%` }
8480
+ variant: "outline",
8481
+ size: "sm",
8482
+ onClick: selectAll,
8483
+ children: "Select all"
8484
+ }
8485
+ ),
8486
+ /* @__PURE__ */ jsxRuntime.jsx(
8487
+ Button,
8488
+ {
8489
+ variant: "outline",
8490
+ size: "sm",
8491
+ onClick: deselectAll,
8492
+ children: "Deselect all"
8493
+ }
8494
+ )
8495
+ ] })
8496
+ ] }),
8497
+ /* @__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: [
8498
+ /* @__PURE__ */ jsxRuntime.jsx(TableHeader, { className: "sticky top-0 z-10", children: /* @__PURE__ */ jsxRuntime.jsxs(TableRow, { className: "bg-muted/50 hover:bg-muted/50", children: [
8499
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "w-[44px] bg-muted/50", children: /* @__PURE__ */ jsxRuntime.jsx(
8500
+ Checkbox,
8501
+ {
8502
+ checked: selectedIds.size === filteredElements.length && filteredElements.length > 0,
8503
+ onCheckedChange: (checked) => {
8504
+ if (checked) {
8505
+ selectAll();
8506
+ } else {
8507
+ deselectAll();
8508
+ }
8509
+ },
8510
+ "aria-label": "Select all elements"
8194
8511
  }
8195
8512
  ) }),
8196
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] font-medium text-primary", children: [
8197
- data.totalBooked.toLocaleString(),
8513
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "bg-muted/50", children: "Element" }),
8514
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "bg-muted/50 w-[80px]", children: "Type" }),
8515
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "bg-muted/50 text-right w-[90px]", children: "Weight" }),
8516
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "bg-muted/50 text-right w-[80px]", children: "Size" }),
8517
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "bg-muted/50 text-center w-[100px]", children: "Status" })
8518
+ ] }) }),
8519
+ /* @__PURE__ */ jsxRuntime.jsx(TableBody, { children: filteredElements.map((element) => {
8520
+ const isSelected = selectedIds.has(element.id);
8521
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8522
+ TableRow,
8523
+ {
8524
+ className: cn(
8525
+ "cursor-pointer transition-colors",
8526
+ isSelected && "bg-green-50/50 dark:bg-green-950/20"
8527
+ ),
8528
+ onClick: () => toggleElement(element.id),
8529
+ children: [
8530
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { className: "w-[44px]", children: /* @__PURE__ */ jsxRuntime.jsx(
8531
+ Checkbox,
8532
+ {
8533
+ checked: isSelected,
8534
+ onCheckedChange: () => toggleElement(element.id),
8535
+ onClick: (e) => e.stopPropagation(),
8536
+ "aria-label": `Mark ${element.name} as produced`
8537
+ }
8538
+ ) }),
8539
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
8540
+ element.prefix && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "outline", className: "text-[10px] h-5 shrink-0 font-mono", children: element.prefix }),
8541
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: element.name })
8542
+ ] }) }),
8543
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { className: "text-muted-foreground w-[80px]", children: element.type || "\u2014" }),
8544
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { className: "text-right tabular-nums text-muted-foreground w-[90px]", children: element.weight != null ? `${element.weight.toLocaleString()} kg` : "\u2014" }),
8545
+ /* @__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" }),
8546
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { className: "text-center w-[100px]", children: isSelected ? /* @__PURE__ */ jsxRuntime.jsxs(
8547
+ Badge,
8548
+ {
8549
+ variant: "outline",
8550
+ className: "border-green-500 text-green-600 bg-green-50 dark:bg-green-950/50",
8551
+ children: [
8552
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3 w-3 mr-1" }),
8553
+ "Produced"
8554
+ ]
8555
+ }
8556
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
8557
+ Badge,
8558
+ {
8559
+ variant: "outline",
8560
+ className: "border-muted-foreground/50 text-muted-foreground",
8561
+ children: "Not produced"
8562
+ }
8563
+ ) })
8564
+ ]
8565
+ },
8566
+ element.id
8567
+ );
8568
+ }) })
8569
+ ] }) }) : /* @__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: [
8570
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Package, { className: "h-10 w-10 mx-auto mb-3 opacity-50" }),
8571
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium", children: "No elements found" }),
8572
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground mt-1", children: "Try adjusting your search" })
8573
+ ] }) }) })
8574
+ ] }),
8575
+ /* @__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: [
8576
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 text-sm text-muted-foreground", children: [
8577
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
8578
+ selectedCount,
8579
+ " / ",
8580
+ totalCount,
8581
+ " elements"
8582
+ ] }),
8583
+ totalWeight > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
8584
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u2022" }),
8585
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "tabular-nums font-medium text-foreground", children: [
8586
+ (selectedWeight / 1e3).toLocaleString(void 0, { maximumFractionDigits: 1 }),
8198
8587
  " / ",
8199
- data.totalRequired.toLocaleString(),
8200
- " Booked"
8588
+ (totalWeight / 1e3).toLocaleString(void 0, { maximumFractionDigits: 1 }),
8589
+ " ton"
8201
8590
  ] })
8202
8591
  ] })
8203
- ]
8204
- }
8205
- );
8206
- }
8592
+ ] }),
8593
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
8594
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), children: "Cancel" }),
8595
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handleSave, children: "Save progress" })
8596
+ ] })
8597
+ ] }) })
8598
+ ] }) });
8599
+ }
8600
+ function DeliveryCommentPopover2({
8601
+ comments = [],
8602
+ onAddComment,
8603
+ deliveryLabel
8604
+ }) {
8605
+ const [open, setOpen] = React29__namespace.useState(false);
8606
+ const [newCommentText, setNewCommentText] = React29__namespace.useState("");
8607
+ const [viewCommentsOpen, setViewCommentsOpen] = React29__namespace.useState(true);
8608
+ const [showAddForm, setShowAddForm] = React29__namespace.useState(false);
8609
+ const handleSubmit = () => {
8610
+ if (newCommentText.trim() && onAddComment) {
8611
+ onAddComment(newCommentText.trim());
8612
+ setNewCommentText("");
8613
+ setShowAddForm(false);
8614
+ setViewCommentsOpen(true);
8615
+ }
8616
+ };
8617
+ const handleKeyDown = (e) => {
8618
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
8619
+ e.preventDefault();
8620
+ handleSubmit();
8621
+ }
8622
+ if (e.key === "Escape") {
8623
+ setShowAddForm(false);
8624
+ setNewCommentText("");
8625
+ }
8626
+ };
8627
+ const formatDate3 = (date) => {
8628
+ return new Intl.DateTimeFormat("en-US", {
8629
+ month: "short",
8630
+ day: "numeric",
8631
+ hour: "numeric",
8632
+ minute: "2-digit"
8633
+ }).format(date);
8634
+ };
8635
+ React29__namespace.useEffect(() => {
8636
+ if (!open) {
8637
+ setShowAddForm(false);
8638
+ setNewCommentText("");
8639
+ }
8640
+ }, [open]);
8641
+ return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange: setOpen, children: [
8642
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(CommentButton, { size: "sm", commentCount: comments.length }) }),
8643
+ /* @__PURE__ */ jsxRuntime.jsxs(
8644
+ PopoverContent,
8645
+ {
8646
+ className: "w-80 p-0 z-[100]",
8647
+ align: "end",
8648
+ sideOffset: 8,
8649
+ collisionPadding: 16,
8650
+ children: [
8651
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 py-3 border-b border-border", children: [
8652
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-sm font-semibold", children: "Comments" }),
8653
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: deliveryLabel })
8654
+ ] }),
8655
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-2 space-y-2 h-fit overflow-y-auto", children: [
8656
+ /* @__PURE__ */ jsxRuntime.jsxs(Collapsible, { open: viewCommentsOpen, onOpenChange: setViewCommentsOpen, children: [
8657
+ /* @__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: [
8658
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs font-medium", children: [
8659
+ "Comments ",
8660
+ comments.length > 0 && `(${comments.length})`
8661
+ ] }),
8662
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: cn(
8663
+ "h-4 w-4 transition-transform duration-200",
8664
+ viewCommentsOpen && "rotate-180"
8665
+ ) })
8666
+ ] }) }),
8667
+ /* @__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: [
8668
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
8669
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium", children: comment.author }),
8670
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: formatDate3(comment.createdAt) })
8671
+ ] }),
8672
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-foreground", children: comment.text })
8673
+ ] }, comment.id)) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground text-center py-2", children: "No comments yet" }) })
8674
+ ] }),
8675
+ /* @__PURE__ */ jsxRuntime.jsx(Separator, { className: "my-2" }),
8676
+ !showAddForm ? /* @__PURE__ */ jsxRuntime.jsxs(
8677
+ Button,
8678
+ {
8679
+ variant: "outline",
8680
+ size: "sm",
8681
+ className: "w-full justify-center gap-2 h-8",
8682
+ onClick: () => setShowAddForm(true),
8683
+ children: [
8684
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3.5 w-3.5" }),
8685
+ "Add comment"
8686
+ ]
8687
+ }
8688
+ ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(
8689
+ "space-y-3 p-3 rounded-lg border border-border bg-muted/30",
8690
+ "animate-in fade-in-0 slide-in-from-top-2 duration-200"
8691
+ ), children: [
8692
+ /* @__PURE__ */ jsxRuntime.jsx(
8693
+ Textarea,
8694
+ {
8695
+ placeholder: "Type your comment...",
8696
+ value: newCommentText,
8697
+ onChange: (e) => setNewCommentText(e.target.value),
8698
+ onKeyDown: handleKeyDown,
8699
+ className: "min-h-[80px] text-sm resize-none",
8700
+ autoFocus: true
8701
+ }
8702
+ ),
8703
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
8704
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: "\u2318+Enter to send \xB7 Esc to cancel" }),
8705
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
8706
+ /* @__PURE__ */ jsxRuntime.jsx(
8707
+ Button,
8708
+ {
8709
+ variant: "ghost",
8710
+ size: "sm",
8711
+ className: "h-7",
8712
+ onClick: () => {
8713
+ setShowAddForm(false);
8714
+ setNewCommentText("");
8715
+ },
8716
+ children: "Cancel"
8717
+ }
8718
+ ),
8719
+ /* @__PURE__ */ jsxRuntime.jsxs(
8720
+ Button,
8721
+ {
8722
+ size: "sm",
8723
+ className: "h-7 gap-1",
8724
+ onClick: handleSubmit,
8725
+ disabled: !newCommentText.trim(),
8726
+ children: [
8727
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "h-3 w-3" }),
8728
+ "Save"
8729
+ ]
8730
+ }
8731
+ )
8732
+ ] })
8733
+ ] })
8734
+ ] })
8735
+ ] })
8736
+ ]
8737
+ }
8738
+ )
8739
+ ] });
8740
+ }
8741
+ function ProductionCommentSection2({
8742
+ comments = [],
8743
+ onAddComment
8744
+ }) {
8745
+ const [showAddForm, setShowAddForm] = React29__namespace.useState(false);
8746
+ const [newComment, setNewComment] = React29__namespace.useState("");
8747
+ const handleSubmit = () => {
8748
+ if (newComment.trim() && onAddComment) {
8749
+ onAddComment(newComment.trim());
8750
+ setNewComment("");
8751
+ setShowAddForm(false);
8752
+ }
8753
+ };
8754
+ const handleKeyDown = (e) => {
8755
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
8756
+ e.preventDefault();
8757
+ handleSubmit();
8758
+ }
8759
+ if (e.key === "Escape") {
8760
+ setShowAddForm(false);
8761
+ setNewComment("");
8762
+ }
8763
+ };
8764
+ const formatDate3 = (date) => {
8765
+ return new Intl.DateTimeFormat("en-US", {
8766
+ month: "short",
8767
+ day: "numeric",
8768
+ hour: "numeric",
8769
+ minute: "2-digit"
8770
+ }).format(date);
8771
+ };
8772
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
8773
+ 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: [
8774
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
8775
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium", children: comment.author }),
8776
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: formatDate3(comment.createdAt) })
8777
+ ] }),
8778
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-foreground", children: comment.text })
8779
+ ] }, comment.id)) }),
8780
+ !showAddForm ? /* @__PURE__ */ jsxRuntime.jsxs(
8781
+ Button,
8782
+ {
8783
+ variant: "ghost",
8784
+ size: "sm",
8785
+ className: "w-full justify-start gap-2 h-8 text-muted-foreground",
8786
+ onClick: () => setShowAddForm(true),
8787
+ children: [
8788
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "h-3.5 w-3.5" }),
8789
+ comments.length > 0 ? "Add another comment" : "Add a comment..."
8790
+ ]
8791
+ }
8792
+ ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 animate-in fade-in-0 slide-in-from-top-2 duration-200", children: [
8793
+ /* @__PURE__ */ jsxRuntime.jsx(
8794
+ Textarea,
8795
+ {
8796
+ placeholder: "Add a comment...",
8797
+ value: newComment,
8798
+ onChange: (e) => setNewComment(e.target.value),
8799
+ onKeyDown: handleKeyDown,
8800
+ className: "min-h-[60px] text-sm resize-none",
8801
+ autoFocus: true
8802
+ }
8803
+ ),
8804
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
8805
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: "\u2318+Enter to send" }),
8806
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
8807
+ /* @__PURE__ */ jsxRuntime.jsx(
8808
+ Button,
8809
+ {
8810
+ variant: "ghost",
8811
+ size: "sm",
8812
+ className: "h-7",
8813
+ onClick: () => {
8814
+ setShowAddForm(false);
8815
+ setNewComment("");
8816
+ },
8817
+ children: "Cancel"
8818
+ }
8819
+ ),
8820
+ /* @__PURE__ */ jsxRuntime.jsxs(
8821
+ Button,
8822
+ {
8823
+ size: "sm",
8824
+ className: "h-7 gap-1",
8825
+ onClick: handleSubmit,
8826
+ disabled: !newComment.trim(),
8827
+ children: [
8828
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "h-3 w-3" }),
8829
+ "Save"
8830
+ ]
8831
+ }
8832
+ )
8833
+ ] })
8834
+ ] })
8835
+ ] })
8836
+ ] });
8837
+ }
8838
+ function DeliveryListItem2({
8839
+ delivery,
8840
+ index,
8841
+ onClick
8842
+ }) {
8843
+ const hasComments = (delivery.comments?.length ?? 0) > 0;
8844
+ const isComplete = (delivery.progress ?? 0) >= 100;
8845
+ const getIconStyles = () => {
8846
+ if (delivery.status === "critical") {
8847
+ return { bg: "bg-red-100 dark:bg-red-950/50", icon: "text-red-600 dark:text-red-400" };
8848
+ }
8849
+ if (delivery.status === "delayed") {
8850
+ return { bg: "bg-amber-100 dark:bg-amber-950/50", icon: "text-amber-600 dark:text-amber-400" };
8851
+ }
8852
+ if (isComplete) {
8853
+ return { bg: "bg-green-100 dark:bg-green-950/50", icon: "text-green-600 dark:text-green-400" };
8854
+ }
8855
+ return { bg: "bg-muted", icon: "text-muted-foreground" };
8856
+ };
8857
+ const iconStyles = getIconStyles();
8858
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8859
+ "button",
8860
+ {
8861
+ onClick,
8862
+ className: cn(
8863
+ "w-full flex items-center justify-between p-3 rounded-lg",
8864
+ "bg-card border hover:bg-muted/50 transition-colors cursor-pointer",
8865
+ "text-left"
8866
+ ),
8867
+ children: [
8868
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
8869
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
8870
+ "flex items-center justify-center h-8 w-8 rounded-lg",
8871
+ iconStyles.bg
8872
+ ), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: cn("h-4 w-4", iconStyles.icon) }) }),
8873
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
8874
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
8875
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: delivery.label || `Delivery ${index + 1}` }),
8876
+ hasComments && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
8877
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "h-3 w-3 text-muted-foreground" }),
8878
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -top-0.5 -right-0.5 h-1.5 w-1.5 rounded-full bg-primary" })
8879
+ ] })
8880
+ ] }),
8881
+ delivery.destination && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-muted-foreground", children: [
8882
+ "\u2192 ",
8883
+ delivery.destination
8884
+ ] })
8885
+ ] })
8886
+ ] }),
8887
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
8888
+ /* @__PURE__ */ jsxRuntime.jsx(
8889
+ Badge,
8890
+ {
8891
+ variant: getStatusBadgeVariant2(delivery.status, isComplete),
8892
+ className: cn("text-xs", getStatusBadgeClasses2(delivery.status, isComplete)),
8893
+ children: getStatusLabel2(delivery.status, isComplete)
8894
+ }
8895
+ ),
8896
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4 text-muted-foreground" })
8897
+ ] })
8898
+ ]
8899
+ }
8900
+ );
8901
+ }
8902
+ function DeliveryDetailsView2({
8903
+ delivery,
8904
+ week,
8905
+ onBack,
8906
+ onAddComment
8907
+ }) {
8908
+ const elements = delivery.elements ?? [];
8909
+ const categorizedElements = React29__namespace.useMemo(() => {
8910
+ const sent = [];
8911
+ const notSent = [];
8912
+ const moved = [];
8913
+ const addons = [];
8914
+ elements.forEach((element) => {
8915
+ const status = getElementShipmentStatus(element, delivery.id);
8916
+ switch (status) {
8917
+ case "sent":
8918
+ sent.push(element);
8919
+ break;
8920
+ case "not-sent":
8921
+ notSent.push(element);
8922
+ break;
8923
+ case "moved":
8924
+ moved.push(element);
8925
+ break;
8926
+ case "addon":
8927
+ addons.push(element);
8928
+ break;
8929
+ default:
8930
+ notSent.push(element);
8931
+ }
8932
+ });
8933
+ return { sent, notSent, moved, addons };
8934
+ }, [elements, delivery.id]);
8935
+ const totalCount = elements.length;
8936
+ const sentCount = categorizedElements.sent.length;
8937
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col h-full animate-in slide-in-from-right-4 duration-200", children: [
8938
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2 px-4 py-3 border-b", children: /* @__PURE__ */ jsxRuntime.jsxs(
8939
+ Button,
8940
+ {
8941
+ variant: "ghost",
8942
+ size: "sm",
8943
+ className: "gap-1 -ml-2",
8944
+ onClick: onBack,
8945
+ children: [
8946
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "h-4 w-4" }),
8947
+ "Back"
8948
+ ]
8949
+ }
8950
+ ) }),
8951
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 py-4 space-y-2", children: [
8952
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
8953
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold", children: delivery.label || "Delivery Details" }),
8954
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
8955
+ /* @__PURE__ */ jsxRuntime.jsx(
8956
+ DeliveryCommentPopover2,
8957
+ {
8958
+ comments: delivery.comments,
8959
+ onAddComment,
8960
+ deliveryLabel: delivery.label || "Delivery"
8961
+ }
8962
+ ),
8963
+ /* @__PURE__ */ jsxRuntime.jsx(
8964
+ Badge,
8965
+ {
8966
+ variant: getStatusBadgeVariant2(delivery.status, sentCount === totalCount && totalCount > 0),
8967
+ className: cn("text-xs", getStatusBadgeClasses2(delivery.status, sentCount === totalCount && totalCount > 0)),
8968
+ children: getStatusLabel2(delivery.status, sentCount === totalCount && totalCount > 0)
8969
+ }
8970
+ )
8971
+ ] })
8972
+ ] }),
8973
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 text-sm text-muted-foreground", children: [
8974
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
8975
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Calendar, { className: "h-3.5 w-3.5" }),
8976
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
8977
+ week.label,
8978
+ " \u2022 ",
8979
+ week.dateRange
8980
+ ] })
8981
+ ] }),
8982
+ delivery.destination && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
8983
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: "h-3.5 w-3.5" }),
8984
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
8985
+ "\u2192 ",
8986
+ delivery.destination
8987
+ ] })
8988
+ ] })
8989
+ ] })
8990
+ ] }),
8991
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "flex-1 px-4 pb-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
8992
+ totalCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg bg-muted/50 p-4 space-y-3", children: [
8993
+ /* @__PURE__ */ jsxRuntime.jsx(
8994
+ StatusProgress,
8995
+ {
8996
+ value: totalCount > 0 ? sentCount / totalCount * 100 : 0,
8997
+ currentCount: sentCount,
8998
+ totalCount,
8999
+ unitLabel: "shipped",
9000
+ showLabel: true,
9001
+ showCheckmark: true,
9002
+ size: "md"
9003
+ }
9004
+ ),
9005
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 flex-wrap", children: [
9006
+ categorizedElements.sent.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [
9007
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircle2, { className: "h-3 w-3 text-green-600" }),
9008
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-green-700 dark:text-green-300", children: [
9009
+ categorizedElements.sent.length,
9010
+ " Sent"
9011
+ ] })
9012
+ ] }),
9013
+ categorizedElements.notSent.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [
9014
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XCircle, { className: "h-3 w-3 text-muted-foreground" }),
9015
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground", children: [
9016
+ categorizedElements.notSent.length,
9017
+ " Missing"
9018
+ ] })
9019
+ ] }),
9020
+ categorizedElements.moved.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [
9021
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowRight, { className: "h-3 w-3 text-blue-600" }),
9022
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-blue-700 dark:text-blue-300", children: [
9023
+ categorizedElements.moved.length,
9024
+ " Moved"
9025
+ ] })
9026
+ ] }),
9027
+ categorizedElements.addons.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [
9028
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3 w-3 text-purple-600" }),
9029
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-purple-700 dark:text-purple-300", children: [
9030
+ categorizedElements.addons.length,
9031
+ " Add-on"
9032
+ ] })
9033
+ ] })
9034
+ ] })
9035
+ ] }),
9036
+ elements.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
9037
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "Elements" }),
9038
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(Table, { children: [
9039
+ /* @__PURE__ */ jsxRuntime.jsx(TableHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(TableRow, { className: "bg-sidebar hover:bg-sidebar", children: [
9040
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "font-semibold", children: "Prefix" }),
9041
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "font-semibold", children: "Type" }),
9042
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "font-semibold text-right", children: "Weight" }),
9043
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "font-semibold text-center", children: "Status" })
9044
+ ] }) }),
9045
+ /* @__PURE__ */ jsxRuntime.jsx(TableBody, { children: elements.map((element) => {
9046
+ const shipmentStatus = getElementShipmentStatus(element, delivery.id);
9047
+ const statusLabel = getShipmentStatusLabel(shipmentStatus);
9048
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9049
+ TableRow,
9050
+ {
9051
+ className: getShipmentStatusRowBg2(shipmentStatus),
9052
+ children: [
9053
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { className: "font-medium", children: element.prefix || "\u2014" }),
9054
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { children: element.type || element.name || "\u2014" }),
9055
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { className: "text-right tabular-nums", children: element.weight ? `${element.weight} ${element.weightUnit || "kg"}` : "\u2014" }),
9056
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-1", children: [
9057
+ /* @__PURE__ */ jsxRuntime.jsx(
9058
+ Badge,
9059
+ {
9060
+ variant: "outline",
9061
+ className: cn("text-[10px] h-5", getShipmentStatusBadgeClasses2(shipmentStatus)),
9062
+ children: statusLabel
9063
+ }
9064
+ ),
9065
+ shipmentStatus === "moved" && element.actualDeliveryLabel && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[9px] text-blue-600 dark:text-blue-400", children: [
9066
+ "\u2192 ",
9067
+ element.actualDeliveryLabel
9068
+ ] }),
9069
+ shipmentStatus === "addon" && element.originalDeliveryLabel && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[9px] text-purple-600 dark:text-purple-400", children: [
9070
+ "from ",
9071
+ element.originalDeliveryLabel
9072
+ ] })
9073
+ ] }) })
9074
+ ]
9075
+ },
9076
+ element.id
9077
+ );
9078
+ }) })
9079
+ ] }) })
9080
+ ] }),
9081
+ elements.length === 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-8 text-muted-foreground", children: [
9082
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Package, { className: "h-8 w-8 mx-auto mb-2 opacity-50" }),
9083
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm", children: "No elements in this delivery" })
9084
+ ] })
9085
+ ] }) })
9086
+ ] });
9087
+ }
9088
+ function MainView2({
9089
+ supplier,
9090
+ week,
9091
+ data,
9092
+ productionElements,
9093
+ previousProducedCount,
9094
+ onOpenProductionDialog,
9095
+ onSelectDelivery,
9096
+ onAddProductionComment
9097
+ }) {
9098
+ const production = data?.production;
9099
+ const producedCount = productionElements.filter((e) => e.isProduced).length;
9100
+ const totalCount = productionElements.length;
9101
+ const productionProgress = totalCount > 0 ? Math.round(producedCount / totalCount * 100) : 0;
9102
+ const isComplete = productionProgress >= 100;
9103
+ const hasProductionComments = (production?.comments?.length ?? 0) > 0;
9104
+ const showPreviousProgress = !isComplete && previousProducedCount !== void 0 && previousProducedCount !== producedCount;
9105
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "animate-in fade-in-0 duration-200", children: [
9106
+ /* @__PURE__ */ jsxRuntime.jsxs(SheetHeader, { className: "px-4 pt-4 pb-3 border-b", children: [
9107
+ /* @__PURE__ */ jsxRuntime.jsxs(SheetTitle, { className: "flex items-center gap-2", children: [
9108
+ supplier.name,
9109
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "secondary", className: "text-xs font-normal", children: supplier.badgeType })
9110
+ ] }),
9111
+ /* @__PURE__ */ jsxRuntime.jsxs(SheetDescription, { className: "flex items-center gap-2", children: [
9112
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Calendar, { className: "h-4 w-4" }),
9113
+ week.label,
9114
+ " \u2022 ",
9115
+ week.dateRange
9116
+ ] })
9117
+ ] }),
9118
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "flex-1 px-4 pb-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6 pt-4", children: [
9119
+ data.type !== "empty" && /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-4", children: [
9120
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
9121
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Factory, { className: "h-4 w-4 text-muted-foreground" }),
9122
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold", children: "Production" })
9123
+ ] }),
9124
+ totalCount > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
9125
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center py-4", children: [
9126
+ /* @__PURE__ */ jsxRuntime.jsx(
9127
+ CircularProgress,
9128
+ {
9129
+ value: productionProgress,
9130
+ size: 88,
9131
+ strokeWidth: 8,
9132
+ variant: productionProgress >= 100 ? "success" : productionProgress >= 50 ? "success" : productionProgress > 0 ? "warning" : "destructive",
9133
+ showCheckmark: true,
9134
+ children: productionProgress < 100 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-lg font-bold tabular-nums", children: [
9135
+ Math.round(productionProgress),
9136
+ "%"
9137
+ ] })
9138
+ }
9139
+ ),
9140
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 text-center", children: [
9141
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm font-semibold text-foreground", children: [
9142
+ producedCount,
9143
+ " / ",
9144
+ totalCount,
9145
+ " elements"
9146
+ ] }),
9147
+ showPreviousProgress && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-muted-foreground mt-1", children: [
9148
+ "Previously: ",
9149
+ previousProducedCount,
9150
+ " / ",
9151
+ totalCount
9152
+ ] })
9153
+ ] })
9154
+ ] }),
9155
+ /* @__PURE__ */ jsxRuntime.jsx(
9156
+ Button,
9157
+ {
9158
+ className: "w-full",
9159
+ onClick: onOpenProductionDialog,
9160
+ children: "Enter production progress"
9161
+ }
9162
+ )
9163
+ ] }) : (
9164
+ /* No elements - show placeholder with button still available */
9165
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
9166
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-6 text-muted-foreground bg-muted/30 rounded-lg", children: [
9167
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Package, { className: "h-8 w-8 mx-auto mb-2 opacity-50" }),
9168
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm", children: "No elements to track" })
9169
+ ] }),
9170
+ /* @__PURE__ */ jsxRuntime.jsx(
9171
+ Button,
9172
+ {
9173
+ className: "w-full",
9174
+ variant: "outline",
9175
+ onClick: onOpenProductionDialog,
9176
+ children: "Enter production progress"
9177
+ }
9178
+ )
9179
+ ] })
9180
+ ),
9181
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
9182
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
9183
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Comments" }),
9184
+ hasProductionComments && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] text-muted-foreground", children: [
9185
+ "(",
9186
+ production?.comments?.length,
9187
+ ")"
9188
+ ] })
9189
+ ] }),
9190
+ /* @__PURE__ */ jsxRuntime.jsx(
9191
+ ProductionCommentSection2,
9192
+ {
9193
+ comments: production?.comments,
9194
+ onAddComment: onAddProductionComment
9195
+ }
9196
+ )
9197
+ ] })
9198
+ ] }),
9199
+ data.deliveries && data.deliveries.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-4", children: [
9200
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
9201
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: "h-4 w-4 text-muted-foreground" }),
9202
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold", children: "Deliveries" }),
9203
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground ml-auto", children: [
9204
+ data.deliveries.length,
9205
+ " scheduled"
9206
+ ] })
9207
+ ] }),
9208
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: data.deliveries.map((delivery, index) => /* @__PURE__ */ jsxRuntime.jsx(
9209
+ DeliveryListItem2,
9210
+ {
9211
+ delivery,
9212
+ index,
9213
+ onClick: () => onSelectDelivery(delivery)
9214
+ },
9215
+ delivery.id
9216
+ )) })
9217
+ ] }),
9218
+ 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: [
9219
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: "h-4 w-4" }),
9220
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: "No logistics scheduled for this week" })
9221
+ ] }),
9222
+ 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: [
9223
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-4 w-4 mt-0.5 shrink-0" }),
9224
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm", children: data.warningMessage })
9225
+ ] }),
9226
+ data.notes && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
9227
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "Notes" }),
9228
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm", children: data.notes })
9229
+ ] })
9230
+ ] }) })
9231
+ ] });
9232
+ }
9233
+ function WeekDetailSheet({
9234
+ open,
9235
+ onOpenChange,
9236
+ supplier,
9237
+ week,
9238
+ data,
9239
+ onProductionUpdate,
9240
+ onAddProductionComment,
9241
+ onAddDeliveryComment
9242
+ }) {
9243
+ const [selectedDelivery, setSelectedDelivery] = React29__namespace.useState(null);
9244
+ const [productionDialogOpen, setProductionDialogOpen] = React29__namespace.useState(false);
9245
+ const [previousProducedCount, setPreviousProducedCount] = React29__namespace.useState(void 0);
9246
+ const productionElements = React29__namespace.useMemo(() => {
9247
+ if (!data?.deliveries) return [];
9248
+ const elements = [];
9249
+ const seenIds = /* @__PURE__ */ new Set();
9250
+ data.deliveries.forEach((delivery) => {
9251
+ delivery.elements?.forEach((element) => {
9252
+ if (!seenIds.has(element.id)) {
9253
+ seenIds.add(element.id);
9254
+ elements.push({
9255
+ id: element.id,
9256
+ name: element.name,
9257
+ prefix: element.prefix,
9258
+ type: element.type,
9259
+ weight: element.weight,
9260
+ size: element.sizeSqm,
9261
+ sizeUnit: "sqm",
9262
+ isProduced: element.isProduced
9263
+ });
9264
+ }
9265
+ });
9266
+ });
9267
+ return elements;
9268
+ }, [data?.deliveries]);
9269
+ const currentProducedCount = productionElements.filter((e) => e.isProduced).length;
9270
+ React29__namespace.useEffect(() => {
9271
+ if (open && data?.deliveries) {
9272
+ setPreviousProducedCount(currentProducedCount);
9273
+ }
9274
+ }, [open]);
9275
+ React29__namespace.useEffect(() => {
9276
+ if (!open) {
9277
+ setSelectedDelivery(null);
9278
+ setProductionDialogOpen(false);
9279
+ setPreviousProducedCount(void 0);
9280
+ }
9281
+ }, [open]);
9282
+ const handleProductionSave = (producedIds) => {
9283
+ if (!supplier || !week || !onProductionUpdate) return;
9284
+ const weekKey = `${week.year}-W${week.weekNumber.toString().padStart(2, "0")}`;
9285
+ onProductionUpdate(supplier.id, weekKey, producedIds);
9286
+ setPreviousProducedCount(producedIds.length);
9287
+ };
9288
+ if (!supplier || !week || !data) {
9289
+ return null;
9290
+ }
9291
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
9292
+ /* @__PURE__ */ jsxRuntime.jsx(Sheet, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsx(
9293
+ SheetContent,
9294
+ {
9295
+ side: "right",
9296
+ className: "w-full sm:max-w-lg p-0 overflow-hidden",
9297
+ children: selectedDelivery ? /* @__PURE__ */ jsxRuntime.jsx(
9298
+ DeliveryDetailsView2,
9299
+ {
9300
+ delivery: selectedDelivery,
9301
+ week,
9302
+ onBack: () => setSelectedDelivery(null),
9303
+ onAddComment: onAddDeliveryComment ? (text) => {
9304
+ const weekKey = `${week.year}-W${week.weekNumber.toString().padStart(2, "0")}`;
9305
+ onAddDeliveryComment(supplier.id, weekKey, selectedDelivery.id, text);
9306
+ } : void 0
9307
+ }
9308
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
9309
+ MainView2,
9310
+ {
9311
+ supplier,
9312
+ week,
9313
+ data,
9314
+ productionElements,
9315
+ previousProducedCount,
9316
+ onOpenProductionDialog: () => setProductionDialogOpen(true),
9317
+ onSelectDelivery: setSelectedDelivery,
9318
+ onAddProductionComment: onAddProductionComment ? (text) => {
9319
+ const weekKey = `${week.year}-W${week.weekNumber.toString().padStart(2, "0")}`;
9320
+ onAddProductionComment(supplier.id, weekKey, text);
9321
+ } : void 0
9322
+ }
9323
+ )
9324
+ }
9325
+ ) }),
9326
+ /* @__PURE__ */ jsxRuntime.jsx(
9327
+ ElementProductionDialog,
9328
+ {
9329
+ open: productionDialogOpen,
9330
+ onOpenChange: setProductionDialogOpen,
9331
+ elements: productionElements,
9332
+ onSave: handleProductionSave
9333
+ }
9334
+ )
9335
+ ] });
9336
+ }
9337
+ function RowHeaderCell({
9338
+ className,
9339
+ data,
9340
+ showProgress = true,
9341
+ ...props
9342
+ }) {
9343
+ const progressPercent = data.totalRequired > 0 ? Math.min(data.totalBooked / data.totalRequired * 100, 100) : 0;
9344
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9345
+ "div",
9346
+ {
9347
+ "data-slot": "row-header-cell",
9348
+ className: cn(
9349
+ "flex flex-col justify-center gap-1.5 py-2 px-3 min-w-[200px] h-[100px] bg-background",
9350
+ className
9351
+ ),
9352
+ ...props,
9353
+ children: [
9354
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-2", children: [
9355
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
9356
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-bold leading-tight text-foreground truncate", children: data.name }),
9357
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: data.typeCode })
9358
+ ] }),
9359
+ /* @__PURE__ */ jsxRuntime.jsxs(
9360
+ Badge,
9361
+ {
9362
+ variant: "outline",
9363
+ className: "text-[10px] px-2 py-0.5 h-[19px] font-medium shrink-0 gap-1 bg-background border-border",
9364
+ children: [
9365
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Flag, { className: "h-2.5 w-2.5" }),
9366
+ "Paint"
9367
+ ]
9368
+ }
9369
+ )
9370
+ ] }),
9371
+ showProgress && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
9372
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-1.5 bg-black/10 dark:bg-white/10 rounded-full overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
9373
+ "div",
9374
+ {
9375
+ className: "h-full bg-primary rounded-full transition-all",
9376
+ style: { width: `${progressPercent}%` }
9377
+ }
9378
+ ) }),
9379
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] font-medium text-primary", children: [
9380
+ data.totalBooked.toLocaleString(),
9381
+ " / ",
9382
+ data.totalRequired.toLocaleString(),
9383
+ " Booked"
9384
+ ] })
9385
+ ] })
9386
+ ]
9387
+ }
9388
+ );
9389
+ }
8207
9390
  function NetBadge({
8208
9391
  className,
8209
9392
  net,
@@ -8322,13 +9505,13 @@ function CalibrationWeekCell({
8322
9505
  onAddClick,
8323
9506
  ...props
8324
9507
  }) {
8325
- const inputRef = React27__namespace.useRef(null);
8326
- const [localValue, setLocalValue] = React27__namespace.useState(
9508
+ const inputRef = React29__namespace.useRef(null);
9509
+ const [localValue, setLocalValue] = React29__namespace.useState(
8327
9510
  data.entered !== null ? String(data.entered) : ""
8328
9511
  );
8329
- const [isHovered, setIsHovered] = React27__namespace.useState(false);
8330
- const [isEditing, setIsEditing] = React27__namespace.useState(false);
8331
- React27__namespace.useEffect(() => {
9512
+ const [isHovered, setIsHovered] = React29__namespace.useState(false);
9513
+ const [isEditing, setIsEditing] = React29__namespace.useState(false);
9514
+ React29__namespace.useEffect(() => {
8332
9515
  setLocalValue(data.entered !== null ? String(data.entered) : "");
8333
9516
  }, [data.entered]);
8334
9517
  const unitLabel = formatCalibrationUnit(unit);
@@ -8514,11 +9697,11 @@ function CommentPopover({
8514
9697
  open,
8515
9698
  onOpenChange
8516
9699
  }) {
8517
- const [newCommentText, setNewCommentText] = React27__namespace.useState("");
8518
- const [selectedPrefixId, setSelectedPrefixId] = React27__namespace.useState("");
8519
- const [viewCommentsOpen, setViewCommentsOpen] = React27__namespace.useState(true);
8520
- const [showAddForm, setShowAddForm] = React27__namespace.useState(false);
8521
- const selectedPrefixName = React27__namespace.useMemo(() => {
9700
+ const [newCommentText, setNewCommentText] = React29__namespace.useState("");
9701
+ const [selectedPrefixId, setSelectedPrefixId] = React29__namespace.useState("");
9702
+ const [viewCommentsOpen, setViewCommentsOpen] = React29__namespace.useState(true);
9703
+ const [showAddForm, setShowAddForm] = React29__namespace.useState(false);
9704
+ const selectedPrefixName = React29__namespace.useMemo(() => {
8522
9705
  const prefix = availablePrefixes.find((p) => p.id === selectedPrefixId);
8523
9706
  return prefix?.name ?? "";
8524
9707
  }, [availablePrefixes, selectedPrefixId]);
@@ -8550,8 +9733,8 @@ function CommentPopover({
8550
9733
  minute: "2-digit"
8551
9734
  }).format(date);
8552
9735
  };
8553
- const prevOpenRef = React27__namespace.useRef(open);
8554
- React27__namespace.useEffect(() => {
9736
+ const prevOpenRef = React29__namespace.useRef(open);
9737
+ React29__namespace.useEffect(() => {
8555
9738
  const wasOpen = prevOpenRef.current;
8556
9739
  prevOpenRef.current = open;
8557
9740
  if (wasOpen && !open) {
@@ -8780,7 +9963,7 @@ function CalibrationTable({
8780
9963
  onAddComment,
8781
9964
  onAddEarlierWeek
8782
9965
  } = config;
8783
- const calculatedStartDate = React27__namespace.useMemo(() => {
9966
+ const calculatedStartDate = React29__namespace.useMemo(() => {
8784
9967
  if (startDate) return startDate;
8785
9968
  let earliest = null;
8786
9969
  for (const prefix of prefixes) {
@@ -8801,31 +9984,31 @@ function CalibrationTable({
8801
9984
  }
8802
9985
  return earliest ?? /* @__PURE__ */ new Date();
8803
9986
  }, [startDate, prefixes]);
8804
- const [additionalWeeks, setAdditionalWeeks] = React27__namespace.useState(0);
8805
- const weeks = React27__namespace.useMemo(() => {
9987
+ const [additionalWeeks, setAdditionalWeeks] = React29__namespace.useState(0);
9988
+ const weeks = React29__namespace.useMemo(() => {
8806
9989
  const start = new Date(calculatedStartDate);
8807
9990
  start.setDate(start.getDate() - additionalWeeks * 7);
8808
9991
  return generateWeeks(start, weekCount + additionalWeeks);
8809
9992
  }, [calculatedStartDate, weekCount, additionalWeeks]);
8810
- React27__namespace.useMemo(() => {
9993
+ React29__namespace.useMemo(() => {
8811
9994
  const currentWeek = weeks.find((w) => w.isCurrentWeek);
8812
9995
  return currentWeek ? getWeekKey(currentWeek.startDate) : null;
8813
9996
  }, [weeks]);
8814
- const [currentPage, setCurrentPage] = React27__namespace.useState(0);
8815
- const [pageSize, setPageSize] = React27__namespace.useState(defaultPageSize);
8816
- const [searchQuery, setSearchQuery] = React27__namespace.useState("");
8817
- const filteredPrefixes = React27__namespace.useMemo(() => {
9997
+ const [currentPage, setCurrentPage] = React29__namespace.useState(0);
9998
+ const [pageSize, setPageSize] = React29__namespace.useState(defaultPageSize);
9999
+ const [searchQuery, setSearchQuery] = React29__namespace.useState("");
10000
+ const filteredPrefixes = React29__namespace.useMemo(() => {
8818
10001
  if (!searchQuery) return prefixes;
8819
10002
  const query = searchQuery.toLowerCase();
8820
10003
  return prefixes.filter(
8821
10004
  (p) => p.name.toLowerCase().includes(query) || p.typeCode.toLowerCase().includes(query)
8822
10005
  );
8823
10006
  }, [prefixes, searchQuery]);
8824
- const paginatedPrefixes = React27__namespace.useMemo(() => {
10007
+ const paginatedPrefixes = React29__namespace.useMemo(() => {
8825
10008
  const start = currentPage * pageSize;
8826
10009
  return filteredPrefixes.slice(start, start + pageSize);
8827
10010
  }, [filteredPrefixes, currentPage, pageSize]);
8828
- React27__namespace.useMemo(
10011
+ React29__namespace.useMemo(
8829
10012
  () => canSubmitCalibration(prefixes),
8830
10013
  [prefixes]
8831
10014
  );
@@ -8849,7 +10032,7 @@ function CalibrationTable({
8849
10032
  }
8850
10033
  return allComments;
8851
10034
  };
8852
- const availablePrefixes = React27__namespace.useMemo(
10035
+ const availablePrefixes = React29__namespace.useMemo(
8853
10036
  () => prefixes.map((p) => ({ id: p.id, name: p.name })),
8854
10037
  [prefixes]
8855
10038
  );
@@ -9086,14 +10269,14 @@ function CommentDialog({
9086
10269
  open,
9087
10270
  onOpenChange
9088
10271
  }) {
9089
- const [selectedPrefixId, setSelectedPrefixId] = React27__namespace.useState("");
9090
- const [selectedWeekKey, setSelectedWeekKey] = React27__namespace.useState("");
9091
- const [commentText, setCommentText] = React27__namespace.useState("");
9092
- const currentWeek = React27__namespace.useMemo(
10272
+ const [selectedPrefixId, setSelectedPrefixId] = React29__namespace.useState("");
10273
+ const [selectedWeekKey, setSelectedWeekKey] = React29__namespace.useState("");
10274
+ const [commentText, setCommentText] = React29__namespace.useState("");
10275
+ const currentWeek = React29__namespace.useMemo(
9093
10276
  () => weeks.find((w) => w.isCurrentWeek),
9094
10277
  [weeks]
9095
10278
  );
9096
- React27__namespace.useEffect(() => {
10279
+ React29__namespace.useEffect(() => {
9097
10280
  if (open) {
9098
10281
  setSelectedPrefixId(prefixes[0]?.id ?? "");
9099
10282
  setSelectedWeekKey(currentWeek ? getWeekKey(currentWeek.startDate) : weeks[0] ? getWeekKey(weeks[0].startDate) : "");
@@ -9423,40 +10606,36 @@ function groupDeliveriesByPrefixAndDay(deliveries) {
9423
10606
  }
9424
10607
  return grouped;
9425
10608
  }
9426
- function getLeftStrokeStyles(state, hasRisk, isHovered) {
10609
+ function getCardStyles(state, hasRisk, isHovered) {
9427
10610
  if (hasRisk) {
9428
10611
  return {
9429
10612
  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"
10613
+ cardBg: "bg-background",
10614
+ titleColor: "text-foreground",
10615
+ opacity: ""
9434
10616
  };
9435
10617
  }
9436
10618
  switch (state) {
9437
10619
  case "sent":
9438
10620
  return {
9439
10621
  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"
10622
+ cardBg: "bg-muted/40",
10623
+ titleColor: "text-muted-foreground",
10624
+ opacity: "opacity-60"
9444
10625
  };
9445
10626
  case "ready":
9446
10627
  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"
10628
+ stroke: "border-l-[4px] border-l-green-500",
10629
+ cardBg: "bg-background",
10630
+ titleColor: "text-foreground",
10631
+ opacity: ""
9452
10632
  };
9453
10633
  default:
9454
10634
  return {
9455
10635
  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"
10636
+ cardBg: "bg-background",
10637
+ titleColor: "text-foreground",
10638
+ opacity: ""
9460
10639
  };
9461
10640
  }
9462
10641
  }
@@ -9466,55 +10645,11 @@ function DeliveryBadge({
9466
10645
  onCommentClick,
9467
10646
  className
9468
10647
  }) {
9469
- const [isHovered, setIsHovered] = React27__namespace.useState(false);
10648
+ const [isHovered, setIsHovered] = React29__namespace.useState(false);
9470
10649
  const hasComments = delivery.comments.length > 0;
9471
10650
  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]);
10651
+ const styles = getCardStyles(visualState, delivery.hasProductionRisk ?? false, isHovered);
10652
+ const projectName = delivery.destination || delivery.label;
9518
10653
  const handleClick = (e) => {
9519
10654
  e.stopPropagation();
9520
10655
  onClick?.();
@@ -9530,38 +10665,24 @@ function DeliveryBadge({
9530
10665
  e.stopPropagation();
9531
10666
  onCommentClick?.();
9532
10667
  };
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
10668
  return /* @__PURE__ */ jsxRuntime.jsxs(
9546
10669
  "div",
9547
10670
  {
9548
10671
  className: cn(
9549
10672
  // Position relative for comment button
9550
10673
  "relative",
9551
- // Full-width in cell, 90° corners
10674
+ // Full-width in cell, 90° corners (j3m.radius.none)
9552
10675
  "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
10676
+ // Compact sizing - min-h-[72px], p-4 (j3m.spacing.m)
10677
+ "min-h-[72px] p-4",
10678
+ // Card base: dynamic background based on state
9560
10679
  styles.cardBg,
9561
10680
  "border border-border",
9562
10681
  // Left stroke for status
9563
10682
  styles.stroke,
9564
- // Interactive states (reduced for sent state)
10683
+ // Opacity for shipped state only
10684
+ styles.opacity,
10685
+ // Interactive states (disabled hover lift for shipped)
9565
10686
  "transition-all duration-200 ease-out",
9566
10687
  visualState !== "sent" && "hover:-translate-y-0.5 hover:shadow-[var(--j3m-shadow-md)]",
9567
10688
  className
@@ -9574,7 +10695,7 @@ function DeliveryBadge({
9574
10695
  variant: "ghost",
9575
10696
  size: "icon",
9576
10697
  className: cn(
9577
- "absolute top-2 right-2",
10698
+ "absolute top-1.5 right-1.5",
9578
10699
  // 44px touch target for accessibility
9579
10700
  "h-11 w-11",
9580
10701
  "rounded-full",
@@ -9606,7 +10727,7 @@ function DeliveryBadge({
9606
10727
  // Full width, no background (inherits from parent)
9607
10728
  "w-full bg-transparent text-left",
9608
10729
  // Layout - vertical stack
9609
- "flex flex-col gap-2",
10730
+ "flex flex-col justify-between h-full min-h-[40px]",
9610
10731
  // Interactive states
9611
10732
  "cursor-pointer",
9612
10733
  "active:translate-y-0 active:shadow-sm",
@@ -9614,33 +10735,19 @@ function DeliveryBadge({
9614
10735
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1"
9615
10736
  ),
9616
10737
  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 })
10738
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2 pr-12", children: [
10739
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
10740
+ "text-sm font-semibold leading-tight line-clamp-2",
10741
+ styles.titleColor
10742
+ ), children: projectName }),
10743
+ delivery.hasProductionRisk && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-4 w-4 text-red-500 shrink-0 mt-0.5" })
9624
10744
  ] }),
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 })
10745
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 mt-2", children: [
10746
+ visualState === "sent" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10747
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3.5 w-3.5 text-green-600 dark:text-green-400 shrink-0" }),
10748
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium text-muted-foreground uppercase tracking-wide", children: "Shipped" })
9639
10749
  ] }),
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
- ] })
10750
+ visualState === "ready" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-semibold text-green-600 dark:text-green-400 uppercase tracking-wide", children: "Ready" })
9644
10751
  ] })
9645
10752
  ]
9646
10753
  }
@@ -9649,6 +10756,62 @@ function DeliveryBadge({
9649
10756
  }
9650
10757
  );
9651
10758
  }
10759
+ function isShippedDelivery(delivery) {
10760
+ return delivery.status === "shipped" || delivery.status === "delivered";
10761
+ }
10762
+ function ShippedDeliveriesToggle({
10763
+ shippedDeliveries,
10764
+ isOpen,
10765
+ onToggle,
10766
+ onDeliveryClick,
10767
+ onDeliveryCommentClick
10768
+ }) {
10769
+ if (shippedDeliveries.length === 0) return null;
10770
+ return /* @__PURE__ */ jsxRuntime.jsxs(Collapsible, { open: isOpen, onOpenChange: onToggle, children: [
10771
+ /* @__PURE__ */ jsxRuntime.jsx(CollapsibleTrigger2, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
10772
+ "button",
10773
+ {
10774
+ type: "button",
10775
+ className: cn(
10776
+ "w-full flex items-center justify-between gap-2",
10777
+ "min-h-[44px] px-3 py-2",
10778
+ "rounded-md",
10779
+ "text-xs text-muted-foreground",
10780
+ "hover:bg-muted/50 transition-colors",
10781
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary"
10782
+ ),
10783
+ children: [
10784
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
10785
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3.5 w-3.5 text-green-600 dark:text-green-400" }),
10786
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
10787
+ "Shipped (",
10788
+ shippedDeliveries.length,
10789
+ ")"
10790
+ ] })
10791
+ ] }),
10792
+ /* @__PURE__ */ jsxRuntime.jsx(
10793
+ lucideReact.ChevronDown,
10794
+ {
10795
+ className: cn(
10796
+ "h-4 w-4 transition-transform duration-200",
10797
+ isOpen && "rotate-180"
10798
+ )
10799
+ }
10800
+ )
10801
+ ]
10802
+ }
10803
+ ) }),
10804
+ /* @__PURE__ */ jsxRuntime.jsx(CollapsibleContent2, { children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-3 pt-2", children: shippedDeliveries.map((delivery) => /* @__PURE__ */ jsxRuntime.jsx(
10805
+ DeliveryBadge,
10806
+ {
10807
+ delivery,
10808
+ onClick: () => onDeliveryClick?.(delivery),
10809
+ onCommentClick: () => onDeliveryCommentClick?.(delivery)
10810
+ },
10811
+ delivery.id
10812
+ )) }) })
10813
+ ] });
10814
+ }
9652
10815
  function WeeklyLoadingView({
9653
10816
  week,
9654
10817
  deliveries,
@@ -9658,7 +10821,25 @@ function WeeklyLoadingView({
9658
10821
  showNavigation = true,
9659
10822
  className
9660
10823
  }) {
9661
- const weekDays = React27__namespace.useMemo(() => {
10824
+ const [shippedOpenState, setShippedOpenState] = React29__namespace.useState({
10825
+ 1: false,
10826
+ // Monday
10827
+ 2: false,
10828
+ // Tuesday
10829
+ 3: false,
10830
+ // Wednesday
10831
+ 4: false,
10832
+ // Thursday
10833
+ 5: false
10834
+ // Friday
10835
+ });
10836
+ const toggleShippedForDay = (dayOfWeek) => {
10837
+ setShippedOpenState((prev) => ({
10838
+ ...prev,
10839
+ [dayOfWeek]: !prev[dayOfWeek]
10840
+ }));
10841
+ };
10842
+ const weekDays = React29__namespace.useMemo(() => {
9662
10843
  const days = [];
9663
10844
  for (let i = 0; i < 5; i++) {
9664
10845
  const date = dateFns.addDays(week.startDate, i);
@@ -9670,22 +10851,26 @@ function WeeklyLoadingView({
9670
10851
  }
9671
10852
  return days;
9672
10853
  }, [week.startDate]);
9673
- const deliveriesByDay = React27__namespace.useMemo(() => {
10854
+ const deliveriesByDay = React29__namespace.useMemo(() => {
9674
10855
  const grouped = /* @__PURE__ */ new Map();
9675
10856
  for (let i = 1; i <= 5; i++) {
9676
- grouped.set(i, []);
10857
+ grouped.set(i, { pending: [], shipped: [] });
9677
10858
  }
9678
10859
  for (const delivery of deliveries) {
9679
10860
  const dayOfWeek = delivery.date.getDay();
9680
10861
  if (dayOfWeek >= 1 && dayOfWeek <= 5) {
9681
- const dayDeliveries = grouped.get(dayOfWeek) ?? [];
9682
- dayDeliveries.push(delivery);
9683
- grouped.set(dayOfWeek, dayDeliveries);
10862
+ const dayData = grouped.get(dayOfWeek);
10863
+ if (isShippedDelivery(delivery)) {
10864
+ dayData.shipped.push(delivery);
10865
+ } else {
10866
+ dayData.pending.push(delivery);
10867
+ }
9684
10868
  }
9685
10869
  }
9686
10870
  return grouped;
9687
10871
  }, [deliveries]);
9688
- const totalDeliveries = deliveries.length;
10872
+ const totalPendingDeliveries = deliveries.filter((d) => !isShippedDelivery(d)).length;
10873
+ const totalShippedDeliveries = deliveries.filter((d) => isShippedDelivery(d)).length;
9689
10874
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col", className), children: [
9690
10875
  /* @__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
10876
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
@@ -9702,9 +10887,9 @@ function WeeklyLoadingView({
9702
10887
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
9703
10888
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: week.dateRange }),
9704
10889
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: [
9705
- totalDeliveries,
9706
- " ",
9707
- totalDeliveries === 1 ? "delivery" : "deliveries"
10890
+ totalPendingDeliveries,
10891
+ " pending",
10892
+ totalShippedDeliveries > 0 && `, ${totalShippedDeliveries} shipped`
9708
10893
  ] })
9709
10894
  ] })
9710
10895
  ] }),
@@ -9771,8 +10956,11 @@ function WeeklyLoadingView({
9771
10956
  dayOfWeek
9772
10957
  )) }),
9773
10958
  /* @__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(
10959
+ const dayData = deliveriesByDay.get(dayOfWeek) ?? { pending: [], shipped: [] };
10960
+ const hasPending = dayData.pending.length > 0;
10961
+ const hasShipped = dayData.shipped.length > 0;
10962
+ const isEmpty = !hasPending && !hasShipped;
10963
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9776
10964
  "div",
9777
10965
  {
9778
10966
  className: cn(
@@ -9780,22 +10968,39 @@ function WeeklyLoadingView({
9780
10968
  "flex flex-col p-3",
9781
10969
  dayIsToday && "bg-primary/5"
9782
10970
  ),
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" }) })
10971
+ children: [
10972
+ hasPending && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-3", children: dayData.pending.map((delivery) => /* @__PURE__ */ jsxRuntime.jsx(
10973
+ DeliveryBadge,
10974
+ {
10975
+ delivery,
10976
+ onClick: () => onDeliveryClick?.(delivery),
10977
+ onCommentClick: () => onDeliveryCommentClick?.(delivery)
10978
+ },
10979
+ delivery.id
10980
+ )) }),
10981
+ hasShipped && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(hasPending && "mt-3"), children: /* @__PURE__ */ jsxRuntime.jsx(
10982
+ ShippedDeliveriesToggle,
10983
+ {
10984
+ shippedDeliveries: dayData.shipped,
10985
+ isOpen: shippedOpenState[dayOfWeek] ?? false,
10986
+ onToggle: () => toggleShippedForDay(dayOfWeek),
10987
+ onDeliveryClick,
10988
+ onDeliveryCommentClick
10989
+ }
10990
+ ) }),
10991
+ isEmpty && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center py-6 text-sm text-muted-foreground/40", children: "\u2014" })
10992
+ ]
9792
10993
  },
9793
10994
  dayOfWeek
9794
10995
  );
9795
10996
  }) })
9796
10997
  ] }),
9797
10998
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sm:hidden divide-y divide-border", children: weekDays.map(({ date, dayOfWeek, isToday: dayIsToday }) => {
9798
- const dayDeliveries = deliveriesByDay.get(dayOfWeek) ?? [];
10999
+ const dayData = deliveriesByDay.get(dayOfWeek) ?? { pending: [], shipped: [] };
11000
+ const hasPending = dayData.pending.length > 0;
11001
+ const hasShipped = dayData.shipped.length > 0;
11002
+ const isEmpty = !hasPending && !hasShipped;
11003
+ dayData.pending.length + dayData.shipped.length;
9799
11004
  return /* @__PURE__ */ jsxRuntime.jsxs(
9800
11005
  "div",
9801
11006
  {
@@ -9818,20 +11023,33 @@ function WeeklyLoadingView({
9818
11023
  dayIsToday && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-primary font-medium bg-primary/10 px-2 py-0.5 rounded", children: "Today" })
9819
11024
  ] }),
9820
11025
  /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", children: [
9821
- dayDeliveries.length,
9822
- " ",
9823
- dayDeliveries.length === 1 ? "delivery" : "deliveries"
11026
+ dayData.pending.length,
11027
+ " pending",
11028
+ hasShipped && `, ${dayData.shipped.length} shipped`
9824
11029
  ] })
9825
11030
  ] }),
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" }) })
11031
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 p-3 pt-0", children: [
11032
+ hasPending && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-3", children: dayData.pending.map((delivery) => /* @__PURE__ */ jsxRuntime.jsx(
11033
+ DeliveryBadge,
11034
+ {
11035
+ delivery,
11036
+ onClick: () => onDeliveryClick?.(delivery),
11037
+ onCommentClick: () => onDeliveryCommentClick?.(delivery)
11038
+ },
11039
+ delivery.id
11040
+ )) }),
11041
+ hasShipped && /* @__PURE__ */ jsxRuntime.jsx(
11042
+ ShippedDeliveriesToggle,
11043
+ {
11044
+ shippedDeliveries: dayData.shipped,
11045
+ isOpen: shippedOpenState[dayOfWeek] ?? false,
11046
+ onToggle: () => toggleShippedForDay(dayOfWeek),
11047
+ onDeliveryClick,
11048
+ onDeliveryCommentClick
11049
+ }
11050
+ ),
11051
+ isEmpty && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm text-muted-foreground/40 py-4 text-center", children: "\u2014" })
11052
+ ] })
9835
11053
  ]
9836
11054
  },
9837
11055
  dayOfWeek
@@ -9840,36 +11058,63 @@ function WeeklyLoadingView({
9840
11058
  ] })
9841
11059
  ] });
9842
11060
  }
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";
11061
+ function getTimelineState(delivery) {
11062
+ const isShipped = delivery.status === "shipped" || delivery.status === "delivered";
11063
+ const isReady = delivery.isReadyToUnload ?? false;
11064
+ const hasProductionData = delivery.producedCount !== void 0 || delivery.producedTons !== void 0;
11065
+ if (isShipped) {
11066
+ return {
11067
+ currentStep: "delivery",
11068
+ documentState: "completed",
11069
+ productionState: "completed",
11070
+ deliveryState: "completed",
11071
+ isReady: true,
11072
+ currentStepLabel: "Delivery",
11073
+ reason: "Delivery completed"
11074
+ };
9856
11075
  }
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";
11076
+ if (isReady) {
11077
+ return {
11078
+ currentStep: "delivery",
11079
+ documentState: "completed",
11080
+ productionState: "completed",
11081
+ deliveryState: "current",
11082
+ isReady: true,
11083
+ currentStepLabel: "Delivery",
11084
+ reason: "All prerequisites complete"
11085
+ };
11086
+ }
11087
+ if (hasProductionData) {
11088
+ return {
11089
+ currentStep: "production",
11090
+ documentState: "completed",
11091
+ productionState: "current",
11092
+ deliveryState: "upcoming",
11093
+ isReady: false,
11094
+ currentStepLabel: "Production",
11095
+ reason: delivery.hasProductionRisk ? delivery.riskReason || "Production delay risk" : "Not all items have been produced"
11096
+ };
11097
+ }
11098
+ if (delivery.status === "planned") {
11099
+ return {
11100
+ currentStep: "document",
11101
+ documentState: "current",
11102
+ productionState: "upcoming",
11103
+ deliveryState: "upcoming",
11104
+ isReady: false,
11105
+ currentStepLabel: "Document",
11106
+ reason: "Waiting for document approval"
11107
+ };
9872
11108
  }
11109
+ return {
11110
+ currentStep: "production",
11111
+ documentState: "completed",
11112
+ productionState: "current",
11113
+ deliveryState: "upcoming",
11114
+ isReady: false,
11115
+ currentStepLabel: "Production",
11116
+ reason: "Production status pending"
11117
+ };
9873
11118
  }
9874
11119
  function getElementStatusBadgeClasses(status) {
9875
11120
  switch (status) {
@@ -9885,6 +11130,166 @@ function getElementStatusBadgeClasses(status) {
9885
11130
  return "border-muted-foreground/50 text-muted-foreground";
9886
11131
  }
9887
11132
  }
11133
+ var TIMELINE_STEPS = [
11134
+ { id: "document", label: "Document", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FileText, { className: "h-4 w-4" }) },
11135
+ { id: "production", label: "Production", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Factory, { className: "h-4 w-4" }) },
11136
+ { id: "delivery", label: "Delivery", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: "h-4 w-4" }) }
11137
+ ];
11138
+ function getStepStyles(state) {
11139
+ switch (state) {
11140
+ case "completed":
11141
+ return {
11142
+ dot: "bg-green-500/20 border-green-500",
11143
+ icon: "text-green-600 dark:text-green-400",
11144
+ label: "text-muted-foreground",
11145
+ line: "bg-green-500"
11146
+ };
11147
+ case "current":
11148
+ return {
11149
+ dot: "bg-primary/20 border-primary",
11150
+ icon: "text-primary",
11151
+ label: "text-foreground font-semibold",
11152
+ line: "bg-border"
11153
+ };
11154
+ case "upcoming":
11155
+ default:
11156
+ return {
11157
+ dot: "bg-muted border-border",
11158
+ icon: "text-muted-foreground/50",
11159
+ label: "text-muted-foreground/50",
11160
+ line: "bg-border"
11161
+ };
11162
+ }
11163
+ }
11164
+ function DeliveryTimeline({ timelineState }) {
11165
+ const getStateForStep = (stepId) => {
11166
+ switch (stepId) {
11167
+ case "document":
11168
+ return timelineState.documentState;
11169
+ case "production":
11170
+ return timelineState.productionState;
11171
+ case "delivery":
11172
+ return timelineState.deliveryState;
11173
+ }
11174
+ };
11175
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-between w-full", children: TIMELINE_STEPS.map((step, index) => {
11176
+ const state = getStateForStep(step.id);
11177
+ const styles = getStepStyles(state);
11178
+ const isLast = index === TIMELINE_STEPS.length - 1;
11179
+ return /* @__PURE__ */ jsxRuntime.jsxs(React29__namespace.Fragment, { children: [
11180
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-2", children: [
11181
+ /* @__PURE__ */ jsxRuntime.jsx(
11182
+ "div",
11183
+ {
11184
+ className: cn(
11185
+ "flex items-center justify-center",
11186
+ "h-10 w-10 rounded-full border-2",
11187
+ "transition-colors duration-200",
11188
+ styles.dot
11189
+ ),
11190
+ 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 })
11191
+ }
11192
+ ),
11193
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-xs", styles.label), children: step.label })
11194
+ ] }),
11195
+ !isLast && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 mx-2 mb-6", children: /* @__PURE__ */ jsxRuntime.jsx(
11196
+ "div",
11197
+ {
11198
+ className: cn(
11199
+ "h-0.5 w-full rounded-full",
11200
+ styles.line
11201
+ )
11202
+ }
11203
+ ) })
11204
+ ] }, step.id);
11205
+ }) });
11206
+ }
11207
+ function PackingStatusBadge({
11208
+ timelineState,
11209
+ hasRisk
11210
+ }) {
11211
+ const getPackingStatus = () => {
11212
+ if (timelineState.isReady) {
11213
+ return {
11214
+ label: "Ready",
11215
+ className: "bg-green-100 dark:bg-green-900/50 text-green-700 dark:text-green-300 border-green-200 dark:border-green-800"
11216
+ };
11217
+ }
11218
+ if (hasRisk) {
11219
+ return {
11220
+ label: "At risk",
11221
+ className: "bg-red-100 dark:bg-red-900/50 text-red-700 dark:text-red-300 border-red-200 dark:border-red-800"
11222
+ };
11223
+ }
11224
+ switch (timelineState.currentStep) {
11225
+ case "document":
11226
+ return {
11227
+ label: "Pending approval",
11228
+ className: "bg-muted text-muted-foreground border-border"
11229
+ };
11230
+ case "production":
11231
+ return {
11232
+ label: "In production",
11233
+ className: "bg-amber-100 dark:bg-amber-900/50 text-amber-700 dark:text-amber-300 border-amber-200 dark:border-amber-800"
11234
+ };
11235
+ default:
11236
+ return {
11237
+ label: "Not ready",
11238
+ className: "bg-muted text-muted-foreground border-border"
11239
+ };
11240
+ }
11241
+ };
11242
+ const status = getPackingStatus();
11243
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
11244
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "Packing status:" }),
11245
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
11246
+ "inline-flex items-center px-2 py-0.5 rounded text-xs font-medium border",
11247
+ status.className
11248
+ ), children: status.label })
11249
+ ] });
11250
+ }
11251
+ function ReadinessMessage({
11252
+ timelineState,
11253
+ hasRisk
11254
+ }) {
11255
+ if (timelineState.isReady && timelineState.deliveryState === "completed") {
11256
+ 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: [
11257
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
11258
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-4 w-4 text-green-600 dark:text-green-400 shrink-0" }),
11259
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-green-700 dark:text-green-300", children: "Shipped" })
11260
+ ] }),
11261
+ /* @__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." })
11262
+ ] });
11263
+ }
11264
+ if (timelineState.isReady) {
11265
+ 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: [
11266
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
11267
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-4 w-4 text-green-600 dark:text-green-400 shrink-0" }),
11268
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-green-700 dark:text-green-300", children: "Ready" })
11269
+ ] }),
11270
+ /* @__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." })
11271
+ ] });
11272
+ }
11273
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
11274
+ "rounded-lg p-3 border",
11275
+ hasRisk ? "bg-red-50/50 dark:bg-red-950/20 border-red-200 dark:border-red-800/50" : "bg-muted/50 border-border"
11276
+ ), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [
11277
+ 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" }),
11278
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
11279
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn(
11280
+ "text-sm font-medium",
11281
+ hasRisk ? "text-red-700 dark:text-red-300" : "text-foreground"
11282
+ ), children: [
11283
+ "Currently in: ",
11284
+ timelineState.currentStepLabel
11285
+ ] }),
11286
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn(
11287
+ "text-xs mt-0.5",
11288
+ hasRisk ? "text-red-600/80 dark:text-red-400/80" : "text-muted-foreground"
11289
+ ), children: timelineState.reason })
11290
+ ] })
11291
+ ] }) });
11292
+ }
9888
11293
  function getElementRowBg(status) {
9889
11294
  switch (status) {
9890
11295
  case "loaded":
@@ -9906,7 +11311,7 @@ function AddCommentDialog({
9906
11311
  weekId,
9907
11312
  onAddComment
9908
11313
  }) {
9909
- const [commentText, setCommentText] = React27__namespace.useState("");
11314
+ const [commentText, setCommentText] = React29__namespace.useState("");
9910
11315
  const handleSubmit = () => {
9911
11316
  if (commentText.trim() && onAddComment) {
9912
11317
  onAddComment({
@@ -9931,7 +11336,7 @@ function AddCommentDialog({
9931
11336
  handleSubmit();
9932
11337
  }
9933
11338
  };
9934
- React27__namespace.useEffect(() => {
11339
+ React29__namespace.useEffect(() => {
9935
11340
  if (!open) {
9936
11341
  setCommentText("");
9937
11342
  }
@@ -9994,8 +11399,8 @@ function CommentsSection({
9994
11399
  weekId,
9995
11400
  onAddComment
9996
11401
  }) {
9997
- const [viewCommentsOpen, setViewCommentsOpen] = React27__namespace.useState(true);
9998
- const [addDialogOpen, setAddDialogOpen] = React27__namespace.useState(false);
11402
+ const [viewCommentsOpen, setViewCommentsOpen] = React29__namespace.useState(true);
11403
+ const [addDialogOpen, setAddDialogOpen] = React29__namespace.useState(false);
9999
11404
  const formatDate3 = (date) => {
10000
11405
  return new Intl.DateTimeFormat("en-US", {
10001
11406
  month: "short",
@@ -10058,31 +11463,6 @@ function CommentsSection({
10058
11463
  )
10059
11464
  ] });
10060
11465
  }
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
11466
  function DeliveryDetailPage({
10087
11467
  delivery,
10088
11468
  week,
@@ -10093,14 +11473,8 @@ function DeliveryDetailPage({
10093
11473
  onAddComment,
10094
11474
  onConfirmLoad
10095
11475
  }) {
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;
10103
- const elementsByStatus = React27__namespace.useMemo(() => {
11476
+ const timelineState = getTimelineState(delivery);
11477
+ const elementsByStatus = React29__namespace.useMemo(() => {
10104
11478
  const loaded = delivery.elements.filter((e) => e.status === "loaded");
10105
11479
  const missing = delivery.elements.filter((e) => e.status === "missing");
10106
11480
  const moved = delivery.elements.filter((e) => e.status === "moved");
@@ -10108,6 +11482,7 @@ function DeliveryDetailPage({
10108
11482
  return { loaded, missing, moved, addons };
10109
11483
  }, [delivery.elements]);
10110
11484
  const preLoadingComments = delivery.comments.filter((c) => c.context === "pre_unloading");
11485
+ const projectName = delivery.destination || delivery.label;
10111
11486
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col h-full", children: [
10112
11487
  /* @__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
11488
  Button,
@@ -10123,129 +11498,39 @@ function DeliveryDetailPage({
10123
11498
  }
10124
11499
  ) }),
10125
11500
  /* @__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: [
11501
+ /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "pt-4 space-y-3", children: [
10127
11502
  /* @__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
- ] })
11503
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-bold leading-tight line-clamp-2", children: projectName }),
11504
+ delivery.hasProductionRisk && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-5 w-5 text-red-500 shrink-0 mt-0.5" })
10163
11505
  ] }),
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" })
11506
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-x-4 gap-y-1 text-sm text-muted-foreground", children: [
11507
+ delivery.location && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
11508
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MapPin, { className: "h-3.5 w-3.5 shrink-0" }),
11509
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: delivery.location })
10168
11510
  ] }),
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
11511
  /* @__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
- ] })
11512
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Calendar, { className: "h-3.5 w-3.5 shrink-0" }),
11513
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
11514
+ "Expected on site: ",
11515
+ delivery.date.toLocaleDateString("en-US", {
11516
+ day: "numeric",
11517
+ month: "short",
11518
+ year: "numeric"
11519
+ })
10246
11520
  ] })
10247
11521
  ] })
10248
- ] })
11522
+ ] }),
11523
+ /* @__PURE__ */ jsxRuntime.jsx(PackingStatusBadge, { timelineState, hasRisk: delivery.hasProductionRisk ?? false })
11524
+ ] }),
11525
+ /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-4", children: [
11526
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-2", children: /* @__PURE__ */ jsxRuntime.jsx(DeliveryTimeline, { timelineState }) }),
11527
+ /* @__PURE__ */ jsxRuntime.jsx(
11528
+ ReadinessMessage,
11529
+ {
11530
+ timelineState,
11531
+ hasRisk: delivery.hasProductionRisk ?? false
11532
+ }
11533
+ )
10249
11534
  ] }),
10250
11535
  (elementsByStatus.loaded.length > 0 || elementsByStatus.missing.length > 0 || elementsByStatus.moved.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-3", children: [
10251
11536
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
@@ -10376,11 +11661,11 @@ function SupplierWeeklyLoading({
10376
11661
  bordered = true,
10377
11662
  className
10378
11663
  }) {
10379
- const [selectedDelivery, setSelectedDelivery] = React27__namespace.useState(null);
10380
- const [sheetOpen, setSheetOpen] = React27__namespace.useState(false);
10381
- const [commentDelivery, setCommentDelivery] = React27__namespace.useState(null);
10382
- const [commentDialogOpen, setCommentDialogOpen] = React27__namespace.useState(false);
10383
- const [commentText, setCommentText] = React27__namespace.useState("");
11664
+ const [selectedDelivery, setSelectedDelivery] = React29__namespace.useState(null);
11665
+ const [sheetOpen, setSheetOpen] = React29__namespace.useState(false);
11666
+ const [commentDelivery, setCommentDelivery] = React29__namespace.useState(null);
11667
+ const [commentDialogOpen, setCommentDialogOpen] = React29__namespace.useState(false);
11668
+ const [commentText, setCommentText] = React29__namespace.useState("");
10384
11669
  const handleDeliveryClick = (delivery) => {
10385
11670
  setSelectedDelivery(delivery);
10386
11671
  setSheetOpen(true);
@@ -10524,59 +11809,36 @@ function SupplierWeeklyLoading({
10524
11809
  ] }) })
10525
11810
  ] });
10526
11811
  }
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) {
11812
+ function getCardStyles2(state, hasRisk, isHovered) {
10559
11813
  if (hasRisk) {
10560
11814
  return {
10561
- stroke: "border-l-2 border-l-red-500",
10562
- iconColor: "text-muted-foreground"
11815
+ stroke: "border-l-[3px] border-l-red-500",
11816
+ cardBg: "bg-background",
11817
+ titleColor: "text-foreground",
11818
+ opacity: ""
10563
11819
  };
10564
11820
  }
10565
11821
  switch (state) {
10566
11822
  case "sent":
10567
11823
  return {
10568
- stroke: "border-l-2 border-l-green-500/50",
10569
- iconColor: "text-muted-foreground/40"
11824
+ stroke: "border-l-[3px] border-l-green-500/40",
11825
+ cardBg: "bg-muted/40",
11826
+ titleColor: "text-muted-foreground",
11827
+ opacity: "opacity-60"
10570
11828
  };
10571
11829
  case "ready":
10572
11830
  return {
10573
- stroke: "border-l-2 border-l-green-500",
10574
- iconColor: "text-muted-foreground"
11831
+ stroke: "border-l-[4px] border-l-green-500",
11832
+ cardBg: "bg-background",
11833
+ titleColor: "text-foreground",
11834
+ opacity: ""
10575
11835
  };
10576
11836
  default:
10577
11837
  return {
10578
- stroke: isHovered ? "border-l-2 border-l-border" : "border-l-2 border-l-transparent",
10579
- iconColor: "text-muted-foreground"
11838
+ stroke: isHovered ? "border-l-[3px] border-l-primary/50" : "border-l-[3px] border-l-border",
11839
+ cardBg: "bg-background",
11840
+ titleColor: "text-foreground",
11841
+ opacity: ""
10580
11842
  };
10581
11843
  }
10582
11844
  }
@@ -10585,22 +11847,11 @@ function DeliveryCard({
10585
11847
  onTap,
10586
11848
  className
10587
11849
  }) {
10588
- const [isHovered, setIsHovered] = React27__namespace.useState(false);
11850
+ const [isHovered, setIsHovered] = React29__namespace.useState(false);
10589
11851
  const hasComments = delivery.comments.length > 0;
10590
11852
  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]);
11853
+ const styles = getCardStyles2(visualState, delivery.hasProductionRisk ?? false, isHovered);
11854
+ const projectName = delivery.destination || delivery.label;
10604
11855
  const handleClick = () => {
10605
11856
  onTap?.();
10606
11857
  };
@@ -10624,69 +11875,43 @@ function DeliveryCard({
10624
11875
  "w-full rounded-none",
10625
11876
  // Touch-friendly sizing - 56px min-height for iPad
10626
11877
  "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)
11878
+ // Card styling: dynamic background based on state
11879
+ styles.cardBg,
11880
+ "border border-border",
11881
+ // Left stroke for status
10630
11882
  styles.stroke,
10631
- // Hover/tap state - lift effect like Calibration
11883
+ // Opacity for shipped state only
11884
+ styles.opacity,
11885
+ // Hover/tap state - lift effect (disabled for shipped)
10632
11886
  "cursor-pointer transition-all duration-200 ease-out",
10633
- "hover:-translate-y-0.5 hover:shadow-[var(--j3m-shadow-md)]",
11887
+ visualState !== "sent" && "hover:-translate-y-0.5 hover:shadow-[var(--j3m-shadow-md)]",
10634
11888
  "active:translate-y-0 active:shadow-sm",
10635
11889
  // Focus state
10636
11890
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary",
10637
- // Greyed out for sent state
10638
- visualState === "sent" && "opacity-60",
10639
11891
  className
10640
11892
  ),
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
- ] })
11893
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3", children: [
11894
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1 min-w-0 flex-1", children: [
11895
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
11896
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
11897
+ "text-sm font-semibold truncate",
11898
+ styles.titleColor
11899
+ ), children: projectName }),
11900
+ delivery.hasProductionRisk && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-4 w-4 text-red-500 shrink-0" }),
11901
+ hasComments && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative shrink-0", children: [
11902
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "h-3.5 w-3.5 text-muted-foreground" }),
11903
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -top-0.5 -right-0.5 h-2 w-2 rounded-full bg-primary" })
10676
11904
  ] })
11905
+ ] }),
11906
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
11907
+ visualState === "sent" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
11908
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-3.5 w-3.5 text-green-600 dark:text-green-400 shrink-0" }),
11909
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium text-muted-foreground uppercase tracking-wide", children: "Shipped" })
11910
+ ] }),
11911
+ visualState === "ready" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-semibold text-green-600 dark:text-green-400 uppercase tracking-wide", children: "Ready" })
10677
11912
  ] })
10678
11913
  ] }),
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
- ] })
11914
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4 text-muted-foreground shrink-0" })
10690
11915
  ] })
10691
11916
  }
10692
11917
  );
@@ -10754,7 +11979,7 @@ var BADGE_VARIANT_LABELS = {
10754
11979
  colored: "Colored",
10755
11980
  mixed: "Mixed"
10756
11981
  };
10757
- var CalendarContext = React27__namespace.createContext(null);
11982
+ var CalendarContext = React29__namespace.createContext(null);
10758
11983
  function EventCalendarProvider({
10759
11984
  children,
10760
11985
  events: initialEvents = [],
@@ -10769,38 +11994,38 @@ function EventCalendarProvider({
10769
11994
  onEventUpdate,
10770
11995
  onEventDelete
10771
11996
  }) {
10772
- const [selectedDate, setSelectedDate] = React27__namespace.useState(defaultDate);
10773
- const [selectedUserId, setSelectedUserId] = React27__namespace.useState(defaultUserId);
10774
- const [events, setEventsState] = React27__namespace.useState(initialEvents);
10775
- const [users] = React27__namespace.useState(initialUsers);
10776
- const [badgeVariant, setBadgeVariant] = React27__namespace.useState(defaultBadgeVariant);
10777
- const [view, setView] = React27__namespace.useState(defaultView);
10778
- const [workingHours, setWorkingHours] = React27__namespace.useState(defaultWorkingHours);
10779
- const [visibleHours, setVisibleHours] = React27__namespace.useState(defaultVisibleHours);
10780
- React27__namespace.useEffect(() => {
11997
+ const [selectedDate, setSelectedDate] = React29__namespace.useState(defaultDate);
11998
+ const [selectedUserId, setSelectedUserId] = React29__namespace.useState(defaultUserId);
11999
+ const [events, setEventsState] = React29__namespace.useState(initialEvents);
12000
+ const [users] = React29__namespace.useState(initialUsers);
12001
+ const [badgeVariant, setBadgeVariant] = React29__namespace.useState(defaultBadgeVariant);
12002
+ const [view, setView] = React29__namespace.useState(defaultView);
12003
+ const [workingHours, setWorkingHours] = React29__namespace.useState(defaultWorkingHours);
12004
+ const [visibleHours, setVisibleHours] = React29__namespace.useState(defaultVisibleHours);
12005
+ React29__namespace.useEffect(() => {
10781
12006
  setEventsState(initialEvents);
10782
12007
  }, [initialEvents]);
10783
- const setEvents = React27__namespace.useCallback((newEvents) => {
12008
+ const setEvents = React29__namespace.useCallback((newEvents) => {
10784
12009
  setEventsState(newEvents);
10785
12010
  }, []);
10786
- const addEvent = React27__namespace.useCallback((event) => {
12011
+ const addEvent = React29__namespace.useCallback((event) => {
10787
12012
  setEventsState((prev) => [...prev, event]);
10788
12013
  onEventAdd?.(event);
10789
12014
  }, [onEventAdd]);
10790
- const updateEvent = React27__namespace.useCallback((event) => {
12015
+ const updateEvent = React29__namespace.useCallback((event) => {
10791
12016
  setEventsState(
10792
12017
  (prev) => prev.map((e) => e.id === event.id ? event : e)
10793
12018
  );
10794
12019
  onEventUpdate?.(event);
10795
12020
  }, [onEventUpdate]);
10796
- const deleteEvent = React27__namespace.useCallback((eventId) => {
12021
+ const deleteEvent = React29__namespace.useCallback((eventId) => {
10797
12022
  setEventsState((prev) => prev.filter((e) => e.id !== eventId));
10798
12023
  onEventDelete?.(eventId);
10799
12024
  }, [onEventDelete]);
10800
- const goToToday = React27__namespace.useCallback(() => {
12025
+ const goToToday = React29__namespace.useCallback(() => {
10801
12026
  setSelectedDate(/* @__PURE__ */ new Date());
10802
12027
  }, []);
10803
- const goToPrevious = React27__namespace.useCallback(() => {
12028
+ const goToPrevious = React29__namespace.useCallback(() => {
10804
12029
  setSelectedDate((current) => {
10805
12030
  switch (view) {
10806
12031
  case "day":
@@ -10818,7 +12043,7 @@ function EventCalendarProvider({
10818
12043
  }
10819
12044
  });
10820
12045
  }, [view]);
10821
- const goToNext = React27__namespace.useCallback(() => {
12046
+ const goToNext = React29__namespace.useCallback(() => {
10822
12047
  setSelectedDate((current) => {
10823
12048
  switch (view) {
10824
12049
  case "day":
@@ -10836,7 +12061,7 @@ function EventCalendarProvider({
10836
12061
  }
10837
12062
  });
10838
12063
  }, [view]);
10839
- const contextValue = React27__namespace.useMemo(
12064
+ const contextValue = React29__namespace.useMemo(
10840
12065
  () => ({
10841
12066
  // State
10842
12067
  selectedDate,
@@ -10883,7 +12108,7 @@ function EventCalendarProvider({
10883
12108
  return /* @__PURE__ */ jsxRuntime.jsx(CalendarContext.Provider, { value: contextValue, children });
10884
12109
  }
10885
12110
  function useEventCalendar() {
10886
- const context = React27__namespace.useContext(CalendarContext);
12111
+ const context = React29__namespace.useContext(CalendarContext);
10887
12112
  if (!context) {
10888
12113
  throw new Error("useEventCalendar must be used within an EventCalendarProvider");
10889
12114
  }
@@ -10891,14 +12116,14 @@ function useEventCalendar() {
10891
12116
  }
10892
12117
  function useFilteredEvents() {
10893
12118
  const { events, selectedUserId } = useEventCalendar();
10894
- return React27__namespace.useMemo(() => {
12119
+ return React29__namespace.useMemo(() => {
10895
12120
  if (!selectedUserId) return events;
10896
12121
  return events.filter((event) => event.user.id === selectedUserId);
10897
12122
  }, [events, selectedUserId]);
10898
12123
  }
10899
12124
  function useEventsInRange(startDate, endDate) {
10900
12125
  const filteredEvents = useFilteredEvents();
10901
- return React27__namespace.useMemo(() => {
12126
+ return React29__namespace.useMemo(() => {
10902
12127
  return filteredEvents.filter((event) => {
10903
12128
  const eventStart = new Date(event.startDate);
10904
12129
  const eventEnd = new Date(event.endDate);
@@ -11456,8 +12681,8 @@ function MoreEvents({ count, onClick, className }) {
11456
12681
  );
11457
12682
  }
11458
12683
  function TimeIndicator({ className }) {
11459
- const [now, setNow] = React27__namespace.useState(/* @__PURE__ */ new Date());
11460
- React27__namespace.useEffect(() => {
12684
+ const [now, setNow] = React29__namespace.useState(/* @__PURE__ */ new Date());
12685
+ React29__namespace.useEffect(() => {
11461
12686
  const interval = setInterval(() => setNow(/* @__PURE__ */ new Date()), 6e4);
11462
12687
  return () => clearInterval(interval);
11463
12688
  }, []);
@@ -11494,24 +12719,24 @@ function DateBadge({ date, className }) {
11494
12719
  }
11495
12720
  );
11496
12721
  }
11497
- var DragContext = React27__namespace.createContext(null);
12722
+ var DragContext = React29__namespace.createContext(null);
11498
12723
  function DragProvider({
11499
12724
  children,
11500
12725
  snapMinutes = 15,
11501
12726
  onDragStart,
11502
12727
  onDragEnd
11503
12728
  }) {
11504
- const [draggedEvent, setDraggedEventState] = React27__namespace.useState(null);
11505
- const [isDragging, setIsDragging] = React27__namespace.useState(false);
12729
+ const [draggedEvent, setDraggedEventState] = React29__namespace.useState(null);
12730
+ const [isDragging, setIsDragging] = React29__namespace.useState(false);
11506
12731
  const { updateEvent } = useEventCalendar();
11507
- const setDraggedEvent = React27__namespace.useCallback((event) => {
12732
+ const setDraggedEvent = React29__namespace.useCallback((event) => {
11508
12733
  setDraggedEventState(event);
11509
12734
  setIsDragging(!!event);
11510
12735
  if (event) {
11511
12736
  onDragStart?.(event);
11512
12737
  }
11513
12738
  }, [onDragStart]);
11514
- const handleDrop = React27__namespace.useCallback((newStartDate) => {
12739
+ const handleDrop = React29__namespace.useCallback((newStartDate) => {
11515
12740
  if (!draggedEvent) return;
11516
12741
  const snappedDate = snapToInterval(newStartDate, snapMinutes);
11517
12742
  const { startDate, endDate } = calculateDropDates(draggedEvent, snappedDate);
@@ -11524,7 +12749,7 @@ function DragProvider({
11524
12749
  onDragEnd?.(updatedEvent, new Date(startDate), new Date(endDate));
11525
12750
  setDraggedEvent(null);
11526
12751
  }, [draggedEvent, snapMinutes, updateEvent, onDragEnd, setDraggedEvent]);
11527
- const contextValue = React27__namespace.useMemo(
12752
+ const contextValue = React29__namespace.useMemo(
11528
12753
  () => ({
11529
12754
  draggedEvent,
11530
12755
  setDraggedEvent,
@@ -11535,7 +12760,7 @@ function DragProvider({
11535
12760
  return /* @__PURE__ */ jsxRuntime.jsx(DragContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(DragDropHandler, { onDrop: handleDrop, children }) });
11536
12761
  }
11537
12762
  function useDrag() {
11538
- const context = React27__namespace.useContext(DragContext);
12763
+ const context = React29__namespace.useContext(DragContext);
11539
12764
  if (!context) {
11540
12765
  throw new Error("useDrag must be used within a DragProvider");
11541
12766
  }
@@ -11580,7 +12805,7 @@ function DroppableZone({
11580
12805
  }) {
11581
12806
  const { draggedEvent, setDraggedEvent } = useDrag();
11582
12807
  const { updateEvent } = useEventCalendar();
11583
- const [isOver, setIsOver] = React27__namespace.useState(false);
12808
+ const [isOver, setIsOver] = React29__namespace.useState(false);
11584
12809
  const handleDragOver = (e) => {
11585
12810
  e.preventDefault();
11586
12811
  e.dataTransfer.dropEffect = "move";
@@ -11618,23 +12843,23 @@ function DroppableZone({
11618
12843
  function useDroppable({ date, hour, minute = 0, onDrop }) {
11619
12844
  const { draggedEvent, setDraggedEvent } = useDrag();
11620
12845
  const { updateEvent } = useEventCalendar();
11621
- const [isOver, setIsOver] = React27__namespace.useState(false);
11622
- const dropTargetDate = React27__namespace.useMemo(() => {
12846
+ const [isOver, setIsOver] = React29__namespace.useState(false);
12847
+ const dropTargetDate = React29__namespace.useMemo(() => {
11623
12848
  const targetDate = new Date(date);
11624
12849
  if (hour !== void 0) {
11625
12850
  targetDate.setHours(hour, minute, 0, 0);
11626
12851
  }
11627
12852
  return targetDate;
11628
12853
  }, [date, hour, minute]);
11629
- const handleDragOver = React27__namespace.useCallback((e) => {
12854
+ const handleDragOver = React29__namespace.useCallback((e) => {
11630
12855
  e.preventDefault();
11631
12856
  e.dataTransfer.dropEffect = "move";
11632
12857
  if (!isOver) setIsOver(true);
11633
12858
  }, [isOver]);
11634
- const handleDragLeave = React27__namespace.useCallback(() => {
12859
+ const handleDragLeave = React29__namespace.useCallback(() => {
11635
12860
  setIsOver(false);
11636
12861
  }, []);
11637
- const handleDrop = React27__namespace.useCallback((e) => {
12862
+ const handleDrop = React29__namespace.useCallback((e) => {
11638
12863
  e.preventDefault();
11639
12864
  setIsOver(false);
11640
12865
  if (!draggedEvent) return;
@@ -11661,13 +12886,13 @@ function useDroppable({ date, hour, minute = 0, onDrop }) {
11661
12886
  function useDraggable(event, disabled = false) {
11662
12887
  const { setDraggedEvent, draggedEvent } = useDrag();
11663
12888
  const isDragged = draggedEvent?.id === event.id;
11664
- const handleDragStart = React27__namespace.useCallback((e) => {
12889
+ const handleDragStart = React29__namespace.useCallback((e) => {
11665
12890
  if (disabled) return;
11666
12891
  e.dataTransfer.effectAllowed = "move";
11667
12892
  e.dataTransfer.setData("text/plain", event.id);
11668
12893
  setDraggedEvent(event);
11669
12894
  }, [disabled, event, setDraggedEvent]);
11670
- const handleDragEnd = React27__namespace.useCallback(() => {
12895
+ const handleDragEnd = React29__namespace.useCallback(() => {
11671
12896
  setDraggedEvent(null);
11672
12897
  }, [setDraggedEvent]);
11673
12898
  return {
@@ -11708,15 +12933,15 @@ function MonthView({
11708
12933
  }) {
11709
12934
  const { selectedDate, badgeVariant, setSelectedDate, setView } = useEventCalendar();
11710
12935
  const filteredEvents = useFilteredEvents();
11711
- const { singleDayEvents, multiDayEvents } = React27__namespace.useMemo(
12936
+ const { singleDayEvents, multiDayEvents } = React29__namespace.useMemo(
11712
12937
  () => splitEventsByDuration(filteredEvents),
11713
12938
  [filteredEvents]
11714
12939
  );
11715
- const cells = React27__namespace.useMemo(
12940
+ const cells = React29__namespace.useMemo(
11716
12941
  () => getCalendarCells(selectedDate),
11717
12942
  [selectedDate]
11718
12943
  );
11719
- const eventPositions = React27__namespace.useMemo(
12944
+ const eventPositions = React29__namespace.useMemo(
11720
12945
  () => calculateMonthEventPositions(multiDayEvents, singleDayEvents, selectedDate),
11721
12946
  [multiDayEvents, singleDayEvents, selectedDate]
11722
12947
  );
@@ -11898,7 +13123,7 @@ function WeekView({
11898
13123
  visibleHours
11899
13124
  } = useEventCalendar();
11900
13125
  const filteredEvents = useFilteredEvents();
11901
- const { singleDayEvents, multiDayEvents } = React27__namespace.useMemo(
13126
+ const { singleDayEvents, multiDayEvents } = React29__namespace.useMemo(
11902
13127
  () => splitEventsByDuration(filteredEvents),
11903
13128
  [filteredEvents]
11904
13129
  );
@@ -12104,8 +13329,8 @@ function CalendarTimeline({
12104
13329
  firstVisibleHour,
12105
13330
  lastVisibleHour
12106
13331
  }) {
12107
- const [currentTime, setCurrentTime] = React27__namespace.useState(/* @__PURE__ */ new Date());
12108
- React27__namespace.useEffect(() => {
13332
+ const [currentTime, setCurrentTime] = React29__namespace.useState(/* @__PURE__ */ new Date());
13333
+ React29__namespace.useEffect(() => {
12109
13334
  const interval = setInterval(() => {
12110
13335
  setCurrentTime(/* @__PURE__ */ new Date());
12111
13336
  }, 6e4);
@@ -12188,7 +13413,7 @@ function DayView({
12188
13413
  visibleHours
12189
13414
  } = useEventCalendar();
12190
13415
  const filteredEvents = useFilteredEvents();
12191
- const { singleDayEvents, multiDayEvents } = React27__namespace.useMemo(
13416
+ const { singleDayEvents, multiDayEvents } = React29__namespace.useMemo(
12192
13417
  () => splitEventsByDuration(filteredEvents),
12193
13418
  [filteredEvents]
12194
13419
  );
@@ -12196,7 +13421,7 @@ function DayView({
12196
13421
  visibleHours,
12197
13422
  singleDayEvents
12198
13423
  );
12199
- const currentEvents = React27__namespace.useMemo(() => {
13424
+ const currentEvents = React29__namespace.useMemo(() => {
12200
13425
  if (!dateFns.isToday(selectedDate)) return [];
12201
13426
  return getCurrentEvents(singleDayEvents);
12202
13427
  }, [singleDayEvents, selectedDate]);
@@ -12420,8 +13645,8 @@ function CalendarTimeline2({
12420
13645
  firstVisibleHour,
12421
13646
  lastVisibleHour
12422
13647
  }) {
12423
- const [currentTime, setCurrentTime] = React27__namespace.useState(/* @__PURE__ */ new Date());
12424
- React27__namespace.useEffect(() => {
13648
+ const [currentTime, setCurrentTime] = React29__namespace.useState(/* @__PURE__ */ new Date());
13649
+ React29__namespace.useEffect(() => {
12425
13650
  const interval = setInterval(() => {
12426
13651
  setCurrentTime(/* @__PURE__ */ new Date());
12427
13652
  }, 6e4);
@@ -12455,7 +13680,7 @@ function YearView({
12455
13680
  }) {
12456
13681
  const { selectedDate, setSelectedDate, setView } = useEventCalendar();
12457
13682
  const filteredEvents = useFilteredEvents();
12458
- const months = React27__namespace.useMemo(() => {
13683
+ const months = React29__namespace.useMemo(() => {
12459
13684
  const yearStart = dateFns.startOfYear(selectedDate);
12460
13685
  return Array.from({ length: 12 }, (_, i) => dateFns.addMonths(yearStart, i));
12461
13686
  }, [selectedDate]);
@@ -12578,11 +13803,11 @@ function AgendaView({
12578
13803
  }) {
12579
13804
  const { selectedDate, setSelectedDate, setView } = useEventCalendar();
12580
13805
  const filteredEvents = useFilteredEvents();
12581
- const { singleDayEvents, multiDayEvents } = React27__namespace.useMemo(
13806
+ const { singleDayEvents, multiDayEvents } = React29__namespace.useMemo(
12582
13807
  () => splitEventsByDuration(filteredEvents),
12583
13808
  [filteredEvents]
12584
13809
  );
12585
- const eventsByDay = React27__namespace.useMemo(() => {
13810
+ const eventsByDay = React29__namespace.useMemo(() => {
12586
13811
  const allDates = /* @__PURE__ */ new Map();
12587
13812
  singleDayEvents.forEach((event) => {
12588
13813
  const eventDate = dateFns.parseISO(event.startDate);
@@ -13047,16 +14272,16 @@ function EventDialog({
13047
14272
  defaultUserId
13048
14273
  }) {
13049
14274
  const { addEvent, updateEvent, deleteEvent, users } = useEventCalendar();
13050
- const [title, setTitle] = React27__namespace.useState("");
13051
- const [description, setDescription] = React27__namespace.useState("");
13052
- const [startDate, setStartDate] = React27__namespace.useState("");
13053
- const [startTime, setStartTime] = React27__namespace.useState("");
13054
- const [endDate, setEndDate] = React27__namespace.useState("");
13055
- const [endTime, setEndTime] = React27__namespace.useState("");
13056
- const [color, setColor] = React27__namespace.useState("blue");
13057
- const [userId, setUserId] = React27__namespace.useState("");
13058
- const [isSubmitting, setIsSubmitting] = React27__namespace.useState(false);
13059
- React27__namespace.useEffect(() => {
14275
+ const [title, setTitle] = React29__namespace.useState("");
14276
+ const [description, setDescription] = React29__namespace.useState("");
14277
+ const [startDate, setStartDate] = React29__namespace.useState("");
14278
+ const [startTime, setStartTime] = React29__namespace.useState("");
14279
+ const [endDate, setEndDate] = React29__namespace.useState("");
14280
+ const [endTime, setEndTime] = React29__namespace.useState("");
14281
+ const [color, setColor] = React29__namespace.useState("blue");
14282
+ const [userId, setUserId] = React29__namespace.useState("");
14283
+ const [isSubmitting, setIsSubmitting] = React29__namespace.useState(false);
14284
+ React29__namespace.useEffect(() => {
13060
14285
  if (open) {
13061
14286
  if (mode === "edit" && event) {
13062
14287
  const start = dateFns.parseISO(event.startDate);
@@ -13279,7 +14504,7 @@ function QuickAddEvent({
13279
14504
  onOpenDialog,
13280
14505
  onClose
13281
14506
  }) {
13282
- const [title, setTitle] = React27__namespace.useState("");
14507
+ const [title, setTitle] = React29__namespace.useState("");
13283
14508
  const { users } = useEventCalendar();
13284
14509
  const handleSubmit = (e) => {
13285
14510
  e.preventDefault();
@@ -13346,8 +14571,8 @@ var HOUR_OPTIONS = Array.from({ length: 25 }, (_, i) => {
13346
14571
  });
13347
14572
  function ChangeVisibleHoursInput() {
13348
14573
  const { visibleHours, setVisibleHours } = useEventCalendar();
13349
- const [from, setFrom] = React27__namespace.useState(visibleHours.from);
13350
- const [to, setTo] = React27__namespace.useState(visibleHours.to);
14574
+ const [from, setFrom] = React29__namespace.useState(visibleHours.from);
14575
+ const [to, setTo] = React29__namespace.useState(visibleHours.to);
13351
14576
  const handleApply = () => {
13352
14577
  const toHour = to === 0 ? 24 : to;
13353
14578
  setVisibleHours({ from, to: toHour });
@@ -13393,7 +14618,7 @@ var HOUR_OPTIONS2 = Array.from({ length: 25 }, (_, i) => {
13393
14618
  });
13394
14619
  function ChangeWorkingHoursInput() {
13395
14620
  const { workingHours, setWorkingHours } = useEventCalendar();
13396
- const [localWorkingHours, setLocalWorkingHours] = React27__namespace.useState({
14621
+ const [localWorkingHours, setLocalWorkingHours] = React29__namespace.useState({
13397
14622
  ...workingHours
13398
14623
  });
13399
14624
  const handleToggleDay = (dayId) => {
@@ -13542,8 +14767,8 @@ function CalendarSettingsButton({
13542
14767
  );
13543
14768
  }
13544
14769
  function useMediaQuery(query) {
13545
- const [matches, setMatches] = React27__namespace.useState(false);
13546
- React27__namespace.useEffect(() => {
14770
+ const [matches, setMatches] = React29__namespace.useState(false);
14771
+ React29__namespace.useEffect(() => {
13547
14772
  const media = window.matchMedia(query);
13548
14773
  setMatches(media.matches);
13549
14774
  const listener = (event) => {
@@ -13595,11 +14820,11 @@ function BigCalendarInner({
13595
14820
  maxEventsPerDay
13596
14821
  }) {
13597
14822
  const { view, setView } = useEventCalendar();
13598
- const [dialogOpen, setDialogOpen] = React27__namespace.useState(false);
13599
- const [settingsDialogOpen, setSettingsDialogOpen] = React27__namespace.useState(false);
13600
- const [selectedEvent, setSelectedEvent] = React27__namespace.useState(null);
13601
- const [dialogMode, setDialogMode] = React27__namespace.useState("add");
13602
- const [defaultDate, setDefaultDate] = React27__namespace.useState(/* @__PURE__ */ new Date());
14823
+ const [dialogOpen, setDialogOpen] = React29__namespace.useState(false);
14824
+ const [settingsDialogOpen, setSettingsDialogOpen] = React29__namespace.useState(false);
14825
+ const [selectedEvent, setSelectedEvent] = React29__namespace.useState(null);
14826
+ const [dialogMode, setDialogMode] = React29__namespace.useState("add");
14827
+ const [defaultDate, setDefaultDate] = React29__namespace.useState(/* @__PURE__ */ new Date());
13603
14828
  const isMobile = useMediaQuery("(max-width: 768px)");
13604
14829
  const isCompact = compact === "auto" ? isMobile : compact;
13605
14830
  const handleAddClick = () => {
@@ -13886,7 +15111,7 @@ var calculateInnerOffset = (date, range, columnWidth) => {
13886
15111
  const dayOfMonth = date.getDate();
13887
15112
  return dayOfMonth / totalRangeDays * columnWidth;
13888
15113
  };
13889
- var GanttContext = React27.createContext({
15114
+ var GanttContext = React29.createContext({
13890
15115
  zoom: 100,
13891
15116
  range: "monthly",
13892
15117
  columnWidth: 50,
@@ -13907,11 +15132,11 @@ var GanttContentHeader = ({
13907
15132
  columns,
13908
15133
  renderHeaderItem
13909
15134
  }) => {
13910
- const id = React27.useId();
15135
+ const id = React29.useId();
13911
15136
  return /* @__PURE__ */ jsxRuntime.jsxs(
13912
15137
  "div",
13913
15138
  {
13914
- className: "sticky top-0 z-20 grid w-full shrink-0 bg-background/95 backdrop-blur-sm",
15139
+ className: "sticky top-0 z-20 grid w-full shrink-0 bg-muted/80 backdrop-blur-sm",
13915
15140
  style: { height: "var(--gantt-header-height)" },
13916
15141
  children: [
13917
15142
  /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -13955,8 +15180,8 @@ var getWeekStartDate = (year, weekNumber) => {
13955
15180
  return dateFns.addWeeks(week1Start, weekNumber - 1);
13956
15181
  };
13957
15182
  var WeeklyHeader = () => {
13958
- const gantt = React27.useContext(GanttContext);
13959
- const weeklyData = React27.useMemo(() => {
15183
+ const gantt = React29.useContext(GanttContext);
15184
+ const weeklyData = React29.useMemo(() => {
13960
15185
  const result = [];
13961
15186
  for (const yearData of gantt.timelineData) {
13962
15187
  const year = yearData.year;
@@ -13991,7 +15216,7 @@ var WeeklyHeader = () => {
13991
15216
  ] }, yearData.year));
13992
15217
  };
13993
15218
  var MonthlyHeader = () => {
13994
- const gantt = React27.useContext(GanttContext);
15219
+ const gantt = React29.useContext(GanttContext);
13995
15220
  return gantt.timelineData.map((year) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex flex-col", children: [
13996
15221
  /* @__PURE__ */ jsxRuntime.jsx(
13997
15222
  GanttContentHeader,
@@ -14010,7 +15235,7 @@ var MonthlyHeader = () => {
14010
15235
  ] }, year.year));
14011
15236
  };
14012
15237
  var QuarterlyHeader = () => {
14013
- const gantt = React27.useContext(GanttContext);
15238
+ const gantt = React29.useContext(GanttContext);
14014
15239
  return gantt.timelineData.map(
14015
15240
  (year) => year.quarters.map((quarter, quarterIndex) => /* @__PURE__ */ jsxRuntime.jsxs(
14016
15241
  "div",
@@ -14038,7 +15263,7 @@ var headers = {
14038
15263
  quarterly: QuarterlyHeader
14039
15264
  };
14040
15265
  var GanttHeader = ({ className }) => {
14041
- const gantt = React27.useContext(GanttContext);
15266
+ const gantt = React29.useContext(GanttContext);
14042
15267
  const Header2 = headers[gantt.range];
14043
15268
  return /* @__PURE__ */ jsxRuntime.jsx(
14044
15269
  "div",
@@ -14056,7 +15281,7 @@ var GanttSidebarItem = ({
14056
15281
  onSelectItem,
14057
15282
  className
14058
15283
  }) => {
14059
- const gantt = React27.useContext(GanttContext);
15284
+ const gantt = React29.useContext(GanttContext);
14060
15285
  const tempEndAt = feature.endAt && dateFns.isSameDay(feature.startAt, feature.endAt) ? dateFns.addDays(feature.endAt, 1) : feature.endAt;
14061
15286
  const duration = tempEndAt ? dateFns.formatDistance(feature.startAt, tempEndAt) : `${dateFns.formatDistance(feature.startAt, /* @__PURE__ */ new Date())} so far`;
14062
15287
  const handleClick = (event) => {
@@ -14108,7 +15333,7 @@ var GanttSidebarHeader = ({
14108
15333
  }) => /* @__PURE__ */ jsxRuntime.jsxs(
14109
15334
  "div",
14110
15335
  {
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",
15336
+ 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
15337
  style: { height: "var(--gantt-header-height)" },
14113
15338
  children: [
14114
15339
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "flex-1 truncate text-left", children: title }),
@@ -14132,24 +15357,24 @@ function computeGroupRange(features) {
14132
15357
  }
14133
15358
  return { start: minStart, end: maxEnd };
14134
15359
  }
14135
- var GanttGroupSummaryBar = React27.memo(({
15360
+ var GanttGroupSummaryBar = React29.memo(({
14136
15361
  group,
14137
15362
  className
14138
15363
  }) => {
14139
- const gantt = React27.useContext(GanttContext);
14140
- const timelineStartDate = React27.useMemo(
15364
+ const gantt = React29.useContext(GanttContext);
15365
+ const timelineStartDate = React29.useMemo(
14141
15366
  () => new Date(gantt.timelineData.at(0)?.year ?? 0, 0, 1),
14142
15367
  [gantt.timelineData]
14143
15368
  );
14144
- const { start: groupStart, end: groupEnd } = React27.useMemo(
15369
+ const { start: groupStart, end: groupEnd } = React29.useMemo(
14145
15370
  () => computeGroupRange(group.features),
14146
15371
  [group.features]
14147
15372
  );
14148
- const offset = React27.useMemo(() => {
15373
+ const offset = React29.useMemo(() => {
14149
15374
  if (!groupStart) return 0;
14150
15375
  return Math.round(getOffset(groupStart, timelineStartDate, gantt));
14151
15376
  }, [groupStart, timelineStartDate, gantt]);
14152
- const width = React27.useMemo(() => {
15377
+ const width = React29.useMemo(() => {
14153
15378
  if (!groupStart || !groupEnd) return 0;
14154
15379
  return Math.round(getWidth(groupStart, groupEnd, gantt));
14155
15380
  }, [groupStart, groupEnd, gantt]);
@@ -14172,11 +15397,12 @@ var GanttGroupSummaryBar = React27.memo(({
14172
15397
  children: /* @__PURE__ */ jsxRuntime.jsx(
14173
15398
  "div",
14174
15399
  {
14175
- className: "h-full w-full rounded-sm border border-border/60 bg-muted/40 shadow-sm",
15400
+ className: "relative h-full w-full rounded-sm border border-border/60 bg-muted/40 shadow-sm overflow-hidden",
14176
15401
  style: {
14177
15402
  // Subtle gradient for depth
14178
15403
  background: "linear-gradient(180deg, hsl(var(--muted) / 0.5) 0%, hsl(var(--muted) / 0.3) 100%)"
14179
- }
15404
+ },
15405
+ 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
15406
  }
14181
15407
  )
14182
15408
  }
@@ -14188,13 +15414,13 @@ var GanttCollapsibleSidebarGroup = ({
14188
15414
  children,
14189
15415
  className
14190
15416
  }) => {
14191
- const gantt = React27.useContext(GanttContext);
15417
+ const gantt = React29.useContext(GanttContext);
14192
15418
  const isExpanded = gantt.expandedGroups[group.id] ?? true;
14193
- const { start: groupStart, end: groupEnd } = React27.useMemo(
15419
+ const { start: groupStart, end: groupEnd } = React29.useMemo(
14194
15420
  () => computeGroupRange(group.features),
14195
15421
  [group.features]
14196
15422
  );
14197
- const duration = React27.useMemo(() => {
15423
+ const duration = React29.useMemo(() => {
14198
15424
  if (!groupStart || !groupEnd) return null;
14199
15425
  return dateFns.formatDistance(groupStart, groupEnd);
14200
15426
  }, [groupStart, groupEnd]);
@@ -14208,7 +15434,7 @@ var GanttCollapsibleSidebarGroup = ({
14208
15434
  /* @__PURE__ */ jsxRuntime.jsx(CollapsibleTrigger2, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
14209
15435
  "button",
14210
15436
  {
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",
15437
+ 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
15438
  style: { height: "var(--gantt-row-height)" },
14213
15439
  type: "button",
14214
15440
  children: [
@@ -14238,7 +15464,7 @@ var GanttCollapsibleTimelineGroup = ({
14238
15464
  children,
14239
15465
  className
14240
15466
  }) => {
14241
- const gantt = React27.useContext(GanttContext);
15467
+ const gantt = React29.useContext(GanttContext);
14242
15468
  const isExpanded = gantt.expandedGroups[group.id] ?? true;
14243
15469
  return /* @__PURE__ */ jsxRuntime.jsxs(
14244
15470
  Collapsible,
@@ -14250,7 +15476,7 @@ var GanttCollapsibleTimelineGroup = ({
14250
15476
  /* @__PURE__ */ jsxRuntime.jsx(
14251
15477
  "div",
14252
15478
  {
14253
- className: "relative w-full border-b border-border/50",
15479
+ className: "relative w-full border-b border-border/50 bg-muted/20",
14254
15480
  style: { height: "var(--gantt-row-height)" },
14255
15481
  children: /* @__PURE__ */ jsxRuntime.jsx(GanttGroupSummaryBar, { group })
14256
15482
  }
@@ -14268,7 +15494,7 @@ var GanttSidebarGroup = ({
14268
15494
  /* @__PURE__ */ jsxRuntime.jsx(
14269
15495
  "p",
14270
15496
  {
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",
15497
+ 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
15498
  style: { height: "var(--gantt-row-height)" },
14273
15499
  children: name
14274
15500
  }
@@ -14282,7 +15508,7 @@ var GanttSidebar = ({
14282
15508
  "div",
14283
15509
  {
14284
15510
  className: cn(
14285
- "sticky left-0 z-30 h-max min-h-full border-border/50 border-r bg-background",
15511
+ "sticky left-0 z-30 h-max min-h-full border-border/50 border-r bg-muted/50",
14286
15512
  className
14287
15513
  ),
14288
15514
  style: { width: "var(--gantt-sidebar-width)" },
@@ -14298,7 +15524,7 @@ var GanttAddFeatureHelper = ({
14298
15524
  className
14299
15525
  }) => {
14300
15526
  const [scrollX] = useGanttScrollX();
14301
- const gantt = React27.useContext(GanttContext);
15527
+ const gantt = React29.useContext(GanttContext);
14302
15528
  const [mousePosition, mouseRef] = usehooks.useMouse();
14303
15529
  const handleClick = () => {
14304
15530
  const ganttRect = gantt.ref?.current?.getBoundingClientRect();
@@ -14337,10 +15563,10 @@ var GanttColumn = ({
14337
15563
  index,
14338
15564
  isColumnSecondary
14339
15565
  }) => {
14340
- const gantt = React27.useContext(GanttContext);
15566
+ const gantt = React29.useContext(GanttContext);
14341
15567
  const [dragging] = useGanttDragging();
14342
15568
  const [mousePosition, mouseRef] = usehooks.useMouse();
14343
- const [hovering, setHovering] = React27.useState(false);
15569
+ const [hovering, setHovering] = React29.useState(false);
14344
15570
  const [windowScroll] = usehooks.useWindowScroll();
14345
15571
  const handleMouseEnter = () => setHovering(true);
14346
15572
  const handleMouseLeave = () => setHovering(false);
@@ -14370,7 +15596,7 @@ var GanttColumns = ({
14370
15596
  columns,
14371
15597
  isColumnSecondary
14372
15598
  }) => {
14373
- const id = React27.useId();
15599
+ const id = React29.useId();
14374
15600
  return /* @__PURE__ */ jsxRuntime.jsx(
14375
15601
  "div",
14376
15602
  {
@@ -14389,12 +15615,12 @@ var GanttColumns = ({
14389
15615
  }
14390
15616
  );
14391
15617
  };
14392
- var GanttGridLines = React27.memo(({
15618
+ var GanttGridLines = React29.memo(({
14393
15619
  className
14394
15620
  }) => {
14395
- const gantt = React27.useContext(GanttContext);
14396
- const id = React27.useId();
14397
- const { columns, monthBoundaryIndices } = React27.useMemo(() => {
15621
+ const gantt = React29.useContext(GanttContext);
15622
+ const id = React29.useId();
15623
+ const { columns, monthBoundaryIndices } = React29.useMemo(() => {
14398
15624
  let totalColumns = 0;
14399
15625
  const monthIndices = [];
14400
15626
  if (gantt.range === "weekly") {
@@ -14458,7 +15684,7 @@ var GanttCreateMarkerTrigger = ({
14458
15684
  onCreateMarker,
14459
15685
  className
14460
15686
  }) => {
14461
- const gantt = React27.useContext(GanttContext);
15687
+ const gantt = React29.useContext(GanttContext);
14462
15688
  const [mousePosition, mouseRef] = usehooks.useMouse();
14463
15689
  const [windowScroll] = usehooks.useWindowScroll();
14464
15690
  const x = usehooks.useThrottle(
@@ -14507,7 +15733,7 @@ var GanttFeatureDragHelper = ({
14507
15733
  id: `feature-drag-helper-${featureId}`
14508
15734
  });
14509
15735
  const isPressed = Boolean(attributes["aria-pressed"]);
14510
- React27.useEffect(() => setDragging(isPressed), [isPressed, setDragging]);
15736
+ React29.useEffect(() => setDragging(isPressed), [isPressed, setDragging]);
14511
15737
  return /* @__PURE__ */ jsxRuntime.jsxs(
14512
15738
  "div",
14513
15739
  {
@@ -14553,7 +15779,7 @@ var GanttFeatureItemCard = ({
14553
15779
  const [, setDragging] = useGanttDragging();
14554
15780
  const { attributes, listeners, setNodeRef } = core.useDraggable({ id });
14555
15781
  const isPressed = Boolean(attributes["aria-pressed"]);
14556
- React27.useEffect(() => setDragging(isPressed), [isPressed, setDragging]);
15782
+ React29.useEffect(() => setDragging(isPressed), [isPressed, setDragging]);
14557
15783
  return /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "h-full w-full rounded-sm border bg-background px-2 py-1.5 text-xs shadow-sm overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
14558
15784
  "div",
14559
15785
  {
@@ -14579,37 +15805,37 @@ var GanttFeatureItem = ({
14579
15805
  ...feature
14580
15806
  }) => {
14581
15807
  const [scrollX] = useGanttScrollX();
14582
- const gantt = React27.useContext(GanttContext);
14583
- const timelineStartDate = React27.useMemo(
15808
+ const gantt = React29.useContext(GanttContext);
15809
+ const timelineStartDate = React29.useMemo(
14584
15810
  () => new Date(gantt.timelineData.at(0)?.year ?? 0, 0, 1),
14585
15811
  [gantt.timelineData]
14586
15812
  );
14587
- const [startAt, setStartAt] = React27.useState(feature.startAt);
14588
- const [endAt, setEndAt] = React27.useState(feature.endAt);
14589
- const width = React27.useMemo(
15813
+ const [startAt, setStartAt] = React29.useState(feature.startAt);
15814
+ const [endAt, setEndAt] = React29.useState(feature.endAt);
15815
+ const width = React29.useMemo(
14590
15816
  () => Math.round(getWidth(startAt, endAt, gantt)),
14591
15817
  [startAt, endAt, gantt]
14592
15818
  );
14593
- const offset = React27.useMemo(
15819
+ const offset = React29.useMemo(
14594
15820
  () => Math.round(getOffset(startAt, timelineStartDate, gantt)),
14595
15821
  [startAt, timelineStartDate, gantt]
14596
15822
  );
14597
- const addRange = React27.useMemo(() => getAddRange(gantt.range), [gantt.range]);
15823
+ const addRange = React29.useMemo(() => getAddRange(gantt.range), [gantt.range]);
14598
15824
  const [mousePosition] = usehooks.useMouse();
14599
- const [previousMouseX, setPreviousMouseX] = React27.useState(0);
14600
- const [previousStartAt, setPreviousStartAt] = React27.useState(startAt);
14601
- const [previousEndAt, setPreviousEndAt] = React27.useState(endAt);
15825
+ const [previousMouseX, setPreviousMouseX] = React29.useState(0);
15826
+ const [previousStartAt, setPreviousStartAt] = React29.useState(startAt);
15827
+ const [previousEndAt, setPreviousEndAt] = React29.useState(endAt);
14602
15828
  const mouseSensor = core.useSensor(core.MouseSensor, {
14603
15829
  activationConstraint: {
14604
15830
  distance: 10
14605
15831
  }
14606
15832
  });
14607
- const handleItemDragStart = React27.useCallback(() => {
15833
+ const handleItemDragStart = React29.useCallback(() => {
14608
15834
  setPreviousMouseX(mousePosition.x);
14609
15835
  setPreviousStartAt(startAt);
14610
15836
  setPreviousEndAt(endAt);
14611
15837
  }, [mousePosition.x, startAt, endAt]);
14612
- const handleItemDragMove = React27.useCallback(() => {
15838
+ const handleItemDragMove = React29.useCallback(() => {
14613
15839
  const currentDate = getDateByMousePosition(gantt, mousePosition.x);
14614
15840
  const originalDate = getDateByMousePosition(gantt, previousMouseX);
14615
15841
  const delta = gantt.range === "weekly" ? dateFns.differenceInDays(currentDate, originalDate) : getInnerDifferenceIn(gantt.range)(currentDate, originalDate);
@@ -14618,17 +15844,17 @@ var GanttFeatureItem = ({
14618
15844
  setStartAt(newStartDate);
14619
15845
  setEndAt(newEndDate);
14620
15846
  }, [gantt, mousePosition.x, previousMouseX, previousStartAt, previousEndAt]);
14621
- const onDragEnd = React27.useCallback(
15847
+ const onDragEnd = React29.useCallback(
14622
15848
  () => onMove?.(feature.id, startAt, endAt),
14623
15849
  [onMove, feature.id, startAt, endAt]
14624
15850
  );
14625
- const handleLeftDragMove = React27.useCallback(() => {
15851
+ const handleLeftDragMove = React29.useCallback(() => {
14626
15852
  const ganttRect = gantt.ref?.current?.getBoundingClientRect();
14627
15853
  const x = mousePosition.x - (ganttRect?.left ?? 0) + scrollX - gantt.sidebarWidth;
14628
15854
  const newStartAt = getDateByMousePosition(gantt, x);
14629
15855
  setStartAt(newStartAt);
14630
15856
  }, [gantt, mousePosition.x, scrollX]);
14631
- const handleRightDragMove = React27.useCallback(() => {
15857
+ const handleRightDragMove = React29.useCallback(() => {
14632
15858
  const ganttRect = gantt.ref?.current?.getBoundingClientRect();
14633
15859
  const x = mousePosition.x - (ganttRect?.left ?? 0) + scrollX - gantt.sidebarWidth;
14634
15860
  const newEndAt = getDateByMousePosition(gantt, x);
@@ -14824,21 +16050,21 @@ var GanttFeatureList = ({
14824
16050
  children
14825
16051
  }
14826
16052
  );
14827
- var GanttMarker = React27.memo(({ label, date, id, onRemove, className }) => {
14828
- const gantt = React27.useContext(GanttContext);
14829
- const differenceIn = React27.useMemo(
16053
+ var GanttMarker = React29.memo(({ label, date, id, onRemove, className }) => {
16054
+ const gantt = React29.useContext(GanttContext);
16055
+ const differenceIn = React29.useMemo(
14830
16056
  () => getDifferenceIn(gantt.range),
14831
16057
  [gantt.range]
14832
16058
  );
14833
- const timelineStartDate = React27.useMemo(
16059
+ const timelineStartDate = React29.useMemo(
14834
16060
  () => new Date(gantt.timelineData.at(0)?.year ?? 0, 0, 1),
14835
16061
  [gantt.timelineData]
14836
16062
  );
14837
- const offset = React27.useMemo(
16063
+ const offset = React29.useMemo(
14838
16064
  () => differenceIn(date, timelineStartDate),
14839
16065
  [differenceIn, date, timelineStartDate]
14840
16066
  );
14841
- const innerOffset = React27.useMemo(
16067
+ const innerOffset = React29.useMemo(
14842
16068
  () => calculateInnerOffset(
14843
16069
  date,
14844
16070
  gantt.range,
@@ -14846,7 +16072,7 @@ var GanttMarker = React27.memo(({ label, date, id, onRemove, className }) => {
14846
16072
  ),
14847
16073
  [date, gantt.range, gantt.columnWidth, gantt.zoom]
14848
16074
  );
14849
- const handleRemove = React27.useCallback(() => onRemove?.(id), [onRemove, id]);
16075
+ const handleRemove = React29.useCallback(() => onRemove?.(id), [onRemove, id]);
14850
16076
  return /* @__PURE__ */ jsxRuntime.jsxs(
14851
16077
  "div",
14852
16078
  {
@@ -14896,14 +16122,14 @@ var GanttProvider = ({
14896
16122
  className,
14897
16123
  defaultExpandedGroups = {}
14898
16124
  }) => {
14899
- const scrollRef = React27.useRef(null);
14900
- const [timelineData, setTimelineData] = React27.useState(
16125
+ const scrollRef = React29.useRef(null);
16126
+ const [timelineData, setTimelineData] = React29.useState(
14901
16127
  createInitialTimelineData(/* @__PURE__ */ new Date())
14902
16128
  );
14903
16129
  const [, setScrollX] = useGanttScrollX();
14904
16130
  const sidebarWidth = 280;
14905
- const [expandedGroups, setExpandedGroups] = React27.useState(defaultExpandedGroups);
14906
- const setGroupExpanded = React27.useCallback((groupId, expanded) => {
16131
+ const [expandedGroups, setExpandedGroups] = React29.useState(defaultExpandedGroups);
16132
+ const setGroupExpanded = React29.useCallback((groupId, expanded) => {
14907
16133
  setExpandedGroups((prev) => ({ ...prev, [groupId]: expanded }));
14908
16134
  }, []);
14909
16135
  const headerHeight = 60;
@@ -14914,7 +16140,7 @@ var GanttProvider = ({
14914
16140
  } else if (range === "quarterly") {
14915
16141
  columnWidth = 100;
14916
16142
  }
14917
- const cssVariables = React27.useMemo(
16143
+ const cssVariables = React29.useMemo(
14918
16144
  () => ({
14919
16145
  "--gantt-zoom": `${zoom}`,
14920
16146
  "--gantt-column-width": `${zoom / 100 * columnWidth}px`,
@@ -14924,13 +16150,13 @@ var GanttProvider = ({
14924
16150
  }),
14925
16151
  [zoom, columnWidth, sidebarWidth]
14926
16152
  );
14927
- React27.useEffect(() => {
16153
+ React29.useEffect(() => {
14928
16154
  if (scrollRef.current) {
14929
16155
  scrollRef.current.scrollLeft = scrollRef.current.scrollWidth / 2 - scrollRef.current.clientWidth / 2;
14930
16156
  setScrollX(scrollRef.current.scrollLeft);
14931
16157
  }
14932
16158
  }, [setScrollX]);
14933
- const handleScroll = React27.useCallback(
16159
+ const handleScroll = React29.useCallback(
14934
16160
  throttle__default.default(() => {
14935
16161
  const scrollElement = scrollRef.current;
14936
16162
  if (!scrollElement) {
@@ -14982,7 +16208,7 @@ var GanttProvider = ({
14982
16208
  }, 100),
14983
16209
  []
14984
16210
  );
14985
- React27.useEffect(() => {
16211
+ React29.useEffect(() => {
14986
16212
  const scrollElement = scrollRef.current;
14987
16213
  if (scrollElement) {
14988
16214
  scrollElement.addEventListener("scroll", handleScroll);
@@ -14993,7 +16219,7 @@ var GanttProvider = ({
14993
16219
  }
14994
16220
  };
14995
16221
  }, [handleScroll]);
14996
- const scrollToFeature = React27.useCallback(
16222
+ const scrollToFeature = React29.useCallback(
14997
16223
  (feature) => {
14998
16224
  const scrollElement = scrollRef.current;
14999
16225
  if (!scrollElement) {
@@ -15073,21 +16299,21 @@ var GanttTimeline = ({
15073
16299
  );
15074
16300
  var GanttToday = ({ className }) => {
15075
16301
  const label = "Today";
15076
- const date = React27.useMemo(() => /* @__PURE__ */ new Date(), []);
15077
- const gantt = React27.useContext(GanttContext);
15078
- const differenceIn = React27.useMemo(
16302
+ const date = React29.useMemo(() => /* @__PURE__ */ new Date(), []);
16303
+ const gantt = React29.useContext(GanttContext);
16304
+ const differenceIn = React29.useMemo(
15079
16305
  () => getDifferenceIn(gantt.range),
15080
16306
  [gantt.range]
15081
16307
  );
15082
- const timelineStartDate = React27.useMemo(
16308
+ const timelineStartDate = React29.useMemo(
15083
16309
  () => new Date(gantt.timelineData.at(0)?.year ?? 0, 0, 1),
15084
16310
  [gantt.timelineData]
15085
16311
  );
15086
- const offset = React27.useMemo(
16312
+ const offset = React29.useMemo(
15087
16313
  () => differenceIn(date, timelineStartDate),
15088
16314
  [differenceIn, date, timelineStartDate]
15089
16315
  );
15090
- const innerOffset = React27.useMemo(
16316
+ const innerOffset = React29.useMemo(
15091
16317
  () => Math.round(calculateInnerOffset(
15092
16318
  date,
15093
16319
  gantt.range,
@@ -15123,7 +16349,7 @@ var GanttToday = ({ className }) => {
15123
16349
  );
15124
16350
  };
15125
16351
  var t = tunnel__default.default();
15126
- var KanbanContext = React27.createContext({
16352
+ var KanbanContext = React29.createContext({
15127
16353
  columns: [],
15128
16354
  data: [],
15129
16355
  activeCardId: null
@@ -15161,7 +16387,7 @@ var KanbanCard = ({
15161
16387
  } = sortable.useSortable({
15162
16388
  id
15163
16389
  });
15164
- const { activeCardId } = React27.useContext(KanbanContext);
16390
+ const { activeCardId } = React29.useContext(KanbanContext);
15165
16391
  const style = {
15166
16392
  transition,
15167
16393
  transform: utilities.CSS.Transform.toString(transform)
@@ -15196,7 +16422,7 @@ var KanbanCards = ({
15196
16422
  className,
15197
16423
  ...props
15198
16424
  }) => {
15199
- const { data } = React27.useContext(KanbanContext);
16425
+ const { data } = React29.useContext(KanbanContext);
15200
16426
  const filteredData = data.filter((item) => item.column === props.id);
15201
16427
  const items = filteredData.map((item) => item.id);
15202
16428
  return /* @__PURE__ */ jsxRuntime.jsxs(ScrollArea, { className: "overflow-hidden", children: [
@@ -15223,7 +16449,7 @@ var KanbanProvider = ({
15223
16449
  onDataChange,
15224
16450
  ...props
15225
16451
  }) => {
15226
- const [activeCardId, setActiveCardId] = React27.useState(null);
16452
+ const [activeCardId, setActiveCardId] = React29.useState(null);
15227
16453
  const sensors = core.useSensors(
15228
16454
  core.useSensor(core.MouseSensor),
15229
16455
  core.useSensor(core.TouchSensor),
@@ -15732,6 +16958,7 @@ exports.SiteHeader = SiteHeader;
15732
16958
  exports.Skeleton = Skeleton;
15733
16959
  exports.Slider = Slider;
15734
16960
  exports.Spinner = Spinner;
16961
+ exports.StatusProgress = StatusProgress;
15735
16962
  exports.SubmitCalibrationBar = SubmitCalibrationBar;
15736
16963
  exports.SupplierCell = SupplierCell;
15737
16964
  exports.SupplierWeeklyLoading = SupplierWeeklyLoading;
@@ -15767,6 +16994,7 @@ exports.UserAvatarsDropdown = UserAvatarsDropdown;
15767
16994
  exports.VIEW_LABELS = VIEW_LABELS;
15768
16995
  exports.WeekCell = WeekCell;
15769
16996
  exports.WeekDetailDialog = WeekDetailDialog;
16997
+ exports.WeekDetailSheet = WeekDetailSheet;
15770
16998
  exports.WeekHeader = WeekHeader;
15771
16999
  exports.WeekView = WeekView;
15772
17000
  exports.WeeklyLoadingView = WeeklyLoadingView;