@open-kingdom/shared-frontend-feature-user-management 0.0.2-10

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.
Files changed (53) hide show
  1. package/.babelrc +12 -0
  2. package/README.md +7 -0
  3. package/dist/index.d.ts +5 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +538 -0
  6. package/dist/lib/components/invitations/AcceptInvitation.component.d.ts +7 -0
  7. package/dist/lib/components/invitations/AcceptInvitation.component.d.ts.map +1 -0
  8. package/dist/lib/components/invitations/InviteUserModal.component.d.ts +7 -0
  9. package/dist/lib/components/invitations/InviteUserModal.component.d.ts.map +1 -0
  10. package/dist/lib/components/invitations/index.d.ts +3 -0
  11. package/dist/lib/components/invitations/index.d.ts.map +1 -0
  12. package/dist/lib/components/shared/ConfirmDialog.component.d.ts +12 -0
  13. package/dist/lib/components/shared/ConfirmDialog.component.d.ts.map +1 -0
  14. package/dist/lib/components/shared/FormField.component.d.ts +10 -0
  15. package/dist/lib/components/shared/FormField.component.d.ts.map +1 -0
  16. package/dist/lib/components/shared/ModalOverlay.component.d.ts +9 -0
  17. package/dist/lib/components/shared/ModalOverlay.component.d.ts.map +1 -0
  18. package/dist/lib/components/shared/RoleBadge.component.d.ts +7 -0
  19. package/dist/lib/components/shared/RoleBadge.component.d.ts.map +1 -0
  20. package/dist/lib/components/shared/StatusCard.component.d.ts +10 -0
  21. package/dist/lib/components/shared/StatusCard.component.d.ts.map +1 -0
  22. package/dist/lib/components/users/UserList.component.d.ts +6 -0
  23. package/dist/lib/components/users/UserList.component.d.ts.map +1 -0
  24. package/dist/lib/styles.d.ts +8 -0
  25. package/dist/lib/styles.d.ts.map +1 -0
  26. package/dist/lib/types.d.ts +9 -0
  27. package/dist/lib/types.d.ts.map +1 -0
  28. package/jest.config.cts +14 -0
  29. package/package.json +27 -0
  30. package/src/index.ts +4 -0
  31. package/src/lib/components/invitations/AcceptInvitation.component.spec.tsx +154 -0
  32. package/src/lib/components/invitations/AcceptInvitation.component.tsx +197 -0
  33. package/src/lib/components/invitations/InviteUserModal.component.spec.tsx +79 -0
  34. package/src/lib/components/invitations/InviteUserModal.component.tsx +121 -0
  35. package/src/lib/components/invitations/index.ts +2 -0
  36. package/src/lib/components/shared/ConfirmDialog.component.spec.tsx +45 -0
  37. package/src/lib/components/shared/ConfirmDialog.component.tsx +58 -0
  38. package/src/lib/components/shared/FormField.component.spec.tsx +50 -0
  39. package/src/lib/components/shared/FormField.component.tsx +34 -0
  40. package/src/lib/components/shared/ModalOverlay.component.spec.tsx +81 -0
  41. package/src/lib/components/shared/ModalOverlay.component.tsx +45 -0
  42. package/src/lib/components/shared/RoleBadge.component.spec.tsx +20 -0
  43. package/src/lib/components/shared/RoleBadge.component.tsx +25 -0
  44. package/src/lib/components/shared/StatusCard.component.spec.tsx +44 -0
  45. package/src/lib/components/shared/StatusCard.component.tsx +47 -0
  46. package/src/lib/components/users/UserList.component.spec.tsx +216 -0
  47. package/src/lib/components/users/UserList.component.tsx +153 -0
  48. package/src/lib/styles.ts +19 -0
  49. package/src/lib/types.ts +9 -0
  50. package/tsconfig.json +13 -0
  51. package/tsconfig.lib.json +47 -0
  52. package/tsconfig.spec.json +27 -0
  53. package/vite.config.mts +58 -0
