@j3m-quantum/ui 1.11.2 → 1.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +2018 -790
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +110 -29
- package/dist/index.d.ts +110 -29
- package/dist/index.js +1946 -720
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as React29 from 'react';
|
|
2
2
|
import { createContext, memo, useContext, useMemo, useId, useCallback, useState, useEffect, useRef } from 'react';
|
|
3
3
|
import { Slot } from '@radix-ui/react-slot';
|
|
4
4
|
import { cva } from 'class-variance-authority';
|
|
@@ -7,7 +7,7 @@ import { twMerge } from 'tailwind-merge';
|
|
|
7
7
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
8
8
|
import * as SeparatorPrimitive from '@radix-ui/react-separator';
|
|
9
9
|
import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
|
|
10
|
-
import { SearchIcon, TrashIcon, CheckIcon, CircleIcon, ChevronDownIcon, ChevronUpIcon, ChevronRightIcon, ChevronLeftIcon, ArrowLeft, ArrowRight, Check, Loader2Icon, OctagonXIcon, TriangleAlertIcon, InfoIcon, CircleCheckIcon, ChevronRight, MoreHorizontal, MoreHorizontalIcon, XIcon, GripVerticalIcon, PanelLeftIcon, ArrowDown, ArrowUp, ChevronsUpDown, EyeOff, ChevronsLeft, ChevronLeft, ChevronsRight, Settings2, FolderIcon, ShareIcon, ChevronsUpDownIcon, SparklesIcon, BadgeCheckIcon, CreditCardIcon, BellIcon, LogOutIcon, X, Flag, Factory, Truck, MessageSquare, ChevronDown, Plus, Send, MessageSquarePlus, AlertTriangle, CheckCircle, Calendar as Calendar$1, MapPin, Package, User, Clock, CalendarX2, List, Columns, Grid2x2, Grid3x3, CalendarRange, Settings, Info, Moon, PlusIcon, PencilIcon, CopyIcon, ArrowUpDown, CheckCircle2, XCircle } from 'lucide-react';
|
|
10
|
+
import { SearchIcon, TrashIcon, CheckIcon, CircleIcon, ChevronDownIcon, ChevronUpIcon, ChevronRightIcon, ChevronLeftIcon, ArrowLeft, ArrowRight, Check, Loader2Icon, OctagonXIcon, TriangleAlertIcon, InfoIcon, CircleCheckIcon, ChevronRight, MoreHorizontal, MoreHorizontalIcon, XIcon, GripVerticalIcon, PanelLeftIcon, ArrowDown, ArrowUp, ChevronsUpDown, EyeOff, ChevronsLeft, ChevronLeft, ChevronsRight, Settings2, FolderIcon, ShareIcon, ChevronsUpDownIcon, SparklesIcon, BadgeCheckIcon, CreditCardIcon, BellIcon, LogOutIcon, X, Flag, Factory, Truck, MessageSquare, ChevronDown, Plus, Send, MessageSquarePlus, AlertTriangle, CheckCircle, Calendar as Calendar$1, MapPin, Package, User, Clock, CalendarX2, List, Columns, Grid2x2, Grid3x3, CalendarRange, Settings, Info, Moon, PlusIcon, PencilIcon, CopyIcon, ArrowUpDown, CheckCircle2, XCircle, Search, FileText } from 'lucide-react';
|
|
11
11
|
import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
|
|
12
12
|
import * as SwitchPrimitive from '@radix-ui/react-switch';
|
|
13
13
|
import * as SliderPrimitive from '@radix-ui/react-slider';
|
|
@@ -57,8 +57,8 @@ import tunnel from 'tunnel-rat';
|
|
|
57
57
|
// src/hooks/use-mobile.ts
|
|
58
58
|
var MOBILE_BREAKPOINT = 768;
|
|
59
59
|
function useIsMobile() {
|
|
60
|
-
const [isMobile, setIsMobile] =
|
|
61
|
-
|
|
60
|
+
const [isMobile, setIsMobile] = React29.useState(void 0);
|
|
61
|
+
React29.useEffect(() => {
|
|
62
62
|
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
|
|
63
63
|
const onChange = () => {
|
|
64
64
|
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
@@ -99,7 +99,7 @@ var buttonVariants = cva(
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
);
|
|
102
|
-
var Button =
|
|
102
|
+
var Button = React29.forwardRef(
|
|
103
103
|
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
104
104
|
const Comp = asChild ? Slot : "button";
|
|
105
105
|
return /* @__PURE__ */ jsx(
|
|
@@ -463,7 +463,7 @@ function Slider({
|
|
|
463
463
|
max = 100,
|
|
464
464
|
...props
|
|
465
465
|
}) {
|
|
466
|
-
const _values =
|
|
466
|
+
const _values = React29.useMemo(
|
|
467
467
|
() => Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min, max],
|
|
468
468
|
[value, defaultValue, min, max]
|
|
469
469
|
);
|
|
@@ -749,7 +749,7 @@ function Toggle({
|
|
|
749
749
|
}
|
|
750
750
|
);
|
|
751
751
|
}
|
|
752
|
-
var ToggleGroupContext =
|
|
752
|
+
var ToggleGroupContext = React29.createContext({
|
|
753
753
|
size: "default",
|
|
754
754
|
variant: "default",
|
|
755
755
|
spacing: 0
|
|
@@ -786,7 +786,7 @@ function ToggleGroupItem({
|
|
|
786
786
|
size,
|
|
787
787
|
...props
|
|
788
788
|
}) {
|
|
789
|
-
const context =
|
|
789
|
+
const context = React29.useContext(ToggleGroupContext);
|
|
790
790
|
return /* @__PURE__ */ jsx(
|
|
791
791
|
ToggleGroupPrimitive.Item,
|
|
792
792
|
{
|
|
@@ -816,7 +816,7 @@ function ThemeSwitch({
|
|
|
816
816
|
className,
|
|
817
817
|
size = "default"
|
|
818
818
|
}) {
|
|
819
|
-
const [isChecked, setIsChecked] =
|
|
819
|
+
const [isChecked, setIsChecked] = React29.useState(defaultChecked);
|
|
820
820
|
const isControlled = checked !== void 0;
|
|
821
821
|
const currentChecked = isControlled ? checked : isChecked;
|
|
822
822
|
const handleClick = () => {
|
|
@@ -1236,7 +1236,7 @@ function Label2({
|
|
|
1236
1236
|
);
|
|
1237
1237
|
}
|
|
1238
1238
|
var Form = FormProvider;
|
|
1239
|
-
var FormFieldContext =
|
|
1239
|
+
var FormFieldContext = React29.createContext(
|
|
1240
1240
|
{}
|
|
1241
1241
|
);
|
|
1242
1242
|
var FormField = ({
|
|
@@ -1245,8 +1245,8 @@ var FormField = ({
|
|
|
1245
1245
|
return /* @__PURE__ */ jsx(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsx(Controller, { ...props }) });
|
|
1246
1246
|
};
|
|
1247
1247
|
var useFormField = () => {
|
|
1248
|
-
const fieldContext =
|
|
1249
|
-
const itemContext =
|
|
1248
|
+
const fieldContext = React29.useContext(FormFieldContext);
|
|
1249
|
+
const itemContext = React29.useContext(FormItemContext);
|
|
1250
1250
|
const { getFieldState } = useFormContext();
|
|
1251
1251
|
const formState = useFormState({ name: fieldContext.name });
|
|
1252
1252
|
const fieldState = getFieldState(fieldContext.name, formState);
|
|
@@ -1263,11 +1263,11 @@ var useFormField = () => {
|
|
|
1263
1263
|
...fieldState
|
|
1264
1264
|
};
|
|
1265
1265
|
};
|
|
1266
|
-
var FormItemContext =
|
|
1266
|
+
var FormItemContext = React29.createContext(
|
|
1267
1267
|
{}
|
|
1268
1268
|
);
|
|
1269
1269
|
function FormItem({ className, ...props }) {
|
|
1270
|
-
const id =
|
|
1270
|
+
const id = React29.useId();
|
|
1271
1271
|
return /* @__PURE__ */ jsx(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx(
|
|
1272
1272
|
"div",
|
|
1273
1273
|
{
|
|
@@ -2369,8 +2369,8 @@ function CalendarDayButton({
|
|
|
2369
2369
|
modifiers,
|
|
2370
2370
|
...props
|
|
2371
2371
|
}) {
|
|
2372
|
-
const ref =
|
|
2373
|
-
|
|
2372
|
+
const ref = React29.useRef(null);
|
|
2373
|
+
React29.useEffect(() => {
|
|
2374
2374
|
if (modifiers.focused) ref.current?.focus();
|
|
2375
2375
|
}, [modifiers.focused]);
|
|
2376
2376
|
return /* @__PURE__ */ jsx(
|
|
@@ -2391,9 +2391,9 @@ function CalendarDayButton({
|
|
|
2391
2391
|
}
|
|
2392
2392
|
);
|
|
2393
2393
|
}
|
|
2394
|
-
var CarouselContext =
|
|
2394
|
+
var CarouselContext = React29.createContext(null);
|
|
2395
2395
|
function useCarousel() {
|
|
2396
|
-
const context =
|
|
2396
|
+
const context = React29.useContext(CarouselContext);
|
|
2397
2397
|
if (!context) {
|
|
2398
2398
|
throw new Error("useCarousel must be used within a <Carousel />");
|
|
2399
2399
|
}
|
|
@@ -2415,20 +2415,20 @@ function Carousel({
|
|
|
2415
2415
|
},
|
|
2416
2416
|
plugins
|
|
2417
2417
|
);
|
|
2418
|
-
const [canScrollPrev, setCanScrollPrev] =
|
|
2419
|
-
const [canScrollNext, setCanScrollNext] =
|
|
2420
|
-
const onSelect =
|
|
2418
|
+
const [canScrollPrev, setCanScrollPrev] = React29.useState(false);
|
|
2419
|
+
const [canScrollNext, setCanScrollNext] = React29.useState(false);
|
|
2420
|
+
const onSelect = React29.useCallback((api2) => {
|
|
2421
2421
|
if (!api2) return;
|
|
2422
2422
|
setCanScrollPrev(api2.canScrollPrev());
|
|
2423
2423
|
setCanScrollNext(api2.canScrollNext());
|
|
2424
2424
|
}, []);
|
|
2425
|
-
const scrollPrev =
|
|
2425
|
+
const scrollPrev = React29.useCallback(() => {
|
|
2426
2426
|
api?.scrollPrev();
|
|
2427
2427
|
}, [api]);
|
|
2428
|
-
const scrollNext =
|
|
2428
|
+
const scrollNext = React29.useCallback(() => {
|
|
2429
2429
|
api?.scrollNext();
|
|
2430
2430
|
}, [api]);
|
|
2431
|
-
const handleKeyDown =
|
|
2431
|
+
const handleKeyDown = React29.useCallback(
|
|
2432
2432
|
(event) => {
|
|
2433
2433
|
if (event.key === "ArrowLeft") {
|
|
2434
2434
|
event.preventDefault();
|
|
@@ -2440,11 +2440,11 @@ function Carousel({
|
|
|
2440
2440
|
},
|
|
2441
2441
|
[scrollPrev, scrollNext]
|
|
2442
2442
|
);
|
|
2443
|
-
|
|
2443
|
+
React29.useEffect(() => {
|
|
2444
2444
|
if (!api || !setApi) return;
|
|
2445
2445
|
setApi(api);
|
|
2446
2446
|
}, [api, setApi]);
|
|
2447
|
-
|
|
2447
|
+
React29.useEffect(() => {
|
|
2448
2448
|
if (!api) return;
|
|
2449
2449
|
onSelect(api);
|
|
2450
2450
|
api.on("reInit", onSelect);
|
|
@@ -2577,9 +2577,9 @@ function CarouselNext({
|
|
|
2577
2577
|
);
|
|
2578
2578
|
}
|
|
2579
2579
|
var THEMES = { light: "", dark: ".dark" };
|
|
2580
|
-
var ChartContext =
|
|
2580
|
+
var ChartContext = React29.createContext(null);
|
|
2581
2581
|
function useChart() {
|
|
2582
|
-
const context =
|
|
2582
|
+
const context = React29.useContext(ChartContext);
|
|
2583
2583
|
if (!context) {
|
|
2584
2584
|
throw new Error("useChart must be used within a <ChartContainer />");
|
|
2585
2585
|
}
|
|
@@ -2592,7 +2592,7 @@ function ChartContainer({
|
|
|
2592
2592
|
config,
|
|
2593
2593
|
...props
|
|
2594
2594
|
}) {
|
|
2595
|
-
const uniqueId =
|
|
2595
|
+
const uniqueId = React29.useId();
|
|
2596
2596
|
const chartId = `chart-${id || uniqueId.replace(/:/g, "")}`;
|
|
2597
2597
|
return /* @__PURE__ */ jsx(ChartContext.Provider, { value: { config }, children: /* @__PURE__ */ jsxs(
|
|
2598
2598
|
"div",
|
|
@@ -2653,7 +2653,7 @@ function ChartTooltipContent({
|
|
|
2653
2653
|
labelKey
|
|
2654
2654
|
}) {
|
|
2655
2655
|
const { config } = useChart();
|
|
2656
|
-
const tooltipLabel =
|
|
2656
|
+
const tooltipLabel = React29.useMemo(() => {
|
|
2657
2657
|
if (hideLabel || !payload?.length) {
|
|
2658
2658
|
return null;
|
|
2659
2659
|
}
|
|
@@ -3408,6 +3408,144 @@ function CircularProgress({
|
|
|
3408
3408
|
}
|
|
3409
3409
|
);
|
|
3410
3410
|
}
|
|
3411
|
+
function getVariantFromProgress(value) {
|
|
3412
|
+
if (value >= 100) return "complete";
|
|
3413
|
+
if (value >= 50) return "normal";
|
|
3414
|
+
if (value > 0) return "warning";
|
|
3415
|
+
return "critical";
|
|
3416
|
+
}
|
|
3417
|
+
function getStatusColors(variant) {
|
|
3418
|
+
switch (variant) {
|
|
3419
|
+
case "complete":
|
|
3420
|
+
return {
|
|
3421
|
+
track: "bg-green-500/20 dark:bg-green-500/10",
|
|
3422
|
+
fill: "bg-green-500",
|
|
3423
|
+
text: "text-green-600 dark:text-green-400",
|
|
3424
|
+
icon: "text-green-600 dark:text-green-400"
|
|
3425
|
+
};
|
|
3426
|
+
case "normal":
|
|
3427
|
+
return {
|
|
3428
|
+
track: "bg-green-500/20 dark:bg-green-500/10",
|
|
3429
|
+
fill: "bg-green-500",
|
|
3430
|
+
text: "text-green-600 dark:text-green-400",
|
|
3431
|
+
icon: "text-green-600 dark:text-green-400"
|
|
3432
|
+
};
|
|
3433
|
+
case "warning":
|
|
3434
|
+
return {
|
|
3435
|
+
track: "bg-amber-500/20 dark:bg-amber-500/10",
|
|
3436
|
+
fill: "bg-amber-500",
|
|
3437
|
+
text: "text-amber-600 dark:text-amber-400",
|
|
3438
|
+
icon: "text-amber-600 dark:text-amber-400"
|
|
3439
|
+
};
|
|
3440
|
+
case "critical":
|
|
3441
|
+
return {
|
|
3442
|
+
track: "bg-red-500/20 dark:bg-red-500/10",
|
|
3443
|
+
fill: "bg-red-500",
|
|
3444
|
+
text: "text-red-600 dark:text-red-400",
|
|
3445
|
+
icon: "text-red-600 dark:text-red-400"
|
|
3446
|
+
};
|
|
3447
|
+
}
|
|
3448
|
+
}
|
|
3449
|
+
function getSizeClasses(size) {
|
|
3450
|
+
switch (size) {
|
|
3451
|
+
case "sm":
|
|
3452
|
+
return {
|
|
3453
|
+
bar: "h-1",
|
|
3454
|
+
text: "text-[10px]",
|
|
3455
|
+
icon: "h-3 w-3",
|
|
3456
|
+
gap: "gap-1"
|
|
3457
|
+
};
|
|
3458
|
+
case "lg":
|
|
3459
|
+
return {
|
|
3460
|
+
bar: "h-3",
|
|
3461
|
+
text: "text-sm",
|
|
3462
|
+
icon: "h-5 w-5",
|
|
3463
|
+
gap: "gap-3"
|
|
3464
|
+
};
|
|
3465
|
+
default:
|
|
3466
|
+
return {
|
|
3467
|
+
bar: "h-2",
|
|
3468
|
+
text: "text-xs",
|
|
3469
|
+
icon: "h-4 w-4",
|
|
3470
|
+
gap: "gap-2"
|
|
3471
|
+
};
|
|
3472
|
+
}
|
|
3473
|
+
}
|
|
3474
|
+
function StatusProgress({
|
|
3475
|
+
className,
|
|
3476
|
+
value,
|
|
3477
|
+
currentCount,
|
|
3478
|
+
totalCount,
|
|
3479
|
+
unitLabel = "elements",
|
|
3480
|
+
showLabel = false,
|
|
3481
|
+
showCheckmark = true,
|
|
3482
|
+
size = "md",
|
|
3483
|
+
variant,
|
|
3484
|
+
...props
|
|
3485
|
+
}) {
|
|
3486
|
+
const clampedValue = Math.min(100, Math.max(0, value));
|
|
3487
|
+
const isComplete = clampedValue >= 100;
|
|
3488
|
+
const resolvedVariant = variant ?? getVariantFromProgress(clampedValue);
|
|
3489
|
+
const colors = getStatusColors(resolvedVariant);
|
|
3490
|
+
const sizes = getSizeClasses(size);
|
|
3491
|
+
const labelText = React29.useMemo(() => {
|
|
3492
|
+
if (currentCount !== void 0 && totalCount !== void 0) {
|
|
3493
|
+
return `${currentCount} / ${totalCount} ${unitLabel}`;
|
|
3494
|
+
}
|
|
3495
|
+
return `${Math.round(clampedValue)}%`;
|
|
3496
|
+
}, [currentCount, totalCount, unitLabel, clampedValue]);
|
|
3497
|
+
return /* @__PURE__ */ jsxs(
|
|
3498
|
+
"div",
|
|
3499
|
+
{
|
|
3500
|
+
"data-slot": "status-progress",
|
|
3501
|
+
"data-value": clampedValue,
|
|
3502
|
+
"data-variant": resolvedVariant,
|
|
3503
|
+
"data-complete": isComplete,
|
|
3504
|
+
className: cn("flex flex-col w-full", sizes.gap, className),
|
|
3505
|
+
...props,
|
|
3506
|
+
children: [
|
|
3507
|
+
showLabel && /* @__PURE__ */ jsxs("div", { className: cn("flex items-center justify-between", sizes.gap), children: [
|
|
3508
|
+
/* @__PURE__ */ jsx("span", { className: cn("font-medium", sizes.text, colors.text), children: isComplete && showCheckmark ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1", children: [
|
|
3509
|
+
/* @__PURE__ */ jsx(Check, { className: cn(sizes.icon, colors.icon) }),
|
|
3510
|
+
"Complete"
|
|
3511
|
+
] }) : labelText }),
|
|
3512
|
+
!isComplete && /* @__PURE__ */ jsxs("span", { className: cn("tabular-nums text-muted-foreground", sizes.text), children: [
|
|
3513
|
+
Math.round(clampedValue),
|
|
3514
|
+
"%"
|
|
3515
|
+
] })
|
|
3516
|
+
] }),
|
|
3517
|
+
/* @__PURE__ */ jsx(
|
|
3518
|
+
"div",
|
|
3519
|
+
{
|
|
3520
|
+
className: cn(
|
|
3521
|
+
"w-full rounded-full overflow-hidden",
|
|
3522
|
+
colors.track,
|
|
3523
|
+
sizes.bar
|
|
3524
|
+
),
|
|
3525
|
+
role: "progressbar",
|
|
3526
|
+
"aria-valuenow": clampedValue,
|
|
3527
|
+
"aria-valuemin": 0,
|
|
3528
|
+
"aria-valuemax": 100,
|
|
3529
|
+
children: /* @__PURE__ */ jsx(
|
|
3530
|
+
"div",
|
|
3531
|
+
{
|
|
3532
|
+
className: cn(
|
|
3533
|
+
"h-full rounded-full transition-all duration-300 ease-out",
|
|
3534
|
+
colors.fill
|
|
3535
|
+
),
|
|
3536
|
+
style: { width: `${clampedValue}%` }
|
|
3537
|
+
}
|
|
3538
|
+
)
|
|
3539
|
+
}
|
|
3540
|
+
),
|
|
3541
|
+
!showLabel && isComplete && showCheckmark && /* @__PURE__ */ jsxs("div", { className: cn("flex items-center", sizes.gap), children: [
|
|
3542
|
+
/* @__PURE__ */ jsx(Check, { className: cn(sizes.icon, colors.icon) }),
|
|
3543
|
+
/* @__PURE__ */ jsx("span", { className: cn("font-medium", sizes.text, colors.text), children: "Complete" })
|
|
3544
|
+
] })
|
|
3545
|
+
]
|
|
3546
|
+
}
|
|
3547
|
+
);
|
|
3548
|
+
}
|
|
3411
3549
|
function TooltipProvider({
|
|
3412
3550
|
delayDuration = 0,
|
|
3413
3551
|
...props
|
|
@@ -3455,8 +3593,8 @@ function TooltipContent({
|
|
|
3455
3593
|
) });
|
|
3456
3594
|
}
|
|
3457
3595
|
function useDetectTheme() {
|
|
3458
|
-
const [theme, setTheme] =
|
|
3459
|
-
|
|
3596
|
+
const [theme, setTheme] = React29.useState("light");
|
|
3597
|
+
React29.useEffect(() => {
|
|
3460
3598
|
const isDark = document.documentElement.classList.contains("dark");
|
|
3461
3599
|
setTheme(isDark ? "dark" : "light");
|
|
3462
3600
|
const observer = new MutationObserver((mutations) => {
|
|
@@ -4105,7 +4243,7 @@ function CommandShortcut({
|
|
|
4105
4243
|
}
|
|
4106
4244
|
);
|
|
4107
4245
|
}
|
|
4108
|
-
var SearchTrigger =
|
|
4246
|
+
var SearchTrigger = React29.forwardRef(
|
|
4109
4247
|
({
|
|
4110
4248
|
className,
|
|
4111
4249
|
placeholder = "Search...",
|
|
@@ -4141,7 +4279,7 @@ var SearchTrigger = React27.forwardRef(
|
|
|
4141
4279
|
);
|
|
4142
4280
|
SearchTrigger.displayName = "SearchTrigger";
|
|
4143
4281
|
function useSearchShortcut(onOpen, key = "k") {
|
|
4144
|
-
|
|
4282
|
+
React29.useEffect(() => {
|
|
4145
4283
|
const down = (e) => {
|
|
4146
4284
|
if (e.key.toLowerCase() === key.toLowerCase() && (e.metaKey || e.ctrlKey)) {
|
|
4147
4285
|
e.preventDefault();
|
|
@@ -5116,9 +5254,9 @@ var SIDEBAR_WIDTH = "16rem";
|
|
|
5116
5254
|
var SIDEBAR_WIDTH_MOBILE = "18rem";
|
|
5117
5255
|
var SIDEBAR_WIDTH_ICON = "3rem";
|
|
5118
5256
|
var SIDEBAR_KEYBOARD_SHORTCUT = "b";
|
|
5119
|
-
var SidebarContext =
|
|
5257
|
+
var SidebarContext = React29.createContext(null);
|
|
5120
5258
|
function useSidebar() {
|
|
5121
|
-
const context =
|
|
5259
|
+
const context = React29.useContext(SidebarContext);
|
|
5122
5260
|
if (!context) {
|
|
5123
5261
|
throw new Error("useSidebar must be used within a SidebarProvider.");
|
|
5124
5262
|
}
|
|
@@ -5134,10 +5272,10 @@ function SidebarProvider({
|
|
|
5134
5272
|
...props
|
|
5135
5273
|
}) {
|
|
5136
5274
|
const isMobile = useIsMobile();
|
|
5137
|
-
const [openMobile, setOpenMobile] =
|
|
5138
|
-
const [_open, _setOpen] =
|
|
5275
|
+
const [openMobile, setOpenMobile] = React29.useState(false);
|
|
5276
|
+
const [_open, _setOpen] = React29.useState(defaultOpen);
|
|
5139
5277
|
const open = openProp ?? _open;
|
|
5140
|
-
const setOpen =
|
|
5278
|
+
const setOpen = React29.useCallback(
|
|
5141
5279
|
(value) => {
|
|
5142
5280
|
const openState = typeof value === "function" ? value(open) : value;
|
|
5143
5281
|
if (setOpenProp) {
|
|
@@ -5149,10 +5287,10 @@ function SidebarProvider({
|
|
|
5149
5287
|
},
|
|
5150
5288
|
[setOpenProp, open]
|
|
5151
5289
|
);
|
|
5152
|
-
const toggleSidebar =
|
|
5290
|
+
const toggleSidebar = React29.useCallback(() => {
|
|
5153
5291
|
return isMobile ? setOpenMobile((open2) => !open2) : setOpen((open2) => !open2);
|
|
5154
5292
|
}, [isMobile, setOpen, setOpenMobile]);
|
|
5155
|
-
|
|
5293
|
+
React29.useEffect(() => {
|
|
5156
5294
|
const handleKeyDown = (event) => {
|
|
5157
5295
|
if (event.key === SIDEBAR_KEYBOARD_SHORTCUT && (event.metaKey || event.ctrlKey)) {
|
|
5158
5296
|
event.preventDefault();
|
|
@@ -5163,7 +5301,7 @@ function SidebarProvider({
|
|
|
5163
5301
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
5164
5302
|
}, [toggleSidebar]);
|
|
5165
5303
|
const state = open ? "expanded" : "collapsed";
|
|
5166
|
-
const contextValue =
|
|
5304
|
+
const contextValue = React29.useMemo(
|
|
5167
5305
|
() => ({
|
|
5168
5306
|
state,
|
|
5169
5307
|
open,
|
|
@@ -5621,7 +5759,7 @@ function SidebarMenuSkeleton({
|
|
|
5621
5759
|
showIcon = false,
|
|
5622
5760
|
...props
|
|
5623
5761
|
}) {
|
|
5624
|
-
const width =
|
|
5762
|
+
const width = React29.useMemo(() => {
|
|
5625
5763
|
return `${Math.floor(Math.random() * 40) + 50}%`;
|
|
5626
5764
|
}, []);
|
|
5627
5765
|
return /* @__PURE__ */ jsxs(
|
|
@@ -5764,7 +5902,7 @@ var sectionVariants = cva(
|
|
|
5764
5902
|
}
|
|
5765
5903
|
);
|
|
5766
5904
|
var isGlassVariant = (variant) => variant?.startsWith("glass-") ?? false;
|
|
5767
|
-
var Section =
|
|
5905
|
+
var Section = React29.forwardRef(
|
|
5768
5906
|
({ className, variant, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
5769
5907
|
"section",
|
|
5770
5908
|
{
|
|
@@ -5776,7 +5914,7 @@ var Section = React27.forwardRef(
|
|
|
5776
5914
|
)
|
|
5777
5915
|
);
|
|
5778
5916
|
Section.displayName = "Section";
|
|
5779
|
-
var SectionHeader =
|
|
5917
|
+
var SectionHeader = React29.forwardRef(
|
|
5780
5918
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
5781
5919
|
"div",
|
|
5782
5920
|
{
|
|
@@ -5791,7 +5929,7 @@ var SectionHeader = React27.forwardRef(
|
|
|
5791
5929
|
)
|
|
5792
5930
|
);
|
|
5793
5931
|
SectionHeader.displayName = "SectionHeader";
|
|
5794
|
-
var SectionTitle =
|
|
5932
|
+
var SectionTitle = React29.forwardRef(
|
|
5795
5933
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
5796
5934
|
"h2",
|
|
5797
5935
|
{
|
|
@@ -5805,7 +5943,7 @@ var SectionTitle = React27.forwardRef(
|
|
|
5805
5943
|
)
|
|
5806
5944
|
);
|
|
5807
5945
|
SectionTitle.displayName = "SectionTitle";
|
|
5808
|
-
var SectionDescription =
|
|
5946
|
+
var SectionDescription = React29.forwardRef(
|
|
5809
5947
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
5810
5948
|
"p",
|
|
5811
5949
|
{
|
|
@@ -5819,7 +5957,7 @@ var SectionDescription = React27.forwardRef(
|
|
|
5819
5957
|
)
|
|
5820
5958
|
);
|
|
5821
5959
|
SectionDescription.displayName = "SectionDescription";
|
|
5822
|
-
var SectionContent =
|
|
5960
|
+
var SectionContent = React29.forwardRef(
|
|
5823
5961
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
5824
5962
|
"div",
|
|
5825
5963
|
{
|
|
@@ -5833,7 +5971,7 @@ var SectionContent = React27.forwardRef(
|
|
|
5833
5971
|
)
|
|
5834
5972
|
);
|
|
5835
5973
|
SectionContent.displayName = "SectionContent";
|
|
5836
|
-
var SectionFooter =
|
|
5974
|
+
var SectionFooter = React29.forwardRef(
|
|
5837
5975
|
({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
5838
5976
|
"div",
|
|
5839
5977
|
{
|
|
@@ -6141,7 +6279,7 @@ function SiteHeader({
|
|
|
6141
6279
|
children: /* @__PURE__ */ 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: [
|
|
6142
6280
|
trigger,
|
|
6143
6281
|
trigger && /* @__PURE__ */ jsx(Separator, { orientation: "vertical", className: "mr-[var(--j3m-spacing-s)] h-4" }),
|
|
6144
|
-
/* @__PURE__ */ jsx(Breadcrumb, { className: "hidden sm:block", children: /* @__PURE__ */ jsx(BreadcrumbList, { children: breadcrumbs.map((item, index) => /* @__PURE__ */ jsxs(
|
|
6282
|
+
/* @__PURE__ */ jsx(Breadcrumb, { className: "hidden sm:block", children: /* @__PURE__ */ jsx(BreadcrumbList, { children: breadcrumbs.map((item, index) => /* @__PURE__ */ jsxs(React29.Fragment, { children: [
|
|
6145
6283
|
index > 0 && /* @__PURE__ */ jsx(BreadcrumbSeparator, {}),
|
|
6146
6284
|
/* @__PURE__ */ jsx(BreadcrumbItem, { children: item.href ? /* @__PURE__ */ jsx(BreadcrumbLink, { href: item.href, children: item.label }) : /* @__PURE__ */ jsx(BreadcrumbPage, { children: item.label }) })
|
|
6147
6285
|
] }, index)) }) }),
|
|
@@ -6380,15 +6518,27 @@ function getCombinedRiskLevel(data) {
|
|
|
6380
6518
|
if (productionStatus === "delayed" || hasDeliveryDelayed || data.hasWarning) {
|
|
6381
6519
|
return "warning";
|
|
6382
6520
|
}
|
|
6521
|
+
const productionProgress = data.production?.progress ?? data.progress ?? 0;
|
|
6522
|
+
const isProductionComplete = productionProgress >= 100;
|
|
6523
|
+
if (isProductionComplete) {
|
|
6524
|
+
return "complete";
|
|
6525
|
+
}
|
|
6383
6526
|
return "normal";
|
|
6384
6527
|
}
|
|
6385
|
-
function getRowStatus(status) {
|
|
6528
|
+
function getRowStatus(status, progress) {
|
|
6386
6529
|
if (status === "critical") return "critical";
|
|
6387
6530
|
if (status === "delayed") return "warning";
|
|
6531
|
+
if (progress !== void 0 && progress >= 100) return "complete";
|
|
6388
6532
|
return "normal";
|
|
6389
6533
|
}
|
|
6390
6534
|
var statusFillClasses = {
|
|
6391
6535
|
normal: {
|
|
6536
|
+
// Grey/muted for "on track but not complete" - reduces visual noise
|
|
6537
|
+
border: "border-l-[3px] border-l-muted-foreground/40",
|
|
6538
|
+
bg: "bg-muted/30 dark:bg-muted/20"
|
|
6539
|
+
},
|
|
6540
|
+
complete: {
|
|
6541
|
+
// Green for "done/complete" - clear success signal
|
|
6392
6542
|
border: "border-l-[3px] border-l-green-500",
|
|
6393
6543
|
bg: "bg-green-50/50 dark:bg-green-950/30"
|
|
6394
6544
|
},
|
|
@@ -6403,6 +6553,13 @@ var statusFillClasses = {
|
|
|
6403
6553
|
};
|
|
6404
6554
|
var statusColors = {
|
|
6405
6555
|
normal: {
|
|
6556
|
+
// Grey/muted for "on track but not complete"
|
|
6557
|
+
icon: "text-muted-foreground",
|
|
6558
|
+
progress: "bg-muted-foreground/60",
|
|
6559
|
+
text: "text-muted-foreground"
|
|
6560
|
+
},
|
|
6561
|
+
complete: {
|
|
6562
|
+
// Green for "done/complete"
|
|
6406
6563
|
icon: "text-green-600 dark:text-green-400",
|
|
6407
6564
|
progress: "bg-green-500",
|
|
6408
6565
|
text: "text-green-700 dark:text-green-300"
|
|
@@ -6430,19 +6587,20 @@ function WeekCell({
|
|
|
6430
6587
|
const combinedRisk = data.type === "data" ? getCombinedRiskLevel(data) : "normal";
|
|
6431
6588
|
const statusClasses = statusFillClasses[combinedRisk];
|
|
6432
6589
|
const productionProgress = data.production?.progress ?? data.progress ?? 0;
|
|
6433
|
-
const productionStatus = getRowStatus(data.production?.status);
|
|
6590
|
+
const productionStatus = getRowStatus(data.production?.status, productionProgress);
|
|
6434
6591
|
const productionColors = statusColors[productionStatus];
|
|
6435
6592
|
const deliveryCount = data.deliveries?.length ?? 0;
|
|
6436
|
-
const
|
|
6593
|
+
const allDeliveriesComplete = data.deliveries?.every((d) => (d.progress ?? 0) >= 100) ?? false;
|
|
6594
|
+
const worstDeliveryStatus = data.deliveries?.some((d) => d.status === "critical") ? "critical" : data.deliveries?.some((d) => d.status === "delayed") ? "warning" : allDeliveriesComplete && deliveryCount > 0 ? "complete" : "normal";
|
|
6437
6595
|
const deliveryColors = statusColors[worstDeliveryStatus];
|
|
6438
|
-
const getDeliveryStatusColor = (
|
|
6439
|
-
switch (status) {
|
|
6596
|
+
const getDeliveryStatusColor = (delivery) => {
|
|
6597
|
+
switch (delivery.status) {
|
|
6440
6598
|
case "critical":
|
|
6441
6599
|
return "bg-red-500";
|
|
6442
6600
|
case "delayed":
|
|
6443
6601
|
return "bg-amber-500";
|
|
6444
6602
|
default:
|
|
6445
|
-
return "bg-green-500";
|
|
6603
|
+
return (delivery.progress ?? 0) >= 100 ? "bg-green-500" : "bg-muted-foreground/60";
|
|
6446
6604
|
}
|
|
6447
6605
|
};
|
|
6448
6606
|
const handleClick = () => {
|
|
@@ -6559,24 +6717,18 @@ function WeekCell({
|
|
|
6559
6717
|
] }) : /* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground", children: "\u2014" })
|
|
6560
6718
|
] }),
|
|
6561
6719
|
deliveryCount > 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
6562
|
-
data.deliveries?.slice(0, 5).map((delivery, index) =>
|
|
6563
|
-
|
|
6564
|
-
|
|
6565
|
-
|
|
6566
|
-
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
|
|
6570
|
-
|
|
6571
|
-
|
|
6572
|
-
|
|
6573
|
-
|
|
6574
|
-
}
|
|
6575
|
-
) })
|
|
6576
|
-
},
|
|
6577
|
-
delivery.id || index
|
|
6578
|
-
);
|
|
6579
|
-
}),
|
|
6720
|
+
data.deliveries?.slice(0, 5).map((delivery, index) => /* @__PURE__ */ jsx(
|
|
6721
|
+
"div",
|
|
6722
|
+
{
|
|
6723
|
+
className: cn(
|
|
6724
|
+
"flex-1 max-w-[24px] h-1.5 rounded-full",
|
|
6725
|
+
// Solid status color - grey=on-track, green=complete, amber=at-risk, red=critical
|
|
6726
|
+
getDeliveryStatusColor(delivery)
|
|
6727
|
+
),
|
|
6728
|
+
title: delivery.label || `Delivery ${index + 1}`
|
|
6729
|
+
},
|
|
6730
|
+
delivery.id || index
|
|
6731
|
+
)),
|
|
6580
6732
|
deliveryCount > 5 && /* @__PURE__ */ jsxs("span", { className: "text-[8px] text-muted-foreground", children: [
|
|
6581
6733
|
"+",
|
|
6582
6734
|
deliveryCount - 5
|
|
@@ -6748,11 +6900,11 @@ function PlanningWeekCommentPopover({
|
|
|
6748
6900
|
open,
|
|
6749
6901
|
onOpenChange
|
|
6750
6902
|
}) {
|
|
6751
|
-
const [newCommentText, setNewCommentText] =
|
|
6752
|
-
const [selectedLocationId, setSelectedLocationId] =
|
|
6753
|
-
const [viewCommentsOpen, setViewCommentsOpen] =
|
|
6754
|
-
const [showAddForm, setShowAddForm] =
|
|
6755
|
-
const selectedLocation =
|
|
6903
|
+
const [newCommentText, setNewCommentText] = React29.useState("");
|
|
6904
|
+
const [selectedLocationId, setSelectedLocationId] = React29.useState("");
|
|
6905
|
+
const [viewCommentsOpen, setViewCommentsOpen] = React29.useState(true);
|
|
6906
|
+
const [showAddForm, setShowAddForm] = React29.useState(false);
|
|
6907
|
+
const selectedLocation = React29.useMemo(() => {
|
|
6756
6908
|
return locationOptions.find((opt) => opt.id === selectedLocationId);
|
|
6757
6909
|
}, [locationOptions, selectedLocationId]);
|
|
6758
6910
|
const handleSubmit = () => {
|
|
@@ -6796,8 +6948,8 @@ function PlanningWeekCommentPopover({
|
|
|
6796
6948
|
minute: "2-digit"
|
|
6797
6949
|
}).format(date);
|
|
6798
6950
|
};
|
|
6799
|
-
const prevOpenRef =
|
|
6800
|
-
|
|
6951
|
+
const prevOpenRef = React29.useRef(open);
|
|
6952
|
+
React29.useEffect(() => {
|
|
6801
6953
|
const wasOpen = prevOpenRef.current;
|
|
6802
6954
|
prevOpenRef.current = open;
|
|
6803
6955
|
if (wasOpen && !open) {
|
|
@@ -7151,22 +7303,22 @@ function PlanningTable({
|
|
|
7151
7303
|
stickySupplierColumn = true,
|
|
7152
7304
|
maxHeight = "600px"
|
|
7153
7305
|
} = config;
|
|
7154
|
-
const weeks =
|
|
7306
|
+
const weeks = React29.useMemo(
|
|
7155
7307
|
() => generateWeeks(startDate, weekCount),
|
|
7156
7308
|
[startDate, weekCount]
|
|
7157
7309
|
);
|
|
7158
|
-
const currentWeekKey =
|
|
7310
|
+
const currentWeekKey = React29.useMemo(() => {
|
|
7159
7311
|
const currentWeek = weeks.find((w) => w.isCurrentWeek);
|
|
7160
7312
|
return currentWeek ? getWeekKey(currentWeek.startDate) : null;
|
|
7161
7313
|
}, [weeks]);
|
|
7162
|
-
const columns =
|
|
7314
|
+
const columns = React29.useMemo(
|
|
7163
7315
|
() => generateColumns(weeks, config, suppliers),
|
|
7164
7316
|
[weeks, config, suppliers]
|
|
7165
7317
|
);
|
|
7166
|
-
const [sorting, setSorting] =
|
|
7167
|
-
const [columnFilters, setColumnFilters] =
|
|
7168
|
-
const [columnVisibility, setColumnVisibility] =
|
|
7169
|
-
const [rowSelection, setRowSelection] =
|
|
7318
|
+
const [sorting, setSorting] = React29.useState([]);
|
|
7319
|
+
const [columnFilters, setColumnFilters] = React29.useState([]);
|
|
7320
|
+
const [columnVisibility, setColumnVisibility] = React29.useState({});
|
|
7321
|
+
const [rowSelection, setRowSelection] = React29.useState({});
|
|
7170
7322
|
const table = useReactTable({
|
|
7171
7323
|
data: suppliers,
|
|
7172
7324
|
columns,
|
|
@@ -7289,10 +7441,12 @@ function PlanningTable({
|
|
|
7289
7441
|
}
|
|
7290
7442
|
);
|
|
7291
7443
|
}
|
|
7292
|
-
function getStatusBadgeVariant(status) {
|
|
7444
|
+
function getStatusBadgeVariant(status, isComplete) {
|
|
7445
|
+
if (isComplete) return "outline";
|
|
7293
7446
|
switch (status) {
|
|
7294
7447
|
case "on-time":
|
|
7295
7448
|
return "outline";
|
|
7449
|
+
// Grey for on-track
|
|
7296
7450
|
case "delayed":
|
|
7297
7451
|
return "secondary";
|
|
7298
7452
|
case "critical":
|
|
@@ -7301,19 +7455,24 @@ function getStatusBadgeVariant(status) {
|
|
|
7301
7455
|
return "outline";
|
|
7302
7456
|
}
|
|
7303
7457
|
}
|
|
7304
|
-
function getStatusBadgeClasses(status) {
|
|
7458
|
+
function getStatusBadgeClasses(status, isComplete) {
|
|
7459
|
+
if (isComplete) {
|
|
7460
|
+
return "border-green-500 text-green-600 bg-green-50 dark:bg-green-950/50";
|
|
7461
|
+
}
|
|
7305
7462
|
switch (status) {
|
|
7306
7463
|
case "on-time":
|
|
7307
|
-
return "border-
|
|
7464
|
+
return "border-muted-foreground/50 text-muted-foreground bg-muted/50";
|
|
7465
|
+
// Grey for on-track
|
|
7308
7466
|
case "delayed":
|
|
7309
7467
|
return "border-amber-500 text-amber-600 bg-amber-50 dark:bg-amber-950/50";
|
|
7310
7468
|
case "critical":
|
|
7311
7469
|
return "";
|
|
7312
7470
|
default:
|
|
7313
|
-
return "";
|
|
7471
|
+
return "border-muted-foreground/50 text-muted-foreground";
|
|
7314
7472
|
}
|
|
7315
7473
|
}
|
|
7316
|
-
function getStatusLabel(status) {
|
|
7474
|
+
function getStatusLabel(status, isComplete) {
|
|
7475
|
+
if (isComplete) return "Complete";
|
|
7317
7476
|
switch (status) {
|
|
7318
7477
|
case "on-time":
|
|
7319
7478
|
return "On Track";
|
|
@@ -7327,10 +7486,12 @@ function getStatusLabel(status) {
|
|
|
7327
7486
|
return status;
|
|
7328
7487
|
}
|
|
7329
7488
|
}
|
|
7330
|
-
function getProgressVariant(status) {
|
|
7489
|
+
function getProgressVariant(status, isComplete) {
|
|
7490
|
+
if (isComplete) return "success";
|
|
7331
7491
|
switch (status) {
|
|
7332
7492
|
case "on-time":
|
|
7333
|
-
return "
|
|
7493
|
+
return "default";
|
|
7494
|
+
// Grey/default for on-track
|
|
7334
7495
|
case "delayed":
|
|
7335
7496
|
return "warning";
|
|
7336
7497
|
case "critical":
|
|
@@ -7373,10 +7534,10 @@ function DeliveryCommentPopover({
|
|
|
7373
7534
|
onAddComment,
|
|
7374
7535
|
deliveryLabel
|
|
7375
7536
|
}) {
|
|
7376
|
-
const [open, setOpen] =
|
|
7377
|
-
const [newCommentText, setNewCommentText] =
|
|
7378
|
-
const [viewCommentsOpen, setViewCommentsOpen] =
|
|
7379
|
-
const [showAddForm, setShowAddForm] =
|
|
7537
|
+
const [open, setOpen] = React29.useState(false);
|
|
7538
|
+
const [newCommentText, setNewCommentText] = React29.useState("");
|
|
7539
|
+
const [viewCommentsOpen, setViewCommentsOpen] = React29.useState(true);
|
|
7540
|
+
const [showAddForm, setShowAddForm] = React29.useState(false);
|
|
7380
7541
|
const handleSubmit = () => {
|
|
7381
7542
|
if (newCommentText.trim() && onAddComment) {
|
|
7382
7543
|
onAddComment(newCommentText.trim());
|
|
@@ -7403,8 +7564,8 @@ function DeliveryCommentPopover({
|
|
|
7403
7564
|
minute: "2-digit"
|
|
7404
7565
|
}).format(date);
|
|
7405
7566
|
};
|
|
7406
|
-
const prevOpenRef =
|
|
7407
|
-
|
|
7567
|
+
const prevOpenRef = React29.useRef(open);
|
|
7568
|
+
React29.useEffect(() => {
|
|
7408
7569
|
const wasOpen = prevOpenRef.current;
|
|
7409
7570
|
prevOpenRef.current = open;
|
|
7410
7571
|
if (wasOpen && !open) {
|
|
@@ -7516,8 +7677,8 @@ function ProductionCommentSection({
|
|
|
7516
7677
|
comments = [],
|
|
7517
7678
|
onAddComment
|
|
7518
7679
|
}) {
|
|
7519
|
-
const [showAddForm, setShowAddForm] =
|
|
7520
|
-
const [newComment, setNewComment] =
|
|
7680
|
+
const [showAddForm, setShowAddForm] = React29.useState(false);
|
|
7681
|
+
const [newComment, setNewComment] = React29.useState("");
|
|
7521
7682
|
const handleSubmit = () => {
|
|
7522
7683
|
if (newComment.trim() && onAddComment) {
|
|
7523
7684
|
onAddComment(newComment.trim());
|
|
@@ -7615,6 +7776,20 @@ function DeliveryListItem({
|
|
|
7615
7776
|
onClick
|
|
7616
7777
|
}) {
|
|
7617
7778
|
const hasComments = (delivery.comments?.length ?? 0) > 0;
|
|
7779
|
+
const isComplete = (delivery.progress ?? 0) >= 100;
|
|
7780
|
+
const getIconStyles = () => {
|
|
7781
|
+
if (delivery.status === "critical") {
|
|
7782
|
+
return { bg: "bg-red-100 dark:bg-red-950/50", icon: "text-red-600 dark:text-red-400" };
|
|
7783
|
+
}
|
|
7784
|
+
if (delivery.status === "delayed") {
|
|
7785
|
+
return { bg: "bg-amber-100 dark:bg-amber-950/50", icon: "text-amber-600 dark:text-amber-400" };
|
|
7786
|
+
}
|
|
7787
|
+
if (isComplete) {
|
|
7788
|
+
return { bg: "bg-green-100 dark:bg-green-950/50", icon: "text-green-600 dark:text-green-400" };
|
|
7789
|
+
}
|
|
7790
|
+
return { bg: "bg-muted", icon: "text-muted-foreground" };
|
|
7791
|
+
};
|
|
7792
|
+
const iconStyles = getIconStyles();
|
|
7618
7793
|
return /* @__PURE__ */ jsxs(
|
|
7619
7794
|
"button",
|
|
7620
7795
|
{
|
|
@@ -7628,15 +7803,8 @@ function DeliveryListItem({
|
|
|
7628
7803
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
7629
7804
|
/* @__PURE__ */ jsx("div", { className: cn(
|
|
7630
7805
|
"flex items-center justify-center h-8 w-8 rounded-lg",
|
|
7631
|
-
|
|
7632
|
-
|
|
7633
|
-
delivery.status === "critical" && "bg-red-100 dark:bg-red-950/50"
|
|
7634
|
-
), children: /* @__PURE__ */ jsx(Truck, { className: cn(
|
|
7635
|
-
"h-4 w-4",
|
|
7636
|
-
delivery.status === "on-time" && "text-green-600 dark:text-green-400",
|
|
7637
|
-
delivery.status === "delayed" && "text-amber-600 dark:text-amber-400",
|
|
7638
|
-
delivery.status === "critical" && "text-red-600 dark:text-red-400"
|
|
7639
|
-
) }) }),
|
|
7806
|
+
iconStyles.bg
|
|
7807
|
+
), children: /* @__PURE__ */ jsx(Truck, { className: cn("h-4 w-4", iconStyles.icon) }) }),
|
|
7640
7808
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
7641
7809
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
7642
7810
|
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: delivery.label || `Delivery ${index + 1}` }),
|
|
@@ -7655,9 +7823,9 @@ function DeliveryListItem({
|
|
|
7655
7823
|
/* @__PURE__ */ jsx(
|
|
7656
7824
|
Badge,
|
|
7657
7825
|
{
|
|
7658
|
-
variant: getStatusBadgeVariant(delivery.status),
|
|
7659
|
-
className: cn("text-xs", getStatusBadgeClasses(delivery.status)),
|
|
7660
|
-
children: getStatusLabel(delivery.status)
|
|
7826
|
+
variant: getStatusBadgeVariant(delivery.status, isComplete),
|
|
7827
|
+
className: cn("text-xs", getStatusBadgeClasses(delivery.status, isComplete)),
|
|
7828
|
+
children: getStatusLabel(delivery.status, isComplete)
|
|
7661
7829
|
}
|
|
7662
7830
|
),
|
|
7663
7831
|
/* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4 text-muted-foreground" })
|
|
@@ -7673,7 +7841,7 @@ function DeliveryDetailsView({
|
|
|
7673
7841
|
onAddComment
|
|
7674
7842
|
}) {
|
|
7675
7843
|
const elements = delivery.elements ?? [];
|
|
7676
|
-
const categorizedElements =
|
|
7844
|
+
const categorizedElements = React29.useMemo(() => {
|
|
7677
7845
|
const sent = [];
|
|
7678
7846
|
const notSent = [];
|
|
7679
7847
|
const moved = [];
|
|
@@ -7731,9 +7899,9 @@ function DeliveryDetailsView({
|
|
|
7731
7899
|
/* @__PURE__ */ jsx(
|
|
7732
7900
|
Badge,
|
|
7733
7901
|
{
|
|
7734
|
-
variant: getStatusBadgeVariant(delivery.status),
|
|
7735
|
-
className: cn("text-xs", getStatusBadgeClasses(delivery.status)),
|
|
7736
|
-
children: getStatusLabel(delivery.status)
|
|
7902
|
+
variant: getStatusBadgeVariant(delivery.status, sentCount === totalCount && totalCount > 0),
|
|
7903
|
+
className: cn("text-xs", getStatusBadgeClasses(delivery.status, sentCount === totalCount && totalCount > 0)),
|
|
7904
|
+
children: getStatusLabel(delivery.status, sentCount === totalCount && totalCount > 0)
|
|
7737
7905
|
}
|
|
7738
7906
|
)
|
|
7739
7907
|
] })
|
|
@@ -7906,9 +8074,9 @@ function MainView({
|
|
|
7906
8074
|
/* @__PURE__ */ jsx(
|
|
7907
8075
|
Badge,
|
|
7908
8076
|
{
|
|
7909
|
-
variant: getStatusBadgeVariant(productionStatus),
|
|
7910
|
-
className: cn("text-xs ml-auto", getStatusBadgeClasses(productionStatus)),
|
|
7911
|
-
children: getStatusLabel(productionStatus)
|
|
8077
|
+
variant: getStatusBadgeVariant(productionStatus, isComplete),
|
|
8078
|
+
className: cn("text-xs ml-auto", getStatusBadgeClasses(productionStatus, isComplete)),
|
|
8079
|
+
children: getStatusLabel(productionStatus, isComplete)
|
|
7912
8080
|
}
|
|
7913
8081
|
)
|
|
7914
8082
|
] }),
|
|
@@ -7919,7 +8087,7 @@ function MainView({
|
|
|
7919
8087
|
value: productionProgress,
|
|
7920
8088
|
size: 100,
|
|
7921
8089
|
strokeWidth: 10,
|
|
7922
|
-
variant: getProgressVariant(productionStatus),
|
|
8090
|
+
variant: getProgressVariant(productionStatus, isComplete),
|
|
7923
8091
|
showCheckmark: isComplete,
|
|
7924
8092
|
children: isComplete ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center", children: [
|
|
7925
8093
|
/* @__PURE__ */ jsx(Check, { className: "h-6 w-6 text-green-600" }),
|
|
@@ -8041,15 +8209,15 @@ function WeekDetailDialog({
|
|
|
8041
8209
|
}) {
|
|
8042
8210
|
const production = data?.production;
|
|
8043
8211
|
const initialProduced = production?.produced ?? 0;
|
|
8044
|
-
const [producedValue, setProducedValue] =
|
|
8045
|
-
const [hasChanges, setHasChanges] =
|
|
8046
|
-
const [selectedDelivery, setSelectedDelivery] =
|
|
8047
|
-
|
|
8212
|
+
const [producedValue, setProducedValue] = React29.useState(initialProduced.toString());
|
|
8213
|
+
const [hasChanges, setHasChanges] = React29.useState(false);
|
|
8214
|
+
const [selectedDelivery, setSelectedDelivery] = React29.useState(null);
|
|
8215
|
+
React29.useEffect(() => {
|
|
8048
8216
|
const newProduced = data?.production?.produced ?? 0;
|
|
8049
8217
|
setProducedValue(newProduced.toString());
|
|
8050
8218
|
setHasChanges(false);
|
|
8051
8219
|
}, [data]);
|
|
8052
|
-
|
|
8220
|
+
React29.useEffect(() => {
|
|
8053
8221
|
if (!open) {
|
|
8054
8222
|
setSelectedDelivery(null);
|
|
8055
8223
|
}
|
|
@@ -8100,59 +8268,1074 @@ function WeekDetailDialog({
|
|
|
8100
8268
|
}
|
|
8101
8269
|
) }) });
|
|
8102
8270
|
}
|
|
8103
|
-
function
|
|
8104
|
-
|
|
8105
|
-
|
|
8106
|
-
|
|
8107
|
-
|
|
8271
|
+
function getStatusBadgeVariant2(status, isComplete) {
|
|
8272
|
+
if (isComplete) return "outline";
|
|
8273
|
+
switch (status) {
|
|
8274
|
+
case "on-time":
|
|
8275
|
+
return "outline";
|
|
8276
|
+
// Grey for on-track
|
|
8277
|
+
case "delayed":
|
|
8278
|
+
return "secondary";
|
|
8279
|
+
case "critical":
|
|
8280
|
+
return "destructive";
|
|
8281
|
+
default:
|
|
8282
|
+
return "outline";
|
|
8283
|
+
}
|
|
8284
|
+
}
|
|
8285
|
+
function getStatusBadgeClasses2(status, isComplete) {
|
|
8286
|
+
if (isComplete) {
|
|
8287
|
+
return "border-green-500 text-green-600 bg-green-50 dark:bg-green-950/50";
|
|
8288
|
+
}
|
|
8289
|
+
switch (status) {
|
|
8290
|
+
case "on-time":
|
|
8291
|
+
return "border-muted-foreground/50 text-muted-foreground bg-muted/50";
|
|
8292
|
+
// Grey for on-track
|
|
8293
|
+
case "delayed":
|
|
8294
|
+
return "border-amber-500 text-amber-600 bg-amber-50 dark:bg-amber-950/50";
|
|
8295
|
+
case "critical":
|
|
8296
|
+
return "";
|
|
8297
|
+
default:
|
|
8298
|
+
return "border-muted-foreground/50 text-muted-foreground";
|
|
8299
|
+
}
|
|
8300
|
+
}
|
|
8301
|
+
function getStatusLabel2(status, isComplete) {
|
|
8302
|
+
if (isComplete) return "Complete";
|
|
8303
|
+
switch (status) {
|
|
8304
|
+
case "on-time":
|
|
8305
|
+
return "On Track";
|
|
8306
|
+
case "delayed":
|
|
8307
|
+
return "At Risk";
|
|
8308
|
+
case "critical":
|
|
8309
|
+
return "Critical";
|
|
8310
|
+
case "pending":
|
|
8311
|
+
return "Pending";
|
|
8312
|
+
default:
|
|
8313
|
+
return status;
|
|
8314
|
+
}
|
|
8315
|
+
}
|
|
8316
|
+
function getShipmentStatusBadgeClasses2(status) {
|
|
8317
|
+
switch (status) {
|
|
8318
|
+
case "sent":
|
|
8319
|
+
return "border-green-500 text-green-600 bg-green-50 dark:bg-green-950/50";
|
|
8320
|
+
case "not-sent":
|
|
8321
|
+
return "border-muted-foreground/50 text-muted-foreground bg-muted/50";
|
|
8322
|
+
case "moved":
|
|
8323
|
+
return "border-blue-500 text-blue-600 bg-blue-50 dark:bg-blue-950/50";
|
|
8324
|
+
case "addon":
|
|
8325
|
+
return "border-purple-500 text-purple-600 bg-purple-50 dark:bg-purple-950/50";
|
|
8326
|
+
case "planned":
|
|
8327
|
+
default:
|
|
8328
|
+
return "border-muted-foreground/50 text-muted-foreground";
|
|
8329
|
+
}
|
|
8330
|
+
}
|
|
8331
|
+
function getShipmentStatusRowBg2(status) {
|
|
8332
|
+
switch (status) {
|
|
8333
|
+
case "sent":
|
|
8334
|
+
return "bg-green-50/30 dark:bg-green-950/10";
|
|
8335
|
+
case "not-sent":
|
|
8336
|
+
return "bg-muted/30";
|
|
8337
|
+
case "moved":
|
|
8338
|
+
return "bg-blue-50/30 dark:bg-blue-950/10";
|
|
8339
|
+
case "addon":
|
|
8340
|
+
return "bg-purple-50/30 dark:bg-purple-950/10";
|
|
8341
|
+
default:
|
|
8342
|
+
return "";
|
|
8343
|
+
}
|
|
8344
|
+
}
|
|
8345
|
+
function ElementProductionDialog({
|
|
8346
|
+
open,
|
|
8347
|
+
onOpenChange,
|
|
8348
|
+
elements,
|
|
8349
|
+
onSave
|
|
8108
8350
|
}) {
|
|
8109
|
-
const
|
|
8110
|
-
|
|
8111
|
-
|
|
8112
|
-
|
|
8113
|
-
|
|
8114
|
-
|
|
8115
|
-
|
|
8116
|
-
|
|
8117
|
-
|
|
8118
|
-
|
|
8119
|
-
|
|
8120
|
-
|
|
8121
|
-
|
|
8122
|
-
|
|
8123
|
-
|
|
8124
|
-
|
|
8125
|
-
|
|
8126
|
-
|
|
8351
|
+
const [searchQuery, setSearchQuery] = React29.useState("");
|
|
8352
|
+
const [selectedIds, setSelectedIds] = React29.useState(
|
|
8353
|
+
new Set(elements.filter((e) => e.isProduced).map((e) => e.id))
|
|
8354
|
+
);
|
|
8355
|
+
React29.useEffect(() => {
|
|
8356
|
+
if (open) {
|
|
8357
|
+
setSelectedIds(new Set(elements.filter((e) => e.isProduced).map((e) => e.id)));
|
|
8358
|
+
setSearchQuery("");
|
|
8359
|
+
}
|
|
8360
|
+
}, [open, elements]);
|
|
8361
|
+
const filteredElements = React29.useMemo(() => {
|
|
8362
|
+
if (!searchQuery.trim()) return elements;
|
|
8363
|
+
const query = searchQuery.toLowerCase();
|
|
8364
|
+
return elements.filter(
|
|
8365
|
+
(e) => e.name.toLowerCase().includes(query) || e.prefix?.toLowerCase().includes(query) || e.type?.toLowerCase().includes(query)
|
|
8366
|
+
);
|
|
8367
|
+
}, [elements, searchQuery]);
|
|
8368
|
+
React29.useMemo(() => {
|
|
8369
|
+
const prefixes = /* @__PURE__ */ new Set();
|
|
8370
|
+
elements.forEach((e) => {
|
|
8371
|
+
if (e.prefix) prefixes.add(e.prefix);
|
|
8372
|
+
});
|
|
8373
|
+
return Array.from(prefixes).sort();
|
|
8374
|
+
}, [elements]);
|
|
8375
|
+
const toggleElement = (id) => {
|
|
8376
|
+
setSelectedIds((prev) => {
|
|
8377
|
+
const next = new Set(prev);
|
|
8378
|
+
if (next.has(id)) {
|
|
8379
|
+
next.delete(id);
|
|
8380
|
+
} else {
|
|
8381
|
+
next.add(id);
|
|
8382
|
+
}
|
|
8383
|
+
return next;
|
|
8384
|
+
});
|
|
8385
|
+
};
|
|
8386
|
+
const selectAll = () => {
|
|
8387
|
+
setSelectedIds(new Set(filteredElements.map((e) => e.id)));
|
|
8388
|
+
};
|
|
8389
|
+
const deselectAll = () => {
|
|
8390
|
+
setSelectedIds(/* @__PURE__ */ new Set());
|
|
8391
|
+
};
|
|
8392
|
+
const handleSave = () => {
|
|
8393
|
+
onSave(Array.from(selectedIds));
|
|
8394
|
+
onOpenChange(false);
|
|
8395
|
+
};
|
|
8396
|
+
const selectedCount = selectedIds.size;
|
|
8397
|
+
const totalCount = elements.length;
|
|
8398
|
+
const selectedWeight = elements.filter((e) => selectedIds.has(e.id)).reduce((sum, e) => sum + (e.weight ?? 0), 0);
|
|
8399
|
+
const totalWeight = elements.reduce((sum, e) => sum + (e.weight ?? 0), 0);
|
|
8400
|
+
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-fit max-w-[950px] w-fit max-h-[85vh] flex flex-col gap-0 p-0 overflow-hidden", children: [
|
|
8401
|
+
/* @__PURE__ */ jsxs(DialogHeader, { className: "w-full p-6 pb-0 shrink-0", children: [
|
|
8402
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: "Enter production progress" }),
|
|
8403
|
+
/* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
|
|
8404
|
+
"Mark elements as produced (",
|
|
8405
|
+
selectedCount,
|
|
8406
|
+
" / ",
|
|
8407
|
+
totalCount,
|
|
8408
|
+
" selected)"
|
|
8409
|
+
] })
|
|
8410
|
+
] }),
|
|
8411
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-h-0 flex flex-col p-6 pt-4 gap-4 overflow-hidden w-fit", children: [
|
|
8412
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col sm:flex-row gap-3 shrink-0", children: [
|
|
8413
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex-1", children: [
|
|
8414
|
+
/* @__PURE__ */ jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" }),
|
|
8415
|
+
/* @__PURE__ */ jsx(
|
|
8416
|
+
Input,
|
|
8127
8417
|
{
|
|
8128
|
-
|
|
8129
|
-
|
|
8130
|
-
|
|
8131
|
-
|
|
8132
|
-
"Paint"
|
|
8133
|
-
]
|
|
8418
|
+
placeholder: "Search elements...",
|
|
8419
|
+
value: searchQuery,
|
|
8420
|
+
onChange: (e) => setSearchQuery(e.target.value),
|
|
8421
|
+
className: "pl-9 w-full"
|
|
8134
8422
|
}
|
|
8135
8423
|
)
|
|
8136
8424
|
] }),
|
|
8137
|
-
|
|
8138
|
-
/* @__PURE__ */ jsx(
|
|
8139
|
-
|
|
8425
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
8426
|
+
/* @__PURE__ */ jsx(
|
|
8427
|
+
Button,
|
|
8140
8428
|
{
|
|
8141
|
-
|
|
8142
|
-
|
|
8429
|
+
variant: "outline",
|
|
8430
|
+
size: "sm",
|
|
8431
|
+
onClick: selectAll,
|
|
8432
|
+
children: "Select all"
|
|
8433
|
+
}
|
|
8434
|
+
),
|
|
8435
|
+
/* @__PURE__ */ jsx(
|
|
8436
|
+
Button,
|
|
8437
|
+
{
|
|
8438
|
+
variant: "outline",
|
|
8439
|
+
size: "sm",
|
|
8440
|
+
onClick: deselectAll,
|
|
8441
|
+
children: "Deselect all"
|
|
8442
|
+
}
|
|
8443
|
+
)
|
|
8444
|
+
] })
|
|
8445
|
+
] }),
|
|
8446
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-h-0 rounded-lg border bg-card overflow-hidden", children: filteredElements.length > 0 ? /* @__PURE__ */ jsx(ScrollArea, { className: "h-full w-fit", children: /* @__PURE__ */ jsxs(Table, { children: [
|
|
8447
|
+
/* @__PURE__ */ jsx(TableHeader, { className: "sticky top-0 z-10", children: /* @__PURE__ */ jsxs(TableRow, { className: "bg-muted/50 hover:bg-muted/50", children: [
|
|
8448
|
+
/* @__PURE__ */ jsx(TableHead, { className: "w-[44px] bg-muted/50", children: /* @__PURE__ */ jsx(
|
|
8449
|
+
Checkbox,
|
|
8450
|
+
{
|
|
8451
|
+
checked: selectedIds.size === filteredElements.length && filteredElements.length > 0,
|
|
8452
|
+
onCheckedChange: (checked) => {
|
|
8453
|
+
if (checked) {
|
|
8454
|
+
selectAll();
|
|
8455
|
+
} else {
|
|
8456
|
+
deselectAll();
|
|
8457
|
+
}
|
|
8458
|
+
},
|
|
8459
|
+
"aria-label": "Select all elements"
|
|
8143
8460
|
}
|
|
8144
8461
|
) }),
|
|
8145
|
-
/* @__PURE__ */
|
|
8146
|
-
|
|
8462
|
+
/* @__PURE__ */ jsx(TableHead, { className: "bg-muted/50", children: "Element" }),
|
|
8463
|
+
/* @__PURE__ */ jsx(TableHead, { className: "bg-muted/50 w-[80px]", children: "Type" }),
|
|
8464
|
+
/* @__PURE__ */ jsx(TableHead, { className: "bg-muted/50 text-right w-[90px]", children: "Weight" }),
|
|
8465
|
+
/* @__PURE__ */ jsx(TableHead, { className: "bg-muted/50 text-right w-[80px]", children: "Size" }),
|
|
8466
|
+
/* @__PURE__ */ jsx(TableHead, { className: "bg-muted/50 text-center w-[100px]", children: "Status" })
|
|
8467
|
+
] }) }),
|
|
8468
|
+
/* @__PURE__ */ jsx(TableBody, { children: filteredElements.map((element) => {
|
|
8469
|
+
const isSelected = selectedIds.has(element.id);
|
|
8470
|
+
return /* @__PURE__ */ jsxs(
|
|
8471
|
+
TableRow,
|
|
8472
|
+
{
|
|
8473
|
+
className: cn(
|
|
8474
|
+
"cursor-pointer transition-colors",
|
|
8475
|
+
isSelected && "bg-green-50/50 dark:bg-green-950/20"
|
|
8476
|
+
),
|
|
8477
|
+
onClick: () => toggleElement(element.id),
|
|
8478
|
+
children: [
|
|
8479
|
+
/* @__PURE__ */ jsx(TableCell, { className: "w-[44px]", children: /* @__PURE__ */ jsx(
|
|
8480
|
+
Checkbox,
|
|
8481
|
+
{
|
|
8482
|
+
checked: isSelected,
|
|
8483
|
+
onCheckedChange: () => toggleElement(element.id),
|
|
8484
|
+
onClick: (e) => e.stopPropagation(),
|
|
8485
|
+
"aria-label": `Mark ${element.name} as produced`
|
|
8486
|
+
}
|
|
8487
|
+
) }),
|
|
8488
|
+
/* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
8489
|
+
element.prefix && /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "text-[10px] h-5 shrink-0 font-mono", children: element.prefix }),
|
|
8490
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: element.name })
|
|
8491
|
+
] }) }),
|
|
8492
|
+
/* @__PURE__ */ jsx(TableCell, { className: "text-muted-foreground w-[80px]", children: element.type || "\u2014" }),
|
|
8493
|
+
/* @__PURE__ */ jsx(TableCell, { className: "text-right tabular-nums text-muted-foreground w-[90px]", children: element.weight != null ? `${element.weight.toLocaleString()} kg` : "\u2014" }),
|
|
8494
|
+
/* @__PURE__ */ jsx(TableCell, { className: "text-right tabular-nums text-muted-foreground w-[80px]", children: element.size != null ? `${element.size.toLocaleString()} ${element.sizeUnit || "sqm"}` : "\u2014" }),
|
|
8495
|
+
/* @__PURE__ */ jsx(TableCell, { className: "text-center w-[100px]", children: isSelected ? /* @__PURE__ */ jsxs(
|
|
8496
|
+
Badge,
|
|
8497
|
+
{
|
|
8498
|
+
variant: "outline",
|
|
8499
|
+
className: "border-green-500 text-green-600 bg-green-50 dark:bg-green-950/50",
|
|
8500
|
+
children: [
|
|
8501
|
+
/* @__PURE__ */ jsx(Check, { className: "h-3 w-3 mr-1" }),
|
|
8502
|
+
"Produced"
|
|
8503
|
+
]
|
|
8504
|
+
}
|
|
8505
|
+
) : /* @__PURE__ */ jsx(
|
|
8506
|
+
Badge,
|
|
8507
|
+
{
|
|
8508
|
+
variant: "outline",
|
|
8509
|
+
className: "border-muted-foreground/50 text-muted-foreground",
|
|
8510
|
+
children: "Not produced"
|
|
8511
|
+
}
|
|
8512
|
+
) })
|
|
8513
|
+
]
|
|
8514
|
+
},
|
|
8515
|
+
element.id
|
|
8516
|
+
);
|
|
8517
|
+
}) })
|
|
8518
|
+
] }) }) : /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center h-full min-h-[200px] text-muted-foreground", children: /* @__PURE__ */ jsxs("div", { className: "text-center py-12", children: [
|
|
8519
|
+
/* @__PURE__ */ jsx(Package, { className: "h-10 w-10 mx-auto mb-3 opacity-50" }),
|
|
8520
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: "No elements found" }),
|
|
8521
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground mt-1", children: "Try adjusting your search" })
|
|
8522
|
+
] }) }) })
|
|
8523
|
+
] }),
|
|
8524
|
+
/* @__PURE__ */ jsx(DialogFooter, { className: "w-full p-6 pt-4 border-t shrink-0", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between w-full gap-4", children: [
|
|
8525
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 text-sm text-muted-foreground", children: [
|
|
8526
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
8527
|
+
selectedCount,
|
|
8528
|
+
" / ",
|
|
8529
|
+
totalCount,
|
|
8530
|
+
" elements"
|
|
8531
|
+
] }),
|
|
8532
|
+
totalWeight > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8533
|
+
/* @__PURE__ */ jsx("span", { children: "\u2022" }),
|
|
8534
|
+
/* @__PURE__ */ jsxs("span", { className: "tabular-nums font-medium text-foreground", children: [
|
|
8535
|
+
(selectedWeight / 1e3).toLocaleString(void 0, { maximumFractionDigits: 1 }),
|
|
8147
8536
|
" / ",
|
|
8148
|
-
|
|
8149
|
-
"
|
|
8537
|
+
(totalWeight / 1e3).toLocaleString(void 0, { maximumFractionDigits: 1 }),
|
|
8538
|
+
" ton"
|
|
8150
8539
|
] })
|
|
8151
8540
|
] })
|
|
8152
|
-
]
|
|
8153
|
-
|
|
8154
|
-
|
|
8155
|
-
}
|
|
8541
|
+
] }),
|
|
8542
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
8543
|
+
/* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () => onOpenChange(false), children: "Cancel" }),
|
|
8544
|
+
/* @__PURE__ */ jsx(Button, { onClick: handleSave, children: "Save progress" })
|
|
8545
|
+
] })
|
|
8546
|
+
] }) })
|
|
8547
|
+
] }) });
|
|
8548
|
+
}
|
|
8549
|
+
function DeliveryCommentPopover2({
|
|
8550
|
+
comments = [],
|
|
8551
|
+
onAddComment,
|
|
8552
|
+
deliveryLabel
|
|
8553
|
+
}) {
|
|
8554
|
+
const [open, setOpen] = React29.useState(false);
|
|
8555
|
+
const [newCommentText, setNewCommentText] = React29.useState("");
|
|
8556
|
+
const [viewCommentsOpen, setViewCommentsOpen] = React29.useState(true);
|
|
8557
|
+
const [showAddForm, setShowAddForm] = React29.useState(false);
|
|
8558
|
+
const handleSubmit = () => {
|
|
8559
|
+
if (newCommentText.trim() && onAddComment) {
|
|
8560
|
+
onAddComment(newCommentText.trim());
|
|
8561
|
+
setNewCommentText("");
|
|
8562
|
+
setShowAddForm(false);
|
|
8563
|
+
setViewCommentsOpen(true);
|
|
8564
|
+
}
|
|
8565
|
+
};
|
|
8566
|
+
const handleKeyDown = (e) => {
|
|
8567
|
+
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
|
|
8568
|
+
e.preventDefault();
|
|
8569
|
+
handleSubmit();
|
|
8570
|
+
}
|
|
8571
|
+
if (e.key === "Escape") {
|
|
8572
|
+
setShowAddForm(false);
|
|
8573
|
+
setNewCommentText("");
|
|
8574
|
+
}
|
|
8575
|
+
};
|
|
8576
|
+
const formatDate3 = (date) => {
|
|
8577
|
+
return new Intl.DateTimeFormat("en-US", {
|
|
8578
|
+
month: "short",
|
|
8579
|
+
day: "numeric",
|
|
8580
|
+
hour: "numeric",
|
|
8581
|
+
minute: "2-digit"
|
|
8582
|
+
}).format(date);
|
|
8583
|
+
};
|
|
8584
|
+
React29.useEffect(() => {
|
|
8585
|
+
if (!open) {
|
|
8586
|
+
setShowAddForm(false);
|
|
8587
|
+
setNewCommentText("");
|
|
8588
|
+
}
|
|
8589
|
+
}, [open]);
|
|
8590
|
+
return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
|
|
8591
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(CommentButton, { size: "sm", commentCount: comments.length }) }),
|
|
8592
|
+
/* @__PURE__ */ jsxs(
|
|
8593
|
+
PopoverContent,
|
|
8594
|
+
{
|
|
8595
|
+
className: "w-80 p-0 z-[100]",
|
|
8596
|
+
align: "end",
|
|
8597
|
+
sideOffset: 8,
|
|
8598
|
+
collisionPadding: 16,
|
|
8599
|
+
children: [
|
|
8600
|
+
/* @__PURE__ */ jsxs("div", { className: "px-4 py-3 border-b border-border", children: [
|
|
8601
|
+
/* @__PURE__ */ jsx("h4", { className: "text-sm font-semibold", children: "Comments" }),
|
|
8602
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: deliveryLabel })
|
|
8603
|
+
] }),
|
|
8604
|
+
/* @__PURE__ */ jsxs("div", { className: "p-2 space-y-2 h-fit overflow-y-auto", children: [
|
|
8605
|
+
/* @__PURE__ */ jsxs(Collapsible, { open: viewCommentsOpen, onOpenChange: setViewCommentsOpen, children: [
|
|
8606
|
+
/* @__PURE__ */ jsx(CollapsibleTrigger2, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "sm", className: "w-full justify-between h-8 px-2", children: [
|
|
8607
|
+
/* @__PURE__ */ jsxs("span", { className: "text-xs font-medium", children: [
|
|
8608
|
+
"Comments ",
|
|
8609
|
+
comments.length > 0 && `(${comments.length})`
|
|
8610
|
+
] }),
|
|
8611
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: cn(
|
|
8612
|
+
"h-4 w-4 transition-transform duration-200",
|
|
8613
|
+
viewCommentsOpen && "rotate-180"
|
|
8614
|
+
) })
|
|
8615
|
+
] }) }),
|
|
8616
|
+
/* @__PURE__ */ jsx(CollapsibleContent2, { className: "space-y-2 pt-2", children: comments.length > 0 ? comments.map((comment) => /* @__PURE__ */ jsxs("div", { className: "rounded-lg bg-muted/50 p-3 space-y-2", children: [
|
|
8617
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
8618
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium", children: comment.author }),
|
|
8619
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground", children: formatDate3(comment.createdAt) })
|
|
8620
|
+
] }),
|
|
8621
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-foreground", children: comment.text })
|
|
8622
|
+
] }, comment.id)) : /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground text-center py-2", children: "No comments yet" }) })
|
|
8623
|
+
] }),
|
|
8624
|
+
/* @__PURE__ */ jsx(Separator, { className: "my-2" }),
|
|
8625
|
+
!showAddForm ? /* @__PURE__ */ jsxs(
|
|
8626
|
+
Button,
|
|
8627
|
+
{
|
|
8628
|
+
variant: "outline",
|
|
8629
|
+
size: "sm",
|
|
8630
|
+
className: "w-full justify-center gap-2 h-8",
|
|
8631
|
+
onClick: () => setShowAddForm(true),
|
|
8632
|
+
children: [
|
|
8633
|
+
/* @__PURE__ */ jsx(Plus, { className: "h-3.5 w-3.5" }),
|
|
8634
|
+
"Add comment"
|
|
8635
|
+
]
|
|
8636
|
+
}
|
|
8637
|
+
) : /* @__PURE__ */ jsxs("div", { className: cn(
|
|
8638
|
+
"space-y-3 p-3 rounded-lg border border-border bg-muted/30",
|
|
8639
|
+
"animate-in fade-in-0 slide-in-from-top-2 duration-200"
|
|
8640
|
+
), children: [
|
|
8641
|
+
/* @__PURE__ */ jsx(
|
|
8642
|
+
Textarea,
|
|
8643
|
+
{
|
|
8644
|
+
placeholder: "Type your comment...",
|
|
8645
|
+
value: newCommentText,
|
|
8646
|
+
onChange: (e) => setNewCommentText(e.target.value),
|
|
8647
|
+
onKeyDown: handleKeyDown,
|
|
8648
|
+
className: "min-h-[80px] text-sm resize-none",
|
|
8649
|
+
autoFocus: true
|
|
8650
|
+
}
|
|
8651
|
+
),
|
|
8652
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
8653
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground", children: "\u2318+Enter to send \xB7 Esc to cancel" }),
|
|
8654
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
8655
|
+
/* @__PURE__ */ jsx(
|
|
8656
|
+
Button,
|
|
8657
|
+
{
|
|
8658
|
+
variant: "ghost",
|
|
8659
|
+
size: "sm",
|
|
8660
|
+
className: "h-7",
|
|
8661
|
+
onClick: () => {
|
|
8662
|
+
setShowAddForm(false);
|
|
8663
|
+
setNewCommentText("");
|
|
8664
|
+
},
|
|
8665
|
+
children: "Cancel"
|
|
8666
|
+
}
|
|
8667
|
+
),
|
|
8668
|
+
/* @__PURE__ */ jsxs(
|
|
8669
|
+
Button,
|
|
8670
|
+
{
|
|
8671
|
+
size: "sm",
|
|
8672
|
+
className: "h-7 gap-1",
|
|
8673
|
+
onClick: handleSubmit,
|
|
8674
|
+
disabled: !newCommentText.trim(),
|
|
8675
|
+
children: [
|
|
8676
|
+
/* @__PURE__ */ jsx(Send, { className: "h-3 w-3" }),
|
|
8677
|
+
"Save"
|
|
8678
|
+
]
|
|
8679
|
+
}
|
|
8680
|
+
)
|
|
8681
|
+
] })
|
|
8682
|
+
] })
|
|
8683
|
+
] })
|
|
8684
|
+
] })
|
|
8685
|
+
]
|
|
8686
|
+
}
|
|
8687
|
+
)
|
|
8688
|
+
] });
|
|
8689
|
+
}
|
|
8690
|
+
function ProductionCommentSection2({
|
|
8691
|
+
comments = [],
|
|
8692
|
+
onAddComment
|
|
8693
|
+
}) {
|
|
8694
|
+
const [showAddForm, setShowAddForm] = React29.useState(false);
|
|
8695
|
+
const [newComment, setNewComment] = React29.useState("");
|
|
8696
|
+
const handleSubmit = () => {
|
|
8697
|
+
if (newComment.trim() && onAddComment) {
|
|
8698
|
+
onAddComment(newComment.trim());
|
|
8699
|
+
setNewComment("");
|
|
8700
|
+
setShowAddForm(false);
|
|
8701
|
+
}
|
|
8702
|
+
};
|
|
8703
|
+
const handleKeyDown = (e) => {
|
|
8704
|
+
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
|
|
8705
|
+
e.preventDefault();
|
|
8706
|
+
handleSubmit();
|
|
8707
|
+
}
|
|
8708
|
+
if (e.key === "Escape") {
|
|
8709
|
+
setShowAddForm(false);
|
|
8710
|
+
setNewComment("");
|
|
8711
|
+
}
|
|
8712
|
+
};
|
|
8713
|
+
const formatDate3 = (date) => {
|
|
8714
|
+
return new Intl.DateTimeFormat("en-US", {
|
|
8715
|
+
month: "short",
|
|
8716
|
+
day: "numeric",
|
|
8717
|
+
hour: "numeric",
|
|
8718
|
+
minute: "2-digit"
|
|
8719
|
+
}).format(date);
|
|
8720
|
+
};
|
|
8721
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
8722
|
+
comments.length > 0 && /* @__PURE__ */ jsx("div", { className: "space-y-2", children: comments.map((comment) => /* @__PURE__ */ jsxs("div", { className: "rounded-lg bg-muted/50 p-2.5 space-y-1", children: [
|
|
8723
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
8724
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium", children: comment.author }),
|
|
8725
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground", children: formatDate3(comment.createdAt) })
|
|
8726
|
+
] }),
|
|
8727
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm text-foreground", children: comment.text })
|
|
8728
|
+
] }, comment.id)) }),
|
|
8729
|
+
!showAddForm ? /* @__PURE__ */ jsxs(
|
|
8730
|
+
Button,
|
|
8731
|
+
{
|
|
8732
|
+
variant: "ghost",
|
|
8733
|
+
size: "sm",
|
|
8734
|
+
className: "w-full justify-start gap-2 h-8 text-muted-foreground",
|
|
8735
|
+
onClick: () => setShowAddForm(true),
|
|
8736
|
+
children: [
|
|
8737
|
+
/* @__PURE__ */ jsx(MessageSquare, { className: "h-3.5 w-3.5" }),
|
|
8738
|
+
comments.length > 0 ? "Add another comment" : "Add a comment..."
|
|
8739
|
+
]
|
|
8740
|
+
}
|
|
8741
|
+
) : /* @__PURE__ */ jsxs("div", { className: "space-y-2 animate-in fade-in-0 slide-in-from-top-2 duration-200", children: [
|
|
8742
|
+
/* @__PURE__ */ jsx(
|
|
8743
|
+
Textarea,
|
|
8744
|
+
{
|
|
8745
|
+
placeholder: "Add a comment...",
|
|
8746
|
+
value: newComment,
|
|
8747
|
+
onChange: (e) => setNewComment(e.target.value),
|
|
8748
|
+
onKeyDown: handleKeyDown,
|
|
8749
|
+
className: "min-h-[60px] text-sm resize-none",
|
|
8750
|
+
autoFocus: true
|
|
8751
|
+
}
|
|
8752
|
+
),
|
|
8753
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
8754
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground", children: "\u2318+Enter to send" }),
|
|
8755
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
8756
|
+
/* @__PURE__ */ jsx(
|
|
8757
|
+
Button,
|
|
8758
|
+
{
|
|
8759
|
+
variant: "ghost",
|
|
8760
|
+
size: "sm",
|
|
8761
|
+
className: "h-7",
|
|
8762
|
+
onClick: () => {
|
|
8763
|
+
setShowAddForm(false);
|
|
8764
|
+
setNewComment("");
|
|
8765
|
+
},
|
|
8766
|
+
children: "Cancel"
|
|
8767
|
+
}
|
|
8768
|
+
),
|
|
8769
|
+
/* @__PURE__ */ jsxs(
|
|
8770
|
+
Button,
|
|
8771
|
+
{
|
|
8772
|
+
size: "sm",
|
|
8773
|
+
className: "h-7 gap-1",
|
|
8774
|
+
onClick: handleSubmit,
|
|
8775
|
+
disabled: !newComment.trim(),
|
|
8776
|
+
children: [
|
|
8777
|
+
/* @__PURE__ */ jsx(Send, { className: "h-3 w-3" }),
|
|
8778
|
+
"Save"
|
|
8779
|
+
]
|
|
8780
|
+
}
|
|
8781
|
+
)
|
|
8782
|
+
] })
|
|
8783
|
+
] })
|
|
8784
|
+
] })
|
|
8785
|
+
] });
|
|
8786
|
+
}
|
|
8787
|
+
function DeliveryListItem2({
|
|
8788
|
+
delivery,
|
|
8789
|
+
index,
|
|
8790
|
+
onClick
|
|
8791
|
+
}) {
|
|
8792
|
+
const hasComments = (delivery.comments?.length ?? 0) > 0;
|
|
8793
|
+
const isComplete = (delivery.progress ?? 0) >= 100;
|
|
8794
|
+
const getIconStyles = () => {
|
|
8795
|
+
if (delivery.status === "critical") {
|
|
8796
|
+
return { bg: "bg-red-100 dark:bg-red-950/50", icon: "text-red-600 dark:text-red-400" };
|
|
8797
|
+
}
|
|
8798
|
+
if (delivery.status === "delayed") {
|
|
8799
|
+
return { bg: "bg-amber-100 dark:bg-amber-950/50", icon: "text-amber-600 dark:text-amber-400" };
|
|
8800
|
+
}
|
|
8801
|
+
if (isComplete) {
|
|
8802
|
+
return { bg: "bg-green-100 dark:bg-green-950/50", icon: "text-green-600 dark:text-green-400" };
|
|
8803
|
+
}
|
|
8804
|
+
return { bg: "bg-muted", icon: "text-muted-foreground" };
|
|
8805
|
+
};
|
|
8806
|
+
const iconStyles = getIconStyles();
|
|
8807
|
+
return /* @__PURE__ */ jsxs(
|
|
8808
|
+
"button",
|
|
8809
|
+
{
|
|
8810
|
+
onClick,
|
|
8811
|
+
className: cn(
|
|
8812
|
+
"w-full flex items-center justify-between p-3 rounded-lg",
|
|
8813
|
+
"bg-card border hover:bg-muted/50 transition-colors cursor-pointer",
|
|
8814
|
+
"text-left"
|
|
8815
|
+
),
|
|
8816
|
+
children: [
|
|
8817
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
8818
|
+
/* @__PURE__ */ jsx("div", { className: cn(
|
|
8819
|
+
"flex items-center justify-center h-8 w-8 rounded-lg",
|
|
8820
|
+
iconStyles.bg
|
|
8821
|
+
), children: /* @__PURE__ */ jsx(Truck, { className: cn("h-4 w-4", iconStyles.icon) }) }),
|
|
8822
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
8823
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
8824
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: delivery.label || `Delivery ${index + 1}` }),
|
|
8825
|
+
hasComments && /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
8826
|
+
/* @__PURE__ */ jsx(MessageSquare, { className: "h-3 w-3 text-muted-foreground" }),
|
|
8827
|
+
/* @__PURE__ */ jsx("span", { className: "absolute -top-0.5 -right-0.5 h-1.5 w-1.5 rounded-full bg-primary" })
|
|
8828
|
+
] })
|
|
8829
|
+
] }),
|
|
8830
|
+
delivery.destination && /* @__PURE__ */ jsxs("div", { className: "text-xs text-muted-foreground", children: [
|
|
8831
|
+
"\u2192 ",
|
|
8832
|
+
delivery.destination
|
|
8833
|
+
] })
|
|
8834
|
+
] })
|
|
8835
|
+
] }),
|
|
8836
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
8837
|
+
/* @__PURE__ */ jsx(
|
|
8838
|
+
Badge,
|
|
8839
|
+
{
|
|
8840
|
+
variant: getStatusBadgeVariant2(delivery.status, isComplete),
|
|
8841
|
+
className: cn("text-xs", getStatusBadgeClasses2(delivery.status, isComplete)),
|
|
8842
|
+
children: getStatusLabel2(delivery.status, isComplete)
|
|
8843
|
+
}
|
|
8844
|
+
),
|
|
8845
|
+
/* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4 text-muted-foreground" })
|
|
8846
|
+
] })
|
|
8847
|
+
]
|
|
8848
|
+
}
|
|
8849
|
+
);
|
|
8850
|
+
}
|
|
8851
|
+
function DeliveryDetailsView2({
|
|
8852
|
+
delivery,
|
|
8853
|
+
week,
|
|
8854
|
+
onBack,
|
|
8855
|
+
onAddComment
|
|
8856
|
+
}) {
|
|
8857
|
+
const elements = delivery.elements ?? [];
|
|
8858
|
+
const categorizedElements = React29.useMemo(() => {
|
|
8859
|
+
const sent = [];
|
|
8860
|
+
const notSent = [];
|
|
8861
|
+
const moved = [];
|
|
8862
|
+
const addons = [];
|
|
8863
|
+
elements.forEach((element) => {
|
|
8864
|
+
const status = getElementShipmentStatus(element, delivery.id);
|
|
8865
|
+
switch (status) {
|
|
8866
|
+
case "sent":
|
|
8867
|
+
sent.push(element);
|
|
8868
|
+
break;
|
|
8869
|
+
case "not-sent":
|
|
8870
|
+
notSent.push(element);
|
|
8871
|
+
break;
|
|
8872
|
+
case "moved":
|
|
8873
|
+
moved.push(element);
|
|
8874
|
+
break;
|
|
8875
|
+
case "addon":
|
|
8876
|
+
addons.push(element);
|
|
8877
|
+
break;
|
|
8878
|
+
default:
|
|
8879
|
+
notSent.push(element);
|
|
8880
|
+
}
|
|
8881
|
+
});
|
|
8882
|
+
return { sent, notSent, moved, addons };
|
|
8883
|
+
}, [elements, delivery.id]);
|
|
8884
|
+
const totalCount = elements.length;
|
|
8885
|
+
const sentCount = categorizedElements.sent.length;
|
|
8886
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full animate-in slide-in-from-right-4 duration-200", children: [
|
|
8887
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-2 px-4 py-3 border-b", children: /* @__PURE__ */ jsxs(
|
|
8888
|
+
Button,
|
|
8889
|
+
{
|
|
8890
|
+
variant: "ghost",
|
|
8891
|
+
size: "sm",
|
|
8892
|
+
className: "gap-1 -ml-2",
|
|
8893
|
+
onClick: onBack,
|
|
8894
|
+
children: [
|
|
8895
|
+
/* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" }),
|
|
8896
|
+
"Back"
|
|
8897
|
+
]
|
|
8898
|
+
}
|
|
8899
|
+
) }),
|
|
8900
|
+
/* @__PURE__ */ jsxs("div", { className: "px-4 py-4 space-y-2", children: [
|
|
8901
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
8902
|
+
/* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold", children: delivery.label || "Delivery Details" }),
|
|
8903
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
8904
|
+
/* @__PURE__ */ jsx(
|
|
8905
|
+
DeliveryCommentPopover2,
|
|
8906
|
+
{
|
|
8907
|
+
comments: delivery.comments,
|
|
8908
|
+
onAddComment,
|
|
8909
|
+
deliveryLabel: delivery.label || "Delivery"
|
|
8910
|
+
}
|
|
8911
|
+
),
|
|
8912
|
+
/* @__PURE__ */ jsx(
|
|
8913
|
+
Badge,
|
|
8914
|
+
{
|
|
8915
|
+
variant: getStatusBadgeVariant2(delivery.status, sentCount === totalCount && totalCount > 0),
|
|
8916
|
+
className: cn("text-xs", getStatusBadgeClasses2(delivery.status, sentCount === totalCount && totalCount > 0)),
|
|
8917
|
+
children: getStatusLabel2(delivery.status, sentCount === totalCount && totalCount > 0)
|
|
8918
|
+
}
|
|
8919
|
+
)
|
|
8920
|
+
] })
|
|
8921
|
+
] }),
|
|
8922
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 text-sm text-muted-foreground", children: [
|
|
8923
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
8924
|
+
/* @__PURE__ */ jsx(Calendar$1, { className: "h-3.5 w-3.5" }),
|
|
8925
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
8926
|
+
week.label,
|
|
8927
|
+
" \u2022 ",
|
|
8928
|
+
week.dateRange
|
|
8929
|
+
] })
|
|
8930
|
+
] }),
|
|
8931
|
+
delivery.destination && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
8932
|
+
/* @__PURE__ */ jsx(Truck, { className: "h-3.5 w-3.5" }),
|
|
8933
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
8934
|
+
"\u2192 ",
|
|
8935
|
+
delivery.destination
|
|
8936
|
+
] })
|
|
8937
|
+
] })
|
|
8938
|
+
] })
|
|
8939
|
+
] }),
|
|
8940
|
+
/* @__PURE__ */ jsx(ScrollArea, { className: "flex-1 px-4 pb-4", children: /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
|
|
8941
|
+
totalCount > 0 && /* @__PURE__ */ jsxs("div", { className: "rounded-lg bg-muted/50 p-4 space-y-3", children: [
|
|
8942
|
+
/* @__PURE__ */ jsx(
|
|
8943
|
+
StatusProgress,
|
|
8944
|
+
{
|
|
8945
|
+
value: totalCount > 0 ? sentCount / totalCount * 100 : 0,
|
|
8946
|
+
currentCount: sentCount,
|
|
8947
|
+
totalCount,
|
|
8948
|
+
unitLabel: "shipped",
|
|
8949
|
+
showLabel: true,
|
|
8950
|
+
showCheckmark: true,
|
|
8951
|
+
size: "md"
|
|
8952
|
+
}
|
|
8953
|
+
),
|
|
8954
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 flex-wrap", children: [
|
|
8955
|
+
categorizedElements.sent.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [
|
|
8956
|
+
/* @__PURE__ */ jsx(CheckCircle2, { className: "h-3 w-3 text-green-600" }),
|
|
8957
|
+
/* @__PURE__ */ jsxs("span", { className: "text-green-700 dark:text-green-300", children: [
|
|
8958
|
+
categorizedElements.sent.length,
|
|
8959
|
+
" Sent"
|
|
8960
|
+
] })
|
|
8961
|
+
] }),
|
|
8962
|
+
categorizedElements.notSent.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [
|
|
8963
|
+
/* @__PURE__ */ jsx(XCircle, { className: "h-3 w-3 text-muted-foreground" }),
|
|
8964
|
+
/* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
|
|
8965
|
+
categorizedElements.notSent.length,
|
|
8966
|
+
" Missing"
|
|
8967
|
+
] })
|
|
8968
|
+
] }),
|
|
8969
|
+
categorizedElements.moved.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [
|
|
8970
|
+
/* @__PURE__ */ jsx(ArrowRight, { className: "h-3 w-3 text-blue-600" }),
|
|
8971
|
+
/* @__PURE__ */ jsxs("span", { className: "text-blue-700 dark:text-blue-300", children: [
|
|
8972
|
+
categorizedElements.moved.length,
|
|
8973
|
+
" Moved"
|
|
8974
|
+
] })
|
|
8975
|
+
] }),
|
|
8976
|
+
categorizedElements.addons.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [
|
|
8977
|
+
/* @__PURE__ */ jsx(Plus, { className: "h-3 w-3 text-purple-600" }),
|
|
8978
|
+
/* @__PURE__ */ jsxs("span", { className: "text-purple-700 dark:text-purple-300", children: [
|
|
8979
|
+
categorizedElements.addons.length,
|
|
8980
|
+
" Add-on"
|
|
8981
|
+
] })
|
|
8982
|
+
] })
|
|
8983
|
+
] })
|
|
8984
|
+
] }),
|
|
8985
|
+
elements.length > 0 && /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
8986
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: "Elements" }),
|
|
8987
|
+
/* @__PURE__ */ jsx("div", { className: "rounded-lg border overflow-hidden", children: /* @__PURE__ */ jsxs(Table, { children: [
|
|
8988
|
+
/* @__PURE__ */ jsx(TableHeader, { children: /* @__PURE__ */ jsxs(TableRow, { className: "bg-sidebar hover:bg-sidebar", children: [
|
|
8989
|
+
/* @__PURE__ */ jsx(TableHead, { className: "font-semibold", children: "Prefix" }),
|
|
8990
|
+
/* @__PURE__ */ jsx(TableHead, { className: "font-semibold", children: "Type" }),
|
|
8991
|
+
/* @__PURE__ */ jsx(TableHead, { className: "font-semibold text-right", children: "Weight" }),
|
|
8992
|
+
/* @__PURE__ */ jsx(TableHead, { className: "font-semibold text-center", children: "Status" })
|
|
8993
|
+
] }) }),
|
|
8994
|
+
/* @__PURE__ */ jsx(TableBody, { children: elements.map((element) => {
|
|
8995
|
+
const shipmentStatus = getElementShipmentStatus(element, delivery.id);
|
|
8996
|
+
const statusLabel = getShipmentStatusLabel(shipmentStatus);
|
|
8997
|
+
return /* @__PURE__ */ jsxs(
|
|
8998
|
+
TableRow,
|
|
8999
|
+
{
|
|
9000
|
+
className: getShipmentStatusRowBg2(shipmentStatus),
|
|
9001
|
+
children: [
|
|
9002
|
+
/* @__PURE__ */ jsx(TableCell, { className: "font-medium", children: element.prefix || "\u2014" }),
|
|
9003
|
+
/* @__PURE__ */ jsx(TableCell, { children: element.type || element.name || "\u2014" }),
|
|
9004
|
+
/* @__PURE__ */ jsx(TableCell, { className: "text-right tabular-nums", children: element.weight ? `${element.weight} ${element.weightUnit || "kg"}` : "\u2014" }),
|
|
9005
|
+
/* @__PURE__ */ jsx(TableCell, { children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-1", children: [
|
|
9006
|
+
/* @__PURE__ */ jsx(
|
|
9007
|
+
Badge,
|
|
9008
|
+
{
|
|
9009
|
+
variant: "outline",
|
|
9010
|
+
className: cn("text-[10px] h-5", getShipmentStatusBadgeClasses2(shipmentStatus)),
|
|
9011
|
+
children: statusLabel
|
|
9012
|
+
}
|
|
9013
|
+
),
|
|
9014
|
+
shipmentStatus === "moved" && element.actualDeliveryLabel && /* @__PURE__ */ jsxs("span", { className: "text-[9px] text-blue-600 dark:text-blue-400", children: [
|
|
9015
|
+
"\u2192 ",
|
|
9016
|
+
element.actualDeliveryLabel
|
|
9017
|
+
] }),
|
|
9018
|
+
shipmentStatus === "addon" && element.originalDeliveryLabel && /* @__PURE__ */ jsxs("span", { className: "text-[9px] text-purple-600 dark:text-purple-400", children: [
|
|
9019
|
+
"from ",
|
|
9020
|
+
element.originalDeliveryLabel
|
|
9021
|
+
] })
|
|
9022
|
+
] }) })
|
|
9023
|
+
]
|
|
9024
|
+
},
|
|
9025
|
+
element.id
|
|
9026
|
+
);
|
|
9027
|
+
}) })
|
|
9028
|
+
] }) })
|
|
9029
|
+
] }),
|
|
9030
|
+
elements.length === 0 && /* @__PURE__ */ jsxs("div", { className: "text-center py-8 text-muted-foreground", children: [
|
|
9031
|
+
/* @__PURE__ */ jsx(Package, { className: "h-8 w-8 mx-auto mb-2 opacity-50" }),
|
|
9032
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm", children: "No elements in this delivery" })
|
|
9033
|
+
] })
|
|
9034
|
+
] }) })
|
|
9035
|
+
] });
|
|
9036
|
+
}
|
|
9037
|
+
function MainView2({
|
|
9038
|
+
supplier,
|
|
9039
|
+
week,
|
|
9040
|
+
data,
|
|
9041
|
+
productionElements,
|
|
9042
|
+
previousProducedCount,
|
|
9043
|
+
onOpenProductionDialog,
|
|
9044
|
+
onSelectDelivery,
|
|
9045
|
+
onAddProductionComment
|
|
9046
|
+
}) {
|
|
9047
|
+
const production = data?.production;
|
|
9048
|
+
const producedCount = productionElements.filter((e) => e.isProduced).length;
|
|
9049
|
+
const totalCount = productionElements.length;
|
|
9050
|
+
const productionProgress = totalCount > 0 ? Math.round(producedCount / totalCount * 100) : 0;
|
|
9051
|
+
const isComplete = productionProgress >= 100;
|
|
9052
|
+
const hasProductionComments = (production?.comments?.length ?? 0) > 0;
|
|
9053
|
+
const showPreviousProgress = !isComplete && previousProducedCount !== void 0 && previousProducedCount !== producedCount;
|
|
9054
|
+
return /* @__PURE__ */ jsxs("div", { className: "animate-in fade-in-0 duration-200", children: [
|
|
9055
|
+
/* @__PURE__ */ jsxs(SheetHeader, { className: "px-4 pt-4 pb-3 border-b", children: [
|
|
9056
|
+
/* @__PURE__ */ jsxs(SheetTitle, { className: "flex items-center gap-2", children: [
|
|
9057
|
+
supplier.name,
|
|
9058
|
+
/* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs font-normal", children: supplier.badgeType })
|
|
9059
|
+
] }),
|
|
9060
|
+
/* @__PURE__ */ jsxs(SheetDescription, { className: "flex items-center gap-2", children: [
|
|
9061
|
+
/* @__PURE__ */ jsx(Calendar$1, { className: "h-4 w-4" }),
|
|
9062
|
+
week.label,
|
|
9063
|
+
" \u2022 ",
|
|
9064
|
+
week.dateRange
|
|
9065
|
+
] })
|
|
9066
|
+
] }),
|
|
9067
|
+
/* @__PURE__ */ jsx(ScrollArea, { className: "flex-1 px-4 pb-4", children: /* @__PURE__ */ jsxs("div", { className: "space-y-6 pt-4", children: [
|
|
9068
|
+
data.type !== "empty" && /* @__PURE__ */ jsxs("section", { className: "space-y-4", children: [
|
|
9069
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
9070
|
+
/* @__PURE__ */ jsx(Factory, { className: "h-4 w-4 text-muted-foreground" }),
|
|
9071
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: "Production" })
|
|
9072
|
+
] }),
|
|
9073
|
+
totalCount > 0 ? /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
9074
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center py-4", children: [
|
|
9075
|
+
/* @__PURE__ */ jsx(
|
|
9076
|
+
CircularProgress,
|
|
9077
|
+
{
|
|
9078
|
+
value: productionProgress,
|
|
9079
|
+
size: 88,
|
|
9080
|
+
strokeWidth: 8,
|
|
9081
|
+
variant: productionProgress >= 100 ? "success" : productionProgress >= 50 ? "success" : productionProgress > 0 ? "warning" : "destructive",
|
|
9082
|
+
showCheckmark: true,
|
|
9083
|
+
children: productionProgress < 100 && /* @__PURE__ */ jsxs("span", { className: "text-lg font-bold tabular-nums", children: [
|
|
9084
|
+
Math.round(productionProgress),
|
|
9085
|
+
"%"
|
|
9086
|
+
] })
|
|
9087
|
+
}
|
|
9088
|
+
),
|
|
9089
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-3 text-center", children: [
|
|
9090
|
+
/* @__PURE__ */ jsxs("span", { className: "text-sm font-semibold text-foreground", children: [
|
|
9091
|
+
producedCount,
|
|
9092
|
+
" / ",
|
|
9093
|
+
totalCount,
|
|
9094
|
+
" elements"
|
|
9095
|
+
] }),
|
|
9096
|
+
showPreviousProgress && /* @__PURE__ */ jsxs("div", { className: "text-xs text-muted-foreground mt-1", children: [
|
|
9097
|
+
"Previously: ",
|
|
9098
|
+
previousProducedCount,
|
|
9099
|
+
" / ",
|
|
9100
|
+
totalCount
|
|
9101
|
+
] })
|
|
9102
|
+
] })
|
|
9103
|
+
] }),
|
|
9104
|
+
/* @__PURE__ */ jsx(
|
|
9105
|
+
Button,
|
|
9106
|
+
{
|
|
9107
|
+
className: "w-full",
|
|
9108
|
+
onClick: onOpenProductionDialog,
|
|
9109
|
+
children: "Enter production progress"
|
|
9110
|
+
}
|
|
9111
|
+
)
|
|
9112
|
+
] }) : (
|
|
9113
|
+
/* No elements - show placeholder with button still available */
|
|
9114
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
9115
|
+
/* @__PURE__ */ jsxs("div", { className: "text-center py-6 text-muted-foreground bg-muted/30 rounded-lg", children: [
|
|
9116
|
+
/* @__PURE__ */ jsx(Package, { className: "h-8 w-8 mx-auto mb-2 opacity-50" }),
|
|
9117
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm", children: "No elements to track" })
|
|
9118
|
+
] }),
|
|
9119
|
+
/* @__PURE__ */ jsx(
|
|
9120
|
+
Button,
|
|
9121
|
+
{
|
|
9122
|
+
className: "w-full",
|
|
9123
|
+
variant: "outline",
|
|
9124
|
+
onClick: onOpenProductionDialog,
|
|
9125
|
+
children: "Enter production progress"
|
|
9126
|
+
}
|
|
9127
|
+
)
|
|
9128
|
+
] })
|
|
9129
|
+
),
|
|
9130
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
9131
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
9132
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Comments" }),
|
|
9133
|
+
hasProductionComments && /* @__PURE__ */ jsxs("span", { className: "text-[10px] text-muted-foreground", children: [
|
|
9134
|
+
"(",
|
|
9135
|
+
production?.comments?.length,
|
|
9136
|
+
")"
|
|
9137
|
+
] })
|
|
9138
|
+
] }),
|
|
9139
|
+
/* @__PURE__ */ jsx(
|
|
9140
|
+
ProductionCommentSection2,
|
|
9141
|
+
{
|
|
9142
|
+
comments: production?.comments,
|
|
9143
|
+
onAddComment: onAddProductionComment
|
|
9144
|
+
}
|
|
9145
|
+
)
|
|
9146
|
+
] })
|
|
9147
|
+
] }),
|
|
9148
|
+
data.deliveries && data.deliveries.length > 0 && /* @__PURE__ */ jsxs("section", { className: "space-y-4", children: [
|
|
9149
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
9150
|
+
/* @__PURE__ */ jsx(Truck, { className: "h-4 w-4 text-muted-foreground" }),
|
|
9151
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold", children: "Deliveries" }),
|
|
9152
|
+
/* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground ml-auto", children: [
|
|
9153
|
+
data.deliveries.length,
|
|
9154
|
+
" scheduled"
|
|
9155
|
+
] })
|
|
9156
|
+
] }),
|
|
9157
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-2", children: data.deliveries.map((delivery, index) => /* @__PURE__ */ jsx(
|
|
9158
|
+
DeliveryListItem2,
|
|
9159
|
+
{
|
|
9160
|
+
delivery,
|
|
9161
|
+
index,
|
|
9162
|
+
onClick: () => onSelectDelivery(delivery)
|
|
9163
|
+
},
|
|
9164
|
+
delivery.id
|
|
9165
|
+
)) })
|
|
9166
|
+
] }),
|
|
9167
|
+
data.type === "no-logistics" && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-muted-foreground p-3 bg-muted/50 rounded-lg", children: [
|
|
9168
|
+
/* @__PURE__ */ jsx(Truck, { className: "h-4 w-4" }),
|
|
9169
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm", children: "No logistics scheduled for this week" })
|
|
9170
|
+
] }),
|
|
9171
|
+
data.hasWarning && data.warningMessage && /* @__PURE__ */ 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: [
|
|
9172
|
+
/* @__PURE__ */ jsx(AlertTriangle, { className: "h-4 w-4 mt-0.5 shrink-0" }),
|
|
9173
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm", children: data.warningMessage })
|
|
9174
|
+
] }),
|
|
9175
|
+
data.notes && /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
9176
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "Notes" }),
|
|
9177
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm", children: data.notes })
|
|
9178
|
+
] })
|
|
9179
|
+
] }) })
|
|
9180
|
+
] });
|
|
9181
|
+
}
|
|
9182
|
+
function WeekDetailSheet({
|
|
9183
|
+
open,
|
|
9184
|
+
onOpenChange,
|
|
9185
|
+
supplier,
|
|
9186
|
+
week,
|
|
9187
|
+
data,
|
|
9188
|
+
onProductionUpdate,
|
|
9189
|
+
onAddProductionComment,
|
|
9190
|
+
onAddDeliveryComment
|
|
9191
|
+
}) {
|
|
9192
|
+
const [selectedDelivery, setSelectedDelivery] = React29.useState(null);
|
|
9193
|
+
const [productionDialogOpen, setProductionDialogOpen] = React29.useState(false);
|
|
9194
|
+
const [previousProducedCount, setPreviousProducedCount] = React29.useState(void 0);
|
|
9195
|
+
const productionElements = React29.useMemo(() => {
|
|
9196
|
+
if (!data?.deliveries) return [];
|
|
9197
|
+
const elements = [];
|
|
9198
|
+
const seenIds = /* @__PURE__ */ new Set();
|
|
9199
|
+
data.deliveries.forEach((delivery) => {
|
|
9200
|
+
delivery.elements?.forEach((element) => {
|
|
9201
|
+
if (!seenIds.has(element.id)) {
|
|
9202
|
+
seenIds.add(element.id);
|
|
9203
|
+
elements.push({
|
|
9204
|
+
id: element.id,
|
|
9205
|
+
name: element.name,
|
|
9206
|
+
prefix: element.prefix,
|
|
9207
|
+
type: element.type,
|
|
9208
|
+
weight: element.weight,
|
|
9209
|
+
size: element.sizeSqm,
|
|
9210
|
+
sizeUnit: "sqm",
|
|
9211
|
+
isProduced: element.isProduced
|
|
9212
|
+
});
|
|
9213
|
+
}
|
|
9214
|
+
});
|
|
9215
|
+
});
|
|
9216
|
+
return elements;
|
|
9217
|
+
}, [data?.deliveries]);
|
|
9218
|
+
const currentProducedCount = productionElements.filter((e) => e.isProduced).length;
|
|
9219
|
+
React29.useEffect(() => {
|
|
9220
|
+
if (open && data?.deliveries) {
|
|
9221
|
+
setPreviousProducedCount(currentProducedCount);
|
|
9222
|
+
}
|
|
9223
|
+
}, [open]);
|
|
9224
|
+
React29.useEffect(() => {
|
|
9225
|
+
if (!open) {
|
|
9226
|
+
setSelectedDelivery(null);
|
|
9227
|
+
setProductionDialogOpen(false);
|
|
9228
|
+
setPreviousProducedCount(void 0);
|
|
9229
|
+
}
|
|
9230
|
+
}, [open]);
|
|
9231
|
+
const handleProductionSave = (producedIds) => {
|
|
9232
|
+
if (!supplier || !week || !onProductionUpdate) return;
|
|
9233
|
+
const weekKey = `${week.year}-W${week.weekNumber.toString().padStart(2, "0")}`;
|
|
9234
|
+
onProductionUpdate(supplier.id, weekKey, producedIds);
|
|
9235
|
+
setPreviousProducedCount(producedIds.length);
|
|
9236
|
+
};
|
|
9237
|
+
if (!supplier || !week || !data) {
|
|
9238
|
+
return null;
|
|
9239
|
+
}
|
|
9240
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
9241
|
+
/* @__PURE__ */ jsx(Sheet, { open, onOpenChange, children: /* @__PURE__ */ jsx(
|
|
9242
|
+
SheetContent,
|
|
9243
|
+
{
|
|
9244
|
+
side: "right",
|
|
9245
|
+
className: "w-full sm:max-w-lg p-0 overflow-hidden",
|
|
9246
|
+
children: selectedDelivery ? /* @__PURE__ */ jsx(
|
|
9247
|
+
DeliveryDetailsView2,
|
|
9248
|
+
{
|
|
9249
|
+
delivery: selectedDelivery,
|
|
9250
|
+
week,
|
|
9251
|
+
onBack: () => setSelectedDelivery(null),
|
|
9252
|
+
onAddComment: onAddDeliveryComment ? (text) => {
|
|
9253
|
+
const weekKey = `${week.year}-W${week.weekNumber.toString().padStart(2, "0")}`;
|
|
9254
|
+
onAddDeliveryComment(supplier.id, weekKey, selectedDelivery.id, text);
|
|
9255
|
+
} : void 0
|
|
9256
|
+
}
|
|
9257
|
+
) : /* @__PURE__ */ jsx(
|
|
9258
|
+
MainView2,
|
|
9259
|
+
{
|
|
9260
|
+
supplier,
|
|
9261
|
+
week,
|
|
9262
|
+
data,
|
|
9263
|
+
productionElements,
|
|
9264
|
+
previousProducedCount,
|
|
9265
|
+
onOpenProductionDialog: () => setProductionDialogOpen(true),
|
|
9266
|
+
onSelectDelivery: setSelectedDelivery,
|
|
9267
|
+
onAddProductionComment: onAddProductionComment ? (text) => {
|
|
9268
|
+
const weekKey = `${week.year}-W${week.weekNumber.toString().padStart(2, "0")}`;
|
|
9269
|
+
onAddProductionComment(supplier.id, weekKey, text);
|
|
9270
|
+
} : void 0
|
|
9271
|
+
}
|
|
9272
|
+
)
|
|
9273
|
+
}
|
|
9274
|
+
) }),
|
|
9275
|
+
/* @__PURE__ */ jsx(
|
|
9276
|
+
ElementProductionDialog,
|
|
9277
|
+
{
|
|
9278
|
+
open: productionDialogOpen,
|
|
9279
|
+
onOpenChange: setProductionDialogOpen,
|
|
9280
|
+
elements: productionElements,
|
|
9281
|
+
onSave: handleProductionSave
|
|
9282
|
+
}
|
|
9283
|
+
)
|
|
9284
|
+
] });
|
|
9285
|
+
}
|
|
9286
|
+
function RowHeaderCell({
|
|
9287
|
+
className,
|
|
9288
|
+
data,
|
|
9289
|
+
showProgress = true,
|
|
9290
|
+
...props
|
|
9291
|
+
}) {
|
|
9292
|
+
const progressPercent = data.totalRequired > 0 ? Math.min(data.totalBooked / data.totalRequired * 100, 100) : 0;
|
|
9293
|
+
return /* @__PURE__ */ jsxs(
|
|
9294
|
+
"div",
|
|
9295
|
+
{
|
|
9296
|
+
"data-slot": "row-header-cell",
|
|
9297
|
+
className: cn(
|
|
9298
|
+
"flex flex-col justify-center gap-1.5 py-2 px-3 min-w-[200px] h-[100px] bg-background",
|
|
9299
|
+
className
|
|
9300
|
+
),
|
|
9301
|
+
...props,
|
|
9302
|
+
children: [
|
|
9303
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-2", children: [
|
|
9304
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
|
|
9305
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-bold leading-tight text-foreground truncate", children: data.name }),
|
|
9306
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: data.typeCode })
|
|
9307
|
+
] }),
|
|
9308
|
+
/* @__PURE__ */ jsxs(
|
|
9309
|
+
Badge,
|
|
9310
|
+
{
|
|
9311
|
+
variant: "outline",
|
|
9312
|
+
className: "text-[10px] px-2 py-0.5 h-[19px] font-medium shrink-0 gap-1 bg-background border-border",
|
|
9313
|
+
children: [
|
|
9314
|
+
/* @__PURE__ */ jsx(Flag, { className: "h-2.5 w-2.5" }),
|
|
9315
|
+
"Paint"
|
|
9316
|
+
]
|
|
9317
|
+
}
|
|
9318
|
+
)
|
|
9319
|
+
] }),
|
|
9320
|
+
showProgress && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
9321
|
+
/* @__PURE__ */ jsx("div", { className: "h-1.5 bg-black/10 dark:bg-white/10 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
9322
|
+
"div",
|
|
9323
|
+
{
|
|
9324
|
+
className: "h-full bg-primary rounded-full transition-all",
|
|
9325
|
+
style: { width: `${progressPercent}%` }
|
|
9326
|
+
}
|
|
9327
|
+
) }),
|
|
9328
|
+
/* @__PURE__ */ jsxs("span", { className: "text-[10px] font-medium text-primary", children: [
|
|
9329
|
+
data.totalBooked.toLocaleString(),
|
|
9330
|
+
" / ",
|
|
9331
|
+
data.totalRequired.toLocaleString(),
|
|
9332
|
+
" Booked"
|
|
9333
|
+
] })
|
|
9334
|
+
] })
|
|
9335
|
+
]
|
|
9336
|
+
}
|
|
9337
|
+
);
|
|
9338
|
+
}
|
|
8156
9339
|
function NetBadge({
|
|
8157
9340
|
className,
|
|
8158
9341
|
net,
|
|
@@ -8271,13 +9454,13 @@ function CalibrationWeekCell({
|
|
|
8271
9454
|
onAddClick,
|
|
8272
9455
|
...props
|
|
8273
9456
|
}) {
|
|
8274
|
-
const inputRef =
|
|
8275
|
-
const [localValue, setLocalValue] =
|
|
9457
|
+
const inputRef = React29.useRef(null);
|
|
9458
|
+
const [localValue, setLocalValue] = React29.useState(
|
|
8276
9459
|
data.entered !== null ? String(data.entered) : ""
|
|
8277
9460
|
);
|
|
8278
|
-
const [isHovered, setIsHovered] =
|
|
8279
|
-
const [isEditing, setIsEditing] =
|
|
8280
|
-
|
|
9461
|
+
const [isHovered, setIsHovered] = React29.useState(false);
|
|
9462
|
+
const [isEditing, setIsEditing] = React29.useState(false);
|
|
9463
|
+
React29.useEffect(() => {
|
|
8281
9464
|
setLocalValue(data.entered !== null ? String(data.entered) : "");
|
|
8282
9465
|
}, [data.entered]);
|
|
8283
9466
|
const unitLabel = formatCalibrationUnit(unit);
|
|
@@ -8463,11 +9646,11 @@ function CommentPopover({
|
|
|
8463
9646
|
open,
|
|
8464
9647
|
onOpenChange
|
|
8465
9648
|
}) {
|
|
8466
|
-
const [newCommentText, setNewCommentText] =
|
|
8467
|
-
const [selectedPrefixId, setSelectedPrefixId] =
|
|
8468
|
-
const [viewCommentsOpen, setViewCommentsOpen] =
|
|
8469
|
-
const [showAddForm, setShowAddForm] =
|
|
8470
|
-
const selectedPrefixName =
|
|
9649
|
+
const [newCommentText, setNewCommentText] = React29.useState("");
|
|
9650
|
+
const [selectedPrefixId, setSelectedPrefixId] = React29.useState("");
|
|
9651
|
+
const [viewCommentsOpen, setViewCommentsOpen] = React29.useState(true);
|
|
9652
|
+
const [showAddForm, setShowAddForm] = React29.useState(false);
|
|
9653
|
+
const selectedPrefixName = React29.useMemo(() => {
|
|
8471
9654
|
const prefix = availablePrefixes.find((p) => p.id === selectedPrefixId);
|
|
8472
9655
|
return prefix?.name ?? "";
|
|
8473
9656
|
}, [availablePrefixes, selectedPrefixId]);
|
|
@@ -8499,8 +9682,8 @@ function CommentPopover({
|
|
|
8499
9682
|
minute: "2-digit"
|
|
8500
9683
|
}).format(date);
|
|
8501
9684
|
};
|
|
8502
|
-
const prevOpenRef =
|
|
8503
|
-
|
|
9685
|
+
const prevOpenRef = React29.useRef(open);
|
|
9686
|
+
React29.useEffect(() => {
|
|
8504
9687
|
const wasOpen = prevOpenRef.current;
|
|
8505
9688
|
prevOpenRef.current = open;
|
|
8506
9689
|
if (wasOpen && !open) {
|
|
@@ -8729,7 +9912,7 @@ function CalibrationTable({
|
|
|
8729
9912
|
onAddComment,
|
|
8730
9913
|
onAddEarlierWeek
|
|
8731
9914
|
} = config;
|
|
8732
|
-
const calculatedStartDate =
|
|
9915
|
+
const calculatedStartDate = React29.useMemo(() => {
|
|
8733
9916
|
if (startDate) return startDate;
|
|
8734
9917
|
let earliest = null;
|
|
8735
9918
|
for (const prefix of prefixes) {
|
|
@@ -8750,31 +9933,31 @@ function CalibrationTable({
|
|
|
8750
9933
|
}
|
|
8751
9934
|
return earliest ?? /* @__PURE__ */ new Date();
|
|
8752
9935
|
}, [startDate, prefixes]);
|
|
8753
|
-
const [additionalWeeks, setAdditionalWeeks] =
|
|
8754
|
-
const weeks =
|
|
9936
|
+
const [additionalWeeks, setAdditionalWeeks] = React29.useState(0);
|
|
9937
|
+
const weeks = React29.useMemo(() => {
|
|
8755
9938
|
const start = new Date(calculatedStartDate);
|
|
8756
9939
|
start.setDate(start.getDate() - additionalWeeks * 7);
|
|
8757
9940
|
return generateWeeks(start, weekCount + additionalWeeks);
|
|
8758
9941
|
}, [calculatedStartDate, weekCount, additionalWeeks]);
|
|
8759
|
-
|
|
9942
|
+
React29.useMemo(() => {
|
|
8760
9943
|
const currentWeek = weeks.find((w) => w.isCurrentWeek);
|
|
8761
9944
|
return currentWeek ? getWeekKey(currentWeek.startDate) : null;
|
|
8762
9945
|
}, [weeks]);
|
|
8763
|
-
const [currentPage, setCurrentPage] =
|
|
8764
|
-
const [pageSize, setPageSize] =
|
|
8765
|
-
const [searchQuery, setSearchQuery] =
|
|
8766
|
-
const filteredPrefixes =
|
|
9946
|
+
const [currentPage, setCurrentPage] = React29.useState(0);
|
|
9947
|
+
const [pageSize, setPageSize] = React29.useState(defaultPageSize);
|
|
9948
|
+
const [searchQuery, setSearchQuery] = React29.useState("");
|
|
9949
|
+
const filteredPrefixes = React29.useMemo(() => {
|
|
8767
9950
|
if (!searchQuery) return prefixes;
|
|
8768
9951
|
const query = searchQuery.toLowerCase();
|
|
8769
9952
|
return prefixes.filter(
|
|
8770
9953
|
(p) => p.name.toLowerCase().includes(query) || p.typeCode.toLowerCase().includes(query)
|
|
8771
9954
|
);
|
|
8772
9955
|
}, [prefixes, searchQuery]);
|
|
8773
|
-
const paginatedPrefixes =
|
|
9956
|
+
const paginatedPrefixes = React29.useMemo(() => {
|
|
8774
9957
|
const start = currentPage * pageSize;
|
|
8775
9958
|
return filteredPrefixes.slice(start, start + pageSize);
|
|
8776
9959
|
}, [filteredPrefixes, currentPage, pageSize]);
|
|
8777
|
-
|
|
9960
|
+
React29.useMemo(
|
|
8778
9961
|
() => canSubmitCalibration(prefixes),
|
|
8779
9962
|
[prefixes]
|
|
8780
9963
|
);
|
|
@@ -8798,7 +9981,7 @@ function CalibrationTable({
|
|
|
8798
9981
|
}
|
|
8799
9982
|
return allComments;
|
|
8800
9983
|
};
|
|
8801
|
-
const availablePrefixes =
|
|
9984
|
+
const availablePrefixes = React29.useMemo(
|
|
8802
9985
|
() => prefixes.map((p) => ({ id: p.id, name: p.name })),
|
|
8803
9986
|
[prefixes]
|
|
8804
9987
|
);
|
|
@@ -9035,14 +10218,14 @@ function CommentDialog({
|
|
|
9035
10218
|
open,
|
|
9036
10219
|
onOpenChange
|
|
9037
10220
|
}) {
|
|
9038
|
-
const [selectedPrefixId, setSelectedPrefixId] =
|
|
9039
|
-
const [selectedWeekKey, setSelectedWeekKey] =
|
|
9040
|
-
const [commentText, setCommentText] =
|
|
9041
|
-
const currentWeek =
|
|
10221
|
+
const [selectedPrefixId, setSelectedPrefixId] = React29.useState("");
|
|
10222
|
+
const [selectedWeekKey, setSelectedWeekKey] = React29.useState("");
|
|
10223
|
+
const [commentText, setCommentText] = React29.useState("");
|
|
10224
|
+
const currentWeek = React29.useMemo(
|
|
9042
10225
|
() => weeks.find((w) => w.isCurrentWeek),
|
|
9043
10226
|
[weeks]
|
|
9044
10227
|
);
|
|
9045
|
-
|
|
10228
|
+
React29.useEffect(() => {
|
|
9046
10229
|
if (open) {
|
|
9047
10230
|
setSelectedPrefixId(prefixes[0]?.id ?? "");
|
|
9048
10231
|
setSelectedWeekKey(currentWeek ? getWeekKey(currentWeek.startDate) : weeks[0] ? getWeekKey(weeks[0].startDate) : "");
|
|
@@ -9372,40 +10555,36 @@ function groupDeliveriesByPrefixAndDay(deliveries) {
|
|
|
9372
10555
|
}
|
|
9373
10556
|
return grouped;
|
|
9374
10557
|
}
|
|
9375
|
-
function
|
|
10558
|
+
function getCardStyles(state, hasRisk, isHovered) {
|
|
9376
10559
|
if (hasRisk) {
|
|
9377
10560
|
return {
|
|
9378
10561
|
stroke: "border-l-[3px] border-l-red-500",
|
|
9379
|
-
|
|
9380
|
-
|
|
9381
|
-
|
|
9382
|
-
cardBg: "bg-background"
|
|
10562
|
+
cardBg: "bg-background",
|
|
10563
|
+
titleColor: "text-foreground",
|
|
10564
|
+
opacity: ""
|
|
9383
10565
|
};
|
|
9384
10566
|
}
|
|
9385
10567
|
switch (state) {
|
|
9386
10568
|
case "sent":
|
|
9387
10569
|
return {
|
|
9388
10570
|
stroke: "border-l-[3px] border-l-green-500/40",
|
|
9389
|
-
|
|
9390
|
-
|
|
9391
|
-
|
|
9392
|
-
cardBg: "bg-muted/30"
|
|
10571
|
+
cardBg: "bg-muted/40",
|
|
10572
|
+
titleColor: "text-muted-foreground",
|
|
10573
|
+
opacity: "opacity-60"
|
|
9393
10574
|
};
|
|
9394
10575
|
case "ready":
|
|
9395
10576
|
return {
|
|
9396
|
-
stroke: "border-l-[
|
|
9397
|
-
|
|
9398
|
-
|
|
9399
|
-
|
|
9400
|
-
cardBg: "bg-background"
|
|
10577
|
+
stroke: "border-l-[4px] border-l-green-500",
|
|
10578
|
+
cardBg: "bg-background",
|
|
10579
|
+
titleColor: "text-foreground",
|
|
10580
|
+
opacity: ""
|
|
9401
10581
|
};
|
|
9402
10582
|
default:
|
|
9403
10583
|
return {
|
|
9404
10584
|
stroke: isHovered ? "border-l-[3px] border-l-primary/50" : "border-l-[3px] border-l-border",
|
|
9405
|
-
|
|
9406
|
-
|
|
9407
|
-
|
|
9408
|
-
cardBg: "bg-background"
|
|
10585
|
+
cardBg: "bg-background",
|
|
10586
|
+
titleColor: "text-foreground",
|
|
10587
|
+
opacity: ""
|
|
9409
10588
|
};
|
|
9410
10589
|
}
|
|
9411
10590
|
}
|
|
@@ -9415,55 +10594,11 @@ function DeliveryBadge({
|
|
|
9415
10594
|
onCommentClick,
|
|
9416
10595
|
className
|
|
9417
10596
|
}) {
|
|
9418
|
-
const [isHovered, setIsHovered] =
|
|
10597
|
+
const [isHovered, setIsHovered] = React29.useState(false);
|
|
9419
10598
|
const hasComments = delivery.comments.length > 0;
|
|
9420
10599
|
const visualState = getDeliveryVisualState(delivery);
|
|
9421
|
-
const styles =
|
|
9422
|
-
const
|
|
9423
|
-
const prefixSet = /* @__PURE__ */ new Set();
|
|
9424
|
-
if (delivery.elements && delivery.elements.length > 0) {
|
|
9425
|
-
for (const element of delivery.elements) {
|
|
9426
|
-
if (element.prefix) {
|
|
9427
|
-
prefixSet.add(element.prefix);
|
|
9428
|
-
}
|
|
9429
|
-
}
|
|
9430
|
-
}
|
|
9431
|
-
if (prefixSet.size === 0 && delivery.prefixScope) {
|
|
9432
|
-
prefixSet.add(delivery.prefixScope);
|
|
9433
|
-
}
|
|
9434
|
-
const prefixes = Array.from(prefixSet);
|
|
9435
|
-
if (prefixes.length === 0) {
|
|
9436
|
-
return delivery.label;
|
|
9437
|
-
}
|
|
9438
|
-
if (prefixes.length > 3) {
|
|
9439
|
-
return `${prefixes.slice(0, 3).join(" \xB7 ")} \xB7 +${prefixes.length - 3}`;
|
|
9440
|
-
}
|
|
9441
|
-
return prefixes.join(" \xB7 ");
|
|
9442
|
-
}, [delivery]);
|
|
9443
|
-
const productionProgress = React27.useMemo(() => {
|
|
9444
|
-
if (delivery.producedTons !== void 0 && delivery.totalTons !== void 0 && delivery.totalTons > 0) {
|
|
9445
|
-
return Math.min(delivery.producedTons / delivery.totalTons * 100, 100);
|
|
9446
|
-
}
|
|
9447
|
-
if (delivery.producedCount !== void 0 && delivery.totalCount !== void 0 && delivery.totalCount > 0) {
|
|
9448
|
-
return Math.min(delivery.producedCount / delivery.totalCount * 100, 100);
|
|
9449
|
-
}
|
|
9450
|
-
if (delivery.loadedCount !== void 0 && delivery.totalCount !== void 0 && delivery.totalCount > 0) {
|
|
9451
|
-
return Math.min(delivery.loadedCount / delivery.totalCount * 100, 100);
|
|
9452
|
-
}
|
|
9453
|
-
return 0;
|
|
9454
|
-
}, [delivery]);
|
|
9455
|
-
const productionDisplay = React27.useMemo(() => {
|
|
9456
|
-
if (delivery.producedTons !== void 0 && delivery.totalTons !== void 0) {
|
|
9457
|
-
return `${delivery.producedTons}/${delivery.totalTons}t`;
|
|
9458
|
-
}
|
|
9459
|
-
if (delivery.producedCount !== void 0 && delivery.totalCount !== void 0) {
|
|
9460
|
-
return `${delivery.producedCount}/${delivery.totalCount}`;
|
|
9461
|
-
}
|
|
9462
|
-
if (delivery.loadedCount !== void 0 && delivery.totalCount !== void 0) {
|
|
9463
|
-
return `${delivery.loadedCount}/${delivery.totalCount}`;
|
|
9464
|
-
}
|
|
9465
|
-
return null;
|
|
9466
|
-
}, [delivery]);
|
|
10600
|
+
const styles = getCardStyles(visualState, delivery.hasProductionRisk ?? false, isHovered);
|
|
10601
|
+
const projectName = delivery.destination || delivery.label;
|
|
9467
10602
|
const handleClick = (e) => {
|
|
9468
10603
|
e.stopPropagation();
|
|
9469
10604
|
onClick?.();
|
|
@@ -9479,38 +10614,24 @@ function DeliveryBadge({
|
|
|
9479
10614
|
e.stopPropagation();
|
|
9480
10615
|
onCommentClick?.();
|
|
9481
10616
|
};
|
|
9482
|
-
const amountColorClass = React27.useMemo(() => {
|
|
9483
|
-
if (visualState === "sent") {
|
|
9484
|
-
return "text-muted-foreground/40";
|
|
9485
|
-
}
|
|
9486
|
-
if (delivery.isReadyToUnload) {
|
|
9487
|
-
return "text-green-600 dark:text-green-400";
|
|
9488
|
-
}
|
|
9489
|
-
if (delivery.hasProductionRisk) {
|
|
9490
|
-
return "text-red-600 dark:text-red-400";
|
|
9491
|
-
}
|
|
9492
|
-
return "text-muted-foreground";
|
|
9493
|
-
}, [visualState, delivery.isReadyToUnload, delivery.hasProductionRisk]);
|
|
9494
10617
|
return /* @__PURE__ */ jsxs(
|
|
9495
10618
|
"div",
|
|
9496
10619
|
{
|
|
9497
10620
|
className: cn(
|
|
9498
10621
|
// Position relative for comment button
|
|
9499
10622
|
"relative",
|
|
9500
|
-
// Full-width in cell, 90° corners
|
|
10623
|
+
// Full-width in cell, 90° corners (j3m.radius.none)
|
|
9501
10624
|
"w-full rounded-none",
|
|
9502
|
-
//
|
|
9503
|
-
|
|
9504
|
-
//
|
|
9505
|
-
// - pl-4 = left padding (j3m.spacing.m)
|
|
9506
|
-
// - pr-2 = minimal right padding (progress bar extends further)
|
|
9507
|
-
"min-h-[100px] pt-4 pb-3 pl-4 pr-2",
|
|
9508
|
-
// Card base: dynamic background based on state, complete border
|
|
10625
|
+
// Compact sizing - min-h-[72px], p-4 (j3m.spacing.m)
|
|
10626
|
+
"min-h-[72px] p-4",
|
|
10627
|
+
// Card base: dynamic background based on state
|
|
9509
10628
|
styles.cardBg,
|
|
9510
10629
|
"border border-border",
|
|
9511
10630
|
// Left stroke for status
|
|
9512
10631
|
styles.stroke,
|
|
9513
|
-
//
|
|
10632
|
+
// Opacity for shipped state only
|
|
10633
|
+
styles.opacity,
|
|
10634
|
+
// Interactive states (disabled hover lift for shipped)
|
|
9514
10635
|
"transition-all duration-200 ease-out",
|
|
9515
10636
|
visualState !== "sent" && "hover:-translate-y-0.5 hover:shadow-[var(--j3m-shadow-md)]",
|
|
9516
10637
|
className
|
|
@@ -9523,7 +10644,7 @@ function DeliveryBadge({
|
|
|
9523
10644
|
variant: "ghost",
|
|
9524
10645
|
size: "icon",
|
|
9525
10646
|
className: cn(
|
|
9526
|
-
"absolute top-
|
|
10647
|
+
"absolute top-1.5 right-1.5",
|
|
9527
10648
|
// 44px touch target for accessibility
|
|
9528
10649
|
"h-11 w-11",
|
|
9529
10650
|
"rounded-full",
|
|
@@ -9555,7 +10676,7 @@ function DeliveryBadge({
|
|
|
9555
10676
|
// Full width, no background (inherits from parent)
|
|
9556
10677
|
"w-full bg-transparent text-left",
|
|
9557
10678
|
// Layout - vertical stack
|
|
9558
|
-
"flex flex-col
|
|
10679
|
+
"flex flex-col justify-between h-full min-h-[40px]",
|
|
9559
10680
|
// Interactive states
|
|
9560
10681
|
"cursor-pointer",
|
|
9561
10682
|
"active:translate-y-0 active:shadow-sm",
|
|
@@ -9563,33 +10684,19 @@ function DeliveryBadge({
|
|
|
9563
10684
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1"
|
|
9564
10685
|
),
|
|
9565
10686
|
children: [
|
|
9566
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-
|
|
9567
|
-
/* @__PURE__ */ jsx("span", { className: cn(
|
|
9568
|
-
|
|
9569
|
-
|
|
9570
|
-
|
|
9571
|
-
|
|
9572
|
-
), children: delivery.supplierName })
|
|
10687
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2 pr-12", children: [
|
|
10688
|
+
/* @__PURE__ */ jsx("span", { className: cn(
|
|
10689
|
+
"text-sm font-semibold leading-tight line-clamp-2",
|
|
10690
|
+
styles.titleColor
|
|
10691
|
+
), children: projectName }),
|
|
10692
|
+
delivery.hasProductionRisk && /* @__PURE__ */ jsx(AlertTriangle, { className: "h-4 w-4 text-red-500 shrink-0 mt-0.5" })
|
|
9573
10693
|
] }),
|
|
9574
|
-
/* @__PURE__ */
|
|
9575
|
-
"
|
|
9576
|
-
|
|
9577
|
-
className:
|
|
9578
|
-
style: { width: `${productionProgress}%` }
|
|
9579
|
-
}
|
|
9580
|
-
) }) }),
|
|
9581
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
9582
|
-
productionDisplay && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
9583
|
-
/* @__PURE__ */ jsx(Factory, { className: cn("h-3 w-3 shrink-0", styles.iconColor) }),
|
|
9584
|
-
/* @__PURE__ */ jsx("span", { className: cn(
|
|
9585
|
-
"text-[11px] tabular-nums font-medium",
|
|
9586
|
-
amountColorClass
|
|
9587
|
-
), children: productionDisplay })
|
|
10694
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 mt-2", children: [
|
|
10695
|
+
visualState === "sent" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
10696
|
+
/* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5 text-green-600 dark:text-green-400 shrink-0" }),
|
|
10697
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium text-muted-foreground uppercase tracking-wide", children: "Shipped" })
|
|
9588
10698
|
] }),
|
|
9589
|
-
visualState === "
|
|
9590
|
-
/* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5 text-green-600/60 dark:text-green-400/60 shrink-0" }),
|
|
9591
|
-
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium text-muted-foreground/50 uppercase tracking-wide", children: "Sent" })
|
|
9592
|
-
] })
|
|
10699
|
+
visualState === "ready" && /* @__PURE__ */ jsx("span", { className: "text-[10px] font-semibold text-green-600 dark:text-green-400 uppercase tracking-wide", children: "Ready" })
|
|
9593
10700
|
] })
|
|
9594
10701
|
]
|
|
9595
10702
|
}
|
|
@@ -9598,6 +10705,62 @@ function DeliveryBadge({
|
|
|
9598
10705
|
}
|
|
9599
10706
|
);
|
|
9600
10707
|
}
|
|
10708
|
+
function isShippedDelivery(delivery) {
|
|
10709
|
+
return delivery.status === "shipped" || delivery.status === "delivered";
|
|
10710
|
+
}
|
|
10711
|
+
function ShippedDeliveriesToggle({
|
|
10712
|
+
shippedDeliveries,
|
|
10713
|
+
isOpen,
|
|
10714
|
+
onToggle,
|
|
10715
|
+
onDeliveryClick,
|
|
10716
|
+
onDeliveryCommentClick
|
|
10717
|
+
}) {
|
|
10718
|
+
if (shippedDeliveries.length === 0) return null;
|
|
10719
|
+
return /* @__PURE__ */ jsxs(Collapsible, { open: isOpen, onOpenChange: onToggle, children: [
|
|
10720
|
+
/* @__PURE__ */ jsx(CollapsibleTrigger2, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
10721
|
+
"button",
|
|
10722
|
+
{
|
|
10723
|
+
type: "button",
|
|
10724
|
+
className: cn(
|
|
10725
|
+
"w-full flex items-center justify-between gap-2",
|
|
10726
|
+
"min-h-[44px] px-3 py-2",
|
|
10727
|
+
"rounded-md",
|
|
10728
|
+
"text-xs text-muted-foreground",
|
|
10729
|
+
"hover:bg-muted/50 transition-colors",
|
|
10730
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary"
|
|
10731
|
+
),
|
|
10732
|
+
children: [
|
|
10733
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
10734
|
+
/* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5 text-green-600 dark:text-green-400" }),
|
|
10735
|
+
/* @__PURE__ */ jsxs("span", { className: "font-medium", children: [
|
|
10736
|
+
"Shipped (",
|
|
10737
|
+
shippedDeliveries.length,
|
|
10738
|
+
")"
|
|
10739
|
+
] })
|
|
10740
|
+
] }),
|
|
10741
|
+
/* @__PURE__ */ jsx(
|
|
10742
|
+
ChevronDown,
|
|
10743
|
+
{
|
|
10744
|
+
className: cn(
|
|
10745
|
+
"h-4 w-4 transition-transform duration-200",
|
|
10746
|
+
isOpen && "rotate-180"
|
|
10747
|
+
)
|
|
10748
|
+
}
|
|
10749
|
+
)
|
|
10750
|
+
]
|
|
10751
|
+
}
|
|
10752
|
+
) }),
|
|
10753
|
+
/* @__PURE__ */ jsx(CollapsibleContent2, { children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-3 pt-2", children: shippedDeliveries.map((delivery) => /* @__PURE__ */ jsx(
|
|
10754
|
+
DeliveryBadge,
|
|
10755
|
+
{
|
|
10756
|
+
delivery,
|
|
10757
|
+
onClick: () => onDeliveryClick?.(delivery),
|
|
10758
|
+
onCommentClick: () => onDeliveryCommentClick?.(delivery)
|
|
10759
|
+
},
|
|
10760
|
+
delivery.id
|
|
10761
|
+
)) }) })
|
|
10762
|
+
] });
|
|
10763
|
+
}
|
|
9601
10764
|
function WeeklyLoadingView({
|
|
9602
10765
|
week,
|
|
9603
10766
|
deliveries,
|
|
@@ -9607,7 +10770,25 @@ function WeeklyLoadingView({
|
|
|
9607
10770
|
showNavigation = true,
|
|
9608
10771
|
className
|
|
9609
10772
|
}) {
|
|
9610
|
-
const
|
|
10773
|
+
const [shippedOpenState, setShippedOpenState] = React29.useState({
|
|
10774
|
+
1: false,
|
|
10775
|
+
// Monday
|
|
10776
|
+
2: false,
|
|
10777
|
+
// Tuesday
|
|
10778
|
+
3: false,
|
|
10779
|
+
// Wednesday
|
|
10780
|
+
4: false,
|
|
10781
|
+
// Thursday
|
|
10782
|
+
5: false
|
|
10783
|
+
// Friday
|
|
10784
|
+
});
|
|
10785
|
+
const toggleShippedForDay = (dayOfWeek) => {
|
|
10786
|
+
setShippedOpenState((prev) => ({
|
|
10787
|
+
...prev,
|
|
10788
|
+
[dayOfWeek]: !prev[dayOfWeek]
|
|
10789
|
+
}));
|
|
10790
|
+
};
|
|
10791
|
+
const weekDays = React29.useMemo(() => {
|
|
9611
10792
|
const days = [];
|
|
9612
10793
|
for (let i = 0; i < 5; i++) {
|
|
9613
10794
|
const date = addDays(week.startDate, i);
|
|
@@ -9619,22 +10800,26 @@ function WeeklyLoadingView({
|
|
|
9619
10800
|
}
|
|
9620
10801
|
return days;
|
|
9621
10802
|
}, [week.startDate]);
|
|
9622
|
-
const deliveriesByDay =
|
|
10803
|
+
const deliveriesByDay = React29.useMemo(() => {
|
|
9623
10804
|
const grouped = /* @__PURE__ */ new Map();
|
|
9624
10805
|
for (let i = 1; i <= 5; i++) {
|
|
9625
|
-
grouped.set(i, []);
|
|
10806
|
+
grouped.set(i, { pending: [], shipped: [] });
|
|
9626
10807
|
}
|
|
9627
10808
|
for (const delivery of deliveries) {
|
|
9628
10809
|
const dayOfWeek = delivery.date.getDay();
|
|
9629
10810
|
if (dayOfWeek >= 1 && dayOfWeek <= 5) {
|
|
9630
|
-
const
|
|
9631
|
-
|
|
9632
|
-
|
|
10811
|
+
const dayData = grouped.get(dayOfWeek);
|
|
10812
|
+
if (isShippedDelivery(delivery)) {
|
|
10813
|
+
dayData.shipped.push(delivery);
|
|
10814
|
+
} else {
|
|
10815
|
+
dayData.pending.push(delivery);
|
|
10816
|
+
}
|
|
9633
10817
|
}
|
|
9634
10818
|
}
|
|
9635
10819
|
return grouped;
|
|
9636
10820
|
}, [deliveries]);
|
|
9637
|
-
const
|
|
10821
|
+
const totalPendingDeliveries = deliveries.filter((d) => !isShippedDelivery(d)).length;
|
|
10822
|
+
const totalShippedDeliveries = deliveries.filter((d) => isShippedDelivery(d)).length;
|
|
9638
10823
|
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col", className), children: [
|
|
9639
10824
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 border-b border-border p-4 lg:flex-row lg:items-center lg:justify-between", children: [
|
|
9640
10825
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
|
|
@@ -9651,9 +10836,9 @@ function WeeklyLoadingView({
|
|
|
9651
10836
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
9652
10837
|
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: week.dateRange }),
|
|
9653
10838
|
/* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
|
|
9654
|
-
|
|
9655
|
-
" ",
|
|
9656
|
-
|
|
10839
|
+
totalPendingDeliveries,
|
|
10840
|
+
" pending",
|
|
10841
|
+
totalShippedDeliveries > 0 && `, ${totalShippedDeliveries} shipped`
|
|
9657
10842
|
] })
|
|
9658
10843
|
] })
|
|
9659
10844
|
] }),
|
|
@@ -9720,8 +10905,11 @@ function WeeklyLoadingView({
|
|
|
9720
10905
|
dayOfWeek
|
|
9721
10906
|
)) }),
|
|
9722
10907
|
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-5", children: weekDays.map(({ dayOfWeek, isToday: dayIsToday }) => {
|
|
9723
|
-
const
|
|
9724
|
-
|
|
10908
|
+
const dayData = deliveriesByDay.get(dayOfWeek) ?? { pending: [], shipped: [] };
|
|
10909
|
+
const hasPending = dayData.pending.length > 0;
|
|
10910
|
+
const hasShipped = dayData.shipped.length > 0;
|
|
10911
|
+
const isEmpty = !hasPending && !hasShipped;
|
|
10912
|
+
return /* @__PURE__ */ jsxs(
|
|
9725
10913
|
"div",
|
|
9726
10914
|
{
|
|
9727
10915
|
className: cn(
|
|
@@ -9729,22 +10917,39 @@ function WeeklyLoadingView({
|
|
|
9729
10917
|
"flex flex-col p-3",
|
|
9730
10918
|
dayIsToday && "bg-primary/5"
|
|
9731
10919
|
),
|
|
9732
|
-
children:
|
|
9733
|
-
|
|
9734
|
-
|
|
9735
|
-
|
|
9736
|
-
|
|
9737
|
-
|
|
9738
|
-
|
|
9739
|
-
|
|
9740
|
-
|
|
10920
|
+
children: [
|
|
10921
|
+
hasPending && /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-3", children: dayData.pending.map((delivery) => /* @__PURE__ */ jsx(
|
|
10922
|
+
DeliveryBadge,
|
|
10923
|
+
{
|
|
10924
|
+
delivery,
|
|
10925
|
+
onClick: () => onDeliveryClick?.(delivery),
|
|
10926
|
+
onCommentClick: () => onDeliveryCommentClick?.(delivery)
|
|
10927
|
+
},
|
|
10928
|
+
delivery.id
|
|
10929
|
+
)) }),
|
|
10930
|
+
hasShipped && /* @__PURE__ */ jsx("div", { className: cn(hasPending && "mt-3"), children: /* @__PURE__ */ jsx(
|
|
10931
|
+
ShippedDeliveriesToggle,
|
|
10932
|
+
{
|
|
10933
|
+
shippedDeliveries: dayData.shipped,
|
|
10934
|
+
isOpen: shippedOpenState[dayOfWeek] ?? false,
|
|
10935
|
+
onToggle: () => toggleShippedForDay(dayOfWeek),
|
|
10936
|
+
onDeliveryClick,
|
|
10937
|
+
onDeliveryCommentClick
|
|
10938
|
+
}
|
|
10939
|
+
) }),
|
|
10940
|
+
isEmpty && /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-6 text-sm text-muted-foreground/40", children: "\u2014" })
|
|
10941
|
+
]
|
|
9741
10942
|
},
|
|
9742
10943
|
dayOfWeek
|
|
9743
10944
|
);
|
|
9744
10945
|
}) })
|
|
9745
10946
|
] }),
|
|
9746
10947
|
/* @__PURE__ */ jsx("div", { className: "sm:hidden divide-y divide-border", children: weekDays.map(({ date, dayOfWeek, isToday: dayIsToday }) => {
|
|
9747
|
-
const
|
|
10948
|
+
const dayData = deliveriesByDay.get(dayOfWeek) ?? { pending: [], shipped: [] };
|
|
10949
|
+
const hasPending = dayData.pending.length > 0;
|
|
10950
|
+
const hasShipped = dayData.shipped.length > 0;
|
|
10951
|
+
const isEmpty = !hasPending && !hasShipped;
|
|
10952
|
+
dayData.pending.length + dayData.shipped.length;
|
|
9748
10953
|
return /* @__PURE__ */ jsxs(
|
|
9749
10954
|
"div",
|
|
9750
10955
|
{
|
|
@@ -9767,20 +10972,33 @@ function WeeklyLoadingView({
|
|
|
9767
10972
|
dayIsToday && /* @__PURE__ */ jsx("span", { className: "text-xs text-primary font-medium bg-primary/10 px-2 py-0.5 rounded", children: "Today" })
|
|
9768
10973
|
] }),
|
|
9769
10974
|
/* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
|
|
9770
|
-
|
|
9771
|
-
" ",
|
|
9772
|
-
|
|
10975
|
+
dayData.pending.length,
|
|
10976
|
+
" pending",
|
|
10977
|
+
hasShipped && `, ${dayData.shipped.length} shipped`
|
|
9773
10978
|
] })
|
|
9774
10979
|
] }),
|
|
9775
|
-
/* @__PURE__ */
|
|
9776
|
-
|
|
9777
|
-
|
|
9778
|
-
|
|
9779
|
-
|
|
9780
|
-
|
|
9781
|
-
|
|
9782
|
-
|
|
9783
|
-
|
|
10980
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 p-3 pt-0", children: [
|
|
10981
|
+
hasPending && /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-3", children: dayData.pending.map((delivery) => /* @__PURE__ */ jsx(
|
|
10982
|
+
DeliveryBadge,
|
|
10983
|
+
{
|
|
10984
|
+
delivery,
|
|
10985
|
+
onClick: () => onDeliveryClick?.(delivery),
|
|
10986
|
+
onCommentClick: () => onDeliveryCommentClick?.(delivery)
|
|
10987
|
+
},
|
|
10988
|
+
delivery.id
|
|
10989
|
+
)) }),
|
|
10990
|
+
hasShipped && /* @__PURE__ */ jsx(
|
|
10991
|
+
ShippedDeliveriesToggle,
|
|
10992
|
+
{
|
|
10993
|
+
shippedDeliveries: dayData.shipped,
|
|
10994
|
+
isOpen: shippedOpenState[dayOfWeek] ?? false,
|
|
10995
|
+
onToggle: () => toggleShippedForDay(dayOfWeek),
|
|
10996
|
+
onDeliveryClick,
|
|
10997
|
+
onDeliveryCommentClick
|
|
10998
|
+
}
|
|
10999
|
+
),
|
|
11000
|
+
isEmpty && /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground/40 py-4 text-center", children: "\u2014" })
|
|
11001
|
+
] })
|
|
9784
11002
|
]
|
|
9785
11003
|
},
|
|
9786
11004
|
dayOfWeek
|
|
@@ -9789,36 +11007,63 @@ function WeeklyLoadingView({
|
|
|
9789
11007
|
] })
|
|
9790
11008
|
] });
|
|
9791
11009
|
}
|
|
9792
|
-
function
|
|
9793
|
-
|
|
9794
|
-
|
|
9795
|
-
|
|
9796
|
-
|
|
9797
|
-
|
|
9798
|
-
|
|
9799
|
-
|
|
9800
|
-
|
|
9801
|
-
|
|
9802
|
-
|
|
9803
|
-
|
|
9804
|
-
|
|
11010
|
+
function getTimelineState(delivery) {
|
|
11011
|
+
const isShipped = delivery.status === "shipped" || delivery.status === "delivered";
|
|
11012
|
+
const isReady = delivery.isReadyToUnload ?? false;
|
|
11013
|
+
const hasProductionData = delivery.producedCount !== void 0 || delivery.producedTons !== void 0;
|
|
11014
|
+
if (isShipped) {
|
|
11015
|
+
return {
|
|
11016
|
+
currentStep: "delivery",
|
|
11017
|
+
documentState: "completed",
|
|
11018
|
+
productionState: "completed",
|
|
11019
|
+
deliveryState: "completed",
|
|
11020
|
+
isReady: true,
|
|
11021
|
+
currentStepLabel: "Delivery",
|
|
11022
|
+
reason: "Delivery completed"
|
|
11023
|
+
};
|
|
9805
11024
|
}
|
|
9806
|
-
|
|
9807
|
-
|
|
9808
|
-
|
|
9809
|
-
|
|
9810
|
-
|
|
9811
|
-
|
|
9812
|
-
|
|
9813
|
-
|
|
9814
|
-
|
|
9815
|
-
|
|
9816
|
-
|
|
9817
|
-
|
|
9818
|
-
|
|
9819
|
-
|
|
9820
|
-
|
|
11025
|
+
if (isReady) {
|
|
11026
|
+
return {
|
|
11027
|
+
currentStep: "delivery",
|
|
11028
|
+
documentState: "completed",
|
|
11029
|
+
productionState: "completed",
|
|
11030
|
+
deliveryState: "current",
|
|
11031
|
+
isReady: true,
|
|
11032
|
+
currentStepLabel: "Delivery",
|
|
11033
|
+
reason: "All prerequisites complete"
|
|
11034
|
+
};
|
|
11035
|
+
}
|
|
11036
|
+
if (hasProductionData) {
|
|
11037
|
+
return {
|
|
11038
|
+
currentStep: "production",
|
|
11039
|
+
documentState: "completed",
|
|
11040
|
+
productionState: "current",
|
|
11041
|
+
deliveryState: "upcoming",
|
|
11042
|
+
isReady: false,
|
|
11043
|
+
currentStepLabel: "Production",
|
|
11044
|
+
reason: delivery.hasProductionRisk ? delivery.riskReason || "Production delay risk" : "Not all items have been produced"
|
|
11045
|
+
};
|
|
11046
|
+
}
|
|
11047
|
+
if (delivery.status === "planned") {
|
|
11048
|
+
return {
|
|
11049
|
+
currentStep: "document",
|
|
11050
|
+
documentState: "current",
|
|
11051
|
+
productionState: "upcoming",
|
|
11052
|
+
deliveryState: "upcoming",
|
|
11053
|
+
isReady: false,
|
|
11054
|
+
currentStepLabel: "Document",
|
|
11055
|
+
reason: "Waiting for document approval"
|
|
11056
|
+
};
|
|
9821
11057
|
}
|
|
11058
|
+
return {
|
|
11059
|
+
currentStep: "production",
|
|
11060
|
+
documentState: "completed",
|
|
11061
|
+
productionState: "current",
|
|
11062
|
+
deliveryState: "upcoming",
|
|
11063
|
+
isReady: false,
|
|
11064
|
+
currentStepLabel: "Production",
|
|
11065
|
+
reason: "Production status pending"
|
|
11066
|
+
};
|
|
9822
11067
|
}
|
|
9823
11068
|
function getElementStatusBadgeClasses(status) {
|
|
9824
11069
|
switch (status) {
|
|
@@ -9834,6 +11079,166 @@ function getElementStatusBadgeClasses(status) {
|
|
|
9834
11079
|
return "border-muted-foreground/50 text-muted-foreground";
|
|
9835
11080
|
}
|
|
9836
11081
|
}
|
|
11082
|
+
var TIMELINE_STEPS = [
|
|
11083
|
+
{ id: "document", label: "Document", icon: /* @__PURE__ */ jsx(FileText, { className: "h-4 w-4" }) },
|
|
11084
|
+
{ id: "production", label: "Production", icon: /* @__PURE__ */ jsx(Factory, { className: "h-4 w-4" }) },
|
|
11085
|
+
{ id: "delivery", label: "Delivery", icon: /* @__PURE__ */ jsx(Truck, { className: "h-4 w-4" }) }
|
|
11086
|
+
];
|
|
11087
|
+
function getStepStyles(state) {
|
|
11088
|
+
switch (state) {
|
|
11089
|
+
case "completed":
|
|
11090
|
+
return {
|
|
11091
|
+
dot: "bg-green-500/20 border-green-500",
|
|
11092
|
+
icon: "text-green-600 dark:text-green-400",
|
|
11093
|
+
label: "text-muted-foreground",
|
|
11094
|
+
line: "bg-green-500"
|
|
11095
|
+
};
|
|
11096
|
+
case "current":
|
|
11097
|
+
return {
|
|
11098
|
+
dot: "bg-primary/20 border-primary",
|
|
11099
|
+
icon: "text-primary",
|
|
11100
|
+
label: "text-foreground font-semibold",
|
|
11101
|
+
line: "bg-border"
|
|
11102
|
+
};
|
|
11103
|
+
case "upcoming":
|
|
11104
|
+
default:
|
|
11105
|
+
return {
|
|
11106
|
+
dot: "bg-muted border-border",
|
|
11107
|
+
icon: "text-muted-foreground/50",
|
|
11108
|
+
label: "text-muted-foreground/50",
|
|
11109
|
+
line: "bg-border"
|
|
11110
|
+
};
|
|
11111
|
+
}
|
|
11112
|
+
}
|
|
11113
|
+
function DeliveryTimeline({ timelineState }) {
|
|
11114
|
+
const getStateForStep = (stepId) => {
|
|
11115
|
+
switch (stepId) {
|
|
11116
|
+
case "document":
|
|
11117
|
+
return timelineState.documentState;
|
|
11118
|
+
case "production":
|
|
11119
|
+
return timelineState.productionState;
|
|
11120
|
+
case "delivery":
|
|
11121
|
+
return timelineState.deliveryState;
|
|
11122
|
+
}
|
|
11123
|
+
};
|
|
11124
|
+
return /* @__PURE__ */ jsx("div", { className: "flex items-center justify-between w-full", children: TIMELINE_STEPS.map((step, index) => {
|
|
11125
|
+
const state = getStateForStep(step.id);
|
|
11126
|
+
const styles = getStepStyles(state);
|
|
11127
|
+
const isLast = index === TIMELINE_STEPS.length - 1;
|
|
11128
|
+
return /* @__PURE__ */ jsxs(React29.Fragment, { children: [
|
|
11129
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2", children: [
|
|
11130
|
+
/* @__PURE__ */ jsx(
|
|
11131
|
+
"div",
|
|
11132
|
+
{
|
|
11133
|
+
className: cn(
|
|
11134
|
+
"flex items-center justify-center",
|
|
11135
|
+
"h-10 w-10 rounded-full border-2",
|
|
11136
|
+
"transition-colors duration-200",
|
|
11137
|
+
styles.dot
|
|
11138
|
+
),
|
|
11139
|
+
children: state === "completed" ? /* @__PURE__ */ jsx(Check, { className: cn("h-4 w-4", styles.icon) }) : /* @__PURE__ */ jsx("span", { className: styles.icon, children: step.icon })
|
|
11140
|
+
}
|
|
11141
|
+
),
|
|
11142
|
+
/* @__PURE__ */ jsx("span", { className: cn("text-xs", styles.label), children: step.label })
|
|
11143
|
+
] }),
|
|
11144
|
+
!isLast && /* @__PURE__ */ jsx("div", { className: "flex-1 mx-2 mb-6", children: /* @__PURE__ */ jsx(
|
|
11145
|
+
"div",
|
|
11146
|
+
{
|
|
11147
|
+
className: cn(
|
|
11148
|
+
"h-0.5 w-full rounded-full",
|
|
11149
|
+
styles.line
|
|
11150
|
+
)
|
|
11151
|
+
}
|
|
11152
|
+
) })
|
|
11153
|
+
] }, step.id);
|
|
11154
|
+
}) });
|
|
11155
|
+
}
|
|
11156
|
+
function PackingStatusBadge({
|
|
11157
|
+
timelineState,
|
|
11158
|
+
hasRisk
|
|
11159
|
+
}) {
|
|
11160
|
+
const getPackingStatus = () => {
|
|
11161
|
+
if (timelineState.isReady) {
|
|
11162
|
+
return {
|
|
11163
|
+
label: "Ready",
|
|
11164
|
+
className: "bg-green-100 dark:bg-green-900/50 text-green-700 dark:text-green-300 border-green-200 dark:border-green-800"
|
|
11165
|
+
};
|
|
11166
|
+
}
|
|
11167
|
+
if (hasRisk) {
|
|
11168
|
+
return {
|
|
11169
|
+
label: "At risk",
|
|
11170
|
+
className: "bg-red-100 dark:bg-red-900/50 text-red-700 dark:text-red-300 border-red-200 dark:border-red-800"
|
|
11171
|
+
};
|
|
11172
|
+
}
|
|
11173
|
+
switch (timelineState.currentStep) {
|
|
11174
|
+
case "document":
|
|
11175
|
+
return {
|
|
11176
|
+
label: "Pending approval",
|
|
11177
|
+
className: "bg-muted text-muted-foreground border-border"
|
|
11178
|
+
};
|
|
11179
|
+
case "production":
|
|
11180
|
+
return {
|
|
11181
|
+
label: "In production",
|
|
11182
|
+
className: "bg-amber-100 dark:bg-amber-900/50 text-amber-700 dark:text-amber-300 border-amber-200 dark:border-amber-800"
|
|
11183
|
+
};
|
|
11184
|
+
default:
|
|
11185
|
+
return {
|
|
11186
|
+
label: "Not ready",
|
|
11187
|
+
className: "bg-muted text-muted-foreground border-border"
|
|
11188
|
+
};
|
|
11189
|
+
}
|
|
11190
|
+
};
|
|
11191
|
+
const status = getPackingStatus();
|
|
11192
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
11193
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "Packing status:" }),
|
|
11194
|
+
/* @__PURE__ */ jsx("span", { className: cn(
|
|
11195
|
+
"inline-flex items-center px-2 py-0.5 rounded text-xs font-medium border",
|
|
11196
|
+
status.className
|
|
11197
|
+
), children: status.label })
|
|
11198
|
+
] });
|
|
11199
|
+
}
|
|
11200
|
+
function ReadinessMessage({
|
|
11201
|
+
timelineState,
|
|
11202
|
+
hasRisk
|
|
11203
|
+
}) {
|
|
11204
|
+
if (timelineState.isReady && timelineState.deliveryState === "completed") {
|
|
11205
|
+
return /* @__PURE__ */ jsxs("div", { className: "rounded-lg bg-green-50/50 dark:bg-green-950/20 border border-green-200 dark:border-green-800/50 p-3", children: [
|
|
11206
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
11207
|
+
/* @__PURE__ */ jsx(Check, { className: "h-4 w-4 text-green-600 dark:text-green-400 shrink-0" }),
|
|
11208
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-green-700 dark:text-green-300", children: "Shipped" })
|
|
11209
|
+
] }),
|
|
11210
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-green-600/80 dark:text-green-400/80 mt-1 ml-6", children: "Delivery has been completed." })
|
|
11211
|
+
] });
|
|
11212
|
+
}
|
|
11213
|
+
if (timelineState.isReady) {
|
|
11214
|
+
return /* @__PURE__ */ jsxs("div", { className: "rounded-lg bg-green-50/50 dark:bg-green-950/20 border border-green-200 dark:border-green-800/50 p-3", children: [
|
|
11215
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
11216
|
+
/* @__PURE__ */ jsx(Check, { className: "h-4 w-4 text-green-600 dark:text-green-400 shrink-0" }),
|
|
11217
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-green-700 dark:text-green-300", children: "Ready" })
|
|
11218
|
+
] }),
|
|
11219
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-green-600/80 dark:text-green-400/80 mt-1 ml-6", children: "All prerequisites are complete." })
|
|
11220
|
+
] });
|
|
11221
|
+
}
|
|
11222
|
+
return /* @__PURE__ */ jsx("div", { className: cn(
|
|
11223
|
+
"rounded-lg p-3 border",
|
|
11224
|
+
hasRisk ? "bg-red-50/50 dark:bg-red-950/20 border-red-200 dark:border-red-800/50" : "bg-muted/50 border-border"
|
|
11225
|
+
), children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
|
|
11226
|
+
hasRisk ? /* @__PURE__ */ jsx(AlertTriangle, { className: "h-4 w-4 text-red-500 shrink-0 mt-0.5" }) : /* @__PURE__ */ jsx("div", { className: "h-4 w-4 rounded-full bg-primary/20 border border-primary shrink-0 mt-0.5" }),
|
|
11227
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
11228
|
+
/* @__PURE__ */ jsxs("span", { className: cn(
|
|
11229
|
+
"text-sm font-medium",
|
|
11230
|
+
hasRisk ? "text-red-700 dark:text-red-300" : "text-foreground"
|
|
11231
|
+
), children: [
|
|
11232
|
+
"Currently in: ",
|
|
11233
|
+
timelineState.currentStepLabel
|
|
11234
|
+
] }),
|
|
11235
|
+
/* @__PURE__ */ jsx("p", { className: cn(
|
|
11236
|
+
"text-xs mt-0.5",
|
|
11237
|
+
hasRisk ? "text-red-600/80 dark:text-red-400/80" : "text-muted-foreground"
|
|
11238
|
+
), children: timelineState.reason })
|
|
11239
|
+
] })
|
|
11240
|
+
] }) });
|
|
11241
|
+
}
|
|
9837
11242
|
function getElementRowBg(status) {
|
|
9838
11243
|
switch (status) {
|
|
9839
11244
|
case "loaded":
|
|
@@ -9855,7 +11260,7 @@ function AddCommentDialog({
|
|
|
9855
11260
|
weekId,
|
|
9856
11261
|
onAddComment
|
|
9857
11262
|
}) {
|
|
9858
|
-
const [commentText, setCommentText] =
|
|
11263
|
+
const [commentText, setCommentText] = React29.useState("");
|
|
9859
11264
|
const handleSubmit = () => {
|
|
9860
11265
|
if (commentText.trim() && onAddComment) {
|
|
9861
11266
|
onAddComment({
|
|
@@ -9880,7 +11285,7 @@ function AddCommentDialog({
|
|
|
9880
11285
|
handleSubmit();
|
|
9881
11286
|
}
|
|
9882
11287
|
};
|
|
9883
|
-
|
|
11288
|
+
React29.useEffect(() => {
|
|
9884
11289
|
if (!open) {
|
|
9885
11290
|
setCommentText("");
|
|
9886
11291
|
}
|
|
@@ -9943,8 +11348,8 @@ function CommentsSection({
|
|
|
9943
11348
|
weekId,
|
|
9944
11349
|
onAddComment
|
|
9945
11350
|
}) {
|
|
9946
|
-
const [viewCommentsOpen, setViewCommentsOpen] =
|
|
9947
|
-
const [addDialogOpen, setAddDialogOpen] =
|
|
11351
|
+
const [viewCommentsOpen, setViewCommentsOpen] = React29.useState(true);
|
|
11352
|
+
const [addDialogOpen, setAddDialogOpen] = React29.useState(false);
|
|
9948
11353
|
const formatDate3 = (date) => {
|
|
9949
11354
|
return new Intl.DateTimeFormat("en-US", {
|
|
9950
11355
|
month: "short",
|
|
@@ -10007,31 +11412,6 @@ function CommentsSection({
|
|
|
10007
11412
|
)
|
|
10008
11413
|
] });
|
|
10009
11414
|
}
|
|
10010
|
-
function getDeliveryHeaderStyles(state, hasRisk) {
|
|
10011
|
-
if (hasRisk) {
|
|
10012
|
-
return {
|
|
10013
|
-
iconBg: "bg-red-100 dark:bg-red-950/50",
|
|
10014
|
-
iconColor: "text-red-600 dark:text-red-400"
|
|
10015
|
-
};
|
|
10016
|
-
}
|
|
10017
|
-
switch (state) {
|
|
10018
|
-
case "sent":
|
|
10019
|
-
return {
|
|
10020
|
-
iconBg: "bg-green-100 dark:bg-green-950/50",
|
|
10021
|
-
iconColor: "text-green-600 dark:text-green-400"
|
|
10022
|
-
};
|
|
10023
|
-
case "ready":
|
|
10024
|
-
return {
|
|
10025
|
-
iconBg: "bg-green-100 dark:bg-green-950/50",
|
|
10026
|
-
iconColor: "text-green-600 dark:text-green-400"
|
|
10027
|
-
};
|
|
10028
|
-
default:
|
|
10029
|
-
return {
|
|
10030
|
-
iconBg: "bg-muted",
|
|
10031
|
-
iconColor: "text-muted-foreground"
|
|
10032
|
-
};
|
|
10033
|
-
}
|
|
10034
|
-
}
|
|
10035
11415
|
function DeliveryDetailPage({
|
|
10036
11416
|
delivery,
|
|
10037
11417
|
week,
|
|
@@ -10042,14 +11422,8 @@ function DeliveryDetailPage({
|
|
|
10042
11422
|
onAddComment,
|
|
10043
11423
|
onConfirmLoad
|
|
10044
11424
|
}) {
|
|
10045
|
-
const
|
|
10046
|
-
const
|
|
10047
|
-
const loadedCount = delivery.loadedCount ?? delivery.elements.filter((e) => e.status === "loaded").length;
|
|
10048
|
-
const totalCount = delivery.totalCount ?? delivery.elements.length;
|
|
10049
|
-
const loadedPercent = totalCount > 0 ? Math.round(loadedCount / totalCount * 100) : 0;
|
|
10050
|
-
const producedCount = delivery.producedCount ?? loadedCount;
|
|
10051
|
-
const producedPercent = totalCount > 0 ? Math.round(producedCount / totalCount * 100) : 0;
|
|
10052
|
-
const elementsByStatus = React27.useMemo(() => {
|
|
11425
|
+
const timelineState = getTimelineState(delivery);
|
|
11426
|
+
const elementsByStatus = React29.useMemo(() => {
|
|
10053
11427
|
const loaded = delivery.elements.filter((e) => e.status === "loaded");
|
|
10054
11428
|
const missing = delivery.elements.filter((e) => e.status === "missing");
|
|
10055
11429
|
const moved = delivery.elements.filter((e) => e.status === "moved");
|
|
@@ -10057,6 +11431,7 @@ function DeliveryDetailPage({
|
|
|
10057
11431
|
return { loaded, missing, moved, addons };
|
|
10058
11432
|
}, [delivery.elements]);
|
|
10059
11433
|
const preLoadingComments = delivery.comments.filter((c) => c.context === "pre_unloading");
|
|
11434
|
+
const projectName = delivery.destination || delivery.label;
|
|
10060
11435
|
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full", children: [
|
|
10061
11436
|
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-2 px-4 py-3 border-b bg-background sticky top-0 z-10", children: /* @__PURE__ */ jsxs(
|
|
10062
11437
|
Button,
|
|
@@ -10072,129 +11447,39 @@ function DeliveryDetailPage({
|
|
|
10072
11447
|
}
|
|
10073
11448
|
) }),
|
|
10074
11449
|
/* @__PURE__ */ jsx(ScrollArea, { className: "flex-1", children: /* @__PURE__ */ jsxs("div", { className: "px-4 pb-6 space-y-6", children: [
|
|
10075
|
-
/* @__PURE__ */ jsxs("section", { className: "pt-4 space-y-
|
|
11450
|
+
/* @__PURE__ */ jsxs("section", { className: "pt-4 space-y-3", children: [
|
|
10076
11451
|
/* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-3", children: [
|
|
10077
|
-
/* @__PURE__ */
|
|
10078
|
-
|
|
10079
|
-
"flex items-center justify-center h-12 w-12 rounded-xl shrink-0",
|
|
10080
|
-
headerStyles.iconBg
|
|
10081
|
-
), children: /* @__PURE__ */ jsx(Truck, { className: cn("h-6 w-6", headerStyles.iconColor) }) }),
|
|
10082
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
10083
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
10084
|
-
/* @__PURE__ */ jsx("h1", { className: "text-lg font-semibold", children: delivery.label }),
|
|
10085
|
-
visualState === "sent" && /* @__PURE__ */ jsx(Check, { className: "h-5 w-5 text-green-600 dark:text-green-400" }),
|
|
10086
|
-
delivery.hasProductionRisk && /* @__PURE__ */ jsx(AlertTriangle, { className: "h-5 w-5 text-red-500" })
|
|
10087
|
-
] }),
|
|
10088
|
-
/* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
|
|
10089
|
-
delivery.supplierName,
|
|
10090
|
-
delivery.prefixScope && ` \u2022 ${delivery.prefixScope}`
|
|
10091
|
-
] })
|
|
10092
|
-
] })
|
|
10093
|
-
] }),
|
|
10094
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-end gap-1.5", children: [
|
|
10095
|
-
/* @__PURE__ */ jsx(
|
|
10096
|
-
Badge,
|
|
10097
|
-
{
|
|
10098
|
-
variant: getStatusBadgeVariant2(delivery.status),
|
|
10099
|
-
className: cn("shrink-0", getStatusBadgeClasses2(delivery.status)),
|
|
10100
|
-
children: getLoadingDeliveryStatusLabel(delivery.status)
|
|
10101
|
-
}
|
|
10102
|
-
),
|
|
10103
|
-
delivery.isReadyToUnload && /* @__PURE__ */ jsx(
|
|
10104
|
-
Badge,
|
|
10105
|
-
{
|
|
10106
|
-
variant: "outline",
|
|
10107
|
-
className: "bg-green-100 dark:bg-green-900/50 border-green-300 dark:border-green-700 text-green-700 dark:text-green-300",
|
|
10108
|
-
children: "Ready to load"
|
|
10109
|
-
}
|
|
10110
|
-
)
|
|
10111
|
-
] })
|
|
11452
|
+
/* @__PURE__ */ jsx("h1", { className: "text-xl font-bold leading-tight line-clamp-2", children: projectName }),
|
|
11453
|
+
delivery.hasProductionRisk && /* @__PURE__ */ jsx(AlertTriangle, { className: "h-5 w-5 text-red-500 shrink-0 mt-0.5" })
|
|
10112
11454
|
] }),
|
|
10113
|
-
|
|
10114
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-
|
|
10115
|
-
/* @__PURE__ */ jsx(
|
|
10116
|
-
/* @__PURE__ */ jsx("span", {
|
|
11455
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-x-4 gap-y-1 text-sm text-muted-foreground", children: [
|
|
11456
|
+
delivery.location && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
11457
|
+
/* @__PURE__ */ jsx(MapPin, { className: "h-3.5 w-3.5 shrink-0" }),
|
|
11458
|
+
/* @__PURE__ */ jsx("span", { children: delivery.location })
|
|
10117
11459
|
] }),
|
|
10118
|
-
delivery.riskReason && /* @__PURE__ */ jsx("p", { className: "text-sm text-red-600 dark:text-red-400 mt-1 ml-6", children: delivery.riskReason })
|
|
10119
|
-
] }),
|
|
10120
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-4 text-sm text-muted-foreground", children: [
|
|
10121
11460
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
10122
|
-
/* @__PURE__ */ jsx(Calendar$1, { className: "h-
|
|
10123
|
-
/* @__PURE__ */
|
|
10124
|
-
|
|
10125
|
-
|
|
10126
|
-
|
|
10127
|
-
|
|
10128
|
-
|
|
10129
|
-
|
|
10130
|
-
/* @__PURE__ */ jsx(MapPin, { className: "h-4 w-4" }),
|
|
10131
|
-
/* @__PURE__ */ jsx("span", { children: delivery.destination })
|
|
10132
|
-
] })
|
|
10133
|
-
] }),
|
|
10134
|
-
/* @__PURE__ */ jsxs("div", { className: "rounded-lg bg-muted/50 p-4 space-y-3", children: [
|
|
10135
|
-
(delivery.producedCount !== void 0 || delivery.producedTons !== void 0) && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
10136
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
10137
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: "Production" }),
|
|
10138
|
-
/* @__PURE__ */ jsxs("span", { className: cn(
|
|
10139
|
-
"text-sm font-semibold tabular-nums",
|
|
10140
|
-
delivery.isReadyToUnload ? "text-green-600 dark:text-green-400" : delivery.hasProductionRisk ? "text-red-600 dark:text-red-400" : ""
|
|
10141
|
-
), children: [
|
|
10142
|
-
delivery.producedTons !== void 0 && delivery.totalTons !== void 0 ? `${delivery.producedTons} / ${delivery.totalTons} tons` : `Produced ${producedCount} / ${totalCount}`,
|
|
10143
|
-
delivery.isReadyToUnload && " \u2713"
|
|
10144
|
-
] })
|
|
10145
|
-
] }),
|
|
10146
|
-
/* @__PURE__ */ jsx("div", { className: "h-2 bg-black/10 dark:bg-white/10 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
10147
|
-
"div",
|
|
10148
|
-
{
|
|
10149
|
-
className: cn(
|
|
10150
|
-
"h-full rounded-full transition-all",
|
|
10151
|
-
delivery.isReadyToUnload ? "bg-green-500" : delivery.hasProductionRisk ? "bg-red-500" : "bg-amber-500"
|
|
10152
|
-
),
|
|
10153
|
-
style: { width: `${producedPercent}%` }
|
|
10154
|
-
}
|
|
10155
|
-
) })
|
|
10156
|
-
] }),
|
|
10157
|
-
/* @__PURE__ */ jsx(Separator, { className: "my-2" }),
|
|
10158
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
10159
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
10160
|
-
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: "Loading Progress" }),
|
|
10161
|
-
/* @__PURE__ */ jsxs("span", { className: "text-sm font-semibold tabular-nums", children: [
|
|
10162
|
-
"Loaded ",
|
|
10163
|
-
loadedCount,
|
|
10164
|
-
" / ",
|
|
10165
|
-
totalCount
|
|
10166
|
-
] })
|
|
10167
|
-
] }),
|
|
10168
|
-
/* @__PURE__ */ jsx("div", { className: "h-2 bg-black/10 dark:bg-white/10 rounded-full overflow-hidden", children: /* @__PURE__ */ jsx(
|
|
10169
|
-
"div",
|
|
10170
|
-
{
|
|
10171
|
-
className: cn(
|
|
10172
|
-
"h-full rounded-full transition-all",
|
|
10173
|
-
loadedPercent === 100 ? "bg-green-500" : "bg-primary"
|
|
10174
|
-
),
|
|
10175
|
-
style: { width: `${loadedPercent}%` }
|
|
10176
|
-
}
|
|
10177
|
-
) }),
|
|
10178
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 flex-wrap text-xs", children: [
|
|
10179
|
-
elementsByStatus.loaded.length > 0 && /* @__PURE__ */ jsxs("span", { className: "text-green-600 dark:text-green-400", children: [
|
|
10180
|
-
elementsByStatus.loaded.length,
|
|
10181
|
-
" Loaded"
|
|
10182
|
-
] }),
|
|
10183
|
-
elementsByStatus.missing.length > 0 && /* @__PURE__ */ jsxs("span", { className: "text-muted-foreground", children: [
|
|
10184
|
-
elementsByStatus.missing.length,
|
|
10185
|
-
" Missing"
|
|
10186
|
-
] }),
|
|
10187
|
-
elementsByStatus.moved.length > 0 && /* @__PURE__ */ jsxs("span", { className: "text-blue-600 dark:text-blue-400", children: [
|
|
10188
|
-
elementsByStatus.moved.length,
|
|
10189
|
-
" Moved"
|
|
10190
|
-
] }),
|
|
10191
|
-
elementsByStatus.addons.length > 0 && /* @__PURE__ */ jsxs("span", { className: "text-purple-600 dark:text-purple-400", children: [
|
|
10192
|
-
elementsByStatus.addons.length,
|
|
10193
|
-
" Add-on"
|
|
10194
|
-
] })
|
|
11461
|
+
/* @__PURE__ */ jsx(Calendar$1, { className: "h-3.5 w-3.5 shrink-0" }),
|
|
11462
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
11463
|
+
"Expected on site: ",
|
|
11464
|
+
delivery.date.toLocaleDateString("en-US", {
|
|
11465
|
+
day: "numeric",
|
|
11466
|
+
month: "short",
|
|
11467
|
+
year: "numeric"
|
|
11468
|
+
})
|
|
10195
11469
|
] })
|
|
10196
11470
|
] })
|
|
10197
|
-
] })
|
|
11471
|
+
] }),
|
|
11472
|
+
/* @__PURE__ */ jsx(PackingStatusBadge, { timelineState, hasRisk: delivery.hasProductionRisk ?? false })
|
|
11473
|
+
] }),
|
|
11474
|
+
/* @__PURE__ */ jsxs("section", { className: "space-y-4", children: [
|
|
11475
|
+
/* @__PURE__ */ jsx("div", { className: "py-2", children: /* @__PURE__ */ jsx(DeliveryTimeline, { timelineState }) }),
|
|
11476
|
+
/* @__PURE__ */ jsx(
|
|
11477
|
+
ReadinessMessage,
|
|
11478
|
+
{
|
|
11479
|
+
timelineState,
|
|
11480
|
+
hasRisk: delivery.hasProductionRisk ?? false
|
|
11481
|
+
}
|
|
11482
|
+
)
|
|
10198
11483
|
] }),
|
|
10199
11484
|
(elementsByStatus.loaded.length > 0 || elementsByStatus.missing.length > 0 || elementsByStatus.moved.length > 0) && /* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
|
|
10200
11485
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
@@ -10325,11 +11610,11 @@ function SupplierWeeklyLoading({
|
|
|
10325
11610
|
bordered = true,
|
|
10326
11611
|
className
|
|
10327
11612
|
}) {
|
|
10328
|
-
const [selectedDelivery, setSelectedDelivery] =
|
|
10329
|
-
const [sheetOpen, setSheetOpen] =
|
|
10330
|
-
const [commentDelivery, setCommentDelivery] =
|
|
10331
|
-
const [commentDialogOpen, setCommentDialogOpen] =
|
|
10332
|
-
const [commentText, setCommentText] =
|
|
11613
|
+
const [selectedDelivery, setSelectedDelivery] = React29.useState(null);
|
|
11614
|
+
const [sheetOpen, setSheetOpen] = React29.useState(false);
|
|
11615
|
+
const [commentDelivery, setCommentDelivery] = React29.useState(null);
|
|
11616
|
+
const [commentDialogOpen, setCommentDialogOpen] = React29.useState(false);
|
|
11617
|
+
const [commentText, setCommentText] = React29.useState("");
|
|
10333
11618
|
const handleDeliveryClick = (delivery) => {
|
|
10334
11619
|
setSelectedDelivery(delivery);
|
|
10335
11620
|
setSheetOpen(true);
|
|
@@ -10473,59 +11758,36 @@ function SupplierWeeklyLoading({
|
|
|
10473
11758
|
] }) })
|
|
10474
11759
|
] });
|
|
10475
11760
|
}
|
|
10476
|
-
function
|
|
10477
|
-
switch (status) {
|
|
10478
|
-
case "shipped":
|
|
10479
|
-
case "delivered":
|
|
10480
|
-
return "default";
|
|
10481
|
-
case "loaded":
|
|
10482
|
-
case "in_progress":
|
|
10483
|
-
return "secondary";
|
|
10484
|
-
case "cancelled":
|
|
10485
|
-
return "destructive";
|
|
10486
|
-
case "planned":
|
|
10487
|
-
default:
|
|
10488
|
-
return "outline";
|
|
10489
|
-
}
|
|
10490
|
-
}
|
|
10491
|
-
function getStatusBadgeClasses3(status) {
|
|
10492
|
-
switch (status) {
|
|
10493
|
-
case "shipped":
|
|
10494
|
-
case "delivered":
|
|
10495
|
-
return "border-green-500 text-green-600 bg-green-50 dark:bg-green-950/50";
|
|
10496
|
-
case "loaded":
|
|
10497
|
-
return "border-blue-500 text-blue-600 bg-blue-50 dark:bg-blue-950/50";
|
|
10498
|
-
case "in_progress":
|
|
10499
|
-
return "border-amber-500 text-amber-600 bg-amber-50 dark:bg-amber-950/50";
|
|
10500
|
-
case "cancelled":
|
|
10501
|
-
return "";
|
|
10502
|
-
case "planned":
|
|
10503
|
-
default:
|
|
10504
|
-
return "border-muted-foreground/50 text-muted-foreground";
|
|
10505
|
-
}
|
|
10506
|
-
}
|
|
10507
|
-
function getLeftStrokeStyles2(state, hasRisk, isHovered) {
|
|
11761
|
+
function getCardStyles2(state, hasRisk, isHovered) {
|
|
10508
11762
|
if (hasRisk) {
|
|
10509
11763
|
return {
|
|
10510
|
-
stroke: "border-l-
|
|
10511
|
-
|
|
11764
|
+
stroke: "border-l-[3px] border-l-red-500",
|
|
11765
|
+
cardBg: "bg-background",
|
|
11766
|
+
titleColor: "text-foreground",
|
|
11767
|
+
opacity: ""
|
|
10512
11768
|
};
|
|
10513
11769
|
}
|
|
10514
11770
|
switch (state) {
|
|
10515
11771
|
case "sent":
|
|
10516
11772
|
return {
|
|
10517
|
-
stroke: "border-l-
|
|
10518
|
-
|
|
11773
|
+
stroke: "border-l-[3px] border-l-green-500/40",
|
|
11774
|
+
cardBg: "bg-muted/40",
|
|
11775
|
+
titleColor: "text-muted-foreground",
|
|
11776
|
+
opacity: "opacity-60"
|
|
10519
11777
|
};
|
|
10520
11778
|
case "ready":
|
|
10521
11779
|
return {
|
|
10522
|
-
stroke: "border-l-
|
|
10523
|
-
|
|
11780
|
+
stroke: "border-l-[4px] border-l-green-500",
|
|
11781
|
+
cardBg: "bg-background",
|
|
11782
|
+
titleColor: "text-foreground",
|
|
11783
|
+
opacity: ""
|
|
10524
11784
|
};
|
|
10525
11785
|
default:
|
|
10526
11786
|
return {
|
|
10527
|
-
stroke: isHovered ? "border-l-
|
|
10528
|
-
|
|
11787
|
+
stroke: isHovered ? "border-l-[3px] border-l-primary/50" : "border-l-[3px] border-l-border",
|
|
11788
|
+
cardBg: "bg-background",
|
|
11789
|
+
titleColor: "text-foreground",
|
|
11790
|
+
opacity: ""
|
|
10529
11791
|
};
|
|
10530
11792
|
}
|
|
10531
11793
|
}
|
|
@@ -10534,22 +11796,11 @@ function DeliveryCard({
|
|
|
10534
11796
|
onTap,
|
|
10535
11797
|
className
|
|
10536
11798
|
}) {
|
|
10537
|
-
const [isHovered, setIsHovered] =
|
|
11799
|
+
const [isHovered, setIsHovered] = React29.useState(false);
|
|
10538
11800
|
const hasComments = delivery.comments.length > 0;
|
|
10539
11801
|
const visualState = getDeliveryVisualState(delivery);
|
|
10540
|
-
const styles =
|
|
10541
|
-
const
|
|
10542
|
-
if (delivery.producedTons !== void 0 && delivery.totalTons !== void 0) {
|
|
10543
|
-
return `${delivery.producedTons} / ${delivery.totalTons}t produced`;
|
|
10544
|
-
}
|
|
10545
|
-
if (delivery.producedCount !== void 0 && delivery.totalCount !== void 0) {
|
|
10546
|
-
return `${delivery.producedCount} / ${delivery.totalCount} produced`;
|
|
10547
|
-
}
|
|
10548
|
-
if (delivery.loadedCount !== void 0 && delivery.totalCount !== void 0) {
|
|
10549
|
-
return `Loaded ${delivery.loadedCount} / ${delivery.totalCount}`;
|
|
10550
|
-
}
|
|
10551
|
-
return null;
|
|
10552
|
-
}, [delivery]);
|
|
11802
|
+
const styles = getCardStyles2(visualState, delivery.hasProductionRisk ?? false, isHovered);
|
|
11803
|
+
const projectName = delivery.destination || delivery.label;
|
|
10553
11804
|
const handleClick = () => {
|
|
10554
11805
|
onTap?.();
|
|
10555
11806
|
};
|
|
@@ -10573,69 +11824,43 @@ function DeliveryCard({
|
|
|
10573
11824
|
"w-full rounded-none",
|
|
10574
11825
|
// Touch-friendly sizing - 56px min-height for iPad
|
|
10575
11826
|
"min-h-[56px] p-4",
|
|
10576
|
-
// Card styling:
|
|
10577
|
-
|
|
10578
|
-
|
|
11827
|
+
// Card styling: dynamic background based on state
|
|
11828
|
+
styles.cardBg,
|
|
11829
|
+
"border border-border",
|
|
11830
|
+
// Left stroke for status
|
|
10579
11831
|
styles.stroke,
|
|
10580
|
-
//
|
|
11832
|
+
// Opacity for shipped state only
|
|
11833
|
+
styles.opacity,
|
|
11834
|
+
// Hover/tap state - lift effect (disabled for shipped)
|
|
10581
11835
|
"cursor-pointer transition-all duration-200 ease-out",
|
|
10582
|
-
"hover:-translate-y-0.5 hover:shadow-[var(--j3m-shadow-md)]",
|
|
11836
|
+
visualState !== "sent" && "hover:-translate-y-0.5 hover:shadow-[var(--j3m-shadow-md)]",
|
|
10583
11837
|
"active:translate-y-0 active:shadow-sm",
|
|
10584
11838
|
// Focus state
|
|
10585
11839
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary",
|
|
10586
|
-
// Greyed out for sent state
|
|
10587
|
-
visualState === "sent" && "opacity-60",
|
|
10588
11840
|
className
|
|
10589
11841
|
),
|
|
10590
|
-
children: /* @__PURE__ */ jsxs("div", { className: "flex items-
|
|
10591
|
-
/* @__PURE__ */ jsxs("div", { className: "flex
|
|
10592
|
-
/* @__PURE__ */
|
|
10593
|
-
|
|
10594
|
-
|
|
10595
|
-
|
|
10596
|
-
|
|
10597
|
-
|
|
10598
|
-
|
|
10599
|
-
|
|
10600
|
-
|
|
10601
|
-
{
|
|
10602
|
-
variant: "outline",
|
|
10603
|
-
className: "text-[9px] px-1.5 py-0 h-4 bg-green-100 dark:bg-green-900/50 border-green-300 dark:border-green-700 text-green-700 dark:text-green-300",
|
|
10604
|
-
children: "Ready"
|
|
10605
|
-
}
|
|
10606
|
-
),
|
|
10607
|
-
delivery.hasProductionRisk && /* @__PURE__ */ jsx(AlertTriangle, { className: "h-4 w-4 text-red-500 shrink-0" }),
|
|
10608
|
-
hasComments && /* @__PURE__ */ jsxs("div", { className: "relative shrink-0", children: [
|
|
10609
|
-
/* @__PURE__ */ jsx(MessageSquare, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
10610
|
-
/* @__PURE__ */ jsx("span", { className: "absolute -top-0.5 -right-0.5 h-2 w-2 rounded-full bg-primary" })
|
|
10611
|
-
] })
|
|
10612
|
-
] }),
|
|
10613
|
-
/* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground truncate", children: [
|
|
10614
|
-
delivery.supplierName,
|
|
10615
|
-
delivery.prefixScope && ` \u2022 ${delivery.prefixScope}`
|
|
10616
|
-
] }),
|
|
10617
|
-
productionDisplay && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-xs", children: [
|
|
10618
|
-
/* @__PURE__ */ jsx(Package, { className: "h-3 w-3 text-muted-foreground" }),
|
|
10619
|
-
/* @__PURE__ */ jsxs("span", { className: cn(
|
|
10620
|
-
delivery.isReadyToUnload ? "text-green-600 dark:text-green-400 font-medium" : delivery.hasProductionRisk ? "text-red-600 dark:text-red-400" : "text-muted-foreground"
|
|
10621
|
-
), children: [
|
|
10622
|
-
delivery.isReadyToUnload ? "\u2713 " : "",
|
|
10623
|
-
productionDisplay
|
|
10624
|
-
] })
|
|
11842
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
|
|
11843
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 min-w-0 flex-1", children: [
|
|
11844
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
11845
|
+
/* @__PURE__ */ jsx("span", { className: cn(
|
|
11846
|
+
"text-sm font-semibold truncate",
|
|
11847
|
+
styles.titleColor
|
|
11848
|
+
), children: projectName }),
|
|
11849
|
+
delivery.hasProductionRisk && /* @__PURE__ */ jsx(AlertTriangle, { className: "h-4 w-4 text-red-500 shrink-0" }),
|
|
11850
|
+
hasComments && /* @__PURE__ */ jsxs("div", { className: "relative shrink-0", children: [
|
|
11851
|
+
/* @__PURE__ */ jsx(MessageSquare, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
11852
|
+
/* @__PURE__ */ jsx("span", { className: "absolute -top-0.5 -right-0.5 h-2 w-2 rounded-full bg-primary" })
|
|
10625
11853
|
] })
|
|
11854
|
+
] }),
|
|
11855
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
11856
|
+
visualState === "sent" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
11857
|
+
/* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5 text-green-600 dark:text-green-400 shrink-0" }),
|
|
11858
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium text-muted-foreground uppercase tracking-wide", children: "Shipped" })
|
|
11859
|
+
] }),
|
|
11860
|
+
visualState === "ready" && /* @__PURE__ */ jsx("span", { className: "text-[10px] font-semibold text-green-600 dark:text-green-400 uppercase tracking-wide", children: "Ready" })
|
|
10626
11861
|
] })
|
|
10627
11862
|
] }),
|
|
10628
|
-
/* @__PURE__ */
|
|
10629
|
-
/* @__PURE__ */ jsx(
|
|
10630
|
-
Badge,
|
|
10631
|
-
{
|
|
10632
|
-
variant: getStatusBadgeVariant3(delivery.status),
|
|
10633
|
-
className: cn("text-[10px] h-5", getStatusBadgeClasses3(delivery.status)),
|
|
10634
|
-
children: getLoadingDeliveryStatusLabel(delivery.status)
|
|
10635
|
-
}
|
|
10636
|
-
),
|
|
10637
|
-
/* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4 text-muted-foreground" })
|
|
10638
|
-
] })
|
|
11863
|
+
/* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4 text-muted-foreground shrink-0" })
|
|
10639
11864
|
] })
|
|
10640
11865
|
}
|
|
10641
11866
|
);
|
|
@@ -10703,7 +11928,7 @@ var BADGE_VARIANT_LABELS = {
|
|
|
10703
11928
|
colored: "Colored",
|
|
10704
11929
|
mixed: "Mixed"
|
|
10705
11930
|
};
|
|
10706
|
-
var CalendarContext =
|
|
11931
|
+
var CalendarContext = React29.createContext(null);
|
|
10707
11932
|
function EventCalendarProvider({
|
|
10708
11933
|
children,
|
|
10709
11934
|
events: initialEvents = [],
|
|
@@ -10718,38 +11943,38 @@ function EventCalendarProvider({
|
|
|
10718
11943
|
onEventUpdate,
|
|
10719
11944
|
onEventDelete
|
|
10720
11945
|
}) {
|
|
10721
|
-
const [selectedDate, setSelectedDate] =
|
|
10722
|
-
const [selectedUserId, setSelectedUserId] =
|
|
10723
|
-
const [events, setEventsState] =
|
|
10724
|
-
const [users] =
|
|
10725
|
-
const [badgeVariant, setBadgeVariant] =
|
|
10726
|
-
const [view, setView] =
|
|
10727
|
-
const [workingHours, setWorkingHours] =
|
|
10728
|
-
const [visibleHours, setVisibleHours] =
|
|
10729
|
-
|
|
11946
|
+
const [selectedDate, setSelectedDate] = React29.useState(defaultDate);
|
|
11947
|
+
const [selectedUserId, setSelectedUserId] = React29.useState(defaultUserId);
|
|
11948
|
+
const [events, setEventsState] = React29.useState(initialEvents);
|
|
11949
|
+
const [users] = React29.useState(initialUsers);
|
|
11950
|
+
const [badgeVariant, setBadgeVariant] = React29.useState(defaultBadgeVariant);
|
|
11951
|
+
const [view, setView] = React29.useState(defaultView);
|
|
11952
|
+
const [workingHours, setWorkingHours] = React29.useState(defaultWorkingHours);
|
|
11953
|
+
const [visibleHours, setVisibleHours] = React29.useState(defaultVisibleHours);
|
|
11954
|
+
React29.useEffect(() => {
|
|
10730
11955
|
setEventsState(initialEvents);
|
|
10731
11956
|
}, [initialEvents]);
|
|
10732
|
-
const setEvents =
|
|
11957
|
+
const setEvents = React29.useCallback((newEvents) => {
|
|
10733
11958
|
setEventsState(newEvents);
|
|
10734
11959
|
}, []);
|
|
10735
|
-
const addEvent =
|
|
11960
|
+
const addEvent = React29.useCallback((event) => {
|
|
10736
11961
|
setEventsState((prev) => [...prev, event]);
|
|
10737
11962
|
onEventAdd?.(event);
|
|
10738
11963
|
}, [onEventAdd]);
|
|
10739
|
-
const updateEvent =
|
|
11964
|
+
const updateEvent = React29.useCallback((event) => {
|
|
10740
11965
|
setEventsState(
|
|
10741
11966
|
(prev) => prev.map((e) => e.id === event.id ? event : e)
|
|
10742
11967
|
);
|
|
10743
11968
|
onEventUpdate?.(event);
|
|
10744
11969
|
}, [onEventUpdate]);
|
|
10745
|
-
const deleteEvent =
|
|
11970
|
+
const deleteEvent = React29.useCallback((eventId) => {
|
|
10746
11971
|
setEventsState((prev) => prev.filter((e) => e.id !== eventId));
|
|
10747
11972
|
onEventDelete?.(eventId);
|
|
10748
11973
|
}, [onEventDelete]);
|
|
10749
|
-
const goToToday =
|
|
11974
|
+
const goToToday = React29.useCallback(() => {
|
|
10750
11975
|
setSelectedDate(/* @__PURE__ */ new Date());
|
|
10751
11976
|
}, []);
|
|
10752
|
-
const goToPrevious =
|
|
11977
|
+
const goToPrevious = React29.useCallback(() => {
|
|
10753
11978
|
setSelectedDate((current) => {
|
|
10754
11979
|
switch (view) {
|
|
10755
11980
|
case "day":
|
|
@@ -10767,7 +11992,7 @@ function EventCalendarProvider({
|
|
|
10767
11992
|
}
|
|
10768
11993
|
});
|
|
10769
11994
|
}, [view]);
|
|
10770
|
-
const goToNext =
|
|
11995
|
+
const goToNext = React29.useCallback(() => {
|
|
10771
11996
|
setSelectedDate((current) => {
|
|
10772
11997
|
switch (view) {
|
|
10773
11998
|
case "day":
|
|
@@ -10785,7 +12010,7 @@ function EventCalendarProvider({
|
|
|
10785
12010
|
}
|
|
10786
12011
|
});
|
|
10787
12012
|
}, [view]);
|
|
10788
|
-
const contextValue =
|
|
12013
|
+
const contextValue = React29.useMemo(
|
|
10789
12014
|
() => ({
|
|
10790
12015
|
// State
|
|
10791
12016
|
selectedDate,
|
|
@@ -10832,7 +12057,7 @@ function EventCalendarProvider({
|
|
|
10832
12057
|
return /* @__PURE__ */ jsx(CalendarContext.Provider, { value: contextValue, children });
|
|
10833
12058
|
}
|
|
10834
12059
|
function useEventCalendar() {
|
|
10835
|
-
const context =
|
|
12060
|
+
const context = React29.useContext(CalendarContext);
|
|
10836
12061
|
if (!context) {
|
|
10837
12062
|
throw new Error("useEventCalendar must be used within an EventCalendarProvider");
|
|
10838
12063
|
}
|
|
@@ -10840,14 +12065,14 @@ function useEventCalendar() {
|
|
|
10840
12065
|
}
|
|
10841
12066
|
function useFilteredEvents() {
|
|
10842
12067
|
const { events, selectedUserId } = useEventCalendar();
|
|
10843
|
-
return
|
|
12068
|
+
return React29.useMemo(() => {
|
|
10844
12069
|
if (!selectedUserId) return events;
|
|
10845
12070
|
return events.filter((event) => event.user.id === selectedUserId);
|
|
10846
12071
|
}, [events, selectedUserId]);
|
|
10847
12072
|
}
|
|
10848
12073
|
function useEventsInRange(startDate, endDate) {
|
|
10849
12074
|
const filteredEvents = useFilteredEvents();
|
|
10850
|
-
return
|
|
12075
|
+
return React29.useMemo(() => {
|
|
10851
12076
|
return filteredEvents.filter((event) => {
|
|
10852
12077
|
const eventStart = new Date(event.startDate);
|
|
10853
12078
|
const eventEnd = new Date(event.endDate);
|
|
@@ -11405,8 +12630,8 @@ function MoreEvents({ count, onClick, className }) {
|
|
|
11405
12630
|
);
|
|
11406
12631
|
}
|
|
11407
12632
|
function TimeIndicator({ className }) {
|
|
11408
|
-
const [now, setNow] =
|
|
11409
|
-
|
|
12633
|
+
const [now, setNow] = React29.useState(/* @__PURE__ */ new Date());
|
|
12634
|
+
React29.useEffect(() => {
|
|
11410
12635
|
const interval = setInterval(() => setNow(/* @__PURE__ */ new Date()), 6e4);
|
|
11411
12636
|
return () => clearInterval(interval);
|
|
11412
12637
|
}, []);
|
|
@@ -11443,24 +12668,24 @@ function DateBadge({ date, className }) {
|
|
|
11443
12668
|
}
|
|
11444
12669
|
);
|
|
11445
12670
|
}
|
|
11446
|
-
var DragContext =
|
|
12671
|
+
var DragContext = React29.createContext(null);
|
|
11447
12672
|
function DragProvider({
|
|
11448
12673
|
children,
|
|
11449
12674
|
snapMinutes = 15,
|
|
11450
12675
|
onDragStart,
|
|
11451
12676
|
onDragEnd
|
|
11452
12677
|
}) {
|
|
11453
|
-
const [draggedEvent, setDraggedEventState] =
|
|
11454
|
-
const [isDragging, setIsDragging] =
|
|
12678
|
+
const [draggedEvent, setDraggedEventState] = React29.useState(null);
|
|
12679
|
+
const [isDragging, setIsDragging] = React29.useState(false);
|
|
11455
12680
|
const { updateEvent } = useEventCalendar();
|
|
11456
|
-
const setDraggedEvent =
|
|
12681
|
+
const setDraggedEvent = React29.useCallback((event) => {
|
|
11457
12682
|
setDraggedEventState(event);
|
|
11458
12683
|
setIsDragging(!!event);
|
|
11459
12684
|
if (event) {
|
|
11460
12685
|
onDragStart?.(event);
|
|
11461
12686
|
}
|
|
11462
12687
|
}, [onDragStart]);
|
|
11463
|
-
const handleDrop =
|
|
12688
|
+
const handleDrop = React29.useCallback((newStartDate) => {
|
|
11464
12689
|
if (!draggedEvent) return;
|
|
11465
12690
|
const snappedDate = snapToInterval(newStartDate, snapMinutes);
|
|
11466
12691
|
const { startDate, endDate } = calculateDropDates(draggedEvent, snappedDate);
|
|
@@ -11473,7 +12698,7 @@ function DragProvider({
|
|
|
11473
12698
|
onDragEnd?.(updatedEvent, new Date(startDate), new Date(endDate));
|
|
11474
12699
|
setDraggedEvent(null);
|
|
11475
12700
|
}, [draggedEvent, snapMinutes, updateEvent, onDragEnd, setDraggedEvent]);
|
|
11476
|
-
const contextValue =
|
|
12701
|
+
const contextValue = React29.useMemo(
|
|
11477
12702
|
() => ({
|
|
11478
12703
|
draggedEvent,
|
|
11479
12704
|
setDraggedEvent,
|
|
@@ -11484,7 +12709,7 @@ function DragProvider({
|
|
|
11484
12709
|
return /* @__PURE__ */ jsx(DragContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(DragDropHandler, { onDrop: handleDrop, children }) });
|
|
11485
12710
|
}
|
|
11486
12711
|
function useDrag() {
|
|
11487
|
-
const context =
|
|
12712
|
+
const context = React29.useContext(DragContext);
|
|
11488
12713
|
if (!context) {
|
|
11489
12714
|
throw new Error("useDrag must be used within a DragProvider");
|
|
11490
12715
|
}
|
|
@@ -11529,7 +12754,7 @@ function DroppableZone({
|
|
|
11529
12754
|
}) {
|
|
11530
12755
|
const { draggedEvent, setDraggedEvent } = useDrag();
|
|
11531
12756
|
const { updateEvent } = useEventCalendar();
|
|
11532
|
-
const [isOver, setIsOver] =
|
|
12757
|
+
const [isOver, setIsOver] = React29.useState(false);
|
|
11533
12758
|
const handleDragOver = (e) => {
|
|
11534
12759
|
e.preventDefault();
|
|
11535
12760
|
e.dataTransfer.dropEffect = "move";
|
|
@@ -11567,23 +12792,23 @@ function DroppableZone({
|
|
|
11567
12792
|
function useDroppable({ date, hour, minute = 0, onDrop }) {
|
|
11568
12793
|
const { draggedEvent, setDraggedEvent } = useDrag();
|
|
11569
12794
|
const { updateEvent } = useEventCalendar();
|
|
11570
|
-
const [isOver, setIsOver] =
|
|
11571
|
-
const dropTargetDate =
|
|
12795
|
+
const [isOver, setIsOver] = React29.useState(false);
|
|
12796
|
+
const dropTargetDate = React29.useMemo(() => {
|
|
11572
12797
|
const targetDate = new Date(date);
|
|
11573
12798
|
if (hour !== void 0) {
|
|
11574
12799
|
targetDate.setHours(hour, minute, 0, 0);
|
|
11575
12800
|
}
|
|
11576
12801
|
return targetDate;
|
|
11577
12802
|
}, [date, hour, minute]);
|
|
11578
|
-
const handleDragOver =
|
|
12803
|
+
const handleDragOver = React29.useCallback((e) => {
|
|
11579
12804
|
e.preventDefault();
|
|
11580
12805
|
e.dataTransfer.dropEffect = "move";
|
|
11581
12806
|
if (!isOver) setIsOver(true);
|
|
11582
12807
|
}, [isOver]);
|
|
11583
|
-
const handleDragLeave =
|
|
12808
|
+
const handleDragLeave = React29.useCallback(() => {
|
|
11584
12809
|
setIsOver(false);
|
|
11585
12810
|
}, []);
|
|
11586
|
-
const handleDrop =
|
|
12811
|
+
const handleDrop = React29.useCallback((e) => {
|
|
11587
12812
|
e.preventDefault();
|
|
11588
12813
|
setIsOver(false);
|
|
11589
12814
|
if (!draggedEvent) return;
|
|
@@ -11610,13 +12835,13 @@ function useDroppable({ date, hour, minute = 0, onDrop }) {
|
|
|
11610
12835
|
function useDraggable(event, disabled = false) {
|
|
11611
12836
|
const { setDraggedEvent, draggedEvent } = useDrag();
|
|
11612
12837
|
const isDragged = draggedEvent?.id === event.id;
|
|
11613
|
-
const handleDragStart =
|
|
12838
|
+
const handleDragStart = React29.useCallback((e) => {
|
|
11614
12839
|
if (disabled) return;
|
|
11615
12840
|
e.dataTransfer.effectAllowed = "move";
|
|
11616
12841
|
e.dataTransfer.setData("text/plain", event.id);
|
|
11617
12842
|
setDraggedEvent(event);
|
|
11618
12843
|
}, [disabled, event, setDraggedEvent]);
|
|
11619
|
-
const handleDragEnd =
|
|
12844
|
+
const handleDragEnd = React29.useCallback(() => {
|
|
11620
12845
|
setDraggedEvent(null);
|
|
11621
12846
|
}, [setDraggedEvent]);
|
|
11622
12847
|
return {
|
|
@@ -11657,15 +12882,15 @@ function MonthView({
|
|
|
11657
12882
|
}) {
|
|
11658
12883
|
const { selectedDate, badgeVariant, setSelectedDate, setView } = useEventCalendar();
|
|
11659
12884
|
const filteredEvents = useFilteredEvents();
|
|
11660
|
-
const { singleDayEvents, multiDayEvents } =
|
|
12885
|
+
const { singleDayEvents, multiDayEvents } = React29.useMemo(
|
|
11661
12886
|
() => splitEventsByDuration(filteredEvents),
|
|
11662
12887
|
[filteredEvents]
|
|
11663
12888
|
);
|
|
11664
|
-
const cells =
|
|
12889
|
+
const cells = React29.useMemo(
|
|
11665
12890
|
() => getCalendarCells(selectedDate),
|
|
11666
12891
|
[selectedDate]
|
|
11667
12892
|
);
|
|
11668
|
-
const eventPositions =
|
|
12893
|
+
const eventPositions = React29.useMemo(
|
|
11669
12894
|
() => calculateMonthEventPositions(multiDayEvents, singleDayEvents, selectedDate),
|
|
11670
12895
|
[multiDayEvents, singleDayEvents, selectedDate]
|
|
11671
12896
|
);
|
|
@@ -11847,7 +13072,7 @@ function WeekView({
|
|
|
11847
13072
|
visibleHours
|
|
11848
13073
|
} = useEventCalendar();
|
|
11849
13074
|
const filteredEvents = useFilteredEvents();
|
|
11850
|
-
const { singleDayEvents, multiDayEvents } =
|
|
13075
|
+
const { singleDayEvents, multiDayEvents } = React29.useMemo(
|
|
11851
13076
|
() => splitEventsByDuration(filteredEvents),
|
|
11852
13077
|
[filteredEvents]
|
|
11853
13078
|
);
|
|
@@ -12053,8 +13278,8 @@ function CalendarTimeline({
|
|
|
12053
13278
|
firstVisibleHour,
|
|
12054
13279
|
lastVisibleHour
|
|
12055
13280
|
}) {
|
|
12056
|
-
const [currentTime, setCurrentTime] =
|
|
12057
|
-
|
|
13281
|
+
const [currentTime, setCurrentTime] = React29.useState(/* @__PURE__ */ new Date());
|
|
13282
|
+
React29.useEffect(() => {
|
|
12058
13283
|
const interval = setInterval(() => {
|
|
12059
13284
|
setCurrentTime(/* @__PURE__ */ new Date());
|
|
12060
13285
|
}, 6e4);
|
|
@@ -12137,7 +13362,7 @@ function DayView({
|
|
|
12137
13362
|
visibleHours
|
|
12138
13363
|
} = useEventCalendar();
|
|
12139
13364
|
const filteredEvents = useFilteredEvents();
|
|
12140
|
-
const { singleDayEvents, multiDayEvents } =
|
|
13365
|
+
const { singleDayEvents, multiDayEvents } = React29.useMemo(
|
|
12141
13366
|
() => splitEventsByDuration(filteredEvents),
|
|
12142
13367
|
[filteredEvents]
|
|
12143
13368
|
);
|
|
@@ -12145,7 +13370,7 @@ function DayView({
|
|
|
12145
13370
|
visibleHours,
|
|
12146
13371
|
singleDayEvents
|
|
12147
13372
|
);
|
|
12148
|
-
const currentEvents =
|
|
13373
|
+
const currentEvents = React29.useMemo(() => {
|
|
12149
13374
|
if (!isToday(selectedDate)) return [];
|
|
12150
13375
|
return getCurrentEvents(singleDayEvents);
|
|
12151
13376
|
}, [singleDayEvents, selectedDate]);
|
|
@@ -12369,8 +13594,8 @@ function CalendarTimeline2({
|
|
|
12369
13594
|
firstVisibleHour,
|
|
12370
13595
|
lastVisibleHour
|
|
12371
13596
|
}) {
|
|
12372
|
-
const [currentTime, setCurrentTime] =
|
|
12373
|
-
|
|
13597
|
+
const [currentTime, setCurrentTime] = React29.useState(/* @__PURE__ */ new Date());
|
|
13598
|
+
React29.useEffect(() => {
|
|
12374
13599
|
const interval = setInterval(() => {
|
|
12375
13600
|
setCurrentTime(/* @__PURE__ */ new Date());
|
|
12376
13601
|
}, 6e4);
|
|
@@ -12404,7 +13629,7 @@ function YearView({
|
|
|
12404
13629
|
}) {
|
|
12405
13630
|
const { selectedDate, setSelectedDate, setView } = useEventCalendar();
|
|
12406
13631
|
const filteredEvents = useFilteredEvents();
|
|
12407
|
-
const months =
|
|
13632
|
+
const months = React29.useMemo(() => {
|
|
12408
13633
|
const yearStart = startOfYear(selectedDate);
|
|
12409
13634
|
return Array.from({ length: 12 }, (_, i) => addMonths(yearStart, i));
|
|
12410
13635
|
}, [selectedDate]);
|
|
@@ -12527,11 +13752,11 @@ function AgendaView({
|
|
|
12527
13752
|
}) {
|
|
12528
13753
|
const { selectedDate, setSelectedDate, setView } = useEventCalendar();
|
|
12529
13754
|
const filteredEvents = useFilteredEvents();
|
|
12530
|
-
const { singleDayEvents, multiDayEvents } =
|
|
13755
|
+
const { singleDayEvents, multiDayEvents } = React29.useMemo(
|
|
12531
13756
|
() => splitEventsByDuration(filteredEvents),
|
|
12532
13757
|
[filteredEvents]
|
|
12533
13758
|
);
|
|
12534
|
-
const eventsByDay =
|
|
13759
|
+
const eventsByDay = React29.useMemo(() => {
|
|
12535
13760
|
const allDates = /* @__PURE__ */ new Map();
|
|
12536
13761
|
singleDayEvents.forEach((event) => {
|
|
12537
13762
|
const eventDate = parseISO(event.startDate);
|
|
@@ -12996,16 +14221,16 @@ function EventDialog({
|
|
|
12996
14221
|
defaultUserId
|
|
12997
14222
|
}) {
|
|
12998
14223
|
const { addEvent, updateEvent, deleteEvent, users } = useEventCalendar();
|
|
12999
|
-
const [title, setTitle] =
|
|
13000
|
-
const [description, setDescription] =
|
|
13001
|
-
const [startDate, setStartDate] =
|
|
13002
|
-
const [startTime, setStartTime] =
|
|
13003
|
-
const [endDate, setEndDate] =
|
|
13004
|
-
const [endTime, setEndTime] =
|
|
13005
|
-
const [color, setColor] =
|
|
13006
|
-
const [userId, setUserId] =
|
|
13007
|
-
const [isSubmitting, setIsSubmitting] =
|
|
13008
|
-
|
|
14224
|
+
const [title, setTitle] = React29.useState("");
|
|
14225
|
+
const [description, setDescription] = React29.useState("");
|
|
14226
|
+
const [startDate, setStartDate] = React29.useState("");
|
|
14227
|
+
const [startTime, setStartTime] = React29.useState("");
|
|
14228
|
+
const [endDate, setEndDate] = React29.useState("");
|
|
14229
|
+
const [endTime, setEndTime] = React29.useState("");
|
|
14230
|
+
const [color, setColor] = React29.useState("blue");
|
|
14231
|
+
const [userId, setUserId] = React29.useState("");
|
|
14232
|
+
const [isSubmitting, setIsSubmitting] = React29.useState(false);
|
|
14233
|
+
React29.useEffect(() => {
|
|
13009
14234
|
if (open) {
|
|
13010
14235
|
if (mode === "edit" && event) {
|
|
13011
14236
|
const start = parseISO(event.startDate);
|
|
@@ -13228,7 +14453,7 @@ function QuickAddEvent({
|
|
|
13228
14453
|
onOpenDialog,
|
|
13229
14454
|
onClose
|
|
13230
14455
|
}) {
|
|
13231
|
-
const [title, setTitle] =
|
|
14456
|
+
const [title, setTitle] = React29.useState("");
|
|
13232
14457
|
const { users } = useEventCalendar();
|
|
13233
14458
|
const handleSubmit = (e) => {
|
|
13234
14459
|
e.preventDefault();
|
|
@@ -13295,8 +14520,8 @@ var HOUR_OPTIONS = Array.from({ length: 25 }, (_, i) => {
|
|
|
13295
14520
|
});
|
|
13296
14521
|
function ChangeVisibleHoursInput() {
|
|
13297
14522
|
const { visibleHours, setVisibleHours } = useEventCalendar();
|
|
13298
|
-
const [from, setFrom] =
|
|
13299
|
-
const [to, setTo] =
|
|
14523
|
+
const [from, setFrom] = React29.useState(visibleHours.from);
|
|
14524
|
+
const [to, setTo] = React29.useState(visibleHours.to);
|
|
13300
14525
|
const handleApply = () => {
|
|
13301
14526
|
const toHour = to === 0 ? 24 : to;
|
|
13302
14527
|
setVisibleHours({ from, to: toHour });
|
|
@@ -13342,7 +14567,7 @@ var HOUR_OPTIONS2 = Array.from({ length: 25 }, (_, i) => {
|
|
|
13342
14567
|
});
|
|
13343
14568
|
function ChangeWorkingHoursInput() {
|
|
13344
14569
|
const { workingHours, setWorkingHours } = useEventCalendar();
|
|
13345
|
-
const [localWorkingHours, setLocalWorkingHours] =
|
|
14570
|
+
const [localWorkingHours, setLocalWorkingHours] = React29.useState({
|
|
13346
14571
|
...workingHours
|
|
13347
14572
|
});
|
|
13348
14573
|
const handleToggleDay = (dayId) => {
|
|
@@ -13491,8 +14716,8 @@ function CalendarSettingsButton({
|
|
|
13491
14716
|
);
|
|
13492
14717
|
}
|
|
13493
14718
|
function useMediaQuery(query) {
|
|
13494
|
-
const [matches, setMatches] =
|
|
13495
|
-
|
|
14719
|
+
const [matches, setMatches] = React29.useState(false);
|
|
14720
|
+
React29.useEffect(() => {
|
|
13496
14721
|
const media = window.matchMedia(query);
|
|
13497
14722
|
setMatches(media.matches);
|
|
13498
14723
|
const listener = (event) => {
|
|
@@ -13544,11 +14769,11 @@ function BigCalendarInner({
|
|
|
13544
14769
|
maxEventsPerDay
|
|
13545
14770
|
}) {
|
|
13546
14771
|
const { view, setView } = useEventCalendar();
|
|
13547
|
-
const [dialogOpen, setDialogOpen] =
|
|
13548
|
-
const [settingsDialogOpen, setSettingsDialogOpen] =
|
|
13549
|
-
const [selectedEvent, setSelectedEvent] =
|
|
13550
|
-
const [dialogMode, setDialogMode] =
|
|
13551
|
-
const [defaultDate, setDefaultDate] =
|
|
14772
|
+
const [dialogOpen, setDialogOpen] = React29.useState(false);
|
|
14773
|
+
const [settingsDialogOpen, setSettingsDialogOpen] = React29.useState(false);
|
|
14774
|
+
const [selectedEvent, setSelectedEvent] = React29.useState(null);
|
|
14775
|
+
const [dialogMode, setDialogMode] = React29.useState("add");
|
|
14776
|
+
const [defaultDate, setDefaultDate] = React29.useState(/* @__PURE__ */ new Date());
|
|
13552
14777
|
const isMobile = useMediaQuery("(max-width: 768px)");
|
|
13553
14778
|
const isCompact = compact === "auto" ? isMobile : compact;
|
|
13554
14779
|
const handleAddClick = () => {
|
|
@@ -13860,7 +15085,7 @@ var GanttContentHeader = ({
|
|
|
13860
15085
|
return /* @__PURE__ */ jsxs(
|
|
13861
15086
|
"div",
|
|
13862
15087
|
{
|
|
13863
|
-
className: "sticky top-0 z-20 grid w-full shrink-0 bg-
|
|
15088
|
+
className: "sticky top-0 z-20 grid w-full shrink-0 bg-muted/80 backdrop-blur-sm",
|
|
13864
15089
|
style: { height: "var(--gantt-header-height)" },
|
|
13865
15090
|
children: [
|
|
13866
15091
|
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
|
|
@@ -14057,7 +15282,7 @@ var GanttSidebarHeader = ({
|
|
|
14057
15282
|
}) => /* @__PURE__ */ jsxs(
|
|
14058
15283
|
"div",
|
|
14059
15284
|
{
|
|
14060
|
-
className: "sticky top-0 z-
|
|
15285
|
+
className: "sticky top-0 z-40 flex shrink-0 items-end justify-between gap-2.5 border-border/50 border-b bg-muted/80 px-2.5 py-2 font-medium text-muted-foreground text-xs backdrop-blur-sm",
|
|
14061
15286
|
style: { height: "var(--gantt-header-height)" },
|
|
14062
15287
|
children: [
|
|
14063
15288
|
/* @__PURE__ */ jsx("p", { className: "flex-1 truncate text-left", children: title }),
|
|
@@ -14121,11 +15346,12 @@ var GanttGroupSummaryBar = memo(({
|
|
|
14121
15346
|
children: /* @__PURE__ */ jsx(
|
|
14122
15347
|
"div",
|
|
14123
15348
|
{
|
|
14124
|
-
className: "h-full w-full rounded-sm border border-border/60 bg-muted/40 shadow-sm",
|
|
15349
|
+
className: "relative h-full w-full rounded-sm border border-border/60 bg-muted/40 shadow-sm overflow-hidden",
|
|
14125
15350
|
style: {
|
|
14126
15351
|
// Subtle gradient for depth
|
|
14127
15352
|
background: "linear-gradient(180deg, hsl(var(--muted) / 0.5) 0%, hsl(var(--muted) / 0.3) 100%)"
|
|
14128
|
-
}
|
|
15353
|
+
},
|
|
15354
|
+
children: /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex items-center px-2", children: /* @__PURE__ */ jsx("span", { className: "truncate text-[10px] font-medium text-muted-foreground", children: group.title }) })
|
|
14129
15355
|
}
|
|
14130
15356
|
)
|
|
14131
15357
|
}
|
|
@@ -14157,7 +15383,7 @@ var GanttCollapsibleSidebarGroup = ({
|
|
|
14157
15383
|
/* @__PURE__ */ jsx(CollapsibleTrigger2, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
14158
15384
|
"button",
|
|
14159
15385
|
{
|
|
14160
|
-
className: "flex w-full items-center gap-2 px-2.5 py-2 text-left font-medium text-xs hover:bg-muted/
|
|
15386
|
+
className: "flex w-full items-center gap-2 px-2.5 py-2 text-left font-medium text-xs hover:bg-muted/70 border-b border-border/50 bg-muted/40",
|
|
14161
15387
|
style: { height: "var(--gantt-row-height)" },
|
|
14162
15388
|
type: "button",
|
|
14163
15389
|
children: [
|
|
@@ -14199,7 +15425,7 @@ var GanttCollapsibleTimelineGroup = ({
|
|
|
14199
15425
|
/* @__PURE__ */ jsx(
|
|
14200
15426
|
"div",
|
|
14201
15427
|
{
|
|
14202
|
-
className: "relative w-full border-b border-border/50",
|
|
15428
|
+
className: "relative w-full border-b border-border/50 bg-muted/20",
|
|
14203
15429
|
style: { height: "var(--gantt-row-height)" },
|
|
14204
15430
|
children: /* @__PURE__ */ jsx(GanttGroupSummaryBar, { group })
|
|
14205
15431
|
}
|
|
@@ -14217,7 +15443,7 @@ var GanttSidebarGroup = ({
|
|
|
14217
15443
|
/* @__PURE__ */ jsx(
|
|
14218
15444
|
"p",
|
|
14219
15445
|
{
|
|
14220
|
-
className: "w-full truncate px-2.5 py-2 text-left font-medium text-muted-foreground text-xs border-b border-border/50 bg-
|
|
15446
|
+
className: "w-full truncate px-2.5 py-2 text-left font-medium text-muted-foreground text-xs border-b border-border/50 bg-muted/40",
|
|
14221
15447
|
style: { height: "var(--gantt-row-height)" },
|
|
14222
15448
|
children: name
|
|
14223
15449
|
}
|
|
@@ -14231,7 +15457,7 @@ var GanttSidebar = ({
|
|
|
14231
15457
|
"div",
|
|
14232
15458
|
{
|
|
14233
15459
|
className: cn(
|
|
14234
|
-
"sticky left-0 z-30 h-max min-h-full border-border/50 border-r bg-
|
|
15460
|
+
"sticky left-0 z-30 h-max min-h-full border-border/50 border-r bg-muted/50",
|
|
14235
15461
|
className
|
|
14236
15462
|
),
|
|
14237
15463
|
style: { width: "var(--gantt-sidebar-width)" },
|
|
@@ -15270,6 +16496,6 @@ var KanbanProvider = ({
|
|
|
15270
16496
|
) });
|
|
15271
16497
|
};
|
|
15272
16498
|
|
|
15273
|
-
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AgendaView, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AspectRatio, Avatar, AvatarFallback, AvatarImage, BADGE_VARIANT_LABELS, Badge, BigCalendar, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, Calendar, CalendarContext, CalendarDayButton, CalendarHeader, CalendarHeaderCompact, CalendarSettingsButton, CalendarSettingsContent, CalendarSettingsDialog, CalibrationTable, CalibrationWeekCell, CalibrationWeekHeader, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, ChangeBadgeVariantInput, ChangeVisibleHoursInput, ChangeWorkingHoursInput, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Checkbox, CircularProgress, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, CommentButton, CommentDialog, CommentPopover, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, DEFAULT_VISIBLE_HOURS, DEFAULT_WORKING_HOURS, DataTableColumnHeader, DataTablePagination, DataTableViewOptions, DateBadge, DayView, DeliveryBadge, DeliveryCard, DeliveryDetailPage, DeliveryIndicator, DeliveryIndicators, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DragContext, DragProvider, DraggableEvent, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, DroppableZone, EVENT_COLORS, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, EventBadge, EventCalendarProvider, EventDialog, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, GanttAddFeatureHelper, GanttCollapsibleSidebarGroup, GanttCollapsibleTimelineGroup, GanttColumn, GanttColumns, GanttContentHeader, GanttCreateMarkerTrigger, GanttFeatureDragHelper, GanttFeatureItem, GanttFeatureItemCard, GanttFeatureList, GanttFeatureListGroup, GanttFeatureRow, GanttGridLines, GanttGroupSummaryBar, GanttHeader, GanttMarker, GanttProvider, GanttSidebar, GanttSidebarGroup, GanttSidebarHeader, GanttSidebarItem, GanttTimeline, GanttToday, HoverCard, HoverCardContent, HoverCardTrigger, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, Item6 as Item, ItemActions, ItemContent, ItemDescription, ItemFooter, ItemGroup, ItemHeader, ItemMedia, ItemSeparator, ItemTitle, KanbanBoard, KanbanCard, KanbanCards, KanbanHeader, KanbanProvider, Kbd, KbdGroup, Label2 as Label, Map2 as Map, MapMarker, MapPopup, MapTileLayer, MapTooltip, MapZoomControl, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, MonthView, MoreEvents, NativeSelect, NativeSelectOptGroup, NativeSelectOption, NavMain, NavProjects, NavSecondary, NavUser, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, NetBadge, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PlanningTable, PlanningTableToolbar, PlanningWeekCommentPopover, PlayerCanvas, PlayerCanvasActionButton, PlayerCanvasControls, PlayerCanvasDivider, PlayerCanvasInfo, PlayerCanvasLabel, PlayerCanvasPlayButton, PlayerCanvasProgress, PlayerCanvasSkipButton, PlayerCanvasTitle, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, QuickAddEvent, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, RowHeaderCell, ScrollArea, ScrollBar, SearchForm, SearchTrigger, Section, SectionContent, SectionDescription, SectionFooter, SectionHeader, SectionTitle, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetBody, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, SiteHeader, Skeleton, Slider, Spinner, SubmitCalibrationBar, SupplierCell, SupplierWeeklyLoading, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemeSwitch, TimeIndicator, Toaster, Toggle, ToggleGroup, ToggleGroupItem, ToolBarCanvas, ToolBarCanvasButton, ToolBarCanvasDivider, ToolBarCanvasGroup, Tooltip2 as Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UserAvatarsDropdown, VIEW_LABELS, WeekCell, WeekDetailDialog, WeekHeader, WeekView, WeeklyLoadingView, YearView, badgeVariants, buttonGroupVariants, buttonVariants, calculateCalibrationCells, calculateDropDates, calculateMonthEventPositions, canSubmitCalibration, cardVariants, createDefaultEvent, deliveryIndicatorVariants, extractPrefixes, formatCalibrationUnit, formatDateRange2 as formatDateRange, formatProductionUnit, formatTime, generateColumns, generateEventId, generateLoadingWeek, generateLocationOptions, generateWeekColumns, generateWeeks, getCalendarCells, getCommentLocationLabel, getCurrentEvents, getDayHours, getDayLabel, getDeliveryVisualState, getElementShipmentStatus, getEventBlockStyle, getEventDuration, getEventDurationMinutes, getEventsCount, getEventsForDate, getEventsInRange, getHeaderLabel, getISOWeek, getLoadingDeliveryStatusLabel, getLoadingElementStatusLabel, getLoadingISOWeek, getLoadingWeekKey, getMonthCellEvents, getMonthDays, getShipmentStatusLabel, getShortDayLabel, getSupplierColumn, getTimeHeight, getTimePosition, getViewDateRange, getVisibleHours, getWeekDayNames, getWeekDays, getWeekKey, getYearMonths, groupDeliveriesByDay, groupDeliveriesByPrefixAndDay, groupEvents, isMultiDayEvent, isWorkingHour, navigateDate, navigationMenuTriggerStyle, playerCanvasPlayButtonVariants, playerCanvasSkipButtonVariants, rangeText, sectionVariants, snapToInterval, sortEvents, splitEventsByDuration, toggleVariants, toolBarCanvasButtonVariants, useDrag, useDraggable, useDroppable, useEventCalendar, useEventsInRange, useFilteredEvents, useFormField, useGanttDragging, useGanttScrollX, useIsMobile, useSearchShortcut, useSidebar };
|
|
16499
|
+
export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AgendaView, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AspectRatio, Avatar, AvatarFallback, AvatarImage, BADGE_VARIANT_LABELS, Badge, BigCalendar, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, Calendar, CalendarContext, CalendarDayButton, CalendarHeader, CalendarHeaderCompact, CalendarSettingsButton, CalendarSettingsContent, CalendarSettingsDialog, CalibrationTable, CalibrationWeekCell, CalibrationWeekHeader, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, ChangeBadgeVariantInput, ChangeVisibleHoursInput, ChangeWorkingHoursInput, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Checkbox, CircularProgress, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, CommentButton, CommentDialog, CommentPopover, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, DEFAULT_VISIBLE_HOURS, DEFAULT_WORKING_HOURS, DataTableColumnHeader, DataTablePagination, DataTableViewOptions, DateBadge, DayView, DeliveryBadge, DeliveryCard, DeliveryDetailPage, DeliveryIndicator, DeliveryIndicators, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DragContext, DragProvider, DraggableEvent, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, DroppableZone, EVENT_COLORS, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, EventBadge, EventCalendarProvider, EventDialog, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, GanttAddFeatureHelper, GanttCollapsibleSidebarGroup, GanttCollapsibleTimelineGroup, GanttColumn, GanttColumns, GanttContentHeader, GanttCreateMarkerTrigger, GanttFeatureDragHelper, GanttFeatureItem, GanttFeatureItemCard, GanttFeatureList, GanttFeatureListGroup, GanttFeatureRow, GanttGridLines, GanttGroupSummaryBar, GanttHeader, GanttMarker, GanttProvider, GanttSidebar, GanttSidebarGroup, GanttSidebarHeader, GanttSidebarItem, GanttTimeline, GanttToday, HoverCard, HoverCardContent, HoverCardTrigger, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, Item6 as Item, ItemActions, ItemContent, ItemDescription, ItemFooter, ItemGroup, ItemHeader, ItemMedia, ItemSeparator, ItemTitle, KanbanBoard, KanbanCard, KanbanCards, KanbanHeader, KanbanProvider, Kbd, KbdGroup, Label2 as Label, Map2 as Map, MapMarker, MapPopup, MapTileLayer, MapTooltip, MapZoomControl, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, MonthView, MoreEvents, NativeSelect, NativeSelectOptGroup, NativeSelectOption, NavMain, NavProjects, NavSecondary, NavUser, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, NetBadge, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PlanningTable, PlanningTableToolbar, PlanningWeekCommentPopover, PlayerCanvas, PlayerCanvasActionButton, PlayerCanvasControls, PlayerCanvasDivider, PlayerCanvasInfo, PlayerCanvasLabel, PlayerCanvasPlayButton, PlayerCanvasProgress, PlayerCanvasSkipButton, PlayerCanvasTitle, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, QuickAddEvent, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, RowHeaderCell, ScrollArea, ScrollBar, SearchForm, SearchTrigger, Section, SectionContent, SectionDescription, SectionFooter, SectionHeader, SectionTitle, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Sheet, SheetBody, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, SiteHeader, Skeleton, Slider, Spinner, StatusProgress, SubmitCalibrationBar, SupplierCell, SupplierWeeklyLoading, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemeSwitch, TimeIndicator, Toaster, Toggle, ToggleGroup, ToggleGroupItem, ToolBarCanvas, ToolBarCanvasButton, ToolBarCanvasDivider, ToolBarCanvasGroup, Tooltip2 as Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UserAvatarsDropdown, VIEW_LABELS, WeekCell, WeekDetailDialog, WeekDetailSheet, WeekHeader, WeekView, WeeklyLoadingView, YearView, badgeVariants, buttonGroupVariants, buttonVariants, calculateCalibrationCells, calculateDropDates, calculateMonthEventPositions, canSubmitCalibration, cardVariants, createDefaultEvent, deliveryIndicatorVariants, extractPrefixes, formatCalibrationUnit, formatDateRange2 as formatDateRange, formatProductionUnit, formatTime, generateColumns, generateEventId, generateLoadingWeek, generateLocationOptions, generateWeekColumns, generateWeeks, getCalendarCells, getCommentLocationLabel, getCurrentEvents, getDayHours, getDayLabel, getDeliveryVisualState, getElementShipmentStatus, getEventBlockStyle, getEventDuration, getEventDurationMinutes, getEventsCount, getEventsForDate, getEventsInRange, getHeaderLabel, getISOWeek, getLoadingDeliveryStatusLabel, getLoadingElementStatusLabel, getLoadingISOWeek, getLoadingWeekKey, getMonthCellEvents, getMonthDays, getShipmentStatusLabel, getShortDayLabel, getSupplierColumn, getTimeHeight, getTimePosition, getViewDateRange, getVisibleHours, getWeekDayNames, getWeekDays, getWeekKey, getYearMonths, groupDeliveriesByDay, groupDeliveriesByPrefixAndDay, groupEvents, isMultiDayEvent, isWorkingHour, navigateDate, navigationMenuTriggerStyle, playerCanvasPlayButtonVariants, playerCanvasSkipButtonVariants, rangeText, sectionVariants, snapToInterval, sortEvents, splitEventsByDuration, toggleVariants, toolBarCanvasButtonVariants, useDrag, useDraggable, useDroppable, useEventCalendar, useEventsInRange, useFilteredEvents, useFormField, useGanttDragging, useGanttScrollX, useIsMobile, useSearchShortcut, useSidebar };
|
|
15274
16500
|
//# sourceMappingURL=index.js.map
|
|
15275
16501
|
//# sourceMappingURL=index.js.map
|