@burdenoff/microfe-auth 2026.916.1 → 2026.917.2

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.
@@ -5,11 +5,12 @@ import { useUserOperations as i } from "../hooks/useUserOperations.js";
5
5
  import { useAuthPermissions as a } from "../hooks/useAuthPermissions.js";
6
6
  import { ConfirmActionDialog as o } from "../components/ConfirmActionDialog.js";
7
7
  import { nativeImpact as s, nativeNotify as c } from "../../utils/nativeBridge.js";
8
- import { useCallback as ee, useEffect as te, useId as l, useState as u } from "react";
9
- import { useNavigate as ne } from "react-router";
8
+ import { validatePhoneNumber as ee, validateUserFields as te } from "../utils/validation.js";
9
+ import { useCallback as ne, useEffect as re, useId as l, useState as u } from "react";
10
+ import { useNavigate as ie } from "react-router";
10
11
  import { Fragment as d, jsx as f, jsxs as p } from "react/jsx-runtime";
11
12
  import { Button as m } from "@burdenoff/fe-libs/button";
12
- import { EmphasisPanel as re, IllustratedEmptyState as h, NextSteps as ie, PagePurpose as ae } from "@burdenoff/fe-libs/ui";
13
+ import { EmphasisPanel as ae, IllustratedEmptyState as h, NextSteps as oe, PagePurpose as se } from "@burdenoff/fe-libs/ui";
13
14
  //#region src/auth/pages/UsersPage.tsx
