@j3m-quantum/ui 1.5.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var React15 = require('react');
3
+ var React22 = 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');
@@ -40,6 +40,7 @@ var PopoverPrimitive = require('@radix-ui/react-popover');
40
40
  var HoverCardPrimitive = require('@radix-ui/react-hover-card');
41
41
  var CollapsiblePrimitive = require('@radix-ui/react-collapsible');
42
42
  var ResizablePrimitive = require('react-resizable-panels');
43
+ var reactTable = require('@tanstack/react-table');
43
44
  var dateFns = require('date-fns');
44
45
 
45
46
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -62,7 +63,7 @@ function _interopNamespace(e) {
62
63
  return Object.freeze(n);
63
64
  }
64
65
 
65
- var React15__namespace = /*#__PURE__*/_interopNamespace(React15);
66
+ var React22__namespace = /*#__PURE__*/_interopNamespace(React22);
66
67
  var SeparatorPrimitive__namespace = /*#__PURE__*/_interopNamespace(SeparatorPrimitive);
67
68
  var CheckboxPrimitive__namespace = /*#__PURE__*/_interopNamespace(CheckboxPrimitive);
68
69
  var RadioGroupPrimitive__namespace = /*#__PURE__*/_interopNamespace(RadioGroupPrimitive);
@@ -95,8 +96,8 @@ var ResizablePrimitive__namespace = /*#__PURE__*/_interopNamespace(ResizablePrim
95
96
  // src/hooks/use-mobile.ts
96
97
  var MOBILE_BREAKPOINT = 768;
97
98
  function useIsMobile() {
98
- const [isMobile, setIsMobile] = React15__namespace.useState(void 0);
99
- React15__namespace.useEffect(() => {
99
+ const [isMobile, setIsMobile] = React22__namespace.useState(void 0);
100
+ React22__namespace.useEffect(() => {
100
101
  const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
101
102
  const onChange = () => {
102
103
  setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
@@ -137,7 +138,7 @@ var buttonVariants = classVarianceAuthority.cva(
137
138
  }
138
139
  }
139
140
  );
140
- var Button = React15__namespace.forwardRef(
141
+ var Button = React22__namespace.forwardRef(
141
142
  ({ className, variant, size, asChild = false, ...props }, ref) => {
142
143
  const Comp = asChild ? reactSlot.Slot : "button";
143
144
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -501,7 +502,7 @@ function Slider({
501
502
  max = 100,
502
503
  ...props
503
504
  }) {
504
- const _values = React15__namespace.useMemo(
505
+ const _values = React22__namespace.useMemo(
505
506
  () => Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min, max],
506
507
  [value, defaultValue, min, max]
507
508
  );
@@ -787,7 +788,7 @@ function Toggle({
787
788
  }
788
789
  );
789
790
  }
790
- var ToggleGroupContext = React15__namespace.createContext({
791
+ var ToggleGroupContext = React22__namespace.createContext({
791
792
  size: "default",
792
793
  variant: "default",
793
794
  spacing: 0
@@ -824,7 +825,7 @@ function ToggleGroupItem({
824
825
  size,
825
826
  ...props
826
827
  }) {
827
- const context = React15__namespace.useContext(ToggleGroupContext);
828
+ const context = React22__namespace.useContext(ToggleGroupContext);
828
829
  return /* @__PURE__ */ jsxRuntime.jsx(
829
830
  ToggleGroupPrimitive__namespace.Item,
830
831
  {
@@ -854,7 +855,7 @@ function ThemeSwitch({
854
855
  className,
855
856
  size = "default"
856
857
  }) {
857
- const [isChecked, setIsChecked] = React15__namespace.useState(defaultChecked);
858
+ const [isChecked, setIsChecked] = React22__namespace.useState(defaultChecked);
858
859
  const isControlled = checked !== void 0;
859
860
  const currentChecked = isControlled ? checked : isChecked;
860
861
  const handleClick = () => {
@@ -1274,7 +1275,7 @@ function Label2({
1274
1275
  );
1275
1276
  }
1276
1277
  var Form = reactHookForm.FormProvider;
1277
- var FormFieldContext = React15__namespace.createContext(
1278
+ var FormFieldContext = React22__namespace.createContext(
1278
1279
  {}
1279
1280
  );
1280
1281
  var FormField = ({
@@ -1283,8 +1284,8 @@ var FormField = ({
1283
1284
  return /* @__PURE__ */ jsxRuntime.jsx(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsxRuntime.jsx(reactHookForm.Controller, { ...props }) });
1284
1285
  };
1285
1286
  var useFormField = () => {
1286
- const fieldContext = React15__namespace.useContext(FormFieldContext);
1287
- const itemContext = React15__namespace.useContext(FormItemContext);
1287
+ const fieldContext = React22__namespace.useContext(FormFieldContext);
1288
+ const itemContext = React22__namespace.useContext(FormItemContext);
1288
1289
  const { getFieldState } = reactHookForm.useFormContext();
1289
1290
  const formState = reactHookForm.useFormState({ name: fieldContext.name });
1290
1291
  const fieldState = getFieldState(fieldContext.name, formState);
@@ -1301,11 +1302,11 @@ var useFormField = () => {
1301
1302
  ...fieldState
1302
1303
  };
1303
1304
  };
1304
- var FormItemContext = React15__namespace.createContext(
1305
+ var FormItemContext = React22__namespace.createContext(
1305
1306
  {}
1306
1307
  );
1307
1308
  function FormItem({ className, ...props }) {
1308
- const id = React15__namespace.useId();
1309
+ const id = React22__namespace.useId();
1309
1310
  return /* @__PURE__ */ jsxRuntime.jsx(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsxRuntime.jsx(
1310
1311
  "div",
1311
1312
  {
@@ -1553,7 +1554,7 @@ function FieldError({
1553
1554
  errors,
1554
1555
  ...props
1555
1556
  }) {
1556
- const content = React15.useMemo(() => {
1557
+ const content = React22.useMemo(() => {
1557
1558
  if (children) {
1558
1559
  return children;
1559
1560
  }
@@ -2407,8 +2408,8 @@ function CalendarDayButton({
2407
2408
  modifiers,
2408
2409
  ...props
2409
2410
  }) {
2410
- const ref = React15__namespace.useRef(null);
2411
- React15__namespace.useEffect(() => {
2411
+ const ref = React22__namespace.useRef(null);
2412
+ React22__namespace.useEffect(() => {
2412
2413
  if (modifiers.focused) ref.current?.focus();
2413
2414
  }, [modifiers.focused]);
2414
2415
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -2429,9 +2430,9 @@ function CalendarDayButton({
2429
2430
  }
2430
2431
  );
2431
2432
  }
2432
- var CarouselContext = React15__namespace.createContext(null);
2433
+ var CarouselContext = React22__namespace.createContext(null);
2433
2434
  function useCarousel() {
2434
- const context = React15__namespace.useContext(CarouselContext);
2435
+ const context = React22__namespace.useContext(CarouselContext);
2435
2436
  if (!context) {
2436
2437
  throw new Error("useCarousel must be used within a <Carousel />");
2437
2438
  }
@@ -2453,20 +2454,20 @@ function Carousel({
2453
2454
  },
2454
2455
  plugins
2455
2456
  );
2456
- const [canScrollPrev, setCanScrollPrev] = React15__namespace.useState(false);
2457
- const [canScrollNext, setCanScrollNext] = React15__namespace.useState(false);
2458
- const onSelect = React15__namespace.useCallback((api2) => {
2457
+ const [canScrollPrev, setCanScrollPrev] = React22__namespace.useState(false);
2458
+ const [canScrollNext, setCanScrollNext] = React22__namespace.useState(false);
2459
+ const onSelect = React22__namespace.useCallback((api2) => {
2459
2460
  if (!api2) return;
2460
2461
  setCanScrollPrev(api2.canScrollPrev());
2461
2462
  setCanScrollNext(api2.canScrollNext());
2462
2463
  }, []);
2463
- const scrollPrev = React15__namespace.useCallback(() => {
2464
+ const scrollPrev = React22__namespace.useCallback(() => {
2464
2465
  api?.scrollPrev();
2465
2466
  }, [api]);
2466
- const scrollNext = React15__namespace.useCallback(() => {
2467
+ const scrollNext = React22__namespace.useCallback(() => {
2467
2468
  api?.scrollNext();
2468
2469
  }, [api]);
2469
- const handleKeyDown = React15__namespace.useCallback(
2470
+ const handleKeyDown = React22__namespace.useCallback(
2470
2471
  (event) => {
2471
2472
  if (event.key === "ArrowLeft") {
2472
2473
  event.preventDefault();
@@ -2478,11 +2479,11 @@ function Carousel({
2478
2479
  },
2479
2480
  [scrollPrev, scrollNext]
2480
2481
  );
2481
- React15__namespace.useEffect(() => {
2482
+ React22__namespace.useEffect(() => {
2482
2483
  if (!api || !setApi) return;
2483
2484
  setApi(api);
2484
2485
  }, [api, setApi]);
2485
- React15__namespace.useEffect(() => {
2486
+ React22__namespace.useEffect(() => {
2486
2487
  if (!api) return;
2487
2488
  onSelect(api);
2488
2489
  api.on("reInit", onSelect);
@@ -2615,9 +2616,9 @@ function CarouselNext({
2615
2616
  );
2616
2617
  }
2617
2618
  var THEMES = { light: "", dark: ".dark" };
2618
- var ChartContext = React15__namespace.createContext(null);
2619
+ var ChartContext = React22__namespace.createContext(null);
2619
2620
  function useChart() {
2620
- const context = React15__namespace.useContext(ChartContext);
2621
+ const context = React22__namespace.useContext(ChartContext);
2621
2622
  if (!context) {
2622
2623
  throw new Error("useChart must be used within a <ChartContainer />");
2623
2624
  }
@@ -2630,7 +2631,7 @@ function ChartContainer({
2630
2631
  config,
2631
2632
  ...props
2632
2633
  }) {
2633
- const uniqueId = React15__namespace.useId();
2634
+ const uniqueId = React22__namespace.useId();
2634
2635
  const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`;
2635
2636
  return /* @__PURE__ */ jsxRuntime.jsx(ChartContext.Provider, { value: { config }, children: /* @__PURE__ */ jsxRuntime.jsxs(
2636
2637
  "div",
@@ -2691,7 +2692,7 @@ function ChartTooltipContent({
2691
2692
  labelKey
2692
2693
  }) {
2693
2694
  const { config } = useChart();
2694
- const tooltipLabel = React15__namespace.useMemo(() => {
2695
+ const tooltipLabel = React22__namespace.useMemo(() => {
2695
2696
  if (hideLabel || !payload?.length) {
2696
2697
  return null;
2697
2698
  }
@@ -3347,6 +3348,105 @@ function Progress({
3347
3348
  }
3348
3349
  );
3349
3350
  }
3351
+ function CircularProgress({
3352
+ className,
3353
+ value,
3354
+ size = 80,
3355
+ strokeWidth = 8,
3356
+ variant = "default",
3357
+ showCheckmark = true,
3358
+ children,
3359
+ ...props
3360
+ }) {
3361
+ const clampedValue = Math.min(100, Math.max(0, value));
3362
+ const isComplete = clampedValue >= 100;
3363
+ const radius = (size - strokeWidth) / 2;
3364
+ const circumference = 2 * Math.PI * radius;
3365
+ const strokeDashoffset = circumference - clampedValue / 100 * circumference;
3366
+ const center = size / 2;
3367
+ const getVariantColors = () => {
3368
+ switch (variant) {
3369
+ case "success":
3370
+ return {
3371
+ track: "stroke-green-500/20",
3372
+ progress: "stroke-green-500",
3373
+ text: "text-green-600 dark:text-green-400"
3374
+ };
3375
+ case "warning":
3376
+ return {
3377
+ track: "stroke-amber-500/20",
3378
+ progress: "stroke-amber-500",
3379
+ text: "text-amber-600 dark:text-amber-400"
3380
+ };
3381
+ case "destructive":
3382
+ return {
3383
+ track: "stroke-red-500/20",
3384
+ progress: "stroke-red-500",
3385
+ text: "text-red-600 dark:text-red-400"
3386
+ };
3387
+ default:
3388
+ return {
3389
+ track: "stroke-primary/20",
3390
+ progress: "stroke-primary",
3391
+ text: "text-primary"
3392
+ };
3393
+ }
3394
+ };
3395
+ const colors = getVariantColors();
3396
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3397
+ "div",
3398
+ {
3399
+ "data-slot": "circular-progress",
3400
+ "data-value": clampedValue,
3401
+ "data-complete": isComplete,
3402
+ className: cn("relative inline-flex items-center justify-center", className),
3403
+ style: { width: size, height: size },
3404
+ ...props,
3405
+ children: [
3406
+ /* @__PURE__ */ jsxRuntime.jsxs(
3407
+ "svg",
3408
+ {
3409
+ className: "transform -rotate-90",
3410
+ width: size,
3411
+ height: size,
3412
+ viewBox: `0 0 ${size} ${size}`,
3413
+ children: [
3414
+ /* @__PURE__ */ jsxRuntime.jsx(
3415
+ "circle",
3416
+ {
3417
+ className: cn("transition-all", colors.track),
3418
+ cx: center,
3419
+ cy: center,
3420
+ r: radius,
3421
+ fill: "none",
3422
+ strokeWidth
3423
+ }
3424
+ ),
3425
+ /* @__PURE__ */ jsxRuntime.jsx(
3426
+ "circle",
3427
+ {
3428
+ className: cn("transition-all duration-300 ease-out", colors.progress),
3429
+ cx: center,
3430
+ cy: center,
3431
+ r: radius,
3432
+ fill: "none",
3433
+ strokeWidth,
3434
+ strokeLinecap: "round",
3435
+ strokeDasharray: circumference,
3436
+ strokeDashoffset
3437
+ }
3438
+ )
3439
+ ]
3440
+ }
3441
+ ),
3442
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: children ? children : isComplete && showCheckmark ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: cn("h-6 w-6", colors.text) }) : /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("text-sm font-semibold tabular-nums", colors.text), children: [
3443
+ Math.round(clampedValue),
3444
+ "%"
3445
+ ] }) })
3446
+ ]
3447
+ }
3448
+ );
3449
+ }
3350
3450
  function TooltipProvider({
3351
3451
  delayDuration = 0,
3352
3452
  ...props
@@ -3394,8 +3494,8 @@ function TooltipContent({
3394
3494
  ) });
3395
3495
  }
3396
3496
  function useDetectTheme() {
3397
- const [theme, setTheme] = React15__namespace.useState("light");
3398
- React15__namespace.useEffect(() => {
3497
+ const [theme, setTheme] = React22__namespace.useState("light");
3498
+ React22__namespace.useEffect(() => {
3399
3499
  const isDark = document.documentElement.classList.contains("dark");
3400
3500
  setTheme(isDark ? "dark" : "light");
3401
3501
  const observer = new MutationObserver((mutations) => {
@@ -3447,6 +3547,81 @@ function Spinner({ className, ...props }) {
3447
3547
  }
3448
3548
  );
3449
3549
  }
3550
+ var deliveryIndicatorVariants = classVarianceAuthority.cva(
3551
+ "inline-block rounded-full shrink-0",
3552
+ {
3553
+ variants: {
3554
+ status: {
3555
+ "on-time": "bg-[var(--j3m-green-9,#84EBB4)]",
3556
+ "delayed": "bg-[var(--j3m-yellow-9,#FFDB43)]",
3557
+ "critical": "bg-[var(--j3m-red-9,#FB3748)]",
3558
+ "pending": "bg-[var(--j3m-gray-6,#D2D2D2)]"
3559
+ },
3560
+ size: {
3561
+ sm: "h-1.5 w-3",
3562
+ default: "h-1.5 w-3",
3563
+ lg: "h-2 w-4"
3564
+ }
3565
+ },
3566
+ defaultVariants: {
3567
+ status: "pending",
3568
+ size: "default"
3569
+ }
3570
+ }
3571
+ );
3572
+ function DeliveryIndicator({
3573
+ className,
3574
+ status,
3575
+ size,
3576
+ label,
3577
+ showTooltip = false,
3578
+ ...props
3579
+ }) {
3580
+ const indicator = /* @__PURE__ */ jsxRuntime.jsx(
3581
+ "span",
3582
+ {
3583
+ "data-slot": "delivery-indicator",
3584
+ "data-status": status,
3585
+ className: cn(deliveryIndicatorVariants({ status, size }), className),
3586
+ "aria-label": label || `Delivery status: ${status}`,
3587
+ role: "img",
3588
+ ...props
3589
+ }
3590
+ );
3591
+ if (showTooltip && label) {
3592
+ return /* @__PURE__ */ jsxRuntime.jsxs(Tooltip2, { children: [
3593
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: indicator }),
3594
+ /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: label })
3595
+ ] });
3596
+ }
3597
+ return indicator;
3598
+ }
3599
+ function DeliveryIndicators({
3600
+ className,
3601
+ deliveries,
3602
+ size = "default",
3603
+ showTooltips = false,
3604
+ ...props
3605
+ }) {
3606
+ return /* @__PURE__ */ jsxRuntime.jsx(
3607
+ "div",
3608
+ {
3609
+ "data-slot": "delivery-indicators",
3610
+ className: cn("flex items-center gap-1", className),
3611
+ ...props,
3612
+ children: deliveries.map((delivery, index) => /* @__PURE__ */ jsxRuntime.jsx(
3613
+ DeliveryIndicator,
3614
+ {
3615
+ status: delivery.status,
3616
+ size,
3617
+ label: delivery.label,
3618
+ showTooltip: showTooltips
3619
+ },
3620
+ index
3621
+ ))
3622
+ }
3623
+ );
3624
+ }
3450
3625
  function Breadcrumb({ ...props }) {
3451
3626
  return /* @__PURE__ */ jsxRuntime.jsx("nav", { "aria-label": "breadcrumb", "data-slot": "breadcrumb", ...props });
3452
3627
  }
@@ -3969,7 +4144,7 @@ function CommandShortcut({
3969
4144
  }
3970
4145
  );
3971
4146
  }
3972
- var SearchTrigger = React15__namespace.forwardRef(
4147
+ var SearchTrigger = React22__namespace.forwardRef(
3973
4148
  ({
3974
4149
  className,
3975
4150
  placeholder = "Search...",
@@ -4005,7 +4180,7 @@ var SearchTrigger = React15__namespace.forwardRef(
4005
4180
  );
4006
4181
  SearchTrigger.displayName = "SearchTrigger";
4007
4182
  function useSearchShortcut(onOpen, key = "k") {
4008
- React15__namespace.useEffect(() => {
4183
+ React22__namespace.useEffect(() => {
4009
4184
  const down = (e) => {
4010
4185
  if (e.key.toLowerCase() === key.toLowerCase() && (e.metaKey || e.ctrlKey)) {
4011
4186
  e.preventDefault();
@@ -4980,9 +5155,9 @@ var SIDEBAR_WIDTH = "16rem";
4980
5155
  var SIDEBAR_WIDTH_MOBILE = "18rem";
4981
5156
  var SIDEBAR_WIDTH_ICON = "3rem";
4982
5157
  var SIDEBAR_KEYBOARD_SHORTCUT = "b";
4983
- var SidebarContext = React15__namespace.createContext(null);
5158
+ var SidebarContext = React22__namespace.createContext(null);
4984
5159
  function useSidebar() {
4985
- const context = React15__namespace.useContext(SidebarContext);
5160
+ const context = React22__namespace.useContext(SidebarContext);
4986
5161
  if (!context) {
4987
5162
  throw new Error("useSidebar must be used within a SidebarProvider.");
4988
5163
  }
@@ -4998,10 +5173,10 @@ function SidebarProvider({
4998
5173
  ...props
4999
5174
  }) {
5000
5175
  const isMobile = useIsMobile();
5001
- const [openMobile, setOpenMobile] = React15__namespace.useState(false);
5002
- const [_open, _setOpen] = React15__namespace.useState(defaultOpen);
5176
+ const [openMobile, setOpenMobile] = React22__namespace.useState(false);
5177
+ const [_open, _setOpen] = React22__namespace.useState(defaultOpen);
5003
5178
  const open = openProp ?? _open;
5004
- const setOpen = React15__namespace.useCallback(
5179
+ const setOpen = React22__namespace.useCallback(
5005
5180
  (value) => {
5006
5181
  const openState = typeof value === "function" ? value(open) : value;
5007
5182
  if (setOpenProp) {
@@ -5013,10 +5188,10 @@ function SidebarProvider({
5013
5188
  },
5014
5189
  [setOpenProp, open]
5015
5190
  );
5016
- const toggleSidebar = React15__namespace.useCallback(() => {
5191
+ const toggleSidebar = React22__namespace.useCallback(() => {
5017
5192
  return isMobile ? setOpenMobile((open2) => !open2) : setOpen((open2) => !open2);
5018
5193
  }, [isMobile, setOpen, setOpenMobile]);
5019
- React15__namespace.useEffect(() => {
5194
+ React22__namespace.useEffect(() => {
5020
5195
  const handleKeyDown = (event) => {
5021
5196
  if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
5022
5197
  event.preventDefault();
@@ -5027,7 +5202,7 @@ function SidebarProvider({
5027
5202
  return () => window.removeEventListener("keydown", handleKeyDown);
5028
5203
  }, [toggleSidebar]);
5029
5204
  const state = open ? "expanded" : "collapsed";
5030
- const contextValue = React15__namespace.useMemo(
5205
+ const contextValue = React22__namespace.useMemo(
5031
5206
  () => ({
5032
5207
  state,
5033
5208
  open,
@@ -5485,7 +5660,7 @@ function SidebarMenuSkeleton({
5485
5660
  showIcon = false,
5486
5661
  ...props
5487
5662
  }) {
5488
- const width = React15__namespace.useMemo(() => {
5663
+ const width = React22__namespace.useMemo(() => {
5489
5664
  return `${Math.floor(Math.random() * 40) + 50}%`;
5490
5665
  }, []);
5491
5666
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -5628,7 +5803,7 @@ var sectionVariants = classVarianceAuthority.cva(
5628
5803
  }
5629
5804
  );
5630
5805
  var isGlassVariant = (variant) => variant?.startsWith("glass-") ?? false;
5631
- var Section = React15__namespace.forwardRef(
5806
+ var Section = React22__namespace.forwardRef(
5632
5807
  ({ className, variant, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
5633
5808
  "section",
5634
5809
  {
@@ -5640,7 +5815,7 @@ var Section = React15__namespace.forwardRef(
5640
5815
  )
5641
5816
  );
5642
5817
  Section.displayName = "Section";
5643
- var SectionHeader = React15__namespace.forwardRef(
5818
+ var SectionHeader = React22__namespace.forwardRef(
5644
5819
  ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
5645
5820
  "div",
5646
5821
  {
@@ -5655,7 +5830,7 @@ var SectionHeader = React15__namespace.forwardRef(
5655
5830
  )
5656
5831
  );
5657
5832
  SectionHeader.displayName = "SectionHeader";
5658
- var SectionTitle = React15__namespace.forwardRef(
5833
+ var SectionTitle = React22__namespace.forwardRef(
5659
5834
  ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
5660
5835
  "h2",
5661
5836
  {
@@ -5669,7 +5844,7 @@ var SectionTitle = React15__namespace.forwardRef(
5669
5844
  )
5670
5845
  );
5671
5846
  SectionTitle.displayName = "SectionTitle";
5672
- var SectionDescription = React15__namespace.forwardRef(
5847
+ var SectionDescription = React22__namespace.forwardRef(
5673
5848
  ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
5674
5849
  "p",
5675
5850
  {
@@ -5683,219 +5858,3315 @@ var SectionDescription = React15__namespace.forwardRef(
5683
5858
  )
5684
5859
  );
5685
5860
  SectionDescription.displayName = "SectionDescription";
5686
- var SectionContent = React15__namespace.forwardRef(
5861
+ var SectionContent = React22__namespace.forwardRef(
5862
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
5863
+ "div",
5864
+ {
5865
+ ref,
5866
+ className: cn(
5867
+ "px-[var(--j3m-spacing-xl)] py-[var(--j3m-spacing-l)]",
5868
+ className
5869
+ ),
5870
+ ...props
5871
+ }
5872
+ )
5873
+ );
5874
+ SectionContent.displayName = "SectionContent";
5875
+ var SectionFooter = React22__namespace.forwardRef(
5687
5876
  ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
5688
5877
  "div",
5689
5878
  {
5690
5879
  ref,
5691
5880
  className: cn(
5881
+ "flex items-center",
5692
5882
  "px-[var(--j3m-spacing-xl)] py-[var(--j3m-spacing-l)]",
5883
+ "border-t border-[inherit]",
5693
5884
  className
5694
5885
  ),
5695
5886
  ...props
5696
5887
  }
5697
- )
5698
- );
5699
- SectionContent.displayName = "SectionContent";
5700
- var SectionFooter = React15__namespace.forwardRef(
5701
- ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
5702
- "div",
5703
- {
5704
- ref,
5705
- className: cn(
5706
- "flex items-center",
5707
- "px-[var(--j3m-spacing-xl)] py-[var(--j3m-spacing-l)]",
5708
- "border-t border-[inherit]",
5709
- className
5710
- ),
5711
- ...props
5888
+ )
5889
+ );
5890
+ SectionFooter.displayName = "SectionFooter";
5891
+ function DataTableColumnHeader({
5892
+ column,
5893
+ title,
5894
+ className
5895
+ }) {
5896
+ if (!column.getCanSort()) {
5897
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(className), children: title });
5898
+ }
5899
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex items-center gap-2", className), children: /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
5900
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
5901
+ Button,
5902
+ {
5903
+ variant: "ghost",
5904
+ size: "sm",
5905
+ className: "data-[state=open]:bg-accent -ml-3 h-8",
5906
+ children: [
5907
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: title }),
5908
+ column.getIsSorted() === "desc" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDown, {}) : column.getIsSorted() === "asc" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, {}) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsUpDown, {})
5909
+ ]
5910
+ }
5911
+ ) }),
5912
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuContent, { align: "start", children: [
5913
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { onClick: () => column.toggleSorting(false), children: [
5914
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, {}),
5915
+ "Asc"
5916
+ ] }),
5917
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { onClick: () => column.toggleSorting(true), children: [
5918
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDown, {}),
5919
+ "Desc"
5920
+ ] }),
5921
+ column.getCanHide() && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5922
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
5923
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { onClick: () => column.toggleVisibility(false), children: [
5924
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.EyeOff, {}),
5925
+ "Hide"
5926
+ ] })
5927
+ ] })
5928
+ ] })
5929
+ ] }) });
5930
+ }
5931
+ function DataTablePagination({
5932
+ table,
5933
+ showRowSelection = true,
5934
+ pageSizeOptions = [10, 20, 25, 30, 40, 50]
5935
+ }) {
5936
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-2", children: [
5937
+ showRowSelection && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-muted-foreground flex-1 text-sm", children: [
5938
+ table.getFilteredSelectedRowModel().rows.length,
5939
+ " of",
5940
+ " ",
5941
+ table.getFilteredRowModel().rows.length,
5942
+ " row(s) selected."
5943
+ ] }),
5944
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-6 lg:space-x-8", children: [
5945
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [
5946
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium", children: "Rows per page" }),
5947
+ /* @__PURE__ */ jsxRuntime.jsxs(
5948
+ Select,
5949
+ {
5950
+ value: `${table.getState().pagination.pageSize}`,
5951
+ onValueChange: (value) => {
5952
+ table.setPageSize(Number(value));
5953
+ },
5954
+ children: [
5955
+ /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "h-8 w-[70px]", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: table.getState().pagination.pageSize }) }),
5956
+ /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { side: "top", children: pageSizeOptions.map((pageSize) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: `${pageSize}`, children: pageSize }, pageSize)) })
5957
+ ]
5958
+ }
5959
+ )
5960
+ ] }),
5961
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-[100px] items-center justify-center text-sm font-medium", children: [
5962
+ "Page ",
5963
+ table.getState().pagination.pageIndex + 1,
5964
+ " of",
5965
+ " ",
5966
+ table.getPageCount()
5967
+ ] }),
5968
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [
5969
+ /* @__PURE__ */ jsxRuntime.jsxs(
5970
+ Button,
5971
+ {
5972
+ variant: "outline",
5973
+ size: "icon",
5974
+ className: "hidden size-8 lg:flex",
5975
+ onClick: () => table.setPageIndex(0),
5976
+ disabled: !table.getCanPreviousPage(),
5977
+ children: [
5978
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Go to first page" }),
5979
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsLeft, {})
5980
+ ]
5981
+ }
5982
+ ),
5983
+ /* @__PURE__ */ jsxRuntime.jsxs(
5984
+ Button,
5985
+ {
5986
+ variant: "outline",
5987
+ size: "icon",
5988
+ className: "size-8",
5989
+ onClick: () => table.previousPage(),
5990
+ disabled: !table.getCanPreviousPage(),
5991
+ children: [
5992
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Go to previous page" }),
5993
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, {})
5994
+ ]
5995
+ }
5996
+ ),
5997
+ /* @__PURE__ */ jsxRuntime.jsxs(
5998
+ Button,
5999
+ {
6000
+ variant: "outline",
6001
+ size: "icon",
6002
+ className: "size-8",
6003
+ onClick: () => table.nextPage(),
6004
+ disabled: !table.getCanNextPage(),
6005
+ children: [
6006
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Go to next page" }),
6007
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, {})
6008
+ ]
6009
+ }
6010
+ ),
6011
+ /* @__PURE__ */ jsxRuntime.jsxs(
6012
+ Button,
6013
+ {
6014
+ variant: "outline",
6015
+ size: "icon",
6016
+ className: "hidden size-8 lg:flex",
6017
+ onClick: () => table.setPageIndex(table.getPageCount() - 1),
6018
+ disabled: !table.getCanNextPage(),
6019
+ children: [
6020
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Go to last page" }),
6021
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsRight, {})
6022
+ ]
6023
+ }
6024
+ )
6025
+ ] })
6026
+ ] })
6027
+ ] });
6028
+ }
6029
+ function DataTableViewOptions({
6030
+ table
6031
+ }) {
6032
+ return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
6033
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
6034
+ Button,
6035
+ {
6036
+ variant: "outline",
6037
+ size: "sm",
6038
+ className: "ml-auto hidden h-8 lg:flex",
6039
+ children: [
6040
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Settings2, {}),
6041
+ "View"
6042
+ ]
6043
+ }
6044
+ ) }),
6045
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuContent, { align: "end", className: "w-[150px]", children: [
6046
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuLabel, { children: "Toggle columns" }),
6047
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
6048
+ table.getAllColumns().filter(
6049
+ (column) => typeof column.accessorFn !== "undefined" && column.getCanHide()
6050
+ ).map((column) => {
6051
+ return /* @__PURE__ */ jsxRuntime.jsx(
6052
+ DropdownMenuCheckboxItem,
6053
+ {
6054
+ className: "capitalize",
6055
+ checked: column.getIsVisible(),
6056
+ onCheckedChange: (value) => column.toggleVisibility(!!value),
6057
+ children: column.id
6058
+ },
6059
+ column.id
6060
+ );
6061
+ })
6062
+ ] })
6063
+ ] });
6064
+ }
6065
+ function SearchForm({ ...props }) {
6066
+ return /* @__PURE__ */ jsxRuntime.jsx("form", { ...props, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
6067
+ /* @__PURE__ */ jsxRuntime.jsx(Label2, { htmlFor: "search", className: "sr-only", children: "Search" }),
6068
+ /* @__PURE__ */ jsxRuntime.jsx(
6069
+ SidebarInput,
6070
+ {
6071
+ id: "search",
6072
+ placeholder: "Type to search...",
6073
+ className: "h-8 pl-7"
6074
+ }
6075
+ ),
6076
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SearchIcon, { className: "pointer-events-none absolute top-1/2 left-2 size-4 -translate-y-1/2 opacity-50 select-none" })
6077
+ ] }) });
6078
+ }
6079
+ function SiteHeader({
6080
+ trigger,
6081
+ breadcrumbs = [
6082
+ { label: "Building Your Application", href: "#" },
6083
+ { label: "Data Fetching" }
6084
+ ],
6085
+ showSearch = true,
6086
+ className,
6087
+ children
6088
+ }) {
6089
+ return /* @__PURE__ */ jsxRuntime.jsx(
6090
+ "header",
6091
+ {
6092
+ "data-slot": "site-header",
6093
+ className: cn(
6094
+ "bg-sidebar text-sidebar-foreground sticky top-0 z-50 flex w-full items-center border-b border-sidebar-border",
6095
+ className
6096
+ ),
6097
+ 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: [
6098
+ trigger,
6099
+ trigger && /* @__PURE__ */ jsxRuntime.jsx(Separator, { orientation: "vertical", className: "mr-[var(--j3m-spacing-s)] h-4" }),
6100
+ /* @__PURE__ */ jsxRuntime.jsx(Breadcrumb, { className: "hidden sm:block", children: /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbList, { children: breadcrumbs.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs(React22__namespace.Fragment, { children: [
6101
+ index > 0 && /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbSeparator, {}),
6102
+ /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbItem, { children: item.href ? /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbLink, { href: item.href, children: item.label }) : /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbPage, { children: item.label }) })
6103
+ ] }, index)) }) }),
6104
+ showSearch && /* @__PURE__ */ jsxRuntime.jsx(SearchForm, { className: "w-full sm:ml-auto sm:w-auto" }),
6105
+ children
6106
+ ] })
6107
+ }
6108
+ );
6109
+ }
6110
+ function NavMain({ items, label = "Platform" }) {
6111
+ return /* @__PURE__ */ jsxRuntime.jsxs(SidebarGroup, { children: [
6112
+ /* @__PURE__ */ jsxRuntime.jsx(SidebarGroupLabel, { children: label }),
6113
+ /* @__PURE__ */ jsxRuntime.jsx(SidebarMenu, { children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(Collapsible, { asChild: true, defaultOpen: item.isActive, children: /* @__PURE__ */ jsxRuntime.jsxs(SidebarMenuItem, { children: [
6114
+ /* @__PURE__ */ jsxRuntime.jsx(SidebarMenuButton, { asChild: true, tooltip: item.title, children: /* @__PURE__ */ jsxRuntime.jsxs("a", { href: item.url, children: [
6115
+ item.icon && /* @__PURE__ */ jsxRuntime.jsx(item.icon, {}),
6116
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: item.title })
6117
+ ] }) }),
6118
+ item.items?.length ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6119
+ /* @__PURE__ */ jsxRuntime.jsx(CollapsibleTrigger2, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(SidebarMenuAction, { className: "data-[state=open]:rotate-90", children: [
6120
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, {}),
6121
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Toggle" })
6122
+ ] }) }),
6123
+ /* @__PURE__ */ jsxRuntime.jsx(CollapsibleContent2, { children: /* @__PURE__ */ jsxRuntime.jsx(SidebarMenuSub, { children: item.items?.map((subItem) => /* @__PURE__ */ jsxRuntime.jsx(SidebarMenuSubItem, { children: /* @__PURE__ */ jsxRuntime.jsx(SidebarMenuSubButton, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: subItem.url, children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: subItem.title }) }) }) }, subItem.title)) }) })
6124
+ ] }) : null
6125
+ ] }) }, item.title)) })
6126
+ ] });
6127
+ }
6128
+ function NavProjects({ projects, label = "Projects" }) {
6129
+ return /* @__PURE__ */ jsxRuntime.jsxs(SidebarGroup, { className: "group-data-[collapsible=icon]:hidden", children: [
6130
+ /* @__PURE__ */ jsxRuntime.jsx(SidebarGroupLabel, { children: label }),
6131
+ /* @__PURE__ */ jsxRuntime.jsxs(SidebarMenu, { children: [
6132
+ projects.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(SidebarMenuItem, { children: [
6133
+ /* @__PURE__ */ jsxRuntime.jsx(SidebarMenuButton, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs("a", { href: item.url, children: [
6134
+ /* @__PURE__ */ jsxRuntime.jsx(item.icon, {}),
6135
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: item.name })
6136
+ ] }) }),
6137
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
6138
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(SidebarMenuAction, { showOnHover: true, children: [
6139
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MoreHorizontalIcon, {}),
6140
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "More" })
6141
+ ] }) }),
6142
+ /* @__PURE__ */ jsxRuntime.jsxs(
6143
+ DropdownMenuContent,
6144
+ {
6145
+ className: "w-48 rounded-[var(--j3m-radius-m)]",
6146
+ side: "right",
6147
+ align: "start",
6148
+ sideOffset: 8,
6149
+ children: [
6150
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { children: [
6151
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FolderIcon, { className: "text-muted-foreground" }),
6152
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "View Project" })
6153
+ ] }),
6154
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { children: [
6155
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ShareIcon, { className: "text-muted-foreground" }),
6156
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Share Project" })
6157
+ ] }),
6158
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
6159
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { children: [
6160
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.TrashIcon, { className: "text-muted-foreground" }),
6161
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Delete Project" })
6162
+ ] })
6163
+ ]
6164
+ }
6165
+ )
6166
+ ] })
6167
+ ] }, item.name)),
6168
+ /* @__PURE__ */ jsxRuntime.jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsxRuntime.jsxs(SidebarMenuButton, { className: "text-sidebar-foreground/70", children: [
6169
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MoreHorizontalIcon, { className: "text-sidebar-foreground/70" }),
6170
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "More" })
6171
+ ] }) })
6172
+ ] })
6173
+ ] });
6174
+ }
6175
+ function NavSecondary({ items, ...props }) {
6176
+ return /* @__PURE__ */ jsxRuntime.jsx(SidebarGroup, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx(SidebarGroupContent, { children: /* @__PURE__ */ jsxRuntime.jsx(SidebarMenu, { children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsxRuntime.jsx(SidebarMenuButton, { asChild: true, size: "sm", children: /* @__PURE__ */ jsxRuntime.jsxs("a", { href: item.url, children: [
6177
+ /* @__PURE__ */ jsxRuntime.jsx(item.icon, {}),
6178
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: item.title })
6179
+ ] }) }) }, item.title)) }) }) });
6180
+ }
6181
+ function NavUser({ user }) {
6182
+ return /* @__PURE__ */ jsxRuntime.jsx(SidebarMenu, { children: /* @__PURE__ */ jsxRuntime.jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
6183
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
6184
+ SidebarMenuButton,
6185
+ {
6186
+ size: "lg",
6187
+ className: "data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground",
6188
+ children: [
6189
+ /* @__PURE__ */ jsxRuntime.jsxs(Avatar, { className: "h-8 w-8 rounded-lg", children: [
6190
+ /* @__PURE__ */ jsxRuntime.jsx(AvatarImage, { src: user.avatar, alt: user.name }),
6191
+ /* @__PURE__ */ jsxRuntime.jsx(AvatarFallback, { className: "rounded-lg", children: user.name.slice(0, 2).toUpperCase() })
6192
+ ] }),
6193
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid flex-1 text-left text-sm leading-tight", children: [
6194
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate font-semibold", children: user.name }),
6195
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-xs", children: user.email })
6196
+ ] }),
6197
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsUpDownIcon, { className: "ml-auto size-4" })
6198
+ ]
6199
+ }
6200
+ ) }),
6201
+ /* @__PURE__ */ jsxRuntime.jsxs(
6202
+ DropdownMenuContent,
6203
+ {
6204
+ className: "w-[--radix-dropdown-menu-trigger-width] min-w-56 rounded-[var(--j3m-radius-m)]",
6205
+ side: "right",
6206
+ align: "end",
6207
+ sideOffset: 8,
6208
+ children: [
6209
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuLabel, { className: "p-0 font-normal", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 px-1 py-1.5 text-left text-sm", children: [
6210
+ /* @__PURE__ */ jsxRuntime.jsxs(Avatar, { className: "h-8 w-8 rounded-lg", children: [
6211
+ /* @__PURE__ */ jsxRuntime.jsx(AvatarImage, { src: user.avatar, alt: user.name }),
6212
+ /* @__PURE__ */ jsxRuntime.jsx(AvatarFallback, { className: "rounded-lg", children: user.name.slice(0, 2).toUpperCase() })
6213
+ ] }),
6214
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid flex-1 text-left text-sm leading-tight", children: [
6215
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate font-semibold", children: user.name }),
6216
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-xs", children: user.email })
6217
+ ] })
6218
+ ] }) }),
6219
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
6220
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuGroup, { children: /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { children: [
6221
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SparklesIcon, {}),
6222
+ "Upgrade to Pro"
6223
+ ] }) }),
6224
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
6225
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuGroup, { children: [
6226
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { children: [
6227
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BadgeCheckIcon, {}),
6228
+ "Account"
6229
+ ] }),
6230
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { children: [
6231
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CreditCardIcon, {}),
6232
+ "Billing"
6233
+ ] }),
6234
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { children: [
6235
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BellIcon, {}),
6236
+ "Notifications"
6237
+ ] })
6238
+ ] }),
6239
+ /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
6240
+ /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { children: [
6241
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.LogOutIcon, {}),
6242
+ "Log out"
6243
+ ] })
6244
+ ]
6245
+ }
6246
+ )
6247
+ ] }) }) });
6248
+ }
6249
+ function PlanningTableToolbar({
6250
+ className,
6251
+ table,
6252
+ ...props
6253
+ }) {
6254
+ const isFiltered = table.getState().columnFilters.length > 0;
6255
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6256
+ "div",
6257
+ {
6258
+ "data-slot": "planning-table-toolbar",
6259
+ className: cn("flex items-center gap-2", className),
6260
+ ...props,
6261
+ children: [
6262
+ /* @__PURE__ */ jsxRuntime.jsx(
6263
+ Input,
6264
+ {
6265
+ placeholder: "Filter suppliers...",
6266
+ value: table.getColumn("supplier")?.getFilterValue() ?? "",
6267
+ onChange: (event) => table.getColumn("supplier")?.setFilterValue(event.target.value),
6268
+ className: "h-8 w-[150px] lg:w-[250px]"
6269
+ }
6270
+ ),
6271
+ isFiltered && /* @__PURE__ */ jsxRuntime.jsxs(
6272
+ Button,
6273
+ {
6274
+ variant: "ghost",
6275
+ onClick: () => table.resetColumnFilters(),
6276
+ className: "h-8 px-2 lg:px-3",
6277
+ children: [
6278
+ "Reset",
6279
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "ml-2 h-4 w-4" })
6280
+ ]
6281
+ }
6282
+ )
6283
+ ]
6284
+ }
6285
+ );
6286
+ }
6287
+ function getBadgeVariant(badgeType) {
6288
+ return "outline";
6289
+ }
6290
+ function SupplierCell({
6291
+ className,
6292
+ supplier,
6293
+ ...props
6294
+ }) {
6295
+ const spacingClasses = "px-[var(--j3m-spacing-xs)] pt-[var(--j3m-spacing-s)] pb-2";
6296
+ return /* @__PURE__ */ jsxRuntime.jsx(
6297
+ "div",
6298
+ {
6299
+ "data-slot": "supplier-cell",
6300
+ className: cn(
6301
+ // Same height as WeekCell (80px) for row alignment
6302
+ "flex flex-col justify-center gap-1.5 min-w-[200px] h-[80px]",
6303
+ // White background for Y-axis legend cells
6304
+ "bg-background",
6305
+ spacingClasses,
6306
+ className
6307
+ ),
6308
+ ...props,
6309
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-2", children: [
6310
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
6311
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-bold leading-tight text-foreground truncate", children: supplier.name }),
6312
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: supplier.scope })
6313
+ ] }),
6314
+ /* @__PURE__ */ jsxRuntime.jsxs(
6315
+ Badge,
6316
+ {
6317
+ variant: getBadgeVariant(supplier.badgeType),
6318
+ className: "text-[10px] px-2 py-0.5 h-[19px] font-medium shrink-0 gap-1 bg-background border-border",
6319
+ children: [
6320
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Flag, { className: "h-2.5 w-2.5" }),
6321
+ supplier.badgeType
6322
+ ]
6323
+ }
6324
+ )
6325
+ ] })
6326
+ }
6327
+ );
6328
+ }
6329
+ function getCombinedRiskLevel(data) {
6330
+ const productionStatus = data.production?.status || "on-time";
6331
+ const hasDeliveryCritical = data.deliveries?.some((d) => d.status === "critical");
6332
+ const hasDeliveryDelayed = data.deliveries?.some((d) => d.status === "delayed");
6333
+ if (productionStatus === "critical" || hasDeliveryCritical) {
6334
+ return "critical";
6335
+ }
6336
+ if (productionStatus === "delayed" || hasDeliveryDelayed || data.hasWarning) {
6337
+ return "warning";
6338
+ }
6339
+ return "normal";
6340
+ }
6341
+ function getRowStatus(status) {
6342
+ if (status === "critical") return "critical";
6343
+ if (status === "delayed") return "warning";
6344
+ return "normal";
6345
+ }
6346
+ var statusFillClasses = {
6347
+ normal: {
6348
+ border: "border-l-[3px] border-l-green-500",
6349
+ bg: "bg-green-50/50 dark:bg-green-950/30"
6350
+ },
6351
+ warning: {
6352
+ border: "border-l-[3px] border-l-amber-500",
6353
+ bg: "bg-amber-50/50 dark:bg-amber-950/30"
6354
+ },
6355
+ critical: {
6356
+ border: "border-l-[3px] border-l-red-500",
6357
+ bg: "bg-red-50/50 dark:bg-red-950/30"
6358
+ }
6359
+ };
6360
+ var statusColors = {
6361
+ normal: {
6362
+ icon: "text-green-600 dark:text-green-400",
6363
+ progress: "bg-green-500",
6364
+ text: "text-green-700 dark:text-green-300"
6365
+ },
6366
+ warning: {
6367
+ icon: "text-amber-600 dark:text-amber-400",
6368
+ progress: "bg-amber-500",
6369
+ text: "text-amber-700 dark:text-amber-300"
6370
+ },
6371
+ critical: {
6372
+ icon: "text-red-600 dark:text-red-400",
6373
+ progress: "bg-red-500",
6374
+ text: "text-red-700 dark:text-red-300"
6375
+ }
6376
+ };
6377
+ function WeekCell({
6378
+ className,
6379
+ data,
6380
+ week,
6381
+ supplier,
6382
+ isCurrentWeek,
6383
+ onCellClick,
6384
+ ...props
6385
+ }) {
6386
+ const combinedRisk = data.type === "data" ? getCombinedRiskLevel(data) : "normal";
6387
+ const statusClasses = statusFillClasses[combinedRisk];
6388
+ const productionProgress = data.production?.progress ?? data.progress ?? 0;
6389
+ const productionStatus = getRowStatus(data.production?.status);
6390
+ const productionColors = statusColors[productionStatus];
6391
+ const deliveryCount = data.deliveries?.length ?? 0;
6392
+ const worstDeliveryStatus = data.deliveries?.some((d) => d.status === "critical") ? "critical" : data.deliveries?.some((d) => d.status === "delayed") ? "warning" : "normal";
6393
+ const deliveryColors = statusColors[worstDeliveryStatus];
6394
+ const getDeliveryStatusColor = (status) => {
6395
+ switch (status) {
6396
+ case "critical":
6397
+ return "bg-red-500";
6398
+ case "delayed":
6399
+ return "bg-amber-500";
6400
+ default:
6401
+ return "bg-green-500";
6402
+ }
6403
+ };
6404
+ const handleClick = () => {
6405
+ if (onCellClick && data.type !== "empty") {
6406
+ onCellClick();
6407
+ }
6408
+ };
6409
+ const handleKeyDown = (e) => {
6410
+ if ((e.key === "Enter" || e.key === " ") && onCellClick && data.type !== "empty") {
6411
+ e.preventDefault();
6412
+ onCellClick();
6413
+ }
6414
+ };
6415
+ const spacingClasses = "px-[var(--j3m-spacing-xs)] pt-[var(--j3m-spacing-s)] pb-2";
6416
+ if (data.type === "empty") {
6417
+ return /* @__PURE__ */ jsxRuntime.jsx(
6418
+ "div",
6419
+ {
6420
+ "data-slot": "week-cell",
6421
+ "data-state": "empty",
6422
+ "data-current-week": isCurrentWeek,
6423
+ className: cn(
6424
+ "flex h-[80px] items-center justify-center cursor-default",
6425
+ "bg-background",
6426
+ spacingClasses,
6427
+ className
6428
+ ),
6429
+ ...props,
6430
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/30 text-xl", children: "\xB7" })
6431
+ }
6432
+ );
6433
+ }
6434
+ if (data.type === "no-logistics") {
6435
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6436
+ "div",
6437
+ {
6438
+ "data-slot": "week-cell",
6439
+ "data-state": "no-logistics",
6440
+ "data-current-week": isCurrentWeek,
6441
+ onClick: handleClick,
6442
+ onKeyDown: handleKeyDown,
6443
+ role: "button",
6444
+ tabIndex: 0,
6445
+ className: cn(
6446
+ "flex flex-col h-[80px] justify-center gap-2",
6447
+ "cursor-pointer bg-background",
6448
+ "border-l-[3px] border-l-muted-foreground/30",
6449
+ spacingClasses,
6450
+ // Hover lift effect
6451
+ "transition-all duration-200 ease-out",
6452
+ "hover:-translate-y-0.5 hover:shadow-[var(--j3m-shadow-md)]",
6453
+ className
6454
+ ),
6455
+ ...props,
6456
+ children: [
6457
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
6458
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Factory, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
6459
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 h-1.5 bg-muted-foreground/20 rounded-full overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
6460
+ "div",
6461
+ {
6462
+ className: "h-full bg-muted-foreground/40 rounded-full",
6463
+ style: { width: `${productionProgress}%` }
6464
+ }
6465
+ ) })
6466
+ ] }),
6467
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-muted-foreground", children: [
6468
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: "h-3.5 w-3.5 shrink-0" }),
6469
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px]", children: "No logistics" })
6470
+ ] })
6471
+ ]
6472
+ }
6473
+ );
6474
+ }
6475
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6476
+ "div",
6477
+ {
6478
+ "data-slot": "week-cell",
6479
+ "data-state": "data",
6480
+ "data-risk": combinedRisk,
6481
+ "data-current-week": isCurrentWeek,
6482
+ onClick: handleClick,
6483
+ onKeyDown: handleKeyDown,
6484
+ role: "button",
6485
+ tabIndex: 0,
6486
+ className: cn(
6487
+ "flex flex-col h-[80px] justify-center gap-2",
6488
+ "cursor-pointer",
6489
+ // Edge-to-edge status fill (no inset card)
6490
+ statusClasses.border,
6491
+ statusClasses.bg,
6492
+ spacingClasses,
6493
+ // Hover lift effect
6494
+ "transition-all duration-200 ease-out",
6495
+ "hover:-translate-y-0.5 hover:shadow-[var(--j3m-shadow-md)]",
6496
+ className
6497
+ ),
6498
+ ...props,
6499
+ children: [
6500
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
6501
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Factory, { className: cn("h-3.5 w-3.5 shrink-0", productionColors.icon) }),
6502
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 h-1.5 bg-black/10 dark:bg-white/10 rounded-full overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
6503
+ "div",
6504
+ {
6505
+ className: cn("h-full rounded-full transition-all", productionColors.progress),
6506
+ style: { width: `${productionProgress}%` }
6507
+ }
6508
+ ) })
6509
+ ] }),
6510
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
6511
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: cn("h-3.5 w-3.5 shrink-0", deliveryColors.icon) }),
6512
+ deliveryCount > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("text-[10px] font-medium", deliveryColors.text), children: [
6513
+ deliveryCount,
6514
+ "x delivery"
6515
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: "\u2014" })
6516
+ ] }),
6517
+ deliveryCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
6518
+ data.deliveries?.slice(0, 5).map((delivery, index) => {
6519
+ const deliveryProgress = delivery.progress ?? (delivery.status === "on-time" ? 100 : delivery.status === "delayed" ? 50 : 25);
6520
+ return /* @__PURE__ */ jsxRuntime.jsx(
6521
+ "div",
6522
+ {
6523
+ className: "flex-1 max-w-[24px]",
6524
+ title: delivery.label || `Delivery ${index + 1}`,
6525
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-1 bg-black/10 dark:bg-white/10 rounded-full overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
6526
+ "div",
6527
+ {
6528
+ className: cn("h-full rounded-full transition-all", getDeliveryStatusColor(delivery.status)),
6529
+ style: { width: `${deliveryProgress}%` }
6530
+ }
6531
+ ) })
6532
+ },
6533
+ delivery.id || index
6534
+ );
6535
+ }),
6536
+ deliveryCount > 5 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[8px] text-muted-foreground", children: [
6537
+ "+",
6538
+ deliveryCount - 5
6539
+ ] })
6540
+ ] })
6541
+ ]
6542
+ }
6543
+ );
6544
+ }
6545
+ function CommentButton({
6546
+ className,
6547
+ commentCount = 0,
6548
+ size = "default",
6549
+ ...props
6550
+ }) {
6551
+ const hasComments = commentCount > 0;
6552
+ const sizeClasses = size === "sm" ? "h-6 w-6" : "h-7 w-7";
6553
+ const iconSize = size === "sm" ? "h-3.5 w-3.5" : "h-4 w-4";
6554
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6555
+ Button,
6556
+ {
6557
+ variant: "outline",
6558
+ size: "icon",
6559
+ className: cn(
6560
+ sizeClasses,
6561
+ "rounded-full shrink-0 relative",
6562
+ "border-border bg-background hover:bg-muted",
6563
+ "shadow-[var(--j3m-shadow-sm)]",
6564
+ hasComments && "border-primary/50",
6565
+ className
6566
+ ),
6567
+ ...props,
6568
+ children: [
6569
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: cn(iconSize, hasComments && "text-primary") }),
6570
+ hasComments && /* @__PURE__ */ jsxRuntime.jsx(
6571
+ "span",
6572
+ {
6573
+ className: cn(
6574
+ "absolute -top-0.5 -right-0.5",
6575
+ "h-2.5 w-2.5 rounded-full",
6576
+ "bg-primary",
6577
+ "border border-background"
6578
+ // Subtle outline for contrast
6579
+ ),
6580
+ "aria-hidden": "true"
6581
+ }
6582
+ ),
6583
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: hasComments ? `${commentCount} comment${commentCount > 1 ? "s" : ""}` : "Add comment" })
6584
+ ]
6585
+ }
6586
+ );
6587
+ }
6588
+
6589
+ // src/blocks/planning-table/types.ts
6590
+ function getCommentLocationLabel(location) {
6591
+ if (location.type === "production") {
6592
+ return location.supplierName ? `Production - ${location.supplierName}` : "Production";
6593
+ }
6594
+ if (location.type === "delivery") {
6595
+ return location.deliveryLabel || `Delivery ${location.deliveryId || ""}`;
6596
+ }
6597
+ return "Unknown";
6598
+ }
6599
+ function getElementShipmentStatus(element, currentDeliveryId) {
6600
+ if (element.shipmentStatus) {
6601
+ return element.shipmentStatus;
6602
+ }
6603
+ if (element.isProduced) {
6604
+ if (element.actualDeliveryId && element.actualDeliveryId !== currentDeliveryId) {
6605
+ return "moved";
6606
+ }
6607
+ return "sent";
6608
+ }
6609
+ if (element.originalDeliveryId && element.originalDeliveryId !== currentDeliveryId) {
6610
+ return "addon";
6611
+ }
6612
+ return "not-sent";
6613
+ }
6614
+ function getShipmentStatusLabel(status) {
6615
+ switch (status) {
6616
+ case "sent":
6617
+ return "Sent";
6618
+ case "not-sent":
6619
+ return "Missing";
6620
+ // Neutral tone, not "Not sent"
6621
+ case "moved":
6622
+ return "Moved to another delivery";
6623
+ case "addon":
6624
+ return "Add-on";
6625
+ case "planned":
6626
+ return "Planned";
6627
+ default:
6628
+ return status;
6629
+ }
6630
+ }
6631
+ function getWeekKey(date) {
6632
+ const year = date.getFullYear();
6633
+ const weekNumber = getISOWeek(date);
6634
+ return `${year}-W${weekNumber.toString().padStart(2, "0")}`;
6635
+ }
6636
+ function getISOWeek(date) {
6637
+ const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
6638
+ const dayNum = d.getUTCDay() || 7;
6639
+ d.setUTCDate(d.getUTCDate() + 4 - dayNum);
6640
+ const yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1));
6641
+ return Math.ceil(((d.getTime() - yearStart.getTime()) / 864e5 + 1) / 7);
6642
+ }
6643
+ function generateWeeks(startDate, count) {
6644
+ const weeks = [];
6645
+ const current = new Date(startDate);
6646
+ const today = /* @__PURE__ */ new Date();
6647
+ const currentWeekKey = getWeekKey(today);
6648
+ const dayOfWeek = current.getDay();
6649
+ const daysToMonday = dayOfWeek === 0 ? -6 : 1 - dayOfWeek;
6650
+ current.setDate(current.getDate() + daysToMonday);
6651
+ for (let i = 0; i < count; i++) {
6652
+ const weekStart = new Date(current);
6653
+ const weekEnd = new Date(current);
6654
+ weekEnd.setDate(weekEnd.getDate() + 6);
6655
+ const weekNumber = getISOWeek(weekStart);
6656
+ const year = weekStart.getFullYear();
6657
+ const weekKey = `${year}-W${weekNumber.toString().padStart(2, "0")}`;
6658
+ weeks.push({
6659
+ weekNumber,
6660
+ year,
6661
+ startDate: weekStart,
6662
+ endDate: weekEnd,
6663
+ label: `W${weekNumber.toString().padStart(2, "0")}`,
6664
+ dateRange: formatDateRange(weekStart, weekEnd),
6665
+ isCurrentWeek: weekKey === currentWeekKey
6666
+ });
6667
+ current.setDate(current.getDate() + 7);
6668
+ }
6669
+ return weeks;
6670
+ }
6671
+ function formatDateRange(start, end) {
6672
+ const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
6673
+ const startMonth = months[start.getMonth()];
6674
+ const endMonth = months[end.getMonth()];
6675
+ if (startMonth === endMonth) {
6676
+ return `${startMonth} ${start.getDate()} - ${end.getDate()}`;
6677
+ }
6678
+ return `${startMonth} ${start.getDate()} - ${endMonth} ${end.getDate()}`;
6679
+ }
6680
+ function formatProductionUnit(unit) {
6681
+ const unitLabels = {
6682
+ quantity: "pcs",
6683
+ kvm: "m\xB2",
6684
+ ton: "ton",
6685
+ kg: "kg",
6686
+ m: "m",
6687
+ pcs: "pcs"
6688
+ };
6689
+ return unitLabels[unit] || unit;
6690
+ }
6691
+ function LocationIcon({ type }) {
6692
+ if (type === "production") {
6693
+ return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Factory, { className: "h-3 w-3" });
6694
+ }
6695
+ return /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: "h-3 w-3" });
6696
+ }
6697
+ function PlanningWeekCommentPopover({
6698
+ comments,
6699
+ weekLabel,
6700
+ weekKey,
6701
+ locationOptions,
6702
+ onAddComment,
6703
+ onCommentClick,
6704
+ open,
6705
+ onOpenChange
6706
+ }) {
6707
+ const [newCommentText, setNewCommentText] = React22__namespace.useState("");
6708
+ const [selectedLocationId, setSelectedLocationId] = React22__namespace.useState("");
6709
+ const [viewCommentsOpen, setViewCommentsOpen] = React22__namespace.useState(true);
6710
+ const [showAddForm, setShowAddForm] = React22__namespace.useState(false);
6711
+ const selectedLocation = React22__namespace.useMemo(() => {
6712
+ return locationOptions.find((opt) => opt.id === selectedLocationId);
6713
+ }, [locationOptions, selectedLocationId]);
6714
+ const handleSubmit = () => {
6715
+ if (newCommentText.trim() && selectedLocation && onAddComment) {
6716
+ const location = {
6717
+ type: selectedLocation.type,
6718
+ weekKey,
6719
+ supplierId: selectedLocation.supplierId,
6720
+ supplierName: selectedLocation.supplierName,
6721
+ deliveryId: selectedLocation.deliveryId,
6722
+ deliveryLabel: selectedLocation.deliveryLabel
6723
+ };
6724
+ onAddComment(newCommentText.trim(), location);
6725
+ setNewCommentText("");
6726
+ setSelectedLocationId("");
6727
+ setShowAddForm(false);
6728
+ setViewCommentsOpen(true);
6729
+ }
6730
+ };
6731
+ const handleKeyDown = (e) => {
6732
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
6733
+ e.preventDefault();
6734
+ handleSubmit();
6735
+ }
6736
+ if (e.key === "Escape") {
6737
+ setShowAddForm(false);
6738
+ setSelectedLocationId("");
6739
+ setNewCommentText("");
6740
+ }
6741
+ };
6742
+ const handleCommentClick = (comment) => {
6743
+ if (comment.location && onCommentClick) {
6744
+ onCommentClick(comment);
6745
+ }
6746
+ };
6747
+ const formatDate2 = (date) => {
6748
+ return new Intl.DateTimeFormat("en-US", {
6749
+ month: "short",
6750
+ day: "numeric",
6751
+ hour: "numeric",
6752
+ minute: "2-digit"
6753
+ }).format(date);
6754
+ };
6755
+ const prevOpenRef = React22__namespace.useRef(open);
6756
+ React22__namespace.useEffect(() => {
6757
+ const wasOpen = prevOpenRef.current;
6758
+ prevOpenRef.current = open;
6759
+ if (wasOpen && !open) {
6760
+ setShowAddForm(false);
6761
+ setNewCommentText("");
6762
+ setSelectedLocationId("");
6763
+ }
6764
+ }, [open]);
6765
+ return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange, children: [
6766
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(CommentButton, { size: "sm", commentCount: comments.length }) }),
6767
+ /* @__PURE__ */ jsxRuntime.jsxs(
6768
+ PopoverContent,
6769
+ {
6770
+ className: "w-80 p-0 z-[100]",
6771
+ align: "end",
6772
+ sideOffset: 8,
6773
+ collisionPadding: 16,
6774
+ children: [
6775
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 py-3 border-b border-border", children: [
6776
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-sm font-semibold", children: "Comments" }),
6777
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: weekLabel })
6778
+ ] }),
6779
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-2 space-y-2 max-h-[400px] overflow-y-auto", children: [
6780
+ /* @__PURE__ */ jsxRuntime.jsxs(Collapsible, { open: viewCommentsOpen, onOpenChange: setViewCommentsOpen, children: [
6781
+ /* @__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: [
6782
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs font-medium", children: [
6783
+ "Comments ",
6784
+ comments.length > 0 && `(${comments.length})`
6785
+ ] }),
6786
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: cn(
6787
+ "h-4 w-4 transition-transform duration-200",
6788
+ viewCommentsOpen && "rotate-180"
6789
+ ) })
6790
+ ] }) }),
6791
+ /* @__PURE__ */ jsxRuntime.jsx(CollapsibleContent2, { className: "space-y-2 pt-2", children: comments.length > 0 ? comments.map((comment) => {
6792
+ const hasLocation = !!comment.location;
6793
+ const locationLabel = comment.location ? getCommentLocationLabel(comment.location) : null;
6794
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6795
+ "div",
6796
+ {
6797
+ className: cn(
6798
+ "rounded-lg bg-muted/50 p-3 space-y-2",
6799
+ hasLocation && "cursor-pointer hover:bg-muted/70 transition-colors"
6800
+ ),
6801
+ onClick: () => handleCommentClick(comment),
6802
+ role: hasLocation ? "button" : void 0,
6803
+ tabIndex: hasLocation ? 0 : void 0,
6804
+ onKeyDown: hasLocation ? (e) => {
6805
+ if (e.key === "Enter" || e.key === " ") {
6806
+ e.preventDefault();
6807
+ handleCommentClick(comment);
6808
+ }
6809
+ } : void 0,
6810
+ children: [
6811
+ locationLabel && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
6812
+ /* @__PURE__ */ jsxRuntime.jsxs(
6813
+ Badge,
6814
+ {
6815
+ variant: "outline",
6816
+ className: "text-[10px] px-2 py-0 h-5 font-medium bg-background gap-1",
6817
+ children: [
6818
+ /* @__PURE__ */ jsxRuntime.jsx(LocationIcon, { type: comment.location.type }),
6819
+ locationLabel
6820
+ ]
6821
+ }
6822
+ ),
6823
+ hasLocation && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-3 w-3 text-muted-foreground" })
6824
+ ] }),
6825
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
6826
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium", children: comment.author }),
6827
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: formatDate2(comment.createdAt) })
6828
+ ] }),
6829
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-foreground", children: comment.text })
6830
+ ]
6831
+ },
6832
+ comment.id
6833
+ );
6834
+ }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground text-center py-2", children: "No comments yet" }) })
6835
+ ] }),
6836
+ /* @__PURE__ */ jsxRuntime.jsx(Separator, { className: "my-2" }),
6837
+ !showAddForm ? /* @__PURE__ */ jsxRuntime.jsxs(
6838
+ Button,
6839
+ {
6840
+ variant: "outline",
6841
+ size: "sm",
6842
+ className: "w-full justify-center gap-2 h-8",
6843
+ onClick: () => setShowAddForm(true),
6844
+ disabled: locationOptions.length === 0,
6845
+ children: [
6846
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3.5 w-3.5" }),
6847
+ locationOptions.length === 0 ? "No suppliers available" : "Add comment"
6848
+ ]
6849
+ }
6850
+ ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(
6851
+ "space-y-3 p-3 rounded-lg border border-border bg-muted/30",
6852
+ "animate-in fade-in-0 slide-in-from-top-2 duration-200"
6853
+ ), children: [
6854
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
6855
+ /* @__PURE__ */ jsxRuntime.jsxs(Label2, { htmlFor: "supplier-prefix-select", className: "text-xs font-medium", children: [
6856
+ "Supplier / Prefix ",
6857
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-destructive", children: "*" })
6858
+ ] }),
6859
+ /* @__PURE__ */ jsxRuntime.jsxs(Select, { value: selectedLocationId, onValueChange: setSelectedLocationId, children: [
6860
+ /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { id: "supplier-prefix-select", size: "sm", className: "w-full", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: "Select supplier / prefix..." }) }),
6861
+ /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: locationOptions.map((option) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: option.id, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
6862
+ /* @__PURE__ */ jsxRuntime.jsx(LocationIcon, { type: option.type }),
6863
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: option.label })
6864
+ ] }) }, option.id)) })
6865
+ ] })
6866
+ ] }),
6867
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
6868
+ /* @__PURE__ */ jsxRuntime.jsx(Label2, { htmlFor: "comment-text", className: "text-xs font-medium", children: "Comment" }),
6869
+ /* @__PURE__ */ jsxRuntime.jsx(
6870
+ Textarea,
6871
+ {
6872
+ id: "comment-text",
6873
+ placeholder: "Type your comment...",
6874
+ value: newCommentText,
6875
+ onChange: (e) => setNewCommentText(e.target.value),
6876
+ onKeyDown: handleKeyDown,
6877
+ className: "min-h-[80px] text-sm resize-none",
6878
+ autoFocus: true
6879
+ }
6880
+ )
6881
+ ] }),
6882
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
6883
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: "\u2318+Enter to send \xB7 Esc to cancel" }),
6884
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
6885
+ /* @__PURE__ */ jsxRuntime.jsx(
6886
+ Button,
6887
+ {
6888
+ variant: "ghost",
6889
+ size: "sm",
6890
+ className: "h-7",
6891
+ onClick: () => {
6892
+ setShowAddForm(false);
6893
+ setNewCommentText("");
6894
+ setSelectedLocationId("");
6895
+ },
6896
+ children: "Cancel"
6897
+ }
6898
+ ),
6899
+ /* @__PURE__ */ jsxRuntime.jsxs(
6900
+ Button,
6901
+ {
6902
+ size: "sm",
6903
+ className: "h-7 gap-1",
6904
+ onClick: handleSubmit,
6905
+ disabled: !newCommentText.trim() || !selectedLocationId,
6906
+ children: [
6907
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "h-3 w-3" }),
6908
+ "Save"
6909
+ ]
6910
+ }
6911
+ )
6912
+ ] })
6913
+ ] })
6914
+ ] })
6915
+ ] })
6916
+ ]
6917
+ }
6918
+ )
6919
+ ] });
6920
+ }
6921
+ function generateLocationOptions(suppliers, weekKey) {
6922
+ const options = [];
6923
+ for (const supplier of suppliers) {
6924
+ const weekData = supplier.weeks[weekKey];
6925
+ options.push({
6926
+ id: `${supplier.id}-production`,
6927
+ label: `${supplier.name} - Production`,
6928
+ type: "production",
6929
+ supplierId: supplier.id,
6930
+ supplierName: supplier.name
6931
+ });
6932
+ if (weekData?.deliveries) {
6933
+ for (const delivery of weekData.deliveries) {
6934
+ options.push({
6935
+ id: `${supplier.id}-delivery-${delivery.id}`,
6936
+ label: `${supplier.name} - ${delivery.label || `Delivery ${delivery.id}`}`,
6937
+ type: "delivery",
6938
+ supplierId: supplier.id,
6939
+ supplierName: supplier.name,
6940
+ deliveryId: delivery.id,
6941
+ deliveryLabel: delivery.label || `Delivery ${delivery.id}`
6942
+ });
6943
+ }
6944
+ }
6945
+ }
6946
+ return options;
6947
+ }
6948
+ function WeekHeader({
6949
+ className,
6950
+ week,
6951
+ weekKey,
6952
+ comments = [],
6953
+ showCommentButton = true,
6954
+ locationOptions = [],
6955
+ onAddComment,
6956
+ onCommentClick,
6957
+ ...props
6958
+ }) {
6959
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6960
+ "div",
6961
+ {
6962
+ "data-slot": "week-header",
6963
+ "data-current-week": week.isCurrentWeek,
6964
+ className: cn(
6965
+ "flex items-center justify-between gap-2 min-w-[140px] text-left",
6966
+ className
6967
+ ),
6968
+ ...props,
6969
+ children: [
6970
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [
6971
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
6972
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
6973
+ "text-sm font-semibold tracking-tight",
6974
+ week.isCurrentWeek ? "text-primary" : "text-foreground"
6975
+ ), children: week.label }),
6976
+ week.isCurrentWeek && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "relative flex h-2 w-2", children: [
6977
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "animate-ping absolute inline-flex h-full w-full rounded-full bg-primary opacity-75" }),
6978
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "relative inline-flex rounded-full h-2 w-2 bg-primary" })
6979
+ ] })
6980
+ ] }),
6981
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-normal text-muted-foreground/60 whitespace-nowrap", children: week.dateRange })
6982
+ ] }),
6983
+ showCommentButton && weekKey && /* @__PURE__ */ jsxRuntime.jsx(
6984
+ PlanningWeekCommentPopover,
6985
+ {
6986
+ comments,
6987
+ weekLabel: week.label,
6988
+ weekKey,
6989
+ locationOptions,
6990
+ onAddComment,
6991
+ onCommentClick
6992
+ }
6993
+ )
6994
+ ]
6995
+ }
6996
+ );
6997
+ }
6998
+ function SupplierColumnHeader({
6999
+ column
7000
+ }) {
7001
+ return /* @__PURE__ */ jsxRuntime.jsxs(
7002
+ Button,
7003
+ {
7004
+ variant: "ghost",
7005
+ size: "sm",
7006
+ className: "-ml-3 h-8 data-[state=open]:bg-accent",
7007
+ onClick: () => column.toggleSorting(column.getIsSorted() === "asc"),
7008
+ children: [
7009
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: "Supplier / Scope" }),
7010
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUpDown, { className: "ml-2 h-4 w-4" })
7011
+ ]
7012
+ }
7013
+ );
7014
+ }
7015
+ function getSupplierColumn() {
7016
+ return {
7017
+ id: "supplier",
7018
+ accessorKey: "name",
7019
+ header: ({ column }) => /* @__PURE__ */ jsxRuntime.jsx(SupplierColumnHeader, { column }),
7020
+ cell: ({ row }) => /* @__PURE__ */ jsxRuntime.jsx(SupplierCell, { supplier: row.original }),
7021
+ enableSorting: true,
7022
+ enableHiding: false
7023
+ };
7024
+ }
7025
+ function WeekHeaderWithComments({
7026
+ week,
7027
+ weekKey,
7028
+ config,
7029
+ suppliers
7030
+ }) {
7031
+ const weekComments = config?.weekComments?.[weekKey] ?? [];
7032
+ let filteredSuppliers = suppliers;
7033
+ if (config?.userRole === "supplier" && config?.currentSupplierId) {
7034
+ filteredSuppliers = suppliers.filter((s) => s.id === config.currentSupplierId);
7035
+ }
7036
+ const locationOptions = generateLocationOptions(filteredSuppliers, weekKey);
7037
+ const handleAddComment = config?.onAddWeekComment ? (text, location) => {
7038
+ config.onAddWeekComment?.(weekKey, text, location);
7039
+ } : void 0;
7040
+ const handleCommentClick = config?.onCommentClick;
7041
+ return /* @__PURE__ */ jsxRuntime.jsx(
7042
+ WeekHeader,
7043
+ {
7044
+ week,
7045
+ weekKey,
7046
+ comments: weekComments,
7047
+ showCommentButton: true,
7048
+ locationOptions,
7049
+ onAddComment: handleAddComment,
7050
+ onCommentClick: handleCommentClick
7051
+ }
7052
+ );
7053
+ }
7054
+ function generateWeekColumns(weeks, config, suppliers) {
7055
+ return weeks.map((week) => {
7056
+ const weekKey = getWeekKey(week.startDate);
7057
+ return {
7058
+ id: weekKey,
7059
+ accessorFn: (supplier) => supplier.weeks[weekKey],
7060
+ header: () => /* @__PURE__ */ jsxRuntime.jsx(
7061
+ WeekHeaderWithComments,
7062
+ {
7063
+ week,
7064
+ weekKey,
7065
+ config,
7066
+ suppliers: suppliers ?? []
7067
+ }
7068
+ ),
7069
+ cell: ({ row }) => {
7070
+ const supplier = row.original;
7071
+ const data = supplier.weeks[weekKey] || { type: "empty" };
7072
+ return /* @__PURE__ */ jsxRuntime.jsx(
7073
+ WeekCell,
7074
+ {
7075
+ data,
7076
+ week,
7077
+ supplier,
7078
+ isCurrentWeek: week.isCurrentWeek,
7079
+ onCellClick: config?.onCellClick ? () => config.onCellClick?.(supplier, week, data) : void 0
7080
+ }
7081
+ );
7082
+ },
7083
+ enableSorting: false,
7084
+ enableHiding: true
7085
+ };
7086
+ });
7087
+ }
7088
+ function generateColumns(weeks, config, suppliers) {
7089
+ return [
7090
+ getSupplierColumn(),
7091
+ ...generateWeekColumns(weeks, config, suppliers)
7092
+ ];
7093
+ }
7094
+ function PlanningTable({
7095
+ className,
7096
+ suppliers,
7097
+ config = {}
7098
+ }) {
7099
+ const {
7100
+ weekCount = 12,
7101
+ startDate = /* @__PURE__ */ new Date(),
7102
+ highlightCurrentWeek = true,
7103
+ showToolbar = true,
7104
+ showPagination = true,
7105
+ pageSizeOptions = [10, 20, 30, 50],
7106
+ defaultPageSize = 10,
7107
+ stickySupplierColumn = true,
7108
+ maxHeight = "600px"
7109
+ } = config;
7110
+ const weeks = React22__namespace.useMemo(
7111
+ () => generateWeeks(startDate, weekCount),
7112
+ [startDate, weekCount]
7113
+ );
7114
+ const currentWeekKey = React22__namespace.useMemo(() => {
7115
+ const currentWeek = weeks.find((w) => w.isCurrentWeek);
7116
+ return currentWeek ? getWeekKey(currentWeek.startDate) : null;
7117
+ }, [weeks]);
7118
+ const columns = React22__namespace.useMemo(
7119
+ () => generateColumns(weeks, config, suppliers),
7120
+ [weeks, config, suppliers]
7121
+ );
7122
+ const [sorting, setSorting] = React22__namespace.useState([]);
7123
+ const [columnFilters, setColumnFilters] = React22__namespace.useState([]);
7124
+ const [columnVisibility, setColumnVisibility] = React22__namespace.useState({});
7125
+ const [rowSelection, setRowSelection] = React22__namespace.useState({});
7126
+ const table = reactTable.useReactTable({
7127
+ data: suppliers,
7128
+ columns,
7129
+ getCoreRowModel: reactTable.getCoreRowModel(),
7130
+ getSortedRowModel: reactTable.getSortedRowModel(),
7131
+ getFilteredRowModel: reactTable.getFilteredRowModel(),
7132
+ getPaginationRowModel: reactTable.getPaginationRowModel(),
7133
+ onSortingChange: setSorting,
7134
+ onColumnFiltersChange: setColumnFilters,
7135
+ onColumnVisibilityChange: setColumnVisibility,
7136
+ onRowSelectionChange: setRowSelection,
7137
+ state: {
7138
+ sorting,
7139
+ columnFilters,
7140
+ columnVisibility,
7141
+ rowSelection
7142
+ },
7143
+ initialState: {
7144
+ pagination: {
7145
+ pageSize: defaultPageSize
7146
+ }
7147
+ }
7148
+ });
7149
+ return /* @__PURE__ */ jsxRuntime.jsxs(
7150
+ "div",
7151
+ {
7152
+ "data-slot": "planning-table",
7153
+ className: cn("flex flex-col gap-4", className),
7154
+ children: [
7155
+ showToolbar && /* @__PURE__ */ jsxRuntime.jsx(PlanningTableToolbar, { table }),
7156
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl border bg-background shadow-sm overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(
7157
+ ScrollArea,
7158
+ {
7159
+ className: "w-full",
7160
+ style: { maxHeight },
7161
+ children: [
7162
+ /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full border-collapse", children: [
7163
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "sticky top-0 z-20", children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsxRuntime.jsx(
7164
+ "tr",
7165
+ {
7166
+ children: headerGroup.headers.map((header, index) => {
7167
+ const isCurrentWeekColumn = header.id === currentWeekKey;
7168
+ return /* @__PURE__ */ jsxRuntime.jsx(
7169
+ "th",
7170
+ {
7171
+ className: cn(
7172
+ "h-14 px-3 text-left align-middle font-semibold text-xs text-muted-foreground uppercase tracking-wide",
7173
+ "border-r border-b border-border last:border-r-0 bg-sidebar",
7174
+ // First column: sticky with right-edge shadow (Quantum token)
7175
+ index === 0 && stickySupplierColumn && [
7176
+ "sticky left-0 z-30 min-w-[200px]",
7177
+ "shadow-[var(--j3m-shadow-sticky-edge)]"
7178
+ ],
7179
+ index > 0 && "min-w-[140px]",
7180
+ // Current week: only highlight text/dot, not full background
7181
+ isCurrentWeekColumn && highlightCurrentWeek && "text-primary"
7182
+ ),
7183
+ children: header.isPlaceholder ? null : reactTable.flexRender(
7184
+ header.column.columnDef.header,
7185
+ header.getContext()
7186
+ )
7187
+ },
7188
+ header.id
7189
+ );
7190
+ })
7191
+ },
7192
+ headerGroup.id
7193
+ )) }),
7194
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "bg-background", children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ jsxRuntime.jsx(
7195
+ "tr",
7196
+ {
7197
+ "data-state": row.getIsSelected() && "selected",
7198
+ className: "border-b border-border last:border-b-0",
7199
+ children: row.getVisibleCells().map((cell, index) => {
7200
+ return /* @__PURE__ */ jsxRuntime.jsx(
7201
+ "td",
7202
+ {
7203
+ className: cn(
7204
+ "p-0 align-top border-r border-border last:border-r-0 bg-background",
7205
+ // First column: sticky WHITE with right-edge shadow (Quantum token)
7206
+ index === 0 && stickySupplierColumn && [
7207
+ "sticky left-0 z-10 min-w-[200px]",
7208
+ "shadow-[var(--j3m-shadow-sticky-edge)]"
7209
+ ],
7210
+ index > 0 && "min-w-[140px]"
7211
+ ),
7212
+ children: reactTable.flexRender(
7213
+ cell.column.columnDef.cell,
7214
+ cell.getContext()
7215
+ )
7216
+ },
7217
+ cell.id
7218
+ );
7219
+ })
7220
+ },
7221
+ row.id
7222
+ )) : /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx(
7223
+ "td",
7224
+ {
7225
+ colSpan: columns.length,
7226
+ className: "h-24 text-center text-muted-foreground bg-background",
7227
+ children: "No suppliers found."
7228
+ }
7229
+ ) }) })
7230
+ ] }),
7231
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollBar, { orientation: "horizontal" }),
7232
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollBar, { orientation: "vertical" })
7233
+ ]
7234
+ }
7235
+ ) }),
7236
+ showPagination && /* @__PURE__ */ jsxRuntime.jsx(
7237
+ DataTablePagination,
7238
+ {
7239
+ table,
7240
+ showRowSelection: false,
7241
+ pageSizeOptions
7242
+ }
7243
+ )
7244
+ ]
7245
+ }
7246
+ );
7247
+ }
7248
+ function getStatusBadgeVariant(status) {
7249
+ switch (status) {
7250
+ case "on-time":
7251
+ return "outline";
7252
+ case "delayed":
7253
+ return "secondary";
7254
+ case "critical":
7255
+ return "destructive";
7256
+ default:
7257
+ return "outline";
7258
+ }
7259
+ }
7260
+ function getStatusBadgeClasses(status) {
7261
+ switch (status) {
7262
+ case "on-time":
7263
+ return "border-green-500 text-green-600 bg-green-50 dark:bg-green-950/50";
7264
+ case "delayed":
7265
+ return "border-amber-500 text-amber-600 bg-amber-50 dark:bg-amber-950/50";
7266
+ case "critical":
7267
+ return "";
7268
+ default:
7269
+ return "";
7270
+ }
7271
+ }
7272
+ function getStatusLabel(status) {
7273
+ switch (status) {
7274
+ case "on-time":
7275
+ return "On Track";
7276
+ case "delayed":
7277
+ return "At Risk";
7278
+ case "critical":
7279
+ return "Critical";
7280
+ case "pending":
7281
+ return "Pending";
7282
+ default:
7283
+ return status;
7284
+ }
7285
+ }
7286
+ function getProgressVariant(status) {
7287
+ switch (status) {
7288
+ case "on-time":
7289
+ return "success";
7290
+ case "delayed":
7291
+ return "warning";
7292
+ case "critical":
7293
+ return "destructive";
7294
+ default:
7295
+ return "default";
7296
+ }
7297
+ }
7298
+ function getShipmentStatusBadgeClasses(status) {
7299
+ switch (status) {
7300
+ case "sent":
7301
+ return "border-green-500 text-green-600 bg-green-50 dark:bg-green-950/50";
7302
+ case "not-sent":
7303
+ return "border-muted-foreground/50 text-muted-foreground bg-muted/50";
7304
+ case "moved":
7305
+ return "border-blue-500 text-blue-600 bg-blue-50 dark:bg-blue-950/50";
7306
+ case "addon":
7307
+ return "border-purple-500 text-purple-600 bg-purple-50 dark:bg-purple-950/50";
7308
+ case "planned":
7309
+ default:
7310
+ return "border-muted-foreground/50 text-muted-foreground";
7311
+ }
7312
+ }
7313
+ function getShipmentStatusRowBg(status) {
7314
+ switch (status) {
7315
+ case "sent":
7316
+ return "bg-green-50/30 dark:bg-green-950/10";
7317
+ case "not-sent":
7318
+ return "bg-muted/30";
7319
+ case "moved":
7320
+ return "bg-blue-50/30 dark:bg-blue-950/10";
7321
+ case "addon":
7322
+ return "bg-purple-50/30 dark:bg-purple-950/10";
7323
+ default:
7324
+ return "";
7325
+ }
7326
+ }
7327
+ function DeliveryCommentPopover({
7328
+ comments = [],
7329
+ onAddComment,
7330
+ deliveryLabel
7331
+ }) {
7332
+ const [open, setOpen] = React22__namespace.useState(false);
7333
+ const [newCommentText, setNewCommentText] = React22__namespace.useState("");
7334
+ const [viewCommentsOpen, setViewCommentsOpen] = React22__namespace.useState(true);
7335
+ const [showAddForm, setShowAddForm] = React22__namespace.useState(false);
7336
+ const handleSubmit = () => {
7337
+ if (newCommentText.trim() && onAddComment) {
7338
+ onAddComment(newCommentText.trim());
7339
+ setNewCommentText("");
7340
+ setShowAddForm(false);
7341
+ setViewCommentsOpen(true);
7342
+ }
7343
+ };
7344
+ const handleKeyDown = (e) => {
7345
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
7346
+ e.preventDefault();
7347
+ handleSubmit();
7348
+ }
7349
+ if (e.key === "Escape") {
7350
+ setShowAddForm(false);
7351
+ setNewCommentText("");
7352
+ }
7353
+ };
7354
+ const formatDate2 = (date) => {
7355
+ return new Intl.DateTimeFormat("en-US", {
7356
+ month: "short",
7357
+ day: "numeric",
7358
+ hour: "numeric",
7359
+ minute: "2-digit"
7360
+ }).format(date);
7361
+ };
7362
+ const prevOpenRef = React22__namespace.useRef(open);
7363
+ React22__namespace.useEffect(() => {
7364
+ const wasOpen = prevOpenRef.current;
7365
+ prevOpenRef.current = open;
7366
+ if (wasOpen && !open) {
7367
+ setShowAddForm(false);
7368
+ setNewCommentText("");
7369
+ }
7370
+ }, [open]);
7371
+ return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange: setOpen, children: [
7372
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(CommentButton, { size: "sm", commentCount: comments.length }) }),
7373
+ /* @__PURE__ */ jsxRuntime.jsxs(
7374
+ PopoverContent,
7375
+ {
7376
+ className: "w-80 p-0 z-[100]",
7377
+ align: "end",
7378
+ sideOffset: 8,
7379
+ collisionPadding: 16,
7380
+ children: [
7381
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 py-3 border-b border-border", children: [
7382
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-sm font-semibold", children: "Comments" }),
7383
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: deliveryLabel })
7384
+ ] }),
7385
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-2 space-y-2 max-h-[400px] overflow-y-auto", children: [
7386
+ /* @__PURE__ */ jsxRuntime.jsxs(Collapsible, { open: viewCommentsOpen, onOpenChange: setViewCommentsOpen, children: [
7387
+ /* @__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: [
7388
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs font-medium", children: [
7389
+ "Comments ",
7390
+ comments.length > 0 && `(${comments.length})`
7391
+ ] }),
7392
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: cn(
7393
+ "h-4 w-4 transition-transform duration-200",
7394
+ viewCommentsOpen && "rotate-180"
7395
+ ) })
7396
+ ] }) }),
7397
+ /* @__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: [
7398
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
7399
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium", children: comment.author }),
7400
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: formatDate2(comment.createdAt) })
7401
+ ] }),
7402
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-foreground", children: comment.text })
7403
+ ] }, comment.id)) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground text-center py-2", children: "No comments yet" }) })
7404
+ ] }),
7405
+ /* @__PURE__ */ jsxRuntime.jsx(Separator, { className: "my-2" }),
7406
+ !showAddForm ? /* @__PURE__ */ jsxRuntime.jsxs(
7407
+ Button,
7408
+ {
7409
+ variant: "outline",
7410
+ size: "sm",
7411
+ className: "w-full justify-center gap-2 h-8",
7412
+ onClick: () => setShowAddForm(true),
7413
+ children: [
7414
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3.5 w-3.5" }),
7415
+ "Add comment"
7416
+ ]
7417
+ }
7418
+ ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(
7419
+ "space-y-3 p-3 rounded-lg border border-border bg-muted/30",
7420
+ "animate-in fade-in-0 slide-in-from-top-2 duration-200"
7421
+ ), children: [
7422
+ /* @__PURE__ */ jsxRuntime.jsx(
7423
+ Textarea,
7424
+ {
7425
+ placeholder: "Type your comment...",
7426
+ value: newCommentText,
7427
+ onChange: (e) => setNewCommentText(e.target.value),
7428
+ onKeyDown: handleKeyDown,
7429
+ className: "min-h-[80px] text-sm resize-none",
7430
+ autoFocus: true
7431
+ }
7432
+ ),
7433
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
7434
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: "\u2318+Enter to send \xB7 Esc to cancel" }),
7435
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
7436
+ /* @__PURE__ */ jsxRuntime.jsx(
7437
+ Button,
7438
+ {
7439
+ variant: "ghost",
7440
+ size: "sm",
7441
+ className: "h-7",
7442
+ onClick: () => {
7443
+ setShowAddForm(false);
7444
+ setNewCommentText("");
7445
+ },
7446
+ children: "Cancel"
7447
+ }
7448
+ ),
7449
+ /* @__PURE__ */ jsxRuntime.jsxs(
7450
+ Button,
7451
+ {
7452
+ size: "sm",
7453
+ className: "h-7 gap-1",
7454
+ onClick: handleSubmit,
7455
+ disabled: !newCommentText.trim(),
7456
+ children: [
7457
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "h-3 w-3" }),
7458
+ "Save"
7459
+ ]
7460
+ }
7461
+ )
7462
+ ] })
7463
+ ] })
7464
+ ] })
7465
+ ] })
7466
+ ]
7467
+ }
7468
+ )
7469
+ ] });
7470
+ }
7471
+ function ProductionCommentSection({
7472
+ comments = [],
7473
+ onAddComment
7474
+ }) {
7475
+ const [showAddForm, setShowAddForm] = React22__namespace.useState(false);
7476
+ const [newComment, setNewComment] = React22__namespace.useState("");
7477
+ const handleSubmit = () => {
7478
+ if (newComment.trim() && onAddComment) {
7479
+ onAddComment(newComment.trim());
7480
+ setNewComment("");
7481
+ setShowAddForm(false);
7482
+ }
7483
+ };
7484
+ const handleKeyDown = (e) => {
7485
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
7486
+ e.preventDefault();
7487
+ handleSubmit();
7488
+ }
7489
+ if (e.key === "Escape") {
7490
+ setShowAddForm(false);
7491
+ setNewComment("");
7492
+ }
7493
+ };
7494
+ const formatDate2 = (date) => {
7495
+ return new Intl.DateTimeFormat("en-US", {
7496
+ month: "short",
7497
+ day: "numeric",
7498
+ hour: "numeric",
7499
+ minute: "2-digit"
7500
+ }).format(date);
7501
+ };
7502
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
7503
+ 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: [
7504
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
7505
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium", children: comment.author }),
7506
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: formatDate2(comment.createdAt) })
7507
+ ] }),
7508
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-foreground", children: comment.text })
7509
+ ] }, comment.id)) }),
7510
+ !showAddForm ? /* @__PURE__ */ jsxRuntime.jsxs(
7511
+ Button,
7512
+ {
7513
+ variant: "ghost",
7514
+ size: "sm",
7515
+ className: "w-full justify-start gap-2 h-8 text-muted-foreground",
7516
+ onClick: () => setShowAddForm(true),
7517
+ children: [
7518
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "h-3.5 w-3.5" }),
7519
+ comments.length > 0 ? "Add another comment" : "Add a comment..."
7520
+ ]
7521
+ }
7522
+ ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 animate-in fade-in-0 slide-in-from-top-2 duration-200", children: [
7523
+ /* @__PURE__ */ jsxRuntime.jsx(
7524
+ Textarea,
7525
+ {
7526
+ placeholder: "Add a comment...",
7527
+ value: newComment,
7528
+ onChange: (e) => setNewComment(e.target.value),
7529
+ onKeyDown: handleKeyDown,
7530
+ className: "min-h-[60px] text-sm resize-none",
7531
+ autoFocus: true
7532
+ }
7533
+ ),
7534
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
7535
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: "\u2318+Enter to send" }),
7536
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
7537
+ /* @__PURE__ */ jsxRuntime.jsx(
7538
+ Button,
7539
+ {
7540
+ variant: "ghost",
7541
+ size: "sm",
7542
+ className: "h-7",
7543
+ onClick: () => {
7544
+ setShowAddForm(false);
7545
+ setNewComment("");
7546
+ },
7547
+ children: "Cancel"
7548
+ }
7549
+ ),
7550
+ /* @__PURE__ */ jsxRuntime.jsxs(
7551
+ Button,
7552
+ {
7553
+ size: "sm",
7554
+ className: "h-7 gap-1",
7555
+ onClick: handleSubmit,
7556
+ disabled: !newComment.trim(),
7557
+ children: [
7558
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "h-3 w-3" }),
7559
+ "Save"
7560
+ ]
7561
+ }
7562
+ )
7563
+ ] })
7564
+ ] })
7565
+ ] })
7566
+ ] });
7567
+ }
7568
+ function DeliveryListItem({
7569
+ delivery,
7570
+ index,
7571
+ onClick
7572
+ }) {
7573
+ const hasComments = (delivery.comments?.length ?? 0) > 0;
7574
+ return /* @__PURE__ */ jsxRuntime.jsxs(
7575
+ "button",
7576
+ {
7577
+ onClick,
7578
+ className: cn(
7579
+ "w-full flex items-center justify-between p-3 rounded-lg",
7580
+ "bg-card border hover:bg-muted/50 transition-colors cursor-pointer",
7581
+ "text-left"
7582
+ ),
7583
+ children: [
7584
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
7585
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
7586
+ "flex items-center justify-center h-8 w-8 rounded-lg",
7587
+ delivery.status === "on-time" && "bg-green-100 dark:bg-green-950/50",
7588
+ delivery.status === "delayed" && "bg-amber-100 dark:bg-amber-950/50",
7589
+ delivery.status === "critical" && "bg-red-100 dark:bg-red-950/50"
7590
+ ), children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: cn(
7591
+ "h-4 w-4",
7592
+ delivery.status === "on-time" && "text-green-600 dark:text-green-400",
7593
+ delivery.status === "delayed" && "text-amber-600 dark:text-amber-400",
7594
+ delivery.status === "critical" && "text-red-600 dark:text-red-400"
7595
+ ) }) }),
7596
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
7597
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
7598
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: delivery.label || `Delivery ${index + 1}` }),
7599
+ hasComments && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
7600
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquare, { className: "h-3 w-3 text-muted-foreground" }),
7601
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute -top-0.5 -right-0.5 h-1.5 w-1.5 rounded-full bg-primary" })
7602
+ ] })
7603
+ ] }),
7604
+ delivery.destination && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-muted-foreground", children: [
7605
+ "\u2192 ",
7606
+ delivery.destination
7607
+ ] })
7608
+ ] })
7609
+ ] }),
7610
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
7611
+ /* @__PURE__ */ jsxRuntime.jsx(
7612
+ Badge,
7613
+ {
7614
+ variant: getStatusBadgeVariant(delivery.status),
7615
+ className: cn("text-xs", getStatusBadgeClasses(delivery.status)),
7616
+ children: getStatusLabel(delivery.status)
7617
+ }
7618
+ ),
7619
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4 text-muted-foreground" })
7620
+ ] })
7621
+ ]
7622
+ }
7623
+ );
7624
+ }
7625
+ function DeliveryDetailsView({
7626
+ delivery,
7627
+ week,
7628
+ onBack,
7629
+ onAddComment
7630
+ }) {
7631
+ const elements = delivery.elements ?? [];
7632
+ const categorizedElements = React22__namespace.useMemo(() => {
7633
+ const sent = [];
7634
+ const notSent = [];
7635
+ const moved = [];
7636
+ const addons = [];
7637
+ elements.forEach((element) => {
7638
+ const status = getElementShipmentStatus(element, delivery.id);
7639
+ switch (status) {
7640
+ case "sent":
7641
+ sent.push(element);
7642
+ break;
7643
+ case "not-sent":
7644
+ notSent.push(element);
7645
+ break;
7646
+ case "moved":
7647
+ moved.push(element);
7648
+ break;
7649
+ case "addon":
7650
+ addons.push(element);
7651
+ break;
7652
+ default:
7653
+ notSent.push(element);
7654
+ }
7655
+ });
7656
+ return { sent, notSent, moved, addons };
7657
+ }, [elements, delivery.id]);
7658
+ const totalCount = elements.length;
7659
+ const sentCount = categorizedElements.sent.length;
7660
+ (delivery.comments?.length ?? 0) > 0;
7661
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col h-full animate-in slide-in-from-right-4 duration-200", children: [
7662
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2 px-6 py-3 border-b", children: /* @__PURE__ */ jsxRuntime.jsxs(
7663
+ Button,
7664
+ {
7665
+ variant: "ghost",
7666
+ size: "sm",
7667
+ className: "gap-1 -ml-2",
7668
+ onClick: onBack,
7669
+ children: [
7670
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "h-4 w-4" }),
7671
+ "Back"
7672
+ ]
7673
+ }
7674
+ ) }),
7675
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-6 py-4 space-y-2", children: [
7676
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
7677
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-lg font-semibold", children: delivery.label || "Delivery Details" }),
7678
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
7679
+ /* @__PURE__ */ jsxRuntime.jsx(
7680
+ DeliveryCommentPopover,
7681
+ {
7682
+ comments: delivery.comments,
7683
+ onAddComment,
7684
+ deliveryLabel: delivery.label || "Delivery"
7685
+ }
7686
+ ),
7687
+ /* @__PURE__ */ jsxRuntime.jsx(
7688
+ Badge,
7689
+ {
7690
+ variant: getStatusBadgeVariant(delivery.status),
7691
+ className: cn("text-xs", getStatusBadgeClasses(delivery.status)),
7692
+ children: getStatusLabel(delivery.status)
7693
+ }
7694
+ )
7695
+ ] })
7696
+ ] }),
7697
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 text-sm text-muted-foreground", children: [
7698
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
7699
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Calendar, { className: "h-3.5 w-3.5" }),
7700
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
7701
+ week.label,
7702
+ " \u2022 ",
7703
+ week.dateRange
7704
+ ] })
7705
+ ] }),
7706
+ delivery.destination && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
7707
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: "h-3.5 w-3.5" }),
7708
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
7709
+ "\u2192 ",
7710
+ delivery.destination
7711
+ ] })
7712
+ ] })
7713
+ ] })
7714
+ ] }),
7715
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "flex-1 px-6 pb-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
7716
+ totalCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg bg-muted/50 p-4", children: [
7717
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-2", children: [
7718
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "Shipment Progress" }),
7719
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm font-semibold tabular-nums", children: [
7720
+ "Shipped ",
7721
+ sentCount,
7722
+ " / ",
7723
+ totalCount
7724
+ ] })
7725
+ ] }),
7726
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-2 bg-black/10 dark:bg-white/10 rounded-full overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
7727
+ "div",
7728
+ {
7729
+ className: cn(
7730
+ "h-full rounded-full transition-all",
7731
+ sentCount === totalCount ? "bg-green-500" : "bg-primary"
7732
+ ),
7733
+ style: { width: `${totalCount > 0 ? sentCount / totalCount * 100 : 0}%` }
7734
+ }
7735
+ ) }),
7736
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 mt-3 flex-wrap", children: [
7737
+ categorizedElements.sent.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [
7738
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircle2, { className: "h-3 w-3 text-green-600" }),
7739
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-green-700 dark:text-green-300", children: [
7740
+ categorizedElements.sent.length,
7741
+ " Sent"
7742
+ ] })
7743
+ ] }),
7744
+ categorizedElements.notSent.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [
7745
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XCircle, { className: "h-3 w-3 text-amber-600" }),
7746
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-amber-700 dark:text-amber-300", children: [
7747
+ categorizedElements.notSent.length,
7748
+ " Not sent"
7749
+ ] })
7750
+ ] }),
7751
+ categorizedElements.moved.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [
7752
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowRight, { className: "h-3 w-3 text-blue-600" }),
7753
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-blue-700 dark:text-blue-300", children: [
7754
+ categorizedElements.moved.length,
7755
+ " Moved"
7756
+ ] })
7757
+ ] }),
7758
+ categorizedElements.addons.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [
7759
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3 w-3 text-purple-600" }),
7760
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-purple-700 dark:text-purple-300", children: [
7761
+ categorizedElements.addons.length,
7762
+ " Add-on"
7763
+ ] })
7764
+ ] })
7765
+ ] })
7766
+ ] }),
7767
+ elements.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
7768
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: "Elements" }),
7769
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(Table, { children: [
7770
+ /* @__PURE__ */ jsxRuntime.jsx(TableHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(TableRow, { className: "bg-sidebar hover:bg-sidebar", children: [
7771
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "font-semibold", children: "Prefix" }),
7772
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "font-semibold", children: "Type" }),
7773
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "font-semibold text-right", children: "Weight" }),
7774
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "font-semibold text-right", children: "Size (m\xB2)" }),
7775
+ /* @__PURE__ */ jsxRuntime.jsx(TableHead, { className: "font-semibold text-center", children: "Status" })
7776
+ ] }) }),
7777
+ /* @__PURE__ */ jsxRuntime.jsx(TableBody, { children: elements.map((element) => {
7778
+ const shipmentStatus = getElementShipmentStatus(element, delivery.id);
7779
+ const statusLabel = getShipmentStatusLabel(shipmentStatus);
7780
+ return /* @__PURE__ */ jsxRuntime.jsxs(
7781
+ TableRow,
7782
+ {
7783
+ className: getShipmentStatusRowBg(shipmentStatus),
7784
+ children: [
7785
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { className: "font-medium", children: element.prefix || "\u2014" }),
7786
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { children: element.type || element.name || "\u2014" }),
7787
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { className: "text-right tabular-nums", children: element.weight ? /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
7788
+ element.weight,
7789
+ " ",
7790
+ element.weightUnit || "kg"
7791
+ ] }) : "\u2014" }),
7792
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { className: "text-right tabular-nums", children: element.sizeSqm ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: element.sizeSqm }) : "\u2014" }),
7793
+ /* @__PURE__ */ jsxRuntime.jsx(TableCell, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-1", children: [
7794
+ /* @__PURE__ */ jsxRuntime.jsx(
7795
+ Badge,
7796
+ {
7797
+ variant: "outline",
7798
+ className: cn(
7799
+ "text-[10px] h-5",
7800
+ getShipmentStatusBadgeClasses(shipmentStatus)
7801
+ ),
7802
+ children: statusLabel
7803
+ }
7804
+ ),
7805
+ shipmentStatus === "moved" && element.actualDeliveryLabel && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[9px] text-blue-600 dark:text-blue-400", children: [
7806
+ "\u2192 ",
7807
+ element.actualDeliveryLabel
7808
+ ] }),
7809
+ shipmentStatus === "addon" && element.originalDeliveryLabel && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[9px] text-purple-600 dark:text-purple-400", children: [
7810
+ "from ",
7811
+ element.originalDeliveryLabel
7812
+ ] })
7813
+ ] }) })
7814
+ ]
7815
+ },
7816
+ element.id
7817
+ );
7818
+ }) })
7819
+ ] }) })
7820
+ ] }),
7821
+ elements.length === 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center py-8 text-muted-foreground", children: [
7822
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Package, { className: "h-8 w-8 mx-auto mb-2 opacity-50" }),
7823
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm", children: "No elements in this delivery" })
7824
+ ] })
7825
+ ] }) })
7826
+ ] });
7827
+ }
7828
+ function MainView({
7829
+ supplier,
7830
+ week,
7831
+ data,
7832
+ producedValue,
7833
+ hasChanges,
7834
+ onProducedChange,
7835
+ onSave,
7836
+ onSelectDelivery,
7837
+ onAddProductionComment
7838
+ }) {
7839
+ const production = data?.production;
7840
+ const productionProgress = production ? Math.min(100, Math.round(production.produced / production.target * 100)) : data?.progress ?? 0;
7841
+ const productionStatus = production?.status ?? "on-time";
7842
+ const isComplete = productionProgress >= 100;
7843
+ const hasProductionComments = (production?.comments?.length ?? 0) > 0;
7844
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "animate-in fade-in-0 duration-200", children: [
7845
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { className: "px-6 pt-6 pb-4", children: [
7846
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogTitle, { className: "flex items-center gap-2", children: [
7847
+ supplier.name,
7848
+ /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "secondary", className: "text-xs font-normal", children: supplier.badgeType })
7849
+ ] }),
7850
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogDescription, { className: "flex items-center gap-2", children: [
7851
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Calendar, { className: "h-4 w-4" }),
7852
+ week.label,
7853
+ " \u2022 ",
7854
+ week.dateRange
7855
+ ] })
7856
+ ] }),
7857
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { className: "flex-1 px-6 pb-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-8", children: [
7858
+ data.type !== "empty" && /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-4", children: [
7859
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
7860
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Factory, { className: "h-4 w-4 text-muted-foreground" }),
7861
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold", children: "Production" }),
7862
+ /* @__PURE__ */ jsxRuntime.jsx(
7863
+ Badge,
7864
+ {
7865
+ variant: getStatusBadgeVariant(productionStatus),
7866
+ className: cn("text-xs ml-auto", getStatusBadgeClasses(productionStatus)),
7867
+ children: getStatusLabel(productionStatus)
7868
+ }
7869
+ )
7870
+ ] }),
7871
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-6", children: [
7872
+ /* @__PURE__ */ jsxRuntime.jsx(
7873
+ CircularProgress,
7874
+ {
7875
+ value: productionProgress,
7876
+ size: 100,
7877
+ strokeWidth: 10,
7878
+ variant: getProgressVariant(productionStatus),
7879
+ showCheckmark: isComplete,
7880
+ children: isComplete ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center", children: [
7881
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-6 w-6 text-green-600" }),
7882
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs font-semibold text-green-600", children: [
7883
+ production?.produced ?? 0,
7884
+ " ",
7885
+ production ? formatProductionUnit(production.unit) : ""
7886
+ ] })
7887
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center", children: [
7888
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-lg font-bold tabular-nums", children: production?.produced ?? 0 }),
7889
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] text-muted-foreground", children: [
7890
+ "/ ",
7891
+ production?.target ?? 0,
7892
+ " ",
7893
+ production ? formatProductionUnit(production.unit) : ""
7894
+ ] })
7895
+ ] })
7896
+ }
7897
+ ),
7898
+ production && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 space-y-3", children: [
7899
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
7900
+ /* @__PURE__ */ jsxRuntime.jsxs(Label2, { htmlFor: "produced", className: "text-xs", children: [
7901
+ "Produced Amount (",
7902
+ formatProductionUnit(production.unit),
7903
+ ")"
7904
+ ] }),
7905
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
7906
+ Input,
7907
+ {
7908
+ id: "produced",
7909
+ type: "number",
7910
+ min: "0",
7911
+ max: production.target * 2,
7912
+ value: producedValue,
7913
+ onChange: onProducedChange,
7914
+ className: "h-9"
7915
+ }
7916
+ ) }),
7917
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-[10px] text-muted-foreground", children: [
7918
+ "Target: ",
7919
+ production.target,
7920
+ " ",
7921
+ formatProductionUnit(production.unit)
7922
+ ] })
7923
+ ] }),
7924
+ /* @__PURE__ */ jsxRuntime.jsx(
7925
+ Button,
7926
+ {
7927
+ size: "sm",
7928
+ className: "w-full",
7929
+ disabled: !hasChanges,
7930
+ onClick: onSave,
7931
+ children: hasChanges ? "Save Progress" : "No Changes"
7932
+ }
7933
+ )
7934
+ ] })
7935
+ ] }),
7936
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
7937
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
7938
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Comments" }),
7939
+ hasProductionComments && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] text-muted-foreground", children: [
7940
+ "(",
7941
+ production?.comments?.length,
7942
+ ")"
7943
+ ] })
7944
+ ] }),
7945
+ /* @__PURE__ */ jsxRuntime.jsx(
7946
+ ProductionCommentSection,
7947
+ {
7948
+ comments: production?.comments,
7949
+ onAddComment: onAddProductionComment
7950
+ }
7951
+ )
7952
+ ] })
7953
+ ] }),
7954
+ data.deliveries && data.deliveries.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-4", children: [
7955
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
7956
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: "h-4 w-4 text-muted-foreground" }),
7957
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-semibold", children: "Deliveries" }),
7958
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground ml-auto", children: [
7959
+ data.deliveries.length,
7960
+ " scheduled"
7961
+ ] })
7962
+ ] }),
7963
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-2", children: data.deliveries.map((delivery, index) => /* @__PURE__ */ jsxRuntime.jsx(
7964
+ DeliveryListItem,
7965
+ {
7966
+ delivery,
7967
+ index,
7968
+ onClick: () => onSelectDelivery(delivery)
7969
+ },
7970
+ delivery.id
7971
+ )) })
7972
+ ] }),
7973
+ 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: [
7974
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Truck, { className: "h-4 w-4" }),
7975
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: "No logistics scheduled for this week" })
7976
+ ] }),
7977
+ 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: [
7978
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-4 w-4 mt-0.5 shrink-0" }),
7979
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm", children: data.warningMessage })
7980
+ ] }),
7981
+ data.notes && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
7982
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "Notes" }),
7983
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm", children: data.notes })
7984
+ ] })
7985
+ ] }) })
7986
+ ] });
7987
+ }
7988
+ function WeekDetailDialog({
7989
+ open,
7990
+ onOpenChange,
7991
+ supplier,
7992
+ week,
7993
+ data,
7994
+ onProgressUpdate,
7995
+ onAddProductionComment,
7996
+ onAddDeliveryComment
7997
+ }) {
7998
+ const production = data?.production;
7999
+ const initialProduced = production?.produced ?? 0;
8000
+ const [producedValue, setProducedValue] = React22__namespace.useState(initialProduced.toString());
8001
+ const [hasChanges, setHasChanges] = React22__namespace.useState(false);
8002
+ const [selectedDelivery, setSelectedDelivery] = React22__namespace.useState(null);
8003
+ React22__namespace.useEffect(() => {
8004
+ const newProduced = data?.production?.produced ?? 0;
8005
+ setProducedValue(newProduced.toString());
8006
+ setHasChanges(false);
8007
+ }, [data]);
8008
+ React22__namespace.useEffect(() => {
8009
+ if (!open) {
8010
+ setSelectedDelivery(null);
8011
+ }
8012
+ }, [open]);
8013
+ const handleProducedChange = (e) => {
8014
+ const value = e.target.value;
8015
+ setProducedValue(value);
8016
+ setHasChanges(true);
8017
+ };
8018
+ const handleSave = () => {
8019
+ if (!supplier || !week || !onProgressUpdate) return;
8020
+ const newProduced = parseFloat(producedValue) || 0;
8021
+ const target = production?.target || 100;
8022
+ const newProgress = Math.min(100, Math.round(newProduced / target * 100));
8023
+ const weekKey = `${week.year}-W${week.weekNumber.toString().padStart(2, "0")}`;
8024
+ onProgressUpdate(supplier.id, weekKey, newProgress, newProduced);
8025
+ setHasChanges(false);
8026
+ };
8027
+ if (!supplier || !week || !data) {
8028
+ return null;
8029
+ }
8030
+ return /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxRuntime.jsx(DialogContent, { className: "max-w-lg max-h-[85vh] p-0 gap-0 overflow-hidden", children: selectedDelivery ? /* @__PURE__ */ jsxRuntime.jsx(
8031
+ DeliveryDetailsView,
8032
+ {
8033
+ delivery: selectedDelivery,
8034
+ week,
8035
+ onBack: () => setSelectedDelivery(null),
8036
+ onAddComment: onAddDeliveryComment ? (text) => {
8037
+ const weekKey = `${week.year}-W${week.weekNumber.toString().padStart(2, "0")}`;
8038
+ onAddDeliveryComment(supplier.id, weekKey, selectedDelivery.id, text);
8039
+ } : void 0
8040
+ }
8041
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
8042
+ MainView,
8043
+ {
8044
+ supplier,
8045
+ week,
8046
+ data,
8047
+ producedValue,
8048
+ hasChanges,
8049
+ onProducedChange: handleProducedChange,
8050
+ onSave: handleSave,
8051
+ onSelectDelivery: setSelectedDelivery,
8052
+ onAddProductionComment: onAddProductionComment ? (text) => {
8053
+ const weekKey = `${week.year}-W${week.weekNumber.toString().padStart(2, "0")}`;
8054
+ onAddProductionComment(supplier.id, weekKey, text);
8055
+ } : void 0
8056
+ }
8057
+ ) }) });
8058
+ }
8059
+ function RowHeaderCell({
8060
+ className,
8061
+ data,
8062
+ showProgress = true,
8063
+ ...props
8064
+ }) {
8065
+ const progressPercent = data.totalRequired > 0 ? Math.min(data.totalBooked / data.totalRequired * 100, 100) : 0;
8066
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8067
+ "div",
8068
+ {
8069
+ "data-slot": "row-header-cell",
8070
+ className: cn(
8071
+ "flex flex-col justify-center gap-1.5 py-2 px-3 min-w-[200px] h-[100px] bg-background",
8072
+ className
8073
+ ),
8074
+ ...props,
8075
+ children: [
8076
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-2", children: [
8077
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
8078
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-bold leading-tight text-foreground truncate", children: data.name }),
8079
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: data.typeCode })
8080
+ ] }),
8081
+ /* @__PURE__ */ jsxRuntime.jsxs(
8082
+ Badge,
8083
+ {
8084
+ variant: "outline",
8085
+ className: "text-[10px] px-2 py-0.5 h-[19px] font-medium shrink-0 gap-1 bg-background border-border",
8086
+ children: [
8087
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Flag, { className: "h-2.5 w-2.5" }),
8088
+ "Paint"
8089
+ ]
8090
+ }
8091
+ )
8092
+ ] }),
8093
+ showProgress && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
8094
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-1.5 bg-black/10 dark:bg-white/10 rounded-full overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx(
8095
+ "div",
8096
+ {
8097
+ className: "h-full bg-primary rounded-full transition-all",
8098
+ style: { width: `${progressPercent}%` }
8099
+ }
8100
+ ) }),
8101
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-[10px] font-medium text-primary", children: [
8102
+ data.totalBooked.toLocaleString(),
8103
+ " / ",
8104
+ data.totalRequired.toLocaleString(),
8105
+ " Booked"
8106
+ ] })
8107
+ ] })
8108
+ ]
8109
+ }
8110
+ );
8111
+ }
8112
+ function NetBadge({
8113
+ className,
8114
+ net,
8115
+ status,
8116
+ compact = false,
8117
+ ...props
8118
+ }) {
8119
+ const statusStyles = {
8120
+ pending: {
8121
+ container: "bg-muted border-border/50",
8122
+ text: "text-muted-foreground",
8123
+ icon: "text-muted-foreground"
8124
+ },
8125
+ valid: {
8126
+ container: "bg-green-100/50 border-green-500 dark:bg-green-950/30 dark:border-green-400",
8127
+ text: "text-green-700 dark:text-green-400",
8128
+ icon: "text-green-600 dark:text-green-400"
8129
+ },
8130
+ shortfall: {
8131
+ container: "bg-red-100/30 border-red-400/50 dark:bg-red-950/30 dark:border-red-400/50",
8132
+ text: "text-red-700 dark:text-red-400",
8133
+ icon: "text-red-600 dark:text-red-400"
8134
+ }
8135
+ };
8136
+ const styles = statusStyles[status];
8137
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8138
+ "div",
8139
+ {
8140
+ "data-slot": "net-badge",
8141
+ "data-status": status,
8142
+ className: cn(
8143
+ "inline-flex items-center gap-1.5 px-3 py-0.5 rounded-full border",
8144
+ styles.container,
8145
+ className
8146
+ ),
8147
+ ...props,
8148
+ children: [
8149
+ status === "valid" && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: cn("h-3 w-3", styles.icon) }),
8150
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
8151
+ "text-xs font-bold leading-none",
8152
+ styles.text
8153
+ ), children: net >= 0 ? net : net }),
8154
+ !compact && /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
8155
+ "text-[10px] font-light opacity-80",
8156
+ styles.text
8157
+ ), children: "net" })
8158
+ ]
8159
+ }
8160
+ );
8161
+ }
8162
+
8163
+ // src/blocks/calibration-table/types.ts
8164
+ function formatCalibrationUnit(unit) {
8165
+ const unitLabels = {
8166
+ ton: "tons",
8167
+ pcs: "pcs",
8168
+ m2: "m\xB2",
8169
+ kg: "kg",
8170
+ m: "m"
8171
+ };
8172
+ return unitLabels[unit] || unit;
8173
+ }
8174
+ function calculateCalibrationCells(weeks) {
8175
+ const result = {};
8176
+ let accumulatedPlanned = 0;
8177
+ let accumulatedEntered = 0;
8178
+ for (const week of weeks) {
8179
+ accumulatedPlanned += week.planned;
8180
+ accumulatedEntered += week.entered ?? 0;
8181
+ const net = accumulatedEntered - accumulatedPlanned;
8182
+ let status = "pending";
8183
+ if (week.entered !== null) {
8184
+ status = net >= 0 ? "valid" : "shortfall";
8185
+ }
8186
+ result[week.weekKey] = {
8187
+ planned: week.planned,
8188
+ entered: week.entered,
8189
+ accumulatedPlanned,
8190
+ accumulatedEntered,
8191
+ net,
8192
+ status,
8193
+ isEditable: true
8194
+ };
8195
+ }
8196
+ return result;
8197
+ }
8198
+ function canSubmitCalibration(prefixes) {
8199
+ let shortfallCount = 0;
8200
+ let pendingCount = 0;
8201
+ for (const prefix of prefixes) {
8202
+ for (const weekKey in prefix.weeks) {
8203
+ const cell = prefix.weeks[weekKey];
8204
+ if (cell.status === "shortfall") shortfallCount++;
8205
+ if (cell.status === "pending") pendingCount++;
8206
+ }
8207
+ }
8208
+ const canSubmit = shortfallCount === 0 && pendingCount === 0;
8209
+ let message = "";
8210
+ if (shortfallCount > 0) {
8211
+ message = `Resolve ${shortfallCount} shortfall${shortfallCount > 1 ? "s" : ""} to submit`;
8212
+ } else if (pendingCount > 0) {
8213
+ message = `Enter production amounts for ${pendingCount} week${pendingCount > 1 ? "s" : ""}`;
8214
+ } else {
8215
+ message = "Ready to submit";
8216
+ }
8217
+ return { canSubmit, shortfallCount, pendingCount, message };
8218
+ }
8219
+ function CalibrationWeekCell({
8220
+ className,
8221
+ data,
8222
+ unit,
8223
+ onValueChange,
8224
+ isFocused,
8225
+ forcedRed = false,
8226
+ isEmpty = false,
8227
+ onAddClick,
8228
+ ...props
8229
+ }) {
8230
+ const inputRef = React22__namespace.useRef(null);
8231
+ const [localValue, setLocalValue] = React22__namespace.useState(
8232
+ data.entered !== null ? String(data.entered) : ""
8233
+ );
8234
+ const [isHovered, setIsHovered] = React22__namespace.useState(false);
8235
+ const [isEditing, setIsEditing] = React22__namespace.useState(false);
8236
+ React22__namespace.useEffect(() => {
8237
+ setLocalValue(data.entered !== null ? String(data.entered) : "");
8238
+ }, [data.entered]);
8239
+ const unitLabel = formatCalibrationUnit(unit);
8240
+ const effectiveStatus = forcedRed ? "forcedRed" : data.status;
8241
+ const handleInputChange = (e) => {
8242
+ const val = e.target.value;
8243
+ setLocalValue(val);
8244
+ if (val === "" || val === "-") {
8245
+ onValueChange?.(null);
8246
+ } else {
8247
+ const numVal = parseFloat(val);
8248
+ if (!isNaN(numVal)) {
8249
+ onValueChange?.(numVal);
8250
+ }
8251
+ }
8252
+ };
8253
+ const handleBlur = () => {
8254
+ setIsEditing(false);
8255
+ if (localValue === "" || localValue === "-") {
8256
+ setLocalValue("");
8257
+ onValueChange?.(null);
8258
+ } else {
8259
+ const numVal = parseFloat(localValue);
8260
+ if (!isNaN(numVal)) {
8261
+ setLocalValue(String(numVal));
8262
+ onValueChange?.(numVal);
8263
+ }
8264
+ }
8265
+ };
8266
+ const handleAddClick = () => {
8267
+ setIsEditing(true);
8268
+ onAddClick?.();
8269
+ setTimeout(() => {
8270
+ inputRef.current?.focus();
8271
+ }, 0);
8272
+ };
8273
+ const getContainerStyles = () => {
8274
+ switch (effectiveStatus) {
8275
+ case "valid":
8276
+ return "border-l-2 border-l-green-500 bg-green-50/50 dark:bg-green-950/30";
8277
+ case "shortfall":
8278
+ case "forcedRed":
8279
+ return "border-l-2 border-l-red-500 bg-red-50/50 dark:bg-red-950/30";
8280
+ case "pending":
8281
+ default:
8282
+ return cn(
8283
+ "bg-background",
8284
+ isHovered ? "border-l-2 border-l-border" : "border-l-2 border-l-transparent"
8285
+ );
8286
+ }
8287
+ };
8288
+ const getInputStyles = () => {
8289
+ switch (effectiveStatus) {
8290
+ case "valid":
8291
+ return "text-green-700 dark:text-green-400";
8292
+ case "shortfall":
8293
+ case "forcedRed":
8294
+ return "text-red-700 dark:text-red-400 font-semibold";
8295
+ default:
8296
+ return "text-foreground";
8297
+ }
8298
+ };
8299
+ const showAddButton = isEmpty && effectiveStatus === "pending" && !isEditing && data.entered === null;
8300
+ if (showAddButton) {
8301
+ return /* @__PURE__ */ jsxRuntime.jsx(
8302
+ "div",
8303
+ {
8304
+ "data-slot": "calibration-week-cell",
8305
+ "data-status": "empty",
8306
+ className: cn(
8307
+ "flex items-center justify-center h-[100px]",
8308
+ "transition-all duration-200 ease-out",
8309
+ "hover:-translate-y-0.5 hover:shadow-[var(--j3m-shadow-md)]",
8310
+ "bg-background",
8311
+ isHovered ? "border-l-2 border-l-border" : "border-l-2 border-l-transparent",
8312
+ className
8313
+ ),
8314
+ onMouseEnter: () => setIsHovered(true),
8315
+ onMouseLeave: () => setIsHovered(false),
8316
+ ...props,
8317
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
8318
+ Button,
8319
+ {
8320
+ variant: "ghost",
8321
+ size: "icon",
8322
+ className: cn(
8323
+ "h-10 w-10 rounded-full",
8324
+ "text-muted-foreground/40 hover:text-muted-foreground hover:bg-muted/50",
8325
+ "transition-all duration-200",
8326
+ "shadow-[var(--j3m-shadow-sm)]"
8327
+ ),
8328
+ onClick: handleAddClick,
8329
+ children: [
8330
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-5 w-5" }),
8331
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Add production amount" })
8332
+ ]
8333
+ }
8334
+ )
8335
+ }
8336
+ );
8337
+ }
8338
+ if (isEmpty && forcedRed) {
8339
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8340
+ "div",
8341
+ {
8342
+ "data-slot": "calibration-week-cell",
8343
+ "data-status": "forcedRed",
8344
+ className: cn(
8345
+ "flex flex-col items-center justify-center gap-2 h-[100px] px-3 py-2",
8346
+ "transition-all duration-200 ease-out",
8347
+ "hover:-translate-y-0.5 hover:shadow-[var(--j3m-shadow-md)]",
8348
+ "border-l-2 border-l-red-500 bg-red-50/50 dark:bg-red-950/30",
8349
+ className
8350
+ ),
8351
+ onMouseEnter: () => setIsHovered(true),
8352
+ onMouseLeave: () => setIsHovered(false),
8353
+ ...props,
8354
+ children: [
8355
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium text-red-600 dark:text-red-400 text-center", children: "Behind schedule" }),
8356
+ /* @__PURE__ */ jsxRuntime.jsx(NetBadge, { net: data.net, status: "shortfall" })
8357
+ ]
8358
+ }
8359
+ );
8360
+ }
8361
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8362
+ "div",
8363
+ {
8364
+ "data-slot": "calibration-week-cell",
8365
+ "data-status": effectiveStatus,
8366
+ className: cn(
8367
+ "flex flex-col gap-2 px-3 py-2 h-[100px]",
8368
+ // Hover lift effect with shadow (like planning table)
8369
+ "transition-all duration-200 ease-out",
8370
+ "hover:-translate-y-0.5 hover:shadow-[var(--j3m-shadow-md)]",
8371
+ getContainerStyles(),
8372
+ className
8373
+ ),
8374
+ onMouseEnter: () => setIsHovered(true),
8375
+ onMouseLeave: () => setIsHovered(false),
8376
+ ...props,
8377
+ children: [
8378
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
8379
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium text-muted-foreground tracking-wide", children: "Accumulated" }),
8380
+ /* @__PURE__ */ jsxRuntime.jsx(NetBadge, { net: data.net, status: forcedRed ? "shortfall" : data.status })
8381
+ ] }),
8382
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
8383
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium text-muted-foreground tracking-wide", children: "Planned" }),
8384
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "inline-flex items-center justify-center px-2 py-0 bg-card border border-border rounded-full", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-medium text-muted-foreground", children: data.planned }) })
8385
+ ] }),
8386
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
8387
+ /* @__PURE__ */ jsxRuntime.jsx(
8388
+ Input,
8389
+ {
8390
+ ref: inputRef,
8391
+ type: "text",
8392
+ inputMode: "decimal",
8393
+ value: localValue,
8394
+ onChange: handleInputChange,
8395
+ onBlur: handleBlur,
8396
+ onFocus: () => setIsEditing(true),
8397
+ disabled: !data.isEditable,
8398
+ placeholder: "Enter amount",
8399
+ className: cn(
8400
+ "h-8 pl-3 pr-12 rounded-full text-sm font-semibold bg-background border-border",
8401
+ // Placeholder: smaller, lighter, lower contrast
8402
+ "placeholder:text-xs placeholder:font-normal placeholder:text-muted-foreground/50",
8403
+ getInputStyles(),
8404
+ !data.isEditable && "opacity-50 cursor-not-allowed"
8405
+ )
8406
+ }
8407
+ ),
8408
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute right-4 top-1/2 -translate-y-1/2 text-[10px] text-muted-foreground/70 pointer-events-none", children: unitLabel })
8409
+ ] })
8410
+ ]
8411
+ }
8412
+ );
8413
+ }
8414
+ function CommentPopover({
8415
+ comments,
8416
+ weekLabel,
8417
+ availablePrefixes,
8418
+ onAddComment,
8419
+ open,
8420
+ onOpenChange
8421
+ }) {
8422
+ const [newCommentText, setNewCommentText] = React22__namespace.useState("");
8423
+ const [selectedPrefixId, setSelectedPrefixId] = React22__namespace.useState("");
8424
+ const [viewCommentsOpen, setViewCommentsOpen] = React22__namespace.useState(true);
8425
+ const [showAddForm, setShowAddForm] = React22__namespace.useState(false);
8426
+ const selectedPrefixName = React22__namespace.useMemo(() => {
8427
+ const prefix = availablePrefixes.find((p) => p.id === selectedPrefixId);
8428
+ return prefix?.name ?? "";
8429
+ }, [availablePrefixes, selectedPrefixId]);
8430
+ const handleSubmit = () => {
8431
+ if (newCommentText.trim() && selectedPrefixId) {
8432
+ onAddComment?.(newCommentText.trim(), selectedPrefixId, selectedPrefixName);
8433
+ setNewCommentText("");
8434
+ setSelectedPrefixId("");
8435
+ setShowAddForm(false);
8436
+ setViewCommentsOpen(true);
8437
+ }
8438
+ };
8439
+ const handleKeyDown = (e) => {
8440
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
8441
+ e.preventDefault();
8442
+ handleSubmit();
8443
+ }
8444
+ if (e.key === "Escape") {
8445
+ setShowAddForm(false);
8446
+ setSelectedPrefixId("");
8447
+ setNewCommentText("");
8448
+ }
8449
+ };
8450
+ const formatDate2 = (date) => {
8451
+ return new Intl.DateTimeFormat("en-US", {
8452
+ month: "short",
8453
+ day: "numeric",
8454
+ hour: "numeric",
8455
+ minute: "2-digit"
8456
+ }).format(date);
8457
+ };
8458
+ const prevOpenRef = React22__namespace.useRef(open);
8459
+ React22__namespace.useEffect(() => {
8460
+ const wasOpen = prevOpenRef.current;
8461
+ prevOpenRef.current = open;
8462
+ if (wasOpen && !open) {
8463
+ setShowAddForm(false);
8464
+ setNewCommentText("");
8465
+ setSelectedPrefixId("");
8466
+ }
8467
+ }, [open]);
8468
+ return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange, children: [
8469
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(CommentButton, { commentCount: comments.length }) }),
8470
+ /* @__PURE__ */ jsxRuntime.jsxs(
8471
+ PopoverContent,
8472
+ {
8473
+ className: "w-80 p-0 z-[100]",
8474
+ align: "end",
8475
+ sideOffset: 8,
8476
+ collisionPadding: 16,
8477
+ children: [
8478
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-4 py-3 border-b border-border", children: [
8479
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-sm font-semibold", children: "Comments" }),
8480
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: weekLabel })
8481
+ ] }),
8482
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-2 space-y-2 max-h-[400px] overflow-y-auto", children: [
8483
+ /* @__PURE__ */ jsxRuntime.jsxs(Collapsible, { open: viewCommentsOpen, onOpenChange: setViewCommentsOpen, children: [
8484
+ /* @__PURE__ */ jsxRuntime.jsx(CollapsibleTrigger2, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
8485
+ Button,
8486
+ {
8487
+ variant: "ghost",
8488
+ size: "sm",
8489
+ className: "w-full justify-between h-8 px-2",
8490
+ children: [
8491
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs font-medium", children: [
8492
+ "Comments ",
8493
+ comments.length > 0 && `(${comments.length})`
8494
+ ] }),
8495
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: cn(
8496
+ "h-4 w-4 transition-transform duration-200",
8497
+ viewCommentsOpen && "rotate-180"
8498
+ ) })
8499
+ ]
8500
+ }
8501
+ ) }),
8502
+ /* @__PURE__ */ jsxRuntime.jsx(CollapsibleContent2, { className: "space-y-2 pt-2", children: comments.length > 0 ? comments.map((comment) => /* @__PURE__ */ jsxRuntime.jsxs(
8503
+ "div",
8504
+ {
8505
+ className: "rounded-lg bg-muted/50 p-3 space-y-2",
8506
+ "aria-label": `Comment by ${comment.author} about ${comment.prefixName}`,
8507
+ children: [
8508
+ /* @__PURE__ */ jsxRuntime.jsx(
8509
+ Badge,
8510
+ {
8511
+ variant: "outline",
8512
+ className: "text-[10px] px-2 py-0 h-5 font-medium bg-background",
8513
+ children: comment.prefixName
8514
+ }
8515
+ ),
8516
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
8517
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium", children: comment.author }),
8518
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: formatDate2(comment.createdAt) })
8519
+ ] }),
8520
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-foreground", children: comment.text })
8521
+ ]
8522
+ },
8523
+ comment.id
8524
+ )) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground text-center py-2", children: "No comments yet" }) })
8525
+ ] }),
8526
+ /* @__PURE__ */ jsxRuntime.jsx(Separator, { className: "my-2" }),
8527
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden", children: !showAddForm ? (
8528
+ /* Add comment Button */
8529
+ /* @__PURE__ */ jsxRuntime.jsxs(
8530
+ Button,
8531
+ {
8532
+ variant: "outline",
8533
+ size: "sm",
8534
+ className: "w-full justify-center gap-2 h-8",
8535
+ onClick: () => setShowAddForm(true),
8536
+ children: [
8537
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3.5 w-3.5" }),
8538
+ "Add comment"
8539
+ ]
8540
+ }
8541
+ )
8542
+ ) : (
8543
+ /* Comment input form with smooth expand animation */
8544
+ /* @__PURE__ */ jsxRuntime.jsxs(
8545
+ "div",
8546
+ {
8547
+ className: cn(
8548
+ "space-y-3 p-3 rounded-lg border border-border bg-muted/30",
8549
+ "animate-in fade-in-0 slide-in-from-top-2 duration-200"
8550
+ ),
8551
+ children: [
8552
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
8553
+ /* @__PURE__ */ jsxRuntime.jsxs(Label2, { htmlFor: "prefix-select", className: "text-xs font-medium", children: [
8554
+ "Applies to ",
8555
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-destructive", children: "*" })
8556
+ ] }),
8557
+ /* @__PURE__ */ jsxRuntime.jsxs(Select, { value: selectedPrefixId, onValueChange: setSelectedPrefixId, children: [
8558
+ /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { id: "prefix-select", size: "sm", className: "w-full", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: "Select row/type..." }) }),
8559
+ /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: availablePrefixes.map((prefix) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: prefix.id, children: prefix.name }, prefix.id)) })
8560
+ ] })
8561
+ ] }),
8562
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
8563
+ /* @__PURE__ */ jsxRuntime.jsx(Label2, { htmlFor: "comment-text", className: "text-xs font-medium", children: "Comment" }),
8564
+ /* @__PURE__ */ jsxRuntime.jsx(
8565
+ Textarea,
8566
+ {
8567
+ id: "comment-text",
8568
+ placeholder: "Type your comment...",
8569
+ value: newCommentText,
8570
+ onChange: (e) => setNewCommentText(e.target.value),
8571
+ onKeyDown: handleKeyDown,
8572
+ className: "min-h-[80px] text-sm resize-none",
8573
+ autoFocus: true
8574
+ }
8575
+ )
8576
+ ] }),
8577
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
8578
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: "\u2318+Enter to send \xB7 Esc to cancel" }),
8579
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
8580
+ /* @__PURE__ */ jsxRuntime.jsx(
8581
+ Button,
8582
+ {
8583
+ variant: "ghost",
8584
+ size: "sm",
8585
+ className: "h-7",
8586
+ onClick: () => {
8587
+ setShowAddForm(false);
8588
+ setNewCommentText("");
8589
+ setSelectedPrefixId("");
8590
+ },
8591
+ children: "Cancel"
8592
+ }
8593
+ ),
8594
+ /* @__PURE__ */ jsxRuntime.jsxs(
8595
+ Button,
8596
+ {
8597
+ size: "sm",
8598
+ className: "h-7 gap-1",
8599
+ onClick: handleSubmit,
8600
+ disabled: !newCommentText.trim() || !selectedPrefixId,
8601
+ children: [
8602
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Send, { className: "h-3 w-3" }),
8603
+ "Save"
8604
+ ]
8605
+ }
8606
+ )
8607
+ ] })
8608
+ ] })
8609
+ ]
8610
+ }
8611
+ )
8612
+ ) })
8613
+ ] })
8614
+ ]
8615
+ }
8616
+ )
8617
+ ] });
8618
+ }
8619
+ function CalibrationWeekHeader({
8620
+ className,
8621
+ week,
8622
+ comments = [],
8623
+ showCommentButton = true,
8624
+ availablePrefixes = [],
8625
+ onAddComment,
8626
+ ...props
8627
+ }) {
8628
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8629
+ "div",
8630
+ {
8631
+ "data-slot": "calibration-week-header",
8632
+ "data-current-week": week.isCurrentWeek,
8633
+ className: cn(
8634
+ "flex items-center justify-between gap-2 px-2 py-2 min-w-[200px]",
8635
+ className
8636
+ ),
8637
+ ...props,
8638
+ children: [
8639
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [
8640
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
8641
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
8642
+ "text-sm font-semibold tracking-tight",
8643
+ week.isCurrentWeek ? "text-primary" : "text-foreground"
8644
+ ), children: week.label }),
8645
+ week.isCurrentWeek && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "relative flex h-2 w-2", children: [
8646
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "animate-ping absolute inline-flex h-full w-full rounded-full bg-primary opacity-75" }),
8647
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "relative inline-flex rounded-full h-2 w-2 bg-primary" })
8648
+ ] })
8649
+ ] }),
8650
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-normal text-muted-foreground/60", children: week.dateRange })
8651
+ ] }),
8652
+ showCommentButton && availablePrefixes.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
8653
+ CommentPopover,
8654
+ {
8655
+ comments,
8656
+ weekLabel: week.label,
8657
+ availablePrefixes,
8658
+ onAddComment
8659
+ }
8660
+ )
8661
+ ]
8662
+ }
8663
+ );
8664
+ }
8665
+ function CalibrationTable({
8666
+ className,
8667
+ prefixes,
8668
+ supplierName,
8669
+ status = "draft",
8670
+ config = {}
8671
+ }) {
8672
+ const {
8673
+ weekCount = 8,
8674
+ startDate,
8675
+ allowTimelineExtension = true,
8676
+ maxEarlierWeeks = 4,
8677
+ showToolbar = true,
8678
+ showPagination = true,
8679
+ pageSizeOptions = [10, 20, 30],
8680
+ defaultPageSize = 10,
8681
+ stickyRowHeader = true,
8682
+ maxHeight = "500px",
8683
+ onCellChange,
8684
+ onSubmit,
8685
+ onAddComment,
8686
+ onAddEarlierWeek
8687
+ } = config;
8688
+ const calculatedStartDate = React22__namespace.useMemo(() => {
8689
+ if (startDate) return startDate;
8690
+ let earliest = null;
8691
+ for (const prefix of prefixes) {
8692
+ for (const weekKey in prefix.weeks) {
8693
+ const cell = prefix.weeks[weekKey];
8694
+ if (cell.planned > 0) {
8695
+ const match = weekKey.match(/(\d{4})-W(\d{2})/);
8696
+ if (match) {
8697
+ const year = parseInt(match[1]);
8698
+ const week = parseInt(match[2]);
8699
+ const date = new Date(year, 0, 1 + (week - 1) * 7);
8700
+ if (earliest === null || date < earliest) {
8701
+ earliest = date;
8702
+ }
8703
+ }
8704
+ }
8705
+ }
8706
+ }
8707
+ return earliest ?? /* @__PURE__ */ new Date();
8708
+ }, [startDate, prefixes]);
8709
+ const [additionalWeeks, setAdditionalWeeks] = React22__namespace.useState(0);
8710
+ const weeks = React22__namespace.useMemo(() => {
8711
+ const start = new Date(calculatedStartDate);
8712
+ start.setDate(start.getDate() - additionalWeeks * 7);
8713
+ return generateWeeks(start, weekCount + additionalWeeks);
8714
+ }, [calculatedStartDate, weekCount, additionalWeeks]);
8715
+ React22__namespace.useMemo(() => {
8716
+ const currentWeek = weeks.find((w) => w.isCurrentWeek);
8717
+ return currentWeek ? getWeekKey(currentWeek.startDate) : null;
8718
+ }, [weeks]);
8719
+ const [currentPage, setCurrentPage] = React22__namespace.useState(0);
8720
+ const [pageSize, setPageSize] = React22__namespace.useState(defaultPageSize);
8721
+ const [searchQuery, setSearchQuery] = React22__namespace.useState("");
8722
+ const filteredPrefixes = React22__namespace.useMemo(() => {
8723
+ if (!searchQuery) return prefixes;
8724
+ const query = searchQuery.toLowerCase();
8725
+ return prefixes.filter(
8726
+ (p) => p.name.toLowerCase().includes(query) || p.typeCode.toLowerCase().includes(query)
8727
+ );
8728
+ }, [prefixes, searchQuery]);
8729
+ const paginatedPrefixes = React22__namespace.useMemo(() => {
8730
+ const start = currentPage * pageSize;
8731
+ return filteredPrefixes.slice(start, start + pageSize);
8732
+ }, [filteredPrefixes, currentPage, pageSize]);
8733
+ React22__namespace.useMemo(
8734
+ () => canSubmitCalibration(prefixes),
8735
+ [prefixes]
8736
+ );
8737
+ const handleAddEarlierWeek = () => {
8738
+ if (additionalWeeks < maxEarlierWeeks) {
8739
+ setAdditionalWeeks((prev) => prev + 1);
8740
+ onAddEarlierWeek?.();
8741
+ }
8742
+ };
8743
+ const handleCellChange = (prefixId, weekKey, value) => {
8744
+ onCellChange?.(prefixId, weekKey, value);
8745
+ };
8746
+ const handleAddWeekComment = (weekKey, text, prefixId, prefixName) => {
8747
+ onAddComment?.(prefixId, weekKey, text);
8748
+ };
8749
+ const getWeekComments = (weekKey) => {
8750
+ const allComments = [];
8751
+ for (const prefix of prefixes) {
8752
+ const weekComments = prefix.comments?.filter((c) => c.weekKey === weekKey) ?? [];
8753
+ allComments.push(...weekComments);
8754
+ }
8755
+ return allComments;
8756
+ };
8757
+ const availablePrefixes = React22__namespace.useMemo(
8758
+ () => prefixes.map((p) => ({ id: p.id, name: p.name })),
8759
+ [prefixes]
8760
+ );
8761
+ return /* @__PURE__ */ jsxRuntime.jsxs(
8762
+ "div",
8763
+ {
8764
+ "data-slot": "calibration-table",
8765
+ className: cn("flex flex-col gap-4", className),
8766
+ children: [
8767
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-start justify-between gap-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
8768
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-semibold tracking-tight", children: "Weekly Production Calibration" }),
8769
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: "Review required weekly production and confirm achievable output at the selected checkpoint." })
8770
+ ] }) }),
8771
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
8772
+ showToolbar && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
8773
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
8774
+ Input,
8775
+ {
8776
+ placeholder: "Search prefixes...",
8777
+ value: searchQuery,
8778
+ onChange: (e) => setSearchQuery(e.target.value),
8779
+ className: "h-8 w-[200px] lg:w-[300px]"
8780
+ }
8781
+ ) }),
8782
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: allowTimelineExtension && additionalWeeks < maxEarlierWeeks && /* @__PURE__ */ jsxRuntime.jsxs(
8783
+ Button,
8784
+ {
8785
+ variant: "outline",
8786
+ size: "sm",
8787
+ className: "gap-2",
8788
+ onClick: handleAddEarlierWeek,
8789
+ children: [
8790
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-4 w-4" }),
8791
+ "Add earlier week"
8792
+ ]
8793
+ }
8794
+ ) })
8795
+ ] }),
8796
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-xl border bg-background shadow-sm overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsxs(
8797
+ ScrollArea,
8798
+ {
8799
+ className: "w-full",
8800
+ style: { maxHeight },
8801
+ children: [
8802
+ /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full border-collapse", children: [
8803
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "sticky top-0 z-20", children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
8804
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: cn(
8805
+ "h-14 px-3 text-left align-middle font-semibold text-xs text-muted-foreground uppercase tracking-wide",
8806
+ "border-r border-b border-border bg-sidebar",
8807
+ stickyRowHeader && "sticky left-0 z-30 min-w-[200px]",
8808
+ // Right shadow using Quantum token
8809
+ stickyRowHeader && "shadow-[var(--j3m-shadow-sticky-edge)]"
8810
+ ), children: "Supplier / Scope" }),
8811
+ weeks.map((week) => {
8812
+ const weekKey = getWeekKey(week.startDate);
8813
+ const weekComments = getWeekComments(weekKey);
8814
+ return /* @__PURE__ */ jsxRuntime.jsx(
8815
+ "th",
8816
+ {
8817
+ className: "h-14 px-2 text-left align-middle border-r border-b border-border last:border-r-0 min-w-[220px] bg-sidebar",
8818
+ children: /* @__PURE__ */ jsxRuntime.jsx(
8819
+ CalibrationWeekHeader,
8820
+ {
8821
+ week,
8822
+ comments: weekComments,
8823
+ showCommentButton: true,
8824
+ availablePrefixes,
8825
+ onAddComment: (text, prefixId, prefixName) => handleAddWeekComment(weekKey, text, prefixId)
8826
+ }
8827
+ )
8828
+ },
8829
+ weekKey
8830
+ );
8831
+ })
8832
+ ] }) }),
8833
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "bg-background", children: paginatedPrefixes.length > 0 ? paginatedPrefixes.map((prefix) => {
8834
+ const sortedWeekKeys = weeks.map((w) => getWeekKey(w.startDate));
8835
+ let hasDeficit = false;
8836
+ const forcedRedMap = {};
8837
+ for (const weekKey of sortedWeekKeys) {
8838
+ const cellData = prefix.weeks[weekKey];
8839
+ if (hasDeficit) {
8840
+ forcedRedMap[weekKey] = true;
8841
+ } else if (cellData && cellData.status === "shortfall") {
8842
+ hasDeficit = true;
8843
+ forcedRedMap[weekKey] = false;
8844
+ } else {
8845
+ forcedRedMap[weekKey] = false;
8846
+ }
8847
+ }
8848
+ return /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "border-b border-border last:border-b-0", children: [
8849
+ /* @__PURE__ */ jsxRuntime.jsx(
8850
+ "td",
8851
+ {
8852
+ className: cn(
8853
+ "p-0 align-top border-r border-border bg-background",
8854
+ stickyRowHeader && "sticky left-0 z-10 min-w-[200px]",
8855
+ // Right shadow using Quantum token
8856
+ stickyRowHeader && "shadow-[var(--j3m-shadow-sticky-edge)]"
8857
+ ),
8858
+ children: /* @__PURE__ */ jsxRuntime.jsx(RowHeaderCell, { data: prefix, showProgress: true })
8859
+ }
8860
+ ),
8861
+ weeks.map((week) => {
8862
+ const weekKey = getWeekKey(week.startDate);
8863
+ const cellData = prefix.weeks[weekKey];
8864
+ const isForcedRed = forcedRedMap[weekKey] ?? false;
8865
+ const isEmpty = !cellData || cellData.planned === 0;
8866
+ const effectiveCellData = cellData ?? {
8867
+ planned: 0,
8868
+ entered: null,
8869
+ accumulatedPlanned: 0,
8870
+ accumulatedEntered: 0,
8871
+ net: 0,
8872
+ status: "pending",
8873
+ isEditable: true
8874
+ };
8875
+ return /* @__PURE__ */ jsxRuntime.jsx(
8876
+ "td",
8877
+ {
8878
+ className: "p-0 align-top border-r border-border last:border-r-0 min-w-[220px] bg-background",
8879
+ children: /* @__PURE__ */ jsxRuntime.jsx(
8880
+ CalibrationWeekCell,
8881
+ {
8882
+ data: effectiveCellData,
8883
+ unit: prefix.unit,
8884
+ onValueChange: (value) => handleCellChange(prefix.id, weekKey, value),
8885
+ forcedRed: isForcedRed,
8886
+ isEmpty,
8887
+ onAddClick: () => {
8888
+ }
8889
+ }
8890
+ )
8891
+ },
8892
+ weekKey
8893
+ );
8894
+ })
8895
+ ] }, prefix.id);
8896
+ }) : /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx(
8897
+ "td",
8898
+ {
8899
+ colSpan: weeks.length + 1,
8900
+ className: "h-24 text-center text-muted-foreground bg-background",
8901
+ children: "No prefixes found."
8902
+ }
8903
+ ) }) })
8904
+ ] }),
8905
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollBar, { orientation: "horizontal" }),
8906
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollBar, { orientation: "vertical" })
8907
+ ]
8908
+ }
8909
+ ) })
8910
+ ] }),
8911
+ showPagination && filteredPrefixes.length > pageSize && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between px-2", children: [
8912
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
8913
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Rows per page" }),
8914
+ /* @__PURE__ */ jsxRuntime.jsx(
8915
+ "select",
8916
+ {
8917
+ value: pageSize,
8918
+ onChange: (e) => {
8919
+ setPageSize(Number(e.target.value));
8920
+ setCurrentPage(0);
8921
+ },
8922
+ className: "h-8 w-16 rounded-md border bg-background px-2 text-sm",
8923
+ children: pageSizeOptions.map((size) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: size, children: size }, size))
8924
+ }
8925
+ )
8926
+ ] }),
8927
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
8928
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
8929
+ "Page ",
8930
+ currentPage + 1,
8931
+ " of ",
8932
+ Math.ceil(filteredPrefixes.length / pageSize)
8933
+ ] }),
8934
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
8935
+ /* @__PURE__ */ jsxRuntime.jsx(
8936
+ Button,
8937
+ {
8938
+ variant: "outline",
8939
+ size: "icon",
8940
+ className: "h-8 w-8",
8941
+ disabled: currentPage === 0,
8942
+ onClick: () => setCurrentPage(0),
8943
+ children: "\xAB\xAB"
8944
+ }
8945
+ ),
8946
+ /* @__PURE__ */ jsxRuntime.jsx(
8947
+ Button,
8948
+ {
8949
+ variant: "outline",
8950
+ size: "icon",
8951
+ className: "h-8 w-8",
8952
+ disabled: currentPage === 0,
8953
+ onClick: () => setCurrentPage((prev) => prev - 1),
8954
+ children: "\xAB"
8955
+ }
8956
+ ),
8957
+ /* @__PURE__ */ jsxRuntime.jsx(
8958
+ Button,
8959
+ {
8960
+ variant: "outline",
8961
+ size: "icon",
8962
+ className: "h-8 w-8",
8963
+ disabled: currentPage >= Math.ceil(filteredPrefixes.length / pageSize) - 1,
8964
+ onClick: () => setCurrentPage((prev) => prev + 1),
8965
+ children: "\xBB"
8966
+ }
8967
+ ),
8968
+ /* @__PURE__ */ jsxRuntime.jsx(
8969
+ Button,
8970
+ {
8971
+ variant: "outline",
8972
+ size: "icon",
8973
+ className: "h-8 w-8",
8974
+ disabled: currentPage >= Math.ceil(filteredPrefixes.length / pageSize) - 1,
8975
+ onClick: () => setCurrentPage(Math.ceil(filteredPrefixes.length / pageSize) - 1),
8976
+ children: "\xBB\xBB"
8977
+ }
8978
+ )
8979
+ ] })
8980
+ ] })
8981
+ ] })
8982
+ ]
8983
+ }
8984
+ );
8985
+ }
8986
+ function CommentDialog({
8987
+ prefixes,
8988
+ weeks,
8989
+ onAddComment,
8990
+ triggerVariant = "outline",
8991
+ open,
8992
+ onOpenChange
8993
+ }) {
8994
+ const [selectedPrefixId, setSelectedPrefixId] = React22__namespace.useState("");
8995
+ const [selectedWeekKey, setSelectedWeekKey] = React22__namespace.useState("");
8996
+ const [commentText, setCommentText] = React22__namespace.useState("");
8997
+ const currentWeek = React22__namespace.useMemo(
8998
+ () => weeks.find((w) => w.isCurrentWeek),
8999
+ [weeks]
9000
+ );
9001
+ React22__namespace.useEffect(() => {
9002
+ if (open) {
9003
+ setSelectedPrefixId(prefixes[0]?.id ?? "");
9004
+ setSelectedWeekKey(currentWeek ? getWeekKey(currentWeek.startDate) : weeks[0] ? getWeekKey(weeks[0].startDate) : "");
9005
+ setCommentText("");
5712
9006
  }
5713
- )
5714
- );
5715
- SectionFooter.displayName = "SectionFooter";
5716
- function SearchForm({ ...props }) {
5717
- return /* @__PURE__ */ jsxRuntime.jsx("form", { ...props, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
5718
- /* @__PURE__ */ jsxRuntime.jsx(Label2, { htmlFor: "search", className: "sr-only", children: "Search" }),
5719
- /* @__PURE__ */ jsxRuntime.jsx(
5720
- SidebarInput,
5721
- {
5722
- id: "search",
5723
- placeholder: "Type to search...",
5724
- className: "h-8 pl-7"
5725
- }
5726
- ),
5727
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SearchIcon, { className: "pointer-events-none absolute top-1/2 left-2 size-4 -translate-y-1/2 opacity-50 select-none" })
5728
- ] }) });
9007
+ }, [open, prefixes, weeks, currentWeek]);
9008
+ const handleSave = () => {
9009
+ if (selectedPrefixId && selectedWeekKey && commentText.trim()) {
9010
+ onAddComment?.(selectedPrefixId, selectedWeekKey, commentText.trim());
9011
+ onOpenChange?.(false);
9012
+ }
9013
+ };
9014
+ const isValid = selectedPrefixId && selectedWeekKey && commentText.trim();
9015
+ return /* @__PURE__ */ jsxRuntime.jsxs(Dialog, { open, onOpenChange, children: [
9016
+ /* @__PURE__ */ jsxRuntime.jsx(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(Button, { variant: triggerVariant, size: "sm", className: "gap-2", children: [
9017
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MessageSquarePlus, { className: "h-4 w-4" }),
9018
+ "Add comment"
9019
+ ] }) }),
9020
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "sm:max-w-[425px]", children: [
9021
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { children: [
9022
+ /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: "Add Comment" }),
9023
+ /* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: "Add a comment to a specific prefix and week. Comments help communicate production updates and issues." })
9024
+ ] }),
9025
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-4 py-4", children: [
9026
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-2", children: [
9027
+ /* @__PURE__ */ jsxRuntime.jsx(Label2, { htmlFor: "prefix-select", children: "Prefix / Element Type" }),
9028
+ /* @__PURE__ */ jsxRuntime.jsxs(Select, { value: selectedPrefixId, onValueChange: setSelectedPrefixId, children: [
9029
+ /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { id: "prefix-select", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: "Select prefix..." }) }),
9030
+ /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: prefixes.map((prefix) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: prefix.id, children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-2", children: [
9031
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: prefix.name }),
9032
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground text-xs", children: [
9033
+ "(",
9034
+ prefix.typeCode,
9035
+ ")"
9036
+ ] })
9037
+ ] }) }, prefix.id)) })
9038
+ ] })
9039
+ ] }),
9040
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-2", children: [
9041
+ /* @__PURE__ */ jsxRuntime.jsx(Label2, { htmlFor: "week-select", children: "Week" }),
9042
+ /* @__PURE__ */ jsxRuntime.jsxs(Select, { value: selectedWeekKey, onValueChange: setSelectedWeekKey, children: [
9043
+ /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { id: "week-select", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: "Select week..." }) }),
9044
+ /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: weeks.map((week) => {
9045
+ const weekKey = getWeekKey(week.startDate);
9046
+ return /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: weekKey, children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-2", children: [
9047
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
9048
+ "font-medium",
9049
+ week.isCurrentWeek && "text-primary"
9050
+ ), children: week.label }),
9051
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-xs", children: week.dateRange }),
9052
+ week.isCurrentWeek && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-primary font-medium", children: "(Current)" })
9053
+ ] }) }, weekKey);
9054
+ }) })
9055
+ ] })
9056
+ ] }),
9057
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-2", children: [
9058
+ /* @__PURE__ */ jsxRuntime.jsx(Label2, { htmlFor: "comment-text", children: "Comment" }),
9059
+ /* @__PURE__ */ jsxRuntime.jsx(
9060
+ Textarea,
9061
+ {
9062
+ id: "comment-text",
9063
+ placeholder: "Enter your comment...",
9064
+ value: commentText,
9065
+ onChange: (e) => setCommentText(e.target.value),
9066
+ className: "min-h-[100px] resize-none"
9067
+ }
9068
+ )
9069
+ ] })
9070
+ ] }),
9071
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogFooter, { children: [
9072
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", onClick: () => onOpenChange?.(false), children: "Cancel" }),
9073
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: handleSave, disabled: !isValid, children: "Save comment" })
9074
+ ] })
9075
+ ] })
9076
+ ] });
5729
9077
  }
5730
- function SiteHeader({
5731
- trigger,
5732
- breadcrumbs = [
5733
- { label: "Building Your Application", href: "#" },
5734
- { label: "Data Fetching" }
5735
- ],
5736
- showSearch = true,
9078
+ function getStatusBadge(status) {
9079
+ switch (status) {
9080
+ case "draft":
9081
+ return { variant: "secondary", label: "DRAFT", color: "bg-blue-500" };
9082
+ case "submitted":
9083
+ return { variant: "secondary", label: "SUBMITTED", color: "bg-amber-500" };
9084
+ case "approved":
9085
+ return { variant: "secondary", label: "APPROVED", color: "bg-green-500" };
9086
+ case "rejected":
9087
+ return { variant: "destructive", label: "REJECTED", color: "bg-red-500" };
9088
+ }
9089
+ }
9090
+ function formatDate(date) {
9091
+ return date.toLocaleDateString("en-US", {
9092
+ month: "short",
9093
+ day: "2-digit",
9094
+ year: "numeric"
9095
+ });
9096
+ }
9097
+ function SubmitCalibrationBar({
5737
9098
  className,
5738
- children
9099
+ status,
9100
+ lastSaved,
9101
+ canSubmit,
9102
+ shortfallCount,
9103
+ pendingCount,
9104
+ message,
9105
+ onSubmit,
9106
+ onSaveDraft,
9107
+ ...props
5739
9108
  }) {
5740
- return /* @__PURE__ */ jsxRuntime.jsx(
5741
- "header",
9109
+ const statusBadge = getStatusBadge(status);
9110
+ return /* @__PURE__ */ jsxRuntime.jsxs(
9111
+ "div",
5742
9112
  {
5743
- "data-slot": "site-header",
9113
+ "data-slot": "submit-calibration-bar",
5744
9114
  className: cn(
5745
- "bg-sidebar text-sidebar-foreground sticky top-0 z-50 flex w-full items-center border-b border-sidebar-border",
9115
+ "flex items-center justify-between gap-4 px-4 py-4",
9116
+ "bg-background",
5746
9117
  className
5747
9118
  ),
5748
- 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: [
5749
- trigger,
5750
- trigger && /* @__PURE__ */ jsxRuntime.jsx(Separator, { orientation: "vertical", className: "mr-[var(--j3m-spacing-s)] h-4" }),
5751
- /* @__PURE__ */ jsxRuntime.jsx(Breadcrumb, { className: "hidden sm:block", children: /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbList, { children: breadcrumbs.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs(React15__namespace.Fragment, { children: [
5752
- index > 0 && /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbSeparator, {}),
5753
- /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbItem, { children: item.href ? /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbLink, { href: item.href, children: item.label }) : /* @__PURE__ */ jsxRuntime.jsx(BreadcrumbPage, { children: item.label }) })
5754
- ] }, index)) }) }),
5755
- showSearch && /* @__PURE__ */ jsxRuntime.jsx(SearchForm, { className: "w-full sm:ml-auto sm:w-auto" }),
5756
- children
5757
- ] })
5758
- }
5759
- );
5760
- }
5761
- function NavMain({ items, label = "Platform" }) {
5762
- return /* @__PURE__ */ jsxRuntime.jsxs(SidebarGroup, { children: [
5763
- /* @__PURE__ */ jsxRuntime.jsx(SidebarGroupLabel, { children: label }),
5764
- /* @__PURE__ */ jsxRuntime.jsx(SidebarMenu, { children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(Collapsible, { asChild: true, defaultOpen: item.isActive, children: /* @__PURE__ */ jsxRuntime.jsxs(SidebarMenuItem, { children: [
5765
- /* @__PURE__ */ jsxRuntime.jsx(SidebarMenuButton, { asChild: true, tooltip: item.title, children: /* @__PURE__ */ jsxRuntime.jsxs("a", { href: item.url, children: [
5766
- item.icon && /* @__PURE__ */ jsxRuntime.jsx(item.icon, {}),
5767
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: item.title })
5768
- ] }) }),
5769
- item.items?.length ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5770
- /* @__PURE__ */ jsxRuntime.jsx(CollapsibleTrigger2, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(SidebarMenuAction, { className: "data-[state=open]:rotate-90", children: [
5771
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, {}),
5772
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Toggle" })
5773
- ] }) }),
5774
- /* @__PURE__ */ jsxRuntime.jsx(CollapsibleContent2, { children: /* @__PURE__ */ jsxRuntime.jsx(SidebarMenuSub, { children: item.items?.map((subItem) => /* @__PURE__ */ jsxRuntime.jsx(SidebarMenuSubItem, { children: /* @__PURE__ */ jsxRuntime.jsx(SidebarMenuSubButton, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: subItem.url, children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: subItem.title }) }) }) }, subItem.title)) }) })
5775
- ] }) : null
5776
- ] }) }, item.title)) })
5777
- ] });
5778
- }
5779
- function NavProjects({ projects, label = "Projects" }) {
5780
- return /* @__PURE__ */ jsxRuntime.jsxs(SidebarGroup, { className: "group-data-[collapsible=icon]:hidden", children: [
5781
- /* @__PURE__ */ jsxRuntime.jsx(SidebarGroupLabel, { children: label }),
5782
- /* @__PURE__ */ jsxRuntime.jsxs(SidebarMenu, { children: [
5783
- projects.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(SidebarMenuItem, { children: [
5784
- /* @__PURE__ */ jsxRuntime.jsx(SidebarMenuButton, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs("a", { href: item.url, children: [
5785
- /* @__PURE__ */ jsxRuntime.jsx(item.icon, {}),
5786
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: item.name })
5787
- ] }) }),
5788
- /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
5789
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(SidebarMenuAction, { showOnHover: true, children: [
5790
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MoreHorizontalIcon, {}),
5791
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "More" })
5792
- ] }) }),
9119
+ ...props,
9120
+ children: [
9121
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
9122
+ !canSubmit && (shortfallCount > 0 || pendingCount > 0) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm", children: [
9123
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, { className: "h-4 w-4 text-amber-500" }),
9124
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: message })
9125
+ ] }),
9126
+ canSubmit && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm", children: [
9127
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircle, { className: "h-4 w-4 text-green-500" }),
9128
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: message })
9129
+ ] })
9130
+ ] }),
9131
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
5793
9132
  /* @__PURE__ */ jsxRuntime.jsxs(
5794
- DropdownMenuContent,
9133
+ Badge,
5795
9134
  {
5796
- className: "w-48 rounded-[var(--j3m-radius-m)]",
5797
- side: "right",
5798
- align: "start",
5799
- sideOffset: 8,
9135
+ variant: statusBadge.variant,
9136
+ className: "flex items-center gap-2 px-3 py-1 rounded-full",
5800
9137
  children: [
5801
- /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { children: [
5802
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.FolderIcon, { className: "text-muted-foreground" }),
5803
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "View Project" })
5804
- ] }),
5805
- /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { children: [
5806
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ShareIcon, { className: "text-muted-foreground" }),
5807
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Share Project" })
5808
- ] }),
5809
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
5810
- /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { children: [
5811
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.TrashIcon, { className: "text-muted-foreground" }),
5812
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Delete Project" })
5813
- ] })
9138
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("h-2 w-2 rounded-full", statusBadge.color) }),
9139
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium", children: statusBadge.label })
9140
+ ]
9141
+ }
9142
+ ),
9143
+ lastSaved && /* @__PURE__ */ jsxRuntime.jsxs(
9144
+ Button,
9145
+ {
9146
+ variant: "outline",
9147
+ size: "sm",
9148
+ className: "gap-2 rounded-full",
9149
+ disabled: true,
9150
+ children: [
9151
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Calendar, { className: "h-4 w-4" }),
9152
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: formatDate(lastSaved) })
5814
9153
  ]
5815
9154
  }
9155
+ ),
9156
+ /* @__PURE__ */ jsxRuntime.jsx(
9157
+ Button,
9158
+ {
9159
+ size: "sm",
9160
+ className: "rounded-full px-4 min-w-[140px]",
9161
+ disabled: !canSubmit || status === "submitted" || status === "approved",
9162
+ onClick: onSubmit,
9163
+ children: status === "submitted" ? "Submitted" : status === "approved" ? "Approved" : "Submit calibration"
9164
+ }
5816
9165
  )
5817
9166
  ] })
5818
- ] }, item.name)),
5819
- /* @__PURE__ */ jsxRuntime.jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsxRuntime.jsxs(SidebarMenuButton, { className: "text-sidebar-foreground/70", children: [
5820
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MoreHorizontalIcon, { className: "text-sidebar-foreground/70" }),
5821
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "More" })
5822
- ] }) })
5823
- ] })
5824
- ] });
5825
- }
5826
- function NavSecondary({ items, ...props }) {
5827
- return /* @__PURE__ */ jsxRuntime.jsx(SidebarGroup, { ...props, children: /* @__PURE__ */ jsxRuntime.jsx(SidebarGroupContent, { children: /* @__PURE__ */ jsxRuntime.jsx(SidebarMenu, { children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsxRuntime.jsx(SidebarMenuButton, { asChild: true, size: "sm", children: /* @__PURE__ */ jsxRuntime.jsxs("a", { href: item.url, children: [
5828
- /* @__PURE__ */ jsxRuntime.jsx(item.icon, {}),
5829
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: item.title })
5830
- ] }) }) }, item.title)) }) }) });
5831
- }
5832
- function NavUser({ user }) {
5833
- return /* @__PURE__ */ jsxRuntime.jsx(SidebarMenu, { children: /* @__PURE__ */ jsxRuntime.jsx(SidebarMenuItem, { children: /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
5834
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
5835
- SidebarMenuButton,
5836
- {
5837
- size: "lg",
5838
- className: "data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground",
5839
- children: [
5840
- /* @__PURE__ */ jsxRuntime.jsxs(Avatar, { className: "h-8 w-8 rounded-lg", children: [
5841
- /* @__PURE__ */ jsxRuntime.jsx(AvatarImage, { src: user.avatar, alt: user.name }),
5842
- /* @__PURE__ */ jsxRuntime.jsx(AvatarFallback, { className: "rounded-lg", children: user.name.slice(0, 2).toUpperCase() })
5843
- ] }),
5844
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid flex-1 text-left text-sm leading-tight", children: [
5845
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate font-semibold", children: user.name }),
5846
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-xs", children: user.email })
5847
- ] }),
5848
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsUpDownIcon, { className: "ml-auto size-4" })
5849
- ]
5850
- }
5851
- ) }),
5852
- /* @__PURE__ */ jsxRuntime.jsxs(
5853
- DropdownMenuContent,
5854
- {
5855
- className: "w-[--radix-dropdown-menu-trigger-width] min-w-56 rounded-[var(--j3m-radius-m)]",
5856
- side: "right",
5857
- align: "end",
5858
- sideOffset: 8,
5859
- children: [
5860
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuLabel, { className: "p-0 font-normal", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 px-1 py-1.5 text-left text-sm", children: [
5861
- /* @__PURE__ */ jsxRuntime.jsxs(Avatar, { className: "h-8 w-8 rounded-lg", children: [
5862
- /* @__PURE__ */ jsxRuntime.jsx(AvatarImage, { src: user.avatar, alt: user.name }),
5863
- /* @__PURE__ */ jsxRuntime.jsx(AvatarFallback, { className: "rounded-lg", children: user.name.slice(0, 2).toUpperCase() })
5864
- ] }),
5865
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid flex-1 text-left text-sm leading-tight", children: [
5866
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate font-semibold", children: user.name }),
5867
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-xs", children: user.email })
5868
- ] })
5869
- ] }) }),
5870
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
5871
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuGroup, { children: /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { children: [
5872
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SparklesIcon, {}),
5873
- "Upgrade to Pro"
5874
- ] }) }),
5875
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
5876
- /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuGroup, { children: [
5877
- /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { children: [
5878
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BadgeCheckIcon, {}),
5879
- "Account"
5880
- ] }),
5881
- /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { children: [
5882
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CreditCardIcon, {}),
5883
- "Billing"
5884
- ] }),
5885
- /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { children: [
5886
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.BellIcon, {}),
5887
- "Notifications"
5888
- ] })
5889
- ] }),
5890
- /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuSeparator, {}),
5891
- /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuItem, { children: [
5892
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.LogOutIcon, {}),
5893
- "Log out"
5894
- ] })
5895
- ]
5896
- }
5897
- )
5898
- ] }) }) });
9167
+ ]
9168
+ }
9169
+ );
5899
9170
  }
5900
9171
 
5901
9172
  // src/components/event-calendar/types.ts
@@ -5960,7 +9231,7 @@ var BADGE_VARIANT_LABELS = {
5960
9231
  colored: "Colored",
5961
9232
  mixed: "Mixed"
5962
9233
  };
5963
- var CalendarContext = React15__namespace.createContext(null);
9234
+ var CalendarContext = React22__namespace.createContext(null);
5964
9235
  function EventCalendarProvider({
5965
9236
  children,
5966
9237
  events: initialEvents = [],
@@ -5975,38 +9246,38 @@ function EventCalendarProvider({
5975
9246
  onEventUpdate,
5976
9247
  onEventDelete
5977
9248
  }) {
5978
- const [selectedDate, setSelectedDate] = React15__namespace.useState(defaultDate);
5979
- const [selectedUserId, setSelectedUserId] = React15__namespace.useState(defaultUserId);
5980
- const [events, setEventsState] = React15__namespace.useState(initialEvents);
5981
- const [users] = React15__namespace.useState(initialUsers);
5982
- const [badgeVariant, setBadgeVariant] = React15__namespace.useState(defaultBadgeVariant);
5983
- const [view, setView] = React15__namespace.useState(defaultView);
5984
- const [workingHours, setWorkingHours] = React15__namespace.useState(defaultWorkingHours);
5985
- const [visibleHours, setVisibleHours] = React15__namespace.useState(defaultVisibleHours);
5986
- React15__namespace.useEffect(() => {
9249
+ const [selectedDate, setSelectedDate] = React22__namespace.useState(defaultDate);
9250
+ const [selectedUserId, setSelectedUserId] = React22__namespace.useState(defaultUserId);
9251
+ const [events, setEventsState] = React22__namespace.useState(initialEvents);
9252
+ const [users] = React22__namespace.useState(initialUsers);
9253
+ const [badgeVariant, setBadgeVariant] = React22__namespace.useState(defaultBadgeVariant);
9254
+ const [view, setView] = React22__namespace.useState(defaultView);
9255
+ const [workingHours, setWorkingHours] = React22__namespace.useState(defaultWorkingHours);
9256
+ const [visibleHours, setVisibleHours] = React22__namespace.useState(defaultVisibleHours);
9257
+ React22__namespace.useEffect(() => {
5987
9258
  setEventsState(initialEvents);
5988
9259
  }, [initialEvents]);
5989
- const setEvents = React15__namespace.useCallback((newEvents) => {
9260
+ const setEvents = React22__namespace.useCallback((newEvents) => {
5990
9261
  setEventsState(newEvents);
5991
9262
  }, []);
5992
- const addEvent = React15__namespace.useCallback((event) => {
9263
+ const addEvent = React22__namespace.useCallback((event) => {
5993
9264
  setEventsState((prev) => [...prev, event]);
5994
9265
  onEventAdd?.(event);
5995
9266
  }, [onEventAdd]);
5996
- const updateEvent = React15__namespace.useCallback((event) => {
9267
+ const updateEvent = React22__namespace.useCallback((event) => {
5997
9268
  setEventsState(
5998
9269
  (prev) => prev.map((e) => e.id === event.id ? event : e)
5999
9270
  );
6000
9271
  onEventUpdate?.(event);
6001
9272
  }, [onEventUpdate]);
6002
- const deleteEvent = React15__namespace.useCallback((eventId) => {
9273
+ const deleteEvent = React22__namespace.useCallback((eventId) => {
6003
9274
  setEventsState((prev) => prev.filter((e) => e.id !== eventId));
6004
9275
  onEventDelete?.(eventId);
6005
9276
  }, [onEventDelete]);
6006
- const goToToday = React15__namespace.useCallback(() => {
9277
+ const goToToday = React22__namespace.useCallback(() => {
6007
9278
  setSelectedDate(/* @__PURE__ */ new Date());
6008
9279
  }, []);
6009
- const goToPrevious = React15__namespace.useCallback(() => {
9280
+ const goToPrevious = React22__namespace.useCallback(() => {
6010
9281
  setSelectedDate((current) => {
6011
9282
  switch (view) {
6012
9283
  case "day":
@@ -6024,7 +9295,7 @@ function EventCalendarProvider({
6024
9295
  }
6025
9296
  });
6026
9297
  }, [view]);
6027
- const goToNext = React15__namespace.useCallback(() => {
9298
+ const goToNext = React22__namespace.useCallback(() => {
6028
9299
  setSelectedDate((current) => {
6029
9300
  switch (view) {
6030
9301
  case "day":
@@ -6042,7 +9313,7 @@ function EventCalendarProvider({
6042
9313
  }
6043
9314
  });
6044
9315
  }, [view]);
6045
- const contextValue = React15__namespace.useMemo(
9316
+ const contextValue = React22__namespace.useMemo(
6046
9317
  () => ({
6047
9318
  // State
6048
9319
  selectedDate,
@@ -6089,7 +9360,7 @@ function EventCalendarProvider({
6089
9360
  return /* @__PURE__ */ jsxRuntime.jsx(CalendarContext.Provider, { value: contextValue, children });
6090
9361
  }
6091
9362
  function useEventCalendar() {
6092
- const context = React15__namespace.useContext(CalendarContext);
9363
+ const context = React22__namespace.useContext(CalendarContext);
6093
9364
  if (!context) {
6094
9365
  throw new Error("useEventCalendar must be used within an EventCalendarProvider");
6095
9366
  }
@@ -6097,14 +9368,14 @@ function useEventCalendar() {
6097
9368
  }
6098
9369
  function useFilteredEvents() {
6099
9370
  const { events, selectedUserId } = useEventCalendar();
6100
- return React15__namespace.useMemo(() => {
9371
+ return React22__namespace.useMemo(() => {
6101
9372
  if (!selectedUserId) return events;
6102
9373
  return events.filter((event) => event.user.id === selectedUserId);
6103
9374
  }, [events, selectedUserId]);
6104
9375
  }
6105
9376
  function useEventsInRange(startDate, endDate) {
6106
9377
  const filteredEvents = useFilteredEvents();
6107
- return React15__namespace.useMemo(() => {
9378
+ return React22__namespace.useMemo(() => {
6108
9379
  return filteredEvents.filter((event) => {
6109
9380
  const eventStart = new Date(event.startDate);
6110
9381
  const eventEnd = new Date(event.endDate);
@@ -6478,7 +9749,7 @@ function getViewDateRange(date, view) {
6478
9749
  return { start: dateFns.startOfMonth(date), end: dateFns.endOfMonth(date) };
6479
9750
  }
6480
9751
  }
6481
- function formatDateRange(start, end) {
9752
+ function formatDateRange2(start, end) {
6482
9753
  if (dateFns.isSameDay(start, end)) {
6483
9754
  return dateFns.format(start, "MMM d, yyyy");
6484
9755
  }
@@ -6662,8 +9933,8 @@ function MoreEvents({ count, onClick, className }) {
6662
9933
  );
6663
9934
  }
6664
9935
  function TimeIndicator({ className }) {
6665
- const [now, setNow] = React15__namespace.useState(/* @__PURE__ */ new Date());
6666
- React15__namespace.useEffect(() => {
9936
+ const [now, setNow] = React22__namespace.useState(/* @__PURE__ */ new Date());
9937
+ React22__namespace.useEffect(() => {
6667
9938
  const interval = setInterval(() => setNow(/* @__PURE__ */ new Date()), 6e4);
6668
9939
  return () => clearInterval(interval);
6669
9940
  }, []);
@@ -6700,24 +9971,24 @@ function DateBadge({ date, className }) {
6700
9971
  }
6701
9972
  );
6702
9973
  }
6703
- var DragContext = React15__namespace.createContext(null);
9974
+ var DragContext = React22__namespace.createContext(null);
6704
9975
  function DragProvider({
6705
9976
  children,
6706
9977
  snapMinutes = 15,
6707
9978
  onDragStart,
6708
9979
  onDragEnd
6709
9980
  }) {
6710
- const [draggedEvent, setDraggedEventState] = React15__namespace.useState(null);
6711
- const [isDragging, setIsDragging] = React15__namespace.useState(false);
9981
+ const [draggedEvent, setDraggedEventState] = React22__namespace.useState(null);
9982
+ const [isDragging, setIsDragging] = React22__namespace.useState(false);
6712
9983
  const { updateEvent } = useEventCalendar();
6713
- const setDraggedEvent = React15__namespace.useCallback((event) => {
9984
+ const setDraggedEvent = React22__namespace.useCallback((event) => {
6714
9985
  setDraggedEventState(event);
6715
9986
  setIsDragging(!!event);
6716
9987
  if (event) {
6717
9988
  onDragStart?.(event);
6718
9989
  }
6719
9990
  }, [onDragStart]);
6720
- const handleDrop = React15__namespace.useCallback((newStartDate) => {
9991
+ const handleDrop = React22__namespace.useCallback((newStartDate) => {
6721
9992
  if (!draggedEvent) return;
6722
9993
  const snappedDate = snapToInterval(newStartDate, snapMinutes);
6723
9994
  const { startDate, endDate } = calculateDropDates(draggedEvent, snappedDate);
@@ -6730,7 +10001,7 @@ function DragProvider({
6730
10001
  onDragEnd?.(updatedEvent, new Date(startDate), new Date(endDate));
6731
10002
  setDraggedEvent(null);
6732
10003
  }, [draggedEvent, snapMinutes, updateEvent, onDragEnd, setDraggedEvent]);
6733
- const contextValue = React15__namespace.useMemo(
10004
+ const contextValue = React22__namespace.useMemo(
6734
10005
  () => ({
6735
10006
  draggedEvent,
6736
10007
  setDraggedEvent,
@@ -6741,7 +10012,7 @@ function DragProvider({
6741
10012
  return /* @__PURE__ */ jsxRuntime.jsx(DragContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(DragDropHandler, { onDrop: handleDrop, children }) });
6742
10013
  }
6743
10014
  function useDrag() {
6744
- const context = React15__namespace.useContext(DragContext);
10015
+ const context = React22__namespace.useContext(DragContext);
6745
10016
  if (!context) {
6746
10017
  throw new Error("useDrag must be used within a DragProvider");
6747
10018
  }
@@ -6786,7 +10057,7 @@ function DroppableZone({
6786
10057
  }) {
6787
10058
  const { draggedEvent, setDraggedEvent } = useDrag();
6788
10059
  const { updateEvent } = useEventCalendar();
6789
- const [isOver, setIsOver] = React15__namespace.useState(false);
10060
+ const [isOver, setIsOver] = React22__namespace.useState(false);
6790
10061
  const handleDragOver = (e) => {
6791
10062
  e.preventDefault();
6792
10063
  e.dataTransfer.dropEffect = "move";
@@ -6824,23 +10095,23 @@ function DroppableZone({
6824
10095
  function useDroppable({ date, hour, minute = 0, onDrop }) {
6825
10096
  const { draggedEvent, setDraggedEvent } = useDrag();
6826
10097
  const { updateEvent } = useEventCalendar();
6827
- const [isOver, setIsOver] = React15__namespace.useState(false);
6828
- const dropTargetDate = React15__namespace.useMemo(() => {
10098
+ const [isOver, setIsOver] = React22__namespace.useState(false);
10099
+ const dropTargetDate = React22__namespace.useMemo(() => {
6829
10100
  const targetDate = new Date(date);
6830
10101
  if (hour !== void 0) {
6831
10102
  targetDate.setHours(hour, minute, 0, 0);
6832
10103
  }
6833
10104
  return targetDate;
6834
10105
  }, [date, hour, minute]);
6835
- const handleDragOver = React15__namespace.useCallback((e) => {
10106
+ const handleDragOver = React22__namespace.useCallback((e) => {
6836
10107
  e.preventDefault();
6837
10108
  e.dataTransfer.dropEffect = "move";
6838
10109
  if (!isOver) setIsOver(true);
6839
10110
  }, [isOver]);
6840
- const handleDragLeave = React15__namespace.useCallback(() => {
10111
+ const handleDragLeave = React22__namespace.useCallback(() => {
6841
10112
  setIsOver(false);
6842
10113
  }, []);
6843
- const handleDrop = React15__namespace.useCallback((e) => {
10114
+ const handleDrop = React22__namespace.useCallback((e) => {
6844
10115
  e.preventDefault();
6845
10116
  setIsOver(false);
6846
10117
  if (!draggedEvent) return;
@@ -6867,13 +10138,13 @@ function useDroppable({ date, hour, minute = 0, onDrop }) {
6867
10138
  function useDraggable(event, disabled = false) {
6868
10139
  const { setDraggedEvent, draggedEvent } = useDrag();
6869
10140
  const isDragged = draggedEvent?.id === event.id;
6870
- const handleDragStart = React15__namespace.useCallback((e) => {
10141
+ const handleDragStart = React22__namespace.useCallback((e) => {
6871
10142
  if (disabled) return;
6872
10143
  e.dataTransfer.effectAllowed = "move";
6873
10144
  e.dataTransfer.setData("text/plain", event.id);
6874
10145
  setDraggedEvent(event);
6875
10146
  }, [disabled, event, setDraggedEvent]);
6876
- const handleDragEnd = React15__namespace.useCallback(() => {
10147
+ const handleDragEnd = React22__namespace.useCallback(() => {
6877
10148
  setDraggedEvent(null);
6878
10149
  }, [setDraggedEvent]);
6879
10150
  return {
@@ -6914,15 +10185,15 @@ function MonthView({
6914
10185
  }) {
6915
10186
  const { selectedDate, badgeVariant, setSelectedDate, setView } = useEventCalendar();
6916
10187
  const filteredEvents = useFilteredEvents();
6917
- const { singleDayEvents, multiDayEvents } = React15__namespace.useMemo(
10188
+ const { singleDayEvents, multiDayEvents } = React22__namespace.useMemo(
6918
10189
  () => splitEventsByDuration(filteredEvents),
6919
10190
  [filteredEvents]
6920
10191
  );
6921
- const cells = React15__namespace.useMemo(
10192
+ const cells = React22__namespace.useMemo(
6922
10193
  () => getCalendarCells(selectedDate),
6923
10194
  [selectedDate]
6924
10195
  );
6925
- const eventPositions = React15__namespace.useMemo(
10196
+ const eventPositions = React22__namespace.useMemo(
6926
10197
  () => calculateMonthEventPositions(multiDayEvents, singleDayEvents, selectedDate),
6927
10198
  [multiDayEvents, singleDayEvents, selectedDate]
6928
10199
  );
@@ -7104,7 +10375,7 @@ function WeekView({
7104
10375
  visibleHours
7105
10376
  } = useEventCalendar();
7106
10377
  const filteredEvents = useFilteredEvents();
7107
- const { singleDayEvents, multiDayEvents } = React15__namespace.useMemo(
10378
+ const { singleDayEvents, multiDayEvents } = React22__namespace.useMemo(
7108
10379
  () => splitEventsByDuration(filteredEvents),
7109
10380
  [filteredEvents]
7110
10381
  );
@@ -7310,8 +10581,8 @@ function CalendarTimeline({
7310
10581
  firstVisibleHour,
7311
10582
  lastVisibleHour
7312
10583
  }) {
7313
- const [currentTime, setCurrentTime] = React15__namespace.useState(/* @__PURE__ */ new Date());
7314
- React15__namespace.useEffect(() => {
10584
+ const [currentTime, setCurrentTime] = React22__namespace.useState(/* @__PURE__ */ new Date());
10585
+ React22__namespace.useEffect(() => {
7315
10586
  const interval = setInterval(() => {
7316
10587
  setCurrentTime(/* @__PURE__ */ new Date());
7317
10588
  }, 6e4);
@@ -7394,7 +10665,7 @@ function DayView({
7394
10665
  visibleHours
7395
10666
  } = useEventCalendar();
7396
10667
  const filteredEvents = useFilteredEvents();
7397
- const { singleDayEvents, multiDayEvents } = React15__namespace.useMemo(
10668
+ const { singleDayEvents, multiDayEvents } = React22__namespace.useMemo(
7398
10669
  () => splitEventsByDuration(filteredEvents),
7399
10670
  [filteredEvents]
7400
10671
  );
@@ -7402,7 +10673,7 @@ function DayView({
7402
10673
  visibleHours,
7403
10674
  singleDayEvents
7404
10675
  );
7405
- const currentEvents = React15__namespace.useMemo(() => {
10676
+ const currentEvents = React22__namespace.useMemo(() => {
7406
10677
  if (!dateFns.isToday(selectedDate)) return [];
7407
10678
  return getCurrentEvents(singleDayEvents);
7408
10679
  }, [singleDayEvents, selectedDate]);
@@ -7626,8 +10897,8 @@ function CalendarTimeline2({
7626
10897
  firstVisibleHour,
7627
10898
  lastVisibleHour
7628
10899
  }) {
7629
- const [currentTime, setCurrentTime] = React15__namespace.useState(/* @__PURE__ */ new Date());
7630
- React15__namespace.useEffect(() => {
10900
+ const [currentTime, setCurrentTime] = React22__namespace.useState(/* @__PURE__ */ new Date());
10901
+ React22__namespace.useEffect(() => {
7631
10902
  const interval = setInterval(() => {
7632
10903
  setCurrentTime(/* @__PURE__ */ new Date());
7633
10904
  }, 6e4);
@@ -7661,7 +10932,7 @@ function YearView({
7661
10932
  }) {
7662
10933
  const { selectedDate, setSelectedDate, setView } = useEventCalendar();
7663
10934
  const filteredEvents = useFilteredEvents();
7664
- const months = React15__namespace.useMemo(() => {
10935
+ const months = React22__namespace.useMemo(() => {
7665
10936
  const yearStart = dateFns.startOfYear(selectedDate);
7666
10937
  return Array.from({ length: 12 }, (_, i) => dateFns.addMonths(yearStart, i));
7667
10938
  }, [selectedDate]);
@@ -7784,11 +11055,11 @@ function AgendaView({
7784
11055
  }) {
7785
11056
  const { selectedDate, setSelectedDate, setView } = useEventCalendar();
7786
11057
  const filteredEvents = useFilteredEvents();
7787
- const { singleDayEvents, multiDayEvents } = React15__namespace.useMemo(
11058
+ const { singleDayEvents, multiDayEvents } = React22__namespace.useMemo(
7788
11059
  () => splitEventsByDuration(filteredEvents),
7789
11060
  [filteredEvents]
7790
11061
  );
7791
- const eventsByDay = React15__namespace.useMemo(() => {
11062
+ const eventsByDay = React22__namespace.useMemo(() => {
7792
11063
  const allDates = /* @__PURE__ */ new Map();
7793
11064
  singleDayEvents.forEach((event) => {
7794
11065
  const eventDate = dateFns.parseISO(event.startDate);
@@ -7981,7 +11252,7 @@ function CalendarHeader({
7981
11252
  const filteredEvents = useFilteredEvents();
7982
11253
  const eventCount = filteredEvents.length;
7983
11254
  const { start: rangeStart, end: rangeEnd } = getViewDateRange(selectedDate, view);
7984
- const dateRangeLabel = formatDateRange(rangeStart, rangeEnd);
11255
+ const dateRangeLabel = formatDateRange2(rangeStart, rangeEnd);
7985
11256
  const getInitials = (name) => {
7986
11257
  return name.split(" ").map((n) => n[0]).join("").toUpperCase().slice(0, 2);
7987
11258
  };
@@ -8253,16 +11524,16 @@ function EventDialog({
8253
11524
  defaultUserId
8254
11525
  }) {
8255
11526
  const { addEvent, updateEvent, deleteEvent, users } = useEventCalendar();
8256
- const [title, setTitle] = React15__namespace.useState("");
8257
- const [description, setDescription] = React15__namespace.useState("");
8258
- const [startDate, setStartDate] = React15__namespace.useState("");
8259
- const [startTime, setStartTime] = React15__namespace.useState("");
8260
- const [endDate, setEndDate] = React15__namespace.useState("");
8261
- const [endTime, setEndTime] = React15__namespace.useState("");
8262
- const [color, setColor] = React15__namespace.useState("blue");
8263
- const [userId, setUserId] = React15__namespace.useState("");
8264
- const [isSubmitting, setIsSubmitting] = React15__namespace.useState(false);
8265
- React15__namespace.useEffect(() => {
11527
+ const [title, setTitle] = React22__namespace.useState("");
11528
+ const [description, setDescription] = React22__namespace.useState("");
11529
+ const [startDate, setStartDate] = React22__namespace.useState("");
11530
+ const [startTime, setStartTime] = React22__namespace.useState("");
11531
+ const [endDate, setEndDate] = React22__namespace.useState("");
11532
+ const [endTime, setEndTime] = React22__namespace.useState("");
11533
+ const [color, setColor] = React22__namespace.useState("blue");
11534
+ const [userId, setUserId] = React22__namespace.useState("");
11535
+ const [isSubmitting, setIsSubmitting] = React22__namespace.useState(false);
11536
+ React22__namespace.useEffect(() => {
8266
11537
  if (open) {
8267
11538
  if (mode === "edit" && event) {
8268
11539
  const start = dateFns.parseISO(event.startDate);
@@ -8485,7 +11756,7 @@ function QuickAddEvent({
8485
11756
  onOpenDialog,
8486
11757
  onClose
8487
11758
  }) {
8488
- const [title, setTitle] = React15__namespace.useState("");
11759
+ const [title, setTitle] = React22__namespace.useState("");
8489
11760
  const { users } = useEventCalendar();
8490
11761
  const handleSubmit = (e) => {
8491
11762
  e.preventDefault();
@@ -8552,8 +11823,8 @@ var HOUR_OPTIONS = Array.from({ length: 25 }, (_, i) => {
8552
11823
  });
8553
11824
  function ChangeVisibleHoursInput() {
8554
11825
  const { visibleHours, setVisibleHours } = useEventCalendar();
8555
- const [from, setFrom] = React15__namespace.useState(visibleHours.from);
8556
- const [to, setTo] = React15__namespace.useState(visibleHours.to);
11826
+ const [from, setFrom] = React22__namespace.useState(visibleHours.from);
11827
+ const [to, setTo] = React22__namespace.useState(visibleHours.to);
8557
11828
  const handleApply = () => {
8558
11829
  const toHour = to === 0 ? 24 : to;
8559
11830
  setVisibleHours({ from, to: toHour });
@@ -8599,7 +11870,7 @@ var HOUR_OPTIONS2 = Array.from({ length: 25 }, (_, i) => {
8599
11870
  });
8600
11871
  function ChangeWorkingHoursInput() {
8601
11872
  const { workingHours, setWorkingHours } = useEventCalendar();
8602
- const [localWorkingHours, setLocalWorkingHours] = React15__namespace.useState({
11873
+ const [localWorkingHours, setLocalWorkingHours] = React22__namespace.useState({
8603
11874
  ...workingHours
8604
11875
  });
8605
11876
  const handleToggleDay = (dayId) => {
@@ -8748,8 +12019,8 @@ function CalendarSettingsButton({
8748
12019
  );
8749
12020
  }
8750
12021
  function useMediaQuery(query) {
8751
- const [matches, setMatches] = React15__namespace.useState(false);
8752
- React15__namespace.useEffect(() => {
12022
+ const [matches, setMatches] = React22__namespace.useState(false);
12023
+ React22__namespace.useEffect(() => {
8753
12024
  const media = window.matchMedia(query);
8754
12025
  setMatches(media.matches);
8755
12026
  const listener = (event) => {
@@ -8801,11 +12072,11 @@ function BigCalendarInner({
8801
12072
  maxEventsPerDay
8802
12073
  }) {
8803
12074
  const { view, setView } = useEventCalendar();
8804
- const [dialogOpen, setDialogOpen] = React15__namespace.useState(false);
8805
- const [settingsDialogOpen, setSettingsDialogOpen] = React15__namespace.useState(false);
8806
- const [selectedEvent, setSelectedEvent] = React15__namespace.useState(null);
8807
- const [dialogMode, setDialogMode] = React15__namespace.useState("add");
8808
- const [defaultDate, setDefaultDate] = React15__namespace.useState(/* @__PURE__ */ new Date());
12075
+ const [dialogOpen, setDialogOpen] = React22__namespace.useState(false);
12076
+ const [settingsDialogOpen, setSettingsDialogOpen] = React22__namespace.useState(false);
12077
+ const [selectedEvent, setSelectedEvent] = React22__namespace.useState(null);
12078
+ const [dialogMode, setDialogMode] = React22__namespace.useState("add");
12079
+ const [defaultDate, setDefaultDate] = React22__namespace.useState(/* @__PURE__ */ new Date());
8809
12080
  const isMobile = useMediaQuery("(max-width: 768px)");
8810
12081
  const isCompact = compact === "auto" ? isMobile : compact;
8811
12082
  const handleAddClick = () => {
@@ -8964,6 +12235,30 @@ function CalendarView({
8964
12235
  }
8965
12236
  }
8966
12237
 
12238
+ Object.defineProperty(exports, "flexRender", {
12239
+ enumerable: true,
12240
+ get: function () { return reactTable.flexRender; }
12241
+ });
12242
+ Object.defineProperty(exports, "getCoreRowModel", {
12243
+ enumerable: true,
12244
+ get: function () { return reactTable.getCoreRowModel; }
12245
+ });
12246
+ Object.defineProperty(exports, "getFilteredRowModel", {
12247
+ enumerable: true,
12248
+ get: function () { return reactTable.getFilteredRowModel; }
12249
+ });
12250
+ Object.defineProperty(exports, "getPaginationRowModel", {
12251
+ enumerable: true,
12252
+ get: function () { return reactTable.getPaginationRowModel; }
12253
+ });
12254
+ Object.defineProperty(exports, "getSortedRowModel", {
12255
+ enumerable: true,
12256
+ get: function () { return reactTable.getSortedRowModel; }
12257
+ });
12258
+ Object.defineProperty(exports, "useReactTable", {
12259
+ enumerable: true,
12260
+ get: function () { return reactTable.useReactTable; }
12261
+ });
8967
12262
  Object.defineProperty(exports, "areIntervalsOverlapping", {
8968
12263
  enumerable: true,
8969
12264
  get: function () { return dateFns.areIntervalsOverlapping; }
@@ -9037,6 +12332,9 @@ exports.CalendarHeaderCompact = CalendarHeaderCompact;
9037
12332
  exports.CalendarSettingsButton = CalendarSettingsButton;
9038
12333
  exports.CalendarSettingsContent = CalendarSettingsContent;
9039
12334
  exports.CalendarSettingsDialog = CalendarSettingsDialog;
12335
+ exports.CalibrationTable = CalibrationTable;
12336
+ exports.CalibrationWeekCell = CalibrationWeekCell;
12337
+ exports.CalibrationWeekHeader = CalibrationWeekHeader;
9040
12338
  exports.Card = Card;
9041
12339
  exports.CardContent = CardContent;
9042
12340
  exports.CardDescription = CardDescription;
@@ -9058,6 +12356,7 @@ exports.ChartStyle = ChartStyle;
9058
12356
  exports.ChartTooltip = ChartTooltip;
9059
12357
  exports.ChartTooltipContent = ChartTooltipContent;
9060
12358
  exports.Checkbox = Checkbox;
12359
+ exports.CircularProgress = CircularProgress;
9061
12360
  exports.Collapsible = Collapsible;
9062
12361
  exports.CollapsibleContent = CollapsibleContent2;
9063
12362
  exports.CollapsibleTrigger = CollapsibleTrigger2;
@@ -9070,6 +12369,9 @@ exports.CommandItem = CommandItem;
9070
12369
  exports.CommandList = CommandList;
9071
12370
  exports.CommandSeparator = CommandSeparator;
9072
12371
  exports.CommandShortcut = CommandShortcut;
12372
+ exports.CommentButton = CommentButton;
12373
+ exports.CommentDialog = CommentDialog;
12374
+ exports.CommentPopover = CommentPopover;
9073
12375
  exports.ContextMenu = ContextMenu;
9074
12376
  exports.ContextMenuCheckboxItem = ContextMenuCheckboxItem;
9075
12377
  exports.ContextMenuContent = ContextMenuContent;
@@ -9087,8 +12389,13 @@ exports.ContextMenuSubTrigger = ContextMenuSubTrigger;
9087
12389
  exports.ContextMenuTrigger = ContextMenuTrigger;
9088
12390
  exports.DEFAULT_VISIBLE_HOURS = DEFAULT_VISIBLE_HOURS;
9089
12391
  exports.DEFAULT_WORKING_HOURS = DEFAULT_WORKING_HOURS;
12392
+ exports.DataTableColumnHeader = DataTableColumnHeader;
12393
+ exports.DataTablePagination = DataTablePagination;
12394
+ exports.DataTableViewOptions = DataTableViewOptions;
9090
12395
  exports.DateBadge = DateBadge;
9091
12396
  exports.DayView = DayView;
12397
+ exports.DeliveryIndicator = DeliveryIndicator;
12398
+ exports.DeliveryIndicators = DeliveryIndicators;
9092
12399
  exports.Dialog = Dialog;
9093
12400
  exports.DialogClose = DialogClose;
9094
12401
  exports.DialogContent = DialogContent;
@@ -9211,6 +12518,7 @@ exports.NavigationMenuLink = NavigationMenuLink;
9211
12518
  exports.NavigationMenuList = NavigationMenuList;
9212
12519
  exports.NavigationMenuTrigger = NavigationMenuTrigger;
9213
12520
  exports.NavigationMenuViewport = NavigationMenuViewport;
12521
+ exports.NetBadge = NetBadge;
9214
12522
  exports.Pagination = Pagination;
9215
12523
  exports.PaginationContent = PaginationContent;
9216
12524
  exports.PaginationEllipsis = PaginationEllipsis;
@@ -9218,6 +12526,9 @@ exports.PaginationItem = PaginationItem;
9218
12526
  exports.PaginationLink = PaginationLink;
9219
12527
  exports.PaginationNext = PaginationNext;
9220
12528
  exports.PaginationPrevious = PaginationPrevious;
12529
+ exports.PlanningTable = PlanningTable;
12530
+ exports.PlanningTableToolbar = PlanningTableToolbar;
12531
+ exports.PlanningWeekCommentPopover = PlanningWeekCommentPopover;
9221
12532
  exports.PlayerCanvas = PlayerCanvas;
9222
12533
  exports.PlayerCanvasActionButton = PlayerCanvasActionButton;
9223
12534
  exports.PlayerCanvasControls = PlayerCanvasControls;
@@ -9239,6 +12550,7 @@ exports.RadioGroupItem = RadioGroupItem;
9239
12550
  exports.ResizableHandle = ResizableHandle;
9240
12551
  exports.ResizablePanel = ResizablePanel;
9241
12552
  exports.ResizablePanelGroup = ResizablePanelGroup;
12553
+ exports.RowHeaderCell = RowHeaderCell;
9242
12554
  exports.ScrollArea = ScrollArea;
9243
12555
  exports.ScrollBar = ScrollBar;
9244
12556
  exports.SearchForm = SearchForm;
@@ -9296,6 +12608,8 @@ exports.SiteHeader = SiteHeader;
9296
12608
  exports.Skeleton = Skeleton;
9297
12609
  exports.Slider = Slider;
9298
12610
  exports.Spinner = Spinner;
12611
+ exports.SubmitCalibrationBar = SubmitCalibrationBar;
12612
+ exports.SupplierCell = SupplierCell;
9299
12613
  exports.Switch = Switch;
9300
12614
  exports.Table = Table;
9301
12615
  exports.TableBody = TableBody;
@@ -9326,21 +12640,35 @@ exports.TooltipProvider = TooltipProvider;
9326
12640
  exports.TooltipTrigger = TooltipTrigger;
9327
12641
  exports.UserAvatarsDropdown = UserAvatarsDropdown;
9328
12642
  exports.VIEW_LABELS = VIEW_LABELS;
12643
+ exports.WeekCell = WeekCell;
12644
+ exports.WeekDetailDialog = WeekDetailDialog;
12645
+ exports.WeekHeader = WeekHeader;
9329
12646
  exports.WeekView = WeekView;
9330
12647
  exports.YearView = YearView;
9331
12648
  exports.badgeVariants = badgeVariants;
9332
12649
  exports.buttonGroupVariants = buttonGroupVariants;
9333
12650
  exports.buttonVariants = buttonVariants;
12651
+ exports.calculateCalibrationCells = calculateCalibrationCells;
9334
12652
  exports.calculateDropDates = calculateDropDates;
9335
12653
  exports.calculateMonthEventPositions = calculateMonthEventPositions;
12654
+ exports.canSubmitCalibration = canSubmitCalibration;
9336
12655
  exports.cardVariants = cardVariants;
9337
12656
  exports.createDefaultEvent = createDefaultEvent;
9338
- exports.formatDateRange = formatDateRange;
12657
+ exports.deliveryIndicatorVariants = deliveryIndicatorVariants;
12658
+ exports.formatCalibrationUnit = formatCalibrationUnit;
12659
+ exports.formatDateRange = formatDateRange2;
12660
+ exports.formatProductionUnit = formatProductionUnit;
9339
12661
  exports.formatTime = formatTime;
12662
+ exports.generateColumns = generateColumns;
9340
12663
  exports.generateEventId = generateEventId;
12664
+ exports.generateLocationOptions = generateLocationOptions;
12665
+ exports.generateWeekColumns = generateWeekColumns;
12666
+ exports.generateWeeks = generateWeeks;
9341
12667
  exports.getCalendarCells = getCalendarCells;
12668
+ exports.getCommentLocationLabel = getCommentLocationLabel;
9342
12669
  exports.getCurrentEvents = getCurrentEvents;
9343
12670
  exports.getDayHours = getDayHours;
12671
+ exports.getElementShipmentStatus = getElementShipmentStatus;
9344
12672
  exports.getEventBlockStyle = getEventBlockStyle;
9345
12673
  exports.getEventDuration = getEventDuration;
9346
12674
  exports.getEventDurationMinutes = getEventDurationMinutes;
@@ -9348,14 +12676,18 @@ exports.getEventsCount = getEventsCount;
9348
12676
  exports.getEventsForDate = getEventsForDate;
9349
12677
  exports.getEventsInRange = getEventsInRange;
9350
12678
  exports.getHeaderLabel = getHeaderLabel;
12679
+ exports.getISOWeek = getISOWeek;
9351
12680
  exports.getMonthCellEvents = getMonthCellEvents;
9352
12681
  exports.getMonthDays = getMonthDays;
12682
+ exports.getShipmentStatusLabel = getShipmentStatusLabel;
12683
+ exports.getSupplierColumn = getSupplierColumn;
9353
12684
  exports.getTimeHeight = getTimeHeight;
9354
12685
  exports.getTimePosition = getTimePosition;
9355
12686
  exports.getViewDateRange = getViewDateRange;
9356
12687
  exports.getVisibleHours = getVisibleHours;
9357
12688
  exports.getWeekDayNames = getWeekDayNames;
9358
12689
  exports.getWeekDays = getWeekDays;
12690
+ exports.getWeekKey = getWeekKey;
9359
12691
  exports.getYearMonths = getYearMonths;
9360
12692
  exports.groupEvents = groupEvents;
9361
12693
  exports.isMultiDayEvent = isMultiDayEvent;