@motor-hero/ui-kit 0.34.1 → 0.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/date-picker.d.ts.map +1 -1
- package/dist/components/filter-toolbar.d.ts +67 -0
- package/dist/components/filter-toolbar.d.ts.map +1 -0
- package/dist/index.cjs +1574 -1402
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +46 -44
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1628 -1459
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/date-picker.tsx +27 -9
- package/src/components/filter-toolbar.tsx +239 -0
- package/src/index.ts +83 -61
package/dist/index.cjs
CHANGED
|
@@ -40,6 +40,9 @@ __export(index_exports, {
|
|
|
40
40
|
DatePicker: () => DatePicker,
|
|
41
41
|
DateTimePicker: () => DateTimePicker,
|
|
42
42
|
EmptyState: () => EmptyState,
|
|
43
|
+
FilterOptionList: () => FilterOptionList,
|
|
44
|
+
FilterPopover: () => FilterPopover,
|
|
45
|
+
FilterToolbar: () => FilterToolbar,
|
|
43
46
|
FormDialog: () => FormDialog,
|
|
44
47
|
FormDialogLayout: () => FormDialogLayout,
|
|
45
48
|
FormField: () => FormField,
|
|
@@ -75,422 +78,375 @@ __export(index_exports, {
|
|
|
75
78
|
});
|
|
76
79
|
module.exports = __toCommonJS(index_exports);
|
|
77
80
|
|
|
78
|
-
// src/components/
|
|
79
|
-
var
|
|
81
|
+
// src/components/app-shell.tsx
|
|
82
|
+
var import_lucide_react2 = require("lucide-react");
|
|
83
|
+
var import_react3 = require("react");
|
|
80
84
|
|
|
81
|
-
// src/lib/
|
|
82
|
-
var
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
secondaryForeground: "--color-secondary-foreground",
|
|
87
|
-
accent: "--color-accent",
|
|
88
|
-
accentForeground: "--color-accent-foreground",
|
|
89
|
-
ring: "--color-ring"
|
|
90
|
-
};
|
|
91
|
-
function definedTokens(tokens) {
|
|
92
|
-
if (!tokens) return {};
|
|
93
|
-
return Object.fromEntries(
|
|
94
|
-
Object.entries(tokens).filter(([, value]) => value != null)
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
function applyCompanyTheme(root, companyTheme, mode) {
|
|
98
|
-
const tokens = companyTheme ? mode === "dark" ? { ...companyTheme.light, ...definedTokens(companyTheme.dark) } : companyTheme.light : {};
|
|
99
|
-
for (const key of Object.keys(VAR_MAP)) {
|
|
100
|
-
const value = tokens[key];
|
|
101
|
-
if (value) root.style.setProperty(VAR_MAP[key], value);
|
|
102
|
-
else root.style.removeProperty(VAR_MAP[key]);
|
|
103
|
-
}
|
|
85
|
+
// src/lib/utils.ts
|
|
86
|
+
var import_clsx = require("clsx");
|
|
87
|
+
var import_tailwind_merge = require("tailwind-merge");
|
|
88
|
+
function cn(...inputs) {
|
|
89
|
+
return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
|
|
104
90
|
}
|
|
105
91
|
|
|
106
|
-
// src/components/
|
|
92
|
+
// src/components/sidebar-nav.tsx
|
|
93
|
+
var import_react = require("react");
|
|
94
|
+
|
|
95
|
+
// src/components/types.tsx
|
|
107
96
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
108
|
-
var
|
|
109
|
-
theme: "system",
|
|
110
|
-
setTheme: () => null
|
|
111
|
-
};
|
|
112
|
-
var ThemeProviderContext = (0, import_react.createContext)(initialState);
|
|
113
|
-
function ThemeProvider({
|
|
114
|
-
children,
|
|
115
|
-
defaultTheme = "system",
|
|
116
|
-
storageKey = "ui-theme",
|
|
117
|
-
companyTheme,
|
|
118
|
-
...props
|
|
119
|
-
}) {
|
|
120
|
-
const [theme, setTheme] = (0, import_react.useState)(
|
|
121
|
-
() => localStorage.getItem(storageKey) || defaultTheme
|
|
122
|
-
);
|
|
123
|
-
(0, import_react.useEffect)(() => {
|
|
124
|
-
const root = window.document.documentElement;
|
|
125
|
-
const applyResolved = (resolved) => {
|
|
126
|
-
root.classList.remove("light", "dark");
|
|
127
|
-
root.classList.add(resolved);
|
|
128
|
-
applyCompanyTheme(root, companyTheme, resolved);
|
|
129
|
-
};
|
|
130
|
-
if (theme === "system") {
|
|
131
|
-
const mql = window.matchMedia("(prefers-color-scheme: dark)");
|
|
132
|
-
applyResolved(mql.matches ? "dark" : "light");
|
|
133
|
-
const onChange = (e) => applyResolved(e.matches ? "dark" : "light");
|
|
134
|
-
mql.addEventListener("change", onChange);
|
|
135
|
-
return () => mql.removeEventListener("change", onChange);
|
|
136
|
-
}
|
|
137
|
-
applyResolved(theme);
|
|
138
|
-
}, [theme, companyTheme]);
|
|
139
|
-
const value = {
|
|
140
|
-
theme,
|
|
141
|
-
setTheme: (theme2) => {
|
|
142
|
-
localStorage.setItem(storageKey, theme2);
|
|
143
|
-
setTheme(theme2);
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ThemeProviderContext.Provider, { ...props, value, children });
|
|
147
|
-
}
|
|
148
|
-
function useTheme() {
|
|
149
|
-
const context = (0, import_react.useContext)(ThemeProviderContext);
|
|
150
|
-
if (context === void 0) {
|
|
151
|
-
throw new Error("useTheme must be used within a ThemeProvider");
|
|
152
|
-
}
|
|
153
|
-
return context;
|
|
154
|
-
}
|
|
97
|
+
var defaultRenderLink = ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { ...props, children });
|
|
155
98
|
|
|
156
|
-
// src/
|
|
157
|
-
var
|
|
158
|
-
function
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const first = labels[0];
|
|
162
|
-
if (!first || first === "www" || first === "localhost") return void 0;
|
|
163
|
-
return first;
|
|
164
|
-
}
|
|
165
|
-
function resolveOverride(storageKey) {
|
|
166
|
-
if (typeof window === "undefined") return void 0;
|
|
167
|
-
const params = new URLSearchParams(window.location.search);
|
|
168
|
-
if (params.has("company")) {
|
|
169
|
-
const value = params.get("company");
|
|
170
|
-
if (value) {
|
|
171
|
-
window.localStorage.setItem(storageKey, value);
|
|
172
|
-
return value;
|
|
173
|
-
}
|
|
174
|
-
window.localStorage.removeItem(storageKey);
|
|
175
|
-
return void 0;
|
|
176
|
-
}
|
|
177
|
-
return window.localStorage.getItem(storageKey) ?? void 0;
|
|
99
|
+
// src/components/sidebar-nav.tsx
|
|
100
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
101
|
+
function defaultIsActive(item, activePath) {
|
|
102
|
+
if (item.href === "/") return activePath === "/";
|
|
103
|
+
return activePath === item.href || activePath.startsWith(item.href + "/");
|
|
178
104
|
}
|
|
179
|
-
function
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
return {
|
|
105
|
+
function SidebarNav({
|
|
106
|
+
items,
|
|
107
|
+
activePath,
|
|
108
|
+
isActive = defaultIsActive,
|
|
109
|
+
isAdmin = false,
|
|
110
|
+
isCollapsed = false,
|
|
111
|
+
renderLink = defaultRenderLink,
|
|
112
|
+
onNavigate
|
|
113
|
+
}) {
|
|
114
|
+
const visible = items.filter((item) => !item.adminOnly || isAdmin);
|
|
115
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("nav", { className: "flex flex-col gap-1", children: visible.map((item) => {
|
|
116
|
+
const active = isActive(item, activePath);
|
|
117
|
+
const link = renderLink({
|
|
118
|
+
href: item.href,
|
|
119
|
+
onClick: onNavigate,
|
|
120
|
+
title: isCollapsed ? item.label : void 0,
|
|
121
|
+
"aria-current": active ? "page" : void 0,
|
|
122
|
+
className: cn(
|
|
123
|
+
"flex cursor-pointer items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition-colors",
|
|
124
|
+
active ? "bg-accent text-accent-foreground font-semibold" : "text-muted-foreground hover:bg-accent hover:text-accent-foreground",
|
|
125
|
+
isCollapsed && "justify-center px-2"
|
|
126
|
+
),
|
|
127
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
128
|
+
item.icon && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "shrink-0", children: item.icon }),
|
|
129
|
+
!isCollapsed && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "truncate", children: item.label })
|
|
130
|
+
] })
|
|
131
|
+
});
|
|
132
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react.Fragment, { children: link }, item.href);
|
|
133
|
+
}) });
|
|
190
134
|
}
|
|
191
135
|
|
|
192
|
-
// src/components/
|
|
136
|
+
// src/components/user-menu.tsx
|
|
193
137
|
var DropdownMenu = __toESM(require("@radix-ui/react-dropdown-menu"), 1);
|
|
194
138
|
var import_lucide_react = require("lucide-react");
|
|
195
|
-
var
|
|
196
|
-
|
|
197
|
-
const { setTheme } = useTheme();
|
|
198
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(DropdownMenu.Root, { children: [
|
|
199
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
200
|
-
"button",
|
|
201
|
-
{
|
|
202
|
-
type: "button",
|
|
203
|
-
className: "relative inline-flex h-9 w-9 items-center justify-center rounded-md border border-input bg-background text-sm font-medium shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
204
|
-
"aria-label": "Alternar tema",
|
|
205
|
-
children: [
|
|
206
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Sun, { className: "h-4 w-4 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" }),
|
|
207
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Moon, { className: "absolute inset-0 m-auto h-4 w-4 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" })
|
|
208
|
-
]
|
|
209
|
-
}
|
|
210
|
-
) }),
|
|
211
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DropdownMenu.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
212
|
-
DropdownMenu.Content,
|
|
213
|
-
{
|
|
214
|
-
align: "end",
|
|
215
|
-
className: "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95",
|
|
216
|
-
children: [
|
|
217
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
218
|
-
DropdownMenu.Item,
|
|
219
|
-
{
|
|
220
|
-
className: "flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent focus:bg-accent",
|
|
221
|
-
onClick: () => setTheme("light"),
|
|
222
|
-
children: [
|
|
223
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Sun, { className: "h-4 w-4" }),
|
|
224
|
-
" Claro"
|
|
225
|
-
]
|
|
226
|
-
}
|
|
227
|
-
),
|
|
228
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
229
|
-
DropdownMenu.Item,
|
|
230
|
-
{
|
|
231
|
-
className: "flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent focus:bg-accent",
|
|
232
|
-
onClick: () => setTheme("dark"),
|
|
233
|
-
children: [
|
|
234
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Moon, { className: "h-4 w-4" }),
|
|
235
|
-
" Escuro"
|
|
236
|
-
]
|
|
237
|
-
}
|
|
238
|
-
),
|
|
239
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
240
|
-
DropdownMenu.Item,
|
|
241
|
-
{
|
|
242
|
-
className: "flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent focus:bg-accent",
|
|
243
|
-
onClick: () => setTheme("system"),
|
|
244
|
-
children: [
|
|
245
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.Monitor, { className: "h-4 w-4" }),
|
|
246
|
-
" Sistema"
|
|
247
|
-
]
|
|
248
|
-
}
|
|
249
|
-
)
|
|
250
|
-
]
|
|
251
|
-
}
|
|
252
|
-
) })
|
|
253
|
-
] });
|
|
254
|
-
}
|
|
139
|
+
var import_react2 = require("react");
|
|
140
|
+
var import_vaul = require("vaul");
|
|
255
141
|
|
|
256
|
-
// src/
|
|
257
|
-
var
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
142
|
+
// src/hooks/use-is-desktop.ts
|
|
143
|
+
var React = __toESM(require("react"), 1);
|
|
144
|
+
var DESKTOP_QUERY = "(min-width: 640px)";
|
|
145
|
+
function useIsDesktop() {
|
|
146
|
+
const [isDesktop, setIsDesktop] = React.useState(
|
|
147
|
+
() => typeof window !== "undefined" ? window.matchMedia(DESKTOP_QUERY).matches : true
|
|
148
|
+
);
|
|
149
|
+
React.useEffect(() => {
|
|
150
|
+
const mql = window.matchMedia(DESKTOP_QUERY);
|
|
151
|
+
const onChange = () => setIsDesktop(mql.matches);
|
|
152
|
+
onChange();
|
|
153
|
+
mql.addEventListener("change", onChange);
|
|
154
|
+
return () => mql.removeEventListener("change", onChange);
|
|
155
|
+
}, []);
|
|
156
|
+
return isDesktop;
|
|
265
157
|
}
|
|
266
158
|
|
|
267
|
-
// src/components/
|
|
268
|
-
var
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
return (0,
|
|
159
|
+
// src/components/user-menu.tsx
|
|
160
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
161
|
+
function initials(user) {
|
|
162
|
+
const source = user?.name?.trim() || user?.email?.trim();
|
|
163
|
+
if (!source) return "";
|
|
164
|
+
const parts = source.split(/\s+/);
|
|
165
|
+
if (parts.length >= 2) return (parts[0][0] + parts[1][0]).toUpperCase();
|
|
166
|
+
return source.slice(0, 2).toUpperCase();
|
|
275
167
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
confirmLabel = "Confirmar",
|
|
286
|
-
cancelLabel = "Cancelar",
|
|
287
|
-
loading = false,
|
|
288
|
-
variant = "default",
|
|
289
|
-
blurBackdrop = true,
|
|
290
|
-
backdropClassName
|
|
168
|
+
var itemClass = "flex w-full cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent focus:bg-accent";
|
|
169
|
+
var sheetItemClass = "flex w-full cursor-pointer select-none items-center gap-3 rounded-md px-3 py-3 text-base outline-none transition-colors hover:bg-accent active:bg-accent";
|
|
170
|
+
function UserMenu({
|
|
171
|
+
user,
|
|
172
|
+
items = [],
|
|
173
|
+
onLogout,
|
|
174
|
+
logoutLabel = "Sair",
|
|
175
|
+
renderLink = defaultRenderLink,
|
|
176
|
+
align = "end"
|
|
291
177
|
}) {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
178
|
+
const isDesktop = useIsDesktop();
|
|
179
|
+
const [open, setOpen] = (0, import_react2.useState)(false);
|
|
180
|
+
const label = initials(user);
|
|
181
|
+
const trigger = /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
182
|
+
"button",
|
|
183
|
+
{
|
|
184
|
+
type: "button",
|
|
185
|
+
className: "inline-flex h-9 w-9 items-center justify-center overflow-hidden rounded-full border border-input bg-background text-xs font-semibold shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
186
|
+
"aria-label": "Menu do usu\xE1rio",
|
|
187
|
+
"data-testid": "user-menu",
|
|
188
|
+
children: user?.avatarUrl ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
189
|
+
"img",
|
|
190
|
+
{
|
|
191
|
+
src: user.avatarUrl,
|
|
192
|
+
alt: user.name ?? user.email ?? "Avatar",
|
|
193
|
+
className: "h-full w-full object-cover"
|
|
194
|
+
}
|
|
195
|
+
) : label ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: label }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react.User, { className: "h-4 w-4" })
|
|
196
|
+
}
|
|
197
|
+
);
|
|
198
|
+
const userInfo = (user?.name || user?.email) && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "px-2 py-1.5", children: [
|
|
199
|
+
user.name && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "truncate text-sm font-medium", children: user.name }),
|
|
200
|
+
user.email && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "truncate text-xs text-muted-foreground", children: user.email })
|
|
201
|
+
] });
|
|
202
|
+
if (isDesktop) {
|
|
203
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(DropdownMenu.Root, { open, onOpenChange: setOpen, children: [
|
|
204
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DropdownMenu.Trigger, { asChild: true, children: trigger }),
|
|
205
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DropdownMenu.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
206
|
+
DropdownMenu.Content,
|
|
207
|
+
{
|
|
208
|
+
align,
|
|
209
|
+
sideOffset: 6,
|
|
210
|
+
className: "z-50 min-w-[12rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95",
|
|
211
|
+
children: [
|
|
212
|
+
userInfo && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
213
|
+
userInfo,
|
|
214
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DropdownMenu.Separator, { className: "-mx-1 my-1 h-px bg-border" })
|
|
215
|
+
] }),
|
|
216
|
+
items.map(
|
|
217
|
+
(item) => item.href ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DropdownMenu.Item, { asChild: true, children: renderLink({
|
|
218
|
+
href: item.href,
|
|
219
|
+
className: itemClass,
|
|
220
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
221
|
+
item.icon,
|
|
222
|
+
item.label
|
|
223
|
+
] })
|
|
224
|
+
}) }, item.label) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
225
|
+
DropdownMenu.Item,
|
|
226
|
+
{
|
|
227
|
+
className: itemClass,
|
|
228
|
+
onClick: item.onClick,
|
|
229
|
+
children: [
|
|
230
|
+
item.icon,
|
|
231
|
+
item.label
|
|
232
|
+
]
|
|
233
|
+
},
|
|
234
|
+
item.label
|
|
235
|
+
)
|
|
236
|
+
),
|
|
237
|
+
onLogout && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
238
|
+
items.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(DropdownMenu.Separator, { className: "-mx-1 my-1 h-px bg-border" }),
|
|
239
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
240
|
+
DropdownMenu.Item,
|
|
241
|
+
{
|
|
242
|
+
className: cn(
|
|
243
|
+
itemClass,
|
|
244
|
+
"text-destructive focus:bg-destructive/10"
|
|
245
|
+
),
|
|
246
|
+
onClick: onLogout,
|
|
247
|
+
children: [
|
|
248
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react.LogOut, { className: "h-4 w-4" }),
|
|
249
|
+
logoutLabel
|
|
250
|
+
]
|
|
251
|
+
}
|
|
252
|
+
)
|
|
253
|
+
] })
|
|
254
|
+
]
|
|
255
|
+
}
|
|
256
|
+
) })
|
|
257
|
+
] });
|
|
258
|
+
}
|
|
259
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_vaul.Drawer.Root, { open, onOpenChange: setOpen, children: [
|
|
260
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_vaul.Drawer.Trigger, { asChild: true, children: trigger }),
|
|
261
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_vaul.Drawer.Portal, { children: [
|
|
262
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_vaul.Drawer.Overlay, { className: "fixed inset-0 z-50 bg-black/80" }),
|
|
263
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_vaul.Drawer.Content, { className: "fixed inset-x-0 bottom-0 z-50 flex flex-col rounded-t-2xl border bg-popover p-2 pb-[max(0.5rem,env(safe-area-inset-bottom))] text-popover-foreground outline-none", children: [
|
|
264
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_vaul.Drawer.Title, { className: "sr-only", children: "Menu do usu\xE1rio" }),
|
|
265
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "mx-auto my-3 h-1.5 w-12 shrink-0 rounded-full bg-muted" }),
|
|
266
|
+
userInfo && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
267
|
+
userInfo,
|
|
268
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "-mx-1 my-1 h-px bg-border" })
|
|
269
|
+
] }),
|
|
270
|
+
items.map(
|
|
271
|
+
(item) => item.href ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
272
|
+
"span",
|
|
273
|
+
{
|
|
274
|
+
onClick: () => setOpen(false),
|
|
275
|
+
onKeyDown: () => setOpen(false),
|
|
276
|
+
children: renderLink({
|
|
277
|
+
href: item.href,
|
|
278
|
+
className: sheetItemClass,
|
|
279
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
280
|
+
item.icon,
|
|
281
|
+
item.label
|
|
282
|
+
] })
|
|
283
|
+
})
|
|
284
|
+
},
|
|
285
|
+
item.label
|
|
286
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
287
|
+
"button",
|
|
288
|
+
{
|
|
289
|
+
type: "button",
|
|
290
|
+
className: sheetItemClass,
|
|
291
|
+
onClick: () => {
|
|
292
|
+
item.onClick?.();
|
|
293
|
+
setOpen(false);
|
|
294
|
+
},
|
|
295
|
+
children: [
|
|
296
|
+
item.icon,
|
|
297
|
+
item.label
|
|
298
|
+
]
|
|
299
|
+
},
|
|
300
|
+
item.label
|
|
301
|
+
)
|
|
302
|
+
),
|
|
303
|
+
onLogout && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
304
|
+
items.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "-mx-1 my-1 h-px bg-border" }),
|
|
305
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
306
|
+
"button",
|
|
307
|
+
{
|
|
308
|
+
type: "button",
|
|
309
|
+
className: cn(sheetItemClass, "text-destructive"),
|
|
310
|
+
onClick: () => {
|
|
311
|
+
onLogout();
|
|
312
|
+
setOpen(false);
|
|
313
|
+
},
|
|
314
|
+
children: [
|
|
315
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react.LogOut, { className: "h-4 w-4" }),
|
|
316
|
+
logoutLabel
|
|
317
|
+
]
|
|
318
|
+
}
|
|
319
|
+
)
|
|
320
|
+
] })
|
|
319
321
|
] })
|
|
320
322
|
] })
|
|
321
|
-
] })
|
|
323
|
+
] });
|
|
322
324
|
}
|
|
323
325
|
|
|
324
|
-
// src/components/
|
|
325
|
-
var
|
|
326
|
-
function
|
|
327
|
-
|
|
328
|
-
|
|
326
|
+
// src/components/app-shell.tsx
|
|
327
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
328
|
+
function AppShell({
|
|
329
|
+
brand,
|
|
330
|
+
brandCollapsed,
|
|
331
|
+
navItems,
|
|
332
|
+
activePath,
|
|
333
|
+
isActive,
|
|
334
|
+
isAdmin = false,
|
|
335
|
+
user,
|
|
336
|
+
userMenuItems,
|
|
337
|
+
onLogout,
|
|
338
|
+
renderLink = defaultRenderLink,
|
|
339
|
+
headerActions,
|
|
340
|
+
collapsible = true,
|
|
341
|
+
defaultCollapsed = false,
|
|
342
|
+
children
|
|
343
|
+
}) {
|
|
344
|
+
const [collapsed, setCollapsed] = (0, import_react3.useState)(defaultCollapsed);
|
|
345
|
+
const [mobileOpen, setMobileOpen] = (0, import_react3.useState)(false);
|
|
346
|
+
const nav = (isCollapsed, onNavigate) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
347
|
+
SidebarNav,
|
|
329
348
|
{
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
]
|
|
349
|
+
items: navItems,
|
|
350
|
+
activePath,
|
|
351
|
+
isActive,
|
|
352
|
+
isAdmin,
|
|
353
|
+
isCollapsed,
|
|
354
|
+
renderLink,
|
|
355
|
+
onNavigate
|
|
338
356
|
}
|
|
339
357
|
);
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
344
|
-
function StatusDot({ active, label, className }) {
|
|
345
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: `inline-flex items-center gap-2 ${className ?? ""}`, children: [
|
|
346
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
347
|
-
"span",
|
|
358
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex h-screen overflow-hidden bg-background", children: [
|
|
359
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
360
|
+
"aside",
|
|
348
361
|
{
|
|
349
|
-
className:
|
|
362
|
+
className: cn(
|
|
363
|
+
"hidden shrink-0 flex-col border-r bg-card transition-all duration-300 md:flex",
|
|
364
|
+
collapsed ? "w-16" : "w-60"
|
|
365
|
+
),
|
|
366
|
+
children: [
|
|
367
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "flex h-14 shrink-0 items-center border-b px-4", children: collapsed ? brandCollapsed ?? brand : brand }),
|
|
368
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "flex-1 overflow-y-auto px-2 py-4", children: nav(collapsed) }),
|
|
369
|
+
collapsible && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "border-t p-2", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
370
|
+
"button",
|
|
371
|
+
{
|
|
372
|
+
type: "button",
|
|
373
|
+
onClick: () => setCollapsed((v) => !v),
|
|
374
|
+
className: "flex w-full items-center justify-center rounded-md px-2 py-2 text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground",
|
|
375
|
+
"aria-label": collapsed ? "Expandir menu" : "Recolher menu",
|
|
376
|
+
children: collapsed ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.ChevronRight, { className: "h-4 w-4" }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.ChevronLeft, { className: "h-4 w-4" })
|
|
377
|
+
}
|
|
378
|
+
) })
|
|
379
|
+
]
|
|
350
380
|
}
|
|
351
381
|
),
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
className,
|
|
384
|
-
children
|
|
385
|
-
}) {
|
|
386
|
-
const classes = variantClasses[variant];
|
|
387
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
388
|
-
"span",
|
|
389
|
-
{
|
|
390
|
-
className: `inline-flex items-center gap-1.5 rounded-md px-2 py-0.5 text-xs font-medium ${classes.badge} ${className ?? ""}`,
|
|
391
|
-
children: [
|
|
392
|
-
dot && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
393
|
-
"span",
|
|
382
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
383
|
+
"div",
|
|
384
|
+
{
|
|
385
|
+
className: cn(
|
|
386
|
+
"fixed inset-0 z-50 transition-opacity duration-300 md:hidden",
|
|
387
|
+
mobileOpen ? "pointer-events-auto opacity-100" : "pointer-events-none opacity-0"
|
|
388
|
+
),
|
|
389
|
+
onClick: () => setMobileOpen(false),
|
|
390
|
+
children: [
|
|
391
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "absolute inset-0 bg-black/50" }),
|
|
392
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
393
|
+
"div",
|
|
394
|
+
{
|
|
395
|
+
className: cn(
|
|
396
|
+
"absolute left-0 top-0 flex h-full w-64 flex-col border-r bg-card transition-transform duration-300",
|
|
397
|
+
mobileOpen ? "translate-x-0" : "-translate-x-full"
|
|
398
|
+
),
|
|
399
|
+
onClick: (e) => e.stopPropagation(),
|
|
400
|
+
children: [
|
|
401
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "flex h-14 shrink-0 items-center border-b px-4", children: brand }),
|
|
402
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "flex-1 overflow-y-auto px-2 py-4", children: nav(false, () => setMobileOpen(false)) })
|
|
403
|
+
]
|
|
404
|
+
}
|
|
405
|
+
)
|
|
406
|
+
]
|
|
407
|
+
}
|
|
408
|
+
),
|
|
409
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
|
|
410
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("header", { className: "flex h-14 shrink-0 items-center gap-2 border-b bg-background px-4", children: [
|
|
411
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
412
|
+
"button",
|
|
394
413
|
{
|
|
395
|
-
|
|
414
|
+
type: "button",
|
|
415
|
+
onClick: () => setMobileOpen(true),
|
|
416
|
+
className: "inline-flex h-9 w-9 items-center justify-center rounded-md border border-input bg-background shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground md:hidden",
|
|
417
|
+
"aria-label": "Abrir menu",
|
|
418
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react2.Menu, { className: "h-4 w-4" })
|
|
396
419
|
}
|
|
397
420
|
),
|
|
398
|
-
children
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
421
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "ml-auto flex items-center gap-2", children: [
|
|
422
|
+
headerActions,
|
|
423
|
+
(user || onLogout) && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(UserMenu, { user, items: userMenuItems, onLogout, renderLink })
|
|
424
|
+
] })
|
|
425
|
+
] }),
|
|
426
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("main", { className: "flex-1 overflow-y-auto", children })
|
|
427
|
+
] })
|
|
428
|
+
] });
|
|
402
429
|
}
|
|
403
430
|
|
|
404
|
-
// src/components/
|
|
405
|
-
var
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
value,
|
|
412
|
-
size = "md",
|
|
413
|
-
label,
|
|
414
|
-
valueLabel,
|
|
415
|
-
className,
|
|
416
|
-
indicatorClassName
|
|
417
|
-
}) {
|
|
418
|
-
const clamped = Math.min(100, Math.max(0, value));
|
|
419
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: `space-y-1.5 ${className ?? ""}`, children: [
|
|
420
|
-
(label || valueLabel) && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-baseline justify-between gap-2", children: [
|
|
421
|
-
label && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-sm text-muted-foreground", children: label }),
|
|
422
|
-
valueLabel && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-sm font-semibold", children: valueLabel })
|
|
431
|
+
// src/components/auth-card.tsx
|
|
432
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
433
|
+
function AuthCard({ title, description, children, footer }) {
|
|
434
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "flex min-h-screen items-center justify-center px-4", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "w-full max-w-sm rounded-lg border bg-card p-6 shadow-sm", children: [
|
|
435
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mb-6 text-center", children: [
|
|
436
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h1", { className: "text-2xl font-semibold tracking-tight", children: title }),
|
|
437
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "mt-1 text-sm text-muted-foreground", children: description })
|
|
423
438
|
] }),
|
|
424
|
-
/* @__PURE__ */ (0,
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
className: `w-full overflow-hidden rounded-full bg-muted ${sizeClasses[size]}`,
|
|
428
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
429
|
-
"div",
|
|
430
|
-
{
|
|
431
|
-
className: `h-full rounded-full transition-all duration-300 ${indicatorClassName ?? "bg-primary"}`,
|
|
432
|
-
style: { width: `${clamped}%` }
|
|
433
|
-
}
|
|
434
|
-
)
|
|
435
|
-
}
|
|
436
|
-
)
|
|
437
|
-
] });
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
// src/components/form-field.tsx
|
|
441
|
-
var import_react3 = require("react");
|
|
442
|
-
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
443
|
-
function FormField({ label, htmlFor, error, required, children, className }) {
|
|
444
|
-
const errorId = (0, import_react3.useId)();
|
|
445
|
-
const field = error && (0, import_react3.isValidElement)(children) ? (0, import_react3.cloneElement)(children, {
|
|
446
|
-
"aria-invalid": true,
|
|
447
|
-
"aria-describedby": [
|
|
448
|
-
children.props["aria-describedby"],
|
|
449
|
-
errorId
|
|
450
|
-
].filter(Boolean).join(" ")
|
|
451
|
-
}) : children;
|
|
452
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: `space-y-2 ${className ?? ""}`, children: [
|
|
453
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
454
|
-
"label",
|
|
455
|
-
{
|
|
456
|
-
htmlFor,
|
|
457
|
-
className: "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
|
458
|
-
children: [
|
|
459
|
-
label,
|
|
460
|
-
required && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "ml-1 text-destructive", children: "*" })
|
|
461
|
-
]
|
|
462
|
-
}
|
|
463
|
-
),
|
|
464
|
-
field,
|
|
465
|
-
error && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { id: errorId, className: "text-sm text-destructive", children: error })
|
|
466
|
-
] });
|
|
439
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "space-y-4", children }),
|
|
440
|
+
footer && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "mt-4", children: footer })
|
|
441
|
+
] }) });
|
|
467
442
|
}
|
|
468
443
|
|
|
469
444
|
// src/components/base-dialog.tsx
|
|
470
445
|
var Dialog = __toESM(require("@radix-ui/react-dialog"), 1);
|
|
471
|
-
var
|
|
446
|
+
var import_lucide_react3 = require("lucide-react");
|
|
472
447
|
var React2 = __toESM(require("react"), 1);
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
var React = __toESM(require("react"), 1);
|
|
476
|
-
var DESKTOP_QUERY = "(min-width: 640px)";
|
|
477
|
-
function useIsDesktop() {
|
|
478
|
-
const [isDesktop, setIsDesktop] = React.useState(
|
|
479
|
-
() => typeof window !== "undefined" ? window.matchMedia(DESKTOP_QUERY).matches : true
|
|
480
|
-
);
|
|
481
|
-
React.useEffect(() => {
|
|
482
|
-
const mql = window.matchMedia(DESKTOP_QUERY);
|
|
483
|
-
const onChange = () => setIsDesktop(mql.matches);
|
|
484
|
-
onChange();
|
|
485
|
-
mql.addEventListener("change", onChange);
|
|
486
|
-
return () => mql.removeEventListener("change", onChange);
|
|
487
|
-
}, []);
|
|
488
|
-
return isDesktop;
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
// src/components/base-dialog.tsx
|
|
492
|
-
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
493
|
-
var sizeClasses2 = {
|
|
448
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
449
|
+
var sizeClasses = {
|
|
494
450
|
sm: "sm:max-w-sm",
|
|
495
451
|
md: "sm:max-w-md",
|
|
496
452
|
lg: "sm:max-w-lg",
|
|
@@ -526,27 +482,27 @@ function BaseDialog({
|
|
|
526
482
|
}, 0);
|
|
527
483
|
return () => window.clearTimeout(id);
|
|
528
484
|
}, [open]);
|
|
529
|
-
const body = /* @__PURE__ */ (0,
|
|
530
|
-
/* @__PURE__ */ (0,
|
|
531
|
-
/* @__PURE__ */ (0,
|
|
532
|
-
/* @__PURE__ */ (0,
|
|
533
|
-
description && /* @__PURE__ */ (0,
|
|
485
|
+
const body = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
486
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex shrink-0 items-start justify-between gap-4 border-b px-6 py-3", children: [
|
|
487
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "min-w-0 space-y-1", children: [
|
|
488
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Dialog.Title, { className: "text-lg font-semibold leading-none tracking-tight", children: title }),
|
|
489
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Dialog.Description, { className: "text-sm text-muted-foreground", children: description })
|
|
534
490
|
] }),
|
|
535
|
-
/* @__PURE__ */ (0,
|
|
491
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
536
492
|
Dialog.Close,
|
|
537
493
|
{
|
|
538
494
|
className: "-mr-1 shrink-0 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
539
495
|
"aria-label": "Fechar",
|
|
540
|
-
children: /* @__PURE__ */ (0,
|
|
496
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react3.X, { className: "h-5 w-5" })
|
|
541
497
|
}
|
|
542
498
|
)
|
|
543
499
|
] }),
|
|
544
|
-
/* @__PURE__ */ (0,
|
|
545
|
-
footer && /* @__PURE__ */ (0,
|
|
500
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "min-h-0 flex-1 overflow-y-auto px-6 py-4", children }),
|
|
501
|
+
footer && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "flex shrink-0 flex-col-reverse gap-2 border-t px-6 py-3 sm:flex-row sm:justify-end", children: footer })
|
|
546
502
|
] });
|
|
547
503
|
const isModal = modal ?? !isDesktop;
|
|
548
|
-
return /* @__PURE__ */ (0,
|
|
549
|
-
isModal ? /* @__PURE__ */ (0,
|
|
504
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Dialog.Root, { open, onOpenChange, modal: isModal, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Dialog.Portal, { children: [
|
|
505
|
+
isModal ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
550
506
|
Dialog.Overlay,
|
|
551
507
|
{
|
|
552
508
|
className: cn(
|
|
@@ -559,7 +515,7 @@ function BaseDialog({
|
|
|
559
515
|
// Radix skips Dialog.Overlay when non-modal, so the backdrop is
|
|
560
516
|
// rendered by hand; pointer-events-none keeps outside interactions
|
|
561
517
|
// working (the reason the dialog is non-modal on desktop).
|
|
562
|
-
(blurBackdrop || backdropClassName) && /* @__PURE__ */ (0,
|
|
518
|
+
(blurBackdrop || backdropClassName) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
563
519
|
"div",
|
|
564
520
|
{
|
|
565
521
|
"aria-hidden": true,
|
|
@@ -571,7 +527,7 @@ function BaseDialog({
|
|
|
571
527
|
}
|
|
572
528
|
)
|
|
573
529
|
),
|
|
574
|
-
/* @__PURE__ */ (0,
|
|
530
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
575
531
|
Dialog.Content,
|
|
576
532
|
{
|
|
577
533
|
onCloseAutoFocus: () => {
|
|
@@ -582,7 +538,7 @@ function BaseDialog({
|
|
|
582
538
|
"inset-x-0 bottom-0 rounded-t-2xl",
|
|
583
539
|
"sm:inset-x-auto sm:bottom-auto sm:left-1/2 sm:top-1/2 sm:max-h-[92vh] sm:w-full sm:-translate-x-1/2 sm:-translate-y-1/2 sm:rounded-lg",
|
|
584
540
|
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
585
|
-
|
|
541
|
+
sizeClasses[size],
|
|
586
542
|
className
|
|
587
543
|
),
|
|
588
544
|
children: contentWrapper(body)
|
|
@@ -591,230 +547,133 @@ function BaseDialog({
|
|
|
591
547
|
] }) });
|
|
592
548
|
}
|
|
593
549
|
|
|
594
|
-
// src/components/
|
|
595
|
-
var
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
550
|
+
// src/components/color-picker.tsx
|
|
551
|
+
var PopoverPrimitive = __toESM(require("@radix-ui/react-popover"), 1);
|
|
552
|
+
var import_lucide_react4 = require("lucide-react");
|
|
553
|
+
var React3 = __toESM(require("react"), 1);
|
|
554
|
+
var import_react_colorful = require("react-colorful");
|
|
555
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
556
|
+
function ColorPicker({
|
|
557
|
+
value,
|
|
558
|
+
onChange,
|
|
559
|
+
placeholder = "Selecionar cor",
|
|
560
|
+
clearable = true,
|
|
561
|
+
alpha = false,
|
|
562
|
+
disabled,
|
|
563
|
+
id,
|
|
564
|
+
className,
|
|
565
|
+
"aria-invalid": ariaInvalid,
|
|
566
|
+
"aria-describedby": ariaDescribedby
|
|
605
567
|
}) {
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
"
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
568
|
+
const [open, setOpen] = React3.useState(false);
|
|
569
|
+
const color = value || "";
|
|
570
|
+
const showClear = clearable && !!color && !disabled;
|
|
571
|
+
const clear = (event) => {
|
|
572
|
+
event.stopPropagation();
|
|
573
|
+
event.preventDefault();
|
|
574
|
+
onChange("");
|
|
575
|
+
};
|
|
576
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(PopoverPrimitive.Root, { open, onOpenChange: setOpen, children: [
|
|
577
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PopoverPrimitive.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
578
|
+
"button",
|
|
579
|
+
{
|
|
580
|
+
type: "button",
|
|
581
|
+
id,
|
|
582
|
+
"aria-invalid": ariaInvalid,
|
|
583
|
+
"aria-describedby": ariaDescribedby,
|
|
584
|
+
disabled,
|
|
585
|
+
className: cn(
|
|
586
|
+
"flex h-9 w-full cursor-pointer items-center justify-between gap-2 rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm transition-colors hover:border-ring/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:focus-visible:ring-destructive",
|
|
587
|
+
className
|
|
588
|
+
),
|
|
589
|
+
children: [
|
|
590
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "flex items-center gap-2 truncate", children: [
|
|
591
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
592
|
+
"span",
|
|
593
|
+
{
|
|
594
|
+
"aria-hidden": true,
|
|
595
|
+
className: "h-5 w-5 shrink-0 rounded border border-border bg-[length:8px_8px] bg-[position:0_0,4px_4px]",
|
|
596
|
+
style: {
|
|
597
|
+
// The checkerboard stays under the color layer so a
|
|
598
|
+
// translucent value reads as translucent in the swatch.
|
|
599
|
+
backgroundImage: `${color ? `linear-gradient(${color},${color}),` : ""}linear-gradient(45deg,var(--color-muted) 25%,transparent 25%,transparent 75%,var(--color-muted) 75%),linear-gradient(45deg,var(--color-muted) 25%,transparent 25%,transparent 75%,var(--color-muted) 75%)`
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
),
|
|
603
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: cn("truncate", !color && "text-muted-foreground"), children: color || placeholder })
|
|
604
|
+
] }),
|
|
605
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "flex shrink-0 items-center gap-1", children: [
|
|
606
|
+
showClear && // Not a <button> — nesting one inside the trigger button is
|
|
607
|
+
// invalid HTML.
|
|
608
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
609
|
+
"span",
|
|
610
|
+
{
|
|
611
|
+
role: "button",
|
|
612
|
+
tabIndex: 0,
|
|
613
|
+
"aria-label": "Limpar cor",
|
|
614
|
+
onClick: clear,
|
|
615
|
+
onKeyDown: (event) => {
|
|
616
|
+
if (event.key === "Enter" || event.key === " ") clear(event);
|
|
617
|
+
},
|
|
618
|
+
className: "rounded p-0.5 text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
619
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react4.X, { className: "h-3.5 w-3.5" })
|
|
620
|
+
}
|
|
621
|
+
),
|
|
622
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react4.ChevronsUpDown, { className: "h-4 w-4 shrink-0 opacity-50" })
|
|
623
|
+
] })
|
|
624
|
+
]
|
|
625
|
+
}
|
|
626
|
+
) }),
|
|
627
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PopoverPrimitive.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
628
|
+
PopoverPrimitive.Content,
|
|
629
|
+
{
|
|
630
|
+
align: "start",
|
|
631
|
+
sideOffset: 4,
|
|
632
|
+
className: "z-50 w-56 rounded-md border bg-popover p-3 text-popover-foreground shadow-md",
|
|
633
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mh-color-picker flex flex-col gap-3", children: [
|
|
634
|
+
alpha ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_colorful.HexAlphaColorPicker, { color, onChange }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_colorful.HexColorPicker, { color, onChange }),
|
|
635
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
636
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-sm text-muted-foreground", children: "#" }),
|
|
637
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
638
|
+
import_react_colorful.HexColorInput,
|
|
639
|
+
{
|
|
640
|
+
color,
|
|
641
|
+
onChange,
|
|
642
|
+
prefixed: false,
|
|
643
|
+
alpha,
|
|
644
|
+
className: "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm uppercase shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
645
|
+
}
|
|
646
|
+
)
|
|
647
|
+
] })
|
|
648
|
+
] })
|
|
649
|
+
}
|
|
650
|
+
) })
|
|
629
651
|
] });
|
|
630
652
|
}
|
|
631
|
-
function FormDialog({ onSubmit, ...rest }) {
|
|
632
|
-
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
633
|
-
BaseDialog,
|
|
634
|
-
{
|
|
635
|
-
...rest,
|
|
636
|
-
contentWrapper: onSubmit ? (content) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("form", { onSubmit, className: "flex min-h-0 flex-1 flex-col", children: content }) : void 0
|
|
637
|
-
}
|
|
638
|
-
);
|
|
639
|
-
}
|
|
640
653
|
|
|
641
|
-
// src/components/
|
|
642
|
-
var
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
description && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "mt-1 text-sm text-muted-foreground", children: description })
|
|
648
|
-
] }),
|
|
649
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "space-y-4", children }),
|
|
650
|
-
footer && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "mt-4", children: footer })
|
|
651
|
-
] }) });
|
|
652
|
-
}
|
|
654
|
+
// src/components/combobox.tsx
|
|
655
|
+
var PopoverPrimitive2 = __toESM(require("@radix-ui/react-popover"), 1);
|
|
656
|
+
var import_cmdk = require("cmdk");
|
|
657
|
+
var import_lucide_react5 = require("lucide-react");
|
|
658
|
+
var React5 = __toESM(require("react"), 1);
|
|
659
|
+
var import_vaul2 = require("vaul");
|
|
653
660
|
|
|
654
|
-
// src/
|
|
655
|
-
var
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
hasNextPage,
|
|
661
|
-
hasPreviousPage,
|
|
662
|
-
totalPages,
|
|
663
|
-
showPageSizeSelector = false,
|
|
664
|
-
pageSize,
|
|
665
|
-
onPageSizeChange,
|
|
666
|
-
pageSizeOptions,
|
|
667
|
-
className
|
|
661
|
+
// src/hooks/use-infinite-scroll-sentinel.ts
|
|
662
|
+
var React4 = __toESM(require("react"), 1);
|
|
663
|
+
function useInfiniteScrollSentinel({
|
|
664
|
+
enabled,
|
|
665
|
+
loading,
|
|
666
|
+
onLoadMore
|
|
668
667
|
}) {
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
showPageSizeSelector && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
675
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { htmlFor: "pagination-page-size", className: "text-sm text-muted-foreground", children: "Itens por p\xE1gina" }),
|
|
676
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
677
|
-
"select",
|
|
678
|
-
{
|
|
679
|
-
id: "pagination-page-size",
|
|
680
|
-
value: pageSize,
|
|
681
|
-
onChange: (e) => onPageSizeChange?.(Number(e.target.value)),
|
|
682
|
-
className: "h-8 rounded-md border border-input bg-background px-2 text-xs font-medium shadow-sm transition-colors hover:bg-accent focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring cursor-pointer",
|
|
683
|
-
children: (pageSizeOptions ?? []).map((size) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: size, children: size }, size))
|
|
684
|
-
}
|
|
685
|
-
)
|
|
686
|
-
] }),
|
|
687
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-4", children: [
|
|
688
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
689
|
-
"button",
|
|
690
|
-
{
|
|
691
|
-
type: "button",
|
|
692
|
-
onClick: () => onPageChange(page - 1),
|
|
693
|
-
disabled: !hasPreviousPage,
|
|
694
|
-
className: navButtonClass,
|
|
695
|
-
children: "Anterior"
|
|
696
|
-
}
|
|
697
|
-
),
|
|
698
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "text-sm text-muted-foreground", children: [
|
|
699
|
-
"P\xE1gina ",
|
|
700
|
-
page,
|
|
701
|
-
totalPages ? ` de ${totalPages}` : ""
|
|
702
|
-
] }),
|
|
703
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
704
|
-
"button",
|
|
705
|
-
{
|
|
706
|
-
type: "button",
|
|
707
|
-
onClick: () => onPageChange(page + 1),
|
|
708
|
-
disabled: !hasNextPage,
|
|
709
|
-
className: navButtonClass,
|
|
710
|
-
children: "Pr\xF3ximo"
|
|
711
|
-
}
|
|
712
|
-
)
|
|
713
|
-
] })
|
|
714
|
-
]
|
|
715
|
-
}
|
|
716
|
-
);
|
|
717
|
-
}
|
|
718
|
-
|
|
719
|
-
// src/components/table-skeleton.tsx
|
|
720
|
-
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
721
|
-
function TableSkeleton({ rows = 5, columns = 4 }) {
|
|
722
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, { children: Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("tr", { className: "border-b transition-colors", children: Array.from({ length: columns }).map((_2, j) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("td", { className: "p-4 align-middle", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "h-5 w-full animate-pulse rounded bg-muted" }) }, j)) }, i)) });
|
|
723
|
-
}
|
|
724
|
-
|
|
725
|
-
// src/components/search-input.tsx
|
|
726
|
-
var React3 = __toESM(require("react"), 1);
|
|
727
|
-
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
728
|
-
var SearchInput = React3.forwardRef(
|
|
729
|
-
({ containerClassName, className, ...props }, ref) => {
|
|
730
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: `relative flex-1 ${containerClassName ?? ""}`, children: [
|
|
731
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
732
|
-
"svg",
|
|
733
|
-
{
|
|
734
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
735
|
-
width: "16",
|
|
736
|
-
height: "16",
|
|
737
|
-
viewBox: "0 0 24 24",
|
|
738
|
-
fill: "none",
|
|
739
|
-
stroke: "currentColor",
|
|
740
|
-
strokeWidth: "2",
|
|
741
|
-
strokeLinecap: "round",
|
|
742
|
-
strokeLinejoin: "round",
|
|
743
|
-
className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground",
|
|
744
|
-
children: [
|
|
745
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("circle", { cx: "11", cy: "11", r: "8" }),
|
|
746
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("path", { d: "m21 21-4.3-4.3" })
|
|
747
|
-
]
|
|
748
|
-
}
|
|
749
|
-
),
|
|
750
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
751
|
-
"input",
|
|
752
|
-
{
|
|
753
|
-
ref,
|
|
754
|
-
type: "text",
|
|
755
|
-
className: `flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 pl-10 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 ${className ?? ""}`,
|
|
756
|
-
...props
|
|
757
|
-
}
|
|
758
|
-
)
|
|
759
|
-
] });
|
|
760
|
-
}
|
|
761
|
-
);
|
|
762
|
-
SearchInput.displayName = "SearchInput";
|
|
763
|
-
|
|
764
|
-
// src/components/password-input.tsx
|
|
765
|
-
var import_lucide_react3 = require("lucide-react");
|
|
766
|
-
var React4 = __toESM(require("react"), 1);
|
|
767
|
-
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
768
|
-
var PasswordInput = React4.forwardRef(({ containerClassName, className, ...props }, ref) => {
|
|
769
|
-
const [visible, setVisible] = React4.useState(false);
|
|
770
|
-
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: `relative ${containerClassName ?? ""}`, children: [
|
|
771
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
772
|
-
"input",
|
|
773
|
-
{
|
|
774
|
-
ref,
|
|
775
|
-
type: visible ? "text" : "password",
|
|
776
|
-
className: `flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 pr-10 text-base shadow-sm transition-all duration-200 placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:focus-visible:ring-destructive md:text-sm ${className ?? ""}`,
|
|
777
|
-
...props
|
|
778
|
-
}
|
|
779
|
-
),
|
|
780
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
781
|
-
"button",
|
|
782
|
-
{
|
|
783
|
-
type: "button",
|
|
784
|
-
onClick: () => setVisible((prev) => !prev),
|
|
785
|
-
"aria-label": visible ? "Ocultar senha" : "Mostrar senha",
|
|
786
|
-
tabIndex: -1,
|
|
787
|
-
className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground transition-colors hover:text-foreground",
|
|
788
|
-
children: visible ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react3.EyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react3.Eye, { className: "h-4 w-4" })
|
|
789
|
-
}
|
|
790
|
-
)
|
|
791
|
-
] });
|
|
792
|
-
});
|
|
793
|
-
PasswordInput.displayName = "PasswordInput";
|
|
794
|
-
|
|
795
|
-
// src/components/combobox.tsx
|
|
796
|
-
var PopoverPrimitive = __toESM(require("@radix-ui/react-popover"), 1);
|
|
797
|
-
var import_cmdk = require("cmdk");
|
|
798
|
-
var import_lucide_react4 = require("lucide-react");
|
|
799
|
-
var React6 = __toESM(require("react"), 1);
|
|
800
|
-
var import_vaul = require("vaul");
|
|
801
|
-
|
|
802
|
-
// src/hooks/use-infinite-scroll-sentinel.ts
|
|
803
|
-
var React5 = __toESM(require("react"), 1);
|
|
804
|
-
function useInfiniteScrollSentinel({
|
|
805
|
-
enabled,
|
|
806
|
-
loading,
|
|
807
|
-
onLoadMore
|
|
808
|
-
}) {
|
|
809
|
-
const listRef = React5.useRef(null);
|
|
810
|
-
const sentinelRef = React5.useRef(null);
|
|
811
|
-
const loadingRef = React5.useRef(loading);
|
|
812
|
-
const onLoadMoreRef = React5.useRef(onLoadMore);
|
|
813
|
-
React5.useEffect(() => {
|
|
668
|
+
const listRef = React4.useRef(null);
|
|
669
|
+
const sentinelRef = React4.useRef(null);
|
|
670
|
+
const loadingRef = React4.useRef(loading);
|
|
671
|
+
const onLoadMoreRef = React4.useRef(onLoadMore);
|
|
672
|
+
React4.useEffect(() => {
|
|
814
673
|
loadingRef.current = loading;
|
|
815
674
|
onLoadMoreRef.current = onLoadMore;
|
|
816
675
|
});
|
|
817
|
-
|
|
676
|
+
React4.useEffect(() => {
|
|
818
677
|
if (!enabled) return;
|
|
819
678
|
const root = listRef.current;
|
|
820
679
|
const sentinel = sentinelRef.current;
|
|
@@ -834,7 +693,7 @@ function useInfiniteScrollSentinel({
|
|
|
834
693
|
}
|
|
835
694
|
|
|
836
695
|
// src/components/combobox.tsx
|
|
837
|
-
var
|
|
696
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
838
697
|
function Combobox({
|
|
839
698
|
options,
|
|
840
699
|
value,
|
|
@@ -855,8 +714,8 @@ function Combobox({
|
|
|
855
714
|
creatable,
|
|
856
715
|
formatCreateLabel
|
|
857
716
|
}) {
|
|
858
|
-
const [open, setOpen] =
|
|
859
|
-
const [search, setSearch] =
|
|
717
|
+
const [open, setOpen] = React5.useState(false);
|
|
718
|
+
const [search, setSearch] = React5.useState("");
|
|
860
719
|
const isDesktop = useIsDesktop();
|
|
861
720
|
const isServer = onSearchChange !== void 0;
|
|
862
721
|
const selected = selectedOption?.value === value ? selectedOption : options.find((option) => option.value === value) ?? (creatable && value ? { value, label: value } : void 0);
|
|
@@ -881,7 +740,7 @@ function Combobox({
|
|
|
881
740
|
loading,
|
|
882
741
|
onLoadMore
|
|
883
742
|
});
|
|
884
|
-
const trigger = /* @__PURE__ */ (0,
|
|
743
|
+
const trigger = /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
885
744
|
"button",
|
|
886
745
|
{
|
|
887
746
|
type: "button",
|
|
@@ -896,20 +755,20 @@ function Combobox({
|
|
|
896
755
|
className
|
|
897
756
|
),
|
|
898
757
|
children: [
|
|
899
|
-
/* @__PURE__ */ (0,
|
|
900
|
-
/* @__PURE__ */ (0,
|
|
758
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: cn("truncate", !selected && "text-muted-foreground"), children: selected ? selected.label : placeholder }),
|
|
759
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react5.ChevronsUpDown, { className: "h-4 w-4 shrink-0 opacity-50" })
|
|
901
760
|
]
|
|
902
761
|
}
|
|
903
762
|
);
|
|
904
|
-
const command = /* @__PURE__ */ (0,
|
|
763
|
+
const command = /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
905
764
|
import_cmdk.Command,
|
|
906
765
|
{
|
|
907
766
|
shouldFilter: !isServer,
|
|
908
767
|
className: "flex h-full w-full flex-col overflow-hidden",
|
|
909
768
|
children: [
|
|
910
|
-
/* @__PURE__ */ (0,
|
|
911
|
-
/* @__PURE__ */ (0,
|
|
912
|
-
/* @__PURE__ */ (0,
|
|
769
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center border-b px-3", children: [
|
|
770
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react5.Search, { className: "mr-2 h-4 w-4 shrink-0 opacity-50" }),
|
|
771
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
913
772
|
import_cmdk.Command.Input,
|
|
914
773
|
{
|
|
915
774
|
placeholder: searchPlaceholder,
|
|
@@ -918,28 +777,28 @@ function Combobox({
|
|
|
918
777
|
}
|
|
919
778
|
)
|
|
920
779
|
] }),
|
|
921
|
-
/* @__PURE__ */ (0,
|
|
780
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
922
781
|
import_cmdk.Command.List,
|
|
923
782
|
{
|
|
924
783
|
ref: listRef,
|
|
925
784
|
className: "max-h-[50vh] overflow-y-auto overflow-x-hidden p-1 sm:max-h-60",
|
|
926
785
|
children: [
|
|
927
|
-
!isServer && !showCreate && /* @__PURE__ */ (0,
|
|
928
|
-
showCreate && /* @__PURE__ */ (0,
|
|
786
|
+
!isServer && !showCreate && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_cmdk.Command.Empty, { className: "py-6 text-center text-sm text-muted-foreground", children: emptyMessage }),
|
|
787
|
+
showCreate && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
929
788
|
import_cmdk.Command.Item,
|
|
930
789
|
{
|
|
931
790
|
value: trimmedSearch,
|
|
932
791
|
onSelect: () => handleSelect(trimmedSearch),
|
|
933
792
|
className: "relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-2.5 text-sm outline-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground sm:py-1.5",
|
|
934
793
|
children: [
|
|
935
|
-
/* @__PURE__ */ (0,
|
|
936
|
-
/* @__PURE__ */ (0,
|
|
794
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react5.Plus, { className: "h-4 w-4 shrink-0" }),
|
|
795
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "truncate", children: (formatCreateLabel ?? ((text) => `Usar "${text}"`))(
|
|
937
796
|
trimmedSearch
|
|
938
797
|
) })
|
|
939
798
|
]
|
|
940
799
|
}
|
|
941
800
|
),
|
|
942
|
-
options.map((option) => /* @__PURE__ */ (0,
|
|
801
|
+
options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
943
802
|
import_cmdk.Command.Item,
|
|
944
803
|
{
|
|
945
804
|
value: isServer ? option.value : option.label,
|
|
@@ -947,8 +806,8 @@ function Combobox({
|
|
|
947
806
|
onSelect: () => handleSelect(option.value),
|
|
948
807
|
className: "relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-2.5 text-sm outline-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 sm:py-1.5",
|
|
949
808
|
children: [
|
|
950
|
-
/* @__PURE__ */ (0,
|
|
951
|
-
|
|
809
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
810
|
+
import_lucide_react5.Check,
|
|
952
811
|
{
|
|
953
812
|
className: cn(
|
|
954
813
|
"h-4 w-4 shrink-0",
|
|
@@ -956,14 +815,14 @@ function Combobox({
|
|
|
956
815
|
)
|
|
957
816
|
}
|
|
958
817
|
),
|
|
959
|
-
/* @__PURE__ */ (0,
|
|
818
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "truncate", children: option.label })
|
|
960
819
|
]
|
|
961
820
|
},
|
|
962
821
|
option.value
|
|
963
822
|
)),
|
|
964
|
-
isServer && !loading && options.length === 0 && /* @__PURE__ */ (0,
|
|
965
|
-
isServer && loading && /* @__PURE__ */ (0,
|
|
966
|
-
isServer && hasMore && /* @__PURE__ */ (0,
|
|
823
|
+
isServer && !loading && options.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "py-6 text-center text-sm text-muted-foreground", children: emptyMessage }),
|
|
824
|
+
isServer && loading && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex items-center justify-center py-6", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react5.Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" }) }),
|
|
825
|
+
isServer && hasMore && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { ref: sentinelRef, "aria-hidden": true, className: "h-1" })
|
|
967
826
|
]
|
|
968
827
|
}
|
|
969
828
|
)
|
|
@@ -971,10 +830,10 @@ function Combobox({
|
|
|
971
830
|
}
|
|
972
831
|
);
|
|
973
832
|
if (isDesktop) {
|
|
974
|
-
return /* @__PURE__ */ (0,
|
|
975
|
-
/* @__PURE__ */ (0,
|
|
976
|
-
/* @__PURE__ */ (0,
|
|
977
|
-
|
|
833
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(PopoverPrimitive2.Root, { open, onOpenChange: handleOpenChange, children: [
|
|
834
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PopoverPrimitive2.Trigger, { asChild: true, children: trigger }),
|
|
835
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(PopoverPrimitive2.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
836
|
+
PopoverPrimitive2.Content,
|
|
978
837
|
{
|
|
979
838
|
align: "start",
|
|
980
839
|
sideOffset: 4,
|
|
@@ -985,314 +844,127 @@ function Combobox({
|
|
|
985
844
|
) })
|
|
986
845
|
] });
|
|
987
846
|
}
|
|
988
|
-
return /* @__PURE__ */ (0,
|
|
989
|
-
/* @__PURE__ */ (0,
|
|
990
|
-
/* @__PURE__ */ (0,
|
|
991
|
-
/* @__PURE__ */ (0,
|
|
992
|
-
/* @__PURE__ */ (0,
|
|
993
|
-
/* @__PURE__ */ (0,
|
|
994
|
-
/* @__PURE__ */ (0,
|
|
847
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_vaul2.Drawer.Root, { open, onOpenChange: handleOpenChange, children: [
|
|
848
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_vaul2.Drawer.Trigger, { asChild: true, children: trigger }),
|
|
849
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_vaul2.Drawer.Portal, { children: [
|
|
850
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_vaul2.Drawer.Overlay, { className: "fixed inset-0 z-50 bg-black/80" }),
|
|
851
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_vaul2.Drawer.Content, { className: "fixed inset-x-0 bottom-0 z-50 mt-24 flex max-h-[85vh] flex-col rounded-t-2xl border bg-popover text-popover-foreground outline-none", children: [
|
|
852
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_vaul2.Drawer.Title, { className: "sr-only", children: placeholder }),
|
|
853
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "mx-auto my-3 h-1.5 w-12 shrink-0 rounded-full bg-muted" }),
|
|
995
854
|
command
|
|
996
855
|
] })
|
|
997
856
|
] })
|
|
998
857
|
] });
|
|
999
858
|
}
|
|
1000
859
|
|
|
1001
|
-
// src/components/
|
|
1002
|
-
var
|
|
1003
|
-
var
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
id,
|
|
1017
|
-
className,
|
|
1018
|
-
"aria-invalid": ariaInvalid,
|
|
1019
|
-
"aria-describedby": ariaDescribedby,
|
|
1020
|
-
onSearchChange,
|
|
1021
|
-
onLoadMore,
|
|
1022
|
-
loading,
|
|
1023
|
-
hasMore,
|
|
1024
|
-
selectedOptions
|
|
860
|
+
// src/components/confirm-dialog.tsx
|
|
861
|
+
var AlertDialog = __toESM(require("@radix-ui/react-alert-dialog"), 1);
|
|
862
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
863
|
+
function ConfirmDialog({
|
|
864
|
+
open,
|
|
865
|
+
onOpenChange,
|
|
866
|
+
onConfirm,
|
|
867
|
+
title,
|
|
868
|
+
description,
|
|
869
|
+
confirmLabel = "Confirmar",
|
|
870
|
+
cancelLabel = "Cancelar",
|
|
871
|
+
loading = false,
|
|
872
|
+
variant = "default",
|
|
873
|
+
blurBackdrop = true,
|
|
874
|
+
backdropClassName
|
|
1025
875
|
}) {
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
onChange(value.filter((v) => v !== optionValue));
|
|
1047
|
-
};
|
|
1048
|
-
const trigger = /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
1049
|
-
"div",
|
|
1050
|
-
{
|
|
1051
|
-
id,
|
|
1052
|
-
role: "combobox",
|
|
1053
|
-
tabIndex: disabled ? -1 : 0,
|
|
1054
|
-
"aria-expanded": open,
|
|
1055
|
-
"aria-invalid": ariaInvalid,
|
|
1056
|
-
"aria-describedby": ariaDescribedby,
|
|
1057
|
-
"aria-disabled": disabled,
|
|
1058
|
-
onKeyDown: (event) => {
|
|
1059
|
-
if (disabled) return;
|
|
1060
|
-
if (event.key === "Enter" || event.key === " " || event.key === "ArrowDown") {
|
|
1061
|
-
event.preventDefault();
|
|
1062
|
-
setOpen(true);
|
|
1063
|
-
}
|
|
1064
|
-
},
|
|
1065
|
-
className: cn(
|
|
1066
|
-
"flex min-h-9 w-full cursor-pointer flex-wrap items-center gap-1 rounded-md border border-input bg-transparent px-3 py-1.5 text-sm shadow-sm transition-colors hover:border-ring/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring aria-disabled:pointer-events-none aria-disabled:opacity-50 aria-invalid:border-destructive aria-invalid:focus-visible:ring-destructive",
|
|
1067
|
-
className
|
|
1068
|
-
),
|
|
1069
|
-
children: [
|
|
1070
|
-
selected.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-muted-foreground", children: placeholder }) : selected.map((option) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
1071
|
-
"span",
|
|
1072
|
-
{
|
|
1073
|
-
className: "inline-flex items-center gap-1 rounded bg-secondary px-1.5 py-0.5 text-xs text-secondary-foreground",
|
|
1074
|
-
children: [
|
|
1075
|
-
option.label,
|
|
1076
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1077
|
-
"button",
|
|
1078
|
-
{
|
|
1079
|
-
type: "button",
|
|
1080
|
-
tabIndex: -1,
|
|
1081
|
-
"aria-label": `Remover ${option.label}`,
|
|
1082
|
-
onClick: (event) => {
|
|
1083
|
-
event.stopPropagation();
|
|
1084
|
-
removeValue(option.value);
|
|
1085
|
-
},
|
|
1086
|
-
onPointerDown: (event) => event.stopPropagation(),
|
|
1087
|
-
className: "rounded-sm opacity-60 transition-opacity hover:opacity-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
1088
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react5.X, { className: "h-3 w-3" })
|
|
1089
|
-
}
|
|
1090
|
-
)
|
|
1091
|
-
]
|
|
1092
|
-
},
|
|
1093
|
-
option.value
|
|
1094
|
-
)),
|
|
1095
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react5.ChevronsUpDown, { className: "ml-auto h-4 w-4 shrink-0 opacity-50" })
|
|
1096
|
-
]
|
|
1097
|
-
}
|
|
1098
|
-
);
|
|
1099
|
-
const command = /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
1100
|
-
import_cmdk2.Command,
|
|
1101
|
-
{
|
|
1102
|
-
shouldFilter: !isServer,
|
|
1103
|
-
className: "flex h-full w-full flex-col overflow-hidden",
|
|
1104
|
-
children: [
|
|
1105
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center border-b px-3", children: [
|
|
1106
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react5.Search, { className: "mr-2 h-4 w-4 shrink-0 opacity-50" }),
|
|
1107
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1108
|
-
import_cmdk2.Command.Input,
|
|
1109
|
-
{
|
|
1110
|
-
placeholder: searchPlaceholder,
|
|
1111
|
-
onValueChange: isServer ? onSearchChange : void 0,
|
|
1112
|
-
className: "flex h-11 w-full bg-transparent py-2 text-base outline-none placeholder:text-muted-foreground sm:h-9 sm:text-sm"
|
|
1113
|
-
}
|
|
1114
|
-
)
|
|
1115
|
-
] }),
|
|
1116
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
1117
|
-
import_cmdk2.Command.List,
|
|
876
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(AlertDialog.Root, { open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(AlertDialog.Portal, { children: [
|
|
877
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
878
|
+
AlertDialog.Overlay,
|
|
879
|
+
{
|
|
880
|
+
className: cn(
|
|
881
|
+
"fixed inset-0 z-50 bg-black/50 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
882
|
+
blurBackdrop && "backdrop-blur-sm",
|
|
883
|
+
backdropClassName
|
|
884
|
+
)
|
|
885
|
+
}
|
|
886
|
+
),
|
|
887
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(AlertDialog.Content, { className: "fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg", children: [
|
|
888
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-col space-y-2 text-center sm:text-left", children: [
|
|
889
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(AlertDialog.Title, { className: "text-lg font-semibold", children: title }),
|
|
890
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(AlertDialog.Description, { className: "text-sm text-muted-foreground", children: description })
|
|
891
|
+
] }),
|
|
892
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", children: [
|
|
893
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(AlertDialog.Cancel, { className: "inline-flex h-9 items-center justify-center rounded-md border border-input bg-background px-4 text-sm font-medium shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 cursor-pointer", children: cancelLabel }),
|
|
894
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
895
|
+
AlertDialog.Action,
|
|
1118
896
|
{
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
1124
|
-
import_cmdk2.Command.Item,
|
|
1125
|
-
{
|
|
1126
|
-
value: isServer ? option.value : option.label,
|
|
1127
|
-
disabled: option.disabled,
|
|
1128
|
-
onSelect: () => toggleValue(option.value),
|
|
1129
|
-
className: "relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-2.5 text-sm outline-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 sm:py-1.5",
|
|
1130
|
-
children: [
|
|
1131
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1132
|
-
import_lucide_react5.Check,
|
|
1133
|
-
{
|
|
1134
|
-
className: cn(
|
|
1135
|
-
"h-4 w-4 shrink-0",
|
|
1136
|
-
value.includes(option.value) ? "opacity-100" : "opacity-0"
|
|
1137
|
-
)
|
|
1138
|
-
}
|
|
1139
|
-
),
|
|
1140
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "truncate", children: option.label })
|
|
1141
|
-
]
|
|
1142
|
-
},
|
|
1143
|
-
option.value
|
|
1144
|
-
)),
|
|
1145
|
-
isServer && !loading && options.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "py-6 text-center text-sm text-muted-foreground", children: emptyMessage }),
|
|
1146
|
-
isServer && loading && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex items-center justify-center py-6", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react5.Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" }) }),
|
|
1147
|
-
isServer && hasMore && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { ref: sentinelRef, "aria-hidden": true, className: "h-1" })
|
|
1148
|
-
]
|
|
897
|
+
onClick: onConfirm,
|
|
898
|
+
disabled: loading,
|
|
899
|
+
className: `inline-flex h-9 items-center justify-center rounded-md px-4 text-sm font-medium shadow transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 cursor-pointer ${variant === "destructive" ? "bg-destructive text-destructive-foreground hover:bg-destructive/90" : "bg-primary text-primary-foreground hover:bg-primary/90"}`,
|
|
900
|
+
children: loading ? "Aguarde..." : confirmLabel
|
|
1149
901
|
}
|
|
1150
902
|
)
|
|
1151
|
-
]
|
|
1152
|
-
}
|
|
1153
|
-
);
|
|
1154
|
-
if (isDesktop) {
|
|
1155
|
-
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(PopoverPrimitive2.Root, { open, onOpenChange: setOpen, children: [
|
|
1156
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(PopoverPrimitive2.Trigger, { asChild: true, disabled, children: trigger }),
|
|
1157
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(PopoverPrimitive2.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
1158
|
-
PopoverPrimitive2.Content,
|
|
1159
|
-
{
|
|
1160
|
-
align: "start",
|
|
1161
|
-
sideOffset: 4,
|
|
1162
|
-
className: "pointer-events-auto z-50 overflow-hidden rounded-md border bg-popover p-0 text-popover-foreground shadow-md",
|
|
1163
|
-
style: { width: "var(--radix-popover-trigger-width)" },
|
|
1164
|
-
children: command
|
|
1165
|
-
}
|
|
1166
|
-
) })
|
|
1167
|
-
] });
|
|
1168
|
-
}
|
|
1169
|
-
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_vaul2.Drawer.Root, { open, onOpenChange: setOpen, children: [
|
|
1170
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_vaul2.Drawer.Trigger, { asChild: true, disabled, children: trigger }),
|
|
1171
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_vaul2.Drawer.Portal, { children: [
|
|
1172
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_vaul2.Drawer.Overlay, { className: "fixed inset-0 z-50 bg-black/80" }),
|
|
1173
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_vaul2.Drawer.Content, { className: "fixed inset-x-0 bottom-0 z-50 mt-24 flex max-h-[85vh] flex-col rounded-t-2xl border bg-popover text-popover-foreground outline-none", children: [
|
|
1174
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_vaul2.Drawer.Title, { className: "sr-only", children: placeholder }),
|
|
1175
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "mx-auto my-3 h-1.5 w-12 shrink-0 rounded-full bg-muted" }),
|
|
1176
|
-
command
|
|
1177
903
|
] })
|
|
1178
904
|
] })
|
|
1179
|
-
] });
|
|
905
|
+
] }) });
|
|
1180
906
|
}
|
|
1181
907
|
|
|
1182
|
-
// src/components/
|
|
1183
|
-
var
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
id,
|
|
1196
|
-
className,
|
|
1197
|
-
"aria-invalid": ariaInvalid,
|
|
1198
|
-
"aria-describedby": ariaDescribedby
|
|
908
|
+
// src/components/data-table-wrapper.tsx
|
|
909
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
910
|
+
function DataTableWrapper({
|
|
911
|
+
children,
|
|
912
|
+
isEmpty,
|
|
913
|
+
isLoading,
|
|
914
|
+
emptyIcon,
|
|
915
|
+
emptyTitle = "Nenhum registro encontrado",
|
|
916
|
+
emptyDescription,
|
|
917
|
+
page,
|
|
918
|
+
onPageChange,
|
|
919
|
+
hasNextPage = false,
|
|
920
|
+
hasPreviousPage = false
|
|
1199
921
|
}) {
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
}
|
|
1234
|
-
),
|
|
1235
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: cn("truncate", !color && "text-muted-foreground"), children: color || placeholder })
|
|
1236
|
-
] }),
|
|
1237
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "flex shrink-0 items-center gap-1", children: [
|
|
1238
|
-
showClear && // Not a <button> — nesting one inside the trigger button is
|
|
1239
|
-
// invalid HTML.
|
|
1240
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1241
|
-
"span",
|
|
1242
|
-
{
|
|
1243
|
-
role: "button",
|
|
1244
|
-
tabIndex: 0,
|
|
1245
|
-
"aria-label": "Limpar cor",
|
|
1246
|
-
onClick: clear,
|
|
1247
|
-
onKeyDown: (event) => {
|
|
1248
|
-
if (event.key === "Enter" || event.key === " ") clear(event);
|
|
1249
|
-
},
|
|
1250
|
-
className: "rounded p-0.5 text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
1251
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react6.X, { className: "h-3.5 w-3.5" })
|
|
1252
|
-
}
|
|
1253
|
-
),
|
|
1254
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react6.ChevronsUpDown, { className: "h-4 w-4 shrink-0 opacity-50" })
|
|
1255
|
-
] })
|
|
1256
|
-
]
|
|
1257
|
-
}
|
|
1258
|
-
) }),
|
|
1259
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(PopoverPrimitive3.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1260
|
-
PopoverPrimitive3.Content,
|
|
1261
|
-
{
|
|
1262
|
-
align: "start",
|
|
1263
|
-
sideOffset: 4,
|
|
1264
|
-
className: "z-50 w-56 rounded-md border bg-popover p-3 text-popover-foreground shadow-md",
|
|
1265
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "mh-color-picker flex flex-col gap-3", children: [
|
|
1266
|
-
alpha ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_colorful.HexAlphaColorPicker, { color, onChange }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_colorful.HexColorPicker, { color, onChange }),
|
|
1267
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
1268
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-sm text-muted-foreground", children: "#" }),
|
|
1269
|
-
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1270
|
-
import_react_colorful.HexColorInput,
|
|
1271
|
-
{
|
|
1272
|
-
color,
|
|
1273
|
-
onChange,
|
|
1274
|
-
prefixed: false,
|
|
1275
|
-
alpha,
|
|
1276
|
-
className: "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm uppercase shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
1277
|
-
}
|
|
1278
|
-
)
|
|
1279
|
-
] })
|
|
1280
|
-
] })
|
|
1281
|
-
}
|
|
1282
|
-
) })
|
|
922
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "space-y-4", children: [
|
|
923
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "overflow-x-auto rounded-md border", children }),
|
|
924
|
+
!isLoading && isEmpty && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex flex-col items-center justify-center py-16 text-center", children: [
|
|
925
|
+
emptyIcon && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mb-4 text-muted-foreground", children: emptyIcon }),
|
|
926
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { className: "text-lg font-semibold tracking-tight", children: emptyTitle }),
|
|
927
|
+
emptyDescription && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "mt-1 max-w-sm text-sm text-muted-foreground", children: emptyDescription })
|
|
928
|
+
] }),
|
|
929
|
+
page !== void 0 && onPageChange && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "flex items-center justify-end gap-4", children: [
|
|
930
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
931
|
+
"button",
|
|
932
|
+
{
|
|
933
|
+
type: "button",
|
|
934
|
+
onClick: () => onPageChange(page - 1),
|
|
935
|
+
disabled: !hasPreviousPage,
|
|
936
|
+
className: "inline-flex h-8 items-center justify-center rounded-md border border-input bg-background px-3 text-xs font-medium shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground cursor-pointer disabled:pointer-events-none disabled:opacity-50",
|
|
937
|
+
children: "Anterior"
|
|
938
|
+
}
|
|
939
|
+
),
|
|
940
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "text-sm text-muted-foreground", children: [
|
|
941
|
+
"P\xE1gina ",
|
|
942
|
+
page
|
|
943
|
+
] }),
|
|
944
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
945
|
+
"button",
|
|
946
|
+
{
|
|
947
|
+
type: "button",
|
|
948
|
+
onClick: () => onPageChange(page + 1),
|
|
949
|
+
disabled: !hasNextPage,
|
|
950
|
+
className: "inline-flex h-8 items-center justify-center rounded-md border border-input bg-background px-3 text-xs font-medium shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground cursor-pointer disabled:pointer-events-none disabled:opacity-50",
|
|
951
|
+
children: "Pr\xF3ximo"
|
|
952
|
+
}
|
|
953
|
+
)
|
|
954
|
+
] })
|
|
1283
955
|
] });
|
|
1284
956
|
}
|
|
1285
957
|
|
|
1286
958
|
// src/components/date-picker.tsx
|
|
1287
|
-
var
|
|
959
|
+
var PopoverPrimitive3 = __toESM(require("@radix-ui/react-popover"), 1);
|
|
1288
960
|
var import_mask = require("@react-input/mask");
|
|
1289
961
|
var import_date_fns = require("date-fns");
|
|
1290
962
|
var import_locale = require("date-fns/locale");
|
|
1291
|
-
var
|
|
1292
|
-
var
|
|
963
|
+
var import_lucide_react6 = require("lucide-react");
|
|
964
|
+
var React6 = __toESM(require("react"), 1);
|
|
1293
965
|
var import_react_day_picker = require("react-day-picker");
|
|
1294
966
|
var import_vaul3 = require("vaul");
|
|
1295
|
-
var
|
|
967
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1296
968
|
var DATE_MASK = "__/__/____";
|
|
1297
969
|
var TIME_MASK = "__:__";
|
|
1298
970
|
var MASK_REPLACEMENT = { _: /\d/ };
|
|
@@ -1334,15 +1006,18 @@ function toMatchers(minDate, maxDate, disabledDates) {
|
|
|
1334
1006
|
}
|
|
1335
1007
|
var triggerInputClass = "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 pr-10 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:focus-visible:ring-destructive";
|
|
1336
1008
|
var fieldInputClass = "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring";
|
|
1337
|
-
var
|
|
1009
|
+
var navButtonClass = "inline-flex size-(--cell-size) shrink-0 select-none items-center justify-center rounded-md p-0 transition-colors hover:bg-accent hover:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:opacity-50";
|
|
1338
1010
|
var calendarClassNames = {
|
|
1339
1011
|
months: "relative flex flex-col gap-4",
|
|
1340
1012
|
month: "flex w-full flex-col gap-4",
|
|
1341
1013
|
month_caption: "flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)",
|
|
1342
|
-
caption_label: "text-sm font-medium select-none",
|
|
1014
|
+
caption_label: "flex h-8 items-center gap-1 rounded-md pl-2 pr-1 text-sm font-medium select-none [&>svg]:size-3.5 [&>svg]:text-muted-foreground",
|
|
1015
|
+
dropdowns: "flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium",
|
|
1016
|
+
dropdown_root: "relative rounded-md border border-input shadow-xs has-focus:border-ring has-focus:ring-[3px] has-focus:ring-ring/50",
|
|
1017
|
+
dropdown: "absolute inset-0 bg-popover opacity-0",
|
|
1343
1018
|
nav: "absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1",
|
|
1344
|
-
button_previous:
|
|
1345
|
-
button_next:
|
|
1019
|
+
button_previous: navButtonClass,
|
|
1020
|
+
button_next: navButtonClass,
|
|
1346
1021
|
month_grid: "w-full border-collapse",
|
|
1347
1022
|
weekdays: "flex",
|
|
1348
1023
|
weekday: "flex-1 select-none rounded-md text-[0.8rem] font-normal text-muted-foreground",
|
|
@@ -1355,8 +1030,13 @@ var calendarClassNames = {
|
|
|
1355
1030
|
hidden: "invisible"
|
|
1356
1031
|
};
|
|
1357
1032
|
var calendarComponents = {
|
|
1358
|
-
Chevron: ({ orientation }) =>
|
|
1033
|
+
Chevron: ({ orientation }) => {
|
|
1034
|
+
if (orientation === "left") return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react6.ChevronLeft, { className: "size-4" });
|
|
1035
|
+
if (orientation === "right") return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react6.ChevronRight, { className: "size-4" });
|
|
1036
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react6.ChevronDown, { className: "size-4" });
|
|
1037
|
+
}
|
|
1359
1038
|
};
|
|
1039
|
+
var formatMonthDropdown = (date) => date.toLocaleString("pt-BR", { month: "short" });
|
|
1360
1040
|
function DatePickerImpl({
|
|
1361
1041
|
value,
|
|
1362
1042
|
onChange,
|
|
@@ -1372,15 +1052,17 @@ function DatePickerImpl({
|
|
|
1372
1052
|
"aria-describedby": ariaDescribedby
|
|
1373
1053
|
}) {
|
|
1374
1054
|
const isDesktop = useIsDesktop();
|
|
1375
|
-
const triggerRef =
|
|
1376
|
-
const [open, setOpenRaw] =
|
|
1377
|
-
const [focused, setFocused] =
|
|
1378
|
-
const [editText, setEditText] =
|
|
1379
|
-
const [pendingDate, setPendingDate] =
|
|
1380
|
-
const [pendingTime, setPendingTime] =
|
|
1055
|
+
const triggerRef = React6.useRef(null);
|
|
1056
|
+
const [open, setOpenRaw] = React6.useState(false);
|
|
1057
|
+
const [focused, setFocused] = React6.useState(false);
|
|
1058
|
+
const [editText, setEditText] = React6.useState("");
|
|
1059
|
+
const [pendingDate, setPendingDate] = React6.useState();
|
|
1060
|
+
const [pendingTime, setPendingTime] = React6.useState("");
|
|
1381
1061
|
const committedDate = withTime ? dateTimeToDate(value) : dateOnlyToDate(value);
|
|
1382
1062
|
const displayValue = displayFor(value, withTime);
|
|
1383
1063
|
const matchers = toMatchers(minDate, maxDate, disabledDates);
|
|
1064
|
+
const startMonth = dateOnlyToDate(minDate) ?? (0, import_date_fns.subYears)(/* @__PURE__ */ new Date(), 100);
|
|
1065
|
+
const endMonth = dateOnlyToDate(maxDate) ?? (0, import_date_fns.endOfYear)(/* @__PURE__ */ new Date());
|
|
1384
1066
|
const setOpen = (next) => {
|
|
1385
1067
|
setOpenRaw(next);
|
|
1386
1068
|
if (next) {
|
|
@@ -1436,8 +1118,8 @@ function DatePickerImpl({
|
|
|
1436
1118
|
}
|
|
1437
1119
|
};
|
|
1438
1120
|
const canApply = withTime && !!pendingDate && !!parseStrict(pendingTime, TIME_FORMAT);
|
|
1439
|
-
const trigger = /* @__PURE__ */ (0,
|
|
1440
|
-
/* @__PURE__ */ (0,
|
|
1121
|
+
const trigger = /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { ref: triggerRef, className: "relative", children: [
|
|
1122
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1441
1123
|
import_mask.InputMask,
|
|
1442
1124
|
{
|
|
1443
1125
|
id,
|
|
@@ -1457,7 +1139,7 @@ function DatePickerImpl({
|
|
|
1457
1139
|
className: cn(triggerInputClass, className)
|
|
1458
1140
|
}
|
|
1459
1141
|
),
|
|
1460
|
-
/* @__PURE__ */ (0,
|
|
1142
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1461
1143
|
"button",
|
|
1462
1144
|
{
|
|
1463
1145
|
type: "button",
|
|
@@ -1467,16 +1149,20 @@ function DatePickerImpl({
|
|
|
1467
1149
|
"aria-expanded": open,
|
|
1468
1150
|
onClick: () => setOpen(!open),
|
|
1469
1151
|
className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground transition-colors hover:text-foreground disabled:pointer-events-none disabled:opacity-50",
|
|
1470
|
-
children: withTime ? /* @__PURE__ */ (0,
|
|
1152
|
+
children: withTime ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react6.Clock, { className: "h-4 w-4" }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react6.CalendarIcon, { className: "h-4 w-4" })
|
|
1471
1153
|
}
|
|
1472
1154
|
)
|
|
1473
1155
|
] });
|
|
1474
|
-
const content = /* @__PURE__ */ (0,
|
|
1475
|
-
/* @__PURE__ */ (0,
|
|
1156
|
+
const content = /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: withTime ? "p-3" : "", children: [
|
|
1157
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1476
1158
|
import_react_day_picker.DayPicker,
|
|
1477
1159
|
{
|
|
1478
1160
|
mode: "single",
|
|
1479
1161
|
locale: import_locale.ptBR,
|
|
1162
|
+
captionLayout: "dropdown",
|
|
1163
|
+
formatters: { formatMonthDropdown },
|
|
1164
|
+
startMonth,
|
|
1165
|
+
endMonth,
|
|
1480
1166
|
selected: withTime ? pendingDate : committedDate,
|
|
1481
1167
|
defaultMonth: (withTime ? pendingDate : committedDate) ?? /* @__PURE__ */ new Date(),
|
|
1482
1168
|
onSelect: (date) => date && handleCalendarSelect(date),
|
|
@@ -1486,10 +1172,10 @@ function DatePickerImpl({
|
|
|
1486
1172
|
components: calendarComponents
|
|
1487
1173
|
}
|
|
1488
1174
|
),
|
|
1489
|
-
withTime && /* @__PURE__ */ (0,
|
|
1490
|
-
/* @__PURE__ */ (0,
|
|
1491
|
-
/* @__PURE__ */ (0,
|
|
1492
|
-
/* @__PURE__ */ (0,
|
|
1175
|
+
withTime && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
|
|
1176
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "mt-2 flex items-center gap-2 border-t pt-3", children: [
|
|
1177
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-sm text-muted-foreground", children: "Hor\xE1rio" }),
|
|
1178
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1493
1179
|
import_mask.InputMask,
|
|
1494
1180
|
{
|
|
1495
1181
|
mask: TIME_MASK,
|
|
@@ -1502,7 +1188,7 @@ function DatePickerImpl({
|
|
|
1502
1188
|
}
|
|
1503
1189
|
)
|
|
1504
1190
|
] }),
|
|
1505
|
-
/* @__PURE__ */ (0,
|
|
1191
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1506
1192
|
"button",
|
|
1507
1193
|
{
|
|
1508
1194
|
type: "button",
|
|
@@ -1515,10 +1201,10 @@ function DatePickerImpl({
|
|
|
1515
1201
|
] })
|
|
1516
1202
|
] });
|
|
1517
1203
|
if (isDesktop) {
|
|
1518
|
-
return /* @__PURE__ */ (0,
|
|
1519
|
-
/* @__PURE__ */ (0,
|
|
1520
|
-
/* @__PURE__ */ (0,
|
|
1521
|
-
|
|
1204
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(PopoverPrimitive3.Root, { open, onOpenChange: setOpen, children: [
|
|
1205
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PopoverPrimitive3.Anchor, { asChild: true, children: trigger }),
|
|
1206
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(PopoverPrimitive3.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1207
|
+
PopoverPrimitive3.Content,
|
|
1522
1208
|
{
|
|
1523
1209
|
align: "start",
|
|
1524
1210
|
sideOffset: 4,
|
|
@@ -1532,11 +1218,11 @@ function DatePickerImpl({
|
|
|
1532
1218
|
) })
|
|
1533
1219
|
] });
|
|
1534
1220
|
}
|
|
1535
|
-
return /* @__PURE__ */ (0,
|
|
1221
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_vaul3.Drawer.Root, { open, onOpenChange: setOpen, children: [
|
|
1536
1222
|
trigger,
|
|
1537
|
-
/* @__PURE__ */ (0,
|
|
1538
|
-
/* @__PURE__ */ (0,
|
|
1539
|
-
/* @__PURE__ */ (0,
|
|
1223
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_vaul3.Drawer.Portal, { children: [
|
|
1224
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_vaul3.Drawer.Overlay, { className: "fixed inset-0 z-50 bg-black/80" }),
|
|
1225
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1540
1226
|
import_vaul3.Drawer.Content,
|
|
1541
1227
|
{
|
|
1542
1228
|
onOpenAutoFocus: (event) => event.preventDefault(),
|
|
@@ -1545,9 +1231,9 @@ function DatePickerImpl({
|
|
|
1545
1231
|
},
|
|
1546
1232
|
className: "fixed inset-x-0 bottom-0 z-50 mt-24 flex max-h-[85vh] flex-col rounded-t-2xl border bg-popover text-popover-foreground outline-none",
|
|
1547
1233
|
children: [
|
|
1548
|
-
/* @__PURE__ */ (0,
|
|
1549
|
-
/* @__PURE__ */ (0,
|
|
1550
|
-
/* @__PURE__ */ (0,
|
|
1234
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_vaul3.Drawer.Title, { className: "sr-only", children: withTime ? "Selecione a data e o hor\xE1rio" : "Selecione a data" }),
|
|
1235
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "mx-auto my-3 h-1.5 w-12 shrink-0 rounded-full bg-muted" }),
|
|
1236
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "flex justify-center overflow-y-auto pb-4", children: content })
|
|
1551
1237
|
]
|
|
1552
1238
|
}
|
|
1553
1239
|
)
|
|
@@ -1555,105 +1241,271 @@ function DatePickerImpl({
|
|
|
1555
1241
|
] });
|
|
1556
1242
|
}
|
|
1557
1243
|
function DatePicker(props) {
|
|
1558
|
-
return /* @__PURE__ */ (0,
|
|
1244
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DatePickerImpl, { ...props });
|
|
1559
1245
|
}
|
|
1560
1246
|
function DateTimePicker(props) {
|
|
1561
|
-
return /* @__PURE__ */ (0,
|
|
1247
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(DatePickerImpl, { ...props, withTime: true });
|
|
1562
1248
|
}
|
|
1563
1249
|
|
|
1564
|
-
// src/components/
|
|
1565
|
-
var
|
|
1566
|
-
function
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
] }),
|
|
1573
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "mt-2 h-7 w-16 animate-pulse rounded bg-muted" }),
|
|
1574
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "mt-1 h-4 w-20 animate-pulse rounded bg-muted" })
|
|
1575
|
-
] });
|
|
1576
|
-
}
|
|
1577
|
-
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "rounded-lg border bg-card p-6 shadow-sm", children: [
|
|
1578
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center justify-between pb-2", children: [
|
|
1579
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-sm font-medium text-muted-foreground", children: label }),
|
|
1580
|
-
icon && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-muted-foreground", children: icon })
|
|
1581
|
-
] }),
|
|
1582
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "text-2xl font-bold", children: value }),
|
|
1583
|
-
detail && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-xs text-muted-foreground", children: detail })
|
|
1250
|
+
// src/components/empty-state.tsx
|
|
1251
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1252
|
+
function EmptyState({ icon, title, description, action, className }) {
|
|
1253
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: `flex flex-col items-center justify-center py-16 text-center ${className ?? ""}`, children: [
|
|
1254
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "mb-4 text-muted-foreground", children: icon }),
|
|
1255
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h3", { className: "text-lg font-semibold tracking-tight", children: title }),
|
|
1256
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "mt-1 max-w-sm text-sm text-muted-foreground", children: description }),
|
|
1257
|
+
action && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "mt-4", children: action })
|
|
1584
1258
|
] });
|
|
1585
1259
|
}
|
|
1586
1260
|
|
|
1587
|
-
// src/components/
|
|
1588
|
-
var
|
|
1589
|
-
|
|
1261
|
+
// src/components/filter-toolbar.tsx
|
|
1262
|
+
var PopoverPrimitive4 = __toESM(require("@radix-ui/react-popover"), 1);
|
|
1263
|
+
var import_lucide_react7 = require("lucide-react");
|
|
1264
|
+
var React7 = __toESM(require("react"), 1);
|
|
1265
|
+
var import_vaul4 = require("vaul");
|
|
1266
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1267
|
+
function FilterToolbar({
|
|
1590
1268
|
children,
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
emptyDescription,
|
|
1596
|
-
page,
|
|
1597
|
-
onPageChange,
|
|
1598
|
-
hasNextPage = false,
|
|
1599
|
-
hasPreviousPage = false
|
|
1269
|
+
isFilterActive = false,
|
|
1270
|
+
onClear,
|
|
1271
|
+
clearLabel = "Limpar filtros",
|
|
1272
|
+
className
|
|
1600
1273
|
}) {
|
|
1601
|
-
return /* @__PURE__ */ (0,
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1274
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: cn("mb-6 flex flex-wrap items-center gap-2", className), children: [
|
|
1275
|
+
children,
|
|
1276
|
+
isFilterActive && onClear && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
1277
|
+
"button",
|
|
1278
|
+
{
|
|
1279
|
+
type: "button",
|
|
1280
|
+
onClick: onClear,
|
|
1281
|
+
className: "inline-flex h-9 shrink-0 items-center gap-1.5 rounded-md px-2.5 text-sm text-muted-foreground transition-colors hover:text-foreground",
|
|
1282
|
+
children: [
|
|
1283
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.X, { className: "h-4 w-4" }),
|
|
1284
|
+
clearLabel
|
|
1285
|
+
]
|
|
1286
|
+
}
|
|
1287
|
+
)
|
|
1288
|
+
] });
|
|
1289
|
+
}
|
|
1290
|
+
function FilterPopover({
|
|
1291
|
+
label,
|
|
1292
|
+
icon: Icon,
|
|
1293
|
+
active = false,
|
|
1294
|
+
badge,
|
|
1295
|
+
contentClassName,
|
|
1296
|
+
align = "start",
|
|
1297
|
+
title,
|
|
1298
|
+
children
|
|
1299
|
+
}) {
|
|
1300
|
+
const [open, setOpen] = React7.useState(false);
|
|
1301
|
+
const isDesktop = useIsDesktop();
|
|
1302
|
+
const close = React7.useCallback(() => setOpen(false), []);
|
|
1303
|
+
const content = typeof children === "function" ? children({ close }) : children;
|
|
1304
|
+
const trigger = /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
1305
|
+
"button",
|
|
1306
|
+
{
|
|
1307
|
+
type: "button",
|
|
1308
|
+
"aria-expanded": open,
|
|
1309
|
+
className: cn(
|
|
1310
|
+
"inline-flex h-9 shrink-0 cursor-pointer items-center gap-1.5 rounded-md border border-input bg-transparent px-3 text-sm shadow-sm transition-colors hover:border-ring/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
1311
|
+
active ? "border-ring/60 text-foreground" : "text-muted-foreground"
|
|
1618
1312
|
),
|
|
1619
|
-
|
|
1620
|
-
"
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1313
|
+
children: [
|
|
1314
|
+
Icon && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Icon, { className: "h-4 w-4 shrink-0 opacity-70" }),
|
|
1315
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "truncate", children: label }),
|
|
1316
|
+
active && badge != null && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "inline-flex h-4 min-w-4 items-center justify-center rounded-full bg-primary px-1 text-[10px] font-medium leading-none text-primary-foreground", children: badge }),
|
|
1317
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react7.ChevronDown, { className: "h-4 w-4 shrink-0 opacity-50" })
|
|
1318
|
+
]
|
|
1319
|
+
}
|
|
1320
|
+
);
|
|
1321
|
+
if (isDesktop) {
|
|
1322
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(PopoverPrimitive4.Root, { open, onOpenChange: setOpen, children: [
|
|
1323
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PopoverPrimitive4.Trigger, { asChild: true, children: trigger }),
|
|
1324
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(PopoverPrimitive4.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1325
|
+
PopoverPrimitive4.Content,
|
|
1625
1326
|
{
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1327
|
+
align,
|
|
1328
|
+
sideOffset: 4,
|
|
1329
|
+
onInteractOutside: (event) => {
|
|
1330
|
+
const target = event.target;
|
|
1331
|
+
if (target?.closest("[data-radix-popper-content-wrapper]")) {
|
|
1332
|
+
event.preventDefault();
|
|
1333
|
+
}
|
|
1334
|
+
},
|
|
1335
|
+
className: cn(
|
|
1336
|
+
"pointer-events-auto z-50 w-60 overflow-hidden rounded-md border bg-popover p-0 text-popover-foreground shadow-md",
|
|
1337
|
+
contentClassName
|
|
1338
|
+
),
|
|
1339
|
+
children: content
|
|
1631
1340
|
}
|
|
1632
|
-
)
|
|
1341
|
+
) })
|
|
1342
|
+
] });
|
|
1343
|
+
}
|
|
1344
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_vaul4.Drawer.Root, { open, onOpenChange: setOpen, children: [
|
|
1345
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_vaul4.Drawer.Trigger, { asChild: true, children: trigger }),
|
|
1346
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_vaul4.Drawer.Portal, { children: [
|
|
1347
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_vaul4.Drawer.Overlay, { className: "fixed inset-0 z-50 bg-black/80" }),
|
|
1348
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_vaul4.Drawer.Content, { className: "fixed inset-x-0 bottom-0 z-50 mt-24 flex max-h-[85vh] flex-col rounded-t-2xl border bg-popover text-popover-foreground outline-none", children: [
|
|
1349
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_vaul4.Drawer.Title, { className: "sr-only", children: title ?? label }),
|
|
1350
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "mx-auto my-3 h-1.5 w-12 shrink-0 rounded-full bg-muted" }),
|
|
1351
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "overflow-y-auto p-2", children: content })
|
|
1352
|
+
] })
|
|
1633
1353
|
] })
|
|
1634
1354
|
] });
|
|
1635
1355
|
}
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
renderCard,
|
|
1644
|
-
keyExtractor,
|
|
1645
|
-
isLoading = false,
|
|
1646
|
-
loadingCount = 5,
|
|
1647
|
-
className
|
|
1356
|
+
function FilterOptionList({
|
|
1357
|
+
options,
|
|
1358
|
+
value,
|
|
1359
|
+
onChange,
|
|
1360
|
+
multiple = false,
|
|
1361
|
+
clearable = false,
|
|
1362
|
+
clearLabel = "Limpar"
|
|
1648
1363
|
}) {
|
|
1649
|
-
const
|
|
1650
|
-
const
|
|
1651
|
-
const
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1364
|
+
const selected = Array.isArray(value) ? value : value ? [value] : [];
|
|
1365
|
+
const hasSelection = selected.length > 0;
|
|
1366
|
+
const toggle = (optionValue) => {
|
|
1367
|
+
if (!multiple) {
|
|
1368
|
+
onChange(optionValue);
|
|
1369
|
+
return;
|
|
1370
|
+
}
|
|
1371
|
+
onChange(
|
|
1372
|
+
selected.includes(optionValue) ? selected.filter((v) => v !== optionValue) : [...selected, optionValue]
|
|
1373
|
+
);
|
|
1655
1374
|
};
|
|
1656
|
-
|
|
1375
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col p-1", children: [
|
|
1376
|
+
options.map((option) => {
|
|
1377
|
+
const isChecked = selected.includes(option.value);
|
|
1378
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
1379
|
+
"button",
|
|
1380
|
+
{
|
|
1381
|
+
type: "button",
|
|
1382
|
+
onClick: () => toggle(option.value),
|
|
1383
|
+
className: "flex cursor-pointer items-center gap-2 rounded-sm px-2 py-1.5 text-left text-sm transition-colors hover:bg-accent hover:text-accent-foreground",
|
|
1384
|
+
children: [
|
|
1385
|
+
option.dotClassName && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1386
|
+
"span",
|
|
1387
|
+
{
|
|
1388
|
+
className: cn(
|
|
1389
|
+
"h-2 w-2 shrink-0 rounded-full",
|
|
1390
|
+
option.dotClassName
|
|
1391
|
+
)
|
|
1392
|
+
}
|
|
1393
|
+
),
|
|
1394
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "flex-1 truncate", children: option.label }),
|
|
1395
|
+
isChecked && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "h-1.5 w-1.5 shrink-0 rounded-full bg-primary" })
|
|
1396
|
+
]
|
|
1397
|
+
},
|
|
1398
|
+
option.value
|
|
1399
|
+
);
|
|
1400
|
+
}),
|
|
1401
|
+
clearable && hasSelection && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1402
|
+
"button",
|
|
1403
|
+
{
|
|
1404
|
+
type: "button",
|
|
1405
|
+
onClick: () => onChange(multiple ? [] : ""),
|
|
1406
|
+
className: "mt-1 border-t px-2 pt-1.5 pb-0.5 text-center text-xs text-muted-foreground transition-colors hover:text-foreground",
|
|
1407
|
+
children: clearLabel
|
|
1408
|
+
}
|
|
1409
|
+
)
|
|
1410
|
+
] });
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
// src/components/form-dialog.tsx
|
|
1414
|
+
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1415
|
+
function FormDialogLayout({
|
|
1416
|
+
title,
|
|
1417
|
+
children,
|
|
1418
|
+
onSubmit,
|
|
1419
|
+
submitLabel = "Salvar",
|
|
1420
|
+
cancelLabel = "Cancelar",
|
|
1421
|
+
onCancel,
|
|
1422
|
+
isSubmitting = false,
|
|
1423
|
+
isDisabled = false
|
|
1424
|
+
}) {
|
|
1425
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("form", { onSubmit, children: [
|
|
1426
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "flex flex-col space-y-1.5 text-center sm:text-left", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h2", { className: "text-lg font-semibold leading-none tracking-tight", children: title }) }),
|
|
1427
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "space-y-4 py-4", children }),
|
|
1428
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", children: [
|
|
1429
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1430
|
+
"button",
|
|
1431
|
+
{
|
|
1432
|
+
type: "button",
|
|
1433
|
+
onClick: onCancel,
|
|
1434
|
+
className: "inline-flex h-9 items-center justify-center rounded-md border border-input bg-background px-4 text-sm font-medium shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground cursor-pointer disabled:pointer-events-none disabled:opacity-50",
|
|
1435
|
+
children: cancelLabel
|
|
1436
|
+
}
|
|
1437
|
+
),
|
|
1438
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1439
|
+
"button",
|
|
1440
|
+
{
|
|
1441
|
+
type: "submit",
|
|
1442
|
+
disabled: isSubmitting || isDisabled,
|
|
1443
|
+
className: "inline-flex h-9 items-center justify-center rounded-md bg-primary px-4 text-sm font-medium text-primary-foreground shadow transition-colors hover:bg-primary/90 cursor-pointer disabled:pointer-events-none disabled:opacity-50",
|
|
1444
|
+
children: isSubmitting ? "Salvando..." : submitLabel
|
|
1445
|
+
}
|
|
1446
|
+
)
|
|
1447
|
+
] })
|
|
1448
|
+
] });
|
|
1449
|
+
}
|
|
1450
|
+
function FormDialog({ onSubmit, ...rest }) {
|
|
1451
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1452
|
+
BaseDialog,
|
|
1453
|
+
{
|
|
1454
|
+
...rest,
|
|
1455
|
+
contentWrapper: onSubmit ? (content) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("form", { onSubmit, className: "flex min-h-0 flex-1 flex-col", children: content }) : void 0
|
|
1456
|
+
}
|
|
1457
|
+
);
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
// src/components/form-field.tsx
|
|
1461
|
+
var import_react4 = require("react");
|
|
1462
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
1463
|
+
function FormField({ label, htmlFor, error, required, children, className }) {
|
|
1464
|
+
const errorId = (0, import_react4.useId)();
|
|
1465
|
+
const field = error && (0, import_react4.isValidElement)(children) ? (0, import_react4.cloneElement)(children, {
|
|
1466
|
+
"aria-invalid": true,
|
|
1467
|
+
"aria-describedby": [
|
|
1468
|
+
children.props["aria-describedby"],
|
|
1469
|
+
errorId
|
|
1470
|
+
].filter(Boolean).join(" ")
|
|
1471
|
+
}) : children;
|
|
1472
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: `space-y-2 ${className ?? ""}`, children: [
|
|
1473
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
1474
|
+
"label",
|
|
1475
|
+
{
|
|
1476
|
+
htmlFor,
|
|
1477
|
+
className: "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
|
|
1478
|
+
children: [
|
|
1479
|
+
label,
|
|
1480
|
+
required && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "ml-1 text-destructive", children: "*" })
|
|
1481
|
+
]
|
|
1482
|
+
}
|
|
1483
|
+
),
|
|
1484
|
+
field,
|
|
1485
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { id: errorId, className: "text-sm text-destructive", children: error })
|
|
1486
|
+
] });
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
// src/components/mobile-card-list.tsx
|
|
1490
|
+
var import_react5 = require("react");
|
|
1491
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1492
|
+
var SCROLL_THRESHOLD = 8;
|
|
1493
|
+
function MobileCardList({
|
|
1494
|
+
data,
|
|
1495
|
+
renderCard,
|
|
1496
|
+
keyExtractor,
|
|
1497
|
+
isLoading = false,
|
|
1498
|
+
loadingCount = 5,
|
|
1499
|
+
className
|
|
1500
|
+
}) {
|
|
1501
|
+
const start = (0, import_react5.useRef)(null);
|
|
1502
|
+
const scrolled = (0, import_react5.useRef)(false);
|
|
1503
|
+
const onTouchStart = (e) => {
|
|
1504
|
+
const t = e.touches[0];
|
|
1505
|
+
start.current = { x: t.clientX, y: t.clientY };
|
|
1506
|
+
scrolled.current = false;
|
|
1507
|
+
};
|
|
1508
|
+
const onTouchMove = (e) => {
|
|
1657
1509
|
if (!start.current) return;
|
|
1658
1510
|
const t = e.touches[0];
|
|
1659
1511
|
if (Math.abs(t.clientX - start.current.x) > SCROLL_THRESHOLD || Math.abs(t.clientY - start.current.y) > SCROLL_THRESHOLD) {
|
|
@@ -1667,26 +1519,26 @@ function MobileCardList({
|
|
|
1667
1519
|
}
|
|
1668
1520
|
};
|
|
1669
1521
|
if (isLoading) {
|
|
1670
|
-
return /* @__PURE__ */ (0,
|
|
1671
|
-
/* @__PURE__ */ (0,
|
|
1672
|
-
/* @__PURE__ */ (0,
|
|
1673
|
-
/* @__PURE__ */ (0,
|
|
1522
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: `space-y-3 ${className ?? ""}`, children: Array.from({ length: loadingCount }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "rounded-xl border p-4", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "space-y-3", children: [
|
|
1523
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex justify-between", children: [
|
|
1524
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "h-5 w-32 animate-pulse rounded bg-muted" }),
|
|
1525
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "h-5 w-16 animate-pulse rounded bg-muted" })
|
|
1674
1526
|
] }),
|
|
1675
|
-
/* @__PURE__ */ (0,
|
|
1676
|
-
/* @__PURE__ */ (0,
|
|
1677
|
-
/* @__PURE__ */ (0,
|
|
1678
|
-
/* @__PURE__ */ (0,
|
|
1527
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "h-4 w-48 animate-pulse rounded bg-muted" }),
|
|
1528
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex justify-between", children: [
|
|
1529
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "h-4 w-24 animate-pulse rounded bg-muted" }),
|
|
1530
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "h-4 w-20 animate-pulse rounded bg-muted" })
|
|
1679
1531
|
] })
|
|
1680
1532
|
] }) }, i)) });
|
|
1681
1533
|
}
|
|
1682
|
-
return /* @__PURE__ */ (0,
|
|
1534
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1683
1535
|
"div",
|
|
1684
1536
|
{
|
|
1685
1537
|
className: `space-y-3 ${className ?? ""}`,
|
|
1686
1538
|
onTouchStart,
|
|
1687
1539
|
onTouchMove,
|
|
1688
1540
|
onClickCapture,
|
|
1689
|
-
children: data.map((item, index) => /* @__PURE__ */ (0,
|
|
1541
|
+
children: data.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1690
1542
|
"div",
|
|
1691
1543
|
{
|
|
1692
1544
|
className: "rounded-xl border p-4 transition-all duration-150 hover:border-foreground/20 active:scale-[0.99]",
|
|
@@ -1698,385 +1550,511 @@ function MobileCardList({
|
|
|
1698
1550
|
);
|
|
1699
1551
|
}
|
|
1700
1552
|
|
|
1701
|
-
// src/components/
|
|
1702
|
-
var
|
|
1703
|
-
|
|
1704
|
-
table,
|
|
1705
|
-
cards,
|
|
1706
|
-
isEmpty,
|
|
1707
|
-
isLoading,
|
|
1708
|
-
emptyIcon,
|
|
1709
|
-
emptyTitle = "Nenhum registro encontrado",
|
|
1710
|
-
emptyDescription,
|
|
1711
|
-
pagination
|
|
1712
|
-
}) {
|
|
1713
|
-
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "space-y-4", children: [
|
|
1714
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "hidden overflow-x-auto rounded-md border md:block", children: table }),
|
|
1715
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "md:hidden", children: cards }),
|
|
1716
|
-
!isLoading && isEmpty && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col items-center justify-center py-16 text-center", children: [
|
|
1717
|
-
emptyIcon && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "mb-4 text-muted-foreground", children: emptyIcon }),
|
|
1718
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { className: "text-lg font-semibold tracking-tight", children: emptyTitle }),
|
|
1719
|
-
emptyDescription && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "mt-1 max-w-sm text-sm text-muted-foreground", children: emptyDescription })
|
|
1720
|
-
] }),
|
|
1721
|
-
pagination
|
|
1722
|
-
] });
|
|
1723
|
-
}
|
|
1553
|
+
// src/components/mode-toggle.tsx
|
|
1554
|
+
var DropdownMenu2 = __toESM(require("@radix-ui/react-dropdown-menu"), 1);
|
|
1555
|
+
var import_lucide_react8 = require("lucide-react");
|
|
1724
1556
|
|
|
1725
|
-
// src/components/
|
|
1726
|
-
var
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
error: "group-[.toaster]:!bg-background group-[.toaster]:!text-foreground group-[.toaster]:!border-destructive/40"
|
|
1743
|
-
}
|
|
1744
|
-
},
|
|
1745
|
-
...props
|
|
1746
|
-
}
|
|
1557
|
+
// src/components/theme-provider.tsx
|
|
1558
|
+
var import_react6 = require("react");
|
|
1559
|
+
|
|
1560
|
+
// src/lib/company-theme.ts
|
|
1561
|
+
var VAR_MAP = {
|
|
1562
|
+
primary: "--color-primary",
|
|
1563
|
+
primaryForeground: "--color-primary-foreground",
|
|
1564
|
+
secondary: "--color-secondary",
|
|
1565
|
+
secondaryForeground: "--color-secondary-foreground",
|
|
1566
|
+
accent: "--color-accent",
|
|
1567
|
+
accentForeground: "--color-accent-foreground",
|
|
1568
|
+
ring: "--color-ring"
|
|
1569
|
+
};
|
|
1570
|
+
function definedTokens(tokens) {
|
|
1571
|
+
if (!tokens) return {};
|
|
1572
|
+
return Object.fromEntries(
|
|
1573
|
+
Object.entries(tokens).filter(([, value]) => value != null)
|
|
1747
1574
|
);
|
|
1748
1575
|
}
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
// src/components/types.tsx
|
|
1758
|
-
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
1759
|
-
var defaultRenderLink = ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("a", { ...props, children });
|
|
1760
|
-
|
|
1761
|
-
// src/components/sidebar-nav.tsx
|
|
1762
|
-
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
1763
|
-
function defaultIsActive(item, activePath) {
|
|
1764
|
-
if (item.href === "/") return activePath === "/";
|
|
1765
|
-
return activePath === item.href || activePath.startsWith(item.href + "/");
|
|
1576
|
+
function applyCompanyTheme(root, companyTheme, mode) {
|
|
1577
|
+
const tokens = companyTheme ? mode === "dark" ? { ...companyTheme.light, ...definedTokens(companyTheme.dark) } : companyTheme.light : {};
|
|
1578
|
+
for (const key of Object.keys(VAR_MAP)) {
|
|
1579
|
+
const value = tokens[key];
|
|
1580
|
+
if (value) root.style.setProperty(VAR_MAP[key], value);
|
|
1581
|
+
else root.style.removeProperty(VAR_MAP[key]);
|
|
1582
|
+
}
|
|
1766
1583
|
}
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1584
|
+
|
|
1585
|
+
// src/components/theme-provider.tsx
|
|
1586
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
1587
|
+
var initialState = {
|
|
1588
|
+
theme: "system",
|
|
1589
|
+
setTheme: () => null
|
|
1590
|
+
};
|
|
1591
|
+
var ThemeProviderContext = (0, import_react6.createContext)(initialState);
|
|
1592
|
+
function ThemeProvider({
|
|
1593
|
+
children,
|
|
1594
|
+
defaultTheme = "system",
|
|
1595
|
+
storageKey = "ui-theme",
|
|
1596
|
+
companyTheme,
|
|
1597
|
+
...props
|
|
1775
1598
|
}) {
|
|
1776
|
-
const
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
)
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1599
|
+
const [theme, setTheme] = (0, import_react6.useState)(
|
|
1600
|
+
() => localStorage.getItem(storageKey) || defaultTheme
|
|
1601
|
+
);
|
|
1602
|
+
(0, import_react6.useEffect)(() => {
|
|
1603
|
+
const root = window.document.documentElement;
|
|
1604
|
+
const applyResolved = (resolved) => {
|
|
1605
|
+
root.classList.remove("light", "dark");
|
|
1606
|
+
root.classList.add(resolved);
|
|
1607
|
+
applyCompanyTheme(root, companyTheme, resolved);
|
|
1608
|
+
};
|
|
1609
|
+
if (theme === "system") {
|
|
1610
|
+
const mql = window.matchMedia("(prefers-color-scheme: dark)");
|
|
1611
|
+
applyResolved(mql.matches ? "dark" : "light");
|
|
1612
|
+
const onChange = (e) => applyResolved(e.matches ? "dark" : "light");
|
|
1613
|
+
mql.addEventListener("change", onChange);
|
|
1614
|
+
return () => mql.removeEventListener("change", onChange);
|
|
1615
|
+
}
|
|
1616
|
+
applyResolved(theme);
|
|
1617
|
+
}, [theme, companyTheme]);
|
|
1618
|
+
const value = {
|
|
1619
|
+
theme,
|
|
1620
|
+
setTheme: (theme2) => {
|
|
1621
|
+
localStorage.setItem(storageKey, theme2);
|
|
1622
|
+
setTheme(theme2);
|
|
1623
|
+
}
|
|
1624
|
+
};
|
|
1625
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ThemeProviderContext.Provider, { ...props, value, children });
|
|
1626
|
+
}
|
|
1627
|
+
function useTheme() {
|
|
1628
|
+
const context = (0, import_react6.useContext)(ThemeProviderContext);
|
|
1629
|
+
if (context === void 0) {
|
|
1630
|
+
throw new Error("useTheme must be used within a ThemeProvider");
|
|
1631
|
+
}
|
|
1632
|
+
return context;
|
|
1796
1633
|
}
|
|
1797
1634
|
|
|
1798
|
-
// src/components/
|
|
1799
|
-
var
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1635
|
+
// src/components/mode-toggle.tsx
|
|
1636
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
1637
|
+
function ModeToggle() {
|
|
1638
|
+
const { setTheme } = useTheme();
|
|
1639
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(DropdownMenu2.Root, { children: [
|
|
1640
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DropdownMenu2.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
1641
|
+
"button",
|
|
1642
|
+
{
|
|
1643
|
+
type: "button",
|
|
1644
|
+
className: "relative inline-flex h-9 w-9 items-center justify-center rounded-md border border-input bg-background text-sm font-medium shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
1645
|
+
"aria-label": "Alternar tema",
|
|
1646
|
+
children: [
|
|
1647
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.Sun, { className: "h-4 w-4 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" }),
|
|
1648
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.Moon, { className: "absolute inset-0 m-auto h-4 w-4 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" })
|
|
1649
|
+
]
|
|
1650
|
+
}
|
|
1651
|
+
) }),
|
|
1652
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(DropdownMenu2.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
1653
|
+
DropdownMenu2.Content,
|
|
1654
|
+
{
|
|
1655
|
+
align: "end",
|
|
1656
|
+
className: "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95",
|
|
1657
|
+
children: [
|
|
1658
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
1659
|
+
DropdownMenu2.Item,
|
|
1660
|
+
{
|
|
1661
|
+
className: "flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent focus:bg-accent",
|
|
1662
|
+
onClick: () => setTheme("light"),
|
|
1663
|
+
children: [
|
|
1664
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.Sun, { className: "h-4 w-4" }),
|
|
1665
|
+
" Claro"
|
|
1666
|
+
]
|
|
1667
|
+
}
|
|
1668
|
+
),
|
|
1669
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
1670
|
+
DropdownMenu2.Item,
|
|
1671
|
+
{
|
|
1672
|
+
className: "flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent focus:bg-accent",
|
|
1673
|
+
onClick: () => setTheme("dark"),
|
|
1674
|
+
children: [
|
|
1675
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.Moon, { className: "h-4 w-4" }),
|
|
1676
|
+
" Escuro"
|
|
1677
|
+
]
|
|
1678
|
+
}
|
|
1679
|
+
),
|
|
1680
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
1681
|
+
DropdownMenu2.Item,
|
|
1682
|
+
{
|
|
1683
|
+
className: "flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent focus:bg-accent",
|
|
1684
|
+
onClick: () => setTheme("system"),
|
|
1685
|
+
children: [
|
|
1686
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react8.Monitor, { className: "h-4 w-4" }),
|
|
1687
|
+
" Sistema"
|
|
1688
|
+
]
|
|
1689
|
+
}
|
|
1690
|
+
)
|
|
1691
|
+
]
|
|
1692
|
+
}
|
|
1693
|
+
) })
|
|
1694
|
+
] });
|
|
1810
1695
|
}
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1696
|
+
|
|
1697
|
+
// src/components/multi-combobox.tsx
|
|
1698
|
+
var PopoverPrimitive5 = __toESM(require("@radix-ui/react-popover"), 1);
|
|
1699
|
+
var import_cmdk2 = require("cmdk");
|
|
1700
|
+
var import_lucide_react9 = require("lucide-react");
|
|
1701
|
+
var React8 = __toESM(require("react"), 1);
|
|
1702
|
+
var import_vaul5 = require("vaul");
|
|
1703
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
1704
|
+
function MultiCombobox({
|
|
1705
|
+
options,
|
|
1706
|
+
value,
|
|
1707
|
+
onChange,
|
|
1708
|
+
placeholder = "Selecione...",
|
|
1709
|
+
searchPlaceholder = "Buscar...",
|
|
1710
|
+
emptyMessage = "Nenhum resultado encontrado.",
|
|
1711
|
+
disabled,
|
|
1712
|
+
id,
|
|
1713
|
+
className,
|
|
1714
|
+
"aria-invalid": ariaInvalid,
|
|
1715
|
+
"aria-describedby": ariaDescribedby,
|
|
1716
|
+
onSearchChange,
|
|
1717
|
+
onLoadMore,
|
|
1718
|
+
loading,
|
|
1719
|
+
hasMore,
|
|
1720
|
+
selectedOptions
|
|
1820
1721
|
}) {
|
|
1722
|
+
const [open, setOpen] = React8.useState(false);
|
|
1821
1723
|
const isDesktop = useIsDesktop();
|
|
1822
|
-
const
|
|
1823
|
-
const
|
|
1824
|
-
const
|
|
1825
|
-
|
|
1724
|
+
const isServer = onSearchChange !== void 0;
|
|
1725
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1726
|
+
const selected = [...selectedOptions ?? [], ...options].filter((option) => {
|
|
1727
|
+
if (!value.includes(option.value) || seen.has(option.value)) return false;
|
|
1728
|
+
seen.add(option.value);
|
|
1729
|
+
return true;
|
|
1730
|
+
});
|
|
1731
|
+
const { listRef, sentinelRef } = useInfiniteScrollSentinel({
|
|
1732
|
+
enabled: isServer && !!hasMore,
|
|
1733
|
+
loading,
|
|
1734
|
+
onLoadMore
|
|
1735
|
+
});
|
|
1736
|
+
const toggleValue = (optionValue) => {
|
|
1737
|
+
onChange(
|
|
1738
|
+
value.includes(optionValue) ? value.filter((v) => v !== optionValue) : [...value, optionValue]
|
|
1739
|
+
);
|
|
1740
|
+
};
|
|
1741
|
+
const removeValue = (optionValue) => {
|
|
1742
|
+
onChange(value.filter((v) => v !== optionValue));
|
|
1743
|
+
};
|
|
1744
|
+
const trigger = /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
1745
|
+
"div",
|
|
1826
1746
|
{
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
"
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1747
|
+
id,
|
|
1748
|
+
role: "combobox",
|
|
1749
|
+
tabIndex: disabled ? -1 : 0,
|
|
1750
|
+
"aria-expanded": open,
|
|
1751
|
+
"aria-invalid": ariaInvalid,
|
|
1752
|
+
"aria-describedby": ariaDescribedby,
|
|
1753
|
+
"aria-disabled": disabled,
|
|
1754
|
+
onKeyDown: (event) => {
|
|
1755
|
+
if (disabled) return;
|
|
1756
|
+
if (event.key === "Enter" || event.key === " " || event.key === "ArrowDown") {
|
|
1757
|
+
event.preventDefault();
|
|
1758
|
+
setOpen(true);
|
|
1837
1759
|
}
|
|
1838
|
-
|
|
1760
|
+
},
|
|
1761
|
+
className: cn(
|
|
1762
|
+
"flex min-h-9 w-full cursor-pointer flex-wrap items-center gap-1 rounded-md border border-input bg-transparent px-3 py-1.5 text-sm shadow-sm transition-colors hover:border-ring/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring aria-disabled:pointer-events-none aria-disabled:opacity-50 aria-invalid:border-destructive aria-invalid:focus-visible:ring-destructive",
|
|
1763
|
+
className
|
|
1764
|
+
),
|
|
1765
|
+
children: [
|
|
1766
|
+
selected.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-muted-foreground", children: placeholder }) : selected.map((option) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
1767
|
+
"span",
|
|
1768
|
+
{
|
|
1769
|
+
className: "inline-flex items-center gap-1 rounded bg-secondary px-1.5 py-0.5 text-xs text-secondary-foreground",
|
|
1770
|
+
children: [
|
|
1771
|
+
option.label,
|
|
1772
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1773
|
+
"button",
|
|
1774
|
+
{
|
|
1775
|
+
type: "button",
|
|
1776
|
+
tabIndex: -1,
|
|
1777
|
+
"aria-label": `Remover ${option.label}`,
|
|
1778
|
+
onClick: (event) => {
|
|
1779
|
+
event.stopPropagation();
|
|
1780
|
+
removeValue(option.value);
|
|
1781
|
+
},
|
|
1782
|
+
onPointerDown: (event) => event.stopPropagation(),
|
|
1783
|
+
className: "rounded-sm opacity-60 transition-opacity hover:opacity-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
1784
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.X, { className: "h-3 w-3" })
|
|
1785
|
+
}
|
|
1786
|
+
)
|
|
1787
|
+
]
|
|
1788
|
+
},
|
|
1789
|
+
option.value
|
|
1790
|
+
)),
|
|
1791
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.ChevronsUpDown, { className: "ml-auto h-4 w-4 shrink-0 opacity-50" })
|
|
1792
|
+
]
|
|
1839
1793
|
}
|
|
1840
1794
|
);
|
|
1841
|
-
const
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
}) }, item.label) : /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
1868
|
-
DropdownMenu2.Item,
|
|
1795
|
+
const command = /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
1796
|
+
import_cmdk2.Command,
|
|
1797
|
+
{
|
|
1798
|
+
shouldFilter: !isServer,
|
|
1799
|
+
className: "flex h-full w-full flex-col overflow-hidden",
|
|
1800
|
+
children: [
|
|
1801
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center border-b px-3", children: [
|
|
1802
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.Search, { className: "mr-2 h-4 w-4 shrink-0 opacity-50" }),
|
|
1803
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1804
|
+
import_cmdk2.Command.Input,
|
|
1805
|
+
{
|
|
1806
|
+
placeholder: searchPlaceholder,
|
|
1807
|
+
onValueChange: isServer ? onSearchChange : void 0,
|
|
1808
|
+
className: "flex h-11 w-full bg-transparent py-2 text-base outline-none placeholder:text-muted-foreground sm:h-9 sm:text-sm"
|
|
1809
|
+
}
|
|
1810
|
+
)
|
|
1811
|
+
] }),
|
|
1812
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
1813
|
+
import_cmdk2.Command.List,
|
|
1814
|
+
{
|
|
1815
|
+
ref: listRef,
|
|
1816
|
+
className: "max-h-[50vh] overflow-y-auto overflow-x-hidden p-1 sm:max-h-60",
|
|
1817
|
+
children: [
|
|
1818
|
+
!isServer && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_cmdk2.Command.Empty, { className: "py-6 text-center text-sm text-muted-foreground", children: emptyMessage }),
|
|
1819
|
+
options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
1820
|
+
import_cmdk2.Command.Item,
|
|
1869
1821
|
{
|
|
1870
|
-
|
|
1871
|
-
|
|
1822
|
+
value: isServer ? option.value : option.label,
|
|
1823
|
+
disabled: option.disabled,
|
|
1824
|
+
onSelect: () => toggleValue(option.value),
|
|
1825
|
+
className: "relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-2.5 text-sm outline-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 sm:py-1.5",
|
|
1872
1826
|
children: [
|
|
1873
|
-
|
|
1874
|
-
|
|
1827
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1828
|
+
import_lucide_react9.Check,
|
|
1829
|
+
{
|
|
1830
|
+
className: cn(
|
|
1831
|
+
"h-4 w-4 shrink-0",
|
|
1832
|
+
value.includes(option.value) ? "opacity-100" : "opacity-0"
|
|
1833
|
+
)
|
|
1834
|
+
}
|
|
1835
|
+
),
|
|
1836
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "truncate", children: option.label })
|
|
1875
1837
|
]
|
|
1876
1838
|
},
|
|
1877
|
-
|
|
1878
|
-
)
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1839
|
+
option.value
|
|
1840
|
+
)),
|
|
1841
|
+
isServer && !loading && options.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "py-6 text-center text-sm text-muted-foreground", children: emptyMessage }),
|
|
1842
|
+
isServer && loading && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "flex items-center justify-center py-6", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_lucide_react9.Loader2, { className: "h-4 w-4 animate-spin text-muted-foreground" }) }),
|
|
1843
|
+
isServer && hasMore && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { ref: sentinelRef, "aria-hidden": true, className: "h-1" })
|
|
1844
|
+
]
|
|
1845
|
+
}
|
|
1846
|
+
)
|
|
1847
|
+
]
|
|
1848
|
+
}
|
|
1849
|
+
);
|
|
1850
|
+
if (isDesktop) {
|
|
1851
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(PopoverPrimitive5.Root, { open, onOpenChange: setOpen, children: [
|
|
1852
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(PopoverPrimitive5.Trigger, { asChild: true, disabled, children: trigger }),
|
|
1853
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(PopoverPrimitive5.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1854
|
+
PopoverPrimitive5.Content,
|
|
1855
|
+
{
|
|
1856
|
+
align: "start",
|
|
1857
|
+
sideOffset: 4,
|
|
1858
|
+
className: "pointer-events-auto z-50 overflow-hidden rounded-md border bg-popover p-0 text-popover-foreground shadow-md",
|
|
1859
|
+
style: { width: "var(--radix-popover-trigger-width)" },
|
|
1860
|
+
children: command
|
|
1898
1861
|
}
|
|
1899
1862
|
) })
|
|
1900
1863
|
] });
|
|
1901
1864
|
}
|
|
1902
|
-
return /* @__PURE__ */ (0,
|
|
1903
|
-
/* @__PURE__ */ (0,
|
|
1904
|
-
/* @__PURE__ */ (0,
|
|
1905
|
-
/* @__PURE__ */ (0,
|
|
1906
|
-
/* @__PURE__ */ (0,
|
|
1907
|
-
/* @__PURE__ */ (0,
|
|
1908
|
-
/* @__PURE__ */ (0,
|
|
1909
|
-
|
|
1910
|
-
userInfo,
|
|
1911
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "-mx-1 my-1 h-px bg-border" })
|
|
1912
|
-
] }),
|
|
1913
|
-
items.map(
|
|
1914
|
-
(item) => item.href ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1915
|
-
"span",
|
|
1916
|
-
{
|
|
1917
|
-
onClick: () => setOpen(false),
|
|
1918
|
-
onKeyDown: () => setOpen(false),
|
|
1919
|
-
children: renderLink({
|
|
1920
|
-
href: item.href,
|
|
1921
|
-
className: sheetItemClass,
|
|
1922
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
1923
|
-
item.icon,
|
|
1924
|
-
item.label
|
|
1925
|
-
] })
|
|
1926
|
-
})
|
|
1927
|
-
},
|
|
1928
|
-
item.label
|
|
1929
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
1930
|
-
"button",
|
|
1931
|
-
{
|
|
1932
|
-
type: "button",
|
|
1933
|
-
className: sheetItemClass,
|
|
1934
|
-
onClick: () => {
|
|
1935
|
-
item.onClick?.();
|
|
1936
|
-
setOpen(false);
|
|
1937
|
-
},
|
|
1938
|
-
children: [
|
|
1939
|
-
item.icon,
|
|
1940
|
-
item.label
|
|
1941
|
-
]
|
|
1942
|
-
},
|
|
1943
|
-
item.label
|
|
1944
|
-
)
|
|
1945
|
-
),
|
|
1946
|
-
onLogout && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
1947
|
-
items.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "-mx-1 my-1 h-px bg-border" }),
|
|
1948
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
1949
|
-
"button",
|
|
1950
|
-
{
|
|
1951
|
-
type: "button",
|
|
1952
|
-
className: cn(sheetItemClass, "text-destructive"),
|
|
1953
|
-
onClick: () => {
|
|
1954
|
-
onLogout();
|
|
1955
|
-
setOpen(false);
|
|
1956
|
-
},
|
|
1957
|
-
children: [
|
|
1958
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react8.LogOut, { className: "h-4 w-4" }),
|
|
1959
|
-
logoutLabel
|
|
1960
|
-
]
|
|
1961
|
-
}
|
|
1962
|
-
)
|
|
1963
|
-
] })
|
|
1865
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_vaul5.Drawer.Root, { open, onOpenChange: setOpen, children: [
|
|
1866
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_vaul5.Drawer.Trigger, { asChild: true, disabled, children: trigger }),
|
|
1867
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_vaul5.Drawer.Portal, { children: [
|
|
1868
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_vaul5.Drawer.Overlay, { className: "fixed inset-0 z-50 bg-black/80" }),
|
|
1869
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_vaul5.Drawer.Content, { className: "fixed inset-x-0 bottom-0 z-50 mt-24 flex max-h-[85vh] flex-col rounded-t-2xl border bg-popover text-popover-foreground outline-none", children: [
|
|
1870
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_vaul5.Drawer.Title, { className: "sr-only", children: placeholder }),
|
|
1871
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "mx-auto my-3 h-1.5 w-12 shrink-0 rounded-full bg-muted" }),
|
|
1872
|
+
command
|
|
1964
1873
|
] })
|
|
1965
1874
|
] })
|
|
1966
1875
|
] });
|
|
1967
1876
|
}
|
|
1968
1877
|
|
|
1969
|
-
// src/components/
|
|
1970
|
-
var
|
|
1971
|
-
function
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
navItems,
|
|
1975
|
-
activePath,
|
|
1976
|
-
isActive,
|
|
1977
|
-
isAdmin = false,
|
|
1978
|
-
user,
|
|
1979
|
-
userMenuItems,
|
|
1980
|
-
onLogout,
|
|
1981
|
-
renderLink = defaultRenderLink,
|
|
1982
|
-
headerActions,
|
|
1983
|
-
collapsible = true,
|
|
1984
|
-
defaultCollapsed = false,
|
|
1985
|
-
children
|
|
1986
|
-
}) {
|
|
1987
|
-
const [collapsed, setCollapsed] = (0, import_react7.useState)(defaultCollapsed);
|
|
1988
|
-
const [mobileOpen, setMobileOpen] = (0, import_react7.useState)(false);
|
|
1989
|
-
const nav = (isCollapsed, onNavigate) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
1990
|
-
SidebarNav,
|
|
1878
|
+
// src/components/page-header.tsx
|
|
1879
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
1880
|
+
function PageHeader({ title, description, action, className }) {
|
|
1881
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
1882
|
+
"div",
|
|
1991
1883
|
{
|
|
1992
|
-
items:
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1884
|
+
className: `flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between ${className ?? ""}`,
|
|
1885
|
+
children: [
|
|
1886
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "min-w-0", children: [
|
|
1887
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("h1", { className: "truncate text-2xl font-semibold tracking-tight", children: title }),
|
|
1888
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-sm text-muted-foreground", children: description })
|
|
1889
|
+
] }),
|
|
1890
|
+
action && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "shrink-0", children: action })
|
|
1891
|
+
]
|
|
1999
1892
|
}
|
|
2000
1893
|
);
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
// src/components/pagination.tsx
|
|
1897
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
1898
|
+
var navButtonClass2 = "inline-flex h-8 items-center justify-center rounded-md border border-input bg-background px-3 text-xs font-medium shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground cursor-pointer disabled:pointer-events-none disabled:opacity-50";
|
|
1899
|
+
function Pagination({
|
|
1900
|
+
page,
|
|
1901
|
+
onPageChange,
|
|
1902
|
+
hasNextPage,
|
|
1903
|
+
hasPreviousPage,
|
|
1904
|
+
totalPages,
|
|
1905
|
+
showPageSizeSelector = false,
|
|
1906
|
+
pageSize,
|
|
1907
|
+
onPageSizeChange,
|
|
1908
|
+
pageSizeOptions,
|
|
1909
|
+
className
|
|
1910
|
+
}) {
|
|
1911
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
1912
|
+
"div",
|
|
1913
|
+
{
|
|
1914
|
+
className: `flex items-center ${showPageSizeSelector ? "justify-between" : "justify-end"} gap-4 ${className ?? ""}`,
|
|
1915
|
+
children: [
|
|
1916
|
+
showPageSizeSelector && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
1917
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("label", { htmlFor: "pagination-page-size", className: "text-sm text-muted-foreground", children: "Itens por p\xE1gina" }),
|
|
1918
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
1919
|
+
"select",
|
|
1920
|
+
{
|
|
1921
|
+
id: "pagination-page-size",
|
|
1922
|
+
value: pageSize,
|
|
1923
|
+
onChange: (e) => onPageSizeChange?.(Number(e.target.value)),
|
|
1924
|
+
className: "h-8 rounded-md border border-input bg-background px-2 text-xs font-medium shadow-sm transition-colors hover:bg-accent focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring cursor-pointer",
|
|
1925
|
+
children: (pageSizeOptions ?? []).map((size) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("option", { value: size, children: size }, size))
|
|
1926
|
+
}
|
|
1927
|
+
)
|
|
1928
|
+
] }),
|
|
1929
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center gap-4", children: [
|
|
1930
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
2013
1931
|
"button",
|
|
2014
1932
|
{
|
|
2015
1933
|
type: "button",
|
|
2016
|
-
onClick: () =>
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
children:
|
|
1934
|
+
onClick: () => onPageChange(page - 1),
|
|
1935
|
+
disabled: !hasPreviousPage,
|
|
1936
|
+
className: navButtonClass2,
|
|
1937
|
+
children: "Anterior"
|
|
2020
1938
|
}
|
|
2021
|
-
)
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
"fixed inset-0 z-50 transition-opacity duration-300 md:hidden",
|
|
2030
|
-
mobileOpen ? "pointer-events-auto opacity-100" : "pointer-events-none opacity-0"
|
|
2031
|
-
),
|
|
2032
|
-
onClick: () => setMobileOpen(false),
|
|
2033
|
-
children: [
|
|
2034
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "absolute inset-0 bg-black/50" }),
|
|
2035
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
2036
|
-
"div",
|
|
1939
|
+
),
|
|
1940
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "text-sm text-muted-foreground", children: [
|
|
1941
|
+
"P\xE1gina ",
|
|
1942
|
+
page,
|
|
1943
|
+
totalPages ? ` de ${totalPages}` : ""
|
|
1944
|
+
] }),
|
|
1945
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
1946
|
+
"button",
|
|
2037
1947
|
{
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
children: [
|
|
2044
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex h-14 shrink-0 items-center border-b px-4", children: brand }),
|
|
2045
|
-
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex-1 overflow-y-auto px-2 py-4", children: nav(false, () => setMobileOpen(false)) })
|
|
2046
|
-
]
|
|
1948
|
+
type: "button",
|
|
1949
|
+
onClick: () => onPageChange(page + 1),
|
|
1950
|
+
disabled: !hasNextPage,
|
|
1951
|
+
className: navButtonClass2,
|
|
1952
|
+
children: "Pr\xF3ximo"
|
|
2047
1953
|
}
|
|
2048
1954
|
)
|
|
2049
|
-
]
|
|
1955
|
+
] })
|
|
1956
|
+
]
|
|
1957
|
+
}
|
|
1958
|
+
);
|
|
1959
|
+
}
|
|
1960
|
+
|
|
1961
|
+
// src/components/password-input.tsx
|
|
1962
|
+
var import_lucide_react10 = require("lucide-react");
|
|
1963
|
+
var React9 = __toESM(require("react"), 1);
|
|
1964
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
1965
|
+
var PasswordInput = React9.forwardRef(({ containerClassName, className, ...props }, ref) => {
|
|
1966
|
+
const [visible, setVisible] = React9.useState(false);
|
|
1967
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: `relative ${containerClassName ?? ""}`, children: [
|
|
1968
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
1969
|
+
"input",
|
|
1970
|
+
{
|
|
1971
|
+
ref,
|
|
1972
|
+
type: visible ? "text" : "password",
|
|
1973
|
+
className: `flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 pr-10 text-base shadow-sm transition-all duration-200 placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:focus-visible:ring-destructive md:text-sm ${className ?? ""}`,
|
|
1974
|
+
...props
|
|
2050
1975
|
}
|
|
2051
1976
|
),
|
|
2052
|
-
/* @__PURE__ */ (0,
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
1977
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
1978
|
+
"button",
|
|
1979
|
+
{
|
|
1980
|
+
type: "button",
|
|
1981
|
+
onClick: () => setVisible((prev) => !prev),
|
|
1982
|
+
"aria-label": visible ? "Ocultar senha" : "Mostrar senha",
|
|
1983
|
+
tabIndex: -1,
|
|
1984
|
+
className: "absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground transition-colors hover:text-foreground",
|
|
1985
|
+
children: visible ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.EyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_lucide_react10.Eye, { className: "h-4 w-4" })
|
|
1986
|
+
}
|
|
1987
|
+
)
|
|
1988
|
+
] });
|
|
1989
|
+
});
|
|
1990
|
+
PasswordInput.displayName = "PasswordInput";
|
|
1991
|
+
|
|
1992
|
+
// src/components/progress-bar.tsx
|
|
1993
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
1994
|
+
var sizeClasses2 = {
|
|
1995
|
+
sm: "h-1.5",
|
|
1996
|
+
md: "h-2"
|
|
1997
|
+
};
|
|
1998
|
+
function ProgressBar({
|
|
1999
|
+
value,
|
|
2000
|
+
size = "md",
|
|
2001
|
+
label,
|
|
2002
|
+
valueLabel,
|
|
2003
|
+
className,
|
|
2004
|
+
indicatorClassName
|
|
2005
|
+
}) {
|
|
2006
|
+
const clamped = Math.min(100, Math.max(0, value));
|
|
2007
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: `space-y-1.5 ${className ?? ""}`, children: [
|
|
2008
|
+
(label || valueLabel) && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex items-baseline justify-between gap-2", children: [
|
|
2009
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-sm text-muted-foreground", children: label }),
|
|
2010
|
+
valueLabel && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-sm font-semibold", children: valueLabel })
|
|
2011
|
+
] }),
|
|
2012
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2013
|
+
"div",
|
|
2014
|
+
{
|
|
2015
|
+
className: `w-full overflow-hidden rounded-full bg-muted ${sizeClasses2[size]}`,
|
|
2016
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2017
|
+
"div",
|
|
2056
2018
|
{
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
className: "inline-flex h-9 w-9 items-center justify-center rounded-md border border-input bg-background shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground md:hidden",
|
|
2060
|
-
"aria-label": "Abrir menu",
|
|
2061
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react9.Menu, { className: "h-4 w-4" })
|
|
2019
|
+
className: `h-full rounded-full transition-all duration-300 ${indicatorClassName ?? "bg-primary"}`,
|
|
2020
|
+
style: { width: `${clamped}%` }
|
|
2062
2021
|
}
|
|
2063
|
-
)
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2022
|
+
)
|
|
2023
|
+
}
|
|
2024
|
+
)
|
|
2025
|
+
] });
|
|
2026
|
+
}
|
|
2027
|
+
|
|
2028
|
+
// src/components/responsive-data-view.tsx
|
|
2029
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
2030
|
+
function ResponsiveDataView({
|
|
2031
|
+
table,
|
|
2032
|
+
cards,
|
|
2033
|
+
isEmpty,
|
|
2034
|
+
isLoading,
|
|
2035
|
+
emptyIcon,
|
|
2036
|
+
emptyTitle = "Nenhum registro encontrado",
|
|
2037
|
+
emptyDescription,
|
|
2038
|
+
pagination
|
|
2039
|
+
}) {
|
|
2040
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "space-y-4", children: [
|
|
2041
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "hidden overflow-x-auto rounded-md border md:block", children: table }),
|
|
2042
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "md:hidden", children: cards }),
|
|
2043
|
+
!isLoading && isEmpty && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-col items-center justify-center py-16 text-center", children: [
|
|
2044
|
+
emptyIcon && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "mb-4 text-muted-foreground", children: emptyIcon }),
|
|
2045
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("h3", { className: "text-lg font-semibold tracking-tight", children: emptyTitle }),
|
|
2046
|
+
emptyDescription && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "mt-1 max-w-sm text-sm text-muted-foreground", children: emptyDescription })
|
|
2047
|
+
] }),
|
|
2048
|
+
pagination
|
|
2071
2049
|
] });
|
|
2072
2050
|
}
|
|
2073
2051
|
|
|
2074
2052
|
// src/components/row-actions-menu.tsx
|
|
2075
2053
|
var DropdownMenu3 = __toESM(require("@radix-ui/react-dropdown-menu"), 1);
|
|
2076
|
-
var
|
|
2077
|
-
var
|
|
2078
|
-
var
|
|
2079
|
-
var
|
|
2054
|
+
var import_lucide_react11 = require("lucide-react");
|
|
2055
|
+
var import_react7 = require("react");
|
|
2056
|
+
var import_vaul6 = require("vaul");
|
|
2057
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
2080
2058
|
var triggerClass = "inline-flex h-8 w-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50";
|
|
2081
2059
|
var itemClass2 = "flex w-full cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent focus:bg-accent data-[disabled]:pointer-events-none data-[disabled]:opacity-50";
|
|
2082
2060
|
var sheetItemClass2 = "flex w-full cursor-pointer select-none items-center gap-3 rounded-md px-3 py-3 text-base outline-none transition-colors hover:bg-accent active:bg-accent disabled:pointer-events-none disabled:opacity-50";
|
|
@@ -2088,22 +2066,22 @@ function RowActionsMenu({
|
|
|
2088
2066
|
renderLink = defaultRenderLink
|
|
2089
2067
|
}) {
|
|
2090
2068
|
const isDesktop = useIsDesktop();
|
|
2091
|
-
const [open, setOpen] = (0,
|
|
2069
|
+
const [open, setOpen] = (0, import_react7.useState)(false);
|
|
2092
2070
|
if (actions.length === 0) return null;
|
|
2093
|
-
const trigger = /* @__PURE__ */ (0,
|
|
2071
|
+
const trigger = /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2094
2072
|
"button",
|
|
2095
2073
|
{
|
|
2096
2074
|
type: "button",
|
|
2097
2075
|
disabled,
|
|
2098
2076
|
"aria-label": label,
|
|
2099
2077
|
className: triggerClass,
|
|
2100
|
-
children: /* @__PURE__ */ (0,
|
|
2078
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react11.MoreVertical, { className: "h-4 w-4" })
|
|
2101
2079
|
}
|
|
2102
2080
|
);
|
|
2103
2081
|
if (isDesktop) {
|
|
2104
|
-
return /* @__PURE__ */ (0,
|
|
2105
|
-
/* @__PURE__ */ (0,
|
|
2106
|
-
/* @__PURE__ */ (0,
|
|
2082
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(DropdownMenu3.Root, { open, onOpenChange: setOpen, modal: false, children: [
|
|
2083
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(DropdownMenu3.Trigger, { asChild: true, children: trigger }),
|
|
2084
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(DropdownMenu3.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2107
2085
|
DropdownMenu3.Content,
|
|
2108
2086
|
{
|
|
2109
2087
|
align,
|
|
@@ -2114,7 +2092,7 @@ function RowActionsMenu({
|
|
|
2114
2092
|
itemClass2,
|
|
2115
2093
|
action.destructive && "text-destructive focus:bg-destructive/10"
|
|
2116
2094
|
);
|
|
2117
|
-
return action.href ? /* @__PURE__ */ (0,
|
|
2095
|
+
return action.href ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2118
2096
|
DropdownMenu3.Item,
|
|
2119
2097
|
{
|
|
2120
2098
|
asChild: true,
|
|
@@ -2122,14 +2100,14 @@ function RowActionsMenu({
|
|
|
2122
2100
|
children: renderLink({
|
|
2123
2101
|
href: action.href,
|
|
2124
2102
|
className: cls,
|
|
2125
|
-
children: /* @__PURE__ */ (0,
|
|
2103
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
2126
2104
|
action.icon,
|
|
2127
2105
|
action.label
|
|
2128
2106
|
] })
|
|
2129
2107
|
})
|
|
2130
2108
|
},
|
|
2131
2109
|
action.label
|
|
2132
|
-
) : /* @__PURE__ */ (0,
|
|
2110
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
2133
2111
|
DropdownMenu3.Item,
|
|
2134
2112
|
{
|
|
2135
2113
|
className: cls,
|
|
@@ -2147,23 +2125,23 @@ function RowActionsMenu({
|
|
|
2147
2125
|
) })
|
|
2148
2126
|
] });
|
|
2149
2127
|
}
|
|
2150
|
-
return /* @__PURE__ */ (0,
|
|
2151
|
-
/* @__PURE__ */ (0,
|
|
2152
|
-
/* @__PURE__ */ (0,
|
|
2153
|
-
/* @__PURE__ */ (0,
|
|
2154
|
-
/* @__PURE__ */ (0,
|
|
2155
|
-
/* @__PURE__ */ (0,
|
|
2156
|
-
/* @__PURE__ */ (0,
|
|
2128
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_vaul6.Drawer.Root, { open, onOpenChange: setOpen, children: [
|
|
2129
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_vaul6.Drawer.Trigger, { asChild: true, children: trigger }),
|
|
2130
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_vaul6.Drawer.Portal, { children: [
|
|
2131
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_vaul6.Drawer.Overlay, { className: "fixed inset-0 z-50 bg-black/80" }),
|
|
2132
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_vaul6.Drawer.Content, { className: "fixed inset-x-0 bottom-0 z-50 flex flex-col rounded-t-2xl border bg-popover p-2 pb-[max(0.5rem,env(safe-area-inset-bottom))] text-popover-foreground outline-none", children: [
|
|
2133
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_vaul6.Drawer.Title, { className: "sr-only", children: label }),
|
|
2134
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "mx-auto my-3 h-1.5 w-12 shrink-0 rounded-full bg-muted" }),
|
|
2157
2135
|
actions.map((action) => {
|
|
2158
2136
|
const cls = cn(
|
|
2159
2137
|
sheetItemClass2,
|
|
2160
2138
|
action.destructive && "text-destructive"
|
|
2161
2139
|
);
|
|
2162
|
-
const inner = /* @__PURE__ */ (0,
|
|
2140
|
+
const inner = /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
2163
2141
|
action.icon,
|
|
2164
2142
|
action.label
|
|
2165
2143
|
] });
|
|
2166
|
-
return action.href ? /* @__PURE__ */ (0,
|
|
2144
|
+
return action.href ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2167
2145
|
"span",
|
|
2168
2146
|
{
|
|
2169
2147
|
onClick: () => setOpen(false),
|
|
@@ -2175,7 +2153,7 @@ function RowActionsMenu({
|
|
|
2175
2153
|
})
|
|
2176
2154
|
},
|
|
2177
2155
|
action.label
|
|
2178
|
-
) : /* @__PURE__ */ (0,
|
|
2156
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
2179
2157
|
"button",
|
|
2180
2158
|
{
|
|
2181
2159
|
type: "button",
|
|
@@ -2195,13 +2173,195 @@ function RowActionsMenu({
|
|
|
2195
2173
|
] });
|
|
2196
2174
|
}
|
|
2197
2175
|
|
|
2198
|
-
// src/
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2176
|
+
// src/components/search-input.tsx
|
|
2177
|
+
var React10 = __toESM(require("react"), 1);
|
|
2178
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
2179
|
+
var SearchInput = React10.forwardRef(
|
|
2180
|
+
({ containerClassName, className, ...props }, ref) => {
|
|
2181
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: `relative flex-1 ${containerClassName ?? ""}`, children: [
|
|
2182
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
2183
|
+
"svg",
|
|
2184
|
+
{
|
|
2185
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2186
|
+
width: "16",
|
|
2187
|
+
height: "16",
|
|
2188
|
+
viewBox: "0 0 24 24",
|
|
2189
|
+
fill: "none",
|
|
2190
|
+
stroke: "currentColor",
|
|
2191
|
+
strokeWidth: "2",
|
|
2192
|
+
strokeLinecap: "round",
|
|
2193
|
+
strokeLinejoin: "round",
|
|
2194
|
+
className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground",
|
|
2195
|
+
children: [
|
|
2196
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("circle", { cx: "11", cy: "11", r: "8" }),
|
|
2197
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("path", { d: "m21 21-4.3-4.3" })
|
|
2198
|
+
]
|
|
2199
|
+
}
|
|
2200
|
+
),
|
|
2201
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
2202
|
+
"input",
|
|
2203
|
+
{
|
|
2204
|
+
ref,
|
|
2205
|
+
type: "text",
|
|
2206
|
+
className: `flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 pl-10 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 ${className ?? ""}`,
|
|
2207
|
+
...props
|
|
2208
|
+
}
|
|
2209
|
+
)
|
|
2210
|
+
] });
|
|
2203
2211
|
}
|
|
2204
|
-
|
|
2212
|
+
);
|
|
2213
|
+
SearchInput.displayName = "SearchInput";
|
|
2214
|
+
|
|
2215
|
+
// src/components/stat-card.tsx
|
|
2216
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
2217
|
+
function StatCard({ label, value, detail, icon, isLoading }) {
|
|
2218
|
+
if (isLoading) {
|
|
2219
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "rounded-lg border bg-card p-6 shadow-sm", children: [
|
|
2220
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center justify-between pb-2", children: [
|
|
2221
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "h-4 w-24 animate-pulse rounded bg-muted" }),
|
|
2222
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "h-4 w-4 animate-pulse rounded bg-muted" })
|
|
2223
|
+
] }),
|
|
2224
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "mt-2 h-7 w-16 animate-pulse rounded bg-muted" }),
|
|
2225
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "mt-1 h-4 w-20 animate-pulse rounded bg-muted" })
|
|
2226
|
+
] });
|
|
2227
|
+
}
|
|
2228
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "rounded-lg border bg-card p-6 shadow-sm", children: [
|
|
2229
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "flex items-center justify-between pb-2", children: [
|
|
2230
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-sm font-medium text-muted-foreground", children: label }),
|
|
2231
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "text-muted-foreground", children: icon })
|
|
2232
|
+
] }),
|
|
2233
|
+
/* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "text-2xl font-bold", children: value }),
|
|
2234
|
+
detail && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("p", { className: "text-xs text-muted-foreground", children: detail })
|
|
2235
|
+
] });
|
|
2236
|
+
}
|
|
2237
|
+
|
|
2238
|
+
// src/components/status-badge.tsx
|
|
2239
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
2240
|
+
var variantClasses = {
|
|
2241
|
+
neutral: {
|
|
2242
|
+
badge: "bg-gray-100 text-gray-700 dark:bg-gray-800 dark:text-gray-300",
|
|
2243
|
+
dot: "bg-gray-400"
|
|
2244
|
+
},
|
|
2245
|
+
info: {
|
|
2246
|
+
badge: "bg-blue-100 text-blue-700 dark:bg-blue-950 dark:text-blue-400",
|
|
2247
|
+
dot: "bg-blue-500"
|
|
2248
|
+
},
|
|
2249
|
+
success: {
|
|
2250
|
+
badge: "bg-green-100 text-green-700 dark:bg-green-950 dark:text-green-400",
|
|
2251
|
+
dot: "bg-green-500"
|
|
2252
|
+
},
|
|
2253
|
+
danger: {
|
|
2254
|
+
badge: "bg-red-100 text-red-700 dark:bg-red-950 dark:text-red-400",
|
|
2255
|
+
dot: "bg-red-500"
|
|
2256
|
+
},
|
|
2257
|
+
warning: {
|
|
2258
|
+
badge: "bg-amber-100 text-amber-700 dark:bg-amber-950 dark:text-amber-400",
|
|
2259
|
+
dot: "bg-amber-500"
|
|
2260
|
+
}
|
|
2261
|
+
};
|
|
2262
|
+
function StatusBadge({
|
|
2263
|
+
variant = "neutral",
|
|
2264
|
+
dot = true,
|
|
2265
|
+
className,
|
|
2266
|
+
children
|
|
2267
|
+
}) {
|
|
2268
|
+
const classes = variantClasses[variant];
|
|
2269
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
2270
|
+
"span",
|
|
2271
|
+
{
|
|
2272
|
+
className: `inline-flex items-center gap-1.5 rounded-md px-2 py-0.5 text-xs font-medium ${classes.badge} ${className ?? ""}`,
|
|
2273
|
+
children: [
|
|
2274
|
+
dot && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
2275
|
+
"span",
|
|
2276
|
+
{
|
|
2277
|
+
className: `inline-block h-1.5 w-1.5 shrink-0 rounded-full ${classes.dot}`
|
|
2278
|
+
}
|
|
2279
|
+
),
|
|
2280
|
+
children
|
|
2281
|
+
]
|
|
2282
|
+
}
|
|
2283
|
+
);
|
|
2284
|
+
}
|
|
2285
|
+
|
|
2286
|
+
// src/components/status-dot.tsx
|
|
2287
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
2288
|
+
function StatusDot({ active, label, className }) {
|
|
2289
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { className: `inline-flex items-center gap-2 ${className ?? ""}`, children: [
|
|
2290
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
2291
|
+
"span",
|
|
2292
|
+
{
|
|
2293
|
+
className: `h-2 w-2 rounded-full ${active ? "bg-green-500" : "bg-red-500"}`
|
|
2294
|
+
}
|
|
2295
|
+
),
|
|
2296
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: label })
|
|
2297
|
+
] });
|
|
2298
|
+
}
|
|
2299
|
+
|
|
2300
|
+
// src/components/table-skeleton.tsx
|
|
2301
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
2302
|
+
function TableSkeleton({ rows = 5, columns = 4 }) {
|
|
2303
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_jsx_runtime30.Fragment, { children: Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("tr", { className: "border-b transition-colors", children: Array.from({ length: columns }).map((_2, j) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("td", { className: "p-4 align-middle", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "h-5 w-full animate-pulse rounded bg-muted" }) }, j)) }, i)) });
|
|
2304
|
+
}
|
|
2305
|
+
|
|
2306
|
+
// src/components/toaster.tsx
|
|
2307
|
+
var import_sonner = require("sonner");
|
|
2308
|
+
var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
2309
|
+
function Toaster(props) {
|
|
2310
|
+
const { theme = "system" } = useTheme();
|
|
2311
|
+
return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
|
|
2312
|
+
import_sonner.Toaster,
|
|
2313
|
+
{
|
|
2314
|
+
theme,
|
|
2315
|
+
className: "toaster group",
|
|
2316
|
+
toastOptions: {
|
|
2317
|
+
classNames: {
|
|
2318
|
+
toast: "group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-md",
|
|
2319
|
+
description: "group-[.toast]:text-muted-foreground",
|
|
2320
|
+
actionButton: "group-[.toast]:bg-primary group-[.toast]:text-primary-foreground",
|
|
2321
|
+
cancelButton: "group-[.toast]:bg-muted group-[.toast]:text-muted-foreground",
|
|
2322
|
+
success: "group-[.toaster]:!bg-background group-[.toaster]:!text-foreground group-[.toaster]:!border-success/40",
|
|
2323
|
+
error: "group-[.toaster]:!bg-background group-[.toaster]:!text-foreground group-[.toaster]:!border-destructive/40"
|
|
2324
|
+
}
|
|
2325
|
+
},
|
|
2326
|
+
...props
|
|
2327
|
+
}
|
|
2328
|
+
);
|
|
2329
|
+
}
|
|
2330
|
+
|
|
2331
|
+
// src/hooks/use-company-subdomain.ts
|
|
2332
|
+
var import_react8 = require("react");
|
|
2333
|
+
function getSubdomain(hostname) {
|
|
2334
|
+
const labels = hostname.split(".");
|
|
2335
|
+
if (labels.length < 2) return void 0;
|
|
2336
|
+
const first = labels[0];
|
|
2337
|
+
if (!first || first === "www" || first === "localhost") return void 0;
|
|
2338
|
+
return first;
|
|
2339
|
+
}
|
|
2340
|
+
function resolveOverride(storageKey) {
|
|
2341
|
+
if (typeof window === "undefined") return void 0;
|
|
2342
|
+
const params = new URLSearchParams(window.location.search);
|
|
2343
|
+
if (params.has("company")) {
|
|
2344
|
+
const value = params.get("company");
|
|
2345
|
+
if (value) {
|
|
2346
|
+
window.localStorage.setItem(storageKey, value);
|
|
2347
|
+
return value;
|
|
2348
|
+
}
|
|
2349
|
+
window.localStorage.removeItem(storageKey);
|
|
2350
|
+
return void 0;
|
|
2351
|
+
}
|
|
2352
|
+
return window.localStorage.getItem(storageKey) ?? void 0;
|
|
2353
|
+
}
|
|
2354
|
+
function useCompanySubdomain(opts = {}) {
|
|
2355
|
+
const { enableOverride = false, overrideStorageKey = "company-subdomain" } = opts;
|
|
2356
|
+
const [subdomain] = (0, import_react8.useState)(() => {
|
|
2357
|
+
if (enableOverride) {
|
|
2358
|
+
const override = resolveOverride(overrideStorageKey);
|
|
2359
|
+
if (override) return override;
|
|
2360
|
+
}
|
|
2361
|
+
if (typeof window === "undefined") return void 0;
|
|
2362
|
+
return getSubdomain(window.location.hostname);
|
|
2363
|
+
});
|
|
2364
|
+
return { subdomain };
|
|
2205
2365
|
}
|
|
2206
2366
|
|
|
2207
2367
|
// src/hooks/use-disclosure.ts
|
|
@@ -2239,6 +2399,15 @@ function useCustomToast() {
|
|
|
2239
2399
|
);
|
|
2240
2400
|
return showToast;
|
|
2241
2401
|
}
|
|
2402
|
+
|
|
2403
|
+
// src/lib/api-error.ts
|
|
2404
|
+
function extractApiError(err, fallbackMessage = "Ocorreu um erro inesperado.") {
|
|
2405
|
+
const detail = err?.body?.detail || err?.message;
|
|
2406
|
+
if (Array.isArray(detail) && detail.length > 0) {
|
|
2407
|
+
return detail[0].msg;
|
|
2408
|
+
}
|
|
2409
|
+
return detail || fallbackMessage;
|
|
2410
|
+
}
|
|
2242
2411
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2243
2412
|
0 && (module.exports = {
|
|
2244
2413
|
AppShell,
|
|
@@ -2251,6 +2420,9 @@ function useCustomToast() {
|
|
|
2251
2420
|
DatePicker,
|
|
2252
2421
|
DateTimePicker,
|
|
2253
2422
|
EmptyState,
|
|
2423
|
+
FilterOptionList,
|
|
2424
|
+
FilterPopover,
|
|
2425
|
+
FilterToolbar,
|
|
2254
2426
|
FormDialog,
|
|
2255
2427
|
FormDialogLayout,
|
|
2256
2428
|
FormField,
|