package/.babelrc ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "presets": [
3
+ [
4
+ "@nx/react/babel",
5
+ {
6
+ "runtime": "automatic",
7
+ "useBuiltIns": "usage"
8
+ }
9
+ ]
10
+ ],
11
+ "plugins": []
12
+ }
package/README.md ADDED
@@ -0,0 +1,7 @@
1
+ # @open-kingdom/feature-user-management
2
+
3
+ This library was generated with [Nx](https://nx.dev).
4
+
5
+ ## Running unit tests
6
+
7
+ Run `nx test @open-kingdom/feature-user-management` to execute the unit tests via [Vitest](https://vitest.dev/).
@@ -0,0 +1,5 @@
1
+ export { UserList } from './lib/components/users/UserList.component';
2
+ export { AcceptInvitation } from './lib/components/invitations';
3
+ export { StatusCard } from './lib/components/shared/StatusCard.component';
4
+ export type { User, Role } from './lib/types';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,2CAA2C,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAC;AAC1E,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,538 @@
1
+ import { jsx as e, jsxs as i } from "react/jsx-runtime";
2
+ import { useCallback as P, useState as I, useMemo as V } from "react";
3
+ import { useDispatch as U } from "react-redux";
4
+ import { useInvitationsControllerInviteMutation as B, useInvitationsControllerValidateQuery as E, useInvitationsControllerAcceptMutation as G, useUsersControllerFindAllQuery as q, useUsersControllerDeleteMutation as z } from "@open-kingdom/shared-frontend-data-access-api-client";
5
+ import { showSuccessNotification as F } from "@open-kingdom/shared-frontend-data-access-notifications";
6
+ import { DataGrid as Y } from "@open-kingdom/shared-frontend-ui-datagrid";
7
+ import { useTheme as O } from "@open-kingdom/shared-frontend-ui-theme";
8
+ import { useKeyboardEvent as Q } from "@react-hookz/web";
9
+ import { useForm as A } from "react-hook-form";
10
+ import { zodResolver as L } from "@hookform/resolvers/zod";
11
+ import { z as p } from "zod";
12
+ function j({
13
+ isOpen: t,
14
+ onClose: a,
15
+ ariaLabelledBy: r,
16
+ children: s
17
+ }) {
18
+ Q("Escape", () => {
19
+ t && a();
20
+ });
21
+ const n = P((l) => {
22
+ l?.focus();
23
+ }, []);
24
+ return t ? /* @__PURE__ */ e(
25
+ "div",
26
+ {
27
+ className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50",
28
+ onClick: a,
29
+ children: /* @__PURE__ */ e(
30
+ "div",
31
+ {
32
+ ref: n,
33
+ className: "w-full max-w-md rounded-lg bg-white p-6 shadow-xl dark:bg-neutral-800",
34
+ role: "dialog",
35
+ "aria-modal": "true",
36
+ "aria-labelledby": r,
37
+ tabIndex: -1,
38
+ onClick: (l) => l.stopPropagation(),
39
+ children: s
40
+ }
41
+ )
42
+ }
43
+ ) : null;
44
+ }
45
+ const b = "w-full px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-md bg-white dark:bg-neutral-700 text-neutral-900 dark:text-neutral-100", J = "block text-sm font-medium text-neutral-700 dark:text-neutral-300 mb-1", k = "max-w-md mx-auto mt-8 p-6 bg-white dark:bg-neutral-800 rounded-lg shadow-lg", S = "text-neutral-600 dark:text-neutral-400", C = "rounded-md px-4 py-2 text-sm font-medium transition-colors", D = `${C} bg-primary-500 text-white hover:bg-primary-600 disabled:opacity-50`, M = `${C} border border-neutral-300 text-neutral-700 hover:bg-neutral-50 dark:border-neutral-600 dark:text-neutral-300 dark:hover:bg-neutral-700`, K = `${C} bg-error-500 text-white hover:bg-error-600 disabled:opacity-50`;
46
+ function H({
47
+ isOpen: t,
48
+ title: a,
49
+ message: r,
50
+ confirmLabel: s = "Confirm",
51
+ onConfirm: n,
52
+ onCancel: l,
53
+ isLoading: o = !1
54
+ }) {
55
+ const d = "confirm-dialog-title";
56
+ return /* @__PURE__ */ i(j, { isOpen: t, onClose: l, ariaLabelledBy: d, children: [
57
+ /* @__PURE__ */ e(
58
+ "h3",
59
+ {
60
+ id: d,
61
+ className: "text-lg font-semibold text-neutral-900 dark:text-neutral-100",
62
+ children: a
63
+ }
64
+ ),
65
+ /* @__PURE__ */ e("p", { className: "mt-2 text-sm text-neutral-600 dark:text-neutral-400", children: r }),
66
+ /* @__PURE__ */ i("div", { className: "mt-6 flex justify-end gap-3", children: [
67
+ /* @__PURE__ */ e(
68
+ "button",
69
+ {
70
+ type: "button",
71
+ "data-testid": "confirm-cancel-btn",
72
+ onClick: l,
73
+ disabled: o,
74
+ className: M,
75
+ children: "Cancel"
76
+ }
77
+ ),
78
+ /* @__PURE__ */ e(
79
+ "button",
80
+ {
81
+ type: "button",
82
+ "data-testid": "confirm-btn",
83
+ onClick: n,
84
+ disabled: o,
85
+ className: K,
86
+ children: s
87
+ }
88
+ )
89
+ ] })
90
+ ] });
91
+ }
92
+ const W = {
93
+ admin: "bg-purple-100 text-purple-800 dark:bg-purple-900/30 dark:text-purple-300",
94
+ user: "bg-primary-100 text-primary-800 dark:bg-primary-900/30 dark:text-primary-300",
95
+ guest: "bg-neutral-100 text-neutral-700 dark:bg-neutral-700 dark:text-neutral-300"
96
+ };
97
+ function X({ role: t }) {
98
+ if (!t) return null;
99
+ const a = t.charAt(0).toUpperCase() + t.slice(1);
100
+ return /* @__PURE__ */ e(
101
+ "span",
102
+ {
103
+ className: `inline-block rounded-full px-2.5 py-0.5 text-xs font-medium ${W[t]}`,
104
+ children: a
105
+ }
106
+ );
107
+ }
108
+ function x({
109
+ label: t,
110
+ htmlFor: a,
111
+ required: r,
112
+ error: s,
113
+ children: n
114
+ }) {
115
+ return /* @__PURE__ */ i("div", { children: [
116
+ /* @__PURE__ */ i("label", { htmlFor: a, className: J, children: [
117
+ t,
118
+ " ",
119
+ r && /* @__PURE__ */ e("span", { className: "text-error-500", children: "*" })
120
+ ] }),
121
+ n,
122
+ s && /* @__PURE__ */ e(
123
+ "p",
124
+ {
125
+ "data-testid": "field-error",
126
+ className: "mt-1 text-sm text-error-600 dark:text-error-400",
127
+ children: s
128
+ }
129
+ )
130
+ ] });
131
+ }
132
+ const Z = p.object({
133
+ email: p.string().email("Invalid email address"),
134
+ role: p.enum(["guest", "user", "admin"])
135
+ });
136
+ function _({ isOpen: t, onClose: a }) {
137
+ const r = U(), [s, { isLoading: n }] = B(), {
138
+ register: l,
139
+ handleSubmit: o,
140
+ reset: d,
141
+ formState: { errors: c }
142
+ } = A({
143
+ resolver: L(Z),
144
+ defaultValues: { email: "", role: "guest" }
145
+ }), h = "invite-modal-title", f = () => {
146
+ d(), a();
147
+ };
148
+ return /* @__PURE__ */ i(
149
+ j,
150
+ {
151
+ isOpen: t,
152
+ onClose: f,
153
+ ariaLabelledBy: h,
154
+ children: [
155
+ /* @__PURE__ */ e(
156
+ "h3",
157
+ {
158
+ id: h,
159
+ className: "text-lg font-semibold text-neutral-900 dark:text-neutral-100",
160
+ children: "Invite User"
161
+ }
162
+ ),
163
+ /* @__PURE__ */ i("form", { onSubmit: o(async (m) => {
164
+ try {
165
+ await s({ inviteUserDto: m }).unwrap(), r(F("Invitation sent successfully")), d(), a();
166
+ } catch {
167
+ }
168
+ }), className: "mt-4 space-y-4", children: [
169
+ /* @__PURE__ */ e(
170
+ x,
171
+ {
172
+ label: "Email",
173
+ htmlFor: "invite-email",
174
+ required: !0,
175
+ error: c.email?.message,
176
+ children: /* @__PURE__ */ e(
177
+ "input",
178
+ {
179
+ id: "invite-email",
180
+ "data-testid": "invite-email-input",
181
+ type: "email",
182
+ placeholder: "user@example.com",
183
+ className: b,
184
+ ...l("email")
185
+ }
186
+ )
187
+ }
188
+ ),
189
+ /* @__PURE__ */ e(x, { label: "Role", htmlFor: "invite-role", children: /* @__PURE__ */ i(
190
+ "select",
191
+ {
192
+ id: "invite-role",
193
+ "data-testid": "invite-role-select",
194
+ className: b,
195
+ ...l("role"),
196
+ children: [
197
+ /* @__PURE__ */ e("option", { value: "guest", children: "Guest" }),
198
+ /* @__PURE__ */ e("option", { value: "user", children: "User" }),
199
+ /* @__PURE__ */ e("option", { value: "admin", children: "Admin" })
200
+ ]
201
+ }
202
+ ) }),
203
+ /* @__PURE__ */ i("div", { className: "flex justify-end gap-3", children: [
204
+ /* @__PURE__ */ e(
205
+ "button",
206
+ {
207
+ type: "button",
208
+ "data-testid": "invite-cancel-btn",
209
+ onClick: f,
210
+ disabled: n,
211
+ className: M,
212
+ children: "Cancel"
213
+ }
214
+ ),
215
+ /* @__PURE__ */ e(
216
+ "button",
217
+ {
218
+ type: "submit",
219
+ "data-testid": "invite-submit-btn",
220
+ disabled: n,
221
+ className: D,
222
+ children: n ? "Sending..." : "Send Invitation"
223
+ }
224
+ )
225
+ ] })
226
+ ] })
227
+ ]
228
+ }
229
+ );
230
+ }
231
+ const ee = {
232
+ error: "text-xl font-bold text-error-700 dark:text-error-400",
233
+ success: "text-xl font-bold text-success-700 dark:text-success-400"
234
+ };
235
+ function w({
236
+ variant: t,
237
+ title: a,
238
+ message: r,
239
+ children: s
240
+ }) {
241
+ return t === "loading" ? /* @__PURE__ */ e("div", { className: k, children: /* @__PURE__ */ e("p", { className: `text-center ${S}`, children: r }) }) : /* @__PURE__ */ i(
242
+ "div",
243
+ {
244
+ className: k,
245
+ role: t === "error" ? "alert" : void 0,
246
+ children: [
247
+ a && /* @__PURE__ */ e("h2", { "data-testid": "status-card-title", className: ee[t], children: a }),
248
+ /* @__PURE__ */ e("p", { "data-testid": "status-card-message", className: `mt-2 ${S}`, children: r }),
249
+ s
250
+ ]
251
+ }
252
+ );
253
+ }
254
+ const te = p.object({
255
+ firstName: p.string().optional(),
256
+ lastName: p.string().optional(),
257
+ password: p.string().min(8, "Password must be at least 8 characters"),
258
+ confirmPassword: p.string()
259
+ }).refine((t) => t.password === t.confirmPassword, {
260
+ message: "Passwords do not match",
261
+ path: ["confirmPassword"]
262
+ });
263
+ function pe({ token: t, loginPath: a }) {
264
+ const {
265
+ data: r,
266
+ isLoading: s,
267
+ error: n
268
+ } = E({ token: t }), [l, { isLoading: o, isSuccess: d }] = G(), {
269
+ register: c,
270
+ handleSubmit: h,
271
+ formState: { errors: f }
272
+ } = A({
273
+ resolver: L(te),
274
+ defaultValues: {
275
+ firstName: "",
276
+ lastName: "",
277
+ password: "",
278
+ confirmPassword: ""
279
+ }
280
+ }), g = r?.email ?? "", m = r?.role ?? "user", v = async (y) => {
281
+ try {
282
+ await l({
283
+ acceptInvitationDto: {
284
+ token: t,
285
+ password: y.password,
286
+ firstName: y.firstName || void 0,
287
+ lastName: y.lastName || void 0
288
+ }
289
+ }).unwrap();
290
+ } catch {
291
+ }
292
+ };
293
+ return d ? /* @__PURE__ */ e(
294
+ w,
295
+ {
296
+ variant: "success",
297
+ title: "Account Created",
298
+ message: "Your account has been created successfully. You can now log in with your email and password.",
299
+ children: a && /* @__PURE__ */ e(
300
+ "a",
301
+ {
302
+ href: a,
303
+ "data-testid": "accept-login-link",
304
+ className: "mt-4 inline-block text-sm font-medium text-primary-600 hover:underline dark:text-primary-400",
305
+ children: "Go to login"
306
+ }
307
+ )
308
+ }
309
+ ) : s ? /* @__PURE__ */ e(w, { variant: "loading", message: "Validating invitation..." }) : n ? /* @__PURE__ */ e(
310
+ w,
311
+ {
312
+ variant: "error",
313
+ title: "Validation Failed",
314
+ message: "Unable to validate this invitation. Please check your connection and try again."
315
+ }
316
+ ) : r?.valid ? /* @__PURE__ */ i("div", { className: k, children: [
317
+ /* @__PURE__ */ e(
318
+ "h2",
319
+ {
320
+ "data-testid": "accept-heading",
321
+ className: "text-xl font-bold text-neutral-900 dark:text-neutral-100",
322
+ children: "Accept Invitation"
323
+ }
324
+ ),
325
+ /* @__PURE__ */ i("p", { className: `mt-1 text-sm ${S}`, children: [
326
+ "You've been invited as ",
327
+ /* @__PURE__ */ e("strong", { "data-testid": "accept-role", children: m }),
328
+ " ",
329
+ "with email ",
330
+ /* @__PURE__ */ e("strong", { "data-testid": "accept-email", children: g })
331
+ ] }),
332
+ /* @__PURE__ */ i("form", { onSubmit: h(v), className: "mt-4 space-y-4", children: [
333
+ /* @__PURE__ */ e(x, { label: "First Name", htmlFor: "accept-firstName", children: /* @__PURE__ */ e(
334
+ "input",
335
+ {
336
+ id: "accept-firstName",
337
+ "data-testid": "accept-first-name-input",
338
+ type: "text",
339
+ placeholder: "John",
340
+ className: b,
341
+ ...c("firstName")
342
+ }
343
+ ) }),
344
+ /* @__PURE__ */ e(x, { label: "Last Name", htmlFor: "accept-lastName", children: /* @__PURE__ */ e(
345
+ "input",
346
+ {
347
+ id: "accept-lastName",
348
+ "data-testid": "accept-last-name-input",
349
+ type: "text",
350
+ placeholder: "Doe",
351
+ className: b,
352
+ ...c("lastName")
353
+ }
354
+ ) }),
355
+ /* @__PURE__ */ e(
356
+ x,
357
+ {
358
+ label: "Password",
359
+ htmlFor: "accept-password",
360
+ required: !0,
361
+ error: f.password?.message,
362
+ children: /* @__PURE__ */ e(
363
+ "input",
364
+ {
365
+ id: "accept-password",
366
+ "data-testid": "accept-password-input",
367
+ type: "password",
368
+ placeholder: "Min. 8 characters",
369
+ className: b,
370
+ ...c("password")
371
+ }
372
+ )
373
+ }
374
+ ),
375
+ /* @__PURE__ */ e(
376
+ x,
377
+ {
378
+ label: "Confirm Password",
379
+ htmlFor: "accept-confirmPassword",
380
+ required: !0,
381
+ error: f.confirmPassword?.message,
382
+ children: /* @__PURE__ */ e(
383
+ "input",
384
+ {
385
+ id: "accept-confirmPassword",
386
+ "data-testid": "accept-confirm-password-input",
387
+ type: "password",
388
+ placeholder: "Repeat password",
389
+ className: b,
390
+ ...c("confirmPassword")
391
+ }
392
+ )
393
+ }
394
+ ),
395
+ /* @__PURE__ */ e(
396
+ "button",
397
+ {
398
+ type: "submit",
399
+ "data-testid": "accept-submit-btn",
400
+ disabled: o,
401
+ className: `w-full ${D}`,
402
+ children: o ? "Creating account..." : "Create Account"
403
+ }
404
+ )
405
+ ] })
406
+ ] }) : /* @__PURE__ */ e(
407
+ w,
408
+ {
409
+ variant: "error",
410
+ title: "Invalid Invitation",
411
+ message: "This invitation link is invalid or has expired. Please contact the person who invited you for a new link."
412
+ }
413
+ );
414
+ }
415
+ function he({ currentUserId: t }) {
416
+ const a = U(), { theme: r, mode: s } = O(), { data: n, isLoading: l, error: o, refetch: d } = q(), [c, { isLoading: h }] = z(), [f, g] = I(!1), [m, v] = I(null), y = n ?? [], $ = P(async () => {
417
+ if (m)
418
+ try {
419
+ await c({ id: m.id }).unwrap(), a(F("User deleted successfully"));
420
+ } catch {
421
+ } finally {
422
+ v(null);
423
+ }
424
+ }, [m, c, a]), R = V(
425
+ () => [
426
+ { field: "email", headerName: "Email", flex: 2 },
427
+ {
428
+ headerName: "Name",
429
+ flex: 2,
430
+ valueGetter: (u) => {
431
+ const { firstName: N, lastName: T } = u.data ?? {};
432
+ return [N, T].filter(Boolean).join(" ") || "—";
433
+ }
434
+ },
435
+ {
436
+ field: "role",
437
+ headerName: "Role",
438
+ flex: 1,
439
+ cellRenderer: (u) => u.data ? /* @__PURE__ */ e(X, { role: u.data.role }) : null
440
+ },
441
+ {
442
+ headerName: "Actions",
443
+ flex: 1,
444
+ sortable: !1,
445
+ filter: !1,
446
+ cellRenderer: (u) => {
447
+ if (!u.data) return null;
448
+ const N = u.data.id === t;
449
+ return /* @__PURE__ */ e(
450
+ "button",
451
+ {
452
+ onClick: () => u.data && v(u.data),
453
+ disabled: N,
454
+ title: N ? "Cannot delete your own account" : "Delete user",
455
+ className: "rounded px-2 py-1 text-xs font-medium text-error-600 transition-colors hover:bg-error-50 disabled:cursor-not-allowed disabled:opacity-40 dark:text-error-400 dark:hover:bg-error-900/20",
456
+ children: "Delete"
457
+ }
458
+ );
459
+ }
460
+ }
461
+ ],
462
+ [t]
463
+ );
464
+ return o ? /* @__PURE__ */ i(
465
+ "div",
466
+ {
467
+ "data-testid": "users-error",
468
+ className: "rounded-lg bg-error-50 p-6 text-center dark:bg-error-900/20",
469
+ role: "alert",
470
+ children: [
471
+ /* @__PURE__ */ e("p", { className: "text-error-700 dark:text-error-300", children: "Failed to load users." }),
472
+ /* @__PURE__ */ e(
473
+ "button",
474
+ {
475
+ "data-testid": "users-retry-btn",
476
+ onClick: d,
477
+ className: "mt-2 text-sm font-medium text-primary-600 hover:underline dark:text-primary-400",
478
+ children: "Try again"
479
+ }
480
+ )
481
+ ]
482
+ }
483
+ ) : /* @__PURE__ */ i("div", { children: [
484
+ /* @__PURE__ */ i("div", { className: "mb-4 flex items-center justify-between", children: [
485
+ /* @__PURE__ */ e(
486
+ "h2",
487
+ {
488
+ "data-testid": "users-heading",
489
+ className: "text-xl font-semibold text-neutral-900 dark:text-neutral-100",
490
+ children: "Users"
491
+ }
492
+ ),
493
+ /* @__PURE__ */ e(
494
+ "button",
495
+ {
496
+ "data-testid": "invite-user-btn",
497
+ onClick: () => g(!0),
498
+ className: D,
499
+ children: "Invite User"
500
+ }
501
+ )
502
+ ] }),
503
+ /* @__PURE__ */ e(
504
+ Y,
505
+ {
506
+ rowData: y,
507
+ columnDefs: R,
508
+ mode: s,
509
+ theme: r,
510
+ loading: l
511
+ }
512
+ ),
513
+ /* @__PURE__ */ e(
514
+ _,
515
+ {
516
+ isOpen: f,
517
+ onClose: () => g(!1)
518
+ }
519
+ ),
520
+ /* @__PURE__ */ e(
521
+ H,
522
+ {
523
+ isOpen: !!m,
524
+ title: "Delete User",
525
+ message: `Are you sure you want to delete ${m?.email}? This action cannot be undone.`,
526
+ confirmLabel: h ? "Deleting..." : "Delete",
527
+ onConfirm: $,
528
+ onCancel: () => v(null),
529
+ isLoading: h
530
+ }
531
+ )
532
+ ] });
533
+ }
534
+ export {
535
+ pe as AcceptInvitation,
536
+ w as StatusCard,
537
+ he as UserList
538
+ };
@@ -0,0 +1,7 @@
1
+ interface AcceptInvitationProps {
2
+ token: string;
3
+ loginPath?: string;
4
+ }
5
+ export declare function AcceptInvitation({ token, loginPath }: AcceptInvitationProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
7
+ //# sourceMappingURL=AcceptInvitation.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AcceptInvitation.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/invitations/AcceptInvitation.component.tsx"],"names":[],"mappings":"AA8BA,UAAU,qBAAqB;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,gBAAgB,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,qBAAqB,2CAiK3E"}
@@ -0,0 +1,7 @@
1
+ interface InviteUserModalProps {
2
+ isOpen: boolean;
3
+ onClose: () => void;
4
+ }
5
+ export declare function InviteUserModal({ isOpen, onClose }: InviteUserModalProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};
7
+ //# sourceMappingURL=InviteUserModal.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InviteUserModal.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/invitations/InviteUserModal.component.tsx"],"names":[],"mappings":"AAqBA,UAAU,oBAAoB;IAC5B,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,eAAe,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,oBAAoB,2CA8FxE"}
@@ -0,0 +1,3 @@
1
+ export { InviteUserModal } from './InviteUserModal.component';
2
+ export { AcceptInvitation } from './AcceptInvitation.component';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/invitations/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC"}
@@ -0,0 +1,12 @@
1
+ interface ConfirmDialogProps {
2
+ isOpen: boolean;
3
+ title: string;
4
+ message: string;
5
+ confirmLabel?: string;
6
+ onConfirm: () => void;
7
+ onCancel: () => void;
8
+ isLoading?: boolean;
9
+ }
10
+ export declare function ConfirmDialog({ isOpen, title, message, confirmLabel, onConfirm, onCancel, isLoading, }: ConfirmDialogProps): import("react/jsx-runtime").JSX.Element;
11
+ export {};
12
+ //# sourceMappingURL=ConfirmDialog.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfirmDialog.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/shared/ConfirmDialog.component.tsx"],"names":[],"mappings":"AAGA,UAAU,kBAAkB;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,KAAK,EACL,OAAO,EACP,YAAwB,EACxB,SAAS,EACT,QAAQ,EACR,SAAiB,GAClB,EAAE,kBAAkB,2CAoCpB"}
@@ -0,0 +1,10 @@
1
+ interface FormFieldProps {
2
+ label: string;
3
+ htmlFor: string;
4
+ required?: boolean;
5
+ error?: string;
6
+ children: React.ReactNode;
7
+ }
8
+ export declare function FormField({ label, htmlFor, required, error, children, }: FormFieldProps): import("react/jsx-runtime").JSX.Element;
9
+ export {};
10
+ //# sourceMappingURL=FormField.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FormField.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/shared/FormField.component.tsx"],"names":[],"mappings":"AAEA,UAAU,cAAc;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,OAAO,EACP,QAAQ,EACR,KAAK,EACL,QAAQ,GACT,EAAE,cAAc,2CAiBhB"}
@@ -0,0 +1,9 @@
1
+ interface ModalOverlayProps {
2
+ isOpen: boolean;
3
+ onClose: () => void;
4
+ ariaLabelledBy: string;
5
+ children: React.ReactNode;
6
+ }
7
+ export declare function ModalOverlay({ isOpen, onClose, ariaLabelledBy, children, }: ModalOverlayProps): import("react/jsx-runtime").JSX.Element | null;
8
+ export {};
9
+ //# sourceMappingURL=ModalOverlay.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModalOverlay.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/shared/ModalOverlay.component.tsx"],"names":[],"mappings":"AAGA,UAAU,iBAAiB;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,wBAAgB,YAAY,CAAC,EAC3B,MAAM,EACN,OAAO,EACP,cAAc,EACd,QAAQ,GACT,EAAE,iBAAiB,kDA6BnB"}
@@ -0,0 +1,7 @@
1
+ import { Role } from '../../types';
2
+ interface RoleBadgeProps {
3
+ role: Role;
4
+ }
5
+ export declare function RoleBadge({ role }: RoleBadgeProps): import("react/jsx-runtime").JSX.Element | null;
6
+ export {};
7
+ //# sourceMappingURL=RoleBadge.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RoleBadge.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/shared/RoleBadge.component.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAUxC,UAAU,cAAc;IACtB,IAAI,EAAE,IAAI,CAAC;CACZ;AAED,wBAAgB,SAAS,CAAC,EAAE,IAAI,EAAE,EAAE,cAAc,kDAUjD"}
@@ -0,0 +1,10 @@
1
+ type StatusVariant = 'loading' | 'error' | 'success';
2
+ interface StatusCardProps {
3
+ variant: StatusVariant;
4
+ title?: string;
5
+ message: string;
6
+ children?: React.ReactNode;
7
+ }
8
+ export declare function StatusCard({ variant, title, message, children, }: StatusCardProps): import("react/jsx-runtime").JSX.Element;
9
+ export {};
10
+ //# sourceMappingURL=StatusCard.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatusCard.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/shared/StatusCard.component.tsx"],"names":[],"mappings":"AAEA,KAAK,aAAa,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAErD,UAAU,eAAe;IACvB,OAAO,EAAE,aAAa,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAOD,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,KAAK,EACL,OAAO,EACP,QAAQ,GACT,EAAE,eAAe,2CAyBjB"}