@underverse-ui/underverse 0.2.39 → 0.2.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -32,9 +32,11 @@ var index_exports = {};
32
32
  __export(index_exports, {
33
33
  AccessDenied: () => AccessDenied,
34
34
  Alert: () => Alert_default,
35
+ AreaChart: () => AreaChart,
35
36
  Avatar: () => Avatar_default,
36
37
  Badge: () => Badge_default,
37
38
  BadgeBase: () => Badge,
39
+ BarChart: () => BarChart,
38
40
  BatteryProgress: () => BatteryProgress,
39
41
  BottomSheet: () => BottomSheet,
40
42
  Breadcrumb: () => Breadcrumb_default,
@@ -72,6 +74,7 @@ __export(index_exports, {
72
74
  FormLabel: () => FormLabel,
73
75
  FormMessage: () => FormMessage,
74
76
  FormSubmitButton: () => FormSubmitButton,
77
+ GaugeChart: () => GaugeChart,
75
78
  GlobalLoading: () => GlobalLoading,
76
79
  GradientBadge: () => GradientBadge,
77
80
  Grid: () => Grid_default,
@@ -83,6 +86,7 @@ __export(index_exports, {
83
86
  Label: () => Label,
84
87
  LanguageSwitcher: () => LanguageSwitcherHeadless,
85
88
  LanguageSwitcherHeadless: () => LanguageSwitcherHeadless,
89
+ LineChart: () => LineChart,
86
90
  List: () => List_default,
87
91
  ListItem: () => ListItem,
88
92
  LoadingBar: () => LoadingBar,
@@ -99,10 +103,12 @@ __export(index_exports, {
99
103
  PageLoading: () => PageLoading,
100
104
  Pagination: () => Pagination,
101
105
  PasswordInput: () => PasswordInput,
106
+ PieChart: () => PieChart,
102
107
  PillTabs: () => PillTabs,
103
108
  Popover: () => Popover,
104
109
  Progress: () => Progress,
105
110
  PulseBadge: () => PulseBadge,
111
+ RadarChart: () => RadarChart,
106
112
  RadioGroup: () => RadioGroup,
107
113
  RadioGroupItem: () => RadioGroupItem,
108
114
  SIZE_STYLES_BTN: () => SIZE_STYLES_BTN,
@@ -127,6 +133,7 @@ __export(index_exports, {
127
133
  SlideOver: () => SlideOver,
128
134
  Slider: () => Slider,
129
135
  SmartImage: () => SmartImage,
136
+ Sparkline: () => Sparkline,
130
137
  StatusBadge: () => StatusBadge,
131
138
  StepProgress: () => StepProgress,
132
139
  Switch: () => Switch_default,
@@ -10439,23 +10446,1387 @@ GridItem.displayName = "Grid.Item";
10439
10446
  var Grid = Object.assign(GridRoot, { Item: GridItem });
10440
10447
  var Grid_default = Grid;
10441
10448
 
10442
- // ../../components/ui/ClientOnly.tsx
10449
+ // ../../components/ui/LineChart.tsx
10450
+ var import_react23 = require("react");
10451
+
10452
+ // ../../components/ui/ChartTooltip.tsx
10443
10453
  var import_react22 = require("react");
10454
+ var import_react_dom10 = require("react-dom");
10444
10455
  var import_jsx_runtime45 = require("react/jsx-runtime");
10445
- function ClientOnly({ children, fallback = null }) {
10446
- const [hasMounted, setHasMounted] = (0, import_react22.useState)(false);
10456
+ function ChartTooltip({ x, y, visible, label, value, color, secondaryLabel, secondaryValue, items, containerRef }) {
10457
+ const [isMounted, setIsMounted] = (0, import_react22.useState)(false);
10458
+ const [position, setPosition] = (0, import_react22.useState)(null);
10459
+ (0, import_react22.useEffect)(() => {
10460
+ setIsMounted(true);
10461
+ }, []);
10447
10462
  (0, import_react22.useEffect)(() => {
10463
+ if (visible && containerRef?.current) {
10464
+ const rect = containerRef.current.getBoundingClientRect();
10465
+ setPosition({
10466
+ top: rect.top + y,
10467
+ left: rect.left + x
10468
+ });
10469
+ }
10470
+ }, [visible, x, y, containerRef]);
10471
+ if (!visible || !isMounted || !position) return null;
10472
+ const tooltipContent = /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
10473
+ "div",
10474
+ {
10475
+ style: {
10476
+ position: "fixed",
10477
+ top: position.top,
10478
+ left: position.left + 12,
10479
+ zIndex: 99999,
10480
+ pointerEvents: "none",
10481
+ animation: "chartTooltipFadeIn 0.15s ease-out"
10482
+ },
10483
+ children: [
10484
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
10485
+ "div",
10486
+ {
10487
+ className: cn("bg-popover text-popover-foreground border border-border", "rounded-lg shadow-xl px-3 py-2 text-sm", "backdrop-blur-sm"),
10488
+ style: {
10489
+ minWidth: "80px",
10490
+ width: "max-content",
10491
+ boxShadow: "0 10px 25px -3px rgba(0, 0, 0, 0.5), 0 4px 10px -2px rgba(0, 0, 0, 0.3)"
10492
+ },
10493
+ children: [
10494
+ label && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "text-muted-foreground text-xs mb-1", children: label }),
10495
+ items && items.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "flex flex-col gap-1", children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center gap-2", children: [
10496
+ item.color && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "w-2 h-2 rounded-full shrink-0", style: { backgroundColor: item.color } }),
10497
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "text-muted-foreground", children: [
10498
+ item.label,
10499
+ ":"
10500
+ ] }),
10501
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "font-semibold ml-auto", children: item.value })
10502
+ ] }, i)) }) : /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_jsx_runtime45.Fragment, { children: [
10503
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-center gap-2", children: [
10504
+ color && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "w-2 h-2 rounded-full shrink-0", style: { backgroundColor: color } }),
10505
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "font-semibold", children: value })
10506
+ ] }),
10507
+ secondaryLabel && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "text-muted-foreground text-xs mt-1", children: [
10508
+ secondaryLabel,
10509
+ ": ",
10510
+ secondaryValue
10511
+ ] })
10512
+ ] })
10513
+ ]
10514
+ }
10515
+ ),
10516
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("style", { children: `
10517
+ @keyframes chartTooltipFadeIn {
10518
+ from { opacity: 0; transform: translateX(-5px); }
10519
+ to { opacity: 1; transform: translateX(0); }
10520
+ }
10521
+ ` })
10522
+ ]
10523
+ }
10524
+ );
10525
+ return (0, import_react_dom10.createPortal)(tooltipContent, document.body);
10526
+ }
10527
+
10528
+ // ../../components/ui/LineChart.tsx
10529
+ var import_jsx_runtime46 = require("react/jsx-runtime");
10530
+ function LineChart({
10531
+ data,
10532
+ width = 400,
10533
+ height = 200,
10534
+ color = "currentColor",
10535
+ fillColor,
10536
+ showDots = true,
10537
+ showGrid = true,
10538
+ showLabels = true,
10539
+ showValues = false,
10540
+ animated = true,
10541
+ curved = true,
10542
+ className = ""
10543
+ }) {
10544
+ const svgRef = (0, import_react23.useRef)(null);
10545
+ const padding = { top: 20, right: 20, bottom: 40, left: 40 };
10546
+ const chartWidth = width - padding.left - padding.right;
10547
+ const chartHeight = height - padding.top - padding.bottom;
10548
+ const [hoveredPoint, setHoveredPoint] = (0, import_react23.useState)(null);
10549
+ const { minValue, maxValue, points, linePath, areaPath } = (0, import_react23.useMemo)(() => {
10550
+ if (!data.length) return { minValue: 0, maxValue: 0, points: [], linePath: "", areaPath: "" };
10551
+ const values = data.map((d) => d.value);
10552
+ const min = Math.min(...values);
10553
+ const max = Math.max(...values);
10554
+ const range = max - min || 1;
10555
+ const pts = data.map((d, i) => ({
10556
+ x: padding.left + i / (data.length - 1 || 1) * chartWidth,
10557
+ y: padding.top + chartHeight - (d.value - min) / range * chartHeight,
10558
+ ...d
10559
+ }));
10560
+ let path = "";
10561
+ let area = "";
10562
+ if (curved && pts.length > 2) {
10563
+ path = `M ${pts[0].x} ${pts[0].y}`;
10564
+ area = `M ${pts[0].x} ${padding.top + chartHeight} L ${pts[0].x} ${pts[0].y}`;
10565
+ for (let i = 0; i < pts.length - 1; i++) {
10566
+ const p0 = pts[Math.max(0, i - 1)];
10567
+ const p1 = pts[i];
10568
+ const p2 = pts[i + 1];
10569
+ const p3 = pts[Math.min(pts.length - 1, i + 2)];
10570
+ const cp1x = p1.x + (p2.x - p0.x) / 6;
10571
+ const cp1y = p1.y + (p2.y - p0.y) / 6;
10572
+ const cp2x = p2.x - (p3.x - p1.x) / 6;
10573
+ const cp2y = p2.y - (p3.y - p1.y) / 6;
10574
+ path += ` C ${cp1x} ${cp1y}, ${cp2x} ${cp2y}, ${p2.x} ${p2.y}`;
10575
+ area += ` C ${cp1x} ${cp1y}, ${cp2x} ${cp2y}, ${p2.x} ${p2.y}`;
10576
+ }
10577
+ area += ` L ${pts[pts.length - 1].x} ${padding.top + chartHeight} Z`;
10578
+ } else {
10579
+ path = pts.map((p, i) => `${i === 0 ? "M" : "L"} ${p.x} ${p.y}`).join(" ");
10580
+ area = `M ${pts[0].x} ${padding.top + chartHeight} ` + pts.map((p) => `L ${p.x} ${p.y}`).join(" ") + ` L ${pts[pts.length - 1].x} ${padding.top + chartHeight} Z`;
10581
+ }
10582
+ return { minValue: min, maxValue: max, points: pts, linePath: path, areaPath: area };
10583
+ }, [data, chartWidth, chartHeight, curved, padding.left, padding.top]);
10584
+ const gridLines = (0, import_react23.useMemo)(() => {
10585
+ const lines = [];
10586
+ const steps = 5;
10587
+ for (let i = 0; i <= steps; i++) {
10588
+ const y = padding.top + i / steps * chartHeight;
10589
+ const value = maxValue - i / steps * (maxValue - minValue);
10590
+ lines.push({ y, value });
10591
+ }
10592
+ return lines;
10593
+ }, [minValue, maxValue, chartHeight, padding.top]);
10594
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_jsx_runtime46.Fragment, { children: [
10595
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("svg", { ref: svgRef, width, height, className: `overflow-visible ${className}`, style: { fontFamily: "inherit" }, children: [
10596
+ showGrid && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("g", { className: "text-muted-foreground/20", children: gridLines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("g", { children: [
10597
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("line", { x1: padding.left, y1: line.y, x2: width - padding.right, y2: line.y, stroke: "currentColor", strokeDasharray: "4 4" }),
10598
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("text", { x: padding.left - 8, y: line.y + 4, textAnchor: "end", fontSize: "10", fill: "currentColor", className: "text-muted-foreground", children: line.value.toFixed(0) })
10599
+ ] }, i)) }),
10600
+ fillColor && areaPath && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("path", { d: areaPath, fill: fillColor, opacity: 0.2, className: animated ? "animate-[fadeIn_0.6s_ease-out]" : "" }),
10601
+ linePath && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
10602
+ "path",
10603
+ {
10604
+ d: linePath,
10605
+ fill: "none",
10606
+ stroke: color,
10607
+ strokeWidth: 2,
10608
+ strokeLinecap: "round",
10609
+ strokeLinejoin: "round",
10610
+ className: animated ? "animate-[drawLine_1s_ease-out]" : "",
10611
+ style: animated ? {
10612
+ strokeDasharray: 1e3,
10613
+ strokeDashoffset: 0,
10614
+ animation: "drawLine 1s ease-out forwards"
10615
+ } : void 0
10616
+ }
10617
+ ),
10618
+ showDots && points.map((point, i) => /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
10619
+ "g",
10620
+ {
10621
+ onMouseEnter: () => setHoveredPoint({ x: point.x, y: point.y, label: point.label, value: point.value }),
10622
+ onMouseLeave: () => setHoveredPoint(null),
10623
+ className: "cursor-pointer",
10624
+ children: [
10625
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
10626
+ "circle",
10627
+ {
10628
+ cx: point.x,
10629
+ cy: point.y,
10630
+ r: hoveredPoint?.x === point.x ? 6 : 4,
10631
+ fill: color,
10632
+ className: `transition-all duration-150 ${animated ? "animate-[scaleIn_0.3s_ease-out]" : ""}`,
10633
+ style: animated ? { animationDelay: `${i * 0.05}s`, animationFillMode: "both" } : void 0
10634
+ }
10635
+ ),
10636
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("circle", { cx: point.x, cy: point.y, r: 16, fill: "transparent" }),
10637
+ showValues && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("text", { x: point.x, y: point.y - 12, textAnchor: "middle", fontSize: "10", fontWeight: "500", className: "text-foreground", fill: "currentColor", children: point.value })
10638
+ ]
10639
+ },
10640
+ i
10641
+ )),
10642
+ hoveredPoint && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("g", { className: "pointer-events-none", children: [
10643
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
10644
+ "line",
10645
+ {
10646
+ x1: hoveredPoint.x,
10647
+ y1: padding.top,
10648
+ x2: hoveredPoint.x,
10649
+ y2: padding.top + chartHeight,
10650
+ stroke: color,
10651
+ strokeWidth: 1,
10652
+ strokeDasharray: "4 4",
10653
+ opacity: 0.5
10654
+ }
10655
+ ),
10656
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
10657
+ "line",
10658
+ {
10659
+ x1: padding.left,
10660
+ y1: hoveredPoint.y,
10661
+ x2: padding.left + chartWidth,
10662
+ y2: hoveredPoint.y,
10663
+ stroke: color,
10664
+ strokeWidth: 1,
10665
+ strokeDasharray: "4 4",
10666
+ opacity: 0.5
10667
+ }
10668
+ )
10669
+ ] }),
10670
+ showLabels && points.map((point, i) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("text", { x: point.x, y: height - 10, textAnchor: "middle", fontSize: "10", className: "text-muted-foreground", fill: "currentColor", children: point.label }, i)),
10671
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("style", { children: `
10672
+ @keyframes drawLine {
10673
+ from { stroke-dashoffset: 1000; }
10674
+ to { stroke-dashoffset: 0; }
10675
+ }
10676
+ @keyframes scaleIn {
10677
+ from { transform: scale(0); opacity: 0; }
10678
+ to { transform: scale(1); opacity: 1; }
10679
+ }
10680
+ @keyframes fadeIn {
10681
+ from { opacity: 0; }
10682
+ to { opacity: 0.2; }
10683
+ }
10684
+ ` })
10685
+ ] }),
10686
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
10687
+ ChartTooltip,
10688
+ {
10689
+ x: hoveredPoint?.x ?? 0,
10690
+ y: hoveredPoint?.y ?? 0,
10691
+ visible: !!hoveredPoint,
10692
+ label: hoveredPoint?.label,
10693
+ value: hoveredPoint?.value,
10694
+ color,
10695
+ containerRef: svgRef
10696
+ }
10697
+ )
10698
+ ] });
10699
+ }
10700
+
10701
+ // ../../components/ui/BarChart.tsx
10702
+ var import_react24 = require("react");
10703
+ var import_jsx_runtime47 = require("react/jsx-runtime");
10704
+ function BarChart({
10705
+ data,
10706
+ width = 400,
10707
+ height = 200,
10708
+ color = "currentColor",
10709
+ showLabels = true,
10710
+ showValues = true,
10711
+ showGrid = true,
10712
+ horizontal = false,
10713
+ animated = true,
10714
+ barRadius = 4,
10715
+ barGap = 0.3,
10716
+ className = ""
10717
+ }) {
10718
+ const svgRef = (0, import_react24.useRef)(null);
10719
+ const padding = horizontal ? { top: 20, right: 40, bottom: 20, left: 80 } : { top: 20, right: 20, bottom: 40, left: 40 };
10720
+ const chartWidth = width - padding.left - padding.right;
10721
+ const chartHeight = height - padding.top - padding.bottom;
10722
+ const [hoveredBar, setHoveredBar] = (0, import_react24.useState)(null);
10723
+ const { maxValue, bars, gridLines } = (0, import_react24.useMemo)(() => {
10724
+ if (!data.length) return { maxValue: 0, bars: [], gridLines: [] };
10725
+ const max = Math.max(...data.map((d) => d.value));
10726
+ const barCount = data.length;
10727
+ const barsData = data.map((d, i) => {
10728
+ if (horizontal) {
10729
+ const barHeight = chartHeight / barCount * (1 - barGap);
10730
+ const gap = chartHeight / barCount * barGap;
10731
+ return {
10732
+ x: padding.left,
10733
+ y: padding.top + i * (barHeight + gap) + gap / 2,
10734
+ width: d.value / max * chartWidth,
10735
+ height: barHeight,
10736
+ ...d
10737
+ };
10738
+ } else {
10739
+ const barWidth = chartWidth / barCount * (1 - barGap);
10740
+ const gap = chartWidth / barCount * barGap;
10741
+ return {
10742
+ x: padding.left + i * (barWidth + gap) + gap / 2,
10743
+ y: padding.top + chartHeight - d.value / max * chartHeight,
10744
+ width: barWidth,
10745
+ height: d.value / max * chartHeight,
10746
+ ...d
10747
+ };
10748
+ }
10749
+ });
10750
+ const lines = [];
10751
+ const steps = 5;
10752
+ for (let i = 0; i <= steps; i++) {
10753
+ const value = i / steps * max;
10754
+ if (horizontal) {
10755
+ lines.push({
10756
+ x: padding.left + i / steps * chartWidth,
10757
+ y1: padding.top,
10758
+ y2: height - padding.bottom,
10759
+ value
10760
+ });
10761
+ } else {
10762
+ lines.push({
10763
+ y: padding.top + chartHeight - i / steps * chartHeight,
10764
+ x1: padding.left,
10765
+ x2: width - padding.right,
10766
+ value
10767
+ });
10768
+ }
10769
+ }
10770
+ return { maxValue: max, bars: barsData, gridLines: lines };
10771
+ }, [data, chartWidth, chartHeight, horizontal, barGap, padding, width, height]);
10772
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_jsx_runtime47.Fragment, { children: [
10773
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("svg", { ref: svgRef, width, height, className: `overflow-visible ${className}`, style: { fontFamily: "inherit" }, children: [
10774
+ showGrid && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("g", { className: "text-muted-foreground/20", children: gridLines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("g", { children: horizontal ? /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_jsx_runtime47.Fragment, { children: [
10775
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("line", { x1: line.x, y1: line.y1, x2: line.x, y2: line.y2, stroke: "currentColor", strokeDasharray: "4 4" }),
10776
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("text", { x: line.x, y: height - 8, textAnchor: "middle", fontSize: "10", className: "text-muted-foreground", fill: "currentColor", children: line.value.toFixed(0) })
10777
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_jsx_runtime47.Fragment, { children: [
10778
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("line", { x1: line.x1, y1: line.y, x2: line.x2, y2: line.y, stroke: "currentColor", strokeDasharray: "4 4" }),
10779
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("text", { x: padding.left - 8, y: line.y + 4, textAnchor: "end", fontSize: "10", className: "text-muted-foreground", fill: "currentColor", children: line.value.toFixed(0) })
10780
+ ] }) }, i)) }),
10781
+ bars.map((bar, i) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
10782
+ "g",
10783
+ {
10784
+ onMouseEnter: () => setHoveredBar({
10785
+ x: horizontal ? bar.x + bar.width : bar.x + bar.width / 2,
10786
+ y: horizontal ? bar.y + bar.height / 2 : bar.y,
10787
+ label: bar.label,
10788
+ value: bar.value,
10789
+ color: bar.color || color
10790
+ }),
10791
+ onMouseLeave: () => setHoveredBar(null),
10792
+ className: "cursor-pointer",
10793
+ children: [
10794
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
10795
+ "rect",
10796
+ {
10797
+ x: bar.x,
10798
+ y: horizontal ? bar.y : bar.y,
10799
+ width: animated && !horizontal ? 0 : bar.width,
10800
+ height: animated && horizontal ? bar.height : horizontal ? bar.height : 0,
10801
+ rx: barRadius,
10802
+ ry: barRadius,
10803
+ fill: bar.color || color,
10804
+ className: `transition-all duration-150 ${hoveredBar?.label === bar.label ? "opacity-80" : ""}`,
10805
+ style: animated ? {
10806
+ animation: horizontal ? `growWidth 0.5s ease-out ${i * 0.1}s forwards` : `growHeight 0.5s ease-out ${i * 0.1}s forwards`,
10807
+ ...horizontal ? { width: 0 } : { height: 0, y: padding.top + chartHeight }
10808
+ } : void 0,
10809
+ children: [
10810
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
10811
+ "animate",
10812
+ {
10813
+ attributeName: horizontal ? "width" : "height",
10814
+ from: "0",
10815
+ to: horizontal ? bar.width : bar.height,
10816
+ dur: "0.5s",
10817
+ begin: `${i * 0.1}s`,
10818
+ fill: "freeze"
10819
+ }
10820
+ ),
10821
+ !horizontal && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("animate", { attributeName: "y", from: padding.top + chartHeight, to: bar.y, dur: "0.5s", begin: `${i * 0.1}s`, fill: "freeze" })
10822
+ ]
10823
+ }
10824
+ ),
10825
+ showValues && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
10826
+ "text",
10827
+ {
10828
+ x: horizontal ? bar.x + bar.width + 8 : bar.x + bar.width / 2,
10829
+ y: horizontal ? bar.y + bar.height / 2 + 4 : bar.y - 8,
10830
+ textAnchor: horizontal ? "start" : "middle",
10831
+ fontSize: "11",
10832
+ fontWeight: "500",
10833
+ className: "text-foreground",
10834
+ fill: "currentColor",
10835
+ style: animated ? { opacity: 0, animation: `fadeIn 0.3s ease-out ${i * 0.1 + 0.3}s forwards` } : void 0,
10836
+ children: bar.value
10837
+ }
10838
+ ),
10839
+ showLabels && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
10840
+ "text",
10841
+ {
10842
+ x: horizontal ? padding.left - 8 : bar.x + bar.width / 2,
10843
+ y: horizontal ? bar.y + bar.height / 2 + 4 : height - 10,
10844
+ textAnchor: horizontal ? "end" : "middle",
10845
+ fontSize: "10",
10846
+ className: "text-muted-foreground",
10847
+ fill: "currentColor",
10848
+ children: bar.label
10849
+ }
10850
+ )
10851
+ ]
10852
+ },
10853
+ i
10854
+ )),
10855
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("style", { children: `
10856
+ @keyframes growHeight {
10857
+ from { height: 0; }
10858
+ }
10859
+ @keyframes growWidth {
10860
+ from { width: 0; }
10861
+ }
10862
+ @keyframes fadeIn {
10863
+ from { opacity: 0; }
10864
+ to { opacity: 1; }
10865
+ }
10866
+ ` })
10867
+ ] }),
10868
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
10869
+ ChartTooltip,
10870
+ {
10871
+ x: hoveredBar?.x ?? 0,
10872
+ y: hoveredBar?.y ?? 0,
10873
+ visible: !!hoveredBar,
10874
+ label: hoveredBar?.label,
10875
+ value: hoveredBar?.value,
10876
+ color: hoveredBar?.color,
10877
+ containerRef: svgRef
10878
+ }
10879
+ )
10880
+ ] });
10881
+ }
10882
+
10883
+ // ../../components/ui/PieChart.tsx
10884
+ var import_react25 = require("react");
10885
+ var import_jsx_runtime48 = require("react/jsx-runtime");
10886
+ function PieChart({
10887
+ data,
10888
+ size = 200,
10889
+ donut = false,
10890
+ donutWidth = 40,
10891
+ showLabels = true,
10892
+ showLegend = true,
10893
+ showPercentage = true,
10894
+ animated = true,
10895
+ startAngle = -90,
10896
+ className = ""
10897
+ }) {
10898
+ const containerRef = (0, import_react25.useRef)(null);
10899
+ const center = size / 2;
10900
+ const radius = size / 2 - 10;
10901
+ const innerRadius = donut ? radius - donutWidth : 0;
10902
+ const { segments, total } = (0, import_react25.useMemo)(() => {
10903
+ if (!data.length) return { segments: [], total: 0 };
10904
+ const sum = data.reduce((acc, d) => acc + d.value, 0);
10905
+ let currentAngle = startAngle;
10906
+ const segs = data.map((d, i) => {
10907
+ const percentage = d.value / sum;
10908
+ const angle = percentage * 360;
10909
+ const startRad = currentAngle * Math.PI / 180;
10910
+ const endRad = (currentAngle + angle) * Math.PI / 180;
10911
+ const midRad = (currentAngle + angle / 2) * Math.PI / 180;
10912
+ const largeArc = angle > 180 ? 1 : 0;
10913
+ const x1 = center + radius * Math.cos(startRad);
10914
+ const y1 = center + radius * Math.sin(startRad);
10915
+ const x2 = center + radius * Math.cos(endRad);
10916
+ const y2 = center + radius * Math.sin(endRad);
10917
+ const x3 = center + innerRadius * Math.cos(endRad);
10918
+ const y3 = center + innerRadius * Math.sin(endRad);
10919
+ const x4 = center + innerRadius * Math.cos(startRad);
10920
+ const y4 = center + innerRadius * Math.sin(startRad);
10921
+ const labelRadius = radius + 20;
10922
+ const labelX = center + labelRadius * Math.cos(midRad);
10923
+ const labelY = center + labelRadius * Math.sin(midRad);
10924
+ let path;
10925
+ if (donut) {
10926
+ path = [
10927
+ `M ${x1} ${y1}`,
10928
+ `A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2}`,
10929
+ `L ${x3} ${y3}`,
10930
+ `A ${innerRadius} ${innerRadius} 0 ${largeArc} 0 ${x4} ${y4}`,
10931
+ "Z"
10932
+ ].join(" ");
10933
+ } else {
10934
+ path = [`M ${center} ${center}`, `L ${x1} ${y1}`, `A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2}`, "Z"].join(" ");
10935
+ }
10936
+ currentAngle += angle;
10937
+ return {
10938
+ path,
10939
+ ...d,
10940
+ percentage,
10941
+ labelX,
10942
+ labelY,
10943
+ midAngle: currentAngle - angle / 2
10944
+ };
10945
+ });
10946
+ return { segments: segs, total: sum };
10947
+ }, [data, center, radius, innerRadius, donut, startAngle]);
10948
+ const [hoveredSegment, setHoveredSegment] = (0, import_react25.useState)(null);
10949
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { ref: containerRef, className: `relative flex items-center gap-6 ${className}`, children: [
10950
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("svg", { width: size + 40, height: size + 40, className: "overflow-visible", style: { fontFamily: "inherit" }, children: [
10951
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("g", { transform: `translate(20, 20)`, children: [
10952
+ segments.map((seg, i) => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
10953
+ "g",
10954
+ {
10955
+ onMouseEnter: () => setHoveredSegment({
10956
+ x: seg.labelX + 20,
10957
+ y: seg.labelY + 20,
10958
+ label: seg.label,
10959
+ value: seg.value,
10960
+ percentage: seg.percentage,
10961
+ color: seg.color
10962
+ }),
10963
+ onMouseLeave: () => setHoveredSegment(null),
10964
+ children: [
10965
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
10966
+ "path",
10967
+ {
10968
+ d: seg.path,
10969
+ fill: seg.color,
10970
+ className: `transition-all duration-150 cursor-pointer ${hoveredSegment?.label === seg.label ? "opacity-80" : ""}`,
10971
+ style: {
10972
+ transformOrigin: `${center}px ${center}px`,
10973
+ transform: hoveredSegment?.label === seg.label ? "scale(1.05)" : "scale(1)",
10974
+ ...animated ? {
10975
+ opacity: hoveredSegment?.label === seg.label ? 0.8 : 0,
10976
+ animation: `pieSlice 0.5s ease-out ${i * 0.1}s forwards`
10977
+ } : void 0
10978
+ }
10979
+ }
10980
+ ),
10981
+ showLabels && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
10982
+ "text",
10983
+ {
10984
+ x: seg.labelX,
10985
+ y: seg.labelY,
10986
+ textAnchor: seg.labelX > center ? "start" : "end",
10987
+ fontSize: "10",
10988
+ className: "text-foreground",
10989
+ fill: "currentColor",
10990
+ style: animated ? { opacity: 0, animation: `fadeIn 0.3s ease-out ${i * 0.1 + 0.3}s forwards` } : void 0,
10991
+ children: showPercentage ? `${(seg.percentage * 100).toFixed(0)}%` : seg.value
10992
+ }
10993
+ )
10994
+ ]
10995
+ },
10996
+ i
10997
+ )),
10998
+ donut && /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("g", { children: [
10999
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("text", { x: center, y: center - 5, textAnchor: "middle", fontSize: "12", className: "text-muted-foreground", fill: "currentColor", children: "Total" }),
11000
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("text", { x: center, y: center + 15, textAnchor: "middle", fontSize: "18", fontWeight: "600", className: "text-foreground", fill: "currentColor", children: total })
11001
+ ] })
11002
+ ] }),
11003
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("style", { children: `
11004
+ @keyframes pieSlice {
11005
+ from {
11006
+ opacity: 0;
11007
+ transform: scale(0);
11008
+ }
11009
+ to {
11010
+ opacity: 1;
11011
+ transform: scale(1);
11012
+ }
11013
+ }
11014
+ @keyframes fadeIn {
11015
+ from { opacity: 0; }
11016
+ to { opacity: 1; }
11017
+ }
11018
+ ` })
11019
+ ] }),
11020
+ showLegend && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "flex flex-col gap-2", children: segments.map((seg, i) => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
11021
+ "div",
11022
+ {
11023
+ className: "flex items-center gap-2 text-sm",
11024
+ style: animated ? { opacity: 0, animation: `fadeIn 0.3s ease-out ${i * 0.1 + 0.3}s forwards` } : void 0,
11025
+ children: [
11026
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "w-3 h-3 rounded-sm shrink-0", style: { backgroundColor: seg.color } }),
11027
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "text-muted-foreground", children: seg.label }),
11028
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "text-foreground font-medium ml-auto", children: showPercentage ? `${(seg.percentage * 100).toFixed(0)}%` : seg.value })
11029
+ ]
11030
+ },
11031
+ i
11032
+ )) }),
11033
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
11034
+ ChartTooltip,
11035
+ {
11036
+ x: hoveredSegment?.x ?? center,
11037
+ y: hoveredSegment?.y ?? center,
11038
+ visible: !!hoveredSegment,
11039
+ label: hoveredSegment?.label,
11040
+ value: `${hoveredSegment?.value} (${((hoveredSegment?.percentage ?? 0) * 100).toFixed(1)}%)`,
11041
+ color: hoveredSegment?.color,
11042
+ containerRef
11043
+ }
11044
+ )
11045
+ ] });
11046
+ }
11047
+
11048
+ // ../../components/ui/AreaChart.tsx
11049
+ var import_react26 = require("react");
11050
+ var import_jsx_runtime49 = require("react/jsx-runtime");
11051
+ function getCatmullRomSpline(points) {
11052
+ if (points.length < 2) return "";
11053
+ if (points.length === 2) {
11054
+ return `M ${points[0].x} ${points[0].y} L ${points[1].x} ${points[1].y}`;
11055
+ }
11056
+ let path = `M ${points[0].x} ${points[0].y}`;
11057
+ for (let i = 0; i < points.length - 1; i++) {
11058
+ const p0 = points[Math.max(0, i - 1)];
11059
+ const p1 = points[i];
11060
+ const p2 = points[i + 1];
11061
+ const p3 = points[Math.min(points.length - 1, i + 2)];
11062
+ const tension = 0.5;
11063
+ const cp1x = p1.x + (p2.x - p0.x) * tension / 6;
11064
+ const cp1y = p1.y + (p2.y - p0.y) * tension / 6;
11065
+ const cp2x = p2.x - (p3.x - p1.x) * tension / 6;
11066
+ const cp2y = p2.y - (p3.y - p1.y) * tension / 6;
11067
+ path += ` C ${cp1x} ${cp1y}, ${cp2x} ${cp2y}, ${p2.x} ${p2.y}`;
11068
+ }
11069
+ return path;
11070
+ }
11071
+ function AreaChart({
11072
+ series,
11073
+ width = 400,
11074
+ height = 200,
11075
+ showDots = true,
11076
+ showGrid = true,
11077
+ showLabels = true,
11078
+ showLegend = true,
11079
+ animated = true,
11080
+ stacked = false,
11081
+ curved = true,
11082
+ className = ""
11083
+ }) {
11084
+ const containerRef = (0, import_react26.useRef)(null);
11085
+ const padding = { top: 20, right: 20, bottom: 40, left: 50 };
11086
+ const chartWidth = width - padding.left - padding.right;
11087
+ const chartHeight = height - padding.top - padding.bottom;
11088
+ const [hoveredPoint, setHoveredPoint] = (0, import_react26.useState)(null);
11089
+ const { processedSeries, gridLines, maxValue, labels } = (0, import_react26.useMemo)(() => {
11090
+ if (!series.length || !series[0]?.data?.length) {
11091
+ return { processedSeries: [], gridLines: [], maxValue: 0, labels: [] };
11092
+ }
11093
+ const allLabels = series[0].data.map((d) => d.label);
11094
+ const dataLength = series[0].data.length;
11095
+ let max = 0;
11096
+ if (stacked) {
11097
+ for (let i = 0; i < dataLength; i++) {
11098
+ const stackedValue = series.reduce((sum, s) => sum + (s.data[i]?.value || 0), 0);
11099
+ max = Math.max(max, stackedValue);
11100
+ }
11101
+ } else {
11102
+ max = Math.max(...series.flatMap((s) => s.data.map((d) => d.value)));
11103
+ }
11104
+ const processed = series.map((s, seriesIndex) => {
11105
+ const points = s.data.map((d, i) => {
11106
+ const x = padding.left + i / (dataLength - 1) * chartWidth;
11107
+ let y;
11108
+ if (stacked && seriesIndex > 0) {
11109
+ const stackedBase = series.slice(0, seriesIndex).reduce((sum, prevS) => sum + (prevS.data[i]?.value || 0), 0);
11110
+ const stackedValue = stackedBase + d.value;
11111
+ y = padding.top + chartHeight - stackedValue / max * chartHeight;
11112
+ } else {
11113
+ y = padding.top + chartHeight - d.value / max * chartHeight;
11114
+ }
11115
+ return { x, y, value: d.value, label: d.label };
11116
+ });
11117
+ const linePath = curved ? getCatmullRomSpline(points) : `M ${points.map((p) => `${p.x} ${p.y}`).join(" L ")}`;
11118
+ let areaPath;
11119
+ if (stacked && seriesIndex > 0) {
11120
+ const prevSeriesPoints = series.slice(0, seriesIndex).reduce((acc, prevS) => {
11121
+ return prevS.data.map((d, i) => {
11122
+ const prevVal = acc[i] || 0;
11123
+ return prevVal + d.value;
11124
+ });
11125
+ }, []).map((val, i) => ({
11126
+ x: padding.left + i / (dataLength - 1) * chartWidth,
11127
+ y: padding.top + chartHeight - val / max * chartHeight
11128
+ }));
11129
+ const reversedPrevPoints = [...prevSeriesPoints].reverse();
11130
+ areaPath = `${linePath} L ${reversedPrevPoints.map((p) => `${p.x} ${p.y}`).join(" L ")} Z`;
11131
+ } else {
11132
+ areaPath = `${linePath} L ${padding.left + chartWidth} ${padding.top + chartHeight} L ${padding.left} ${padding.top + chartHeight} Z`;
11133
+ }
11134
+ return {
11135
+ ...s,
11136
+ points,
11137
+ linePath,
11138
+ areaPath,
11139
+ lineLength: points.reduce((acc, p, i) => {
11140
+ if (i === 0) return 0;
11141
+ const prev = points[i - 1];
11142
+ return acc + Math.sqrt(Math.pow(p.x - prev.x, 2) + Math.pow(p.y - prev.y, 2));
11143
+ }, 0)
11144
+ };
11145
+ });
11146
+ const lines = [];
11147
+ const steps = 5;
11148
+ for (let i = 0; i <= steps; i++) {
11149
+ const value = i / steps * max;
11150
+ lines.push({
11151
+ y: padding.top + chartHeight - i / steps * chartHeight,
11152
+ value
11153
+ });
11154
+ }
11155
+ return { processedSeries: processed, gridLines: lines, maxValue: max, labels: allLabels };
11156
+ }, [series, chartWidth, chartHeight, padding, stacked, curved]);
11157
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { ref: containerRef, className: `relative flex flex-col gap-4 ${className}`, children: [
11158
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("svg", { width, height, className: "overflow-visible", style: { fontFamily: "inherit" }, children: [
11159
+ showGrid && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("g", { className: "text-muted-foreground/20", children: gridLines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("g", { children: [
11160
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("line", { x1: padding.left, y1: line.y, x2: width - padding.right, y2: line.y, stroke: "currentColor", strokeDasharray: "4 4" }),
11161
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("text", { x: padding.left - 8, y: line.y + 4, textAnchor: "end", fontSize: "10", className: "text-muted-foreground", fill: "currentColor", children: line.value.toFixed(0) })
11162
+ ] }, i)) }),
11163
+ [...processedSeries].reverse().map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
11164
+ "path",
11165
+ {
11166
+ d: s.areaPath,
11167
+ fill: s.color,
11168
+ fillOpacity: s.fillOpacity ?? 0.3,
11169
+ className: "transition-all duration-300",
11170
+ style: animated ? {
11171
+ opacity: 0,
11172
+ animation: `fadeIn 0.5s ease-out ${i * 0.1}s forwards`
11173
+ } : void 0
11174
+ },
11175
+ `area-${i}`
11176
+ )),
11177
+ processedSeries.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
11178
+ "path",
11179
+ {
11180
+ d: s.linePath,
11181
+ fill: "none",
11182
+ stroke: s.color,
11183
+ strokeWidth: 2,
11184
+ strokeLinecap: "round",
11185
+ strokeLinejoin: "round",
11186
+ style: animated ? {
11187
+ strokeDasharray: s.lineLength,
11188
+ strokeDashoffset: s.lineLength,
11189
+ animation: `drawLine 1s ease-out ${i * 0.1}s forwards`
11190
+ } : void 0
11191
+ },
11192
+ `line-${i}`
11193
+ )),
11194
+ showDots && processedSeries.map(
11195
+ (s, seriesIdx) => s.points.map((point, i) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
11196
+ "g",
11197
+ {
11198
+ onMouseEnter: () => {
11199
+ const items = processedSeries.map((ps) => ({
11200
+ label: ps.name,
11201
+ value: ps.points[i]?.value ?? 0,
11202
+ color: ps.color
11203
+ }));
11204
+ setHoveredPoint({
11205
+ x: point.x,
11206
+ y: point.y,
11207
+ label: point.label,
11208
+ items
11209
+ });
11210
+ },
11211
+ onMouseLeave: () => setHoveredPoint(null),
11212
+ className: "cursor-pointer",
11213
+ children: [
11214
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
11215
+ "circle",
11216
+ {
11217
+ cx: point.x,
11218
+ cy: point.y,
11219
+ r: hoveredPoint?.x === point.x ? 6 : 4,
11220
+ fill: s.color,
11221
+ className: "transition-all duration-150",
11222
+ style: animated ? {
11223
+ transform: "scale(0)",
11224
+ opacity: 0,
11225
+ transformOrigin: `${point.x}px ${point.y}px`,
11226
+ animation: `dotPop 0.3s ease-out ${seriesIdx * 0.1 + i * 0.05 + 0.5}s forwards`
11227
+ } : void 0
11228
+ }
11229
+ ),
11230
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("circle", { cx: point.x, cy: point.y, r: 12, fill: "transparent" })
11231
+ ]
11232
+ },
11233
+ `dot-${seriesIdx}-${i}`
11234
+ ))
11235
+ ),
11236
+ showLabels && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("g", { className: "text-muted-foreground", children: labels.map((label, i) => {
11237
+ const x = padding.left + i / (labels.length - 1) * chartWidth;
11238
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("text", { x, y: height - 10, textAnchor: "middle", fontSize: "10", fill: "currentColor", children: label }, i);
11239
+ }) }),
11240
+ hoveredPoint && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("g", { className: "pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
11241
+ "line",
11242
+ {
11243
+ x1: hoveredPoint.x,
11244
+ y1: padding.top,
11245
+ x2: hoveredPoint.x,
11246
+ y2: padding.top + chartHeight,
11247
+ stroke: "currentColor",
11248
+ strokeWidth: 1,
11249
+ strokeDasharray: "4 4",
11250
+ opacity: 0.3,
11251
+ className: "text-foreground"
11252
+ }
11253
+ ) }),
11254
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("style", { children: `
11255
+ @keyframes drawLine {
11256
+ to {
11257
+ stroke-dashoffset: 0;
11258
+ }
11259
+ }
11260
+ @keyframes fadeIn {
11261
+ from { opacity: 0; }
11262
+ to { opacity: 1; }
11263
+ }
11264
+ @keyframes dotPop {
11265
+ from {
11266
+ transform: scale(0);
11267
+ opacity: 0;
11268
+ }
11269
+ to {
11270
+ transform: scale(1);
11271
+ opacity: 1;
11272
+ }
11273
+ }
11274
+ ` })
11275
+ ] }),
11276
+ showLegend && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "flex items-center justify-center gap-6", children: series.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
11277
+ "div",
11278
+ {
11279
+ className: "flex items-center gap-2 text-sm",
11280
+ style: animated ? { opacity: 0, animation: `fadeIn 0.3s ease-out ${i * 0.1 + 0.5}s forwards` } : void 0,
11281
+ children: [
11282
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "w-3 h-3 rounded-sm", style: { backgroundColor: s.color } }),
11283
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-muted-foreground", children: s.name })
11284
+ ]
11285
+ },
11286
+ i
11287
+ )) }),
11288
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
11289
+ ChartTooltip,
11290
+ {
11291
+ x: hoveredPoint?.x ?? 0,
11292
+ y: hoveredPoint?.y ?? 0,
11293
+ visible: !!hoveredPoint,
11294
+ label: hoveredPoint?.label,
11295
+ items: hoveredPoint?.items,
11296
+ containerRef
11297
+ }
11298
+ )
11299
+ ] });
11300
+ }
11301
+
11302
+ // ../../components/ui/Sparkline.tsx
11303
+ var import_react27 = require("react");
11304
+ var import_jsx_runtime50 = require("react/jsx-runtime");
11305
+ function getCatmullRomSpline2(points) {
11306
+ if (points.length < 2) return "";
11307
+ if (points.length === 2) {
11308
+ return `M ${points[0].x} ${points[0].y} L ${points[1].x} ${points[1].y}`;
11309
+ }
11310
+ let path = `M ${points[0].x} ${points[0].y}`;
11311
+ for (let i = 0; i < points.length - 1; i++) {
11312
+ const p0 = points[Math.max(0, i - 1)];
11313
+ const p1 = points[i];
11314
+ const p2 = points[i + 1];
11315
+ const p3 = points[Math.min(points.length - 1, i + 2)];
11316
+ const tension = 0.5;
11317
+ const cp1x = p1.x + (p2.x - p0.x) * tension / 6;
11318
+ const cp1y = p1.y + (p2.y - p0.y) * tension / 6;
11319
+ const cp2x = p2.x - (p3.x - p1.x) * tension / 6;
11320
+ const cp2y = p2.y - (p3.y - p1.y) * tension / 6;
11321
+ path += ` C ${cp1x} ${cp1y}, ${cp2x} ${cp2y}, ${p2.x} ${p2.y}`;
11322
+ }
11323
+ return path;
11324
+ }
11325
+ function Sparkline({
11326
+ data,
11327
+ width = 100,
11328
+ height = 30,
11329
+ color = "currentColor",
11330
+ fillColor,
11331
+ showFill = true,
11332
+ showDots = false,
11333
+ showEndDot = true,
11334
+ animated = true,
11335
+ curved = true,
11336
+ strokeWidth = 2,
11337
+ className = ""
11338
+ }) {
11339
+ const padding = 4;
11340
+ const chartWidth = width - padding * 2;
11341
+ const chartHeight = height - padding * 2;
11342
+ const { points, linePath, areaPath, lineLength, trend } = (0, import_react27.useMemo)(() => {
11343
+ const normalizedData = data.map((d) => typeof d === "number" ? d : d.value);
11344
+ if (!normalizedData.length) {
11345
+ return { points: [], linePath: "", areaPath: "", lineLength: 0, trend: 0 };
11346
+ }
11347
+ const min = Math.min(...normalizedData);
11348
+ const max = Math.max(...normalizedData);
11349
+ const range = max - min || 1;
11350
+ const pts = normalizedData.map((value, i) => ({
11351
+ x: padding + i / (normalizedData.length - 1) * chartWidth,
11352
+ y: padding + chartHeight - (value - min) / range * chartHeight,
11353
+ value
11354
+ }));
11355
+ const line = curved ? getCatmullRomSpline2(pts) : `M ${pts.map((p) => `${p.x} ${p.y}`).join(" L ")}`;
11356
+ const area = `${line} L ${padding + chartWidth} ${padding + chartHeight} L ${padding} ${padding + chartHeight} Z`;
11357
+ const length = pts.reduce((acc, p, i) => {
11358
+ if (i === 0) return 0;
11359
+ const prev = pts[i - 1];
11360
+ return acc + Math.sqrt(Math.pow(p.x - prev.x, 2) + Math.pow(p.y - prev.y, 2));
11361
+ }, 0);
11362
+ const trendValue = normalizedData[normalizedData.length - 1] - normalizedData[0];
11363
+ return { points: pts, linePath: line, areaPath: area, lineLength: length, trend: trendValue };
11364
+ }, [data, chartWidth, chartHeight, padding, curved]);
11365
+ const effectiveFillColor = fillColor || color;
11366
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("svg", { width, height, className: `overflow-visible ${className}`, style: { fontFamily: "inherit" }, children: [
11367
+ showFill && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
11368
+ "path",
11369
+ {
11370
+ d: areaPath,
11371
+ fill: effectiveFillColor,
11372
+ fillOpacity: 0.1,
11373
+ style: animated ? { opacity: 0, animation: "fadeIn 0.5s ease-out 0.3s forwards" } : void 0
11374
+ }
11375
+ ),
11376
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
11377
+ "path",
11378
+ {
11379
+ d: linePath,
11380
+ fill: "none",
11381
+ stroke: color,
11382
+ strokeWidth,
11383
+ strokeLinecap: "round",
11384
+ strokeLinejoin: "round",
11385
+ style: animated ? {
11386
+ strokeDasharray: lineLength,
11387
+ strokeDashoffset: lineLength,
11388
+ animation: "drawLine 0.8s ease-out forwards"
11389
+ } : void 0
11390
+ }
11391
+ ),
11392
+ showDots && points.map((point, i) => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
11393
+ "circle",
11394
+ {
11395
+ cx: point.x,
11396
+ cy: point.y,
11397
+ r: 2,
11398
+ fill: color,
11399
+ style: animated ? {
11400
+ opacity: 0,
11401
+ animation: `fadeIn 0.3s ease-out ${i * 0.05 + 0.5}s forwards`
11402
+ } : void 0
11403
+ },
11404
+ i
11405
+ )),
11406
+ showEndDot && !showDots && points.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
11407
+ "circle",
11408
+ {
11409
+ cx: points[points.length - 1].x,
11410
+ cy: points[points.length - 1].y,
11411
+ r: 3,
11412
+ fill: color,
11413
+ style: animated ? {
11414
+ opacity: 0,
11415
+ transform: "scale(0)",
11416
+ transformOrigin: `${points[points.length - 1].x}px ${points[points.length - 1].y}px`,
11417
+ animation: "dotPop 0.3s ease-out 0.6s forwards"
11418
+ } : void 0
11419
+ }
11420
+ ),
11421
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("style", { children: `
11422
+ @keyframes drawLine {
11423
+ to {
11424
+ stroke-dashoffset: 0;
11425
+ }
11426
+ }
11427
+ @keyframes fadeIn {
11428
+ from { opacity: 0; }
11429
+ to { opacity: 1; }
11430
+ }
11431
+ @keyframes dotPop {
11432
+ from {
11433
+ transform: scale(0);
11434
+ opacity: 0;
11435
+ }
11436
+ to {
11437
+ transform: scale(1);
11438
+ opacity: 1;
11439
+ }
11440
+ }
11441
+ ` })
11442
+ ] });
11443
+ }
11444
+
11445
+ // ../../components/ui/RadarChart.tsx
11446
+ var import_react28 = require("react");
11447
+ var import_jsx_runtime51 = require("react/jsx-runtime");
11448
+ function RadarChart({
11449
+ series,
11450
+ size = 300,
11451
+ levels = 5,
11452
+ showLabels = true,
11453
+ showLegend = true,
11454
+ showValues = false,
11455
+ animated = true,
11456
+ className = ""
11457
+ }) {
11458
+ const containerRef = (0, import_react28.useRef)(null);
11459
+ const center = size / 2;
11460
+ const radius = size / 2 - 40;
11461
+ const [hoveredPoint, setHoveredPoint] = (0, import_react28.useState)(null);
11462
+ const { axes, processedSeries, levelPaths } = (0, import_react28.useMemo)(() => {
11463
+ if (!series.length || !series[0]?.data?.length) {
11464
+ return { axes: [], processedSeries: [], levelPaths: [] };
11465
+ }
11466
+ const axisLabels = series[0].data.map((d) => d.axis);
11467
+ const axisCount = axisLabels.length;
11468
+ const angleStep = 2 * Math.PI / axisCount;
11469
+ const maxValue = Math.max(...series.flatMap((s) => s.data.map((d) => d.value)));
11470
+ const axesData = axisLabels.map((label, i) => {
11471
+ const angle = i * angleStep - Math.PI / 2;
11472
+ const x = center + radius * Math.cos(angle);
11473
+ const y = center + radius * Math.sin(angle);
11474
+ const labelX = center + (radius + 20) * Math.cos(angle);
11475
+ const labelY = center + (radius + 20) * Math.sin(angle);
11476
+ return { label, x, y, labelX, labelY, angle };
11477
+ });
11478
+ const levelsData = [];
11479
+ for (let l = 1; l <= levels; l++) {
11480
+ const levelRadius = l / levels * radius;
11481
+ const points = axisLabels.map((_, i) => {
11482
+ const angle = i * angleStep - Math.PI / 2;
11483
+ return {
11484
+ x: center + levelRadius * Math.cos(angle),
11485
+ y: center + levelRadius * Math.sin(angle)
11486
+ };
11487
+ });
11488
+ levelsData.push({
11489
+ path: `M ${points.map((p) => `${p.x} ${p.y}`).join(" L ")} Z`,
11490
+ level: l,
11491
+ value: l / levels * maxValue
11492
+ });
11493
+ }
11494
+ const processed = series.map((s) => {
11495
+ const points = s.data.map((d, i) => {
11496
+ const angle = i * angleStep - Math.PI / 2;
11497
+ const r = d.value / maxValue * radius;
11498
+ return {
11499
+ x: center + r * Math.cos(angle),
11500
+ y: center + r * Math.sin(angle),
11501
+ value: d.value
11502
+ };
11503
+ });
11504
+ return {
11505
+ ...s,
11506
+ points,
11507
+ path: `M ${points.map((p) => `${p.x} ${p.y}`).join(" L ")} Z`
11508
+ };
11509
+ });
11510
+ return { axes: axesData, processedSeries: processed, levelPaths: levelsData };
11511
+ }, [series, center, radius, levels]);
11512
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { ref: containerRef, className: `relative flex flex-col gap-4 ${className}`, children: [
11513
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("svg", { width: size, height: size, className: "overflow-visible", style: { fontFamily: "inherit" }, children: [
11514
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("g", { className: "text-muted-foreground/20", children: levelPaths.map((level, i) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("path", { d: level.path, fill: "none", stroke: "currentColor", strokeWidth: 1 }, i)) }),
11515
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("g", { className: "text-muted-foreground/30", children: axes.map((axis, i) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("line", { x1: center, y1: center, x2: axis.x, y2: axis.y, stroke: "currentColor", strokeWidth: 1 }, i)) }),
11516
+ processedSeries.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("g", { children: [
11517
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
11518
+ "path",
11519
+ {
11520
+ d: s.path,
11521
+ fill: s.color,
11522
+ fillOpacity: s.fillOpacity ?? 0.2,
11523
+ stroke: s.color,
11524
+ strokeWidth: 2,
11525
+ strokeLinejoin: "round",
11526
+ className: "transition-all duration-300",
11527
+ style: animated ? {
11528
+ opacity: 0,
11529
+ transform: "scale(0)",
11530
+ transformOrigin: `${center}px ${center}px`,
11531
+ animation: `radarPop 0.5s ease-out ${i * 0.15}s forwards`
11532
+ } : void 0
11533
+ }
11534
+ ),
11535
+ s.points.map((point, j) => /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
11536
+ "g",
11537
+ {
11538
+ onMouseEnter: () => {
11539
+ const items = processedSeries.map((ps) => ({
11540
+ label: ps.name,
11541
+ value: ps.points[j]?.value ?? 0,
11542
+ color: ps.color
11543
+ }));
11544
+ setHoveredPoint({
11545
+ x: point.x,
11546
+ y: point.y,
11547
+ axis: series[0]?.data[j]?.axis ?? "",
11548
+ items
11549
+ });
11550
+ },
11551
+ onMouseLeave: () => setHoveredPoint(null),
11552
+ className: "cursor-pointer",
11553
+ children: [
11554
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
11555
+ "circle",
11556
+ {
11557
+ cx: point.x,
11558
+ cy: point.y,
11559
+ r: hoveredPoint?.axis === series[0]?.data[j]?.axis ? 6 : 4,
11560
+ fill: s.color,
11561
+ className: "transition-all duration-150",
11562
+ style: animated ? {
11563
+ opacity: 0,
11564
+ transform: "scale(0)",
11565
+ transformOrigin: `${point.x}px ${point.y}px`,
11566
+ animation: `dotPop 0.3s ease-out ${i * 0.15 + j * 0.05 + 0.3}s forwards`
11567
+ } : void 0
11568
+ }
11569
+ ),
11570
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("circle", { cx: point.x, cy: point.y, r: 12, fill: "transparent" })
11571
+ ]
11572
+ },
11573
+ j
11574
+ )),
11575
+ showValues && s.points.map((point, j) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
11576
+ "text",
11577
+ {
11578
+ x: point.x,
11579
+ y: point.y - 10,
11580
+ textAnchor: "middle",
11581
+ fontSize: "10",
11582
+ fontWeight: "500",
11583
+ className: "text-foreground",
11584
+ fill: "currentColor",
11585
+ style: animated ? { opacity: 0, animation: `fadeIn 0.3s ease-out ${i * 0.15 + 0.5}s forwards` } : void 0,
11586
+ children: point.value
11587
+ },
11588
+ `val-${j}`
11589
+ ))
11590
+ ] }, i)),
11591
+ showLabels && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("g", { className: "text-muted-foreground", children: axes.map((axis, i) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("text", { x: axis.labelX, y: axis.labelY, textAnchor: "middle", dominantBaseline: "middle", fontSize: "11", fill: "currentColor", children: axis.label }, i)) }),
11592
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("style", { children: `
11593
+ @keyframes radarPop {
11594
+ from {
11595
+ opacity: 0;
11596
+ transform: scale(0);
11597
+ }
11598
+ to {
11599
+ opacity: 1;
11600
+ transform: scale(1);
11601
+ }
11602
+ }
11603
+ @keyframes dotPop {
11604
+ from {
11605
+ transform: scale(0);
11606
+ opacity: 0;
11607
+ }
11608
+ to {
11609
+ transform: scale(1);
11610
+ opacity: 1;
11611
+ }
11612
+ }
11613
+ @keyframes fadeIn {
11614
+ from { opacity: 0; }
11615
+ to { opacity: 1; }
11616
+ }
11617
+ ` })
11618
+ ] }),
11619
+ showLegend && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "flex items-center justify-center gap-6", children: series.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
11620
+ "div",
11621
+ {
11622
+ className: "flex items-center gap-2 text-sm",
11623
+ style: animated ? { opacity: 0, animation: `fadeIn 0.3s ease-out ${i * 0.1 + 0.5}s forwards` } : void 0,
11624
+ children: [
11625
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "w-3 h-3 rounded-sm", style: { backgroundColor: s.color } }),
11626
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "text-muted-foreground", children: s.name })
11627
+ ]
11628
+ },
11629
+ i
11630
+ )) }),
11631
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
11632
+ ChartTooltip,
11633
+ {
11634
+ x: hoveredPoint?.x ?? 0,
11635
+ y: hoveredPoint?.y ?? 0,
11636
+ visible: !!hoveredPoint,
11637
+ label: hoveredPoint?.axis,
11638
+ items: hoveredPoint?.items,
11639
+ containerRef
11640
+ }
11641
+ )
11642
+ ] });
11643
+ }
11644
+
11645
+ // ../../components/ui/GaugeChart.tsx
11646
+ var import_react29 = require("react");
11647
+ var import_jsx_runtime52 = require("react/jsx-runtime");
11648
+ function GaugeChart({
11649
+ value,
11650
+ min = 0,
11651
+ max = 100,
11652
+ size = 200,
11653
+ thickness = 20,
11654
+ color = "currentColor",
11655
+ backgroundColor,
11656
+ showValue = true,
11657
+ showMinMax = true,
11658
+ label,
11659
+ animated = true,
11660
+ startAngle = -135,
11661
+ endAngle = 135,
11662
+ className = ""
11663
+ }) {
11664
+ const center = size / 2;
11665
+ const radius = center - thickness / 2 - 10;
11666
+ const { backgroundPath, valuePath, percentage, needleAngle } = (0, import_react29.useMemo)(() => {
11667
+ const normalizedValue = Math.min(Math.max(value, min), max);
11668
+ const pct = (normalizedValue - min) / (max - min);
11669
+ const totalAngle = endAngle - startAngle;
11670
+ const currentAngle = startAngle + pct * totalAngle;
11671
+ const polarToCartesian = (angle) => {
11672
+ const radians = angle * Math.PI / 180;
11673
+ return {
11674
+ x: center + radius * Math.cos(radians),
11675
+ y: center + radius * Math.sin(radians)
11676
+ };
11677
+ };
11678
+ const createArc = (start, end) => {
11679
+ const startPoint = polarToCartesian(start);
11680
+ const endPoint = polarToCartesian(end);
11681
+ const largeArc = Math.abs(end - start) > 180 ? 1 : 0;
11682
+ return `M ${startPoint.x} ${startPoint.y} A ${radius} ${radius} 0 ${largeArc} 1 ${endPoint.x} ${endPoint.y}`;
11683
+ };
11684
+ return {
11685
+ backgroundPath: createArc(startAngle, endAngle),
11686
+ valuePath: createArc(startAngle, currentAngle),
11687
+ percentage: pct,
11688
+ needleAngle: currentAngle
11689
+ };
11690
+ }, [value, min, max, center, radius, startAngle, endAngle]);
11691
+ const needleLength = radius - 10;
11692
+ const needleAngleRad = needleAngle * Math.PI / 180;
11693
+ const needleX = center + needleLength * Math.cos(needleAngleRad);
11694
+ const needleY = center + needleLength * Math.sin(needleAngleRad);
11695
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("svg", { width: size, height: size * 0.7, className: `overflow-visible ${className}`, style: { fontFamily: "inherit" }, children: [
11696
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
11697
+ "path",
11698
+ {
11699
+ d: backgroundPath,
11700
+ fill: "none",
11701
+ stroke: backgroundColor || "currentColor",
11702
+ strokeWidth: thickness,
11703
+ strokeLinecap: "round",
11704
+ className: !backgroundColor ? "text-muted-foreground/20" : ""
11705
+ }
11706
+ ),
11707
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
11708
+ "path",
11709
+ {
11710
+ d: valuePath,
11711
+ fill: "none",
11712
+ stroke: color,
11713
+ strokeWidth: thickness,
11714
+ strokeLinecap: "round",
11715
+ style: animated ? {
11716
+ strokeDasharray: "1000",
11717
+ strokeDashoffset: 1e3,
11718
+ animation: "drawArc 1s ease-out forwards"
11719
+ } : void 0
11720
+ }
11721
+ ),
11722
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(
11723
+ "g",
11724
+ {
11725
+ style: animated ? {
11726
+ transform: `rotate(${startAngle}deg)`,
11727
+ transformOrigin: `${center}px ${center}px`,
11728
+ animation: `needleRotate 1s ease-out forwards`,
11729
+ ["--needle-end"]: `${needleAngle}deg`
11730
+ } : {
11731
+ transform: `rotate(${needleAngle}deg)`,
11732
+ transformOrigin: `${center}px ${center}px`
11733
+ },
11734
+ children: [
11735
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("line", { x1: center, y1: center, x2: center + needleLength, y2: center, stroke: color, strokeWidth: 3, strokeLinecap: "round" }),
11736
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("circle", { cx: center, cy: center, r: 8, fill: color }),
11737
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("circle", { cx: center, cy: center, r: 4, className: "text-background", fill: "currentColor" })
11738
+ ]
11739
+ }
11740
+ ),
11741
+ showMinMax && /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("g", { className: "text-muted-foreground", children: [
11742
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
11743
+ "text",
11744
+ {
11745
+ x: center + (radius + 20) * Math.cos(startAngle * Math.PI / 180),
11746
+ y: center + (radius + 20) * Math.sin(startAngle * Math.PI / 180) + 5,
11747
+ textAnchor: "middle",
11748
+ fontSize: "10",
11749
+ fill: "currentColor",
11750
+ children: min
11751
+ }
11752
+ ),
11753
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
11754
+ "text",
11755
+ {
11756
+ x: center + (radius + 20) * Math.cos(endAngle * Math.PI / 180),
11757
+ y: center + (radius + 20) * Math.sin(endAngle * Math.PI / 180) + 5,
11758
+ textAnchor: "middle",
11759
+ fontSize: "10",
11760
+ fill: "currentColor",
11761
+ children: max
11762
+ }
11763
+ )
11764
+ ] }),
11765
+ showValue && /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("g", { children: [
11766
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
11767
+ "text",
11768
+ {
11769
+ x: center,
11770
+ y: center + 35,
11771
+ textAnchor: "middle",
11772
+ fontSize: "24",
11773
+ fontWeight: "600",
11774
+ className: "text-foreground",
11775
+ fill: "currentColor",
11776
+ style: animated ? { opacity: 0, animation: "fadeIn 0.5s ease-out 0.5s forwards" } : void 0,
11777
+ children: value
11778
+ }
11779
+ ),
11780
+ label && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
11781
+ "text",
11782
+ {
11783
+ x: center,
11784
+ y: center + 55,
11785
+ textAnchor: "middle",
11786
+ fontSize: "12",
11787
+ className: "text-muted-foreground",
11788
+ fill: "currentColor",
11789
+ style: animated ? { opacity: 0, animation: "fadeIn 0.5s ease-out 0.6s forwards" } : void 0,
11790
+ children: label
11791
+ }
11792
+ )
11793
+ ] }),
11794
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("style", { children: `
11795
+ @keyframes drawArc {
11796
+ to {
11797
+ stroke-dashoffset: 0;
11798
+ }
11799
+ }
11800
+ @keyframes needleRotate {
11801
+ to {
11802
+ transform: rotate(var(--needle-end));
11803
+ }
11804
+ }
11805
+ @keyframes fadeIn {
11806
+ from { opacity: 0; }
11807
+ to { opacity: 1; }
11808
+ }
11809
+ ` })
11810
+ ] });
11811
+ }
11812
+
11813
+ // ../../components/ui/ClientOnly.tsx
11814
+ var import_react30 = require("react");
11815
+ var import_jsx_runtime53 = require("react/jsx-runtime");
11816
+ function ClientOnly({ children, fallback = null }) {
11817
+ const [hasMounted, setHasMounted] = (0, import_react30.useState)(false);
11818
+ (0, import_react30.useEffect)(() => {
10448
11819
  setHasMounted(true);
10449
11820
  }, []);
10450
11821
  if (!hasMounted) {
10451
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_jsx_runtime45.Fragment, { children: fallback });
11822
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_jsx_runtime53.Fragment, { children: fallback });
10452
11823
  }
