@tree-ia/design-system 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +311 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1520 -171
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +6 -5
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { createPortal } from "react-dom";
|
|
4
|
-
import { AlertTriangle, Check, CheckCircle, ChevronDown, ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight, Info, LogOut, Moon, Sun, User, X, XCircle } from "lucide-react";
|
|
4
|
+
import { AlertCircle, AlertOctagon, AlertTriangle, ArrowDown, ArrowUp, ArrowUpDown, Check, CheckCircle, ChevronDown, ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight, File, GripVertical, Image, Inbox, Info, LogOut, Moon, Search, Sun, Upload, User, X, XCircle } from "lucide-react";
|
|
5
5
|
import { Bar, Line } from "react-chartjs-2";
|
|
6
|
-
import { BarElement, CategoryScale, Chart, Filler, Legend, LineElement, LinearScale, PointElement, Title as Title$1, Tooltip } from "chart.js";
|
|
6
|
+
import { BarElement, CategoryScale, Chart, Filler, Legend, LineElement, LinearScale, PointElement, Title as Title$1, Tooltip as Tooltip$1 } from "chart.js";
|
|
7
|
+
import { createColumnHelper, flexRender, getCoreRowModel, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, useReactTable } from "@tanstack/react-table";
|
|
7
8
|
|
|
8
9
|
//#region src/components/Loading/index.tsx
|
|
9
10
|
const sizeMap = {
|
|
@@ -34,14 +35,14 @@ function Loading({ size = "md", className = "", text, textColor, color, variant
|
|
|
34
35
|
|
|
35
36
|
//#endregion
|
|
36
37
|
//#region src/components/Button/index.tsx
|
|
37
|
-
const cn$
|
|
38
|
+
const cn$29 = (...classes) => classes.filter(Boolean).join(" ");
|
|
38
39
|
function Button({ children, variant = "primary", size = "md", isLoading = false, icon, iconPosition = "left", className, disabled, ...props }) {
|
|
39
|
-
const baseStyles = "font-medium rounded-lg transition-all duration-200 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed inline-flex items-center justify-center";
|
|
40
|
+
const baseStyles = "font-medium rounded-lg transition-all duration-200 ease-out cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed inline-flex items-center justify-center focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--dashboard-primary,#2563EB)] active:scale-[0.97]";
|
|
40
41
|
const variantStyles = {
|
|
41
|
-
primary: "bg-[var(--dashboard-primary,#
|
|
42
|
-
secondary: "bg-[var(--dashboard-text-secondary,#
|
|
43
|
-
danger: "bg-[var(--dashboard-status-danger,#
|
|
44
|
-
ghost: "bg-transparent hover:bg-[var(--dashboard-text-secondary,#
|
|
42
|
+
primary: "bg-[var(--dashboard-primary,#2563EB)] text-white hover:brightness-110 hover:shadow-md",
|
|
43
|
+
secondary: "bg-[var(--dashboard-text-secondary,#64748B)]/10 text-[var(--dashboard-text-primary,#0F172A)] border border-[var(--dashboard-text-secondary,#64748B)]/20 hover:bg-[var(--dashboard-text-secondary,#64748B)]/15 hover:border-[var(--dashboard-text-secondary,#64748B)]/30",
|
|
44
|
+
danger: "bg-[var(--dashboard-status-danger,#DC2626)] text-white hover:brightness-110 hover:shadow-md",
|
|
45
|
+
ghost: "bg-transparent hover:bg-[var(--dashboard-text-secondary,#64748B)]/8 text-[var(--dashboard-text-primary,#0F172A)]"
|
|
45
46
|
};
|
|
46
47
|
const sizeStyles = {
|
|
47
48
|
sm: "px-2 py-1 text-xs sm:px-3 sm:py-1.5 sm:text-sm",
|
|
@@ -55,7 +56,7 @@ function Button({ children, variant = "primary", size = "md", isLoading = false,
|
|
|
55
56
|
};
|
|
56
57
|
const isIconOnly = !!icon && (children === void 0 || children === null || typeof children === "string" && children.trim() === "");
|
|
57
58
|
return /* @__PURE__ */ jsx("button", {
|
|
58
|
-
className: cn$
|
|
59
|
+
className: cn$29(baseStyles, variantStyles[variant], isIconOnly ? iconOnlySizeStyles[size] : sizeStyles[size], className),
|
|
59
60
|
disabled: disabled || isLoading,
|
|
60
61
|
...props,
|
|
61
62
|
children: isLoading ? /* @__PURE__ */ jsxs("span", {
|
|
@@ -80,7 +81,7 @@ function Button({ children, variant = "primary", size = "md", isLoading = false,
|
|
|
80
81
|
|
|
81
82
|
//#endregion
|
|
82
83
|
//#region src/components/Input/index.tsx
|
|
83
|
-
const cn$
|
|
84
|
+
const cn$28 = (...classes) => classes.filter(Boolean).join(" ");
|
|
84
85
|
const Input = React.forwardRef(({ className, type = "text", label, error, children, id, ...props }, ref) => {
|
|
85
86
|
const inputId = id || (label ? `input-${label.toLowerCase().replace(/\s+/g, "-")}` : void 0);
|
|
86
87
|
return /* @__PURE__ */ jsxs("div", {
|
|
@@ -96,7 +97,7 @@ const Input = React.forwardRef(({ className, type = "text", label, error, childr
|
|
|
96
97
|
children: [/* @__PURE__ */ jsx("input", {
|
|
97
98
|
type,
|
|
98
99
|
id: inputId,
|
|
99
|
-
className: cn$
|
|
100
|
+
className: cn$28("flex h-10 w-full rounded-md border border-[var(--dashboard-text-secondary,#6b7280)]/30 bg-[var(--dashboard-surface,#ffffff)] px-3 py-2 text-sm text-[var(--dashboard-text-primary,#2d2d2d)] shadow-sm transition-colors duration-200 focus:border-[var(--dashboard-primary,#37a501)] placeholder:text-[var(--dashboard-text-secondary,#6b7280)] focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50", error ? "border-[var(--dashboard-status-danger,#EF4444)] focus:border-[var(--dashboard-status-danger,#EF4444)]" : void 0, children ? "pr-10" : void 0, className),
|
|
100
101
|
ref,
|
|
101
102
|
...props
|
|
102
103
|
}), children && /* @__PURE__ */ jsx("div", {
|
|
@@ -247,7 +248,7 @@ function Dropdown({ options, value, onChange, label, placeholder = "Selecione um
|
|
|
247
248
|
top: position.top,
|
|
248
249
|
left: position.left,
|
|
249
250
|
width: position.width,
|
|
250
|
-
zIndex:
|
|
251
|
+
zIndex: 10001
|
|
251
252
|
},
|
|
252
253
|
children: /* @__PURE__ */ jsx("ul", {
|
|
253
254
|
className: "py-1",
|
|
@@ -284,9 +285,9 @@ function Table({ columns, data, onRowClick, isLoading = false, emptyMessage = "N
|
|
|
284
285
|
icon: emptyIcon
|
|
285
286
|
});
|
|
286
287
|
return /* @__PURE__ */ jsx("div", {
|
|
287
|
-
className: `overflow-x-auto bg-[var(--dashboard-surface,#ffffff)] rounded-
|
|
288
|
+
className: `overflow-x-auto bg-[var(--dashboard-surface,#ffffff)] rounded-xl border border-[var(--dashboard-text-secondary,#64748B)]/12 dashboard-shadow-sm ${className}`,
|
|
288
289
|
children: /* @__PURE__ */ jsxs("table", {
|
|
289
|
-
className: "min-w-full divide-y divide-[var(--dashboard-text-secondary,#
|
|
290
|
+
className: "min-w-full divide-y divide-[var(--dashboard-text-secondary,#64748B)]/10",
|
|
290
291
|
children: [/* @__PURE__ */ jsx(TableHeader, { columns }), /* @__PURE__ */ jsx(TableBody, {
|
|
291
292
|
columns,
|
|
292
293
|
data,
|
|
@@ -299,10 +300,10 @@ function Table({ columns, data, onRowClick, isLoading = false, emptyMessage = "N
|
|
|
299
300
|
function TableHeader({ columns }) {
|
|
300
301
|
const alignClass = (align) => align === "center" ? "text-center" : align === "right" ? "text-right" : "text-left";
|
|
301
302
|
return /* @__PURE__ */ jsx("thead", {
|
|
302
|
-
className: "bg-[var(--dashboard-
|
|
303
|
+
className: "bg-[var(--dashboard-background,#F8FAFC)] sticky top-0 z-10",
|
|
303
304
|
children: /* @__PURE__ */ jsx("tr", { children: columns.map((column) => /* @__PURE__ */ jsx("th", {
|
|
304
305
|
scope: "col",
|
|
305
|
-
className: `px-6 py-3 text-
|
|
306
|
+
className: `px-6 py-3 text-[0.6875rem] font-semibold text-[var(--dashboard-text-secondary,#64748B)] uppercase tracking-wider ${alignClass(column.align)} ${column.width ? `w-[${column.width}]` : ""}`,
|
|
306
307
|
children: column.header
|
|
307
308
|
}, column.key)) })
|
|
308
309
|
});
|
|
@@ -310,12 +311,12 @@ function TableHeader({ columns }) {
|
|
|
310
311
|
function TableBody({ columns, data, onRowClick, keyExtractor }) {
|
|
311
312
|
const alignClass = (align) => align === "center" ? "text-center" : align === "right" ? "text-right" : "text-left";
|
|
312
313
|
return /* @__PURE__ */ jsx("tbody", {
|
|
313
|
-
className: "bg-[var(--dashboard-surface,#ffffff)] divide-y divide-[var(--dashboard-text-secondary,#
|
|
314
|
-
children: data.map((item) => /* @__PURE__ */ jsx("tr", {
|
|
314
|
+
className: "bg-[var(--dashboard-surface,#ffffff)] divide-y divide-[var(--dashboard-text-secondary,#64748B)]/8",
|
|
315
|
+
children: data.map((item, index) => /* @__PURE__ */ jsx("tr", {
|
|
315
316
|
onClick: () => onRowClick?.(item),
|
|
316
|
-
className: `
|
|
317
|
+
className: `transition-colors duration-150 ${index % 2 === 1 ? "bg-[var(--dashboard-text-secondary,#64748B)]/[0.02]" : ""} hover:bg-[var(--dashboard-primary,#2563EB)]/[0.04] ${onRowClick ? "cursor-pointer" : ""}`,
|
|
317
318
|
children: columns.map((column) => /* @__PURE__ */ jsx("td", {
|
|
318
|
-
className: `px-6 py-
|
|
319
|
+
className: `px-6 py-3.5 whitespace-nowrap text-sm leading-snug ${alignClass(column.align)}`,
|
|
319
320
|
children: column.render(item)
|
|
320
321
|
}, column.key))
|
|
321
322
|
}, keyExtractor(item)))
|
|
@@ -323,7 +324,7 @@ function TableBody({ columns, data, onRowClick, keyExtractor }) {
|
|
|
323
324
|
}
|
|
324
325
|
function TableSkeleton() {
|
|
325
326
|
return /* @__PURE__ */ jsx("div", {
|
|
326
|
-
className: "bg-[var(--dashboard-surface,#ffffff)] rounded-
|
|
327
|
+
className: "bg-[var(--dashboard-surface,#ffffff)] rounded-xl border border-[var(--dashboard-text-secondary,#64748B)]/12 dashboard-shadow-sm p-6",
|
|
327
328
|
children: /* @__PURE__ */ jsx("div", {
|
|
328
329
|
className: "flex items-center justify-center h-64",
|
|
329
330
|
children: /* @__PURE__ */ jsx(Loading, {
|
|
@@ -335,22 +336,22 @@ function TableSkeleton() {
|
|
|
335
336
|
}
|
|
336
337
|
function TableEmpty({ message, icon }) {
|
|
337
338
|
return /* @__PURE__ */ jsx("div", {
|
|
338
|
-
className: "bg-[var(--dashboard-surface,#ffffff)] rounded-
|
|
339
|
+
className: "bg-[var(--dashboard-surface,#ffffff)] rounded-xl border border-[var(--dashboard-text-secondary,#64748B)]/12 dashboard-shadow-sm p-12",
|
|
339
340
|
children: /* @__PURE__ */ jsxs("div", {
|
|
340
341
|
className: "text-center",
|
|
341
342
|
children: [icon || /* @__PURE__ */ jsx("svg", {
|
|
342
|
-
className: "mx-auto h-12 w-12 text-[var(--dashboard-text-secondary,#
|
|
343
|
+
className: "mx-auto h-12 w-12 text-[var(--dashboard-text-secondary,#64748B)]/40",
|
|
343
344
|
fill: "none",
|
|
344
345
|
stroke: "currentColor",
|
|
345
346
|
viewBox: "0 0 24 24",
|
|
346
347
|
children: /* @__PURE__ */ jsx("path", {
|
|
347
348
|
strokeLinecap: "round",
|
|
348
349
|
strokeLinejoin: "round",
|
|
349
|
-
strokeWidth:
|
|
350
|
+
strokeWidth: 1.5,
|
|
350
351
|
d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
|
|
351
352
|
})
|
|
352
353
|
}), /* @__PURE__ */ jsx("p", {
|
|
353
|
-
className: "mt-4 text-[var(--dashboard-text-secondary,#
|
|
354
|
+
className: "mt-4 text-sm text-[var(--dashboard-text-secondary,#64748B)]",
|
|
354
355
|
children: message
|
|
355
356
|
})]
|
|
356
357
|
})
|
|
@@ -435,13 +436,13 @@ function Modal({ isOpen, onClose, onSave, title = "", children, showFooter = fal
|
|
|
435
436
|
"aria-labelledby": title ? "modal-title" : void 0,
|
|
436
437
|
children: /* @__PURE__ */ jsxs("div", {
|
|
437
438
|
ref: modalRef,
|
|
438
|
-
className: `w-full rounded-
|
|
439
|
+
className: `w-full rounded-2xl bg-[var(--dashboard-surface,#ffffff)] border border-[var(--dashboard-text-secondary,#64748B)]/10 dashboard-shadow-xl ${sizeClasses[size]} flex max-h-[90vh] flex-col transition-all duration-200 ease-out ${isClosing ? "scale-[0.98] opacity-0" : "scale-100 opacity-100"}`,
|
|
439
440
|
children: [
|
|
440
441
|
/* @__PURE__ */ jsxs("div", {
|
|
441
|
-
className: "flex h-fit items-center justify-between border-b border-[var(--dashboard-text-secondary,#
|
|
442
|
+
className: "flex h-fit items-center justify-between border-b border-[var(--dashboard-text-secondary,#64748B)]/10 px-6 py-4",
|
|
442
443
|
children: [title && /* @__PURE__ */ jsx("h2", {
|
|
443
444
|
id: "modal-title",
|
|
444
|
-
className: "text-
|
|
445
|
+
className: "text-lg font-semibold text-[var(--dashboard-text-primary,#0F172A)] tracking-tight",
|
|
445
446
|
children: title
|
|
446
447
|
}), /* @__PURE__ */ jsx(Button, {
|
|
447
448
|
variant: "ghost",
|
|
@@ -480,21 +481,21 @@ function Modal({ isOpen, onClose, onSave, title = "", children, showFooter = fal
|
|
|
480
481
|
//#region src/components/Card/index.tsx
|
|
481
482
|
function Card({ children, className = "", title, subtitle, icon, headerActions, showDivider = false }) {
|
|
482
483
|
return /* @__PURE__ */ jsx("div", {
|
|
483
|
-
className: `bg-[var(--dashboard-surface,#ffffff)] rounded-
|
|
484
|
+
className: `bg-[var(--dashboard-surface,#ffffff)] rounded-xl border border-[var(--dashboard-text-secondary,#64748B)]/12 transition-shadow duration-200 ease-out dashboard-shadow-sm hover:dashboard-shadow-md ${className}`,
|
|
484
485
|
children: /* @__PURE__ */ jsxs("div", {
|
|
485
|
-
className: "p-
|
|
486
|
+
className: "p-5",
|
|
486
487
|
children: [title && /* @__PURE__ */ jsxs("div", {
|
|
487
|
-
className: showDivider ? "mb-
|
|
488
|
+
className: showDivider ? "mb-5" : "mb-3",
|
|
488
489
|
children: [
|
|
489
490
|
/* @__PURE__ */ jsxs("div", {
|
|
490
491
|
className: "flex items-center justify-between",
|
|
491
492
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
492
|
-
className: "flex items-center gap-2",
|
|
493
|
+
className: "flex items-center gap-2.5",
|
|
493
494
|
children: [icon && /* @__PURE__ */ jsx("div", {
|
|
494
|
-
className: "text-[var(--dashboard-text-secondary,#
|
|
495
|
+
className: "text-[var(--dashboard-text-secondary,#64748B)]",
|
|
495
496
|
children: icon
|
|
496
497
|
}), /* @__PURE__ */ jsx("h3", {
|
|
497
|
-
className: `${showDivider ? "font-medium" : "text-base font-semibold"} text-[var(--dashboard-text-primary,#
|
|
498
|
+
className: `${showDivider ? "font-medium" : "text-base font-semibold"} text-[var(--dashboard-text-primary,#0F172A)] truncate tracking-tight`,
|
|
498
499
|
children: title
|
|
499
500
|
})]
|
|
500
501
|
}), headerActions && /* @__PURE__ */ jsx("div", {
|
|
@@ -503,10 +504,10 @@ function Card({ children, className = "", title, subtitle, icon, headerActions,
|
|
|
503
504
|
})]
|
|
504
505
|
}),
|
|
505
506
|
subtitle && /* @__PURE__ */ jsx("p", {
|
|
506
|
-
className: "text-sm text-[var(--dashboard-text-secondary,#
|
|
507
|
+
className: "text-sm text-[var(--dashboard-text-secondary,#64748B)] mt-1",
|
|
507
508
|
children: subtitle
|
|
508
509
|
}),
|
|
509
|
-
showDivider && /* @__PURE__ */ jsx("div", { className: "w-full h-px bg-[var(--dashboard-text-secondary,#
|
|
510
|
+
showDivider && /* @__PURE__ */ jsx("div", { className: "w-full h-px bg-[var(--dashboard-text-secondary,#64748B)]/10 mt-5" })
|
|
510
511
|
]
|
|
511
512
|
}), children]
|
|
512
513
|
})
|
|
@@ -760,16 +761,16 @@ function FormField({ label, name, type = "text", value, onChange, error, require
|
|
|
760
761
|
|
|
761
762
|
//#endregion
|
|
762
763
|
//#region src/components/Tabs/index.tsx
|
|
763
|
-
const cn$
|
|
764
|
+
const cn$27 = (...classes) => classes.filter(Boolean).join(" ");
|
|
764
765
|
function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
|
|
765
766
|
if (variant === "pill") return /* @__PURE__ */ jsx("div", {
|
|
766
|
-
className: cn$
|
|
767
|
+
className: cn$27("flex flex-wrap gap-2", className),
|
|
767
768
|
role: "tablist",
|
|
768
769
|
children: tabs.map((tab) => {
|
|
769
770
|
const isActive = activeTab === tab.id;
|
|
770
771
|
return /* @__PURE__ */ jsxs("button", {
|
|
771
772
|
onClick: () => onChange(tab.id),
|
|
772
|
-
className: cn$
|
|
773
|
+
className: cn$27("flex items-center gap-2 px-4 py-2 rounded-full text-sm font-medium transition-colors cursor-pointer", isActive ? "bg-[var(--dashboard-primary,#37a501)] text-white" : "bg-[var(--dashboard-text-secondary,#6b7280)]/10 text-[var(--dashboard-text-secondary,#6b7280)] hover:bg-[var(--dashboard-text-secondary,#6b7280)]/20"),
|
|
773
774
|
role: "tab",
|
|
774
775
|
"aria-selected": isActive,
|
|
775
776
|
children: [
|
|
@@ -779,7 +780,7 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
|
|
|
779
780
|
}),
|
|
780
781
|
tab.label,
|
|
781
782
|
tab.count !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
782
|
-
className: cn$
|
|
783
|
+
className: cn$27("ml-1 text-xs rounded-full px-1.5 py-0.5", isActive ? "bg-white/20 text-white" : "bg-[var(--dashboard-text-secondary,#6b7280)]/10 text-[var(--dashboard-text-secondary,#6b7280)]"),
|
|
783
784
|
children: tab.count
|
|
784
785
|
})
|
|
785
786
|
]
|
|
@@ -787,7 +788,7 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
|
|
|
787
788
|
})
|
|
788
789
|
});
|
|
789
790
|
return /* @__PURE__ */ jsx("div", {
|
|
790
|
-
className: cn$
|
|
791
|
+
className: cn$27("border-b border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
|
|
791
792
|
children: /* @__PURE__ */ jsx("nav", {
|
|
792
793
|
className: "flex gap-6",
|
|
793
794
|
"aria-label": "Tabs",
|
|
@@ -795,7 +796,7 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
|
|
|
795
796
|
const isActive = activeTab === tab.id;
|
|
796
797
|
return /* @__PURE__ */ jsxs("button", {
|
|
797
798
|
onClick: () => onChange(tab.id),
|
|
798
|
-
className: cn$
|
|
799
|
+
className: cn$27("relative pb-3 px-1 text-sm font-medium transition-colors border-b-2 flex items-center gap-2 cursor-pointer", isActive ? "text-[var(--dashboard-primary,#37a501)] border-[var(--dashboard-primary,#37a501)]" : "text-[var(--dashboard-text-secondary,#6b7280)] hover:text-[var(--dashboard-text-primary,#2d2d2d)] border-transparent"),
|
|
799
800
|
role: "tab",
|
|
800
801
|
"aria-selected": isActive,
|
|
801
802
|
children: [
|
|
@@ -805,7 +806,7 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
|
|
|
805
806
|
}),
|
|
806
807
|
tab.label,
|
|
807
808
|
tab.count !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
808
|
-
className: cn$
|
|
809
|
+
className: cn$27("ml-1 text-xs rounded-full px-1.5 py-0.5", isActive ? "bg-[var(--dashboard-primary,#37a501)]/10 text-[var(--dashboard-primary,#37a501)]" : "bg-[var(--dashboard-text-secondary,#6b7280)]/10 text-[var(--dashboard-text-secondary,#6b7280)]"),
|
|
809
810
|
children: tab.count
|
|
810
811
|
})
|
|
811
812
|
]
|
|
@@ -817,7 +818,7 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
|
|
|
817
818
|
|
|
818
819
|
//#endregion
|
|
819
820
|
//#region src/components/DateRangePicker/index.tsx
|
|
820
|
-
const cn$
|
|
821
|
+
const cn$26 = (...classes) => classes.filter(Boolean).join(" ");
|
|
821
822
|
const locales = {
|
|
822
823
|
pt: {
|
|
823
824
|
months: [
|
|
@@ -924,7 +925,7 @@ function DateRangePicker({ value, onChange, locale = "pt", className }) {
|
|
|
924
925
|
};
|
|
925
926
|
const days = getDaysInMonth(currentMonth);
|
|
926
927
|
return /* @__PURE__ */ jsxs("div", {
|
|
927
|
-
className: cn$
|
|
928
|
+
className: cn$26("w-64 bg-[var(--dashboard-surface,#ffffff)] rounded-lg p-4 shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
|
|
928
929
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
929
930
|
className: "flex items-center justify-between mb-4",
|
|
930
931
|
children: [
|
|
@@ -962,9 +963,9 @@ function DateRangePicker({ value, onChange, locale = "pt", className }) {
|
|
|
962
963
|
const isSelected = isStart || isEnd;
|
|
963
964
|
return /* @__PURE__ */ jsxs("div", {
|
|
964
965
|
className: "relative h-8 w-8",
|
|
965
|
-
children: [value.start && value.end && (inRange || isStart || isEnd) && /* @__PURE__ */ jsx("div", { className: cn$
|
|
966
|
+
children: [value.start && value.end && (inRange || isStart || isEnd) && /* @__PURE__ */ jsx("div", { className: cn$26("absolute inset-0 bg-[var(--dashboard-text-secondary,#6b7280)]/10", isStart && "rounded-l-full", isEnd && "rounded-r-full") }), /* @__PURE__ */ jsx("button", {
|
|
966
967
|
onClick: () => handleDayClick(day),
|
|
967
|
-
className: cn$
|
|
968
|
+
className: cn$26("relative h-8 w-8 flex items-center justify-center text-xs font-medium transition-colors z-10 rounded-full cursor-pointer", isSelected ? "bg-[var(--dashboard-primary,#37a501)] text-white hover:opacity-90" : "text-[var(--dashboard-text-primary,#2d2d2d)] hover:bg-[var(--dashboard-text-secondary,#6b7280)]/20"),
|
|
968
969
|
children: day
|
|
969
970
|
})]
|
|
970
971
|
}, day);
|
|
@@ -975,7 +976,7 @@ function DateRangePicker({ value, onChange, locale = "pt", className }) {
|
|
|
975
976
|
|
|
976
977
|
//#endregion
|
|
977
978
|
//#region src/components/Title/index.tsx
|
|
978
|
-
const cn$
|
|
979
|
+
const cn$25 = (...classes) => classes.filter(Boolean).join(" ");
|
|
979
980
|
const defaultSizeByLevel = {
|
|
980
981
|
1: "text-2xl sm:text-3xl md:text-4xl lg:text-5xl",
|
|
981
982
|
2: "text-xl sm:text-2xl md:text-3xl lg:text-4xl",
|
|
@@ -1010,7 +1011,7 @@ function Title({ children, level = 1, size, weight = "bold", align = "left", col
|
|
|
1010
1011
|
const sizeClass = size ? customSizes[size] : defaultSizeByLevel[level];
|
|
1011
1012
|
const colorClass = color || "text-[var(--dashboard-text-primary,#2d2d2d)]";
|
|
1012
1013
|
return /* @__PURE__ */ jsx(Tag, {
|
|
1013
|
-
className: cn$
|
|
1014
|
+
className: cn$25(sizeClass, weightStyles[weight], alignStyles[align], colorClass, className),
|
|
1014
1015
|
...props,
|
|
1015
1016
|
children
|
|
1016
1017
|
});
|
|
@@ -1018,7 +1019,7 @@ function Title({ children, level = 1, size, weight = "bold", align = "left", col
|
|
|
1018
1019
|
|
|
1019
1020
|
//#endregion
|
|
1020
1021
|
//#region src/components/ToggleSwitch/index.tsx
|
|
1021
|
-
const cn$
|
|
1022
|
+
const cn$24 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1022
1023
|
const sizeConfig$1 = {
|
|
1023
1024
|
sm: {
|
|
1024
1025
|
track: "h-5 w-9",
|
|
@@ -1042,7 +1043,7 @@ const sizeConfig$1 = {
|
|
|
1042
1043
|
function ToggleSwitch({ enabled, onChange, disabled = false, size = "md", label, className }) {
|
|
1043
1044
|
const config = sizeConfig$1[size];
|
|
1044
1045
|
return /* @__PURE__ */ jsxs("div", {
|
|
1045
|
-
className: cn$
|
|
1046
|
+
className: cn$24("inline-flex items-center gap-2", className),
|
|
1046
1047
|
children: [/* @__PURE__ */ jsx("button", {
|
|
1047
1048
|
type: "button",
|
|
1048
1049
|
role: "switch",
|
|
@@ -1050,10 +1051,10 @@ function ToggleSwitch({ enabled, onChange, disabled = false, size = "md", label,
|
|
|
1050
1051
|
"aria-label": label,
|
|
1051
1052
|
disabled,
|
|
1052
1053
|
onClick: () => onChange(!enabled),
|
|
1053
|
-
className: cn$
|
|
1054
|
-
children: /* @__PURE__ */ jsx("span", { className: cn$
|
|
1054
|
+
className: cn$24("relative inline-flex items-center rounded-full transition-colors outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-[var(--dashboard-primary,#37a501)]", config.track, enabled ? "bg-[var(--dashboard-primary,#37a501)]" : "bg-[var(--dashboard-text-secondary,#6b7280)]/30", disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"),
|
|
1055
|
+
children: /* @__PURE__ */ jsx("span", { className: cn$24("inline-block transform rounded-full bg-white shadow-sm transition-transform", config.thumb, enabled ? config.translateOn : config.translateOff) })
|
|
1055
1056
|
}), label && /* @__PURE__ */ jsx("span", {
|
|
1056
|
-
className: cn$
|
|
1057
|
+
className: cn$24("text-sm text-[var(--dashboard-text-primary,#2d2d2d)]", disabled && "opacity-50"),
|
|
1057
1058
|
children: label
|
|
1058
1059
|
})]
|
|
1059
1060
|
});
|
|
@@ -1061,7 +1062,7 @@ function ToggleSwitch({ enabled, onChange, disabled = false, size = "md", label,
|
|
|
1061
1062
|
|
|
1062
1063
|
//#endregion
|
|
1063
1064
|
//#region src/components/BadgeStatus/index.tsx
|
|
1064
|
-
const cn$
|
|
1065
|
+
const cn$23 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1065
1066
|
const variantStyles = {
|
|
1066
1067
|
success: {
|
|
1067
1068
|
color: "text-[var(--dashboard-status-success,#10B981)]",
|
|
@@ -1084,7 +1085,7 @@ const variantStyles = {
|
|
|
1084
1085
|
bgColor: "bg-[var(--dashboard-text-secondary,#6b7280)]/10"
|
|
1085
1086
|
}
|
|
1086
1087
|
};
|
|
1087
|
-
const sizeClasses = {
|
|
1088
|
+
const sizeClasses$1 = {
|
|
1088
1089
|
sm: "px-2 py-0.5 text-xs",
|
|
1089
1090
|
md: "px-3 py-1 text-sm"
|
|
1090
1091
|
};
|
|
@@ -1092,7 +1093,7 @@ function BadgeStatus({ label, variant = "neutral", color, bgColor, size = "md",
|
|
|
1092
1093
|
const styles = variantStyles[variant];
|
|
1093
1094
|
const useCustomColors = color || bgColor;
|
|
1094
1095
|
return /* @__PURE__ */ jsx("span", {
|
|
1095
|
-
className: cn$
|
|
1096
|
+
className: cn$23("inline-flex items-center rounded-full font-medium whitespace-nowrap", sizeClasses$1[size], !useCustomColors && styles.color, !useCustomColors && styles.bgColor, className),
|
|
1096
1097
|
style: useCustomColors ? {
|
|
1097
1098
|
color: color || void 0,
|
|
1098
1099
|
backgroundColor: bgColor || void 0
|
|
@@ -1103,7 +1104,7 @@ function BadgeStatus({ label, variant = "neutral", color, bgColor, size = "md",
|
|
|
1103
1104
|
|
|
1104
1105
|
//#endregion
|
|
1105
1106
|
//#region src/components/Sidebar/index.tsx
|
|
1106
|
-
const cn$
|
|
1107
|
+
const cn$22 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1107
1108
|
function DefaultLink({ href, className, children }) {
|
|
1108
1109
|
return /* @__PURE__ */ jsx("a", {
|
|
1109
1110
|
href,
|
|
@@ -1113,7 +1114,117 @@ function DefaultLink({ href, className, children }) {
|
|
|
1113
1114
|
}
|
|
1114
1115
|
function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: LinkComponent = DefaultLink, isCollapsed = false, onToggleCollapse, user, onUserClick, onLogout, logoutLabel = "Sair", className }) {
|
|
1115
1116
|
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
|
1117
|
+
const [expandedIds, setExpandedIds] = useState(/* @__PURE__ */ new Set());
|
|
1116
1118
|
const cubicBezier = "cubic-bezier(0.4, 0, 0.2, 1)";
|
|
1119
|
+
function toggleExpand(id) {
|
|
1120
|
+
setExpandedIds((prev) => {
|
|
1121
|
+
const next = new Set(prev);
|
|
1122
|
+
if (next.has(id)) next.delete(id);
|
|
1123
|
+
else next.add(id);
|
|
1124
|
+
return next;
|
|
1125
|
+
});
|
|
1126
|
+
}
|
|
1127
|
+
/** Group items by section — items before any section go into a null group */
|
|
1128
|
+
function groupBySection(items) {
|
|
1129
|
+
const groups = [];
|
|
1130
|
+
for (const item of items) if (item.section) groups.push({
|
|
1131
|
+
section: item.section,
|
|
1132
|
+
items: [item]
|
|
1133
|
+
});
|
|
1134
|
+
else {
|
|
1135
|
+
if (groups.length === 0) groups.push({
|
|
1136
|
+
section: null,
|
|
1137
|
+
items: []
|
|
1138
|
+
});
|
|
1139
|
+
groups[groups.length - 1].items.push(item);
|
|
1140
|
+
}
|
|
1141
|
+
return groups;
|
|
1142
|
+
}
|
|
1143
|
+
function renderSectionHeader(section, collapsed) {
|
|
1144
|
+
if (collapsed) return /* @__PURE__ */ jsx("div", { className: "my-2 mx-2 border-t border-[var(--dashboard-sidebar-border,#2A6510)]" });
|
|
1145
|
+
return /* @__PURE__ */ jsx("div", {
|
|
1146
|
+
className: "mb-1 mt-4 px-4 text-[10px] font-bold uppercase tracking-widest text-[var(--dashboard-sidebar-text,#FFFFFF)]/50",
|
|
1147
|
+
children: section
|
|
1148
|
+
});
|
|
1149
|
+
}
|
|
1150
|
+
function renderMenuItem(item, collapsed, mobile) {
|
|
1151
|
+
const Icon = item.icon;
|
|
1152
|
+
const hasChildren = item.children && item.children.length > 0;
|
|
1153
|
+
const isActive = currentPath === item.href;
|
|
1154
|
+
const isExpanded = expandedIds.has(item.id);
|
|
1155
|
+
const isChildActive = item.children?.some((c) => currentPath === c.href);
|
|
1156
|
+
if (isChildActive && !isExpanded) setTimeout(() => setExpandedIds((p) => new Set(p).add(item.id)), 0);
|
|
1157
|
+
if (hasChildren) return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("button", {
|
|
1158
|
+
onClick: () => toggleExpand(item.id),
|
|
1159
|
+
className: cn$22("w-full flex items-center px-4 py-3 rounded-lg text-sm font-medium cursor-pointer", collapsed && !mobile ? "justify-center" : "justify-start", isChildActive ? "text-[var(--dashboard-sidebar-active-text,#5DD611)]" : "text-[var(--dashboard-sidebar-text,#FFFFFF)] hover:bg-[var(--dashboard-primary,#37a501)]/10"),
|
|
1160
|
+
style: { transition: "background-color 200ms, color 200ms" },
|
|
1161
|
+
title: collapsed && !mobile ? item.label : void 0,
|
|
1162
|
+
children: [/* @__PURE__ */ jsx(Icon, {
|
|
1163
|
+
size: 20,
|
|
1164
|
+
style: {
|
|
1165
|
+
marginRight: collapsed && !mobile ? 0 : "0.75rem",
|
|
1166
|
+
flexShrink: 0,
|
|
1167
|
+
transition: `margin 400ms ${cubicBezier}`
|
|
1168
|
+
}
|
|
1169
|
+
}), (!collapsed || mobile) && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
1170
|
+
className: "whitespace-nowrap flex-1 text-left",
|
|
1171
|
+
children: item.label
|
|
1172
|
+
}), /* @__PURE__ */ jsx(ChevronRight, {
|
|
1173
|
+
size: 14,
|
|
1174
|
+
className: cn$22("ml-auto flex-shrink-0 transition-transform duration-200", isExpanded ? "rotate-90" : "")
|
|
1175
|
+
})] })]
|
|
1176
|
+
}), (!collapsed || mobile) && /* @__PURE__ */ jsx("div", {
|
|
1177
|
+
className: "overflow-hidden transition-all duration-200",
|
|
1178
|
+
style: { maxHeight: isExpanded ? `${item.children.length * 48}px` : "0" },
|
|
1179
|
+
children: item.children.map((child) => {
|
|
1180
|
+
const ChildIcon = child.icon;
|
|
1181
|
+
const childActive = currentPath === child.href;
|
|
1182
|
+
return /* @__PURE__ */ jsx(LinkComponent, {
|
|
1183
|
+
href: child.href,
|
|
1184
|
+
className: "block",
|
|
1185
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
1186
|
+
className: cn$22("w-full flex items-center pl-11 pr-4 py-2.5 rounded-lg text-sm cursor-pointer", childActive ? "bg-[var(--dashboard-primary,#37a501)]/25 text-[var(--dashboard-sidebar-active-text,#5DD611)] font-medium" : "text-[var(--dashboard-sidebar-text,#FFFFFF)]/70 hover:bg-[var(--dashboard-primary,#37a501)]/10 hover:text-[var(--dashboard-sidebar-text,#FFFFFF)]"),
|
|
1187
|
+
style: { transition: "background-color 200ms, color 200ms" },
|
|
1188
|
+
children: [/* @__PURE__ */ jsx(ChildIcon, {
|
|
1189
|
+
size: 16,
|
|
1190
|
+
className: "mr-2.5 flex-shrink-0"
|
|
1191
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
1192
|
+
className: "whitespace-nowrap",
|
|
1193
|
+
children: child.label
|
|
1194
|
+
})]
|
|
1195
|
+
})
|
|
1196
|
+
}, child.id);
|
|
1197
|
+
})
|
|
1198
|
+
})] }, item.id);
|
|
1199
|
+
return /* @__PURE__ */ jsx(LinkComponent, {
|
|
1200
|
+
href: item.href,
|
|
1201
|
+
className: "block",
|
|
1202
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
1203
|
+
className: cn$22("w-full flex items-center px-4 py-3 rounded-lg text-sm font-medium cursor-pointer", collapsed && !mobile ? "justify-center" : "justify-start", isActive ? "bg-[var(--dashboard-primary,#37a501)]/25 text-[var(--dashboard-sidebar-active-text,#5DD611)]" : "text-[var(--dashboard-sidebar-text,#FFFFFF)] hover:bg-[var(--dashboard-primary,#37a501)]/10"),
|
|
1204
|
+
style: { transition: "background-color 200ms, color 200ms" },
|
|
1205
|
+
title: collapsed && !mobile ? item.label : void 0,
|
|
1206
|
+
children: [/* @__PURE__ */ jsx(Icon, {
|
|
1207
|
+
size: 20,
|
|
1208
|
+
style: {
|
|
1209
|
+
marginRight: collapsed && !mobile ? 0 : "0.75rem",
|
|
1210
|
+
flexShrink: 0,
|
|
1211
|
+
transition: `margin 400ms ${cubicBezier}`
|
|
1212
|
+
}
|
|
1213
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
1214
|
+
className: "whitespace-nowrap overflow-hidden",
|
|
1215
|
+
style: !mobile ? {
|
|
1216
|
+
width: collapsed ? 0 : "auto",
|
|
1217
|
+
opacity: collapsed ? 0 : 1,
|
|
1218
|
+
transition: `width 400ms ${cubicBezier}, opacity 400ms ${cubicBezier}`
|
|
1219
|
+
} : void 0,
|
|
1220
|
+
children: item.label
|
|
1221
|
+
})]
|
|
1222
|
+
})
|
|
1223
|
+
}, item.id);
|
|
1224
|
+
}
|
|
1225
|
+
function renderMenuGroups(collapsed, mobile) {
|
|
1226
|
+
return groupBySection(menuItems).map((group, i) => /* @__PURE__ */ jsxs("div", { children: [group.section && renderSectionHeader(group.section, collapsed), group.items.map((item) => renderMenuItem(item, collapsed, mobile))] }, group.section || `group-${i}`));
|
|
1227
|
+
}
|
|
1117
1228
|
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("header", {
|
|
1118
1229
|
className: "xl:hidden fixed top-0 left-0 right-0 z-40 bg-[var(--dashboard-sidebar-bg,#1B4D08)] border-b border-[var(--dashboard-sidebar-border,#2A6510)]",
|
|
1119
1230
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
@@ -1135,28 +1246,11 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1135
1246
|
className: `absolute top-16 left-0 right-0 bg-[var(--dashboard-sidebar-bg,#1B4D08)] border-b border-[var(--dashboard-sidebar-border,#2A6510)] shadow-lg transition-all duration-200 ${isMobileMenuOpen ? "max-h-[calc(100vh-4rem)] overflow-y-auto" : "max-h-0 overflow-hidden"}`,
|
|
1136
1247
|
children: /* @__PURE__ */ jsxs("div", {
|
|
1137
1248
|
className: "px-4 py-2",
|
|
1138
|
-
children: [
|
|
1139
|
-
const Icon = item.icon;
|
|
1140
|
-
const isActive = currentPath === item.href;
|
|
1141
|
-
return /* @__PURE__ */ jsx(LinkComponent, {
|
|
1142
|
-
href: item.href,
|
|
1143
|
-
className: "block",
|
|
1144
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
1145
|
-
className: cn$11("w-full flex items-center justify-start px-4 py-3 rounded-lg text-sm font-medium transition-colors mb-1 cursor-pointer", isActive ? "bg-[var(--dashboard-primary,#37a501)]/25 text-[var(--dashboard-sidebar-active-text,#5DD611)]" : "text-[var(--dashboard-sidebar-text,#FFFFFF)] hover:bg-white/10"),
|
|
1146
|
-
children: [/* @__PURE__ */ jsx(Icon, {
|
|
1147
|
-
size: 20,
|
|
1148
|
-
className: "mr-3 flex-shrink-0"
|
|
1149
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
1150
|
-
className: "whitespace-nowrap",
|
|
1151
|
-
children: item.label
|
|
1152
|
-
})]
|
|
1153
|
-
})
|
|
1154
|
-
}, item.id);
|
|
1155
|
-
}), /* @__PURE__ */ jsxs("div", {
|
|
1249
|
+
children: [renderMenuGroups(false, true), /* @__PURE__ */ jsxs("div", {
|
|
1156
1250
|
className: "mt-2 pt-2 border-t border-[var(--dashboard-sidebar-border,#2A6510)] space-y-2",
|
|
1157
1251
|
children: [user && /* @__PURE__ */ jsxs("button", {
|
|
1158
1252
|
onClick: onUserClick,
|
|
1159
|
-
className: "w-full flex items-center px-4 py-3 rounded-lg bg-
|
|
1253
|
+
className: "w-full flex items-center px-4 py-3 rounded-lg bg-[var(--dashboard-primary,#37a501)]/5 hover:bg-[var(--dashboard-primary,#37a501)]/10 transition-colors cursor-pointer",
|
|
1160
1254
|
children: [/* @__PURE__ */ jsx("div", {
|
|
1161
1255
|
className: "flex items-center justify-center w-8 h-8 rounded-full bg-[var(--dashboard-primary,#37a501)]/30 text-[var(--dashboard-sidebar-text,#FFFFFF)] flex-shrink-0",
|
|
1162
1256
|
children: /* @__PURE__ */ jsx(User, { size: 16 })
|
|
@@ -1179,7 +1273,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1179
1273
|
})]
|
|
1180
1274
|
}), onLogout && /* @__PURE__ */ jsxs("button", {
|
|
1181
1275
|
onClick: onLogout,
|
|
1182
|
-
className: "w-full flex items-center justify-start px-4 py-3 rounded-lg text-sm font-medium transition-colors cursor-pointer text-[var(--dashboard-sidebar-text,#FFFFFF)] hover:bg-
|
|
1276
|
+
className: "w-full flex items-center justify-start px-4 py-3 rounded-lg text-sm font-medium transition-colors cursor-pointer text-[var(--dashboard-sidebar-text,#FFFFFF)] hover:bg-[var(--dashboard-primary,#37a501)]/10",
|
|
1183
1277
|
children: [/* @__PURE__ */ jsx(LogOut, {
|
|
1184
1278
|
size: 20,
|
|
1185
1279
|
className: "mr-3 flex-shrink-0"
|
|
@@ -1192,7 +1286,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1192
1286
|
})
|
|
1193
1287
|
})]
|
|
1194
1288
|
}), /* @__PURE__ */ jsxs("aside", {
|
|
1195
|
-
className: cn$
|
|
1289
|
+
className: cn$22("hidden xl:flex xl:flex-col xl:fixed xl:left-0 xl:top-0 xl:h-screen bg-[var(--dashboard-sidebar-bg,#1B4D08)] border-r border-[var(--dashboard-sidebar-border,#2A6510)] overflow-visible", isCollapsed ? "xl:w-[109px]" : "xl:w-[280px]", className),
|
|
1196
1290
|
style: { transition: `width 400ms ${cubicBezier}` },
|
|
1197
1291
|
children: [onToggleCollapse && /* @__PURE__ */ jsxs("button", {
|
|
1198
1292
|
onClick: onToggleCollapse,
|
|
@@ -1253,41 +1347,14 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1253
1347
|
})]
|
|
1254
1348
|
}),
|
|
1255
1349
|
/* @__PURE__ */ jsx("nav", {
|
|
1256
|
-
className: "flex-1 px-
|
|
1257
|
-
children:
|
|
1258
|
-
const Icon = item.icon;
|
|
1259
|
-
const isActive = currentPath === item.href;
|
|
1260
|
-
return /* @__PURE__ */ jsx(LinkComponent, {
|
|
1261
|
-
href: item.href,
|
|
1262
|
-
className: "block",
|
|
1263
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
1264
|
-
className: cn$11("w-full flex items-center px-4 py-3 rounded-lg text-sm font-medium cursor-pointer", isCollapsed ? "justify-center" : "justify-start", isActive ? "bg-[var(--dashboard-primary,#37a501)]/25 text-[var(--dashboard-sidebar-active-text,#5DD611)]" : "text-[var(--dashboard-sidebar-text,#FFFFFF)] hover:bg-white/10"),
|
|
1265
|
-
style: { transition: "background-color 200ms, color 200ms" },
|
|
1266
|
-
title: isCollapsed ? item.label : void 0,
|
|
1267
|
-
children: [/* @__PURE__ */ jsx(Icon, {
|
|
1268
|
-
size: 20,
|
|
1269
|
-
style: {
|
|
1270
|
-
marginRight: isCollapsed ? 0 : "0.75rem",
|
|
1271
|
-
transition: `margin 400ms ${cubicBezier}`
|
|
1272
|
-
}
|
|
1273
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
1274
|
-
className: "whitespace-nowrap overflow-hidden",
|
|
1275
|
-
style: {
|
|
1276
|
-
width: isCollapsed ? 0 : "auto",
|
|
1277
|
-
opacity: isCollapsed ? 0 : 1,
|
|
1278
|
-
transition: `width 400ms ${cubicBezier}, opacity 400ms ${cubicBezier}`
|
|
1279
|
-
},
|
|
1280
|
-
children: item.label
|
|
1281
|
-
})]
|
|
1282
|
-
})
|
|
1283
|
-
}, item.id);
|
|
1284
|
-
})
|
|
1350
|
+
className: "flex-1 px-3 py-3 space-y-0.5 overflow-y-auto",
|
|
1351
|
+
children: renderMenuGroups(isCollapsed, false)
|
|
1285
1352
|
}),
|
|
1286
1353
|
/* @__PURE__ */ jsxs("footer", {
|
|
1287
1354
|
className: "p-4 border-t border-[var(--dashboard-sidebar-border,#2A6510)] space-y-2",
|
|
1288
1355
|
children: [user && /* @__PURE__ */ jsxs("button", {
|
|
1289
1356
|
onClick: onUserClick,
|
|
1290
|
-
className: cn$
|
|
1357
|
+
className: cn$22("w-full flex items-center px-4 py-3 rounded-lg bg-[var(--dashboard-primary,#37a501)]/5 hover:bg-[var(--dashboard-primary,#37a501)]/10 transition-colors cursor-pointer", isCollapsed ? "justify-center" : "justify-start"),
|
|
1291
1358
|
title: isCollapsed ? `${user.subtitle ? user.subtitle + " - " : ""}${user.name}` : void 0,
|
|
1292
1359
|
children: [/* @__PURE__ */ jsx("div", {
|
|
1293
1360
|
className: "flex items-center justify-center w-8 h-8 rounded-full bg-[var(--dashboard-primary,#37a501)]/30 text-[var(--dashboard-sidebar-text,#FFFFFF)] flex-shrink-0",
|
|
@@ -1316,7 +1383,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1316
1383
|
})]
|
|
1317
1384
|
}), onLogout && /* @__PURE__ */ jsxs("button", {
|
|
1318
1385
|
onClick: onLogout,
|
|
1319
|
-
className: cn$
|
|
1386
|
+
className: cn$22("w-full flex items-center px-4 py-3 rounded-lg text-sm font-medium cursor-pointer text-[var(--dashboard-sidebar-text,#FFFFFF)] hover:bg-[var(--dashboard-primary,#37a501)]/10", isCollapsed ? "justify-center" : "justify-start"),
|
|
1320
1387
|
style: { transition: "background-color 200ms" },
|
|
1321
1388
|
title: isCollapsed ? logoutLabel : void 0,
|
|
1322
1389
|
children: [/* @__PURE__ */ jsx(LogOut, {
|
|
@@ -1352,7 +1419,7 @@ function useTheme() {
|
|
|
1352
1419
|
|
|
1353
1420
|
//#endregion
|
|
1354
1421
|
//#region src/components/ThemeSwitcher/index.tsx
|
|
1355
|
-
const cn$
|
|
1422
|
+
const cn$21 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1356
1423
|
function ThemeSwitcher({ className }) {
|
|
1357
1424
|
const { resolvedTheme, setTheme } = useTheme();
|
|
1358
1425
|
const toggle = () => {
|
|
@@ -1361,7 +1428,7 @@ function ThemeSwitcher({ className }) {
|
|
|
1361
1428
|
return /* @__PURE__ */ jsxs("button", {
|
|
1362
1429
|
type: "button",
|
|
1363
1430
|
onClick: toggle,
|
|
1364
|
-
className: cn$
|
|
1431
|
+
className: cn$21("relative inline-flex items-center justify-center h-9 w-9 rounded-md border border-[var(--dashboard-text-secondary,#6b7280)]/30 bg-[var(--dashboard-surface,#ffffff)] shadow-sm transition-colors cursor-pointer hover:bg-[var(--dashboard-text-secondary,#6b7280)]/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--dashboard-primary,#37a501)] focus-visible:ring-offset-2", className),
|
|
1365
1432
|
"aria-label": "Alternar tema",
|
|
1366
1433
|
children: [
|
|
1367
1434
|
/* @__PURE__ */ jsx(Sun, { className: "h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" }),
|
|
@@ -1376,7 +1443,7 @@ function ThemeSwitcher({ className }) {
|
|
|
1376
1443
|
|
|
1377
1444
|
//#endregion
|
|
1378
1445
|
//#region src/components/KPICard/index.tsx
|
|
1379
|
-
const cn$
|
|
1446
|
+
const cn$20 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1380
1447
|
function formatValue(value, format) {
|
|
1381
1448
|
switch (format) {
|
|
1382
1449
|
case "currency": return new Intl.NumberFormat("pt-BR", {
|
|
@@ -1391,44 +1458,44 @@ function formatValue(value, format) {
|
|
|
1391
1458
|
const trendConfigs = {
|
|
1392
1459
|
up: {
|
|
1393
1460
|
icon: "↑",
|
|
1394
|
-
color: "text-[var(--dashboard-status-success,#
|
|
1461
|
+
color: "text-[var(--dashboard-status-success,#059669)] bg-[var(--dashboard-status-success,#059669)]/8"
|
|
1395
1462
|
},
|
|
1396
1463
|
down: {
|
|
1397
1464
|
icon: "↓",
|
|
1398
|
-
color: "text-[var(--dashboard-status-danger,#
|
|
1465
|
+
color: "text-[var(--dashboard-status-danger,#DC2626)] bg-[var(--dashboard-status-danger,#DC2626)]/8"
|
|
1399
1466
|
},
|
|
1400
1467
|
stable: {
|
|
1401
1468
|
icon: "→",
|
|
1402
|
-
color: "text-[var(--dashboard-text-secondary,#
|
|
1469
|
+
color: "text-[var(--dashboard-text-secondary,#64748B)] bg-[var(--dashboard-text-secondary,#64748B)]/8"
|
|
1403
1470
|
}
|
|
1404
1471
|
};
|
|
1405
1472
|
function KPICard({ title, value, variation, trend, format = "number", benchmark, isLoading, className }) {
|
|
1406
1473
|
if (isLoading) return /* @__PURE__ */ jsx(KPICardSkeleton, { className });
|
|
1407
1474
|
const trendConfig = trendConfigs[trend];
|
|
1408
1475
|
return /* @__PURE__ */ jsxs("div", {
|
|
1409
|
-
className: cn$
|
|
1476
|
+
className: cn$20("h-full w-full bg-[var(--dashboard-surface,#ffffff)] rounded-xl p-6 border border-[var(--dashboard-text-secondary,#64748B)]/12 transition-all duration-200 ease-out dashboard-shadow-sm hover:dashboard-shadow-md flex flex-col", className),
|
|
1410
1477
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
1411
1478
|
className: "flex justify-between items-start mb-4",
|
|
1412
1479
|
children: [/* @__PURE__ */ jsx("h3", {
|
|
1413
|
-
className: "text-
|
|
1480
|
+
className: "text-xs font-semibold uppercase tracking-wider text-[var(--dashboard-text-secondary,#64748B)] whitespace-nowrap",
|
|
1414
1481
|
children: title
|
|
1415
1482
|
}), benchmark && /* @__PURE__ */ jsx("span", {
|
|
1416
|
-
className: "text-xs text-[var(--dashboard-text-secondary,#
|
|
1483
|
+
className: "text-xs text-[var(--dashboard-text-secondary,#64748B)]/50 ml-2 whitespace-nowrap flex-shrink-0",
|
|
1417
1484
|
title: "Benchmark de referência",
|
|
1418
1485
|
children: benchmark
|
|
1419
1486
|
})]
|
|
1420
1487
|
}), /* @__PURE__ */ jsxs("div", {
|
|
1421
|
-
className: "flex items-
|
|
1488
|
+
className: "flex items-end gap-3 flex-1",
|
|
1422
1489
|
children: [/* @__PURE__ */ jsx("p", {
|
|
1423
|
-
className: "text-3xl font-bold text-[var(--dashboard-text-primary,#
|
|
1490
|
+
className: "text-3xl font-bold text-[var(--dashboard-text-primary,#0F172A)] whitespace-nowrap tracking-tight",
|
|
1424
1491
|
children: formatValue(value, format)
|
|
1425
1492
|
}), /* @__PURE__ */ jsxs("div", {
|
|
1426
|
-
className: cn$
|
|
1493
|
+
className: cn$20("inline-flex items-center gap-1 px-2 py-1 rounded-full flex-shrink-0 mb-1", trendConfig.color),
|
|
1427
1494
|
children: [/* @__PURE__ */ jsx("span", {
|
|
1428
|
-
className: "text-
|
|
1495
|
+
className: "text-sm",
|
|
1429
1496
|
children: trendConfig.icon
|
|
1430
1497
|
}), /* @__PURE__ */ jsxs("span", {
|
|
1431
|
-
className: "text-
|
|
1498
|
+
className: "text-xs font-semibold whitespace-nowrap",
|
|
1432
1499
|
children: [Math.abs(variation).toFixed(1), "%"]
|
|
1433
1500
|
})]
|
|
1434
1501
|
})]
|
|
@@ -1437,23 +1504,23 @@ function KPICard({ title, value, variation, trend, format = "number", benchmark,
|
|
|
1437
1504
|
}
|
|
1438
1505
|
function KPICardSkeleton({ className }) {
|
|
1439
1506
|
return /* @__PURE__ */ jsxs("div", {
|
|
1440
|
-
className: cn$
|
|
1441
|
-
children: [/* @__PURE__ */ jsx("div", { className: "h-
|
|
1442
|
-
className: "flex items-
|
|
1443
|
-
children: [/* @__PURE__ */ jsx("div", { className: "h-8 bg-[var(--dashboard-text-secondary,#
|
|
1507
|
+
className: cn$20("h-full bg-[var(--dashboard-surface,#ffffff)] rounded-xl p-6 border border-[var(--dashboard-text-secondary,#64748B)]/12 dashboard-shadow-sm animate-pulse flex flex-col", className),
|
|
1508
|
+
children: [/* @__PURE__ */ jsx("div", { className: "h-3 bg-[var(--dashboard-text-secondary,#64748B)]/10 rounded w-2/3 mb-4" }), /* @__PURE__ */ jsxs("div", {
|
|
1509
|
+
className: "flex items-end gap-3 flex-1",
|
|
1510
|
+
children: [/* @__PURE__ */ jsx("div", { className: "h-8 bg-[var(--dashboard-text-secondary,#64748B)]/10 rounded w-1/2" }), /* @__PURE__ */ jsx("div", { className: "h-5 bg-[var(--dashboard-text-secondary,#64748B)]/10 rounded-full w-1/4" })]
|
|
1444
1511
|
})]
|
|
1445
1512
|
});
|
|
1446
1513
|
}
|
|
1447
1514
|
|
|
1448
1515
|
//#endregion
|
|
1449
1516
|
//#region src/components/PageLayout/index.tsx
|
|
1450
|
-
const cn$
|
|
1517
|
+
const cn$19 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1451
1518
|
function PageLayout({ title, description, headerActions, children, contentPadding = true, sidebar, sidebarCollapsed = false, sidebarWidth = 280, sidebarCollapsedWidth = 109, className }) {
|
|
1452
1519
|
const marginLeft = sidebar ? sidebarCollapsed ? `max(0px, ${sidebarCollapsedWidth}px)` : `max(0px, ${sidebarWidth}px)` : "0px";
|
|
1453
1520
|
return /* @__PURE__ */ jsxs("div", {
|
|
1454
|
-
className: cn$
|
|
1521
|
+
className: cn$19("min-h-screen bg-[var(--dashboard-background,#f2f2f2)]", className),
|
|
1455
1522
|
children: [sidebar, /* @__PURE__ */ jsxs("main", {
|
|
1456
|
-
className: cn$
|
|
1523
|
+
className: cn$19("pt-16 xl:pt-0", !sidebar && "pt-0"),
|
|
1457
1524
|
style: {
|
|
1458
1525
|
marginLeft,
|
|
1459
1526
|
transition: "margin-left 400ms cubic-bezier(0.4, 0, 0.2, 1)"
|
|
@@ -1490,8 +1557,8 @@ function PageLayout({ title, description, headerActions, children, contentPaddin
|
|
|
1490
1557
|
|
|
1491
1558
|
//#endregion
|
|
1492
1559
|
//#region src/components/ComparisonLineChart/index.tsx
|
|
1493
|
-
Chart.register(CategoryScale, LinearScale, PointElement, LineElement, Title$1, Tooltip, Legend, Filler);
|
|
1494
|
-
const cn$
|
|
1560
|
+
Chart.register(CategoryScale, LinearScale, PointElement, LineElement, Title$1, Tooltip$1, Legend, Filler);
|
|
1561
|
+
const cn$18 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1495
1562
|
function ComparisonLineChart({ labels, currentPeriodData, previousPeriodData, currentPeriodLabel = "Período atual", previousPeriodLabel = "Período anterior", title, color, height = 300, className }) {
|
|
1496
1563
|
const primaryColor = color || (typeof document !== "undefined" ? getComputedStyle(document.documentElement).getPropertyValue("--dashboard-primary").trim() : "") || "#37a501";
|
|
1497
1564
|
const data = {
|
|
@@ -1585,7 +1652,7 @@ function ComparisonLineChart({ labels, currentPeriodData, previousPeriodData, cu
|
|
|
1585
1652
|
}
|
|
1586
1653
|
};
|
|
1587
1654
|
return /* @__PURE__ */ jsxs("div", {
|
|
1588
|
-
className: cn$
|
|
1655
|
+
className: cn$18("bg-[var(--dashboard-surface,#ffffff)] rounded-lg shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20 p-6", className),
|
|
1589
1656
|
children: [title && /* @__PURE__ */ jsx("h3", {
|
|
1590
1657
|
className: "text-base font-semibold mb-4 text-[var(--dashboard-text-primary,#2d2d2d)]",
|
|
1591
1658
|
children: title
|
|
@@ -1601,8 +1668,8 @@ function ComparisonLineChart({ labels, currentPeriodData, previousPeriodData, cu
|
|
|
1601
1668
|
|
|
1602
1669
|
//#endregion
|
|
1603
1670
|
//#region src/components/HorizontalBarChart/index.tsx
|
|
1604
|
-
Chart.register(CategoryScale, LinearScale, BarElement, Title$1, Tooltip, Legend);
|
|
1605
|
-
const cn$
|
|
1671
|
+
Chart.register(CategoryScale, LinearScale, BarElement, Title$1, Tooltip$1, Legend);
|
|
1672
|
+
const cn$17 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1606
1673
|
function HorizontalBarChart({ labels, datasets, tabs, title, titleIcon, color, valueLabel = "itens", valueLabelSingular, bestItemLabel = "Melhor item", className }) {
|
|
1607
1674
|
const [activeTab, setActiveTab] = useState((tabs ? tabs.map((t) => t.id) : Object.keys(datasets))[0]);
|
|
1608
1675
|
const [isMobile, setIsMobile] = useState(false);
|
|
@@ -1677,7 +1744,7 @@ function HorizontalBarChart({ labels, datasets, tabs, title, titleIcon, color, v
|
|
|
1677
1744
|
}
|
|
1678
1745
|
};
|
|
1679
1746
|
return /* @__PURE__ */ jsxs("div", {
|
|
1680
|
-
className: cn$
|
|
1747
|
+
className: cn$17("bg-[var(--dashboard-surface,#ffffff)] rounded-lg shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20 p-5 sm:p-6 min-h-[850px] sm:h-full flex flex-col", className),
|
|
1681
1748
|
children: [
|
|
1682
1749
|
title && /* @__PURE__ */ jsxs("div", {
|
|
1683
1750
|
className: "flex items-center gap-2 mb-4",
|
|
@@ -1690,7 +1757,7 @@ function HorizontalBarChart({ labels, datasets, tabs, title, titleIcon, color, v
|
|
|
1690
1757
|
className: "flex gap-2 mb-4 flex-wrap",
|
|
1691
1758
|
children: tabs.map((tab) => /* @__PURE__ */ jsx("button", {
|
|
1692
1759
|
onClick: () => setActiveTab(tab.id),
|
|
1693
|
-
className: cn$
|
|
1760
|
+
className: cn$17("px-3.5 py-2 sm:px-4 sm:py-2 rounded-full text-sm font-medium transition-colors whitespace-nowrap cursor-pointer", activeTab === tab.id ? "bg-[var(--dashboard-primary,#37a501)] text-white" : "bg-[var(--dashboard-text-secondary,#6b7280)]/10 text-[var(--dashboard-text-secondary,#6b7280)] hover:bg-[var(--dashboard-text-secondary,#6b7280)]/20"),
|
|
1694
1761
|
children: tab.label
|
|
1695
1762
|
}, tab.id))
|
|
1696
1763
|
}),
|
|
@@ -1728,8 +1795,8 @@ function HorizontalBarChart({ labels, datasets, tabs, title, titleIcon, color, v
|
|
|
1728
1795
|
|
|
1729
1796
|
//#endregion
|
|
1730
1797
|
//#region src/components/VerticalBarChart/index.tsx
|
|
1731
|
-
Chart.register(CategoryScale, LinearScale, BarElement, Title$1, Tooltip, Legend);
|
|
1732
|
-
const cn$
|
|
1798
|
+
Chart.register(CategoryScale, LinearScale, BarElement, Title$1, Tooltip$1, Legend);
|
|
1799
|
+
const cn$16 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1733
1800
|
function VerticalBarChart({ labels, data: values, title, titleIcon, color, valueLabel = "itens", valueLabelSingular, bestItemLabel = "Melhor item", labelMaxChars = 3, className }) {
|
|
1734
1801
|
const maxValue = Math.max(...values);
|
|
1735
1802
|
const bestLabel = labels[values.indexOf(maxValue)];
|
|
@@ -1792,7 +1859,7 @@ function VerticalBarChart({ labels, data: values, title, titleIcon, color, value
|
|
|
1792
1859
|
}
|
|
1793
1860
|
};
|
|
1794
1861
|
return /* @__PURE__ */ jsxs("div", {
|
|
1795
|
-
className: cn$
|
|
1862
|
+
className: cn$16("bg-[var(--dashboard-surface,#ffffff)] rounded-lg shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20 p-6 flex-1 flex flex-col", className),
|
|
1796
1863
|
children: [
|
|
1797
1864
|
title && /* @__PURE__ */ jsxs("div", {
|
|
1798
1865
|
className: "flex items-center gap-2 mb-4",
|
|
@@ -1835,7 +1902,7 @@ function VerticalBarChart({ labels, data: values, title, titleIcon, color, value
|
|
|
1835
1902
|
|
|
1836
1903
|
//#endregion
|
|
1837
1904
|
//#region src/components/ProgressBarList/index.tsx
|
|
1838
|
-
const cn$
|
|
1905
|
+
const cn$15 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1839
1906
|
function ProgressBarList({ items, title, titleIcon, color, valueLabel = "itens", valueLabelSingular, sortByValue = true, formatValue, className }) {
|
|
1840
1907
|
const sortedItems = sortByValue ? [...items].sort((a, b) => b.value - a.value) : items;
|
|
1841
1908
|
const maxValue = Math.max(...items.map((i) => i.value));
|
|
@@ -1844,7 +1911,7 @@ function ProgressBarList({ items, title, titleIcon, color, valueLabel = "itens",
|
|
|
1844
1911
|
const defaultFormat = (v) => `${v} ${v === 1 ? singular : valueLabel}`;
|
|
1845
1912
|
const fmt = formatValue || defaultFormat;
|
|
1846
1913
|
return /* @__PURE__ */ jsxs("div", {
|
|
1847
|
-
className: cn$
|
|
1914
|
+
className: cn$15("bg-[var(--dashboard-surface,#ffffff)] rounded-lg shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20 p-6 flex-1 flex flex-col", className),
|
|
1848
1915
|
children: [title && /* @__PURE__ */ jsxs("div", {
|
|
1849
1916
|
className: "flex items-center gap-2 mb-4",
|
|
1850
1917
|
children: [titleIcon, /* @__PURE__ */ jsx("h3", {
|
|
@@ -1892,8 +1959,8 @@ function ProgressBarList({ items, title, titleIcon, color, valueLabel = "itens",
|
|
|
1892
1959
|
|
|
1893
1960
|
//#endregion
|
|
1894
1961
|
//#region src/components/MetricPanel/index.tsx
|
|
1895
|
-
Chart.register(CategoryScale, LinearScale, PointElement, LineElement, Title$1, Tooltip, Legend, Filler);
|
|
1896
|
-
const cn$
|
|
1962
|
+
Chart.register(CategoryScale, LinearScale, PointElement, LineElement, Title$1, Tooltip$1, Legend, Filler);
|
|
1963
|
+
const cn$14 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1897
1964
|
function MetricPanel({ title, titleIcon: TitleIcon, metrics, chartData, color, secondaryColor, onActionClick, actionLabel, isLoading = false, className }) {
|
|
1898
1965
|
const [selectedMetricKey, setSelectedMetricKey] = useState(metrics[0]?.key);
|
|
1899
1966
|
const [isMobile, setIsMobile] = useState(false);
|
|
@@ -1991,7 +2058,7 @@ function MetricPanel({ title, titleIcon: TitleIcon, metrics, chartData, color, s
|
|
|
1991
2058
|
}
|
|
1992
2059
|
};
|
|
1993
2060
|
return /* @__PURE__ */ jsxs("div", {
|
|
1994
|
-
className: cn$
|
|
2061
|
+
className: cn$14("bg-[var(--dashboard-surface,#ffffff)] rounded-lg shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
|
|
1995
2062
|
style: { overflow: "visible" },
|
|
1996
2063
|
children: [
|
|
1997
2064
|
/* @__PURE__ */ jsxs("div", {
|
|
@@ -2032,7 +2099,7 @@ function MetricPanel({ title, titleIcon: TitleIcon, metrics, chartData, color, s
|
|
|
2032
2099
|
const Icon = metric.icon;
|
|
2033
2100
|
return /* @__PURE__ */ jsxs("button", {
|
|
2034
2101
|
onClick: () => setSelectedMetricKey(metric.key),
|
|
2035
|
-
className: cn$
|
|
2102
|
+
className: cn$14("flex items-center gap-2 px-4 md:px-6 py-2 rounded-full text-sm font-medium transition-colors cursor-pointer", selectedMetricKey === metric.key ? "bg-[var(--dashboard-surface,#ffffff)] border-2 text-[var(--dashboard-primary,#37a501)]" : "bg-[var(--dashboard-surface,#ffffff)] border border-[var(--dashboard-text-secondary,#6b7280)]/30 text-[var(--dashboard-text-secondary,#6b7280)] hover:border-[var(--dashboard-text-secondary,#6b7280)]/50"),
|
|
2036
2103
|
style: selectedMetricKey === metric.key ? {
|
|
2037
2104
|
borderColor: primaryColor,
|
|
2038
2105
|
color: primaryColor
|
|
@@ -2080,10 +2147,10 @@ function MetricPanel({ title, titleIcon: TitleIcon, metrics, chartData, color, s
|
|
|
2080
2147
|
|
|
2081
2148
|
//#endregion
|
|
2082
2149
|
//#region src/components/FilterBar/index.tsx
|
|
2083
|
-
const cn$
|
|
2150
|
+
const cn$13 = (...classes) => classes.filter(Boolean).join(" ");
|
|
2084
2151
|
function FilterBar({ searchValue, onSearchChange, searchPlaceholder = "Buscar...", children, actions, className }) {
|
|
2085
2152
|
return /* @__PURE__ */ jsxs("div", {
|
|
2086
|
-
className: cn$
|
|
2153
|
+
className: cn$13("flex flex-col gap-3 sm:flex-row sm:items-center sm:flex-wrap", className),
|
|
2087
2154
|
children: [
|
|
2088
2155
|
onSearchChange !== void 0 && /* @__PURE__ */ jsx("div", {
|
|
2089
2156
|
className: "flex-1 min-w-[200px]",
|
|
@@ -2123,7 +2190,7 @@ function FilterBar({ searchValue, onSearchChange, searchPlaceholder = "Buscar...
|
|
|
2123
2190
|
|
|
2124
2191
|
//#endregion
|
|
2125
2192
|
//#region src/components/Checkbox/index.tsx
|
|
2126
|
-
const cn$
|
|
2193
|
+
const cn$12 = (...classes) => classes.filter(Boolean).join(" ");
|
|
2127
2194
|
const sizeConfig = {
|
|
2128
2195
|
sm: {
|
|
2129
2196
|
box: 16,
|
|
@@ -2171,7 +2238,7 @@ function Checkbox({ name, id, label, checked = false, onChange, disabled = false
|
|
|
2171
2238
|
const resolvedColor = primaryColor || "var(--dashboard-primary, #37A501)";
|
|
2172
2239
|
return /* @__PURE__ */ jsxs("label", {
|
|
2173
2240
|
htmlFor: inputId,
|
|
2174
|
-
className: cn$
|
|
2241
|
+
className: cn$12("inline-flex items-center cursor-pointer select-none", disabled && "opacity-50 cursor-not-allowed", className),
|
|
2175
2242
|
style: { gap: cfg.gap },
|
|
2176
2243
|
children: [
|
|
2177
2244
|
/* @__PURE__ */ jsx("input", {
|
|
@@ -2222,7 +2289,7 @@ function Checkbox({ name, id, label, checked = false, onChange, disabled = false
|
|
|
2222
2289
|
|
|
2223
2290
|
//#endregion
|
|
2224
2291
|
//#region src/components/AuthLayout/index.tsx
|
|
2225
|
-
const cn = (...classes) => classes.filter(Boolean).join(" ");
|
|
2292
|
+
const cn$11 = (...classes) => classes.filter(Boolean).join(" ");
|
|
2226
2293
|
/** Resolves a CSS color value (including var() references) to a computed hex/rgb string */
|
|
2227
2294
|
function useResolvedColor(cssValue) {
|
|
2228
2295
|
const [resolved, setResolved] = useState(cssValue);
|
|
@@ -2389,7 +2456,7 @@ function AuthLayout({ logo, title, subtitle, error, success, fields, values, onF
|
|
|
2389
2456
|
if (link.onClick) return /* @__PURE__ */ jsx("button", {
|
|
2390
2457
|
type: "button",
|
|
2391
2458
|
onClick: link.onClick,
|
|
2392
|
-
className: cn("bg-transparent border-none cursor-pointer hover:opacity-80 text-sm font-semibold p-0 transition-colors", extraClass),
|
|
2459
|
+
className: cn$11("bg-transparent border-none cursor-pointer hover:opacity-80 text-sm font-semibold p-0 transition-colors", extraClass),
|
|
2393
2460
|
style,
|
|
2394
2461
|
children: link.label
|
|
2395
2462
|
});
|
|
@@ -2397,13 +2464,13 @@ function AuthLayout({ logo, title, subtitle, error, success, fields, values, onF
|
|
|
2397
2464
|
href: link.href,
|
|
2398
2465
|
target: link.target,
|
|
2399
2466
|
rel: link.target === "_blank" ? "noopener noreferrer" : void 0,
|
|
2400
|
-
className: cn("hover:opacity-80 text-sm font-semibold transition-colors", extraClass),
|
|
2467
|
+
className: cn$11("hover:opacity-80 text-sm font-semibold transition-colors", extraClass),
|
|
2401
2468
|
style,
|
|
2402
2469
|
children: link.label
|
|
2403
2470
|
});
|
|
2404
2471
|
}
|
|
2405
2472
|
return /* @__PURE__ */ jsxs("div", {
|
|
2406
|
-
className: cn("fixed inset-0 flex select-none overflow-hidden", className),
|
|
2473
|
+
className: cn$11("fixed inset-0 flex select-none overflow-hidden", className),
|
|
2407
2474
|
style: bgCss,
|
|
2408
2475
|
children: [
|
|
2409
2476
|
branding && branding.logos.length > 0 && /* @__PURE__ */ jsx("div", {
|
|
@@ -2684,26 +2751,1308 @@ function CodeInput({ length = 6, value, onChange, disabled = false, error = fals
|
|
|
2684
2751
|
});
|
|
2685
2752
|
}
|
|
2686
2753
|
|
|
2754
|
+
//#endregion
|
|
2755
|
+
//#region src/components/Skeleton/index.tsx
|
|
2756
|
+
const cn$10 = (...classes) => classes.filter(Boolean).join(" ");
|
|
2757
|
+
function Skeleton({ variant = "text", width, height, animate = true, className, lines = 1 }) {
|
|
2758
|
+
const baseStyles = "bg-[var(--dashboard-text-secondary,#6b7280)]/10 relative overflow-hidden";
|
|
2759
|
+
const shimmerStyles = animate ? "after:absolute after:inset-0 after:bg-gradient-to-r after:from-transparent after:via-[var(--dashboard-text-secondary,#6b7280)]/5 after:to-transparent dashboard-animate-shimmer after:content-['']" : "";
|
|
2760
|
+
const variantStyles = {
|
|
2761
|
+
text: "h-4 rounded",
|
|
2762
|
+
circle: "rounded-full",
|
|
2763
|
+
rectangle: "rounded-lg",
|
|
2764
|
+
card: "rounded-lg"
|
|
2765
|
+
};
|
|
2766
|
+
const style = {};
|
|
2767
|
+
if (width) style.width = typeof width === "number" ? `${width}px` : width;
|
|
2768
|
+
if (height) style.height = typeof height === "number" ? `${height}px` : height;
|
|
2769
|
+
if (variant === "circle" && !height) {
|
|
2770
|
+
style.height = style.width || "40px";
|
|
2771
|
+
if (!width) style.width = "40px";
|
|
2772
|
+
}
|
|
2773
|
+
if (variant === "card" && !height) style.height = "120px";
|
|
2774
|
+
if (variant === "text" && lines > 1) return /* @__PURE__ */ jsx("div", {
|
|
2775
|
+
className: cn$10("flex flex-col gap-2", className),
|
|
2776
|
+
children: Array.from({ length: lines }).map((_, i) => /* @__PURE__ */ jsx("div", {
|
|
2777
|
+
className: cn$10(baseStyles, shimmerStyles, variantStyles.text),
|
|
2778
|
+
style: {
|
|
2779
|
+
...style,
|
|
2780
|
+
width: i === lines - 1 ? "75%" : style.width || "100%"
|
|
2781
|
+
}
|
|
2782
|
+
}, i))
|
|
2783
|
+
});
|
|
2784
|
+
return /* @__PURE__ */ jsx("div", {
|
|
2785
|
+
className: cn$10(baseStyles, shimmerStyles, variantStyles[variant], className),
|
|
2786
|
+
style
|
|
2787
|
+
});
|
|
2788
|
+
}
|
|
2789
|
+
|
|
2790
|
+
//#endregion
|
|
2791
|
+
//#region src/components/DataGrid/index.tsx
|
|
2792
|
+
const cn$9 = (...classes) => classes.filter(Boolean).join(" ");
|
|
2793
|
+
function SortIcon({ sorted }) {
|
|
2794
|
+
if (sorted === "asc") return /* @__PURE__ */ jsx(ArrowUp, { className: "h-3.5 w-3.5" });
|
|
2795
|
+
if (sorted === "desc") return /* @__PURE__ */ jsx(ArrowDown, { className: "h-3.5 w-3.5" });
|
|
2796
|
+
return /* @__PURE__ */ jsx(ArrowUpDown, { className: "h-3.5 w-3.5 opacity-40" });
|
|
2797
|
+
}
|
|
2798
|
+
function DataGridSkeleton({ columns, rows, compact }) {
|
|
2799
|
+
const cellPadding = compact ? "px-4 py-2" : "px-6 py-3";
|
|
2800
|
+
return /* @__PURE__ */ jsx(Fragment, { children: Array.from({ length: rows }).map((_, rowIdx) => /* @__PURE__ */ jsx("tr", { children: Array.from({ length: columns }).map((_, colIdx) => /* @__PURE__ */ jsx("td", {
|
|
2801
|
+
className: cellPadding,
|
|
2802
|
+
children: /* @__PURE__ */ jsx(Skeleton, { variant: "text" })
|
|
2803
|
+
}, colIdx)) }, rowIdx)) });
|
|
2804
|
+
}
|
|
2805
|
+
function VirtualRows({ table, rowHeight, onRowClick, compact }) {
|
|
2806
|
+
const containerRef = useRef(null);
|
|
2807
|
+
const [scrollTop, setScrollTop] = useState(0);
|
|
2808
|
+
const [containerHeight, setContainerHeight] = useState(400);
|
|
2809
|
+
const rows = table.getRowModel().rows;
|
|
2810
|
+
const totalHeight = rows.length * rowHeight;
|
|
2811
|
+
useEffect(() => {
|
|
2812
|
+
const container = containerRef.current;
|
|
2813
|
+
if (!container) return;
|
|
2814
|
+
const observer = new ResizeObserver((entries) => {
|
|
2815
|
+
for (const entry of entries) setContainerHeight(entry.contentRect.height);
|
|
2816
|
+
});
|
|
2817
|
+
observer.observe(container);
|
|
2818
|
+
const handleScroll = () => {
|
|
2819
|
+
setScrollTop(container.scrollTop);
|
|
2820
|
+
};
|
|
2821
|
+
container.addEventListener("scroll", handleScroll, { passive: true });
|
|
2822
|
+
return () => {
|
|
2823
|
+
observer.disconnect();
|
|
2824
|
+
container.removeEventListener("scroll", handleScroll);
|
|
2825
|
+
};
|
|
2826
|
+
}, []);
|
|
2827
|
+
const overscan = 5;
|
|
2828
|
+
const startIndex = Math.max(0, Math.floor(scrollTop / rowHeight) - overscan);
|
|
2829
|
+
const endIndex = Math.min(rows.length, Math.ceil((scrollTop + containerHeight) / rowHeight) + overscan);
|
|
2830
|
+
const visibleRows = rows.slice(startIndex, endIndex);
|
|
2831
|
+
const cellPadding = compact ? "px-4 py-2" : "px-6 py-4";
|
|
2832
|
+
return /* @__PURE__ */ jsx("div", {
|
|
2833
|
+
ref: containerRef,
|
|
2834
|
+
className: "overflow-auto",
|
|
2835
|
+
style: { maxHeight: containerHeight },
|
|
2836
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
2837
|
+
style: {
|
|
2838
|
+
height: totalHeight,
|
|
2839
|
+
position: "relative"
|
|
2840
|
+
},
|
|
2841
|
+
children: /* @__PURE__ */ jsxs("table", {
|
|
2842
|
+
className: "min-w-full divide-y divide-[var(--dashboard-text-secondary,#6b7280)]/20",
|
|
2843
|
+
children: [/* @__PURE__ */ jsx("thead", {
|
|
2844
|
+
className: "bg-[var(--dashboard-text-secondary,#6b7280)]/5 sticky top-0 z-10",
|
|
2845
|
+
children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx("tr", { children: headerGroup.headers.map((header) => /* @__PURE__ */ jsx("th", {
|
|
2846
|
+
scope: "col",
|
|
2847
|
+
className: cn$9("text-left text-xs font-semibold text-[var(--dashboard-text-secondary,#6b7280)] uppercase tracking-wider", compact ? "px-4 py-2" : "px-6 py-3", header.column.getCanSort() && "cursor-pointer select-none"),
|
|
2848
|
+
style: { width: header.getSize() },
|
|
2849
|
+
onClick: header.column.getToggleSortingHandler(),
|
|
2850
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
2851
|
+
className: "flex items-center gap-1",
|
|
2852
|
+
children: [flexRender(header.column.columnDef.header, header.getContext()), header.column.getCanSort() && /* @__PURE__ */ jsx(SortIcon, { sorted: header.column.getIsSorted() })]
|
|
2853
|
+
})
|
|
2854
|
+
}, header.id)) }, headerGroup.id))
|
|
2855
|
+
}), /* @__PURE__ */ jsxs("tbody", { children: [
|
|
2856
|
+
/* @__PURE__ */ jsx("tr", {
|
|
2857
|
+
style: { height: startIndex * rowHeight },
|
|
2858
|
+
children: /* @__PURE__ */ jsx("td", { colSpan: table.getAllColumns().length })
|
|
2859
|
+
}),
|
|
2860
|
+
visibleRows.map((row) => /* @__PURE__ */ jsx("tr", {
|
|
2861
|
+
onClick: () => onRowClick?.(row.original),
|
|
2862
|
+
className: cn$9("hover:bg-[var(--dashboard-text-secondary,#6b7280)]/5 transition-colors", onRowClick && "cursor-pointer", row.getIsSelected() && "bg-[var(--dashboard-primary,#37a501)]/5"),
|
|
2863
|
+
style: { height: rowHeight },
|
|
2864
|
+
children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx("td", {
|
|
2865
|
+
className: cn$9(cellPadding, "text-sm whitespace-nowrap"),
|
|
2866
|
+
children: flexRender(cell.column.columnDef.cell, cell.getContext())
|
|
2867
|
+
}, cell.id))
|
|
2868
|
+
}, row.id)),
|
|
2869
|
+
/* @__PURE__ */ jsx("tr", {
|
|
2870
|
+
style: { height: (rows.length - endIndex) * rowHeight },
|
|
2871
|
+
children: /* @__PURE__ */ jsx("td", { colSpan: table.getAllColumns().length })
|
|
2872
|
+
})
|
|
2873
|
+
] })]
|
|
2874
|
+
})
|
|
2875
|
+
})
|
|
2876
|
+
});
|
|
2877
|
+
}
|
|
2878
|
+
function DataGrid({ columns, data, isLoading = false, skeletonRows = 5, sorting: controlledSorting, onSortingChange, globalFilter: controlledGlobalFilter, onGlobalFilterChange, columnFilters: controlledColumnFilters, onColumnFiltersChange, rowSelection: controlledRowSelection, onRowSelectionChange, enableRowSelection = false, pagination: controlledPagination, onPaginationChange, pageCount, manualPagination = false, pageSizeOptions = [
|
|
2879
|
+
10,
|
|
2880
|
+
20,
|
|
2881
|
+
30,
|
|
2882
|
+
50
|
|
2883
|
+
], onRowClick, getRowId, enableVirtualization = false, rowHeight = 48, emptyMessage = "Nenhum registro encontrado", emptyIcon, stickyHeader = false, compact = false, striped = false, bordered = false, className }) {
|
|
2884
|
+
const [internalSorting, setInternalSorting] = useState([]);
|
|
2885
|
+
const [internalGlobalFilter, setInternalGlobalFilter] = useState("");
|
|
2886
|
+
const [internalColumnFilters, setInternalColumnFilters] = useState([]);
|
|
2887
|
+
const [internalRowSelection, setInternalRowSelection] = useState({});
|
|
2888
|
+
const [internalPagination, setInternalPagination] = useState({
|
|
2889
|
+
pageIndex: 0,
|
|
2890
|
+
pageSize: 10
|
|
2891
|
+
});
|
|
2892
|
+
const sorting = controlledSorting ?? internalSorting;
|
|
2893
|
+
const globalFilter = controlledGlobalFilter ?? internalGlobalFilter;
|
|
2894
|
+
const columnFilters = controlledColumnFilters ?? internalColumnFilters;
|
|
2895
|
+
const rowSelection = controlledRowSelection ?? internalRowSelection;
|
|
2896
|
+
const pagination = controlledPagination ?? internalPagination;
|
|
2897
|
+
const handleSortingChange = useCallback((updater) => {
|
|
2898
|
+
const next = typeof updater === "function" ? updater(sorting) : updater;
|
|
2899
|
+
onSortingChange ? onSortingChange(next) : setInternalSorting(next);
|
|
2900
|
+
}, [sorting, onSortingChange]);
|
|
2901
|
+
const handleGlobalFilterChange = useCallback((updater) => {
|
|
2902
|
+
const next = typeof updater === "function" ? updater(globalFilter) : updater;
|
|
2903
|
+
onGlobalFilterChange ? onGlobalFilterChange(next) : setInternalGlobalFilter(next);
|
|
2904
|
+
}, [globalFilter, onGlobalFilterChange]);
|
|
2905
|
+
const handleColumnFiltersChange = useCallback((updater) => {
|
|
2906
|
+
const next = typeof updater === "function" ? updater(columnFilters) : updater;
|
|
2907
|
+
onColumnFiltersChange ? onColumnFiltersChange(next) : setInternalColumnFilters(next);
|
|
2908
|
+
}, [columnFilters, onColumnFiltersChange]);
|
|
2909
|
+
const handleRowSelectionChange = useCallback((updater) => {
|
|
2910
|
+
const next = typeof updater === "function" ? updater(rowSelection) : updater;
|
|
2911
|
+
onRowSelectionChange ? onRowSelectionChange(next) : setInternalRowSelection(next);
|
|
2912
|
+
}, [rowSelection, onRowSelectionChange]);
|
|
2913
|
+
const handlePaginationChange = useCallback((updater) => {
|
|
2914
|
+
const next = typeof updater === "function" ? updater(pagination) : updater;
|
|
2915
|
+
onPaginationChange ? onPaginationChange(next) : setInternalPagination(next);
|
|
2916
|
+
}, [pagination, onPaginationChange]);
|
|
2917
|
+
const table = useReactTable({
|
|
2918
|
+
data,
|
|
2919
|
+
columns,
|
|
2920
|
+
state: {
|
|
2921
|
+
sorting,
|
|
2922
|
+
globalFilter,
|
|
2923
|
+
columnFilters,
|
|
2924
|
+
rowSelection,
|
|
2925
|
+
pagination
|
|
2926
|
+
},
|
|
2927
|
+
onSortingChange: handleSortingChange,
|
|
2928
|
+
onGlobalFilterChange: handleGlobalFilterChange,
|
|
2929
|
+
onColumnFiltersChange: handleColumnFiltersChange,
|
|
2930
|
+
onRowSelectionChange: handleRowSelectionChange,
|
|
2931
|
+
onPaginationChange: handlePaginationChange,
|
|
2932
|
+
getCoreRowModel: getCoreRowModel(),
|
|
2933
|
+
getSortedRowModel: getSortedRowModel(),
|
|
2934
|
+
getFilteredRowModel: getFilteredRowModel(),
|
|
2935
|
+
getPaginationRowModel: manualPagination ? void 0 : getPaginationRowModel(),
|
|
2936
|
+
enableRowSelection,
|
|
2937
|
+
getRowId,
|
|
2938
|
+
manualPagination,
|
|
2939
|
+
pageCount
|
|
2940
|
+
});
|
|
2941
|
+
const cellPadding = compact ? "px-4 py-2" : "px-6 py-4";
|
|
2942
|
+
const headerPadding = compact ? "px-4 py-2" : "px-6 py-3";
|
|
2943
|
+
if (enableVirtualization) return /* @__PURE__ */ jsx("div", {
|
|
2944
|
+
className: cn$9("overflow-hidden rounded-lg bg-[var(--dashboard-surface,#ffffff)] shadow-sm", bordered && "border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
|
|
2945
|
+
children: /* @__PURE__ */ jsx(VirtualRows, {
|
|
2946
|
+
table,
|
|
2947
|
+
rowHeight,
|
|
2948
|
+
onRowClick,
|
|
2949
|
+
compact
|
|
2950
|
+
})
|
|
2951
|
+
});
|
|
2952
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
2953
|
+
className: cn$9("overflow-hidden rounded-lg bg-[var(--dashboard-surface,#ffffff)] shadow-sm", bordered && "border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
|
|
2954
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
2955
|
+
className: "overflow-x-auto",
|
|
2956
|
+
children: /* @__PURE__ */ jsxs("table", {
|
|
2957
|
+
className: "min-w-full divide-y divide-[var(--dashboard-text-secondary,#6b7280)]/20",
|
|
2958
|
+
children: [/* @__PURE__ */ jsx("thead", {
|
|
2959
|
+
className: cn$9("bg-[var(--dashboard-text-secondary,#6b7280)]/5", stickyHeader && "sticky top-0 z-10"),
|
|
2960
|
+
children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx("tr", { children: headerGroup.headers.map((header) => /* @__PURE__ */ jsx("th", {
|
|
2961
|
+
scope: "col",
|
|
2962
|
+
className: cn$9("text-left text-xs font-semibold text-[var(--dashboard-text-secondary,#6b7280)] uppercase tracking-wider", headerPadding, header.column.getCanSort() && "cursor-pointer select-none"),
|
|
2963
|
+
style: header.getSize() !== 150 ? { width: header.getSize() } : void 0,
|
|
2964
|
+
onClick: header.column.getToggleSortingHandler(),
|
|
2965
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
2966
|
+
className: "flex items-center gap-1",
|
|
2967
|
+
children: [header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext()), header.column.getCanSort() && /* @__PURE__ */ jsx(SortIcon, { sorted: header.column.getIsSorted() })]
|
|
2968
|
+
})
|
|
2969
|
+
}, header.id)) }, headerGroup.id))
|
|
2970
|
+
}), /* @__PURE__ */ jsx("tbody", {
|
|
2971
|
+
className: "divide-y divide-[var(--dashboard-text-secondary,#6b7280)]/20",
|
|
2972
|
+
children: isLoading ? /* @__PURE__ */ jsx(DataGridSkeleton, {
|
|
2973
|
+
columns: columns.length,
|
|
2974
|
+
rows: skeletonRows,
|
|
2975
|
+
compact
|
|
2976
|
+
}) : table.getRowModel().rows.length === 0 ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", {
|
|
2977
|
+
colSpan: columns.length,
|
|
2978
|
+
className: "py-12",
|
|
2979
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
2980
|
+
className: "text-center",
|
|
2981
|
+
children: [emptyIcon || /* @__PURE__ */ jsx("svg", {
|
|
2982
|
+
className: "mx-auto h-10 w-10 text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
2983
|
+
fill: "none",
|
|
2984
|
+
stroke: "currentColor",
|
|
2985
|
+
viewBox: "0 0 24 24",
|
|
2986
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
2987
|
+
strokeLinecap: "round",
|
|
2988
|
+
strokeLinejoin: "round",
|
|
2989
|
+
strokeWidth: 2,
|
|
2990
|
+
d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
|
|
2991
|
+
})
|
|
2992
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
2993
|
+
className: "mt-3 text-sm text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
2994
|
+
children: emptyMessage
|
|
2995
|
+
})]
|
|
2996
|
+
})
|
|
2997
|
+
}) }) : table.getRowModel().rows.map((row, rowIndex) => /* @__PURE__ */ jsx("tr", {
|
|
2998
|
+
onClick: () => onRowClick?.(row.original),
|
|
2999
|
+
className: cn$9("transition-colors", onRowClick && "cursor-pointer", "hover:bg-[var(--dashboard-text-secondary,#6b7280)]/5", row.getIsSelected() && "bg-[var(--dashboard-primary,#37a501)]/5", striped && rowIndex % 2 === 1 && "bg-[var(--dashboard-text-secondary,#6b7280)]/3"),
|
|
3000
|
+
children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx("td", {
|
|
3001
|
+
className: cn$9(cellPadding, "text-sm text-[var(--dashboard-text-primary,#2d2d2d)]"),
|
|
3002
|
+
children: flexRender(cell.column.columnDef.cell, cell.getContext())
|
|
3003
|
+
}, cell.id))
|
|
3004
|
+
}, row.id))
|
|
3005
|
+
})]
|
|
3006
|
+
})
|
|
3007
|
+
}), (onPaginationChange || !manualPagination) && table.getPageCount() > 1 && /* @__PURE__ */ jsxs("div", {
|
|
3008
|
+
className: "flex items-center justify-between gap-4 flex-wrap border-t border-[var(--dashboard-text-secondary,#6b7280)]/20 px-4 py-3",
|
|
3009
|
+
children: [
|
|
3010
|
+
/* @__PURE__ */ jsxs("div", {
|
|
3011
|
+
className: "flex items-center gap-2",
|
|
3012
|
+
children: [/* @__PURE__ */ jsx("select", {
|
|
3013
|
+
value: pagination.pageSize,
|
|
3014
|
+
onChange: (e) => handlePaginationChange({
|
|
3015
|
+
pageIndex: 0,
|
|
3016
|
+
pageSize: Number(e.target.value)
|
|
3017
|
+
}),
|
|
3018
|
+
className: "rounded-md border border-[var(--dashboard-text-secondary,#6b7280)]/30 bg-[var(--dashboard-surface,#ffffff)] px-2 py-1 text-sm text-[var(--dashboard-text-primary,#2d2d2d)]",
|
|
3019
|
+
children: pageSizeOptions.map((size) => /* @__PURE__ */ jsx("option", {
|
|
3020
|
+
value: size,
|
|
3021
|
+
children: size
|
|
3022
|
+
}, size))
|
|
3023
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
3024
|
+
className: "text-sm text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
3025
|
+
children: "por pagina"
|
|
3026
|
+
})]
|
|
3027
|
+
}),
|
|
3028
|
+
/* @__PURE__ */ jsxs("span", {
|
|
3029
|
+
className: "text-sm text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
3030
|
+
children: [
|
|
3031
|
+
"Pagina ",
|
|
3032
|
+
pagination.pageIndex + 1,
|
|
3033
|
+
" de ",
|
|
3034
|
+
table.getPageCount()
|
|
3035
|
+
]
|
|
3036
|
+
}),
|
|
3037
|
+
/* @__PURE__ */ jsxs("div", {
|
|
3038
|
+
className: "flex items-center gap-1",
|
|
3039
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
3040
|
+
type: "button",
|
|
3041
|
+
onClick: () => table.previousPage(),
|
|
3042
|
+
disabled: !table.getCanPreviousPage(),
|
|
3043
|
+
className: "rounded-md p-1.5 text-[var(--dashboard-text-secondary,#6b7280)] hover:bg-[var(--dashboard-text-secondary,#6b7280)]/10 disabled:opacity-40 disabled:cursor-not-allowed transition-colors cursor-pointer",
|
|
3044
|
+
"aria-label": "Pagina anterior",
|
|
3045
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "h-4 w-4" })
|
|
3046
|
+
}), /* @__PURE__ */ jsx("button", {
|
|
3047
|
+
type: "button",
|
|
3048
|
+
onClick: () => table.nextPage(),
|
|
3049
|
+
disabled: !table.getCanNextPage(),
|
|
3050
|
+
className: "rounded-md p-1.5 text-[var(--dashboard-text-secondary,#6b7280)] hover:bg-[var(--dashboard-text-secondary,#6b7280)]/10 disabled:opacity-40 disabled:cursor-not-allowed transition-colors cursor-pointer",
|
|
3051
|
+
"aria-label": "Proxima pagina",
|
|
3052
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4" })
|
|
3053
|
+
})]
|
|
3054
|
+
})
|
|
3055
|
+
]
|
|
3056
|
+
})]
|
|
3057
|
+
});
|
|
3058
|
+
}
|
|
3059
|
+
|
|
3060
|
+
//#endregion
|
|
3061
|
+
//#region src/components/TreeView/index.tsx
|
|
3062
|
+
const cn$8 = (...classes) => classes.filter(Boolean).join(" ");
|
|
3063
|
+
function TreeItem({ node, level, expanded, selectedId, draggable, indentSize, onSelect, onToggle, onMove, renderNode, dragState, setDragState }) {
|
|
3064
|
+
const hasChildren = node.children && node.children.length > 0;
|
|
3065
|
+
const isExpanded = expanded.has(node.id);
|
|
3066
|
+
const isSelected = selectedId === node.id;
|
|
3067
|
+
const isDragging = dragState.draggingId === node.id;
|
|
3068
|
+
const isDropTarget = dragState.targetId === node.id;
|
|
3069
|
+
const handleDragStart = (e) => {
|
|
3070
|
+
if (!draggable || node.disabled) return;
|
|
3071
|
+
e.dataTransfer.setData("text/plain", node.id);
|
|
3072
|
+
e.dataTransfer.effectAllowed = "move";
|
|
3073
|
+
setDragState((prev) => ({
|
|
3074
|
+
...prev,
|
|
3075
|
+
draggingId: node.id
|
|
3076
|
+
}));
|
|
3077
|
+
};
|
|
3078
|
+
const handleDragOver = (e) => {
|
|
3079
|
+
if (!draggable || !dragState.draggingId || dragState.draggingId === node.id) return;
|
|
3080
|
+
e.preventDefault();
|
|
3081
|
+
e.dataTransfer.dropEffect = "move";
|
|
3082
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
3083
|
+
const y = e.clientY - rect.top;
|
|
3084
|
+
const height = rect.height;
|
|
3085
|
+
let position;
|
|
3086
|
+
if (y < height * .25) position = "before";
|
|
3087
|
+
else if (y > height * .75) position = "after";
|
|
3088
|
+
else position = "inside";
|
|
3089
|
+
setDragState((prev) => ({
|
|
3090
|
+
...prev,
|
|
3091
|
+
targetId: node.id,
|
|
3092
|
+
position
|
|
3093
|
+
}));
|
|
3094
|
+
};
|
|
3095
|
+
const handleDragLeave = () => {
|
|
3096
|
+
setDragState((prev) => {
|
|
3097
|
+
if (prev.targetId === node.id) return {
|
|
3098
|
+
...prev,
|
|
3099
|
+
targetId: null,
|
|
3100
|
+
position: null
|
|
3101
|
+
};
|
|
3102
|
+
return prev;
|
|
3103
|
+
});
|
|
3104
|
+
};
|
|
3105
|
+
const handleDrop = (e) => {
|
|
3106
|
+
e.preventDefault();
|
|
3107
|
+
if (!draggable || !dragState.draggingId || !dragState.position || dragState.draggingId === node.id) return;
|
|
3108
|
+
onMove?.(dragState.draggingId, node.id, dragState.position);
|
|
3109
|
+
setDragState({
|
|
3110
|
+
draggingId: null,
|
|
3111
|
+
targetId: null,
|
|
3112
|
+
position: null
|
|
3113
|
+
});
|
|
3114
|
+
};
|
|
3115
|
+
const handleDragEnd = () => {
|
|
3116
|
+
setDragState({
|
|
3117
|
+
draggingId: null,
|
|
3118
|
+
targetId: null,
|
|
3119
|
+
position: null
|
|
3120
|
+
});
|
|
3121
|
+
};
|
|
3122
|
+
return /* @__PURE__ */ jsxs("li", {
|
|
3123
|
+
role: "treeitem",
|
|
3124
|
+
"aria-expanded": hasChildren ? isExpanded : void 0,
|
|
3125
|
+
"aria-selected": isSelected,
|
|
3126
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
3127
|
+
className: cn$8("group flex items-center gap-1 rounded-md px-2 py-1.5 transition-colors", isSelected ? "bg-[var(--dashboard-primary,#37a501)]/10 text-[var(--dashboard-primary,#37a501)]" : "hover:bg-[var(--dashboard-text-secondary,#6b7280)]/10 text-[var(--dashboard-text-primary,#2d2d2d)]", isDragging && "opacity-40", isDropTarget && dragState.position === "inside" && "ring-2 ring-[var(--dashboard-primary,#37a501)] ring-inset", node.disabled && "opacity-50 cursor-not-allowed"),
|
|
3128
|
+
style: { paddingLeft: `${level * indentSize + 4}px` },
|
|
3129
|
+
draggable: draggable && !node.disabled,
|
|
3130
|
+
onDragStart: handleDragStart,
|
|
3131
|
+
onDragOver: handleDragOver,
|
|
3132
|
+
onDragLeave: handleDragLeave,
|
|
3133
|
+
onDrop: handleDrop,
|
|
3134
|
+
onDragEnd: handleDragEnd,
|
|
3135
|
+
children: [
|
|
3136
|
+
isDropTarget && dragState.position === "before" && /* @__PURE__ */ jsx("div", { className: "absolute left-0 right-0 top-0 h-0.5 bg-[var(--dashboard-primary,#37a501)]" }),
|
|
3137
|
+
isDropTarget && dragState.position === "after" && /* @__PURE__ */ jsx("div", { className: "absolute left-0 right-0 bottom-0 h-0.5 bg-[var(--dashboard-primary,#37a501)]" }),
|
|
3138
|
+
draggable && !node.disabled && /* @__PURE__ */ jsx("span", {
|
|
3139
|
+
className: "flex-shrink-0 opacity-0 group-hover:opacity-60 cursor-grab active:cursor-grabbing",
|
|
3140
|
+
children: /* @__PURE__ */ jsx(GripVertical, { className: "h-3.5 w-3.5 text-[var(--dashboard-text-secondary,#6b7280)]" })
|
|
3141
|
+
}),
|
|
3142
|
+
/* @__PURE__ */ jsx("button", {
|
|
3143
|
+
type: "button",
|
|
3144
|
+
onClick: () => hasChildren && onToggle(node.id),
|
|
3145
|
+
className: cn$8("flex-shrink-0 w-5 h-5 flex items-center justify-center rounded transition-transform", hasChildren ? "cursor-pointer" : "invisible"),
|
|
3146
|
+
tabIndex: hasChildren ? 0 : -1,
|
|
3147
|
+
"aria-label": isExpanded ? "Recolher" : "Expandir",
|
|
3148
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { className: cn$8("h-3.5 w-3.5 transition-transform duration-150", isExpanded && "rotate-90") })
|
|
3149
|
+
}),
|
|
3150
|
+
renderNode ? /* @__PURE__ */ jsx("div", {
|
|
3151
|
+
className: "flex-1 min-w-0 cursor-pointer",
|
|
3152
|
+
onClick: () => !node.disabled && onSelect?.(node),
|
|
3153
|
+
children: renderNode(node, isSelected, isExpanded)
|
|
3154
|
+
}) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3155
|
+
node.icon && /* @__PURE__ */ jsx("span", {
|
|
3156
|
+
className: "flex-shrink-0 h-4 w-4",
|
|
3157
|
+
children: node.icon
|
|
3158
|
+
}),
|
|
3159
|
+
/* @__PURE__ */ jsx("span", {
|
|
3160
|
+
className: cn$8("flex-1 min-w-0 text-sm truncate", !node.disabled && "cursor-pointer"),
|
|
3161
|
+
onClick: () => !node.disabled && onSelect?.(node),
|
|
3162
|
+
children: node.label
|
|
3163
|
+
}),
|
|
3164
|
+
node.badge && /* @__PURE__ */ jsx("span", {
|
|
3165
|
+
className: "flex-shrink-0",
|
|
3166
|
+
children: node.badge
|
|
3167
|
+
}),
|
|
3168
|
+
node.actions && /* @__PURE__ */ jsx("span", {
|
|
3169
|
+
className: "flex-shrink-0 opacity-0 group-hover:opacity-100 transition-opacity",
|
|
3170
|
+
children: node.actions
|
|
3171
|
+
})
|
|
3172
|
+
] })
|
|
3173
|
+
]
|
|
3174
|
+
}), hasChildren && isExpanded && /* @__PURE__ */ jsx("ul", {
|
|
3175
|
+
role: "group",
|
|
3176
|
+
className: "dashboard-animate-expand",
|
|
3177
|
+
children: node.children.map((child) => /* @__PURE__ */ jsx(TreeItem, {
|
|
3178
|
+
node: child,
|
|
3179
|
+
level: level + 1,
|
|
3180
|
+
expanded,
|
|
3181
|
+
selectedId,
|
|
3182
|
+
draggable,
|
|
3183
|
+
indentSize,
|
|
3184
|
+
onSelect,
|
|
3185
|
+
onToggle,
|
|
3186
|
+
onMove,
|
|
3187
|
+
renderNode,
|
|
3188
|
+
dragState,
|
|
3189
|
+
setDragState
|
|
3190
|
+
}, child.id))
|
|
3191
|
+
})]
|
|
3192
|
+
});
|
|
3193
|
+
}
|
|
3194
|
+
function TreeView({ nodes, onSelect, onExpand, onMove, renderNode, selectedId, defaultExpanded = [], draggable = false, indentSize = 20, className }) {
|
|
3195
|
+
const [expanded, setExpanded] = useState(() => new Set(defaultExpanded));
|
|
3196
|
+
const [dragState, setDragState] = useState({
|
|
3197
|
+
draggingId: null,
|
|
3198
|
+
targetId: null,
|
|
3199
|
+
position: null
|
|
3200
|
+
});
|
|
3201
|
+
const handleToggle = useCallback((nodeId) => {
|
|
3202
|
+
setExpanded((prev) => {
|
|
3203
|
+
const next = new Set(prev);
|
|
3204
|
+
const willExpand = !next.has(nodeId);
|
|
3205
|
+
if (willExpand) next.add(nodeId);
|
|
3206
|
+
else next.delete(nodeId);
|
|
3207
|
+
onExpand?.(nodeId, willExpand);
|
|
3208
|
+
return next;
|
|
3209
|
+
});
|
|
3210
|
+
}, [onExpand]);
|
|
3211
|
+
return /* @__PURE__ */ jsx("ul", {
|
|
3212
|
+
role: "tree",
|
|
3213
|
+
className: cn$8("select-none", className),
|
|
3214
|
+
children: nodes.map((node) => /* @__PURE__ */ jsx(TreeItem, {
|
|
3215
|
+
node,
|
|
3216
|
+
level: 0,
|
|
3217
|
+
expanded,
|
|
3218
|
+
selectedId,
|
|
3219
|
+
draggable,
|
|
3220
|
+
indentSize,
|
|
3221
|
+
onSelect,
|
|
3222
|
+
onToggle: handleToggle,
|
|
3223
|
+
onMove,
|
|
3224
|
+
renderNode,
|
|
3225
|
+
dragState,
|
|
3226
|
+
setDragState
|
|
3227
|
+
}, node.id))
|
|
3228
|
+
});
|
|
3229
|
+
}
|
|
3230
|
+
|
|
3231
|
+
//#endregion
|
|
3232
|
+
//#region src/components/Stepper/index.tsx
|
|
3233
|
+
const cn$7 = (...classes) => classes.filter(Boolean).join(" ");
|
|
3234
|
+
function StepIcon({ step, index }) {
|
|
3235
|
+
const status = step.status || "pending";
|
|
3236
|
+
if (status === "completed") return /* @__PURE__ */ jsx("div", {
|
|
3237
|
+
className: "flex h-8 w-8 items-center justify-center rounded-full bg-[var(--dashboard-primary,#37a501)] text-white flex-shrink-0",
|
|
3238
|
+
children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" })
|
|
3239
|
+
});
|
|
3240
|
+
if (status === "error") return /* @__PURE__ */ jsx("div", {
|
|
3241
|
+
className: "flex h-8 w-8 items-center justify-center rounded-full bg-[var(--dashboard-status-danger,#EF4444)] text-white flex-shrink-0",
|
|
3242
|
+
children: /* @__PURE__ */ jsx(AlertCircle, { className: "h-4 w-4" })
|
|
3243
|
+
});
|
|
3244
|
+
if (status === "active") return /* @__PURE__ */ jsx("div", {
|
|
3245
|
+
className: "flex h-8 w-8 items-center justify-center rounded-full border-2 border-[var(--dashboard-primary,#37a501)] bg-[var(--dashboard-primary,#37a501)]/10 text-[var(--dashboard-primary,#37a501)] flex-shrink-0",
|
|
3246
|
+
children: step.icon || /* @__PURE__ */ jsx("span", {
|
|
3247
|
+
className: "text-sm font-semibold",
|
|
3248
|
+
children: index + 1
|
|
3249
|
+
})
|
|
3250
|
+
});
|
|
3251
|
+
return /* @__PURE__ */ jsx("div", {
|
|
3252
|
+
className: "flex h-8 w-8 items-center justify-center rounded-full border-2 border-[var(--dashboard-text-secondary,#6b7280)]/30 text-[var(--dashboard-text-secondary,#6b7280)] flex-shrink-0",
|
|
3253
|
+
children: step.icon || /* @__PURE__ */ jsx("span", {
|
|
3254
|
+
className: "text-sm font-medium",
|
|
3255
|
+
children: index + 1
|
|
3256
|
+
})
|
|
3257
|
+
});
|
|
3258
|
+
}
|
|
3259
|
+
function Stepper({ steps, activeStep, onStepChange, orientation = "horizontal", className }) {
|
|
3260
|
+
const resolvedSteps = steps.map((step, i) => ({
|
|
3261
|
+
...step,
|
|
3262
|
+
status: step.status || (i < activeStep ? "completed" : i === activeStep ? "active" : "pending")
|
|
3263
|
+
}));
|
|
3264
|
+
if (orientation === "vertical") return /* @__PURE__ */ jsx("nav", {
|
|
3265
|
+
"aria-label": "Progress",
|
|
3266
|
+
className,
|
|
3267
|
+
children: /* @__PURE__ */ jsx("ol", {
|
|
3268
|
+
className: "flex flex-col",
|
|
3269
|
+
children: resolvedSteps.map((step, index) => /* @__PURE__ */ jsxs("li", {
|
|
3270
|
+
className: "flex gap-3",
|
|
3271
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
3272
|
+
className: "flex flex-col items-center",
|
|
3273
|
+
children: [/* @__PURE__ */ jsx("button", {
|
|
3274
|
+
type: "button",
|
|
3275
|
+
onClick: () => onStepChange?.(index),
|
|
3276
|
+
disabled: !onStepChange,
|
|
3277
|
+
className: cn$7("relative z-10", onStepChange && "cursor-pointer", !onStepChange && "cursor-default"),
|
|
3278
|
+
"aria-current": step.status === "active" ? "step" : void 0,
|
|
3279
|
+
children: /* @__PURE__ */ jsx(StepIcon, {
|
|
3280
|
+
step,
|
|
3281
|
+
index
|
|
3282
|
+
})
|
|
3283
|
+
}), index < resolvedSteps.length - 1 && /* @__PURE__ */ jsx("div", { className: cn$7("w-0.5 flex-1 min-h-[32px]", step.status === "completed" ? "bg-[var(--dashboard-primary,#37a501)]" : "bg-[var(--dashboard-text-secondary,#6b7280)]/20") })]
|
|
3284
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
3285
|
+
className: cn$7("pb-6", index === resolvedSteps.length - 1 && "pb-0"),
|
|
3286
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
3287
|
+
className: cn$7("text-sm font-medium leading-8", step.status === "active" ? "text-[var(--dashboard-primary,#37a501)]" : step.status === "completed" ? "text-[var(--dashboard-text-primary,#2d2d2d)]" : step.status === "error" ? "text-[var(--dashboard-status-danger,#EF4444)]" : "text-[var(--dashboard-text-secondary,#6b7280)]"),
|
|
3288
|
+
children: step.label
|
|
3289
|
+
}), step.description && /* @__PURE__ */ jsx("p", {
|
|
3290
|
+
className: "text-xs text-[var(--dashboard-text-secondary,#6b7280)] mt-0.5",
|
|
3291
|
+
children: step.description
|
|
3292
|
+
})]
|
|
3293
|
+
})]
|
|
3294
|
+
}, step.id))
|
|
3295
|
+
})
|
|
3296
|
+
});
|
|
3297
|
+
return /* @__PURE__ */ jsx("nav", {
|
|
3298
|
+
"aria-label": "Progress",
|
|
3299
|
+
className,
|
|
3300
|
+
children: /* @__PURE__ */ jsx("ol", {
|
|
3301
|
+
className: "flex items-center",
|
|
3302
|
+
children: resolvedSteps.map((step, index) => /* @__PURE__ */ jsxs("li", {
|
|
3303
|
+
className: cn$7("flex items-center", index < resolvedSteps.length - 1 && "flex-1"),
|
|
3304
|
+
children: [/* @__PURE__ */ jsxs("button", {
|
|
3305
|
+
type: "button",
|
|
3306
|
+
onClick: () => onStepChange?.(index),
|
|
3307
|
+
disabled: !onStepChange,
|
|
3308
|
+
className: cn$7("flex items-center gap-2 group", onStepChange && "cursor-pointer", !onStepChange && "cursor-default"),
|
|
3309
|
+
"aria-current": step.status === "active" ? "step" : void 0,
|
|
3310
|
+
children: [/* @__PURE__ */ jsx(StepIcon, {
|
|
3311
|
+
step,
|
|
3312
|
+
index
|
|
3313
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
3314
|
+
className: "hidden sm:block text-left",
|
|
3315
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
3316
|
+
className: cn$7("text-sm font-medium whitespace-nowrap", step.status === "active" ? "text-[var(--dashboard-primary,#37a501)]" : step.status === "completed" ? "text-[var(--dashboard-text-primary,#2d2d2d)]" : step.status === "error" ? "text-[var(--dashboard-status-danger,#EF4444)]" : "text-[var(--dashboard-text-secondary,#6b7280)]"),
|
|
3317
|
+
children: step.label
|
|
3318
|
+
}), step.description && /* @__PURE__ */ jsx("p", {
|
|
3319
|
+
className: "text-xs text-[var(--dashboard-text-secondary,#6b7280)] whitespace-nowrap",
|
|
3320
|
+
children: step.description
|
|
3321
|
+
})]
|
|
3322
|
+
})]
|
|
3323
|
+
}), index < resolvedSteps.length - 1 && /* @__PURE__ */ jsx("div", { className: cn$7("flex-1 h-0.5 mx-3", step.status === "completed" ? "bg-[var(--dashboard-primary,#37a501)]" : "bg-[var(--dashboard-text-secondary,#6b7280)]/20") })]
|
|
3324
|
+
}, step.id))
|
|
3325
|
+
})
|
|
3326
|
+
});
|
|
3327
|
+
}
|
|
3328
|
+
|
|
3329
|
+
//#endregion
|
|
3330
|
+
//#region src/components/FileUpload/index.tsx
|
|
3331
|
+
const cn$6 = (...classes) => classes.filter(Boolean).join(" ");
|
|
3332
|
+
function formatSize(bytes) {
|
|
3333
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
3334
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
3335
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
3336
|
+
}
|
|
3337
|
+
function isImageType(type) {
|
|
3338
|
+
return type.startsWith("image/");
|
|
3339
|
+
}
|
|
3340
|
+
function FileUpload({ accept, maxSize, multiple = false, onUpload, onRemove, preview = true, disabled = false, label = "Arraste arquivos aqui ou clique para selecionar", description, icon, maxFiles, className, files: controlledFiles }) {
|
|
3341
|
+
const [internalFiles, setInternalFiles] = useState([]);
|
|
3342
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
3343
|
+
const [error, setError] = useState(null);
|
|
3344
|
+
const inputRef = useRef(null);
|
|
3345
|
+
const files = controlledFiles || internalFiles;
|
|
3346
|
+
const validateFiles = useCallback((fileList) => {
|
|
3347
|
+
setError(null);
|
|
3348
|
+
const valid = [];
|
|
3349
|
+
for (const file of fileList) {
|
|
3350
|
+
if (maxSize && file.size > maxSize) {
|
|
3351
|
+
setError(`"${file.name}" excede o limite de ${formatSize(maxSize)}`);
|
|
3352
|
+
continue;
|
|
3353
|
+
}
|
|
3354
|
+
valid.push(file);
|
|
3355
|
+
}
|
|
3356
|
+
if (maxFiles) {
|
|
3357
|
+
const available = maxFiles - files.length;
|
|
3358
|
+
if (valid.length > available) {
|
|
3359
|
+
setError(`Limite de ${maxFiles} arquivos`);
|
|
3360
|
+
return valid.slice(0, Math.max(0, available));
|
|
3361
|
+
}
|
|
3362
|
+
}
|
|
3363
|
+
return valid;
|
|
3364
|
+
}, [
|
|
3365
|
+
maxSize,
|
|
3366
|
+
maxFiles,
|
|
3367
|
+
files.length
|
|
3368
|
+
]);
|
|
3369
|
+
const addFiles = useCallback((newFiles) => {
|
|
3370
|
+
const validated = validateFiles(newFiles);
|
|
3371
|
+
if (validated.length === 0) return;
|
|
3372
|
+
const uploaded = validated.map((file) => ({
|
|
3373
|
+
file,
|
|
3374
|
+
id: `${file.name}-${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
3375
|
+
preview: isImageType(file.type) ? URL.createObjectURL(file) : void 0
|
|
3376
|
+
}));
|
|
3377
|
+
if (!controlledFiles) setInternalFiles((prev) => multiple ? [...prev, ...uploaded] : uploaded);
|
|
3378
|
+
onUpload?.(validated);
|
|
3379
|
+
}, [
|
|
3380
|
+
validateFiles,
|
|
3381
|
+
multiple,
|
|
3382
|
+
onUpload,
|
|
3383
|
+
controlledFiles
|
|
3384
|
+
]);
|
|
3385
|
+
const handleRemove = useCallback((fileId) => {
|
|
3386
|
+
if (!controlledFiles) setInternalFiles((prev) => {
|
|
3387
|
+
const file = prev.find((f) => f.id === fileId);
|
|
3388
|
+
if (file?.preview) URL.revokeObjectURL(file.preview);
|
|
3389
|
+
return prev.filter((f) => f.id !== fileId);
|
|
3390
|
+
});
|
|
3391
|
+
onRemove?.(fileId);
|
|
3392
|
+
}, [onRemove, controlledFiles]);
|
|
3393
|
+
const handleDrop = useCallback((e) => {
|
|
3394
|
+
e.preventDefault();
|
|
3395
|
+
setIsDragging(false);
|
|
3396
|
+
if (disabled) return;
|
|
3397
|
+
addFiles(Array.from(e.dataTransfer.files));
|
|
3398
|
+
}, [addFiles, disabled]);
|
|
3399
|
+
const handleDragOver = useCallback((e) => {
|
|
3400
|
+
e.preventDefault();
|
|
3401
|
+
if (!disabled) setIsDragging(true);
|
|
3402
|
+
}, [disabled]);
|
|
3403
|
+
const handleDragLeave = useCallback((e) => {
|
|
3404
|
+
e.preventDefault();
|
|
3405
|
+
setIsDragging(false);
|
|
3406
|
+
}, []);
|
|
3407
|
+
const handleInputChange = useCallback((e) => {
|
|
3408
|
+
addFiles(e.target.files ? Array.from(e.target.files) : []);
|
|
3409
|
+
if (inputRef.current) inputRef.current.value = "";
|
|
3410
|
+
}, [addFiles]);
|
|
3411
|
+
useEffect(() => {
|
|
3412
|
+
return () => {
|
|
3413
|
+
internalFiles.forEach((f) => {
|
|
3414
|
+
if (f.preview) URL.revokeObjectURL(f.preview);
|
|
3415
|
+
});
|
|
3416
|
+
};
|
|
3417
|
+
}, []);
|
|
3418
|
+
const descText = description || [accept && `Formatos: ${accept}`, maxSize && `Tamanho max: ${formatSize(maxSize)}`].filter(Boolean).join(" | ") || void 0;
|
|
3419
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
3420
|
+
className,
|
|
3421
|
+
children: [
|
|
3422
|
+
/* @__PURE__ */ jsxs("div", {
|
|
3423
|
+
onDrop: handleDrop,
|
|
3424
|
+
onDragOver: handleDragOver,
|
|
3425
|
+
onDragLeave: handleDragLeave,
|
|
3426
|
+
onClick: () => !disabled && inputRef.current?.click(),
|
|
3427
|
+
className: cn$6("relative flex flex-col items-center justify-center rounded-lg border-2 border-dashed p-6 transition-colors", isDragging ? "border-[var(--dashboard-primary,#37a501)] bg-[var(--dashboard-primary,#37a501)]/5" : "border-[var(--dashboard-text-secondary,#6b7280)]/30 hover:border-[var(--dashboard-text-secondary,#6b7280)]/50", disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"),
|
|
3428
|
+
role: "button",
|
|
3429
|
+
tabIndex: disabled ? -1 : 0,
|
|
3430
|
+
"aria-label": label,
|
|
3431
|
+
onKeyDown: (e) => {
|
|
3432
|
+
if ((e.key === "Enter" || e.key === " ") && !disabled) {
|
|
3433
|
+
e.preventDefault();
|
|
3434
|
+
inputRef.current?.click();
|
|
3435
|
+
}
|
|
3436
|
+
},
|
|
3437
|
+
children: [/* @__PURE__ */ jsx("input", {
|
|
3438
|
+
ref: inputRef,
|
|
3439
|
+
type: "file",
|
|
3440
|
+
accept,
|
|
3441
|
+
multiple,
|
|
3442
|
+
onChange: handleInputChange,
|
|
3443
|
+
className: "hidden",
|
|
3444
|
+
disabled,
|
|
3445
|
+
"aria-hidden": "true",
|
|
3446
|
+
tabIndex: -1
|
|
3447
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
3448
|
+
className: "flex flex-col items-center text-center",
|
|
3449
|
+
children: [
|
|
3450
|
+
icon || /* @__PURE__ */ jsx(Upload, { className: cn$6("h-8 w-8 mb-3", isDragging ? "text-[var(--dashboard-primary,#37a501)]" : "text-[var(--dashboard-text-secondary,#6b7280)]") }),
|
|
3451
|
+
/* @__PURE__ */ jsx("p", {
|
|
3452
|
+
className: "text-sm font-medium text-[var(--dashboard-text-primary,#2d2d2d)]",
|
|
3453
|
+
children: label
|
|
3454
|
+
}),
|
|
3455
|
+
descText && /* @__PURE__ */ jsx("p", {
|
|
3456
|
+
className: "mt-1 text-xs text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
3457
|
+
children: descText
|
|
3458
|
+
})
|
|
3459
|
+
]
|
|
3460
|
+
})]
|
|
3461
|
+
}),
|
|
3462
|
+
error && /* @__PURE__ */ jsx("p", {
|
|
3463
|
+
className: "mt-2 text-xs text-[var(--dashboard-status-danger,#EF4444)]",
|
|
3464
|
+
children: error
|
|
3465
|
+
}),
|
|
3466
|
+
preview && files.length > 0 && /* @__PURE__ */ jsx("ul", {
|
|
3467
|
+
className: "mt-3 space-y-2",
|
|
3468
|
+
children: files.map((uploaded) => /* @__PURE__ */ jsxs("li", {
|
|
3469
|
+
className: "flex items-center gap-3 rounded-lg border border-[var(--dashboard-text-secondary,#6b7280)]/20 bg-[var(--dashboard-surface,#ffffff)] p-3",
|
|
3470
|
+
children: [
|
|
3471
|
+
uploaded.preview ? /* @__PURE__ */ jsx("img", {
|
|
3472
|
+
src: uploaded.preview,
|
|
3473
|
+
alt: uploaded.file.name,
|
|
3474
|
+
className: "h-10 w-10 rounded object-cover flex-shrink-0"
|
|
3475
|
+
}) : /* @__PURE__ */ jsx("div", {
|
|
3476
|
+
className: "flex h-10 w-10 items-center justify-center rounded bg-[var(--dashboard-text-secondary,#6b7280)]/10 flex-shrink-0",
|
|
3477
|
+
children: isImageType(uploaded.file.type) ? /* @__PURE__ */ jsx(Image, { className: "h-5 w-5 text-[var(--dashboard-text-secondary,#6b7280)]" }) : /* @__PURE__ */ jsx(File, { className: "h-5 w-5 text-[var(--dashboard-text-secondary,#6b7280)]" })
|
|
3478
|
+
}),
|
|
3479
|
+
/* @__PURE__ */ jsxs("div", {
|
|
3480
|
+
className: "flex-1 min-w-0",
|
|
3481
|
+
children: [
|
|
3482
|
+
/* @__PURE__ */ jsx("p", {
|
|
3483
|
+
className: "text-sm font-medium text-[var(--dashboard-text-primary,#2d2d2d)] truncate",
|
|
3484
|
+
children: uploaded.file.name
|
|
3485
|
+
}),
|
|
3486
|
+
/* @__PURE__ */ jsx("p", {
|
|
3487
|
+
className: "text-xs text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
3488
|
+
children: formatSize(uploaded.file.size)
|
|
3489
|
+
}),
|
|
3490
|
+
uploaded.progress !== void 0 && uploaded.progress < 100 && /* @__PURE__ */ jsx("div", {
|
|
3491
|
+
className: "mt-1 h-1 w-full rounded-full bg-[var(--dashboard-text-secondary,#6b7280)]/10 overflow-hidden",
|
|
3492
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
3493
|
+
className: "h-full rounded-full bg-[var(--dashboard-primary,#37a501)] transition-all duration-300",
|
|
3494
|
+
style: { width: `${uploaded.progress}%` }
|
|
3495
|
+
})
|
|
3496
|
+
})
|
|
3497
|
+
]
|
|
3498
|
+
}),
|
|
3499
|
+
/* @__PURE__ */ jsx("button", {
|
|
3500
|
+
onClick: (e) => {
|
|
3501
|
+
e.stopPropagation();
|
|
3502
|
+
handleRemove(uploaded.id);
|
|
3503
|
+
},
|
|
3504
|
+
className: "flex-shrink-0 rounded-md p-1 text-[var(--dashboard-text-secondary,#6b7280)] hover:bg-[var(--dashboard-text-secondary,#6b7280)]/10 transition-colors cursor-pointer",
|
|
3505
|
+
"aria-label": `Remover ${uploaded.file.name}`,
|
|
3506
|
+
children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
|
|
3507
|
+
})
|
|
3508
|
+
]
|
|
3509
|
+
}, uploaded.id))
|
|
3510
|
+
})
|
|
3511
|
+
]
|
|
3512
|
+
});
|
|
3513
|
+
}
|
|
3514
|
+
|
|
3515
|
+
//#endregion
|
|
3516
|
+
//#region src/components/Tooltip/index.tsx
|
|
3517
|
+
const cn$5 = (...classes) => classes.filter(Boolean).join(" ");
|
|
3518
|
+
function Tooltip({ content, position = "top", delay = 200, children, className, maxWidth = 240 }) {
|
|
3519
|
+
const [visible, setVisible] = useState(false);
|
|
3520
|
+
const [coords, setCoords] = useState({
|
|
3521
|
+
top: 0,
|
|
3522
|
+
left: 0
|
|
3523
|
+
});
|
|
3524
|
+
const triggerRef = useRef(null);
|
|
3525
|
+
const tooltipRef = useRef(null);
|
|
3526
|
+
const timeoutRef = useRef();
|
|
3527
|
+
const idRef = useRef(`tooltip-${Math.random().toString(36).slice(2, 9)}`);
|
|
3528
|
+
const calculatePosition = useCallback(() => {
|
|
3529
|
+
if (!triggerRef.current || !tooltipRef.current) return;
|
|
3530
|
+
const trigger = triggerRef.current.getBoundingClientRect();
|
|
3531
|
+
const tooltip = tooltipRef.current.getBoundingClientRect();
|
|
3532
|
+
const gap = 8;
|
|
3533
|
+
let top = 0;
|
|
3534
|
+
let left = 0;
|
|
3535
|
+
switch (position) {
|
|
3536
|
+
case "top":
|
|
3537
|
+
top = trigger.top - tooltip.height - gap;
|
|
3538
|
+
left = trigger.left + trigger.width / 2 - tooltip.width / 2;
|
|
3539
|
+
break;
|
|
3540
|
+
case "bottom":
|
|
3541
|
+
top = trigger.bottom + gap;
|
|
3542
|
+
left = trigger.left + trigger.width / 2 - tooltip.width / 2;
|
|
3543
|
+
break;
|
|
3544
|
+
case "left":
|
|
3545
|
+
top = trigger.top + trigger.height / 2 - tooltip.height / 2;
|
|
3546
|
+
left = trigger.left - tooltip.width - gap;
|
|
3547
|
+
break;
|
|
3548
|
+
case "right":
|
|
3549
|
+
top = trigger.top + trigger.height / 2 - tooltip.height / 2;
|
|
3550
|
+
left = trigger.right + gap;
|
|
3551
|
+
break;
|
|
3552
|
+
}
|
|
3553
|
+
left = Math.max(8, Math.min(left, window.innerWidth - tooltip.width - 8));
|
|
3554
|
+
top = Math.max(8, Math.min(top, window.innerHeight - tooltip.height - 8));
|
|
3555
|
+
setCoords({
|
|
3556
|
+
top,
|
|
3557
|
+
left
|
|
3558
|
+
});
|
|
3559
|
+
}, [position]);
|
|
3560
|
+
const show = useCallback(() => {
|
|
3561
|
+
timeoutRef.current = setTimeout(() => {
|
|
3562
|
+
setVisible(true);
|
|
3563
|
+
}, delay);
|
|
3564
|
+
}, [delay]);
|
|
3565
|
+
const hide = useCallback(() => {
|
|
3566
|
+
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
3567
|
+
setVisible(false);
|
|
3568
|
+
}, []);
|
|
3569
|
+
useEffect(() => {
|
|
3570
|
+
if (visible) requestAnimationFrame(calculatePosition);
|
|
3571
|
+
}, [visible, calculatePosition]);
|
|
3572
|
+
useEffect(() => {
|
|
3573
|
+
return () => {
|
|
3574
|
+
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
3575
|
+
};
|
|
3576
|
+
}, []);
|
|
3577
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
3578
|
+
ref: triggerRef,
|
|
3579
|
+
onMouseEnter: show,
|
|
3580
|
+
onMouseLeave: hide,
|
|
3581
|
+
onFocus: show,
|
|
3582
|
+
onBlur: hide,
|
|
3583
|
+
"aria-describedby": visible ? idRef.current : void 0,
|
|
3584
|
+
className: "inline-flex",
|
|
3585
|
+
children
|
|
3586
|
+
}), visible && typeof document !== "undefined" && createPortal(/* @__PURE__ */ jsx("div", {
|
|
3587
|
+
ref: tooltipRef,
|
|
3588
|
+
id: idRef.current,
|
|
3589
|
+
role: "tooltip",
|
|
3590
|
+
className: cn$5("fixed z-[10002] rounded-md px-3 py-2 text-xs font-medium", "bg-[var(--dashboard-text-primary,#2d2d2d)] text-white", "shadow-lg dashboard-animate-fade-in pointer-events-none", className),
|
|
3591
|
+
style: {
|
|
3592
|
+
top: coords.top,
|
|
3593
|
+
left: coords.left,
|
|
3594
|
+
maxWidth
|
|
3595
|
+
},
|
|
3596
|
+
children: content
|
|
3597
|
+
}), document.body)] });
|
|
3598
|
+
}
|
|
3599
|
+
|
|
3600
|
+
//#endregion
|
|
3601
|
+
//#region src/components/Breadcrumb/index.tsx
|
|
3602
|
+
const cn$4 = (...classes) => classes.filter(Boolean).join(" ");
|
|
3603
|
+
function Breadcrumb({ items, separator, onNavigate, className }) {
|
|
3604
|
+
const defaultSeparator = /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4 text-[var(--dashboard-text-secondary,#6b7280)] flex-shrink-0" });
|
|
3605
|
+
const handleClick = (e, href) => {
|
|
3606
|
+
if (href && onNavigate) {
|
|
3607
|
+
e.preventDefault();
|
|
3608
|
+
onNavigate(href);
|
|
3609
|
+
}
|
|
3610
|
+
};
|
|
3611
|
+
return /* @__PURE__ */ jsx("nav", {
|
|
3612
|
+
"aria-label": "Breadcrumb",
|
|
3613
|
+
className,
|
|
3614
|
+
children: /* @__PURE__ */ jsx("ol", {
|
|
3615
|
+
className: "flex items-center gap-1.5 flex-wrap",
|
|
3616
|
+
children: items.map((item, index) => {
|
|
3617
|
+
const isLast = index === items.length - 1;
|
|
3618
|
+
return /* @__PURE__ */ jsxs("li", {
|
|
3619
|
+
className: "flex items-center gap-1.5",
|
|
3620
|
+
children: [index > 0 && /* @__PURE__ */ jsx("span", {
|
|
3621
|
+
"aria-hidden": "true",
|
|
3622
|
+
children: separator || defaultSeparator
|
|
3623
|
+
}), isLast ? /* @__PURE__ */ jsxs("span", {
|
|
3624
|
+
className: cn$4("flex items-center gap-1.5 text-sm font-medium", "text-[var(--dashboard-text-primary,#2d2d2d)]"),
|
|
3625
|
+
"aria-current": "page",
|
|
3626
|
+
children: [item.icon && /* @__PURE__ */ jsx("span", {
|
|
3627
|
+
className: "flex-shrink-0 h-4 w-4",
|
|
3628
|
+
children: item.icon
|
|
3629
|
+
}), item.label]
|
|
3630
|
+
}) : /* @__PURE__ */ jsxs("a", {
|
|
3631
|
+
href: item.href || "#",
|
|
3632
|
+
onClick: (e) => handleClick(e, item.href),
|
|
3633
|
+
className: cn$4("flex items-center gap-1.5 text-sm", "text-[var(--dashboard-text-secondary,#6b7280)]", "hover:text-[var(--dashboard-primary,#37a501)] transition-colors"),
|
|
3634
|
+
children: [item.icon && /* @__PURE__ */ jsx("span", {
|
|
3635
|
+
className: "flex-shrink-0 h-4 w-4",
|
|
3636
|
+
children: item.icon
|
|
3637
|
+
}), item.label]
|
|
3638
|
+
})]
|
|
3639
|
+
}, index);
|
|
3640
|
+
})
|
|
3641
|
+
})
|
|
3642
|
+
});
|
|
3643
|
+
}
|
|
3644
|
+
|
|
3645
|
+
//#endregion
|
|
3646
|
+
//#region src/components/Combobox/index.tsx
|
|
3647
|
+
const cn$3 = (...classes) => classes.filter(Boolean).join(" ");
|
|
3648
|
+
function Combobox({ options, value, onChange, multiple = false, searchable = true, placeholder = "Selecione...", label, error, disabled = false, renderOption, noResultsText = "Nenhum resultado encontrado", className }) {
|
|
3649
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
3650
|
+
const [query, setQuery] = useState("");
|
|
3651
|
+
const [position, setPosition] = useState({
|
|
3652
|
+
top: 0,
|
|
3653
|
+
left: 0,
|
|
3654
|
+
width: 0
|
|
3655
|
+
});
|
|
3656
|
+
const [focusedIndex, setFocusedIndex] = useState(-1);
|
|
3657
|
+
const containerRef = useRef(null);
|
|
3658
|
+
const inputRef = useRef(null);
|
|
3659
|
+
const listRef = useRef(null);
|
|
3660
|
+
const selectedValues = useMemo(() => {
|
|
3661
|
+
if (!value) return [];
|
|
3662
|
+
return Array.isArray(value) ? value : [value];
|
|
3663
|
+
}, [value]);
|
|
3664
|
+
const filtered = useMemo(() => {
|
|
3665
|
+
if (!query) return options;
|
|
3666
|
+
const lower = query.toLowerCase();
|
|
3667
|
+
return options.filter((o) => o.label.toLowerCase().includes(lower));
|
|
3668
|
+
}, [options, query]);
|
|
3669
|
+
const calculatePosition = useCallback(() => {
|
|
3670
|
+
if (!containerRef.current) return;
|
|
3671
|
+
const rect = containerRef.current.getBoundingClientRect();
|
|
3672
|
+
setPosition({
|
|
3673
|
+
top: rect.bottom + 4,
|
|
3674
|
+
left: rect.left,
|
|
3675
|
+
width: rect.width
|
|
3676
|
+
});
|
|
3677
|
+
}, []);
|
|
3678
|
+
const open = useCallback(() => {
|
|
3679
|
+
if (disabled) return;
|
|
3680
|
+
calculatePosition();
|
|
3681
|
+
setIsOpen(true);
|
|
3682
|
+
setFocusedIndex(-1);
|
|
3683
|
+
setTimeout(() => inputRef.current?.focus(), 0);
|
|
3684
|
+
}, [disabled, calculatePosition]);
|
|
3685
|
+
const close = useCallback(() => {
|
|
3686
|
+
setIsOpen(false);
|
|
3687
|
+
setQuery("");
|
|
3688
|
+
setFocusedIndex(-1);
|
|
3689
|
+
}, []);
|
|
3690
|
+
const toggleOption = useCallback((optionValue) => {
|
|
3691
|
+
if (multiple) {
|
|
3692
|
+
const current = selectedValues;
|
|
3693
|
+
onChange(current.includes(optionValue) ? current.filter((v) => v !== optionValue) : [...current, optionValue]);
|
|
3694
|
+
} else {
|
|
3695
|
+
onChange(optionValue);
|
|
3696
|
+
close();
|
|
3697
|
+
}
|
|
3698
|
+
}, [
|
|
3699
|
+
multiple,
|
|
3700
|
+
selectedValues,
|
|
3701
|
+
onChange,
|
|
3702
|
+
close
|
|
3703
|
+
]);
|
|
3704
|
+
const removeValue = useCallback((val, e) => {
|
|
3705
|
+
e?.stopPropagation();
|
|
3706
|
+
if (multiple) onChange(selectedValues.filter((v) => v !== val));
|
|
3707
|
+
else onChange(multiple ? [] : "");
|
|
3708
|
+
}, [
|
|
3709
|
+
multiple,
|
|
3710
|
+
selectedValues,
|
|
3711
|
+
onChange
|
|
3712
|
+
]);
|
|
3713
|
+
useEffect(() => {
|
|
3714
|
+
if (!isOpen) return;
|
|
3715
|
+
const handleClick = (e) => {
|
|
3716
|
+
const portal = document.querySelector(".dc-combobox-portal");
|
|
3717
|
+
if (containerRef.current && !containerRef.current.contains(e.target) && (!portal || !portal.contains(e.target))) close();
|
|
3718
|
+
};
|
|
3719
|
+
const handleScroll = (e) => {
|
|
3720
|
+
const portal = document.querySelector(".dc-combobox-portal");
|
|
3721
|
+
if (!portal || !portal.contains(e.target)) close();
|
|
3722
|
+
};
|
|
3723
|
+
document.addEventListener("mousedown", handleClick);
|
|
3724
|
+
window.addEventListener("scroll", handleScroll, true);
|
|
3725
|
+
window.addEventListener("resize", close);
|
|
3726
|
+
return () => {
|
|
3727
|
+
document.removeEventListener("mousedown", handleClick);
|
|
3728
|
+
window.removeEventListener("scroll", handleScroll, true);
|
|
3729
|
+
window.removeEventListener("resize", close);
|
|
3730
|
+
};
|
|
3731
|
+
}, [isOpen, close]);
|
|
3732
|
+
const handleKeyDown = useCallback((e) => {
|
|
3733
|
+
if (!isOpen) {
|
|
3734
|
+
if (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") {
|
|
3735
|
+
e.preventDefault();
|
|
3736
|
+
open();
|
|
3737
|
+
}
|
|
3738
|
+
return;
|
|
3739
|
+
}
|
|
3740
|
+
switch (e.key) {
|
|
3741
|
+
case "ArrowDown":
|
|
3742
|
+
e.preventDefault();
|
|
3743
|
+
setFocusedIndex((prev) => {
|
|
3744
|
+
const next = prev + 1;
|
|
3745
|
+
return next >= filtered.length ? 0 : next;
|
|
3746
|
+
});
|
|
3747
|
+
break;
|
|
3748
|
+
case "ArrowUp":
|
|
3749
|
+
e.preventDefault();
|
|
3750
|
+
setFocusedIndex((prev) => {
|
|
3751
|
+
const next = prev - 1;
|
|
3752
|
+
return next < 0 ? filtered.length - 1 : next;
|
|
3753
|
+
});
|
|
3754
|
+
break;
|
|
3755
|
+
case "Enter":
|
|
3756
|
+
e.preventDefault();
|
|
3757
|
+
if (focusedIndex >= 0 && filtered[focusedIndex] && !filtered[focusedIndex].disabled) toggleOption(filtered[focusedIndex].value);
|
|
3758
|
+
break;
|
|
3759
|
+
case "Escape":
|
|
3760
|
+
e.preventDefault();
|
|
3761
|
+
close();
|
|
3762
|
+
break;
|
|
3763
|
+
}
|
|
3764
|
+
}, [
|
|
3765
|
+
isOpen,
|
|
3766
|
+
open,
|
|
3767
|
+
close,
|
|
3768
|
+
filtered,
|
|
3769
|
+
focusedIndex,
|
|
3770
|
+
toggleOption
|
|
3771
|
+
]);
|
|
3772
|
+
useEffect(() => {
|
|
3773
|
+
if (focusedIndex >= 0 && listRef.current) listRef.current.children[focusedIndex]?.scrollIntoView({ block: "nearest" });
|
|
3774
|
+
}, [focusedIndex]);
|
|
3775
|
+
const selectedLabels = selectedValues.map((v) => options.find((o) => o.value === v)?.label).filter(Boolean);
|
|
3776
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
3777
|
+
className: cn$3("space-y-2", className),
|
|
3778
|
+
children: [
|
|
3779
|
+
label && /* @__PURE__ */ jsx("label", {
|
|
3780
|
+
className: "block text-sm text-[var(--dashboard-text-primary,#2d2d2d)]",
|
|
3781
|
+
children: label
|
|
3782
|
+
}),
|
|
3783
|
+
/* @__PURE__ */ jsxs("div", {
|
|
3784
|
+
ref: containerRef,
|
|
3785
|
+
onKeyDown: handleKeyDown,
|
|
3786
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
3787
|
+
role: "combobox",
|
|
3788
|
+
"aria-expanded": isOpen,
|
|
3789
|
+
"aria-haspopup": "listbox",
|
|
3790
|
+
"aria-controls": "combobox-listbox",
|
|
3791
|
+
tabIndex: disabled ? -1 : 0,
|
|
3792
|
+
onClick: () => isOpen ? close() : open(),
|
|
3793
|
+
className: cn$3("flex min-h-[40px] w-full items-center gap-2 rounded-lg border px-3 py-2 transition-colors", isOpen ? "border-[var(--dashboard-primary,#37a501)] ring-2 ring-[var(--dashboard-primary,#37a501)]/20" : error ? "border-[var(--dashboard-status-danger,#EF4444)]" : "border-[var(--dashboard-text-secondary,#6b7280)]/30 hover:border-[var(--dashboard-text-secondary,#6b7280)]/50", disabled ? "opacity-50 cursor-not-allowed bg-[var(--dashboard-text-secondary,#6b7280)]/10" : "cursor-pointer bg-[var(--dashboard-surface,#ffffff)]"),
|
|
3794
|
+
children: [
|
|
3795
|
+
/* @__PURE__ */ jsx("div", {
|
|
3796
|
+
className: "flex flex-1 flex-wrap items-center gap-1 min-w-0",
|
|
3797
|
+
children: multiple && selectedLabels.length > 0 ? selectedLabels.map((lbl, i) => /* @__PURE__ */ jsxs("span", {
|
|
3798
|
+
className: "inline-flex items-center gap-1 rounded-md bg-[var(--dashboard-primary,#37a501)]/10 px-2 py-0.5 text-xs font-medium text-[var(--dashboard-primary,#37a501)]",
|
|
3799
|
+
children: [lbl, /* @__PURE__ */ jsx("button", {
|
|
3800
|
+
type: "button",
|
|
3801
|
+
onClick: (e) => removeValue(selectedValues[i], e),
|
|
3802
|
+
className: "rounded-sm hover:bg-[var(--dashboard-primary,#37a501)]/20 cursor-pointer",
|
|
3803
|
+
"aria-label": `Remover ${lbl}`,
|
|
3804
|
+
children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
|
|
3805
|
+
})]
|
|
3806
|
+
}, selectedValues[i])) : !multiple && selectedLabels.length === 1 ? /* @__PURE__ */ jsx("span", {
|
|
3807
|
+
className: "text-sm text-[var(--dashboard-text-primary,#2d2d2d)] truncate",
|
|
3808
|
+
children: selectedLabels[0]
|
|
3809
|
+
}) : /* @__PURE__ */ jsx("span", {
|
|
3810
|
+
className: "text-sm text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
3811
|
+
children: placeholder
|
|
3812
|
+
})
|
|
3813
|
+
}),
|
|
3814
|
+
!multiple && selectedValues.length > 0 && /* @__PURE__ */ jsx("button", {
|
|
3815
|
+
type: "button",
|
|
3816
|
+
onClick: (e) => removeValue(selectedValues[0], e),
|
|
3817
|
+
className: "flex-shrink-0 rounded-md p-0.5 text-[var(--dashboard-text-secondary,#6b7280)] hover:bg-[var(--dashboard-text-secondary,#6b7280)]/10 cursor-pointer",
|
|
3818
|
+
"aria-label": "Limpar seleção",
|
|
3819
|
+
children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5" })
|
|
3820
|
+
}),
|
|
3821
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: cn$3("h-4 w-4 flex-shrink-0 text-[var(--dashboard-text-secondary,#6b7280)] transition-transform", isOpen && "rotate-180") })
|
|
3822
|
+
]
|
|
3823
|
+
}), isOpen && typeof document !== "undefined" && createPortal(/* @__PURE__ */ jsxs("div", {
|
|
3824
|
+
className: "dc-combobox-portal rounded-lg border border-[var(--dashboard-text-secondary,#6b7280)]/20 bg-[var(--dashboard-surface,#ffffff)] shadow-lg dashboard-animate-fade-in overflow-hidden",
|
|
3825
|
+
style: {
|
|
3826
|
+
position: "fixed",
|
|
3827
|
+
top: position.top,
|
|
3828
|
+
left: position.left,
|
|
3829
|
+
width: position.width,
|
|
3830
|
+
zIndex: 10001
|
|
3831
|
+
},
|
|
3832
|
+
children: [searchable && /* @__PURE__ */ jsxs("div", {
|
|
3833
|
+
className: "flex items-center gap-2 border-b border-[var(--dashboard-text-secondary,#6b7280)]/20 px-3 py-2",
|
|
3834
|
+
children: [/* @__PURE__ */ jsx(Search, { className: "h-4 w-4 text-[var(--dashboard-text-secondary,#6b7280)] flex-shrink-0" }), /* @__PURE__ */ jsx("input", {
|
|
3835
|
+
ref: inputRef,
|
|
3836
|
+
type: "text",
|
|
3837
|
+
value: query,
|
|
3838
|
+
onChange: (e) => {
|
|
3839
|
+
setQuery(e.target.value);
|
|
3840
|
+
setFocusedIndex(-1);
|
|
3841
|
+
},
|
|
3842
|
+
placeholder: "Buscar...",
|
|
3843
|
+
className: "flex-1 bg-transparent text-sm text-[var(--dashboard-text-primary,#2d2d2d)] placeholder:text-[var(--dashboard-text-secondary,#6b7280)] outline-none",
|
|
3844
|
+
"aria-label": "Buscar opções"
|
|
3845
|
+
})]
|
|
3846
|
+
}), /* @__PURE__ */ jsx("ul", {
|
|
3847
|
+
ref: listRef,
|
|
3848
|
+
id: "combobox-listbox",
|
|
3849
|
+
role: "listbox",
|
|
3850
|
+
"aria-multiselectable": multiple,
|
|
3851
|
+
className: "max-h-60 overflow-y-auto py-1",
|
|
3852
|
+
children: filtered.length === 0 ? /* @__PURE__ */ jsx("li", {
|
|
3853
|
+
className: "px-3 py-3 text-center text-sm text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
3854
|
+
children: noResultsText
|
|
3855
|
+
}) : filtered.map((option, index) => {
|
|
3856
|
+
const isSelected = selectedValues.includes(option.value);
|
|
3857
|
+
const isFocused = index === focusedIndex;
|
|
3858
|
+
return /* @__PURE__ */ jsx("li", {
|
|
3859
|
+
role: "option",
|
|
3860
|
+
"aria-selected": isSelected,
|
|
3861
|
+
"aria-disabled": option.disabled,
|
|
3862
|
+
"data-modal-ignore": true,
|
|
3863
|
+
onClick: () => {
|
|
3864
|
+
if (!option.disabled) toggleOption(option.value);
|
|
3865
|
+
},
|
|
3866
|
+
className: cn$3("flex items-center justify-between px-3 py-2 text-sm transition-colors", option.disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer", isFocused && "bg-[var(--dashboard-text-secondary,#6b7280)]/10", !isFocused && !option.disabled && "hover:bg-[var(--dashboard-text-secondary,#6b7280)]/10", isSelected ? "text-[var(--dashboard-primary,#37a501)] font-medium" : "text-[var(--dashboard-text-primary,#2d2d2d)]"),
|
|
3867
|
+
children: renderOption ? renderOption(option, isSelected) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
3868
|
+
className: "truncate",
|
|
3869
|
+
children: option.label
|
|
3870
|
+
}), isSelected && /* @__PURE__ */ jsx(Check, { className: "h-4 w-4 flex-shrink-0 text-[var(--dashboard-primary,#37a501)]" })] })
|
|
3871
|
+
}, option.value);
|
|
3872
|
+
})
|
|
3873
|
+
})]
|
|
3874
|
+
}), document.body)]
|
|
3875
|
+
}),
|
|
3876
|
+
error && /* @__PURE__ */ jsx("p", {
|
|
3877
|
+
className: "text-xs text-[var(--dashboard-status-danger,#EF4444)]",
|
|
3878
|
+
children: error
|
|
3879
|
+
})
|
|
3880
|
+
]
|
|
3881
|
+
});
|
|
3882
|
+
}
|
|
3883
|
+
|
|
3884
|
+
//#endregion
|
|
3885
|
+
//#region src/components/Alert/index.tsx
|
|
3886
|
+
const cn$2 = (...classes) => classes.filter(Boolean).join(" ");
|
|
3887
|
+
const variantConfig = {
|
|
3888
|
+
info: {
|
|
3889
|
+
border: "border-[var(--dashboard-status-info,#3b82f6)]",
|
|
3890
|
+
bg: "bg-[var(--dashboard-status-info,#3b82f6)]/5",
|
|
3891
|
+
text: "text-[var(--dashboard-status-info,#3b82f6)]",
|
|
3892
|
+
icon: /* @__PURE__ */ jsx(Info, { className: "h-5 w-5" })
|
|
3893
|
+
},
|
|
3894
|
+
success: {
|
|
3895
|
+
border: "border-[var(--dashboard-status-success,#10B981)]",
|
|
3896
|
+
bg: "bg-[var(--dashboard-status-success,#10B981)]/5",
|
|
3897
|
+
text: "text-[var(--dashboard-status-success,#10B981)]",
|
|
3898
|
+
icon: /* @__PURE__ */ jsx(CheckCircle, { className: "h-5 w-5" })
|
|
3899
|
+
},
|
|
3900
|
+
warning: {
|
|
3901
|
+
border: "border-[var(--dashboard-status-warning,#f59e0b)]",
|
|
3902
|
+
bg: "bg-[var(--dashboard-status-warning,#f59e0b)]/5",
|
|
3903
|
+
text: "text-[var(--dashboard-status-warning,#f59e0b)]",
|
|
3904
|
+
icon: /* @__PURE__ */ jsx(AlertTriangle, { className: "h-5 w-5" })
|
|
3905
|
+
},
|
|
3906
|
+
danger: {
|
|
3907
|
+
border: "border-[var(--dashboard-status-danger,#EF4444)]",
|
|
3908
|
+
bg: "bg-[var(--dashboard-status-danger,#EF4444)]/5",
|
|
3909
|
+
text: "text-[var(--dashboard-status-danger,#EF4444)]",
|
|
3910
|
+
icon: /* @__PURE__ */ jsx(AlertOctagon, { className: "h-5 w-5" })
|
|
3911
|
+
}
|
|
3912
|
+
};
|
|
3913
|
+
function Alert({ variant = "info", title, description, onClose, actions, icon, className }) {
|
|
3914
|
+
const config = variantConfig[variant];
|
|
3915
|
+
return /* @__PURE__ */ jsx("div", {
|
|
3916
|
+
className: cn$2("rounded-lg border-l-4 p-4", config.border, config.bg, className),
|
|
3917
|
+
role: "alert",
|
|
3918
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
3919
|
+
className: "flex gap-3",
|
|
3920
|
+
children: [
|
|
3921
|
+
/* @__PURE__ */ jsx("div", {
|
|
3922
|
+
className: cn$2("flex-shrink-0 mt-0.5", config.text),
|
|
3923
|
+
children: icon || config.icon
|
|
3924
|
+
}),
|
|
3925
|
+
/* @__PURE__ */ jsxs("div", {
|
|
3926
|
+
className: "flex-1 min-w-0",
|
|
3927
|
+
children: [
|
|
3928
|
+
title && /* @__PURE__ */ jsx("h3", {
|
|
3929
|
+
className: cn$2("text-sm font-semibold", "text-[var(--dashboard-text-primary,#2d2d2d)]"),
|
|
3930
|
+
children: title
|
|
3931
|
+
}),
|
|
3932
|
+
description && /* @__PURE__ */ jsx("div", {
|
|
3933
|
+
className: cn$2("text-sm text-[var(--dashboard-text-secondary,#6b7280)]", title && "mt-1"),
|
|
3934
|
+
children: description
|
|
3935
|
+
}),
|
|
3936
|
+
actions && /* @__PURE__ */ jsx("div", {
|
|
3937
|
+
className: "mt-3 flex gap-2",
|
|
3938
|
+
children: actions
|
|
3939
|
+
})
|
|
3940
|
+
]
|
|
3941
|
+
}),
|
|
3942
|
+
onClose && /* @__PURE__ */ jsx("button", {
|
|
3943
|
+
onClick: onClose,
|
|
3944
|
+
className: "flex-shrink-0 rounded-md p-1 text-[var(--dashboard-text-secondary,#6b7280)] hover:bg-[var(--dashboard-text-secondary,#6b7280)]/10 transition-colors cursor-pointer",
|
|
3945
|
+
"aria-label": "Fechar alerta",
|
|
3946
|
+
children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
|
|
3947
|
+
})
|
|
3948
|
+
]
|
|
3949
|
+
})
|
|
3950
|
+
});
|
|
3951
|
+
}
|
|
3952
|
+
|
|
3953
|
+
//#endregion
|
|
3954
|
+
//#region src/components/EmptyState/index.tsx
|
|
3955
|
+
const cn$1 = (...classes) => classes.filter(Boolean).join(" ");
|
|
3956
|
+
function EmptyState({ icon, title, description, action, className }) {
|
|
3957
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
3958
|
+
className: cn$1("flex flex-col items-center justify-center py-12 px-6 text-center", className),
|
|
3959
|
+
children: [
|
|
3960
|
+
/* @__PURE__ */ jsx("div", {
|
|
3961
|
+
className: "flex h-16 w-16 items-center justify-center rounded-full bg-[var(--dashboard-text-secondary,#6b7280)]/10 mb-4",
|
|
3962
|
+
children: icon || /* @__PURE__ */ jsx(Inbox, { className: "h-8 w-8 text-[var(--dashboard-text-secondary,#6b7280)]" })
|
|
3963
|
+
}),
|
|
3964
|
+
/* @__PURE__ */ jsx("h3", {
|
|
3965
|
+
className: "text-lg font-semibold text-[var(--dashboard-text-primary,#2d2d2d)]",
|
|
3966
|
+
children: title
|
|
3967
|
+
}),
|
|
3968
|
+
description && /* @__PURE__ */ jsx("p", {
|
|
3969
|
+
className: "mt-2 max-w-sm text-sm text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
3970
|
+
children: description
|
|
3971
|
+
}),
|
|
3972
|
+
action && /* @__PURE__ */ jsx("div", {
|
|
3973
|
+
className: "mt-6",
|
|
3974
|
+
children: action
|
|
3975
|
+
})
|
|
3976
|
+
]
|
|
3977
|
+
});
|
|
3978
|
+
}
|
|
3979
|
+
|
|
3980
|
+
//#endregion
|
|
3981
|
+
//#region src/components/StatusBadge/index.tsx
|
|
3982
|
+
const cn = (...classes) => classes.filter(Boolean).join(" ");
|
|
3983
|
+
const defaultColorMap = {
|
|
3984
|
+
ACTIVE: "var(--dashboard-status-success,#10B981)",
|
|
3985
|
+
APPROVED: "var(--dashboard-status-success,#10B981)",
|
|
3986
|
+
COMPLETED: "var(--dashboard-status-success,#10B981)",
|
|
3987
|
+
DELIVERED: "var(--dashboard-status-success,#10B981)",
|
|
3988
|
+
SUCCESS: "var(--dashboard-status-success,#10B981)",
|
|
3989
|
+
PENDING: "var(--dashboard-status-warning,#f59e0b)",
|
|
3990
|
+
IN_REVIEW: "var(--dashboard-status-warning,#f59e0b)",
|
|
3991
|
+
AWAITING: "var(--dashboard-status-warning,#f59e0b)",
|
|
3992
|
+
DRAFT: "var(--dashboard-status-warning,#f59e0b)",
|
|
3993
|
+
PROCESSING: "var(--dashboard-status-info,#3b82f6)",
|
|
3994
|
+
IN_PROGRESS: "var(--dashboard-status-info,#3b82f6)",
|
|
3995
|
+
SENT: "var(--dashboard-status-info,#3b82f6)",
|
|
3996
|
+
QUOTED: "var(--dashboard-status-info,#3b82f6)",
|
|
3997
|
+
CANCELLED: "var(--dashboard-status-danger,#EF4444)",
|
|
3998
|
+
REJECTED: "var(--dashboard-status-danger,#EF4444)",
|
|
3999
|
+
EXPIRED: "var(--dashboard-status-danger,#EF4444)",
|
|
4000
|
+
ERROR: "var(--dashboard-status-danger,#EF4444)",
|
|
4001
|
+
INACTIVE: "var(--dashboard-text-secondary,#6b7280)",
|
|
4002
|
+
ARCHIVED: "var(--dashboard-text-secondary,#6b7280)"
|
|
4003
|
+
};
|
|
4004
|
+
const sizeClasses = {
|
|
4005
|
+
sm: "px-2 py-0.5 text-xs",
|
|
4006
|
+
md: "px-2.5 py-1 text-xs",
|
|
4007
|
+
lg: "px-3 py-1 text-sm"
|
|
4008
|
+
};
|
|
4009
|
+
const dotSizeClasses = {
|
|
4010
|
+
sm: "h-1.5 w-1.5",
|
|
4011
|
+
md: "h-2 w-2",
|
|
4012
|
+
lg: "h-2.5 w-2.5"
|
|
4013
|
+
};
|
|
4014
|
+
function formatLabel(status) {
|
|
4015
|
+
return status.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
4016
|
+
}
|
|
4017
|
+
function StatusBadge({ status, colorMap, size = "md", label, dot = true, className }) {
|
|
4018
|
+
const color = {
|
|
4019
|
+
...defaultColorMap,
|
|
4020
|
+
...colorMap
|
|
4021
|
+
}[status.toUpperCase().replace(/[\s-]/g, "_")] || "var(--dashboard-text-secondary,#6b7280)";
|
|
4022
|
+
const displayLabel = label || formatLabel(status);
|
|
4023
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
4024
|
+
className: cn("inline-flex items-center gap-1.5 rounded-full font-medium whitespace-nowrap", sizeClasses[size], className),
|
|
4025
|
+
style: {
|
|
4026
|
+
color,
|
|
4027
|
+
backgroundColor: `color-mix(in srgb, ${color} 12%, transparent)`
|
|
4028
|
+
},
|
|
4029
|
+
children: [dot && /* @__PURE__ */ jsx("span", {
|
|
4030
|
+
className: cn("rounded-full flex-shrink-0", dotSizeClasses[size]),
|
|
4031
|
+
style: { backgroundColor: color }
|
|
4032
|
+
}), displayLabel]
|
|
4033
|
+
});
|
|
4034
|
+
}
|
|
4035
|
+
|
|
2687
4036
|
//#endregion
|
|
2688
4037
|
//#region src/config/defaults.ts
|
|
2689
4038
|
const defaultConfig = {
|
|
2690
4039
|
name: "Dashboard",
|
|
2691
4040
|
colors: {
|
|
2692
|
-
primary: "#
|
|
2693
|
-
secondary: "#
|
|
2694
|
-
background: "#
|
|
4041
|
+
primary: "#2563EB",
|
|
4042
|
+
secondary: "#F1F5F9",
|
|
4043
|
+
background: "#F8FAFC",
|
|
2695
4044
|
surface: "#FFFFFF",
|
|
2696
|
-
textPrimary: "#
|
|
2697
|
-
textSecondary: "#
|
|
2698
|
-
sidebarBg: "#
|
|
2699
|
-
sidebarBorder: "#
|
|
2700
|
-
sidebarText: "#
|
|
2701
|
-
sidebarActiveText: "#
|
|
2702
|
-
statusSuccess: "#
|
|
2703
|
-
statusDanger: "#
|
|
2704
|
-
statusWarning: "#
|
|
2705
|
-
statusInfo: "#
|
|
2706
|
-
statusNeutral: "#
|
|
4045
|
+
textPrimary: "#0F172A",
|
|
4046
|
+
textSecondary: "#64748B",
|
|
4047
|
+
sidebarBg: "#0F172A",
|
|
4048
|
+
sidebarBorder: "#1E293B",
|
|
4049
|
+
sidebarText: "#CBD5E1",
|
|
4050
|
+
sidebarActiveText: "#FFFFFF",
|
|
4051
|
+
statusSuccess: "#059669",
|
|
4052
|
+
statusDanger: "#DC2626",
|
|
4053
|
+
statusWarning: "#D97706",
|
|
4054
|
+
statusInfo: "#2563EB",
|
|
4055
|
+
statusNeutral: "#64748B"
|
|
2707
4056
|
},
|
|
2708
4057
|
components: {
|
|
2709
4058
|
modal: {
|
|
@@ -2875,7 +4224,7 @@ function NotificationsProvider({ children }) {
|
|
|
2875
4224
|
clearNotifications
|
|
2876
4225
|
},
|
|
2877
4226
|
children: [children, notifications.length > 0 && /* @__PURE__ */ jsx("div", {
|
|
2878
|
-
className: "fixed w-full max-w-[400px] px-4 z-
|
|
4227
|
+
className: "fixed w-full max-w-[400px] px-4 z-[10002] top-4 left-1/2 -translate-x-1/2 sm:top-5 sm:right-4 sm:left-auto sm:translate-x-0 flex flex-col gap-2",
|
|
2879
4228
|
children: notifications.map((notification) => /* @__PURE__ */ jsx(Toast, {
|
|
2880
4229
|
title: notification.title,
|
|
2881
4230
|
subtitle: notification.subtitle,
|
|
@@ -2937,5 +4286,5 @@ function DashboardProvider({ config: configOverrides, children }) {
|
|
|
2937
4286
|
}
|
|
2938
4287
|
|
|
2939
4288
|
//#endregion
|
|
2940
|
-
export { AuthLayout, BadgeStatus, Button, Card, Checkbox, CodeInput, ComparisonLineChart, DashboardProvider, DateRangePicker, Dropdown, FilterBar, FormField, HorizontalBarChart, Input, KPICard, Loading, LoadingProvider, MetricPanel, Modal, NotificationsProvider, PageLayout, Pagination, ProgressBarList, Sidebar, Table, TableBody, TableEmpty, TableHeader, TableSkeleton, Tabs, ThemeProvider, ThemeSwitcher, Title, Toast, ToggleSwitch, VerticalBarChart, createConfig, defaultConfig, useConfig, useLoading, useNotifications, useTheme };
|
|
4289
|
+
export { Alert, AuthLayout, BadgeStatus, Breadcrumb, Button, Card, Checkbox, CodeInput, Combobox, ComparisonLineChart, DashboardProvider, DataGrid, DateRangePicker, Dropdown, EmptyState, FileUpload, FilterBar, FormField, HorizontalBarChart, Input, KPICard, Loading, LoadingProvider, MetricPanel, Modal, NotificationsProvider, PageLayout, Pagination, ProgressBarList, Sidebar, Skeleton, StatusBadge, Stepper, Table, TableBody, TableEmpty, TableHeader, TableSkeleton, Tabs, ThemeProvider, ThemeSwitcher, Title, Toast, ToggleSwitch, Tooltip, TreeView, VerticalBarChart, createColumnHelper, createConfig, defaultConfig, useConfig, useLoading, useNotifications, useTheme };
|
|
2941
4290
|
//# sourceMappingURL=index.mjs.map
|