@greatapps/greatauth-ui 0.3.15 → 0.3.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -779,6 +779,7 @@ function SidebarMenuButton({
779
779
  }
780
780
 
781
781
  // src/components/app-sidebar.tsx
782
+ import { useState as useState3, useEffect as useEffect3 } from "react";
782
783
  import { usePathname, useRouter } from "next/navigation";
783
784
  import Link from "next/link";
784
785
  import { ChevronsUpDown, ChevronRight as ChevronRight2, LogOut } from "lucide-react";
@@ -1024,7 +1025,12 @@ function CollapsibleMenuItem({ item, pathname }) {
1024
1025
  const isChildActive = item.children?.some(
1025
1026
  (child) => child.isActive !== void 0 ? child.isActive : pathname.startsWith(child.href)
1026
1027
  ) ?? false;
1027
- return /* @__PURE__ */ jsx12(Collapsible, { defaultOpen: isParentActive || isChildActive, className: "group/collapsible", children: /* @__PURE__ */ jsxs5(SidebarMenuItem, { children: [
1028
+ const isActive = isParentActive || isChildActive;
1029
+ const [open, setOpen] = useState3(isActive);
1030
+ useEffect3(() => {
1031
+ if (isActive) setOpen(true);
1032
+ }, [isActive]);
1033
+ return /* @__PURE__ */ jsx12(Collapsible, { open, onOpenChange: setOpen, className: "group/collapsible", children: /* @__PURE__ */ jsxs5(SidebarMenuItem, { children: [
1028
1034
  /* @__PURE__ */ jsx12(SidebarMenuButton, { asChild: true, isActive: isParentActive, tooltip: item.label, children: /* @__PURE__ */ jsxs5(Link, { href: item.href, onClick: item.onClick, children: [
1029
1035
  /* @__PURE__ */ jsx12(Icon, { className: "size-4" }),
1030
1036
  /* @__PURE__ */ jsx12("span", { children: item.label })
@@ -1075,7 +1081,7 @@ function AppSidebar({ config }) {
1075
1081
  /* @__PURE__ */ jsx12("span", { className: "truncate font-semibold", children: userName }),
1076
1082
  /* @__PURE__ */ jsx12("span", { className: "truncate text-xs text-muted-foreground", children: userEmail })
1077
1083
  ] }),
1078
- /* @__PURE__ */ jsx12(ChevronsUpDown, { className: "ml-auto size-4 group-data-[collapsible=icon]:hidden" })
1084
+ /* @__PURE__ */ jsx12(ChevronsUpDown, { "aria-hidden": "true", className: "ml-auto size-4 group-data-[collapsible=icon]:hidden" })
1079
1085
  ] }) }),
1080
1086
  /* @__PURE__ */ jsxs5(
1081
1087
  DropdownMenuContent,
@@ -1092,7 +1098,7 @@ function AppSidebar({ config }) {
1092
1098
  /* @__PURE__ */ jsx12(DropdownMenuSeparator, {}),
1093
1099
  config.footerExtra,
1094
1100
  /* @__PURE__ */ jsxs5(DropdownMenuItem, { onClick: handleLogout, children: [
1095
- /* @__PURE__ */ jsx12(LogOut, { className: "size-4" }),
1101
+ /* @__PURE__ */ jsx12(LogOut, { "aria-hidden": "true", className: "size-4" }),
1096
1102
  "Sair"
1097
1103
  ] })
1098
1104
  ]
@@ -1239,8 +1245,8 @@ function ThemeToggle() {
1239
1245
  [theme, setTheme]
1240
1246
  );
1241
1247
  return /* @__PURE__ */ jsxs7(Button, { variant: "ghost", size: "icon", onClick: toggleTheme, children: [
1242
- /* @__PURE__ */ jsx14(Sun, { className: "h-5 w-5 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" }),
1243
- /* @__PURE__ */ jsx14(Moon, { className: "absolute h-5 w-5 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" }),
1248
+ /* @__PURE__ */ jsx14(Sun, { "aria-hidden": "true", className: "h-5 w-5 rotate-0 scale-100 transition-transform transition-opacity dark:-rotate-90 dark:scale-0" }),
1249
+ /* @__PURE__ */ jsx14(Moon, { "aria-hidden": "true", className: "absolute h-5 w-5 rotate-90 scale-0 transition-transform transition-opacity dark:rotate-0 dark:scale-100" }),
1244
1250
  /* @__PURE__ */ jsx14("span", { className: "sr-only", children: "Alternar tema" })
1245
1251
  ] });
1246
1252
  }
@@ -1294,7 +1300,7 @@ function AppShell({ config, children, renderAbove }) {
1294
1300
  }
1295
1301
 
1296
1302
  // src/components/login-form.tsx
1297
- import { useState as useState3 } from "react";
1303
+ import { useState as useState4 } from "react";
1298
1304
  import { useRouter as useRouter2, useSearchParams } from "next/navigation";
1299
1305
  import { Loader2, Mail, Lock, AlertCircle, Eye, EyeOff } from "lucide-react";
1300
1306
 
@@ -1324,11 +1330,11 @@ function LoginForm({ config }) {
1324
1330
  const router = useRouter2();
1325
1331
  const searchParams = useSearchParams();
1326
1332
  const callbackUrl = searchParams.get("callbackUrl") || config.callbackUrlDefault;
1327
- const [email, setEmail] = useState3("");
1328
- const [password, setPassword] = useState3("");
1329
- const [loading, setLoading] = useState3(false);
1330
- const [error, setError] = useState3("");
1331
- const [showPassword, setShowPassword] = useState3(false);
1333
+ const [email, setEmail] = useState4("");
1334
+ const [password, setPassword] = useState4("");
1335
+ const [loading, setLoading] = useState4(false);
1336
+ const [error, setError] = useState4("");
1337
+ const [showPassword, setShowPassword] = useState4(false);
1332
1338
  const handleSubmit = async (e) => {
1333
1339
  e.preventDefault();
1334
1340
  if (loading) return;
@@ -1390,17 +1396,18 @@ function LoginForm({ config }) {
1390
1396
  ] }),
1391
1397
  /* @__PURE__ */ jsx18("div", { className: "rounded-xl border bg-card p-6 shadow-sm", children: /* @__PURE__ */ jsxs10("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
1392
1398
  error && /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2 rounded-lg border border-destructive/30 bg-destructive/5 px-3 py-2.5 text-sm text-destructive", children: [
1393
- /* @__PURE__ */ jsx18(AlertCircle, { className: "h-4 w-4 shrink-0" }),
1399
+ /* @__PURE__ */ jsx18(AlertCircle, { "aria-hidden": "true", className: "h-4 w-4 shrink-0" }),
1394
1400
  error
1395
1401
  ] }),
1396
1402
  /* @__PURE__ */ jsxs10("div", { className: "space-y-1.5", children: [
1397
1403
  /* @__PURE__ */ jsx18(Label, { htmlFor: "login-email", className: "text-sm font-medium", children: "Email" }),
1398
1404
  /* @__PURE__ */ jsxs10("div", { className: "relative", children: [
1399
- /* @__PURE__ */ jsx18(Mail, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
1405
+ /* @__PURE__ */ jsx18(Mail, { "aria-hidden": "true", className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
1400
1406
  /* @__PURE__ */ jsx18(
1401
1407
  Input,
1402
1408
  {
1403
1409
  id: "login-email",
1410
+ name: "email",
1404
1411
  type: "email",
1405
1412
  placeholder: "email@exemplo.com",
1406
1413
  value: email,
@@ -1415,11 +1422,12 @@ function LoginForm({ config }) {
1415
1422
  /* @__PURE__ */ jsxs10("div", { className: "space-y-1.5", children: [
1416
1423
  /* @__PURE__ */ jsx18(Label, { htmlFor: "login-password", className: "text-sm font-medium", children: "Senha" }),
1417
1424
  /* @__PURE__ */ jsxs10("div", { className: "relative", children: [
1418
- /* @__PURE__ */ jsx18(Lock, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
1425
+ /* @__PURE__ */ jsx18(Lock, { "aria-hidden": "true", className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
1419
1426
  /* @__PURE__ */ jsx18(
1420
1427
  Input,
1421
1428
  {
1422
1429
  id: "login-password",
1430
+ name: "password",
1423
1431
  type: showPassword ? "text" : "password",
1424
1432
  placeholder: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022",
1425
1433
  value: password,
@@ -1448,8 +1456,8 @@ function LoginForm({ config }) {
1448
1456
  className: cn("w-full", loading && "cursor-wait"),
1449
1457
  disabled: loading,
1450
1458
  children: loading ? /* @__PURE__ */ jsxs10(Fragment3, { children: [
1451
- /* @__PURE__ */ jsx18(Loader2, { className: "h-4 w-4 animate-spin" }),
1452
- "A entrar..."
1459
+ /* @__PURE__ */ jsx18(Loader2, { "aria-hidden": "true", className: "h-4 w-4 animate-spin" }),
1460
+ "A entrar\u2026"
1453
1461
  ] }) : "Entrar"
1454
1462
  }
1455
1463
  )
@@ -1521,7 +1529,7 @@ function EntityAvatar({
1521
1529
  }
1522
1530
 
1523
1531
  // src/components/image-crop-upload.tsx
1524
- import { useCallback as useCallback3, useRef, useState as useState4 } from "react";
1532
+ import { useCallback as useCallback3, useRef, useState as useState5 } from "react";
1525
1533
  import Cropper from "react-easy-crop";
1526
1534
 
1527
1535
  // src/components/ui/dialog.tsx
@@ -1780,12 +1788,12 @@ function ImageCropUpload({
1780
1788
  name,
1781
1789
  disabled = false
1782
1790
  }) {
1783
- const [imageSrc, setImageSrc] = useState4(null);
1784
- const [crop, setCrop] = useState4({ x: 0, y: 0 });
1785
- const [zoom, setZoom] = useState4(1);
1786
- const [croppedArea, setCroppedArea] = useState4(null);
1787
- const [isOpen, setIsOpen] = useState4(false);
1788
- const [isUploading, setIsUploading] = useState4(false);
1791
+ const [imageSrc, setImageSrc] = useState5(null);
1792
+ const [crop, setCrop] = useState5({ x: 0, y: 0 });
1793
+ const [zoom, setZoom] = useState5(1);
1794
+ const [croppedArea, setCroppedArea] = useState5(null);
1795
+ const [isOpen, setIsOpen] = useState5(false);
1796
+ const [isUploading, setIsUploading] = useState5(false);
1789
1797
  const inputRef = useRef(null);
1790
1798
  const onCropComplete = useCallback3((_, croppedAreaPixels) => {
1791
1799
  setCroppedArea(croppedAreaPixels);
@@ -1865,7 +1873,8 @@ function ImageCropUpload({
1865
1873
  type: "button",
1866
1874
  onClick: () => inputRef.current?.click(),
1867
1875
  className: "absolute inset-0 flex items-center justify-center rounded-full bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity cursor-pointer",
1868
- children: /* @__PURE__ */ jsx22(Camera, { className: "h-5 w-5 text-white" })
1876
+ "aria-label": "Alterar foto",
1877
+ children: /* @__PURE__ */ jsx22(Camera, { "aria-hidden": "true", className: "h-5 w-5 text-white" })
1869
1878
  }
1870
1879
  )
1871
1880
  ] }),
@@ -1877,7 +1886,8 @@ function ImageCropUpload({
1877
1886
  accept: "image/png,image/jpeg,image/webp",
1878
1887
  onChange: handleFileSelect,
1879
1888
  className: "hidden",
1880
- disabled
1889
+ disabled,
1890
+ "aria-label": "Selecionar imagem"
1881
1891
  }
1882
1892
  ),
1883
1893
  !disabled && value && /* @__PURE__ */ jsxs14(
@@ -1889,7 +1899,7 @@ function ImageCropUpload({
1889
1899
  onClick: handleRemove,
1890
1900
  className: "text-destructive hover:text-destructive",
1891
1901
  children: [
1892
- /* @__PURE__ */ jsx22(Trash2, { className: "h-4 w-4 mr-1" }),
1902
+ /* @__PURE__ */ jsx22(Trash2, { "aria-hidden": "true", className: "h-4 w-4 mr-1" }),
1893
1903
  "Remover"
1894
1904
  ]
1895
1905
  }
@@ -1942,7 +1952,7 @@ function ImageCropUpload({
1942
1952
  {
1943
1953
  onClick: handleConfirmCrop,
1944
1954
  disabled: isUploading || !croppedArea,
1945
- children: isUploading ? "Enviando..." : "Confirmar"
1955
+ children: isUploading ? "Enviando\u2026" : "Confirmar"
1946
1956
  }
1947
1957
  )
1948
1958
  ] })
@@ -2025,10 +2035,10 @@ function useResetPassword(config) {
2025
2035
  }
2026
2036
 
2027
2037
  // src/components/users/users-page.tsx
2028
- import { useMemo as useMemo4, useState as useState7 } from "react";
2038
+ import { useMemo as useMemo4, useState as useState8 } from "react";
2029
2039
 
2030
2040
  // src/components/users/user-form-dialog.tsx
2031
- import { useEffect as useEffect3, useState as useState5 } from "react";
2041
+ import { useEffect as useEffect4, useState as useState6 } from "react";
2032
2042
 
2033
2043
  // src/components/ui/select.tsx
2034
2044
  import { Select as SelectPrimitive } from "radix-ui";
@@ -2172,13 +2182,13 @@ function UserFormDialog({
2172
2182
  const isEditing = !!user;
2173
2183
  const createUser = useCreateUser(config);
2174
2184
  const updateUser = useUpdateUser(config);
2175
- const [name, setName] = useState5("");
2176
- const [lastName, setLastName] = useState5("");
2177
- const [email, setEmail] = useState5("");
2178
- const [profile, setProfile] = useState5("collaborator");
2179
- const [password, setPassword] = useState5("");
2180
- const [photo, setPhoto] = useState5("");
2181
- useEffect3(() => {
2185
+ const [name, setName] = useState6("");
2186
+ const [lastName, setLastName] = useState6("");
2187
+ const [email, setEmail] = useState6("");
2188
+ const [profile, setProfile] = useState6("collaborator");
2189
+ const [password, setPassword] = useState6("");
2190
+ const [photo, setPhoto] = useState6("");
2191
+ useEffect4(() => {
2182
2192
  if (user) {
2183
2193
  setName(user.name || "");
2184
2194
  setLastName(user.last_name || "");
@@ -2246,25 +2256,25 @@ function UserFormDialog({
2246
2256
  /* @__PURE__ */ jsxs16("div", { className: "grid grid-cols-2 gap-4", children: [
2247
2257
  /* @__PURE__ */ jsxs16("div", { className: "space-y-2", children: [
2248
2258
  /* @__PURE__ */ jsx24(Label, { htmlFor: "user-name", children: "Nome *" }),
2249
- /* @__PURE__ */ jsx24(Input, { id: "user-name", value: name, onChange: (e) => setName(e.target.value), placeholder: "Nome", required: true, disabled: isPending })
2259
+ /* @__PURE__ */ jsx24(Input, { id: "user-name", name: "firstName", value: name, onChange: (e) => setName(e.target.value), placeholder: "Nome", required: true, disabled: isPending })
2250
2260
  ] }),
2251
2261
  /* @__PURE__ */ jsxs16("div", { className: "space-y-2", children: [
2252
2262
  /* @__PURE__ */ jsx24(Label, { htmlFor: "user-lastname", children: "Sobrenome" }),
2253
- /* @__PURE__ */ jsx24(Input, { id: "user-lastname", value: lastName, onChange: (e) => setLastName(e.target.value), placeholder: "Sobrenome", disabled: isPending })
2263
+ /* @__PURE__ */ jsx24(Input, { id: "user-lastname", name: "lastName", value: lastName, onChange: (e) => setLastName(e.target.value), placeholder: "Sobrenome", disabled: isPending })
2254
2264
  ] })
2255
2265
  ] }),
2256
2266
  /* @__PURE__ */ jsxs16("div", { className: "space-y-2", children: [
2257
2267
  /* @__PURE__ */ jsx24(Label, { htmlFor: "user-email", children: "E-mail *" }),
2258
- /* @__PURE__ */ jsx24(Input, { id: "user-email", type: "email", value: email, onChange: (e) => setEmail(e.target.value), placeholder: "email@exemplo.com", required: true, disabled: isPending })
2268
+ /* @__PURE__ */ jsx24(Input, { id: "user-email", name: "email", type: "email", autoComplete: "email", value: email, onChange: (e) => setEmail(e.target.value), placeholder: "email@exemplo.com", required: true, disabled: isPending })
2259
2269
  ] }),
2260
2270
  !isEditing && /* @__PURE__ */ jsxs16("div", { className: "space-y-2", children: [
2261
2271
  /* @__PURE__ */ jsx24(Label, { htmlFor: "user-password", children: "Senha" }),
2262
- /* @__PURE__ */ jsx24(Input, { id: "user-password", type: "password", value: password, onChange: (e) => setPassword(e.target.value), placeholder: "Senha inicial (opcional)", disabled: isPending })
2272
+ /* @__PURE__ */ jsx24(Input, { id: "user-password", name: "password", type: "password", autoComplete: "new-password", value: password, onChange: (e) => setPassword(e.target.value), placeholder: "Senha inicial (opcional)", disabled: isPending })
2263
2273
  ] }),
2264
2274
  /* @__PURE__ */ jsxs16("div", { className: "space-y-2", children: [
2265
- /* @__PURE__ */ jsx24(Label, { children: "Perfil de acesso" }),
2275
+ /* @__PURE__ */ jsx24(Label, { htmlFor: "user-profile", children: "Perfil de acesso" }),
2266
2276
  /* @__PURE__ */ jsxs16(Select, { value: profile, onValueChange: setProfile, disabled: isPending, children: [
2267
- /* @__PURE__ */ jsx24(SelectTrigger, { className: "w-full", children: /* @__PURE__ */ jsx24(SelectValue, {}) }),
2277
+ /* @__PURE__ */ jsx24(SelectTrigger, { id: "user-profile", className: "w-full", children: /* @__PURE__ */ jsx24(SelectValue, {}) }),
2268
2278
  /* @__PURE__ */ jsx24(SelectContent, { children: PROFILE_OPTIONS.map((opt) => /* @__PURE__ */ jsx24(SelectItem, { value: opt.value, children: opt.label }, opt.value)) })
2269
2279
  ] })
2270
2280
  ] }),
@@ -2272,7 +2282,7 @@ function UserFormDialog({
2272
2282
  /* @__PURE__ */ jsxs16(DialogFooter, { children: [
2273
2283
  /* @__PURE__ */ jsx24(Button, { type: "button", variant: "outline", onClick: () => onOpenChange(false), disabled: isPending, children: "Cancelar" }),
2274
2284
  /* @__PURE__ */ jsxs16(Button, { type: "submit", disabled: isPending || !name.trim() || !email.trim(), children: [
2275
- isPending && /* @__PURE__ */ jsx24(Loader22, { className: "mr-2 h-4 w-4 animate-spin" }),
2285
+ isPending && /* @__PURE__ */ jsx24(Loader22, { "aria-hidden": "true", className: "mr-2 h-4 w-4 animate-spin" }),
2276
2286
  isEditing ? "Salvar" : "Criar"
2277
2287
  ] })
2278
2288
  ] })
@@ -2307,7 +2317,7 @@ import {
2307
2317
  getSortedRowModel,
2308
2318
  useReactTable
2309
2319
  } from "@tanstack/react-table";
2310
- import { useState as useState6 } from "react";
2320
+ import { useState as useState7 } from "react";
2311
2321
 
2312
2322
  // src/components/ui/table.tsx
2313
2323
  import { jsx as jsx26 } from "react/jsx-runtime";
@@ -2389,7 +2399,7 @@ function DataTable({
2389
2399
  getRowId,
2390
2400
  compact
2391
2401
  }) {
2392
- const [sorting, setSorting] = useState6([]);
2402
+ const [sorting, setSorting] = useState7([]);
2393
2403
  const table = useReactTable({
2394
2404
  data,
2395
2405
  columns,
@@ -2413,12 +2423,13 @@ function DataTable({
2413
2423
  type: "button",
2414
2424
  className: "flex items-center gap-1 hover:text-foreground -ml-1 px-1 py-0.5 rounded cursor-pointer select-none",
2415
2425
  onClick: header.column.getToggleSortingHandler(),
2426
+ "aria-label": "Ordenar",
2416
2427
  children: [
2417
2428
  flexRender(header.column.columnDef.header, header.getContext()),
2418
2429
  {
2419
- asc: /* @__PURE__ */ jsx27(ArrowUp, { className: "h-3.5 w-3.5" }),
2420
- desc: /* @__PURE__ */ jsx27(ArrowDown, { className: "h-3.5 w-3.5" })
2421
- }[header.column.getIsSorted()] ?? /* @__PURE__ */ jsx27(ArrowUpDown, { className: "h-3.5 w-3.5 text-muted-foreground/50" })
2430
+ asc: /* @__PURE__ */ jsx27(ArrowUp, { "aria-hidden": "true", className: "h-3.5 w-3.5" }),
2431
+ desc: /* @__PURE__ */ jsx27(ArrowDown, { "aria-hidden": "true", className: "h-3.5 w-3.5" })
2432
+ }[header.column.getIsSorted()] ?? /* @__PURE__ */ jsx27(ArrowUpDown, { "aria-hidden": "true", className: "h-3.5 w-3.5 text-muted-foreground/50" })
2422
2433
  ]
2423
2434
  }
2424
2435
  ) : flexRender(header.column.columnDef.header, header.getContext())
@@ -2453,7 +2464,7 @@ function DataTable({
2453
2464
  }) })
2454
2465
  ] }) }),
2455
2466
  showPagination && /* @__PURE__ */ jsxs17("div", { className: "flex items-center justify-between px-2", children: [
2456
- /* @__PURE__ */ jsxs17("p", { className: "text-sm text-muted-foreground", children: [
2467
+ /* @__PURE__ */ jsxs17("p", { className: "text-sm text-muted-foreground tabular-nums", children: [
2457
2468
  total,
2458
2469
  " registro",
2459
2470
  total !== 1 ? "s" : ""
@@ -2467,12 +2478,12 @@ function DataTable({
2467
2478
  onClick: () => onPageChange(page - 1),
2468
2479
  disabled: page <= 1,
2469
2480
  children: [
2470
- /* @__PURE__ */ jsx27(ChevronLeft, { className: "h-4 w-4" }),
2481
+ /* @__PURE__ */ jsx27(ChevronLeft, { "aria-hidden": "true", className: "h-4 w-4" }),
2471
2482
  "Anterior"
2472
2483
  ]
2473
2484
  }
2474
2485
  ),
2475
- /* @__PURE__ */ jsxs17("span", { className: "text-sm text-muted-foreground", children: [
2486
+ /* @__PURE__ */ jsxs17("span", { className: "text-sm text-muted-foreground tabular-nums", children: [
2476
2487
  page,
2477
2488
  " de ",
2478
2489
  totalPages
@@ -2486,7 +2497,7 @@ function DataTable({
2486
2497
  disabled: page >= totalPages,
2487
2498
  children: [
2488
2499
  "Pr\xF3ximo",
2489
- /* @__PURE__ */ jsx27(ChevronRight4, { className: "h-4 w-4" })
2500
+ /* @__PURE__ */ jsx27(ChevronRight4, { "aria-hidden": "true", className: "h-4 w-4" })
2490
2501
  ]
2491
2502
  }
2492
2503
  )
@@ -2682,12 +2693,12 @@ function useColumns(onEdit, onDelete, onResetPassword) {
2682
2693
  {
2683
2694
  accessorKey: "last_login",
2684
2695
  header: "\xDAltimo acesso",
2685
- cell: ({ row }) => /* @__PURE__ */ jsx29("span", { className: "text-muted-foreground text-sm", children: row.original.last_login ? format(new Date(row.original.last_login), "dd/MM/yyyy HH:mm", { locale: ptBR }) : "\u2014" })
2696
+ cell: ({ row }) => /* @__PURE__ */ jsx29("span", { className: "text-muted-foreground text-sm tabular-nums", children: row.original.last_login ? format(new Date(row.original.last_login), "dd/MM/yyyy HH:mm", { locale: ptBR }) : "\u2014" })
2686
2697
  },
2687
2698
  {
2688
2699
  accessorKey: "datetime_add",
2689
2700
  header: "Criado em",
2690
- cell: ({ row }) => /* @__PURE__ */ jsx29("span", { className: "text-muted-foreground text-sm", children: format(new Date(row.original.datetime_add), "dd/MM/yyyy", { locale: ptBR }) })
2701
+ cell: ({ row }) => /* @__PURE__ */ jsx29("span", { className: "text-muted-foreground text-sm tabular-nums", children: format(new Date(row.original.datetime_add), "dd/MM/yyyy", { locale: ptBR }) })
2691
2702
  },
2692
2703
  {
2693
2704
  id: "actions",
@@ -2695,15 +2706,15 @@ function useColumns(onEdit, onDelete, onResetPassword) {
2695
2706
  enableSorting: false,
2696
2707
  cell: ({ row }) => /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-1", children: [
2697
2708
  /* @__PURE__ */ jsxs19(Tooltip, { children: [
2698
- /* @__PURE__ */ jsx29(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx29(Button, { variant: "ghost", size: "icon", className: "h-8 w-8", onClick: () => onResetPassword(row.original), children: /* @__PURE__ */ jsx29(Forward, { className: "h-4 w-4" }) }) }),
2709
+ /* @__PURE__ */ jsx29(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx29(Button, { variant: "ghost", size: "icon", className: "h-8 w-8", onClick: () => onResetPassword(row.original), "aria-label": "Reenviar senha", children: /* @__PURE__ */ jsx29(Forward, { className: "h-4 w-4" }) }) }),
2699
2710
  /* @__PURE__ */ jsx29(TooltipContent, { children: "Resetar senha" })
2700
2711
  ] }),
2701
2712
  /* @__PURE__ */ jsxs19(Tooltip, { children: [
2702
- /* @__PURE__ */ jsx29(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx29(Button, { variant: "ghost", size: "icon", className: "h-8 w-8", onClick: () => onEdit(row.original), children: /* @__PURE__ */ jsx29(Pencil, { className: "h-4 w-4" }) }) }),
2713
+ /* @__PURE__ */ jsx29(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx29(Button, { variant: "ghost", size: "icon", className: "h-8 w-8", onClick: () => onEdit(row.original), "aria-label": "Editar", children: /* @__PURE__ */ jsx29(Pencil, { className: "h-4 w-4" }) }) }),
2703
2714
  /* @__PURE__ */ jsx29(TooltipContent, { children: "Editar" })
2704
2715
  ] }),
2705
2716
  /* @__PURE__ */ jsxs19(Tooltip, { children: [
2706
- /* @__PURE__ */ jsx29(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx29(Button, { variant: "ghost", size: "icon", className: "h-8 w-8 text-destructive hover:text-destructive", onClick: () => onDelete(row.original.id), children: /* @__PURE__ */ jsx29(Trash22, { className: "h-4 w-4" }) }) }),
2717
+ /* @__PURE__ */ jsx29(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx29(Button, { variant: "ghost", size: "icon", className: "h-8 w-8 text-destructive hover:text-destructive", onClick: () => onDelete(row.original.id), "aria-label": "Excluir", children: /* @__PURE__ */ jsx29(Trash22, { className: "h-4 w-4" }) }) }),
2707
2718
  /* @__PURE__ */ jsx29(TooltipContent, { children: "Excluir" })
2708
2719
  ] })
2709
2720
  ] })
@@ -2711,9 +2722,9 @@ function useColumns(onEdit, onDelete, onResetPassword) {
2711
2722
  ];
2712
2723
  }
2713
2724
  function UsersPage({ config, renderPhones }) {
2714
- const [search, setSearch] = useState7("");
2715
- const [profileFilter, setProfileFilter] = useState7("all");
2716
- const [page, setPage] = useState7(1);
2725
+ const [search, setSearch] = useState8("");
2726
+ const [profileFilter, setProfileFilter] = useState8("all");
2727
+ const [page, setPage] = useState8(1);
2717
2728
  const queryParams = useMemo4(() => {
2718
2729
  const params = {
2719
2730
  limit: String(PAGE_SIZE),
@@ -2725,10 +2736,10 @@ function UsersPage({ config, renderPhones }) {
2725
2736
  const { data, isLoading } = useUsers(config, queryParams);
2726
2737
  const deleteUser = useDeleteUser(config);
2727
2738
  const resetPassword = useResetPassword(config);
2728
- const [editUser, setEditUser] = useState7(null);
2729
- const [formOpen, setFormOpen] = useState7(false);
2730
- const [deleteId, setDeleteId] = useState7(null);
2731
- const [resetUser, setResetUser] = useState7(null);
2739
+ const [editUser, setEditUser] = useState8(null);
2740
+ const [formOpen, setFormOpen] = useState8(false);
2741
+ const [deleteId, setDeleteId] = useState8(null);
2742
+ const [resetUser, setResetUser] = useState8(null);
2732
2743
  const users = data?.data || [];
2733
2744
  const total = data?.total || 0;
2734
2745
  const filtered = useMemo4(() => {
@@ -2779,23 +2790,26 @@ function UsersPage({ config, renderPhones }) {
2779
2790
  setEditUser(null);
2780
2791
  setFormOpen(true);
2781
2792
  }, size: "sm", children: [
2782
- /* @__PURE__ */ jsx29(Plus, { className: "mr-2 h-4 w-4" }),
2793
+ /* @__PURE__ */ jsx29(Plus, { "aria-hidden": "true", className: "mr-2 h-4 w-4" }),
2783
2794
  "Novo Usu\xE1rio"
2784
2795
  ] })
2785
2796
  ] }),
2786
2797
  /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-3", children: [
2787
2798
  /* @__PURE__ */ jsxs19("div", { className: "relative flex-1 max-w-md", children: [
2788
- /* @__PURE__ */ jsx29(Search, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
2799
+ /* @__PURE__ */ jsx29(Search, { "aria-hidden": "true", className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
2789
2800
  /* @__PURE__ */ jsx29(
2790
2801
  Input,
2791
2802
  {
2792
- placeholder: "Buscar por nome ou e-mail...",
2803
+ placeholder: "Buscar por nome ou e-mail\\u2026",
2793
2804
  value: search,
2794
2805
  onChange: (e) => {
2795
2806
  setSearch(e.target.value);
2796
2807
  setPage(1);
2797
2808
  },
2798
- className: "pl-9"
2809
+ className: "pl-9",
2810
+ name: "search",
2811
+ autoComplete: "off",
2812
+ "aria-label": "Buscar por nome ou e-mail"
2799
2813
  }
2800
2814
  )
2801
2815
  ] }),