@motor-hero/ui-kit 0.33.0 → 0.34.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 +21 -0
- package/dist/components/date-picker.d.ts.map +1 -0
- package/dist/index.cjs +414 -132
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +423 -143
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
- package/src/components/date-picker.tsx +348 -0
- package/src/index.ts +2 -0
package/dist/index.cjs
CHANGED
|
@@ -37,6 +37,8 @@ __export(index_exports, {
|
|
|
37
37
|
Combobox: () => Combobox,
|
|
38
38
|
ConfirmDialog: () => ConfirmDialog,
|
|
39
39
|
DataTableWrapper: () => DataTableWrapper,
|
|
40
|
+
DatePicker: () => DatePicker,
|
|
41
|
+
DateTimePicker: () => DateTimePicker,
|
|
40
42
|
EmptyState: () => EmptyState,
|
|
41
43
|
FormDialog: () => FormDialog,
|
|
42
44
|
FormDialogLayout: () => FormDialogLayout,
|
|
@@ -1281,31 +1283,309 @@ function ColorPicker({
|
|
|
1281
1283
|
] });
|
|
1282
1284
|
}
|
|
1283
1285
|
|
|
1284
|
-
// src/components/
|
|
1286
|
+
// src/components/date-picker.tsx
|
|
1287
|
+
var PopoverPrimitive4 = __toESM(require("@radix-ui/react-popover"), 1);
|
|
1288
|
+
var import_mask = require("@react-input/mask");
|
|
1289
|
+
var import_date_fns = require("date-fns");
|
|
1290
|
+
var import_locale = require("date-fns/locale");
|
|
1291
|
+
var import_lucide_react7 = require("lucide-react");
|
|
1292
|
+
var React9 = __toESM(require("react"), 1);
|
|
1293
|
+
var import_react_day_picker = require("react-day-picker");
|
|
1294
|
+
var import_vaul3 = require("vaul");
|
|
1285
1295
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
1296
|
+
var DATE_MASK = "__/__/____";
|
|
1297
|
+
var TIME_MASK = "__:__";
|
|
1298
|
+
var MASK_REPLACEMENT = { _: /\d/ };
|
|
1299
|
+
var DATE_FORMAT = "dd/MM/yyyy";
|
|
1300
|
+
var TIME_FORMAT = "HH:mm";
|
|
1301
|
+
var DATE_VALUE_FORMAT = "yyyy-MM-dd";
|
|
1302
|
+
function pad(n) {
|
|
1303
|
+
return String(n).padStart(2, "0");
|
|
1304
|
+
}
|
|
1305
|
+
function parseStrict(text, fmt) {
|
|
1306
|
+
const parsed = (0, import_date_fns.parse)(text, fmt, /* @__PURE__ */ new Date());
|
|
1307
|
+
if (!(0, import_date_fns.isValid)(parsed)) return null;
|
|
1308
|
+
return (0, import_date_fns.format)(parsed, fmt) === text ? parsed : null;
|
|
1309
|
+
}
|
|
1310
|
+
function dateOnlyToDate(value) {
|
|
1311
|
+
if (!value) return void 0;
|
|
1312
|
+
const parsed = (0, import_date_fns.parse)(value, DATE_VALUE_FORMAT, /* @__PURE__ */ new Date());
|
|
1313
|
+
return (0, import_date_fns.isValid)(parsed) ? parsed : void 0;
|
|
1314
|
+
}
|
|
1315
|
+
function dateTimeToDate(value) {
|
|
1316
|
+
if (!value) return void 0;
|
|
1317
|
+
const parsed = new Date(value);
|
|
1318
|
+
return Number.isNaN(parsed.getTime()) ? void 0 : parsed;
|
|
1319
|
+
}
|
|
1320
|
+
function displayFor(value, withTime) {
|
|
1321
|
+
const date = withTime ? dateTimeToDate(value) : dateOnlyToDate(value);
|
|
1322
|
+
if (!date) return "";
|
|
1323
|
+
const datePart = (0, import_date_fns.format)(date, DATE_FORMAT);
|
|
1324
|
+
return withTime ? `${datePart} ${pad(date.getHours())}:${pad(date.getMinutes())}` : datePart;
|
|
1325
|
+
}
|
|
1326
|
+
function toMatchers(minDate, maxDate, disabledDates) {
|
|
1327
|
+
const matchers = [];
|
|
1328
|
+
const min = dateOnlyToDate(minDate);
|
|
1329
|
+
const max = dateOnlyToDate(maxDate);
|
|
1330
|
+
if (min) matchers.push({ before: min });
|
|
1331
|
+
if (max) matchers.push({ after: max });
|
|
1332
|
+
if (disabledDates) matchers.push(disabledDates);
|
|
1333
|
+
return matchers;
|
|
1334
|
+
}
|
|
1335
|
+
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
|
+
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 calendarClassNames = {
|
|
1338
|
+
months: "flex flex-col",
|
|
1339
|
+
month: "flex flex-col gap-4",
|
|
1340
|
+
month_caption: "flex justify-center pt-1 relative items-center h-7",
|
|
1341
|
+
caption_label: "text-sm font-medium",
|
|
1342
|
+
nav: "flex items-center gap-1 absolute inset-x-0 top-0 justify-between px-1",
|
|
1343
|
+
button_previous: "inline-flex size-7 items-center justify-center rounded-md border border-input bg-transparent p-0 opacity-50 hover:opacity-100",
|
|
1344
|
+
button_next: "inline-flex size-7 items-center justify-center rounded-md border border-input bg-transparent p-0 opacity-50 hover:opacity-100",
|
|
1345
|
+
month_grid: "w-full border-collapse space-y-1",
|
|
1346
|
+
weekdays: "flex",
|
|
1347
|
+
weekday: "text-muted-foreground rounded-md w-8 font-normal text-[0.8rem]",
|
|
1348
|
+
week: "flex w-full mt-2",
|
|
1349
|
+
day: "relative p-0 text-center text-sm focus-within:relative focus-within:z-20",
|
|
1350
|
+
day_button: "inline-flex size-8 items-center justify-center rounded-md p-0 font-normal hover:bg-accent hover:text-accent-foreground aria-selected:opacity-100",
|
|
1351
|
+
selected: "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground rounded-md [&>button]:bg-primary [&>button]:text-primary-foreground",
|
|
1352
|
+
today: "bg-accent text-accent-foreground rounded-md",
|
|
1353
|
+
outside: "text-muted-foreground opacity-50",
|
|
1354
|
+
disabled: "text-muted-foreground opacity-50 pointer-events-none",
|
|
1355
|
+
hidden: "invisible"
|
|
1356
|
+
};
|
|
1357
|
+
var calendarComponents = {
|
|
1358
|
+
Chevron: ({ orientation }) => orientation === "left" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react7.ChevronLeft, { className: "size-4" }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react7.ChevronRight, { className: "size-4" })
|
|
1359
|
+
};
|
|
1360
|
+
function DatePickerImpl({
|
|
1361
|
+
value,
|
|
1362
|
+
onChange,
|
|
1363
|
+
placeholder,
|
|
1364
|
+
disabled,
|
|
1365
|
+
minDate,
|
|
1366
|
+
maxDate,
|
|
1367
|
+
disabledDates,
|
|
1368
|
+
withTime = false,
|
|
1369
|
+
id,
|
|
1370
|
+
className,
|
|
1371
|
+
"aria-invalid": ariaInvalid,
|
|
1372
|
+
"aria-describedby": ariaDescribedby
|
|
1373
|
+
}) {
|
|
1374
|
+
const isDesktop = useIsDesktop();
|
|
1375
|
+
const triggerRef = React9.useRef(null);
|
|
1376
|
+
const [open, setOpenRaw] = React9.useState(false);
|
|
1377
|
+
const [focused, setFocused] = React9.useState(false);
|
|
1378
|
+
const [editText, setEditText] = React9.useState("");
|
|
1379
|
+
const [pendingDate, setPendingDate] = React9.useState();
|
|
1380
|
+
const [pendingTime, setPendingTime] = React9.useState("");
|
|
1381
|
+
const committedDate = withTime ? dateTimeToDate(value) : dateOnlyToDate(value);
|
|
1382
|
+
const displayValue = displayFor(value, withTime);
|
|
1383
|
+
const matchers = toMatchers(minDate, maxDate, disabledDates);
|
|
1384
|
+
const setOpen = (next) => {
|
|
1385
|
+
setOpenRaw(next);
|
|
1386
|
+
if (next) {
|
|
1387
|
+
setEditText(displayValue);
|
|
1388
|
+
setPendingDate(committedDate);
|
|
1389
|
+
setPendingTime(
|
|
1390
|
+
committedDate ? `${pad(committedDate.getHours())}:${pad(committedDate.getMinutes())}` : ""
|
|
1391
|
+
);
|
|
1392
|
+
}
|
|
1393
|
+
};
|
|
1394
|
+
const commitDateOnly = (date) => {
|
|
1395
|
+
onChange((0, import_date_fns.format)(date, DATE_VALUE_FORMAT));
|
|
1396
|
+
setOpen(false);
|
|
1397
|
+
};
|
|
1398
|
+
const commitDateTime = (date, timeText) => {
|
|
1399
|
+
const time = parseStrict(timeText, TIME_FORMAT);
|
|
1400
|
+
if (!time) return;
|
|
1401
|
+
const combined = new Date(date);
|
|
1402
|
+
combined.setHours(time.getHours(), time.getMinutes(), 0, 0);
|
|
1403
|
+
onChange(combined.toISOString());
|
|
1404
|
+
setOpen(false);
|
|
1405
|
+
};
|
|
1406
|
+
const handleCalendarSelect = (date) => {
|
|
1407
|
+
if (!withTime) {
|
|
1408
|
+
commitDateOnly(date);
|
|
1409
|
+
return;
|
|
1410
|
+
}
|
|
1411
|
+
setPendingDate(date);
|
|
1412
|
+
setEditText(`${(0, import_date_fns.format)(date, DATE_FORMAT)} ${pendingTime}`.trim());
|
|
1413
|
+
};
|
|
1414
|
+
const handleTriggerChange = (event) => {
|
|
1415
|
+
const text = event.target.value;
|
|
1416
|
+
setEditText(text);
|
|
1417
|
+
if (!withTime) {
|
|
1418
|
+
const parsed = parseStrict(text, DATE_FORMAT);
|
|
1419
|
+
if (parsed) commitDateOnly(parsed);
|
|
1420
|
+
return;
|
|
1421
|
+
}
|
|
1422
|
+
const [datePart, timePart] = [text.slice(0, 10), text.slice(11)];
|
|
1423
|
+
const parsedDate = parseStrict(datePart, DATE_FORMAT);
|
|
1424
|
+
if (parsedDate) {
|
|
1425
|
+
setPendingDate(parsedDate);
|
|
1426
|
+
if (timePart) setPendingTime(timePart);
|
|
1427
|
+
}
|
|
1428
|
+
if (parsedDate && timePart && parseStrict(timePart, TIME_FORMAT)) {
|
|
1429
|
+
commitDateTime(parsedDate, timePart);
|
|
1430
|
+
}
|
|
1431
|
+
};
|
|
1432
|
+
const handleTimeFieldChange = (event) => {
|
|
1433
|
+
setPendingTime(event.target.value);
|
|
1434
|
+
if (pendingDate) {
|
|
1435
|
+
setEditText(`${(0, import_date_fns.format)(pendingDate, DATE_FORMAT)} ${event.target.value}`.trim());
|
|
1436
|
+
}
|
|
1437
|
+
};
|
|
1438
|
+
const canApply = withTime && !!pendingDate && !!parseStrict(pendingTime, TIME_FORMAT);
|
|
1439
|
+
const trigger = /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { ref: triggerRef, className: "relative", children: [
|
|
1440
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1441
|
+
import_mask.InputMask,
|
|
1442
|
+
{
|
|
1443
|
+
id,
|
|
1444
|
+
mask: withTime ? `${DATE_MASK} ${TIME_MASK}` : DATE_MASK,
|
|
1445
|
+
replacement: MASK_REPLACEMENT,
|
|
1446
|
+
value: focused ? editText : displayValue,
|
|
1447
|
+
onChange: handleTriggerChange,
|
|
1448
|
+
onFocus: () => {
|
|
1449
|
+
setFocused(true);
|
|
1450
|
+
setOpen(true);
|
|
1451
|
+
},
|
|
1452
|
+
onBlur: () => setFocused(false),
|
|
1453
|
+
placeholder: placeholder ?? (withTime ? "dd/mm/aaaa hh:mm" : "dd/mm/aaaa"),
|
|
1454
|
+
disabled,
|
|
1455
|
+
"aria-invalid": ariaInvalid,
|
|
1456
|
+
"aria-describedby": ariaDescribedby,
|
|
1457
|
+
className: cn(triggerInputClass, className)
|
|
1458
|
+
}
|
|
1459
|
+
),
|
|
1460
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1461
|
+
"button",
|
|
1462
|
+
{
|
|
1463
|
+
type: "button",
|
|
1464
|
+
disabled,
|
|
1465
|
+
"aria-label": withTime ? "Abrir calend\xE1rio e hor\xE1rio" : "Abrir calend\xE1rio",
|
|
1466
|
+
"aria-haspopup": "dialog",
|
|
1467
|
+
"aria-expanded": open,
|
|
1468
|
+
onClick: () => setOpen(!open),
|
|
1469
|
+
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, import_jsx_runtime20.jsx)(import_lucide_react7.Clock, { className: "h-4 w-4" }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react7.CalendarIcon, { className: "h-4 w-4" })
|
|
1471
|
+
}
|
|
1472
|
+
)
|
|
1473
|
+
] });
|
|
1474
|
+
const content = /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: withTime ? "p-3" : "", children: [
|
|
1475
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1476
|
+
import_react_day_picker.DayPicker,
|
|
1477
|
+
{
|
|
1478
|
+
mode: "single",
|
|
1479
|
+
locale: import_locale.ptBR,
|
|
1480
|
+
selected: withTime ? pendingDate : committedDate,
|
|
1481
|
+
defaultMonth: (withTime ? pendingDate : committedDate) ?? /* @__PURE__ */ new Date(),
|
|
1482
|
+
onSelect: (date) => date && handleCalendarSelect(date),
|
|
1483
|
+
disabled: matchers,
|
|
1484
|
+
className: withTime ? "p-0" : "p-3",
|
|
1485
|
+
classNames: calendarClassNames,
|
|
1486
|
+
components: calendarComponents
|
|
1487
|
+
}
|
|
1488
|
+
),
|
|
1489
|
+
withTime && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
|
|
1490
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "mt-2 flex items-center gap-2 border-t pt-3", children: [
|
|
1491
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-sm text-muted-foreground", children: "Hor\xE1rio" }),
|
|
1492
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1493
|
+
import_mask.InputMask,
|
|
1494
|
+
{
|
|
1495
|
+
mask: TIME_MASK,
|
|
1496
|
+
replacement: MASK_REPLACEMENT,
|
|
1497
|
+
value: pendingTime,
|
|
1498
|
+
onChange: handleTimeFieldChange,
|
|
1499
|
+
placeholder: "hh:mm",
|
|
1500
|
+
"aria-label": "Hor\xE1rio",
|
|
1501
|
+
className: cn(fieldInputClass, "flex-1")
|
|
1502
|
+
}
|
|
1503
|
+
)
|
|
1504
|
+
] }),
|
|
1505
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1506
|
+
"button",
|
|
1507
|
+
{
|
|
1508
|
+
type: "button",
|
|
1509
|
+
disabled: !canApply,
|
|
1510
|
+
onClick: () => pendingDate && commitDateTime(pendingDate, pendingTime),
|
|
1511
|
+
className: "mt-3 flex h-9 w-full items-center justify-center rounded-md bg-primary text-sm font-medium text-primary-foreground shadow-sm transition-colors hover:bg-primary/90 disabled:pointer-events-none disabled:opacity-50",
|
|
1512
|
+
children: "Aplicar"
|
|
1513
|
+
}
|
|
1514
|
+
)
|
|
1515
|
+
] })
|
|
1516
|
+
] });
|
|
1517
|
+
if (isDesktop) {
|
|
1518
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(PopoverPrimitive4.Root, { open, onOpenChange: setOpen, children: [
|
|
1519
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(PopoverPrimitive4.Anchor, { asChild: true, children: trigger }),
|
|
1520
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(PopoverPrimitive4.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
1521
|
+
PopoverPrimitive4.Content,
|
|
1522
|
+
{
|
|
1523
|
+
align: "start",
|
|
1524
|
+
sideOffset: 4,
|
|
1525
|
+
onOpenAutoFocus: (event) => event.preventDefault(),
|
|
1526
|
+
onInteractOutside: (event) => {
|
|
1527
|
+
if (triggerRef.current?.contains(event.target)) event.preventDefault();
|
|
1528
|
+
},
|
|
1529
|
+
className: "pointer-events-auto z-50 w-auto overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md",
|
|
1530
|
+
children: content
|
|
1531
|
+
}
|
|
1532
|
+
) })
|
|
1533
|
+
] });
|
|
1534
|
+
}
|
|
1535
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_vaul3.Drawer.Root, { open, onOpenChange: setOpen, children: [
|
|
1536
|
+
trigger,
|
|
1537
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_vaul3.Drawer.Portal, { children: [
|
|
1538
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_vaul3.Drawer.Overlay, { className: "fixed inset-0 z-50 bg-black/80" }),
|
|
1539
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
1540
|
+
import_vaul3.Drawer.Content,
|
|
1541
|
+
{
|
|
1542
|
+
onOpenAutoFocus: (event) => event.preventDefault(),
|
|
1543
|
+
onInteractOutside: (event) => {
|
|
1544
|
+
if (triggerRef.current?.contains(event.target)) event.preventDefault();
|
|
1545
|
+
},
|
|
1546
|
+
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
|
+
children: [
|
|
1548
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_vaul3.Drawer.Title, { className: "sr-only", children: withTime ? "Selecione a data e o hor\xE1rio" : "Selecione a data" }),
|
|
1549
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "mx-auto my-3 h-1.5 w-12 shrink-0 rounded-full bg-muted" }),
|
|
1550
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex justify-center overflow-y-auto pb-4", children: content })
|
|
1551
|
+
]
|
|
1552
|
+
}
|
|
1553
|
+
)
|
|
1554
|
+
] })
|
|
1555
|
+
] });
|
|
1556
|
+
}
|
|
1557
|
+
function DatePicker(props) {
|
|
1558
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DatePickerImpl, { ...props });
|
|
1559
|
+
}
|
|
1560
|
+
function DateTimePicker(props) {
|
|
1561
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DatePickerImpl, { ...props, withTime: true });
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1564
|
+
// src/components/stat-card.tsx
|
|
1565
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
1286
1566
|
function StatCard({ label, value, detail, icon, isLoading }) {
|
|
1287
1567
|
if (isLoading) {
|
|
1288
|
-
return /* @__PURE__ */ (0,
|
|
1289
|
-
/* @__PURE__ */ (0,
|
|
1290
|
-
/* @__PURE__ */ (0,
|
|
1291
|
-
/* @__PURE__ */ (0,
|
|
1568
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "rounded-lg border bg-card p-6 shadow-sm", children: [
|
|
1569
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex items-center justify-between pb-2", children: [
|
|
1570
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "h-4 w-24 animate-pulse rounded bg-muted" }),
|
|
1571
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "h-4 w-4 animate-pulse rounded bg-muted" })
|
|
1292
1572
|
] }),
|
|
1293
|
-
/* @__PURE__ */ (0,
|
|
1294
|
-
/* @__PURE__ */ (0,
|
|
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" })
|
|
1295
1575
|
] });
|
|
1296
1576
|
}
|
|
1297
|
-
return /* @__PURE__ */ (0,
|
|
1298
|
-
/* @__PURE__ */ (0,
|
|
1299
|
-
/* @__PURE__ */ (0,
|
|
1300
|
-
icon && /* @__PURE__ */ (0,
|
|
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 })
|
|
1301
1581
|
] }),
|
|
1302
|
-
/* @__PURE__ */ (0,
|
|
1303
|
-
detail && /* @__PURE__ */ (0,
|
|
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 })
|
|
1304
1584
|
] });
|
|
1305
1585
|
}
|
|
1306
1586
|
|
|
1307
1587
|
// src/components/data-table-wrapper.tsx
|
|
1308
|
-
var
|
|
1588
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
1309
1589
|
function DataTableWrapper({
|
|
1310
1590
|
children,
|
|
1311
1591
|
isEmpty,
|
|
@@ -1318,15 +1598,15 @@ function DataTableWrapper({
|
|
|
1318
1598
|
hasNextPage = false,
|
|
1319
1599
|
hasPreviousPage = false
|
|
1320
1600
|
}) {
|
|
1321
|
-
return /* @__PURE__ */ (0,
|
|
1322
|
-
/* @__PURE__ */ (0,
|
|
1323
|
-
!isLoading && isEmpty && /* @__PURE__ */ (0,
|
|
1324
|
-
emptyIcon && /* @__PURE__ */ (0,
|
|
1325
|
-
/* @__PURE__ */ (0,
|
|
1326
|
-
emptyDescription && /* @__PURE__ */ (0,
|
|
1601
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-4", children: [
|
|
1602
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "overflow-x-auto rounded-md border", children }),
|
|
1603
|
+
!isLoading && isEmpty && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex flex-col items-center justify-center py-16 text-center", children: [
|
|
1604
|
+
emptyIcon && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "mb-4 text-muted-foreground", children: emptyIcon }),
|
|
1605
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("h3", { className: "text-lg font-semibold tracking-tight", children: emptyTitle }),
|
|
1606
|
+
emptyDescription && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "mt-1 max-w-sm text-sm text-muted-foreground", children: emptyDescription })
|
|
1327
1607
|
] }),
|
|
1328
|
-
page !== void 0 && onPageChange && /* @__PURE__ */ (0,
|
|
1329
|
-
/* @__PURE__ */ (0,
|
|
1608
|
+
page !== void 0 && onPageChange && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex items-center justify-end gap-4", children: [
|
|
1609
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
1330
1610
|
"button",
|
|
1331
1611
|
{
|
|
1332
1612
|
type: "button",
|
|
@@ -1336,11 +1616,11 @@ function DataTableWrapper({
|
|
|
1336
1616
|
children: "Anterior"
|
|
1337
1617
|
}
|
|
1338
1618
|
),
|
|
1339
|
-
/* @__PURE__ */ (0,
|
|
1619
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { className: "text-sm text-muted-foreground", children: [
|
|
1340
1620
|
"P\xE1gina ",
|
|
1341
1621
|
page
|
|
1342
1622
|
] }),
|
|
1343
|
-
/* @__PURE__ */ (0,
|
|
1623
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
1344
1624
|
"button",
|
|
1345
1625
|
{
|
|
1346
1626
|
type: "button",
|
|
@@ -1356,7 +1636,7 @@ function DataTableWrapper({
|
|
|
1356
1636
|
|
|
1357
1637
|
// src/components/mobile-card-list.tsx
|
|
1358
1638
|
var import_react4 = require("react");
|
|
1359
|
-
var
|
|
1639
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
1360
1640
|
var SCROLL_THRESHOLD = 8;
|
|
1361
1641
|
function MobileCardList({
|
|
1362
1642
|
data,
|
|
@@ -1387,26 +1667,26 @@ function MobileCardList({
|
|
|
1387
1667
|
}
|
|
1388
1668
|
};
|
|
1389
1669
|
if (isLoading) {
|
|
1390
|
-
return /* @__PURE__ */ (0,
|
|
1391
|
-
/* @__PURE__ */ (0,
|
|
1392
|
-
/* @__PURE__ */ (0,
|
|
1393
|
-
/* @__PURE__ */ (0,
|
|
1670
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: `space-y-3 ${className ?? ""}`, children: Array.from({ length: loadingCount }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "rounded-xl border p-4", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "space-y-3", children: [
|
|
1671
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex justify-between", children: [
|
|
1672
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "h-5 w-32 animate-pulse rounded bg-muted" }),
|
|
1673
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "h-5 w-16 animate-pulse rounded bg-muted" })
|
|
1394
1674
|
] }),
|
|
1395
|
-
/* @__PURE__ */ (0,
|
|
1396
|
-
/* @__PURE__ */ (0,
|
|
1397
|
-
/* @__PURE__ */ (0,
|
|
1398
|
-
/* @__PURE__ */ (0,
|
|
1675
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "h-4 w-48 animate-pulse rounded bg-muted" }),
|
|
1676
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex justify-between", children: [
|
|
1677
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "h-4 w-24 animate-pulse rounded bg-muted" }),
|
|
1678
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "h-4 w-20 animate-pulse rounded bg-muted" })
|
|
1399
1679
|
] })
|
|
1400
1680
|
] }) }, i)) });
|
|
1401
1681
|
}
|
|
1402
|
-
return /* @__PURE__ */ (0,
|
|
1682
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
1403
1683
|
"div",
|
|
1404
1684
|
{
|
|
1405
1685
|
className: `space-y-3 ${className ?? ""}`,
|
|
1406
1686
|
onTouchStart,
|
|
1407
1687
|
onTouchMove,
|
|
1408
1688
|
onClickCapture,
|
|
1409
|
-
children: data.map((item, index) => /* @__PURE__ */ (0,
|
|
1689
|
+
children: data.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
1410
1690
|
"div",
|
|
1411
1691
|
{
|
|
1412
1692
|
className: "rounded-xl border p-4 transition-all duration-150 hover:border-foreground/20 active:scale-[0.99]",
|
|
@@ -1419,7 +1699,7 @@ function MobileCardList({
|
|
|
1419
1699
|
}
|
|
1420
1700
|
|
|
1421
1701
|
// src/components/responsive-data-view.tsx
|
|
1422
|
-
var
|
|
1702
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
1423
1703
|
function ResponsiveDataView({
|
|
1424
1704
|
table,
|
|
1425
1705
|
cards,
|
|
@@ -1430,13 +1710,13 @@ function ResponsiveDataView({
|
|
|
1430
1710
|
emptyDescription,
|
|
1431
1711
|
pagination
|
|
1432
1712
|
}) {
|
|
1433
|
-
return /* @__PURE__ */ (0,
|
|
1434
|
-
/* @__PURE__ */ (0,
|
|
1435
|
-
/* @__PURE__ */ (0,
|
|
1436
|
-
!isLoading && isEmpty && /* @__PURE__ */ (0,
|
|
1437
|
-
emptyIcon && /* @__PURE__ */ (0,
|
|
1438
|
-
/* @__PURE__ */ (0,
|
|
1439
|
-
emptyDescription && /* @__PURE__ */ (0,
|
|
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 })
|
|
1440
1720
|
] }),
|
|
1441
1721
|
pagination
|
|
1442
1722
|
] });
|
|
@@ -1444,10 +1724,10 @@ function ResponsiveDataView({
|
|
|
1444
1724
|
|
|
1445
1725
|
// src/components/toaster.tsx
|
|
1446
1726
|
var import_sonner = require("sonner");
|
|
1447
|
-
var
|
|
1727
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
1448
1728
|
function Toaster(props) {
|
|
1449
1729
|
const { theme = "system" } = useTheme();
|
|
1450
|
-
return /* @__PURE__ */ (0,
|
|
1730
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
1451
1731
|
import_sonner.Toaster,
|
|
1452
1732
|
{
|
|
1453
1733
|
theme,
|
|
@@ -1468,18 +1748,18 @@ function Toaster(props) {
|
|
|
1468
1748
|
}
|
|
1469
1749
|
|
|
1470
1750
|
// src/components/app-shell.tsx
|
|
1471
|
-
var
|
|
1751
|
+
var import_lucide_react9 = require("lucide-react");
|
|
1472
1752
|
var import_react7 = require("react");
|
|
1473
1753
|
|
|
1474
1754
|
// src/components/sidebar-nav.tsx
|
|
1475
1755
|
var import_react5 = require("react");
|
|
1476
1756
|
|
|
1477
1757
|
// src/components/types.tsx
|
|
1478
|
-
var
|
|
1479
|
-
var defaultRenderLink = ({ children, ...props }) => /* @__PURE__ */ (0,
|
|
1758
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
1759
|
+
var defaultRenderLink = ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("a", { ...props, children });
|
|
1480
1760
|
|
|
1481
1761
|
// src/components/sidebar-nav.tsx
|
|
1482
|
-
var
|
|
1762
|
+
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
1483
1763
|
function defaultIsActive(item, activePath) {
|
|
1484
1764
|
if (item.href === "/") return activePath === "/";
|
|
1485
1765
|
return activePath === item.href || activePath.startsWith(item.href + "/");
|
|
@@ -1494,7 +1774,7 @@ function SidebarNav({
|
|
|
1494
1774
|
onNavigate
|
|
1495
1775
|
}) {
|
|
1496
1776
|
const visible = items.filter((item) => !item.adminOnly || isAdmin);
|
|
1497
|
-
return /* @__PURE__ */ (0,
|
|
1777
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("nav", { className: "flex flex-col gap-1", children: visible.map((item) => {
|
|
1498
1778
|
const active = isActive(item, activePath);
|
|
1499
1779
|
const link = renderLink({
|
|
1500
1780
|
href: item.href,
|
|
@@ -1506,21 +1786,21 @@ function SidebarNav({
|
|
|
1506
1786
|
active ? "bg-accent text-accent-foreground font-semibold" : "text-muted-foreground hover:bg-accent hover:text-accent-foreground",
|
|
1507
1787
|
isCollapsed && "justify-center px-2"
|
|
1508
1788
|
),
|
|
1509
|
-
children: /* @__PURE__ */ (0,
|
|
1510
|
-
item.icon && /* @__PURE__ */ (0,
|
|
1511
|
-
!isCollapsed && /* @__PURE__ */ (0,
|
|
1789
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_jsx_runtime27.Fragment, { children: [
|
|
1790
|
+
item.icon && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "shrink-0", children: item.icon }),
|
|
1791
|
+
!isCollapsed && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "truncate", children: item.label })
|
|
1512
1792
|
] })
|
|
1513
1793
|
});
|
|
1514
|
-
return /* @__PURE__ */ (0,
|
|
1794
|
+
return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react5.Fragment, { children: link }, item.href);
|
|
1515
1795
|
}) });
|
|
1516
1796
|
}
|
|
1517
1797
|
|
|
1518
1798
|
// src/components/user-menu.tsx
|
|
1519
1799
|
var DropdownMenu2 = __toESM(require("@radix-ui/react-dropdown-menu"), 1);
|
|
1520
|
-
var
|
|
1800
|
+
var import_lucide_react8 = require("lucide-react");
|
|
1521
1801
|
var import_react6 = require("react");
|
|
1522
|
-
var
|
|
1523
|
-
var
|
|
1802
|
+
var import_vaul4 = require("vaul");
|
|
1803
|
+
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
1524
1804
|
function initials(user) {
|
|
1525
1805
|
const source = user?.name?.trim() || user?.email?.trim();
|
|
1526
1806
|
if (!source) return "";
|
|
@@ -1541,50 +1821,50 @@ function UserMenu({
|
|
|
1541
1821
|
const isDesktop = useIsDesktop();
|
|
1542
1822
|
const [open, setOpen] = (0, import_react6.useState)(false);
|
|
1543
1823
|
const label = initials(user);
|
|
1544
|
-
const trigger = /* @__PURE__ */ (0,
|
|
1824
|
+
const trigger = /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1545
1825
|
"button",
|
|
1546
1826
|
{
|
|
1547
1827
|
type: "button",
|
|
1548
1828
|
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",
|
|
1549
1829
|
"aria-label": "Menu do usu\xE1rio",
|
|
1550
1830
|
"data-testid": "user-menu",
|
|
1551
|
-
children: user?.avatarUrl ? /* @__PURE__ */ (0,
|
|
1831
|
+
children: user?.avatarUrl ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1552
1832
|
"img",
|
|
1553
1833
|
{
|
|
1554
1834
|
src: user.avatarUrl,
|
|
1555
1835
|
alt: user.name ?? user.email ?? "Avatar",
|
|
1556
1836
|
className: "h-full w-full object-cover"
|
|
1557
1837
|
}
|
|
1558
|
-
) : label ? /* @__PURE__ */ (0,
|
|
1838
|
+
) : label ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { children: label }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react8.User, { className: "h-4 w-4" })
|
|
1559
1839
|
}
|
|
1560
1840
|
);
|
|
1561
|
-
const userInfo = (user?.name || user?.email) && /* @__PURE__ */ (0,
|
|
1562
|
-
user.name && /* @__PURE__ */ (0,
|
|
1563
|
-
user.email && /* @__PURE__ */ (0,
|
|
1841
|
+
const userInfo = (user?.name || user?.email) && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "px-2 py-1.5", children: [
|
|
1842
|
+
user.name && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "truncate text-sm font-medium", children: user.name }),
|
|
1843
|
+
user.email && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { className: "truncate text-xs text-muted-foreground", children: user.email })
|
|
1564
1844
|
] });
|
|
1565
1845
|
if (isDesktop) {
|
|
1566
|
-
return /* @__PURE__ */ (0,
|
|
1567
|
-
/* @__PURE__ */ (0,
|
|
1568
|
-
/* @__PURE__ */ (0,
|
|
1846
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(DropdownMenu2.Root, { open, onOpenChange: setOpen, children: [
|
|
1847
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(DropdownMenu2.Trigger, { asChild: true, children: trigger }),
|
|
1848
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(DropdownMenu2.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
1569
1849
|
DropdownMenu2.Content,
|
|
1570
1850
|
{
|
|
1571
1851
|
align,
|
|
1572
1852
|
sideOffset: 6,
|
|
1573
1853
|
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",
|
|
1574
1854
|
children: [
|
|
1575
|
-
userInfo && /* @__PURE__ */ (0,
|
|
1855
|
+
userInfo && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
1576
1856
|
userInfo,
|
|
1577
|
-
/* @__PURE__ */ (0,
|
|
1857
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(DropdownMenu2.Separator, { className: "-mx-1 my-1 h-px bg-border" })
|
|
1578
1858
|
] }),
|
|
1579
1859
|
items.map(
|
|
1580
|
-
(item) => item.href ? /* @__PURE__ */ (0,
|
|
1860
|
+
(item) => item.href ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(DropdownMenu2.Item, { asChild: true, children: renderLink({
|
|
1581
1861
|
href: item.href,
|
|
1582
1862
|
className: itemClass,
|
|
1583
|
-
children: /* @__PURE__ */ (0,
|
|
1863
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
1584
1864
|
item.icon,
|
|
1585
1865
|
item.label
|
|
1586
1866
|
] })
|
|
1587
|
-
}) }, item.label) : /* @__PURE__ */ (0,
|
|
1867
|
+
}) }, item.label) : /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
1588
1868
|
DropdownMenu2.Item,
|
|
1589
1869
|
{
|
|
1590
1870
|
className: itemClass,
|
|
@@ -1597,9 +1877,9 @@ function UserMenu({
|
|
|
1597
1877
|
item.label
|
|
1598
1878
|
)
|
|
1599
1879
|
),
|
|
1600
|
-
onLogout && /* @__PURE__ */ (0,
|
|
1601
|
-
items.length > 0 && /* @__PURE__ */ (0,
|
|
1602
|
-
/* @__PURE__ */ (0,
|
|
1880
|
+
onLogout && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
1881
|
+
items.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(DropdownMenu2.Separator, { className: "-mx-1 my-1 h-px bg-border" }),
|
|
1882
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
1603
1883
|
DropdownMenu2.Item,
|
|
1604
1884
|
{
|
|
1605
1885
|
className: cn(
|
|
@@ -1608,7 +1888,7 @@ function UserMenu({
|
|
|
1608
1888
|
),
|
|
1609
1889
|
onClick: onLogout,
|
|
1610
1890
|
children: [
|
|
1611
|
-
/* @__PURE__ */ (0,
|
|
1891
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react8.LogOut, { className: "h-4 w-4" }),
|
|
1612
1892
|
logoutLabel
|
|
1613
1893
|
]
|
|
1614
1894
|
}
|
|
@@ -1619,19 +1899,19 @@ function UserMenu({
|
|
|
1619
1899
|
) })
|
|
1620
1900
|
] });
|
|
1621
1901
|
}
|
|
1622
|
-
return /* @__PURE__ */ (0,
|
|
1623
|
-
/* @__PURE__ */ (0,
|
|
1624
|
-
/* @__PURE__ */ (0,
|
|
1625
|
-
/* @__PURE__ */ (0,
|
|
1626
|
-
/* @__PURE__ */ (0,
|
|
1627
|
-
/* @__PURE__ */ (0,
|
|
1628
|
-
/* @__PURE__ */ (0,
|
|
1629
|
-
userInfo && /* @__PURE__ */ (0,
|
|
1902
|
+
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_vaul4.Drawer.Root, { open, onOpenChange: setOpen, children: [
|
|
1903
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_vaul4.Drawer.Trigger, { asChild: true, children: trigger }),
|
|
1904
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_vaul4.Drawer.Portal, { children: [
|
|
1905
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_vaul4.Drawer.Overlay, { className: "fixed inset-0 z-50 bg-black/80" }),
|
|
1906
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_vaul4.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: [
|
|
1907
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_vaul4.Drawer.Title, { className: "sr-only", children: "Menu do usu\xE1rio" }),
|
|
1908
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "mx-auto my-3 h-1.5 w-12 shrink-0 rounded-full bg-muted" }),
|
|
1909
|
+
userInfo && /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
1630
1910
|
userInfo,
|
|
1631
|
-
/* @__PURE__ */ (0,
|
|
1911
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "-mx-1 my-1 h-px bg-border" })
|
|
1632
1912
|
] }),
|
|
1633
1913
|
items.map(
|
|
1634
|
-
(item) => item.href ? /* @__PURE__ */ (0,
|
|
1914
|
+
(item) => item.href ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
1635
1915
|
"span",
|
|
1636
1916
|
{
|
|
1637
1917
|
onClick: () => setOpen(false),
|
|
@@ -1639,14 +1919,14 @@ function UserMenu({
|
|
|
1639
1919
|
children: renderLink({
|
|
1640
1920
|
href: item.href,
|
|
1641
1921
|
className: sheetItemClass,
|
|
1642
|
-
children: /* @__PURE__ */ (0,
|
|
1922
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
|
|
1643
1923
|
item.icon,
|
|
1644
1924
|
item.label
|
|
1645
1925
|
] })
|
|
1646
1926
|
})
|
|
1647
1927
|
},
|
|
1648
1928
|
item.label
|
|
1649
|
-
) : /* @__PURE__ */ (0,
|
|
1929
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
1650
1930
|
"button",
|
|
1651
1931
|
{
|
|
1652
1932
|
type: "button",
|
|
@@ -1663,9 +1943,9 @@ function UserMenu({
|
|
|
1663
1943
|
item.label
|
|
1664
1944
|
)
|
|
1665
1945
|
),
|
|
1666
|
-
onLogout && /* @__PURE__ */ (0,
|
|
1667
|
-
items.length > 0 && /* @__PURE__ */ (0,
|
|
1668
|
-
/* @__PURE__ */ (0,
|
|
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)(
|
|
1669
1949
|
"button",
|
|
1670
1950
|
{
|
|
1671
1951
|
type: "button",
|
|
@@ -1675,7 +1955,7 @@ function UserMenu({
|
|
|
1675
1955
|
setOpen(false);
|
|
1676
1956
|
},
|
|
1677
1957
|
children: [
|
|
1678
|
-
/* @__PURE__ */ (0,
|
|
1958
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react8.LogOut, { className: "h-4 w-4" }),
|
|
1679
1959
|
logoutLabel
|
|
1680
1960
|
]
|
|
1681
1961
|
}
|
|
@@ -1687,7 +1967,7 @@ function UserMenu({
|
|
|
1687
1967
|
}
|
|
1688
1968
|
|
|
1689
1969
|
// src/components/app-shell.tsx
|
|
1690
|
-
var
|
|
1970
|
+
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
1691
1971
|
function AppShell({
|
|
1692
1972
|
brand,
|
|
1693
1973
|
brandCollapsed,
|
|
@@ -1706,7 +1986,7 @@ function AppShell({
|
|
|
1706
1986
|
}) {
|
|
1707
1987
|
const [collapsed, setCollapsed] = (0, import_react7.useState)(defaultCollapsed);
|
|
1708
1988
|
const [mobileOpen, setMobileOpen] = (0, import_react7.useState)(false);
|
|
1709
|
-
const nav = (isCollapsed, onNavigate) => /* @__PURE__ */ (0,
|
|
1989
|
+
const nav = (isCollapsed, onNavigate) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
1710
1990
|
SidebarNav,
|
|
1711
1991
|
{
|
|
1712
1992
|
items: navItems,
|
|
@@ -1718,8 +1998,8 @@ function AppShell({
|
|
|
1718
1998
|
onNavigate
|
|
1719
1999
|
}
|
|
1720
2000
|
);
|
|
1721
|
-
return /* @__PURE__ */ (0,
|
|
1722
|
-
/* @__PURE__ */ (0,
|
|
2001
|
+
return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex h-screen overflow-hidden bg-background", children: [
|
|
2002
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
1723
2003
|
"aside",
|
|
1724
2004
|
{
|
|
1725
2005
|
className: cn(
|
|
@@ -1727,22 +2007,22 @@ function AppShell({
|
|
|
1727
2007
|
collapsed ? "w-16" : "w-60"
|
|
1728
2008
|
),
|
|
1729
2009
|
children: [
|
|
1730
|
-
/* @__PURE__ */ (0,
|
|
1731
|
-
/* @__PURE__ */ (0,
|
|
1732
|
-
collapsible && /* @__PURE__ */ (0,
|
|
2010
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex h-14 shrink-0 items-center border-b px-4", children: collapsed ? brandCollapsed ?? brand : brand }),
|
|
2011
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "flex-1 overflow-y-auto px-2 py-4", children: nav(collapsed) }),
|
|
2012
|
+
collapsible && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "border-t p-2", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
1733
2013
|
"button",
|
|
1734
2014
|
{
|
|
1735
2015
|
type: "button",
|
|
1736
2016
|
onClick: () => setCollapsed((v) => !v),
|
|
1737
2017
|
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",
|
|
1738
2018
|
"aria-label": collapsed ? "Expandir menu" : "Recolher menu",
|
|
1739
|
-
children: collapsed ? /* @__PURE__ */ (0,
|
|
2019
|
+
children: collapsed ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react9.ChevronRight, { className: "h-4 w-4" }) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react9.ChevronLeft, { className: "h-4 w-4" })
|
|
1740
2020
|
}
|
|
1741
2021
|
) })
|
|
1742
2022
|
]
|
|
1743
2023
|
}
|
|
1744
2024
|
),
|
|
1745
|
-
/* @__PURE__ */ (0,
|
|
2025
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
1746
2026
|
"div",
|
|
1747
2027
|
{
|
|
1748
2028
|
className: cn(
|
|
@@ -1751,8 +2031,8 @@ function AppShell({
|
|
|
1751
2031
|
),
|
|
1752
2032
|
onClick: () => setMobileOpen(false),
|
|
1753
2033
|
children: [
|
|
1754
|
-
/* @__PURE__ */ (0,
|
|
1755
|
-
/* @__PURE__ */ (0,
|
|
2034
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "absolute inset-0 bg-black/50" }),
|
|
2035
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
|
|
1756
2036
|
"div",
|
|
1757
2037
|
{
|
|
1758
2038
|
className: cn(
|
|
@@ -1761,42 +2041,42 @@ function AppShell({
|
|
|
1761
2041
|
),
|
|
1762
2042
|
onClick: (e) => e.stopPropagation(),
|
|
1763
2043
|
children: [
|
|
1764
|
-
/* @__PURE__ */ (0,
|
|
1765
|
-
/* @__PURE__ */ (0,
|
|
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)) })
|
|
1766
2046
|
]
|
|
1767
2047
|
}
|
|
1768
2048
|
)
|
|
1769
2049
|
]
|
|
1770
2050
|
}
|
|
1771
2051
|
),
|
|
1772
|
-
/* @__PURE__ */ (0,
|
|
1773
|
-
/* @__PURE__ */ (0,
|
|
1774
|
-
/* @__PURE__ */ (0,
|
|
2052
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex flex-1 flex-col overflow-hidden", children: [
|
|
2053
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("header", { className: "flex h-14 shrink-0 items-center gap-2 border-b bg-background px-4", children: [
|
|
2054
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
|
|
1775
2055
|
"button",
|
|
1776
2056
|
{
|
|
1777
2057
|
type: "button",
|
|
1778
2058
|
onClick: () => setMobileOpen(true),
|
|
1779
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",
|
|
1780
2060
|
"aria-label": "Abrir menu",
|
|
1781
|
-
children: /* @__PURE__ */ (0,
|
|
2061
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react9.Menu, { className: "h-4 w-4" })
|
|
1782
2062
|
}
|
|
1783
2063
|
),
|
|
1784
|
-
/* @__PURE__ */ (0,
|
|
2064
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "ml-auto flex items-center gap-2", children: [
|
|
1785
2065
|
headerActions,
|
|
1786
|
-
(user || onLogout) && /* @__PURE__ */ (0,
|
|
2066
|
+
(user || onLogout) && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(UserMenu, { user, items: userMenuItems, onLogout, renderLink })
|
|
1787
2067
|
] })
|
|
1788
2068
|
] }),
|
|
1789
|
-
/* @__PURE__ */ (0,
|
|
2069
|
+
/* @__PURE__ */ (0, import_jsx_runtime29.jsx)("main", { className: "flex-1 overflow-y-auto", children })
|
|
1790
2070
|
] })
|
|
1791
2071
|
] });
|
|
1792
2072
|
}
|
|
1793
2073
|
|
|
1794
2074
|
// src/components/row-actions-menu.tsx
|
|
1795
2075
|
var DropdownMenu3 = __toESM(require("@radix-ui/react-dropdown-menu"), 1);
|
|
1796
|
-
var
|
|
2076
|
+
var import_lucide_react10 = require("lucide-react");
|
|
1797
2077
|
var import_react8 = require("react");
|
|
1798
|
-
var
|
|
1799
|
-
var
|
|
2078
|
+
var import_vaul5 = require("vaul");
|
|
2079
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
1800
2080
|
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";
|
|
1801
2081
|
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";
|
|
1802
2082
|
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";
|
|
@@ -1810,20 +2090,20 @@ function RowActionsMenu({
|
|
|
1810
2090
|
const isDesktop = useIsDesktop();
|
|
1811
2091
|
const [open, setOpen] = (0, import_react8.useState)(false);
|
|
1812
2092
|
if (actions.length === 0) return null;
|
|
1813
|
-
const trigger = /* @__PURE__ */ (0,
|
|
2093
|
+
const trigger = /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
1814
2094
|
"button",
|
|
1815
2095
|
{
|
|
1816
2096
|
type: "button",
|
|
1817
2097
|
disabled,
|
|
1818
2098
|
"aria-label": label,
|
|
1819
2099
|
className: triggerClass,
|
|
1820
|
-
children: /* @__PURE__ */ (0,
|
|
2100
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react10.MoreVertical, { className: "h-4 w-4" })
|
|
1821
2101
|
}
|
|
1822
2102
|
);
|
|
1823
2103
|
if (isDesktop) {
|
|
1824
|
-
return /* @__PURE__ */ (0,
|
|
1825
|
-
/* @__PURE__ */ (0,
|
|
1826
|
-
/* @__PURE__ */ (0,
|
|
2104
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(DropdownMenu3.Root, { open, onOpenChange: setOpen, modal: false, children: [
|
|
2105
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(DropdownMenu3.Trigger, { asChild: true, children: trigger }),
|
|
2106
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(DropdownMenu3.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
1827
2107
|
DropdownMenu3.Content,
|
|
1828
2108
|
{
|
|
1829
2109
|
align,
|
|
@@ -1834,7 +2114,7 @@ function RowActionsMenu({
|
|
|
1834
2114
|
itemClass2,
|
|
1835
2115
|
action.destructive && "text-destructive focus:bg-destructive/10"
|
|
1836
2116
|
);
|
|
1837
|
-
return action.href ? /* @__PURE__ */ (0,
|
|
2117
|
+
return action.href ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
1838
2118
|
DropdownMenu3.Item,
|
|
1839
2119
|
{
|
|
1840
2120
|
asChild: true,
|
|
@@ -1842,14 +2122,14 @@ function RowActionsMenu({
|
|
|
1842
2122
|
children: renderLink({
|
|
1843
2123
|
href: action.href,
|
|
1844
2124
|
className: cls,
|
|
1845
|
-
children: /* @__PURE__ */ (0,
|
|
2125
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
|
|
1846
2126
|
action.icon,
|
|
1847
2127
|
action.label
|
|
1848
2128
|
] })
|
|
1849
2129
|
})
|
|
1850
2130
|
},
|
|
1851
2131
|
action.label
|
|
1852
|
-
) : /* @__PURE__ */ (0,
|
|
2132
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
1853
2133
|
DropdownMenu3.Item,
|
|
1854
2134
|
{
|
|
1855
2135
|
className: cls,
|
|
@@ -1867,23 +2147,23 @@ function RowActionsMenu({
|
|
|
1867
2147
|
) })
|
|
1868
2148
|
] });
|
|
1869
2149
|
}
|
|
1870
|
-
return /* @__PURE__ */ (0,
|
|
1871
|
-
/* @__PURE__ */ (0,
|
|
1872
|
-
/* @__PURE__ */ (0,
|
|
1873
|
-
/* @__PURE__ */ (0,
|
|
1874
|
-
/* @__PURE__ */ (0,
|
|
1875
|
-
/* @__PURE__ */ (0,
|
|
1876
|
-
/* @__PURE__ */ (0,
|
|
2150
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_vaul5.Drawer.Root, { open, onOpenChange: setOpen, children: [
|
|
2151
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_vaul5.Drawer.Trigger, { asChild: true, children: trigger }),
|
|
2152
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_vaul5.Drawer.Portal, { children: [
|
|
2153
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_vaul5.Drawer.Overlay, { className: "fixed inset-0 z-50 bg-black/80" }),
|
|
2154
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_vaul5.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: [
|
|
2155
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_vaul5.Drawer.Title, { className: "sr-only", children: label }),
|
|
2156
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "mx-auto my-3 h-1.5 w-12 shrink-0 rounded-full bg-muted" }),
|
|
1877
2157
|
actions.map((action) => {
|
|
1878
2158
|
const cls = cn(
|
|
1879
2159
|
sheetItemClass2,
|
|
1880
2160
|
action.destructive && "text-destructive"
|
|
1881
2161
|
);
|
|
1882
|
-
const inner = /* @__PURE__ */ (0,
|
|
2162
|
+
const inner = /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_jsx_runtime30.Fragment, { children: [
|
|
1883
2163
|
action.icon,
|
|
1884
2164
|
action.label
|
|
1885
2165
|
] });
|
|
1886
|
-
return action.href ? /* @__PURE__ */ (0,
|
|
2166
|
+
return action.href ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
1887
2167
|
"span",
|
|
1888
2168
|
{
|
|
1889
2169
|
onClick: () => setOpen(false),
|
|
@@ -1895,7 +2175,7 @@ function RowActionsMenu({
|
|
|
1895
2175
|
})
|
|
1896
2176
|
},
|
|
1897
2177
|
action.label
|
|
1898
|
-
) : /* @__PURE__ */ (0,
|
|
2178
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
1899
2179
|
"button",
|
|
1900
2180
|
{
|
|
1901
2181
|
type: "button",
|
|
@@ -1968,6 +2248,8 @@ function useCustomToast() {
|
|
|
1968
2248
|
Combobox,
|
|
1969
2249
|
ConfirmDialog,
|
|
1970
2250
|
DataTableWrapper,
|
|
2251
|
+
DatePicker,
|
|
2252
|
+
DateTimePicker,
|
|
1971
2253
|
EmptyState,
|
|
1972
2254
|
FormDialog,
|
|
1973
2255
|
FormDialogLayout,
|