10453
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_jsx_runtime45.Fragment, { children });
11824
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_jsx_runtime53.Fragment, { children });
10454
11825
  }
10455
11826
 
10456
11827
  // ../../components/ui/Loading.tsx
10457
11828
  var import_lucide_react25 = require("lucide-react");
10458
- var import_jsx_runtime46 = require("react/jsx-runtime");
11829
+ var import_jsx_runtime54 = require("react/jsx-runtime");
10459
11830
  var LoadingSpinner = ({
10460
11831
  size = "md",
10461
11832
  className,
@@ -10471,7 +11842,7 @@ var LoadingSpinner = ({
10471
11842
  foreground: "text-foreground",
10472
11843
  muted: "text-muted-foreground"
10473
11844
  };
10474
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
11845
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
10475
11846
  import_lucide_react25.Activity,
10476
11847
  {
10477
11848
  className: cn(
@@ -10492,7 +11863,7 @@ var LoadingDots = ({
10492
11863
  foreground: "bg-foreground",
10493
11864
  muted: "bg-muted-foreground"
10494
11865
  };
10495
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: cn("flex items-center space-x-1", className), children: [0, 1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
11866
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: cn("flex items-center space-x-1", className), children: [0, 1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
10496
11867
  "div",
10497
11868
  {
10498
11869
  className: cn(
@@ -10514,7 +11885,7 @@ var LoadingBar = ({
10514
11885
  label
10515
11886
  }) => {
10516
11887
  const pct = progress ? Math.min(Math.max(progress, 0), 100) : void 0;
10517
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
11888
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
10518
11889
  "div",
10519
11890
  {
10520
11891
  className: cn("w-full bg-muted rounded-full h-2", className),
@@ -10523,7 +11894,7 @@ var LoadingBar = ({
10523
11894
  "aria-valuemax": pct === void 0 ? void 0 : 100,
10524
11895
  "aria-valuenow": pct === void 0 ? void 0 : Math.round(pct),
10525
11896
  "aria-label": label || "Loading",
10526
- children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
11897
+ children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
10527
11898
  "div",
10528
11899
  {
10529
11900
  className: cn(
@@ -10540,9 +11911,9 @@ var LoadingBar = ({
10540
11911
  };
10541
11912
 
10542
11913
  // ../../components/ui/Table.tsx
10543
- var import_react23 = __toESM(require("react"), 1);
10544
- var import_jsx_runtime47 = require("react/jsx-runtime");
10545
- var Table = import_react23.default.forwardRef(({ className, containerClassName, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
11914
+ var import_react31 = __toESM(require("react"), 1);
11915
+ var import_jsx_runtime55 = require("react/jsx-runtime");
11916
+ var Table = import_react31.default.forwardRef(({ className, containerClassName, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
10546
11917
  "div",
10547
11918
  {
10548
11919
  className: cn(
@@ -10552,20 +11923,20 @@ var Table = import_react23.default.forwardRef(({ className, containerClassName,
10552
11923
  "backdrop-blur-sm transition-all duration-300",
10553
11924
  containerClassName
10554
11925
  ),
10555
- children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("table", { ref, className: cn("w-full caption-bottom text-sm", className), ...props })
11926
+ children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("table", { ref, className: cn("w-full caption-bottom text-sm", className), ...props })
10556
11927
  }
10557
11928
  ));
10558
11929
  Table.displayName = "Table";
10559
- var TableHeader = import_react23.default.forwardRef(({ className, children, filterRow, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("thead", { ref, className: cn("[&_tr]:border-b [&_tr]:border-border", "bg-muted/50", className), ...props, children: [
11930
+ var TableHeader = import_react31.default.forwardRef(({ className, children, filterRow, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("thead", { ref, className: cn("[&_tr]:border-b [&_tr]:border-border", "bg-muted/50", className), ...props, children: [
10560
11931
  children,
10561
11932
  filterRow
10562
11933
  ] }));
10563
11934
  TableHeader.displayName = "TableHeader";
10564
- var TableBody = import_react23.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("tbody", { ref, className: cn("[&_tr:last-child]:border-0", className), ...props }));
11935
+ var TableBody = import_react31.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("tbody", { ref, className: cn("[&_tr:last-child]:border-0", className), ...props }));
10565
11936
  TableBody.displayName = "TableBody";
10566
- var TableFooter = import_react23.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("tfoot", { ref, className: cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className), ...props }));
11937
+ var TableFooter = import_react31.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("tfoot", { ref, className: cn("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0", className), ...props }));
10567
11938
  TableFooter.displayName = "TableFooter";
10568
- var TableRow = import_react23.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
11939
+ var TableRow = import_react31.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
10569
11940
  "tr",
10570
11941
  {
10571
11942
  ref,
@@ -10579,7 +11950,7 @@ var TableRow = import_react23.default.forwardRef(({ className, ...props }, ref)
10579
11950
  }
10580
11951
  ));
10581
11952
  TableRow.displayName = "TableRow";
10582
- var TableHead = import_react23.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
11953
+ var TableHead = import_react31.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
10583
11954
  "th",
10584
11955
  {
10585
11956
  ref,
@@ -10588,18 +11959,18 @@ var TableHead = import_react23.default.forwardRef(({ className, ...props }, ref)
10588
11959
  }
10589
11960
  ));
10590
11961
  TableHead.displayName = "TableHead";
10591
- var TableCell = import_react23.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("td", { ref, className: cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className), ...props }));
11962
+ var TableCell = import_react31.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("td", { ref, className: cn("p-4 align-middle [&:has([role=checkbox])]:pr-0", className), ...props }));
10592
11963
  TableCell.displayName = "TableCell";
10593
- var TableCaption = import_react23.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("caption", { ref, className: cn("mt-4 text-sm text-muted-foreground", className), ...props }));
11964
+ var TableCaption = import_react31.default.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("caption", { ref, className: cn("mt-4 text-sm text-muted-foreground", className), ...props }));
10594
11965
  TableCaption.displayName = "TableCaption";
10595
11966
 
10596
11967
  // ../../components/ui/DataTable.tsx
10597
11968
  var import_lucide_react26 = require("lucide-react");
10598
- var import_react24 = __toESM(require("react"), 1);
10599
- var import_jsx_runtime48 = require("react/jsx-runtime");
11969
+ var import_react32 = __toESM(require("react"), 1);
11970
+ var import_jsx_runtime56 = require("react/jsx-runtime");
10600
11971
  function useDebounced(value, delay = 300) {
10601
- const [debounced, setDebounced] = import_react24.default.useState(value);
10602
- import_react24.default.useEffect(() => {
11972
+ const [debounced, setDebounced] = import_react32.default.useState(value);
11973
+ import_react32.default.useEffect(() => {
10603
11974
  const id = setTimeout(() => setDebounced(value), delay);
10604
11975
  return () => clearTimeout(id);
10605
11976
  }, [value, delay]);
@@ -10628,15 +11999,15 @@ function DataTable({
10628
11999
  labels
10629
12000
  }) {
10630
12001
  const t = useTranslations("Common");
10631
- const [headerAlign, setHeaderAlign] = import_react24.default.useState("left");
10632
- const [visibleCols, setVisibleCols] = import_react24.default.useState(() => columns.filter((c) => c.visible !== false).map((c) => c.key));
10633
- const [filters, setFilters] = import_react24.default.useState({});
10634
- const [sort, setSort] = import_react24.default.useState(null);
10635
- const [density, setDensity] = import_react24.default.useState("normal");
10636
- const [curPage, setCurPage] = import_react24.default.useState(page);
10637
- const hasMounted = import_react24.default.useRef(false);
10638
- const loadedFromStorage = import_react24.default.useRef(false);
10639
- const getInitialPageSize = import_react24.default.useCallback(() => {
12002
+ const [headerAlign, setHeaderAlign] = import_react32.default.useState("left");
12003
+ const [visibleCols, setVisibleCols] = import_react32.default.useState(() => columns.filter((c) => c.visible !== false).map((c) => c.key));
12004
+ const [filters, setFilters] = import_react32.default.useState({});
12005
+ const [sort, setSort] = import_react32.default.useState(null);
12006
+ const [density, setDensity] = import_react32.default.useState("normal");
12007
+ const [curPage, setCurPage] = import_react32.default.useState(page);
12008
+ const hasMounted = import_react32.default.useRef(false);
12009
+ const loadedFromStorage = import_react32.default.useRef(false);
12010
+ const getInitialPageSize = import_react32.default.useCallback(() => {
10640
12011
  if (typeof window === "undefined" || !storageKey) return pageSize;
10641
12012
  try {
10642
12013
  const saved = localStorage.getItem(`datatable_${storageKey}_pageSize`);
@@ -10651,8 +12022,8 @@ function DataTable({
10651
12022
  }
10652
12023
  return pageSize;
10653
12024
  }, [storageKey, pageSize]);
10654
- const [curPageSize, setCurPageSize] = import_react24.default.useState(getInitialPageSize);
10655
- import_react24.default.useEffect(() => {
12025
+ const [curPageSize, setCurPageSize] = import_react32.default.useState(getInitialPageSize);
12026
+ import_react32.default.useEffect(() => {
10656
12027
  if (typeof window === "undefined" || !storageKey) return;
10657
12028
  if (!hasMounted.current) return;
10658
12029
  try {
@@ -10660,7 +12031,7 @@ function DataTable({
10660
12031
  } catch {
10661
12032
  }
10662
12033
  }, [curPageSize, storageKey]);
10663
- import_react24.default.useEffect(() => {
12034
+ import_react32.default.useEffect(() => {
10664
12035
  const newColKeys = columns.filter((c) => c.visible !== false).map((c) => c.key);
10665
12036
  setVisibleCols((prev) => {
10666
12037
  const uniqueKeys = /* @__PURE__ */ new Set([...prev, ...newColKeys]);
@@ -10668,16 +12039,16 @@ function DataTable({
10668
12039
  });
10669
12040
  }, [columns]);
10670
12041
  const debouncedFilters = useDebounced(filters, 350);
10671
- import_react24.default.useEffect(() => {
12042
+ import_react32.default.useEffect(() => {
10672
12043
  setCurPage(page);
10673
12044
  }, [page]);
10674
- import_react24.default.useEffect(() => {
12045
+ import_react32.default.useEffect(() => {
10675
12046
  if (storageKey && loadedFromStorage.current) {
10676
12047
  return;
10677
12048
  }
10678
12049
  setCurPageSize(pageSize);
10679
12050
  }, [pageSize, storageKey]);
10680
- import_react24.default.useEffect(() => {
12051
+ import_react32.default.useEffect(() => {
10681
12052
  if (!onQueryChange) return;
10682
12053
  if (!hasMounted.current) {
10683
12054
  hasMounted.current = true;
@@ -10700,7 +12071,7 @@ function DataTable({
10700
12071
  className: "h-8 w-full text-sm"
10701
12072
  };
10702
12073
  if (col.filter.type === "text") {
10703
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
12074
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
10704
12075
  Input_default,
10705
12076
  {
10706
12077
  ...commonProps,
@@ -10715,7 +12086,7 @@ function DataTable({
10715
12086
  }
10716
12087
  if (col.filter.type === "select") {
10717
12088
  const options = col.filter.options || [];
10718
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
12089
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
10719
12090
  Combobox,
10720
12091
  {
10721
12092
  options: ["", ...options],
@@ -10731,7 +12102,7 @@ function DataTable({
10731
12102
  );
10732
12103
  }
10733
12104
  if (col.filter.type === "date") {
10734
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
12105
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
10735
12106
  DatePicker,
10736
12107
  {
10737
12108
  placeholder: col.filter.placeholder || `Select ${String(col.title)}`,
@@ -10745,7 +12116,7 @@ function DataTable({
10745
12116
  }
10746
12117
  return null;
10747
12118
  };
10748
- const renderHeader = /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(TableRow, { children: visibleColumns.map((col, colIdx) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
12119
+ const renderHeader = /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(TableRow, { children: visibleColumns.map((col, colIdx) => /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
10749
12120
  TableHead,
10750
12121
  {
10751
12122
  style: { width: col.width },
@@ -10758,9 +12129,9 @@ function DataTable({
10758
12129
  children: (() => {
10759
12130
  const isRightAlign = col.align === "right" || !col.align && headerAlign === "right";
10760
12131
  const isCenterAlign = col.align === "center" || !col.align && headerAlign === "center";
10761
- const titleContent = /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-center gap-1 min-w-0 shrink", children: [
10762
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "truncate font-medium text-sm", children: col.title }),
10763
- col.sortable && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
12132
+ const titleContent = /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex items-center gap-1 min-w-0 shrink", children: [
12133
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "truncate font-medium text-sm", children: col.title }),
12134
+ col.sortable && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
10764
12135
  "button",
10765
12136
  {
10766
12137
  className: cn(
@@ -10777,8 +12148,8 @@ function DataTable({
10777
12148
  },
10778
12149
  "aria-label": "Sort",
10779
12150
  title: `Sort by ${String(col.title)}`,
10780
- children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 20 20", fill: "none", className: "inline-block", children: [
10781
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
12151
+ children: /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 20 20", fill: "none", className: "inline-block", children: [
12152
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
10782
12153
  "path",
10783
12154
  {
10784
12155
  d: "M7 8l3-3 3 3",
@@ -10789,7 +12160,7 @@ function DataTable({
10789
12160
  opacity: sort?.key === col.key && sort.order === "asc" ? 1 : 0.4
10790
12161
  }
10791
12162
  ),
10792
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
12163
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
10793
12164
  "path",
10794
12165
  {
10795
12166
  d: "M7 12l3 3 3-3",
@@ -10804,11 +12175,11 @@ function DataTable({
10804
12175
  }
10805
12176
  )
10806
12177
  ] });
10807
- const filterContent = col.filter && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
12178
+ const filterContent = col.filter && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
10808
12179
  Popover,
10809
12180
  {
10810
12181
  placement: isRightAlign ? "bottom-end" : "bottom-start",
10811
- trigger: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
12182
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
10812
12183
  "button",
10813
12184
  {
10814
12185
  className: cn(
@@ -10818,16 +12189,16 @@ function DataTable({
10818
12189
  ),
10819
12190
  "aria-label": "Filter",
10820
12191
  title: "Filter",
10821
- children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_lucide_react26.Filter, { className: "h-4 w-4" })
12192
+ children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_lucide_react26.Filter, { className: "h-4 w-4" })
10822
12193
  }
10823
12194
  ),
10824
- children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "w-48 p-2 space-y-2", children: [
10825
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "text-xs font-medium text-muted-foreground mb-2", children: [
12195
+ children: /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "w-48 p-2 space-y-2", children: [
12196
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "text-xs font-medium text-muted-foreground mb-2", children: [
10826
12197
  "Filter ",
10827
12198
  col.title
10828
12199
  ] }),
10829
12200
  renderFilterControl(col),
10830
- filters[col.key] && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
12201
+ filters[col.key] && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
10831
12202
  "button",
10832
12203
  {
10833
12204
  onClick: () => {
@@ -10845,7 +12216,7 @@ function DataTable({
10845
12216
  ] })
10846
12217
  }
10847
12218
  );
10848
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
12219
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
10849
12220
  "div",
10850
12221
  {
10851
12222
  className: cn(
@@ -10854,10 +12225,10 @@ function DataTable({
10854
12225
  isCenterAlign && "justify-center",
10855
12226
  !isRightAlign && !isCenterAlign && "justify-between"
10856
12227
  ),
10857
- children: isRightAlign ? /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_jsx_runtime48.Fragment, { children: [
12228
+ children: isRightAlign ? /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_jsx_runtime56.Fragment, { children: [
10858
12229
  filterContent,
10859
12230
  titleContent
10860
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_jsx_runtime48.Fragment, { children: [
12231
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_jsx_runtime56.Fragment, { children: [
10861
12232
  titleContent,
10862
12233
  filterContent
10863
12234
  ] })
@@ -10868,7 +12239,7 @@ function DataTable({
10868
12239
  col.key
10869
12240
  )) });
10870
12241
  const isServerMode = Boolean(onQueryChange);
10871
- const processedData = import_react24.default.useMemo(() => {
12242
+ const processedData = import_react32.default.useMemo(() => {
10872
12243
  if (isServerMode) return data;
10873
12244
  let result = [...data];
10874
12245
  if (Object.keys(filters).length > 0) {
@@ -10900,21 +12271,21 @@ function DataTable({
10900
12271
  return result;
10901
12272
  }, [data, isServerMode, filters, sort, columns]);
10902
12273
  const totalItems = isServerMode ? total : processedData.length;
10903
- const displayedData = isServerMode ? data : import_react24.default.useMemo(() => {
12274
+ const displayedData = isServerMode ? data : import_react32.default.useMemo(() => {
10904
12275
  const start = (curPage - 1) * curPageSize;
10905
12276
  if (start >= processedData.length && curPage > 1) {
10906
12277
  }
10907
12278
  return processedData.slice(start, start + curPageSize);
10908
12279
  }, [processedData, curPage, curPageSize]);
10909
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: cn("space-y-2", className), children: [
10910
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-center justify-between gap-4 mb-1", children: [
10911
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "text-sm text-muted-foreground", children: caption }),
10912
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-center gap-2", children: [
10913
- enableDensityToggle && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
12280
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: cn("space-y-2", className), children: [
12281
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex items-center justify-between gap-4 mb-1", children: [
12282
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "text-sm text-muted-foreground", children: caption }),
12283
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex items-center gap-2", children: [
12284
+ enableDensityToggle && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
10914
12285
  DropdownMenu_default,
10915
12286
  {
10916
- trigger: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(Button_default, { variant: "ghost", size: "sm", className: "h-8 px-2", children: [
10917
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("svg", { className: "w-4 h-4 mr-1", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 10h16M4 14h16M4 18h16" }) }),
12287
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(Button_default, { variant: "ghost", size: "sm", className: "h-8 px-2", children: [
12288
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("svg", { className: "w-4 h-4 mr-1", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 10h16M4 14h16M4 18h16" }) }),
10918
12289
  labels?.density || t("density")
10919
12290
  ] }),
10920
12291
  items: [
@@ -10924,11 +12295,11 @@ function DataTable({
10924
12295
  ]
10925
12296
  }
10926
12297
  ),
10927
- enableColumnVisibilityToggle && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
12298
+ enableColumnVisibilityToggle && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
10928
12299
  DropdownMenu_default,
10929
12300
  {
10930
- trigger: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(Button_default, { variant: "ghost", size: "sm", className: "h-8 px-2", children: [
10931
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("svg", { className: "w-4 h-4 mr-1", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
12301
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(Button_default, { variant: "ghost", size: "sm", className: "h-8 px-2", children: [
12302
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("svg", { className: "w-4 h-4 mr-1", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
10932
12303
  "path",
10933
12304
  {
10934
12305
  strokeLinecap: "round",
@@ -10939,26 +12310,26 @@ function DataTable({
10939
12310
  ) }),
10940
12311
  labels?.columns || t("columns")
10941
12312
  ] }),
10942
- children: columns.map((c) => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
12313
+ children: columns.map((c) => /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
10943
12314
  DropdownMenuItem,
10944
12315
  {
10945
12316
  onClick: () => {
10946
12317
  setVisibleCols((prev) => prev.includes(c.key) ? prev.filter((k) => k !== c.key) : [...prev, c.key]);
10947
12318
  },
10948
12319
  children: [
10949
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("input", { type: "checkbox", className: "mr-2 rounded border-border", readOnly: true, checked: visibleCols.includes(c.key) }),
10950
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "truncate", children: c.title })
12320
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("input", { type: "checkbox", className: "mr-2 rounded border-border", readOnly: true, checked: visibleCols.includes(c.key) }),
12321
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "truncate", children: c.title })
10951
12322
  ]
10952
12323
  },
10953
12324
  c.key
10954
12325
  ))
10955
12326
  }
10956
12327
  ),
10957
- enableHeaderAlignToggle && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
12328
+ enableHeaderAlignToggle && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
10958
12329
  DropdownMenu_default,
10959
12330
  {
10960
- trigger: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(Button_default, { variant: "ghost", size: "sm", className: "h-8 px-2", children: [
10961
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("svg", { className: "w-4 h-4 mr-1", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 12h10M4 18h16" }) }),
12331
+ trigger: /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(Button_default, { variant: "ghost", size: "sm", className: "h-8 px-2", children: [
12332
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("svg", { className: "w-4 h-4 mr-1", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 12h10M4 18h16" }) }),
10962
12333
  labels?.headerAlign || t("headerAlign")
10963
12334
  ] }),
10964
12335
  items: [
@@ -10971,17 +12342,17 @@ function DataTable({
10971
12342
  toolbar
10972
12343
  ] })
10973
12344
  ] }),
10974
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: cn("relative rounded-md border border-border/50 overflow-hidden", loading2 && "opacity-60 pointer-events-none"), children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
12345
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: cn("relative rounded-md border border-border/50 overflow-hidden", loading2 && "opacity-60 pointer-events-none"), children: /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
10975
12346
  Table,
10976
12347
  {
10977
12348
  containerClassName: "border-0 md:border-0 rounded-none md:rounded-none shadow-none bg-transparent",
10978
12349
  className: "[&_thead]:sticky [&_thead]:top-0 [&_thead]:z-5 [&_thead]:bg-background [&_thead]:backdrop-blur-sm",
10979
12350
  children: [
10980
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(TableHeader, { children: renderHeader }),
10981
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(TableBody, { children: loading2 ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(TableCell, { colSpan: visibleColumns.length, className: "text-center py-8", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "flex items-center justify-center gap-2 text-muted-foreground", children: [
10982
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("svg", { className: "animate-spin h-4 w-4", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
10983
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
10984
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
12351
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(TableHeader, { children: renderHeader }),
12352
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(TableBody, { children: loading2 ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(TableCell, { colSpan: visibleColumns.length, className: "text-center py-8", children: /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "flex items-center justify-center gap-2 text-muted-foreground", children: [
12353
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("svg", { className: "animate-spin h-4 w-4", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
12354
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
12355
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
10985
12356
  "path",
10986
12357
  {
10987
12358
  className: "opacity-75",
@@ -10990,12 +12361,12 @@ function DataTable({
10990
12361
  }
10991
12362
  )
10992
12363
  ] }),
10993
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "text-sm", children: "Loading..." })
10994
- ] }) }) }) : !displayedData || displayedData.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(TableCell, { colSpan: visibleColumns.length, className: "text-center py-6 text-muted-foreground", children: "No data" }) }) : displayedData.map((row, idx) => {
12364
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "text-sm", children: "Loading..." })
12365
+ ] }) }) }) : !displayedData || displayedData.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(TableCell, { colSpan: visibleColumns.length, className: "text-center py-6 text-muted-foreground", children: "No data" }) }) : displayedData.map((row, idx) => {
10995
12366
  const isLastRow = idx === displayedData.length - 1;
10996
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(TableRow, { className: cn(densityRowClass, striped && idx % 2 === 0 && "bg-muted/50"), children: visibleColumns.map((col, colIdx) => {
12367
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(TableRow, { className: cn(densityRowClass, striped && idx % 2 === 0 && "bg-muted/50"), children: visibleColumns.map((col, colIdx) => {
10997
12368
  const value = col.dataIndex ? row[col.dataIndex] : void 0;
10998
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
12369
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
10999
12370
  TableCell,
11000
12371
  {
11001
12372
  className: cn(
@@ -11015,7 +12386,7 @@ function DataTable({
11015
12386
  ]
11016
12387
  }
11017
12388
  ) }),
11018
- totalItems > 0 && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "border-t bg-muted/30 p-4 rounded-b-md", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
12389
+ totalItems > 0 && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "border-t bg-muted/30 p-4 rounded-b-md", children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
11019
12390
  Pagination,
11020
12391
  {
11021
12392
  page: curPage,
@@ -11037,10 +12408,10 @@ function DataTable({
11037
12408
  var DataTable_default = DataTable;
11038
12409
 
11039
12410
  // ../../components/ui/Form.tsx
11040
- var React40 = __toESM(require("react"), 1);
12411
+ var React48 = __toESM(require("react"), 1);
11041
12412
  var import_react_hook_form = require("react-hook-form");
11042
- var import_jsx_runtime49 = require("react/jsx-runtime");
11043
- var FormConfigContext = React40.createContext({ size: "md" });
12413
+ var import_jsx_runtime57 = require("react/jsx-runtime");
12414
+ var FormConfigContext = React48.createContext({ size: "md" });
11044
12415
  var FormWrapper = ({
11045
12416
  children,
11046
12417
  onSubmit,
@@ -11053,24 +12424,24 @@ var FormWrapper = ({
11053
12424
  const methods = (0, import_react_hook_form.useForm)({
11054
12425
  defaultValues: initialValues
11055
12426
  });
11056
- React40.useEffect(() => {
12427
+ React48.useEffect(() => {
11057
12428
  if (initialValues) {
11058
12429
  methods.reset(initialValues);
11059
12430
  }
11060
12431
  }, [JSON.stringify(initialValues)]);
11061
12432
  const { validationSchema: _, ...formProps } = props;
11062
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_react_hook_form.FormProvider, { ...methods, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(FormConfigContext.Provider, { value: { size }, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("form", { onSubmit: methods.handleSubmit(onSubmit), className, ...formProps, children }) }) });
12433
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_react_hook_form.FormProvider, { ...methods, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(FormConfigContext.Provider, { value: { size }, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("form", { onSubmit: methods.handleSubmit(onSubmit), className, ...formProps, children }) }) });
11063
12434
  };
11064
12435
  var Form = FormWrapper;
11065
- var FormFieldContext = React40.createContext({});
12436
+ var FormFieldContext = React48.createContext({});
11066
12437
  var FormField = ({
11067
12438
  ...props
11068
12439
  }) => {
11069
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_react_hook_form.Controller, { ...props }) });
12440
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_react_hook_form.Controller, { ...props }) });
11070
12441
  };
11071
12442
  var useFormField = () => {
11072
- const fieldContext = React40.useContext(FormFieldContext);
11073
- const itemContext = React40.useContext(FormItemContext);
12443
+ const fieldContext = React48.useContext(FormFieldContext);
12444
+ const itemContext = React48.useContext(FormItemContext);
11074
12445
  const { getFieldState, formState } = (0, import_react_hook_form.useFormContext)();
11075
12446
  if (!fieldContext) {
11076
12447
  try {
@@ -11091,27 +12462,27 @@ var useFormField = () => {
11091
12462
  ...fieldState
11092
12463
  };
11093
12464
  };
11094
- var FormItemContext = React40.createContext({});
11095
- var FormItem = React40.forwardRef(({ className, ...props }, ref) => {
11096
- const id = React40.useId();
11097
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { ref, className: cn("space-y-2", className), ...props }) });
12465
+ var FormItemContext = React48.createContext({});
12466
+ var FormItem = React48.forwardRef(({ className, ...props }, ref) => {
12467
+ const id = React48.useId();
12468
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { ref, className: cn("space-y-2", className), ...props }) });
11098
12469
  });
11099
12470
  FormItem.displayName = "FormItem";
11100
- var FormLabel = React40.forwardRef(
12471
+ var FormLabel = React48.forwardRef(
11101
12472
  ({ className, children, required, ...props }, ref) => {
11102
12473
  const { error, formItemId } = useFormField();
11103
- const config = React40.useContext(FormConfigContext);
12474
+ const config = React48.useContext(FormConfigContext);
11104
12475
  const sizeClass = config.size === "sm" ? "text-xs" : config.size === "lg" ? "text-base" : "text-sm";
11105
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(Label, { ref, className: cn(sizeClass, error && "text-destructive", className), htmlFor: formItemId, ...props, children: [
12476
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(Label, { ref, className: cn(sizeClass, error && "text-destructive", className), htmlFor: formItemId, ...props, children: [
11106
12477
  children,
11107
- required && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-destructive ml-1", children: "*" })
12478
+ required && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "text-destructive ml-1", children: "*" })
11108
12479
  ] });
11109
12480
  }
11110
12481
  );
11111
12482
  FormLabel.displayName = "FormLabel";
11112
- var FormControl = React40.forwardRef(({ ...props }, ref) => {
12483
+ var FormControl = React48.forwardRef(({ ...props }, ref) => {
11113
12484
  const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
11114
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
12485
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
11115
12486
  "div",
11116
12487
  {
11117
12488
  ref,
@@ -11123,37 +12494,37 @@ var FormControl = React40.forwardRef(({ ...props }, ref) => {
11123
12494
  );
11124
12495
  });
11125
12496
  FormControl.displayName = "FormControl";
11126
- var FormDescription = React40.forwardRef(({ className, ...props }, ref) => {
12497
+ var FormDescription = React48.forwardRef(({ className, ...props }, ref) => {
11127
12498
  const { formDescriptionId } = useFormField();
11128
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("p", { ref, id: formDescriptionId, className: cn("text-sm text-muted-foreground", className), ...props });
12499
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { ref, id: formDescriptionId, className: cn("text-sm text-muted-foreground", className), ...props });
11129
12500
  });
11130
12501
  FormDescription.displayName = "FormDescription";
11131
- var FormMessage = React40.forwardRef(({ className, children, ...props }, ref) => {
12502
+ var FormMessage = React48.forwardRef(({ className, children, ...props }, ref) => {
11132
12503
  const { error, formMessageId } = useFormField();
11133
12504
  const body = error ? String(error?.message) : children;
11134
12505
  if (!body) {
11135
12506
  return null;
11136
12507
  }
11137
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("p", { ref, id: formMessageId, className: cn("text-sm font-medium text-destructive", className), ...props, children: body });
12508
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { ref, id: formMessageId, className: cn("text-sm font-medium text-destructive", className), ...props, children: body });
11138
12509
  });
11139
12510
  FormMessage.displayName = "FormMessage";
11140
- var FormInput = React40.forwardRef(({ name, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(FormConfigContext.Consumer, { children: ({ size }) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
12511
+ var FormInput = React48.forwardRef(({ name, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(FormConfigContext.Consumer, { children: ({ size }) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
11141
12512
  FormField,
11142
12513
  {
11143
12514
  name,
11144
- render: ({ field }) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(FormItem, { children: [
11145
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(FormControl, { children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Input_default, { size: props.size ?? size, ...field, ...props }) }),
11146
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(FormMessage, {})
12515
+ render: ({ field }) => /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(FormItem, { children: [
12516
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(FormControl, { children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(Input_default, { size: props.size ?? size, ...field, ...props }) }),
12517
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(FormMessage, {})
11147
12518
  ] })
11148
12519
  }
11149
12520
  ) }));
11150
12521
  FormInput.displayName = "FormInput";
11151
- var FormCheckbox = React40.forwardRef(({ name, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(FormConfigContext.Consumer, { children: ({ size }) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
12522
+ var FormCheckbox = React48.forwardRef(({ name, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(FormConfigContext.Consumer, { children: ({ size }) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
11152
12523
  FormField,
11153
12524
  {
11154
12525
  name,
11155
- render: ({ field }) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(FormItem, { children: [
11156
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(FormControl, { children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
12526
+ render: ({ field }) => /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(FormItem, { children: [
12527
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(FormControl, { children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
11157
12528
  Checkbox,
11158
12529
  {
11159
12530
  ref,
@@ -11167,21 +12538,21 @@ var FormCheckbox = React40.forwardRef(({ name, ...props }, ref) => /* @__PURE__
11167
12538
  ...props
11168
12539
  }
11169
12540
  ) }),
11170
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(FormMessage, {})
12541
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(FormMessage, {})
11171
12542
  ] })
11172
12543
  }
11173
12544
  ) }));
11174
12545
  FormCheckbox.displayName = "FormCheckbox";
11175
- var FormActions = React40.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { ref, className: cn("flex gap-2 justify-end", className), ...props }));
12546
+ var FormActions = React48.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { ref, className: cn("flex gap-2 justify-end", className), ...props }));
11176
12547
  FormActions.displayName = "FormActions";
11177
- var FormSubmitButton = React40.forwardRef(
11178
- ({ children, loading: loading2, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(FormConfigContext.Consumer, { children: ({ size }) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(Button_default, { ref, type: "submit", size: props.size ?? size, disabled: loading2, ...props, children }) })
12548
+ var FormSubmitButton = React48.forwardRef(
12549
+ ({ children, loading: loading2, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(FormConfigContext.Consumer, { children: ({ size }) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(Button_default, { ref, type: "submit", size: props.size ?? size, disabled: loading2, ...props, children }) })
11179
12550
  );
11180
12551
  FormSubmitButton.displayName = "FormSubmitButton";
11181
12552
 
11182
12553
  // ../../components/ui/NotificationModal.tsx
11183
12554
  var import_lucide_react27 = require("lucide-react");
11184
- var import_jsx_runtime50 = require("react/jsx-runtime");
12555
+ var import_jsx_runtime58 = require("react/jsx-runtime");
11185
12556
  function NotificationModal({ isOpen, onClose, notification, titleText, openLinkText, closeText }) {
11186
12557
  const t = useTranslations("Common");
11187
12558
  if (!notification) return null;
@@ -11202,20 +12573,20 @@ function NotificationModal({ isOpen, onClose, notification, titleText, openLinkT
11202
12573
  onClose();
11203
12574
  }
11204
12575
  };
11205
- return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(Modal_default, { isOpen, onClose, title: titleText || t("notifications"), size: "md", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "space-y-4", children: [
11206
- /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "flex items-center gap-2 pb-2 border-b border-border", children: [
11207
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: cn("w-2 h-2 rounded-full", !notification.is_read ? "bg-primary" : "bg-border") }),
11208
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "text-xs text-muted-foreground", children: !notification.is_read ? t("newNotification") : t("readStatus") })
12576
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(Modal_default, { isOpen, onClose, title: titleText || t("notifications"), size: "md", children: /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "space-y-4", children: [
12577
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "flex items-center gap-2 pb-2 border-b border-border", children: [
12578
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: cn("w-2 h-2 rounded-full", !notification.is_read ? "bg-primary" : "bg-border") }),
12579
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "text-xs text-muted-foreground", children: !notification.is_read ? t("newNotification") : t("readStatus") })
11209
12580
  ] }),
11210
- notification.title && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("h3", { className: "text-lg font-semibold text-foreground", children: notification.title }),
11211
- notification.body && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "text-sm text-muted-foreground whitespace-pre-wrap leading-relaxed", children: notification.body }),
11212
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "text-xs text-muted-foreground border-t border-border pt-2", children: formatTime3(notification.created_at) }),
11213
- /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "flex gap-2 justify-end pt-2", children: [
11214
- hasLink && /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(Button_default, { variant: "primary", size: "sm", onClick: handleLinkClick, className: "gap-2", children: [
11215
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_lucide_react27.ExternalLink, { className: "w-4 h-4" }),
12581
+ notification.title && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("h3", { className: "text-lg font-semibold text-foreground", children: notification.title }),
12582
+ notification.body && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "text-sm text-muted-foreground whitespace-pre-wrap leading-relaxed", children: notification.body }),
12583
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "text-xs text-muted-foreground border-t border-border pt-2", children: formatTime3(notification.created_at) }),
12584
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "flex gap-2 justify-end pt-2", children: [
12585
+ hasLink && /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(Button_default, { variant: "primary", size: "sm", onClick: handleLinkClick, className: "gap-2", children: [
12586
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_lucide_react27.ExternalLink, { className: "w-4 h-4" }),
11216
12587
  openLinkText || t("openLink")
11217
12588
  ] }),
11218
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(Button_default, { variant: "ghost", size: "sm", onClick: onClose, children: closeText || t("close") })
12589
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(Button_default, { variant: "ghost", size: "sm", onClick: onClose, children: closeText || t("close") })
11219
12590
  ] })
11220
12591
  ] }) });
11221
12592
  }
@@ -11225,9 +12596,9 @@ var NotificationModal_default = NotificationModal;
11225
12596
  var import_link2 = __toESM(require("next/link"), 1);
11226
12597
  var import_navigation = require("next/navigation");
11227
12598
  var import_lucide_react28 = require("lucide-react");
11228
- var import_jsx_runtime51 = require("react/jsx-runtime");
12599
+ var import_jsx_runtime59 = require("react/jsx-runtime");
11229
12600
  function MessengerIcon(props) {
11230
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("svg", { viewBox: "0 0 24 24", width: 24, height: 24, "aria-hidden": "true", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
12601
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("svg", { viewBox: "0 0 24 24", width: 24, height: 24, "aria-hidden": "true", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
11231
12602
  "path",
11232
12603
  {
11233
12604
  d: "M12 2C6.477 2 2 6.145 2 11.235c0 2.93 1.35 5.542 3.464 7.25v3.515l3.344-1.836c.894.247 1.843.375 2.192.375 5.523 0 10-4.145 10-9.235S17.523 2 12 2zm.994 12.444l-2.563-2.73-5.004 2.73 5.507-5.84 2.626 2.729 4.942-2.729-5.508 5.84z",
@@ -11236,7 +12607,7 @@ function MessengerIcon(props) {
11236
12607
  ) });
11237
12608
  }
11238
12609
  function ZaloIcon(props) {
11239
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("svg", { viewBox: "0 0 48 48", width: 20, height: 20, "aria-hidden": "true", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
12610
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("svg", { viewBox: "0 0 48 48", width: 20, height: 20, "aria-hidden": "true", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
11240
12611
  "path",
11241
12612
  {
11242
12613
  fill: "white",
@@ -11245,7 +12616,7 @@ function ZaloIcon(props) {
11245
12616
  ) });
11246
12617
  }
11247
12618
  function InstagramIcon(props) {
11248
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("svg", { viewBox: "0 0 24 24", width: 20, height: 20, "aria-hidden": "true", fill: "white", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("path", { d: "M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z" }) });
12619
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("svg", { viewBox: "0 0 24 24", width: 20, height: 20, "aria-hidden": "true", fill: "white", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("path", { d: "M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.149 3.225-1.664 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.149-4.771-1.699-4.919-4.92-.058-1.265-.07-1.644-.07-4.849 0-3.204.013-3.583.07-4.849.149-3.227 1.664-4.771 4.919-4.919 1.266-.057 1.645-.069 4.849-.069zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.668.072 4.948.2 4.358 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.668-.014 4.948-.072 4.354-.2 6.782-2.618 6.979-6.98.059-1.28.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.196-4.354-2.617-6.78-6.979-6.98-1.281-.059-1.69-.073-4.949-.073zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z" }) });
11249
12620
  }
11250
12621
  function FloatingContacts({ className }) {
11251
12622
  const pathname = (0, import_navigation.usePathname)();
@@ -11280,8 +12651,8 @@ function FloatingContacts({ className }) {
11280
12651
  external: true
11281
12652
  }
11282
12653
  ];
11283
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: cn("fixed bottom-6 right-4 z-100000", "flex flex-col items-end gap-3", className), "aria-label": "Quick contacts", children: [
11284
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
12654
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: cn("fixed bottom-6 right-4 z-100000", "flex flex-col items-end gap-3", className), "aria-label": "Quick contacts", children: [
12655
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
11285
12656
  import_link2.default,
11286
12657
  {
11287
12658
  href: `tel:${hotline.replace(/\D/g, "")}`,
@@ -11292,10 +12663,10 @@ function FloatingContacts({ className }) {
11292
12663
  "hover:scale-105 active:scale-95 transition-transform",
11293
12664
  "bg-[#22c55e]"
11294
12665
  ),
11295
- children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_lucide_react28.Phone, { className: "w-6 h-6" })
12666
+ children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_lucide_react28.Phone, { className: "w-6 h-6" })
11296
12667
  }
11297
12668
  ),
11298
- moreItems.map(({ key, href, label, bg, Icon, external }) => /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
12669
+ moreItems.map(({ key, href, label, bg, Icon, external }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
11299
12670
  import_link2.default,
11300
12671
  {
11301
12672
  href,
@@ -11307,7 +12678,7 @@ function FloatingContacts({ className }) {
11307
12678
  "hover:scale-105 active:scale-95 transition-transform",
11308
12679
  bg
11309
12680
  ),
11310
- children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Icon, { className: "w-6 h-6" })
12681
+ children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(Icon, { className: "w-6 h-6" })
11311
12682
  },
11312
12683
  key
11313
12684
  ))
@@ -11316,7 +12687,7 @@ function FloatingContacts({ className }) {
11316
12687
 
11317
12688
  // ../../components/ui/AccessDenied.tsx
11318
12689
  var import_lucide_react29 = require("lucide-react");
11319
- var import_jsx_runtime52 = require("react/jsx-runtime");
12690
+ var import_jsx_runtime60 = require("react/jsx-runtime");
11320
12691
  var VARIANT_STYLES = {
11321
12692
  destructive: { bg: "bg-destructive/5", border: "border-destructive/20", text: "text-destructive" },
11322
12693
  warning: { bg: "bg-warning/5", border: "border-warning/20", text: "text-warning" },
@@ -11337,32 +12708,32 @@ function AccessDenied({
11337
12708
  }) {
11338
12709
  const styles = VARIANT_STYLES[variant];
11339
12710
  const UsedIcon = Icon || DEFAULT_ICONS[variant];
11340
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Card_default, { className: cn("p-8 text-center shadow-sm", styles.bg, styles.border, className), children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
11341
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: cn("p-3 rounded-lg", styles.bg.replace("/5", "/10")), children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(UsedIcon, { className: cn("w-8 h-8", styles.text) }) }),
11342
- /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { children: [
11343
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("h3", { className: cn("font-semibold mb-2", styles.text), children: title }),
11344
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("p", { className: cn(styles.text.replace("text-", "text-") + "/80", "text-sm"), children: description })
12711
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Card_default, { className: cn("p-8 text-center shadow-sm", styles.bg, styles.border, className), children: /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
12712
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: cn("p-3 rounded-lg", styles.bg.replace("/5", "/10")), children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(UsedIcon, { className: cn("w-8 h-8", styles.text) }) }),
12713
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { children: [
12714
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("h3", { className: cn("font-semibold mb-2", styles.text), children: title }),
12715
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { className: cn(styles.text.replace("text-", "text-") + "/80", "text-sm"), children: description })
11345
12716
  ] }),
11346
- children && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "mt-2 flex flex-wrap gap-2 justify-center", children })
12717
+ children && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "mt-2 flex flex-wrap gap-2 justify-center", children })
11347
12718
  ] }) });
11348
12719
  }
11349
12720
 
11350
12721
  // ../../components/ui/ThemeToggleHeadless.tsx
11351
12722
  var import_lucide_react30 = require("lucide-react");
11352
- var import_react25 = require("react");
11353
- var import_react_dom10 = require("react-dom");
11354
- var import_jsx_runtime53 = require("react/jsx-runtime");
12723
+ var import_react33 = require("react");
12724
+ var import_react_dom11 = require("react-dom");
12725
+ var import_jsx_runtime61 = require("react/jsx-runtime");
11355
12726
  function ThemeToggleHeadless({
11356
12727
  theme,
11357
12728
  onChange,
11358
12729
  labels,
11359
12730
  className
11360
12731
  }) {
11361
- const [isOpen, setIsOpen] = (0, import_react25.useState)(false);
11362
- const [mounted, setMounted] = (0, import_react25.useState)(false);
11363
- const triggerRef = (0, import_react25.useRef)(null);
11364
- const [dropdownPosition, setDropdownPosition] = (0, import_react25.useState)(null);
11365
- (0, import_react25.useEffect)(() => setMounted(true), []);
12732
+ const [isOpen, setIsOpen] = (0, import_react33.useState)(false);
12733
+ const [mounted, setMounted] = (0, import_react33.useState)(false);
12734
+ const triggerRef = (0, import_react33.useRef)(null);
12735
+ const [dropdownPosition, setDropdownPosition] = (0, import_react33.useState)(null);
12736
+ (0, import_react33.useEffect)(() => setMounted(true), []);
11366
12737
  const themes = [
11367
12738
  { value: "light", label: labels?.light ?? "Light", icon: import_lucide_react30.Sun },
11368
12739
  { value: "dark", label: labels?.dark ?? "Dark", icon: import_lucide_react30.Moon },
@@ -11380,8 +12751,8 @@ function ThemeToggleHeadless({
11380
12751
  const top = rect.bottom + scrollTop + 8;
11381
12752
  return { top, left, width };
11382
12753
  };
11383
- return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: cn("relative", className), children: [
11384
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
12754
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: cn("relative", className), children: [
12755
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
11385
12756
  Button_default,
11386
12757
  {
11387
12758
  variant: "ghost",
@@ -11399,25 +12770,25 @@ function ThemeToggleHeadless({
11399
12770
  "aria-haspopup": "menu",
11400
12771
  "aria-expanded": isOpen,
11401
12772
  "aria-label": labels?.heading ?? "Theme",
11402
- children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(CurrentIcon, { className: "h-5 w-5" })
12773
+ children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(CurrentIcon, { className: "h-5 w-5" })
11403
12774
  }
11404
12775
  ),
11405
- isOpen && /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_jsx_runtime53.Fragment, { children: [
11406
- typeof window !== "undefined" && (0, import_react_dom10.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "fixed inset-0 z-9998", onClick: () => setIsOpen(false) }), document.body),
11407
- typeof window !== "undefined" && dropdownPosition && (0, import_react_dom10.createPortal)(
11408
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
12776
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_jsx_runtime61.Fragment, { children: [
12777
+ typeof window !== "undefined" && (0, import_react_dom11.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "fixed inset-0 z-9998", onClick: () => setIsOpen(false) }), document.body),
12778
+ typeof window !== "undefined" && dropdownPosition && (0, import_react_dom11.createPortal)(
12779
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
11409
12780
  "div",
11410
12781
  {
11411
12782
  className: "z-9999 bg-card border border-border rounded-lg shadow-lg overflow-hidden",
11412
12783
  style: { position: "absolute", top: dropdownPosition.top, left: dropdownPosition.left, width: dropdownPosition.width },
11413
12784
  onMouseDown: (e) => e.stopPropagation(),
11414
12785
  role: "menu",
11415
- children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: "p-2", children: [
11416
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "px-3 py-2 text-sm font-medium text-muted-foreground border-b border-border mb-2", children: labels?.heading ?? "Theme" }),
12786
+ children: /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "p-2", children: [
12787
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "px-3 py-2 text-sm font-medium text-muted-foreground border-b border-border mb-2", children: labels?.heading ?? "Theme" }),
11417
12788
  themes.map((opt) => {
11418
12789
  const Icon = opt.icon;
11419
12790
  const active = theme === opt.value;
11420
- return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
12791
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(
11421
12792
  Button_default,
11422
12793
  {
11423
12794
  variant: "ghost",
@@ -11433,9 +12804,9 @@ function ThemeToggleHeadless({
11433
12804
  role: "menuitemradio",
11434
12805
  "aria-checked": active,
11435
12806
  children: [
11436
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Icon, { className: "h-4 w-4" }),
11437
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "flex-1 text-left", children: opt.label }),
11438
- active && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "w-2 h-2 rounded-full bg-primary" })
12807
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(Icon, { className: "h-4 w-4" }),
12808
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "flex-1 text-left", children: opt.label }),
12809
+ active && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "w-2 h-2 rounded-full bg-primary" })
11439
12810
  ]
11440
12811
  },
11441
12812
  opt.value
@@ -11451,10 +12822,10 @@ function ThemeToggleHeadless({
11451
12822
  }
11452
12823
 
11453
12824
  // ../../components/ui/LanguageSwitcherHeadless.tsx
11454
- var import_react26 = require("react");
11455
- var import_react_dom11 = require("react-dom");
12825
+ var import_react34 = require("react");
12826
+ var import_react_dom12 = require("react-dom");
11456
12827
  var import_lucide_react31 = require("lucide-react");
11457
- var import_jsx_runtime54 = require("react/jsx-runtime");
12828
+ var import_jsx_runtime62 = require("react/jsx-runtime");
11458
12829
  function LanguageSwitcherHeadless({
11459
12830
  locales,
11460
12831
  currentLocale,
@@ -11462,9 +12833,9 @@ function LanguageSwitcherHeadless({
11462
12833
  labels,
11463
12834
  className
11464
12835
  }) {
11465
- const [isOpen, setIsOpen] = (0, import_react26.useState)(false);
11466
- const [dropdownPosition, setDropdownPosition] = (0, import_react26.useState)(null);
11467
- const triggerButtonRef = (0, import_react26.useRef)(null);
12836
+ const [isOpen, setIsOpen] = (0, import_react34.useState)(false);
12837
+ const [dropdownPosition, setDropdownPosition] = (0, import_react34.useState)(null);
12838
+ const triggerButtonRef = (0, import_react34.useRef)(null);
11468
12839
  const currentLanguage = locales.find((l) => l.code === currentLocale) || locales[0];
11469
12840
  const calculatePosition = () => {
11470
12841
  const rect = triggerButtonRef.current?.getBoundingClientRect();
@@ -11476,8 +12847,8 @@ function LanguageSwitcherHeadless({
11476
12847
  const top = rect.bottom + scrollTop + 8;
11477
12848
  return { top, left, width };
11478
12849
  };
11479
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: cn("relative", className), children: [
11480
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
12850
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: cn("relative", className), children: [
12851
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
11481
12852
  Button_default,
11482
12853
  {
11483
12854
  variant: "ghost",
@@ -11496,22 +12867,22 @@ function LanguageSwitcherHeadless({
11496
12867
  "aria-expanded": isOpen,
11497
12868
  "aria-label": labels?.heading ?? "Language",
11498
12869
  title: labels?.heading ?? "Language",
11499
- children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_lucide_react31.Globe, { className: "h-5 w-5" })
12870
+ children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_lucide_react31.Globe, { className: "h-5 w-5" })
11500
12871
  }
11501
12872
  ),
11502
- isOpen && /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_jsx_runtime54.Fragment, { children: [
11503
- typeof window !== "undefined" && (0, import_react_dom11.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "fixed inset-0 z-9998", onClick: () => setIsOpen(false) }), document.body),
11504
- typeof window !== "undefined" && dropdownPosition && (0, import_react_dom11.createPortal)(
11505
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
12873
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(import_jsx_runtime62.Fragment, { children: [
12874
+ typeof window !== "undefined" && (0, import_react_dom12.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "fixed inset-0 z-9998", onClick: () => setIsOpen(false) }), document.body),
12875
+ typeof window !== "undefined" && dropdownPosition && (0, import_react_dom12.createPortal)(
12876
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
11506
12877
  "div",
11507
12878
  {
11508
12879
  className: "z-9999 bg-card border border-border rounded-lg shadow-lg overflow-hidden",
11509
12880
  style: { position: "absolute", top: dropdownPosition.top, left: dropdownPosition.left, width: dropdownPosition.width },
11510
12881
  onMouseDown: (e) => e.stopPropagation(),
11511
12882
  role: "menu",
11512
- children: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "p-2", children: [
11513
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "px-3 py-2 text-sm font-medium text-muted-foreground border-b border-border mb-2", children: labels?.heading ?? "Language" }),
11514
- locales.map((language) => /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
12883
+ children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "p-2", children: [
12884
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "px-3 py-2 text-sm font-medium text-muted-foreground border-b border-border mb-2", children: labels?.heading ?? "Language" }),
12885
+ locales.map((language) => /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(
11515
12886
  Button_default,
11516
12887
  {
11517
12888
  variant: "ghost",
@@ -11524,9 +12895,9 @@ function LanguageSwitcherHeadless({
11524
12895
  role: "menuitemradio",
11525
12896
  "aria-checked": currentLocale === language.code,
11526
12897
  children: [
11527
- language.flag && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "text-lg", children: language.flag }),
11528
- /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "flex-1 text-left", children: language.name }),
11529
- currentLocale === language.code && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "w-2 h-2 rounded-full bg-primary" })
12898
+ language.flag && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "text-lg", children: language.flag }),
12899
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "flex-1 text-left", children: language.name }),
12900
+ currentLocale === language.code && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "w-2 h-2 rounded-full bg-primary" })
11530
12901
  ]
11531
12902
  },
11532
12903
  language.code
@@ -11956,7 +13327,7 @@ var VARIANT_STYLES_ALERT = {
11956
13327
  };
11957
13328
 
11958
13329
  // src/contexts/TranslationContext.tsx
11959
- var React42 = __toESM(require("react"), 1);
13330
+ var React50 = __toESM(require("react"), 1);
11960
13331
 
11961
13332
  // locales/en.json
11962
13333
  var en_default = {
@@ -12211,16 +13582,16 @@ var ja_default = {
12211
13582
  };
12212
13583
 
12213
13584
  // src/contexts/TranslationContext.tsx
12214
- var import_jsx_runtime55 = require("react/jsx-runtime");
13585
+ var import_jsx_runtime63 = require("react/jsx-runtime");
12215
13586
  var defaultTranslations2 = {
12216
13587
  en: en_default,
12217
13588
  vi: vi_default,
12218
13589
  ko: ko_default,
12219
13590
  ja: ja_default
12220
13591
  };
12221
- var TranslationContext2 = React42.createContext(null);
13592
+ var TranslationContext2 = React50.createContext(null);
12222
13593
  var TranslationProvider = ({ children, locale = "en", translations }) => {
12223
- const t = React42.useCallback(
13594
+ const t = React50.useCallback(
12224
13595
  (namespace) => {
12225
13596
  return (key) => {
12226
13597
  const mergedTranslations = {
@@ -12245,10 +13616,10 @@ var TranslationProvider = ({ children, locale = "en", translations }) => {
12245
13616
  },
12246
13617
  [locale, translations]
12247
13618
  );
12248
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(TranslationContext2.Provider, { value: { locale, t }, children });
13619
+ return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(TranslationContext2.Provider, { value: { locale, t }, children });
12249
13620
  };
12250
13621
  var useUnderverseTranslations = (namespace) => {
12251
- const context = React42.useContext(TranslationContext2);
13622
+ const context = React50.useContext(TranslationContext2);
12252
13623
  if (!context) {
12253
13624
  return (key) => {
12254
13625
  const parts = namespace.split(".");
@@ -12270,13 +13641,13 @@ var useUnderverseTranslations = (namespace) => {
12270
13641
  return context.t(namespace);
12271
13642
  };
12272
13643
  var useUnderverseLocale = () => {
12273
- const context = React42.useContext(TranslationContext2);
13644
+ const context = React50.useContext(TranslationContext2);
12274
13645
  return context?.locale || "en";
12275
13646
  };
12276
13647
 
12277
13648
  // src/hooks/useSmartTranslations.tsx
12278
- var React43 = __toESM(require("react"), 1);
12279
- var import_jsx_runtime56 = require("react/jsx-runtime");
13649
+ var React51 = __toESM(require("react"), 1);
13650
+ var import_jsx_runtime64 = require("react/jsx-runtime");
12280
13651
  var nextIntlHooks = null;
12281
13652
  try {
12282
13653
  const nextIntl = require("next-intl");
@@ -12287,12 +13658,12 @@ try {
12287
13658
  } catch {
12288
13659
  nextIntlHooks = null;
12289
13660
  }
12290
- var ForceInternalContext = React43.createContext(false);
13661
+ var ForceInternalContext = React51.createContext(false);
12291
13662
  var ForceInternalTranslationsProvider = ({ children }) => {
12292
- return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(ForceInternalContext.Provider, { value: true, children });
13663
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(ForceInternalContext.Provider, { value: true, children });
12293
13664
  };
12294
13665
  function useSmartTranslations(namespace) {
12295
- const forceInternal = React43.useContext(ForceInternalContext);
13666
+ const forceInternal = React51.useContext(ForceInternalContext);
12296
13667
  const internalT = useUnderverseTranslations(namespace);
12297
13668
  if (forceInternal || !nextIntlHooks?.useTranslations) {
12298
13669
  return internalT;
@@ -12305,7 +13676,7 @@ function useSmartTranslations(namespace) {
12305
13676
  }
12306
13677
  }
12307
13678
  function useSmartLocale() {
12308
- const forceInternal = React43.useContext(ForceInternalContext);
13679
+ const forceInternal = React51.useContext(ForceInternalContext);
12309
13680
  const internalLocale = useUnderverseLocale();
12310
13681
  if (forceInternal || !nextIntlHooks?.useLocale) {
12311
13682
  return internalLocale;
@@ -12327,9 +13698,11 @@ function getUnderverseMessages(locale = "en") {
12327
13698
  0 && (module.exports = {
12328
13699
  AccessDenied,
12329
13700
  Alert,
13701
+ AreaChart,
12330
13702
  Avatar,
12331
13703
  Badge,
12332
13704
  BadgeBase,
13705
+ BarChart,
12333
13706
  BatteryProgress,
12334
13707
  BottomSheet,
12335
13708
  Breadcrumb,
@@ -12367,6 +13740,7 @@ function getUnderverseMessages(locale = "en") {
12367
13740
  FormLabel,
12368
13741
  FormMessage,
12369
13742
  FormSubmitButton,
13743
+ GaugeChart,
12370
13744
  GlobalLoading,
12371
13745
  GradientBadge,
12372
13746
  Grid,
@@ -12378,6 +13752,7 @@ function getUnderverseMessages(locale = "en") {
12378
13752
  Label,
12379
13753
  LanguageSwitcher,
12380
13754
  LanguageSwitcherHeadless,
13755
+ LineChart,
12381
13756
  List,
12382
13757
  ListItem,
12383
13758
  LoadingBar,
@@ -12394,10 +13769,12 @@ function getUnderverseMessages(locale = "en") {
12394
13769
  PageLoading,
12395
13770
  Pagination,
12396
13771
  PasswordInput,
13772
+ PieChart,
12397
13773
  PillTabs,
12398
13774
  Popover,
12399
13775
  Progress,
12400
13776
  PulseBadge,
13777
+ RadarChart,
12401
13778
  RadioGroup,
12402
13779
  RadioGroupItem,
12403
13780
  SIZE_STYLES_BTN,
@@ -12422,6 +13799,7 @@ function getUnderverseMessages(locale = "en") {
12422
13799
  SlideOver,
12423
13800
  Slider,
12424
13801
  SmartImage,
13802
+ Sparkline,
12425
13803
  StatusBadge,
12426
13804
  StepProgress,
12427
13805
  Switch,