@tree-ia/design-system 2.2.1 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -0
- package/dist/index.d.mts +574 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2639 -514
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +12 -11
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import React, { cloneElement, createContext, isValidElement, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
1
|
+
import React, { cloneElement, createContext, isValidElement, useCallback, useContext, useEffect, useId, 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, Building2, Check, CheckCircle, ChevronDown, ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight, Copy, File, GripVertical, Image, Inbox, Info, Lightbulb, LogOut, Menu, Monitor, Moon, Search, ShieldAlert, Sun, Text, Upload, User, X, XCircle } from "lucide-react";
|
|
4
|
+
import { AlertCircle, AlertOctagon, AlertTriangle, ArrowDown, ArrowLeft, ArrowUp, ArrowUpDown, Bot, Building2, Camera, Check, CheckCheck, CheckCircle, ChevronDown, ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight, Copy, File, FileText, GripVertical, Image, Inbox, Info, Lightbulb, Loader2, LogOut, Menu, MessageCircle, Mic, Monitor, Moon, MoreVertical, Paperclip, Phone, Play, PlaySquare, Search, Send, Settings, ShieldAlert, Smile, Sun, Text, Upload, User, Video, Wifi, 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$37 = (...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 = {
|
|
@@ -56,7 +56,7 @@ function Button({ children, variant = "primary", size = "md", isLoading = false,
|
|
|
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$37(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,7 +81,7 @@ 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$
|
|
84
|
+
const cn$36 = (...classes) => classes.filter(Boolean).join(" ");
|
|
85
85
|
const sizeStyles = {
|
|
86
86
|
sm: "h-8 px-2.5 text-xs",
|
|
87
87
|
md: "h-9 px-3 text-sm",
|
|
@@ -102,7 +102,7 @@ const Input = React.forwardRef(({ className, type = "text", label, error, childr
|
|
|
102
102
|
children: [/* @__PURE__ */ jsx("input", {
|
|
103
103
|
type,
|
|
104
104
|
id: inputId,
|
|
105
|
-
className: cn$
|
|
105
|
+
className: cn$36("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),
|
|
106
106
|
ref,
|
|
107
107
|
...props
|
|
108
108
|
}), children && /* @__PURE__ */ jsx("div", {
|
|
@@ -757,16 +757,16 @@ function FormField({ label, name, type = "text", value, onChange, error, require
|
|
|
757
757
|
|
|
758
758
|
//#endregion
|
|
759
759
|
//#region src/components/Tabs/index.tsx
|
|
760
|
-
const cn$
|
|
760
|
+
const cn$35 = (...classes) => classes.filter(Boolean).join(" ");
|
|
761
761
|
function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
|
|
762
762
|
if (variant === "pill") return /* @__PURE__ */ jsx("div", {
|
|
763
|
-
className: cn$
|
|
763
|
+
className: cn$35("flex flex-wrap gap-2", className),
|
|
764
764
|
role: "tablist",
|
|
765
765
|
children: tabs.map((tab) => {
|
|
766
766
|
const isActive = activeTab === tab.id;
|
|
767
767
|
return /* @__PURE__ */ jsxs("button", {
|
|
768
768
|
onClick: () => onChange(tab.id),
|
|
769
|
-
className: cn$
|
|
769
|
+
className: cn$35("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"),
|
|
770
770
|
role: "tab",
|
|
771
771
|
"aria-selected": isActive,
|
|
772
772
|
children: [
|
|
@@ -776,7 +776,7 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
|
|
|
776
776
|
}),
|
|
777
777
|
tab.label,
|
|
778
778
|
tab.count !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
779
|
-
className: cn$
|
|
779
|
+
className: cn$35("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)]"),
|
|
780
780
|
children: tab.count
|
|
781
781
|
})
|
|
782
782
|
]
|
|
@@ -784,7 +784,7 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
|
|
|
784
784
|
})
|
|
785
785
|
});
|
|
786
786
|
return /* @__PURE__ */ jsx("div", {
|
|
787
|
-
className: cn$
|
|
787
|
+
className: cn$35("border-b border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
|
|
788
788
|
children: /* @__PURE__ */ jsx("nav", {
|
|
789
789
|
className: "flex gap-6",
|
|
790
790
|
"aria-label": "Tabs",
|
|
@@ -792,7 +792,7 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
|
|
|
792
792
|
const isActive = activeTab === tab.id;
|
|
793
793
|
return /* @__PURE__ */ jsxs("button", {
|
|
794
794
|
onClick: () => onChange(tab.id),
|
|
795
|
-
className: cn$
|
|
795
|
+
className: cn$35("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"),
|
|
796
796
|
role: "tab",
|
|
797
797
|
"aria-selected": isActive,
|
|
798
798
|
children: [
|
|
@@ -802,7 +802,7 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
|
|
|
802
802
|
}),
|
|
803
803
|
tab.label,
|
|
804
804
|
tab.count !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
805
|
-
className: cn$
|
|
805
|
+
className: cn$35("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)]"),
|
|
806
806
|
children: tab.count
|
|
807
807
|
})
|
|
808
808
|
]
|
|
@@ -814,7 +814,7 @@ function Tabs({ tabs, activeTab, onChange, variant = "underline", className }) {
|
|
|
814
814
|
|
|
815
815
|
//#endregion
|
|
816
816
|
//#region src/components/DateRangePicker/index.tsx
|
|
817
|
-
const cn$
|
|
817
|
+
const cn$34 = (...classes) => classes.filter(Boolean).join(" ");
|
|
818
818
|
const locales$1 = {
|
|
819
819
|
pt: {
|
|
820
820
|
months: [
|
|
@@ -921,7 +921,7 @@ function DateRangePicker({ value, onChange, locale = "pt", className }) {
|
|
|
921
921
|
};
|
|
922
922
|
const days = getDaysInMonth(currentMonth);
|
|
923
923
|
return /* @__PURE__ */ jsxs("div", {
|
|
924
|
-
className: cn$
|
|
924
|
+
className: cn$34("w-64 bg-[var(--dashboard-surface,#ffffff)] rounded-lg p-4 shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
|
|
925
925
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
926
926
|
className: "flex items-center justify-between mb-4",
|
|
927
927
|
children: [
|
|
@@ -959,9 +959,9 @@ function DateRangePicker({ value, onChange, locale = "pt", className }) {
|
|
|
959
959
|
const isSelected = isStart || isEnd;
|
|
960
960
|
return /* @__PURE__ */ jsxs("div", {
|
|
961
961
|
className: "relative h-8 w-8",
|
|
962
|
-
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$34("absolute inset-0 bg-[var(--dashboard-text-secondary,#6b7280)]/10", isStart && "rounded-l-full", isEnd && "rounded-r-full") }), /* @__PURE__ */ jsx("button", {
|
|
963
963
|
onClick: () => handleDayClick(day),
|
|
964
|
-
className: cn$
|
|
964
|
+
className: cn$34("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"),
|
|
965
965
|
children: day
|
|
966
966
|
})]
|
|
967
967
|
}, day);
|
|
@@ -972,7 +972,7 @@ function DateRangePicker({ value, onChange, locale = "pt", className }) {
|
|
|
972
972
|
|
|
973
973
|
//#endregion
|
|
974
974
|
//#region src/components/DatePicker/index.tsx
|
|
975
|
-
const cn$
|
|
975
|
+
const cn$33 = (...classes) => classes.filter(Boolean).join(" ");
|
|
976
976
|
const locales = {
|
|
977
977
|
pt: {
|
|
978
978
|
months: [
|
|
@@ -1067,7 +1067,7 @@ function DatePicker({ value, onChange, locale = "pt", minDate, maxDate, classNam
|
|
|
1067
1067
|
};
|
|
1068
1068
|
const days = getDaysInMonth(currentMonth);
|
|
1069
1069
|
return /* @__PURE__ */ jsxs("div", {
|
|
1070
|
-
className: cn$
|
|
1070
|
+
className: cn$33("w-64 bg-[var(--dashboard-surface,#ffffff)] rounded-lg p-4 shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
|
|
1071
1071
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
1072
1072
|
className: "flex items-center justify-between mb-4",
|
|
1073
1073
|
children: [
|
|
@@ -1109,7 +1109,7 @@ function DatePicker({ value, onChange, locale = "pt", minDate, maxDate, classNam
|
|
|
1109
1109
|
type: "button",
|
|
1110
1110
|
onClick: () => handleDayClick(day),
|
|
1111
1111
|
disabled,
|
|
1112
|
-
className: cn$
|
|
1112
|
+
className: cn$33("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
1113
|
children: day
|
|
1114
1114
|
})
|
|
1115
1115
|
}, day);
|
|
@@ -1120,7 +1120,7 @@ function DatePicker({ value, onChange, locale = "pt", minDate, maxDate, classNam
|
|
|
1120
1120
|
|
|
1121
1121
|
//#endregion
|
|
1122
1122
|
//#region src/components/Title/index.tsx
|
|
1123
|
-
const cn$
|
|
1123
|
+
const cn$32 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1124
1124
|
const defaultSizeByLevel = {
|
|
1125
1125
|
1: "text-2xl sm:text-3xl md:text-4xl lg:text-5xl",
|
|
1126
1126
|
2: "text-xl sm:text-2xl md:text-3xl lg:text-4xl",
|
|
@@ -1155,7 +1155,7 @@ function Title({ children, level = 1, size, weight = "bold", align = "left", col
|
|
|
1155
1155
|
const sizeClass = size ? customSizes[size] : defaultSizeByLevel[level];
|
|
1156
1156
|
const colorClass = color || "text-[var(--dashboard-text-primary,#2d2d2d)]";
|
|
1157
1157
|
return /* @__PURE__ */ jsx(Tag, {
|
|
1158
|
-
className: cn$
|
|
1158
|
+
className: cn$32(sizeClass, weightStyles[weight], alignStyles[align], colorClass, className),
|
|
1159
1159
|
...props,
|
|
1160
1160
|
children
|
|
1161
1161
|
});
|
|
@@ -1163,7 +1163,7 @@ function Title({ children, level = 1, size, weight = "bold", align = "left", col
|
|
|
1163
1163
|
|
|
1164
1164
|
//#endregion
|
|
1165
1165
|
//#region src/components/ToggleSwitch/index.tsx
|
|
1166
|
-
const cn$
|
|
1166
|
+
const cn$31 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1167
1167
|
const sizeConfig$1 = {
|
|
1168
1168
|
sm: {
|
|
1169
1169
|
track: "h-5 w-9",
|
|
@@ -1187,7 +1187,7 @@ const sizeConfig$1 = {
|
|
|
1187
1187
|
function ToggleSwitch({ enabled, onChange, disabled = false, size = "md", label, className }) {
|
|
1188
1188
|
const config = sizeConfig$1[size];
|
|
1189
1189
|
return /* @__PURE__ */ jsxs("div", {
|
|
1190
|
-
className: cn$
|
|
1190
|
+
className: cn$31("inline-flex items-center gap-2", className),
|
|
1191
1191
|
children: [/* @__PURE__ */ jsx("button", {
|
|
1192
1192
|
type: "button",
|
|
1193
1193
|
role: "switch",
|
|
@@ -1195,10 +1195,10 @@ function ToggleSwitch({ enabled, onChange, disabled = false, size = "md", label,
|
|
|
1195
1195
|
"aria-label": label,
|
|
1196
1196
|
disabled,
|
|
1197
1197
|
onClick: () => onChange(!enabled),
|
|
1198
|
-
className: cn$
|
|
1199
|
-
children: /* @__PURE__ */ jsx("span", { className: cn$
|
|
1198
|
+
className: cn$31("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$31("inline-block transform rounded-full bg-white shadow-sm transition-transform", config.thumb, enabled ? config.translateOn : config.translateOff) })
|
|
1200
1200
|
}), label && /* @__PURE__ */ jsx("span", {
|
|
1201
|
-
className: cn$
|
|
1201
|
+
className: cn$31("text-sm text-[var(--dashboard-text-primary,#2d2d2d)]", disabled && "opacity-50"),
|
|
1202
1202
|
children: label
|
|
1203
1203
|
})]
|
|
1204
1204
|
});
|
|
@@ -1206,7 +1206,7 @@ function ToggleSwitch({ enabled, onChange, disabled = false, size = "md", label,
|
|
|
1206
1206
|
|
|
1207
1207
|
//#endregion
|
|
1208
1208
|
//#region src/components/BadgeStatus/index.tsx
|
|
1209
|
-
const cn$
|
|
1209
|
+
const cn$30 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1210
1210
|
const variantStyles = {
|
|
1211
1211
|
success: {
|
|
1212
1212
|
color: "text-[var(--dashboard-status-success,#10B981)]",
|
|
@@ -1237,7 +1237,7 @@ function BadgeStatus({ label, variant = "neutral", color, bgColor, size = "md",
|
|
|
1237
1237
|
const styles = variantStyles[variant];
|
|
1238
1238
|
const useCustomColors = color || bgColor;
|
|
1239
1239
|
return /* @__PURE__ */ jsx("span", {
|
|
1240
|
-
className: cn$
|
|
1240
|
+
className: cn$30("inline-flex w-fit items-center justify-center rounded-full font-medium whitespace-nowrap", sizeClasses$1[size], !useCustomColors && styles.color, !useCustomColors && styles.bgColor, className),
|
|
1241
1241
|
style: useCustomColors ? {
|
|
1242
1242
|
color: color || void 0,
|
|
1243
1243
|
backgroundColor: bgColor || void 0
|
|
@@ -1248,7 +1248,7 @@ function BadgeStatus({ label, variant = "neutral", color, bgColor, size = "md",
|
|
|
1248
1248
|
|
|
1249
1249
|
//#endregion
|
|
1250
1250
|
//#region src/components/Sidebar/index.tsx
|
|
1251
|
-
const cn$
|
|
1251
|
+
const cn$29 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1252
1252
|
function DefaultLink$1({ href, className, children }) {
|
|
1253
1253
|
return /* @__PURE__ */ jsx("a", {
|
|
1254
1254
|
href,
|
|
@@ -1324,7 +1324,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1324
1324
|
const isChildActive = item.children?.some((c) => currentPath === c.href);
|
|
1325
1325
|
if (hasChildren) return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("button", {
|
|
1326
1326
|
onClick: () => toggleExpand(item.id),
|
|
1327
|
-
className: cn$
|
|
1327
|
+
className: cn$29("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"),
|
|
1328
1328
|
style: { transition: "background-color 200ms, color 200ms" },
|
|
1329
1329
|
title: collapsed && !mobile ? item.label : void 0,
|
|
1330
1330
|
children: [/* @__PURE__ */ jsx(Icon, {
|
|
@@ -1339,7 +1339,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1339
1339
|
children: item.label
|
|
1340
1340
|
}), /* @__PURE__ */ jsx(ChevronRight, {
|
|
1341
1341
|
size: 14,
|
|
1342
|
-
className: cn$
|
|
1342
|
+
className: cn$29("ml-auto flex-shrink-0 transition-transform duration-200", isExpanded ? "rotate-90" : "")
|
|
1343
1343
|
})] })]
|
|
1344
1344
|
}), (!collapsed || mobile) && /* @__PURE__ */ jsx("div", {
|
|
1345
1345
|
className: "overflow-hidden transition-all duration-200 ml-7 border-l-2 border-[var(--dashboard-sidebar-border,#e0dfe3)]",
|
|
@@ -1351,7 +1351,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1351
1351
|
href: child.href,
|
|
1352
1352
|
className: "block",
|
|
1353
1353
|
children: /* @__PURE__ */ jsxs("div", {
|
|
1354
|
-
className: cn$
|
|
1354
|
+
className: cn$29("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)]"),
|
|
1355
1355
|
style: { transition: "background-color 200ms, color 200ms" },
|
|
1356
1356
|
children: [/* @__PURE__ */ jsx(ChildIcon, {
|
|
1357
1357
|
size: 15,
|
|
@@ -1368,7 +1368,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1368
1368
|
href: item.href,
|
|
1369
1369
|
className: "block",
|
|
1370
1370
|
children: /* @__PURE__ */ jsxs("div", {
|
|
1371
|
-
className: cn$
|
|
1371
|
+
className: cn$29("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"),
|
|
1372
1372
|
style: { transition: "background-color 200ms, color 200ms" },
|
|
1373
1373
|
title: collapsed && !mobile ? item.label : void 0,
|
|
1374
1374
|
children: [/* @__PURE__ */ jsx(Icon, {
|
|
@@ -1463,7 +1463,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1463
1463
|
})]
|
|
1464
1464
|
});
|
|
1465
1465
|
const desktopSidebar = /* @__PURE__ */ jsxs("aside", {
|
|
1466
|
-
className: cn$
|
|
1466
|
+
className: cn$29("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),
|
|
1467
1467
|
style: { transition: `width 400ms ${cubicBezier}` },
|
|
1468
1468
|
children: [onToggleCollapse && /* @__PURE__ */ jsxs("button", {
|
|
1469
1469
|
onClick: onToggleCollapse,
|
|
@@ -1537,7 +1537,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1537
1537
|
children: [
|
|
1538
1538
|
user && /* @__PURE__ */ jsxs("button", {
|
|
1539
1539
|
onClick: onUserClick,
|
|
1540
|
-
className: cn$
|
|
1540
|
+
className: cn$29("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"),
|
|
1541
1541
|
title: isCollapsed ? `${user.subtitle ? user.subtitle + " - " : ""}${user.name}` : void 0,
|
|
1542
1542
|
children: [/* @__PURE__ */ jsx("div", {
|
|
1543
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",
|
|
@@ -1570,7 +1570,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1570
1570
|
footerItems?.map((item) => renderMenuItem(item, isCollapsed, false)),
|
|
1571
1571
|
onLogout && /* @__PURE__ */ jsxs("button", {
|
|
1572
1572
|
onClick: onLogout,
|
|
1573
|
-
className: cn$
|
|
1573
|
+
className: cn$29("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"),
|
|
1574
1574
|
style: { transition: "background-color 200ms" },
|
|
1575
1575
|
title: isCollapsed ? logoutLabel : void 0,
|
|
1576
1576
|
children: [/* @__PURE__ */ jsx(LogOut, {
|
|
@@ -1599,7 +1599,7 @@ function Sidebar({ menuItems, logo, collapsedLogo, currentPath, linkComponent: L
|
|
|
1599
1599
|
|
|
1600
1600
|
//#endregion
|
|
1601
1601
|
//#region src/components/Header/index.tsx
|
|
1602
|
-
const cn$
|
|
1602
|
+
const cn$28 = (...classes) => classes.filter(Boolean).join(" ");
|
|
1603
1603
|
function isGroup(item) {
|
|
1604
1604
|
return "children" in item && Array.isArray(item.children);
|
|
1605
1605
|
}
|
|
@@ -1625,15 +1625,27 @@ function useOnClickOutside(ref, handler) {
|
|
|
1625
1625
|
};
|
|
1626
1626
|
}, [ref, handler]);
|
|
1627
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 }) {
|
|
1628
|
+
function Header({ menuItems, logo, currentPath, linkComponent: LinkComponent = DefaultLink, user, establishments = [], establishmentsLabel = "Estabelecimento", onEstablishmentChange, actions, onUserClick, onLogout, logoutLabel = "Sair", menuLabel = "Menu", openDropdownOnHover = true, desktopOffsetLeft = 0, className }) {
|
|
1629
1629
|
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
|
1630
1630
|
const [isUserMenuOpen, setIsUserMenuOpen] = useState(false);
|
|
1631
1631
|
const [openDropdownId, setOpenDropdownId] = useState(null);
|
|
1632
1632
|
const dropdownRef = useRef(null);
|
|
1633
1633
|
const userMenuRef = useRef(null);
|
|
1634
|
+
const hoverCloseTimeoutRef = useRef(null);
|
|
1634
1635
|
useOnClickOutside(dropdownRef, () => setOpenDropdownId(null));
|
|
1635
1636
|
useOnClickOutside(userMenuRef, () => setIsUserMenuOpen(false));
|
|
1637
|
+
useEffect(() => {
|
|
1638
|
+
return () => {
|
|
1639
|
+
if (hoverCloseTimeoutRef.current) clearTimeout(hoverCloseTimeoutRef.current);
|
|
1640
|
+
};
|
|
1641
|
+
}, []);
|
|
1642
|
+
const clearHoverCloseTimeout = () => {
|
|
1643
|
+
if (!hoverCloseTimeoutRef.current) return;
|
|
1644
|
+
clearTimeout(hoverCloseTimeoutRef.current);
|
|
1645
|
+
hoverCloseTimeoutRef.current = null;
|
|
1646
|
+
};
|
|
1636
1647
|
const closeMenus = () => {
|
|
1648
|
+
clearHoverCloseTimeout();
|
|
1637
1649
|
setIsMobileMenuOpen(false);
|
|
1638
1650
|
setIsUserMenuOpen(false);
|
|
1639
1651
|
setOpenDropdownId(null);
|
|
@@ -1646,7 +1658,7 @@ function Header({ menuItems, logo, currentPath, linkComponent: LinkComponent = D
|
|
|
1646
1658
|
const Icon = item.icon;
|
|
1647
1659
|
const active = currentPath === item.href;
|
|
1648
1660
|
if (item.disabled) return /* @__PURE__ */ jsxs("span", {
|
|
1649
|
-
className: cn$
|
|
1661
|
+
className: cn$28("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
1662
|
title: "Em breve",
|
|
1651
1663
|
children: [/* @__PURE__ */ jsx(Icon, {
|
|
1652
1664
|
size: 18,
|
|
@@ -1661,7 +1673,7 @@ function Header({ menuItems, logo, currentPath, linkComponent: LinkComponent = D
|
|
|
1661
1673
|
className: "block",
|
|
1662
1674
|
onClick: closeMenus,
|
|
1663
1675
|
children: /* @__PURE__ */ jsxs("div", {
|
|
1664
|
-
className: cn$
|
|
1676
|
+
className: cn$28("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
1677
|
"aria-current": active ? "page" : void 0,
|
|
1666
1678
|
children: [/* @__PURE__ */ jsx(Icon, {
|
|
1667
1679
|
size: 18,
|
|
@@ -1698,7 +1710,7 @@ function Header({ menuItems, logo, currentPath, linkComponent: LinkComponent = D
|
|
|
1698
1710
|
className: "block",
|
|
1699
1711
|
onClick: closeMenus,
|
|
1700
1712
|
children: /* @__PURE__ */ jsxs("div", {
|
|
1701
|
-
className: cn$
|
|
1713
|
+
className: cn$28("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
1714
|
children: [/* @__PURE__ */ jsx(child.icon, {
|
|
1703
1715
|
size: 16,
|
|
1704
1716
|
className: "flex-shrink-0"
|
|
@@ -1711,10 +1723,25 @@ function Header({ menuItems, logo, currentPath, linkComponent: LinkComponent = D
|
|
|
1711
1723
|
return /* @__PURE__ */ jsxs("div", {
|
|
1712
1724
|
className: "relative",
|
|
1713
1725
|
ref: isOpen ? dropdownRef : void 0,
|
|
1726
|
+
onMouseEnter: () => {
|
|
1727
|
+
if (!openDropdownOnHover) return;
|
|
1728
|
+
clearHoverCloseTimeout();
|
|
1729
|
+
setOpenDropdownId(group.id);
|
|
1730
|
+
},
|
|
1731
|
+
onMouseLeave: () => {
|
|
1732
|
+
if (!openDropdownOnHover) return;
|
|
1733
|
+
hoverCloseTimeoutRef.current = setTimeout(() => {
|
|
1734
|
+
setOpenDropdownId((current) => current === group.id ? null : current);
|
|
1735
|
+
hoverCloseTimeoutRef.current = null;
|
|
1736
|
+
}, 120);
|
|
1737
|
+
},
|
|
1714
1738
|
children: [/* @__PURE__ */ jsxs("button", {
|
|
1715
1739
|
type: "button",
|
|
1716
|
-
onClick: () =>
|
|
1717
|
-
|
|
1740
|
+
onClick: () => {
|
|
1741
|
+
clearHoverCloseTimeout();
|
|
1742
|
+
setOpenDropdownId((prev) => prev === group.id ? null : group.id);
|
|
1743
|
+
},
|
|
1744
|
+
className: cn$28("flex h-10 items-center gap-1.5 rounded-lg 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
1745
|
"aria-expanded": isOpen,
|
|
1719
1746
|
children: [
|
|
1720
1747
|
/* @__PURE__ */ jsx(Icon, {
|
|
@@ -1724,7 +1751,7 @@ function Header({ menuItems, logo, currentPath, linkComponent: LinkComponent = D
|
|
|
1724
1751
|
/* @__PURE__ */ jsx("span", { children: group.label }),
|
|
1725
1752
|
/* @__PURE__ */ jsx(ChevronDown, {
|
|
1726
1753
|
size: 14,
|
|
1727
|
-
className: cn$
|
|
1754
|
+
className: cn$28("flex-shrink-0 transition-transform", isOpen && "rotate-180")
|
|
1728
1755
|
})
|
|
1729
1756
|
]
|
|
1730
1757
|
}), isOpen && /* @__PURE__ */ jsx("div", {
|
|
@@ -1746,7 +1773,7 @@ function Header({ menuItems, logo, currentPath, linkComponent: LinkComponent = D
|
|
|
1746
1773
|
className: "block",
|
|
1747
1774
|
onClick: () => setOpenDropdownId(null),
|
|
1748
1775
|
children: /* @__PURE__ */ jsxs("div", {
|
|
1749
|
-
className: cn$
|
|
1776
|
+
className: cn$28("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
1777
|
children: [
|
|
1751
1778
|
/* @__PURE__ */ jsx(child.icon, {
|
|
1752
1779
|
size: 16,
|
|
@@ -1781,12 +1808,12 @@ function Header({ menuItems, logo, currentPath, linkComponent: LinkComponent = D
|
|
|
1781
1808
|
}),
|
|
1782
1809
|
/* @__PURE__ */ jsx("div", {
|
|
1783
1810
|
"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)]
|
|
1811
|
+
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)] min-[800px]:left-[calc(var(--dashboard-header-offset-left,0px)+var(--dashboard-page-gutter,0px))]",
|
|
1785
1812
|
style: { "--dashboard-header-offset-left": desktopOffset }
|
|
1786
1813
|
}),
|
|
1787
1814
|
/* @__PURE__ */ jsx("div", {
|
|
1788
1815
|
"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)]
|
|
1816
|
+
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)] min-[800px]:left-[calc(var(--dashboard-header-offset-left,0px)+var(--dashboard-page-gutter,0px))]",
|
|
1790
1817
|
style: { "--dashboard-header-offset-left": desktopOffset }
|
|
1791
1818
|
}),
|
|
1792
1819
|
/* @__PURE__ */ jsx("div", {
|
|
@@ -1795,44 +1822,45 @@ function Header({ menuItems, logo, currentPath, linkComponent: LinkComponent = D
|
|
|
1795
1822
|
}),
|
|
1796
1823
|
/* @__PURE__ */ jsx("div", {
|
|
1797
1824
|
"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)]
|
|
1825
|
+
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)] min-[800px]:left-[calc(var(--dashboard-header-offset-left,0px)+var(--dashboard-page-gutter,0px))]",
|
|
1799
1826
|
style: { "--dashboard-header-offset-left": desktopOffset }
|
|
1800
1827
|
}),
|
|
1801
1828
|
/* @__PURE__ */ jsxs("header", {
|
|
1802
|
-
className: cn$
|
|
1829
|
+
className: cn$28("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)] dashboard-header-shadow transition-[left,right] duration-[400ms] ease-[cubic-bezier(0.4,0,0.2,1)] min-[800px]:left-[calc(var(--dashboard-header-offset-left,0px)+var(--dashboard-page-gutter,0px))]", className),
|
|
1803
1830
|
style: { "--dashboard-header-offset-left": desktopOffset },
|
|
1804
1831
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
1805
|
-
className: "flex h-20 items-center gap-4 px-4 sm:px-5
|
|
1832
|
+
className: "flex h-20 items-center gap-4 px-4 sm:px-5 min-[800px]:grid min-[800px]:grid-cols-[minmax(7rem,1fr)_auto_minmax(3rem,1fr)] min-[800px]:gap-3 min-[1000px]:grid-cols-[minmax(8rem,1fr)_auto_minmax(10rem,1fr)] min-[1120px]:gap-4",
|
|
1806
1833
|
children: [
|
|
1807
1834
|
/* @__PURE__ */ jsx("div", {
|
|
1808
|
-
className: "flex min-w-0 flex-1 items-center gap-4 lg:flex-none
|
|
1835
|
+
className: "flex min-w-0 flex-1 items-center gap-4 lg:flex-none min-[800px]:col-start-1 min-[800px]:justify-self-start",
|
|
1809
1836
|
children: /* @__PURE__ */ jsx("div", {
|
|
1810
1837
|
className: "flex min-w-0 items-center",
|
|
1811
1838
|
children: logo
|
|
1812
1839
|
})
|
|
1813
1840
|
}),
|
|
1814
1841
|
/* @__PURE__ */ jsx("nav", {
|
|
1815
|
-
className: "hidden min-w-0 items-center justify-center gap-1
|
|
1842
|
+
className: "hidden min-w-0 items-center justify-center gap-1 min-[800px]:col-start-2 min-[800px]:flex",
|
|
1816
1843
|
"aria-label": "Navegacao principal",
|
|
1817
1844
|
children: menuItems.map((item) => renderNavItem(item))
|
|
1818
1845
|
}),
|
|
1819
1846
|
/* @__PURE__ */ jsxs("div", {
|
|
1820
|
-
className: "hidden items-center gap-3
|
|
1847
|
+
className: "hidden items-center gap-3 min-[800px]:col-start-3 min-[800px]:flex min-[800px]:justify-self-end",
|
|
1821
1848
|
children: [actions, user && /* @__PURE__ */ jsxs("div", {
|
|
1822
|
-
className: "relative w-[260px]",
|
|
1849
|
+
className: "relative w-11 min-[1000px]:w-[220px] min-[1120px]:w-[260px]",
|
|
1823
1850
|
ref: userMenuRef,
|
|
1824
1851
|
children: [/* @__PURE__ */ jsxs("button", {
|
|
1825
1852
|
type: "button",
|
|
1826
1853
|
onClick: () => setIsUserMenuOpen((open) => !open),
|
|
1827
|
-
className: "flex h-11 w-full items-center gap-3 rounded-lg bg-[var(--dashboard-background,#f2f2f2)] px-
|
|
1854
|
+
className: "flex h-11 w-full items-center justify-center gap-3 rounded-lg bg-[var(--dashboard-background,#f2f2f2)] px-0 text-left transition-colors hover:bg-[var(--dashboard-primary,#37a501)]/8 min-[1000px]:justify-start min-[1000px]:px-3",
|
|
1828
1855
|
"aria-expanded": isUserMenuOpen,
|
|
1856
|
+
"aria-label": user.name,
|
|
1829
1857
|
children: [
|
|
1830
1858
|
/* @__PURE__ */ jsx("div", {
|
|
1831
1859
|
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
1860
|
children: /* @__PURE__ */ jsx(User, { size: 16 })
|
|
1833
1861
|
}),
|
|
1834
1862
|
/* @__PURE__ */ jsxs("div", {
|
|
1835
|
-
className: "min-w-0 flex-1",
|
|
1863
|
+
className: "hidden min-w-0 flex-1 min-[1000px]:block",
|
|
1836
1864
|
children: [user.subtitle && /* @__PURE__ */ jsx("p", {
|
|
1837
1865
|
className: "truncate text-[11px] leading-4 text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
1838
1866
|
children: user.subtitle
|
|
@@ -1843,11 +1871,11 @@ function Header({ menuItems, logo, currentPath, linkComponent: LinkComponent = D
|
|
|
1843
1871
|
}),
|
|
1844
1872
|
/* @__PURE__ */ jsx(ChevronDown, {
|
|
1845
1873
|
size: 16,
|
|
1846
|
-
className: cn$
|
|
1874
|
+
className: cn$28("ml-auto hidden flex-shrink-0 transition-transform min-[1000px]:block", isUserMenuOpen && "rotate-180")
|
|
1847
1875
|
})
|
|
1848
1876
|
]
|
|
1849
1877
|
}), isUserMenuOpen && /* @__PURE__ */ jsxs("div", {
|
|
1850
|
-
className: "absolute right-0 top-[calc(100%+0.5rem)] w-
|
|
1878
|
+
className: "absolute right-0 top-[calc(100%+0.5rem)] w-[260px] 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 min-[1000px]:w-full",
|
|
1851
1879
|
children: [
|
|
1852
1880
|
/* @__PURE__ */ jsxs("button", {
|
|
1853
1881
|
type: "button",
|
|
@@ -1887,7 +1915,7 @@ function Header({ menuItems, logo, currentPath, linkComponent: LinkComponent = D
|
|
|
1887
1915
|
onEstablishmentChange?.(establishment.id);
|
|
1888
1916
|
},
|
|
1889
1917
|
disabled: isDisabled,
|
|
1890
|
-
className: cn$
|
|
1918
|
+
className: cn$28("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
1919
|
children: [
|
|
1892
1920
|
/* @__PURE__ */ jsx("div", {
|
|
1893
1921
|
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)]",
|
|
@@ -1928,14 +1956,14 @@ function Header({ menuItems, logo, currentPath, linkComponent: LinkComponent = D
|
|
|
1928
1956
|
/* @__PURE__ */ jsx("button", {
|
|
1929
1957
|
type: "button",
|
|
1930
1958
|
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
|
|
1959
|
+
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 min-[800px]:hidden",
|
|
1932
1960
|
"aria-label": menuLabel,
|
|
1933
1961
|
"aria-expanded": isMobileMenuOpen,
|
|
1934
1962
|
children: isMobileMenuOpen ? /* @__PURE__ */ jsx(X, { size: 22 }) : /* @__PURE__ */ jsx(Menu, { size: 22 })
|
|
1935
1963
|
})
|
|
1936
1964
|
]
|
|
1937
1965
|
}), /* @__PURE__ */ jsx("div", {
|
|
1938
|
-
className: cn$
|
|
1966
|
+
className: cn$28("overflow-hidden border-t border-[var(--dashboard-text-secondary,#6b7280)]/20 bg-[var(--dashboard-surface,#ffffff)] shadow-lg transition-[max-height] duration-200 min-[800px]:hidden", isMobileMenuOpen ? "max-h-[calc(100vh-4rem)]" : "max-h-0"),
|
|
1939
1967
|
children: /* @__PURE__ */ jsxs("div", {
|
|
1940
1968
|
className: "max-h-[calc(100vh-4rem)] overflow-y-auto px-4 py-3",
|
|
1941
1969
|
children: [/* @__PURE__ */ jsx("nav", {
|
|
@@ -1988,7 +2016,7 @@ function Header({ menuItems, logo, currentPath, linkComponent: LinkComponent = D
|
|
|
1988
2016
|
onEstablishmentChange?.(establishment.id);
|
|
1989
2017
|
},
|
|
1990
2018
|
disabled: isDisabled,
|
|
1991
|
-
className: cn$
|
|
2019
|
+
className: cn$28("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
2020
|
children: [
|
|
1993
2021
|
/* @__PURE__ */ jsx("div", {
|
|
1994
2022
|
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)]",
|
|
@@ -2031,7 +2059,7 @@ function Header({ menuItems, logo, currentPath, linkComponent: LinkComponent = D
|
|
|
2031
2059
|
|
|
2032
2060
|
//#endregion
|
|
2033
2061
|
//#region src/components/ThemeSwitcher/index.tsx
|
|
2034
|
-
const cn$
|
|
2062
|
+
const cn$27 = (...classes) => classes.filter(Boolean).join(" ");
|
|
2035
2063
|
const modes = [
|
|
2036
2064
|
{
|
|
2037
2065
|
value: "light",
|
|
@@ -2051,11 +2079,11 @@ const modes = [
|
|
|
2051
2079
|
];
|
|
2052
2080
|
function ThemeSwitcher({ mode, onModeChange, className }) {
|
|
2053
2081
|
return /* @__PURE__ */ jsx("div", {
|
|
2054
|
-
className: cn$
|
|
2082
|
+
className: cn$27("inline-flex items-center gap-1 rounded-lg bg-[var(--dashboard-background,#f2f2f2)] p-1", className),
|
|
2055
2083
|
children: modes.map(({ value, icon: Icon, label }) => /* @__PURE__ */ jsxs("button", {
|
|
2056
2084
|
type: "button",
|
|
2057
2085
|
onClick: () => onModeChange(value),
|
|
2058
|
-
className: cn$
|
|
2086
|
+
className: cn$27("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)]"),
|
|
2059
2087
|
title: label,
|
|
2060
2088
|
children: [/* @__PURE__ */ jsx(Icon, { size: 14 }), /* @__PURE__ */ jsx("span", { children: label })]
|
|
2061
2089
|
}, value))
|
|
@@ -2064,7 +2092,7 @@ function ThemeSwitcher({ mode, onModeChange, className }) {
|
|
|
2064
2092
|
|
|
2065
2093
|
//#endregion
|
|
2066
2094
|
//#region src/components/KPICard/index.tsx
|
|
2067
|
-
const cn$
|
|
2095
|
+
const cn$26 = (...classes) => classes.filter(Boolean).join(" ");
|
|
2068
2096
|
function formatValue(value, format) {
|
|
2069
2097
|
switch (format) {
|
|
2070
2098
|
case "currency": return new Intl.NumberFormat("pt-BR", {
|
|
@@ -2094,45 +2122,112 @@ function KPICard({ title, value, variation, trend, format = "number", benchmark,
|
|
|
2094
2122
|
if (isLoading) return /* @__PURE__ */ jsx(KPICardSkeleton, { className });
|
|
2095
2123
|
const trendConfig = trendConfigs[trend];
|
|
2096
2124
|
return /* @__PURE__ */ jsxs("div", {
|
|
2097
|
-
className: cn$
|
|
2098
|
-
children: [
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2125
|
+
className: cn$26("dashboard-kpi-card h-full w-full min-w-0 bg-[var(--dashboard-surface,#ffffff)] rounded-xl p-4 md:p-5 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),
|
|
2126
|
+
children: [
|
|
2127
|
+
/* @__PURE__ */ jsx("style", { children: `
|
|
2128
|
+
.dashboard-kpi-card {
|
|
2129
|
+
container-type: inline-size;
|
|
2130
|
+
}
|
|
2131
|
+
|
|
2132
|
+
@container (max-width: 13.5rem) {
|
|
2133
|
+
.dashboard-kpi-card__content {
|
|
2134
|
+
gap: 0.45rem;
|
|
2135
|
+
}
|
|
2136
|
+
|
|
2137
|
+
.dashboard-kpi-card__value {
|
|
2138
|
+
font-size: 1.55rem;
|
|
2139
|
+
line-height: 1;
|
|
2140
|
+
}
|
|
2141
|
+
|
|
2142
|
+
.dashboard-kpi-card__trend {
|
|
2143
|
+
padding-inline: 0.5rem;
|
|
2144
|
+
gap: 0.2rem;
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2147
|
+
.dashboard-kpi-card__trend-value {
|
|
2148
|
+
font-size: 0.75rem;
|
|
2149
|
+
line-height: 1rem;
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
|
|
2153
|
+
@container (max-width: 11.5rem) {
|
|
2154
|
+
.dashboard-kpi-card__value {
|
|
2155
|
+
font-size: 1.4rem;
|
|
2156
|
+
}
|
|
2157
|
+
|
|
2158
|
+
.dashboard-kpi-card__trend {
|
|
2159
|
+
padding-inline: 0.4rem;
|
|
2160
|
+
padding-block: 0.2rem;
|
|
2161
|
+
}
|
|
2162
|
+
|
|
2163
|
+
.dashboard-kpi-card__trend-value {
|
|
2164
|
+
font-size: 0.7rem;
|
|
2165
|
+
}
|
|
2166
|
+
}
|
|
2167
|
+
|
|
2168
|
+
@container (max-width: 9.75rem) {
|
|
2169
|
+
.dashboard-kpi-card__content {
|
|
2170
|
+
gap: 0.35rem;
|
|
2171
|
+
}
|
|
2172
|
+
|
|
2173
|
+
.dashboard-kpi-card__value {
|
|
2174
|
+
font-size: 1.25rem;
|
|
2175
|
+
}
|
|
2176
|
+
|
|
2177
|
+
.dashboard-kpi-card__trend {
|
|
2178
|
+
padding-inline: 0.32rem;
|
|
2179
|
+
}
|
|
2180
|
+
|
|
2181
|
+
.dashboard-kpi-card__trend-icon {
|
|
2182
|
+
font-size: 0.9rem;
|
|
2183
|
+
}
|
|
2184
|
+
|
|
2185
|
+
.dashboard-kpi-card__trend-value {
|
|
2186
|
+
font-size: 0.625rem;
|
|
2187
|
+
line-height: 0.875rem;
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
` }),
|
|
2191
|
+
/* @__PURE__ */ jsxs("div", {
|
|
2192
|
+
className: "flex justify-between items-start mb-4 gap-2",
|
|
2193
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
2194
|
+
className: "flex items-center gap-2 min-w-0",
|
|
2195
|
+
children: [icon && /* @__PURE__ */ jsx("span", {
|
|
2196
|
+
className: "shrink-0 text-[var(--dashboard-text-secondary,#64748B)]",
|
|
2197
|
+
"aria-hidden": "true",
|
|
2198
|
+
children: icon
|
|
2199
|
+
}), /* @__PURE__ */ jsx("h3", {
|
|
2200
|
+
className: "min-w-0 truncate text-xs font-semibold uppercase tracking-wider text-[var(--dashboard-text-secondary,#64748B)]",
|
|
2201
|
+
children: title
|
|
2202
|
+
})]
|
|
2203
|
+
}), benchmark && /* @__PURE__ */ jsx("span", {
|
|
2204
|
+
className: "text-xs text-[var(--dashboard-text-secondary,#64748B)]/50 ml-2 whitespace-nowrap flex-shrink-0",
|
|
2205
|
+
title: "Benchmark de referência",
|
|
2206
|
+
children: benchmark
|
|
2109
2207
|
})]
|
|
2110
|
-
}),
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
children:
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
}), /* @__PURE__ */ jsxs("span", {
|
|
2126
|
-
className: "text-xs font-semibold whitespace-nowrap",
|
|
2127
|
-
children: [Math.abs(variation).toFixed(1), "%"]
|
|
2208
|
+
}),
|
|
2209
|
+
/* @__PURE__ */ jsxs("div", {
|
|
2210
|
+
className: "dashboard-kpi-card__content flex min-w-0 items-end gap-3 flex-1",
|
|
2211
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
2212
|
+
className: "dashboard-kpi-card__value min-w-0 text-3xl font-bold text-[var(--dashboard-text-primary,#0F172A)] whitespace-nowrap tracking-tight",
|
|
2213
|
+
children: formatValue(value, format)
|
|
2214
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
2215
|
+
className: cn$26("dashboard-kpi-card__trend inline-flex items-center gap-1 px-2 py-1 rounded-full flex-shrink-0 mb-1", trendConfig.color),
|
|
2216
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
2217
|
+
className: "dashboard-kpi-card__trend-icon text-sm leading-none",
|
|
2218
|
+
children: trendConfig.icon
|
|
2219
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
2220
|
+
className: "dashboard-kpi-card__trend-value text-xs font-semibold whitespace-nowrap",
|
|
2221
|
+
children: [Math.abs(variation).toFixed(1), "%"]
|
|
2222
|
+
})]
|
|
2128
2223
|
})]
|
|
2129
|
-
})
|
|
2130
|
-
|
|
2224
|
+
})
|
|
2225
|
+
]
|
|
2131
2226
|
});
|
|
2132
2227
|
}
|
|
2133
2228
|
function KPICardSkeleton({ className }) {
|
|
2134
2229
|
return /* @__PURE__ */ jsxs("div", {
|
|
2135
|
-
className: cn$
|
|
2230
|
+
className: cn$26("h-full bg-[var(--dashboard-surface,#ffffff)] rounded-xl p-4 md:p-5 border border-[var(--dashboard-text-secondary,#64748B)]/12 dashboard-shadow-sm animate-pulse flex flex-col", className),
|
|
2136
2231
|
children: [/* @__PURE__ */ jsx("div", { className: "h-3 bg-[var(--dashboard-text-secondary,#64748B)]/10 rounded w-2/3 mb-4" }), /* @__PURE__ */ jsxs("div", {
|
|
2137
2232
|
className: "flex items-end gap-3 flex-1",
|
|
2138
2233
|
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" })]
|
|
@@ -2142,18 +2237,18 @@ function KPICardSkeleton({ className }) {
|
|
|
2142
2237
|
|
|
2143
2238
|
//#endregion
|
|
2144
2239
|
//#region src/components/PageLayout/index.tsx
|
|
2145
|
-
const cn$
|
|
2146
|
-
function PageLayout({ title, description, headerActions, appHeader, children, contentPadding = true, sidebar, sidebarCollapsed = false, sidebarWidth = 280, sidebarCollapsedWidth = 109, className }) {
|
|
2240
|
+
const cn$25 = (...classes) => classes.filter(Boolean).join(" ");
|
|
2241
|
+
function PageLayout({ eyebrow, title, description, headerActions, appHeader, children, contentPadding = true, contentClassName, contentFillViewport = false, sidebar, sidebarCollapsed = false, sidebarWidth = 280, sidebarCollapsedWidth = 109, className }) {
|
|
2147
2242
|
const marginLeft = sidebar ? sidebarCollapsed ? `max(0px, ${sidebarCollapsedWidth}px)` : `max(0px, ${sidebarWidth}px)` : "0px";
|
|
2148
2243
|
const mainTopPadding = appHeader ? "pt-24" : sidebar ? "pt-16 xl:pt-0" : "pt-0";
|
|
2149
2244
|
const layoutContainer = "mx-[var(--dashboard-page-gutter)]";
|
|
2150
2245
|
return /* @__PURE__ */ jsxs("div", {
|
|
2151
|
-
className: cn$
|
|
2246
|
+
className: cn$25("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
2247
|
children: [
|
|
2153
2248
|
appHeader,
|
|
2154
2249
|
sidebar,
|
|
2155
2250
|
/* @__PURE__ */ jsxs("main", {
|
|
2156
|
-
className: mainTopPadding,
|
|
2251
|
+
className: cn$25(mainTopPadding, "box-border flex flex-col", contentFillViewport ? "h-dvh overflow-hidden" : "min-h-dvh"),
|
|
2157
2252
|
style: {
|
|
2158
2253
|
marginLeft,
|
|
2159
2254
|
transition: "margin-left 400ms cubic-bezier(0.4, 0, 0.2, 1)"
|
|
@@ -2167,18 +2262,25 @@ function PageLayout({ title, description, headerActions, appHeader, children, co
|
|
|
2167
2262
|
}
|
|
2168
2263
|
` }),
|
|
2169
2264
|
/* @__PURE__ */ jsx("div", {
|
|
2170
|
-
className: cn$
|
|
2265
|
+
className: cn$25(layoutContainer, "mt-4 box-border px-6 py-5 sm:px-8 lg:px-10"),
|
|
2171
2266
|
children: /* @__PURE__ */ jsxs("div", {
|
|
2172
|
-
className: "flex flex-col gap-
|
|
2267
|
+
className: "flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between",
|
|
2173
2268
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
2174
2269
|
className: "min-w-0",
|
|
2175
|
-
children: [
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2270
|
+
children: [
|
|
2271
|
+
eyebrow && /* @__PURE__ */ jsx("p", {
|
|
2272
|
+
className: "mb-1 text-xs font-semibold uppercase tracking-[0.16em] text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
2273
|
+
children: eyebrow
|
|
2274
|
+
}),
|
|
2275
|
+
/* @__PURE__ */ jsx("h1", {
|
|
2276
|
+
className: "text-2xl font-semibold leading-tight tracking-tight text-[var(--dashboard-text-primary,#2d2d2d)] sm:text-3xl",
|
|
2277
|
+
children: title
|
|
2278
|
+
}),
|
|
2279
|
+
description && /* @__PURE__ */ jsx("p", {
|
|
2280
|
+
className: "mt-2 text-sm font-medium text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
2281
|
+
children: description
|
|
2282
|
+
})
|
|
2283
|
+
]
|
|
2182
2284
|
}), headerActions && /* @__PURE__ */ jsx("div", {
|
|
2183
2285
|
className: "flex max-w-full justify-start lg:justify-end",
|
|
2184
2286
|
children: headerActions
|
|
@@ -2186,7 +2288,7 @@ function PageLayout({ title, description, headerActions, appHeader, children, co
|
|
|
2186
2288
|
})
|
|
2187
2289
|
}),
|
|
2188
2290
|
/* @__PURE__ */ jsx("div", {
|
|
2189
|
-
className: contentPadding ? cn$
|
|
2291
|
+
className: contentPadding ? cn$25(layoutContainer, "min-h-0 flex-1 pb-6 pt-5", contentClassName) : cn$25("min-h-0 flex-1", contentClassName),
|
|
2190
2292
|
children
|
|
2191
2293
|
})
|
|
2192
2294
|
]
|
|
@@ -2198,7 +2300,7 @@ function PageLayout({ title, description, headerActions, appHeader, children, co
|
|
|
2198
2300
|
//#endregion
|
|
2199
2301
|
//#region src/components/ComparisonLineChart/index.tsx
|
|
2200
2302
|
Chart.register(CategoryScale, LinearScale, PointElement, LineElement, Title$1, Tooltip$1, Legend, Filler);
|
|
2201
|
-
const cn$
|
|
2303
|
+
const cn$24 = (...classes) => classes.filter(Boolean).join(" ");
|
|
2202
2304
|
function ComparisonLineChart({ labels, currentPeriodData, previousPeriodData, currentPeriodLabel = "Período atual", previousPeriodLabel = "Período anterior", title, color, height = 300, className }) {
|
|
2203
2305
|
const primaryColor = color || (typeof document !== "undefined" ? getComputedStyle(document.documentElement).getPropertyValue("--dashboard-primary").trim() : "") || "#37a501";
|
|
2204
2306
|
const data = {
|
|
@@ -2292,7 +2394,7 @@ function ComparisonLineChart({ labels, currentPeriodData, previousPeriodData, cu
|
|
|
2292
2394
|
}
|
|
2293
2395
|
};
|
|
2294
2396
|
return /* @__PURE__ */ jsxs("div", {
|
|
2295
|
-
className: cn$
|
|
2397
|
+
className: cn$24("bg-[var(--dashboard-surface,#ffffff)] rounded-lg shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20 p-6", className),
|
|
2296
2398
|
children: [title && /* @__PURE__ */ jsx("h3", {
|
|
2297
2399
|
className: "text-base font-semibold mb-4 text-[var(--dashboard-text-primary,#2d2d2d)]",
|
|
2298
2400
|
children: title
|
|
@@ -2309,7 +2411,7 @@ function ComparisonLineChart({ labels, currentPeriodData, previousPeriodData, cu
|
|
|
2309
2411
|
//#endregion
|
|
2310
2412
|
//#region src/components/HorizontalBarChart/index.tsx
|
|
2311
2413
|
Chart.register(CategoryScale, LinearScale, BarElement, Title$1, Tooltip$1, Legend);
|
|
2312
|
-
const cn$
|
|
2414
|
+
const cn$23 = (...classes) => classes.filter(Boolean).join(" ");
|
|
2313
2415
|
function HorizontalBarChart({ labels, datasets, tabs, title, titleIcon, color, valueLabel = "itens", valueLabelSingular, bestItemLabel = "Melhor item", className }) {
|
|
2314
2416
|
const [activeTab, setActiveTab] = useState((tabs ? tabs.map((t) => t.id) : Object.keys(datasets))[0]);
|
|
2315
2417
|
const [isMobile, setIsMobile] = useState(false);
|
|
@@ -2384,7 +2486,7 @@ function HorizontalBarChart({ labels, datasets, tabs, title, titleIcon, color, v
|
|
|
2384
2486
|
}
|
|
2385
2487
|
};
|
|
2386
2488
|
return /* @__PURE__ */ jsxs("div", {
|
|
2387
|
-
className: cn$
|
|
2489
|
+
className: cn$23("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),
|
|
2388
2490
|
children: [
|
|
2389
2491
|
title && /* @__PURE__ */ jsxs("div", {
|
|
2390
2492
|
className: "flex items-center gap-2 mb-4",
|
|
@@ -2397,7 +2499,7 @@ function HorizontalBarChart({ labels, datasets, tabs, title, titleIcon, color, v
|
|
|
2397
2499
|
className: "flex gap-2 mb-4 flex-wrap",
|
|
2398
2500
|
children: tabs.map((tab) => /* @__PURE__ */ jsx("button", {
|
|
2399
2501
|
onClick: () => setActiveTab(tab.id),
|
|
2400
|
-
className: cn$
|
|
2502
|
+
className: cn$23("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"),
|
|
2401
2503
|
children: tab.label
|
|
2402
2504
|
}, tab.id))
|
|
2403
2505
|
}),
|
|
@@ -2436,7 +2538,7 @@ function HorizontalBarChart({ labels, datasets, tabs, title, titleIcon, color, v
|
|
|
2436
2538
|
//#endregion
|
|
2437
2539
|
//#region src/components/VerticalBarChart/index.tsx
|
|
2438
2540
|
Chart.register(CategoryScale, LinearScale, BarElement, Title$1, Tooltip$1, Legend);
|
|
2439
|
-
const cn$
|
|
2541
|
+
const cn$22 = (...classes) => classes.filter(Boolean).join(" ");
|
|
2440
2542
|
function VerticalBarChart({ labels, data: values, title, titleIcon, color, valueLabel = "itens", valueLabelSingular, bestItemLabel = "Melhor item", labelMaxChars = 3, className }) {
|
|
2441
2543
|
const maxValue = Math.max(...values);
|
|
2442
2544
|
const bestLabel = labels[values.indexOf(maxValue)];
|
|
@@ -2499,7 +2601,7 @@ function VerticalBarChart({ labels, data: values, title, titleIcon, color, value
|
|
|
2499
2601
|
}
|
|
2500
2602
|
};
|
|
2501
2603
|
return /* @__PURE__ */ jsxs("div", {
|
|
2502
|
-
className: cn$
|
|
2604
|
+
className: cn$22("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),
|
|
2503
2605
|
children: [
|
|
2504
2606
|
title && /* @__PURE__ */ jsxs("div", {
|
|
2505
2607
|
className: "flex items-center gap-2 mb-4",
|
|
@@ -2555,7 +2657,7 @@ const DEFAULT_COLORS = [
|
|
|
2555
2657
|
"#EA580C",
|
|
2556
2658
|
"#4F46E5"
|
|
2557
2659
|
];
|
|
2558
|
-
const cn$
|
|
2660
|
+
const cn$21 = (...classes) => classes.filter(Boolean).join(" ");
|
|
2559
2661
|
function DoughnutChart({ items, title, titleIcon, centerLabel, centerValue, showLegend = true, formatValue, cutout = 65, height = 240, className }) {
|
|
2560
2662
|
const total = items.reduce((sum, item) => sum + item.value, 0);
|
|
2561
2663
|
const format = formatValue || ((v) => String(v));
|
|
@@ -2595,7 +2697,7 @@ function DoughnutChart({ items, title, titleIcon, centerLabel, centerValue, show
|
|
|
2595
2697
|
}
|
|
2596
2698
|
};
|
|
2597
2699
|
return /* @__PURE__ */ jsxs("div", {
|
|
2598
|
-
className: cn$
|
|
2700
|
+
className: cn$21("bg-[var(--dashboard-surface,#ffffff)] rounded-lg shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20 p-6", className),
|
|
2599
2701
|
children: [title && /* @__PURE__ */ jsxs("div", {
|
|
2600
2702
|
className: "flex items-center gap-2 mb-4",
|
|
2601
2703
|
children: [titleIcon, /* @__PURE__ */ jsx("h3", {
|
|
@@ -2603,7 +2705,7 @@ function DoughnutChart({ items, title, titleIcon, centerLabel, centerValue, show
|
|
|
2603
2705
|
children: title
|
|
2604
2706
|
})]
|
|
2605
2707
|
}), /* @__PURE__ */ jsxs("div", {
|
|
2606
|
-
className: cn$
|
|
2708
|
+
className: cn$21("flex items-center", showLegend ? "gap-6" : "justify-center"),
|
|
2607
2709
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
2608
2710
|
className: "relative flex-shrink-0",
|
|
2609
2711
|
style: {
|
|
@@ -2656,7 +2758,7 @@ function DoughnutChart({ items, title, titleIcon, centerLabel, centerValue, show
|
|
|
2656
2758
|
|
|
2657
2759
|
//#endregion
|
|
2658
2760
|
//#region src/components/ProgressBarList/index.tsx
|
|
2659
|
-
const cn$
|
|
2761
|
+
const cn$20 = (...classes) => classes.filter(Boolean).join(" ");
|
|
2660
2762
|
function ProgressBarList({ items, title, titleIcon, color, valueLabel = "itens", valueLabelSingular, sortByValue = true, formatValue, className }) {
|
|
2661
2763
|
const sortedItems = sortByValue ? [...items].sort((a, b) => b.value - a.value) : items;
|
|
2662
2764
|
const maxValue = Math.max(...items.map((i) => i.value));
|
|
@@ -2665,7 +2767,7 @@ function ProgressBarList({ items, title, titleIcon, color, valueLabel = "itens",
|
|
|
2665
2767
|
const defaultFormat = (v) => `${v} ${v === 1 ? singular : valueLabel}`;
|
|
2666
2768
|
const fmt = formatValue || defaultFormat;
|
|
2667
2769
|
return /* @__PURE__ */ jsxs("div", {
|
|
2668
|
-
className: cn$
|
|
2770
|
+
className: cn$20("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),
|
|
2669
2771
|
children: [title && /* @__PURE__ */ jsxs("div", {
|
|
2670
2772
|
className: "flex items-center gap-2 mb-4",
|
|
2671
2773
|
children: [titleIcon, /* @__PURE__ */ jsx("h3", {
|
|
@@ -2714,7 +2816,7 @@ function ProgressBarList({ items, title, titleIcon, color, valueLabel = "itens",
|
|
|
2714
2816
|
//#endregion
|
|
2715
2817
|
//#region src/components/MetricPanel/index.tsx
|
|
2716
2818
|
Chart.register(CategoryScale, LinearScale, PointElement, LineElement, Title$1, Tooltip$1, Legend, Filler);
|
|
2717
|
-
const cn$
|
|
2819
|
+
const cn$19 = (...classes) => classes.filter(Boolean).join(" ");
|
|
2718
2820
|
function formatMetricValue(value, format) {
|
|
2719
2821
|
switch (format) {
|
|
2720
2822
|
case "currency": return new Intl.NumberFormat("pt-BR", {
|
|
@@ -3034,14 +3136,14 @@ function MetricPanel({ title, titleIcon: TitleIcon, metrics, chartData, color, s
|
|
|
3034
3136
|
}
|
|
3035
3137
|
};
|
|
3036
3138
|
return /* @__PURE__ */ jsxs("div", {
|
|
3037
|
-
className: cn$
|
|
3139
|
+
className: cn$19("bg-[var(--dashboard-surface,#ffffff)] rounded-lg shadow-sm border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
|
|
3038
3140
|
style: { overflow: "visible" },
|
|
3039
3141
|
children: [
|
|
3040
3142
|
/* @__PURE__ */ jsxs("div", {
|
|
3041
3143
|
className: "flex items-center justify-between p-4 md:p-6 pb-3 md:pb-4 border-b border-[var(--dashboard-text-secondary,#6b7280)]/10",
|
|
3042
3144
|
children: [/* @__PURE__ */ jsxs("h2", {
|
|
3043
|
-
className: "flex items-center gap-2 text-
|
|
3044
|
-
children: [/* @__PURE__ */ jsx(TitleIcon, { className: "w-5 h-5
|
|
3145
|
+
className: "flex items-center gap-2 text-base md:text-lg font-bold text-[var(--dashboard-text-primary,#2d2d2d)]",
|
|
3146
|
+
children: [/* @__PURE__ */ jsx(TitleIcon, { className: "w-5 h-5" }), title]
|
|
3045
3147
|
}), onActionClick && actionLabel && /* @__PURE__ */ jsx("button", {
|
|
3046
3148
|
onClick: onActionClick,
|
|
3047
3149
|
className: "px-3 md:px-4 py-1.5 md:py-2 text-xs md:text-sm font-medium border rounded-lg transition-colors cursor-pointer",
|
|
@@ -3075,7 +3177,7 @@ function MetricPanel({ title, titleIcon: TitleIcon, metrics, chartData, color, s
|
|
|
3075
3177
|
const Icon = metric.icon;
|
|
3076
3178
|
return /* @__PURE__ */ jsxs("button", {
|
|
3077
3179
|
onClick: () => setSelectedMetricKey(metric.key),
|
|
3078
|
-
className: cn$
|
|
3180
|
+
className: cn$19("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"),
|
|
3079
3181
|
style: selectedMetricKey === metric.key ? {
|
|
3080
3182
|
borderColor: primaryColor,
|
|
3081
3183
|
color: primaryColor
|
|
@@ -3123,10 +3225,10 @@ function MetricPanel({ title, titleIcon: TitleIcon, metrics, chartData, color, s
|
|
|
3123
3225
|
|
|
3124
3226
|
//#endregion
|
|
3125
3227
|
//#region src/components/FilterBar/index.tsx
|
|
3126
|
-
const cn$
|
|
3228
|
+
const cn$18 = (...classes) => classes.filter(Boolean).join(" ");
|
|
3127
3229
|
function FilterBar({ searchValue, onSearchChange, searchPlaceholder = "Buscar...", children, actions, className }) {
|
|
3128
3230
|
return /* @__PURE__ */ jsxs("div", {
|
|
3129
|
-
className: cn$
|
|
3231
|
+
className: cn$18("flex flex-col gap-3 sm:flex-row sm:items-center sm:flex-wrap", className),
|
|
3130
3232
|
children: [
|
|
3131
3233
|
onSearchChange !== void 0 && /* @__PURE__ */ jsx("div", {
|
|
3132
3234
|
className: "flex-1 min-w-[200px]",
|
|
@@ -3166,7 +3268,7 @@ function FilterBar({ searchValue, onSearchChange, searchPlaceholder = "Buscar...
|
|
|
3166
3268
|
|
|
3167
3269
|
//#endregion
|
|
3168
3270
|
//#region src/components/Checkbox/index.tsx
|
|
3169
|
-
const cn$
|
|
3271
|
+
const cn$17 = (...classes) => classes.filter(Boolean).join(" ");
|
|
3170
3272
|
const sizeConfig = {
|
|
3171
3273
|
sm: {
|
|
3172
3274
|
box: 16,
|
|
@@ -3214,7 +3316,7 @@ function Checkbox({ name, id, label, checked = false, onChange, disabled = false
|
|
|
3214
3316
|
const resolvedColor = primaryColor || "var(--dashboard-primary, #37A501)";
|
|
3215
3317
|
return /* @__PURE__ */ jsxs("label", {
|
|
3216
3318
|
htmlFor: inputId,
|
|
3217
|
-
className: cn$
|
|
3319
|
+
className: cn$17("inline-flex items-center cursor-pointer select-none", disabled && "opacity-50 cursor-not-allowed", className),
|
|
3218
3320
|
style: { gap: cfg.gap },
|
|
3219
3321
|
children: [
|
|
3220
3322
|
/* @__PURE__ */ jsx("input", {
|
|
@@ -3265,7 +3367,7 @@ function Checkbox({ name, id, label, checked = false, onChange, disabled = false
|
|
|
3265
3367
|
|
|
3266
3368
|
//#endregion
|
|
3267
3369
|
//#region src/components/AuthLayout/index.tsx
|
|
3268
|
-
const cn$
|
|
3370
|
+
const cn$16 = (...classes) => classes.filter(Boolean).join(" ");
|
|
3269
3371
|
/** Resolves a CSS color value (including var() references) to a computed hex/rgb string */
|
|
3270
3372
|
function useResolvedColor(cssValue) {
|
|
3271
3373
|
const [resolved, setResolved] = useState(cssValue);
|
|
@@ -3432,7 +3534,7 @@ function AuthLayout({ logo, title, subtitle, error, success, fields, values, onF
|
|
|
3432
3534
|
if (link.onClick) return /* @__PURE__ */ jsx("button", {
|
|
3433
3535
|
type: "button",
|
|
3434
3536
|
onClick: link.onClick,
|
|
3435
|
-
className: cn$
|
|
3537
|
+
className: cn$16("bg-transparent border-none cursor-pointer hover:opacity-80 text-sm font-semibold p-0 transition-colors", extraClass),
|
|
3436
3538
|
style,
|
|
3437
3539
|
children: link.label
|
|
3438
3540
|
});
|
|
@@ -3440,13 +3542,13 @@ function AuthLayout({ logo, title, subtitle, error, success, fields, values, onF
|
|
|
3440
3542
|
href: link.href,
|
|
3441
3543
|
target: link.target,
|
|
3442
3544
|
rel: link.target === "_blank" ? "noopener noreferrer" : void 0,
|
|
3443
|
-
className: cn$
|
|
3545
|
+
className: cn$16("hover:opacity-80 text-sm font-semibold transition-colors", extraClass),
|
|
3444
3546
|
style,
|
|
3445
3547
|
children: link.label
|
|
3446
3548
|
});
|
|
3447
3549
|
}
|
|
3448
3550
|
return /* @__PURE__ */ jsxs("div", {
|
|
3449
|
-
className: cn$
|
|
3551
|
+
className: cn$16("fixed inset-0 flex select-none overflow-hidden", className),
|
|
3450
3552
|
style: bgCss,
|
|
3451
3553
|
children: [
|
|
3452
3554
|
branding && branding.logos.length > 0 && /* @__PURE__ */ jsx("div", {
|
|
@@ -3729,7 +3831,7 @@ function CodeInput({ length = 6, value, onChange, disabled = false, error = fals
|
|
|
3729
3831
|
|
|
3730
3832
|
//#endregion
|
|
3731
3833
|
//#region src/components/Skeleton/index.tsx
|
|
3732
|
-
const cn$
|
|
3834
|
+
const cn$15 = (...classes) => classes.filter(Boolean).join(" ");
|
|
3733
3835
|
function Skeleton({ variant = "text", width, height, animate = true, className, lines = 1 }) {
|
|
3734
3836
|
const baseStyles = "bg-[var(--dashboard-text-secondary,#6b7280)]/10 relative overflow-hidden";
|
|
3735
3837
|
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-['']" : "";
|
|
@@ -3748,9 +3850,9 @@ function Skeleton({ variant = "text", width, height, animate = true, className,
|
|
|
3748
3850
|
}
|
|
3749
3851
|
if (variant === "card" && !height) style.height = "120px";
|
|
3750
3852
|
if (variant === "text" && lines > 1) return /* @__PURE__ */ jsx("div", {
|
|
3751
|
-
className: cn$
|
|
3853
|
+
className: cn$15("flex flex-col gap-2", className),
|
|
3752
3854
|
children: Array.from({ length: lines }).map((_, i) => /* @__PURE__ */ jsx("div", {
|
|
3753
|
-
className: cn$
|
|
3855
|
+
className: cn$15(baseStyles, shimmerStyles, variantStyles.text),
|
|
3754
3856
|
style: {
|
|
3755
3857
|
...style,
|
|
3756
3858
|
width: i === lines - 1 ? "75%" : style.width || "100%"
|
|
@@ -3758,14 +3860,14 @@ function Skeleton({ variant = "text", width, height, animate = true, className,
|
|
|
3758
3860
|
}, i))
|
|
3759
3861
|
});
|
|
3760
3862
|
return /* @__PURE__ */ jsx("div", {
|
|
3761
|
-
className: cn$
|
|
3863
|
+
className: cn$15(baseStyles, shimmerStyles, variantStyles[variant], className),
|
|
3762
3864
|
style
|
|
3763
3865
|
});
|
|
3764
3866
|
}
|
|
3765
3867
|
|
|
3766
3868
|
//#endregion
|
|
3767
3869
|
//#region src/components/DataGrid/index.tsx
|
|
3768
|
-
const cn$
|
|
3870
|
+
const cn$14 = (...classes) => classes.filter(Boolean).join(" ");
|
|
3769
3871
|
function SortIcon({ sorted }) {
|
|
3770
3872
|
if (sorted === "asc") return /* @__PURE__ */ jsx(ArrowUp, { className: "h-3.5 w-3.5" });
|
|
3771
3873
|
if (sorted === "desc") return /* @__PURE__ */ jsx(ArrowDown, { className: "h-3.5 w-3.5" });
|
|
@@ -3820,7 +3922,7 @@ function VirtualRows({ table, rowHeight, onRowClick, compact }) {
|
|
|
3820
3922
|
className: "bg-[var(--dashboard-text-secondary,#6b7280)]/5 sticky top-0 z-10",
|
|
3821
3923
|
children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx("tr", { children: headerGroup.headers.map((header) => /* @__PURE__ */ jsx("th", {
|
|
3822
3924
|
scope: "col",
|
|
3823
|
-
className: cn$
|
|
3925
|
+
className: cn$14("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"),
|
|
3824
3926
|
style: { width: header.getSize() },
|
|
3825
3927
|
onClick: header.column.getToggleSortingHandler(),
|
|
3826
3928
|
children: /* @__PURE__ */ jsxs("div", {
|
|
@@ -3835,10 +3937,10 @@ function VirtualRows({ table, rowHeight, onRowClick, compact }) {
|
|
|
3835
3937
|
}),
|
|
3836
3938
|
visibleRows.map((row) => /* @__PURE__ */ jsx("tr", {
|
|
3837
3939
|
onClick: () => onRowClick?.(row.original),
|
|
3838
|
-
className: cn$
|
|
3940
|
+
className: cn$14("hover:bg-[var(--dashboard-text-secondary,#6b7280)]/5 transition-colors", onRowClick && "cursor-pointer", row.getIsSelected() && "bg-[var(--dashboard-primary,#37a501)]/5"),
|
|
3839
3941
|
style: { height: rowHeight },
|
|
3840
3942
|
children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx("td", {
|
|
3841
|
-
className: cn$
|
|
3943
|
+
className: cn$14(cellPadding, "text-sm whitespace-nowrap"),
|
|
3842
3944
|
children: flexRender(cell.column.columnDef.cell, cell.getContext())
|
|
3843
3945
|
}, cell.id))
|
|
3844
3946
|
}, row.id)),
|
|
@@ -3917,7 +4019,7 @@ function DataGrid({ columns, data, isLoading = false, skeletonRows = 5, sorting:
|
|
|
3917
4019
|
const cellPadding = compact ? "px-4 py-2" : "px-6 py-4";
|
|
3918
4020
|
const headerPadding = compact ? "px-4 py-2" : "px-6 py-3";
|
|
3919
4021
|
if (enableVirtualization) return /* @__PURE__ */ jsx("div", {
|
|
3920
|
-
className: cn$
|
|
4022
|
+
className: cn$14("overflow-hidden rounded-lg bg-[var(--dashboard-surface,#ffffff)] shadow-sm", bordered && "border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
|
|
3921
4023
|
children: /* @__PURE__ */ jsx(VirtualRows, {
|
|
3922
4024
|
table,
|
|
3923
4025
|
rowHeight,
|
|
@@ -3926,16 +4028,16 @@ function DataGrid({ columns, data, isLoading = false, skeletonRows = 5, sorting:
|
|
|
3926
4028
|
})
|
|
3927
4029
|
});
|
|
3928
4030
|
return /* @__PURE__ */ jsxs("div", {
|
|
3929
|
-
className: cn$
|
|
4031
|
+
className: cn$14("overflow-hidden rounded-lg bg-[var(--dashboard-surface,#ffffff)] shadow-sm", bordered && "border border-[var(--dashboard-text-secondary,#6b7280)]/20", className),
|
|
3930
4032
|
children: [/* @__PURE__ */ jsx("div", {
|
|
3931
4033
|
className: "overflow-x-auto",
|
|
3932
4034
|
children: /* @__PURE__ */ jsxs("table", {
|
|
3933
4035
|
className: "min-w-full divide-y divide-[var(--dashboard-text-secondary,#6b7280)]/20",
|
|
3934
4036
|
children: [/* @__PURE__ */ jsx("thead", {
|
|
3935
|
-
className: cn$
|
|
4037
|
+
className: cn$14("bg-[var(--dashboard-text-secondary,#6b7280)]/5", stickyHeader && "sticky top-0 z-10"),
|
|
3936
4038
|
children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsx("tr", { children: headerGroup.headers.map((header) => /* @__PURE__ */ jsx("th", {
|
|
3937
4039
|
scope: "col",
|
|
3938
|
-
className: cn$
|
|
4040
|
+
className: cn$14("text-left text-xs font-semibold text-[var(--dashboard-text-secondary,#6b7280)] uppercase tracking-wider", headerPadding, header.column.getCanSort() && "cursor-pointer select-none"),
|
|
3939
4041
|
style: header.getSize() !== 150 ? { width: header.getSize() } : void 0,
|
|
3940
4042
|
onClick: header.column.getToggleSortingHandler(),
|
|
3941
4043
|
children: /* @__PURE__ */ jsxs("div", {
|
|
@@ -3972,9 +4074,9 @@ function DataGrid({ columns, data, isLoading = false, skeletonRows = 5, sorting:
|
|
|
3972
4074
|
})
|
|
3973
4075
|
}) }) : table.getRowModel().rows.map((row, rowIndex) => /* @__PURE__ */ jsx("tr", {
|
|
3974
4076
|
onClick: () => onRowClick?.(row.original),
|
|
3975
|
-
className: cn$
|
|
4077
|
+
className: cn$14("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"),
|
|
3976
4078
|
children: row.getVisibleCells().map((cell) => /* @__PURE__ */ jsx("td", {
|
|
3977
|
-
className: cn$
|
|
4079
|
+
className: cn$14(cellPadding, "text-sm text-[var(--dashboard-text-primary,#2d2d2d)]"),
|
|
3978
4080
|
children: flexRender(cell.column.columnDef.cell, cell.getContext())
|
|
3979
4081
|
}, cell.id))
|
|
3980
4082
|
}, row.id))
|
|
@@ -4035,7 +4137,7 @@ function DataGrid({ columns, data, isLoading = false, skeletonRows = 5, sorting:
|
|
|
4035
4137
|
|
|
4036
4138
|
//#endregion
|
|
4037
4139
|
//#region src/components/TreeView/index.tsx
|
|
4038
|
-
const cn$
|
|
4140
|
+
const cn$13 = (...classes) => classes.filter(Boolean).join(" ");
|
|
4039
4141
|
function TreeItem({ node, level, expanded, selectedId, draggable, indentSize, onSelect, onToggle, onMove, renderNode, dragState, setDragState }) {
|
|
4040
4142
|
const hasChildren = node.children && node.children.length > 0;
|
|
4041
4143
|
const isExpanded = expanded.has(node.id);
|
|
@@ -4100,7 +4202,7 @@ function TreeItem({ node, level, expanded, selectedId, draggable, indentSize, on
|
|
|
4100
4202
|
"aria-expanded": hasChildren ? isExpanded : void 0,
|
|
4101
4203
|
"aria-selected": isSelected,
|
|
4102
4204
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
4103
|
-
className: cn$
|
|
4205
|
+
className: cn$13("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"),
|
|
4104
4206
|
style: { paddingLeft: `${level * indentSize + 4}px` },
|
|
4105
4207
|
draggable: draggable && !node.disabled,
|
|
4106
4208
|
onDragStart: handleDragStart,
|
|
@@ -4118,10 +4220,10 @@ function TreeItem({ node, level, expanded, selectedId, draggable, indentSize, on
|
|
|
4118
4220
|
/* @__PURE__ */ jsx("button", {
|
|
4119
4221
|
type: "button",
|
|
4120
4222
|
onClick: () => hasChildren && onToggle(node.id),
|
|
4121
|
-
className: cn$
|
|
4223
|
+
className: cn$13("flex-shrink-0 w-5 h-5 flex items-center justify-center rounded transition-transform", hasChildren ? "cursor-pointer" : "invisible"),
|
|
4122
4224
|
tabIndex: hasChildren ? 0 : -1,
|
|
4123
4225
|
"aria-label": isExpanded ? "Recolher" : "Expandir",
|
|
4124
|
-
children: /* @__PURE__ */ jsx(ChevronRight, { className: cn$
|
|
4226
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { className: cn$13("h-3.5 w-3.5 transition-transform duration-150", isExpanded && "rotate-90") })
|
|
4125
4227
|
}),
|
|
4126
4228
|
renderNode ? /* @__PURE__ */ jsx("div", {
|
|
4127
4229
|
className: "flex-1 min-w-0 cursor-pointer",
|
|
@@ -4133,7 +4235,7 @@ function TreeItem({ node, level, expanded, selectedId, draggable, indentSize, on
|
|
|
4133
4235
|
children: node.icon
|
|
4134
4236
|
}),
|
|
4135
4237
|
/* @__PURE__ */ jsx("span", {
|
|
4136
|
-
className: cn$
|
|
4238
|
+
className: cn$13("flex-1 min-w-0 text-sm truncate", !node.disabled && "cursor-pointer"),
|
|
4137
4239
|
onClick: () => !node.disabled && onSelect?.(node),
|
|
4138
4240
|
children: node.label
|
|
4139
4241
|
}),
|
|
@@ -4186,7 +4288,7 @@ function TreeView({ nodes, onSelect, onExpand, onMove, renderNode, selectedId, d
|
|
|
4186
4288
|
}, [onExpand]);
|
|
4187
4289
|
return /* @__PURE__ */ jsx("ul", {
|
|
4188
4290
|
role: "tree",
|
|
4189
|
-
className: cn$
|
|
4291
|
+
className: cn$13("select-none", className),
|
|
4190
4292
|
children: nodes.map((node) => /* @__PURE__ */ jsx(TreeItem, {
|
|
4191
4293
|
node,
|
|
4192
4294
|
level: 0,
|
|
@@ -4206,7 +4308,7 @@ function TreeView({ nodes, onSelect, onExpand, onMove, renderNode, selectedId, d
|
|
|
4206
4308
|
|
|
4207
4309
|
//#endregion
|
|
4208
4310
|
//#region src/components/Stepper/index.tsx
|
|
4209
|
-
const cn$
|
|
4311
|
+
const cn$12 = (...classes) => classes.filter(Boolean).join(" ");
|
|
4210
4312
|
function StepIcon({ step, index }) {
|
|
4211
4313
|
const status = step.status || "pending";
|
|
4212
4314
|
if (status === "completed") return /* @__PURE__ */ jsx("div", {
|
|
@@ -4250,17 +4352,17 @@ function Stepper({ steps, activeStep, onStepChange, orientation = "horizontal",
|
|
|
4250
4352
|
type: "button",
|
|
4251
4353
|
onClick: () => onStepChange?.(index),
|
|
4252
4354
|
disabled: !onStepChange,
|
|
4253
|
-
className: cn$
|
|
4355
|
+
className: cn$12("relative z-10", onStepChange && "cursor-pointer", !onStepChange && "cursor-default"),
|
|
4254
4356
|
"aria-current": step.status === "active" ? "step" : void 0,
|
|
4255
4357
|
children: /* @__PURE__ */ jsx(StepIcon, {
|
|
4256
4358
|
step,
|
|
4257
4359
|
index
|
|
4258
4360
|
})
|
|
4259
|
-
}), index < resolvedSteps.length - 1 && /* @__PURE__ */ jsx("div", { className: cn$
|
|
4361
|
+
}), index < resolvedSteps.length - 1 && /* @__PURE__ */ jsx("div", { className: cn$12("w-0.5 flex-1 min-h-[32px]", step.status === "completed" ? "bg-[var(--dashboard-primary,#37a501)]" : "bg-[var(--dashboard-text-secondary,#6b7280)]/20") })]
|
|
4260
4362
|
}), /* @__PURE__ */ jsxs("div", {
|
|
4261
|
-
className: cn$
|
|
4363
|
+
className: cn$12("pb-6", index === resolvedSteps.length - 1 && "pb-0"),
|
|
4262
4364
|
children: [/* @__PURE__ */ jsx("p", {
|
|
4263
|
-
className: cn$
|
|
4365
|
+
className: cn$12("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)]"),
|
|
4264
4366
|
children: step.label
|
|
4265
4367
|
}), step.description && /* @__PURE__ */ jsx("p", {
|
|
4266
4368
|
className: "text-xs text-[var(--dashboard-text-secondary,#6b7280)] mt-0.5",
|
|
@@ -4276,12 +4378,12 @@ function Stepper({ steps, activeStep, onStepChange, orientation = "horizontal",
|
|
|
4276
4378
|
children: /* @__PURE__ */ jsx("ol", {
|
|
4277
4379
|
className: "flex items-center",
|
|
4278
4380
|
children: resolvedSteps.map((step, index) => /* @__PURE__ */ jsxs("li", {
|
|
4279
|
-
className: cn$
|
|
4381
|
+
className: cn$12("flex items-center", index < resolvedSteps.length - 1 && "flex-1"),
|
|
4280
4382
|
children: [/* @__PURE__ */ jsxs("button", {
|
|
4281
4383
|
type: "button",
|
|
4282
4384
|
onClick: () => onStepChange?.(index),
|
|
4283
4385
|
disabled: !onStepChange,
|
|
4284
|
-
className: cn$
|
|
4386
|
+
className: cn$12("flex items-center gap-2 group", onStepChange && "cursor-pointer", !onStepChange && "cursor-default"),
|
|
4285
4387
|
"aria-current": step.status === "active" ? "step" : void 0,
|
|
4286
4388
|
children: [/* @__PURE__ */ jsx(StepIcon, {
|
|
4287
4389
|
step,
|
|
@@ -4289,14 +4391,14 @@ function Stepper({ steps, activeStep, onStepChange, orientation = "horizontal",
|
|
|
4289
4391
|
}), /* @__PURE__ */ jsxs("div", {
|
|
4290
4392
|
className: "hidden sm:block text-left",
|
|
4291
4393
|
children: [/* @__PURE__ */ jsx("p", {
|
|
4292
|
-
className: cn$
|
|
4394
|
+
className: cn$12("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)]"),
|
|
4293
4395
|
children: step.label
|
|
4294
4396
|
}), step.description && /* @__PURE__ */ jsx("p", {
|
|
4295
4397
|
className: "text-xs text-[var(--dashboard-text-secondary,#6b7280)] whitespace-nowrap",
|
|
4296
4398
|
children: step.description
|
|
4297
4399
|
})]
|
|
4298
4400
|
})]
|
|
4299
|
-
}), index < resolvedSteps.length - 1 && /* @__PURE__ */ jsx("div", { className: cn$
|
|
4401
|
+
}), index < resolvedSteps.length - 1 && /* @__PURE__ */ jsx("div", { className: cn$12("flex-1 h-0.5 mx-3", step.status === "completed" ? "bg-[var(--dashboard-primary,#37a501)]" : "bg-[var(--dashboard-text-secondary,#6b7280)]/20") })]
|
|
4300
4402
|
}, step.id))
|
|
4301
4403
|
})
|
|
4302
4404
|
});
|
|
@@ -4304,7 +4406,7 @@ function Stepper({ steps, activeStep, onStepChange, orientation = "horizontal",
|
|
|
4304
4406
|
|
|
4305
4407
|
//#endregion
|
|
4306
4408
|
//#region src/components/FileUpload/index.tsx
|
|
4307
|
-
const cn$
|
|
4409
|
+
const cn$11 = (...classes) => classes.filter(Boolean).join(" ");
|
|
4308
4410
|
function formatSize(bytes) {
|
|
4309
4411
|
if (bytes < 1024) return `${bytes} B`;
|
|
4310
4412
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
@@ -4400,7 +4502,7 @@ function FileUpload({ accept, maxSize, multiple = false, onUpload, onRemove, pre
|
|
|
4400
4502
|
onDragOver: handleDragOver,
|
|
4401
4503
|
onDragLeave: handleDragLeave,
|
|
4402
4504
|
onClick: () => !disabled && inputRef.current?.click(),
|
|
4403
|
-
className: cn$
|
|
4505
|
+
className: cn$11("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"),
|
|
4404
4506
|
role: "button",
|
|
4405
4507
|
tabIndex: disabled ? -1 : 0,
|
|
4406
4508
|
"aria-label": label,
|
|
@@ -4423,7 +4525,7 @@ function FileUpload({ accept, maxSize, multiple = false, onUpload, onRemove, pre
|
|
|
4423
4525
|
}), /* @__PURE__ */ jsxs("div", {
|
|
4424
4526
|
className: "flex flex-col items-center text-center",
|
|
4425
4527
|
children: [
|
|
4426
|
-
icon || /* @__PURE__ */ jsx(Upload, { className: cn$
|
|
4528
|
+
icon || /* @__PURE__ */ jsx(Upload, { className: cn$11("h-8 w-8 mb-3", isDragging ? "text-[var(--dashboard-primary,#37a501)]" : "text-[var(--dashboard-text-secondary,#6b7280)]") }),
|
|
4427
4529
|
/* @__PURE__ */ jsx("p", {
|
|
4428
4530
|
className: "text-sm font-medium text-[var(--dashboard-text-primary,#2d2d2d)]",
|
|
4429
4531
|
children: label
|
|
@@ -4490,7 +4592,7 @@ function FileUpload({ accept, maxSize, multiple = false, onUpload, onRemove, pre
|
|
|
4490
4592
|
|
|
4491
4593
|
//#endregion
|
|
4492
4594
|
//#region src/components/Tooltip/index.tsx
|
|
4493
|
-
const cn$
|
|
4595
|
+
const cn$10 = (...classes) => classes.filter(Boolean).join(" ");
|
|
4494
4596
|
function Tooltip({ content, position = "top", delay = 200, children, className, maxWidth = 240 }) {
|
|
4495
4597
|
const [visible, setVisible] = useState(false);
|
|
4496
4598
|
const [positioned, setPositioned] = useState(false);
|
|
@@ -4601,14 +4703,14 @@ function Tooltip({ content, position = "top", delay = 200, children, className,
|
|
|
4601
4703
|
ref: tooltipRef,
|
|
4602
4704
|
id: idRef.current,
|
|
4603
4705
|
role: "tooltip",
|
|
4604
|
-
className: cn$
|
|
4706
|
+
className: cn$10("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),
|
|
4605
4707
|
style: {
|
|
4606
4708
|
top: coords.top,
|
|
4607
4709
|
left: coords.left,
|
|
4608
4710
|
maxWidth,
|
|
4609
4711
|
opacity: positioned ? 1 : 0
|
|
4610
4712
|
},
|
|
4611
|
-
children: [content, /* @__PURE__ */ jsx("span", { className: cn$
|
|
4713
|
+
children: [content, /* @__PURE__ */ jsx("span", { className: cn$10("absolute w-0 h-0 border-[5px]", {
|
|
4612
4714
|
top: "left-1/2 -translate-x-1/2 top-full border-t-[var(--dashboard-tooltip-bg,#1a1a1a)] border-x-transparent border-b-transparent",
|
|
4613
4715
|
bottom: "left-1/2 -translate-x-1/2 bottom-full border-b-[var(--dashboard-tooltip-bg,#1a1a1a)] border-x-transparent border-t-transparent",
|
|
4614
4716
|
left: "top-1/2 -translate-y-1/2 left-full border-l-[var(--dashboard-tooltip-bg,#1a1a1a)] border-y-transparent border-r-transparent",
|
|
@@ -4677,7 +4779,7 @@ function InfoTooltip({ content, term, size = 14, position = "top", maxWidth = 28
|
|
|
4677
4779
|
|
|
4678
4780
|
//#endregion
|
|
4679
4781
|
//#region src/components/Breadcrumb/index.tsx
|
|
4680
|
-
const cn$
|
|
4782
|
+
const cn$9 = (...classes) => classes.filter(Boolean).join(" ");
|
|
4681
4783
|
function Breadcrumb({ items, separator, onNavigate, className }) {
|
|
4682
4784
|
const defaultSeparator = /* @__PURE__ */ jsx(ChevronRight, { className: "h-4 w-4 text-[var(--dashboard-text-secondary,#6b7280)] flex-shrink-0" });
|
|
4683
4785
|
const handleClick = (e, href) => {
|
|
@@ -4699,7 +4801,7 @@ function Breadcrumb({ items, separator, onNavigate, className }) {
|
|
|
4699
4801
|
"aria-hidden": "true",
|
|
4700
4802
|
children: separator || defaultSeparator
|
|
4701
4803
|
}), isLast ? /* @__PURE__ */ jsxs("span", {
|
|
4702
|
-
className: cn$
|
|
4804
|
+
className: cn$9("flex items-center gap-1.5 text-sm font-medium", "text-[var(--dashboard-text-primary,#2d2d2d)]"),
|
|
4703
4805
|
"aria-current": "page",
|
|
4704
4806
|
children: [item.icon && /* @__PURE__ */ jsx("span", {
|
|
4705
4807
|
className: "flex-shrink-0 h-4 w-4",
|
|
@@ -4708,7 +4810,7 @@ function Breadcrumb({ items, separator, onNavigate, className }) {
|
|
|
4708
4810
|
}) : /* @__PURE__ */ jsxs("a", {
|
|
4709
4811
|
href: item.href || "#",
|
|
4710
4812
|
onClick: (e) => handleClick(e, item.href),
|
|
4711
|
-
className: cn$
|
|
4813
|
+
className: cn$9("flex items-center gap-1.5 text-sm", "text-[var(--dashboard-text-secondary,#6b7280)]", "hover:text-[var(--dashboard-primary,#37a501)] transition-colors"),
|
|
4712
4814
|
children: [item.icon && /* @__PURE__ */ jsx("span", {
|
|
4713
4815
|
className: "flex-shrink-0 h-4 w-4",
|
|
4714
4816
|
children: item.icon
|
|
@@ -4722,7 +4824,7 @@ function Breadcrumb({ items, separator, onNavigate, className }) {
|
|
|
4722
4824
|
|
|
4723
4825
|
//#endregion
|
|
4724
4826
|
//#region src/components/Combobox/index.tsx
|
|
4725
|
-
const cn$
|
|
4827
|
+
const cn$8 = (...classes) => classes.filter(Boolean).join(" ");
|
|
4726
4828
|
function Combobox({ options, value, onChange, multiple = false, searchable = true, placeholder = "Selecione...", label, error, disabled = false, renderOption, noResultsText = "Nenhum resultado encontrado", className }) {
|
|
4727
4829
|
const [isOpen, setIsOpen] = useState(false);
|
|
4728
4830
|
const [query, setQuery] = useState("");
|
|
@@ -4852,7 +4954,7 @@ function Combobox({ options, value, onChange, multiple = false, searchable = tru
|
|
|
4852
4954
|
}, [focusedIndex]);
|
|
4853
4955
|
const selectedLabels = selectedValues.map((v) => options.find((o) => o.value === v)?.label).filter(Boolean);
|
|
4854
4956
|
return /* @__PURE__ */ jsxs("div", {
|
|
4855
|
-
className: cn$
|
|
4957
|
+
className: cn$8("space-y-2", className),
|
|
4856
4958
|
children: [
|
|
4857
4959
|
label && /* @__PURE__ */ jsx("label", {
|
|
4858
4960
|
className: "block text-sm text-[var(--dashboard-text-primary,#2d2d2d)]",
|
|
@@ -4868,7 +4970,7 @@ function Combobox({ options, value, onChange, multiple = false, searchable = tru
|
|
|
4868
4970
|
"aria-controls": "combobox-listbox",
|
|
4869
4971
|
tabIndex: disabled ? -1 : 0,
|
|
4870
4972
|
onClick: () => isOpen ? close() : open(),
|
|
4871
|
-
className: cn$
|
|
4973
|
+
className: cn$8("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)]"),
|
|
4872
4974
|
children: [
|
|
4873
4975
|
/* @__PURE__ */ jsx("div", {
|
|
4874
4976
|
className: "flex flex-1 flex-wrap items-center gap-1 min-w-0",
|
|
@@ -4896,7 +4998,7 @@ function Combobox({ options, value, onChange, multiple = false, searchable = tru
|
|
|
4896
4998
|
"aria-label": "Limpar seleção",
|
|
4897
4999
|
children: /* @__PURE__ */ jsx(X, { className: "h-3.5 w-3.5" })
|
|
4898
5000
|
}),
|
|
4899
|
-
/* @__PURE__ */ jsx(ChevronDown, { className: cn$
|
|
5001
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: cn$8("h-4 w-4 flex-shrink-0 text-[var(--dashboard-text-secondary,#6b7280)] transition-transform", isOpen && "rotate-180") })
|
|
4900
5002
|
]
|
|
4901
5003
|
}), isOpen && typeof document !== "undefined" && createPortal(/* @__PURE__ */ jsxs("div", {
|
|
4902
5004
|
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",
|
|
@@ -4941,7 +5043,7 @@ function Combobox({ options, value, onChange, multiple = false, searchable = tru
|
|
|
4941
5043
|
onClick: () => {
|
|
4942
5044
|
if (!option.disabled) toggleOption(option.value);
|
|
4943
5045
|
},
|
|
4944
|
-
className: cn$
|
|
5046
|
+
className: cn$8("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)]"),
|
|
4945
5047
|
children: renderOption ? renderOption(option, isSelected) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
4946
5048
|
className: "truncate",
|
|
4947
5049
|
children: option.label
|
|
@@ -4961,7 +5063,7 @@ function Combobox({ options, value, onChange, multiple = false, searchable = tru
|
|
|
4961
5063
|
|
|
4962
5064
|
//#endregion
|
|
4963
5065
|
//#region src/components/Alert/index.tsx
|
|
4964
|
-
const cn$
|
|
5066
|
+
const cn$7 = (...classes) => classes.filter(Boolean).join(" ");
|
|
4965
5067
|
const variantConfig$1 = {
|
|
4966
5068
|
info: {
|
|
4967
5069
|
border: "border-[var(--dashboard-status-info,#3b82f6)]",
|
|
@@ -4991,24 +5093,24 @@ const variantConfig$1 = {
|
|
|
4991
5093
|
function Alert({ variant = "info", title, description, onClose, actions, icon, className }) {
|
|
4992
5094
|
const config = variantConfig$1[variant];
|
|
4993
5095
|
return /* @__PURE__ */ jsx("div", {
|
|
4994
|
-
className: cn$
|
|
5096
|
+
className: cn$7("rounded-lg border-l-4 p-4", config.border, config.bg, className),
|
|
4995
5097
|
role: "alert",
|
|
4996
5098
|
children: /* @__PURE__ */ jsxs("div", {
|
|
4997
5099
|
className: "flex gap-3",
|
|
4998
5100
|
children: [
|
|
4999
5101
|
/* @__PURE__ */ jsx("div", {
|
|
5000
|
-
className: cn$
|
|
5102
|
+
className: cn$7("flex-shrink-0 mt-0.5", config.text),
|
|
5001
5103
|
children: icon || config.icon
|
|
5002
5104
|
}),
|
|
5003
5105
|
/* @__PURE__ */ jsxs("div", {
|
|
5004
5106
|
className: "flex-1 min-w-0",
|
|
5005
5107
|
children: [
|
|
5006
5108
|
title && /* @__PURE__ */ jsx("h3", {
|
|
5007
|
-
className: cn$
|
|
5109
|
+
className: cn$7("text-sm font-semibold", "text-[var(--dashboard-text-primary,#2d2d2d)]"),
|
|
5008
5110
|
children: title
|
|
5009
5111
|
}),
|
|
5010
5112
|
description && /* @__PURE__ */ jsx("div", {
|
|
5011
|
-
className: cn$
|
|
5113
|
+
className: cn$7("text-sm text-[var(--dashboard-text-secondary,#6b7280)]", title && "mt-1"),
|
|
5012
5114
|
children: description
|
|
5013
5115
|
}),
|
|
5014
5116
|
actions && /* @__PURE__ */ jsx("div", {
|
|
@@ -5030,7 +5132,7 @@ function Alert({ variant = "info", title, description, onClose, actions, icon, c
|
|
|
5030
5132
|
|
|
5031
5133
|
//#endregion
|
|
5032
5134
|
//#region src/components/Callout/index.tsx
|
|
5033
|
-
const cn$
|
|
5135
|
+
const cn$6 = (...classes) => classes.filter(Boolean).join(" ");
|
|
5034
5136
|
const variantConfig = {
|
|
5035
5137
|
info: {
|
|
5036
5138
|
border: "border-[var(--dashboard-status-info,#3b82f6)]",
|
|
@@ -5060,20 +5162,20 @@ const variantConfig = {
|
|
|
5060
5162
|
function Callout({ variant = "info", title, children, icon, className }) {
|
|
5061
5163
|
const config = variantConfig[variant];
|
|
5062
5164
|
return /* @__PURE__ */ jsx("div", {
|
|
5063
|
-
className: cn$
|
|
5165
|
+
className: cn$6("rounded-lg border-l-4 p-4 my-4", config.border, config.bg, className),
|
|
5064
5166
|
role: "note",
|
|
5065
5167
|
children: /* @__PURE__ */ jsxs("div", {
|
|
5066
5168
|
className: "flex gap-3",
|
|
5067
5169
|
children: [/* @__PURE__ */ jsx("div", {
|
|
5068
|
-
className: cn$
|
|
5170
|
+
className: cn$6("flex-shrink-0 mt-0.5", config.text),
|
|
5069
5171
|
children: icon || config.icon
|
|
5070
5172
|
}), /* @__PURE__ */ jsxs("div", {
|
|
5071
5173
|
className: "flex-1 min-w-0",
|
|
5072
5174
|
children: [title && /* @__PURE__ */ jsx("p", {
|
|
5073
|
-
className: cn$
|
|
5175
|
+
className: cn$6("text-sm font-semibold", "text-[var(--dashboard-text-primary,#2d2d2d)]"),
|
|
5074
5176
|
children: title
|
|
5075
5177
|
}), children && /* @__PURE__ */ jsx("div", {
|
|
5076
|
-
className: cn$
|
|
5178
|
+
className: cn$6("text-sm text-[var(--dashboard-text-secondary,#6b7280)]", title && "mt-1"),
|
|
5077
5179
|
children
|
|
5078
5180
|
})]
|
|
5079
5181
|
})]
|
|
@@ -5083,7 +5185,7 @@ function Callout({ variant = "info", title, children, icon, className }) {
|
|
|
5083
5185
|
|
|
5084
5186
|
//#endregion
|
|
5085
5187
|
//#region src/components/CodeBlock/index.tsx
|
|
5086
|
-
const cn$
|
|
5188
|
+
const cn$5 = (...classes) => classes.filter(Boolean).join(" ");
|
|
5087
5189
|
function CodeBlock({ code, language, filename, showLineNumbers = false, className, copyLabel = "Copiar", copiedLabel = "Copiado!" }) {
|
|
5088
5190
|
const [copied, setCopied] = useState(false);
|
|
5089
5191
|
const handleCopy = useCallback(async () => {
|
|
@@ -5095,7 +5197,7 @@ function CodeBlock({ code, language, filename, showLineNumbers = false, classNam
|
|
|
5095
5197
|
}, [code]);
|
|
5096
5198
|
const lines = code.split("\n");
|
|
5097
5199
|
return /* @__PURE__ */ jsxs("div", {
|
|
5098
|
-
className: cn$
|
|
5200
|
+
className: cn$5("relative rounded-lg overflow-hidden border border-[var(--dashboard-text-secondary,#64748B)]/12 my-4", className),
|
|
5099
5201
|
children: [(filename || language) && /* @__PURE__ */ jsxs("div", {
|
|
5100
5202
|
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
5203
|
children: [
|
|
@@ -5129,7 +5231,7 @@ function CodeBlock({ code, language, filename, showLineNumbers = false, classNam
|
|
|
5129
5231
|
})
|
|
5130
5232
|
}), /* @__PURE__ */ jsxs("button", {
|
|
5131
5233
|
onClick: handleCopy,
|
|
5132
|
-
className: cn$
|
|
5234
|
+
className: cn$5("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
5235
|
"aria-label": copied ? copiedLabel : copyLabel,
|
|
5134
5236
|
title: copied ? copiedLabel : copyLabel,
|
|
5135
5237
|
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 })]
|
|
@@ -5140,10 +5242,10 @@ function CodeBlock({ code, language, filename, showLineNumbers = false, classNam
|
|
|
5140
5242
|
|
|
5141
5243
|
//#endregion
|
|
5142
5244
|
//#region src/components/EmptyState/index.tsx
|
|
5143
|
-
const cn$
|
|
5245
|
+
const cn$4 = (...classes) => classes.filter(Boolean).join(" ");
|
|
5144
5246
|
function EmptyState({ icon, title, description, action, className }) {
|
|
5145
5247
|
return /* @__PURE__ */ jsxs("div", {
|
|
5146
|
-
className: cn$
|
|
5248
|
+
className: cn$4("flex flex-col items-center justify-center py-12 px-6 text-center", className),
|
|
5147
5249
|
children: [
|
|
5148
5250
|
/* @__PURE__ */ jsx("div", {
|
|
5149
5251
|
className: "flex h-16 w-16 items-center justify-center rounded-full bg-[var(--dashboard-text-secondary,#6b7280)]/10 mb-4",
|
|
@@ -5167,7 +5269,7 @@ function EmptyState({ icon, title, description, action, className }) {
|
|
|
5167
5269
|
|
|
5168
5270
|
//#endregion
|
|
5169
5271
|
//#region src/components/StatusBadge/index.tsx
|
|
5170
|
-
const cn$
|
|
5272
|
+
const cn$3 = (...classes) => classes.filter(Boolean).join(" ");
|
|
5171
5273
|
const defaultColorMap = {
|
|
5172
5274
|
ACTIVE: "var(--dashboard-status-success,#10B981)",
|
|
5173
5275
|
APPROVED: "var(--dashboard-status-success,#10B981)",
|
|
@@ -5209,120 +5311,1362 @@ function StatusBadge({ status, colorMap, size = "md", label, dot = true, classNa
|
|
|
5209
5311
|
}[status.toUpperCase().replace(/[\s-]/g, "_")] || "var(--dashboard-text-secondary,#6b7280)";
|
|
5210
5312
|
const displayLabel = label || formatLabel(status);
|
|
5211
5313
|
return /* @__PURE__ */ jsxs("span", {
|
|
5212
|
-
className: cn$
|
|
5314
|
+
className: cn$3("inline-flex items-center gap-1.5 rounded-full font-medium whitespace-nowrap", sizeClasses[size], className),
|
|
5213
5315
|
style: {
|
|
5214
5316
|
color,
|
|
5215
5317
|
backgroundColor: `color-mix(in srgb, ${color} 12%, transparent)`
|
|
5216
5318
|
},
|
|
5217
5319
|
children: [dot && /* @__PURE__ */ jsx("span", {
|
|
5218
|
-
className: cn$
|
|
5320
|
+
className: cn$3("rounded-full flex-shrink-0", dotSizeClasses[size]),
|
|
5219
5321
|
style: { backgroundColor: color }
|
|
5220
5322
|
}), displayLabel]
|
|
5221
5323
|
});
|
|
5222
5324
|
}
|
|
5223
5325
|
|
|
5224
5326
|
//#endregion
|
|
5225
|
-
//#region src/components/
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5327
|
+
//#region src/components/IPhoneMockup/index.tsx
|
|
5328
|
+
function IPhoneMockup({ screenWidth, screenType = "island", isLandscape = false, frameColor = "#666666", frameOnly = false, statusbarColor = "#CCCCCC", hideStatusBar = false, transparentNavBar = false, hideNavBar = false, className, containerStyle, containerStlye, children }) {
|
|
5329
|
+
const Mockup = useMemo(() => {
|
|
5330
|
+
if (screenType === "legacy") return isLandscape ? IPhoneLegacyLandscape : IPhoneLegacyPortrait;
|
|
5331
|
+
if (screenType === "notch") return isLandscape ? IPhoneNotchLandscape : IPhoneNotchPortrait;
|
|
5332
|
+
return isLandscape ? IPhoneIslandLandscape : IPhoneIslandPortrait;
|
|
5333
|
+
}, [isLandscape, screenType]);
|
|
5334
|
+
return /* @__PURE__ */ jsx("div", {
|
|
5335
|
+
className,
|
|
5336
|
+
style: containerStyle ?? containerStlye,
|
|
5337
|
+
children: /* @__PURE__ */ jsx(Mockup, {
|
|
5338
|
+
screenWidth,
|
|
5339
|
+
frameColor,
|
|
5340
|
+
frameOnly,
|
|
5341
|
+
statusbarColor,
|
|
5342
|
+
hideStatusBar,
|
|
5343
|
+
transparentNavigationBar: transparentNavBar,
|
|
5344
|
+
hideNavigationBar: hideNavBar,
|
|
5345
|
+
children
|
|
5346
|
+
})
|
|
5347
|
+
});
|
|
5230
5348
|
}
|
|
5231
|
-
function
|
|
5232
|
-
|
|
5233
|
-
if (a.length !== b.length) return false;
|
|
5234
|
-
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
5235
|
-
return true;
|
|
5349
|
+
function createStyles(styles) {
|
|
5350
|
+
return styles;
|
|
5236
5351
|
}
|
|
5237
|
-
function
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5352
|
+
function getStyles({ screenType, isLandscape, getSizeWithRatio, screenWidth, mockupHeight, frameColor, frameWidth, statusbarColor, frameOnly, bezelRadius }) {
|
|
5353
|
+
const frameWidthValue = frameWidth;
|
|
5354
|
+
const halfFrameWidth = Math.floor(frameWidthValue / 2);
|
|
5355
|
+
const widthAndFrame = screenWidth + frameWidthValue * 2;
|
|
5356
|
+
const heightAndFrame = mockupHeight + frameWidthValue * 2;
|
|
5357
|
+
const frameButtonSize = Math.floor(frameWidthValue * .9);
|
|
5358
|
+
const frameButtonPosition = (isLandscape ? mockupHeight : screenWidth) + frameWidthValue + halfFrameWidth + frameButtonSize - halfFrameWidth;
|
|
5359
|
+
const paddingRight = frameOnly ? 0 : isLandscape ? 0 : frameButtonSize - halfFrameWidth;
|
|
5360
|
+
const paddingLeft = paddingRight;
|
|
5361
|
+
const paddingTop = frameOnly ? 0 : isLandscape ? frameButtonSize - halfFrameWidth : 0;
|
|
5362
|
+
const paddingBottom = paddingTop;
|
|
5363
|
+
const isIsland = screenType === "island";
|
|
5364
|
+
const topInset = isLandscape ? 0 : getSizeWithRatio(isIsland ? 59 : 44);
|
|
5365
|
+
const leftInset = isLandscape ? getSizeWithRatio(isIsland ? 59 : 44) : 0;
|
|
5366
|
+
const rightInset = leftInset;
|
|
5367
|
+
const bottomInset = isLandscape ? getSizeWithRatio(21) : getSizeWithRatio(34);
|
|
5368
|
+
const powerPosition = getSizeWithRatio(isIsland ? 280 : 250);
|
|
5369
|
+
return createStyles({
|
|
5370
|
+
container: {
|
|
5371
|
+
display: "flex",
|
|
5372
|
+
flexDirection: isLandscape ? "row" : "column",
|
|
5373
|
+
boxSizing: "content-box",
|
|
5374
|
+
position: "relative",
|
|
5375
|
+
width: widthAndFrame,
|
|
5376
|
+
height: heightAndFrame,
|
|
5377
|
+
paddingRight,
|
|
5378
|
+
paddingLeft,
|
|
5379
|
+
paddingTop,
|
|
5380
|
+
paddingBottom
|
|
5381
|
+
},
|
|
5382
|
+
frame: {
|
|
5383
|
+
display: "flex",
|
|
5384
|
+
flexDirection: "column",
|
|
5385
|
+
position: "relative",
|
|
5386
|
+
boxSizing: "border-box",
|
|
5387
|
+
borderRadius: bezelRadius,
|
|
5388
|
+
borderStyle: "solid",
|
|
5389
|
+
borderWidth: frameWidthValue,
|
|
5390
|
+
borderColor: frameColor,
|
|
5391
|
+
overflow: "hidden"
|
|
5392
|
+
},
|
|
5393
|
+
screen: {
|
|
5394
|
+
display: "flex",
|
|
5395
|
+
flexDirection: isLandscape ? "row" : "column",
|
|
5396
|
+
position: "relative",
|
|
5397
|
+
width: screenWidth,
|
|
5398
|
+
height: mockupHeight,
|
|
5399
|
+
backgroundColor: "transparent",
|
|
5400
|
+
overflow: "hidden"
|
|
5401
|
+
},
|
|
5402
|
+
notchContainer: {
|
|
5403
|
+
display: "flex",
|
|
5404
|
+
flexDirection: "column",
|
|
5405
|
+
width: isLandscape ? leftInset : "100%",
|
|
5406
|
+
height: isLandscape ? "100%" : topInset,
|
|
5407
|
+
backgroundColor: statusbarColor,
|
|
5408
|
+
alignItems: isLandscape ? "flex-start" : "center",
|
|
5409
|
+
justifyContent: isLandscape ? "center" : "flex-start"
|
|
5410
|
+
},
|
|
5411
|
+
notchContainerFullScreen: {
|
|
5412
|
+
display: "flex",
|
|
5413
|
+
flexDirection: "column",
|
|
5414
|
+
position: "absolute",
|
|
5415
|
+
width: isLandscape ? leftInset : "100%",
|
|
5416
|
+
height: isLandscape ? "100%" : topInset,
|
|
5417
|
+
alignItems: isLandscape ? "flex-start" : "center",
|
|
5418
|
+
justifyContent: isLandscape ? "center" : "flex-start",
|
|
5419
|
+
pointerEvents: "none"
|
|
5420
|
+
},
|
|
5421
|
+
safeAreaRight: {
|
|
5422
|
+
width: rightInset,
|
|
5423
|
+
height: "100%",
|
|
5424
|
+
backgroundColor: statusbarColor
|
|
5425
|
+
},
|
|
5426
|
+
island: {
|
|
5427
|
+
width: isLandscape ? getSizeWithRatio(35) : getSizeWithRatio(128),
|
|
5428
|
+
height: isLandscape ? getSizeWithRatio(128) : getSizeWithRatio(35),
|
|
5429
|
+
backgroundColor: frameColor,
|
|
5430
|
+
borderRadius: getSizeWithRatio(50),
|
|
5431
|
+
marginTop: isLandscape ? void 0 : getSizeWithRatio(13),
|
|
5432
|
+
marginLeft: isLandscape ? getSizeWithRatio(13) : void 0
|
|
5433
|
+
},
|
|
5434
|
+
notch: {
|
|
5435
|
+
width: isLandscape ? getSizeWithRatio(31) : getSizeWithRatio(160),
|
|
5436
|
+
height: isLandscape ? getSizeWithRatio(160) : getSizeWithRatio(31),
|
|
5437
|
+
backgroundColor: frameColor,
|
|
5438
|
+
borderBottomLeftRadius: isLandscape ? 0 : getSizeWithRatio(20),
|
|
5439
|
+
borderBottomRightRadius: getSizeWithRatio(20),
|
|
5440
|
+
borderTopRightRadius: isLandscape ? getSizeWithRatio(20) : 0
|
|
5441
|
+
},
|
|
5442
|
+
swipeContainer: {
|
|
5443
|
+
display: "flex",
|
|
5444
|
+
flexDirection: "column",
|
|
5445
|
+
width: "100%",
|
|
5446
|
+
height: bottomInset,
|
|
5447
|
+
backgroundColor: statusbarColor,
|
|
5448
|
+
alignItems: "center",
|
|
5449
|
+
justifyContent: "flex-end"
|
|
5450
|
+
},
|
|
5451
|
+
swipeContainerFullScreen: {
|
|
5452
|
+
display: "flex",
|
|
5453
|
+
flexDirection: "column",
|
|
5454
|
+
position: "absolute",
|
|
5455
|
+
bottom: 0,
|
|
5456
|
+
width: "100%",
|
|
5457
|
+
height: bottomInset,
|
|
5458
|
+
alignItems: "center",
|
|
5459
|
+
justifyContent: "flex-end",
|
|
5460
|
+
pointerEvents: "none"
|
|
5461
|
+
},
|
|
5462
|
+
swipeBar: {
|
|
5463
|
+
backgroundColor: frameColor,
|
|
5464
|
+
borderRadius: getSizeWithRatio(100),
|
|
5465
|
+
width: isLandscape ? getSizeWithRatio(230) : "35%",
|
|
5466
|
+
height: getSizeWithRatio(7),
|
|
5467
|
+
marginBottom: isLandscape ? getSizeWithRatio(5) : getSizeWithRatio(10)
|
|
5468
|
+
},
|
|
5469
|
+
silenceSwitch: {
|
|
5470
|
+
position: "absolute",
|
|
5471
|
+
borderRadius: frameWidthValue,
|
|
5472
|
+
top: isLandscape ? frameButtonPosition : getSizeWithRatio(165),
|
|
5473
|
+
left: isLandscape ? getSizeWithRatio(165) : void 0,
|
|
5474
|
+
right: isLandscape ? void 0 : frameButtonPosition,
|
|
5475
|
+
width: isLandscape ? getSizeWithRatio(34) : frameButtonSize,
|
|
5476
|
+
height: isLandscape ? frameButtonSize : getSizeWithRatio(34),
|
|
5477
|
+
backgroundColor: frameColor
|
|
5478
|
+
},
|
|
5479
|
+
volumeUp: {
|
|
5480
|
+
position: "absolute",
|
|
5481
|
+
borderRadius: frameWidthValue,
|
|
5482
|
+
top: isLandscape ? frameButtonPosition : getSizeWithRatio(230),
|
|
5483
|
+
left: isLandscape ? getSizeWithRatio(230) : void 0,
|
|
5484
|
+
right: isLandscape ? void 0 : frameButtonPosition,
|
|
5485
|
+
width: isLandscape ? getSizeWithRatio(65) : frameButtonSize,
|
|
5486
|
+
height: isLandscape ? frameButtonSize : getSizeWithRatio(65),
|
|
5487
|
+
backgroundColor: frameColor
|
|
5488
|
+
},
|
|
5489
|
+
volumeDown: {
|
|
5490
|
+
position: "absolute",
|
|
5491
|
+
borderRadius: frameWidthValue,
|
|
5492
|
+
top: isLandscape ? frameButtonPosition : getSizeWithRatio(315),
|
|
5493
|
+
left: isLandscape ? getSizeWithRatio(315) : void 0,
|
|
5494
|
+
right: isLandscape ? void 0 : frameButtonPosition,
|
|
5495
|
+
width: isLandscape ? getSizeWithRatio(65) : frameButtonSize,
|
|
5496
|
+
height: isLandscape ? frameButtonSize : getSizeWithRatio(65),
|
|
5497
|
+
backgroundColor: frameColor
|
|
5498
|
+
},
|
|
5499
|
+
power: {
|
|
5500
|
+
position: "absolute",
|
|
5501
|
+
borderRadius: frameWidthValue,
|
|
5502
|
+
top: isLandscape ? void 0 : powerPosition,
|
|
5503
|
+
left: isLandscape ? powerPosition : frameButtonPosition,
|
|
5504
|
+
bottom: isLandscape ? frameButtonPosition : void 0,
|
|
5505
|
+
width: isLandscape ? getSizeWithRatio(105) : frameButtonSize,
|
|
5506
|
+
height: isLandscape ? frameButtonSize : getSizeWithRatio(105),
|
|
5507
|
+
backgroundColor: frameColor
|
|
5508
|
+
},
|
|
5509
|
+
notchPad: {
|
|
5510
|
+
alignSelf: "center",
|
|
5511
|
+
position: "absolute",
|
|
5512
|
+
top: isLandscape ? void 0 : halfFrameWidth,
|
|
5513
|
+
left: isLandscape ? halfFrameWidth : void 0,
|
|
5514
|
+
width: isLandscape ? getSizeWithRatio(20) : getSizeWithRatio(160),
|
|
5515
|
+
height: isLandscape ? getSizeWithRatio(160) : getSizeWithRatio(20),
|
|
5516
|
+
backgroundColor: frameColor
|
|
5243
5517
|
}
|
|
5244
|
-
current = current.parentElement;
|
|
5245
|
-
}
|
|
5246
|
-
return document.documentElement;
|
|
5247
|
-
}
|
|
5248
|
-
function scrollAnchorIntoView(anchor, container, options = {}) {
|
|
5249
|
-
const { behavior = "smooth", block = "center" } = options;
|
|
5250
|
-
const containerRect = container.getBoundingClientRect();
|
|
5251
|
-
const offsetTopRelativeToContainer = anchor.getBoundingClientRect().top - containerRect.top + container.scrollTop;
|
|
5252
|
-
let targetScroll;
|
|
5253
|
-
if (block === "center") targetScroll = offsetTopRelativeToContainer - container.clientHeight / 2 + anchor.clientHeight / 2;
|
|
5254
|
-
else if (block === "end") targetScroll = offsetTopRelativeToContainer - container.clientHeight + anchor.clientHeight;
|
|
5255
|
-
else targetScroll = offsetTopRelativeToContainer;
|
|
5256
|
-
container.scrollTo({
|
|
5257
|
-
top: Math.max(0, targetScroll),
|
|
5258
|
-
behavior
|
|
5259
5518
|
});
|
|
5260
5519
|
}
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
5271
|
-
|
|
5272
|
-
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
const el = document.getElementById(item.id);
|
|
5277
|
-
if (el) this.intersectionObserver.unobserve(el);
|
|
5278
|
-
}
|
|
5279
|
-
const next = [];
|
|
5280
|
-
for (const item of nextItems) {
|
|
5281
|
-
const id = getIdFromUrl(item.url);
|
|
5282
|
-
if (!id) continue;
|
|
5283
|
-
next.push({
|
|
5284
|
-
id,
|
|
5285
|
-
active: false,
|
|
5286
|
-
fallback: false,
|
|
5287
|
-
t: 0,
|
|
5288
|
-
original: item
|
|
5289
|
-
});
|
|
5290
|
-
}
|
|
5291
|
-
this.update(next);
|
|
5292
|
-
this.observeAll();
|
|
5293
|
-
}
|
|
5294
|
-
watch(options) {
|
|
5295
|
-
if (this.intersectionObserver) return;
|
|
5296
|
-
if (typeof window === "undefined") return;
|
|
5297
|
-
this.intersectionObserver = new IntersectionObserver(this.handleIntersection.bind(this), options);
|
|
5298
|
-
this.observeAll();
|
|
5299
|
-
}
|
|
5300
|
-
unwatch() {
|
|
5301
|
-
this.intersectionObserver?.disconnect();
|
|
5302
|
-
this.intersectionObserver = null;
|
|
5303
|
-
}
|
|
5304
|
-
handleIntersection(entries) {
|
|
5305
|
-
if (entries.length === 0) return;
|
|
5306
|
-
let hasActive = false;
|
|
5307
|
-
const updated = this.items.map((item) => {
|
|
5308
|
-
const entry = entries.find((e) => e.target.id === item.id);
|
|
5309
|
-
let active = entry ? entry.isIntersecting : item.active && !item.fallback;
|
|
5310
|
-
if (this.single && hasActive) active = false;
|
|
5311
|
-
let nextItem = item;
|
|
5312
|
-
if (item.active !== active) nextItem = {
|
|
5313
|
-
...item,
|
|
5314
|
-
t: Date.now(),
|
|
5315
|
-
active,
|
|
5316
|
-
fallback: false
|
|
5317
|
-
};
|
|
5318
|
-
if (active) hasActive = true;
|
|
5319
|
-
return nextItem;
|
|
5520
|
+
function IPhoneIslandPortrait(props) {
|
|
5521
|
+
const { screenWidth, frameColor, frameOnly, statusbarColor, hideStatusBar, hideNavigationBar, transparentNavigationBar, children } = props;
|
|
5522
|
+
const styles = useMemo(() => {
|
|
5523
|
+
const getSizeWithRatio = (size) => Math.max(Math.floor(screenWidth * size / 390), 1);
|
|
5524
|
+
return getStyles({
|
|
5525
|
+
screenType: "island",
|
|
5526
|
+
isLandscape: false,
|
|
5527
|
+
getSizeWithRatio,
|
|
5528
|
+
screenWidth,
|
|
5529
|
+
mockupHeight: Math.floor(screenWidth / 9 * 19.5),
|
|
5530
|
+
frameColor,
|
|
5531
|
+
frameWidth: getSizeWithRatio(10),
|
|
5532
|
+
frameOnly,
|
|
5533
|
+
statusbarColor,
|
|
5534
|
+
bezelRadius: getSizeWithRatio(68)
|
|
5320
5535
|
});
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5536
|
+
}, [
|
|
5537
|
+
screenWidth,
|
|
5538
|
+
frameColor,
|
|
5539
|
+
statusbarColor,
|
|
5540
|
+
frameOnly
|
|
5541
|
+
]);
|
|
5542
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
5543
|
+
style: styles.container,
|
|
5544
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
5545
|
+
style: styles.frame,
|
|
5546
|
+
children: [
|
|
5547
|
+
/* @__PURE__ */ jsxs("div", {
|
|
5548
|
+
style: styles.screen,
|
|
5549
|
+
children: [
|
|
5550
|
+
!hideStatusBar && /* @__PURE__ */ jsx("div", {
|
|
5551
|
+
style: styles.notchContainer,
|
|
5552
|
+
children: /* @__PURE__ */ jsx("div", { style: styles.island })
|
|
5553
|
+
}),
|
|
5554
|
+
/* @__PURE__ */ jsx("div", {
|
|
5555
|
+
style: {
|
|
5556
|
+
display: "flex",
|
|
5557
|
+
flex: 1,
|
|
5558
|
+
overflow: "hidden"
|
|
5559
|
+
},
|
|
5560
|
+
children
|
|
5561
|
+
}),
|
|
5562
|
+
!hideNavigationBar && !transparentNavigationBar && /* @__PURE__ */ jsx("div", {
|
|
5563
|
+
style: styles.swipeContainer,
|
|
5564
|
+
children: /* @__PURE__ */ jsx("div", { style: styles.swipeBar })
|
|
5565
|
+
})
|
|
5566
|
+
]
|
|
5567
|
+
}),
|
|
5568
|
+
hideStatusBar && /* @__PURE__ */ jsx("div", {
|
|
5569
|
+
style: styles.notchContainerFullScreen,
|
|
5570
|
+
children: /* @__PURE__ */ jsx("div", { style: styles.island })
|
|
5571
|
+
}),
|
|
5572
|
+
!hideNavigationBar && transparentNavigationBar && /* @__PURE__ */ jsx("div", {
|
|
5573
|
+
style: styles.swipeContainerFullScreen,
|
|
5574
|
+
children: /* @__PURE__ */ jsx("div", { style: styles.swipeBar })
|
|
5575
|
+
})
|
|
5576
|
+
]
|
|
5577
|
+
}), !frameOnly && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5578
|
+
/* @__PURE__ */ jsx("div", { style: styles.silenceSwitch }),
|
|
5579
|
+
/* @__PURE__ */ jsx("div", { style: styles.volumeUp }),
|
|
5580
|
+
/* @__PURE__ */ jsx("div", { style: styles.volumeDown }),
|
|
5581
|
+
/* @__PURE__ */ jsx("div", { style: styles.power })
|
|
5582
|
+
] })]
|
|
5583
|
+
});
|
|
5584
|
+
}
|
|
5585
|
+
function IPhoneIslandLandscape(props) {
|
|
5586
|
+
const { screenWidth, frameColor, frameOnly, statusbarColor, hideStatusBar, hideNavigationBar, transparentNavigationBar, children } = props;
|
|
5587
|
+
const styles = useMemo(() => {
|
|
5588
|
+
const getSizeWithRatio = (size) => Math.max(Math.floor(screenWidth * size / 844), 1);
|
|
5589
|
+
return getStyles({
|
|
5590
|
+
screenType: "island",
|
|
5591
|
+
isLandscape: true,
|
|
5592
|
+
getSizeWithRatio,
|
|
5593
|
+
screenWidth,
|
|
5594
|
+
mockupHeight: Math.floor(screenWidth / 19.5 * 9),
|
|
5595
|
+
frameColor,
|
|
5596
|
+
frameWidth: getSizeWithRatio(10),
|
|
5597
|
+
frameOnly,
|
|
5598
|
+
statusbarColor,
|
|
5599
|
+
bezelRadius: getSizeWithRatio(68)
|
|
5600
|
+
});
|
|
5601
|
+
}, [
|
|
5602
|
+
screenWidth,
|
|
5603
|
+
frameColor,
|
|
5604
|
+
statusbarColor,
|
|
5605
|
+
frameOnly
|
|
5606
|
+
]);
|
|
5607
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
5608
|
+
style: styles.container,
|
|
5609
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
5610
|
+
style: styles.frame,
|
|
5611
|
+
children: [
|
|
5612
|
+
/* @__PURE__ */ jsxs("div", {
|
|
5613
|
+
style: styles.screen,
|
|
5614
|
+
children: [
|
|
5615
|
+
!hideStatusBar && /* @__PURE__ */ jsx("div", {
|
|
5616
|
+
style: styles.notchContainer,
|
|
5617
|
+
children: /* @__PURE__ */ jsx("div", { style: styles.island })
|
|
5618
|
+
}),
|
|
5619
|
+
/* @__PURE__ */ jsxs("div", {
|
|
5620
|
+
style: {
|
|
5621
|
+
display: "flex",
|
|
5622
|
+
flex: 1,
|
|
5623
|
+
flexDirection: "column"
|
|
5624
|
+
},
|
|
5625
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
5626
|
+
style: {
|
|
5627
|
+
display: "flex",
|
|
5628
|
+
flex: 1,
|
|
5629
|
+
overflow: "hidden"
|
|
5630
|
+
},
|
|
5631
|
+
children
|
|
5632
|
+
}), !hideNavigationBar && !transparentNavigationBar && /* @__PURE__ */ jsx("div", {
|
|
5633
|
+
style: styles.swipeContainer,
|
|
5634
|
+
children: /* @__PURE__ */ jsx("div", { style: styles.swipeBar })
|
|
5635
|
+
})]
|
|
5636
|
+
}),
|
|
5637
|
+
!hideStatusBar && /* @__PURE__ */ jsx("div", { style: styles.safeAreaRight })
|
|
5638
|
+
]
|
|
5639
|
+
}),
|
|
5640
|
+
hideStatusBar && /* @__PURE__ */ jsx("div", {
|
|
5641
|
+
style: styles.notchContainerFullScreen,
|
|
5642
|
+
children: /* @__PURE__ */ jsx("div", { style: styles.island })
|
|
5643
|
+
}),
|
|
5644
|
+
!hideNavigationBar && transparentNavigationBar && /* @__PURE__ */ jsx("div", {
|
|
5645
|
+
style: styles.swipeContainerFullScreen,
|
|
5646
|
+
children: /* @__PURE__ */ jsx("div", { style: styles.swipeBar })
|
|
5647
|
+
})
|
|
5648
|
+
]
|
|
5649
|
+
}), !frameOnly && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5650
|
+
/* @__PURE__ */ jsx("div", { style: styles.silenceSwitch }),
|
|
5651
|
+
/* @__PURE__ */ jsx("div", { style: styles.volumeUp }),
|
|
5652
|
+
/* @__PURE__ */ jsx("div", { style: styles.volumeDown }),
|
|
5653
|
+
/* @__PURE__ */ jsx("div", { style: styles.power })
|
|
5654
|
+
] })]
|
|
5655
|
+
});
|
|
5656
|
+
}
|
|
5657
|
+
function IPhoneNotchPortrait(props) {
|
|
5658
|
+
const { screenWidth, frameColor, frameOnly, statusbarColor, hideStatusBar, hideNavigationBar, transparentNavigationBar, children } = props;
|
|
5659
|
+
const styles = useMemo(() => {
|
|
5660
|
+
const getSizeWithRatio = (size) => Math.max(Math.floor(screenWidth * size / 390), 1);
|
|
5661
|
+
return getStyles({
|
|
5662
|
+
screenType: "notch",
|
|
5663
|
+
isLandscape: false,
|
|
5664
|
+
getSizeWithRatio,
|
|
5665
|
+
screenWidth,
|
|
5666
|
+
mockupHeight: Math.floor(screenWidth / 9 * 19.5),
|
|
5667
|
+
frameColor,
|
|
5668
|
+
frameWidth: getSizeWithRatio(14),
|
|
5669
|
+
frameOnly,
|
|
5670
|
+
statusbarColor,
|
|
5671
|
+
bezelRadius: getSizeWithRatio(64)
|
|
5672
|
+
});
|
|
5673
|
+
}, [
|
|
5674
|
+
screenWidth,
|
|
5675
|
+
frameColor,
|
|
5676
|
+
statusbarColor,
|
|
5677
|
+
frameOnly
|
|
5678
|
+
]);
|
|
5679
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
5680
|
+
style: styles.container,
|
|
5681
|
+
children: [
|
|
5682
|
+
/* @__PURE__ */ jsxs("div", {
|
|
5683
|
+
style: styles.frame,
|
|
5684
|
+
children: [
|
|
5685
|
+
/* @__PURE__ */ jsxs("div", {
|
|
5686
|
+
style: styles.screen,
|
|
5687
|
+
children: [
|
|
5688
|
+
!hideStatusBar && /* @__PURE__ */ jsx("div", {
|
|
5689
|
+
style: styles.notchContainer,
|
|
5690
|
+
children: /* @__PURE__ */ jsx("div", { style: styles.notch })
|
|
5691
|
+
}),
|
|
5692
|
+
/* @__PURE__ */ jsx("div", {
|
|
5693
|
+
style: {
|
|
5694
|
+
display: "flex",
|
|
5695
|
+
flex: 1,
|
|
5696
|
+
overflow: "hidden"
|
|
5697
|
+
},
|
|
5698
|
+
children
|
|
5699
|
+
}),
|
|
5700
|
+
!hideNavigationBar && !transparentNavigationBar && /* @__PURE__ */ jsx("div", {
|
|
5701
|
+
style: styles.swipeContainer,
|
|
5702
|
+
children: /* @__PURE__ */ jsx("div", { style: styles.swipeBar })
|
|
5703
|
+
})
|
|
5704
|
+
]
|
|
5705
|
+
}),
|
|
5706
|
+
hideStatusBar && /* @__PURE__ */ jsx("div", {
|
|
5707
|
+
style: styles.notchContainerFullScreen,
|
|
5708
|
+
children: /* @__PURE__ */ jsx("div", { style: styles.notch })
|
|
5709
|
+
}),
|
|
5710
|
+
!hideNavigationBar && transparentNavigationBar && /* @__PURE__ */ jsx("div", {
|
|
5711
|
+
style: styles.swipeContainerFullScreen,
|
|
5712
|
+
children: /* @__PURE__ */ jsx("div", { style: styles.swipeBar })
|
|
5713
|
+
})
|
|
5714
|
+
]
|
|
5715
|
+
}),
|
|
5716
|
+
/* @__PURE__ */ jsx("div", { style: styles.notchPad }),
|
|
5717
|
+
!frameOnly && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5718
|
+
/* @__PURE__ */ jsx("div", { style: styles.silenceSwitch }),
|
|
5719
|
+
/* @__PURE__ */ jsx("div", { style: styles.volumeUp }),
|
|
5720
|
+
/* @__PURE__ */ jsx("div", { style: styles.volumeDown }),
|
|
5721
|
+
/* @__PURE__ */ jsx("div", { style: styles.power })
|
|
5722
|
+
] })
|
|
5723
|
+
]
|
|
5724
|
+
});
|
|
5725
|
+
}
|
|
5726
|
+
function IPhoneNotchLandscape(props) {
|
|
5727
|
+
const { screenWidth, frameColor, frameOnly, statusbarColor, hideStatusBar, hideNavigationBar, transparentNavigationBar, children } = props;
|
|
5728
|
+
const styles = useMemo(() => {
|
|
5729
|
+
const getSizeWithRatio = (size) => Math.max(Math.floor(screenWidth * size / 844), 1);
|
|
5730
|
+
return getStyles({
|
|
5731
|
+
screenType: "notch",
|
|
5732
|
+
isLandscape: true,
|
|
5733
|
+
getSizeWithRatio,
|
|
5734
|
+
screenWidth,
|
|
5735
|
+
mockupHeight: Math.floor(screenWidth / 19.5 * 9),
|
|
5736
|
+
frameColor,
|
|
5737
|
+
frameWidth: getSizeWithRatio(14),
|
|
5738
|
+
frameOnly,
|
|
5739
|
+
statusbarColor,
|
|
5740
|
+
bezelRadius: getSizeWithRatio(64)
|
|
5741
|
+
});
|
|
5742
|
+
}, [
|
|
5743
|
+
screenWidth,
|
|
5744
|
+
frameColor,
|
|
5745
|
+
statusbarColor,
|
|
5746
|
+
frameOnly
|
|
5747
|
+
]);
|
|
5748
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
5749
|
+
style: styles.container,
|
|
5750
|
+
children: [
|
|
5751
|
+
/* @__PURE__ */ jsxs("div", {
|
|
5752
|
+
style: styles.frame,
|
|
5753
|
+
children: [
|
|
5754
|
+
/* @__PURE__ */ jsxs("div", {
|
|
5755
|
+
style: styles.screen,
|
|
5756
|
+
children: [
|
|
5757
|
+
!hideStatusBar && /* @__PURE__ */ jsx("div", {
|
|
5758
|
+
style: styles.notchContainer,
|
|
5759
|
+
children: /* @__PURE__ */ jsx("div", { style: styles.notch })
|
|
5760
|
+
}),
|
|
5761
|
+
/* @__PURE__ */ jsxs("div", {
|
|
5762
|
+
style: {
|
|
5763
|
+
display: "flex",
|
|
5764
|
+
flex: 1,
|
|
5765
|
+
flexDirection: "column"
|
|
5766
|
+
},
|
|
5767
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
5768
|
+
style: {
|
|
5769
|
+
display: "flex",
|
|
5770
|
+
flex: 1,
|
|
5771
|
+
flexDirection: "column",
|
|
5772
|
+
overflow: "hidden"
|
|
5773
|
+
},
|
|
5774
|
+
children
|
|
5775
|
+
}), !hideNavigationBar && !transparentNavigationBar && /* @__PURE__ */ jsx("div", {
|
|
5776
|
+
style: styles.swipeContainer,
|
|
5777
|
+
children: /* @__PURE__ */ jsx("div", { style: styles.swipeBar })
|
|
5778
|
+
})]
|
|
5779
|
+
}),
|
|
5780
|
+
!hideStatusBar && /* @__PURE__ */ jsx("div", { style: styles.safeAreaRight })
|
|
5781
|
+
]
|
|
5782
|
+
}),
|
|
5783
|
+
hideStatusBar && /* @__PURE__ */ jsx("div", {
|
|
5784
|
+
style: styles.notchContainerFullScreen,
|
|
5785
|
+
children: /* @__PURE__ */ jsx("div", { style: styles.notch })
|
|
5786
|
+
}),
|
|
5787
|
+
!hideNavigationBar && transparentNavigationBar && /* @__PURE__ */ jsx("div", {
|
|
5788
|
+
style: styles.swipeContainerFullScreen,
|
|
5789
|
+
children: /* @__PURE__ */ jsx("div", { style: styles.swipeBar })
|
|
5790
|
+
})
|
|
5791
|
+
]
|
|
5792
|
+
}),
|
|
5793
|
+
/* @__PURE__ */ jsx("div", { style: styles.notchPad }),
|
|
5794
|
+
!frameOnly && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5795
|
+
/* @__PURE__ */ jsx("div", { style: styles.silenceSwitch }),
|
|
5796
|
+
/* @__PURE__ */ jsx("div", { style: styles.volumeUp }),
|
|
5797
|
+
/* @__PURE__ */ jsx("div", { style: styles.volumeDown }),
|
|
5798
|
+
/* @__PURE__ */ jsx("div", { style: styles.power })
|
|
5799
|
+
] })
|
|
5800
|
+
]
|
|
5801
|
+
});
|
|
5802
|
+
}
|
|
5803
|
+
function getLegacyStyles({ isLandscape, getSizeWithRatio, screenWidth, mockupHeight, frameColor, statusbarColor, frameOnly }) {
|
|
5804
|
+
const frameWidth = getSizeWithRatio(22);
|
|
5805
|
+
const halfFrameWidth = Math.floor(frameWidth / 2);
|
|
5806
|
+
const widthAndFrame = screenWidth + frameWidth * 2;
|
|
5807
|
+
const heightAndFrame = mockupHeight + frameWidth * 2;
|
|
5808
|
+
const upperBezelSize = getSizeWithRatio(110);
|
|
5809
|
+
const lowerBezelSize = getSizeWithRatio(110);
|
|
5810
|
+
const frameButtonSize = Math.floor(frameWidth * .8);
|
|
5811
|
+
const frameButtonPosition = (isLandscape ? mockupHeight : screenWidth) + frameWidth + halfFrameWidth + frameButtonSize - halfFrameWidth;
|
|
5812
|
+
const paddingRight = frameOnly ? 0 : isLandscape ? 0 : frameButtonSize - halfFrameWidth;
|
|
5813
|
+
const paddingLeft = paddingRight;
|
|
5814
|
+
const paddingTop = frameOnly ? 0 : isLandscape ? frameButtonSize - halfFrameWidth : 0;
|
|
5815
|
+
const paddingBottom = paddingTop;
|
|
5816
|
+
const bezelRadius = getSizeWithRatio(60);
|
|
5817
|
+
return createStyles({
|
|
5818
|
+
container: {
|
|
5819
|
+
display: "flex",
|
|
5820
|
+
flexDirection: isLandscape ? "row" : "column",
|
|
5821
|
+
boxSizing: "content-box",
|
|
5822
|
+
position: "relative",
|
|
5823
|
+
width: isLandscape ? screenWidth + upperBezelSize + lowerBezelSize : widthAndFrame,
|
|
5824
|
+
height: isLandscape ? heightAndFrame : mockupHeight + upperBezelSize + lowerBezelSize,
|
|
5825
|
+
paddingRight,
|
|
5826
|
+
paddingLeft,
|
|
5827
|
+
paddingTop,
|
|
5828
|
+
paddingBottom
|
|
5829
|
+
},
|
|
5830
|
+
frame: {
|
|
5831
|
+
display: "flex",
|
|
5832
|
+
flexDirection: "column",
|
|
5833
|
+
alignItems: isLandscape ? "flex-start" : "center",
|
|
5834
|
+
justifyContent: isLandscape ? "center" : "flex-start",
|
|
5835
|
+
position: "relative",
|
|
5836
|
+
boxSizing: "border-box",
|
|
5837
|
+
borderLeftWidth: frameWidth,
|
|
5838
|
+
borderLeftStyle: "solid",
|
|
5839
|
+
borderRightWidth: frameWidth,
|
|
5840
|
+
borderRightStyle: "solid",
|
|
5841
|
+
borderColor: frameColor,
|
|
5842
|
+
width: isLandscape ? screenWidth : widthAndFrame,
|
|
5843
|
+
height: isLandscape ? heightAndFrame : mockupHeight,
|
|
5844
|
+
overflow: "hidden"
|
|
5845
|
+
},
|
|
5846
|
+
upperBezel: {
|
|
5847
|
+
display: "flex",
|
|
5848
|
+
flexDirection: "column",
|
|
5849
|
+
position: "relative",
|
|
5850
|
+
borderTopLeftRadius: bezelRadius,
|
|
5851
|
+
borderTopRightRadius: isLandscape ? 0 : bezelRadius,
|
|
5852
|
+
borderBottomLeftRadius: isLandscape ? bezelRadius : 0,
|
|
5853
|
+
width: isLandscape ? upperBezelSize : widthAndFrame,
|
|
5854
|
+
height: isLandscape ? heightAndFrame : upperBezelSize,
|
|
5855
|
+
backgroundColor: frameColor,
|
|
5856
|
+
justifyContent: "center"
|
|
5857
|
+
},
|
|
5858
|
+
cameraSpeakerContainer: {
|
|
5859
|
+
display: "flex",
|
|
5860
|
+
flexDirection: isLandscape ? "row" : "column",
|
|
5861
|
+
position: "relative",
|
|
5862
|
+
width: "100%",
|
|
5863
|
+
height: "100%",
|
|
5864
|
+
alignItems: "center",
|
|
5865
|
+
justifyContent: "center"
|
|
5866
|
+
},
|
|
5867
|
+
camera: {
|
|
5868
|
+
position: "absolute",
|
|
5869
|
+
left: isLandscape ? void 0 : -getSizeWithRatio(38),
|
|
5870
|
+
bottom: isLandscape ? -getSizeWithRatio(38) : 0,
|
|
5871
|
+
width: getSizeWithRatio(10),
|
|
5872
|
+
height: getSizeWithRatio(10),
|
|
5873
|
+
borderRadius: getSizeWithRatio(10),
|
|
5874
|
+
backgroundColor: statusbarColor
|
|
5875
|
+
},
|
|
5876
|
+
speaker: {
|
|
5877
|
+
position: "relative",
|
|
5878
|
+
width: isLandscape ? getSizeWithRatio(10) : getSizeWithRatio(80),
|
|
5879
|
+
height: isLandscape ? getSizeWithRatio(80) : getSizeWithRatio(10),
|
|
5880
|
+
backgroundColor: statusbarColor,
|
|
5881
|
+
borderRadius: getSizeWithRatio(10)
|
|
5882
|
+
},
|
|
5883
|
+
lowerBezel: {
|
|
5884
|
+
display: "flex",
|
|
5885
|
+
flexDirection: isLandscape ? "row" : "column",
|
|
5886
|
+
borderTopRightRadius: isLandscape ? bezelRadius : 0,
|
|
5887
|
+
borderBottomLeftRadius: isLandscape ? 0 : bezelRadius,
|
|
5888
|
+
borderBottomRightRadius: bezelRadius,
|
|
5889
|
+
width: isLandscape ? lowerBezelSize : widthAndFrame,
|
|
5890
|
+
height: isLandscape ? heightAndFrame : lowerBezelSize,
|
|
5891
|
+
backgroundColor: frameColor,
|
|
5892
|
+
alignItems: "center",
|
|
5893
|
+
justifyContent: "center"
|
|
5894
|
+
},
|
|
5895
|
+
homeButton: {
|
|
5896
|
+
width: getSizeWithRatio(65),
|
|
5897
|
+
height: getSizeWithRatio(65),
|
|
5898
|
+
backgroundColor: statusbarColor,
|
|
5899
|
+
borderRadius: getSizeWithRatio(65)
|
|
5900
|
+
},
|
|
5901
|
+
screen: {
|
|
5902
|
+
display: "flex",
|
|
5903
|
+
flexDirection: isLandscape ? "row" : "column",
|
|
5904
|
+
position: "relative",
|
|
5905
|
+
width: screenWidth,
|
|
5906
|
+
height: mockupHeight,
|
|
5907
|
+
backgroundColor: "transparent"
|
|
5908
|
+
},
|
|
5909
|
+
statusbar: {
|
|
5910
|
+
width: "100%",
|
|
5911
|
+
height: getSizeWithRatio(20),
|
|
5912
|
+
backgroundColor: statusbarColor,
|
|
5913
|
+
alignItems: "center"
|
|
5914
|
+
},
|
|
5915
|
+
silenceSwitch: {
|
|
5916
|
+
position: "absolute",
|
|
5917
|
+
borderRadius: frameWidth,
|
|
5918
|
+
top: isLandscape ? frameButtonPosition : getSizeWithRatio(115),
|
|
5919
|
+
left: isLandscape ? getSizeWithRatio(115) : void 0,
|
|
5920
|
+
right: isLandscape ? void 0 : frameButtonPosition,
|
|
5921
|
+
width: isLandscape ? getSizeWithRatio(36) : frameButtonSize,
|
|
5922
|
+
height: isLandscape ? frameButtonSize : getSizeWithRatio(36),
|
|
5923
|
+
backgroundColor: frameColor
|
|
5924
|
+
},
|
|
5925
|
+
volumeUp: {
|
|
5926
|
+
position: "absolute",
|
|
5927
|
+
borderRadius: frameWidth,
|
|
5928
|
+
top: isLandscape ? frameButtonPosition : getSizeWithRatio(185),
|
|
5929
|
+
left: isLandscape ? getSizeWithRatio(185) : void 0,
|
|
5930
|
+
right: frameButtonPosition,
|
|
5931
|
+
width: isLandscape ? getSizeWithRatio(70) : frameButtonSize,
|
|
5932
|
+
height: isLandscape ? frameButtonSize : getSizeWithRatio(70),
|
|
5933
|
+
backgroundColor: frameColor
|
|
5934
|
+
},
|
|
5935
|
+
volumeDown: {
|
|
5936
|
+
position: "absolute",
|
|
5937
|
+
borderRadius: frameWidth,
|
|
5938
|
+
top: isLandscape ? frameButtonPosition : getSizeWithRatio(270),
|
|
5939
|
+
left: isLandscape ? getSizeWithRatio(270) : void 0,
|
|
5940
|
+
right: isLandscape ? void 0 : frameButtonPosition,
|
|
5941
|
+
width: isLandscape ? getSizeWithRatio(70) : frameButtonSize,
|
|
5942
|
+
height: isLandscape ? frameButtonSize : getSizeWithRatio(70),
|
|
5943
|
+
backgroundColor: frameColor
|
|
5944
|
+
},
|
|
5945
|
+
power: {
|
|
5946
|
+
position: "absolute",
|
|
5947
|
+
borderRadius: frameWidth,
|
|
5948
|
+
top: isLandscape ? void 0 : getSizeWithRatio(190),
|
|
5949
|
+
left: isLandscape ? getSizeWithRatio(190) : frameButtonPosition,
|
|
5950
|
+
bottom: isLandscape ? frameButtonPosition : void 0,
|
|
5951
|
+
width: isLandscape ? getSizeWithRatio(64) : frameButtonSize,
|
|
5952
|
+
height: isLandscape ? frameButtonSize : getSizeWithRatio(64),
|
|
5953
|
+
backgroundColor: frameColor
|
|
5954
|
+
}
|
|
5955
|
+
});
|
|
5956
|
+
}
|
|
5957
|
+
function IPhoneLegacyPortrait(props) {
|
|
5958
|
+
const { screenWidth, frameColor, frameOnly, statusbarColor, hideStatusBar, children } = props;
|
|
5959
|
+
const styles = useMemo(() => {
|
|
5960
|
+
const getSizeWithRatio = (size) => Math.max(Math.floor(screenWidth * size / 375), 1);
|
|
5961
|
+
return getLegacyStyles({
|
|
5962
|
+
isLandscape: false,
|
|
5963
|
+
getSizeWithRatio,
|
|
5964
|
+
screenWidth,
|
|
5965
|
+
mockupHeight: Math.floor(screenWidth / 9 * 16),
|
|
5966
|
+
frameColor,
|
|
5967
|
+
statusbarColor,
|
|
5968
|
+
frameOnly
|
|
5969
|
+
});
|
|
5970
|
+
}, [
|
|
5971
|
+
screenWidth,
|
|
5972
|
+
frameColor,
|
|
5973
|
+
statusbarColor,
|
|
5974
|
+
frameOnly
|
|
5975
|
+
]);
|
|
5976
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
5977
|
+
style: styles.container,
|
|
5978
|
+
children: [
|
|
5979
|
+
/* @__PURE__ */ jsx("div", {
|
|
5980
|
+
style: styles.upperBezel,
|
|
5981
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
5982
|
+
style: styles.cameraSpeakerContainer,
|
|
5983
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
5984
|
+
style: styles.speaker,
|
|
5985
|
+
children: /* @__PURE__ */ jsx("div", { style: styles.camera })
|
|
5986
|
+
})
|
|
5987
|
+
})
|
|
5988
|
+
}),
|
|
5989
|
+
/* @__PURE__ */ jsx("div", {
|
|
5990
|
+
style: styles.frame,
|
|
5991
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
5992
|
+
style: styles.screen,
|
|
5993
|
+
children: [!hideStatusBar && /* @__PURE__ */ jsx("div", { style: styles.statusbar }), /* @__PURE__ */ jsx("div", {
|
|
5994
|
+
style: {
|
|
5995
|
+
display: "flex",
|
|
5996
|
+
flex: 1,
|
|
5997
|
+
overflow: "hidden"
|
|
5998
|
+
},
|
|
5999
|
+
children
|
|
6000
|
+
})]
|
|
6001
|
+
})
|
|
6002
|
+
}),
|
|
6003
|
+
/* @__PURE__ */ jsx("div", {
|
|
6004
|
+
style: styles.lowerBezel,
|
|
6005
|
+
children: /* @__PURE__ */ jsx("div", { style: styles.homeButton })
|
|
6006
|
+
}),
|
|
6007
|
+
!frameOnly && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6008
|
+
/* @__PURE__ */ jsx("div", { style: styles.silenceSwitch }),
|
|
6009
|
+
/* @__PURE__ */ jsx("div", { style: styles.volumeUp }),
|
|
6010
|
+
/* @__PURE__ */ jsx("div", { style: styles.volumeDown }),
|
|
6011
|
+
/* @__PURE__ */ jsx("div", { style: styles.power })
|
|
6012
|
+
] })
|
|
6013
|
+
]
|
|
6014
|
+
});
|
|
6015
|
+
}
|
|
6016
|
+
function IPhoneLegacyLandscape(props) {
|
|
6017
|
+
const { screenWidth, frameColor, frameOnly, statusbarColor, children } = props;
|
|
6018
|
+
const styles = useMemo(() => {
|
|
6019
|
+
const getSizeWithRatio = (size) => Math.max(Math.floor(screenWidth * size / 667), 1);
|
|
6020
|
+
return getLegacyStyles({
|
|
6021
|
+
isLandscape: true,
|
|
6022
|
+
getSizeWithRatio,
|
|
6023
|
+
screenWidth,
|
|
6024
|
+
mockupHeight: Math.floor(screenWidth / 16 * 9),
|
|
6025
|
+
frameColor,
|
|
6026
|
+
statusbarColor,
|
|
6027
|
+
frameOnly
|
|
6028
|
+
});
|
|
6029
|
+
}, [
|
|
6030
|
+
screenWidth,
|
|
6031
|
+
frameColor,
|
|
6032
|
+
statusbarColor,
|
|
6033
|
+
frameOnly
|
|
6034
|
+
]);
|
|
6035
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
6036
|
+
style: styles.container,
|
|
6037
|
+
children: [
|
|
6038
|
+
/* @__PURE__ */ jsx("div", {
|
|
6039
|
+
style: styles.upperBezel,
|
|
6040
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
6041
|
+
style: styles.cameraSpeakerContainer,
|
|
6042
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
6043
|
+
style: styles.speaker,
|
|
6044
|
+
children: /* @__PURE__ */ jsx("div", { style: styles.camera })
|
|
6045
|
+
})
|
|
6046
|
+
})
|
|
6047
|
+
}),
|
|
6048
|
+
/* @__PURE__ */ jsx("div", {
|
|
6049
|
+
style: styles.frame,
|
|
6050
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
6051
|
+
style: styles.screen,
|
|
6052
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
6053
|
+
style: {
|
|
6054
|
+
display: "flex",
|
|
6055
|
+
flex: 1,
|
|
6056
|
+
overflow: "hidden"
|
|
6057
|
+
},
|
|
6058
|
+
children
|
|
6059
|
+
})
|
|
6060
|
+
})
|
|
6061
|
+
}),
|
|
6062
|
+
/* @__PURE__ */ jsx("div", {
|
|
6063
|
+
style: styles.lowerBezel,
|
|
6064
|
+
children: /* @__PURE__ */ jsx("div", { style: styles.homeButton })
|
|
6065
|
+
}),
|
|
6066
|
+
!frameOnly && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6067
|
+
/* @__PURE__ */ jsx("div", { style: styles.silenceSwitch }),
|
|
6068
|
+
/* @__PURE__ */ jsx("div", { style: styles.volumeUp }),
|
|
6069
|
+
/* @__PURE__ */ jsx("div", { style: styles.volumeDown }),
|
|
6070
|
+
/* @__PURE__ */ jsx("div", { style: styles.power })
|
|
6071
|
+
] })
|
|
6072
|
+
]
|
|
6073
|
+
});
|
|
6074
|
+
}
|
|
6075
|
+
|
|
6076
|
+
//#endregion
|
|
6077
|
+
//#region src/components/WhatsAppMockup/index.tsx
|
|
6078
|
+
const DEFAULT_WAVEFORM = [
|
|
6079
|
+
10,
|
|
6080
|
+
18,
|
|
6081
|
+
27,
|
|
6082
|
+
14,
|
|
6083
|
+
31,
|
|
6084
|
+
23,
|
|
6085
|
+
38,
|
|
6086
|
+
17,
|
|
6087
|
+
29,
|
|
6088
|
+
21,
|
|
6089
|
+
12,
|
|
6090
|
+
25,
|
|
6091
|
+
15,
|
|
6092
|
+
32,
|
|
6093
|
+
19,
|
|
6094
|
+
11,
|
|
6095
|
+
23,
|
|
6096
|
+
15,
|
|
6097
|
+
29,
|
|
6098
|
+
17
|
|
6099
|
+
];
|
|
6100
|
+
const WHATSAPP_PALETTES = {
|
|
6101
|
+
dark: {
|
|
6102
|
+
frame: "#0a0d12",
|
|
6103
|
+
statusbar: "#111b21",
|
|
6104
|
+
statusText: "#e9edef",
|
|
6105
|
+
screen: "#0b141a",
|
|
6106
|
+
header: "#111b21",
|
|
6107
|
+
headerText: "#e9edef",
|
|
6108
|
+
mutedText: "#aebac1",
|
|
6109
|
+
subtleText: "#8696a0",
|
|
6110
|
+
action: "#00a884",
|
|
6111
|
+
wallpaperStroke: "#e9edef",
|
|
6112
|
+
wallpaperOpacity: .045,
|
|
6113
|
+
dateBg: "#182229",
|
|
6114
|
+
dateText: "#aebac1",
|
|
6115
|
+
noticeBg: "#182229",
|
|
6116
|
+
noticeText: "#d0b66b",
|
|
6117
|
+
incoming: "#202c33",
|
|
6118
|
+
incomingText: "#e9edef",
|
|
6119
|
+
outgoing: "#005c4b",
|
|
6120
|
+
outgoingText: "#e9edef",
|
|
6121
|
+
outgoingMeta: "#c7d4cf",
|
|
6122
|
+
read: "#53bdeb",
|
|
6123
|
+
avatarBg: "#60b531",
|
|
6124
|
+
composer: "#111b21",
|
|
6125
|
+
composerInput: "#202c33",
|
|
6126
|
+
composerText: "#8696a0",
|
|
6127
|
+
micBg: "#00a884",
|
|
6128
|
+
micIcon: "#07130f",
|
|
6129
|
+
audioWave: "#9ad8ca",
|
|
6130
|
+
audioButtonBg: "#00a884",
|
|
6131
|
+
shadow: "rgba(0, 0, 0, 0.22)"
|
|
6132
|
+
},
|
|
6133
|
+
light: {
|
|
6134
|
+
frame: "#0a0d12",
|
|
6135
|
+
statusbar: "#f7f5f0",
|
|
6136
|
+
statusText: "#111b21",
|
|
6137
|
+
screen: "#efe7db",
|
|
6138
|
+
header: "#f7f5f0",
|
|
6139
|
+
headerText: "#111b21",
|
|
6140
|
+
mutedText: "#667781",
|
|
6141
|
+
subtleText: "#667781",
|
|
6142
|
+
action: "#008069",
|
|
6143
|
+
wallpaperStroke: "#7d6f59",
|
|
6144
|
+
wallpaperOpacity: .075,
|
|
6145
|
+
dateBg: "rgba(255, 255, 255, 0.88)",
|
|
6146
|
+
dateText: "#6b6255",
|
|
6147
|
+
noticeBg: "#fff7d6",
|
|
6148
|
+
noticeText: "#7a6420",
|
|
6149
|
+
incoming: "#ffffff",
|
|
6150
|
+
incomingText: "#111b21",
|
|
6151
|
+
outgoing: "#d9fdd3",
|
|
6152
|
+
outgoingText: "#111b13",
|
|
6153
|
+
outgoingMeta: "#66756b",
|
|
6154
|
+
read: "#53bdeb",
|
|
6155
|
+
avatarBg: "#60b531",
|
|
6156
|
+
composer: "#f7f5f0",
|
|
6157
|
+
composerInput: "#ffffff",
|
|
6158
|
+
composerText: "#667781",
|
|
6159
|
+
micBg: "#00a884",
|
|
6160
|
+
micIcon: "#ffffff",
|
|
6161
|
+
audioWave: "#177866",
|
|
6162
|
+
audioButtonBg: "#00a884",
|
|
6163
|
+
shadow: "rgba(15, 23, 42, 0.11)"
|
|
6164
|
+
}
|
|
6165
|
+
};
|
|
6166
|
+
const cn$2 = (...classes) => classes.filter(Boolean).join(" ");
|
|
6167
|
+
function WhatsAppMockup({ contactName, profilePhoto, profilePhotoAlt, profileAvatar, profileType = "business", contactSubtitle, theme = "dark", headerBackgroundColor, profileAvatarBackgroundColor, messages = [], statusTime = "14:32", dateLabel = "Hoje", encryptionNotice = "Mensagens e ligações são protegidas com criptografia de ponta a ponta.", composerPlaceholder = "Mensagem", composer, showComposer = true, showHeaderActions = true, showWallpaper = true, screenWidth = 266, frameColor, statusbarColor, containerStyle, frameOnly, hideStatusBar, className, phoneClassName, screenClassName, messagesClassName, "aria-label": ariaLabel }) {
|
|
6168
|
+
const palette = WHATSAPP_PALETTES[theme];
|
|
6169
|
+
const resolvedFrameColor = frameColor ?? palette.frame;
|
|
6170
|
+
const resolvedStatusbarColor = statusbarColor ?? palette.statusbar;
|
|
6171
|
+
const subtitle = contactSubtitle === void 0 ? profileType === "business" ? "WhatsApp Business" : void 0 : contactSubtitle || void 0;
|
|
6172
|
+
return /* @__PURE__ */ jsx("div", {
|
|
6173
|
+
className: cn$2("rounded-[2.65rem] shadow-[0_34px_74px_-34px_rgba(15,23,42,0.58)] dark:shadow-[0_34px_86px_-34px_rgba(10,13,18,0.82)]", className),
|
|
6174
|
+
"aria-label": ariaLabel ?? `Conversa no WhatsApp com ${contactName}`,
|
|
6175
|
+
children: /* @__PURE__ */ jsx(IPhoneMockup, {
|
|
6176
|
+
screenWidth,
|
|
6177
|
+
screenType: "island",
|
|
6178
|
+
frameColor: resolvedFrameColor,
|
|
6179
|
+
statusbarColor: resolvedStatusbarColor,
|
|
6180
|
+
hideNavBar: true,
|
|
6181
|
+
frameOnly,
|
|
6182
|
+
hideStatusBar,
|
|
6183
|
+
containerStyle,
|
|
6184
|
+
className: phoneClassName,
|
|
6185
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
6186
|
+
className: cn$2("flex h-full w-full flex-col", screenClassName),
|
|
6187
|
+
style: {
|
|
6188
|
+
backgroundColor: palette.screen,
|
|
6189
|
+
color: palette.headerText
|
|
6190
|
+
},
|
|
6191
|
+
children: [
|
|
6192
|
+
/* @__PURE__ */ jsx(StatusBar, {
|
|
6193
|
+
time: statusTime,
|
|
6194
|
+
screenWidth,
|
|
6195
|
+
palette
|
|
6196
|
+
}),
|
|
6197
|
+
/* @__PURE__ */ jsx(WhatsAppHeader, {
|
|
6198
|
+
contactName,
|
|
6199
|
+
subtitle,
|
|
6200
|
+
profilePhoto,
|
|
6201
|
+
profilePhotoAlt,
|
|
6202
|
+
profileAvatar,
|
|
6203
|
+
showActions: showHeaderActions,
|
|
6204
|
+
backgroundColor: headerBackgroundColor ?? palette.header,
|
|
6205
|
+
avatarBackgroundColor: profileAvatarBackgroundColor ?? palette.avatarBg,
|
|
6206
|
+
palette
|
|
6207
|
+
}),
|
|
6208
|
+
/* @__PURE__ */ jsxs("div", {
|
|
6209
|
+
className: cn$2("relative flex flex-1 flex-col gap-2 overflow-hidden px-2.5 py-2.5", messagesClassName),
|
|
6210
|
+
children: [
|
|
6211
|
+
showWallpaper ? /* @__PURE__ */ jsx(WhatsAppWallpaper, { palette }) : null,
|
|
6212
|
+
dateLabel ? /* @__PURE__ */ jsx("div", {
|
|
6213
|
+
className: "relative z-10 mx-auto rounded-full px-2.5 py-0.5 text-[9px] font-semibold uppercase shadow-[0_1px_2px_rgba(15,23,42,0.08)]",
|
|
6214
|
+
style: {
|
|
6215
|
+
backgroundColor: palette.dateBg,
|
|
6216
|
+
color: palette.dateText
|
|
6217
|
+
},
|
|
6218
|
+
children: dateLabel
|
|
6219
|
+
}) : null,
|
|
6220
|
+
encryptionNotice ? /* @__PURE__ */ jsx("div", {
|
|
6221
|
+
className: "relative z-10 mx-auto max-w-[92%] rounded-md px-2.5 py-1.5 text-center text-[9px] leading-snug shadow-[0_1px_2px_rgba(15,23,42,0.06)]",
|
|
6222
|
+
style: {
|
|
6223
|
+
backgroundColor: palette.noticeBg,
|
|
6224
|
+
color: palette.noticeText
|
|
6225
|
+
},
|
|
6226
|
+
children: encryptionNotice
|
|
6227
|
+
}) : null,
|
|
6228
|
+
messages.map((message, index) => /* @__PURE__ */ jsx(WhatsAppMessageBubble, {
|
|
6229
|
+
message,
|
|
6230
|
+
palette
|
|
6231
|
+
}, message.id ?? `${message.time}-${index}`))
|
|
6232
|
+
]
|
|
6233
|
+
}),
|
|
6234
|
+
showComposer ? composer ?? /* @__PURE__ */ jsx(WhatsAppComposer, {
|
|
6235
|
+
composerPlaceholder,
|
|
6236
|
+
palette
|
|
6237
|
+
}) : null
|
|
6238
|
+
]
|
|
6239
|
+
})
|
|
6240
|
+
})
|
|
6241
|
+
});
|
|
6242
|
+
}
|
|
6243
|
+
function StatusBar({ time, screenWidth, palette }) {
|
|
6244
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
6245
|
+
"aria-hidden": true,
|
|
6246
|
+
className: "absolute left-0 right-0 top-0 z-50 flex items-center justify-between px-6 text-[11px] font-semibold tracking-tight",
|
|
6247
|
+
style: { height: `${Math.floor(screenWidth * 59 / 390)}px` },
|
|
6248
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
6249
|
+
className: "tabular-nums",
|
|
6250
|
+
style: { color: palette.statusText },
|
|
6251
|
+
children: time
|
|
6252
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
6253
|
+
className: "flex items-center gap-1",
|
|
6254
|
+
style: { color: palette.statusText },
|
|
6255
|
+
children: [
|
|
6256
|
+
/* @__PURE__ */ jsx(IosSignal, { color: palette.statusText }),
|
|
6257
|
+
/* @__PURE__ */ jsx(Wifi, {
|
|
6258
|
+
className: "h-3 w-3",
|
|
6259
|
+
strokeWidth: 2.4,
|
|
6260
|
+
"aria-hidden": true
|
|
6261
|
+
}),
|
|
6262
|
+
/* @__PURE__ */ jsx(IosBattery, { color: palette.statusText })
|
|
6263
|
+
]
|
|
6264
|
+
})]
|
|
6265
|
+
});
|
|
6266
|
+
}
|
|
6267
|
+
function IosSignal({ color }) {
|
|
6268
|
+
return /* @__PURE__ */ jsx("span", {
|
|
6269
|
+
className: "flex h-3 w-3 items-end gap-[1px]",
|
|
6270
|
+
"aria-hidden": true,
|
|
6271
|
+
children: [
|
|
6272
|
+
4,
|
|
6273
|
+
6,
|
|
6274
|
+
8,
|
|
6275
|
+
10
|
|
6276
|
+
].map((height) => /* @__PURE__ */ jsx("span", {
|
|
6277
|
+
className: "w-[2px] rounded-sm",
|
|
6278
|
+
style: {
|
|
6279
|
+
height,
|
|
6280
|
+
backgroundColor: color
|
|
6281
|
+
}
|
|
6282
|
+
}, height))
|
|
6283
|
+
});
|
|
6284
|
+
}
|
|
6285
|
+
function IosBattery({ color }) {
|
|
6286
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
6287
|
+
className: "flex items-center gap-[1px]",
|
|
6288
|
+
"aria-hidden": true,
|
|
6289
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
6290
|
+
className: "relative h-[8px] w-[16px] rounded-[2px] border",
|
|
6291
|
+
style: { borderColor: color },
|
|
6292
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
6293
|
+
className: "absolute bottom-[1px] left-[1px] top-[1px] w-[10px] rounded-[1px]",
|
|
6294
|
+
style: { backgroundColor: color }
|
|
6295
|
+
})
|
|
6296
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
6297
|
+
className: "h-[4px] w-[1.5px] rounded-r",
|
|
6298
|
+
style: { backgroundColor: color }
|
|
6299
|
+
})]
|
|
6300
|
+
});
|
|
6301
|
+
}
|
|
6302
|
+
function WhatsAppHeader({ contactName, subtitle, profilePhoto, profilePhotoAlt, profileAvatar, showActions, backgroundColor, avatarBackgroundColor, palette }) {
|
|
6303
|
+
return /* @__PURE__ */ jsx("div", {
|
|
6304
|
+
className: "relative shadow-[0_1px_0_rgba(17,27,33,0.08)]",
|
|
6305
|
+
style: {
|
|
6306
|
+
backgroundColor,
|
|
6307
|
+
color: palette.headerText
|
|
6308
|
+
},
|
|
6309
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
6310
|
+
className: "flex items-center gap-2 px-2.5 pb-2 pt-2",
|
|
6311
|
+
children: [
|
|
6312
|
+
/* @__PURE__ */ jsx(ChevronLeft, {
|
|
6313
|
+
className: "h-5 w-5 shrink-0",
|
|
6314
|
+
strokeWidth: 2.4,
|
|
6315
|
+
style: { color: palette.action },
|
|
6316
|
+
"aria-hidden": true
|
|
6317
|
+
}),
|
|
6318
|
+
/* @__PURE__ */ jsx(ProfileAvatar, {
|
|
6319
|
+
contactName,
|
|
6320
|
+
profilePhoto,
|
|
6321
|
+
profilePhotoAlt,
|
|
6322
|
+
profileAvatar,
|
|
6323
|
+
backgroundColor: avatarBackgroundColor
|
|
6324
|
+
}),
|
|
6325
|
+
/* @__PURE__ */ jsxs("div", {
|
|
6326
|
+
className: "min-w-0 flex-1",
|
|
6327
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
6328
|
+
className: "truncate text-[13px] font-semibold leading-tight",
|
|
6329
|
+
children: contactName
|
|
6330
|
+
}), subtitle ? /* @__PURE__ */ jsx("p", {
|
|
6331
|
+
className: "truncate text-[10px] leading-tight",
|
|
6332
|
+
style: { color: palette.mutedText },
|
|
6333
|
+
children: subtitle
|
|
6334
|
+
}) : null]
|
|
6335
|
+
}),
|
|
6336
|
+
showActions ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6337
|
+
/* @__PURE__ */ jsx(Video, {
|
|
6338
|
+
className: "h-4 w-4 shrink-0",
|
|
6339
|
+
strokeWidth: 2.2,
|
|
6340
|
+
style: { color: palette.action },
|
|
6341
|
+
"aria-hidden": true
|
|
6342
|
+
}),
|
|
6343
|
+
/* @__PURE__ */ jsx(Phone, {
|
|
6344
|
+
className: "h-3.5 w-3.5 shrink-0",
|
|
6345
|
+
strokeWidth: 2.2,
|
|
6346
|
+
style: { color: palette.action },
|
|
6347
|
+
"aria-hidden": true
|
|
6348
|
+
}),
|
|
6349
|
+
/* @__PURE__ */ jsx(MoreVertical, {
|
|
6350
|
+
className: "h-4 w-4 shrink-0",
|
|
6351
|
+
strokeWidth: 2.2,
|
|
6352
|
+
style: { color: palette.action },
|
|
6353
|
+
"aria-hidden": true
|
|
6354
|
+
})
|
|
6355
|
+
] }) : null
|
|
6356
|
+
]
|
|
6357
|
+
})
|
|
6358
|
+
});
|
|
6359
|
+
}
|
|
6360
|
+
function ProfileAvatar({ contactName, profilePhoto, profilePhotoAlt, profileAvatar, backgroundColor }) {
|
|
6361
|
+
if (profileAvatar) return /* @__PURE__ */ jsx("div", {
|
|
6362
|
+
className: "flex h-8 w-8 shrink-0 items-center justify-center overflow-hidden rounded-full",
|
|
6363
|
+
style: { backgroundColor },
|
|
6364
|
+
children: profileAvatar
|
|
6365
|
+
});
|
|
6366
|
+
if (profilePhoto) return /* @__PURE__ */ jsx("img", {
|
|
6367
|
+
src: profilePhoto,
|
|
6368
|
+
alt: profilePhotoAlt ?? contactName,
|
|
6369
|
+
className: "h-8 w-8 shrink-0 rounded-full object-cover",
|
|
6370
|
+
style: { backgroundColor }
|
|
6371
|
+
});
|
|
6372
|
+
return /* @__PURE__ */ jsx("div", {
|
|
6373
|
+
className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-[11px] font-bold uppercase text-white",
|
|
6374
|
+
style: { backgroundColor },
|
|
6375
|
+
children: getInitials(contactName)
|
|
6376
|
+
});
|
|
6377
|
+
}
|
|
6378
|
+
function getInitials(name) {
|
|
6379
|
+
const parts = name.trim().split(/\s+/).filter(Boolean);
|
|
6380
|
+
return `${parts[0]?.[0] ?? "W"}${(parts.length > 1 ? parts[parts.length - 1]?.[0] : void 0) ?? ""}`;
|
|
6381
|
+
}
|
|
6382
|
+
function WhatsAppMessageBubble({ message, palette }) {
|
|
6383
|
+
const direction = message.direction ?? "outgoing";
|
|
6384
|
+
const type = message.type ?? "text";
|
|
6385
|
+
const isOutgoing = direction === "outgoing";
|
|
6386
|
+
const bubbleColor = isOutgoing ? palette.outgoing : palette.incoming;
|
|
6387
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
6388
|
+
className: cn$2("relative z-10 max-w-[86%] rounded-[14px] px-2.5 py-2 shadow-[0_1px_1.5px_rgba(15,23,42,0.11)]", isOutgoing ? "ml-auto rounded-tr-[4px]" : "mr-auto rounded-tl-[4px]", message.className),
|
|
6389
|
+
style: {
|
|
6390
|
+
backgroundColor: bubbleColor,
|
|
6391
|
+
color: isOutgoing ? palette.outgoingText : palette.incomingText,
|
|
6392
|
+
boxShadow: `0 1px 1.5px ${palette.shadow}`,
|
|
6393
|
+
...message.style
|
|
6394
|
+
},
|
|
6395
|
+
children: [
|
|
6396
|
+
/* @__PURE__ */ jsx(BubbleTail, {
|
|
6397
|
+
side: isOutgoing ? "out" : "in",
|
|
6398
|
+
color: message.style?.backgroundColor?.toString() ?? bubbleColor
|
|
6399
|
+
}),
|
|
6400
|
+
/* @__PURE__ */ jsx("div", {
|
|
6401
|
+
className: message.contentClassName,
|
|
6402
|
+
children: message.children ?? (type === "audio" ? /* @__PURE__ */ jsx(AudioMessage, {
|
|
6403
|
+
message,
|
|
6404
|
+
palette
|
|
6405
|
+
}) : type === "custom" ? null : /* @__PURE__ */ jsx("p", {
|
|
6406
|
+
className: "max-w-[31ch] text-[10.5px] leading-snug",
|
|
6407
|
+
children: message.text
|
|
6408
|
+
}))
|
|
6409
|
+
}),
|
|
6410
|
+
message.hideMeta ? null : /* @__PURE__ */ jsx(MessageMeta, {
|
|
6411
|
+
time: message.time,
|
|
6412
|
+
direction,
|
|
6413
|
+
read: message.read,
|
|
6414
|
+
palette
|
|
6415
|
+
})
|
|
6416
|
+
]
|
|
6417
|
+
});
|
|
6418
|
+
}
|
|
6419
|
+
function AudioMessage({ message, palette }) {
|
|
6420
|
+
const waveform = message.waveform ?? DEFAULT_WAVEFORM;
|
|
6421
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
|
|
6422
|
+
className: "flex items-center gap-2",
|
|
6423
|
+
children: [
|
|
6424
|
+
/* @__PURE__ */ jsx("span", {
|
|
6425
|
+
className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-full",
|
|
6426
|
+
style: {
|
|
6427
|
+
backgroundColor: palette.audioButtonBg,
|
|
6428
|
+
color: palette.micIcon
|
|
6429
|
+
},
|
|
6430
|
+
children: /* @__PURE__ */ jsx(Play, {
|
|
6431
|
+
className: "ml-0.5 h-3.5 w-3.5 fill-current",
|
|
6432
|
+
strokeWidth: 2.2,
|
|
6433
|
+
"aria-hidden": true
|
|
6434
|
+
})
|
|
6435
|
+
}),
|
|
6436
|
+
/* @__PURE__ */ jsx("div", {
|
|
6437
|
+
className: "flex h-7 flex-1 items-center gap-[2px]",
|
|
6438
|
+
"aria-hidden": true,
|
|
6439
|
+
children: waveform.map((height, index) => /* @__PURE__ */ jsx("span", {
|
|
6440
|
+
className: "origin-center rounded-full",
|
|
6441
|
+
style: {
|
|
6442
|
+
backgroundColor: palette.audioWave,
|
|
6443
|
+
height: Math.max(8, Math.round(height * .78)),
|
|
6444
|
+
opacity: .76,
|
|
6445
|
+
width: 2
|
|
6446
|
+
}
|
|
6447
|
+
}, `${height}-${index}`))
|
|
6448
|
+
}),
|
|
6449
|
+
message.duration ? /* @__PURE__ */ jsx("span", {
|
|
6450
|
+
className: "text-[10px] font-medium",
|
|
6451
|
+
style: { color: palette.outgoingMeta },
|
|
6452
|
+
children: message.duration
|
|
6453
|
+
}) : null
|
|
6454
|
+
]
|
|
6455
|
+
}), message.text ? /* @__PURE__ */ jsx("p", {
|
|
6456
|
+
className: "mt-1.5 max-w-[29ch] text-[9.5px] leading-snug",
|
|
6457
|
+
style: { color: palette.outgoingMeta },
|
|
6458
|
+
children: message.text
|
|
6459
|
+
}) : null] });
|
|
6460
|
+
}
|
|
6461
|
+
function MessageMeta({ time, direction, read, palette }) {
|
|
6462
|
+
const isOutgoing = direction === "outgoing";
|
|
6463
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
6464
|
+
className: "mt-1 flex items-center justify-end gap-1 text-[9px]",
|
|
6465
|
+
style: { color: isOutgoing ? palette.outgoingMeta : palette.subtleText },
|
|
6466
|
+
children: [/* @__PURE__ */ jsx("span", { children: time }), isOutgoing ? read === void 0 ? /* @__PURE__ */ jsx(Check, {
|
|
6467
|
+
className: "h-3 w-3",
|
|
6468
|
+
strokeWidth: 2.5,
|
|
6469
|
+
"aria-hidden": true
|
|
6470
|
+
}) : /* @__PURE__ */ jsx(CheckCheck, {
|
|
6471
|
+
className: "h-3 w-3",
|
|
6472
|
+
strokeWidth: 2.5,
|
|
6473
|
+
style: { color: read ? palette.read : void 0 },
|
|
6474
|
+
"aria-hidden": true
|
|
6475
|
+
}) : null]
|
|
6476
|
+
});
|
|
6477
|
+
}
|
|
6478
|
+
function BubbleTail({ side, color }) {
|
|
6479
|
+
const path = side === "out" ? "M0 0H14C10 1.8 7.4 4.7 6.4 8.3L5.3 12C4.2 7 2.4 2.9 0 0Z" : "M14 0H0C4 1.8 6.6 4.7 7.6 8.3L8.7 12C9.8 7 11.6 2.9 14 0Z";
|
|
6480
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
6481
|
+
"aria-hidden": true,
|
|
6482
|
+
className: cn$2("pointer-events-none absolute top-0 h-3.5 w-3.5", side === "out" ? "-right-[7px]" : "-left-[7px]"),
|
|
6483
|
+
style: { fill: color },
|
|
6484
|
+
viewBox: "0 0 14 12",
|
|
6485
|
+
children: /* @__PURE__ */ jsx("path", { d: path })
|
|
6486
|
+
});
|
|
6487
|
+
}
|
|
6488
|
+
function WhatsAppWallpaper({ palette }) {
|
|
6489
|
+
const patternId = useId().replace(/:/g, "");
|
|
6490
|
+
return /* @__PURE__ */ jsxs("svg", {
|
|
6491
|
+
"aria-hidden": true,
|
|
6492
|
+
className: "pointer-events-none absolute inset-0 h-full w-full",
|
|
6493
|
+
children: [/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("pattern", {
|
|
6494
|
+
id: patternId,
|
|
6495
|
+
width: "46",
|
|
6496
|
+
height: "46",
|
|
6497
|
+
patternUnits: "userSpaceOnUse",
|
|
6498
|
+
children: [/* @__PURE__ */ jsx("path", {
|
|
6499
|
+
d: "M8 11h12m-6-6v12M31 7c4 0 7 3 7 7 0 5-5 7-7 10-2-3-7-5-7-10 0-4 3-7 7-7Zm-14 25c4 0 6 2 6 5s-2 5-6 5-6-2-6-5 2-5 6-5Zm19 10 6-6m-6 0 6 6",
|
|
6500
|
+
stroke: palette.wallpaperStroke,
|
|
6501
|
+
strokeWidth: "1",
|
|
6502
|
+
fill: "none",
|
|
6503
|
+
opacity: palette.wallpaperOpacity,
|
|
6504
|
+
strokeLinecap: "round",
|
|
6505
|
+
strokeLinejoin: "round"
|
|
6506
|
+
}), /* @__PURE__ */ jsx("path", {
|
|
6507
|
+
d: "M34 29c3 0 5 2 5 4s-2 4-5 4h-6v-4c0-2 3-4 6-4Z",
|
|
6508
|
+
stroke: palette.wallpaperStroke,
|
|
6509
|
+
strokeWidth: "1",
|
|
6510
|
+
fill: "none",
|
|
6511
|
+
opacity: palette.wallpaperOpacity,
|
|
6512
|
+
strokeLinecap: "round",
|
|
6513
|
+
strokeLinejoin: "round"
|
|
6514
|
+
})]
|
|
6515
|
+
}) }), /* @__PURE__ */ jsx("rect", {
|
|
6516
|
+
width: "100%",
|
|
6517
|
+
height: "100%",
|
|
6518
|
+
fill: `url(#${patternId})`
|
|
6519
|
+
})]
|
|
6520
|
+
});
|
|
6521
|
+
}
|
|
6522
|
+
function WhatsAppComposer({ composerPlaceholder, palette }) {
|
|
6523
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
6524
|
+
className: "flex items-center gap-1.5 px-2 pb-[22px] pt-2",
|
|
6525
|
+
style: { backgroundColor: palette.composer },
|
|
6526
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
6527
|
+
className: "flex min-w-0 flex-1 items-center gap-1.5 rounded-full px-2.5 py-1.5 shadow-[0_1px_1px_rgba(15,23,42,0.06)]",
|
|
6528
|
+
style: {
|
|
6529
|
+
backgroundColor: palette.composerInput,
|
|
6530
|
+
color: palette.composerText
|
|
6531
|
+
},
|
|
6532
|
+
children: [
|
|
6533
|
+
/* @__PURE__ */ jsx(Smile, {
|
|
6534
|
+
className: "h-3.5 w-3.5 shrink-0",
|
|
6535
|
+
strokeWidth: 2,
|
|
6536
|
+
"aria-hidden": true
|
|
6537
|
+
}),
|
|
6538
|
+
/* @__PURE__ */ jsx("span", {
|
|
6539
|
+
className: "flex-1 truncate text-[10px]",
|
|
6540
|
+
children: composerPlaceholder
|
|
6541
|
+
}),
|
|
6542
|
+
/* @__PURE__ */ jsx(Paperclip, {
|
|
6543
|
+
className: "h-3.5 w-3.5 shrink-0",
|
|
6544
|
+
strokeWidth: 2,
|
|
6545
|
+
"aria-hidden": true
|
|
6546
|
+
}),
|
|
6547
|
+
/* @__PURE__ */ jsx(Camera, {
|
|
6548
|
+
className: "h-3.5 w-3.5 shrink-0",
|
|
6549
|
+
strokeWidth: 2,
|
|
6550
|
+
"aria-hidden": true
|
|
6551
|
+
})
|
|
6552
|
+
]
|
|
6553
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
6554
|
+
className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-full",
|
|
6555
|
+
style: {
|
|
6556
|
+
backgroundColor: palette.micBg,
|
|
6557
|
+
color: palette.micIcon
|
|
6558
|
+
},
|
|
6559
|
+
children: /* @__PURE__ */ jsx(Mic, {
|
|
6560
|
+
className: "h-3.5 w-3.5",
|
|
6561
|
+
strokeWidth: 2.2,
|
|
6562
|
+
"aria-hidden": true
|
|
6563
|
+
})
|
|
6564
|
+
})]
|
|
6565
|
+
});
|
|
6566
|
+
}
|
|
6567
|
+
|
|
6568
|
+
//#endregion
|
|
6569
|
+
//#region src/components/TableOfContents/index.tsx
|
|
6570
|
+
const cn$1 = (...classes) => classes.filter(Boolean).join(" ");
|
|
6571
|
+
function getIdFromUrl(url) {
|
|
6572
|
+
if (typeof url === "string" && url.startsWith("#")) return url.slice(1);
|
|
6573
|
+
return null;
|
|
6574
|
+
}
|
|
6575
|
+
function arraysShallowEqual(a, b) {
|
|
6576
|
+
if (a === b) return true;
|
|
6577
|
+
if (a.length !== b.length) return false;
|
|
6578
|
+
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
6579
|
+
return true;
|
|
6580
|
+
}
|
|
6581
|
+
function findScrollableParent(el) {
|
|
6582
|
+
let current = el?.parentElement;
|
|
6583
|
+
while (current && current !== document.body) {
|
|
6584
|
+
const overflowY = getComputedStyle(current).overflowY;
|
|
6585
|
+
if (overflowY === "auto" || overflowY === "scroll" || overflowY === "overlay") {
|
|
6586
|
+
if (current.scrollHeight > current.clientHeight) return current;
|
|
6587
|
+
}
|
|
6588
|
+
current = current.parentElement;
|
|
6589
|
+
}
|
|
6590
|
+
return document.documentElement;
|
|
6591
|
+
}
|
|
6592
|
+
function scrollAnchorIntoView(anchor, container, options = {}) {
|
|
6593
|
+
const { behavior = "smooth", block = "center" } = options;
|
|
6594
|
+
const containerRect = container.getBoundingClientRect();
|
|
6595
|
+
const offsetTopRelativeToContainer = anchor.getBoundingClientRect().top - containerRect.top + container.scrollTop;
|
|
6596
|
+
let targetScroll;
|
|
6597
|
+
if (block === "center") targetScroll = offsetTopRelativeToContainer - container.clientHeight / 2 + anchor.clientHeight / 2;
|
|
6598
|
+
else if (block === "end") targetScroll = offsetTopRelativeToContainer - container.clientHeight + anchor.clientHeight;
|
|
6599
|
+
else targetScroll = offsetTopRelativeToContainer;
|
|
6600
|
+
container.scrollTo({
|
|
6601
|
+
top: Math.max(0, targetScroll),
|
|
6602
|
+
behavior
|
|
6603
|
+
});
|
|
6604
|
+
}
|
|
6605
|
+
var TocObserver = class {
|
|
6606
|
+
constructor() {
|
|
6607
|
+
this.items = [];
|
|
6608
|
+
this.single = false;
|
|
6609
|
+
this.intersectionObserver = null;
|
|
6610
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
6611
|
+
}
|
|
6612
|
+
listen(fn) {
|
|
6613
|
+
this.listeners.add(fn);
|
|
6614
|
+
}
|
|
6615
|
+
unlisten(fn) {
|
|
6616
|
+
this.listeners.delete(fn);
|
|
6617
|
+
}
|
|
6618
|
+
setItems(nextItems) {
|
|
6619
|
+
if (this.intersectionObserver) for (const item of this.items) {
|
|
6620
|
+
const el = document.getElementById(item.id);
|
|
6621
|
+
if (el) this.intersectionObserver.unobserve(el);
|
|
6622
|
+
}
|
|
6623
|
+
const next = [];
|
|
6624
|
+
for (const item of nextItems) {
|
|
6625
|
+
const id = getIdFromUrl(item.url);
|
|
6626
|
+
if (!id) continue;
|
|
6627
|
+
next.push({
|
|
6628
|
+
id,
|
|
6629
|
+
active: false,
|
|
6630
|
+
fallback: false,
|
|
6631
|
+
t: 0,
|
|
6632
|
+
original: item
|
|
6633
|
+
});
|
|
6634
|
+
}
|
|
6635
|
+
this.update(next);
|
|
6636
|
+
this.observeAll();
|
|
6637
|
+
}
|
|
6638
|
+
watch(options) {
|
|
6639
|
+
if (this.intersectionObserver) return;
|
|
6640
|
+
if (typeof window === "undefined") return;
|
|
6641
|
+
this.intersectionObserver = new IntersectionObserver(this.handleIntersection.bind(this), options);
|
|
6642
|
+
this.observeAll();
|
|
6643
|
+
}
|
|
6644
|
+
unwatch() {
|
|
6645
|
+
this.intersectionObserver?.disconnect();
|
|
6646
|
+
this.intersectionObserver = null;
|
|
6647
|
+
}
|
|
6648
|
+
handleIntersection(entries) {
|
|
6649
|
+
if (entries.length === 0) return;
|
|
6650
|
+
let hasActive = false;
|
|
6651
|
+
const updated = this.items.map((item) => {
|
|
6652
|
+
const entry = entries.find((e) => e.target.id === item.id);
|
|
6653
|
+
let active = entry ? entry.isIntersecting : item.active && !item.fallback;
|
|
6654
|
+
if (this.single && hasActive) active = false;
|
|
6655
|
+
let nextItem = item;
|
|
6656
|
+
if (item.active !== active) nextItem = {
|
|
6657
|
+
...item,
|
|
6658
|
+
t: Date.now(),
|
|
6659
|
+
active,
|
|
6660
|
+
fallback: false
|
|
6661
|
+
};
|
|
6662
|
+
if (active) hasActive = true;
|
|
6663
|
+
return nextItem;
|
|
6664
|
+
});
|
|
6665
|
+
if (!hasActive && entries[0].rootBounds) {
|
|
6666
|
+
const viewTop = entries[0].rootBounds.top;
|
|
6667
|
+
let min = Number.POSITIVE_INFINITY;
|
|
6668
|
+
let fallbackIdx = -1;
|
|
6669
|
+
for (let i = 0; i < updated.length; i++) {
|
|
5326
6670
|
const el = document.getElementById(updated[i].id);
|
|
5327
6671
|
if (!el) continue;
|
|
5328
6672
|
const distance = Math.abs(viewTop - el.getBoundingClientRect().top);
|
|
@@ -5361,246 +6705,1027 @@ function useObserver() {
|
|
|
5361
6705
|
return observer;
|
|
5362
6706
|
}
|
|
5363
6707
|
/**
|
|
5364
|
-
* Headless provider that drives the scrollspy. Use directly when you want to
|
|
5365
|
-
* render the visual ToC yourself (e.g. mobile drawer, custom layout).
|
|
6708
|
+
* Headless provider that drives the scrollspy. Use directly when you want to
|
|
6709
|
+
* render the visual ToC yourself (e.g. mobile drawer, custom layout).
|
|
6710
|
+
*/
|
|
6711
|
+
function TOCProvider({ items, single = false, rootMargin = "0px 0px -70% 0px", threshold = 0, children }) {
|
|
6712
|
+
const observer = useMemo(() => new TocObserver(), []);
|
|
6713
|
+
observer.single = single;
|
|
6714
|
+
useEffect(() => {
|
|
6715
|
+
observer.setItems(items);
|
|
6716
|
+
}, [observer, items]);
|
|
6717
|
+
useEffect(() => {
|
|
6718
|
+
observer.watch({
|
|
6719
|
+
rootMargin,
|
|
6720
|
+
threshold
|
|
6721
|
+
});
|
|
6722
|
+
return () => observer.unwatch();
|
|
6723
|
+
}, [
|
|
6724
|
+
observer,
|
|
6725
|
+
rootMargin,
|
|
6726
|
+
threshold
|
|
6727
|
+
]);
|
|
6728
|
+
return /* @__PURE__ */ jsx(ObserverContext.Provider, {
|
|
6729
|
+
value: observer,
|
|
6730
|
+
children: /* @__PURE__ */ jsx(ItemsContext.Provider, {
|
|
6731
|
+
value: items,
|
|
6732
|
+
children
|
|
6733
|
+
})
|
|
6734
|
+
});
|
|
6735
|
+
}
|
|
6736
|
+
function useObserverState(select, isEqual = Object.is) {
|
|
6737
|
+
const observer = useObserver();
|
|
6738
|
+
const [value, setValue] = useState(() => select(observer.items));
|
|
6739
|
+
const selectRef = useRef(select);
|
|
6740
|
+
const isEqualRef = useRef(isEqual);
|
|
6741
|
+
selectRef.current = select;
|
|
6742
|
+
isEqualRef.current = isEqual;
|
|
6743
|
+
useEffect(() => {
|
|
6744
|
+
const listener = (items) => {
|
|
6745
|
+
const next = selectRef.current(items);
|
|
6746
|
+
setValue((prev) => isEqualRef.current(prev, next) ? prev : next);
|
|
6747
|
+
};
|
|
6748
|
+
observer.listen(listener);
|
|
6749
|
+
return () => observer.unlisten(listener);
|
|
6750
|
+
}, [observer]);
|
|
6751
|
+
return value;
|
|
6752
|
+
}
|
|
6753
|
+
/** Returns the id of the most recently activated heading (best guess). */
|
|
6754
|
+
function useActiveAnchor() {
|
|
6755
|
+
return useObserverState((items) => {
|
|
6756
|
+
let best;
|
|
6757
|
+
for (const item of items) {
|
|
6758
|
+
if (!item.active) continue;
|
|
6759
|
+
if (!best || item.t > best.t) best = item;
|
|
6760
|
+
}
|
|
6761
|
+
return best?.id;
|
|
6762
|
+
});
|
|
6763
|
+
}
|
|
6764
|
+
/** Returns the ids of every currently active heading. */
|
|
6765
|
+
function useActiveAnchors() {
|
|
6766
|
+
return useObserverState((items) => {
|
|
6767
|
+
const out = [];
|
|
6768
|
+
for (const item of items) if (item.active) out.push(item.id);
|
|
6769
|
+
return out;
|
|
6770
|
+
}, arraysShallowEqual);
|
|
6771
|
+
}
|
|
6772
|
+
/** Returns the static items list registered with the provider. */
|
|
6773
|
+
function useTOCItems() {
|
|
6774
|
+
return useContext(ItemsContext);
|
|
6775
|
+
}
|
|
6776
|
+
function handleAnchorClick(e, id) {
|
|
6777
|
+
const el = document.getElementById(id);
|
|
6778
|
+
if (!el) return;
|
|
6779
|
+
e.preventDefault();
|
|
6780
|
+
el.scrollIntoView({
|
|
6781
|
+
behavior: "smooth",
|
|
6782
|
+
block: "start"
|
|
6783
|
+
});
|
|
6784
|
+
if (typeof window !== "undefined" && window.history) window.history.replaceState(null, "", `#${id}`);
|
|
6785
|
+
}
|
|
6786
|
+
function TocAnchor({ item }) {
|
|
6787
|
+
const id = getIdFromUrl(item.url) ?? "";
|
|
6788
|
+
const activeIds = useActiveAnchors();
|
|
6789
|
+
const isActive = id ? activeIds.includes(id) : false;
|
|
6790
|
+
const linksRef = useContext(LinksRefContext);
|
|
6791
|
+
return /* @__PURE__ */ jsx("a", {
|
|
6792
|
+
ref: useCallback((node) => {
|
|
6793
|
+
if (!linksRef || !id) return;
|
|
6794
|
+
if (node) linksRef.current.set(id, node);
|
|
6795
|
+
else linksRef.current.delete(id);
|
|
6796
|
+
}, [linksRef, id]),
|
|
6797
|
+
href: item.url,
|
|
6798
|
+
"data-active": isActive,
|
|
6799
|
+
onClick: (e) => handleAnchorClick(e, id),
|
|
6800
|
+
className: cn$1("py-1.5 text-sm transition-colors scroll-m-4 wrap-anywhere first:pt-0 last:pb-0", "text-[var(--dashboard-text-secondary,#6b7280)]", "hover:text-[var(--dashboard-text-primary,#2d2d2d)]", "data-[active=true]:text-[var(--dashboard-primary,#e74410)]", item.depth <= 2 && "pl-3", item.depth === 3 && "pl-6", item.depth >= 4 && "pl-8"),
|
|
6801
|
+
children: item.title
|
|
6802
|
+
});
|
|
6803
|
+
}
|
|
6804
|
+
function TocThumb({ computed }) {
|
|
6805
|
+
const ref = useRef(null);
|
|
6806
|
+
const observer = useObserver();
|
|
6807
|
+
const calculate = useCallback((items) => {
|
|
6808
|
+
const out = {};
|
|
6809
|
+
const startIdx = items.findIndex((item) => item.active);
|
|
6810
|
+
if (startIdx === -1) return out;
|
|
6811
|
+
let endIdx = startIdx;
|
|
6812
|
+
for (let i = items.length - 1; i >= startIdx; i--) if (items[i].active) {
|
|
6813
|
+
endIdx = i;
|
|
6814
|
+
break;
|
|
6815
|
+
}
|
|
6816
|
+
const startPos = computed.positions[startIdx];
|
|
6817
|
+
const endPos = computed.positions[endIdx];
|
|
6818
|
+
if (!startPos || !endPos) return out;
|
|
6819
|
+
out["--track-top"] = `${startPos[0]}px`;
|
|
6820
|
+
out["--track-bottom"] = `${endPos[1]}px`;
|
|
6821
|
+
return out;
|
|
6822
|
+
}, [computed]);
|
|
6823
|
+
useEffect(() => {
|
|
6824
|
+
const el = ref.current;
|
|
6825
|
+
if (!el) return;
|
|
6826
|
+
const apply = (items) => {
|
|
6827
|
+
const styles = calculate(items);
|
|
6828
|
+
for (const [k, v] of Object.entries(styles)) el.style.setProperty(k, v);
|
|
6829
|
+
};
|
|
6830
|
+
apply(observer.items);
|
|
6831
|
+
observer.listen(apply);
|
|
6832
|
+
return () => observer.unlisten(apply);
|
|
6833
|
+
}, [observer, calculate]);
|
|
6834
|
+
const initialStyles = calculate(observer.items);
|
|
6835
|
+
return /* @__PURE__ */ jsx("div", {
|
|
6836
|
+
ref,
|
|
6837
|
+
"aria-hidden": true,
|
|
6838
|
+
className: "absolute inset-y-0 left-0 w-px bg-[var(--dashboard-primary,#e74410)] transition-[clip-path]",
|
|
6839
|
+
style: {
|
|
6840
|
+
clipPath: "polygon(0 var(--track-top, 0), 100% var(--track-top, 0), 100% var(--track-bottom, 0), 0 var(--track-bottom, 0))",
|
|
6841
|
+
...initialStyles
|
|
6842
|
+
}
|
|
6843
|
+
});
|
|
6844
|
+
}
|
|
6845
|
+
function TocList({ items, showThumb }) {
|
|
6846
|
+
const containerRef = useRef(null);
|
|
6847
|
+
const [computed, setComputed] = useState(null);
|
|
6848
|
+
const recompute = useCallback(() => {
|
|
6849
|
+
const container = containerRef.current;
|
|
6850
|
+
if (!container) return;
|
|
6851
|
+
if (items.length === 0) {
|
|
6852
|
+
setComputed(null);
|
|
6853
|
+
return;
|
|
6854
|
+
}
|
|
6855
|
+
const positions = [];
|
|
6856
|
+
for (const item of items) {
|
|
6857
|
+
const el = container.querySelector(`a[href="${item.url}"]`);
|
|
6858
|
+
if (!el) {
|
|
6859
|
+
positions.push([0, 0]);
|
|
6860
|
+
continue;
|
|
6861
|
+
}
|
|
6862
|
+
const styles = window.getComputedStyle(el);
|
|
6863
|
+
const top = el.offsetTop + parseFloat(styles.paddingTop || "0");
|
|
6864
|
+
const bottom = el.offsetTop + el.clientHeight - parseFloat(styles.paddingBottom || "0");
|
|
6865
|
+
positions.push([top, bottom]);
|
|
6866
|
+
}
|
|
6867
|
+
setComputed({ positions });
|
|
6868
|
+
}, [items]);
|
|
6869
|
+
useLayoutEffect(() => {
|
|
6870
|
+
recompute();
|
|
6871
|
+
}, [recompute]);
|
|
6872
|
+
useEffect(() => {
|
|
6873
|
+
const container = containerRef.current;
|
|
6874
|
+
if (!container || typeof ResizeObserver === "undefined") return;
|
|
6875
|
+
const ro = new ResizeObserver(() => recompute());
|
|
6876
|
+
ro.observe(container);
|
|
6877
|
+
return () => ro.disconnect();
|
|
6878
|
+
}, [recompute]);
|
|
6879
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
6880
|
+
className: "relative",
|
|
6881
|
+
children: [showThumb && computed && /* @__PURE__ */ jsx(TocThumb, { computed }), /* @__PURE__ */ jsx("div", {
|
|
6882
|
+
ref: containerRef,
|
|
6883
|
+
className: "flex flex-col border-l border-[var(--dashboard-text-secondary,#6b7280)]/15",
|
|
6884
|
+
children: items.map((item) => /* @__PURE__ */ jsx(TocAnchor, { item }, item.url))
|
|
6885
|
+
})]
|
|
6886
|
+
});
|
|
6887
|
+
}
|
|
6888
|
+
function ActiveChangeReporter({ onActiveChange }) {
|
|
6889
|
+
const ids = useActiveAnchors();
|
|
6890
|
+
const cbRef = useRef(onActiveChange);
|
|
6891
|
+
cbRef.current = onActiveChange;
|
|
6892
|
+
useEffect(() => {
|
|
6893
|
+
cbRef.current(ids);
|
|
6894
|
+
}, [ids]);
|
|
6895
|
+
return null;
|
|
6896
|
+
}
|
|
6897
|
+
function ActiveScrollSync({ linksRef }) {
|
|
6898
|
+
const activeId = useActiveAnchor();
|
|
6899
|
+
useEffect(() => {
|
|
6900
|
+
if (!activeId) return;
|
|
6901
|
+
const link = linksRef.current.get(activeId);
|
|
6902
|
+
if (!link) return;
|
|
6903
|
+
const container = findScrollableParent(link);
|
|
6904
|
+
if (container === document.documentElement) return;
|
|
6905
|
+
scrollAnchorIntoView(link, container);
|
|
6906
|
+
}, [activeId, linksRef]);
|
|
6907
|
+
return null;
|
|
6908
|
+
}
|
|
6909
|
+
/**
|
|
6910
|
+
* Adapted from Fumadocs (MIT) — https://github.com/fuma-nama/fumadocs
|
|
6911
|
+
*
|
|
6912
|
+
* Scrollspy table of contents. Renders a sticky list of headings and tracks
|
|
6913
|
+
* which are visible in the viewport via IntersectionObserver. The active
|
|
6914
|
+
* range is highlighted with a thin animated bar (TocThumb).
|
|
5366
6915
|
*/
|
|
5367
|
-
function
|
|
5368
|
-
const
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
}, [observer, items]);
|
|
5373
|
-
useEffect(() => {
|
|
5374
|
-
observer.watch({
|
|
5375
|
-
rootMargin,
|
|
5376
|
-
threshold
|
|
5377
|
-
});
|
|
5378
|
-
return () => observer.unwatch();
|
|
5379
|
-
}, [
|
|
5380
|
-
observer,
|
|
6916
|
+
function TableOfContents({ items, title = "Nesta página", showThumb = true, single = false, rootMargin = "0px 0px -70% 0px", threshold = 0, className, onActiveChange }) {
|
|
6917
|
+
const linksRef = useRef(/* @__PURE__ */ new Map());
|
|
6918
|
+
return /* @__PURE__ */ jsx(TOCProvider, {
|
|
6919
|
+
items,
|
|
6920
|
+
single,
|
|
5381
6921
|
rootMargin,
|
|
5382
|
-
threshold
|
|
5383
|
-
|
|
5384
|
-
|
|
5385
|
-
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
|
|
6922
|
+
threshold,
|
|
6923
|
+
children: /* @__PURE__ */ jsx(LinksRefContext.Provider, {
|
|
6924
|
+
value: linksRef,
|
|
6925
|
+
children: /* @__PURE__ */ jsxs("nav", {
|
|
6926
|
+
"aria-label": typeof title === "string" ? title : "Sumário",
|
|
6927
|
+
className: cn$1("text-sm", className),
|
|
6928
|
+
children: [
|
|
6929
|
+
title !== null && /* @__PURE__ */ jsxs("h3", {
|
|
6930
|
+
className: "inline-flex items-center gap-1.5 text-sm font-medium mb-3 text-[var(--dashboard-text-primary,#2d2d2d)]",
|
|
6931
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
6932
|
+
className: "h-4 w-4",
|
|
6933
|
+
"aria-hidden": true
|
|
6934
|
+
}), title]
|
|
6935
|
+
}),
|
|
6936
|
+
/* @__PURE__ */ jsx(TocList, {
|
|
6937
|
+
items,
|
|
6938
|
+
showThumb
|
|
6939
|
+
}),
|
|
6940
|
+
onActiveChange && /* @__PURE__ */ jsx(ActiveChangeReporter, { onActiveChange }),
|
|
6941
|
+
/* @__PURE__ */ jsx(ActiveScrollSync, { linksRef })
|
|
6942
|
+
]
|
|
6943
|
+
})
|
|
5389
6944
|
})
|
|
5390
6945
|
});
|
|
5391
6946
|
}
|
|
5392
|
-
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
},
|
|
5407
|
-
|
|
6947
|
+
|
|
6948
|
+
//#endregion
|
|
6949
|
+
//#region src/components/SocialIcon/index.tsx
|
|
6950
|
+
const socialIconNames = [
|
|
6951
|
+
"whatsapp",
|
|
6952
|
+
"instagram",
|
|
6953
|
+
"linkedin",
|
|
6954
|
+
"github",
|
|
6955
|
+
"youtube"
|
|
6956
|
+
];
|
|
6957
|
+
const socialIconPaths = {
|
|
6958
|
+
whatsapp: {
|
|
6959
|
+
viewBox: "0 0 448 512",
|
|
6960
|
+
path: "M380.9 97.1C339 55.1 283.2 32 223.9 32c-122.4 0-222 99.6-222 222 0 39.1 10.2 77.3 29.6 111L0 480l117.7-30.9c32.4 17.7 68.9 27 106.1 27h.1c122.3 0 224.1-99.6 224.1-222 0-59.3-25.2-115-67.1-157zm-157 341.6c-33.2 0-65.7-8.9-94-25.7l-6.7-4-69.8 18.3L72 359.2l-4.4-7c-18.5-29.4-28.2-63.3-28.2-98.2 0-101.7 82.8-184.5 184.6-184.5 49.3 0 95.6 19.2 130.4 54.1 34.8 34.9 56.2 81.2 56.1 130.5 0 101.8-84.9 184.6-186.6 184.6zm101.2-138.2c-5.5-2.8-32.8-16.2-37.9-18-5.1-1.9-8.8-2.8-12.5 2.8-3.7 5.6-14.3 18-17.6 21.8-3.2 3.7-6.5 4.2-12 1.4-32.6-16.3-54-29.1-75.5-66-5.7-9.8 5.7-9.1 16.3-30.3 1.8-3.7.9-6.9-.5-9.7-1.4-2.8-12.5-30.1-17.1-41.2-4.5-10.8-9.1-9.3-12.5-9.5-3.2-.2-6.9-.2-10.6-.2-3.7 0-9.7 1.4-14.8 6.9-5.1 5.6-19.4 19-19.4 46.3 0 27.3 19.9 53.7 22.6 57.4 2.8 3.7 39.1 59.7 94.8 83.8 35.2 15.2 49 16.5 66.6 13.9 10.7-1.6 32.8-13.4 37.4-26.4 4.6-13 4.6-24.1 3.2-26.4-1.3-2.5-5-3.9-10.5-6.6z"
|
|
6961
|
+
},
|
|
6962
|
+
instagram: {
|
|
6963
|
+
viewBox: "0 0 448 512",
|
|
6964
|
+
path: "M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z"
|
|
6965
|
+
},
|
|
6966
|
+
linkedin: {
|
|
6967
|
+
viewBox: "0 0 448 512",
|
|
6968
|
+
path: "M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"
|
|
6969
|
+
},
|
|
6970
|
+
github: {
|
|
6971
|
+
viewBox: "0 0 496 512",
|
|
6972
|
+
path: "M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"
|
|
6973
|
+
},
|
|
6974
|
+
youtube: {
|
|
6975
|
+
viewBox: "0 0 576 512",
|
|
6976
|
+
path: "M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z"
|
|
6977
|
+
}
|
|
6978
|
+
};
|
|
6979
|
+
function SocialIcon({ name, size = 24, title, fill = "currentColor", ...props }) {
|
|
6980
|
+
const icon = socialIconPaths[name];
|
|
6981
|
+
return /* @__PURE__ */ jsxs("svg", {
|
|
6982
|
+
width: size,
|
|
6983
|
+
height: size,
|
|
6984
|
+
viewBox: icon.viewBox,
|
|
6985
|
+
fill,
|
|
6986
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
6987
|
+
"aria-hidden": title ? void 0 : true,
|
|
6988
|
+
role: title ? "img" : void 0,
|
|
6989
|
+
...props,
|
|
6990
|
+
children: [title ? /* @__PURE__ */ jsx("title", { children: title }) : null, /* @__PURE__ */ jsx("path", { d: icon.path })]
|
|
6991
|
+
});
|
|
5408
6992
|
}
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5414
|
-
|
|
5415
|
-
|
|
5416
|
-
|
|
5417
|
-
|
|
6993
|
+
function WhatsappIcon(props) {
|
|
6994
|
+
return /* @__PURE__ */ jsx(SocialIcon, {
|
|
6995
|
+
name: "whatsapp",
|
|
6996
|
+
...props
|
|
6997
|
+
});
|
|
6998
|
+
}
|
|
6999
|
+
function InstagramIcon(props) {
|
|
7000
|
+
return /* @__PURE__ */ jsx(SocialIcon, {
|
|
7001
|
+
name: "instagram",
|
|
7002
|
+
...props
|
|
7003
|
+
});
|
|
7004
|
+
}
|
|
7005
|
+
function LinkedinIcon(props) {
|
|
7006
|
+
return /* @__PURE__ */ jsx(SocialIcon, {
|
|
7007
|
+
name: "linkedin",
|
|
7008
|
+
...props
|
|
7009
|
+
});
|
|
7010
|
+
}
|
|
7011
|
+
function GithubIcon(props) {
|
|
7012
|
+
return /* @__PURE__ */ jsx(SocialIcon, {
|
|
7013
|
+
name: "github",
|
|
7014
|
+
...props
|
|
7015
|
+
});
|
|
7016
|
+
}
|
|
7017
|
+
function YoutubeIcon(props) {
|
|
7018
|
+
return /* @__PURE__ */ jsx(SocialIcon, {
|
|
7019
|
+
name: "youtube",
|
|
7020
|
+
...props
|
|
7021
|
+
});
|
|
7022
|
+
}
|
|
7023
|
+
|
|
7024
|
+
//#endregion
|
|
7025
|
+
//#region src/components/ConversationPanel/utils.ts
|
|
7026
|
+
const cn = (...classes) => classes.filter(Boolean).join(" ");
|
|
7027
|
+
function getConversationInitials(participant) {
|
|
7028
|
+
if (participant.initials) return participant.initials;
|
|
7029
|
+
return (participant.name || participant.email || participant.phone || "?").split(/\s+/).filter(Boolean).slice(0, 2).map((part) => part.charAt(0).toUpperCase()).join("");
|
|
7030
|
+
}
|
|
7031
|
+
function defaultConversationDateFormatter(value) {
|
|
7032
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
7033
|
+
if (Number.isNaN(date.getTime())) return "";
|
|
7034
|
+
const diff = (/* @__PURE__ */ new Date()).getTime() - date.getTime();
|
|
7035
|
+
const day = 1440 * 60 * 1e3;
|
|
7036
|
+
if (diff >= 0 && diff < day) return date.toLocaleTimeString("pt-BR", {
|
|
7037
|
+
hour: "2-digit",
|
|
7038
|
+
minute: "2-digit"
|
|
7039
|
+
});
|
|
7040
|
+
if (diff >= day && diff < day * 2) return "Ontem";
|
|
7041
|
+
return date.toLocaleDateString("pt-BR", {
|
|
7042
|
+
day: "2-digit",
|
|
7043
|
+
month: "2-digit"
|
|
7044
|
+
});
|
|
7045
|
+
}
|
|
7046
|
+
function defaultConversationTimeFormatter(value) {
|
|
7047
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
7048
|
+
if (Number.isNaN(date.getTime())) return "";
|
|
7049
|
+
return date.toLocaleString("pt-BR", {
|
|
7050
|
+
day: "2-digit",
|
|
7051
|
+
month: "2-digit",
|
|
7052
|
+
hour: "2-digit",
|
|
7053
|
+
minute: "2-digit"
|
|
7054
|
+
});
|
|
7055
|
+
}
|
|
7056
|
+
|
|
7057
|
+
//#endregion
|
|
7058
|
+
//#region src/components/ConversationPanel/ConversationAvatar.tsx
|
|
7059
|
+
function ConversationAvatar({ participant, size = "md", className }) {
|
|
7060
|
+
const sizeClass = {
|
|
7061
|
+
sm: "h-9 w-9 text-sm",
|
|
7062
|
+
md: "h-11 w-11 text-base",
|
|
7063
|
+
lg: "h-12 w-12 text-lg"
|
|
7064
|
+
}[size];
|
|
7065
|
+
if (participant.avatarUrl) return /* @__PURE__ */ jsx("img", {
|
|
7066
|
+
src: participant.avatarUrl,
|
|
7067
|
+
alt: participant.name,
|
|
7068
|
+
className: cn("flex-shrink-0 rounded-full object-cover", sizeClass, className)
|
|
7069
|
+
});
|
|
7070
|
+
return /* @__PURE__ */ jsx("div", {
|
|
7071
|
+
className: cn("flex flex-shrink-0 items-center justify-center rounded-full bg-[var(--dashboard-primary,#37a501)]/12 font-semibold text-[var(--dashboard-primary,#37a501)]", sizeClass, className),
|
|
7072
|
+
children: getConversationInitials(participant)
|
|
7073
|
+
});
|
|
7074
|
+
}
|
|
7075
|
+
|
|
7076
|
+
//#endregion
|
|
7077
|
+
//#region src/components/ConversationPanel/ConversationComposer.tsx
|
|
7078
|
+
function ConversationComposer({ value = "", onChange, onSend, onAttachClick, onFileSelect, acceptedFileTypes, placeholder = "Digite sua mensagem...", disabled = false, sending = false, uploading = false, status = "active", inactiveLabel = "IA esta respondendo esta conversa", expiredLabel = "Janela de atendimento expirada. Envie um template para reabrir a conversa.", attachLabel = "Enviar arquivo", sendLabel = "Enviar mensagem", className }) {
|
|
7079
|
+
const fileInputRef = useRef(null);
|
|
7080
|
+
const isExpired = status === "expired";
|
|
7081
|
+
const isAi = status === "ai";
|
|
7082
|
+
const isDisabled = disabled || status === "disabled" || isExpired || isAi;
|
|
7083
|
+
const canAttach = !!onAttachClick || !!onFileSelect;
|
|
7084
|
+
if (isAi) return /* @__PURE__ */ jsxs("div", {
|
|
7085
|
+
className: cn("flex items-center justify-center gap-2 border-t border-[var(--dashboard-text-secondary,#6b7280)]/20 bg-[var(--dashboard-surface,#ffffff)] px-4 py-4 text-xs text-[var(--dashboard-text-secondary,#6b7280)]", className),
|
|
7086
|
+
children: [/* @__PURE__ */ jsx(Bot, {
|
|
7087
|
+
size: 16,
|
|
7088
|
+
className: "text-[var(--dashboard-primary,#37a501)]"
|
|
7089
|
+
}), inactiveLabel]
|
|
7090
|
+
});
|
|
7091
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
7092
|
+
className: cn("border-t border-[var(--dashboard-text-secondary,#6b7280)]/20 bg-[var(--dashboard-surface,#ffffff)] px-4 py-3 sm:px-6", className),
|
|
7093
|
+
children: [
|
|
7094
|
+
isExpired && /* @__PURE__ */ jsxs("div", {
|
|
7095
|
+
className: "mb-2 flex items-center gap-2 rounded-lg border border-[var(--dashboard-status-warning,#f59e0b)]/30 bg-[var(--dashboard-status-warning,#f59e0b)]/10 p-2 text-xs text-[var(--dashboard-status-warning,#f59e0b)]",
|
|
7096
|
+
children: [/* @__PURE__ */ jsx(AlertTriangle, {
|
|
7097
|
+
size: 16,
|
|
7098
|
+
className: "flex-shrink-0"
|
|
7099
|
+
}), /* @__PURE__ */ jsx("p", { children: expiredLabel })]
|
|
7100
|
+
}),
|
|
7101
|
+
onFileSelect && /* @__PURE__ */ jsx("input", {
|
|
7102
|
+
ref: fileInputRef,
|
|
7103
|
+
type: "file",
|
|
7104
|
+
className: "hidden",
|
|
7105
|
+
accept: acceptedFileTypes,
|
|
7106
|
+
onChange: (event) => {
|
|
7107
|
+
const file = event.target.files?.[0];
|
|
7108
|
+
if (file) onFileSelect(file);
|
|
7109
|
+
event.target.value = "";
|
|
7110
|
+
}
|
|
7111
|
+
}),
|
|
7112
|
+
/* @__PURE__ */ jsxs("div", {
|
|
7113
|
+
className: "flex items-center gap-2",
|
|
7114
|
+
children: [
|
|
7115
|
+
canAttach && /* @__PURE__ */ jsx("button", {
|
|
7116
|
+
type: "button",
|
|
7117
|
+
onClick: () => {
|
|
7118
|
+
onAttachClick?.();
|
|
7119
|
+
if (onFileSelect) fileInputRef.current?.click();
|
|
7120
|
+
},
|
|
7121
|
+
disabled: disabled || sending || uploading,
|
|
7122
|
+
className: "inline-flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-lg text-[var(--dashboard-text-secondary,#6b7280)] transition-colors hover:bg-[var(--dashboard-primary,#37a501)]/10 hover:text-[var(--dashboard-primary,#37a501)] disabled:cursor-not-allowed disabled:opacity-50",
|
|
7123
|
+
"aria-label": attachLabel,
|
|
7124
|
+
children: uploading ? /* @__PURE__ */ jsx(Loader2, {
|
|
7125
|
+
size: 18,
|
|
7126
|
+
className: "animate-spin"
|
|
7127
|
+
}) : /* @__PURE__ */ jsx(Paperclip, { size: 18 })
|
|
7128
|
+
}),
|
|
7129
|
+
/* @__PURE__ */ jsx("input", {
|
|
7130
|
+
type: "text",
|
|
7131
|
+
value,
|
|
7132
|
+
onChange: (event) => onChange?.(event.target.value),
|
|
7133
|
+
onKeyDown: (event) => {
|
|
7134
|
+
if (event.key === "Enter" && !event.shiftKey) {
|
|
7135
|
+
event.preventDefault();
|
|
7136
|
+
if (!isDisabled && value.trim() && !sending) onSend?.();
|
|
7137
|
+
}
|
|
7138
|
+
},
|
|
7139
|
+
placeholder: isExpired ? "Mensagens livres indisponiveis" : placeholder,
|
|
7140
|
+
disabled: isDisabled || sending,
|
|
7141
|
+
className: "h-10 min-w-0 flex-1 rounded-lg border border-[var(--dashboard-text-secondary,#6b7280)]/25 bg-[var(--dashboard-surface,#ffffff)] px-4 text-sm text-[var(--dashboard-text-primary,#2d2d2d)] outline-none transition-colors focus:border-[var(--dashboard-primary,#37a501)] focus:ring-2 focus:ring-[var(--dashboard-primary,#37a501)]/20 disabled:cursor-not-allowed disabled:bg-[var(--dashboard-text-secondary,#6b7280)]/8 disabled:opacity-60"
|
|
7142
|
+
}),
|
|
7143
|
+
/* @__PURE__ */ jsx("button", {
|
|
7144
|
+
type: "button",
|
|
7145
|
+
onClick: onSend,
|
|
7146
|
+
disabled: isDisabled || sending || !value.trim(),
|
|
7147
|
+
className: "inline-flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-lg bg-[var(--dashboard-primary,#37a501)] text-white transition-colors hover:brightness-110 disabled:cursor-not-allowed disabled:opacity-50",
|
|
7148
|
+
"aria-label": sendLabel,
|
|
7149
|
+
children: sending ? /* @__PURE__ */ jsx(Loader2, {
|
|
7150
|
+
size: 18,
|
|
7151
|
+
className: "animate-spin"
|
|
7152
|
+
}) : /* @__PURE__ */ jsx(Send, { size: 18 })
|
|
7153
|
+
})
|
|
7154
|
+
]
|
|
7155
|
+
})
|
|
7156
|
+
]
|
|
7157
|
+
});
|
|
7158
|
+
}
|
|
7159
|
+
|
|
7160
|
+
//#endregion
|
|
7161
|
+
//#region src/components/ConversationPanel/ConversationEventSeparator.tsx
|
|
7162
|
+
function ConversationEventSeparator({ label, description, className }) {
|
|
7163
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
7164
|
+
className: cn("group relative flex w-full items-center gap-3 py-1", className),
|
|
7165
|
+
title: typeof description === "string" ? description : void 0,
|
|
7166
|
+
children: [
|
|
7167
|
+
/* @__PURE__ */ jsx("div", { className: "h-px flex-1 bg-[var(--dashboard-text-secondary,#6b7280)]/25" }),
|
|
7168
|
+
/* @__PURE__ */ jsx("span", {
|
|
7169
|
+
className: "whitespace-nowrap text-xs text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
7170
|
+
children: label
|
|
7171
|
+
}),
|
|
7172
|
+
/* @__PURE__ */ jsx("div", { className: "h-px flex-1 bg-[var(--dashboard-text-secondary,#6b7280)]/25" }),
|
|
7173
|
+
description && /* @__PURE__ */ jsx("div", {
|
|
7174
|
+
className: "pointer-events-none absolute left-1/2 top-full z-10 mt-2 max-w-sm -translate-x-1/2 opacity-0 transition-opacity group-hover:opacity-100",
|
|
7175
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
7176
|
+
className: "rounded-lg bg-[var(--dashboard-text-primary,#2d2d2d)] px-3 py-2 text-xs text-[var(--dashboard-surface,#ffffff)] shadow-lg",
|
|
7177
|
+
children: description
|
|
7178
|
+
})
|
|
7179
|
+
})
|
|
7180
|
+
]
|
|
7181
|
+
});
|
|
7182
|
+
}
|
|
7183
|
+
|
|
7184
|
+
//#endregion
|
|
7185
|
+
//#region src/components/ConversationPanel/ConversationSupportBadge.tsx
|
|
7186
|
+
function ConversationSupportBadge({ status, label, className }) {
|
|
7187
|
+
if (!status || status === "none") return null;
|
|
7188
|
+
return /* @__PURE__ */ jsx("span", {
|
|
7189
|
+
className: cn("inline-flex items-center rounded-full px-2 py-0.5 text-[11px] font-semibold", status === "requested" && "animate-pulse", status === "requested" ? "bg-[var(--dashboard-status-warning,#f59e0b)] text-white" : "bg-[var(--dashboard-primary,#37a501)] text-white", className),
|
|
7190
|
+
children: label || (status === "requested" ? "Aguardando" : "Em suporte")
|
|
7191
|
+
});
|
|
7192
|
+
}
|
|
7193
|
+
|
|
7194
|
+
//#endregion
|
|
7195
|
+
//#region src/components/ConversationPanel/ConversationPreviewCard.tsx
|
|
7196
|
+
function ConversationPreviewCard({ item, selected = item.selected, onSelect, formatDate = defaultConversationDateFormatter, variant = "card", showContact = true, showMeta = true, showSupportBadge = true, showUnreadBadge = true, contentClassName, className }) {
|
|
7197
|
+
const timeLabel = item.lastMessageLabel || (item.lastMessageAt ? formatDate(item.lastMessageAt) : void 0);
|
|
7198
|
+
const compact = variant === "compact";
|
|
7199
|
+
const list = variant === "list";
|
|
7200
|
+
const content = /* @__PURE__ */ jsxs("div", {
|
|
7201
|
+
className: cn("flex gap-3", compact ? "px-3 py-3" : "px-4 py-4", contentClassName),
|
|
7202
|
+
children: [/* @__PURE__ */ jsx(ConversationAvatar, {
|
|
7203
|
+
participant: item.participant,
|
|
7204
|
+
size: compact ? "md" : "lg"
|
|
7205
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
7206
|
+
className: "min-w-0 flex-1",
|
|
7207
|
+
children: [
|
|
7208
|
+
/* @__PURE__ */ jsxs("div", {
|
|
7209
|
+
className: "mb-1 flex items-start justify-between gap-3",
|
|
7210
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
7211
|
+
className: "min-w-0",
|
|
7212
|
+
children: [/* @__PURE__ */ jsx("h3", {
|
|
7213
|
+
className: "truncate text-sm font-semibold text-[var(--dashboard-text-primary,#2d2d2d)]",
|
|
7214
|
+
children: item.participant.name
|
|
7215
|
+
}), showContact && (item.participant.phone || item.participant.email) && /* @__PURE__ */ jsx("p", {
|
|
7216
|
+
className: "truncate text-xs text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
7217
|
+
children: item.participant.phone || item.participant.email
|
|
7218
|
+
})]
|
|
7219
|
+
}), timeLabel && /* @__PURE__ */ jsx("span", {
|
|
7220
|
+
className: "flex-shrink-0 text-xs text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
7221
|
+
children: timeLabel
|
|
7222
|
+
})]
|
|
7223
|
+
}),
|
|
7224
|
+
item.lastMessage && /* @__PURE__ */ jsx("p", {
|
|
7225
|
+
className: cn("text-[var(--dashboard-text-secondary,#6b7280)]", compact ? "truncate text-xs" : "truncate text-sm"),
|
|
7226
|
+
children: item.lastMessage
|
|
7227
|
+
}),
|
|
7228
|
+
(showMeta || showSupportBadge || showUnreadBadge) && /* @__PURE__ */ jsxs("div", {
|
|
7229
|
+
className: "mt-2 flex items-center justify-between gap-2",
|
|
7230
|
+
children: [showMeta ? /* @__PURE__ */ jsx("span", {
|
|
7231
|
+
className: "text-xs text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
7232
|
+
children: typeof item.messageCount === "number" ? `${item.messageCount} mensagens` : item.meta
|
|
7233
|
+
}) : /* @__PURE__ */ jsx("span", {}), /* @__PURE__ */ jsxs("div", {
|
|
7234
|
+
className: "flex items-center gap-2",
|
|
7235
|
+
children: [showSupportBadge && /* @__PURE__ */ jsx(ConversationSupportBadge, {
|
|
7236
|
+
status: item.supportStatus,
|
|
7237
|
+
label: item.supportLabel
|
|
7238
|
+
}), showUnreadBadge && !!item.unreadCount && item.unreadCount > 0 && /* @__PURE__ */ jsx("span", {
|
|
7239
|
+
className: "inline-flex min-w-5 items-center justify-center rounded-full bg-[var(--dashboard-primary,#37a501)] px-1.5 py-0.5 text-xs font-semibold text-white",
|
|
7240
|
+
children: item.unreadCount
|
|
7241
|
+
})]
|
|
7242
|
+
})]
|
|
7243
|
+
})
|
|
7244
|
+
]
|
|
7245
|
+
})]
|
|
7246
|
+
});
|
|
7247
|
+
const itemClassName = cn("group w-full text-left transition-colors", onSelect && "hover:bg-[var(--dashboard-primary,#37a501)]/8", list ? selected ? "border-l-4 border-[var(--dashboard-primary,#37a501)] bg-[var(--dashboard-primary,#37a501)]/10" : item.supportStatus === "requested" ? "border-l-4 border-[var(--dashboard-status-warning,#f59e0b)] bg-[var(--dashboard-status-warning,#f59e0b)]/8" : item.supportStatus === "active" ? "border-l-4 border-[var(--dashboard-primary,#37a501)] bg-[var(--dashboard-primary,#37a501)]/5" : "border-l-4 border-transparent" : cn("rounded-lg border bg-[var(--dashboard-surface,#ffffff)] shadow-sm", compact ? "border-[var(--dashboard-text-secondary,#6b7280)]/15" : "border-[var(--dashboard-text-secondary,#6b7280)]/20", selected ? "border-[var(--dashboard-primary,#37a501)] ring-2 ring-[var(--dashboard-primary,#37a501)]/15" : item.supportStatus === "requested" ? "border-[var(--dashboard-status-warning,#f59e0b)]/35" : "hover:border-[var(--dashboard-primary,#37a501)]/35"), item.disabled && "cursor-not-allowed opacity-60", className);
|
|
7248
|
+
if (onSelect) return /* @__PURE__ */ jsx("button", {
|
|
7249
|
+
type: "button",
|
|
7250
|
+
disabled: item.disabled,
|
|
7251
|
+
onClick: () => onSelect(item),
|
|
7252
|
+
className: itemClassName,
|
|
7253
|
+
children: content
|
|
7254
|
+
});
|
|
7255
|
+
return /* @__PURE__ */ jsx("div", {
|
|
7256
|
+
className: itemClassName,
|
|
7257
|
+
children: content
|
|
7258
|
+
});
|
|
7259
|
+
}
|
|
7260
|
+
function ConversationListItem(props) {
|
|
7261
|
+
return /* @__PURE__ */ jsx(ConversationPreviewCard, {
|
|
7262
|
+
...props,
|
|
7263
|
+
variant: "list"
|
|
7264
|
+
});
|
|
7265
|
+
}
|
|
7266
|
+
|
|
7267
|
+
//#endregion
|
|
7268
|
+
//#region src/components/ConversationPanel/ConversationSearch.tsx
|
|
7269
|
+
function ConversationSearch({ value = "", placeholder = "Buscar conversas...", onChange, onClear, className }) {
|
|
7270
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
7271
|
+
className: cn("relative w-full", className),
|
|
7272
|
+
children: [
|
|
7273
|
+
/* @__PURE__ */ jsx(Search, {
|
|
7274
|
+
size: 18,
|
|
7275
|
+
className: "absolute left-3 top-1/2 -translate-y-1/2 text-[var(--dashboard-primary,#37a501)]/60"
|
|
7276
|
+
}),
|
|
7277
|
+
/* @__PURE__ */ jsx("input", {
|
|
7278
|
+
type: "search",
|
|
7279
|
+
value,
|
|
7280
|
+
onChange: (event) => onChange?.(event.target.value),
|
|
7281
|
+
placeholder,
|
|
7282
|
+
className: "h-10 w-full rounded-lg border border-[var(--dashboard-text-secondary,#6b7280)]/25 bg-[var(--dashboard-surface,#ffffff)] pl-10 pr-10 text-sm text-[var(--dashboard-text-primary,#2d2d2d)] outline-none transition-colors focus:border-[var(--dashboard-primary,#37a501)] focus:ring-2 focus:ring-[var(--dashboard-primary,#37a501)]/20"
|
|
7283
|
+
}),
|
|
7284
|
+
value && /* @__PURE__ */ jsx("button", {
|
|
7285
|
+
type: "button",
|
|
7286
|
+
onClick: onClear || (() => onChange?.("")),
|
|
7287
|
+
className: "absolute right-3 top-1/2 -translate-y-1/2 rounded p-1 text-[var(--dashboard-text-secondary,#6b7280)] transition-colors hover:bg-[var(--dashboard-text-secondary,#6b7280)]/10 hover:text-[var(--dashboard-text-primary,#2d2d2d)]",
|
|
7288
|
+
"aria-label": "Limpar busca",
|
|
7289
|
+
children: /* @__PURE__ */ jsx(X, { size: 16 })
|
|
7290
|
+
})
|
|
7291
|
+
]
|
|
7292
|
+
});
|
|
7293
|
+
}
|
|
7294
|
+
|
|
7295
|
+
//#endregion
|
|
7296
|
+
//#region src/components/ConversationPanel/ConversationList.tsx
|
|
7297
|
+
function ConversationList({ items, selectedId, searchValue = "", searchPlaceholder = "Buscar conversas...", onSearchChange, onClearSearch, onSelect, loading = false, emptyTitle = "Nenhuma conversa encontrada", emptyDescription, formatDate, className }) {
|
|
7298
|
+
return /* @__PURE__ */ jsxs("aside", {
|
|
7299
|
+
className: cn("flex min-h-0 flex-col overflow-hidden border-r border-[var(--dashboard-text-secondary,#6b7280)]/20 bg-[var(--dashboard-surface,#ffffff)]", className),
|
|
7300
|
+
children: [(onSearchChange || searchValue) && /* @__PURE__ */ jsx("div", {
|
|
7301
|
+
className: "flex h-20 shrink-0 items-center border-b border-[var(--dashboard-text-secondary,#6b7280)]/20 px-4",
|
|
7302
|
+
children: /* @__PURE__ */ jsx(ConversationSearch, {
|
|
7303
|
+
value: searchValue,
|
|
7304
|
+
placeholder: searchPlaceholder,
|
|
7305
|
+
onChange: onSearchChange,
|
|
7306
|
+
onClear: onClearSearch,
|
|
7307
|
+
className: "w-full"
|
|
7308
|
+
})
|
|
7309
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
7310
|
+
className: "conversation-scrollbar min-h-0 flex-1 overflow-y-auto divide-y divide-[var(--dashboard-text-secondary,#6b7280)]/15",
|
|
7311
|
+
children: loading ? /* @__PURE__ */ jsx("div", {
|
|
7312
|
+
className: "flex h-full min-h-64 items-center justify-center p-6",
|
|
7313
|
+
children: /* @__PURE__ */ jsx(Loading, {
|
|
7314
|
+
size: "md",
|
|
7315
|
+
text: "Carregando conversas..."
|
|
7316
|
+
})
|
|
7317
|
+
}) : items.length === 0 ? /* @__PURE__ */ jsx(EmptyState, {
|
|
7318
|
+
icon: /* @__PURE__ */ jsx(MessageCircle, { className: "h-8 w-8 text-[var(--dashboard-text-secondary,#6b7280)]" }),
|
|
7319
|
+
title: emptyTitle,
|
|
7320
|
+
description: emptyDescription
|
|
7321
|
+
}) : items.map((item) => /* @__PURE__ */ jsx(ConversationPreviewCard, {
|
|
7322
|
+
item,
|
|
7323
|
+
selected: item.id === selectedId || item.selected,
|
|
7324
|
+
onSelect,
|
|
7325
|
+
formatDate,
|
|
7326
|
+
variant: "list"
|
|
7327
|
+
}, item.id))
|
|
7328
|
+
})]
|
|
7329
|
+
});
|
|
7330
|
+
}
|
|
7331
|
+
|
|
7332
|
+
//#endregion
|
|
7333
|
+
//#region src/components/ConversationPanel/ConversationMediaPreview.tsx
|
|
7334
|
+
function ConversationMediaPreview({ message, onMediaOpen, className }) {
|
|
7335
|
+
const { media, kind } = message;
|
|
7336
|
+
if (kind === "loading-media") return /* @__PURE__ */ jsxs("div", {
|
|
7337
|
+
className: cn("flex items-center gap-2 py-2 text-sm opacity-75", className),
|
|
7338
|
+
children: [/* @__PURE__ */ jsx(Loader2, {
|
|
7339
|
+
size: 16,
|
|
7340
|
+
className: "animate-spin"
|
|
7341
|
+
}), /* @__PURE__ */ jsx("span", { children: message.pendingLabel || "Carregando midia..." })]
|
|
7342
|
+
});
|
|
7343
|
+
if (!media?.url) return null;
|
|
7344
|
+
if (kind === "image") return /* @__PURE__ */ jsx("button", {
|
|
7345
|
+
type: "button",
|
|
7346
|
+
onClick: () => onMediaOpen?.(message),
|
|
7347
|
+
className: cn("block overflow-hidden rounded-md text-left", className),
|
|
7348
|
+
children: /* @__PURE__ */ jsx("img", {
|
|
7349
|
+
src: media.url,
|
|
7350
|
+
alt: media.alt || media.fileName || "Imagem da conversa",
|
|
7351
|
+
className: "max-h-64 max-w-full rounded-md object-contain",
|
|
7352
|
+
loading: "lazy"
|
|
7353
|
+
})
|
|
7354
|
+
});
|
|
7355
|
+
if (kind === "audio") return /* @__PURE__ */ jsxs("div", {
|
|
7356
|
+
className: cn("space-y-2", className),
|
|
7357
|
+
children: [/* @__PURE__ */ jsx("audio", {
|
|
7358
|
+
controls: true,
|
|
7359
|
+
className: "max-w-full min-w-60",
|
|
7360
|
+
children: /* @__PURE__ */ jsx("source", {
|
|
7361
|
+
src: media.url,
|
|
7362
|
+
type: media.mimeType || "audio/ogg"
|
|
7363
|
+
})
|
|
7364
|
+
}), message.content && /* @__PURE__ */ jsx("p", {
|
|
7365
|
+
className: "text-xs italic opacity-70",
|
|
7366
|
+
children: message.content
|
|
7367
|
+
})]
|
|
7368
|
+
});
|
|
7369
|
+
if (kind === "video") return /* @__PURE__ */ jsx("video", {
|
|
7370
|
+
controls: true,
|
|
7371
|
+
className: cn("max-h-64 max-w-full rounded-md", className),
|
|
7372
|
+
children: /* @__PURE__ */ jsx("source", {
|
|
7373
|
+
src: media.url,
|
|
7374
|
+
type: media.mimeType || "video/mp4"
|
|
7375
|
+
})
|
|
7376
|
+
});
|
|
7377
|
+
return /* @__PURE__ */ jsxs("a", {
|
|
7378
|
+
href: media.url,
|
|
7379
|
+
target: "_blank",
|
|
7380
|
+
rel: "noopener noreferrer",
|
|
7381
|
+
className: cn("flex items-center gap-2 rounded-md bg-current/10 px-3 py-2 transition-colors hover:bg-current/15", className),
|
|
7382
|
+
children: [kind === "file" ? /* @__PURE__ */ jsx(FileText, { size: 18 }) : /* @__PURE__ */ jsx(Paperclip, { size: 18 }), /* @__PURE__ */ jsx("span", {
|
|
7383
|
+
className: "max-w-52 truncate text-sm",
|
|
7384
|
+
children: media.fileName || "Documento"
|
|
7385
|
+
})]
|
|
7386
|
+
});
|
|
7387
|
+
}
|
|
7388
|
+
|
|
7389
|
+
//#endregion
|
|
7390
|
+
//#region src/components/ConversationPanel/ConversationMessageBubble.tsx
|
|
7391
|
+
function ConversationMessageBubble({ message, onMediaOpen, formatTime = defaultConversationTimeFormatter, className }) {
|
|
7392
|
+
const kind = message.kind || "text";
|
|
7393
|
+
const timeLabel = message.timestampLabel || (message.createdAt ? formatTime(message.createdAt) : void 0);
|
|
7394
|
+
if (kind === "event") return /* @__PURE__ */ jsx(ConversationEventSeparator, {
|
|
7395
|
+
label: message.eventLabel || message.content,
|
|
7396
|
+
description: message.eventDescription,
|
|
7397
|
+
className
|
|
7398
|
+
});
|
|
7399
|
+
if (message.direction === "system") return /* @__PURE__ */ jsx("div", {
|
|
7400
|
+
className: cn("flex justify-center", className),
|
|
7401
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
7402
|
+
className: "max-w-lg rounded-lg border border-[var(--dashboard-text-secondary,#6b7280)]/20 bg-[var(--dashboard-text-secondary,#6b7280)]/10 px-4 py-2 text-[var(--dashboard-text-primary,#2d2d2d)]",
|
|
7403
|
+
children: [
|
|
7404
|
+
/* @__PURE__ */ jsx("p", {
|
|
7405
|
+
className: "mb-1 text-xs font-medium text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
7406
|
+
children: message.authorLabel || "Sistema"
|
|
7407
|
+
}),
|
|
7408
|
+
/* @__PURE__ */ jsx("div", {
|
|
7409
|
+
className: "text-sm",
|
|
7410
|
+
children: message.content
|
|
7411
|
+
}),
|
|
7412
|
+
timeLabel && /* @__PURE__ */ jsx("p", {
|
|
7413
|
+
className: "mt-1 text-xs text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
7414
|
+
children: timeLabel
|
|
7415
|
+
})
|
|
7416
|
+
]
|
|
7417
|
+
})
|
|
7418
|
+
});
|
|
7419
|
+
if (kind === "interactive") return /* @__PURE__ */ jsx("div", {
|
|
7420
|
+
className: cn("flex", message.direction === "outbound" ? "justify-end" : "justify-start", className),
|
|
7421
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
7422
|
+
className: "max-w-lg rounded-lg border border-[var(--dashboard-primary,#37a501)]/25 bg-[var(--dashboard-primary,#37a501)]/10 px-4 py-2",
|
|
7423
|
+
children: [
|
|
7424
|
+
/* @__PURE__ */ jsx("p", {
|
|
7425
|
+
className: "mb-1 text-xs font-medium text-[var(--dashboard-primary,#37a501)]",
|
|
7426
|
+
children: message.interactiveLabel || "Resposta"
|
|
7427
|
+
}),
|
|
7428
|
+
/* @__PURE__ */ jsx("p", {
|
|
7429
|
+
className: "text-sm font-medium text-[var(--dashboard-text-primary,#2d2d2d)]",
|
|
7430
|
+
children: message.interactiveTitle || message.content
|
|
7431
|
+
}),
|
|
7432
|
+
timeLabel && /* @__PURE__ */ jsx("p", {
|
|
7433
|
+
className: "mt-1 text-xs text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
7434
|
+
children: timeLabel
|
|
7435
|
+
})
|
|
7436
|
+
]
|
|
7437
|
+
})
|
|
7438
|
+
});
|
|
7439
|
+
const outbound = message.direction === "outbound";
|
|
7440
|
+
return /* @__PURE__ */ jsx("div", {
|
|
7441
|
+
className: cn("flex", outbound ? "justify-end" : "justify-start", className),
|
|
7442
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
7443
|
+
className: cn("max-w-[78%] rounded-lg px-4 py-3 text-sm shadow-sm", outbound ? "bg-[var(--dashboard-primary,#37a501)] text-white" : "border border-[var(--dashboard-text-secondary,#6b7280)]/18 bg-[var(--dashboard-surface,#ffffff)] text-[var(--dashboard-text-primary,#2d2d2d)]"),
|
|
7444
|
+
children: [
|
|
7445
|
+
message.authorLabel && /* @__PURE__ */ jsx("p", {
|
|
7446
|
+
className: cn("mb-1 text-xs font-medium", outbound ? "text-white/75" : "text-[var(--dashboard-text-secondary,#6b7280)]"),
|
|
7447
|
+
children: message.authorLabel
|
|
7448
|
+
}),
|
|
7449
|
+
kind !== "text" && /* @__PURE__ */ jsx(ConversationMediaPreview, {
|
|
7450
|
+
message,
|
|
7451
|
+
onMediaOpen
|
|
7452
|
+
}),
|
|
7453
|
+
kind === "text" && message.content && /* @__PURE__ */ jsx("div", {
|
|
7454
|
+
className: "whitespace-pre-wrap break-words leading-relaxed",
|
|
7455
|
+
children: message.content
|
|
7456
|
+
}),
|
|
7457
|
+
timeLabel && /* @__PURE__ */ jsx("p", {
|
|
7458
|
+
className: cn("mt-1 text-xs", outbound ? "text-white/75" : "text-[var(--dashboard-text-secondary,#6b7280)]"),
|
|
7459
|
+
children: timeLabel
|
|
7460
|
+
})
|
|
7461
|
+
]
|
|
7462
|
+
})
|
|
5418
7463
|
});
|
|
5419
7464
|
}
|
|
5420
|
-
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
7465
|
+
|
|
7466
|
+
//#endregion
|
|
7467
|
+
//#region src/components/ConversationPanel/ConversationThreadHeader.tsx
|
|
7468
|
+
function ConversationThreadHeader({ participant, stats, subtitle, supportStatus, supportLabel, onBack, onSettingsClick, actions, className }) {
|
|
7469
|
+
return /* @__PURE__ */ jsx("div", {
|
|
7470
|
+
className: cn("flex h-20 shrink-0 items-center border-b border-[var(--dashboard-text-secondary,#6b7280)]/20 bg-[var(--dashboard-surface,#ffffff)] px-4 sm:px-6", className),
|
|
7471
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
7472
|
+
className: "flex w-full items-center gap-3",
|
|
7473
|
+
children: [
|
|
7474
|
+
onBack && /* @__PURE__ */ jsx("button", {
|
|
7475
|
+
type: "button",
|
|
7476
|
+
onClick: onBack,
|
|
7477
|
+
className: "inline-flex h-9 w-9 items-center justify-center rounded-full text-[var(--dashboard-primary,#37a501)] transition-colors hover:bg-[var(--dashboard-primary,#37a501)]/10 md:hidden",
|
|
7478
|
+
"aria-label": "Voltar para lista",
|
|
7479
|
+
children: /* @__PURE__ */ jsx(ArrowLeft, { size: 18 })
|
|
7480
|
+
}),
|
|
7481
|
+
/* @__PURE__ */ jsx(ConversationAvatar, { participant }),
|
|
7482
|
+
/* @__PURE__ */ jsxs("div", {
|
|
7483
|
+
className: "min-w-0",
|
|
7484
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
7485
|
+
className: "flex flex-wrap items-baseline gap-2",
|
|
7486
|
+
children: [/* @__PURE__ */ jsx("h2", {
|
|
7487
|
+
className: "truncate text-sm font-semibold text-[var(--dashboard-text-primary,#2d2d2d)] sm:text-base",
|
|
7488
|
+
children: participant.name
|
|
7489
|
+
}), (participant.phone || participant.email) && /* @__PURE__ */ jsx("span", {
|
|
7490
|
+
className: "truncate text-xs text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
7491
|
+
children: participant.phone || participant.email
|
|
7492
|
+
})]
|
|
7493
|
+
}), (subtitle || stats) && /* @__PURE__ */ jsx("p", {
|
|
7494
|
+
className: "mt-0.5 text-xs text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
7495
|
+
children: subtitle || `${stats?.total ?? 0} mensagens · ${stats?.inbound ?? 0} recebidas · ${stats?.outbound ?? 0} enviadas`
|
|
7496
|
+
})]
|
|
7497
|
+
}),
|
|
7498
|
+
onSettingsClick && /* @__PURE__ */ jsx("button", {
|
|
7499
|
+
type: "button",
|
|
7500
|
+
onClick: onSettingsClick,
|
|
7501
|
+
className: "inline-flex h-8 w-8 items-center justify-center rounded-lg text-[var(--dashboard-text-secondary,#6b7280)] transition-colors hover:bg-[var(--dashboard-text-secondary,#6b7280)]/10 hover:text-[var(--dashboard-text-primary,#2d2d2d)]",
|
|
7502
|
+
"aria-label": "Configurar conversa",
|
|
7503
|
+
children: /* @__PURE__ */ jsx(Settings, { size: 16 })
|
|
7504
|
+
}),
|
|
7505
|
+
/* @__PURE__ */ jsxs("div", {
|
|
7506
|
+
className: "ml-auto flex items-center gap-3",
|
|
7507
|
+
children: [/* @__PURE__ */ jsx(ConversationSupportBadge, {
|
|
7508
|
+
status: supportStatus,
|
|
7509
|
+
label: supportLabel
|
|
7510
|
+
}), actions]
|
|
7511
|
+
})
|
|
7512
|
+
]
|
|
7513
|
+
})
|
|
5439
7514
|
});
|
|
5440
|
-
if (typeof window !== "undefined" && window.history) window.history.replaceState(null, "", `#${id}`);
|
|
5441
7515
|
}
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
|
|
5447
|
-
|
|
5448
|
-
|
|
5449
|
-
|
|
5450
|
-
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
className: cn("py-1.5 text-sm transition-colors scroll-m-4 wrap-anywhere first:pt-0 last:pb-0", "text-[var(--dashboard-text-secondary,#6b7280)]", "hover:text-[var(--dashboard-text-primary,#2d2d2d)]", "data-[active=true]:text-[var(--dashboard-primary,#e74410)]", item.depth <= 2 && "pl-3", item.depth === 3 && "pl-6", item.depth >= 4 && "pl-8"),
|
|
5457
|
-
children: item.title
|
|
7516
|
+
|
|
7517
|
+
//#endregion
|
|
7518
|
+
//#region src/components/ConversationPanel/ConversationUnreadMarker.tsx
|
|
7519
|
+
function ConversationUnreadMarker({ label = "Novas mensagens", className }) {
|
|
7520
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
7521
|
+
className: cn("flex w-full items-center gap-3", className),
|
|
7522
|
+
children: [
|
|
7523
|
+
/* @__PURE__ */ jsx("div", { className: "h-px flex-1 bg-[var(--dashboard-primary,#37a501)]" }),
|
|
7524
|
+
/* @__PURE__ */ jsx("span", {
|
|
7525
|
+
className: "whitespace-nowrap text-xs font-medium text-[var(--dashboard-primary,#37a501)]",
|
|
7526
|
+
children: label
|
|
7527
|
+
}),
|
|
7528
|
+
/* @__PURE__ */ jsx("div", { className: "h-px flex-1 bg-[var(--dashboard-primary,#37a501)]" })
|
|
7529
|
+
]
|
|
5458
7530
|
});
|
|
5459
7531
|
}
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
}
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5477
|
-
|
|
5478
|
-
|
|
5479
|
-
|
|
5480
|
-
|
|
5481
|
-
|
|
5482
|
-
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
|
|
5489
|
-
|
|
5490
|
-
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5495
|
-
|
|
5496
|
-
|
|
5497
|
-
|
|
5498
|
-
|
|
7532
|
+
|
|
7533
|
+
//#endregion
|
|
7534
|
+
//#region src/components/ConversationPanel/ConversationThread.tsx
|
|
7535
|
+
function ConversationThread({ participant, messages = [], stats, loading = false, loadingLabel = "Carregando mensagens...", emptyTitle = "Selecione uma conversa", emptyDescription = "Escolha uma conversa na lista para visualizar as mensagens.", unreadMessageId, unreadLabel, headerActions, composer, supportStatus, supportLabel, onBack, onSettingsClick, onMediaOpen, formatTime, messagesContainerRef, className }) {
|
|
7536
|
+
if (!participant) return /* @__PURE__ */ jsx("section", {
|
|
7537
|
+
className: cn("flex min-h-0 flex-1 flex-col bg-[var(--dashboard-background,#f2f2f2)]", className),
|
|
7538
|
+
children: /* @__PURE__ */ jsx(EmptyState, {
|
|
7539
|
+
icon: /* @__PURE__ */ jsx(MessageCircle, { className: "h-8 w-8 text-[var(--dashboard-primary,#37a501)]/60" }),
|
|
7540
|
+
title: emptyTitle,
|
|
7541
|
+
description: emptyDescription,
|
|
7542
|
+
className: "h-full min-h-80 flex-1"
|
|
7543
|
+
})
|
|
7544
|
+
});
|
|
7545
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
7546
|
+
className: cn("flex min-h-0 flex-1 flex-col bg-[var(--dashboard-background,#f2f2f2)]", className),
|
|
7547
|
+
children: [
|
|
7548
|
+
/* @__PURE__ */ jsx(ConversationThreadHeader, {
|
|
7549
|
+
participant,
|
|
7550
|
+
stats,
|
|
7551
|
+
actions: headerActions,
|
|
7552
|
+
supportStatus,
|
|
7553
|
+
supportLabel,
|
|
7554
|
+
onBack,
|
|
7555
|
+
onSettingsClick
|
|
7556
|
+
}),
|
|
7557
|
+
/* @__PURE__ */ jsx("div", {
|
|
7558
|
+
ref: messagesContainerRef,
|
|
7559
|
+
className: "conversation-scrollbar min-h-0 flex-1 space-y-4 overflow-y-auto p-4 sm:p-6",
|
|
7560
|
+
children: loading ? /* @__PURE__ */ jsx("div", {
|
|
7561
|
+
className: "flex h-full min-h-64 items-center justify-center",
|
|
7562
|
+
children: /* @__PURE__ */ jsx(Loading, {
|
|
7563
|
+
size: "md",
|
|
7564
|
+
text: loadingLabel
|
|
7565
|
+
})
|
|
7566
|
+
}) : messages.length === 0 ? /* @__PURE__ */ jsx(EmptyState, {
|
|
7567
|
+
icon: /* @__PURE__ */ jsx(MessageCircle, { className: "h-8 w-8 text-[var(--dashboard-text-secondary,#6b7280)]" }),
|
|
7568
|
+
title: "Nenhuma mensagem nesta conversa"
|
|
7569
|
+
}) : messages.map((message) => /* @__PURE__ */ jsxs(React.Fragment, { children: [unreadMessageId === message.id && /* @__PURE__ */ jsx(ConversationUnreadMarker, { label: unreadLabel }), /* @__PURE__ */ jsx(ConversationMessageBubble, {
|
|
7570
|
+
message,
|
|
7571
|
+
onMediaOpen,
|
|
7572
|
+
formatTime
|
|
7573
|
+
})] }, message.id))
|
|
7574
|
+
}),
|
|
7575
|
+
composer
|
|
7576
|
+
]
|
|
5499
7577
|
});
|
|
5500
7578
|
}
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
|
|
5504
|
-
|
|
5505
|
-
const container = containerRef.current;
|
|
5506
|
-
if (!container) return;
|
|
5507
|
-
if (items.length === 0) {
|
|
5508
|
-
setComputed(null);
|
|
5509
|
-
return;
|
|
5510
|
-
}
|
|
5511
|
-
const positions = [];
|
|
5512
|
-
for (const item of items) {
|
|
5513
|
-
const el = container.querySelector(`a[href="${item.url}"]`);
|
|
5514
|
-
if (!el) {
|
|
5515
|
-
positions.push([0, 0]);
|
|
5516
|
-
continue;
|
|
5517
|
-
}
|
|
5518
|
-
const styles = window.getComputedStyle(el);
|
|
5519
|
-
const top = el.offsetTop + parseFloat(styles.paddingTop || "0");
|
|
5520
|
-
const bottom = el.offsetTop + el.clientHeight - parseFloat(styles.paddingBottom || "0");
|
|
5521
|
-
positions.push([top, bottom]);
|
|
5522
|
-
}
|
|
5523
|
-
setComputed({ positions });
|
|
5524
|
-
}, [items]);
|
|
5525
|
-
useLayoutEffect(() => {
|
|
5526
|
-
recompute();
|
|
5527
|
-
}, [recompute]);
|
|
5528
|
-
useEffect(() => {
|
|
5529
|
-
const container = containerRef.current;
|
|
5530
|
-
if (!container || typeof ResizeObserver === "undefined") return;
|
|
5531
|
-
const ro = new ResizeObserver(() => recompute());
|
|
5532
|
-
ro.observe(container);
|
|
5533
|
-
return () => ro.disconnect();
|
|
5534
|
-
}, [recompute]);
|
|
7579
|
+
|
|
7580
|
+
//#endregion
|
|
7581
|
+
//#region src/components/ConversationPanel/ConversationLayout.tsx
|
|
7582
|
+
function ConversationLayout({ title = "Conversas", subtitle, hideHeader = false, connected, conversations, selectedId, selectedParticipant, messages, stats, searchValue, onSearchChange, onClearSearch, onSelectConversation, listLoading, threadLoading, threadActions, composer, supportStatus, supportLabel, unreadMessageId, unreadLabel, onBack, onSettingsClick, onMediaOpen, formatListDate, formatMessageTime, className }) {
|
|
5535
7583
|
return /* @__PURE__ */ jsxs("div", {
|
|
5536
|
-
className: "
|
|
5537
|
-
children: [
|
|
5538
|
-
|
|
5539
|
-
|
|
5540
|
-
|
|
5541
|
-
|
|
7584
|
+
className: cn("conversation-panel flex h-full min-h-0 flex-col overflow-hidden rounded-lg border border-[var(--dashboard-text-secondary,#6b7280)]/20 bg-[var(--dashboard-surface,#ffffff)]", className),
|
|
7585
|
+
children: [
|
|
7586
|
+
/* @__PURE__ */ jsx("style", { children: `
|
|
7587
|
+
.conversation-panel .conversation-scrollbar {
|
|
7588
|
+
scrollbar-color: var(--dashboard-primary,#37a501) color-mix(in srgb, var(--dashboard-primary,#37a501) 12%, transparent);
|
|
7589
|
+
scrollbar-width: thin;
|
|
7590
|
+
}
|
|
7591
|
+
|
|
7592
|
+
.conversation-panel .conversation-scrollbar::-webkit-scrollbar {
|
|
7593
|
+
width: 0.5rem;
|
|
7594
|
+
height: 0.5rem;
|
|
7595
|
+
}
|
|
7596
|
+
|
|
7597
|
+
.conversation-panel .conversation-scrollbar::-webkit-scrollbar-track {
|
|
7598
|
+
background: color-mix(in srgb, var(--dashboard-primary,#37a501) 10%, transparent);
|
|
7599
|
+
border-radius: 999px;
|
|
7600
|
+
}
|
|
7601
|
+
|
|
7602
|
+
.conversation-panel .conversation-scrollbar::-webkit-scrollbar-thumb {
|
|
7603
|
+
background: var(--dashboard-primary,#37a501);
|
|
7604
|
+
border-radius: 999px;
|
|
7605
|
+
}
|
|
7606
|
+
|
|
7607
|
+
.conversation-panel .conversation-scrollbar::-webkit-scrollbar-thumb:hover {
|
|
7608
|
+
background: color-mix(in srgb, var(--dashboard-primary,#37a501) 84%, var(--dashboard-text-primary,#2d2d2d));
|
|
7609
|
+
}
|
|
7610
|
+
` }),
|
|
7611
|
+
!hideHeader && (title || subtitle || typeof connected === "boolean") && /* @__PURE__ */ jsxs("div", {
|
|
7612
|
+
className: "border-b border-[var(--dashboard-text-secondary,#6b7280)]/20 bg-[var(--dashboard-surface,#ffffff)] px-4 py-4 sm:px-6",
|
|
7613
|
+
children: [(title || typeof connected === "boolean") && /* @__PURE__ */ jsxs("div", {
|
|
7614
|
+
className: "flex items-center gap-2",
|
|
7615
|
+
children: [title && /* @__PURE__ */ jsx("h1", {
|
|
7616
|
+
className: "text-xl font-bold text-[var(--dashboard-text-primary,#2d2d2d)]",
|
|
7617
|
+
children: title
|
|
7618
|
+
}), typeof connected === "boolean" && /* @__PURE__ */ jsx("span", {
|
|
7619
|
+
className: cn("h-2 w-2 rounded-full", connected ? "bg-[var(--dashboard-primary,#37a501)]" : "bg-[var(--dashboard-text-secondary,#6b7280)]/40"),
|
|
7620
|
+
title: connected ? "Conectado em tempo real" : "Desconectado"
|
|
7621
|
+
})]
|
|
7622
|
+
}), subtitle && /* @__PURE__ */ jsx("p", {
|
|
7623
|
+
className: "mt-1 text-sm text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
7624
|
+
children: subtitle
|
|
7625
|
+
})]
|
|
7626
|
+
}),
|
|
7627
|
+
/* @__PURE__ */ jsxs("div", {
|
|
7628
|
+
className: "flex min-h-0 flex-1 overflow-hidden",
|
|
7629
|
+
children: [/* @__PURE__ */ jsx(ConversationList, {
|
|
7630
|
+
items: conversations,
|
|
7631
|
+
selectedId,
|
|
7632
|
+
searchValue,
|
|
7633
|
+
onSearchChange,
|
|
7634
|
+
onClearSearch,
|
|
7635
|
+
onSelect: onSelectConversation,
|
|
7636
|
+
loading: listLoading,
|
|
7637
|
+
formatDate: formatListDate,
|
|
7638
|
+
className: cn("w-full md:flex md:w-80 lg:w-96", selectedParticipant ? "hidden md:flex" : "flex")
|
|
7639
|
+
}), /* @__PURE__ */ jsx(ConversationThread, {
|
|
7640
|
+
participant: selectedParticipant,
|
|
7641
|
+
messages,
|
|
7642
|
+
stats,
|
|
7643
|
+
loading: threadLoading,
|
|
7644
|
+
headerActions: threadActions,
|
|
7645
|
+
composer,
|
|
7646
|
+
supportStatus,
|
|
7647
|
+
supportLabel,
|
|
7648
|
+
unreadMessageId,
|
|
7649
|
+
unreadLabel,
|
|
7650
|
+
onBack,
|
|
7651
|
+
onSettingsClick,
|
|
7652
|
+
onMediaOpen,
|
|
7653
|
+
formatTime: formatMessageTime,
|
|
7654
|
+
className: cn(selectedParticipant ? "flex" : "hidden md:flex")
|
|
7655
|
+
})]
|
|
7656
|
+
})
|
|
7657
|
+
]
|
|
5542
7658
|
});
|
|
5543
7659
|
}
|
|
5544
|
-
function
|
|
5545
|
-
|
|
5546
|
-
const cbRef = useRef(onActiveChange);
|
|
5547
|
-
cbRef.current = onActiveChange;
|
|
5548
|
-
useEffect(() => {
|
|
5549
|
-
cbRef.current(ids);
|
|
5550
|
-
}, [ids]);
|
|
5551
|
-
return null;
|
|
5552
|
-
}
|
|
5553
|
-
function ActiveScrollSync({ linksRef }) {
|
|
5554
|
-
const activeId = useActiveAnchor();
|
|
5555
|
-
useEffect(() => {
|
|
5556
|
-
if (!activeId) return;
|
|
5557
|
-
const link = linksRef.current.get(activeId);
|
|
5558
|
-
if (!link) return;
|
|
5559
|
-
const container = findScrollableParent(link);
|
|
5560
|
-
if (container === document.documentElement) return;
|
|
5561
|
-
scrollAnchorIntoView(link, container);
|
|
5562
|
-
}, [activeId, linksRef]);
|
|
5563
|
-
return null;
|
|
7660
|
+
function ConversationPanel(props) {
|
|
7661
|
+
return /* @__PURE__ */ jsx(ConversationLayout, { ...props });
|
|
5564
7662
|
}
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
-
|
|
5568
|
-
|
|
5569
|
-
|
|
5570
|
-
|
|
5571
|
-
|
|
5572
|
-
|
|
5573
|
-
|
|
5574
|
-
|
|
5575
|
-
|
|
5576
|
-
|
|
5577
|
-
|
|
5578
|
-
|
|
5579
|
-
|
|
5580
|
-
|
|
5581
|
-
|
|
5582
|
-
|
|
5583
|
-
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
className: "inline-flex items-center gap-1.5 text-sm font-medium mb-3 text-[var(--dashboard-text-primary,#2d2d2d)]",
|
|
5587
|
-
children: [/* @__PURE__ */ jsx(Text, {
|
|
5588
|
-
className: "h-4 w-4",
|
|
5589
|
-
"aria-hidden": true
|
|
5590
|
-
}), title]
|
|
5591
|
-
}),
|
|
5592
|
-
/* @__PURE__ */ jsx(TocList, {
|
|
5593
|
-
items,
|
|
5594
|
-
showThumb
|
|
5595
|
-
}),
|
|
5596
|
-
onActiveChange && /* @__PURE__ */ jsx(ActiveChangeReporter, { onActiveChange }),
|
|
5597
|
-
/* @__PURE__ */ jsx(ActiveScrollSync, { linksRef })
|
|
5598
|
-
]
|
|
7663
|
+
|
|
7664
|
+
//#endregion
|
|
7665
|
+
//#region src/components/ConversationPanel/ConversationSupportActions.tsx
|
|
7666
|
+
function ConversationSupportActions({ status, stats, reason, startLabel = "Assumir conversa", endLabel = "Encerrar atendimento", endSilentLabel = "Encerrar sem notificar", onStart, onEnd, onEndSilent, startDisabled, endDisabled, endSilentDisabled, activeActions, inactiveActions, className }) {
|
|
7667
|
+
if (status === "active") return /* @__PURE__ */ jsxs("div", {
|
|
7668
|
+
className: cn("flex items-center gap-2", className),
|
|
7669
|
+
children: [
|
|
7670
|
+
activeActions,
|
|
7671
|
+
onEndSilent && /* @__PURE__ */ jsx("button", {
|
|
7672
|
+
type: "button",
|
|
7673
|
+
onClick: onEndSilent,
|
|
7674
|
+
disabled: endSilentDisabled,
|
|
7675
|
+
className: "rounded-lg bg-[var(--dashboard-text-secondary,#6b7280)] px-4 py-2 text-sm font-medium text-white transition-colors hover:brightness-95 disabled:cursor-not-allowed disabled:opacity-50",
|
|
7676
|
+
children: endSilentLabel
|
|
7677
|
+
}),
|
|
7678
|
+
onEnd && /* @__PURE__ */ jsx("button", {
|
|
7679
|
+
type: "button",
|
|
7680
|
+
onClick: onEnd,
|
|
7681
|
+
disabled: endDisabled,
|
|
7682
|
+
className: "rounded-lg bg-[var(--dashboard-status-danger,#ef4444)] px-4 py-2 text-sm font-medium text-white transition-colors hover:brightness-95 disabled:cursor-not-allowed disabled:opacity-50",
|
|
7683
|
+
children: endLabel
|
|
5599
7684
|
})
|
|
5600
|
-
|
|
7685
|
+
]
|
|
7686
|
+
});
|
|
7687
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
7688
|
+
className: cn("flex items-center gap-3", className),
|
|
7689
|
+
children: [
|
|
7690
|
+
inactiveActions,
|
|
7691
|
+
(stats || reason) && /* @__PURE__ */ jsxs("div", {
|
|
7692
|
+
className: "text-right",
|
|
7693
|
+
children: [stats && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("p", {
|
|
7694
|
+
className: "text-xs font-medium text-[var(--dashboard-primary,#37a501)]",
|
|
7695
|
+
children: [stats.total ?? 0, " mensagens"]
|
|
7696
|
+
}), /* @__PURE__ */ jsxs("p", {
|
|
7697
|
+
className: "text-xs text-[var(--dashboard-text-secondary,#6b7280)]",
|
|
7698
|
+
children: [
|
|
7699
|
+
stats.inbound ?? 0,
|
|
7700
|
+
" recebidas · ",
|
|
7701
|
+
stats.outbound ?? 0,
|
|
7702
|
+
" enviadas"
|
|
7703
|
+
]
|
|
7704
|
+
})] }), reason && /* @__PURE__ */ jsx("p", {
|
|
7705
|
+
className: "mt-1 text-xs text-[var(--dashboard-status-warning,#f59e0b)]",
|
|
7706
|
+
children: reason
|
|
7707
|
+
})]
|
|
7708
|
+
}),
|
|
7709
|
+
onStart && /* @__PURE__ */ jsx("button", {
|
|
7710
|
+
type: "button",
|
|
7711
|
+
onClick: onStart,
|
|
7712
|
+
disabled: startDisabled,
|
|
7713
|
+
className: "rounded-lg bg-[var(--dashboard-primary,#37a501)] px-4 py-2 text-sm font-medium text-white transition-colors hover:brightness-95 disabled:cursor-not-allowed disabled:opacity-50",
|
|
7714
|
+
children: startLabel
|
|
7715
|
+
})
|
|
7716
|
+
]
|
|
5601
7717
|
});
|
|
5602
7718
|
}
|
|
5603
7719
|
|
|
7720
|
+
//#endregion
|
|
7721
|
+
//#region src/components/ConversationPanel/index.ts
|
|
7722
|
+
const conversationMessageIcons = {
|
|
7723
|
+
image: Image,
|
|
7724
|
+
audio: Mic,
|
|
7725
|
+
video: PlaySquare,
|
|
7726
|
+
file: FileText
|
|
7727
|
+
};
|
|
7728
|
+
|
|
5604
7729
|
//#endregion
|
|
5605
7730
|
//#region src/config/defaults.ts
|
|
5606
7731
|
const defaultConfig = {
|
|
@@ -5895,5 +8020,5 @@ const modalSizes = {
|
|
|
5895
8020
|
};
|
|
5896
8021
|
|
|
5897
8022
|
//#endregion
|
|
5898
|
-
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, TOCProvider, Table, TableBody, TableEmpty, TableHeader, TableOfContents, TableSkeleton, Tabs, ThemeProvider, ThemeSwitcher, Title, Toast, ToggleSwitch, Tooltip, TreeView, VerticalBarChart, badgeSizes, componentSizes, createColumnHelper, createConfig, defaultConfig, modalSizes, useActiveAnchor, useActiveAnchors, useConfig, useLoading, useNotifications, useTOCItems, useTheme };
|
|
8023
|
+
export { Alert, AuthLayout, BadgeStatus, Breadcrumb, Button, Callout, Card, Checkbox, CodeBlock, CodeInput, Combobox, ComparisonLineChart, ConversationAvatar, ConversationComposer, ConversationEventSeparator, ConversationLayout, ConversationList, ConversationListItem, ConversationMediaPreview, ConversationMessageBubble, ConversationPanel, ConversationPreviewCard, ConversationSearch, ConversationSupportActions, ConversationSupportBadge, ConversationThread, ConversationThreadHeader, ConversationUnreadMarker, DashboardProvider, DataGrid, DatePicker, DateRangePicker, DoughnutChart, Dropdown, EmptyState, FileUpload, FilterBar, FormField, GithubIcon, Header, HorizontalBarChart, IPhoneMockup, InfoTooltip, Input, InstagramIcon, KPICard, LinkedinIcon, Loading, LoadingProvider, MetricPanel, Modal, NotificationsProvider, PageLayout, Pagination, ProgressBarList, Sidebar, Skeleton, SocialIcon, StatusBadge, Stepper, TOCProvider, Table, TableBody, TableEmpty, TableHeader, TableOfContents, TableSkeleton, Tabs, ThemeProvider, ThemeSwitcher, Title, Toast, ToggleSwitch, Tooltip, TreeView, VerticalBarChart, WhatsAppMockup, WhatsappIcon, YoutubeIcon, badgeSizes, componentSizes, conversationMessageIcons, createColumnHelper, createConfig, defaultConfig, modalSizes, socialIconNames, socialIconPaths, useActiveAnchor, useActiveAnchors, useConfig, useLoading, useNotifications, useTOCItems, useTheme };
|
|
5899
8024
|
//# sourceMappingURL=index.mjs.map
|