14
15
  var g = [
15
16
  "TENANT_ADMIN",
@@ -24,11 +25,11 @@ var g = [
24
25
  "DELETED"
25
26
  ];
26
27
  function v() {
27
- let v = t(), oe = ne(), y = e((e) => e.isAuthenticated), se = e((e) => e.user), { canViewUsers: ce, canUpdateUsers: le, canDeleteUsers: b, isLoading: ue } = a(), { listUsers: x, updateUser: de, deleteUser: fe, hardDeleteUser: pe, isLoading: S } = i(), C = l(), w = l(), T = l(), E = l(), me = l(), [D, O] = u(!1), k = async () => {
28
- O(!0);
28
+ let v = t(), ce = ie(), y = e((e) => e.isAuthenticated), le = e((e) => e.user), { canViewUsers: ue, canUpdateUsers: de, canDeleteUsers: b, isLoading: fe } = a(), { listUsers: x, updateUser: pe, deleteUser: me, hardDeleteUser: he, isLoading: S } = i(), C = l(), ge = l(), w = l(), T = l(), _e = l(), [E, D] = u(!1), O = async () => {
29
+ D(!0);
29
30
  try {
30
31
  let e = {};
31
- G && (e.search = G), K && (e.role = K), q && (e.status = q);
32
+ K && (e.search = K), q && (e.role = q), J && (e.status = J);
32
33
  let t = (await x(e, {
33
34
  offset: 0,
34
35
  limit: 1e4
@@ -65,11 +66,11 @@ function v() {
65
66
  ].join(","))], a = new Blob([i.join("\n")], { type: "text/csv;charset=utf-8;" }), o = URL.createObjectURL(a), s = document.createElement("a");
66
67
  s.href = o, s.download = `users-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.csv`, s.click(), URL.revokeObjectURL(o);
67
68
  } catch (e) {
68
- z(e instanceof Error ? e.message : "Failed to export users");
69
+ R(e instanceof Error ? e.message : "Failed to export users");
69
70
  } finally {
70
- O(!1);
71
+ D(!1);
71
72
  }
72
- }, [A, he] = u([]), [j, ge] = u(0), [_e, ve] = u(!1), [M, N] = u("list"), [P, F] = u(null), [I, L] = u({
73
+ }, [k, ve] = u([]), [A, ye] = u(0), [be, xe] = u(!1), [j, M] = u("list"), [N, P] = u(null), [F, I] = u({
73
74
  username: "",
74
75
  firstName: "",
75
76
  lastName: "",
@@ -78,34 +79,34 @@ function v() {
78
79
  role: "MEMBER",
79
80
  status: "ACTIVE",
80
81
  emailVerified: !1
81
- }), [R, z] = u(null), [ye, B] = u(!1), [V, H] = u(null), [U, W] = u(null), [G, be] = u(""), [K, xe] = u(""), [q, Se] = u(""), [J, Y] = u(0), X = ee(async () => {
82
+ }), [L, R] = u(null), [z, B] = u(null), [Se, V] = u(!1), [H, U] = u(null), [W, G] = u(null), [K, Ce] = u(""), [q, we] = u(""), [J, Te] = u(""), [Y, X] = u(0), Z = ne(async () => {
82
83
  if (y) try {
83
- B(!1);
84
+ V(!1);
84
85
  let e = {};
85
- G && (e.search = G), K && (e.role = K), q && (e.status = q);
86
+ K && (e.search = K), q && (e.role = q), J && (e.status = J);
86
87
  let t = await x(e, {
87
- offset: J * 10,
88
+ offset: Y * 10,
88
89
  limit: 10
89
90
  });
90
- he(t.users), ge(t.totalCount), ve(t.hasMore), z(null);
91
+ ve(t.users), ye(t.totalCount), xe(t.hasMore), R(null);
91
92
  } catch (e) {
92
93
  if (e instanceof Error && (e.name === "AbortError" || e.message.includes("aborted"))) return;
93
94
  let t = e instanceof Error ? e.message : "Failed to fetch users";
94
- t.toLowerCase().includes("not authorized") || t.toLowerCase().includes("forbidden") ? (B(!0), z(null)) : z(t);
95
+ t.toLowerCase().includes("not authorized") || t.toLowerCase().includes("forbidden") ? (V(!0), R(null)) : R(t);
95
96
  }
96
97
  }, [
97
98
  x,
98
- G,
99
99
  K,
100
100
  q,
101
101
  J,
102
+ Y,
102
103
  y
103
104
  ]);
104
- te(() => {
105
- X();
106
- }, [X]);
107
- let Z = () => {
108
- L({
105
+ re(() => {
106
+ Z();
107
+ }, [Z]);
108
+ let Q = () => {
109
+ I({
109
110
  username: "",
110
111
  firstName: "",
111
112
  lastName: "",
@@ -114,42 +115,50 @@ function v() {
114
115
  role: "MEMBER",
115
116
  status: "ACTIVE",
116
117
  emailVerified: !1
117
- }), F(null), z(null), H(null);
118
- }, Ce = async (e) => {
119
- if (e.preventDefault(), P) {
120
- z(null);
121
- try {
122
- await de(P.id, {
123
- username: I.username || void 0,
124
- firstName: I.firstName || void 0,
125
- lastName: I.lastName || void 0,
126
- name: I.name || void 0,
127
- phoneNumber: I.phoneNumber || void 0,
128
- role: I.role,
129
- status: I.status,
130
- emailVerified: I.emailVerified
131
- }), H(v("auth.users.updateSuccess", "User updated successfully!")), N("list"), Z(), X();
132
- } catch (e) {
133
- z(e instanceof Error ? e.message : "Failed to update user");
134
- }
118
+ }), P(null), R(null), B(null), U(null);
119
+ }, Ee = async (e) => {
120
+ if (e.preventDefault(), !N) return;
121
+ if (R(null), B(null), !ee(F.phoneNumber).valid) {
122
+ let e = v("auth.users.phoneNumber_invalid", "Invalid phone number");
123
+ B(e), R(e);
124
+ return;
125
+ }
126
+ let t = te(F, { requireAll: !1 });
127
+ if (!t.valid) {
128
+ R(t.errors.map((e) => v(`auth.users.${e.field}_${e.code}`, e.message)).join(" · "));
129
+ return;
130
+ }
131
+ try {
132
+ await pe(N.id, {
133
+ username: t.values.username || void 0,
134
+ firstName: t.values.firstName || void 0,
135
+ lastName: t.values.lastName || void 0,
136
+ name: F.name || void 0,
137
+ phoneNumber: F.phoneNumber || void 0,
138
+ role: F.role,
139
+ status: F.status,
140
+ emailVerified: F.emailVerified
141
+ }), U(v("auth.users.updateSuccess", "User updated successfully!")), M("list"), Q(), Z();
142
+ } catch (e) {
143
+ R(e instanceof Error ? e.message : "Failed to update user");
135
144
  }
136
- }, we = async (e) => {
145
+ }, De = async (e) => {
137
146
  s("medium");
138
147
  try {
139
- let t = await fe(e.id);
140
- t.success ? (c("success"), H(v("auth.users.userDeactivated", "User \"{email}\" has been deactivated.").replace("{email}", e.email)), W(null), X()) : (c("error"), z(t.message));
148
+ let t = await me(e.id);
149
+ t.success ? (c("success"), U(v("auth.users.userDeactivated", "User \"{email}\" has been deactivated.").replace("{email}", e.email)), G(null), Z()) : (c("error"), R(t.message));
141
150
  } catch (e) {
142
- c("error"), z(e instanceof Error ? e.message : "Failed to delete user");
151
+ c("error"), R(e instanceof Error ? e.message : "Failed to delete user");
143
152
  }
144
- }, Te = async (e) => {
153
+ }, Oe = async (e) => {
145
154
  try {
146
- let t = await pe(e.id);
147
- t.success ? (H(v("auth.users.userPermanentlyDeleted", "User \"{email}\" has been permanently deleted.").replace("{email}", e.email)), W(null), X()) : z(t.message);
155
+ let t = await he(e.id);
156
+ t.success ? (U(v("auth.users.userPermanentlyDeleted", "User \"{email}\" has been permanently deleted.").replace("{email}", e.email)), G(null), Z()) : R(t.message);
148
157
  } catch (e) {
149
- z(e instanceof Error ? e.message : "Failed to hard delete user");
158
+ R(e instanceof Error ? e.message : "Failed to hard delete user");
150
159
  }
151
- }, Q = (e) => {
152
- F(e), L({
160
+ }, ke = (e) => {
161
+ P(e), I({
153
162
  username: e.username || "",
154
163
  firstName: e.firstName || "",
155
164
  lastName: e.lastName || "",
@@ -158,26 +167,26 @@ function v() {
158
167
  role: e.role,
159
168
  status: e.status,
160
169
  emailVerified: e.emailVerified
161
- }), N("edit"), z(null);
170
+ }), M("edit"), R(null);
162
171
  }, $ = /* @__PURE__ */ f(o, {
163
- open: U !== null,
172
+ open: W !== null,
164
173
  onOpenChange: (e) => {
165
- e || W(null);
174
+ e || G(null);
166
175
  },
167
- title: U?.type === "hard-delete" ? v("auth.users.hardDeleteTitle", "Permanently delete user?") : v("auth.users.deactivateTitle", "Deactivate user?"),
168
- description: U?.type === "hard-delete" ? U ? v("auth.users.hardDeleteDesc", "This permanently deletes \"{email}\" and cannot be undone.").replace("{email}", U.user.email) : "" : U ? v("auth.users.deactivateDesc", "\"{email}\" will be prevented from signing in until reactivated.").replace("{email}", U.user.email) : "",
169
- confirmText: U?.type === "hard-delete" ? v("auth.users.hardDeleteConfirm", "Delete permanently") : v("auth.users.deactivateConfirm", "Deactivate user"),
170
- variant: U?.type === "hard-delete" ? "danger" : "warning",
176
+ title: W?.type === "hard-delete" ? v("auth.users.hardDeleteTitle", "Permanently delete user?") : v("auth.users.deactivateTitle", "Deactivate user?"),
177
+ description: W?.type === "hard-delete" ? W ? v("auth.users.hardDeleteDesc", "This permanently deletes \"{email}\" and cannot be undone.").replace("{email}", W.user.email) : "" : W ? v("auth.users.deactivateDesc", "\"{email}\" will be prevented from signing in until reactivated.").replace("{email}", W.user.email) : "",
178
+ confirmText: W?.type === "hard-delete" ? v("auth.users.hardDeleteConfirm", "Delete permanently") : v("auth.users.deactivateConfirm", "Deactivate user"),
179
+ variant: W?.type === "hard-delete" ? "danger" : "warning",
171
180
  onConfirm: async () => {
172
- if (U) {
173
- if (U.type === "hard-delete") {
174
- await Te(U.user);
181
+ if (W) {
182
+ if (W.type === "hard-delete") {
183
+ await Oe(W.user);
175
184
  return;
176
185
  }
177
- await we(U.user);
186
+ await De(W.user);
178
187
  }
179
188
  }
180
- }), Ee = (e) => {
189
+ }), Ae = (e) => {
181
190
  switch (e) {
182
191
  case "SUPER_ADMIN": return "bg-accent-purple-subtle text-accent-purple";
183
192
  case "TENANT_ADMIN": return "bg-status-info-bg-subtle text-status-info-text";
@@ -187,7 +196,7 @@ function v() {
187
196
  case "GUEST": return "bg-bg-sunken text-text-primary";
188
197
  default: return "bg-bg-sunken text-text-primary";
189
198
  }
190
- }, De = (e) => {
199
+ }, je = (e) => {
191
200
  switch (e) {
192
201
  case "ACTIVE": return "bg-status-success-bg-subtle text-status-success-text";
193
202
  case "INACTIVE": return "bg-status-warning-bg-subtle text-status-warning-text";
@@ -196,7 +205,7 @@ function v() {
196
205
  default: return "bg-bg-sunken text-text-primary";
197
206
  }
198
207
  };
199
- return y ? ue ? /* @__PURE__ */ f("div", {
208
+ return y ? fe ? /* @__PURE__ */ f("div", {
200
209
  className: "max-w-6xl mx-auto p-6",
201
210
  children: /* @__PURE__ */ p("div", {
202
211
  className: "text-center py-16",
@@ -205,7 +214,7 @@ function v() {
205
214
  children: v("auth.users.loadingPermissions", "Loading permissions...")
206
215
  })]
207
216
  })
208
- }) : !ce || ye ? /* @__PURE__ */ f("div", {
217
+ }) : !ue || Se ? /* @__PURE__ */ f("div", {
209
218
  className: "max-w-6xl mx-auto p-6",
210
219
  children: /* @__PURE__ */ f(h, {
211
220
  illustration: "empty-generic",
@@ -216,7 +225,7 @@ function v() {
216
225
  v("auth.users.requiredRoles", "Required roles: Super Admin, Tenant Admin, or Org Admin")
217
226
  ] })
218
227
  })
219
- }) : M === "list" ? /* @__PURE__ */ p("div", {
228
+ }) : j === "list" ? /* @__PURE__ */ p("div", {
220
229
  className: "max-w-6xl mx-auto p-6",
221
230
  children: [
222
231
  $,
@@ -230,18 +239,18 @@ function v() {
230
239
  children: [
231
240
  v("auth.users.subtitle", "Manage users in your organization"),
232
241
  " (",
233
- j,
242
+ A,
234
243
  " ",
235
244
  v("auth.users.paginationUsers", "total"),
236
245
  ")"
237
246
  ]
238
247
  })] }), /* @__PURE__ */ f("button", {
239
248
  type: "button",
240
- onClick: () => void k(),
241
- disabled: D,
249
+ onClick: () => void O(),
250
+ disabled: E,
242
251
  "aria-label": v("auth.users.exportAriaLabel", "Export user list"),
243
252
  className: "flex items-center gap-2 px-4 py-2.5 rounded-xl border border-border-default text-text-primary bg-bg-surface hover:bg-bg-sunken disabled:opacity-50 disabled:cursor-not-allowed transition-colors font-medium",
244
- children: D ? /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f(r, {
253
+ children: E ? /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f(r, {
245
254
  className: "size-4 animate-spin",
246
255
  "aria-hidden": "true"
247
256
  }), v("auth.users.exporting", "Exporting...")] }) : /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f("svg", {
@@ -259,11 +268,11 @@ function v() {
259
268
  }), v("auth.users.export", "Export")] })
260
269
  })]
261
270
  }),
262
- /* @__PURE__ */ f(ae, {
271
+ /* @__PURE__ */ f(se, {
263
272
  className: "mb-6",
264
273
  children: v("auth.users.purpose", "Manage everyone with access to your organization. Search and filter accounts, review their role and status, edit details, or deactivate people who should no longer have access.")
265
274
  }),
266
- /* @__PURE__ */ p(re, {
275
+ /* @__PURE__ */ p(ae, {
267
276
  className: "mb-6",
268
277
  children: [
269
278
  /* @__PURE__ */ f("p", {
@@ -272,7 +281,7 @@ function v() {
272
281
  }),
273
282
  /* @__PURE__ */ f("p", {
274
283
  className: "mt-1 text-3xl font-semibold text-text-primary",
275
- children: j
284
+ children: A
276
285
  }),
277
286
  /* @__PURE__ */ f("p", {
278
287
  className: "mt-1 text-sm text-text-secondary",
@@ -284,30 +293,30 @@ function v() {
284
293
  "aria-live": "polite",
285
294
  "aria-atomic": "true",
286
295
  className: "sr-only",
287
- children: V
296
+ children: H
288
297
  }),
289
298
  /* @__PURE__ */ f("div", {
290
299
  role: "alert",
291
300
  "aria-live": "assertive",
292
301
  "aria-atomic": "true",
293
302
  className: "sr-only",
294
- children: R
303
+ children: L
295
304
  }),
296
- V && /* @__PURE__ */ p("output", {
297
- id: me,
305
+ H && /* @__PURE__ */ p("output", {
306
+ id: _e,
298
307
  className: "block mb-6 p-4 rounded-xl bg-status-success-bg-subtle border border-status-success-border",
299
308
  children: [/* @__PURE__ */ f("p", {
300
309
  className: "text-status-success-text",
301
- children: V
310
+ children: H
302
311
  }), /* @__PURE__ */ f("button", {
303
312
  type: "button",
304
- onClick: () => H(null),
313
+ onClick: () => U(null),
305
314
  className: "mt-2 text-sm text-status-success-text hover:underline",
306
315
  children: v("auth.users.dismiss", "Dismiss")
307
316
  })]
308
317
  }),
309
- R && /* @__PURE__ */ p("div", {
310
- id: E,
318
+ L && /* @__PURE__ */ p("div", {
319
+ id: T,
311
320
  role: "alert",
312
321
  className: "mb-6 flex items-start gap-3 p-4 rounded-xl bg-status-error-bg-subtle border border-status-error-border",
313
322
  children: [/* @__PURE__ */ f(n, {
@@ -317,10 +326,10 @@ function v() {
317
326
  className: "flex-1",
318
327
  children: [/* @__PURE__ */ f("p", {
319
328
  className: "text-sm text-status-error-text",
320
- children: R
329
+ children: L
321
330
  }), /* @__PURE__ */ f("button", {
322
331
  type: "button",
323
- onClick: () => z(null),
332
+ onClick: () => R(null),
324
333
  className: "mt-2 text-sm text-status-error-text hover:underline",
325
334
  children: v("auth.users.dismiss", "Dismiss")
326
335
  })]
@@ -342,22 +351,22 @@ function v() {
342
351
  type: "search",
343
352
  "aria-label": v("auth.users.searchLabel", "Search users"),
344
353
  placeholder: v("auth.users.searchPlaceholder", "Search by email, username, or name..."),
345
- value: G,
354
+ value: K,
346
355
  onChange: (e) => {
347
- be(e.target.value), Y(0);
356
+ Ce(e.target.value), X(0);
348
357
  },
349
358
  className: "w-full px-4 py-2.5 border border-border-default rounded-xl bg-bg-surface text-text-primary placeholder-text-tertiary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all"
350
359
  })]
351
360
  }),
352
361
  /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
353
- htmlFor: w,
362
+ htmlFor: ge,
354
363
  className: "sr-only",
355
364
  children: v("auth.users.filterRoleLabel", "Filter by role")
356
365
  }), /* @__PURE__ */ p("select", {
357
- id: w,
358
- value: K,
366
+ id: ge,
367
+ value: q,
359
368
  onChange: (e) => {
360
- xe(e.target.value), Y(0);
369
+ we(e.target.value), X(0);
361
370
  },
362
371
  className: "px-4 py-2.5 border border-border-default rounded-xl bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all",
363
372
  children: [/* @__PURE__ */ f("option", {
@@ -369,14 +378,14 @@ function v() {
369
378
  }, e))]
370
379
  })] }),
371
380
  /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
372
- htmlFor: T,
381
+ htmlFor: w,
373
382
  className: "sr-only",
374
383
  children: v("auth.users.filterStatusLabel", "Filter by status")
375
384
  }), /* @__PURE__ */ p("select", {
376
- id: T,
377
- value: q,
385
+ id: w,
386
+ value: J,
378
387
  onChange: (e) => {
379
- Se(e.target.value), Y(0);
388
+ Te(e.target.value), X(0);
380
389
  },
381
390
  className: "px-4 py-2.5 border border-border-default rounded-xl bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all",
382
391
  children: [/* @__PURE__ */ f("option", {
@@ -401,10 +410,10 @@ function v() {
401
410
  className: "ml-3 text-text-secondary",
402
411
  children: v("auth.users.loadingUsers", "Loading users...")
403
412
  })]
404
- }) : A.length === 0 ? /* @__PURE__ */ f(h, {
405
- illustration: G || K || q ? "empty-search" : "empty-people",
413
+ }) : k.length === 0 ? /* @__PURE__ */ f(h, {
414
+ illustration: K || q || J ? "empty-search" : "empty-people",
406
415
  title: v("auth.users.noUsersFound", "No users found"),
407
- description: G || K || q ? v("auth.users.noUsersFilteredDesc", "No users match your current search or filters. Try clearing them to see everyone.") : v("auth.users.noUsersDesc", "Once people join your organization they'll show up here for you to manage.")
416
+ description: K || q || J ? v("auth.users.noUsersFilteredDesc", "No users match your current search or filters. Try clearing them to see everyone.") : v("auth.users.noUsersDesc", "Once people join your organization they'll show up here for you to manage.")
408
417
  }) : /* @__PURE__ */ p(d, { children: [
409
418
  /* @__PURE__ */ f("div", {
410
419
  className: "rounded-xl border border-border-subtle bg-bg-surface overflow-hidden shadow-sm",
@@ -447,7 +456,7 @@ function v() {
447
456
  children: v("auth.users.columnActions", "Actions")
448
457
  })
449
458
  ]
450
- }) }), /* @__PURE__ */ f("tbody", { children: A.map((e) => /* @__PURE__ */ p("tr", {
459
+ }) }), /* @__PURE__ */ f("tbody", { children: k.map((e) => /* @__PURE__ */ p("tr", {
451
460
  className: "border-b border-border-subtle last:border-b-0 hover:bg-bg-sunken/50 transition-colors",
452
461
  children: [
453
462
  /* @__PURE__ */ f("td", {
@@ -472,14 +481,14 @@ function v() {
472
481
  /* @__PURE__ */ f("td", {
473
482
  className: "p-4",
474
483
  children: /* @__PURE__ */ f("span", {
475
- className: `inline-block px-2.5 py-1 rounded-full text-xs font-medium whitespace-nowrap ${Ee(e.role)}`,
484
+ className: `inline-block px-2.5 py-1 rounded-full text-xs font-medium whitespace-nowrap ${Ae(e.role)}`,
476
485
  children: e.role.replace("_", " ")
477
486
  })
478
487
  }),
479
488
  /* @__PURE__ */ f("td", {
480
489
  className: "p-4",
481
490
  children: /* @__PURE__ */ f("span", {
482
- className: `inline-block px-2.5 py-1 rounded-full text-xs font-medium whitespace-nowrap ${De(e.status)}`,
491
+ className: `inline-block px-2.5 py-1 rounded-full text-xs font-medium whitespace-nowrap ${je(e.status)}`,
483
492
  children: e.status
484
493
  })
485
494
  }),
@@ -528,21 +537,21 @@ function v() {
528
537
  children: [
529
538
  /* @__PURE__ */ f("button", {
530
539
  type: "button",
531
- onClick: () => oe(`/auth/users/${e.id}`),
540
+ onClick: () => ce(`/auth/users/${e.id}`),
532
541
  "aria-label": `${v("auth.users.actionView", "View")} ${e.name || e.username || e.email}`,
533
542
  className: "px-2.5 py-1.5 rounded-lg text-xs font-medium border border-border-default text-text-primary bg-bg-surface hover:bg-bg-sunken transition-colors whitespace-nowrap flex-shrink-0",
534
543
  children: v("auth.users.actionView", "View")
535
544
  }),
536
- le && /* @__PURE__ */ f("button", {
545
+ de && /* @__PURE__ */ f("button", {
537
546
  type: "button",
538
- onClick: () => Q(e),
547
+ onClick: () => ke(e),
539
548
  "aria-label": `${v("auth.users.actionEdit", "Edit")} ${e.name || e.username || e.email}`,
540
549
  className: "px-2.5 py-1.5 rounded-lg text-xs font-medium border border-status-info-border text-text-link bg-bg-surface hover:bg-status-info-bg-subtle transition-colors whitespace-nowrap flex-shrink-0",
541
550
  children: v("auth.users.actionEdit", "Edit")
542
551
  }),
543
552
  b && e.status !== "DELETED" && /* @__PURE__ */ f("button", {
544
553
  type: "button",
545
- onClick: () => W({
554
+ onClick: () => G({
546
555
  type: "deactivate",
547
556
  user: e
548
557
  }),
@@ -565,15 +574,15 @@ function v() {
565
574
  children: [
566
575
  v("auth.users.showing", "Showing"),
567
576
  " ",
568
- J * 10 + 1,
577
+ Y * 10 + 1,
569
578
  " ",
570
579
  v("auth.users.to", "to"),
571
580
  " ",
572
- Math.min((J + 1) * 10, j),
581
+ Math.min((Y + 1) * 10, A),
573
582
  " ",
574
583
  v("auth.users.of", "of"),
575
584
  " ",
576
- j,
585
+ A,
577
586
  " ",
578
587
  v("auth.users.paginationUsers", "users")
579
588
  ]
@@ -583,15 +592,15 @@ function v() {
583
592
  className: "flex gap-2",
584
593
  children: [/* @__PURE__ */ f("button", {
585
594
  type: "button",
586
- onClick: () => Y((e) => Math.max(0, e - 1)),
587
- disabled: J === 0,
595
+ onClick: () => X((e) => Math.max(0, e - 1)),
596
+ disabled: Y === 0,
588
597
  "aria-label": v("auth.users.previousPageAriaLabel", "Go to previous page"),
589
598
  className: "px-4 py-2 rounded-lg border border-border-default text-text-primary bg-bg-surface disabled:opacity-50 disabled:cursor-not-allowed hover:bg-bg-sunken transition-colors",
590
599
  children: v("auth.users.previousPage", "Previous")
591
600
  }), /* @__PURE__ */ f("button", {
592
601
  type: "button",
593
- onClick: () => Y((e) => e + 1),
594
- disabled: !_e,
602
+ onClick: () => X((e) => e + 1),
603
+ disabled: !be,
595
604
  "aria-label": v("auth.users.nextPageAriaLabel", "Go to next page"),
596
605
  className: "px-4 py-2 rounded-lg border border-border-default text-text-primary bg-bg-surface disabled:opacity-50 disabled:cursor-not-allowed hover:bg-bg-sunken transition-colors",
597
606
  children: v("auth.users.nextPage", "Next")
@@ -599,7 +608,7 @@ function v() {
599
608
  })
600
609
  })]
601
610
  }),
602
- /* @__PURE__ */ f(ie, {
611
+ /* @__PURE__ */ f(oe, {
603
612
  className: "mt-8",
604
613
  storageKey: "auth-users",
605
614
  steps: [{
@@ -614,19 +623,19 @@ function v() {
614
623
  id: "export-users",
615
624
  label: v("auth.users.nextExport", "Export the user list"),
616
625
  description: v("auth.users.nextExportDesc", "Download a CSV of users matching your current filters."),
617
- onClick: () => void k()
626
+ onClick: () => void O()
618
627
  }]
619
628
  })
620
629
  ] })
621
630
  ]
622
- }) : M === "view" && P ? /* @__PURE__ */ p("div", {
631
+ }) : j === "view" && N ? /* @__PURE__ */ p("div", {
623
632
  className: "max-w-4xl mx-auto p-6",
624
633
  children: [
625
634
  $,
626
635
  /* @__PURE__ */ p("button", {
627
636
  type: "button",
628
637
  onClick: () => {
629
- N("list"), Z();
638
+ M("list"), Q();
630
639
  },
631
640
  className: "mb-6 flex items-center gap-2 text-text-link hover:underline font-medium",
632
641
  children: [/* @__PURE__ */ f("svg", {
@@ -649,24 +658,24 @@ function v() {
649
658
  className: "flex items-center gap-4 mb-8",
650
659
  children: [/* @__PURE__ */ f("div", {
651
660
  className: "auth-brand-badge flex size-20 items-center justify-center rounded-full text-3xl font-semibold",
652
- children: (P.name || P.username || P.email).charAt(0).toUpperCase()
661
+ children: (N.name || N.username || N.email).charAt(0).toUpperCase()
653
662
  }), /* @__PURE__ */ p("div", { children: [
654
663
  /* @__PURE__ */ f("h1", {
655
664
  className: "text-2xl font-semibold text-text-primary",
656
- children: P.name || P.username
665
+ children: N.name || N.username
657
666
  }),
658
667
  /* @__PURE__ */ f("p", {
659
668
  className: "text-text-secondary",
660
- children: P.email
669
+ children: N.email
661
670
  }),
662
671
  /* @__PURE__ */ p("div", {
663
672
  className: "flex items-center gap-2 mt-2",
664
673
  children: [/* @__PURE__ */ f("span", {
665
- className: `px-2.5 py-1 rounded-full text-xs font-medium ${Ee(P.role)}`,
666
- children: P.role.replace("_", " ")
674
+ className: `px-2.5 py-1 rounded-full text-xs font-medium ${Ae(N.role)}`,
675
+ children: N.role.replace("_", " ")
667
676
  }), /* @__PURE__ */ f("span", {
668
- className: `px-2.5 py-1 rounded-full text-xs font-medium ${De(P.status)}`,
669
- children: P.status
677
+ className: `px-2.5 py-1 rounded-full text-xs font-medium ${je(N.status)}`,
678
+ children: N.status
670
679
  })]
671
680
  })
672
681
  ] })]
@@ -681,7 +690,7 @@ function v() {
681
690
  children: v("auth.users.viewDetailsUsername", "Username")
682
691
  }), /* @__PURE__ */ f("p", {
683
692
  className: "text-text-primary font-medium",
684
- children: P.username
693
+ children: N.username
685
694
  })]
686
695
  }),
687
696
  /* @__PURE__ */ p("div", {
@@ -691,7 +700,7 @@ function v() {
691
700
  children: v("auth.users.viewDetailsEmail", "Email")
692
701
  }), /* @__PURE__ */ f("p", {
693
702
  className: "text-text-primary font-medium",
694
- children: P.email
703
+ children: N.email
695
704
  })]
696
705
  }),
697
706
  /* @__PURE__ */ p("div", {
@@ -701,7 +710,7 @@ function v() {
701
710
  children: v("auth.users.viewDetailsEmailVerified", "Email Verified")
702
711
  }), /* @__PURE__ */ f("p", {
703
712
  className: "text-text-primary font-medium",
704
- children: P.emailVerified ? /* @__PURE__ */ f("span", {
713
+ children: N.emailVerified ? /* @__PURE__ */ f("span", {
705
714
  className: "text-status-success-text",
706
715
  children: v("auth.users.verifiedYes", "Yes")
707
716
  }) : /* @__PURE__ */ f("span", {
@@ -717,7 +726,7 @@ function v() {
717
726
  children: v("auth.users.viewDetailsMfaEnabled", "MFA Enabled")
718
727
  }), /* @__PURE__ */ f("p", {
719
728
  className: "text-text-primary font-medium",
720
- children: P.mfaEnabled ? /* @__PURE__ */ f("span", {
729
+ children: N.mfaEnabled ? /* @__PURE__ */ f("span", {
721
730
  className: "text-status-success-text",
722
731
  children: v("auth.users.verifiedYes", "Yes")
723
732
  }) : /* @__PURE__ */ f("span", {
@@ -726,14 +735,14 @@ function v() {
726
735
  })
727
736
  })]
728
737
  }),
729
- P.phoneNumber && /* @__PURE__ */ p("div", {
738
+ N.phoneNumber && /* @__PURE__ */ p("div", {
730
739
  className: "p-4 rounded-lg bg-bg-canvas/50",
731
740
  children: [/* @__PURE__ */ f("label", {
732
741
  className: "block text-sm font-medium text-text-secondary mb-1",
733
742
  children: v("auth.users.viewDetailsPhoneNumber", "Phone Number")
734
743
  }), /* @__PURE__ */ f("p", {
735
744
  className: "text-text-primary font-medium",
736
- children: P.phoneNumber
745
+ children: N.phoneNumber
737
746
  })]
738
747
  }),
739
748
  /* @__PURE__ */ p("div", {
@@ -743,7 +752,7 @@ function v() {
743
752
  children: v("auth.users.viewDetailsLastLogin", "Last Login")
744
753
  }), /* @__PURE__ */ f("p", {
745
754
  className: "text-text-primary font-medium",
746
- children: P.lastLoginAt ? new Date(P.lastLoginAt).toLocaleString() : v("auth.users.lastLoginNever", "Never")
755
+ children: N.lastLoginAt ? new Date(N.lastLoginAt).toLocaleString() : v("auth.users.lastLoginNever", "Never")
747
756
  })]
748
757
  }),
749
758
  /* @__PURE__ */ p("div", {
@@ -753,7 +762,7 @@ function v() {
753
762
  children: v("auth.users.viewDetailsCreated", "Created")
754
763
  }), /* @__PURE__ */ f("p", {
755
764
  className: "text-text-primary font-medium",
756
- children: new Date(P.createdAt).toLocaleString()
765
+ children: new Date(N.createdAt).toLocaleString()
757
766
  })]
758
767
  }),
759
768
  /* @__PURE__ */ p("div", {
@@ -763,7 +772,7 @@ function v() {
763
772
  children: v("auth.users.viewDetailsLastUpdated", "Last Updated")
764
773
  }), /* @__PURE__ */ f("p", {
765
774
  className: "text-text-primary font-medium",
766
- children: new Date(P.updatedAt).toLocaleString()
775
+ children: new Date(N.updatedAt).toLocaleString()
767
776
  })]
768
777
  })
769
778
  ]
@@ -773,25 +782,25 @@ function v() {
773
782
  children: [
774
783
  /* @__PURE__ */ f(m, {
775
784
  type: "button",
776
- onClick: () => Q(P),
785
+ onClick: () => ke(N),
777
786
  variant: "default",
778
787
  className: "font-semibold",
779
788
  children: v("auth.users.editUser", "Edit User")
780
789
  }),
781
- P.status !== "DELETED" && /* @__PURE__ */ f("button", {
790
+ N.status !== "DELETED" && /* @__PURE__ */ f("button", {
782
791
  type: "button",
783
- onClick: () => W({
792
+ onClick: () => G({
784
793
  type: "deactivate",
785
- user: P
794
+ user: N
786
795
  }),
787
796
  className: "px-4 py-2.5 rounded-xl border border-status-error-border text-status-error-text font-medium hover:bg-status-error-bg-subtle transition-colors",
788
797
  children: v("auth.users.deleteUser", "Delete User")
789
798
  }),
790
- b && P.status === "DELETED" && se?.role === "SUPER_ADMIN" && /* @__PURE__ */ f("button", {
799
+ b && N.status === "DELETED" && le?.role === "SUPER_ADMIN" && /* @__PURE__ */ f("button", {
791
800
  type: "button",
792
- onClick: () => W({
801
+ onClick: () => G({
793
802
  type: "hard-delete",
794
- user: P
803
+ user: N
795
804
  }),
796
805
  className: "px-4 py-2.5 rounded-xl bg-status-error-bg text-white font-medium hover:bg-status-error-bg-hover transition-colors",
797
806
  children: v("auth.users.permanentlyDelete", "Permanently Delete")
@@ -808,7 +817,7 @@ function v() {
808
817
  /* @__PURE__ */ p("button", {
809
818
  type: "button",
810
819
  onClick: () => {
811
- N("list"), Z();
820
+ M("list"), Q();
812
821
  },
813
822
  className: "mb-6 flex items-center gap-2 text-text-link hover:underline font-medium",
814
823
  children: [/* @__PURE__ */ f("svg", {
@@ -831,28 +840,28 @@ function v() {
831
840
  className: "text-2xl font-semibold text-text-primary mb-2",
832
841
  children: v("auth.users.editUser", "Edit User")
833
842
  }),
834
- P && /* @__PURE__ */ p("p", {
843
+ N && /* @__PURE__ */ p("p", {
835
844
  className: "text-text-secondary mb-6",
836
845
  children: [
837
846
  v("auth.users.editingUser", "Editing:"),
838
847
  " ",
839
- /* @__PURE__ */ f("strong", { children: P.email })
848
+ /* @__PURE__ */ f("strong", { children: N.email })
840
849
  ]
841
850
  }),
842
- R && /* @__PURE__ */ p("div", {
851
+ L && /* @__PURE__ */ p("div", {
843
852
  className: "mb-6 flex items-start gap-3 p-4 rounded-xl bg-status-error-bg-subtle border border-status-error-border",
844
853
  children: [/* @__PURE__ */ f(n, { className: "size-5 text-status-error-text flex-shrink-0 mt-0.5" }), /* @__PURE__ */ f("div", {
845
854
  className: "flex-1",
846
855
  children: /* @__PURE__ */ f("p", {
847
856
  className: "text-sm text-status-error-text",
848
- children: R
857
+ children: L
849
858
  })
850
859
  })]
851
860
  }),
852
861
  /* @__PURE__ */ p("form", {
853
- onSubmit: Ce,
862
+ onSubmit: Ee,
854
863
  className: "space-y-6",
855
- "aria-describedby": R ? E : void 0,
864
+ "aria-describedby": L ? T : void 0,
856
865
  noValidate: !0,
857
866
  children: [
858
867
  /* @__PURE__ */ p("div", {
@@ -865,9 +874,9 @@ function v() {
865
874
  id: "edit-username",
866
875
  type: "text",
867
876
  "aria-label": v("auth.users.fieldUsername", "Username"),
868
- value: I.username,
869
- onChange: (e) => L({
870
- ...I,
877
+ value: F.username,
878
+ onChange: (e) => I({
879
+ ...F,
871
880
  username: e.target.value
872
881
  }),
873
882
  className: "block w-full px-4 py-3 border border-border-default rounded-xl bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all"
@@ -879,9 +888,9 @@ function v() {
879
888
  id: "edit-name",
880
889
  type: "text",
881
890
  "aria-label": v("auth.users.fieldName", "Name"),
882
- value: I.name,
883
- onChange: (e) => L({
884
- ...I,
891
+ value: F.name,
892
+ onChange: (e) => I({
893
+ ...F,
885
894
  name: e.target.value
886
895
  }),
887
896
  className: "block w-full px-4 py-3 border border-border-default rounded-xl bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all"
@@ -897,9 +906,9 @@ function v() {
897
906
  id: "edit-firstName",
898
907
  type: "text",
899
908
  "aria-label": v("auth.users.fieldFirstName", "First Name"),
900
- value: I.firstName,
901
- onChange: (e) => L({
902
- ...I,
909
+ value: F.firstName,
910
+ onChange: (e) => I({
911
+ ...F,
903
912
  firstName: e.target.value
904
913
  }),
905
914
  className: "block w-full px-4 py-3 border border-border-default rounded-xl bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all"
@@ -911,29 +920,42 @@ function v() {
911
920
  id: "edit-lastName",
912
921
  type: "text",
913
922
  "aria-label": v("auth.users.fieldLastName", "Last Name"),
914
- value: I.lastName,
915
- onChange: (e) => L({
916
- ...I,
923
+ value: F.lastName,
924
+ onChange: (e) => I({
925
+ ...F,
917
926
  lastName: e.target.value
918
927
  }),
919
928
  className: "block w-full px-4 py-3 border border-border-default rounded-xl bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all"
920
929
  })] })]
921
930
  }),
922
- /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
923
- htmlFor: "edit-phoneNumber",
924
- className: "block text-sm font-medium text-text-primary mb-2",
925
- children: v("auth.users.fieldPhoneNumber", "Phone Number")
926
- }), /* @__PURE__ */ f("input", {
927
- id: "edit-phoneNumber",
928
- type: "tel",
929
- "aria-label": v("auth.users.fieldPhoneNumber", "Phone Number"),
930
- value: I.phoneNumber,
931
- onChange: (e) => L({
932
- ...I,
933
- phoneNumber: e.target.value
931
+ /* @__PURE__ */ p("div", { children: [
932
+ /* @__PURE__ */ f("label", {
933
+ htmlFor: "edit-phoneNumber",
934
+ className: "block text-sm font-medium text-text-primary mb-2",
935
+ children: v("auth.users.fieldPhoneNumber", "Phone Number")
936
+ }),
937
+ /* @__PURE__ */ f("input", {
938
+ id: "edit-phoneNumber",
939
+ type: "tel",
940
+ "aria-label": v("auth.users.fieldPhoneNumber", "Phone Number"),
941
+ "aria-invalid": z ? !0 : void 0,
942
+ "aria-describedby": z ? "edit-phoneNumber-error" : void 0,
943
+ value: F.phoneNumber,
944
+ onChange: (e) => {
945
+ I({
946
+ ...F,
947
+ phoneNumber: e.target.value
948
+ }), z && (B(null), R(null));
949
+ },
950
+ className: "block w-full px-4 py-3 border border-border-default rounded-xl bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all"
934
951
  }),
935
- className: "block w-full px-4 py-3 border border-border-default rounded-xl bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all"
936
- })] }),
952
+ z && /* @__PURE__ */ f("p", {
953
+ id: "edit-phoneNumber-error",
954
+ role: "alert",
955
+ className: "mt-2 text-sm text-[var(--color-status-error-text)]",
956
+ children: z
957
+ })
958
+ ] }),
937
959
  /* @__PURE__ */ p("div", {
938
960
  className: "grid grid-cols-2 gap-4",
939
961
  children: [/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
@@ -943,9 +965,9 @@ function v() {
943
965
  }), /* @__PURE__ */ f("select", {
944
966
  id: "edit-role",
945
967
  "aria-label": v("auth.users.fieldRole", "Role"),
946
- value: I.role,
947
- onChange: (e) => L({
948
- ...I,
968
+ value: F.role,
969
+ onChange: (e) => I({
970
+ ...F,
949
971
  role: e.target.value
950
972
  }),
951
973
  className: "block w-full px-4 py-3 border border-border-default rounded-xl bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all",
@@ -960,9 +982,9 @@ function v() {
960
982
  }), /* @__PURE__ */ f("select", {
961
983
  id: "edit-status",
962
984
  "aria-label": v("auth.users.fieldStatus", "Status"),
963
- value: I.status,
964
- onChange: (e) => L({
965
- ...I,
985
+ value: F.status,
986
+ onChange: (e) => I({
987
+ ...F,
966
988
  status: e.target.value
967
989
  }),
968
990
  className: "block w-full px-4 py-3 border border-border-default rounded-xl bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all",
@@ -977,9 +999,9 @@ function v() {
977
999
  children: [/* @__PURE__ */ f("input", {
978
1000
  type: "checkbox",
979
1001
  id: "emailVerified",
980
- checked: I.emailVerified,
981
- onChange: (e) => L({
982
- ...I,
1002
+ checked: F.emailVerified,
1003
+ onChange: (e) => I({
1004
+ ...F,
983
1005
  emailVerified: e.target.checked
984
1006
  }),
985
1007
  className: "size-5 rounded border-border-default text-text-link focus:ring-action-primary-bg"
@@ -990,7 +1012,7 @@ function v() {
990
1012
  })]
991
1013
  }),
992
1014
  /* @__PURE__ */ p("div", {
993
- className: "flex gap-3 pt-4",
1015
+ className: "flex gap-3 pt-6 mt-6 border-t border-border-default",
994
1016
  children: [/* @__PURE__ */ f(m, {
995
1017
  type: "submit",
996
1018
  disabled: S,
@@ -1001,9 +1023,9 @@ function v() {
1001
1023
  }), /* @__PURE__ */ f("button", {
1002
1024
  type: "button",
1003
1025
  onClick: () => {
1004
- N("list"), Z();
1026
+ M("list"), Q();
1005
1027
  },
1006
- className: "px-6 py-3 rounded-xl border border-border-default text-text-primary font-medium hover:bg-bg-sunken transition-colors",
1028
+ className: "inline-flex items-center h-10 px-8 rounded-xl border border-border-default text-text-primary font-medium hover:bg-bg-sunken transition-colors",
1007
1029
  children: v("auth.users.cancel", "Cancel")
1008
1030
  })]
1009
1031
  })