@tree-ia/design-system 1.5.8 → 2.0.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 +233 -4
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1280 -190
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import React, { createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
1
|
+
import React, { cloneElement, createContext, isValidElement, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { createPortal } from "react-dom";
|
|
4
|
-
import { AlertCircle, AlertOctagon, AlertTriangle, ArrowDown, ArrowUp, ArrowUpDown, Check, CheckCircle, ChevronDown, ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight, File, GripVertical, Image, Inbox, Info, LogOut, Monitor, Moon, Search, Sun, Upload, User, X, XCircle } from "lucide-react";
|
|
4
|
+
import { AlertCircle, AlertOctagon, AlertTriangle, ArrowDown, ArrowUp, ArrowUpDown, Building2, Check, CheckCircle, ChevronDown, ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight, Copy, File, GripVertical, Image, Inbox, Info, Lightbulb, LogOut, Menu, Monitor, Moon, Search, ShieldAlert, Sun, Upload, User, X, XCircle } from "lucide-react";
|
|
5
5
|
import { Bar, Doughnut, Line } from "react-chartjs-2";
|
|
6
6
|
import { ArcElement, BarElement, CategoryScale, Chart, Filler, Legend, LineElement, LinearScale, PointElement, Title as Title$1, Tooltip as Tooltip$1 } from "chart.js";
|
|
7
7
|
import { createColumnHelper, flexRender, getCoreRowModel, getFilteredRowModel, getPaginationRowModel, getSortedRowModel, useReactTable } from "@tanstack/react-table";
|
|
@@ -35,7 +35,7 @@ function Loading({ size = "md", className = "", text, textColor, color, variant
|
|
|
35
35
|
|
|
36
36
|
//#endregion
|
|
37
37
|
//#region src/components/Button/index.tsx
|
|
38
|
-
const cn$
|
|
38
|
+
const cn$34 = (...classes) => classes.filter(Boolean).join(" ");
|
|
39
39
|
function Button({ children, variant = "primary", size = "md", isLoading = false, icon, iconPosition = "left", className, disabled, ...props }) {
|
|
40
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]";
|
|
41
41
|
const variantStyles = {
|
|
@@ -45,18 +45,18 @@ function Button({ children, variant = "primary", size = "md", isLoading = false,
|
|
|
45
45
|
ghost: "bg-transparent hover:bg-[var(--dashboard-text-secondary,#64748B)]/8 text-[var(--dashboard-text-primary,#0F172A)]"
|
|
46
46
|
};
|
|
47
47
|
const sizeStyles = {
|
|
48
|
-
sm: "px-2
|
|
49
|
-
md: "px-3
|
|
50
|
-
lg: "px-4
|
|
48
|
+
sm: "h-8 px-2 text-xs sm:px-3 sm:text-sm",
|
|
49
|
+
md: "h-9 px-3 text-sm sm:px-4 sm:text-base",
|
|
50
|
+
lg: "h-10 px-4 text-base sm:px-6 sm:text-lg"
|
|
51
51
|
};
|
|
52
52
|
const iconOnlySizeStyles = {
|
|
53
|
-
sm: "
|
|
54
|
-
md: "
|
|
55
|
-
lg: "
|
|
53
|
+
sm: "h-8 w-8",
|
|
54
|
+
md: "h-9 w-9",
|
|
55
|
+
lg: "h-10 w-10"
|
|
56
56
|
};
|
|
57
57
|
const isIconOnly = !!icon && (children === void 0 || children === null || typeof children === "string" && children.trim() === "");
|
|
58
58
|
return /* @__PURE__ */ jsx("button", {
|
|
59
|
-
className: cn$
|
|
59
|
+
className: cn$34(baseStyles, variantStyles[variant], isIconOnly ? iconOnlySizeStyles[size] : sizeStyles[size], className),
|
|
60
60
|
disabled: disabled || isLoading,
|
|
61
61
|
...props,
|
|
62
62
|
children: isLoading ? /* @__PURE__ */ jsxs("span", {
|
|
@@ -81,8 +81,13 @@ function Button({ children, variant = "primary", size = "md", isLoading = false,
|
|
|
81
81
|
|
|
82
82
|
//#endregion
|
|
83
83
|
//#region src/components/Input/index.tsx
|
|
84
|
-
const cn$
|
|
85
|
-
const
|
|
84
|
+
const cn$33 = (...classes) => classes.filter(Boolean).join(" ");
|
|
85
|
+
const sizeStyles = {
|
|
86
|
+
sm: "h-8 px-2.5 text-xs",
|
|
87
|
+
md: "h-9 px-3 text-sm",
|
|
88
|
+
lg: "h-10 px-4 text-base"
|
|
89
|
+
};
|
|
90
|
+
const Input = React.forwardRef(({ className, type = "text", label, error, children, id, size = "md", ...props }, ref) => {
|
|
86
91
|
const inputId = id || (label ? `input-${label.toLowerCase().replace(/\s+/g, "-")}` : void 0);
|
|
87
92
|
return /* @__PURE__ */ jsxs("div", {
|
|
88
93
|
className: "w-full",
|
|
@@ -97,7 +102,7 @@ const Input = React.forwardRef(({ className, type = "text", label, error, childr
|
|
|
97
102
|
children: [/* @__PURE__ */ jsx("input", {
|
|
98
103
|
type,
|
|
99
104
|
id: inputId,
|
|
100
|
-
className: cn$
|
|
105
|
+
className: cn$33("flex w-full rounded-md border border-[var(--dashboard-text-secondary,#6b7280)]/30 bg-[var(--dashboard-surface,#ffffff)] 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", sizeStyles[size], error ? "border-[var(--dashboard-status-danger,#EF4444)] focus:border-[var(--dashboard-status-danger,#EF4444)]" : void 0, children ? "pr-10" : void 0, className),
|
|
101
106
|
ref,
|
|
102
107
|
...props
|
|
103
108
|
}), children && /* @__PURE__ */ jsx("div", {
|
|
@@ -116,7 +121,7 @@ Input.displayName = "Input";
|
|
|
116
121
|
|
|
117
122
|
//#endregion
|
|
118
123
|
//#region src/components/Dropdown/index.tsx
|
|
119
|
-
function Dropdown({ options, value, onChange, label, placeholder = "Selecione uma opção", disabled = false, className = "", containerClassName = "", fullWidth = false, size = "
|
|
124
|
+
function Dropdown({ options, value, onChange, label, placeholder = "Selecione uma opção", disabled = false, className = "", containerClassName = "", fullWidth = false, size = "md", error, variant = "default", customDropdownHeight, icon, fitContent = false, isActive = false }) {
|
|
120
125
|
const [isOpen, setIsOpen] = useState(false);
|
|
121
126
|
const [isVisible, setIsVisible] = useState(false);
|
|
122
127
|
const [position, setPosition] = useState({
|
|
@@ -127,23 +132,23 @@ function Dropdown({ options, value, onChange, label, placeholder = "Selecione um
|
|
|
127
132
|
const dropdownRef = useRef(null);
|
|
128
133
|
const selectedOption = options.find((option) => option.value === value);
|
|
129
134
|
const selectedStyle = {
|
|
130
|
-
|
|
131
|
-
container: "h-8 px-2",
|
|
135
|
+
sm: {
|
|
136
|
+
container: "h-8 px-2.5",
|
|
132
137
|
text: "text-xs",
|
|
133
138
|
wrapper: "space-y-1",
|
|
134
139
|
label: "text-sm",
|
|
135
140
|
iconPadding: "pl-8"
|
|
136
141
|
},
|
|
137
|
-
|
|
138
|
-
container: "h-
|
|
142
|
+
md: {
|
|
143
|
+
container: "h-9 px-3",
|
|
139
144
|
text: "text-sm",
|
|
140
145
|
wrapper: "space-y-2",
|
|
141
146
|
label: "text-base",
|
|
142
147
|
iconPadding: "pl-10"
|
|
143
148
|
},
|
|
144
|
-
|
|
145
|
-
container: "h-
|
|
146
|
-
text: "text-
|
|
149
|
+
lg: {
|
|
150
|
+
container: "h-10 px-4",
|
|
151
|
+
text: "text-base",
|
|
147
152
|
wrapper: "space-y-3",
|
|
148
153
|
label: "text-lg",
|
|
149
154
|
iconPadding: "pl-12"
|
|
@@ -362,13 +367,14 @@ function TableEmpty({ message, icon }) {
|
|
|
362
367
|
//#region src/components/Modal/index.tsx
|
|
363
368
|
const ANIMATION_MS = 200;
|
|
364
369
|
const sizeClasses$2 = {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
+
sm: "max-w-sm",
|
|
371
|
+
md: "max-w-md",
|
|
372
|
+
lg: "max-w-lg",
|
|
373
|
+
xl: "max-w-2xl",
|
|
374
|
+
"2xl": "max-w-4xl",
|
|
375
|
+
"3xl": "max-w-screen-xl"
|
|
370
376
|
};
|
|
371
|
-
function Modal({ isOpen, onClose, onSave, title = "", children, showFooter = false, saveButtonText = "Salvar", cancelButtonText = "Cancelar", size = "
|
|
377
|
+
function Modal({ isOpen, onClose, onSave, title = "", children, showFooter = false, saveButtonText = "Salvar", cancelButtonText = "Cancelar", size = "md", disableSaveButton = false, saveButtonVariant = "primary", closeOnEscape = true, closeOnOverlayClick = true }) {
|
|
372
378
|
const [shouldRender, setShouldRender] = useState(false);
|
|
373
379
|
const modalRef = useRef(null);
|
|
374
380
|
if (isOpen && !shouldRender) setShouldRender(true);
|
|
@@ -619,7 +625,7 @@ function Pagination({ currentPage, totalPages, onPageChange, itemsPerPage, total
|
|
|
619
625
|
options: dropdownOptions,
|
|
620
626
|
value: String(itemsPerPage),
|
|
621
627
|
onChange: (val) => onItemsPerPageChange(Number(val)),
|
|
622
|
-
size: "
|
|
628
|
+
size: "sm",
|
|
623
629
|
variant: "compact",
|
|
624
630
|
fitContent: true
|
|
625
631
|
}), /* @__PURE__ */ jsx("span", {
|
|
@@ -751,16 +757,16 @@ function FormField({ label, name, type = "text", value, onChange, error, require
|
|
|
751
757
|
|
|
752
758
|
//#endregion
|
|
753
759
|
//#region src/components/Tabs/index.tsx
|
|
754
|
-
const cn$
|
|
760
|
+
const cn$32 = (...classes) => classes.filter(Boolean).join(" ");
|
|
755
761
|
function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
|
|
756
762
|
if (variant === "pill") return /* @__PURE__ */ jsx("div", {
|
|
757
|
-
className: cn$
|
|
763
|
+
className: cn$32("flex flex-wrap gap-2", className),
|
|
758
764
|
role: "tablist",
|
|
759
765
|
children: tabs.map((tab) => {
|
|
760
766
|
const isActive = activeTab === tab.id;
|
|
761
767
|
return /* @__PURE__ */ jsxs("button", {
|
|
762
768
|
onClick: () => onChange(tab.id),
|
|
763
|
-
className: cn$
|
|
769
|
+
className: cn$32("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"),
|
|
764
770
|
role: "tab",
|
|
765
771
|
"aria-selected": isActive,
|
|
766
772
|
children: [
|
|
@@ -770,7 +776,7 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
|
|
|
770
776
|
}),
|
|
771
777
|
tab.label,
|
|
772
778
|
tab.count !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
773
|
-
className: cn$
|
|
779
|
+
className: cn$32("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)]"),
|
|
774
780
|
children: tab.count
|
|
775
781
|
})
|
|
776
782
|
]
|
|
@@ -778,7 +784,7 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
|
|
|
778
784
|
})
|
|
779
785
|
});
|
|
780
786
|
return /* @__PURE__ */ jsx("div", {
|
|
781
|
-
className: cn$
|
|
787
|
+
className: cn$32("border-b border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
|
|
782
788
|
children: /* @__PURE__ */ jsx("nav", {
|
|
783
789
|
className: "flex gap-6",
|
|
784
790
|
"aria-label": "Tabs",
|
|
@@ -786,7 +792,7 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
|
|
|
786
792
|
const isActive = activeTab === tab.id;
|
|
787
793
|
return /* @__PURE__ */ jsxs("button", {
|
|
788
794
|
onClick: () => onChange(tab.id),
|
|
789
|
-
className: cn$
|
|
795
|
+
className: cn$32("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"),
|
|
790
796
|
role: "tab",
|
|
791
797
|
"aria-selected": isActive,
|
|
792
798
|
children: [
|
|
@@ -796,7 +802,7 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
|
|
|
796
802
|
}),
|
|
797
803
|
tab.label,
|
|
798
804
|
tab.count !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
799
|
-
className: cn$
|
|
805
|
+
className: cn$32("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)]"),
|
|
800
806
|
children: tab.count
|
|
801
807
|
})
|
|
802
808
|
]
|
|
@@ -808,8 +814,8 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
|
|
|
808
814
|
|
|
809
815
|
//#endregion
|
|
810
816
|
//#region src/components/DateRangePicker/index.tsx
|
|
811
|
-
const cn$
|
|
812
|
-
const locales = {
|
|
817
|
+
const cn$31 = (...classes) => classes.filter(Boolean).join(" ");
|
|
818
|
+
const locales$1 = {
|
|
813
819
|
pt: {
|
|
814
820
|
months: [
|
|
815
821
|
"Janeiro",
|
|
@@ -867,7 +873,7 @@ const locales = {
|
|
|
867
873
|
};
|
|
868
874
|
function DateRangePicker({ value, onChange, locale = "pt", className }) {
|
|
869
875
|
const [currentMonth, setCurrentMonth] = useState(/* @__PURE__ */ new Date());
|
|
870
|
-
const l = locales[locale];
|
|
876
|
+
const l = locales$1[locale];
|
|
871
877
|
const getDaysInMonth = (date) => {
|
|
872
878
|
const year = date.getFullYear();
|
|
873
879
|
const month = date.getMonth();
|
|
@@ -915,7 +921,7 @@ function DateRangePicker({ value, onChange, locale = "pt", className }) {
|
|
|
915
921
|
};
|
|
916
922
|
const days = getDaysInMonth(currentMonth);
|
|
917
923
|
return /* @__PURE__ */ jsxs("div", {
|
|
918
|
-
className: cn$
|
|
924
|
+
className: cn$31("w-64 bg-[var(--dashboard-surface,#ffffff)] rounded-lg p-4 shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
|
|
919
925
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
920
926
|
className: "flex items-center justify-between mb-4",
|
|
921
927
|
children: [
|
|
@@ -953,9 +959,9 @@ function DateRangePicker({ value, onChange, locale = "pt", className }) {
|
|
|
953
959
|
const isSelected = isStart || isEnd;
|
|
954
960
|
return /* @__PURE__ */ jsxs("div", {
|
|
955
961
|
className: "relative h-8 w-8",
|
|
956
|
-
children: [value.start && value.end && (inRange || isStart || isEnd) && /* @__PURE__ */ jsx("div", { className: cn$
|
|
962
|
+
children: [value.start && value.end && (inRange || isStart || isEnd) && /* @__PURE__ */ jsx("div", { className: cn$31("absolute inset-0 bg-[var(--dashboard-text-secondary,#6b7280)]/10", isStart && "rounded-l-full", isEnd && "rounded-r-full") }), /* @__PURE__ */ jsx("button", {
|
|
957
963
|
onClick: () => handleDayClick(day),
|
|
958
|
-
className: cn$
|
|
964
|
+
className: cn$31("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"),
|
|
959
965
|
children: day
|
|
960
966
|
})]
|
|
961
967
|
}, day);
|
|
@@ -964,9 +970,157 @@ function DateRangePicker({ value, onChange, locale = "pt", className }) {
|
|
|
964
970
|
});
|
|
965
971
|
}
|
|
966
972
|
|
|
973
|
+
//#endregion
|
|
974
|
+
//#region src/components/DatePicker/index.tsx
|
|
975
|
+
const cn$30 = (...classes) => classes.filter(Boolean).join(" ");
|
|
976
|
+
const locales = {
|
|
977
|
+
pt: {
|
|
978
|
+
months: [
|
|
979
|
+
"Janeiro",
|
|
980
|
+
"Fevereiro",
|
|
981
|
+
"Março",
|
|
982
|
+
"Abril",
|
|
983
|
+
"Maio",
|
|
984
|
+
"Junho",
|
|
985
|
+
"Julho",
|
|
986
|
+
"Agosto",
|
|
987
|
+
"Setembro",
|
|
988
|
+
"Outubro",
|
|
989
|
+
"Novembro",
|
|
990
|
+
"Dezembro"
|
|
991
|
+
],
|
|
992
|
+
weekDays: [
|
|
993
|
+
"D",
|
|
994
|
+
"S",
|
|
995
|
+
"T",
|
|
996
|
+
"Q",
|
|
997
|
+
"Q",
|
|
998
|
+
"S",
|
|
999
|
+
"S"
|
|
1000
|
+
],
|
|
1001
|
+
prevMonth: "Mês anterior",
|
|
1002
|
+
nextMonth: "Próximo mês"
|
|
1003
|
+
},
|
|
1004
|
+
en: {
|
|
1005
|
+
months: [
|
|
1006
|
+
"January",
|
|
1007
|
+
"February",
|
|
1008
|
+
"March",
|
|
1009
|
+
"April",
|
|
1010
|
+
"May",
|
|
1011
|
+
"June",
|
|
1012
|
+
"July",
|
|
1013
|
+
"August",
|
|
1014
|
+
"September",
|
|
1015
|
+
"October",
|
|
1016
|
+
"November",
|
|
1017
|
+
"December"
|
|
1018
|
+
],
|
|
1019
|
+
weekDays: [
|
|
1020
|
+
"S",
|
|
1021
|
+
"M",
|
|
1022
|
+
"T",
|
|
1023
|
+
"W",
|
|
1024
|
+
"T",
|
|
1025
|
+
"F",
|
|
1026
|
+
"S"
|
|
1027
|
+
],
|
|
1028
|
+
prevMonth: "Previous month",
|
|
1029
|
+
nextMonth: "Next month"
|
|
1030
|
+
}
|
|
1031
|
+
};
|
|
1032
|
+
const startOfDay = (date) => new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
1033
|
+
function DatePicker({ value, onChange, locale = "pt", minDate, maxDate, className }) {
|
|
1034
|
+
const [currentMonth, setCurrentMonth] = useState(value ?? /* @__PURE__ */ new Date());
|
|
1035
|
+
const l = locales[locale];
|
|
1036
|
+
const getDaysInMonth = (date) => {
|
|
1037
|
+
const year = date.getFullYear();
|
|
1038
|
+
const month = date.getMonth();
|
|
1039
|
+
const firstDay = new Date(year, month, 1);
|
|
1040
|
+
const daysInMonth = new Date(year, month + 1, 0).getDate();
|
|
1041
|
+
const startDayOfWeek = firstDay.getDay();
|
|
1042
|
+
const days = [];
|
|
1043
|
+
for (let i = 0; i < startDayOfWeek; i++) days.push(null);
|
|
1044
|
+
for (let i = 1; i <= daysInMonth; i++) days.push(i);
|
|
1045
|
+
return days;
|
|
1046
|
+
};
|
|
1047
|
+
const buildDate = (day) => new Date(currentMonth.getFullYear(), currentMonth.getMonth(), day);
|
|
1048
|
+
const isDisabled = (day) => {
|
|
1049
|
+
const date = buildDate(day);
|
|
1050
|
+
if (minDate && date < startOfDay(minDate)) return true;
|
|
1051
|
+
if (maxDate && date > startOfDay(maxDate)) return true;
|
|
1052
|
+
return false;
|
|
1053
|
+
};
|
|
1054
|
+
const isSelected = (day) => {
|
|
1055
|
+
if (!value) return false;
|
|
1056
|
+
return buildDate(day).getTime() === startOfDay(value).getTime();
|
|
1057
|
+
};
|
|
1058
|
+
const handleDayClick = (day) => {
|
|
1059
|
+
if (isDisabled(day)) return;
|
|
1060
|
+
onChange(buildDate(day));
|
|
1061
|
+
};
|
|
1062
|
+
const previousMonth = () => {
|
|
1063
|
+
setCurrentMonth(new Date(currentMonth.getFullYear(), currentMonth.getMonth() - 1));
|
|
1064
|
+
};
|
|
1065
|
+
const nextMonth = () => {
|
|
1066
|
+
setCurrentMonth(new Date(currentMonth.getFullYear(), currentMonth.getMonth() + 1));
|
|
1067
|
+
};
|
|
1068
|
+
const days = getDaysInMonth(currentMonth);
|
|
1069
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1070
|
+
className: cn$30("w-64 bg-[var(--dashboard-surface,#ffffff)] rounded-lg p-4 shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
|
|
1071
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
1072
|
+
className: "flex items-center justify-between mb-4",
|
|
1073
|
+
children: [
|
|
1074
|
+
/* @__PURE__ */ jsx("button", {
|
|
1075
|
+
type: "button",
|
|
1076
|
+
onClick: previousMonth,
|
|
1077
|
+
className: "p-1 hover:bg-[var(--dashboard-text-secondary,#6b7280)]/10 rounded transition-colors cursor-pointer",
|
|
1078
|
+
"aria-label": l.prevMonth,
|
|
1079
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { className: "w-4 h-4 text-[var(--dashboard-text-primary,#2d2d2d)]" })
|
|
1080
|
+
}),
|
|
1081
|
+
/* @__PURE__ */ jsxs("h2", {
|
|
1082
|
+
className: "text-base font-semibold text-[var(--dashboard-text-primary,#2d2d2d)]",
|
|
1083
|
+
children: [
|
|
1084
|
+
l.months[currentMonth.getMonth()],
|
|
1085
|
+
" ",
|
|
1086
|
+
currentMonth.getFullYear()
|
|
1087
|
+
]
|
|
1088
|
+
}),
|
|
1089
|
+
/* @__PURE__ */ jsx("button", {
|
|
1090
|
+
type: "button",
|
|
1091
|
+
onClick: nextMonth,
|
|
1092
|
+
className: "p-1 hover:bg-[var(--dashboard-text-secondary,#6b7280)]/10 rounded transition-colors cursor-pointer",
|
|
1093
|
+
"aria-label": l.nextMonth,
|
|
1094
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { className: "w-4 h-4 text-[var(--dashboard-text-primary,#2d2d2d)]" })
|
|
1095
|
+
})
|
|
1096
|
+
]
|
|
1097
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
1098
|
+
className: "grid grid-cols-7",
|
|
1099
|
+
children: [l.weekDays.map((day, index) => /* @__PURE__ */ jsx("div", {
|
|
1100
|
+
className: "h-8 w-8 flex items-center justify-center text-xs font-medium text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
1101
|
+
children: day
|
|
1102
|
+
}, index)), days.map((day, index) => {
|
|
1103
|
+
if (day === null) return /* @__PURE__ */ jsx("div", { className: "h-8 w-8" }, `empty-${index}`);
|
|
1104
|
+
const selected = isSelected(day);
|
|
1105
|
+
const disabled = isDisabled(day);
|
|
1106
|
+
return /* @__PURE__ */ jsx("div", {
|
|
1107
|
+
className: "relative h-8 w-8",
|
|
1108
|
+
children: /* @__PURE__ */ jsx("button", {
|
|
1109
|
+
type: "button",
|
|
1110
|
+
onClick: () => handleDayClick(day),
|
|
1111
|
+
disabled,
|
|
1112
|
+
className: cn$30("relative h-8 w-8 flex items-center justify-center text-xs font-medium transition-colors z-10 rounded-full", disabled ? "text-[var(--dashboard-text-secondary,#6b7280)]/40 cursor-not-allowed" : "cursor-pointer", !disabled && selected ? "bg-[var(--dashboard-primary,#37a501)] text-white hover:opacity-90" : !disabled && "text-[var(--dashboard-text-primary,#2d2d2d)] hover:bg-[var(--dashboard-text-secondary,#6b7280)]/20"),
|
|
1113
|
+
children: day
|
|
1114
|
+
})
|
|
1115
|
+
}, day);
|
|
1116
|
+
})]
|
|
1117
|
+
})]
|
|
1118
|
+
});
|
|
1119
|
+
}
|
|
1120
|
+
|
|
967
1121
|
//#endregion
|
|
968
1122
|
//#region src/components/Title/index.tsx
|
|
969
|
-
const cn$
|
|
1123
|
+
const cn$29 = (...classes) => classes.filter(Boolean).join(" ");
|
|
970
1124
|
const defaultSizeByLevel = {
|
|
971
1125
|
1: "text-2xl sm:text-3xl md:text-4xl lg:text-5xl",
|
|
972
1126
|
2: "text-xl sm:text-2xl md:text-3xl lg:text-4xl",
|
|
@@ -1001,7 +1155,7 @@ function Title({ children, level = 1, size, weight = "bold", align = "left", col
|
|
|
1001
1155
|
const sizeClass = size ? customSizes[size] : defaultSizeByLevel[level];
|
|
1002
1156
|
const colorClass = color || "text-[var(--dashboard-text-primary,#2d2d2d)]";
|
|
1003
1157
|
return /* @__PURE__ */ jsx(Tag, {
|
|
1004
|
-
className: cn$
|
|
1158
|
+
className: cn$29(sizeClass, weightStyles[weight], alignStyles[align], colorClass, className),
|
|
1005
1159
|
...props,
|
|
1006
1160
|
children
|
|
1007
1161
|
});
|
|
@@ -1009,7 +1163,7 @@ function Title({ children, level = 1, size, weight = "bold", align = "left", col
|
|
|
1009
1163
|
|
|
1010
1164
|
//#endregion
|
|
1011
1165
|
//#region src/components/ToggleSwitch/index.tsx
|
|
1012
|
-
const cn$
|
|
1166
|
+
const cn$28 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1013
1167
|
const sizeConfig$1 = {
|
|
1014
1168
|
sm: {
|
|
1015
1169
|
track: "h-5 w-9",
|
|
@@ -1033,7 +1187,7 @@ const sizeConfig$1 = {
|
|
|
1033
1187
|
function ToggleSwitch({ enabled, onChange, disabled = false, size = "md", label, className }) {
|
|
1034
1188
|
const config = sizeConfig$1[size];
|
|
1035
1189
|
return /* @__PURE__ */ jsxs("div", {
|
|
1036
|
-
className: cn$
|
|
1190
|
+
className: cn$28("inline-flex items-center gap-2", className),
|
|
1037
1191
|
children: [/* @__PURE__ */ jsx("button", {
|
|
1038
1192
|
type: "button",
|
|
1039
1193
|
role: "switch",
|
|
@@ -1041,10 +1195,10 @@ function ToggleSwitch({ enabled, onChange, disabled = false, size = "md", label,
|
|
|
1041
1195
|
"aria-label": label,
|
|
1042
1196
|
disabled,
|
|
1043
1197
|
onClick: () => onChange(!enabled),
|
|
1044
|
-
className: cn$
|
|
1045
|
-
children: /* @__PURE__ */ jsx("span", { className: cn$
|
|
1198
|
+
className: cn$28("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"),
|
|
1199
|
+
children: /* @__PURE__ */ jsx("span", { className: cn$28("inline-block transform rounded-full bg-white shadow-sm transition-transform", config.thumb, enabled ? config.translateOn : config.translateOff) })
|
|
1046
1200
|
}), label && /* @__PURE__ */ jsx("span", {
|
|
1047
|
-
className: cn$
|
|
1201
|
+
className: cn$28("text-sm text-[var(--dashboard-text-primary,#2d2d2d)]", disabled && "opacity-50"),
|
|
1048
1202
|
children: label
|
|
1049
1203
|
})]
|
|
1050
1204
|
});
|
|
@@ -1052,7 +1206,7 @@ function ToggleSwitch({ enabled, onChange, disabled = false, size = "md", label,
|
|
|
1052
1206
|
|
|
1053
1207
|
//#endregion
|
|
1054
1208
|
//#region src/components/BadgeStatus/index.tsx
|
|
1055
|
-
const cn$
|
|
1209
|
+
const cn$27 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1056
1210
|
const variantStyles = {
|
|
1057
1211
|
success: {
|
|
1058
1212
|
color: "text-[var(--dashboard-status-success,#10B981)]",
|
|
@@ -1083,7 +1237,7 @@ function BadgeStatus({ label, variant = "neutral", color, bgColor, size = "md",
|
|
|
1083
1237
|
const styles = variantStyles[variant];
|
|
1084
1238
|
const useCustomColors = color || bgColor;
|
|
1085
1239
|
return /* @__PURE__ */ jsx("span", {
|
|
1086
|
-
className: cn$
|
|
1240
|
+
className: cn$27("inline-flex w-fit items-center justify-center rounded-full font-medium whitespace-nowrap", sizeClasses$1[size], !useCustomColors && styles.color, !useCustomColors && styles.bgColor, className),
|
|
1087
1241
|
style: useCustomColors ? {
|
|
1088
1242
|
color: color || void 0,
|
|
1089
1243
|
backgroundColor: bgColor || void 0
|
|
@@ -1094,15 +1248,15 @@ function BadgeStatus({ label, variant = "neutral", color, bgColor, size = "md",
|
|
|
1094
1248
|
|
|
1095
1249
|
//#endregion
|
|
1096
1250
|
//#region src/components/Sidebar/index.tsx
|
|
1097
|
-
const cn$
|
|
1098
|
-
function DefaultLink({ href, className, children }) {
|
|
1251
|
+
const cn$26 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1252
|
+
function DefaultLink$1({ href, className, children }) {
|
|
1099
1253
|
return /* @__PURE__ */ jsx("a", {
|
|
1100
1254
|
href,
|
|
1101
1255
|
className,
|
|
1102
1256
|
children
|
|
1103
1257
|
});
|
|
1104
1258
|
}
|
|
1105
|
-
function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: LinkComponent = DefaultLink, isCollapsed = false, onToggleCollapse, user, onUserClick, onLogout, logoutLabel = "Sair", footerItems, footerSlot, defaultExpandedIds, persistExpandedKey, className }) {
|
|
1259
|
+
function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: LinkComponent = DefaultLink$1, isCollapsed = false, onToggleCollapse, user, onUserClick, onLogout, logoutLabel = "Sair", footerItems, footerSlot, defaultExpandedIds, persistExpandedKey, showMobileHeader = true, className }) {
|
|
1106
1260
|
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
|
1107
1261
|
const [expandedIds, setExpandedIds] = useState(() => new Set(defaultExpandedIds ?? []));
|
|
1108
1262
|
const cubicBezier = "cubic-bezier(0.4, 0, 0.2, 1)";
|
|
@@ -1170,7 +1324,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1170
1324
|
const isChildActive = item.children?.some((c) => currentPath === c.href);
|
|
1171
1325
|
if (hasChildren) return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("button", {
|
|
1172
1326
|
onClick: () => toggleExpand(item.id),
|
|
1173
|
-
className: cn$
|
|
1327
|
+
className: cn$26("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,#ff521d)]" : "text-[var(--dashboard-sidebar-text,#403f52)] hover:bg-[var(--dashboard-primary,#ff521d)]/10"),
|
|
1174
1328
|
style: { transition: "background-color 200ms, color 200ms" },
|
|
1175
1329
|
title: collapsed && !mobile ? item.label : void 0,
|
|
1176
1330
|
children: [/* @__PURE__ */ jsx(Icon, {
|
|
@@ -1185,7 +1339,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1185
1339
|
children: item.label
|
|
1186
1340
|
}), /* @__PURE__ */ jsx(ChevronRight, {
|
|
1187
1341
|
size: 14,
|
|
1188
|
-
className: cn$
|
|
1342
|
+
className: cn$26("ml-auto flex-shrink-0 transition-transform duration-200", isExpanded ? "rotate-90" : "")
|
|
1189
1343
|
})] })]
|
|
1190
1344
|
}), (!collapsed || mobile) && /* @__PURE__ */ jsx("div", {
|
|
1191
1345
|
className: "overflow-hidden transition-all duration-200 ml-7 border-l-2 border-[var(--dashboard-sidebar-border,#e0dfe3)]",
|
|
@@ -1197,7 +1351,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1197
1351
|
href: child.href,
|
|
1198
1352
|
className: "block",
|
|
1199
1353
|
children: /* @__PURE__ */ jsxs("div", {
|
|
1200
|
-
className: cn$
|
|
1354
|
+
className: cn$26("w-full flex items-center pl-4 pr-4 py-2 rounded-r-lg text-[13px] cursor-pointer", childActive ? "text-[var(--dashboard-sidebar-active-text,#ff521d)] font-semibold border-l-2 border-[var(--dashboard-primary,#ff521d)] -ml-[2px]" : "text-[var(--dashboard-sidebar-text,#403f52)] hover:text-[var(--dashboard-sidebar-active-text,#ff521d)]"),
|
|
1201
1355
|
style: { transition: "background-color 200ms, color 200ms" },
|
|
1202
1356
|
children: [/* @__PURE__ */ jsx(ChildIcon, {
|
|
1203
1357
|
size: 15,
|
|
@@ -1214,7 +1368,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1214
1368
|
href: item.href,
|
|
1215
1369
|
className: "block",
|
|
1216
1370
|
children: /* @__PURE__ */ jsxs("div", {
|
|
1217
|
-
className: cn$
|
|
1371
|
+
className: cn$26("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,#ff521d)]/25 text-[var(--dashboard-sidebar-active-text,#ff521d)]" : "text-[var(--dashboard-sidebar-text,#403f52)] hover:bg-[var(--dashboard-primary,#ff521d)]/10"),
|
|
1218
1372
|
style: { transition: "background-color 200ms, color 200ms" },
|
|
1219
1373
|
title: collapsed && !mobile ? item.label : void 0,
|
|
1220
1374
|
children: [/* @__PURE__ */ jsx(Icon, {
|
|
@@ -1242,7 +1396,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1242
1396
|
children: [group.section && renderSectionHeader(group.section, collapsed), group.items.map((item) => renderMenuItem(item, collapsed, mobile))]
|
|
1243
1397
|
}, group.section || `group-${i}`));
|
|
1244
1398
|
}
|
|
1245
|
-
|
|
1399
|
+
const mobileHeader = /* @__PURE__ */ jsxs("header", {
|
|
1246
1400
|
className: "xl:hidden fixed top-0 left-0 right-0 z-40 bg-[var(--dashboard-sidebar-bg,#f0f0f0)] border-b border-[var(--dashboard-sidebar-border,#e0dfe3)]",
|
|
1247
1401
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
1248
1402
|
className: "flex items-center justify-center px-4 h-16 relative",
|
|
@@ -1307,8 +1461,9 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1307
1461
|
})]
|
|
1308
1462
|
})
|
|
1309
1463
|
})]
|
|
1310
|
-
})
|
|
1311
|
-
|
|
1464
|
+
});
|
|
1465
|
+
const desktopSidebar = /* @__PURE__ */ jsxs("aside", {
|
|
1466
|
+
className: cn$26("hidden xl:flex xl:flex-col xl:fixed xl:left-0 xl:top-0 xl:h-screen bg-[var(--dashboard-sidebar-bg,#f0f0f0)] border-r border-[var(--dashboard-sidebar-border,#e0dfe3)] overflow-visible", isCollapsed ? "xl:w-[109px]" : "xl:w-[280px]", className),
|
|
1312
1467
|
style: { transition: `width 400ms ${cubicBezier}` },
|
|
1313
1468
|
children: [onToggleCollapse && /* @__PURE__ */ jsxs("button", {
|
|
1314
1469
|
onClick: onToggleCollapse,
|
|
@@ -1382,7 +1537,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1382
1537
|
children: [
|
|
1383
1538
|
user && /* @__PURE__ */ jsxs("button", {
|
|
1384
1539
|
onClick: onUserClick,
|
|
1385
|
-
className: cn$
|
|
1540
|
+
className: cn$26("w-full flex items-center px-4 py-3 rounded-lg bg-[var(--dashboard-primary,#ff521d)]/5 hover:bg-[var(--dashboard-primary,#ff521d)]/10 transition-colors cursor-pointer", isCollapsed ? "justify-center" : "justify-start"),
|
|
1386
1541
|
title: isCollapsed ? `${user.subtitle ? user.subtitle + " - " : ""}${user.name}` : void 0,
|
|
1387
1542
|
children: [/* @__PURE__ */ jsx("div", {
|
|
1388
1543
|
className: "flex items-center justify-center w-8 h-8 rounded-full bg-[var(--dashboard-primary,#ff521d)]/30 text-[var(--dashboard-sidebar-text,#403f52)] flex-shrink-0",
|
|
@@ -1415,7 +1570,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1415
1570
|
footerItems?.map((item) => renderMenuItem(item, isCollapsed, false)),
|
|
1416
1571
|
onLogout && /* @__PURE__ */ jsxs("button", {
|
|
1417
1572
|
onClick: onLogout,
|
|
1418
|
-
className: cn$
|
|
1573
|
+
className: cn$26("w-full flex items-center px-4 py-3 rounded-lg text-sm font-medium cursor-pointer text-[var(--dashboard-sidebar-text,#403f52)] hover:bg-[var(--dashboard-primary,#ff521d)]/10", isCollapsed ? "justify-center" : "justify-start"),
|
|
1419
1574
|
style: { transition: "background-color 200ms" },
|
|
1420
1575
|
title: isCollapsed ? logoutLabel : void 0,
|
|
1421
1576
|
children: [/* @__PURE__ */ jsx(LogOut, {
|
|
@@ -1438,12 +1593,445 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1438
1593
|
})
|
|
1439
1594
|
]
|
|
1440
1595
|
})]
|
|
1441
|
-
})
|
|
1596
|
+
});
|
|
1597
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [showMobileHeader && mobileHeader, desktopSidebar] });
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
//#endregion
|
|
1601
|
+
//#region src/components/Header/index.tsx
|
|
1602
|
+
const cn$25 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1603
|
+
function isGroup(item) {
|
|
1604
|
+
return "children" in item && Array.isArray(item.children);
|
|
1605
|
+
}
|
|
1606
|
+
function DefaultLink({ href, className, onClick, children }) {
|
|
1607
|
+
return /* @__PURE__ */ jsx("a", {
|
|
1608
|
+
href,
|
|
1609
|
+
className,
|
|
1610
|
+
onClick,
|
|
1611
|
+
children
|
|
1612
|
+
});
|
|
1613
|
+
}
|
|
1614
|
+
function useOnClickOutside(ref, handler) {
|
|
1615
|
+
useEffect(() => {
|
|
1616
|
+
const listener = (event) => {
|
|
1617
|
+
if (!ref.current || ref.current.contains(event.target)) return;
|
|
1618
|
+
handler();
|
|
1619
|
+
};
|
|
1620
|
+
document.addEventListener("mousedown", listener);
|
|
1621
|
+
document.addEventListener("touchstart", listener);
|
|
1622
|
+
return () => {
|
|
1623
|
+
document.removeEventListener("mousedown", listener);
|
|
1624
|
+
document.removeEventListener("touchstart", listener);
|
|
1625
|
+
};
|
|
1626
|
+
}, [ref, handler]);
|
|
1627
|
+
}
|
|
1628
|
+
function Header({ menuItems, logo, currentPath, linkComponent: LinkComponent = DefaultLink, user, establishments = [], establishmentsLabel = "Estabelecimento", onEstablishmentChange, actions, onUserClick, onLogout, logoutLabel = "Sair", menuLabel = "Menu", desktopOffsetLeft = 0, className }) {
|
|
1629
|
+
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
|
1630
|
+
const [isUserMenuOpen, setIsUserMenuOpen] = useState(false);
|
|
1631
|
+
const [openDropdownId, setOpenDropdownId] = useState(null);
|
|
1632
|
+
const dropdownRef = useRef(null);
|
|
1633
|
+
const userMenuRef = useRef(null);
|
|
1634
|
+
useOnClickOutside(dropdownRef, () => setOpenDropdownId(null));
|
|
1635
|
+
useOnClickOutside(userMenuRef, () => setIsUserMenuOpen(false));
|
|
1636
|
+
const closeMenus = () => {
|
|
1637
|
+
setIsMobileMenuOpen(false);
|
|
1638
|
+
setIsUserMenuOpen(false);
|
|
1639
|
+
setOpenDropdownId(null);
|
|
1640
|
+
};
|
|
1641
|
+
const isItemActive = (item) => {
|
|
1642
|
+
if (isGroup(item)) return item.children.some((child) => currentPath === child.href || child.href !== "/dashboard" && currentPath.startsWith(child.href));
|
|
1643
|
+
return currentPath === item.href;
|
|
1644
|
+
};
|
|
1645
|
+
const renderNavLink = (item, options = {}) => {
|
|
1646
|
+
const Icon = item.icon;
|
|
1647
|
+
const active = currentPath === item.href;
|
|
1648
|
+
if (item.disabled) return /* @__PURE__ */ jsxs("span", {
|
|
1649
|
+
className: cn$25("flex items-center gap-2 rounded-lg text-sm font-medium cursor-not-allowed", options.mobile ? "px-4 py-3" : "h-10 px-3", "text-[var(--dashboard-text-secondary,#6b7280)]/40"),
|
|
1650
|
+
title: "Em breve",
|
|
1651
|
+
children: [/* @__PURE__ */ jsx(Icon, {
|
|
1652
|
+
size: 18,
|
|
1653
|
+
className: "flex-shrink-0 opacity-40"
|
|
1654
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
1655
|
+
className: "line-through opacity-50",
|
|
1656
|
+
children: item.label
|
|
1657
|
+
})]
|
|
1658
|
+
}, item.id);
|
|
1659
|
+
return /* @__PURE__ */ jsx(LinkComponent, {
|
|
1660
|
+
href: item.href,
|
|
1661
|
+
className: "block",
|
|
1662
|
+
onClick: closeMenus,
|
|
1663
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
1664
|
+
className: cn$25("flex items-center gap-2 rounded-lg text-sm font-medium transition-colors", options.mobile ? "px-4 py-3" : "h-10 px-3", active ? "bg-[var(--dashboard-primary,#37a501)]/12 text-[var(--dashboard-primary,#37a501)]" : "text-[var(--dashboard-text-secondary,#6b7280)] hover:bg-[var(--dashboard-primary,#37a501)]/8 hover:text-[var(--dashboard-text-primary,#2d2d2d)]"),
|
|
1665
|
+
"aria-current": active ? "page" : void 0,
|
|
1666
|
+
children: [/* @__PURE__ */ jsx(Icon, {
|
|
1667
|
+
size: 18,
|
|
1668
|
+
className: "flex-shrink-0"
|
|
1669
|
+
}), /* @__PURE__ */ jsx("span", { children: item.label })]
|
|
1670
|
+
})
|
|
1671
|
+
}, item.id);
|
|
1672
|
+
};
|
|
1673
|
+
const renderDropdown = (group, options = {}) => {
|
|
1674
|
+
const Icon = group.icon;
|
|
1675
|
+
const groupActive = isItemActive(group);
|
|
1676
|
+
const isOpen = openDropdownId === group.id;
|
|
1677
|
+
if (options.mobile) return /* @__PURE__ */ jsxs("div", {
|
|
1678
|
+
className: "space-y-1",
|
|
1679
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
1680
|
+
className: "flex items-center gap-2 px-4 py-2 text-xs font-semibold uppercase tracking-wider text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
1681
|
+
children: [/* @__PURE__ */ jsx(Icon, { size: 16 }), group.label]
|
|
1682
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
1683
|
+
className: "ml-3 space-y-1 border-l border-[var(--dashboard-text-secondary,#6b7280)]/20 pl-3",
|
|
1684
|
+
children: group.children.map((child) => {
|
|
1685
|
+
const active = currentPath === child.href;
|
|
1686
|
+
return child.disabled ? /* @__PURE__ */ jsxs("span", {
|
|
1687
|
+
className: "flex items-center gap-2 rounded-lg px-4 py-2.5 text-sm font-medium cursor-not-allowed text-[var(--dashboard-text-secondary,#6b7280)]/40",
|
|
1688
|
+
title: "Em breve",
|
|
1689
|
+
children: [/* @__PURE__ */ jsx(child.icon, {
|
|
1690
|
+
size: 16,
|
|
1691
|
+
className: "flex-shrink-0 opacity-40"
|
|
1692
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
1693
|
+
className: "line-through opacity-50",
|
|
1694
|
+
children: child.label
|
|
1695
|
+
})]
|
|
1696
|
+
}, child.id) : /* @__PURE__ */ jsx(LinkComponent, {
|
|
1697
|
+
href: child.href,
|
|
1698
|
+
className: "block",
|
|
1699
|
+
onClick: closeMenus,
|
|
1700
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
1701
|
+
className: cn$25("flex items-center gap-2 rounded-lg px-4 py-2.5 text-sm font-medium transition-colors", active ? "bg-[var(--dashboard-primary,#37a501)]/12 text-[var(--dashboard-primary,#37a501)]" : "text-[var(--dashboard-text-secondary,#6b7280)] hover:bg-[var(--dashboard-primary,#37a501)]/8 hover:text-[var(--dashboard-text-primary,#2d2d2d)]"),
|
|
1702
|
+
children: [/* @__PURE__ */ jsx(child.icon, {
|
|
1703
|
+
size: 16,
|
|
1704
|
+
className: "flex-shrink-0"
|
|
1705
|
+
}), /* @__PURE__ */ jsx("span", { children: child.label })]
|
|
1706
|
+
})
|
|
1707
|
+
}, child.id);
|
|
1708
|
+
})
|
|
1709
|
+
})]
|
|
1710
|
+
}, group.id);
|
|
1711
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
1712
|
+
className: "relative",
|
|
1713
|
+
ref: isOpen ? dropdownRef : void 0,
|
|
1714
|
+
children: [/* @__PURE__ */ jsxs("button", {
|
|
1715
|
+
type: "button",
|
|
1716
|
+
onClick: () => setOpenDropdownId((prev) => prev === group.id ? null : group.id),
|
|
1717
|
+
className: cn$25("flex items-center gap-1.5 rounded-lg h-10 px-3 text-sm font-medium transition-colors", groupActive ? "bg-[var(--dashboard-primary,#37a501)]/12 text-[var(--dashboard-primary,#37a501)]" : "text-[var(--dashboard-text-secondary,#6b7280)] hover:bg-[var(--dashboard-primary,#37a501)]/8 hover:text-[var(--dashboard-text-primary,#2d2d2d)]"),
|
|
1718
|
+
"aria-expanded": isOpen,
|
|
1719
|
+
children: [
|
|
1720
|
+
/* @__PURE__ */ jsx(Icon, {
|
|
1721
|
+
size: 18,
|
|
1722
|
+
className: "flex-shrink-0"
|
|
1723
|
+
}),
|
|
1724
|
+
/* @__PURE__ */ jsx("span", { children: group.label }),
|
|
1725
|
+
/* @__PURE__ */ jsx(ChevronDown, {
|
|
1726
|
+
size: 14,
|
|
1727
|
+
className: cn$25("flex-shrink-0 transition-transform", isOpen && "rotate-180")
|
|
1728
|
+
})
|
|
1729
|
+
]
|
|
1730
|
+
}), isOpen && /* @__PURE__ */ jsx("div", {
|
|
1731
|
+
className: "absolute left-1/2 top-[calc(100%+0.5rem)] z-50 w-max min-w-full max-w-[24rem] -translate-x-1/2 rounded-xl border border-[var(--dashboard-text-secondary,#6b7280)]/20 bg-[var(--dashboard-surface,#ffffff)] p-1.5 shadow-xl",
|
|
1732
|
+
children: group.children.map((child) => {
|
|
1733
|
+
const active = currentPath === child.href;
|
|
1734
|
+
return child.disabled ? /* @__PURE__ */ jsxs("span", {
|
|
1735
|
+
className: "flex cursor-not-allowed items-center gap-2 rounded-lg px-3 py-2 text-sm text-[var(--dashboard-text-secondary,#6b7280)]/40",
|
|
1736
|
+
title: "Em breve",
|
|
1737
|
+
children: [/* @__PURE__ */ jsx(child.icon, {
|
|
1738
|
+
size: 16,
|
|
1739
|
+
className: "flex-shrink-0 opacity-40"
|
|
1740
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
1741
|
+
className: "whitespace-nowrap line-through opacity-50",
|
|
1742
|
+
children: child.label
|
|
1743
|
+
})]
|
|
1744
|
+
}, child.id) : /* @__PURE__ */ jsx(LinkComponent, {
|
|
1745
|
+
href: child.href,
|
|
1746
|
+
className: "block",
|
|
1747
|
+
onClick: () => setOpenDropdownId(null),
|
|
1748
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
1749
|
+
className: cn$25("flex items-center gap-2 rounded-lg px-3 py-2 text-sm transition-colors", active ? "bg-[var(--dashboard-primary,#37a501)]/10 text-[var(--dashboard-primary,#37a501)] font-semibold" : "text-[var(--dashboard-text-primary,#2d2d2d)]/80 hover:bg-[var(--dashboard-primary,#37a501)]/8 hover:text-[var(--dashboard-text-primary,#2d2d2d)]"),
|
|
1750
|
+
children: [
|
|
1751
|
+
/* @__PURE__ */ jsx(child.icon, {
|
|
1752
|
+
size: 16,
|
|
1753
|
+
className: "flex-shrink-0"
|
|
1754
|
+
}),
|
|
1755
|
+
/* @__PURE__ */ jsx("span", {
|
|
1756
|
+
className: "whitespace-nowrap",
|
|
1757
|
+
children: child.label
|
|
1758
|
+
}),
|
|
1759
|
+
active && /* @__PURE__ */ jsx("span", { className: "ml-auto h-1.5 w-1.5 rounded-full bg-[var(--dashboard-primary,#37a501)]" })
|
|
1760
|
+
]
|
|
1761
|
+
})
|
|
1762
|
+
}, child.id);
|
|
1763
|
+
})
|
|
1764
|
+
})]
|
|
1765
|
+
}, group.id);
|
|
1766
|
+
};
|
|
1767
|
+
const renderNavItem = (item, options = {}) => {
|
|
1768
|
+
if (isGroup(item)) return renderDropdown(item, options);
|
|
1769
|
+
return renderNavLink(item, options);
|
|
1770
|
+
};
|
|
1771
|
+
const desktopOffset = typeof desktopOffsetLeft === "number" ? `${desktopOffsetLeft}px` : desktopOffsetLeft;
|
|
1772
|
+
const userEstablishments = establishments.length > 0 ? establishments : user?.subtitle ? [{
|
|
1773
|
+
id: "current",
|
|
1774
|
+
label: user.subtitle,
|
|
1775
|
+
active: true
|
|
1776
|
+
}] : [];
|
|
1777
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1778
|
+
/* @__PURE__ */ jsx("div", {
|
|
1779
|
+
"aria-hidden": "true",
|
|
1780
|
+
className: "pointer-events-none fixed inset-x-0 top-0 z-30 h-2 bg-[var(--dashboard-background,#f2f2f2)]"
|
|
1781
|
+
}),
|
|
1782
|
+
/* @__PURE__ */ jsx("div", {
|
|
1783
|
+
"aria-hidden": "true",
|
|
1784
|
+
className: "pointer-events-none fixed left-[var(--dashboard-page-gutter,0px)] right-[var(--dashboard-page-gutter,0px)] top-2 z-30 h-5 bg-[var(--dashboard-background,#f2f2f2)] transition-[left,right] duration-[400ms] ease-[cubic-bezier(0.4,0,0.2,1)] xl:left-[calc(var(--dashboard-header-offset-left,0px)+var(--dashboard-page-gutter,0px))]",
|
|
1785
|
+
style: { "--dashboard-header-offset-left": desktopOffset }
|
|
1786
|
+
}),
|
|
1787
|
+
/* @__PURE__ */ jsx("div", {
|
|
1788
|
+
"aria-hidden": "true",
|
|
1789
|
+
className: "pointer-events-none fixed left-[var(--dashboard-page-gutter,0px)] top-2 z-30 h-14 w-5 bg-[var(--dashboard-background,#f2f2f2)] transition-[left] duration-[400ms] ease-[cubic-bezier(0.4,0,0.2,1)] xl:left-[calc(var(--dashboard-header-offset-left,0px)+var(--dashboard-page-gutter,0px))]",
|
|
1790
|
+
style: { "--dashboard-header-offset-left": desktopOffset }
|
|
1791
|
+
}),
|
|
1792
|
+
/* @__PURE__ */ jsx("div", {
|
|
1793
|
+
"aria-hidden": "true",
|
|
1794
|
+
className: "pointer-events-none fixed right-[var(--dashboard-page-gutter,0px)] top-2 z-30 h-14 w-5 bg-[var(--dashboard-background,#f2f2f2)] transition-[right] duration-[400ms] ease-[cubic-bezier(0.4,0,0.2,1)]"
|
|
1795
|
+
}),
|
|
1796
|
+
/* @__PURE__ */ jsx("div", {
|
|
1797
|
+
"aria-hidden": "true",
|
|
1798
|
+
className: "pointer-events-none fixed left-[var(--dashboard-page-gutter,0px)] right-[var(--dashboard-page-gutter,0px)] top-2 z-30 h-20 rounded-2xl bg-[var(--dashboard-background,#f2f2f2)] transition-[left,right] duration-[400ms] ease-[cubic-bezier(0.4,0,0.2,1)] xl:left-[calc(var(--dashboard-header-offset-left,0px)+var(--dashboard-page-gutter,0px))]",
|
|
1799
|
+
style: { "--dashboard-header-offset-left": desktopOffset }
|
|
1800
|
+
}),
|
|
1801
|
+
/* @__PURE__ */ jsxs("header", {
|
|
1802
|
+
className: cn$25("fixed left-[var(--dashboard-page-gutter,0px)] right-[var(--dashboard-page-gutter,0px)] top-2 z-40 rounded-2xl border border-[var(--dashboard-text-secondary,#6b7280)]/15 bg-[var(--dashboard-surface,#ffffff)] text-[var(--dashboard-text-primary,#2d2d2d)] shadow-sm transition-[left,right] duration-[400ms] ease-[cubic-bezier(0.4,0,0.2,1)] xl:left-[calc(var(--dashboard-header-offset-left,0px)+var(--dashboard-page-gutter,0px))]", className),
|
|
1803
|
+
style: { "--dashboard-header-offset-left": desktopOffset },
|
|
1804
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
1805
|
+
className: "flex h-20 items-center gap-4 px-4 sm:px-5 xl:grid xl:grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)]",
|
|
1806
|
+
children: [
|
|
1807
|
+
/* @__PURE__ */ jsx("div", {
|
|
1808
|
+
className: "flex min-w-0 flex-1 items-center gap-4 lg:flex-none xl:col-start-1 xl:justify-self-start",
|
|
1809
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
1810
|
+
className: "flex min-w-0 items-center",
|
|
1811
|
+
children: logo
|
|
1812
|
+
})
|
|
1813
|
+
}),
|
|
1814
|
+
/* @__PURE__ */ jsx("nav", {
|
|
1815
|
+
className: "hidden min-w-0 items-center justify-center gap-1 xl:col-start-2 xl:flex",
|
|
1816
|
+
"aria-label": "Navegacao principal",
|
|
1817
|
+
children: menuItems.map((item) => renderNavItem(item))
|
|
1818
|
+
}),
|
|
1819
|
+
/* @__PURE__ */ jsxs("div", {
|
|
1820
|
+
className: "hidden items-center gap-3 xl:col-start-3 xl:flex xl:justify-self-end",
|
|
1821
|
+
children: [actions, user && /* @__PURE__ */ jsxs("div", {
|
|
1822
|
+
className: "relative w-[260px]",
|
|
1823
|
+
ref: userMenuRef,
|
|
1824
|
+
children: [/* @__PURE__ */ jsxs("button", {
|
|
1825
|
+
type: "button",
|
|
1826
|
+
onClick: () => setIsUserMenuOpen((open) => !open),
|
|
1827
|
+
className: "flex h-11 w-full items-center gap-3 rounded-lg bg-[var(--dashboard-background,#f2f2f2)] px-3 text-left transition-colors hover:bg-[var(--dashboard-primary,#37a501)]/8",
|
|
1828
|
+
"aria-expanded": isUserMenuOpen,
|
|
1829
|
+
children: [
|
|
1830
|
+
/* @__PURE__ */ jsx("div", {
|
|
1831
|
+
className: "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-[var(--dashboard-primary,#37a501)]/12 text-[var(--dashboard-primary,#37a501)]",
|
|
1832
|
+
children: /* @__PURE__ */ jsx(User, { size: 16 })
|
|
1833
|
+
}),
|
|
1834
|
+
/* @__PURE__ */ jsxs("div", {
|
|
1835
|
+
className: "min-w-0 flex-1",
|
|
1836
|
+
children: [user.subtitle && /* @__PURE__ */ jsx("p", {
|
|
1837
|
+
className: "truncate text-[11px] leading-4 text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
1838
|
+
children: user.subtitle
|
|
1839
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
1840
|
+
className: "truncate text-sm font-medium leading-4",
|
|
1841
|
+
children: user.name
|
|
1842
|
+
})]
|
|
1843
|
+
}),
|
|
1844
|
+
/* @__PURE__ */ jsx(ChevronDown, {
|
|
1845
|
+
size: 16,
|
|
1846
|
+
className: cn$25("ml-auto flex-shrink-0 transition-transform", isUserMenuOpen && "rotate-180")
|
|
1847
|
+
})
|
|
1848
|
+
]
|
|
1849
|
+
}), isUserMenuOpen && /* @__PURE__ */ jsxs("div", {
|
|
1850
|
+
className: "absolute right-0 top-[calc(100%+0.5rem)] w-full rounded-lg border border-[var(--dashboard-text-secondary,#6b7280)]/20 bg-[var(--dashboard-surface,#ffffff)] p-2 text-[var(--dashboard-text-primary,#2d2d2d)] shadow-xl",
|
|
1851
|
+
children: [
|
|
1852
|
+
/* @__PURE__ */ jsxs("button", {
|
|
1853
|
+
type: "button",
|
|
1854
|
+
onClick: () => {
|
|
1855
|
+
setIsUserMenuOpen(false);
|
|
1856
|
+
onUserClick?.();
|
|
1857
|
+
},
|
|
1858
|
+
className: "flex w-full items-center gap-3 rounded-lg px-3 py-3 text-left transition-colors hover:bg-[var(--dashboard-primary,#37a501)]/8",
|
|
1859
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
1860
|
+
className: "flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-full bg-[var(--dashboard-primary,#37a501)]/12 text-[var(--dashboard-primary,#37a501)]",
|
|
1861
|
+
children: /* @__PURE__ */ jsx(User, { size: 17 })
|
|
1862
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
1863
|
+
className: "min-w-0",
|
|
1864
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
1865
|
+
className: "truncate text-sm font-semibold",
|
|
1866
|
+
children: user.name
|
|
1867
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
1868
|
+
className: "truncate text-xs text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
1869
|
+
children: user.email
|
|
1870
|
+
})]
|
|
1871
|
+
})]
|
|
1872
|
+
}),
|
|
1873
|
+
userEstablishments.length > 0 && /* @__PURE__ */ jsxs("div", {
|
|
1874
|
+
className: "mt-1 border-t border-[var(--dashboard-text-secondary,#6b7280)]/15 pt-2",
|
|
1875
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
1876
|
+
className: "px-3 pb-1 text-[11px] font-semibold uppercase tracking-wide text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
1877
|
+
children: establishmentsLabel
|
|
1878
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
1879
|
+
className: "space-y-1",
|
|
1880
|
+
children: userEstablishments.map((establishment) => {
|
|
1881
|
+
const isDisabled = establishment.disabled || !onEstablishmentChange || establishment.active;
|
|
1882
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
1883
|
+
type: "button",
|
|
1884
|
+
onClick: () => {
|
|
1885
|
+
if (isDisabled) return;
|
|
1886
|
+
setIsUserMenuOpen(false);
|
|
1887
|
+
onEstablishmentChange?.(establishment.id);
|
|
1888
|
+
},
|
|
1889
|
+
disabled: isDisabled,
|
|
1890
|
+
className: cn$25("flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-left transition-colors", establishment.active ? "bg-[var(--dashboard-primary,#37a501)]/10 text-[var(--dashboard-primary,#37a501)]" : "hover:bg-[var(--dashboard-primary,#37a501)]/8", isDisabled ? establishment.active ? "cursor-default" : "cursor-not-allowed opacity-60" : "cursor-pointer"),
|
|
1891
|
+
children: [
|
|
1892
|
+
/* @__PURE__ */ jsx("div", {
|
|
1893
|
+
className: "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-[var(--dashboard-primary,#37a501)]/12 text-[var(--dashboard-primary,#37a501)]",
|
|
1894
|
+
children: /* @__PURE__ */ jsx(Building2, { size: 15 })
|
|
1895
|
+
}),
|
|
1896
|
+
/* @__PURE__ */ jsxs("div", {
|
|
1897
|
+
className: "min-w-0 flex-1",
|
|
1898
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
1899
|
+
className: "truncate text-sm font-semibold",
|
|
1900
|
+
children: establishment.label
|
|
1901
|
+
}), establishment.description && /* @__PURE__ */ jsx("p", {
|
|
1902
|
+
className: "truncate text-xs text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
1903
|
+
children: establishment.description
|
|
1904
|
+
})]
|
|
1905
|
+
}),
|
|
1906
|
+
establishment.active && /* @__PURE__ */ jsx(Check, {
|
|
1907
|
+
size: 16,
|
|
1908
|
+
className: "flex-shrink-0"
|
|
1909
|
+
})
|
|
1910
|
+
]
|
|
1911
|
+
}, establishment.id);
|
|
1912
|
+
})
|
|
1913
|
+
})]
|
|
1914
|
+
}),
|
|
1915
|
+
onLogout && /* @__PURE__ */ jsxs("button", {
|
|
1916
|
+
type: "button",
|
|
1917
|
+
onClick: () => {
|
|
1918
|
+
setIsUserMenuOpen(false);
|
|
1919
|
+
onLogout();
|
|
1920
|
+
},
|
|
1921
|
+
className: "mt-1 flex w-full items-center gap-3 rounded-lg px-3 py-3 text-sm font-medium transition-colors hover:bg-[var(--dashboard-primary,#37a501)]/8",
|
|
1922
|
+
children: [/* @__PURE__ */ jsx(LogOut, { size: 18 }), logoutLabel]
|
|
1923
|
+
})
|
|
1924
|
+
]
|
|
1925
|
+
})]
|
|
1926
|
+
})]
|
|
1927
|
+
}),
|
|
1928
|
+
/* @__PURE__ */ jsx("button", {
|
|
1929
|
+
type: "button",
|
|
1930
|
+
onClick: () => setIsMobileMenuOpen((open) => !open),
|
|
1931
|
+
className: "inline-flex h-10 w-10 items-center justify-center rounded-lg bg-[var(--dashboard-primary,#37a501)]/10 text-[var(--dashboard-primary,#37a501)] transition-colors hover:bg-[var(--dashboard-primary,#37a501)]/15 xl:hidden",
|
|
1932
|
+
"aria-label": menuLabel,
|
|
1933
|
+
"aria-expanded": isMobileMenuOpen,
|
|
1934
|
+
children: isMobileMenuOpen ? /* @__PURE__ */ jsx(X, { size: 22 }) : /* @__PURE__ */ jsx(Menu, { size: 22 })
|
|
1935
|
+
})
|
|
1936
|
+
]
|
|
1937
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
1938
|
+
className: cn$25("xl:hidden overflow-hidden border-t border-[var(--dashboard-text-secondary,#6b7280)]/20 bg-[var(--dashboard-surface,#ffffff)] shadow-lg transition-[max-height] duration-200", isMobileMenuOpen ? "max-h-[calc(100vh-4rem)]" : "max-h-0"),
|
|
1939
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
1940
|
+
className: "max-h-[calc(100vh-4rem)] overflow-y-auto px-4 py-3",
|
|
1941
|
+
children: [/* @__PURE__ */ jsx("nav", {
|
|
1942
|
+
className: "space-y-1",
|
|
1943
|
+
"aria-label": "Navegacao principal",
|
|
1944
|
+
children: menuItems.map((item) => renderNavItem(item, { mobile: true }))
|
|
1945
|
+
}), (user || actions || onLogout) && /* @__PURE__ */ jsxs("div", {
|
|
1946
|
+
className: "mt-3 space-y-2 border-t border-[var(--dashboard-text-secondary,#6b7280)]/20 pt-3",
|
|
1947
|
+
children: [
|
|
1948
|
+
actions,
|
|
1949
|
+
user && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("button", {
|
|
1950
|
+
type: "button",
|
|
1951
|
+
onClick: () => {
|
|
1952
|
+
closeMenus();
|
|
1953
|
+
onUserClick?.();
|
|
1954
|
+
},
|
|
1955
|
+
className: "flex w-full items-center gap-3 rounded-lg bg-[var(--dashboard-background,#f2f2f2)] px-4 py-3 text-left transition-colors hover:bg-[var(--dashboard-primary,#37a501)]/8",
|
|
1956
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
1957
|
+
className: "flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-full bg-[var(--dashboard-primary,#37a501)]/12 text-[var(--dashboard-primary,#37a501)]",
|
|
1958
|
+
children: /* @__PURE__ */ jsx(User, { size: 17 })
|
|
1959
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
1960
|
+
className: "min-w-0",
|
|
1961
|
+
children: [
|
|
1962
|
+
user.subtitle && /* @__PURE__ */ jsx("p", {
|
|
1963
|
+
className: "truncate text-xs text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
1964
|
+
children: user.subtitle
|
|
1965
|
+
}),
|
|
1966
|
+
/* @__PURE__ */ jsx("p", {
|
|
1967
|
+
className: "truncate text-sm font-semibold",
|
|
1968
|
+
children: user.name
|
|
1969
|
+
}),
|
|
1970
|
+
/* @__PURE__ */ jsx("p", {
|
|
1971
|
+
className: "truncate text-xs text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
1972
|
+
children: user.email
|
|
1973
|
+
})
|
|
1974
|
+
]
|
|
1975
|
+
})]
|
|
1976
|
+
}), userEstablishments.length > 0 && /* @__PURE__ */ jsxs("div", {
|
|
1977
|
+
className: "space-y-1",
|
|
1978
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
1979
|
+
className: "px-4 pt-2 text-[11px] font-semibold uppercase tracking-wide text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
1980
|
+
children: establishmentsLabel
|
|
1981
|
+
}), userEstablishments.map((establishment) => {
|
|
1982
|
+
const isDisabled = establishment.disabled || !onEstablishmentChange || establishment.active;
|
|
1983
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
1984
|
+
type: "button",
|
|
1985
|
+
onClick: () => {
|
|
1986
|
+
if (isDisabled) return;
|
|
1987
|
+
closeMenus();
|
|
1988
|
+
onEstablishmentChange?.(establishment.id);
|
|
1989
|
+
},
|
|
1990
|
+
disabled: isDisabled,
|
|
1991
|
+
className: cn$25("flex w-full items-center gap-3 rounded-lg px-4 py-3 text-left transition-colors", establishment.active ? "bg-[var(--dashboard-primary,#37a501)]/10 text-[var(--dashboard-primary,#37a501)]" : "hover:bg-[var(--dashboard-primary,#37a501)]/8", isDisabled ? establishment.active ? "cursor-default" : "cursor-not-allowed opacity-60" : "cursor-pointer"),
|
|
1992
|
+
children: [
|
|
1993
|
+
/* @__PURE__ */ jsx("div", {
|
|
1994
|
+
className: "flex h-8 w-8 flex-shrink-0 items-center justify-center rounded-full bg-[var(--dashboard-primary,#37a501)]/12 text-[var(--dashboard-primary,#37a501)]",
|
|
1995
|
+
children: /* @__PURE__ */ jsx(Building2, { size: 15 })
|
|
1996
|
+
}),
|
|
1997
|
+
/* @__PURE__ */ jsxs("div", {
|
|
1998
|
+
className: "min-w-0 flex-1",
|
|
1999
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
2000
|
+
className: "truncate text-sm font-semibold",
|
|
2001
|
+
children: establishment.label
|
|
2002
|
+
}), establishment.description && /* @__PURE__ */ jsx("p", {
|
|
2003
|
+
className: "truncate text-xs text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
2004
|
+
children: establishment.description
|
|
2005
|
+
})]
|
|
2006
|
+
}),
|
|
2007
|
+
establishment.active && /* @__PURE__ */ jsx(Check, {
|
|
2008
|
+
size: 16,
|
|
2009
|
+
className: "flex-shrink-0"
|
|
2010
|
+
})
|
|
2011
|
+
]
|
|
2012
|
+
}, establishment.id);
|
|
2013
|
+
})]
|
|
2014
|
+
})] }),
|
|
2015
|
+
onLogout && /* @__PURE__ */ jsxs("button", {
|
|
2016
|
+
type: "button",
|
|
2017
|
+
onClick: () => {
|
|
2018
|
+
closeMenus();
|
|
2019
|
+
onLogout();
|
|
2020
|
+
},
|
|
2021
|
+
className: "flex w-full items-center gap-3 rounded-lg px-4 py-3 text-sm font-medium transition-colors hover:bg-[var(--dashboard-primary,#37a501)]/8",
|
|
2022
|
+
children: [/* @__PURE__ */ jsx(LogOut, { size: 18 }), logoutLabel]
|
|
2023
|
+
})
|
|
2024
|
+
]
|
|
2025
|
+
})]
|
|
2026
|
+
})
|
|
2027
|
+
})]
|
|
2028
|
+
})
|
|
2029
|
+
] });
|
|
1442
2030
|
}
|
|
1443
2031
|
|
|
1444
2032
|
//#endregion
|
|
1445
2033
|
//#region src/components/ThemeSwitcher/index.tsx
|
|
1446
|
-
const cn$
|
|
2034
|
+
const cn$24 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1447
2035
|
const modes = [
|
|
1448
2036
|
{
|
|
1449
2037
|
value: "light",
|
|
@@ -1463,11 +2051,11 @@ const modes = [
|
|
|
1463
2051
|
];
|
|
1464
2052
|
function ThemeSwitcher({ mode, onModeChange, className }) {
|
|
1465
2053
|
return /* @__PURE__ */ jsx("div", {
|
|
1466
|
-
className: cn$
|
|
2054
|
+
className: cn$24("inline-flex items-center gap-1 rounded-lg bg-[var(--dashboard-background,#f2f2f2)] p-1", className),
|
|
1467
2055
|
children: modes.map(({ value, icon: Icon, label }) => /* @__PURE__ */ jsxs("button", {
|
|
1468
2056
|
type: "button",
|
|
1469
2057
|
onClick: () => onModeChange(value),
|
|
1470
|
-
className: cn$
|
|
2058
|
+
className: cn$24("flex cursor-pointer items-center gap-1.5 rounded-md px-3 py-1.5 text-xs font-medium transition-colors", mode === value ? "bg-[var(--dashboard-surface,#ffffff)] text-[var(--dashboard-text-primary,#2d2d2d)] shadow-sm" : "text-[var(--dashboard-text-secondary,#6b7280)] hover:text-[var(--dashboard-text-primary,#2d2d2d)]"),
|
|
1471
2059
|
title: label,
|
|
1472
2060
|
children: [/* @__PURE__ */ jsx(Icon, { size: 14 }), /* @__PURE__ */ jsx("span", { children: label })]
|
|
1473
2061
|
}, value))
|
|
@@ -1476,7 +2064,7 @@ function ThemeSwitcher({ mode, onModeChange, className }) {
|
|
|
1476
2064
|
|
|
1477
2065
|
//#endregion
|
|
1478
2066
|
//#region src/components/KPICard/index.tsx
|
|
1479
|
-
const cn$
|
|
2067
|
+
const cn$23 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1480
2068
|
function formatValue(value, format) {
|
|
1481
2069
|
switch (format) {
|
|
1482
2070
|
case "currency": return new Intl.NumberFormat("pt-BR", {
|
|
@@ -1502,16 +2090,23 @@ const trendConfigs = {
|
|
|
1502
2090
|
color: "text-[var(--dashboard-text-secondary,#64748B)] bg-[var(--dashboard-text-secondary,#64748B)]/8"
|
|
1503
2091
|
}
|
|
1504
2092
|
};
|
|
1505
|
-
function KPICard({ title, value, variation, trend, format = "number", benchmark, isLoading, className }) {
|
|
2093
|
+
function KPICard({ title, value, variation, trend, format = "number", benchmark, icon, isLoading, className }) {
|
|
1506
2094
|
if (isLoading) return /* @__PURE__ */ jsx(KPICardSkeleton, { className });
|
|
1507
2095
|
const trendConfig = trendConfigs[trend];
|
|
1508
2096
|
return /* @__PURE__ */ jsxs("div", {
|
|
1509
|
-
className: cn$
|
|
2097
|
+
className: cn$23("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),
|
|
1510
2098
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
1511
|
-
className: "flex justify-between items-start mb-4",
|
|
1512
|
-
children: [/* @__PURE__ */
|
|
1513
|
-
className: "
|
|
1514
|
-
children:
|
|
2099
|
+
className: "flex justify-between items-start mb-4 gap-2",
|
|
2100
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
2101
|
+
className: "flex items-center gap-2 min-w-0",
|
|
2102
|
+
children: [icon && /* @__PURE__ */ jsx("span", {
|
|
2103
|
+
className: "shrink-0 text-[var(--dashboard-text-secondary,#64748B)]",
|
|
2104
|
+
"aria-hidden": "true",
|
|
2105
|
+
children: icon
|
|
2106
|
+
}), /* @__PURE__ */ jsx("h3", {
|
|
2107
|
+
className: "text-xs font-semibold uppercase tracking-wider text-[var(--dashboard-text-secondary,#64748B)] whitespace-nowrap truncate",
|
|
2108
|
+
children: title
|
|
2109
|
+
})]
|
|
1515
2110
|
}), benchmark && /* @__PURE__ */ jsx("span", {
|
|
1516
2111
|
className: "text-xs text-[var(--dashboard-text-secondary,#64748B)]/50 ml-2 whitespace-nowrap flex-shrink-0",
|
|
1517
2112
|
title: "Benchmark de referência",
|
|
@@ -1523,7 +2118,7 @@ function KPICard({ title, value, variation, trend, format = "number", benchmark,
|
|
|
1523
2118
|
className: "text-3xl font-bold text-[var(--dashboard-text-primary,#0F172A)] whitespace-nowrap tracking-tight",
|
|
1524
2119
|
children: formatValue(value, format)
|
|
1525
2120
|
}), /* @__PURE__ */ jsxs("div", {
|
|
1526
|
-
className: cn$
|
|
2121
|
+
className: cn$23("inline-flex items-center gap-1 px-2 py-1 rounded-full flex-shrink-0 mb-1", trendConfig.color),
|
|
1527
2122
|
children: [/* @__PURE__ */ jsx("span", {
|
|
1528
2123
|
className: "text-sm",
|
|
1529
2124
|
children: trendConfig.icon
|
|
@@ -1537,7 +2132,7 @@ function KPICard({ title, value, variation, trend, format = "number", benchmark,
|
|
|
1537
2132
|
}
|
|
1538
2133
|
function KPICardSkeleton({ className }) {
|
|
1539
2134
|
return /* @__PURE__ */ jsxs("div", {
|
|
1540
|
-
className: cn$
|
|
2135
|
+
className: cn$23("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),
|
|
1541
2136
|
children: [/* @__PURE__ */ jsx("div", { className: "h-3 bg-[var(--dashboard-text-secondary,#64748B)]/10 rounded w-2/3 mb-4" }), /* @__PURE__ */ jsxs("div", {
|
|
1542
2137
|
className: "flex items-end gap-3 flex-1",
|
|
1543
2138
|
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" })]
|
|
@@ -1547,51 +2142,63 @@ function KPICardSkeleton({ className }) {
|
|
|
1547
2142
|
|
|
1548
2143
|
//#endregion
|
|
1549
2144
|
//#region src/components/PageLayout/index.tsx
|
|
1550
|
-
const cn$
|
|
1551
|
-
function PageLayout({ title, description, headerActions, children, contentPadding = true, sidebar, sidebarCollapsed = false, sidebarWidth = 280, sidebarCollapsedWidth = 109, className }) {
|
|
2145
|
+
const cn$22 = (...classes) => classes.filter(Boolean).join(" ");
|
|
2146
|
+
function PageLayout({ title, description, headerActions, appHeader, children, contentPadding = true, sidebar, sidebarCollapsed = false, sidebarWidth = 280, sidebarCollapsedWidth = 109, className }) {
|
|
1552
2147
|
const marginLeft = sidebar ? sidebarCollapsed ? `max(0px, ${sidebarCollapsedWidth}px)` : `max(0px, ${sidebarWidth}px)` : "0px";
|
|
2148
|
+
const mainTopPadding = appHeader ? "pt-24" : sidebar ? "pt-16 xl:pt-0" : "pt-0";
|
|
2149
|
+
const layoutContainer = "mx-[var(--dashboard-page-gutter)]";
|
|
1553
2150
|
return /* @__PURE__ */ jsxs("div", {
|
|
1554
|
-
className: cn$
|
|
1555
|
-
children: [
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
2151
|
+
className: cn$22("min-h-screen bg-[var(--dashboard-background,#f2f2f2)] [--dashboard-page-gutter:1.5rem] sm:[--dashboard-page-gutter:2rem] lg:[--dashboard-page-gutter:2.5rem] xl:[--dashboard-page-gutter:3rem]", className),
|
|
2152
|
+
children: [
|
|
2153
|
+
appHeader,
|
|
2154
|
+
sidebar,
|
|
2155
|
+
/* @__PURE__ */ jsxs("main", {
|
|
2156
|
+
className: mainTopPadding,
|
|
2157
|
+
style: {
|
|
2158
|
+
marginLeft,
|
|
2159
|
+
transition: "margin-left 400ms cubic-bezier(0.4, 0, 0.2, 1)"
|
|
2160
|
+
},
|
|
2161
|
+
children: [
|
|
2162
|
+
/* @__PURE__ */ jsx("style", { children: `
|
|
1563
2163
|
@media (max-width: 1279px) {
|
|
1564
2164
|
main {
|
|
1565
2165
|
margin-left: 0 !important;
|
|
1566
2166
|
}
|
|
1567
2167
|
}
|
|
1568
2168
|
` }),
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
2169
|
+
/* @__PURE__ */ jsx("div", {
|
|
2170
|
+
className: cn$22(layoutContainer, "-mt-10 rounded-b-2xl border-b border-[var(--dashboard-text-secondary,#6b7280)]/20 bg-[var(--dashboard-surface,#ffffff)] px-7 pb-7 pt-16 sm:px-10 lg:px-12"),
|
|
2171
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
2172
|
+
className: "flex flex-col gap-5 lg:flex-row lg:items-end lg:justify-between",
|
|
2173
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
2174
|
+
className: "min-w-0",
|
|
2175
|
+
children: [/* @__PURE__ */ jsx("h1", {
|
|
2176
|
+
className: "text-2xl font-bold text-[var(--dashboard-text-primary,#2d2d2d)] sm:text-3xl",
|
|
2177
|
+
children: title
|
|
2178
|
+
}), description && /* @__PURE__ */ jsx("p", {
|
|
2179
|
+
className: "mt-2 text-sm font-medium text-[var(--dashboard-text-secondary,#6b7280)] sm:text-base",
|
|
2180
|
+
children: description
|
|
2181
|
+
})]
|
|
2182
|
+
}), headerActions && /* @__PURE__ */ jsx("div", {
|
|
2183
|
+
className: "flex max-w-full justify-start lg:justify-end",
|
|
2184
|
+
children: headerActions
|
|
2185
|
+
})]
|
|
2186
|
+
})
|
|
2187
|
+
}),
|
|
2188
|
+
/* @__PURE__ */ jsx("div", {
|
|
2189
|
+
className: contentPadding ? cn$22(layoutContainer, "py-6") : "",
|
|
2190
|
+
children
|
|
2191
|
+
})
|
|
2192
|
+
]
|
|
2193
|
+
})
|
|
2194
|
+
]
|
|
1588
2195
|
});
|
|
1589
2196
|
}
|
|
1590
2197
|
|
|
1591
2198
|
//#endregion
|
|
1592
2199
|
//#region src/components/ComparisonLineChart/index.tsx
|
|
1593
2200
|
Chart.register(CategoryScale, LinearScale, PointElement, LineElement, Title$1, Tooltip$1, Legend, Filler);
|
|
1594
|
-
const cn$
|
|
2201
|
+
const cn$21 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1595
2202
|
function ComparisonLineChart({ labels, currentPeriodData, previousPeriodData, currentPeriodLabel = "Período atual", previousPeriodLabel = "Período anterior", title, color, height = 300, className }) {
|
|
1596
2203
|
const primaryColor = color || (typeof document !== "undefined" ? getComputedStyle(document.documentElement).getPropertyValue("--dashboard-primary").trim() : "") || "#37a501";
|
|
1597
2204
|
const data = {
|
|
@@ -1685,7 +2292,7 @@ function ComparisonLineChart({ labels, currentPeriodData, previousPeriodData, cu
|
|
|
1685
2292
|
}
|
|
1686
2293
|
};
|
|
1687
2294
|
return /* @__PURE__ */ jsxs("div", {
|
|
1688
|
-
className: cn$
|
|
2295
|
+
className: cn$21("bg-[var(--dashboard-surface,#ffffff)] rounded-lg shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20 p-6", className),
|
|
1689
2296
|
children: [title && /* @__PURE__ */ jsx("h3", {
|
|
1690
2297
|
className: "text-base font-semibold mb-4 text-[var(--dashboard-text-primary,#2d2d2d)]",
|
|
1691
2298
|
children: title
|
|
@@ -1702,7 +2309,7 @@ function ComparisonLineChart({ labels, currentPeriodData, previousPeriodData, cu
|
|
|
1702
2309
|
//#endregion
|
|
1703
2310
|
//#region src/components/HorizontalBarChart/index.tsx
|
|
1704
2311
|
Chart.register(CategoryScale, LinearScale, BarElement, Title$1, Tooltip$1, Legend);
|
|
1705
|
-
const cn$
|
|
2312
|
+
const cn$20 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1706
2313
|
function HorizontalBarChart({ labels, datasets, tabs, title, titleIcon, color, valueLabel = "itens", valueLabelSingular, bestItemLabel = "Melhor item", className }) {
|
|
1707
2314
|
const [activeTab, setActiveTab] = useState((tabs ? tabs.map((t) => t.id) : Object.keys(datasets))[0]);
|
|
1708
2315
|
const [isMobile, setIsMobile] = useState(false);
|
|
@@ -1777,7 +2384,7 @@ function HorizontalBarChart({ labels, datasets, tabs, title, titleIcon, color, v
|
|
|
1777
2384
|
}
|
|
1778
2385
|
};
|
|
1779
2386
|
return /* @__PURE__ */ jsxs("div", {
|
|
1780
|
-
className: cn$
|
|
2387
|
+
className: cn$20("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),
|
|
1781
2388
|
children: [
|
|
1782
2389
|
title && /* @__PURE__ */ jsxs("div", {
|
|
1783
2390
|
className: "flex items-center gap-2 mb-4",
|
|
@@ -1790,7 +2397,7 @@ function HorizontalBarChart({ labels, datasets, tabs, title, titleIcon, color, v
|
|
|
1790
2397
|
className: "flex gap-2 mb-4 flex-wrap",
|
|
1791
2398
|
children: tabs.map((tab) => /* @__PURE__ */ jsx("button", {
|
|
1792
2399
|
onClick: () => setActiveTab(tab.id),
|
|
1793
|
-
className: cn$
|
|
2400
|
+
className: cn$20("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"),
|
|
1794
2401
|
children: tab.label
|
|
1795
2402
|
}, tab.id))
|
|
1796
2403
|
}),
|
|
@@ -1829,7 +2436,7 @@ function HorizontalBarChart({ labels, datasets, tabs, title, titleIcon, color, v
|
|
|
1829
2436
|
//#endregion
|
|
1830
2437
|
//#region src/components/VerticalBarChart/index.tsx
|
|
1831
2438
|
Chart.register(CategoryScale, LinearScale, BarElement, Title$1, Tooltip$1, Legend);
|
|
1832
|
-
const cn$
|
|
2439
|
+
const cn$19 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1833
2440
|
function VerticalBarChart({ labels, data: values, title, titleIcon, color, valueLabel = "itens", valueLabelSingular, bestItemLabel = "Melhor item", labelMaxChars = 3, className }) {
|
|
1834
2441
|
const maxValue = Math.max(...values);
|
|
1835
2442
|
const bestLabel = labels[values.indexOf(maxValue)];
|
|
@@ -1892,7 +2499,7 @@ function VerticalBarChart({ labels, data: values, title, titleIcon, color, value
|
|
|
1892
2499
|
}
|
|
1893
2500
|
};
|
|
1894
2501
|
return /* @__PURE__ */ jsxs("div", {
|
|
1895
|
-
className: cn$
|
|
2502
|
+
className: cn$19("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),
|
|
1896
2503
|
children: [
|
|
1897
2504
|
title && /* @__PURE__ */ jsxs("div", {
|
|
1898
2505
|
className: "flex items-center gap-2 mb-4",
|
|
@@ -1948,7 +2555,7 @@ const DEFAULT_COLORS = [
|
|
|
1948
2555
|
"#EA580C",
|
|
1949
2556
|
"#4F46E5"
|
|
1950
2557
|
];
|
|
1951
|
-
const cn$
|
|
2558
|
+
const cn$18 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1952
2559
|
function DoughnutChart({ items, title, titleIcon, centerLabel, centerValue, showLegend = true, formatValue, cutout = 65, height = 240, className }) {
|
|
1953
2560
|
const total = items.reduce((sum, item) => sum + item.value, 0);
|
|
1954
2561
|
const format = formatValue || ((v) => String(v));
|
|
@@ -1988,7 +2595,7 @@ function DoughnutChart({ items, title, titleIcon, centerLabel, centerValue, show
|
|
|
1988
2595
|
}
|
|
1989
2596
|
};
|
|
1990
2597
|
return /* @__PURE__ */ jsxs("div", {
|
|
1991
|
-
className: cn$
|
|
2598
|
+
className: cn$18("bg-[var(--dashboard-surface,#ffffff)] rounded-lg shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20 p-6", className),
|
|
1992
2599
|
children: [title && /* @__PURE__ */ jsxs("div", {
|
|
1993
2600
|
className: "flex items-center gap-2 mb-4",
|
|
1994
2601
|
children: [titleIcon, /* @__PURE__ */ jsx("h3", {
|
|
@@ -1996,7 +2603,7 @@ function DoughnutChart({ items, title, titleIcon, centerLabel, centerValue, show
|
|
|
1996
2603
|
children: title
|
|
1997
2604
|
})]
|
|
1998
2605
|
}), /* @__PURE__ */ jsxs("div", {
|
|
1999
|
-
className: cn$
|
|
2606
|
+
className: cn$18("flex items-center", showLegend ? "gap-6" : "justify-center"),
|
|
2000
2607
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
2001
2608
|
className: "relative flex-shrink-0",
|
|
2002
2609
|
style: {
|
|
@@ -2049,7 +2656,7 @@ function DoughnutChart({ items, title, titleIcon, centerLabel, centerValue, show
|
|
|
2049
2656
|
|
|
2050
2657
|
//#endregion
|
|
2051
2658
|
//#region src/components/ProgressBarList/index.tsx
|
|
2052
|
-
const cn$
|
|
2659
|
+
const cn$17 = (...classes) => classes.filter(Boolean).join(" ");
|
|
2053
2660
|
function ProgressBarList({ items, title, titleIcon, color, valueLabel = "itens", valueLabelSingular, sortByValue = true, formatValue, className }) {
|
|
2054
2661
|
const sortedItems = sortByValue ? [...items].sort((a, b) => b.value - a.value) : items;
|
|
2055
2662
|
const maxValue = Math.max(...items.map((i) => i.value));
|
|
@@ -2058,7 +2665,7 @@ function ProgressBarList({ items, title, titleIcon, color, valueLabel = "itens",
|
|
|
2058
2665
|
const defaultFormat = (v) => `${v} ${v === 1 ? singular : valueLabel}`;
|
|
2059
2666
|
const fmt = formatValue || defaultFormat;
|
|
2060
2667
|
return /* @__PURE__ */ jsxs("div", {
|
|
2061
|
-
className: cn$
|
|
2668
|
+
className: cn$17("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),
|
|
2062
2669
|
children: [title && /* @__PURE__ */ jsxs("div", {
|
|
2063
2670
|
className: "flex items-center gap-2 mb-4",
|
|
2064
2671
|
children: [titleIcon, /* @__PURE__ */ jsx("h3", {
|
|
@@ -2107,19 +2714,237 @@ function ProgressBarList({ items, title, titleIcon, color, valueLabel = "itens",
|
|
|
2107
2714
|
//#endregion
|
|
2108
2715
|
//#region src/components/MetricPanel/index.tsx
|
|
2109
2716
|
Chart.register(CategoryScale, LinearScale, PointElement, LineElement, Title$1, Tooltip$1, Legend, Filler);
|
|
2110
|
-
const cn$
|
|
2111
|
-
function
|
|
2717
|
+
const cn$16 = (...classes) => classes.filter(Boolean).join(" ");
|
|
2718
|
+
function formatMetricValue(value, format) {
|
|
2719
|
+
switch (format) {
|
|
2720
|
+
case "currency": return new Intl.NumberFormat("pt-BR", {
|
|
2721
|
+
style: "currency",
|
|
2722
|
+
currency: "BRL"
|
|
2723
|
+
}).format(value);
|
|
2724
|
+
case "percentage": return `${value.toFixed(2)}%`;
|
|
2725
|
+
case "rating": return value.toFixed(2);
|
|
2726
|
+
default: return new Intl.NumberFormat("pt-BR").format(Math.round(value));
|
|
2727
|
+
}
|
|
2728
|
+
}
|
|
2729
|
+
function calculateVariation(current, previous) {
|
|
2730
|
+
if (previous === 0) return 0;
|
|
2731
|
+
return (current - previous) / previous * 100;
|
|
2732
|
+
}
|
|
2733
|
+
function escapeHtml(value) {
|
|
2734
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
2735
|
+
}
|
|
2736
|
+
function getTooltipDateInfo(label) {
|
|
2737
|
+
const dayNames = [
|
|
2738
|
+
"Domingo",
|
|
2739
|
+
"Segunda",
|
|
2740
|
+
"Terca",
|
|
2741
|
+
"Quarta",
|
|
2742
|
+
"Quinta",
|
|
2743
|
+
"Sexta",
|
|
2744
|
+
"Sabado"
|
|
2745
|
+
];
|
|
2746
|
+
const [day, month] = label.split("/").map(Number);
|
|
2747
|
+
if (!day || !month) return {
|
|
2748
|
+
dayName: "",
|
|
2749
|
+
previousDate: ""
|
|
2750
|
+
};
|
|
2751
|
+
const date = new Date((/* @__PURE__ */ new Date()).getFullYear(), month - 1, day);
|
|
2752
|
+
const previousDate = new Date(date);
|
|
2753
|
+
previousDate.setDate(previousDate.getDate() - 7);
|
|
2754
|
+
return {
|
|
2755
|
+
dayName: dayNames[date.getDay()],
|
|
2756
|
+
previousDate: `${String(previousDate.getDate()).padStart(2, "0")}/${String(previousDate.getMonth() + 1).padStart(2, "0")}`
|
|
2757
|
+
};
|
|
2758
|
+
}
|
|
2759
|
+
function MetricPanel({ title, titleIcon: TitleIcon, metrics, chartData, color, secondaryColor, onActionClick, actionLabel, tooltipConfig, isLoading = false, className }) {
|
|
2112
2760
|
const [selectedMetricKey, setSelectedMetricKey] = useState(metrics[0]?.key);
|
|
2113
2761
|
const [isMobile, setIsMobile] = useState(false);
|
|
2762
|
+
const hideTooltipTimeoutRef = useRef(null);
|
|
2763
|
+
const isTooltipHoveredRef = useRef(false);
|
|
2114
2764
|
useEffect(() => {
|
|
2115
2765
|
const check = () => setIsMobile(window.innerWidth < 768);
|
|
2116
2766
|
check();
|
|
2117
2767
|
window.addEventListener("resize", check);
|
|
2118
|
-
return () =>
|
|
2768
|
+
return () => {
|
|
2769
|
+
window.removeEventListener("resize", check);
|
|
2770
|
+
if (hideTooltipTimeoutRef.current) clearTimeout(hideTooltipTimeoutRef.current);
|
|
2771
|
+
};
|
|
2119
2772
|
}, []);
|
|
2120
2773
|
const currentMetric = metrics.find((m) => m.key === selectedMetricKey) || metrics[0];
|
|
2121
2774
|
const primaryColor = color || (typeof document !== "undefined" ? getComputedStyle(document.documentElement).getPropertyValue("--dashboard-primary").trim() : "") || "#37a501";
|
|
2122
2775
|
const secColor = secondaryColor || `${primaryColor}66`;
|
|
2776
|
+
const renderExternalTooltip = (context) => {
|
|
2777
|
+
const { chart, tooltip } = context;
|
|
2778
|
+
const parent = chart.canvas.parentElement;
|
|
2779
|
+
if (!parent) return;
|
|
2780
|
+
let tooltipEl = parent.querySelector(":scope > .metric-panel-chart-tooltip");
|
|
2781
|
+
if (!tooltipEl) {
|
|
2782
|
+
tooltipEl = document.createElement("div");
|
|
2783
|
+
tooltipEl.className = "metric-panel-chart-tooltip";
|
|
2784
|
+
tooltipEl.style.position = "absolute";
|
|
2785
|
+
tooltipEl.style.pointerEvents = "auto";
|
|
2786
|
+
tooltipEl.style.transition = "opacity 0.2s ease";
|
|
2787
|
+
tooltipEl.style.zIndex = "100";
|
|
2788
|
+
tooltipEl.style.opacity = "0";
|
|
2789
|
+
const createdTooltipEl = tooltipEl;
|
|
2790
|
+
createdTooltipEl.addEventListener("mouseenter", () => {
|
|
2791
|
+
isTooltipHoveredRef.current = true;
|
|
2792
|
+
if (hideTooltipTimeoutRef.current) {
|
|
2793
|
+
clearTimeout(hideTooltipTimeoutRef.current);
|
|
2794
|
+
hideTooltipTimeoutRef.current = null;
|
|
2795
|
+
}
|
|
2796
|
+
});
|
|
2797
|
+
createdTooltipEl.addEventListener("mouseleave", () => {
|
|
2798
|
+
isTooltipHoveredRef.current = false;
|
|
2799
|
+
createdTooltipEl.style.opacity = "0";
|
|
2800
|
+
});
|
|
2801
|
+
parent.appendChild(createdTooltipEl);
|
|
2802
|
+
}
|
|
2803
|
+
if (hideTooltipTimeoutRef.current) {
|
|
2804
|
+
clearTimeout(hideTooltipTimeoutRef.current);
|
|
2805
|
+
hideTooltipTimeoutRef.current = null;
|
|
2806
|
+
}
|
|
2807
|
+
if (tooltip.opacity === 0) {
|
|
2808
|
+
hideTooltipTimeoutRef.current = setTimeout(() => {
|
|
2809
|
+
if (!isTooltipHoveredRef.current && tooltipEl) tooltipEl.style.opacity = "0";
|
|
2810
|
+
}, 300);
|
|
2811
|
+
return;
|
|
2812
|
+
}
|
|
2813
|
+
const dataPoint = tooltip.dataPoints?.find((point) => point.datasetIndex === 0);
|
|
2814
|
+
if (!dataPoint) {
|
|
2815
|
+
tooltipEl.style.opacity = "0";
|
|
2816
|
+
return;
|
|
2817
|
+
}
|
|
2818
|
+
const dataIndex = dataPoint.dataIndex;
|
|
2819
|
+
const label = dataPoint.label;
|
|
2820
|
+
const currentValue = typeof dataPoint.parsed.y === "number" ? dataPoint.parsed.y : 0;
|
|
2821
|
+
const previousValue = chartData.metrics[currentMetric.key]?.previousPeriod[dataIndex] || 0;
|
|
2822
|
+
const variation = calculateVariation(currentValue, previousValue);
|
|
2823
|
+
const formattedValue = formatMetricValue(currentValue, currentMetric.format);
|
|
2824
|
+
const formattedPrevious = formatMetricValue(previousValue, currentMetric.format);
|
|
2825
|
+
const { dayName, previousDate } = getTooltipDateInfo(label);
|
|
2826
|
+
const metricUnit = currentMetric.unit || "";
|
|
2827
|
+
const isButtonDisabled = currentValue === 0;
|
|
2828
|
+
const safeLabel = escapeHtml(label);
|
|
2829
|
+
const safeDayName = escapeHtml(dayName);
|
|
2830
|
+
const safePreviousDate = escapeHtml(previousDate);
|
|
2831
|
+
const safeMetricUnit = escapeHtml(metricUnit);
|
|
2832
|
+
const variationSign = variation > 0 ? "+" : "";
|
|
2833
|
+
const variationIcon = variation >= 0 ? "▲" : "▼";
|
|
2834
|
+
const variationColor = variation >= 0 ? "var(--dashboard-status-success,#10B981)" : "var(--dashboard-status-danger,#EF4444)";
|
|
2835
|
+
if (tooltipConfig?.customContent) tooltipEl.innerHTML = tooltipConfig.customContent({
|
|
2836
|
+
value: currentValue,
|
|
2837
|
+
previousValue,
|
|
2838
|
+
variation,
|
|
2839
|
+
date: label,
|
|
2840
|
+
dayName,
|
|
2841
|
+
previousDate,
|
|
2842
|
+
formattedValue,
|
|
2843
|
+
formattedPrevious,
|
|
2844
|
+
metricUnit
|
|
2845
|
+
});
|
|
2846
|
+
else tooltipEl.innerHTML = `
|
|
2847
|
+
<div style="
|
|
2848
|
+
background: var(--dashboard-surface,#ffffff);
|
|
2849
|
+
border-radius: 8px;
|
|
2850
|
+
box-shadow: 0 8px 20px rgba(15, 23, 42, 0.14);
|
|
2851
|
+
border: 1px solid rgba(93, 114, 128, 0.2);
|
|
2852
|
+
color: var(--dashboard-text-primary,#2d2d2d);
|
|
2853
|
+
padding: 12px;
|
|
2854
|
+
min-width: 220px;
|
|
2855
|
+
max-width: 250px;
|
|
2856
|
+
font-family: inherit;
|
|
2857
|
+
">
|
|
2858
|
+
<div style="
|
|
2859
|
+
font-size: 11px;
|
|
2860
|
+
font-weight: 500;
|
|
2861
|
+
color: var(--dashboard-text-secondary,#6b7280);
|
|
2862
|
+
margin-bottom: 8px;
|
|
2863
|
+
">
|
|
2864
|
+
${safeDayName ? `${safeDayName} ` : ""}${safeLabel}
|
|
2865
|
+
</div>
|
|
2866
|
+
<div style="
|
|
2867
|
+
display: flex;
|
|
2868
|
+
align-items: baseline;
|
|
2869
|
+
gap: 6px;
|
|
2870
|
+
margin-bottom: 10px;
|
|
2871
|
+
">
|
|
2872
|
+
<div style="
|
|
2873
|
+
font-size: 22px;
|
|
2874
|
+
font-weight: 700;
|
|
2875
|
+
color: ${primaryColor};
|
|
2876
|
+
line-height: 1;
|
|
2877
|
+
">
|
|
2878
|
+
${escapeHtml(formattedValue)}${safeMetricUnit ? ` ${safeMetricUnit}` : ""}
|
|
2879
|
+
</div>
|
|
2880
|
+
<div style="
|
|
2881
|
+
display: flex;
|
|
2882
|
+
align-items: center;
|
|
2883
|
+
gap: 3px;
|
|
2884
|
+
color: ${variationColor};
|
|
2885
|
+
font-size: 13px;
|
|
2886
|
+
font-weight: 600;
|
|
2887
|
+
">
|
|
2888
|
+
<span style="font-size: 10px;">${variationIcon}</span>
|
|
2889
|
+
<span>${variationSign}${Math.abs(variation).toFixed(2)}%</span>
|
|
2890
|
+
</div>
|
|
2891
|
+
</div>
|
|
2892
|
+
<div style="
|
|
2893
|
+
font-size: 11px;
|
|
2894
|
+
color: var(--dashboard-text-secondary,#6b7280);
|
|
2895
|
+
line-height: 1.35;
|
|
2896
|
+
margin-bottom: ${tooltipConfig?.showButton ? "10px" : "0"};
|
|
2897
|
+
padding-bottom: ${tooltipConfig?.showButton ? "10px" : "0"};
|
|
2898
|
+
border-bottom: ${tooltipConfig?.showButton ? "1px solid rgba(93, 114, 128, 0.2)" : "none"};
|
|
2899
|
+
">
|
|
2900
|
+
em relacao aos <strong style="color: var(--dashboard-text-primary,#2d2d2d);">${escapeHtml(formattedPrevious)}${safeMetricUnit ? ` ${safeMetricUnit}` : ""}</strong>${safePreviousDate ? ` do dia <strong style="color: var(--dashboard-text-primary,#2d2d2d);">${safePreviousDate}</strong>` : ""}
|
|
2901
|
+
</div>
|
|
2902
|
+
${tooltipConfig?.showButton && tooltipConfig.buttonLabel ? `
|
|
2903
|
+
<button type="button" data-tooltip-action ${isButtonDisabled ? "disabled" : ""} style="
|
|
2904
|
+
width: 100%;
|
|
2905
|
+
padding: 8px 12px;
|
|
2906
|
+
background: ${isButtonDisabled ? "rgba(93, 114, 128, 0.08)" : "var(--dashboard-surface,#ffffff)"};
|
|
2907
|
+
color: ${isButtonDisabled ? "var(--dashboard-text-secondary,#6b7280)" : primaryColor};
|
|
2908
|
+
border: 2px solid ${isButtonDisabled ? "rgba(93, 114, 128, 0.2)" : primaryColor};
|
|
2909
|
+
border-radius: 6px;
|
|
2910
|
+
font-size: 13px;
|
|
2911
|
+
font-weight: 600;
|
|
2912
|
+
font-family: inherit;
|
|
2913
|
+
cursor: ${isButtonDisabled ? "not-allowed" : "pointer"};
|
|
2914
|
+
opacity: ${isButtonDisabled ? "0.65" : "1"};
|
|
2915
|
+
">
|
|
2916
|
+
${escapeHtml(tooltipConfig.buttonLabel)}
|
|
2917
|
+
</button>
|
|
2918
|
+
` : ""}
|
|
2919
|
+
</div>
|
|
2920
|
+
`;
|
|
2921
|
+
const actionButton = tooltipEl.querySelector("[data-tooltip-action]");
|
|
2922
|
+
if (actionButton && !isButtonDisabled) {
|
|
2923
|
+
actionButton.onclick = () => tooltipConfig?.onButtonClick?.(dataIndex, label);
|
|
2924
|
+
actionButton.onmouseenter = () => {
|
|
2925
|
+
actionButton.style.background = primaryColor;
|
|
2926
|
+
actionButton.style.color = "#ffffff";
|
|
2927
|
+
};
|
|
2928
|
+
actionButton.onmouseleave = () => {
|
|
2929
|
+
actionButton.style.background = "var(--dashboard-surface,#ffffff)";
|
|
2930
|
+
actionButton.style.color = primaryColor;
|
|
2931
|
+
};
|
|
2932
|
+
}
|
|
2933
|
+
const tooltipWidth = 250;
|
|
2934
|
+
const tooltipHeight = tooltipConfig?.showButton ? 180 : 140;
|
|
2935
|
+
const offsetX = 15;
|
|
2936
|
+
const centerY = Math.max(0, (chart.height - tooltipHeight) / 2);
|
|
2937
|
+
const isNearRightEdge = tooltip.caretX > chart.width - tooltipWidth - offsetX;
|
|
2938
|
+
tooltipEl.style.opacity = "1";
|
|
2939
|
+
tooltipEl.style.top = `${centerY}px`;
|
|
2940
|
+
if (isNearRightEdge) {
|
|
2941
|
+
tooltipEl.style.left = "auto";
|
|
2942
|
+
tooltipEl.style.right = `${chart.width - tooltip.caretX + offsetX}px`;
|
|
2943
|
+
} else {
|
|
2944
|
+
tooltipEl.style.left = `${tooltip.caretX + offsetX}px`;
|
|
2945
|
+
tooltipEl.style.right = "auto";
|
|
2946
|
+
}
|
|
2947
|
+
};
|
|
2123
2948
|
const data = {
|
|
2124
2949
|
labels: chartData.labels,
|
|
2125
2950
|
datasets: [{
|
|
@@ -2171,14 +2996,18 @@ function MetricPanel({ title, titleIcon: TitleIcon, metrics, chartData, color, s
|
|
|
2171
2996
|
color: "var(--dashboard-text-secondary, #6b7280)"
|
|
2172
2997
|
}
|
|
2173
2998
|
},
|
|
2174
|
-
tooltip: {
|
|
2999
|
+
tooltip: { ...tooltipConfig ? {
|
|
3000
|
+
enabled: false,
|
|
3001
|
+
position: "nearest",
|
|
3002
|
+
external: tooltipConfig.enabled ? renderExternalTooltip : void 0
|
|
3003
|
+
} : {
|
|
2175
3004
|
backgroundColor: "rgba(45, 45, 45, 0.95)",
|
|
2176
3005
|
titleColor: "#fff",
|
|
2177
3006
|
bodyColor: "#fff",
|
|
2178
3007
|
borderColor: primaryColor,
|
|
2179
3008
|
borderWidth: 1,
|
|
2180
3009
|
padding: 12
|
|
2181
|
-
}
|
|
3010
|
+
} }
|
|
2182
3011
|
},
|
|
2183
3012
|
scales: {
|
|
2184
3013
|
x: {
|
|
@@ -2205,7 +3034,7 @@ function MetricPanel({ title, titleIcon: TitleIcon, metrics, chartData, color, s
|
|
|
2205
3034
|
}
|
|
2206
3035
|
};
|
|
2207
3036
|
return /* @__PURE__ */ jsxs("div", {
|
|
2208
|
-
className: cn$
|
|
3037
|
+
className: cn$16("bg-[var(--dashboard-surface,#ffffff)] rounded-lg shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
|
|
2209
3038
|
style: { overflow: "visible" },
|
|
2210
3039
|
children: [
|
|
2211
3040
|
/* @__PURE__ */ jsxs("div", {
|
|
@@ -2246,7 +3075,7 @@ function MetricPanel({ title, titleIcon: TitleIcon, metrics, chartData, color, s
|
|
|
2246
3075
|
const Icon = metric.icon;
|
|
2247
3076
|
return /* @__PURE__ */ jsxs("button", {
|
|
2248
3077
|
onClick: () => setSelectedMetricKey(metric.key),
|
|
2249
|
-
className: cn$
|
|
3078
|
+
className: cn$16("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"),
|
|
2250
3079
|
style: selectedMetricKey === metric.key ? {
|
|
2251
3080
|
borderColor: primaryColor,
|
|
2252
3081
|
color: primaryColor
|
|
@@ -2294,10 +3123,10 @@ function MetricPanel({ title, titleIcon: TitleIcon, metrics, chartData, color, s
|
|
|
2294
3123
|
|
|
2295
3124
|
//#endregion
|
|
2296
3125
|
//#region src/components/FilterBar/index.tsx
|
|
2297
|
-
const cn$
|
|
3126
|
+
const cn$15 = (...classes) => classes.filter(Boolean).join(" ");
|
|
2298
3127
|
function FilterBar({ searchValue, onSearchChange, searchPlaceholder = "Buscar...", children, actions, className }) {
|
|
2299
3128
|
return /* @__PURE__ */ jsxs("div", {
|
|
2300
|
-
className: cn$
|
|
3129
|
+
className: cn$15("flex flex-col gap-3 sm:flex-row sm:items-center sm:flex-wrap", className),
|
|
2301
3130
|
children: [
|
|
2302
3131
|
onSearchChange !== void 0 && /* @__PURE__ */ jsx("div", {
|
|
2303
3132
|
className: "flex-1 min-w-[200px]",
|
|
@@ -2337,7 +3166,7 @@ function FilterBar({ searchValue, onSearchChange, searchPlaceholder = "Buscar...
|
|
|
2337
3166
|
|
|
2338
3167
|
//#endregion
|
|
2339
3168
|
//#region src/components/Checkbox/index.tsx
|
|
2340
|
-
const cn$
|
|
3169
|
+
const cn$14 = (...classes) => classes.filter(Boolean).join(" ");
|
|
2341
3170
|
const sizeConfig = {
|
|
2342
3171
|
sm: {
|
|
2343
3172
|
box: 16,
|
|
@@ -2385,7 +3214,7 @@ function Checkbox({ name, id, label, checked = false, onChange, disabled = false
|
|
|
2385
3214
|
const resolvedColor = primaryColor || "var(--dashboard-primary, #37A501)";
|
|
2386
3215
|
return /* @__PURE__ */ jsxs("label", {
|
|
2387
3216
|
htmlFor: inputId,
|
|
2388
|
-
className: cn$
|
|
3217
|
+
className: cn$14("inline-flex items-center cursor-pointer select-none", disabled && "opacity-50 cursor-not-allowed", className),
|
|
2389
3218
|
style: { gap: cfg.gap },
|
|
2390
3219
|
children: [
|
|
2391
3220
|
/* @__PURE__ */ jsx("input", {
|
|
@@ -2436,7 +3265,7 @@ function Checkbox({ name, id, label, checked = false, onChange, disabled = false
|
|
|
2436
3265
|
|
|
2437
3266
|
//#endregion
|
|
2438
3267
|
//#region src/components/AuthLayout/index.tsx
|
|
2439
|
-
const cn$
|
|
3268
|
+
const cn$13 = (...classes) => classes.filter(Boolean).join(" ");
|
|
2440
3269
|
/** Resolves a CSS color value (including var() references) to a computed hex/rgb string */
|
|
2441
3270
|
function useResolvedColor(cssValue) {
|
|
2442
3271
|
const [resolved, setResolved] = useState(cssValue);
|
|
@@ -2603,7 +3432,7 @@ function AuthLayout({ logo, title, subtitle, error, success, fields, values, onF
|
|
|
2603
3432
|
if (link.onClick) return /* @__PURE__ */ jsx("button", {
|
|
2604
3433
|
type: "button",
|
|
2605
3434
|
onClick: link.onClick,
|
|
2606
|
-
className: cn$
|
|
3435
|
+
className: cn$13("bg-transparent border-none cursor-pointer hover:opacity-80 text-sm font-semibold p-0 transition-colors", extraClass),
|
|
2607
3436
|
style,
|
|
2608
3437
|
children: link.label
|
|
2609
3438
|
});
|
|
@@ -2611,13 +3440,13 @@ function AuthLayout({ logo, title, subtitle, error, success, fields, values, onF
|
|
|
2611
3440
|
href: link.href,
|
|
2612
3441
|
target: link.target,
|
|
2613
3442
|
rel: link.target === "_blank" ? "noopener noreferrer" : void 0,
|
|
2614
|
-
className: cn$
|
|
3443
|
+
className: cn$13("hover:opacity-80 text-sm font-semibold transition-colors", extraClass),
|
|
2615
3444
|
style,
|
|
2616
3445
|
children: link.label
|
|
2617
3446
|
});
|
|
2618
3447
|
}
|
|
2619
3448
|
return /* @__PURE__ */ jsxs("div", {
|
|
2620
|
-
className: cn$
|
|
3449
|
+
className: cn$13("fixed inset-0 flex select-none overflow-hidden", className),
|
|
2621
3450
|
style: bgCss,
|
|
2622
3451
|
children: [
|
|
2623
3452
|
branding && branding.logos.length > 0 && /* @__PURE__ */ jsx("div", {
|
|
@@ -2900,7 +3729,7 @@ function CodeInput({ length = 6, value, onChange, disabled = false, error = fals
|
|
|
2900
3729
|
|
|
2901
3730
|
//#endregion
|
|
2902
3731
|
//#region src/components/Skeleton/index.tsx
|
|
2903
|
-
const cn$
|
|
3732
|
+
const cn$12 = (...classes) => classes.filter(Boolean).join(" ");
|
|
2904
3733
|
function Skeleton({ variant = "text", width, height, animate = true, className, lines = 1 }) {
|
|
2905
3734
|
const baseStyles = "bg-[var(--dashboard-text-secondary,#6b7280)]/10 relative overflow-hidden";
|
|
2906
3735
|
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-['']" : "";
|
|
@@ -2919,9 +3748,9 @@ function Skeleton({ variant = "text", width, height, animate = true, className,
|
|
|
2919
3748
|
}
|
|
2920
3749
|
if (variant === "card" && !height) style.height = "120px";
|
|
2921
3750
|
if (variant === "text" && lines > 1) return /* @__PURE__ */ jsx("div", {
|
|
2922
|
-
className: cn$
|
|
3751
|
+
className: cn$12("flex flex-col gap-2", className),
|
|
2923
3752
|
children: Array.from({ length: lines }).map((_, i) => /* @__PURE__ */ jsx("div", {
|
|
2924
|
-
className: cn$
|
|
3753
|
+
className: cn$12(baseStyles, shimmerStyles, variantStyles.text),
|
|
2925
3754
|
style: {
|
|
2926
3755
|
...style,
|
|
2927
3756
|
width: i === lines - 1 ? "75%" : style.width || "100%"
|
|
@@ -2929,14 +3758,14 @@ function Skeleton({ variant = "text", width, height, animate = true, className,
|
|
|
2929
3758
|
}, i))
|
|
2930
3759
|
});
|
|
2931
3760
|
return /* @__PURE__ */ jsx("div", {
|
|
2932
|
-
className: cn$
|
|
3761
|
+
className: cn$12(baseStyles, shimmerStyles, variantStyles[variant], className),
|
|
2933
3762
|
style
|
|
2934
3763
|
});
|
|
2935
3764
|
}
|
|
2936
3765
|
|
|
2937
3766
|
//#endregion
|
|
2938
3767
|
//#region src/components/DataGrid/index.tsx
|
|
2939
|
-
const cn$
|
|
3768
|
+
const cn$11 = (...classes) => classes.filter(Boolean).join(" ");
|
|
2940
3769
|
function SortIcon({ sorted }) {
|
|
2941
3770
|
if (sorted === "asc") return /* @__PURE__ */ jsx(ArrowUp, { className: "h-3.5 w-3.5" });
|
|
2942
3771
|
if (sorted === "desc") return /* @__PURE__ */ jsx(ArrowDown, { className: "h-3.5 w-3.5" });
|
|
@@ -2991,7 +3820,7 @@ function VirtualRows({ table, rowHeight, onRowClick, compact }) {
|
|
|
2991
3820
|
className: "bg-[var(--dashboard-text-secondary,#6b7280)]/5 sticky top-0 z-10",
|
|
2992
3821
|
children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx("tr", { children: headerGroup.headers.map((header) => /* @__PURE__ */ jsx("th", {
|
|
2993
3822
|
scope: "col",
|
|
2994
|
-
className: cn$
|
|
3823
|
+
className: cn$11("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"),
|
|
2995
3824
|
style: { width: header.getSize() },
|
|
2996
3825
|
onClick: header.column.getToggleSortingHandler(),
|
|
2997
3826
|
children: /* @__PURE__ */ jsxs("div", {
|
|
@@ -3006,10 +3835,10 @@ function VirtualRows({ table, rowHeight, onRowClick, compact }) {
|
|
|
3006
3835
|
}),
|
|
3007
3836
|
visibleRows.map((row) => /* @__PURE__ */ jsx("tr", {
|
|
3008
3837
|
onClick: () => onRowClick?.(row.original),
|
|
3009
|
-
className: cn$
|
|
3838
|
+
className: cn$11("hover:bg-[var(--dashboard-text-secondary,#6b7280)]/5 transition-colors", onRowClick && "cursor-pointer", row.getIsSelected() && "bg-[var(--dashboard-primary,#37a501)]/5"),
|
|
3010
3839
|
style: { height: rowHeight },
|
|
3011
3840
|
children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx("td", {
|
|
3012
|
-
className: cn$
|
|
3841
|
+
className: cn$11(cellPadding, "text-sm whitespace-nowrap"),
|
|
3013
3842
|
children: flexRender(cell.column.columnDef.cell, cell.getContext())
|
|
3014
3843
|
}, cell.id))
|
|
3015
3844
|
}, row.id)),
|
|
@@ -3088,7 +3917,7 @@ function DataGrid({ columns, data, isLoading = false, skeletonRows = 5, sorting:
|
|
|
3088
3917
|
const cellPadding = compact ? "px-4 py-2" : "px-6 py-4";
|
|
3089
3918
|
const headerPadding = compact ? "px-4 py-2" : "px-6 py-3";
|
|
3090
3919
|
if (enableVirtualization) return /* @__PURE__ */ jsx("div", {
|
|
3091
|
-
className: cn$
|
|
3920
|
+
className: cn$11("overflow-hidden rounded-lg bg-[var(--dashboard-surface,#ffffff)] shadow-sm", bordered && "border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
|
|
3092
3921
|
children: /* @__PURE__ */ jsx(VirtualRows, {
|
|
3093
3922
|
table,
|
|
3094
3923
|
rowHeight,
|
|
@@ -3097,16 +3926,16 @@ function DataGrid({ columns, data, isLoading = false, skeletonRows = 5, sorting:
|
|
|
3097
3926
|
})
|
|
3098
3927
|
});
|
|
3099
3928
|
return /* @__PURE__ */ jsxs("div", {
|
|
3100
|
-
className: cn$
|
|
3929
|
+
className: cn$11("overflow-hidden rounded-lg bg-[var(--dashboard-surface,#ffffff)] shadow-sm", bordered && "border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
|
|
3101
3930
|
children: [/* @__PURE__ */ jsx("div", {
|
|
3102
3931
|
className: "overflow-x-auto",
|
|
3103
3932
|
children: /* @__PURE__ */ jsxs("table", {
|
|
3104
3933
|
className: "min-w-full divide-y divide-[var(--dashboard-text-secondary,#6b7280)]/20",
|
|
3105
3934
|
children: [/* @__PURE__ */ jsx("thead", {
|
|
3106
|
-
className: cn$
|
|
3935
|
+
className: cn$11("bg-[var(--dashboard-text-secondary,#6b7280)]/5", stickyHeader && "sticky top-0 z-10"),
|
|
3107
3936
|
children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx("tr", { children: headerGroup.headers.map((header) => /* @__PURE__ */ jsx("th", {
|
|
3108
3937
|
scope: "col",
|
|
3109
|
-
className: cn$
|
|
3938
|
+
className: cn$11("text-left text-xs font-semibold text-[var(--dashboard-text-secondary,#6b7280)] uppercase tracking-wider", headerPadding, header.column.getCanSort() && "cursor-pointer select-none"),
|
|
3110
3939
|
style: header.getSize() !== 150 ? { width: header.getSize() } : void 0,
|
|
3111
3940
|
onClick: header.column.getToggleSortingHandler(),
|
|
3112
3941
|
children: /* @__PURE__ */ jsxs("div", {
|
|
@@ -3143,9 +3972,9 @@ function DataGrid({ columns, data, isLoading = false, skeletonRows = 5, sorting:
|
|
|
3143
3972
|
})
|
|
3144
3973
|
}) }) : table.getRowModel().rows.map((row, rowIndex) => /* @__PURE__ */ jsx("tr", {
|
|
3145
3974
|
onClick: () => onRowClick?.(row.original),
|
|
3146
|
-
className: cn$
|
|
3975
|
+
className: cn$11("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"),
|
|
3147
3976
|
children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx("td", {
|
|
3148
|
-
className: cn$
|
|
3977
|
+
className: cn$11(cellPadding, "text-sm text-[var(--dashboard-text-primary,#2d2d2d)]"),
|
|
3149
3978
|
children: flexRender(cell.column.columnDef.cell, cell.getContext())
|
|
3150
3979
|
}, cell.id))
|
|
3151
3980
|
}, row.id))
|
|
@@ -3206,7 +4035,7 @@ function DataGrid({ columns, data, isLoading = false, skeletonRows = 5, sorting:
|
|
|
3206
4035
|
|
|
3207
4036
|
//#endregion
|
|
3208
4037
|
//#region src/components/TreeView/index.tsx
|
|
3209
|
-
const cn$
|
|
4038
|
+
const cn$10 = (...classes) => classes.filter(Boolean).join(" ");
|
|
3210
4039
|
function TreeItem({ node, level, expanded, selectedId, draggable, indentSize, onSelect, onToggle, onMove, renderNode, dragState, setDragState }) {
|
|
3211
4040
|
const hasChildren = node.children && node.children.length > 0;
|
|
3212
4041
|
const isExpanded = expanded.has(node.id);
|
|
@@ -3271,7 +4100,7 @@ function TreeItem({ node, level, expanded, selectedId, draggable, indentSize, on
|
|
|
3271
4100
|
"aria-expanded": hasChildren ? isExpanded : void 0,
|
|
3272
4101
|
"aria-selected": isSelected,
|
|
3273
4102
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
3274
|
-
className: cn$
|
|
4103
|
+
className: cn$10("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"),
|
|
3275
4104
|
style: { paddingLeft: `${level * indentSize + 4}px` },
|
|
3276
4105
|
draggable: draggable && !node.disabled,
|
|
3277
4106
|
onDragStart: handleDragStart,
|
|
@@ -3289,10 +4118,10 @@ function TreeItem({ node, level, expanded, selectedId, draggable, indentSize, on
|
|
|
3289
4118
|
/* @__PURE__ */ jsx("button", {
|
|
3290
4119
|
type: "button",
|
|
3291
4120
|
onClick: () => hasChildren && onToggle(node.id),
|
|
3292
|
-
className: cn$
|
|
4121
|
+
className: cn$10("flex-shrink-0 w-5 h-5 flex items-center justify-center rounded transition-transform", hasChildren ? "cursor-pointer" : "invisible"),
|
|
3293
4122
|
tabIndex: hasChildren ? 0 : -1,
|
|
3294
4123
|
"aria-label": isExpanded ? "Recolher" : "Expandir",
|
|
3295
|
-
children: /* @__PURE__ */ jsx(ChevronRight, { className: cn$
|
|
4124
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { className: cn$10("h-3.5 w-3.5 transition-transform duration-150", isExpanded && "rotate-90") })
|
|
3296
4125
|
}),
|
|
3297
4126
|
renderNode ? /* @__PURE__ */ jsx("div", {
|
|
3298
4127
|
className: "flex-1 min-w-0 cursor-pointer",
|
|
@@ -3304,7 +4133,7 @@ function TreeItem({ node, level, expanded, selectedId, draggable, indentSize, on
|
|
|
3304
4133
|
children: node.icon
|
|
3305
4134
|
}),
|
|
3306
4135
|
/* @__PURE__ */ jsx("span", {
|
|
3307
|
-
className: cn$
|
|
4136
|
+
className: cn$10("flex-1 min-w-0 text-sm truncate", !node.disabled && "cursor-pointer"),
|
|
3308
4137
|
onClick: () => !node.disabled && onSelect?.(node),
|
|
3309
4138
|
children: node.label
|
|
3310
4139
|
}),
|
|
@@ -3357,7 +4186,7 @@ function TreeView({ nodes, onSelect, onExpand, onMove, renderNode, selectedId, d
|
|
|
3357
4186
|
}, [onExpand]);
|
|
3358
4187
|
return /* @__PURE__ */ jsx("ul", {
|
|
3359
4188
|
role: "tree",
|
|
3360
|
-
className: cn$
|
|
4189
|
+
className: cn$10("select-none", className),
|
|
3361
4190
|
children: nodes.map((node) => /* @__PURE__ */ jsx(TreeItem, {
|
|
3362
4191
|
node,
|
|
3363
4192
|
level: 0,
|
|
@@ -3377,7 +4206,7 @@ function TreeView({ nodes, onSelect, onExpand, onMove, renderNode, selectedId, d
|
|
|
3377
4206
|
|
|
3378
4207
|
//#endregion
|
|
3379
4208
|
//#region src/components/Stepper/index.tsx
|
|
3380
|
-
const cn$
|
|
4209
|
+
const cn$9 = (...classes) => classes.filter(Boolean).join(" ");
|
|
3381
4210
|
function StepIcon({ step, index }) {
|
|
3382
4211
|
const status = step.status || "pending";
|
|
3383
4212
|
if (status === "completed") return /* @__PURE__ */ jsx("div", {
|
|
@@ -3421,17 +4250,17 @@ function Stepper({ steps, activeStep, onStepChange, orientation = "horizontal",
|
|
|
3421
4250
|
type: "button",
|
|
3422
4251
|
onClick: () => onStepChange?.(index),
|
|
3423
4252
|
disabled: !onStepChange,
|
|
3424
|
-
className: cn$
|
|
4253
|
+
className: cn$9("relative z-10", onStepChange && "cursor-pointer", !onStepChange && "cursor-default"),
|
|
3425
4254
|
"aria-current": step.status === "active" ? "step" : void 0,
|
|
3426
4255
|
children: /* @__PURE__ */ jsx(StepIcon, {
|
|
3427
4256
|
step,
|
|
3428
4257
|
index
|
|
3429
4258
|
})
|
|
3430
|
-
}), index < resolvedSteps.length - 1 && /* @__PURE__ */ jsx("div", { className: cn$
|
|
4259
|
+
}), index < resolvedSteps.length - 1 && /* @__PURE__ */ jsx("div", { className: cn$9("w-0.5 flex-1 min-h-[32px]", step.status === "completed" ? "bg-[var(--dashboard-primary,#37a501)]" : "bg-[var(--dashboard-text-secondary,#6b7280)]/20") })]
|
|
3431
4260
|
}), /* @__PURE__ */ jsxs("div", {
|
|
3432
|
-
className: cn$
|
|
4261
|
+
className: cn$9("pb-6", index === resolvedSteps.length - 1 && "pb-0"),
|
|
3433
4262
|
children: [/* @__PURE__ */ jsx("p", {
|
|
3434
|
-
className: cn$
|
|
4263
|
+
className: cn$9("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)]"),
|
|
3435
4264
|
children: step.label
|
|
3436
4265
|
}), step.description && /* @__PURE__ */ jsx("p", {
|
|
3437
4266
|
className: "text-xs text-[var(--dashboard-text-secondary,#6b7280)] mt-0.5",
|
|
@@ -3447,12 +4276,12 @@ function Stepper({ steps, activeStep, onStepChange, orientation = "horizontal",
|
|
|
3447
4276
|
children: /* @__PURE__ */ jsx("ol", {
|
|
3448
4277
|
className: "flex items-center",
|
|
3449
4278
|
children: resolvedSteps.map((step, index) => /* @__PURE__ */ jsxs("li", {
|
|
3450
|
-
className: cn$
|
|
4279
|
+
className: cn$9("flex items-center", index < resolvedSteps.length - 1 && "flex-1"),
|
|
3451
4280
|
children: [/* @__PURE__ */ jsxs("button", {
|
|
3452
4281
|
type: "button",
|
|
3453
4282
|
onClick: () => onStepChange?.(index),
|
|
3454
4283
|
disabled: !onStepChange,
|
|
3455
|
-
className: cn$
|
|
4284
|
+
className: cn$9("flex items-center gap-2 group", onStepChange && "cursor-pointer", !onStepChange && "cursor-default"),
|
|
3456
4285
|
"aria-current": step.status === "active" ? "step" : void 0,
|
|
3457
4286
|
children: [/* @__PURE__ */ jsx(StepIcon, {
|
|
3458
4287
|
step,
|
|
@@ -3460,14 +4289,14 @@ function Stepper({ steps, activeStep, onStepChange, orientation = "horizontal",
|
|
|
3460
4289
|
}), /* @__PURE__ */ jsxs("div", {
|
|
3461
4290
|
className: "hidden sm:block text-left",
|
|
3462
4291
|
children: [/* @__PURE__ */ jsx("p", {
|
|
3463
|
-
className: cn$
|
|
4292
|
+
className: cn$9("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)]"),
|
|
3464
4293
|
children: step.label
|
|
3465
4294
|
}), step.description && /* @__PURE__ */ jsx("p", {
|
|
3466
4295
|
className: "text-xs text-[var(--dashboard-text-secondary,#6b7280)] whitespace-nowrap",
|
|
3467
4296
|
children: step.description
|
|
3468
4297
|
})]
|
|
3469
4298
|
})]
|
|
3470
|
-
}), index < resolvedSteps.length - 1 && /* @__PURE__ */ jsx("div", { className: cn$
|
|
4299
|
+
}), index < resolvedSteps.length - 1 && /* @__PURE__ */ jsx("div", { className: cn$9("flex-1 h-0.5 mx-3", step.status === "completed" ? "bg-[var(--dashboard-primary,#37a501)]" : "bg-[var(--dashboard-text-secondary,#6b7280)]/20") })]
|
|
3471
4300
|
}, step.id))
|
|
3472
4301
|
})
|
|
3473
4302
|
});
|
|
@@ -3475,7 +4304,7 @@ function Stepper({ steps, activeStep, onStepChange, orientation = "horizontal",
|
|
|
3475
4304
|
|
|
3476
4305
|
//#endregion
|
|
3477
4306
|
//#region src/components/FileUpload/index.tsx
|
|
3478
|
-
const cn$
|
|
4307
|
+
const cn$8 = (...classes) => classes.filter(Boolean).join(" ");
|
|
3479
4308
|
function formatSize(bytes) {
|
|
3480
4309
|
if (bytes < 1024) return `${bytes} B`;
|
|
3481
4310
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
@@ -3571,7 +4400,7 @@ function FileUpload({ accept, maxSize, multiple = false, onUpload, onRemove, pre
|
|
|
3571
4400
|
onDragOver: handleDragOver,
|
|
3572
4401
|
onDragLeave: handleDragLeave,
|
|
3573
4402
|
onClick: () => !disabled && inputRef.current?.click(),
|
|
3574
|
-
className: cn$
|
|
4403
|
+
className: cn$8("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"),
|
|
3575
4404
|
role: "button",
|
|
3576
4405
|
tabIndex: disabled ? -1 : 0,
|
|
3577
4406
|
"aria-label": label,
|
|
@@ -3594,7 +4423,7 @@ function FileUpload({ accept, maxSize, multiple = false, onUpload, onRemove, pre
|
|
|
3594
4423
|
}), /* @__PURE__ */ jsxs("div", {
|
|
3595
4424
|
className: "flex flex-col items-center text-center",
|
|
3596
4425
|
children: [
|
|
3597
|
-
icon || /* @__PURE__ */ jsx(Upload, { className: cn$
|
|
4426
|
+
icon || /* @__PURE__ */ jsx(Upload, { className: cn$8("h-8 w-8 mb-3", isDragging ? "text-[var(--dashboard-primary,#37a501)]" : "text-[var(--dashboard-text-secondary,#6b7280)]") }),
|
|
3598
4427
|
/* @__PURE__ */ jsx("p", {
|
|
3599
4428
|
className: "text-sm font-medium text-[var(--dashboard-text-primary,#2d2d2d)]",
|
|
3600
4429
|
children: label
|
|
@@ -3661,16 +4490,18 @@ function FileUpload({ accept, maxSize, multiple = false, onUpload, onRemove, pre
|
|
|
3661
4490
|
|
|
3662
4491
|
//#endregion
|
|
3663
4492
|
//#region src/components/Tooltip/index.tsx
|
|
3664
|
-
const cn$
|
|
4493
|
+
const cn$7 = (...classes) => classes.filter(Boolean).join(" ");
|
|
3665
4494
|
function Tooltip({ content, position = "top", delay = 200, children, className, maxWidth = 240 }) {
|
|
3666
4495
|
const [visible, setVisible] = useState(false);
|
|
4496
|
+
const [positioned, setPositioned] = useState(false);
|
|
3667
4497
|
const [coords, setCoords] = useState({
|
|
3668
4498
|
top: 0,
|
|
3669
4499
|
left: 0
|
|
3670
4500
|
});
|
|
4501
|
+
const [actualPosition, setActualPosition] = useState(position);
|
|
3671
4502
|
const triggerRef = useRef(null);
|
|
3672
4503
|
const tooltipRef = useRef(null);
|
|
3673
|
-
const timeoutRef = useRef();
|
|
4504
|
+
const timeoutRef = useRef(null);
|
|
3674
4505
|
const idRef = useRef(`tooltip-${Math.random().toString(36).slice(2, 9)}`);
|
|
3675
4506
|
const calculatePosition = useCallback(() => {
|
|
3676
4507
|
if (!triggerRef.current || !tooltipRef.current) return;
|
|
@@ -3679,6 +4510,7 @@ function Tooltip({ content, position = "top", delay = 200, children, className,
|
|
|
3679
4510
|
const gap = 8;
|
|
3680
4511
|
let top = 0;
|
|
3681
4512
|
let left = 0;
|
|
4513
|
+
let resolvedPosition = position;
|
|
3682
4514
|
switch (position) {
|
|
3683
4515
|
case "top":
|
|
3684
4516
|
top = trigger.top - tooltip.height - gap;
|
|
@@ -3697,31 +4529,65 @@ function Tooltip({ content, position = "top", delay = 200, children, className,
|
|
|
3697
4529
|
left = trigger.right + gap;
|
|
3698
4530
|
break;
|
|
3699
4531
|
}
|
|
4532
|
+
if (position === "top" && top < 8) {
|
|
4533
|
+
top = trigger.bottom + gap;
|
|
4534
|
+
resolvedPosition = "bottom";
|
|
4535
|
+
} else if (position === "bottom" && top + tooltip.height > window.innerHeight - 8) {
|
|
4536
|
+
top = trigger.top - tooltip.height - gap;
|
|
4537
|
+
resolvedPosition = "top";
|
|
4538
|
+
}
|
|
3700
4539
|
left = Math.max(8, Math.min(left, window.innerWidth - tooltip.width - 8));
|
|
3701
4540
|
top = Math.max(8, Math.min(top, window.innerHeight - tooltip.height - 8));
|
|
3702
4541
|
setCoords({
|
|
3703
4542
|
top,
|
|
3704
4543
|
left
|
|
3705
4544
|
});
|
|
4545
|
+
setActualPosition(resolvedPosition);
|
|
4546
|
+
setPositioned(true);
|
|
3706
4547
|
}, [position]);
|
|
3707
4548
|
const show = useCallback(() => {
|
|
3708
4549
|
timeoutRef.current = setTimeout(() => {
|
|
3709
4550
|
setVisible(true);
|
|
4551
|
+
setPositioned(false);
|
|
3710
4552
|
}, delay);
|
|
3711
4553
|
}, [delay]);
|
|
3712
4554
|
const hide = useCallback(() => {
|
|
3713
4555
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
3714
4556
|
setVisible(false);
|
|
4557
|
+
setPositioned(false);
|
|
3715
4558
|
}, []);
|
|
3716
4559
|
useEffect(() => {
|
|
3717
|
-
if (visible) requestAnimationFrame(
|
|
4560
|
+
if (visible) requestAnimationFrame(() => {
|
|
4561
|
+
requestAnimationFrame(calculatePosition);
|
|
4562
|
+
});
|
|
3718
4563
|
}, [visible, calculatePosition]);
|
|
3719
4564
|
useEffect(() => {
|
|
3720
4565
|
return () => {
|
|
3721
4566
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
3722
4567
|
};
|
|
3723
4568
|
}, []);
|
|
3724
|
-
|
|
4569
|
+
let trigger;
|
|
4570
|
+
if (isValidElement(children)) trigger = cloneElement(children, {
|
|
4571
|
+
ref: triggerRef,
|
|
4572
|
+
onMouseEnter: (e) => {
|
|
4573
|
+
show();
|
|
4574
|
+
children.props?.onMouseEnter?.(e);
|
|
4575
|
+
},
|
|
4576
|
+
onMouseLeave: (e) => {
|
|
4577
|
+
hide();
|
|
4578
|
+
children.props?.onMouseLeave?.(e);
|
|
4579
|
+
},
|
|
4580
|
+
onFocus: (e) => {
|
|
4581
|
+
show();
|
|
4582
|
+
children.props?.onFocus?.(e);
|
|
4583
|
+
},
|
|
4584
|
+
onBlur: (e) => {
|
|
4585
|
+
hide();
|
|
4586
|
+
children.props?.onBlur?.(e);
|
|
4587
|
+
},
|
|
4588
|
+
"aria-describedby": visible ? idRef.current : void 0
|
|
4589
|
+
});
|
|
4590
|
+
else trigger = /* @__PURE__ */ jsx("span", {
|
|
3725
4591
|
ref: triggerRef,
|
|
3726
4592
|
onMouseEnter: show,
|
|
3727
4593
|
onMouseLeave: hide,
|
|
@@ -3730,23 +4596,88 @@ function Tooltip({ content, position = "top", delay = 200, children, className,
|
|
|
3730
4596
|
"aria-describedby": visible ? idRef.current : void 0,
|
|
3731
4597
|
className: "inline-flex",
|
|
3732
4598
|
children
|
|
3733
|
-
})
|
|
4599
|
+
});
|
|
4600
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [trigger, visible && typeof document !== "undefined" && createPortal(/* @__PURE__ */ jsxs("div", {
|
|
3734
4601
|
ref: tooltipRef,
|
|
3735
4602
|
id: idRef.current,
|
|
3736
4603
|
role: "tooltip",
|
|
3737
|
-
className: cn$
|
|
4604
|
+
className: cn$7("fixed z-[10002] rounded-md px-3 py-2 text-xs font-medium", "bg-[var(--dashboard-tooltip-bg,#1a1a1a)] text-[var(--dashboard-tooltip-text,#ffffff)]", "shadow-lg pointer-events-none", positioned && "dashboard-animate-fade-in", className),
|
|
3738
4605
|
style: {
|
|
3739
4606
|
top: coords.top,
|
|
3740
4607
|
left: coords.left,
|
|
3741
|
-
maxWidth
|
|
4608
|
+
maxWidth,
|
|
4609
|
+
opacity: positioned ? 1 : 0
|
|
3742
4610
|
},
|
|
3743
|
-
children: content
|
|
4611
|
+
children: [content, /* @__PURE__ */ jsx("span", { className: cn$7("absolute w-0 h-0 border-[5px]", {
|
|
4612
|
+
top: "left-1/2 -translate-x-1/2 top-full border-t-[var(--dashboard-tooltip-bg,#1a1a1a)] border-x-transparent border-b-transparent",
|
|
4613
|
+
bottom: "left-1/2 -translate-x-1/2 bottom-full border-b-[var(--dashboard-tooltip-bg,#1a1a1a)] border-x-transparent border-t-transparent",
|
|
4614
|
+
left: "top-1/2 -translate-y-1/2 left-full border-l-[var(--dashboard-tooltip-bg,#1a1a1a)] border-y-transparent border-r-transparent",
|
|
4615
|
+
right: "top-1/2 -translate-y-1/2 right-full border-r-[var(--dashboard-tooltip-bg,#1a1a1a)] border-y-transparent border-l-transparent"
|
|
4616
|
+
}[actualPosition]) })]
|
|
3744
4617
|
}), document.body)] });
|
|
3745
4618
|
}
|
|
3746
4619
|
|
|
4620
|
+
//#endregion
|
|
4621
|
+
//#region src/components/InfoTooltip/index.tsx
|
|
4622
|
+
function InfoTooltip({ content, term, size = 14, position = "top", maxWidth = 280, className }) {
|
|
4623
|
+
return /* @__PURE__ */ jsx(Tooltip, {
|
|
4624
|
+
content: term ? /* @__PURE__ */ jsxs("span", {
|
|
4625
|
+
className: "text-xs leading-relaxed",
|
|
4626
|
+
children: [
|
|
4627
|
+
/* @__PURE__ */ jsx("strong", { children: term }),
|
|
4628
|
+
" — ",
|
|
4629
|
+
content
|
|
4630
|
+
]
|
|
4631
|
+
}) : /* @__PURE__ */ jsx("span", {
|
|
4632
|
+
className: "text-xs leading-relaxed",
|
|
4633
|
+
children: content
|
|
4634
|
+
}),
|
|
4635
|
+
position,
|
|
4636
|
+
maxWidth,
|
|
4637
|
+
children: /* @__PURE__ */ jsx("button", {
|
|
4638
|
+
type: "button",
|
|
4639
|
+
tabIndex: 0,
|
|
4640
|
+
"aria-label": term ? `Informação sobre ${term}` : "Mais informações",
|
|
4641
|
+
className: [
|
|
4642
|
+
"inline-flex items-center justify-center rounded-full",
|
|
4643
|
+
"text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
4644
|
+
"hover:text-[var(--dashboard-text-primary,#2d2d2d)]",
|
|
4645
|
+
"hover:bg-[var(--dashboard-text-secondary,#6b7280)]/10",
|
|
4646
|
+
"transition-colors duration-150 cursor-help",
|
|
4647
|
+
"focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--dashboard-primary,#2563EB)]/40",
|
|
4648
|
+
className
|
|
4649
|
+
].filter(Boolean).join(" "),
|
|
4650
|
+
style: {
|
|
4651
|
+
width: size + 6,
|
|
4652
|
+
height: size + 6
|
|
4653
|
+
},
|
|
4654
|
+
children: /* @__PURE__ */ jsxs("svg", {
|
|
4655
|
+
width: size,
|
|
4656
|
+
height: size,
|
|
4657
|
+
viewBox: "0 0 24 24",
|
|
4658
|
+
fill: "none",
|
|
4659
|
+
stroke: "currentColor",
|
|
4660
|
+
strokeWidth: "2",
|
|
4661
|
+
strokeLinecap: "round",
|
|
4662
|
+
strokeLinejoin: "round",
|
|
4663
|
+
"aria-hidden": "true",
|
|
4664
|
+
children: [
|
|
4665
|
+
/* @__PURE__ */ jsx("circle", {
|
|
4666
|
+
cx: "12",
|
|
4667
|
+
cy: "12",
|
|
4668
|
+
r: "10"
|
|
4669
|
+
}),
|
|
4670
|
+
/* @__PURE__ */ jsx("path", { d: "M12 16v-4" }),
|
|
4671
|
+
/* @__PURE__ */ jsx("path", { d: "M12 8h.01" })
|
|
4672
|
+
]
|
|
4673
|
+
})
|
|
4674
|
+
})
|
|
4675
|
+
});
|
|
4676
|
+
}
|
|
4677
|
+
|
|
3747
4678
|
//#endregion
|
|
3748
4679
|
//#region src/components/Breadcrumb/index.tsx
|
|
3749
|
-
const cn$
|
|
4680
|
+
const cn$6 = (...classes) => classes.filter(Boolean).join(" ");
|
|
3750
4681
|
function Breadcrumb({ items, separator, onNavigate, className }) {
|
|
3751
4682
|
const defaultSeparator = /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4 text-[var(--dashboard-text-secondary,#6b7280)] flex-shrink-0" });
|
|
3752
4683
|
const handleClick = (e, href) => {
|
|
@@ -3768,7 +4699,7 @@ function Breadcrumb({ items, separator, onNavigate, className }) {
|
|
|
3768
4699
|
"aria-hidden": "true",
|
|
3769
4700
|
children: separator || defaultSeparator
|
|
3770
4701
|
}), isLast ? /* @__PURE__ */ jsxs("span", {
|
|
3771
|
-
className: cn$
|
|
4702
|
+
className: cn$6("flex items-center gap-1.5 text-sm font-medium", "text-[var(--dashboard-text-primary,#2d2d2d)]"),
|
|
3772
4703
|
"aria-current": "page",
|
|
3773
4704
|
children: [item.icon && /* @__PURE__ */ jsx("span", {
|
|
3774
4705
|
className: "flex-shrink-0 h-4 w-4",
|
|
@@ -3777,7 +4708,7 @@ function Breadcrumb({ items, separator, onNavigate, className }) {
|
|
|
3777
4708
|
}) : /* @__PURE__ */ jsxs("a", {
|
|
3778
4709
|
href: item.href || "#",
|
|
3779
4710
|
onClick: (e) => handleClick(e, item.href),
|
|
3780
|
-
className: cn$
|
|
4711
|
+
className: cn$6("flex items-center gap-1.5 text-sm", "text-[var(--dashboard-text-secondary,#6b7280)]", "hover:text-[var(--dashboard-primary,#37a501)] transition-colors"),
|
|
3781
4712
|
children: [item.icon && /* @__PURE__ */ jsx("span", {
|
|
3782
4713
|
className: "flex-shrink-0 h-4 w-4",
|
|
3783
4714
|
children: item.icon
|
|
@@ -3791,7 +4722,7 @@ function Breadcrumb({ items, separator, onNavigate, className }) {
|
|
|
3791
4722
|
|
|
3792
4723
|
//#endregion
|
|
3793
4724
|
//#region src/components/Combobox/index.tsx
|
|
3794
|
-
const cn$
|
|
4725
|
+
const cn$5 = (...classes) => classes.filter(Boolean).join(" ");
|
|
3795
4726
|
function Combobox({ options, value, onChange, multiple = false, searchable = true, placeholder = "Selecione...", label, error, disabled = false, renderOption, noResultsText = "Nenhum resultado encontrado", className }) {
|
|
3796
4727
|
const [isOpen, setIsOpen] = useState(false);
|
|
3797
4728
|
const [query, setQuery] = useState("");
|
|
@@ -3921,7 +4852,7 @@ function Combobox({ options, value, onChange, multiple = false, searchable = tru
|
|
|
3921
4852
|
}, [focusedIndex]);
|
|
3922
4853
|
const selectedLabels = selectedValues.map((v) => options.find((o) => o.value === v)?.label).filter(Boolean);
|
|
3923
4854
|
return /* @__PURE__ */ jsxs("div", {
|
|
3924
|
-
className: cn$
|
|
4855
|
+
className: cn$5("space-y-2", className),
|
|
3925
4856
|
children: [
|
|
3926
4857
|
label && /* @__PURE__ */ jsx("label", {
|
|
3927
4858
|
className: "block text-sm text-[var(--dashboard-text-primary,#2d2d2d)]",
|
|
@@ -3937,7 +4868,7 @@ function Combobox({ options, value, onChange, multiple = false, searchable = tru
|
|
|
3937
4868
|
"aria-controls": "combobox-listbox",
|
|
3938
4869
|
tabIndex: disabled ? -1 : 0,
|
|
3939
4870
|
onClick: () => isOpen ? close() : open(),
|
|
3940
|
-
className: cn$
|
|
4871
|
+
className: cn$5("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)]"),
|
|
3941
4872
|
children: [
|
|
3942
4873
|
/* @__PURE__ */ jsx("div", {
|
|
3943
4874
|
className: "flex flex-1 flex-wrap items-center gap-1 min-w-0",
|
|
@@ -3965,7 +4896,7 @@ function Combobox({ options, value, onChange, multiple = false, searchable = tru
|
|
|
3965
4896
|
"aria-label": "Limpar seleção",
|
|
3966
4897
|
children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5" })
|
|
3967
4898
|
}),
|
|
3968
|
-
/* @__PURE__ */ jsx(ChevronDown, { className: cn$
|
|
4899
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: cn$5("h-4 w-4 flex-shrink-0 text-[var(--dashboard-text-secondary,#6b7280)] transition-transform", isOpen && "rotate-180") })
|
|
3969
4900
|
]
|
|
3970
4901
|
}), isOpen && typeof document !== "undefined" && createPortal(/* @__PURE__ */ jsxs("div", {
|
|
3971
4902
|
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",
|
|
@@ -4010,7 +4941,7 @@ function Combobox({ options, value, onChange, multiple = false, searchable = tru
|
|
|
4010
4941
|
onClick: () => {
|
|
4011
4942
|
if (!option.disabled) toggleOption(option.value);
|
|
4012
4943
|
},
|
|
4013
|
-
className: cn$
|
|
4944
|
+
className: cn$5("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)]"),
|
|
4014
4945
|
children: renderOption ? renderOption(option, isSelected) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
4015
4946
|
className: "truncate",
|
|
4016
4947
|
children: option.label
|
|
@@ -4030,8 +4961,8 @@ function Combobox({ options, value, onChange, multiple = false, searchable = tru
|
|
|
4030
4961
|
|
|
4031
4962
|
//#endregion
|
|
4032
4963
|
//#region src/components/Alert/index.tsx
|
|
4033
|
-
const cn$
|
|
4034
|
-
const variantConfig = {
|
|
4964
|
+
const cn$4 = (...classes) => classes.filter(Boolean).join(" ");
|
|
4965
|
+
const variantConfig$1 = {
|
|
4035
4966
|
info: {
|
|
4036
4967
|
border: "border-[var(--dashboard-status-info,#3b82f6)]",
|
|
4037
4968
|
bg: "bg-[var(--dashboard-status-info,#3b82f6)]/5",
|
|
@@ -4058,26 +4989,26 @@ const variantConfig = {
|
|
|
4058
4989
|
}
|
|
4059
4990
|
};
|
|
4060
4991
|
function Alert({ variant = "info", title, description, onClose, actions, icon, className }) {
|
|
4061
|
-
const config = variantConfig[variant];
|
|
4992
|
+
const config = variantConfig$1[variant];
|
|
4062
4993
|
return /* @__PURE__ */ jsx("div", {
|
|
4063
|
-
className: cn$
|
|
4994
|
+
className: cn$4("rounded-lg border-l-4 p-4", config.border, config.bg, className),
|
|
4064
4995
|
role: "alert",
|
|
4065
4996
|
children: /* @__PURE__ */ jsxs("div", {
|
|
4066
4997
|
className: "flex gap-3",
|
|
4067
4998
|
children: [
|
|
4068
4999
|
/* @__PURE__ */ jsx("div", {
|
|
4069
|
-
className: cn$
|
|
5000
|
+
className: cn$4("flex-shrink-0 mt-0.5", config.text),
|
|
4070
5001
|
children: icon || config.icon
|
|
4071
5002
|
}),
|
|
4072
5003
|
/* @__PURE__ */ jsxs("div", {
|
|
4073
5004
|
className: "flex-1 min-w-0",
|
|
4074
5005
|
children: [
|
|
4075
5006
|
title && /* @__PURE__ */ jsx("h3", {
|
|
4076
|
-
className: cn$
|
|
5007
|
+
className: cn$4("text-sm font-semibold", "text-[var(--dashboard-text-primary,#2d2d2d)]"),
|
|
4077
5008
|
children: title
|
|
4078
5009
|
}),
|
|
4079
5010
|
description && /* @__PURE__ */ jsx("div", {
|
|
4080
|
-
className: cn$
|
|
5011
|
+
className: cn$4("text-sm text-[var(--dashboard-text-secondary,#6b7280)]", title && "mt-1"),
|
|
4081
5012
|
children: description
|
|
4082
5013
|
}),
|
|
4083
5014
|
actions && /* @__PURE__ */ jsx("div", {
|
|
@@ -4097,6 +5028,116 @@ function Alert({ variant = "info", title, description, onClose, actions, icon, c
|
|
|
4097
5028
|
});
|
|
4098
5029
|
}
|
|
4099
5030
|
|
|
5031
|
+
//#endregion
|
|
5032
|
+
//#region src/components/Callout/index.tsx
|
|
5033
|
+
const cn$3 = (...classes) => classes.filter(Boolean).join(" ");
|
|
5034
|
+
const variantConfig = {
|
|
5035
|
+
info: {
|
|
5036
|
+
border: "border-[var(--dashboard-status-info,#3b82f6)]",
|
|
5037
|
+
bg: "bg-[var(--dashboard-status-info,#3b82f6)]/5",
|
|
5038
|
+
text: "text-[var(--dashboard-status-info,#3b82f6)]",
|
|
5039
|
+
icon: /* @__PURE__ */ jsx(Info, { className: "h-4 w-4" })
|
|
5040
|
+
},
|
|
5041
|
+
warning: {
|
|
5042
|
+
border: "border-[var(--dashboard-status-warning,#f59e0b)]",
|
|
5043
|
+
bg: "bg-[var(--dashboard-status-warning,#f59e0b)]/5",
|
|
5044
|
+
text: "text-[var(--dashboard-status-warning,#f59e0b)]",
|
|
5045
|
+
icon: /* @__PURE__ */ jsx(AlertTriangle, { className: "h-4 w-4" })
|
|
5046
|
+
},
|
|
5047
|
+
tip: {
|
|
5048
|
+
border: "border-[var(--dashboard-status-success,#10B981)]",
|
|
5049
|
+
bg: "bg-[var(--dashboard-status-success,#10B981)]/5",
|
|
5050
|
+
text: "text-[var(--dashboard-status-success,#10B981)]",
|
|
5051
|
+
icon: /* @__PURE__ */ jsx(Lightbulb, { className: "h-4 w-4" })
|
|
5052
|
+
},
|
|
5053
|
+
danger: {
|
|
5054
|
+
border: "border-[var(--dashboard-status-danger,#EF4444)]",
|
|
5055
|
+
bg: "bg-[var(--dashboard-status-danger,#EF4444)]/5",
|
|
5056
|
+
text: "text-[var(--dashboard-status-danger,#EF4444)]",
|
|
5057
|
+
icon: /* @__PURE__ */ jsx(ShieldAlert, { className: "h-4 w-4" })
|
|
5058
|
+
}
|
|
5059
|
+
};
|
|
5060
|
+
function Callout({ variant = "info", title, children, icon, className }) {
|
|
5061
|
+
const config = variantConfig[variant];
|
|
5062
|
+
return /* @__PURE__ */ jsx("div", {
|
|
5063
|
+
className: cn$3("rounded-lg border-l-4 p-4 my-4", config.border, config.bg, className),
|
|
5064
|
+
role: "note",
|
|
5065
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
5066
|
+
className: "flex gap-3",
|
|
5067
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
5068
|
+
className: cn$3("flex-shrink-0 mt-0.5", config.text),
|
|
5069
|
+
children: icon || config.icon
|
|
5070
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
5071
|
+
className: "flex-1 min-w-0",
|
|
5072
|
+
children: [title && /* @__PURE__ */ jsx("p", {
|
|
5073
|
+
className: cn$3("text-sm font-semibold", "text-[var(--dashboard-text-primary,#2d2d2d)]"),
|
|
5074
|
+
children: title
|
|
5075
|
+
}), children && /* @__PURE__ */ jsx("div", {
|
|
5076
|
+
className: cn$3("text-sm text-[var(--dashboard-text-secondary,#6b7280)]", title && "mt-1"),
|
|
5077
|
+
children
|
|
5078
|
+
})]
|
|
5079
|
+
})]
|
|
5080
|
+
})
|
|
5081
|
+
});
|
|
5082
|
+
}
|
|
5083
|
+
|
|
5084
|
+
//#endregion
|
|
5085
|
+
//#region src/components/CodeBlock/index.tsx
|
|
5086
|
+
const cn$2 = (...classes) => classes.filter(Boolean).join(" ");
|
|
5087
|
+
function CodeBlock({ code, language, filename, showLineNumbers = false, className, copyLabel = "Copiar", copiedLabel = "Copiado!" }) {
|
|
5088
|
+
const [copied, setCopied] = useState(false);
|
|
5089
|
+
const handleCopy = useCallback(async () => {
|
|
5090
|
+
try {
|
|
5091
|
+
await navigator.clipboard.writeText(code);
|
|
5092
|
+
setCopied(true);
|
|
5093
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
5094
|
+
} catch {}
|
|
5095
|
+
}, [code]);
|
|
5096
|
+
const lines = code.split("\n");
|
|
5097
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
5098
|
+
className: cn$2("relative rounded-lg overflow-hidden border border-[var(--dashboard-text-secondary,#64748B)]/12 my-4", className),
|
|
5099
|
+
children: [(filename || language) && /* @__PURE__ */ jsxs("div", {
|
|
5100
|
+
className: "flex items-center justify-between px-4 py-2 bg-[var(--dashboard-text-primary,#0F172A)] border-b border-[var(--dashboard-text-secondary,#64748B)]/20",
|
|
5101
|
+
children: [
|
|
5102
|
+
filename && /* @__PURE__ */ jsx("span", {
|
|
5103
|
+
className: "text-xs text-[var(--dashboard-text-secondary,#64748B)] font-mono",
|
|
5104
|
+
children: filename
|
|
5105
|
+
}),
|
|
5106
|
+
language && !filename && /* @__PURE__ */ jsx("span", {}),
|
|
5107
|
+
language && /* @__PURE__ */ jsx("span", {
|
|
5108
|
+
className: "text-xs text-[var(--dashboard-text-secondary,#64748B)]/60",
|
|
5109
|
+
children: language
|
|
5110
|
+
})
|
|
5111
|
+
]
|
|
5112
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
5113
|
+
className: "relative",
|
|
5114
|
+
children: [/* @__PURE__ */ jsx("pre", {
|
|
5115
|
+
className: "overflow-x-auto p-4 bg-[var(--dashboard-text-primary,#0F172A)] m-0",
|
|
5116
|
+
"data-language": language,
|
|
5117
|
+
children: /* @__PURE__ */ jsx("code", {
|
|
5118
|
+
className: "text-sm font-mono leading-relaxed text-[var(--dashboard-surface,#FFFFFF)]/90",
|
|
5119
|
+
children: showLineNumbers ? lines.map((line, i) => /* @__PURE__ */ jsxs("span", {
|
|
5120
|
+
className: "table-row",
|
|
5121
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
5122
|
+
className: "table-cell pr-4 text-right select-none text-[var(--dashboard-text-secondary,#64748B)]/40 text-xs w-8",
|
|
5123
|
+
children: i + 1
|
|
5124
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
5125
|
+
className: "table-cell",
|
|
5126
|
+
children: [line, "\n"]
|
|
5127
|
+
})]
|
|
5128
|
+
}, i)) : code
|
|
5129
|
+
})
|
|
5130
|
+
}), /* @__PURE__ */ jsxs("button", {
|
|
5131
|
+
onClick: handleCopy,
|
|
5132
|
+
className: cn$2("absolute top-3 right-3 flex items-center gap-1.5 px-2 py-1 rounded-md text-xs font-medium transition-all duration-200 cursor-pointer", copied ? "bg-[var(--dashboard-status-success,#059669)]/20 text-[var(--dashboard-status-success,#059669)]" : "bg-[var(--dashboard-surface,#FFFFFF)]/10 text-[var(--dashboard-surface,#FFFFFF)]/60 hover:bg-[var(--dashboard-surface,#FFFFFF)]/20 hover:text-[var(--dashboard-surface,#FFFFFF)]/80"),
|
|
5133
|
+
"aria-label": copied ? copiedLabel : copyLabel,
|
|
5134
|
+
title: copied ? copiedLabel : copyLabel,
|
|
5135
|
+
children: [copied ? /* @__PURE__ */ jsx(Check, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(Copy, { className: "h-3.5 w-3.5" }), /* @__PURE__ */ jsx("span", { children: copied ? copiedLabel : copyLabel })]
|
|
5136
|
+
})]
|
|
5137
|
+
})]
|
|
5138
|
+
});
|
|
5139
|
+
}
|
|
5140
|
+
|
|
4100
5141
|
//#endregion
|
|
4101
5142
|
//#region src/components/EmptyState/index.tsx
|
|
4102
5143
|
const cn$1 = (...classes) => classes.filter(Boolean).join(" ");
|
|
@@ -4150,7 +5191,7 @@ const defaultColorMap = {
|
|
|
4150
5191
|
};
|
|
4151
5192
|
const sizeClasses = {
|
|
4152
5193
|
sm: "px-2 py-0.5 text-xs",
|
|
4153
|
-
md: "px-2.5 py-1 text-
|
|
5194
|
+
md: "px-2.5 py-1 text-sm",
|
|
4154
5195
|
lg: "px-3 py-1 text-sm"
|
|
4155
5196
|
};
|
|
4156
5197
|
const dotSizeClasses = {
|
|
@@ -4199,7 +5240,9 @@ const defaultConfig = {
|
|
|
4199
5240
|
statusDanger: "#DC2626",
|
|
4200
5241
|
statusWarning: "#D97706",
|
|
4201
5242
|
statusInfo: "#2563EB",
|
|
4202
|
-
statusNeutral: "#64748B"
|
|
5243
|
+
statusNeutral: "#64748B",
|
|
5244
|
+
tooltipBg: "#1a1a1a",
|
|
5245
|
+
tooltipText: "#ffffff"
|
|
4203
5246
|
},
|
|
4204
5247
|
components: {
|
|
4205
5248
|
modal: {
|
|
@@ -4413,6 +5456,8 @@ function CSSVarsInjector({ config }) {
|
|
|
4413
5456
|
root.style.setProperty("--dashboard-status-warning", colors.statusWarning);
|
|
4414
5457
|
root.style.setProperty("--dashboard-status-info", colors.statusInfo);
|
|
4415
5458
|
root.style.setProperty("--dashboard-status-neutral", colors.statusNeutral);
|
|
5459
|
+
root.style.setProperty("--dashboard-tooltip-bg", colors.tooltipBg);
|
|
5460
|
+
root.style.setProperty("--dashboard-tooltip-text", colors.tooltipText);
|
|
4416
5461
|
}, [config]);
|
|
4417
5462
|
return null;
|
|
4418
5463
|
}
|
|
@@ -4425,5 +5470,50 @@ function DashboardProvider({ config: configOverrides, children }) {
|
|
|
4425
5470
|
}
|
|
4426
5471
|
|
|
4427
5472
|
//#endregion
|
|
4428
|
-
|
|
5473
|
+
//#region src/config/sizes.ts
|
|
5474
|
+
const componentSizes = {
|
|
5475
|
+
sm: {
|
|
5476
|
+
height: "h-8",
|
|
5477
|
+
paddingX: "px-3",
|
|
5478
|
+
paddingY: "py-0",
|
|
5479
|
+
font: "text-xs"
|
|
5480
|
+
},
|
|
5481
|
+
md: {
|
|
5482
|
+
height: "h-9",
|
|
5483
|
+
paddingX: "px-4",
|
|
5484
|
+
paddingY: "py-0",
|
|
5485
|
+
font: "text-sm"
|
|
5486
|
+
},
|
|
5487
|
+
lg: {
|
|
5488
|
+
height: "h-10",
|
|
5489
|
+
paddingX: "px-6",
|
|
5490
|
+
paddingY: "py-0",
|
|
5491
|
+
font: "text-base"
|
|
5492
|
+
}
|
|
5493
|
+
};
|
|
5494
|
+
const badgeSizes = {
|
|
5495
|
+
sm: {
|
|
5496
|
+
padding: "px-2 py-0.5",
|
|
5497
|
+
font: "text-xs"
|
|
5498
|
+
},
|
|
5499
|
+
md: {
|
|
5500
|
+
padding: "px-3 py-1",
|
|
5501
|
+
font: "text-sm"
|
|
5502
|
+
},
|
|
5503
|
+
lg: {
|
|
5504
|
+
padding: "px-3 py-1",
|
|
5505
|
+
font: "text-sm"
|
|
5506
|
+
}
|
|
5507
|
+
};
|
|
5508
|
+
const modalSizes = {
|
|
5509
|
+
sm: "max-w-sm",
|
|
5510
|
+
md: "max-w-md",
|
|
5511
|
+
lg: "max-w-lg",
|
|
5512
|
+
xl: "max-w-2xl",
|
|
5513
|
+
"2xl": "max-w-4xl",
|
|
5514
|
+
"3xl": "max-w-screen-xl"
|
|
5515
|
+
};
|
|
5516
|
+
|
|
5517
|
+
//#endregion
|
|
5518
|
+
export { Alert, AuthLayout, BadgeStatus, Breadcrumb, Button, Callout, Card, Checkbox, CodeBlock, CodeInput, Combobox, ComparisonLineChart, DashboardProvider, DataGrid, DatePicker, DateRangePicker, DoughnutChart, Dropdown, EmptyState, FileUpload, FilterBar, FormField, Header, HorizontalBarChart, InfoTooltip, 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, badgeSizes, componentSizes, createColumnHelper, createConfig, defaultConfig, modalSizes, useConfig, useLoading, useNotifications, useTheme };
|
|
4429
5519
|
//# sourceMappingURL=index.mjs.map
|