@memberjunction/ng-explorer-settings 3.2.0 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/lib/account-info/account-info.component.d.ts +23 -0
  2. package/dist/lib/account-info/account-info.component.d.ts.map +1 -0
  3. package/dist/lib/account-info/account-info.component.js +155 -0
  4. package/dist/lib/account-info/account-info.component.js.map +1 -0
  5. package/dist/lib/appearance-settings/appearance-settings.component.d.ts +15 -0
  6. package/dist/lib/appearance-settings/appearance-settings.component.d.ts.map +1 -0
  7. package/dist/lib/appearance-settings/appearance-settings.component.js +79 -0
  8. package/dist/lib/appearance-settings/appearance-settings.component.js.map +1 -0
  9. package/dist/lib/application-management/application-dialog/application-dialog.component.d.ts +15 -1
  10. package/dist/lib/application-management/application-dialog/application-dialog.component.d.ts.map +1 -1
  11. package/dist/lib/application-management/application-dialog/application-dialog.component.js +329 -190
  12. package/dist/lib/application-management/application-dialog/application-dialog.component.js.map +1 -1
  13. package/dist/lib/application-management/application-management.component.d.ts.map +1 -1
  14. package/dist/lib/application-management/application-management.component.js +265 -184
  15. package/dist/lib/application-management/application-management.component.js.map +1 -1
  16. package/dist/lib/application-settings/application-settings.component.d.ts +113 -0
  17. package/dist/lib/application-settings/application-settings.component.d.ts.map +1 -0
  18. package/dist/lib/application-settings/application-settings.component.js +520 -0
  19. package/dist/lib/application-settings/application-settings.component.js.map +1 -0
  20. package/dist/lib/entity-permissions/entity-permissions.component.d.ts +1 -0
  21. package/dist/lib/entity-permissions/entity-permissions.component.d.ts.map +1 -1
  22. package/dist/lib/entity-permissions/entity-permissions.component.js +369 -192
  23. package/dist/lib/entity-permissions/entity-permissions.component.js.map +1 -1
  24. package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.d.ts.map +1 -1
  25. package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js +160 -143
  26. package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js.map +1 -1
  27. package/dist/lib/general-settings/general-settings.component.d.ts +14 -0
  28. package/dist/lib/general-settings/general-settings.component.d.ts.map +1 -0
  29. package/dist/lib/general-settings/general-settings.component.js +50 -0
  30. package/dist/lib/general-settings/general-settings.component.js.map +1 -0
  31. package/dist/lib/module.d.ts +28 -30
  32. package/dist/lib/module.d.ts.map +1 -1
  33. package/dist/lib/module.js +75 -68
  34. package/dist/lib/module.js.map +1 -1
  35. package/dist/lib/notification-preferences/notification-preferences.component.d.ts +77 -0
  36. package/dist/lib/notification-preferences/notification-preferences.component.d.ts.map +1 -1
  37. package/dist/lib/notification-preferences/notification-preferences.component.js +153 -77
  38. package/dist/lib/notification-preferences/notification-preferences.component.js.map +1 -1
  39. package/dist/lib/role-management/role-dialog/role-dialog.component.d.ts.map +1 -1
  40. package/dist/lib/role-management/role-dialog/role-dialog.component.js +93 -89
  41. package/dist/lib/role-management/role-dialog/role-dialog.component.js.map +1 -1
  42. package/dist/lib/role-management/role-management.component.d.ts +1 -0
  43. package/dist/lib/role-management/role-management.component.d.ts.map +1 -1
  44. package/dist/lib/role-management/role-management.component.js +275 -158
  45. package/dist/lib/role-management/role-management.component.js.map +1 -1
  46. package/dist/lib/settings/settings.component.d.ts +47 -3
  47. package/dist/lib/settings/settings.component.d.ts.map +1 -1
  48. package/dist/lib/settings/settings.component.js +339 -269
  49. package/dist/lib/settings/settings.component.js.map +1 -1
  50. package/dist/lib/shared/settings-card.component.d.ts.map +1 -1
  51. package/dist/lib/shared/settings-card.component.js +21 -18
  52. package/dist/lib/shared/settings-card.component.js.map +1 -1
  53. package/dist/lib/sql-logging/sql-logging.component.d.ts +11 -2
  54. package/dist/lib/sql-logging/sql-logging.component.d.ts.map +1 -1
  55. package/dist/lib/sql-logging/sql-logging.component.js +318 -245
  56. package/dist/lib/sql-logging/sql-logging.component.js.map +1 -1
  57. package/dist/lib/user-app-config/user-app-config.component.d.ts +21 -3
  58. package/dist/lib/user-app-config/user-app-config.component.d.ts.map +1 -1
  59. package/dist/lib/user-app-config/user-app-config.component.js +202 -147
  60. package/dist/lib/user-app-config/user-app-config.component.js.map +1 -1
  61. package/dist/lib/user-management/user-dialog/user-dialog.component.d.ts.map +1 -1
  62. package/dist/lib/user-management/user-dialog/user-dialog.component.js +120 -116
  63. package/dist/lib/user-management/user-dialog/user-dialog.component.js.map +1 -1
  64. package/dist/lib/user-management/user-management.component.d.ts +32 -2
  65. package/dist/lib/user-management/user-management.component.d.ts.map +1 -1
  66. package/dist/lib/user-management/user-management.component.js +822 -297
  67. package/dist/lib/user-management/user-management.component.js.map +1 -1
  68. package/dist/lib/user-profile-settings/user-profile-settings.component.d.ts +31 -2
  69. package/dist/lib/user-profile-settings/user-profile-settings.component.d.ts.map +1 -1
  70. package/dist/lib/user-profile-settings/user-profile-settings.component.js +213 -80
  71. package/dist/lib/user-profile-settings/user-profile-settings.component.js.map +1 -1
  72. package/package.json +20 -20
@@ -12,294 +12,576 @@ import { BaseDashboard } from '@memberjunction/ng-shared';
12
12
  import { RegisterClass } from '@memberjunction/global';
13
13
  import * as i0 from "@angular/core";
14
14
  import * as i1 from "@angular/forms";
15
- import * as i2 from "./user-dialog/user-dialog.component";
16
- import * as i3 from "@angular/common";
15
+ import * as i2 from "@memberjunction/ng-shared-generic";
16
+ import * as i3 from "./user-dialog/user-dialog.component";
17
+ import * as i4 from "@angular/common";
17
18
  const _forTrack0 = ($index, $item) => $item.ID;
18
- function UserManagementComponent_For_66_Template(rf, ctx) { if (rf & 1) {
19
- i0.ɵɵelementStart(0, "option", 32);
19
+ function UserManagementComponent_Conditional_15_Template(rf, ctx) { if (rf & 1) {
20
+ const _r1 = i0.ɵɵgetCurrentView();
21
+ i0.ɵɵelementStart(0, "div", 10)(1, "div", 52);
22
+ i0.ɵɵelement(2, "i", 53);
23
+ i0.ɵɵelementStart(3, "span");
24
+ i0.ɵɵtext(4);
25
+ i0.ɵɵelementEnd();
26
+ i0.ɵɵelementStart(5, "button", 54);
27
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_15_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.clearSelection()); });
28
+ i0.ɵɵelement(6, "i", 55);
29
+ i0.ɵɵtext(7, " Clear ");
30
+ i0.ɵɵelementEnd()();
31
+ i0.ɵɵelementStart(8, "div", 56)(9, "button", 57);
32
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_15_Template_button_click_9_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.confirmBulkAction("enable")); });
33
+ i0.ɵɵelement(10, "i", 58);
34
+ i0.ɵɵelementStart(11, "span", 5);
35
+ i0.ɵɵtext(12, "Enable");
36
+ i0.ɵɵelementEnd()();
37
+ i0.ɵɵelementStart(13, "button", 59);
38
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_15_Template_button_click_13_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.confirmBulkAction("disable")); });
39
+ i0.ɵɵelement(14, "i", 60);
40
+ i0.ɵɵelementStart(15, "span", 5);
41
+ i0.ɵɵtext(16, "Disable");
42
+ i0.ɵɵelementEnd()();
43
+ i0.ɵɵelementStart(17, "button", 61);
44
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_15_Template_button_click_17_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.openBulkRoleAssign()); });
45
+ i0.ɵɵelement(18, "i", 62);
46
+ i0.ɵɵelementStart(19, "span", 5);
47
+ i0.ɵɵtext(20, "Assign Role");
48
+ i0.ɵɵelementEnd()();
49
+ i0.ɵɵelementStart(21, "button", 63);
50
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_15_Template_button_click_21_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.confirmBulkAction("delete")); });
51
+ i0.ɵɵelement(22, "i", 64);
52
+ i0.ɵɵelementStart(23, "span", 5);
53
+ i0.ɵɵtext(24, "Delete");
54
+ i0.ɵɵelementEnd()()()();
55
+ } if (rf & 2) {
56
+ const ctx_r1 = i0.ɵɵnextContext();
57
+ i0.ɵɵadvance(4);
58
+ i0.ɵɵtextInterpolate2("", ctx_r1.selectedCount, " user", ctx_r1.selectedCount > 1 ? "s" : "", " selected");
59
+ } }
60
+ function UserManagementComponent_Conditional_56_Template(rf, ctx) { if (rf & 1) {
61
+ i0.ɵɵelementStart(0, "span", 34);
20
62
  i0.ɵɵtext(1);
21
63
  i0.ɵɵelementEnd();
22
64
  } if (rf & 2) {
23
- const role_r1 = ctx.$implicit;
24
- i0.ɵɵproperty("value", role_r1.ID);
65
+ const ctx_r1 = i0.ɵɵnextContext();
25
66
  i0.ɵɵadvance();
26
- i0.ɵɵtextInterpolate(role_r1.Name);
67
+ i0.ɵɵtextInterpolate(ctx_r1.activeFilterCount);
27
68
  } }
28
- function UserManagementComponent_Conditional_72_Template(rf, ctx) { if (rf & 1) {
29
- i0.ɵɵelementStart(0, "div", 38)(1, "div", 43);
30
- i0.ɵɵelement(2, "div", 44)(3, "div", 44)(4, "div", 44);
69
+ function UserManagementComponent_For_74_Template(rf, ctx) { if (rf & 1) {
70
+ i0.ɵɵelementStart(0, "option", 42);
71
+ i0.ɵɵtext(1);
31
72
  i0.ɵɵelementEnd();
32
- i0.ɵɵelementStart(5, "div", 45);
33
- i0.ɵɵtext(6, "Loading users...");
34
- i0.ɵɵelementEnd()();
73
+ } if (rf & 2) {
74
+ const role_r3 = ctx.$implicit;
75
+ i0.ɵɵproperty("value", role_r3.ID);
76
+ i0.ɵɵadvance();
77
+ i0.ɵɵtextInterpolate(role_r3.Name);
35
78
  } }
36
- function UserManagementComponent_Conditional_73_Template(rf, ctx) { if (rf & 1) {
37
- const _r2 = i0.ɵɵgetCurrentView();
38
- i0.ɵɵelementStart(0, "div", 39)(1, "div", 46);
39
- i0.ɵɵelement(2, "i", 47);
40
- i0.ɵɵelementStart(3, "p", 48);
41
- i0.ɵɵtext(4);
79
+ function UserManagementComponent_Conditional_75_For_19_Template(rf, ctx) { if (rf & 1) {
80
+ i0.ɵɵelementStart(0, "option", 42);
81
+ i0.ɵɵtext(1);
42
82
  i0.ɵɵelementEnd();
43
- i0.ɵɵelementStart(5, "button", 49);
44
- i0.ɵɵlistener("click", function UserManagementComponent_Conditional_73_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r2); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.loadInitialData()); });
45
- i0.ɵɵelement(6, "i", 3);
46
- i0.ɵɵtext(7, " Try Again ");
47
- i0.ɵɵelementEnd()()();
48
83
  } if (rf & 2) {
49
- const ctx_r2 = i0.ɵɵnextContext();
50
- i0.ɵɵadvance(4);
51
- i0.ɵɵtextInterpolate(ctx_r2.error);
84
+ const role_r5 = ctx.$implicit;
85
+ i0.ɵɵproperty("value", role_r5.ID);
86
+ i0.ɵɵadvance();
87
+ i0.ɵɵtextInterpolate(role_r5.Name);
52
88
  } }
53
- function UserManagementComponent_Conditional_74_Conditional_1_For_20_Template(rf, ctx) { if (rf & 1) {
89
+ function UserManagementComponent_Conditional_75_Conditional_20_Template(rf, ctx) { if (rf & 1) {
90
+ const _r6 = i0.ɵɵgetCurrentView();
91
+ i0.ɵɵelementStart(0, "button", 75);
92
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_75_Conditional_20_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.clearFilters()); });
93
+ i0.ɵɵelement(1, "i", 55);
94
+ i0.ɵɵtext(2, " Clear Filters ");
95
+ i0.ɵɵelementEnd();
96
+ } }
97
+ function UserManagementComponent_Conditional_75_Template(rf, ctx) { if (rf & 1) {
54
98
  const _r4 = i0.ɵɵgetCurrentView();
55
- i0.ɵɵelementStart(0, "tr", 58);
56
- i0.ɵɵlistener("click", function UserManagementComponent_Conditional_74_Conditional_1_For_20_Template_tr_click_0_listener() { const user_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.selectUser(user_r5)); });
57
- i0.ɵɵelementStart(1, "td", 59);
58
- i0.ɵɵlistener("click", function UserManagementComponent_Conditional_74_Conditional_1_For_20_Template_td_click_1_listener($event) { i0.ɵɵrestoreView(_r4); return i0.ɵɵresetView($event.stopPropagation()); });
59
- i0.ɵɵelement(2, "input", 54);
99
+ i0.ɵɵelementStart(0, "div", 43)(1, "div", 65)(2, "div", 66)(3, "label", 67);
100
+ i0.ɵɵtext(4, "Status");
60
101
  i0.ɵɵelementEnd();
61
- i0.ɵɵelementStart(3, "td")(4, "div", 60)(5, "div", 61);
62
- i0.ɵɵtext(6);
102
+ i0.ɵɵelementStart(5, "select", 68);
103
+ i0.ɵɵlistener("change", function UserManagementComponent_Conditional_75_Template_select_change_5_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onStatusFilterChange($event.target.value)); });
104
+ i0.ɵɵelementStart(6, "option", 69);
105
+ i0.ɵɵtext(7, "All Status");
63
106
  i0.ɵɵelementEnd();
64
- i0.ɵɵelementStart(7, "div", 62)(8, "div", 63);
65
- i0.ɵɵtext(9);
107
+ i0.ɵɵelementStart(8, "option", 70);
108
+ i0.ɵɵtext(9, "Active");
66
109
  i0.ɵɵelementEnd();
67
- i0.ɵɵelementStart(10, "div", 64);
68
- i0.ɵɵtext(11);
69
- i0.ɵɵelementEnd()()()();
70
- i0.ɵɵelementStart(12, "td");
71
- i0.ɵɵtext(13);
110
+ i0.ɵɵelementStart(10, "option", 71);
111
+ i0.ɵɵtext(11, "Inactive");
112
+ i0.ɵɵelementEnd()()();
113
+ i0.ɵɵelementStart(12, "div", 66)(13, "label", 72);
114
+ i0.ɵɵtext(14, "Role");
72
115
  i0.ɵɵelementEnd();
73
- i0.ɵɵelementStart(14, "td")(15, "div", 65);
74
- i0.ɵɵelement(16, "i");
75
- i0.ɵɵtext(17);
76
- i0.ɵɵelementEnd()();
77
- i0.ɵɵelementStart(18, "td")(19, "span", 66);
78
- i0.ɵɵelement(20, "i");
79
- i0.ɵɵtext(21);
116
+ i0.ɵɵelementStart(15, "select", 73);
117
+ i0.ɵɵlistener("change", function UserManagementComponent_Conditional_75_Template_select_change_15_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onRoleFilterChange($event.target.value)); });
118
+ i0.ɵɵelementStart(16, "option", 41);
119
+ i0.ɵɵtext(17, "All Roles");
120
+ i0.ɵɵelementEnd();
121
+ i0.ɵɵrepeaterCreate(18, UserManagementComponent_Conditional_75_For_19_Template, 2, 2, "option", 42, _forTrack0);
80
122
  i0.ɵɵelementEnd()();
81
- i0.ɵɵelementStart(22, "td")(23, "span", 67);
82
- i0.ɵɵtext(24);
83
- i0.ɵɵpipe(25, "date");
123
+ i0.ɵɵtemplate(20, UserManagementComponent_Conditional_75_Conditional_20_Template, 3, 0, "button", 74);
84
124
  i0.ɵɵelementEnd()();
85
- i0.ɵɵelementStart(26, "td", 68);
86
- i0.ɵɵlistener("click", function UserManagementComponent_Conditional_74_Conditional_1_For_20_Template_td_click_26_listener($event) { i0.ɵɵrestoreView(_r4); return i0.ɵɵresetView($event.stopPropagation()); });
87
- i0.ɵɵelementStart(27, "button", 69);
88
- i0.ɵɵlistener("click", function UserManagementComponent_Conditional_74_Conditional_1_For_20_Template_button_click_27_listener() { const user_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.editUser(user_r5)); });
89
- i0.ɵɵelement(28, "i", 70);
90
- i0.ɵɵelementEnd();
91
- i0.ɵɵelementStart(29, "button", 71);
92
- i0.ɵɵlistener("click", function UserManagementComponent_Conditional_74_Conditional_1_For_20_Template_button_click_29_listener() { const user_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.toggleUserStatus(user_r5)); });
93
- i0.ɵɵelement(30, "i");
94
- i0.ɵɵelementEnd();
95
- i0.ɵɵelementStart(31, "button", 72);
96
- i0.ɵɵlistener("click", function UserManagementComponent_Conditional_74_Conditional_1_For_20_Template_button_click_31_listener() { const user_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.confirmDeleteUser(user_r5)); });
97
- i0.ɵɵelement(32, "i", 73);
98
- i0.ɵɵelementEnd()()();
99
125
  } if (rf & 2) {
100
- const user_r5 = ctx.$implicit;
101
- const ctx_r2 = i0.ɵɵnextContext(3);
102
- i0.ɵɵadvance(6);
103
- i0.ɵɵtextInterpolate1(" ", ctx_r2.getUserInitials(user_r5), " ");
104
- i0.ɵɵadvance(3);
105
- i0.ɵɵtextInterpolate(user_r5.Name);
106
- i0.ɵɵadvance(2);
107
- i0.ɵɵtextInterpolate2(" ", user_r5.FirstName, " ", user_r5.LastName, " ");
126
+ const ctx_r1 = i0.ɵɵnextContext();
127
+ i0.ɵɵadvance(5);
128
+ i0.ɵɵproperty("value", ctx_r1.filters$.value.status);
129
+ i0.ɵɵadvance(13);
130
+ i0.ɵɵrepeater(ctx_r1.roles);
108
131
  i0.ɵɵadvance(2);
109
- i0.ɵɵtextInterpolate(user_r5.Email);
110
- i0.ɵɵadvance(3);
111
- i0.ɵɵclassMap("fa-solid " + ctx_r2.getUserTypeIcon(user_r5));
132
+ i0.ɵɵconditional(ctx_r1.hasActiveFilters ? 20 : -1);
133
+ } }
134
+ function UserManagementComponent_Conditional_77_Template(rf, ctx) { if (rf & 1) {
135
+ i0.ɵɵelementStart(0, "div", 45);
136
+ i0.ɵɵelement(1, "mj-loading", 76);
137
+ i0.ɵɵelementEnd();
138
+ } }
139
+ function UserManagementComponent_Conditional_78_Template(rf, ctx) { if (rf & 1) {
140
+ const _r7 = i0.ɵɵgetCurrentView();
141
+ i0.ɵɵelementStart(0, "div", 46)(1, "div", 77);
142
+ i0.ɵɵelement(2, "i", 78);
143
+ i0.ɵɵelementStart(3, "p", 79);
144
+ i0.ɵɵtext(4);
145
+ i0.ɵɵelementEnd();
146
+ i0.ɵɵelementStart(5, "button", 80);
147
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_78_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.loadInitialData()); });
148
+ i0.ɵɵelement(6, "i", 4);
149
+ i0.ɵɵtext(7, " Try Again ");
150
+ i0.ɵɵelementEnd()()();
151
+ } if (rf & 2) {
152
+ const ctx_r1 = i0.ɵɵnextContext();
153
+ i0.ɵɵadvance(4);
154
+ i0.ɵɵtextInterpolate(ctx_r1.error);
155
+ } }
156
+ function UserManagementComponent_Conditional_79_Conditional_7_Template(rf, ctx) { if (rf & 1) {
157
+ i0.ɵɵelementStart(0, "span", 86);
158
+ i0.ɵɵtext(1);
159
+ i0.ɵɵelementEnd();
160
+ } if (rf & 2) {
161
+ const ctx_r1 = i0.ɵɵnextContext(2);
112
162
  i0.ɵɵadvance();
113
- i0.ɵɵtextInterpolate1(" ", user_r5.Type, " ");
163
+ i0.ɵɵtextInterpolate1("", ctx_r1.selectedCount, " selected");
164
+ } }
165
+ function UserManagementComponent_Conditional_79_For_9_Conditional_25_Conditional_50_For_2_Template(rf, ctx) { if (rf & 1) {
166
+ i0.ɵɵelementStart(0, "div", 125);
167
+ i0.ɵɵelement(1, "i", 126);
168
+ i0.ɵɵtext(2);
169
+ i0.ɵɵelementEnd();
170
+ } if (rf & 2) {
171
+ const role_r12 = ctx.$implicit;
114
172
  i0.ɵɵadvance(2);
115
- i0.ɵɵclassMap(ctx_r2.getStatusClass(user_r5));
116
- i0.ɵɵadvance();
117
- i0.ɵɵclassMap("fa-solid " + ctx_r2.getStatusIcon(user_r5));
118
- i0.ɵɵadvance();
119
- i0.ɵɵtextInterpolate1(" ", user_r5.IsActive ? "Active" : "Inactive", " ");
120
- i0.ɵɵadvance(3);
121
- i0.ɵɵtextInterpolate1(" ", user_r5.__mj_UpdatedAt ? i0.ɵɵpipeBind2(25, 17, user_r5.__mj_UpdatedAt, "short") : "Never", " ");
122
- i0.ɵɵadvance(5);
123
- i0.ɵɵproperty("title", user_r5.IsActive ? "Deactivate" : "Activate");
124
- i0.ɵɵadvance();
125
- i0.ɵɵclassMap(user_r5.IsActive ? "fa-solid fa-toggle-on" : "fa-solid fa-toggle-off");
173
+ i0.ɵɵtextInterpolate1(" ", role_r12.Name, " ");
126
174
  } }
127
- function UserManagementComponent_Conditional_74_Conditional_1_Conditional_21_Template(rf, ctx) { if (rf & 1) {
128
- i0.ɵɵelementStart(0, "div", 57);
129
- i0.ɵɵelement(1, "i", 74);
130
- i0.ɵɵelementStart(2, "p", 75);
131
- i0.ɵɵtext(3, "No users found");
175
+ function UserManagementComponent_Conditional_79_For_9_Conditional_25_Conditional_50_Template(rf, ctx) { if (rf & 1) {
176
+ i0.ɵɵelementStart(0, "div", 123);
177
+ i0.ɵɵrepeaterCreate(1, UserManagementComponent_Conditional_79_For_9_Conditional_25_Conditional_50_For_2_Template, 3, 1, "div", 125, _forTrack0);
132
178
  i0.ɵɵelementEnd();
133
- i0.ɵɵelementStart(4, "p", 76);
134
- i0.ɵɵtext(5, "Try adjusting your filters or add a new user");
135
- i0.ɵɵelementEnd()();
179
+ } if (rf & 2) {
180
+ const user_r10 = i0.ɵɵnextContext(2).$implicit;
181
+ const ctx_r1 = i0.ɵɵnextContext(2);
182
+ i0.ɵɵadvance();
183
+ i0.ɵɵrepeater(ctx_r1.getUserRoles(user_r10.ID));
136
184
  } }
137
- function UserManagementComponent_Conditional_74_Conditional_1_Template(rf, ctx) { if (rf & 1) {
138
- i0.ɵɵelementStart(0, "div", 50)(1, "table", 52)(2, "thead")(3, "tr")(4, "th", 53);
139
- i0.ɵɵelement(5, "input", 54);
185
+ function UserManagementComponent_Conditional_79_For_9_Conditional_25_Conditional_51_Template(rf, ctx) { if (rf & 1) {
186
+ i0.ɵɵelementStart(0, "p", 124);
187
+ i0.ɵɵtext(1, "No roles assigned to this user");
140
188
  i0.ɵɵelementEnd();
141
- i0.ɵɵelementStart(6, "th");
142
- i0.ɵɵtext(7, "User");
189
+ } }
190
+ function UserManagementComponent_Conditional_79_For_9_Conditional_25_Template(rf, ctx) { if (rf & 1) {
191
+ const _r11 = i0.ɵɵgetCurrentView();
192
+ i0.ɵɵelementStart(0, "div", 108)(1, "div", 109);
193
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_79_For_9_Conditional_25_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r11); return i0.ɵɵresetView($event.stopPropagation()); });
194
+ i0.ɵɵelementStart(2, "span", 99);
195
+ i0.ɵɵelement(3, "i", 100);
196
+ i0.ɵɵtext(4);
143
197
  i0.ɵɵelementEnd();
144
- i0.ɵɵelementStart(8, "th");
145
- i0.ɵɵtext(9, "Email");
198
+ i0.ɵɵelementStart(5, "div", 110)(6, "button", 111);
199
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_79_For_9_Conditional_25_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r11); const user_r10 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.editUser(user_r10)); });
200
+ i0.ɵɵelement(7, "i", 103);
201
+ i0.ɵɵelementStart(8, "span", 112);
202
+ i0.ɵɵtext(9, "Edit");
203
+ i0.ɵɵelementEnd()();
204
+ i0.ɵɵelementStart(10, "button", 111);
205
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_79_For_9_Conditional_25_Template_button_click_10_listener() { i0.ɵɵrestoreView(_r11); const user_r10 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleUserStatus(user_r10)); });
206
+ i0.ɵɵelement(11, "i", 100);
207
+ i0.ɵɵelementStart(12, "span", 112);
208
+ i0.ɵɵtext(13);
209
+ i0.ɵɵelementEnd()();
210
+ i0.ɵɵelementStart(14, "button", 113);
211
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_79_For_9_Conditional_25_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r11); const user_r10 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.confirmDeleteUser(user_r10)); });
212
+ i0.ɵɵelement(15, "i", 64);
213
+ i0.ɵɵelementStart(16, "span", 112);
214
+ i0.ɵɵtext(17, "Delete");
215
+ i0.ɵɵelementEnd()()()();
216
+ i0.ɵɵelementStart(18, "div", 114)(19, "div", 115);
217
+ i0.ɵɵelement(20, "i", 62);
218
+ i0.ɵɵelementStart(21, "span", 17);
219
+ i0.ɵɵtext(22, "Type:");
146
220
  i0.ɵɵelementEnd();
147
- i0.ɵɵelementStart(10, "th");
148
- i0.ɵɵtext(11, "Type");
221
+ i0.ɵɵelementStart(23, "span", 116);
222
+ i0.ɵɵelement(24, "i", 100);
223
+ i0.ɵɵtext(25);
224
+ i0.ɵɵelementEnd()();
225
+ i0.ɵɵelementStart(26, "div", 115);
226
+ i0.ɵɵelement(27, "i", 117);
227
+ i0.ɵɵelementStart(28, "span", 17);
228
+ i0.ɵɵtext(29, "Full Name:");
149
229
  i0.ɵɵelementEnd();
150
- i0.ɵɵelementStart(12, "th");
151
- i0.ɵɵtext(13, "Status");
230
+ i0.ɵɵelementStart(30, "span", 116);
231
+ i0.ɵɵtext(31);
232
+ i0.ɵɵelementEnd()();
233
+ i0.ɵɵelementStart(32, "div", 115);
234
+ i0.ɵɵelement(33, "i", 118);
235
+ i0.ɵɵelementStart(34, "span", 17);
236
+ i0.ɵɵtext(35, "Created:");
152
237
  i0.ɵɵelementEnd();
153
- i0.ɵɵelementStart(14, "th");
154
- i0.ɵɵtext(15, "Last Updated");
238
+ i0.ɵɵelementStart(36, "span", 116);
239
+ i0.ɵɵtext(37);
240
+ i0.ɵɵpipe(38, "date");
241
+ i0.ɵɵelementEnd()();
242
+ i0.ɵɵelementStart(39, "div", 115);
243
+ i0.ɵɵelement(40, "i", 119);
244
+ i0.ɵɵelementStart(41, "span", 17);
245
+ i0.ɵɵtext(42, "Updated:");
155
246
  i0.ɵɵelementEnd();
156
- i0.ɵɵelementStart(16, "th", 55);
157
- i0.ɵɵtext(17, "Actions");
247
+ i0.ɵɵelementStart(43, "span", 116);
248
+ i0.ɵɵtext(44);
249
+ i0.ɵɵpipe(45, "date");
158
250
  i0.ɵɵelementEnd()()();
159
- i0.ɵɵelementStart(18, "tbody");
160
- i0.ɵɵrepeaterCreate(19, UserManagementComponent_Conditional_74_Conditional_1_For_20_Template, 33, 20, "tr", 56, _forTrack0);
161
- i0.ɵɵelementEnd()();
162
- i0.ɵɵtemplate(21, UserManagementComponent_Conditional_74_Conditional_1_Conditional_21_Template, 6, 0, "div", 57);
251
+ i0.ɵɵelementStart(46, "div", 120)(47, "h4", 121);
252
+ i0.ɵɵelement(48, "i", 122);
253
+ i0.ɵɵtext(49, " Assigned Roles ");
163
254
  i0.ɵɵelementEnd();
255
+ i0.ɵɵtemplate(50, UserManagementComponent_Conditional_79_For_9_Conditional_25_Conditional_50_Template, 3, 0, "div", 123)(51, UserManagementComponent_Conditional_79_For_9_Conditional_25_Conditional_51_Template, 2, 0, "p", 124);
256
+ i0.ɵɵelementEnd()();
164
257
  } if (rf & 2) {
165
- const ctx_r2 = i0.ɵɵnextContext(2);
166
- i0.ɵɵadvance(19);
167
- i0.ɵɵrepeater(ctx_r2.filteredUsers);
258
+ const user_r10 = i0.ɵɵnextContext().$implicit;
259
+ const ctx_r1 = i0.ɵɵnextContext(2);
260
+ i0.ɵɵadvance(2);
261
+ i0.ɵɵclassMap(ctx_r1.getStatusClass(user_r10));
262
+ i0.ɵɵadvance();
263
+ i0.ɵɵclassMap("fa-solid " + ctx_r1.getStatusIcon(user_r10));
264
+ i0.ɵɵadvance();
265
+ i0.ɵɵtextInterpolate1(" ", user_r10.IsActive ? "Active" : "Inactive", " ");
266
+ i0.ɵɵadvance(2);
267
+ i0.ɵɵattribute("aria-label", "Edit " + user_r10.Name);
268
+ i0.ɵɵadvance(4);
269
+ i0.ɵɵattribute("aria-label", (user_r10.IsActive ? "Deactivate " : "Activate ") + user_r10.Name);
270
+ i0.ɵɵadvance();
271
+ i0.ɵɵclassMap(user_r10.IsActive ? "fa-solid fa-toggle-on" : "fa-solid fa-toggle-off");
168
272
  i0.ɵɵadvance(2);
169
- i0.ɵɵconditional(ctx_r2.filteredUsers.length === 0 ? 21 : -1);
273
+ i0.ɵɵtextInterpolate(user_r10.IsActive ? "Disable" : "Enable");
274
+ i0.ɵɵadvance();
275
+ i0.ɵɵattribute("aria-label", "Delete " + user_r10.Name);
276
+ i0.ɵɵadvance(10);
277
+ i0.ɵɵclassMap("fa-solid " + ctx_r1.getUserTypeIcon(user_r10));
278
+ i0.ɵɵadvance();
279
+ i0.ɵɵtextInterpolate1(" ", user_r10.Type, " ");
280
+ i0.ɵɵadvance(6);
281
+ i0.ɵɵtextInterpolate2("", user_r10.FirstName, " ", user_r10.LastName, "");
282
+ i0.ɵɵadvance(6);
283
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(38, 19, user_r10.__mj_CreatedAt, "short"));
284
+ i0.ɵɵadvance(7);
285
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(45, 22, user_r10.__mj_UpdatedAt, "short"));
286
+ i0.ɵɵadvance(6);
287
+ i0.ɵɵconditional(ctx_r1.getUserRoles(user_r10.ID).length > 0 ? 50 : 51);
170
288
  } }
171
- function UserManagementComponent_Conditional_74_Conditional_2_For_2_Template(rf, ctx) { if (rf & 1) {
172
- const _r6 = i0.ɵɵgetCurrentView();
173
- i0.ɵɵelementStart(0, "div", 78);
174
- i0.ɵɵlistener("click", function UserManagementComponent_Conditional_74_Conditional_2_For_2_Template_div_click_0_listener() { const user_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r2.selectUser(user_r7)); });
175
- i0.ɵɵelementStart(1, "div", 79)(2, "div", 80);
176
- i0.ɵɵtext(3);
289
+ function UserManagementComponent_Conditional_79_For_9_Template(rf, ctx) { if (rf & 1) {
290
+ const _r9 = i0.ɵɵgetCurrentView();
291
+ i0.ɵɵelementStart(0, "div", 89)(1, "div", 90);
292
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_79_For_9_Template_div_click_1_listener() { const user_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleUserExpansion(user_r10.ID)); })("keydown.enter", function UserManagementComponent_Conditional_79_For_9_Template_div_keydown_enter_1_listener() { const user_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleUserExpansion(user_r10.ID)); });
293
+ i0.ɵɵelementStart(2, "div", 91);
294
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_79_For_9_Template_div_click_2_listener($event) { i0.ɵɵrestoreView(_r9); return i0.ɵɵresetView($event.stopPropagation()); });
295
+ i0.ɵɵelementStart(3, "input", 92);
296
+ i0.ɵɵlistener("change", function UserManagementComponent_Conditional_79_For_9_Template_input_change_3_listener($event) { const user_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleUserSelection(user_r10.ID, $event)); });
297
+ i0.ɵɵelementEnd()();
298
+ i0.ɵɵelementStart(4, "div", 93)(5, "div", 94);
299
+ i0.ɵɵtext(6);
177
300
  i0.ɵɵelementEnd();
178
- i0.ɵɵelementStart(4, "div", 81)(5, "button", 69);
179
- i0.ɵɵlistener("click", function UserManagementComponent_Conditional_74_Conditional_2_For_2_Template_button_click_5_listener($event) { const user_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); ctx_r2.editUser(user_r7); return i0.ɵɵresetView($event.stopPropagation()); });
180
- i0.ɵɵelement(6, "i", 70);
301
+ i0.ɵɵelementStart(7, "div", 95)(8, "h3", 96);
302
+ i0.ɵɵtext(9);
181
303
  i0.ɵɵelementEnd();
182
- i0.ɵɵelementStart(7, "button", 72);
183
- i0.ɵɵlistener("click", function UserManagementComponent_Conditional_74_Conditional_2_For_2_Template_button_click_7_listener($event) { const user_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r2 = i0.ɵɵnextContext(3); ctx_r2.confirmDeleteUser(user_r7); return i0.ɵɵresetView($event.stopPropagation()); });
184
- i0.ɵɵelement(8, "i", 73);
185
- i0.ɵɵelementEnd()()();
186
- i0.ɵɵelementStart(9, "div", 82)(10, "h3", 63);
304
+ i0.ɵɵelementStart(10, "p", 97);
187
305
  i0.ɵɵtext(11);
306
+ i0.ɵɵelementEnd()()();
307
+ i0.ɵɵelementStart(12, "div", 98)(13, "span", 99);
308
+ i0.ɵɵelement(14, "i", 100);
309
+ i0.ɵɵtext(15);
188
310
  i0.ɵɵelementEnd();
189
- i0.ɵɵelementStart(12, "p", 64);
190
- i0.ɵɵtext(13);
191
- i0.ɵɵelementEnd();
192
- i0.ɵɵelementStart(14, "p", 83);
193
- i0.ɵɵelement(15, "i", 84);
194
- i0.ɵɵtext(16);
311
+ i0.ɵɵelementStart(16, "div", 101);
312
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_79_For_9_Template_div_click_16_listener($event) { i0.ɵɵrestoreView(_r9); return i0.ɵɵresetView($event.stopPropagation()); });
313
+ i0.ɵɵelementStart(17, "button", 102);
314
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_79_For_9_Template_button_click_17_listener() { const user_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.editUser(user_r10)); });
315
+ i0.ɵɵelement(18, "i", 103);
195
316
  i0.ɵɵelementEnd();
196
- i0.ɵɵelementStart(17, "div", 85)(18, "div", 86);
197
- i0.ɵɵelement(19, "i");
198
- i0.ɵɵtext(20);
317
+ i0.ɵɵelementStart(19, "button", 104);
318
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_79_For_9_Template_button_click_19_listener() { const user_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.toggleUserStatus(user_r10)); });
319
+ i0.ɵɵelement(20, "i", 100);
199
320
  i0.ɵɵelementEnd();
200
- i0.ɵɵelementStart(21, "span", 66);
201
- i0.ɵɵelement(22, "i");
202
- i0.ɵɵtext(23);
321
+ i0.ɵɵelementStart(21, "button", 105);
322
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_79_For_9_Template_button_click_21_listener() { const user_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.confirmDeleteUser(user_r10)); });
323
+ i0.ɵɵelement(22, "i", 64);
203
324
  i0.ɵɵelementEnd()();
204
- i0.ɵɵelementStart(24, "div", 87)(25, "div", 67);
205
- i0.ɵɵelement(26, "i", 88);
206
- i0.ɵɵtext(27);
207
- i0.ɵɵpipe(28, "date");
208
- i0.ɵɵelementEnd()()()();
325
+ i0.ɵɵelementStart(23, "button", 106);
326
+ i0.ɵɵelement(24, "i", 107);
327
+ i0.ɵɵelementEnd()()();
328
+ i0.ɵɵtemplate(25, UserManagementComponent_Conditional_79_For_9_Conditional_25_Template, 52, 25, "div", 108);
329
+ i0.ɵɵelementEnd();
209
330
  } if (rf & 2) {
210
- const user_r7 = ctx.$implicit;
211
- const ctx_r2 = i0.ɵɵnextContext(3);
212
- i0.ɵɵadvance(3);
213
- i0.ɵɵtextInterpolate1(" ", ctx_r2.getUserInitials(user_r7), " ");
214
- i0.ɵɵadvance(8);
215
- i0.ɵɵtextInterpolate(user_r7.Name);
331
+ const user_r10 = ctx.$implicit;
332
+ const ctx_r1 = i0.ɵɵnextContext(2);
333
+ i0.ɵɵclassProp("expanded", ctx_r1.isUserExpanded(user_r10.ID))("selected", ctx_r1.isUserSelected(user_r10.ID));
334
+ i0.ɵɵadvance();
335
+ i0.ɵɵattribute("aria-expanded", ctx_r1.isUserExpanded(user_r10.ID));
216
336
  i0.ɵɵadvance(2);
217
- i0.ɵɵtextInterpolate2("", user_r7.FirstName, " ", user_r7.LastName, "");
337
+ i0.ɵɵproperty("checked", ctx_r1.isUserSelected(user_r10.ID));
338
+ i0.ɵɵattribute("aria-label", "Select " + user_r10.Name);
218
339
  i0.ɵɵadvance(3);
219
- i0.ɵɵtextInterpolate1(" ", user_r7.Email, " ");
340
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.getUserInitials(user_r10), " ");
220
341
  i0.ɵɵadvance(3);
221
- i0.ɵɵclassMap("fa-solid " + ctx_r2.getUserTypeIcon(user_r7));
342
+ i0.ɵɵtextInterpolate(user_r10.Name);
343
+ i0.ɵɵadvance(2);
344
+ i0.ɵɵtextInterpolate(user_r10.Email);
345
+ i0.ɵɵadvance(2);
346
+ i0.ɵɵclassMap(ctx_r1.getStatusClass(user_r10));
222
347
  i0.ɵɵadvance();
223
- i0.ɵɵtextInterpolate1(" ", user_r7.Type, " ");
348
+ i0.ɵɵclassMap("fa-solid " + ctx_r1.getStatusIcon(user_r10));
224
349
  i0.ɵɵadvance();
225
- i0.ɵɵclassMap(ctx_r2.getStatusClass(user_r7));
350
+ i0.ɵɵtextInterpolate1(" ", user_r10.IsActive ? "Active" : "Inactive", " ");
351
+ i0.ɵɵadvance(2);
352
+ i0.ɵɵattribute("aria-label", "Edit " + user_r10.Name);
353
+ i0.ɵɵadvance(2);
354
+ i0.ɵɵproperty("title", user_r10.IsActive ? "Deactivate" : "Activate");
355
+ i0.ɵɵattribute("aria-label", (user_r10.IsActive ? "Deactivate " : "Activate ") + user_r10.Name);
226
356
  i0.ɵɵadvance();
227
- i0.ɵɵclassMap("fa-solid " + ctx_r2.getStatusIcon(user_r7));
357
+ i0.ɵɵclassMap(user_r10.IsActive ? "fa-solid fa-toggle-on" : "fa-solid fa-toggle-off");
228
358
  i0.ɵɵadvance();
229
- i0.ɵɵtextInterpolate1(" ", user_r7.IsActive ? "Active" : "Inactive", " ");
359
+ i0.ɵɵattribute("aria-label", "Delete " + user_r10.Name);
230
360
  i0.ɵɵadvance(4);
231
- i0.ɵɵtextInterpolate1(" Last updated: ", user_r7.__mj_UpdatedAt ? i0.ɵɵpipeBind2(28, 14, user_r7.__mj_UpdatedAt, "short") : "Never", " ");
361
+ i0.ɵɵconditional(ctx_r1.isUserExpanded(user_r10.ID) ? 25 : -1);
232
362
  } }
233
- function UserManagementComponent_Conditional_74_Conditional_2_Conditional_3_Template(rf, ctx) { if (rf & 1) {
234
- i0.ɵɵelementStart(0, "div", 57);
235
- i0.ɵɵelement(1, "i", 74);
236
- i0.ɵɵelementStart(2, "p", 75);
363
+ function UserManagementComponent_Conditional_79_Conditional_10_Template(rf, ctx) { if (rf & 1) {
364
+ i0.ɵɵelementStart(0, "div", 88);
365
+ i0.ɵɵelement(1, "i", 127);
366
+ i0.ɵɵelementStart(2, "p", 128);
237
367
  i0.ɵɵtext(3, "No users found");
238
368
  i0.ɵɵelementEnd();
239
- i0.ɵɵelementStart(4, "p", 76);
369
+ i0.ɵɵelementStart(4, "p", 129);
240
370
  i0.ɵɵtext(5, "Try adjusting your filters or add a new user");
241
371
  i0.ɵɵelementEnd()();
242
372
  } }
243
- function UserManagementComponent_Conditional_74_Conditional_2_Template(rf, ctx) { if (rf & 1) {
244
- i0.ɵɵelementStart(0, "div", 51);
245
- i0.ɵɵrepeaterCreate(1, UserManagementComponent_Conditional_74_Conditional_2_For_2_Template, 29, 17, "div", 77, _forTrack0);
246
- i0.ɵɵtemplate(3, UserManagementComponent_Conditional_74_Conditional_2_Conditional_3_Template, 6, 0, "div", 57);
373
+ function UserManagementComponent_Conditional_79_Template(rf, ctx) { if (rf & 1) {
374
+ const _r8 = i0.ɵɵgetCurrentView();
375
+ i0.ɵɵelementStart(0, "div", 47)(1, "div", 81)(2, "div", 82)(3, "label", 83)(4, "input", 84);
376
+ i0.ɵɵlistener("change", function UserManagementComponent_Conditional_79_Template_input_change_4_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.toggleSelectAll()); });
247
377
  i0.ɵɵelementEnd();
248
- } if (rf & 2) {
249
- const ctx_r2 = i0.ɵɵnextContext(2);
250
- i0.ɵɵadvance();
251
- i0.ɵɵrepeater(ctx_r2.filteredUsers);
252
- i0.ɵɵadvance(2);
253
- i0.ɵɵconditional(ctx_r2.filteredUsers.length === 0 ? 3 : -1);
254
- } }
255
- function UserManagementComponent_Conditional_74_Template(rf, ctx) { if (rf & 1) {
256
- i0.ɵɵelementStart(0, "div", 40);
257
- i0.ɵɵtemplate(1, UserManagementComponent_Conditional_74_Conditional_1_Template, 22, 1, "div", 50)(2, UserManagementComponent_Conditional_74_Conditional_2_Template, 4, 1, "div", 51);
378
+ i0.ɵɵelementStart(5, "span", 85);
379
+ i0.ɵɵtext(6);
380
+ i0.ɵɵelementEnd()();
381
+ i0.ɵɵtemplate(7, UserManagementComponent_Conditional_79_Conditional_7_Template, 2, 1, "span", 86);
258
382
  i0.ɵɵelementEnd();
383
+ i0.ɵɵrepeaterCreate(8, UserManagementComponent_Conditional_79_For_9_Template, 26, 22, "div", 87, _forTrack0);
384
+ i0.ɵɵtemplate(10, UserManagementComponent_Conditional_79_Conditional_10_Template, 6, 0, "div", 88);
385
+ i0.ɵɵelementEnd()();
259
386
  } if (rf & 2) {
260
- const ctx_r2 = i0.ɵɵnextContext();
387
+ const ctx_r1 = i0.ɵɵnextContext();
388
+ i0.ɵɵadvance(4);
389
+ i0.ɵɵproperty("checked", ctx_r1.isAllSelected)("indeterminate", ctx_r1.isIndeterminate);
390
+ i0.ɵɵadvance(2);
391
+ i0.ɵɵtextInterpolate1("Select All (", ctx_r1.filteredUsers.length, ")");
261
392
  i0.ɵɵadvance();
262
- i0.ɵɵconditional(ctx_r2.viewMode === "grid" ? 1 : -1);
393
+ i0.ɵɵconditional(ctx_r1.hasSelection ? 7 : -1);
263
394
  i0.ɵɵadvance();
264
- i0.ɵɵconditional(ctx_r2.viewMode === "cards" ? 2 : -1);
395
+ i0.ɵɵrepeater(ctx_r1.filteredUsers);
396
+ i0.ɵɵadvance(2);
397
+ i0.ɵɵconditional(ctx_r1.filteredUsers.length === 0 ? 10 : -1);
265
398
  } }
266
- function UserManagementComponent_Conditional_76_Template(rf, ctx) { if (rf & 1) {
267
- const _r8 = i0.ɵɵgetCurrentView();
268
- i0.ɵɵelementStart(0, "div", 89);
269
- i0.ɵɵlistener("click", function UserManagementComponent_Conditional_76_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.showDeleteConfirm = false); });
270
- i0.ɵɵelementStart(1, "div", 90);
271
- i0.ɵɵlistener("click", function UserManagementComponent_Conditional_76_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r8); return i0.ɵɵresetView($event.stopPropagation()); });
272
- i0.ɵɵelementStart(2, "div", 91)(3, "h3", 92);
273
- i0.ɵɵelement(4, "i", 93);
399
+ function UserManagementComponent_Conditional_81_Template(rf, ctx) { if (rf & 1) {
400
+ const _r13 = i0.ɵɵgetCurrentView();
401
+ i0.ɵɵelementStart(0, "div", 130);
402
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_81_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showDeleteConfirm = false); });
403
+ i0.ɵɵelementStart(1, "div", 131);
404
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_81_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r13); return i0.ɵɵresetView($event.stopPropagation()); });
405
+ i0.ɵɵelementStart(2, "div", 132)(3, "h3", 133);
406
+ i0.ɵɵelement(4, "i", 134);
274
407
  i0.ɵɵtext(5, " Confirm Delete ");
275
408
  i0.ɵɵelementEnd();
276
- i0.ɵɵelementStart(6, "button", 94);
277
- i0.ɵɵlistener("click", function UserManagementComponent_Conditional_76_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.showDeleteConfirm = false); });
278
- i0.ɵɵelement(7, "i", 95);
409
+ i0.ɵɵelementStart(6, "button", 135);
410
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_81_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showDeleteConfirm = false); });
411
+ i0.ɵɵelement(7, "i", 55);
279
412
  i0.ɵɵelementEnd()();
280
- i0.ɵɵelementStart(8, "div", 96)(9, "p");
413
+ i0.ɵɵelementStart(8, "div", 136)(9, "p");
281
414
  i0.ɵɵtext(10, "Are you sure you want to delete user ");
282
415
  i0.ɵɵelementStart(11, "strong");
283
416
  i0.ɵɵtext(12);
284
417
  i0.ɵɵelementEnd();
285
418
  i0.ɵɵtext(13, "?");
286
419
  i0.ɵɵelementEnd();
287
- i0.ɵɵelementStart(14, "p", 97);
420
+ i0.ɵɵelementStart(14, "p", 137);
288
421
  i0.ɵɵtext(15, "This action cannot be undone.");
289
422
  i0.ɵɵelementEnd()();
290
- i0.ɵɵelementStart(16, "div", 98)(17, "button", 4);
291
- i0.ɵɵlistener("click", function UserManagementComponent_Conditional_76_Template_button_click_17_listener() { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.showDeleteConfirm = false); });
292
- i0.ɵɵtext(18, "Cancel");
293
- i0.ɵɵelementEnd();
294
- i0.ɵɵelementStart(19, "button", 99);
295
- i0.ɵɵlistener("click", function UserManagementComponent_Conditional_76_Template_button_click_19_listener() { i0.ɵɵrestoreView(_r8); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.deleteUser()); });
296
- i0.ɵɵelement(20, "i", 73);
297
- i0.ɵɵtext(21, " Delete User ");
423
+ i0.ɵɵelementStart(16, "div", 138)(17, "button", 139);
424
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_81_Template_button_click_17_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.deleteUser()); });
425
+ i0.ɵɵelement(18, "i", 64);
426
+ i0.ɵɵtext(19, " Delete User ");
427
+ i0.ɵɵelementEnd();
428
+ i0.ɵɵelementStart(20, "button", 140);
429
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_81_Template_button_click_20_listener() { i0.ɵɵrestoreView(_r13); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.showDeleteConfirm = false); });
430
+ i0.ɵɵtext(21, " Cancel ");
298
431
  i0.ɵɵelementEnd()()()();
299
432
  } if (rf & 2) {
300
- const ctx_r2 = i0.ɵɵnextContext();
433
+ const ctx_r1 = i0.ɵɵnextContext();
301
434
  i0.ɵɵadvance(12);
302
- i0.ɵɵtextInterpolate(ctx_r2.selectedUser.Name);
435
+ i0.ɵɵtextInterpolate(ctx_r1.selectedUser.Name);
436
+ } }
437
+ function UserManagementComponent_Conditional_82_Conditional_4_Template(rf, ctx) { if (rf & 1) {
438
+ i0.ɵɵelement(0, "i", 134);
439
+ } }
440
+ function UserManagementComponent_Conditional_82_Conditional_5_Template(rf, ctx) { if (rf & 1) {
441
+ i0.ɵɵelement(0, "i", 143);
442
+ } }
443
+ function UserManagementComponent_Conditional_82_Conditional_6_Template(rf, ctx) { if (rf & 1) {
444
+ i0.ɵɵelement(0, "i", 144);
445
+ } }
446
+ function UserManagementComponent_Conditional_82_Conditional_13_Template(rf, ctx) { if (rf & 1) {
447
+ i0.ɵɵelementStart(0, "p", 137);
448
+ i0.ɵɵtext(1, "This action cannot be undone.");
449
+ i0.ɵɵelementEnd();
450
+ } }
451
+ function UserManagementComponent_Conditional_82_Conditional_16_Template(rf, ctx) { if (rf & 1) {
452
+ i0.ɵɵelement(0, "i", 148);
453
+ i0.ɵɵtext(1, " Processing... ");
454
+ } }
455
+ function UserManagementComponent_Conditional_82_Conditional_17_Conditional_0_Template(rf, ctx) { if (rf & 1) {
456
+ i0.ɵɵelement(0, "i", 64);
457
+ } }
458
+ function UserManagementComponent_Conditional_82_Conditional_17_Conditional_1_Template(rf, ctx) { if (rf & 1) {
459
+ i0.ɵɵelement(0, "i", 58);
460
+ } }
461
+ function UserManagementComponent_Conditional_82_Conditional_17_Conditional_2_Template(rf, ctx) { if (rf & 1) {
462
+ i0.ɵɵelement(0, "i", 60);
463
+ } }
464
+ function UserManagementComponent_Conditional_82_Conditional_17_Template(rf, ctx) { if (rf & 1) {
465
+ i0.ɵɵtemplate(0, UserManagementComponent_Conditional_82_Conditional_17_Conditional_0_Template, 1, 0, "i", 64)(1, UserManagementComponent_Conditional_82_Conditional_17_Conditional_1_Template, 1, 0, "i", 58)(2, UserManagementComponent_Conditional_82_Conditional_17_Conditional_2_Template, 1, 0, "i", 60);
466
+ i0.ɵɵtext(3);
467
+ } if (rf & 2) {
468
+ const ctx_r1 = i0.ɵɵnextContext(2);
469
+ i0.ɵɵconditional(ctx_r1.bulkActionType === "delete" ? 0 : ctx_r1.bulkActionType === "enable" ? 1 : 2);
470
+ i0.ɵɵadvance(3);
471
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.getBulkActionButtonText(), " ");
472
+ } }
473
+ function UserManagementComponent_Conditional_82_Template(rf, ctx) { if (rf & 1) {
474
+ const _r14 = i0.ɵɵgetCurrentView();
475
+ i0.ɵɵelementStart(0, "div", 141);
476
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_82_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.cancelBulkAction()); });
477
+ i0.ɵɵelementStart(1, "div", 131);
478
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_82_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r14); return i0.ɵɵresetView($event.stopPropagation()); });
479
+ i0.ɵɵelementStart(2, "div", 132)(3, "h3", 142);
480
+ i0.ɵɵtemplate(4, UserManagementComponent_Conditional_82_Conditional_4_Template, 1, 0, "i", 134)(5, UserManagementComponent_Conditional_82_Conditional_5_Template, 1, 0, "i", 143)(6, UserManagementComponent_Conditional_82_Conditional_6_Template, 1, 0, "i", 144);
481
+ i0.ɵɵtext(7);
482
+ i0.ɵɵelementEnd();
483
+ i0.ɵɵelementStart(8, "button", 135);
484
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_82_Template_button_click_8_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.cancelBulkAction()); });
485
+ i0.ɵɵelement(9, "i", 55);
486
+ i0.ɵɵelementEnd()();
487
+ i0.ɵɵelementStart(10, "div", 145)(11, "p");
488
+ i0.ɵɵtext(12);
489
+ i0.ɵɵelementEnd();
490
+ i0.ɵɵtemplate(13, UserManagementComponent_Conditional_82_Conditional_13_Template, 2, 0, "p", 137);
491
+ i0.ɵɵelementEnd();
492
+ i0.ɵɵelementStart(14, "div", 138)(15, "button", 146);
493
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_82_Template_button_click_15_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.executeBulkAction()); });
494
+ i0.ɵɵtemplate(16, UserManagementComponent_Conditional_82_Conditional_16_Template, 2, 0)(17, UserManagementComponent_Conditional_82_Conditional_17_Template, 4, 2);
495
+ i0.ɵɵelementEnd();
496
+ i0.ɵɵelementStart(18, "button", 147);
497
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_82_Template_button_click_18_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.cancelBulkAction()); });
498
+ i0.ɵɵtext(19, " Cancel ");
499
+ i0.ɵɵelementEnd()()()();
500
+ } if (rf & 2) {
501
+ const ctx_r1 = i0.ɵɵnextContext();
502
+ i0.ɵɵadvance(4);
503
+ i0.ɵɵconditional(ctx_r1.bulkActionType === "delete" ? 4 : ctx_r1.bulkActionType === "enable" ? 5 : 6);
504
+ i0.ɵɵadvance(3);
505
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.getBulkActionTitle(), " ");
506
+ i0.ɵɵadvance(5);
507
+ i0.ɵɵtextInterpolate(ctx_r1.getBulkActionMessage());
508
+ i0.ɵɵadvance();
509
+ i0.ɵɵconditional(ctx_r1.bulkActionType === "delete" ? 13 : -1);
510
+ i0.ɵɵadvance(2);
511
+ i0.ɵɵclassMap(ctx_r1.bulkActionType === "delete" ? "mj-btn mj-btn-danger" : "mj-btn mj-btn-primary");
512
+ i0.ɵɵproperty("disabled", ctx_r1.isLoading);
513
+ i0.ɵɵadvance();
514
+ i0.ɵɵconditional(ctx_r1.isLoading ? 16 : 17);
515
+ i0.ɵɵadvance(2);
516
+ i0.ɵɵproperty("disabled", ctx_r1.isLoading);
517
+ } }
518
+ function UserManagementComponent_Conditional_83_For_18_Template(rf, ctx) { if (rf & 1) {
519
+ i0.ɵɵelementStart(0, "option", 42);
520
+ i0.ɵɵtext(1);
521
+ i0.ɵɵelementEnd();
522
+ } if (rf & 2) {
523
+ const role_r16 = ctx.$implicit;
524
+ i0.ɵɵproperty("value", role_r16.ID);
525
+ i0.ɵɵadvance();
526
+ i0.ɵɵtextInterpolate(role_r16.Name);
527
+ } }
528
+ function UserManagementComponent_Conditional_83_Conditional_21_Template(rf, ctx) { if (rf & 1) {
529
+ i0.ɵɵelement(0, "i", 148);
530
+ i0.ɵɵtext(1, " Assigning... ");
531
+ } }
532
+ function UserManagementComponent_Conditional_83_Conditional_22_Template(rf, ctx) { if (rf & 1) {
533
+ i0.ɵɵelement(0, "i", 62);
534
+ i0.ɵɵtext(1, " Assign Role ");
535
+ } }
536
+ function UserManagementComponent_Conditional_83_Template(rf, ctx) { if (rf & 1) {
537
+ const _r15 = i0.ɵɵgetCurrentView();
538
+ i0.ɵɵelementStart(0, "div", 149);
539
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_83_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.cancelBulkRoleAssign()); });
540
+ i0.ɵɵelementStart(1, "div", 131);
541
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_83_Template_div_click_1_listener($event) { i0.ɵɵrestoreView(_r15); return i0.ɵɵresetView($event.stopPropagation()); });
542
+ i0.ɵɵelementStart(2, "div", 132)(3, "h3", 150);
543
+ i0.ɵɵelement(4, "i", 62);
544
+ i0.ɵɵtext(5);
545
+ i0.ɵɵelementEnd();
546
+ i0.ɵɵelementStart(6, "button", 135);
547
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_83_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.cancelBulkRoleAssign()); });
548
+ i0.ɵɵelement(7, "i", 55);
549
+ i0.ɵɵelementEnd()();
550
+ i0.ɵɵelementStart(8, "div", 151)(9, "p");
551
+ i0.ɵɵtext(10, "Select a role to assign to the selected users:");
552
+ i0.ɵɵelementEnd();
553
+ i0.ɵɵelementStart(11, "div", 152)(12, "label", 153);
554
+ i0.ɵɵtext(13, "Role");
555
+ i0.ɵɵelementEnd();
556
+ i0.ɵɵelementStart(14, "select", 154);
557
+ i0.ɵɵtwoWayListener("ngModelChange", function UserManagementComponent_Conditional_83_Template_select_ngModelChange_14_listener($event) { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.bulkRoleId, $event) || (ctx_r1.bulkRoleId = $event); return i0.ɵɵresetView($event); });
558
+ i0.ɵɵelementStart(15, "option", 41);
559
+ i0.ɵɵtext(16, "Select a role...");
560
+ i0.ɵɵelementEnd();
561
+ i0.ɵɵrepeaterCreate(17, UserManagementComponent_Conditional_83_For_18_Template, 2, 2, "option", 42, _forTrack0);
562
+ i0.ɵɵelementEnd()()();
563
+ i0.ɵɵelementStart(19, "div", 138)(20, "button", 155);
564
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_83_Template_button_click_20_listener() { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.executeBulkRoleAssign()); });
565
+ i0.ɵɵtemplate(21, UserManagementComponent_Conditional_83_Conditional_21_Template, 2, 0)(22, UserManagementComponent_Conditional_83_Conditional_22_Template, 2, 0);
566
+ i0.ɵɵelementEnd();
567
+ i0.ɵɵelementStart(23, "button", 147);
568
+ i0.ɵɵlistener("click", function UserManagementComponent_Conditional_83_Template_button_click_23_listener() { i0.ɵɵrestoreView(_r15); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.cancelBulkRoleAssign()); });
569
+ i0.ɵɵtext(24, " Cancel ");
570
+ i0.ɵɵelementEnd()()()();
571
+ } if (rf & 2) {
572
+ const ctx_r1 = i0.ɵɵnextContext();
573
+ i0.ɵɵadvance(5);
574
+ i0.ɵɵtextInterpolate2(" Assign Role to ", ctx_r1.selectedCount, " User", ctx_r1.selectedCount > 1 ? "s" : "", " ");
575
+ i0.ɵɵadvance(9);
576
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r1.bulkRoleId);
577
+ i0.ɵɵadvance(3);
578
+ i0.ɵɵrepeater(ctx_r1.roles);
579
+ i0.ɵɵadvance(3);
580
+ i0.ɵɵproperty("disabled", !ctx_r1.bulkRoleId || ctx_r1.isLoading);
581
+ i0.ɵɵadvance();
582
+ i0.ɵɵconditional(ctx_r1.isLoading ? 21 : 22);
583
+ i0.ɵɵadvance(2);
584
+ i0.ɵɵproperty("disabled", ctx_r1.isLoading);
303
585
  } }
304
586
  let UserManagementComponent = class UserManagementComponent extends BaseDashboard {
305
587
  // State management
@@ -309,9 +591,16 @@ let UserManagementComponent = class UserManagementComponent extends BaseDashboar
309
591
  selectedUser = null;
310
592
  isLoading = false;
311
593
  error = null;
594
+ // Selection state for bulk actions
595
+ selectedUserIds = new Set();
312
596
  // Dialog state
313
597
  showUserDialog = false;
314
598
  userDialogData = null;
599
+ // Bulk action dialog state
600
+ showBulkActionConfirm = false;
601
+ bulkActionType = null;
602
+ showBulkRoleAssign = false;
603
+ bulkRoleId = '';
315
604
  // Stats
316
605
  stats = {
317
606
  totalUsers: 0,
@@ -329,7 +618,9 @@ let UserManagementComponent = class UserManagementComponent extends BaseDashboar
329
618
  showCreateDialog = false;
330
619
  showEditDialog = false;
331
620
  showDeleteConfirm = false;
332
- viewMode = 'grid';
621
+ showMobileFilters = false;
622
+ // Mobile expansion state
623
+ expandedUserIds = new Set();
333
624
  // User-Role mapping
334
625
  userRoleMap = new Map(); // userId -> roleIds[]
335
626
  // Grid configuration
@@ -535,9 +826,6 @@ let UserManagementComponent = class UserManagementComponent extends BaseDashboar
535
826
  user.IsActive = !user.IsActive; // Revert on error
536
827
  }
537
828
  }
538
- toggleViewMode() {
539
- this.viewMode = this.viewMode === 'grid' ? 'cards' : 'grid';
540
- }
541
829
  exportUsers() {
542
830
  if (this.filteredUsers.length === 0) {
543
831
  this.error = 'No users to export';
@@ -618,109 +906,336 @@ let UserManagementComponent = class UserManagementComponent extends BaseDashboar
618
906
  this.loadInitialData();
619
907
  }
620
908
  }
909
+ // Selection methods for bulk actions
910
+ get isAllSelected() {
911
+ return this.filteredUsers.length > 0 &&
912
+ this.filteredUsers.every(user => this.selectedUserIds.has(user.ID));
913
+ }
914
+ get isIndeterminate() {
915
+ const selectedCount = this.filteredUsers.filter(user => this.selectedUserIds.has(user.ID)).length;
916
+ return selectedCount > 0 && selectedCount < this.filteredUsers.length;
917
+ }
918
+ get hasSelection() {
919
+ return this.selectedUserIds.size > 0;
920
+ }
921
+ get selectedCount() {
922
+ return this.selectedUserIds.size;
923
+ }
924
+ get hasActiveFilters() {
925
+ const filters = this.filters$.value;
926
+ return filters.status !== 'all' || filters.role !== '';
927
+ }
928
+ get activeFilterCount() {
929
+ let count = 0;
930
+ const filters = this.filters$.value;
931
+ if (filters.status !== 'all')
932
+ count++;
933
+ if (filters.role !== '')
934
+ count++;
935
+ return count;
936
+ }
937
+ clearFilters() {
938
+ this.filters$.next({
939
+ ...this.filters$.value,
940
+ status: 'all',
941
+ role: ''
942
+ });
943
+ this.showMobileFilters = false;
944
+ }
945
+ toggleSelectAll() {
946
+ if (this.isAllSelected) {
947
+ // Deselect all filtered users
948
+ this.filteredUsers.forEach(user => this.selectedUserIds.delete(user.ID));
949
+ }
950
+ else {
951
+ // Select all filtered users
952
+ this.filteredUsers.forEach(user => this.selectedUserIds.add(user.ID));
953
+ }
954
+ }
955
+ toggleUserSelection(userId, event) {
956
+ if (event) {
957
+ event.stopPropagation();
958
+ }
959
+ if (this.selectedUserIds.has(userId)) {
960
+ this.selectedUserIds.delete(userId);
961
+ }
962
+ else {
963
+ this.selectedUserIds.add(userId);
964
+ }
965
+ }
966
+ isUserSelected(userId) {
967
+ return this.selectedUserIds.has(userId);
968
+ }
969
+ clearSelection() {
970
+ this.selectedUserIds.clear();
971
+ }
972
+ // Bulk action methods
973
+ confirmBulkAction(action) {
974
+ if (!this.hasSelection)
975
+ return;
976
+ this.bulkActionType = action;
977
+ this.showBulkActionConfirm = true;
978
+ }
979
+ cancelBulkAction() {
980
+ this.showBulkActionConfirm = false;
981
+ this.bulkActionType = null;
982
+ }
983
+ async executeBulkAction() {
984
+ if (!this.bulkActionType || !this.hasSelection)
985
+ return;
986
+ try {
987
+ this.isLoading = true;
988
+ const selectedUsers = this.users.filter(user => this.selectedUserIds.has(user.ID));
989
+ switch (this.bulkActionType) {
990
+ case 'enable':
991
+ await this.bulkSetUserStatus(selectedUsers, true);
992
+ break;
993
+ case 'disable':
994
+ await this.bulkSetUserStatus(selectedUsers, false);
995
+ break;
996
+ case 'delete':
997
+ await this.bulkDeleteUsers(selectedUsers);
998
+ break;
999
+ }
1000
+ this.clearSelection();
1001
+ this.showBulkActionConfirm = false;
1002
+ this.bulkActionType = null;
1003
+ await this.loadInitialData();
1004
+ }
1005
+ catch (error) {
1006
+ console.error('Bulk action failed:', error);
1007
+ this.error = error instanceof Error ? error.message : 'Bulk action failed';
1008
+ }
1009
+ finally {
1010
+ this.isLoading = false;
1011
+ }
1012
+ }
1013
+ async bulkSetUserStatus(users, isActive) {
1014
+ for (const user of users) {
1015
+ user.IsActive = isActive;
1016
+ const result = await user.Save();
1017
+ if (!result) {
1018
+ throw new Error(`Failed to update user ${user.Name}: ${user.LatestResult?.Message}`);
1019
+ }
1020
+ }
1021
+ }
1022
+ async bulkDeleteUsers(users) {
1023
+ for (const user of users) {
1024
+ const result = await user.Delete();
1025
+ if (!result) {
1026
+ throw new Error(`Failed to delete user ${user.Name}: ${user.LatestResult?.Message}`);
1027
+ }
1028
+ }
1029
+ }
1030
+ // Bulk role assignment
1031
+ openBulkRoleAssign() {
1032
+ if (!this.hasSelection)
1033
+ return;
1034
+ this.bulkRoleId = '';
1035
+ this.showBulkRoleAssign = true;
1036
+ }
1037
+ cancelBulkRoleAssign() {
1038
+ this.showBulkRoleAssign = false;
1039
+ this.bulkRoleId = '';
1040
+ }
1041
+ async executeBulkRoleAssign() {
1042
+ if (!this.bulkRoleId || !this.hasSelection)
1043
+ return;
1044
+ try {
1045
+ this.isLoading = true;
1046
+ const selectedUserIds = Array.from(this.selectedUserIds);
1047
+ for (const userId of selectedUserIds) {
1048
+ // Check if user already has this role
1049
+ const existingRoles = this.userRoleMap.get(userId) || [];
1050
+ if (!existingRoles.includes(this.bulkRoleId)) {
1051
+ const userRole = await this.metadata.GetEntityObject('User Roles');
1052
+ userRole.NewRecord();
1053
+ userRole.UserID = userId;
1054
+ userRole.RoleID = this.bulkRoleId;
1055
+ const result = await userRole.Save();
1056
+ if (!result) {
1057
+ console.warn(`Failed to assign role to user ${userId}:`, userRole.LatestResult?.Message);
1058
+ }
1059
+ }
1060
+ }
1061
+ this.clearSelection();
1062
+ this.showBulkRoleAssign = false;
1063
+ this.bulkRoleId = '';
1064
+ await this.loadInitialData();
1065
+ }
1066
+ catch (error) {
1067
+ console.error('Bulk role assignment failed:', error);
1068
+ this.error = error instanceof Error ? error.message : 'Bulk role assignment failed';
1069
+ }
1070
+ finally {
1071
+ this.isLoading = false;
1072
+ }
1073
+ }
1074
+ getBulkActionMessage() {
1075
+ const count = this.selectedCount;
1076
+ switch (this.bulkActionType) {
1077
+ case 'enable':
1078
+ return `Are you sure you want to enable ${count} user${count > 1 ? 's' : ''}?`;
1079
+ case 'disable':
1080
+ return `Are you sure you want to disable ${count} user${count > 1 ? 's' : ''}?`;
1081
+ case 'delete':
1082
+ return `Are you sure you want to delete ${count} user${count > 1 ? 's' : ''}? This action cannot be undone.`;
1083
+ default:
1084
+ return '';
1085
+ }
1086
+ }
1087
+ getBulkActionTitle() {
1088
+ switch (this.bulkActionType) {
1089
+ case 'enable':
1090
+ return 'Enable Users';
1091
+ case 'disable':
1092
+ return 'Disable Users';
1093
+ case 'delete':
1094
+ return 'Delete Users';
1095
+ default:
1096
+ return 'Confirm Action';
1097
+ }
1098
+ }
1099
+ getBulkActionButtonText() {
1100
+ const count = this.selectedCount;
1101
+ switch (this.bulkActionType) {
1102
+ case 'enable':
1103
+ return `Enable ${count} User${count > 1 ? 's' : ''}`;
1104
+ case 'disable':
1105
+ return `Disable ${count} User${count > 1 ? 's' : ''}`;
1106
+ case 'delete':
1107
+ return `Delete ${count} User${count > 1 ? 's' : ''}`;
1108
+ default:
1109
+ return 'Confirm';
1110
+ }
1111
+ }
1112
+ // Expansion methods
1113
+ toggleUserExpansion(userId) {
1114
+ if (this.expandedUserIds.has(userId)) {
1115
+ this.expandedUserIds.delete(userId);
1116
+ }
1117
+ else {
1118
+ this.expandedUserIds.add(userId);
1119
+ }
1120
+ }
1121
+ isUserExpanded(userId) {
1122
+ return this.expandedUserIds.has(userId);
1123
+ }
1124
+ // Get roles for a specific user
1125
+ getUserRoles(userId) {
1126
+ const roleIds = this.userRoleMap.get(userId) || [];
1127
+ return this.roles.filter(role => roleIds.includes(role.ID));
1128
+ }
621
1129
  static ɵfac = function UserManagementComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || UserManagementComponent)(); };
622
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: UserManagementComponent, selectors: [["mj-user-management"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 77, vars: 28, consts: [[1, "user-management-container"], [1, "action-buttons"], [1, "mj-btn", "mj-btn-secondary", 3, "click", "disabled"], [1, "fa-solid", "fa-refresh"], [1, "mj-btn", "mj-btn-secondary", 3, "click"], [1, "fa-solid", "fa-download"], [1, "mj-btn", "mj-btn-primary", 3, "click"], [1, "fa-solid", "fa-plus"], [1, "mj-grid", "mj-grid-4"], [1, "mj-card"], [1, "stat-icon", "stat-icon-total"], [1, "fa-solid", "fa-users"], [1, "stat-content"], [1, "stat-value"], [1, "stat-label"], [1, "stat-icon", "stat-icon-active"], [1, "fa-solid", "fa-user-check"], [1, "stat-icon", "stat-icon-inactive"], [1, "fa-solid", "fa-user-xmark"], [1, "stat-icon", "stat-icon-admin"], [1, "fa-solid", "fa-shield-halved"], [1, "filters-section"], [1, "filters-row"], [1, "search-container"], [1, "fa-solid", "fa-search", "search-icon"], ["type", "text", "placeholder", "Search users by name or email...", 1, "search-input", 3, "input", "value"], [1, "filter-group"], [1, "filter-label"], [1, "filter-buttons"], [1, "mj-btn", "mj-btn-ghost", 3, "click"], [1, "filter-select", 3, "change"], ["value", ""], [3, "value"], [1, "view-toggle"], ["title", "Grid View", 1, "mj-btn", "mj-btn-icon-only", 3, "click"], [1, "fa-solid", "fa-table"], ["title", "Card View", 1, "mj-btn", "mj-btn-icon-only", 3, "click"], [1, "fa-solid", "fa-th-large"], [1, "loading-container"], [1, "error-container"], [1, "content-area"], [3, "result", "data", "visible"], [1, "modal-backdrop"], [1, "loading-spinner"], [1, "spinner-ring"], [1, "loading-text"], [1, "error-content"], [1, "fa-solid", "fa-exclamation-triangle", "error-icon"], [1, "error-message"], [1, "retry-button", 3, "click"], [1, "users-table"], [1, "users-grid"], [1, "modern-table"], [1, "th-checkbox"], ["type", "checkbox", 1, "checkbox"], [1, "th-actions"], [1, "table-row"], [1, "empty-state"], [1, "table-row", 3, "click"], [1, "td-checkbox", 3, "click"], [1, "user-cell"], [1, "user-avatar"], [1, "user-info"], [1, "user-name"], [1, "user-fullname"], [1, "user-type"], [1, "status-badge"], [1, "last-login"], [1, "td-actions", 3, "click"], ["title", "Edit", 1, "mj-btn", "mj-btn-ghost", "mj-btn-sm", 3, "click"], [1, "fa-solid", "fa-edit"], [1, "mj-btn", "mj-btn-ghost", "mj-btn-sm", 3, "click", "title"], ["title", "Delete", 1, "mj-btn", "mj-btn-ghost", "mj-btn-sm", "text-danger", 3, "click"], [1, "fa-solid", "fa-trash"], [1, "fa-solid", "fa-users-slash", "empty-icon"], [1, "empty-text"], [1, "empty-subtext"], [1, "user-card"], [1, "user-card", 3, "click"], [1, "card-header"], [1, "user-avatar-large"], [1, "card-actions"], [1, "card-body"], [1, "user-email"], [1, "fa-solid", "fa-envelope"], [1, "card-meta"], [1, "meta-item"], [1, "card-footer"], [1, "fa-solid", "fa-clock"], [1, "modal-backdrop", 3, "click"], [1, "modal-dialog", 3, "click"], [1, "modal-header"], [1, "modal-title"], [1, "fa-solid", "fa-exclamation-triangle", "text-danger"], [1, "modal-close", 3, "click"], [1, "fa-solid", "fa-times"], [1, "modal-body"], [1, "text-muted"], [1, "modal-footer"], [1, "mj-btn", "mj-btn-primary", "text-danger", 3, "click"]], template: function UserManagementComponent_Template(rf, ctx) { if (rf & 1) {
623
- i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "button", 2);
624
- i0.ɵɵlistener("click", function UserManagementComponent_Template_button_click_2_listener() { return ctx.refreshData(); });
625
- i0.ɵɵelement(3, "i", 3);
626
- i0.ɵɵtext(4, " Refresh ");
627
- i0.ɵɵelementEnd();
628
- i0.ɵɵelementStart(5, "button", 4);
629
- i0.ɵɵlistener("click", function UserManagementComponent_Template_button_click_5_listener() { return ctx.exportUsers(); });
630
- i0.ɵɵelement(6, "i", 5);
631
- i0.ɵɵtext(7, " Export ");
632
- i0.ɵɵelementEnd();
633
- i0.ɵɵelementStart(8, "button", 6);
634
- i0.ɵɵlistener("click", function UserManagementComponent_Template_button_click_8_listener() { return ctx.createNewUser(); });
635
- i0.ɵɵelement(9, "i", 7);
636
- i0.ɵɵtext(10, " Add User ");
1130
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: UserManagementComponent, selectors: [["mj-user-management"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 84, vars: 31, consts: [[1, "user-management-container"], [1, "sticky-header"], ["role", "toolbar", "aria-label", "User management actions", 1, "action-buttons"], ["aria-label", "Refresh user list", 1, "mj-btn", "mj-btn-secondary", "mj-btn-icon-mobile", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-refresh"], [1, "btn-text"], ["aria-label", "Export users to file", 1, "mj-btn", "mj-btn-secondary", "mj-btn-icon-mobile", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-download"], ["aria-label", "Add new user", 1, "mj-btn", "mj-btn-primary", "mj-btn-icon-mobile", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-plus"], ["role", "toolbar", "aria-label", "Bulk actions", 1, "bulk-action-toolbar"], ["role", "region", "aria-label", "User statistics", 1, "mj-grid-4"], [1, "mj-card"], ["aria-hidden", "true", 1, "stat-icon", "stat-icon-total"], [1, "fa-solid", "fa-users"], [1, "stat-content"], ["aria-label", "Total users count", 1, "stat-value"], [1, "stat-label"], ["aria-hidden", "true", 1, "stat-icon", "stat-icon-active"], [1, "fa-solid", "fa-user-check"], ["aria-label", "Active users count", 1, "stat-value"], ["aria-hidden", "true", 1, "stat-icon", "stat-icon-inactive"], [1, "fa-solid", "fa-user-xmark"], ["aria-label", "Inactive users count", 1, "stat-value"], ["aria-hidden", "true", 1, "stat-icon", "stat-icon-admin"], [1, "fa-solid", "fa-shield-halved"], ["aria-label", "Owner users count", 1, "stat-value"], ["role", "search", "aria-label", "Filter users", 1, "filters-section"], [1, "filters-row"], [1, "mj-search"], ["aria-hidden", "true", 1, "fa-solid", "fa-search", "mj-search-icon"], ["type", "text", "placeholder", "Search users by name or email...", "aria-label", "Search users by name or email", 1, "mj-search-input", 3, "input", "value"], ["aria-label", "Toggle filters", 1, "mobile-filter-toggle", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-filter"], [1, "filter-badge"], [1, "mj-filter-group", "desktop-filter-group"], ["id", "status-filter-label", 1, "mj-filter-label"], ["role", "group", "aria-labelledby", "status-filter-label", 1, "mj-filter-buttons"], [1, "mj-btn", "mj-btn-ghost", 3, "click"], ["for", "role-filter", 1, "mj-filter-label"], ["id", "role-filter", "aria-label", "Filter by role", 1, "mj-filter-select", 3, "change"], ["value", ""], [3, "value"], [1, "mobile-filter-dropdown"], [1, "scrollable-content"], ["role", "status", "aria-live", "polite", "aria-busy", "true", 1, "loading-container"], ["role", "alert", "aria-live", "assertive", 1, "error-container"], [1, "content-area"], [3, "result", "data", "visible"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "delete-dialog-title", "aria-describedby", "delete-dialog-desc", 1, "modal-backdrop"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "bulk-action-dialog-title", "aria-describedby", "bulk-action-dialog-desc", 1, "modal-backdrop"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "bulk-role-dialog-title", "aria-describedby", "bulk-role-dialog-desc", 1, "modal-backdrop"], [1, "bulk-selection-info"], ["aria-hidden", "true", 1, "fa-solid", "fa-check-square"], ["aria-label", "Clear selection", 1, "mj-btn", "mj-btn-ghost", "mj-btn-sm", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-times"], [1, "bulk-action-buttons"], ["aria-label", "Enable selected users", 1, "mj-btn", "mj-btn-secondary", "mj-btn-sm", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-toggle-on"], ["aria-label", "Disable selected users", 1, "mj-btn", "mj-btn-secondary", "mj-btn-sm", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-toggle-off"], ["aria-label", "Assign role to selected users", 1, "mj-btn", "mj-btn-secondary", "mj-btn-sm", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-user-tag"], ["aria-label", "Delete selected users", 1, "mj-btn", "mj-btn-danger", "mj-btn-sm", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-trash"], [1, "mobile-filter-content"], [1, "mj-filter-group"], ["id", "status-filter-label-mobile", 1, "mj-filter-label"], ["aria-labelledby", "status-filter-label-mobile", 1, "mj-filter-select", 3, "change", "value"], ["value", "all"], ["value", "active"], ["value", "inactive"], ["for", "role-filter-mobile", 1, "mj-filter-label"], ["id", "role-filter-mobile", "aria-label", "Filter by role", 1, "mj-filter-select", 3, "change"], [1, "mj-btn", "mj-btn-ghost", "mj-btn-sm", "clear-filters-btn"], [1, "mj-btn", "mj-btn-ghost", "mj-btn-sm", "clear-filters-btn", 3, "click"], ["text", "Loading users...", "size", "medium"], [1, "error-content"], ["aria-hidden", "true", 1, "fa-solid", "fa-exclamation-triangle", "error-icon"], [1, "error-message"], ["aria-label", "Retry loading users", 1, "retry-button", 3, "click"], ["role", "list", "aria-label", "Users list", 1, "users-list"], [1, "list-header"], [1, "select-all-label"], ["type", "checkbox", "aria-label", "Select all users", 1, "checkbox", 3, "change", "checked", "indeterminate"], [1, "select-all-text"], [1, "selection-count"], ["role", "listitem", 1, "user-card", 3, "expanded", "selected"], ["role", "status", 1, "empty-state"], ["role", "listitem", 1, "user-card"], ["role", "button", "tabindex", "0", 1, "user-header", 3, "click", "keydown.enter"], [1, "user-selection", 3, "click"], ["type", "checkbox", 1, "checkbox", 3, "change", "checked"], [1, "user-info"], ["aria-hidden", "true", 1, "user-avatar"], [1, "user-details"], [1, "user-name"], [1, "user-email"], [1, "user-meta"], [1, "status-badge"], ["aria-hidden", "true"], [1, "user-actions", "desktop-only", 3, "click"], ["title", "Edit", 1, "mj-btn", "mj-btn-ghost", "mj-btn-sm", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-edit"], [1, "mj-btn", "mj-btn-ghost", "mj-btn-sm", 3, "click", "title"], ["title", "Delete", 1, "mj-btn", "mj-btn-ghost", "mj-btn-sm", "mj-btn-danger", 3, "click"], ["aria-label", "Toggle user details", 1, "expand-btn"], ["aria-hidden", "true", 1, "fa-solid", "fa-chevron-down"], [1, "user-content"], [1, "mobile-actions-bar", 3, "click"], [1, "mobile-action-buttons"], [1, "mj-btn", "mj-btn-ghost", "mj-btn-sm", 3, "click"], [1, "btn-label"], [1, "mj-btn", "mj-btn-ghost", "mj-btn-sm", "mj-btn-danger", 3, "click"], [1, "user-stats"], [1, "stat-item"], [1, "stat-value"], ["aria-hidden", "true", 1, "fa-solid", "fa-id-card"], ["aria-hidden", "true", 1, "fa-solid", "fa-calendar"], ["aria-hidden", "true", 1, "fa-solid", "fa-clock"], [1, "roles-section"], [1, "section-title"], ["aria-hidden", "true", 1, "fa-solid", "fa-user-shield"], [1, "roles-grid"], [1, "no-roles"], [1, "role-item"], ["aria-hidden", "true", 1, "fa-solid", "fa-shield"], ["aria-hidden", "true", 1, "fa-solid", "fa-users-slash", "empty-icon"], [1, "empty-text"], [1, "empty-subtext"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "delete-dialog-title", "aria-describedby", "delete-dialog-desc", 1, "modal-backdrop", 3, "click"], [1, "modal-dialog", 3, "click"], [1, "modal-header"], ["id", "delete-dialog-title", 1, "modal-title"], ["aria-hidden", "true", 1, "fa-solid", "fa-exclamation-triangle", "text-danger"], ["aria-label", "Close dialog", 1, "modal-close", 3, "click"], ["id", "delete-dialog-desc", 1, "modal-body"], [1, "text-muted"], [1, "modal-footer"], [1, "mj-btn", "mj-btn-danger", 3, "click"], [1, "mj-btn", "mj-btn-secondary", 3, "click"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "bulk-action-dialog-title", "aria-describedby", "bulk-action-dialog-desc", 1, "modal-backdrop", 3, "click"], ["id", "bulk-action-dialog-title", 1, "modal-title"], ["aria-hidden", "true", 1, "fa-solid", "fa-toggle-on", "text-success"], ["aria-hidden", "true", 1, "fa-solid", "fa-toggle-off", "text-warning"], ["id", "bulk-action-dialog-desc", 1, "modal-body"], [3, "click", "disabled"], [1, "mj-btn", "mj-btn-secondary", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-spinner", "fa-spin"], ["role", "dialog", "aria-modal", "true", "aria-labelledby", "bulk-role-dialog-title", "aria-describedby", "bulk-role-dialog-desc", 1, "modal-backdrop", 3, "click"], ["id", "bulk-role-dialog-title", 1, "modal-title"], ["id", "bulk-role-dialog-desc", 1, "modal-body"], [1, "form-field"], ["for", "bulk-role-select", 1, "field-label"], ["id", "bulk-role-select", "aria-label", "Select role to assign", 1, "field-select", 3, "ngModelChange", "ngModel"], [1, "mj-btn", "mj-btn-primary", 3, "click", "disabled"]], template: function UserManagementComponent_Template(rf, ctx) { if (rf & 1) {
1131
+ i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2)(3, "button", 3);
1132
+ i0.ɵɵlistener("click", function UserManagementComponent_Template_button_click_3_listener() { return ctx.refreshData(); });
1133
+ i0.ɵɵelement(4, "i", 4);
1134
+ i0.ɵɵelementStart(5, "span", 5);
1135
+ i0.ɵɵtext(6, "Refresh");
637
1136
  i0.ɵɵelementEnd()();
638
- i0.ɵɵelementStart(11, "div", 8)(12, "div", 9)(13, "div", 10);
639
- i0.ɵɵelement(14, "i", 11);
1137
+ i0.ɵɵelementStart(7, "button", 6);
1138
+ i0.ɵɵlistener("click", function UserManagementComponent_Template_button_click_7_listener() { return ctx.exportUsers(); });
1139
+ i0.ɵɵelement(8, "i", 7);
1140
+ i0.ɵɵelementStart(9, "span", 5);
1141
+ i0.ɵɵtext(10, "Export");
1142
+ i0.ɵɵelementEnd()();
1143
+ i0.ɵɵelementStart(11, "button", 8);
1144
+ i0.ɵɵlistener("click", function UserManagementComponent_Template_button_click_11_listener() { return ctx.createNewUser(); });
1145
+ i0.ɵɵelement(12, "i", 9);
1146
+ i0.ɵɵelementStart(13, "span", 5);
1147
+ i0.ɵɵtext(14, "Add User");
1148
+ i0.ɵɵelementEnd()()();
1149
+ i0.ɵɵtemplate(15, UserManagementComponent_Conditional_15_Template, 25, 2, "div", 10);
1150
+ i0.ɵɵelementStart(16, "div", 11)(17, "div", 12)(18, "div", 13);
1151
+ i0.ɵɵelement(19, "i", 14);
640
1152
  i0.ɵɵelementEnd();
641
- i0.ɵɵelementStart(15, "div", 12)(16, "div", 13);
642
- i0.ɵɵtext(17);
1153
+ i0.ɵɵelementStart(20, "div", 15)(21, "div", 16);
1154
+ i0.ɵɵtext(22);
643
1155
  i0.ɵɵelementEnd();
644
- i0.ɵɵelementStart(18, "div", 14);
645
- i0.ɵɵtext(19, "Total Users");
1156
+ i0.ɵɵelementStart(23, "div", 17);
1157
+ i0.ɵɵtext(24, "Total Users");
646
1158
  i0.ɵɵelementEnd()()();
647
- i0.ɵɵelementStart(20, "div", 9)(21, "div", 15);
648
- i0.ɵɵelement(22, "i", 16);
1159
+ i0.ɵɵelementStart(25, "div", 12)(26, "div", 18);
1160
+ i0.ɵɵelement(27, "i", 19);
649
1161
  i0.ɵɵelementEnd();
650
- i0.ɵɵelementStart(23, "div", 12)(24, "div", 13);
651
- i0.ɵɵtext(25);
1162
+ i0.ɵɵelementStart(28, "div", 15)(29, "div", 20);
1163
+ i0.ɵɵtext(30);
652
1164
  i0.ɵɵelementEnd();
653
- i0.ɵɵelementStart(26, "div", 14);
654
- i0.ɵɵtext(27, "Active Users");
1165
+ i0.ɵɵelementStart(31, "div", 17);
1166
+ i0.ɵɵtext(32, "Active Users");
655
1167
  i0.ɵɵelementEnd()()();
656
- i0.ɵɵelementStart(28, "div", 9)(29, "div", 17);
657
- i0.ɵɵelement(30, "i", 18);
1168
+ i0.ɵɵelementStart(33, "div", 12)(34, "div", 21);
1169
+ i0.ɵɵelement(35, "i", 22);
658
1170
  i0.ɵɵelementEnd();
659
- i0.ɵɵelementStart(31, "div", 12)(32, "div", 13);
660
- i0.ɵɵtext(33);
1171
+ i0.ɵɵelementStart(36, "div", 15)(37, "div", 23);
1172
+ i0.ɵɵtext(38);
661
1173
  i0.ɵɵelementEnd();
662
- i0.ɵɵelementStart(34, "div", 14);
663
- i0.ɵɵtext(35, "Inactive Users");
1174
+ i0.ɵɵelementStart(39, "div", 17);
1175
+ i0.ɵɵtext(40, "Inactive Users");
664
1176
  i0.ɵɵelementEnd()()();
665
- i0.ɵɵelementStart(36, "div", 9)(37, "div", 19);
666
- i0.ɵɵelement(38, "i", 20);
1177
+ i0.ɵɵelementStart(41, "div", 12)(42, "div", 24);
1178
+ i0.ɵɵelement(43, "i", 25);
667
1179
  i0.ɵɵelementEnd();
668
- i0.ɵɵelementStart(39, "div", 12)(40, "div", 13);
669
- i0.ɵɵtext(41);
1180
+ i0.ɵɵelementStart(44, "div", 15)(45, "div", 26);
1181
+ i0.ɵɵtext(46);
670
1182
  i0.ɵɵelementEnd();
671
- i0.ɵɵelementStart(42, "div", 14);
672
- i0.ɵɵtext(43, "Owners");
1183
+ i0.ɵɵelementStart(47, "div", 17);
1184
+ i0.ɵɵtext(48, "Owners");
673
1185
  i0.ɵɵelementEnd()()()();
674
- i0.ɵɵelementStart(44, "div", 21)(45, "div", 22)(46, "div", 23);
675
- i0.ɵɵelement(47, "i", 24);
676
- i0.ɵɵelementStart(48, "input", 25);
677
- i0.ɵɵlistener("input", function UserManagementComponent_Template_input_input_48_listener($event) { return ctx.onSearchChange($event); });
1186
+ i0.ɵɵelementStart(49, "div", 27)(50, "div", 28)(51, "div", 29);
1187
+ i0.ɵɵelement(52, "i", 30);
1188
+ i0.ɵɵelementStart(53, "input", 31);
1189
+ i0.ɵɵlistener("input", function UserManagementComponent_Template_input_input_53_listener($event) { return ctx.onSearchChange($event); });
678
1190
  i0.ɵɵelementEnd()();
679
- i0.ɵɵelementStart(49, "div", 26)(50, "label", 27);
680
- i0.ɵɵtext(51, "Status");
1191
+ i0.ɵɵelementStart(54, "button", 32);
1192
+ i0.ɵɵlistener("click", function UserManagementComponent_Template_button_click_54_listener() { return ctx.showMobileFilters = !ctx.showMobileFilters; });
1193
+ i0.ɵɵelement(55, "i", 33);
1194
+ i0.ɵɵtemplate(56, UserManagementComponent_Conditional_56_Template, 2, 1, "span", 34);
681
1195
  i0.ɵɵelementEnd();
682
- i0.ɵɵelementStart(52, "div", 28)(53, "button", 29);
683
- i0.ɵɵlistener("click", function UserManagementComponent_Template_button_click_53_listener() { return ctx.onStatusFilterChange("all"); });
684
- i0.ɵɵtext(54, " All ");
1196
+ i0.ɵɵelementStart(57, "div", 35)(58, "label", 36);
1197
+ i0.ɵɵtext(59, "Status");
685
1198
  i0.ɵɵelementEnd();
686
- i0.ɵɵelementStart(55, "button", 29);
687
- i0.ɵɵlistener("click", function UserManagementComponent_Template_button_click_55_listener() { return ctx.onStatusFilterChange("active"); });
688
- i0.ɵɵtext(56, " Active ");
1199
+ i0.ɵɵelementStart(60, "div", 37)(61, "button", 38);
1200
+ i0.ɵɵlistener("click", function UserManagementComponent_Template_button_click_61_listener() { return ctx.onStatusFilterChange("all"); });
1201
+ i0.ɵɵtext(62, " All ");
689
1202
  i0.ɵɵelementEnd();
690
- i0.ɵɵelementStart(57, "button", 29);
691
- i0.ɵɵlistener("click", function UserManagementComponent_Template_button_click_57_listener() { return ctx.onStatusFilterChange("inactive"); });
692
- i0.ɵɵtext(58, " Inactive ");
1203
+ i0.ɵɵelementStart(63, "button", 38);
1204
+ i0.ɵɵlistener("click", function UserManagementComponent_Template_button_click_63_listener() { return ctx.onStatusFilterChange("active"); });
1205
+ i0.ɵɵtext(64, " Active ");
1206
+ i0.ɵɵelementEnd();
1207
+ i0.ɵɵelementStart(65, "button", 38);
1208
+ i0.ɵɵlistener("click", function UserManagementComponent_Template_button_click_65_listener() { return ctx.onStatusFilterChange("inactive"); });
1209
+ i0.ɵɵtext(66, " Inactive ");
693
1210
  i0.ɵɵelementEnd()()();
694
- i0.ɵɵelementStart(59, "div", 26)(60, "label", 27);
695
- i0.ɵɵtext(61, "Role");
1211
+ i0.ɵɵelementStart(67, "div", 35)(68, "label", 39);
1212
+ i0.ɵɵtext(69, "Role");
696
1213
  i0.ɵɵelementEnd();
697
- i0.ɵɵelementStart(62, "select", 30);
698
- i0.ɵɵlistener("change", function UserManagementComponent_Template_select_change_62_listener($event) { return ctx.onRoleFilterChange($event.target.value); });
699
- i0.ɵɵelementStart(63, "option", 31);
700
- i0.ɵɵtext(64, "All Roles");
1214
+ i0.ɵɵelementStart(70, "select", 40);
1215
+ i0.ɵɵlistener("change", function UserManagementComponent_Template_select_change_70_listener($event) { return ctx.onRoleFilterChange($event.target.value); });
1216
+ i0.ɵɵelementStart(71, "option", 41);
1217
+ i0.ɵɵtext(72, "All Roles");
701
1218
  i0.ɵɵelementEnd();
702
- i0.ɵɵrepeaterCreate(65, UserManagementComponent_For_66_Template, 2, 2, "option", 32, _forTrack0);
1219
+ i0.ɵɵrepeaterCreate(73, UserManagementComponent_For_74_Template, 2, 2, "option", 42, _forTrack0);
1220
+ i0.ɵɵelementEnd()()();
1221
+ i0.ɵɵtemplate(75, UserManagementComponent_Conditional_75_Template, 21, 2, "div", 43);
703
1222
  i0.ɵɵelementEnd()();
704
- i0.ɵɵelementStart(67, "div", 33)(68, "button", 34);
705
- i0.ɵɵlistener("click", function UserManagementComponent_Template_button_click_68_listener() { return ctx.viewMode = "grid"; });
706
- i0.ɵɵelement(69, "i", 35);
1223
+ i0.ɵɵelementStart(76, "div", 44);
1224
+ i0.ɵɵtemplate(77, UserManagementComponent_Conditional_77_Template, 2, 0, "div", 45)(78, UserManagementComponent_Conditional_78_Template, 8, 1, "div", 46)(79, UserManagementComponent_Conditional_79_Template, 11, 5, "div", 47);
707
1225
  i0.ɵɵelementEnd();
708
- i0.ɵɵelementStart(70, "button", 36);
709
- i0.ɵɵlistener("click", function UserManagementComponent_Template_button_click_70_listener() { return ctx.viewMode = "cards"; });
710
- i0.ɵɵelement(71, "i", 37);
711
- i0.ɵɵelementEnd()()()();
712
- i0.ɵɵtemplate(72, UserManagementComponent_Conditional_72_Template, 7, 0, "div", 38)(73, UserManagementComponent_Conditional_73_Template, 8, 1, "div", 39)(74, UserManagementComponent_Conditional_74_Template, 3, 2, "div", 40);
713
- i0.ɵɵelementStart(75, "mj-user-dialog", 41);
714
- i0.ɵɵlistener("result", function UserManagementComponent_Template_mj_user_dialog_result_75_listener($event) { return ctx.onUserDialogResult($event); });
1226
+ i0.ɵɵelementStart(80, "mj-user-dialog", 48);
1227
+ i0.ɵɵlistener("result", function UserManagementComponent_Template_mj_user_dialog_result_80_listener($event) { return ctx.onUserDialogResult($event); });
715
1228
  i0.ɵɵelementEnd();
716
- i0.ɵɵtemplate(76, UserManagementComponent_Conditional_76_Template, 22, 1, "div", 42);
1229
+ i0.ɵɵtemplate(81, UserManagementComponent_Conditional_81_Template, 22, 1, "div", 49)(82, UserManagementComponent_Conditional_82_Template, 20, 9, "div", 50)(83, UserManagementComponent_Conditional_83_Template, 25, 6, "div", 51);
717
1230
  i0.ɵɵelementEnd();
718
1231
  } if (rf & 2) {
719
- i0.ɵɵadvance(2);
1232
+ i0.ɵɵadvance(3);
720
1233
  i0.ɵɵproperty("disabled", ctx.isLoading);
721
1234
  i0.ɵɵadvance();
722
1235
  i0.ɵɵclassProp("fa-spin", ctx.isLoading);
723
- i0.ɵɵadvance(14);
1236
+ i0.ɵɵadvance(11);
1237
+ i0.ɵɵconditional(ctx.hasSelection ? 15 : -1);
1238
+ i0.ɵɵadvance(7);
724
1239
  i0.ɵɵtextInterpolate(ctx.stats.totalUsers);
725
1240
  i0.ɵɵadvance(8);
726
1241
  i0.ɵɵtextInterpolate(ctx.stats.activeUsers);
@@ -730,29 +1245,39 @@ let UserManagementComponent = class UserManagementComponent extends BaseDashboar
730
1245
  i0.ɵɵtextInterpolate(ctx.stats.adminUsers);
731
1246
  i0.ɵɵadvance(7);
732
1247
  i0.ɵɵproperty("value", ctx.filters$.value.search);
1248
+ i0.ɵɵadvance();
1249
+ i0.ɵɵclassProp("active", ctx.showMobileFilters);
1250
+ i0.ɵɵattribute("aria-expanded", ctx.showMobileFilters);
1251
+ i0.ɵɵadvance(2);
1252
+ i0.ɵɵconditional(ctx.hasActiveFilters ? 56 : -1);
733
1253
  i0.ɵɵadvance(5);
734
1254
  i0.ɵɵclassProp("mj-btn-primary", ctx.filters$.value.status === "all");
1255
+ i0.ɵɵattribute("aria-pressed", ctx.filters$.value.status === "all");
735
1256
  i0.ɵɵadvance(2);
736
1257
  i0.ɵɵclassProp("mj-btn-primary", ctx.filters$.value.status === "active");
1258
+ i0.ɵɵattribute("aria-pressed", ctx.filters$.value.status === "active");
737
1259
  i0.ɵɵadvance(2);
738
1260
  i0.ɵɵclassProp("mj-btn-primary", ctx.filters$.value.status === "inactive");
1261
+ i0.ɵɵattribute("aria-pressed", ctx.filters$.value.status === "inactive");
739
1262
  i0.ɵɵadvance(8);
740
1263
  i0.ɵɵrepeater(ctx.roles);
741
- i0.ɵɵadvance(3);
742
- i0.ɵɵclassProp("mj-btn-primary", ctx.viewMode === "grid")("mj-btn-ghost", ctx.viewMode !== "grid");
743
1264
  i0.ɵɵadvance(2);
744
- i0.ɵɵclassProp("mj-btn-primary", ctx.viewMode === "cards")("mj-btn-ghost", ctx.viewMode !== "cards");
1265
+ i0.ɵɵconditional(ctx.showMobileFilters ? 75 : -1);
745
1266
  i0.ɵɵadvance(2);
746
- i0.ɵɵconditional(ctx.isLoading ? 72 : -1);
1267
+ i0.ɵɵconditional(ctx.isLoading ? 77 : -1);
747
1268
  i0.ɵɵadvance();
748
- i0.ɵɵconditional(ctx.error && !ctx.isLoading ? 73 : -1);
1269
+ i0.ɵɵconditional(ctx.error && !ctx.isLoading ? 78 : -1);
749
1270
  i0.ɵɵadvance();
750
- i0.ɵɵconditional(!ctx.isLoading && !ctx.error ? 74 : -1);
1271
+ i0.ɵɵconditional(!ctx.isLoading && !ctx.error ? 79 : -1);
751
1272
  i0.ɵɵadvance();
752
1273
  i0.ɵɵproperty("data", ctx.userDialogData)("visible", ctx.showUserDialog);
753
1274
  i0.ɵɵadvance();
754
- i0.ɵɵconditional(ctx.showDeleteConfirm && ctx.selectedUser ? 76 : -1);
755
- } }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i2.UserDialogComponent, i3.DatePipe], styles: ["@keyframes _ngcontent-%COMP%_shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n.user-management-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n max-height: 100%;\n overflow: hidden;\n position: relative;\n width: 100%;\n height: 100%;\n}\n\n.action-buttons[_ngcontent-%COMP%] {\n flex-shrink: 0;\n position: sticky;\n top: 0;\n z-index: 10;\n background: inherit;\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n padding: 1rem 2rem;\n background: white;\n border-bottom: 1px solid #e0e0e0;\n}\n@media (max-width: 768px) {\n .action-buttons[_ngcontent-%COMP%] {\n justify-content: center;\n flex-wrap: wrap;\n padding: 1rem;\n }\n}\n\n.btn-primary[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #2196f3;\n color: white;\n}\n.btn-primary[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-primary[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n}\n.btn-primary[_ngcontent-%COMP%]:hover {\n background-color: #1976d2;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.3);\n}\n.btn-primary[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n transform: none;\n}\n\n.btn-secondary[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #ffffff;\n color: #374151;\n border: 1px solid #e5e7eb;\n}\n.btn-secondary[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-secondary[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n}\n.btn-secondary[_ngcontent-%COMP%]:hover {\n background-color: #f9fafb;\n border-color: #2196f3;\n color: #2196f3;\n}\n\n.btn-danger[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #f44336;\n color: white;\n}\n.btn-danger[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-danger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n}\n.btn-danger[_ngcontent-%COMP%]:hover {\n background-color: #d32f2f;\n}\n\n.stats-grid[_ngcontent-%COMP%] {\n flex-shrink: 0;\n position: sticky;\n top: 0;\n z-index: 10;\n background: inherit;\n display: grid !important;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 1.5rem;\n padding: 1rem 2rem;\n background: white;\n border-bottom: 1px solid #e0e0e0;\n width: 100%;\n}\n@media (max-width: 768px) {\n .stats-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n padding: 1rem;\n }\n}\n\n.stat-card[_ngcontent-%COMP%] {\n background: white;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n display: flex;\n margin-right: 10px;\n align-items: center;\n gap: 1rem;\n transition: all 0.3s ease;\n min-width: 0;\n}\n.stat-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n\n.stat-icon[_ngcontent-%COMP%] {\n width: 60px;\n height: 60px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.5rem;\n}\n.stat-icon-total[_ngcontent-%COMP%] {\n background: rgba(33, 150, 243, 0.1);\n color: #2196f3;\n}\n.stat-icon-active[_ngcontent-%COMP%] {\n background: rgba(76, 175, 80, 0.1);\n color: #4caf50;\n}\n.stat-icon-inactive[_ngcontent-%COMP%] {\n background: rgba(244, 67, 54, 0.1);\n color: #f44336;\n}\n.stat-icon-admin[_ngcontent-%COMP%] {\n background: rgba(156, 39, 176, 0.1);\n color: #9c27b0;\n}\n\n.stat-content[_ngcontent-%COMP%] {\n flex: 1;\n}\n.stat-content[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 2rem;\n font-weight: 700;\n color: #1f2937;\n line-height: 1;\n}\n.stat-content[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n color: #6b7280;\n font-size: 0.875rem;\n margin-top: 0.25rem;\n}\n\n.filters-section[_ngcontent-%COMP%] {\n flex-shrink: 0;\n position: sticky;\n top: 0;\n z-index: 10;\n background: inherit;\n background: white;\n padding: 1.5rem 2rem;\n border-bottom: 1px solid #e0e0e0;\n}\n@media (max-width: 768px) {\n .filters-section[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n}\n\n.filters-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 1.5rem;\n align-items: flex-end;\n flex-wrap: wrap;\n}\n@media (max-width: 768px) {\n .filters-row[_ngcontent-%COMP%] {\n gap: 1rem;\n }\n}\n\n.search-container[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 250px;\n position: relative;\n}\n.search-container[_ngcontent-%COMP%] .search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: #6b7280;\n font-size: 1rem;\n}\n.search-container[_ngcontent-%COMP%] .search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 0.75rem 1rem 0.75rem 2.75rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n font-size: 0.95rem;\n transition: all 0.2s;\n}\n.search-container[_ngcontent-%COMP%] .search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n}\n\n.filter-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n.filter-group[_ngcontent-%COMP%] .filter-label[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n font-weight: 500;\n color: #374151;\n}\n.filter-group[_ngcontent-%COMP%] .filter-buttons[_ngcontent-%COMP%] {\n display: flex;\n background: #f3f4f6;\n border-radius: 8px;\n padding: 4px;\n}\n.filter-group[_ngcontent-%COMP%] .filter-btn[_ngcontent-%COMP%] {\n padding: 0.5rem 1rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 0.875rem;\n font-weight: 500;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.filter-group[_ngcontent-%COMP%] .filter-btn[_ngcontent-%COMP%]:hover {\n color: #374151;\n}\n.filter-group[_ngcontent-%COMP%] .filter-btn.active[_ngcontent-%COMP%] {\n background: white;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n.filter-group[_ngcontent-%COMP%] .filter-select[_ngcontent-%COMP%] {\n padding: 0.625rem 1rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n background: white;\n font-size: 0.875rem;\n color: #374151;\n cursor: pointer;\n transition: all 0.2s;\n}\n.filter-group[_ngcontent-%COMP%] .filter-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n}\n\n.view-toggle[_ngcontent-%COMP%] {\n display: flex;\n background: #f3f4f6;\n border-radius: 8px;\n padding: 4px;\n}\n.view-toggle[_ngcontent-%COMP%] .view-btn[_ngcontent-%COMP%] {\n padding: 0.5rem 0.75rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1rem;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.view-toggle[_ngcontent-%COMP%] .view-btn[_ngcontent-%COMP%]:hover {\n color: #374151;\n}\n.view-toggle[_ngcontent-%COMP%] .view-btn.active[_ngcontent-%COMP%] {\n background: white;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n.content-area[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n min-height: 0;\n position: relative;\n padding: 2rem;\n background: white;\n}\n@media (max-width: 768px) {\n .content-area[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n}\n\n.users-table[_ngcontent-%COMP%] {\n width: 100%;\n overflow-x: auto;\n}\n\n.modern-table[_ngcontent-%COMP%] {\n width: 100%;\n border-collapse: collapse;\n}\n.modern-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] {\n background: #f9fafb;\n border-bottom: 1px solid #e5e7eb;\n}\n.modern-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th[_ngcontent-%COMP%] {\n padding: 1rem;\n text-align: left;\n font-size: 0.875rem;\n font-weight: 600;\n color: #374151;\n white-space: nowrap;\n}\n.modern-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th.th-checkbox[_ngcontent-%COMP%] {\n width: 50px;\n}\n.modern-table[_ngcontent-%COMP%] thead[_ngcontent-%COMP%] th.th-actions[_ngcontent-%COMP%] {\n text-align: center;\n width: 150px;\n}\n.modern-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%] {\n border-bottom: 1px solid #f3f4f6;\n transition: background-color 0.2s;\n cursor: pointer;\n}\n.modern-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] tr[_ngcontent-%COMP%]:hover {\n background-color: #f9fafb;\n}\n.modern-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] td[_ngcontent-%COMP%] {\n padding: 1rem;\n font-size: 0.875rem;\n color: #374151;\n}\n.modern-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] td.td-checkbox[_ngcontent-%COMP%] {\n width: 50px;\n}\n.modern-table[_ngcontent-%COMP%] tbody[_ngcontent-%COMP%] td.td-actions[_ngcontent-%COMP%] {\n text-align: center;\n}\n\n.checkbox[_ngcontent-%COMP%] {\n width: 18px;\n height: 18px;\n cursor: pointer;\n}\n\n.user-cell[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n}\n\n.user-avatar[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n font-size: 0.875rem;\n}\n\n.user-avatar-large[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n font-size: 1.5rem;\n margin: 0 auto 1rem;\n}\n\n.user-info[_ngcontent-%COMP%] .user-name[_ngcontent-%COMP%] {\n font-weight: 600;\n color: #1f2937;\n}\n.user-info[_ngcontent-%COMP%] .user-fullname[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n color: #6b7280;\n}\n\n.user-type[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n color: #4b5563;\n}\n.user-type[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n}\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.25rem 0.75rem;\n border-radius: 20px;\n font-size: 0.75rem;\n font-weight: 500;\n}\n.status-badge.status-active[_ngcontent-%COMP%] {\n background: rgba(76, 175, 80, 0.1);\n color: #388e3c;\n}\n.status-badge.status-inactive[_ngcontent-%COMP%] {\n background: rgba(244, 67, 54, 0.1);\n color: #d32f2f;\n}\n.status-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.625rem;\n}\n\n.last-login[_ngcontent-%COMP%] {\n color: #6b7280;\n font-size: 0.875rem;\n}\n\n.action-btn[_ngcontent-%COMP%] {\n padding: 0.5rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1rem;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.action-btn[_ngcontent-%COMP%]:hover {\n background: #f3f4f6;\n color: #2196f3;\n}\n.action-btn-danger[_ngcontent-%COMP%]:hover {\n color: #f44336;\n}\n\n.users-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 1.5rem;\n padding: 1.5rem;\n}\n@media (max-width: 768px) {\n .users-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n gap: 1rem;\n padding: 1rem;\n }\n}\n\n.user-card[_ngcontent-%COMP%] {\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 12px;\n padding: 1.5rem;\n cursor: pointer;\n transition: all 0.3s ease;\n}\n.user-card[_ngcontent-%COMP%]:hover {\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);\n transform: translateY(-2px);\n border-color: #2196f3;\n}\n\n.card-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 1rem;\n}\n\n.card-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n}\n\n.card-body[_ngcontent-%COMP%] {\n text-align: center;\n}\n.card-body[_ngcontent-%COMP%] .user-name[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0 0 0.25rem 0;\n}\n.card-body[_ngcontent-%COMP%] .user-fullname[_ngcontent-%COMP%] {\n color: #6b7280;\n margin: 0 0 0.75rem 0;\n}\n.card-body[_ngcontent-%COMP%] .user-email[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n color: #4b5563;\n font-size: 0.875rem;\n margin-bottom: 1rem;\n}\n.card-body[_ngcontent-%COMP%] .user-email[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #6b7280;\n}\n\n.card-meta[_ngcontent-%COMP%] {\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 1rem;\n padding: 1rem 0;\n border-top: 1px solid #f3f4f6;\n border-bottom: 1px solid #f3f4f6;\n margin-bottom: 1rem;\n}\n.card-meta[_ngcontent-%COMP%] .meta-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.375rem;\n color: #4b5563;\n font-size: 0.875rem;\n}\n\n.card-footer[_ngcontent-%COMP%] .last-login[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n color: #6b7280;\n font-size: 0.75rem;\n}\n.card-footer[_ngcontent-%COMP%] .last-login[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n}\n\n.empty-state[_ngcontent-%COMP%] {\n text-align: center;\n padding: 4rem 2rem;\n}\n.empty-state[_ngcontent-%COMP%] .empty-icon[_ngcontent-%COMP%] {\n font-size: 4rem;\n color: #e5e7eb;\n margin-bottom: 1rem;\n}\n.empty-state[_ngcontent-%COMP%] .empty-text[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n font-weight: 600;\n color: #374151;\n margin: 0 0 0.5rem 0;\n}\n.empty-state[_ngcontent-%COMP%] .empty-subtext[_ngcontent-%COMP%] {\n color: #6b7280;\n margin: 0;\n}\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n}\n\n.loading-spinner[_ngcontent-%COMP%] {\n position: relative;\n width: 60px;\n height: 60px;\n margin-bottom: 1rem;\n}\n.loading-spinner[_ngcontent-%COMP%] .spinner-ring[_ngcontent-%COMP%] {\n position: absolute;\n width: 100%;\n height: 100%;\n border: 3px solid transparent;\n border-radius: 50%;\n animation: _ngcontent-%COMP%_spin 1.5s cubic-bezier(0.5, 0, 0.5, 1) infinite;\n}\n.loading-spinner[_ngcontent-%COMP%] .spinner-ring[_ngcontent-%COMP%]:nth-child(1) {\n border-color: #2196f3 transparent transparent transparent;\n animation-delay: -0.45s;\n}\n.loading-spinner[_ngcontent-%COMP%] .spinner-ring[_ngcontent-%COMP%]:nth-child(2) {\n border-color: transparent #4caf50 transparent transparent;\n animation-delay: -0.3s;\n}\n.loading-spinner[_ngcontent-%COMP%] .spinner-ring[_ngcontent-%COMP%]:nth-child(3) {\n border-color: transparent transparent #ff9800 transparent;\n animation-delay: -0.15s;\n}\n\n@keyframes _ngcontent-%COMP%_spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n.loading-text[_ngcontent-%COMP%] {\n color: #6b7280;\n font-size: 0.95rem;\n}\n\n.error-container[_ngcontent-%COMP%] {\n text-align: center;\n padding: 4rem 2rem;\n}\n.error-container[_ngcontent-%COMP%] .error-icon[_ngcontent-%COMP%] {\n font-size: 3rem;\n color: #f44336;\n margin-bottom: 1rem;\n}\n.error-container[_ngcontent-%COMP%] .error-message[_ngcontent-%COMP%] {\n color: #374151;\n margin-bottom: 1.5rem;\n}\n.error-container[_ngcontent-%COMP%] .retry-button[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #2196f3;\n color: white;\n}\n.error-container[_ngcontent-%COMP%] .retry-button[_ngcontent-%COMP%]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.error-container[_ngcontent-%COMP%] .retry-button[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n}\n\n.modal-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease;\n}\n\n.modal-dialog[_ngcontent-%COMP%] {\n background: white;\n border-radius: 12px;\n box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);\n max-width: 500px;\n width: 90%;\n max-height: 90vh;\n overflow: hidden;\n animation: _ngcontent-%COMP%_slideUp 0.3s ease;\n}\n\n.modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.5rem;\n border-bottom: 1px solid #e5e7eb;\n}\n.modal-header[_ngcontent-%COMP%] .modal-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.25rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0;\n}\n.modal-header[_ngcontent-%COMP%] .modal-close[_ngcontent-%COMP%] {\n padding: 0.5rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n.modal-header[_ngcontent-%COMP%] .modal-close[_ngcontent-%COMP%]:hover {\n background: #f3f4f6;\n color: #374151;\n}\n\n.modal-body[_ngcontent-%COMP%] {\n padding: 1.5rem;\n}\n.modal-body[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0 0 1rem 0;\n color: #374151;\n}\n.modal-body[_ngcontent-%COMP%] p[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n.modal-body[_ngcontent-%COMP%] .text-muted[_ngcontent-%COMP%] {\n color: #6b7280;\n font-size: 0.875rem;\n}\n\n.modal-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid #e5e7eb;\n background: #f9fafb;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n@keyframes _ngcontent-%COMP%_slideUp {\n from {\n transform: translateY(20px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n.text-danger[_ngcontent-%COMP%] {\n color: #f44336;\n}"] });
1275
+ i0.ɵɵconditional(ctx.showDeleteConfirm && ctx.selectedUser ? 81 : -1);
1276
+ i0.ɵɵadvance();
1277
+ i0.ɵɵconditional(ctx.showBulkActionConfirm ? 82 : -1);
1278
+ i0.ɵɵadvance();
1279
+ i0.ɵɵconditional(ctx.showBulkRoleAssign ? 83 : -1);
1280
+ } }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i1.SelectControlValueAccessor, i1.NgControlStatus, i1.NgModel, i2.LoadingComponent, i3.UserDialogComponent, i4.DatePipe], styles: ["\n\n\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n \n\n --md-primary: #0076B6;\n --md-on-primary: #FFFFFF;\n --md-primary-container: #AAE7FD;\n --md-on-primary-container: #001F2A;\n\n \n\n --md-secondary: #F5A623;\n --md-on-secondary: #FFFFFF;\n --md-secondary-container: #FFECD6;\n --md-on-secondary-container: #2D1600;\n\n \n\n --md-tertiary: #4CAF50;\n --md-on-tertiary: #FFFFFF;\n --md-tertiary-container: #C8E6C9;\n --md-on-tertiary-container: #002204;\n\n \n\n --md-error: #D32F2F;\n --md-on-error: #FFFFFF;\n --md-error-container: #FFCDD2;\n --md-on-error-container: #410002;\n\n \n\n --md-surface: #FAFCFF;\n --md-surface-container-lowest: #FFFFFF;\n --md-surface-container-low: #F3F5F9;\n --md-surface-container: #EDF0F4;\n --md-surface-container-high: #E7EAEE;\n --md-surface-container-highest: #E1E3E8;\n --md-on-surface: #191C20;\n --md-on-surface-variant: #43474E;\n --md-outline: #74777F;\n --md-outline-variant: #C4C6D0;\n\n \n\n --md-elevation-1: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n --md-elevation-2: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n --md-elevation-3: 0 4px 8px rgba(0, 0, 0, 0.1), 0 8px 16px rgba(0, 0, 0, 0.08);\n --md-elevation-4: 0 6px 12px rgba(0, 0, 0, 0.1), 0 12px 24px rgba(0, 0, 0, 0.08);\n --md-elevation-5: 0 8px 16px rgba(0, 0, 0, 0.12), 0 16px 32px rgba(0, 0, 0, 0.1);\n\n \n\n --md-corner-extra-small: 4px;\n --md-corner-small: 8px;\n --md-corner-medium: 12px;\n --md-corner-large: 16px;\n --md-corner-extra-large: 28px;\n --md-corner-full: 9999px;\n\n \n\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n\n\n\n\n.user-management-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n position: relative;\n width: 100%;\n background: var(--md-surface);\n}\n\n\n\n\n\n.sticky-header[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: var(--md-surface);\n border-bottom: 1px solid var(--md-outline-variant);\n box-shadow: var(--md-elevation-1);\n z-index: 10;\n}\n\n\n\n\n\n.scrollable-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch;\n padding: 1rem;\n background: var(--md-surface-container-lowest);\n}\n\n@media (min-width: 768px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 1.5rem 2rem;\n }\n}\n\n@media (min-width: 1024px) {\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 2rem;\n }\n}\n\n\n\n\n\n.action-buttons[_ngcontent-%COMP%] {\n flex-shrink: 0;\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n padding: 0.75rem 1rem;\n background: var(--md-surface);\n}\n\n@media (min-width: 768px) {\n .action-buttons[_ngcontent-%COMP%] {\n padding: 1rem 1.5rem;\n }\n}\n\n@media (max-width: 639px) {\n .action-buttons[_ngcontent-%COMP%] {\n justify-content: center;\n flex-wrap: wrap;\n }\n\n .mj-btn-icon-mobile[_ngcontent-%COMP%] .btn-text[_ngcontent-%COMP%] {\n display: none;\n }\n\n .mj-btn-icon-mobile[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n padding: 0;\n border-radius: var(--md-corner-full);\n min-width: 48px;\n min-height: 48px;\n }\n\n .mj-btn-icon-mobile[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n }\n\n .mj-btn-primary.mj-btn-icon-mobile[_ngcontent-%COMP%] {\n box-shadow: var(--md-elevation-2);\n }\n\n .mj-btn-primary.mj-btn-icon-mobile[_ngcontent-%COMP%]:hover {\n box-shadow: var(--md-elevation-3);\n transform: scale(1.05);\n }\n\n .mj-btn-secondary.mj-btn-icon-mobile[_ngcontent-%COMP%] {\n background: var(--md-surface);\n border: 1px solid var(--md-outline);\n }\n\n .mj-btn-secondary.mj-btn-icon-mobile[_ngcontent-%COMP%]:hover {\n background: var(--md-primary);\n color: var(--md-on-primary);\n border-color: var(--md-primary);\n }\n}\n\n\n\n\n\n.bulk-action-toolbar[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n background: var(--md-primary-container);\n border-bottom: 1px solid var(--md-outline-variant);\n animation: _ngcontent-%COMP%_slideDown 0.2s ease;\n}\n\n@media (min-width: 768px) {\n .bulk-action-toolbar[_ngcontent-%COMP%] {\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n padding: 1rem 1.5rem;\n }\n}\n\n.bulk-selection-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--md-on-primary-container);\n}\n\n.bulk-selection-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n}\n\n.bulk-action-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n flex-wrap: wrap;\n}\n\n@media (max-width: 639px) {\n .bulk-action-buttons[_ngcontent-%COMP%] .btn-text[_ngcontent-%COMP%] {\n display: none;\n }\n\n .bulk-action-buttons[_ngcontent-%COMP%] .mj-btn-sm[_ngcontent-%COMP%] {\n padding: 0.5rem;\n min-width: 36px;\n }\n}\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from {\n transform: translateY(-10px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n\n\n\n\n.mj-grid-4[_ngcontent-%COMP%] {\n display: none;\n grid-template-columns: repeat(2, 1fr);\n gap: 0.5rem;\n padding: 0 1rem 0.75rem 1rem;\n background: var(--md-surface);\n}\n\n@media (min-width: 768px) {\n .mj-grid-4[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n padding: 0 1.5rem 1rem 1.5rem;\n gap: 0.75rem;\n }\n}\n\n@media (min-width: 1024px) {\n .mj-grid-4[_ngcontent-%COMP%] {\n gap: 1rem;\n }\n}\n\n\n\n.mj-card[_ngcontent-%COMP%] {\n background: var(--md-surface-container-low);\n border-radius: var(--md-corner-medium);\n padding: 1rem;\n box-shadow: none;\n display: flex;\n align-items: center;\n gap: 1rem;\n border: 1px solid var(--md-outline-variant);\n cursor: default;\n pointer-events: none;\n}\n\n@media (min-width: 768px) {\n .mj-card[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem;\n }\n}\n\n.stat-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n border-radius: var(--md-corner-medium);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.25rem;\n flex-shrink: 0;\n}\n\n@media (min-width: 768px) {\n .stat-icon[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n font-size: 1.25rem;\n }\n}\n\n.stat-icon-total[_ngcontent-%COMP%] {\n background: var(--md-primary-container);\n color: var(--md-primary);\n}\n\n.stat-icon-active[_ngcontent-%COMP%] {\n background: var(--md-tertiary-container);\n color: var(--md-tertiary);\n}\n\n.stat-icon-inactive[_ngcontent-%COMP%] {\n background: var(--md-error-container);\n color: var(--md-error);\n}\n\n.stat-icon-admin[_ngcontent-%COMP%] {\n background: var(--md-secondary-container);\n color: #B5751A;\n}\n\n.stat-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.stat-content[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 1.75rem;\n font-weight: 700;\n color: var(--md-on-surface);\n line-height: 1;\n letter-spacing: -0.02em;\n}\n\n@media (min-width: 768px) {\n .stat-content[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 2rem;\n }\n}\n\n.stat-content[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--md-on-surface-variant);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin-top: 0.25rem;\n}\n\n@media (min-width: 768px) {\n .stat-content[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n }\n}\n\n\n\n\n\n.filters-section[_ngcontent-%COMP%] {\n flex-shrink: 0;\n background: var(--md-surface-container);\n margin: 0 1rem 0.75rem 1rem;\n padding: 0.75rem;\n border-radius: var(--md-corner-medium);\n border: 1px solid var(--md-outline-variant);\n}\n\n@media (min-width: 768px) {\n .filters-section[_ngcontent-%COMP%] {\n margin: 0 1.5rem 1rem 1.5rem;\n padding: 1rem 1.25rem;\n }\n}\n\n.filters-row[_ngcontent-%COMP%] {\n display: flex;\n gap: 1rem;\n align-items: flex-end;\n flex-wrap: wrap;\n}\n\n@media (min-width: 768px) {\n .filters-row[_ngcontent-%COMP%] {\n gap: 1.5rem;\n }\n}\n\n@media (max-width: 767px) {\n .filters-section[_ngcontent-%COMP%] {\n padding: 0.75rem;\n }\n\n .filters-row[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: row;\n gap: 0.75rem;\n align-items: center;\n }\n\n .filters-row[_ngcontent-%COMP%] .mj-search[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n }\n}\n\n\n\n\n\n.mj-search[_ngcontent-%COMP%] {\n position: relative;\n flex: 1;\n min-width: 200px;\n max-width: 100%;\n}\n\n@media (min-width: 640px) {\n .mj-search[_ngcontent-%COMP%] {\n min-width: 280px;\n max-width: 500px;\n }\n}\n\n@media (min-width: 768px) {\n .mj-search[_ngcontent-%COMP%] {\n min-width: 320px;\n max-width: 600px;\n }\n}\n\n@media (max-width: 767px) {\n .mj-search[_ngcontent-%COMP%] {\n width: 100%;\n max-width: none;\n min-width: 0;\n }\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-icon[_ngcontent-%COMP%] {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: var(--md-on-surface-variant);\n font-size: 1rem;\n pointer-events: none;\n transition: color 0.2s ease;\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 0.875rem 1rem 0.875rem 2.75rem;\n border: 2px solid var(--md-outline-variant);\n border-radius: var(--md-corner-full);\n font-size: 1rem;\n background: var(--md-surface);\n color: var(--md-on-surface);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 48px;\n}\n\n@media (min-width: 768px) {\n .mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%] {\n padding: 1rem 1.25rem 1rem 3rem;\n min-height: 52px;\n font-size: 1.0625rem;\n }\n\n .mj-search[_ngcontent-%COMP%] .mj-search-icon[_ngcontent-%COMP%] {\n left: 1.125rem;\n font-size: 1.125rem;\n }\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%]::placeholder {\n color: var(--md-on-surface-variant);\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%]:hover {\n border-color: var(--md-primary);\n background: var(--md-surface-container-lowest);\n}\n\n.mj-search[_ngcontent-%COMP%] .mj-search-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--md-primary);\n box-shadow: 0 0 0 3px rgba(0, 118, 182, 0.2);\n background: var(--md-surface);\n}\n\n.mj-search[_ngcontent-%COMP%]:focus-within .mj-search-icon[_ngcontent-%COMP%] {\n color: var(--md-primary);\n}\n\n\n\n\n\n.mobile-filter-toggle[_ngcontent-%COMP%] {\n display: none;\n align-items: center;\n justify-content: center;\n position: relative;\n width: 48px;\n height: 48px;\n min-width: 48px;\n border: 1px solid var(--md-outline-variant);\n border-radius: var(--md-corner-small);\n background: var(--md-surface-container-low);\n color: var(--md-on-surface-variant);\n font-size: 1.125rem;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n box-shadow: var(--md-elevation-1);\n flex-shrink: 0;\n}\n\n.mobile-filter-toggle[_ngcontent-%COMP%]:hover {\n background: var(--md-surface-container);\n border-color: var(--md-primary);\n color: var(--md-primary);\n}\n\n.mobile-filter-toggle.active[_ngcontent-%COMP%] {\n background: var(--md-primary);\n color: var(--md-on-primary);\n border-color: var(--md-primary);\n}\n\n.filter-badge[_ngcontent-%COMP%] {\n position: absolute;\n top: -4px;\n right: -4px;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n border-radius: var(--md-corner-full);\n background: var(--md-error);\n color: var(--md-on-error);\n font-size: 0.6875rem;\n font-weight: 700;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n}\n\n\n\n\n\n.mobile-filter-dropdown[_ngcontent-%COMP%] {\n display: none;\n margin-top: 0.75rem;\n padding-top: 0.75rem;\n border-top: 1px solid var(--md-outline-variant);\n animation: _ngcontent-%COMP%_slideDown 0.2s ease;\n}\n\n\n\n@media (max-width: 767px) {\n .mobile-filter-toggle[_ngcontent-%COMP%] {\n display: flex !important;\n }\n\n .mobile-filter-dropdown[_ngcontent-%COMP%] {\n display: block;\n }\n\n .desktop-filter-group[_ngcontent-%COMP%] {\n display: none !important;\n }\n}\n\n.mobile-filter-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.mobile-filter-content[_ngcontent-%COMP%] .mj-filter-group[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.mobile-filter-content[_ngcontent-%COMP%] .mj-filter-select[_ngcontent-%COMP%] {\n width: 100%;\n}\n\n.clear-filters-btn[_ngcontent-%COMP%] {\n align-self: flex-start;\n margin-top: 0.25rem;\n}\n\n\n\n\n\n\n\n\n.desktop-filter-group[_ngcontent-%COMP%] {\n display: none !important;\n}\n\n\n\n@media screen and (min-width: 768px) {\n .desktop-filter-group[_ngcontent-%COMP%] {\n display: flex !important;\n flex-direction: column;\n gap: 0.375rem;\n }\n\n .mobile-filter-toggle[_ngcontent-%COMP%] {\n display: none !important;\n }\n\n .mobile-filter-dropdown[_ngcontent-%COMP%] {\n display: none !important;\n }\n}\n\n.mj-filter-group[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.375rem;\n}\n\n@media (max-width: 767px) {\n .mj-filter-group[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 100px;\n }\n}\n\n.mj-filter-label[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--md-on-surface);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.mj-filter-buttons[_ngcontent-%COMP%] {\n display: flex;\n background: var(--md-surface-container);\n border-radius: var(--md-corner-full);\n padding: 4px;\n gap: 2px;\n}\n\n.mj-filter-buttons[_ngcontent-%COMP%] .mj-btn[_ngcontent-%COMP%] {\n border-radius: var(--md-corner-full);\n}\n\n.mj-filter-buttons[_ngcontent-%COMP%] .mj-btn-primary[_ngcontent-%COMP%] {\n background-color: var(--md-primary);\n color: var(--md-on-primary);\n box-shadow: var(--md-elevation-1);\n}\n\n.mj-filter-select[_ngcontent-%COMP%] {\n padding: 0.625rem 1rem;\n border: 1px solid var(--md-outline-variant);\n border-radius: var(--md-corner-small);\n background: var(--md-surface-container-low);\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--md-on-surface);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 120px;\n box-shadow: var(--md-elevation-1);\n}\n\n.mj-filter-select[_ngcontent-%COMP%]:hover {\n background: var(--md-surface-container);\n border-color: var(--md-primary);\n}\n\n@media (max-width: 767px) {\n .mj-filter-select[_ngcontent-%COMP%] {\n width: 100%;\n padding: 0.5rem 0.75rem;\n font-size: 0.8125rem;\n }\n}\n\n.mj-filter-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--md-primary);\n box-shadow: 0 0 0 3px rgba(0, 118, 182, 0.2);\n}\n\n\n\n\n\n.content-area[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n overflow: visible;\n position: relative;\n background: var(--md-surface);\n border-radius: var(--md-corner-large);\n box-shadow: var(--md-elevation-1);\n padding: 1rem;\n border: 1px solid var(--md-outline-variant);\n}\n\n@media (min-width: 768px) {\n .content-area[_ngcontent-%COMP%] {\n padding: 1.5rem;\n }\n}\n\n\n\n\n\n.users-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n\n\n.list-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.75rem 1rem;\n background: var(--md-surface-container);\n border-radius: var(--md-corner-small);\n border: 1px solid var(--md-outline-variant);\n margin-bottom: 0.5rem;\n}\n\n.select-all-label[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n cursor: pointer;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--md-on-surface);\n}\n\n.select-all-text[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n.selection-count[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--md-primary);\n background: var(--md-primary-container);\n padding: 0.25rem 0.75rem;\n border-radius: var(--md-corner-full);\n}\n\n\n\n.user-card[_ngcontent-%COMP%] {\n background: var(--md-surface);\n border: 1px solid var(--md-outline-variant);\n border-radius: var(--md-corner-large);\n overflow: hidden;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.user-card[_ngcontent-%COMP%]:hover {\n box-shadow: var(--md-elevation-2);\n border-color: var(--md-primary);\n}\n\n.user-card.expanded[_ngcontent-%COMP%] {\n box-shadow: var(--md-elevation-3);\n border-color: var(--md-primary);\n}\n\n.user-card.selected[_ngcontent-%COMP%] {\n background: var(--md-primary-container);\n border-color: var(--md-primary);\n}\n\n.user-card.selected[_ngcontent-%COMP%] .user-header[_ngcontent-%COMP%] {\n background: transparent;\n}\n\n.user-card.selected[_ngcontent-%COMP%]:hover .user-header[_ngcontent-%COMP%] {\n background: rgba(0, 118, 182, 0.08);\n}\n\n\n\n.user-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 1.25rem 1.5rem;\n cursor: pointer;\n background: var(--md-surface-container-lowest);\n transition: background-color 0.2s ease;\n}\n\n.user-header[_ngcontent-%COMP%]:hover {\n background: var(--md-surface-container-low);\n}\n\n@media (max-width: 639px) {\n .user-header[_ngcontent-%COMP%] {\n padding: 0.875rem 1rem;\n gap: 0.625rem;\n }\n}\n\n\n\n.user-selection[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n.checkbox[_ngcontent-%COMP%] {\n width: 20px;\n height: 20px;\n cursor: pointer;\n accent-color: var(--md-primary);\n}\n\n\n\n.user-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n flex: 1;\n min-width: 0;\n}\n\n.user-avatar[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n border-radius: var(--md-corner-full);\n background: linear-gradient(135deg, var(--md-primary) 0%, #3395C8 100%);\n color: var(--md-on-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 0.875rem;\n font-weight: 600;\n flex-shrink: 0;\n}\n\n@media (max-width: 639px) {\n .user-avatar[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 0.8125rem;\n }\n\n .user-details[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n }\n\n .user-name[_ngcontent-%COMP%] {\n font-size: 0.9375rem;\n font-weight: 600;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .user-email[_ngcontent-%COMP%] {\n font-size: 0.8125rem;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n}\n\n.user-details[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.user-name[_ngcontent-%COMP%] {\n font-size: 1rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.user-email[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n color: var(--md-on-surface-variant);\n margin: 0.125rem 0 0 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n\n\n.user-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n flex-shrink: 0;\n}\n\n@media (max-width: 767px) {\n .user-meta[_ngcontent-%COMP%] .status-badge[_ngcontent-%COMP%], \n .user-meta[_ngcontent-%COMP%] .user-actions[_ngcontent-%COMP%] {\n display: none !important;\n }\n\n .user-meta[_ngcontent-%COMP%] {\n gap: 0;\n }\n}\n\n\n\n.desktop-only[_ngcontent-%COMP%] {\n display: none;\n}\n\n@media (min-width: 768px) {\n .desktop-only[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.25rem;\n }\n}\n\n.user-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.25rem;\n}\n\n\n\n.expand-btn[_ngcontent-%COMP%] {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--md-on-surface-variant);\n font-size: 1rem;\n cursor: pointer;\n transition: all 0.2s ease;\n border-radius: var(--md-corner-full);\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.expand-btn[_ngcontent-%COMP%]:hover {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.expand-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n.user-card.expanded[_ngcontent-%COMP%] .expand-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n transform: rotate(180deg);\n}\n\n\n\n.user-content[_ngcontent-%COMP%] {\n padding: 1.25rem 1.5rem;\n background: var(--md-surface);\n border-top: 1px solid var(--md-outline-variant);\n animation: _ngcontent-%COMP%_slideDown 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n\n\n.mobile-actions-bar[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-bottom: 1rem;\n margin-bottom: 1rem;\n border-bottom: 1px solid var(--md-outline-variant);\n}\n\n@media (min-width: 768px) {\n .mobile-actions-bar[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n.mobile-action-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n}\n\n.mobile-action-buttons[_ngcontent-%COMP%] .btn-label[_ngcontent-%COMP%] {\n margin-left: 0.375rem;\n}\n\n\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.875rem;\n border-radius: var(--md-corner-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n.status-badge.status-active[_ngcontent-%COMP%] {\n background: var(--md-tertiary-container);\n color: #1B5E20;\n border: 1px solid var(--md-tertiary);\n}\n\n.status-badge.status-inactive[_ngcontent-%COMP%] {\n background: var(--md-error-container);\n color: var(--md-on-error-container);\n border: 1px solid var(--md-error);\n}\n\n.status-badge[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.625rem;\n}\n\n\n\n.user-stats[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 1rem;\n margin-bottom: 1rem;\n}\n\n.user-stats[_ngcontent-%COMP%] .stat-item[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.875rem;\n color: var(--md-on-surface-variant);\n}\n\n.user-stats[_ngcontent-%COMP%] .stat-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--md-primary);\n font-size: 0.875rem;\n}\n\n.user-stats[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n color: var(--md-on-surface-variant);\n}\n\n.user-stats[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n color: var(--md-on-surface);\n font-weight: 500;\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n\n.user-stats[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n}\n\n\n\n.roles-section[_ngcontent-%COMP%] {\n padding-top: 1rem;\n border-top: 1px solid var(--md-outline-variant);\n}\n\n.section-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n font-size: 1rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0 0 0.75rem 0;\n}\n\n.section-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--md-primary);\n font-size: 1.125rem;\n}\n\n.roles-grid[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n}\n\n.role-item[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.875rem;\n background: var(--md-secondary-container);\n color: #7A4D0C;\n border: 1px solid var(--md-secondary);\n border-radius: var(--md-corner-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n.role-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.625rem;\n}\n\n.no-roles[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n color: var(--md-on-surface-variant);\n margin: 0;\n}\n\n\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n text-align: center;\n padding: 4rem 2rem;\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-icon[_ngcontent-%COMP%] {\n font-size: 4rem;\n color: var(--md-outline-variant);\n margin-bottom: 1.5rem;\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-text[_ngcontent-%COMP%] {\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0 0 0.5rem 0;\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-subtext[_ngcontent-%COMP%] {\n font-size: 1rem;\n color: var(--md-on-surface-variant);\n margin: 0;\n}\n\n\n\n\n\n.loading-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n}\n\n\n\n\n\n.error-container[_ngcontent-%COMP%] {\n text-align: center;\n padding: 4rem 2rem;\n}\n\n.error-container[_ngcontent-%COMP%] .error-content[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.error-container[_ngcontent-%COMP%] .error-icon[_ngcontent-%COMP%] {\n font-size: 3.5rem;\n color: var(--md-error);\n margin-bottom: 1rem;\n}\n\n.error-container[_ngcontent-%COMP%] .error-message[_ngcontent-%COMP%] {\n font-size: 1.0625rem;\n color: var(--md-on-surface);\n margin: 0 0 1.5rem 0;\n}\n\n.error-container[_ngcontent-%COMP%] .retry-button[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n font-size: 0.875rem;\n font-weight: 600;\n border: none;\n border-radius: var(--md-corner-full);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n background: var(--md-primary);\n color: var(--md-on-primary);\n box-shadow: var(--md-elevation-1);\n min-height: 44px;\n}\n\n.error-container[_ngcontent-%COMP%] .retry-button[_ngcontent-%COMP%]:hover {\n background: #3395C8;\n box-shadow: var(--md-elevation-2);\n}\n\n.error-container[_ngcontent-%COMP%] .retry-button[_ngcontent-%COMP%]:active {\n background: #4BA5D4;\n transform: scale(0.98);\n}\n\n\n\n\n\n.modal-backdrop[_ngcontent-%COMP%] {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n padding: 1rem;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease;\n}\n\n.modal-dialog[_ngcontent-%COMP%] {\n background: var(--md-surface);\n border-radius: var(--md-corner-extra-large);\n box-shadow: var(--md-elevation-5);\n max-width: 500px;\n width: 100%;\n max-height: 90vh;\n overflow: hidden;\n animation: _ngcontent-%COMP%_slideUp 0.3s ease;\n}\n\n.modal-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.5rem;\n border-bottom: 1px solid var(--md-outline-variant);\n}\n\n.modal-header[_ngcontent-%COMP%] .modal-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.375rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0;\n}\n\n.modal-header[_ngcontent-%COMP%] .modal-close[_ngcontent-%COMP%] {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--md-on-surface-variant);\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: var(--md-corner-full);\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n}\n\n.modal-header[_ngcontent-%COMP%] .modal-close[_ngcontent-%COMP%]:hover {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.modal-body[_ngcontent-%COMP%] {\n padding: 1.5rem;\n}\n\n.modal-body[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 1rem;\n color: var(--md-on-surface);\n margin: 0 0 1rem 0;\n line-height: 1.5;\n}\n\n.modal-body[_ngcontent-%COMP%] p[_ngcontent-%COMP%]:last-child {\n margin-bottom: 0;\n}\n\n.modal-body[_ngcontent-%COMP%] .text-muted[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n color: var(--md-on-surface-variant);\n}\n\n.modal-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-start;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid var(--md-outline-variant);\n background: var(--md-surface-container-low);\n}\n\n@media (max-width: 639px) {\n .modal-dialog[_ngcontent-%COMP%] {\n width: 95%;\n max-height: 85vh;\n }\n\n .modal-header[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .modal-header[_ngcontent-%COMP%] .modal-title[_ngcontent-%COMP%] {\n font-size: 1.125rem;\n }\n\n .modal-body[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .modal-body[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n font-size: 0.9375rem;\n }\n\n .modal-footer[_ngcontent-%COMP%] {\n padding: 1rem;\n flex-wrap: wrap;\n }\n\n .modal-footer[_ngcontent-%COMP%] .mj-btn[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 100px;\n }\n}\n\n\n\n.form-field[_ngcontent-%COMP%] {\n margin-bottom: 1rem;\n}\n\n.form-field[_ngcontent-%COMP%] .field-label[_ngcontent-%COMP%] {\n display: block;\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--md-on-surface);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin-bottom: 0.5rem;\n}\n\n.form-field[_ngcontent-%COMP%] .field-select[_ngcontent-%COMP%] {\n width: 100%;\n padding: 0.75rem 1rem;\n border: 1px solid var(--md-outline);\n border-radius: var(--md-corner-small);\n background: var(--md-surface);\n font-size: 1rem;\n color: var(--md-on-surface);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.form-field[_ngcontent-%COMP%] .field-select[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--md-primary);\n box-shadow: 0 0 0 3px rgba(0, 118, 182, 0.2);\n}\n\n\n\n\n\n.mj-btn[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n font-size: 0.875rem;\n font-weight: 600;\n border: none;\n border-radius: var(--md-corner-full);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n white-space: nowrap;\n min-height: 44px;\n}\n\n.mj-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n\n\n.mj-btn-primary[_ngcontent-%COMP%] {\n background: var(--md-primary);\n color: var(--md-on-primary);\n box-shadow: var(--md-elevation-1);\n}\n\n.mj-btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #3395C8;\n box-shadow: var(--md-elevation-2);\n}\n\n.mj-btn-primary[_ngcontent-%COMP%]:active:not(:disabled) {\n background: #4BA5D4;\n transform: scale(0.98);\n}\n\n\n\n.mj-btn-secondary[_ngcontent-%COMP%] {\n background: var(--md-surface);\n color: var(--md-primary);\n border: 1px solid var(--md-outline);\n}\n\n.mj-btn-secondary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--md-primary);\n color: var(--md-on-primary);\n border-color: var(--md-primary);\n}\n\n.mj-btn-secondary[_ngcontent-%COMP%]:active:not(:disabled) {\n background: #005A8C;\n border-color: #005A8C;\n}\n\n\n\n.mj-btn-ghost[_ngcontent-%COMP%] {\n background: transparent;\n color: var(--md-on-surface-variant);\n}\n\n.mj-btn-ghost[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.mj-btn-ghost[_ngcontent-%COMP%]:active:not(:disabled) {\n background: #005A8C;\n}\n\n\n\n.mj-btn-danger[_ngcontent-%COMP%] {\n background: var(--md-error);\n color: var(--md-on-error);\n box-shadow: var(--md-elevation-1);\n}\n\n.mj-btn-danger[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #E57373;\n box-shadow: var(--md-elevation-2);\n}\n\n.mj-btn-danger[_ngcontent-%COMP%]:active:not(:disabled) {\n background: #EF9A9A;\n transform: scale(0.98);\n}\n\n\n\n.mj-btn-sm[_ngcontent-%COMP%] {\n padding: 0.5rem 0.875rem;\n font-size: 0.8125rem;\n min-height: 36px;\n}\n\n\n\n.mj-btn-ghost.mj-btn-danger[_ngcontent-%COMP%] {\n background: transparent;\n color: var(--md-error);\n box-shadow: none;\n}\n\n.mj-btn-ghost.mj-btn-danger[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--md-error-container);\n color: var(--md-error);\n}\n\n\n\n\n\n.text-danger[_ngcontent-%COMP%] {\n color: var(--md-error);\n}\n\n.text-success[_ngcontent-%COMP%] {\n color: var(--md-tertiary);\n}\n\n.text-warning[_ngcontent-%COMP%] {\n color: var(--md-secondary);\n}\n\n\n\n\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes _ngcontent-%COMP%_slideUp {\n from {\n transform: translateY(20px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n\n\n\n\n.mj-search-input[_ngcontent-%COMP%]:focus-visible, \n.mj-filter-select[_ngcontent-%COMP%]:focus-visible, \nbutton[_ngcontent-%COMP%]:focus-visible, \n.checkbox[_ngcontent-%COMP%]:focus-visible, \n.user-header[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\n}\n\n\n\n\n\n@media (prefers-reduced-motion: reduce) {\n *[_ngcontent-%COMP%], \n *[_ngcontent-%COMP%]::before, \n *[_ngcontent-%COMP%]::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n}\n\n\n\n\n\n@media (min-width: 1440px) {\n .user-management-container[_ngcontent-%COMP%] {\n max-width: 1920px;\n margin: 0 auto;\n }\n\n .action-buttons[_ngcontent-%COMP%] {\n padding: 1.25rem 2rem;\n }\n\n .bulk-action-toolbar[_ngcontent-%COMP%] {\n padding: 1.25rem 2rem;\n }\n\n .mj-grid-4[_ngcontent-%COMP%] {\n gap: 1.5rem;\n padding: 0 2rem 1rem 2rem;\n }\n\n .filters-section[_ngcontent-%COMP%] {\n margin: 0 2rem 1rem 2rem;\n padding: 1rem 1.5rem;\n }\n\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 2rem;\n }\n}\n\n\n\n\n\n@media (max-width: 639px) {\n .sticky-header[_ngcontent-%COMP%] {\n padding-bottom: 0;\n }\n\n .mj-grid-4[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n gap: 0.5rem;\n padding: 0 0.75rem 0.5rem 0.75rem;\n }\n\n .mj-card[_ngcontent-%COMP%] {\n padding: 0.75rem;\n gap: 0.75rem;\n }\n\n .stat-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 1.125rem;\n }\n\n .stat-content[_ngcontent-%COMP%] .stat-value[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n }\n\n .stat-content[_ngcontent-%COMP%] .stat-label[_ngcontent-%COMP%] {\n font-size: 0.6875rem;\n }\n\n .filters-section[_ngcontent-%COMP%] {\n margin: 0 0.75rem 0.5rem 0.75rem;\n padding: 0.75rem;\n }\n\n .scrollable-content[_ngcontent-%COMP%] {\n padding: 0.75rem;\n }\n\n .content-area[_ngcontent-%COMP%] {\n padding: 0.875rem;\n border-radius: var(--md-corner-medium);\n }\n\n .list-header[_ngcontent-%COMP%] {\n padding: 0.625rem 0.75rem;\n }\n\n .empty-state[_ngcontent-%COMP%] {\n padding: 2rem 1rem;\n }\n\n .empty-state[_ngcontent-%COMP%] .empty-icon[_ngcontent-%COMP%] {\n font-size: 3rem;\n }\n\n .empty-state[_ngcontent-%COMP%] .empty-text[_ngcontent-%COMP%] {\n font-size: 1.0625rem;\n }\n\n .empty-state[_ngcontent-%COMP%] .empty-subtext[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n }\n}"] });
756
1281
  };
757
1282
  UserManagementComponent = __decorate([
758
1283
  RegisterClass(BaseDashboard, 'UserManagement')
@@ -760,7 +1285,7 @@ UserManagementComponent = __decorate([
760
1285
  export { UserManagementComponent };
761
1286
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(UserManagementComponent, [{
762
1287
  type: Component,
763
- args: [{ selector: 'mj-user-management', template: "<div class=\"user-management-container\">\n <!-- Action Buttons -->\n <div class=\"action-buttons\">\n <button class=\"mj-btn mj-btn-secondary\" (click)=\"refreshData()\" [disabled]=\"isLoading\">\n <i class=\"fa-solid fa-refresh\" [class.fa-spin]=\"isLoading\"></i>\n Refresh\n </button>\n <button class=\"mj-btn mj-btn-secondary\" (click)=\"exportUsers()\">\n <i class=\"fa-solid fa-download\"></i>\n Export\n </button>\n <button class=\"mj-btn mj-btn-primary\" (click)=\"createNewUser()\">\n <i class=\"fa-solid fa-plus\"></i>\n Add User\n </button>\n </div>\n\n <!-- Stats Cards -->\n <div class=\"mj-grid mj-grid-4\">\n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-total\">\n <i class=\"fa-solid fa-users\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.totalUsers }}</div>\n <div class=\"stat-label\">Total Users</div>\n </div>\n </div>\n \n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-active\">\n <i class=\"fa-solid fa-user-check\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.activeUsers }}</div>\n <div class=\"stat-label\">Active Users</div>\n </div>\n </div>\n \n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-inactive\">\n <i class=\"fa-solid fa-user-xmark\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.inactiveUsers }}</div>\n <div class=\"stat-label\">Inactive Users</div>\n </div>\n </div>\n \n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-admin\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\">{{ stats.adminUsers }}</div>\n <div class=\"stat-label\">Owners</div>\n </div>\n </div>\n </div>\n\n <!-- Filters Section -->\n <div class=\"filters-section\">\n <div class=\"filters-row\">\n <!-- Search -->\n <div class=\"search-container\">\n <i class=\"fa-solid fa-search search-icon\"></i>\n <input \n type=\"text\" \n class=\"search-input\" \n placeholder=\"Search users by name or email...\"\n (input)=\"onSearchChange($event)\"\n [value]=\"filters$.value.search\"\n />\n </div>\n \n <!-- Status Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">Status</label>\n <div class=\"filter-buttons\">\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.status === 'all'\"\n (click)=\"onStatusFilterChange('all')\"\n >\n All\n </button>\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.status === 'active'\"\n (click)=\"onStatusFilterChange('active')\"\n >\n Active\n </button>\n <button \n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.status === 'inactive'\"\n (click)=\"onStatusFilterChange('inactive')\"\n >\n Inactive\n </button>\n </div>\n </div>\n \n <!-- Role Filter -->\n <div class=\"filter-group\">\n <label class=\"filter-label\">Role</label>\n <select class=\"filter-select\" (change)=\"onRoleFilterChange($any($event.target).value)\">\n <option value=\"\">All Roles</option>\n @for (role of roles; track role.ID) {\n <option [value]=\"role.ID\">{{ role.Name }}</option>\n }\n </select>\n </div>\n \n <!-- View Toggle -->\n <div class=\"view-toggle\">\n <button \n class=\"mj-btn mj-btn-icon-only\"\n [class.mj-btn-primary]=\"viewMode === 'grid'\"\n [class.mj-btn-ghost]=\"viewMode !== 'grid'\"\n (click)=\"viewMode = 'grid'\"\n title=\"Grid View\"\n >\n <i class=\"fa-solid fa-table\"></i>\n </button>\n <button \n class=\"mj-btn mj-btn-icon-only\"\n [class.mj-btn-primary]=\"viewMode === 'cards'\"\n [class.mj-btn-ghost]=\"viewMode !== 'cards'\"\n (click)=\"viewMode = 'cards'\"\n title=\"Card View\"\n >\n <i class=\"fa-solid fa-th-large\"></i>\n </button>\n </div>\n </div>\n </div>\n\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\">\n <div class=\"loading-spinner\">\n <div class=\"spinner-ring\"></div>\n <div class=\"spinner-ring\"></div>\n <div class=\"spinner-ring\"></div>\n </div>\n <div class=\"loading-text\">Loading users...</div>\n </div>\n }\n\n <!-- Error State -->\n @if (error && !isLoading) {\n <div class=\"error-container\">\n <div class=\"error-content\">\n <i class=\"fa-solid fa-exclamation-triangle error-icon\"></i>\n <p class=\"error-message\">{{ error }}</p>\n <button class=\"retry-button\" (click)=\"loadInitialData()\">\n <i class=\"fa-solid fa-refresh\"></i>\n Try Again\n </button>\n </div>\n </div>\n }\n\n <!-- Content Area -->\n @if (!isLoading && !error) {\n <div class=\"content-area\">\n <!-- Grid View -->\n @if (viewMode === 'grid') {\n <div class=\"users-table\">\n <table class=\"modern-table\">\n <thead>\n <tr>\n <th class=\"th-checkbox\">\n <input type=\"checkbox\" class=\"checkbox\" />\n </th>\n <th>User</th>\n <th>Email</th>\n <th>Type</th>\n <th>Status</th>\n <th>Last Updated</th>\n <th class=\"th-actions\">Actions</th>\n </tr>\n </thead>\n <tbody>\n @for (user of filteredUsers; track user.ID) {\n <tr class=\"table-row\" (click)=\"selectUser(user)\">\n <td class=\"td-checkbox\" (click)=\"$event.stopPropagation()\">\n <input type=\"checkbox\" class=\"checkbox\" />\n </td>\n <td>\n <div class=\"user-cell\">\n <div class=\"user-avatar\">\n {{ getUserInitials(user) }}\n </div>\n <div class=\"user-info\">\n <div class=\"user-name\">{{ user.Name }}</div>\n <div class=\"user-fullname\">\n {{ user.FirstName }} {{ user.LastName }}\n </div>\n </div>\n </div>\n </td>\n <td>{{ user.Email }}</td>\n <td>\n <div class=\"user-type\">\n <i [class]=\"'fa-solid ' + getUserTypeIcon(user)\"></i>\n {{ user.Type }}\n </div>\n </td>\n <td>\n <span class=\"status-badge\" [class]=\"getStatusClass(user)\">\n <i [class]=\"'fa-solid ' + getStatusIcon(user)\"></i>\n {{ user.IsActive ? 'Active' : 'Inactive' }}\n </span>\n </td>\n <td>\n <span class=\"last-login\">\n {{ user.__mj_UpdatedAt ? (user.__mj_UpdatedAt | date:'short') : 'Never' }}\n </span>\n </td>\n <td class=\"td-actions\" (click)=\"$event.stopPropagation()\">\n <button class=\"mj-btn mj-btn-ghost mj-btn-sm\" (click)=\"editUser(user)\" title=\"Edit\">\n <i class=\"fa-solid fa-edit\"></i>\n </button>\n <button \n class=\"mj-btn mj-btn-ghost mj-btn-sm\" \n (click)=\"toggleUserStatus(user)\"\n [title]=\"user.IsActive ? 'Deactivate' : 'Activate'\"\n >\n <i [class]=\"user.IsActive ? 'fa-solid fa-toggle-on' : 'fa-solid fa-toggle-off'\"></i>\n </button>\n <button class=\"mj-btn mj-btn-ghost mj-btn-sm text-danger\" (click)=\"confirmDeleteUser(user)\" title=\"Delete\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </td>\n </tr>\n }\n </tbody>\n </table>\n \n @if (filteredUsers.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-users-slash empty-icon\"></i>\n <p class=\"empty-text\">No users found</p>\n <p class=\"empty-subtext\">Try adjusting your filters or add a new user</p>\n </div>\n }\n </div>\n }\n\n <!-- Card View -->\n @if (viewMode === 'cards') {\n <div class=\"users-grid\">\n @for (user of filteredUsers; track user.ID) {\n <div class=\"user-card\" (click)=\"selectUser(user)\">\n <div class=\"card-header\">\n <div class=\"user-avatar-large\">\n {{ getUserInitials(user) }}\n </div>\n <div class=\"card-actions\">\n <button class=\"mj-btn mj-btn-ghost mj-btn-sm\" (click)=\"editUser(user); $event.stopPropagation()\" title=\"Edit\">\n <i class=\"fa-solid fa-edit\"></i>\n </button>\n <button class=\"mj-btn mj-btn-ghost mj-btn-sm text-danger\" (click)=\"confirmDeleteUser(user); $event.stopPropagation()\" title=\"Delete\">\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n </div>\n \n <div class=\"card-body\">\n <h3 class=\"user-name\">{{ user.Name }}</h3>\n <p class=\"user-fullname\">{{ user.FirstName }} {{ user.LastName }}</p>\n <p class=\"user-email\">\n <i class=\"fa-solid fa-envelope\"></i>\n {{ user.Email }}\n </p>\n \n <div class=\"card-meta\">\n <div class=\"meta-item\">\n <i [class]=\"'fa-solid ' + getUserTypeIcon(user)\"></i>\n {{ user.Type }}\n </div>\n <span class=\"status-badge\" [class]=\"getStatusClass(user)\">\n <i [class]=\"'fa-solid ' + getStatusIcon(user)\"></i>\n {{ user.IsActive ? 'Active' : 'Inactive' }}\n </span>\n </div>\n \n <div class=\"card-footer\">\n <div class=\"last-login\">\n <i class=\"fa-solid fa-clock\"></i>\n Last updated: {{ user.__mj_UpdatedAt ? (user.__mj_UpdatedAt | date:'short') : 'Never' }}\n </div>\n </div>\n </div>\n </div>\n }\n \n @if (filteredUsers.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-users-slash empty-icon\"></i>\n <p class=\"empty-text\">No users found</p>\n <p class=\"empty-subtext\">Try adjusting your filters or add a new user</p>\n </div>\n }\n </div>\n }\n </div>\n }\n\n <!-- User Create/Edit Dialog -->\n <mj-user-dialog \n [data]=\"userDialogData\"\n [visible]=\"showUserDialog\"\n (result)=\"onUserDialogResult($event)\">\n </mj-user-dialog>\n\n <!-- Delete Confirmation Dialog -->\n @if (showDeleteConfirm && selectedUser) {\n <div class=\"modal-backdrop\" (click)=\"showDeleteConfirm = false\">\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3 class=\"modal-title\">\n <i class=\"fa-solid fa-exclamation-triangle text-danger\"></i>\n Confirm Delete\n </h3>\n <button class=\"modal-close\" (click)=\"showDeleteConfirm = false\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n <div class=\"modal-body\">\n <p>Are you sure you want to delete user <strong>{{ selectedUser.Name }}</strong>?</p>\n <p class=\"text-muted\">This action cannot be undone.</p>\n </div>\n <div class=\"modal-footer\">\n <button class=\"mj-btn mj-btn-secondary\" (click)=\"showDeleteConfirm = false\">Cancel</button>\n <button class=\"mj-btn mj-btn-primary text-danger\" (click)=\"deleteUser()\">\n <i class=\"fa-solid fa-trash\"></i>\n Delete User\n </button>\n </div>\n </div>\n </div>\n }\n</div>", styles: ["@keyframes shimmer {\n 0% {\n background-position: -200% 0;\n }\n 100% {\n background-position: 200% 0;\n }\n}\n.user-management-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n max-height: 100%;\n overflow: hidden;\n position: relative;\n width: 100%;\n height: 100%;\n}\n\n.action-buttons {\n flex-shrink: 0;\n position: sticky;\n top: 0;\n z-index: 10;\n background: inherit;\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n padding: 1rem 2rem;\n background: white;\n border-bottom: 1px solid #e0e0e0;\n}\n@media (max-width: 768px) {\n .action-buttons {\n justify-content: center;\n flex-wrap: wrap;\n padding: 1rem;\n }\n}\n\n.btn-primary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #2196f3;\n color: white;\n}\n.btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-primary i {\n font-size: 0.875rem;\n}\n.btn-primary:hover {\n background-color: #1976d2;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(33, 150, 243, 0.3);\n}\n.btn-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n transform: none;\n}\n\n.btn-secondary {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #ffffff;\n color: #374151;\n border: 1px solid #e5e7eb;\n}\n.btn-secondary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-secondary i {\n font-size: 0.875rem;\n}\n.btn-secondary:hover {\n background-color: #f9fafb;\n border-color: #2196f3;\n color: #2196f3;\n}\n\n.btn-danger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #f44336;\n color: white;\n}\n.btn-danger:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.btn-danger i {\n font-size: 0.875rem;\n}\n.btn-danger:hover {\n background-color: #d32f2f;\n}\n\n.stats-grid {\n flex-shrink: 0;\n position: sticky;\n top: 0;\n z-index: 10;\n background: inherit;\n display: grid !important;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 1.5rem;\n padding: 1rem 2rem;\n background: white;\n border-bottom: 1px solid #e0e0e0;\n width: 100%;\n}\n@media (max-width: 768px) {\n .stats-grid {\n grid-template-columns: repeat(2, 1fr);\n gap: 1rem;\n padding: 1rem;\n }\n}\n\n.stat-card {\n background: white;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n display: flex;\n margin-right: 10px;\n align-items: center;\n gap: 1rem;\n transition: all 0.3s ease;\n min-width: 0;\n}\n.stat-card:hover {\n transform: translateY(-2px);\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);\n}\n\n.stat-icon {\n width: 60px;\n height: 60px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.5rem;\n}\n.stat-icon-total {\n background: rgba(33, 150, 243, 0.1);\n color: #2196f3;\n}\n.stat-icon-active {\n background: rgba(76, 175, 80, 0.1);\n color: #4caf50;\n}\n.stat-icon-inactive {\n background: rgba(244, 67, 54, 0.1);\n color: #f44336;\n}\n.stat-icon-admin {\n background: rgba(156, 39, 176, 0.1);\n color: #9c27b0;\n}\n\n.stat-content {\n flex: 1;\n}\n.stat-content .stat-value {\n font-size: 2rem;\n font-weight: 700;\n color: #1f2937;\n line-height: 1;\n}\n.stat-content .stat-label {\n color: #6b7280;\n font-size: 0.875rem;\n margin-top: 0.25rem;\n}\n\n.filters-section {\n flex-shrink: 0;\n position: sticky;\n top: 0;\n z-index: 10;\n background: inherit;\n background: white;\n padding: 1.5rem 2rem;\n border-bottom: 1px solid #e0e0e0;\n}\n@media (max-width: 768px) {\n .filters-section {\n padding: 1rem;\n }\n}\n\n.filters-row {\n display: flex;\n gap: 1.5rem;\n align-items: flex-end;\n flex-wrap: wrap;\n}\n@media (max-width: 768px) {\n .filters-row {\n gap: 1rem;\n }\n}\n\n.search-container {\n flex: 1;\n min-width: 250px;\n position: relative;\n}\n.search-container .search-icon {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: #6b7280;\n font-size: 1rem;\n}\n.search-container .search-input {\n width: 100%;\n padding: 0.75rem 1rem 0.75rem 2.75rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n font-size: 0.95rem;\n transition: all 0.2s;\n}\n.search-container .search-input:focus {\n outline: none;\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n}\n\n.filter-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n.filter-group .filter-label {\n font-size: 0.875rem;\n font-weight: 500;\n color: #374151;\n}\n.filter-group .filter-buttons {\n display: flex;\n background: #f3f4f6;\n border-radius: 8px;\n padding: 4px;\n}\n.filter-group .filter-btn {\n padding: 0.5rem 1rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 0.875rem;\n font-weight: 500;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.filter-group .filter-btn:hover {\n color: #374151;\n}\n.filter-group .filter-btn.active {\n background: white;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n.filter-group .filter-select {\n padding: 0.625rem 1rem;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n background: white;\n font-size: 0.875rem;\n color: #374151;\n cursor: pointer;\n transition: all 0.2s;\n}\n.filter-group .filter-select:focus {\n outline: none;\n border-color: #2196f3;\n box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);\n}\n\n.view-toggle {\n display: flex;\n background: #f3f4f6;\n border-radius: 8px;\n padding: 4px;\n}\n.view-toggle .view-btn {\n padding: 0.5rem 0.75rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1rem;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.view-toggle .view-btn:hover {\n color: #374151;\n}\n.view-toggle .view-btn.active {\n background: white;\n color: #2196f3;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);\n}\n\n.content-area {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n min-height: 0;\n position: relative;\n padding: 2rem;\n background: white;\n}\n@media (max-width: 768px) {\n .content-area {\n padding: 1rem;\n }\n}\n\n.users-table {\n width: 100%;\n overflow-x: auto;\n}\n\n.modern-table {\n width: 100%;\n border-collapse: collapse;\n}\n.modern-table thead {\n background: #f9fafb;\n border-bottom: 1px solid #e5e7eb;\n}\n.modern-table thead th {\n padding: 1rem;\n text-align: left;\n font-size: 0.875rem;\n font-weight: 600;\n color: #374151;\n white-space: nowrap;\n}\n.modern-table thead th.th-checkbox {\n width: 50px;\n}\n.modern-table thead th.th-actions {\n text-align: center;\n width: 150px;\n}\n.modern-table tbody tr {\n border-bottom: 1px solid #f3f4f6;\n transition: background-color 0.2s;\n cursor: pointer;\n}\n.modern-table tbody tr:hover {\n background-color: #f9fafb;\n}\n.modern-table tbody td {\n padding: 1rem;\n font-size: 0.875rem;\n color: #374151;\n}\n.modern-table tbody td.td-checkbox {\n width: 50px;\n}\n.modern-table tbody td.td-actions {\n text-align: center;\n}\n\n.checkbox {\n width: 18px;\n height: 18px;\n cursor: pointer;\n}\n\n.user-cell {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n}\n\n.user-avatar {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n font-size: 0.875rem;\n}\n\n.user-avatar-large {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);\n color: white;\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 600;\n font-size: 1.5rem;\n margin: 0 auto 1rem;\n}\n\n.user-info .user-name {\n font-weight: 600;\n color: #1f2937;\n}\n.user-info .user-fullname {\n font-size: 0.75rem;\n color: #6b7280;\n}\n\n.user-type {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n color: #4b5563;\n}\n.user-type i {\n font-size: 0.875rem;\n}\n\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.25rem 0.75rem;\n border-radius: 20px;\n font-size: 0.75rem;\n font-weight: 500;\n}\n.status-badge.status-active {\n background: rgba(76, 175, 80, 0.1);\n color: #388e3c;\n}\n.status-badge.status-inactive {\n background: rgba(244, 67, 54, 0.1);\n color: #d32f2f;\n}\n.status-badge i {\n font-size: 0.625rem;\n}\n\n.last-login {\n color: #6b7280;\n font-size: 0.875rem;\n}\n\n.action-btn {\n padding: 0.5rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1rem;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n.action-btn:hover {\n background: #f3f4f6;\n color: #2196f3;\n}\n.action-btn-danger:hover {\n color: #f44336;\n}\n\n.users-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));\n gap: 1.5rem;\n padding: 1.5rem;\n}\n@media (max-width: 768px) {\n .users-grid {\n grid-template-columns: 1fr;\n gap: 1rem;\n padding: 1rem;\n }\n}\n\n.user-card {\n background: white;\n border: 1px solid #e5e7eb;\n border-radius: 12px;\n padding: 1.5rem;\n cursor: pointer;\n transition: all 0.3s ease;\n}\n.user-card:hover {\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);\n transform: translateY(-2px);\n border-color: #2196f3;\n}\n\n.card-header {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 1rem;\n}\n\n.card-actions {\n display: flex;\n gap: 0.5rem;\n}\n\n.card-body {\n text-align: center;\n}\n.card-body .user-name {\n font-size: 1.25rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0 0 0.25rem 0;\n}\n.card-body .user-fullname {\n color: #6b7280;\n margin: 0 0 0.75rem 0;\n}\n.card-body .user-email {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n color: #4b5563;\n font-size: 0.875rem;\n margin-bottom: 1rem;\n}\n.card-body .user-email i {\n color: #6b7280;\n}\n\n.card-meta {\n display: flex;\n justify-content: center;\n align-items: center;\n gap: 1rem;\n padding: 1rem 0;\n border-top: 1px solid #f3f4f6;\n border-bottom: 1px solid #f3f4f6;\n margin-bottom: 1rem;\n}\n.card-meta .meta-item {\n display: flex;\n align-items: center;\n gap: 0.375rem;\n color: #4b5563;\n font-size: 0.875rem;\n}\n\n.card-footer .last-login {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n color: #6b7280;\n font-size: 0.75rem;\n}\n.card-footer .last-login i {\n font-size: 0.875rem;\n}\n\n.empty-state {\n text-align: center;\n padding: 4rem 2rem;\n}\n.empty-state .empty-icon {\n font-size: 4rem;\n color: #e5e7eb;\n margin-bottom: 1rem;\n}\n.empty-state .empty-text {\n font-size: 1.25rem;\n font-weight: 600;\n color: #374151;\n margin: 0 0 0.5rem 0;\n}\n.empty-state .empty-subtext {\n color: #6b7280;\n margin: 0;\n}\n\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n}\n\n.loading-spinner {\n position: relative;\n width: 60px;\n height: 60px;\n margin-bottom: 1rem;\n}\n.loading-spinner .spinner-ring {\n position: absolute;\n width: 100%;\n height: 100%;\n border: 3px solid transparent;\n border-radius: 50%;\n animation: spin 1.5s cubic-bezier(0.5, 0, 0.5, 1) infinite;\n}\n.loading-spinner .spinner-ring:nth-child(1) {\n border-color: #2196f3 transparent transparent transparent;\n animation-delay: -0.45s;\n}\n.loading-spinner .spinner-ring:nth-child(2) {\n border-color: transparent #4caf50 transparent transparent;\n animation-delay: -0.3s;\n}\n.loading-spinner .spinner-ring:nth-child(3) {\n border-color: transparent transparent #ff9800 transparent;\n animation-delay: -0.15s;\n}\n\n@keyframes spin {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n.loading-text {\n color: #6b7280;\n font-size: 0.95rem;\n}\n\n.error-container {\n text-align: center;\n padding: 4rem 2rem;\n}\n.error-container .error-icon {\n font-size: 3rem;\n color: #f44336;\n margin-bottom: 1rem;\n}\n.error-container .error-message {\n color: #374151;\n margin-bottom: 1.5rem;\n}\n.error-container .retry-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n padding: 0.625rem 1.25rem;\n font-size: 0.95rem;\n font-weight: 500;\n border: none;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n background-color: #2196f3;\n color: white;\n}\n.error-container .retry-button:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.error-container .retry-button i {\n font-size: 0.875rem;\n}\n\n.modal-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n animation: fadeIn 0.2s ease;\n}\n\n.modal-dialog {\n background: white;\n border-radius: 12px;\n box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);\n max-width: 500px;\n width: 90%;\n max-height: 90vh;\n overflow: hidden;\n animation: slideUp 0.3s ease;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.5rem;\n border-bottom: 1px solid #e5e7eb;\n}\n.modal-header .modal-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.25rem;\n font-weight: 600;\n color: #1f2937;\n margin: 0;\n}\n.modal-header .modal-close {\n padding: 0.5rem;\n border: none;\n background: transparent;\n color: #6b7280;\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: 6px;\n transition: all 0.2s;\n}\n.modal-header .modal-close:hover {\n background: #f3f4f6;\n color: #374151;\n}\n\n.modal-body {\n padding: 1.5rem;\n}\n.modal-body p {\n margin: 0 0 1rem 0;\n color: #374151;\n}\n.modal-body p:last-child {\n margin-bottom: 0;\n}\n.modal-body .text-muted {\n color: #6b7280;\n font-size: 0.875rem;\n}\n\n.modal-footer {\n display: flex;\n justify-content: flex-end;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid #e5e7eb;\n background: #f9fafb;\n}\n\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n@keyframes slideUp {\n from {\n transform: translateY(20px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n.text-danger {\n color: #f44336;\n}\n"] }]
1288
+ args: [{ selector: 'mj-user-management', template: "<div class=\"user-management-container\">\n <!-- Sticky Header Section -->\n <div class=\"sticky-header\">\n <!-- Action Buttons -->\n <div class=\"action-buttons\" role=\"toolbar\" aria-label=\"User management actions\">\n <button\n class=\"mj-btn mj-btn-secondary mj-btn-icon-mobile\"\n (click)=\"refreshData()\"\n [disabled]=\"isLoading\"\n aria-label=\"Refresh user list\"\n >\n <i class=\"fa-solid fa-refresh\" [class.fa-spin]=\"isLoading\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Refresh</span>\n </button>\n <button\n class=\"mj-btn mj-btn-secondary mj-btn-icon-mobile\"\n (click)=\"exportUsers()\"\n aria-label=\"Export users to file\"\n >\n <i class=\"fa-solid fa-download\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Export</span>\n </button>\n <button\n class=\"mj-btn mj-btn-primary mj-btn-icon-mobile\"\n (click)=\"createNewUser()\"\n aria-label=\"Add new user\"\n >\n <i class=\"fa-solid fa-plus\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Add User</span>\n </button>\n </div>\n\n <!-- Bulk Action Toolbar -->\n @if (hasSelection) {\n <div class=\"bulk-action-toolbar\" role=\"toolbar\" aria-label=\"Bulk actions\">\n <div class=\"bulk-selection-info\">\n <i class=\"fa-solid fa-check-square\" aria-hidden=\"true\"></i>\n <span>{{ selectedCount }} user{{ selectedCount > 1 ? 's' : '' }} selected</span>\n <button\n class=\"mj-btn mj-btn-ghost mj-btn-sm\"\n (click)=\"clearSelection()\"\n aria-label=\"Clear selection\"\n >\n <i class=\"fa-solid fa-times\" aria-hidden=\"true\"></i>\n Clear\n </button>\n </div>\n <div class=\"bulk-action-buttons\">\n <button\n class=\"mj-btn mj-btn-secondary mj-btn-sm\"\n (click)=\"confirmBulkAction('enable')\"\n aria-label=\"Enable selected users\"\n >\n <i class=\"fa-solid fa-toggle-on\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Enable</span>\n </button>\n <button\n class=\"mj-btn mj-btn-secondary mj-btn-sm\"\n (click)=\"confirmBulkAction('disable')\"\n aria-label=\"Disable selected users\"\n >\n <i class=\"fa-solid fa-toggle-off\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Disable</span>\n </button>\n <button\n class=\"mj-btn mj-btn-secondary mj-btn-sm\"\n (click)=\"openBulkRoleAssign()\"\n aria-label=\"Assign role to selected users\"\n >\n <i class=\"fa-solid fa-user-tag\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Assign Role</span>\n </button>\n <button\n class=\"mj-btn mj-btn-danger mj-btn-sm\"\n (click)=\"confirmBulkAction('delete')\"\n aria-label=\"Delete selected users\"\n >\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Delete</span>\n </button>\n </div>\n </div>\n }\n\n <!-- Stats Cards -->\n <div class=\"mj-grid-4\" role=\"region\" aria-label=\"User statistics\">\n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-total\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-users\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" aria-label=\"Total users count\">{{ stats.totalUsers }}</div>\n <div class=\"stat-label\">Total Users</div>\n </div>\n </div>\n\n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-active\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-user-check\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" aria-label=\"Active users count\">{{ stats.activeUsers }}</div>\n <div class=\"stat-label\">Active Users</div>\n </div>\n </div>\n\n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-inactive\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-user-xmark\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" aria-label=\"Inactive users count\">{{ stats.inactiveUsers }}</div>\n <div class=\"stat-label\">Inactive Users</div>\n </div>\n </div>\n\n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-admin\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" aria-label=\"Owner users count\">{{ stats.adminUsers }}</div>\n <div class=\"stat-label\">Owners</div>\n </div>\n </div>\n </div>\n\n <!-- Filters Section -->\n <div class=\"filters-section\" role=\"search\" aria-label=\"Filter users\">\n <div class=\"filters-row\">\n <!-- Search -->\n <div class=\"mj-search\">\n <i class=\"fa-solid fa-search mj-search-icon\" aria-hidden=\"true\"></i>\n <input\n type=\"text\"\n class=\"mj-search-input\"\n placeholder=\"Search users by name or email...\"\n (input)=\"onSearchChange($event)\"\n [value]=\"filters$.value.search\"\n aria-label=\"Search users by name or email\"\n />\n </div>\n\n <!-- Mobile: Filter Toggle Button -->\n <button\n class=\"mobile-filter-toggle\"\n (click)=\"showMobileFilters = !showMobileFilters\"\n [class.active]=\"showMobileFilters\"\n [attr.aria-expanded]=\"showMobileFilters\"\n aria-label=\"Toggle filters\"\n >\n <i class=\"fa-solid fa-filter\" aria-hidden=\"true\"></i>\n @if (hasActiveFilters) {\n <span class=\"filter-badge\">{{ activeFilterCount }}</span>\n }\n </button>\n\n <!-- Desktop: Status Filter - Button group -->\n <div class=\"mj-filter-group desktop-filter-group\">\n <label class=\"mj-filter-label\" id=\"status-filter-label\">Status</label>\n <div class=\"mj-filter-buttons\" role=\"group\" aria-labelledby=\"status-filter-label\">\n <button\n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.status === 'all'\"\n (click)=\"onStatusFilterChange('all')\"\n [attr.aria-pressed]=\"filters$.value.status === 'all'\"\n >\n All\n </button>\n <button\n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.status === 'active'\"\n (click)=\"onStatusFilterChange('active')\"\n [attr.aria-pressed]=\"filters$.value.status === 'active'\"\n >\n Active\n </button>\n <button\n class=\"mj-btn mj-btn-ghost\"\n [class.mj-btn-primary]=\"filters$.value.status === 'inactive'\"\n (click)=\"onStatusFilterChange('inactive')\"\n [attr.aria-pressed]=\"filters$.value.status === 'inactive'\"\n >\n Inactive\n </button>\n </div>\n </div>\n\n <!-- Desktop: Role Filter -->\n <div class=\"mj-filter-group desktop-filter-group\">\n <label class=\"mj-filter-label\" for=\"role-filter\">Role</label>\n <select\n id=\"role-filter\"\n class=\"mj-filter-select\"\n (change)=\"onRoleFilterChange($any($event.target).value)\"\n aria-label=\"Filter by role\"\n >\n <option value=\"\">All Roles</option>\n @for (role of roles; track role.ID) {\n <option [value]=\"role.ID\">{{ role.Name }}</option>\n }\n </select>\n </div>\n </div>\n\n <!-- Mobile: Filter Dropdown Panel -->\n @if (showMobileFilters) {\n <div class=\"mobile-filter-dropdown\">\n <div class=\"mobile-filter-content\">\n <!-- Status Filter -->\n <div class=\"mj-filter-group\">\n <label class=\"mj-filter-label\" id=\"status-filter-label-mobile\">Status</label>\n <select\n class=\"mj-filter-select\"\n [value]=\"filters$.value.status\"\n (change)=\"onStatusFilterChange($any($event.target).value)\"\n aria-labelledby=\"status-filter-label-mobile\"\n >\n <option value=\"all\">All Status</option>\n <option value=\"active\">Active</option>\n <option value=\"inactive\">Inactive</option>\n </select>\n </div>\n\n <!-- Role Filter -->\n <div class=\"mj-filter-group\">\n <label class=\"mj-filter-label\" for=\"role-filter-mobile\">Role</label>\n <select\n id=\"role-filter-mobile\"\n class=\"mj-filter-select\"\n (change)=\"onRoleFilterChange($any($event.target).value)\"\n aria-label=\"Filter by role\"\n >\n <option value=\"\">All Roles</option>\n @for (role of roles; track role.ID) {\n <option [value]=\"role.ID\">{{ role.Name }}</option>\n }\n </select>\n </div>\n\n <!-- Clear Filters Button -->\n @if (hasActiveFilters) {\n <button class=\"mj-btn mj-btn-ghost mj-btn-sm clear-filters-btn\" (click)=\"clearFilters()\">\n <i class=\"fa-solid fa-times\" aria-hidden=\"true\"></i>\n Clear Filters\n </button>\n }\n </div>\n </div>\n }\n </div>\n </div><!-- End Sticky Header -->\n\n <!-- Scrollable Content Section -->\n <div class=\"scrollable-content\">\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\" role=\"status\" aria-live=\"polite\" aria-busy=\"true\">\n <mj-loading text=\"Loading users...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (error && !isLoading) {\n <div class=\"error-container\" role=\"alert\" aria-live=\"assertive\">\n <div class=\"error-content\">\n <i class=\"fa-solid fa-exclamation-triangle error-icon\" aria-hidden=\"true\"></i>\n <p class=\"error-message\">{{ error }}</p>\n <button class=\"retry-button\" (click)=\"loadInitialData()\" aria-label=\"Retry loading users\">\n <i class=\"fa-solid fa-refresh\" aria-hidden=\"true\"></i>\n Try Again\n </button>\n </div>\n </div>\n }\n\n <!-- Content Area -->\n @if (!isLoading && !error) {\n <div class=\"content-area\">\n <!-- Users List -->\n <div class=\"users-list\" role=\"list\" aria-label=\"Users list\">\n <!-- List Header with Select All -->\n <div class=\"list-header\">\n <label class=\"select-all-label\">\n <input\n type=\"checkbox\"\n class=\"checkbox\"\n [checked]=\"isAllSelected\"\n [indeterminate]=\"isIndeterminate\"\n (change)=\"toggleSelectAll()\"\n aria-label=\"Select all users\"\n />\n <span class=\"select-all-text\">Select All ({{ filteredUsers.length }})</span>\n </label>\n @if (hasSelection) {\n <span class=\"selection-count\">{{ selectedCount }} selected</span>\n }\n </div>\n\n @for (user of filteredUsers; track user.ID) {\n <div\n class=\"user-card\"\n [class.expanded]=\"isUserExpanded(user.ID)\"\n [class.selected]=\"isUserSelected(user.ID)\"\n role=\"listitem\"\n >\n <!-- User Card Header - Always Visible -->\n <div\n class=\"user-header\"\n (click)=\"toggleUserExpansion(user.ID)\"\n role=\"button\"\n [attr.aria-expanded]=\"isUserExpanded(user.ID)\"\n tabindex=\"0\"\n (keydown.enter)=\"toggleUserExpansion(user.ID)\"\n >\n <!-- Selection Checkbox -->\n <div class=\"user-selection\" (click)=\"$event.stopPropagation()\">\n <input\n type=\"checkbox\"\n class=\"checkbox\"\n [checked]=\"isUserSelected(user.ID)\"\n (change)=\"toggleUserSelection(user.ID, $event)\"\n [attr.aria-label]=\"'Select ' + user.Name\"\n />\n </div>\n\n <!-- User Info -->\n <div class=\"user-info\">\n <div class=\"user-avatar\" aria-hidden=\"true\">\n {{ getUserInitials(user) }}\n </div>\n <div class=\"user-details\">\n <h3 class=\"user-name\">{{ user.Name }}</h3>\n <p class=\"user-email\">{{ user.Email }}</p>\n </div>\n </div>\n\n <!-- User Meta -->\n <div class=\"user-meta\">\n <span class=\"status-badge\" [class]=\"getStatusClass(user)\">\n <i [class]=\"'fa-solid ' + getStatusIcon(user)\" aria-hidden=\"true\"></i>\n {{ user.IsActive ? 'Active' : 'Inactive' }}\n </span>\n <div class=\"user-actions desktop-only\" (click)=\"$event.stopPropagation()\">\n <button\n class=\"mj-btn mj-btn-ghost mj-btn-sm\"\n (click)=\"editUser(user)\"\n [attr.aria-label]=\"'Edit ' + user.Name\"\n title=\"Edit\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n </button>\n <button\n class=\"mj-btn mj-btn-ghost mj-btn-sm\"\n (click)=\"toggleUserStatus(user)\"\n [attr.aria-label]=\"(user.IsActive ? 'Deactivate ' : 'Activate ') + user.Name\"\n [title]=\"user.IsActive ? 'Deactivate' : 'Activate'\"\n >\n <i [class]=\"user.IsActive ? 'fa-solid fa-toggle-on' : 'fa-solid fa-toggle-off'\" aria-hidden=\"true\"></i>\n </button>\n <button\n class=\"mj-btn mj-btn-ghost mj-btn-sm mj-btn-danger\"\n (click)=\"confirmDeleteUser(user)\"\n [attr.aria-label]=\"'Delete ' + user.Name\"\n title=\"Delete\"\n >\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <button class=\"expand-btn\" aria-label=\"Toggle user details\">\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n\n <!-- User Card Content - Expanded -->\n @if (isUserExpanded(user.ID)) {\n <div class=\"user-content\">\n <!-- Mobile Actions Bar -->\n <div class=\"mobile-actions-bar\" (click)=\"$event.stopPropagation()\">\n <span class=\"status-badge\" [class]=\"getStatusClass(user)\">\n <i [class]=\"'fa-solid ' + getStatusIcon(user)\" aria-hidden=\"true\"></i>\n {{ user.IsActive ? 'Active' : 'Inactive' }}\n </span>\n <div class=\"mobile-action-buttons\">\n <button\n class=\"mj-btn mj-btn-ghost mj-btn-sm\"\n (click)=\"editUser(user)\"\n [attr.aria-label]=\"'Edit ' + user.Name\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n <span class=\"btn-label\">Edit</span>\n </button>\n <button\n class=\"mj-btn mj-btn-ghost mj-btn-sm\"\n (click)=\"toggleUserStatus(user)\"\n [attr.aria-label]=\"(user.IsActive ? 'Deactivate ' : 'Activate ') + user.Name\"\n >\n <i [class]=\"user.IsActive ? 'fa-solid fa-toggle-on' : 'fa-solid fa-toggle-off'\" aria-hidden=\"true\"></i>\n <span class=\"btn-label\">{{ user.IsActive ? 'Disable' : 'Enable' }}</span>\n </button>\n <button\n class=\"mj-btn mj-btn-ghost mj-btn-sm mj-btn-danger\"\n (click)=\"confirmDeleteUser(user)\"\n [attr.aria-label]=\"'Delete ' + user.Name\"\n >\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n <span class=\"btn-label\">Delete</span>\n </button>\n </div>\n </div>\n\n <!-- User Stats -->\n <div class=\"user-stats\">\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-user-tag\" aria-hidden=\"true\"></i>\n <span class=\"stat-label\">Type:</span>\n <span class=\"stat-value\">\n <i [class]=\"'fa-solid ' + getUserTypeIcon(user)\" aria-hidden=\"true\"></i>\n {{ user.Type }}\n </span>\n </div>\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-id-card\" aria-hidden=\"true\"></i>\n <span class=\"stat-label\">Full Name:</span>\n <span class=\"stat-value\">{{ user.FirstName }} {{ user.LastName }}</span>\n </div>\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-calendar\" aria-hidden=\"true\"></i>\n <span class=\"stat-label\">Created:</span>\n <span class=\"stat-value\">{{ user.__mj_CreatedAt | date:'short' }}</span>\n </div>\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-clock\" aria-hidden=\"true\"></i>\n <span class=\"stat-label\">Updated:</span>\n <span class=\"stat-value\">{{ user.__mj_UpdatedAt | date:'short' }}</span>\n </div>\n </div>\n\n <!-- User Roles Section -->\n <div class=\"roles-section\">\n <h4 class=\"section-title\">\n <i class=\"fa-solid fa-user-shield\" aria-hidden=\"true\"></i>\n Assigned Roles\n </h4>\n @if (getUserRoles(user.ID).length > 0) {\n <div class=\"roles-grid\">\n @for (role of getUserRoles(user.ID); track role.ID) {\n <div class=\"role-item\">\n <i class=\"fa-solid fa-shield\" aria-hidden=\"true\"></i>\n {{ role.Name }}\n </div>\n }\n </div>\n } @else {\n <p class=\"no-roles\">No roles assigned to this user</p>\n }\n </div>\n </div>\n }\n </div>\n }\n\n @if (filteredUsers.length === 0) {\n <div class=\"empty-state\" role=\"status\">\n <i class=\"fa-solid fa-users-slash empty-icon\" aria-hidden=\"true\"></i>\n <p class=\"empty-text\">No users found</p>\n <p class=\"empty-subtext\">Try adjusting your filters or add a new user</p>\n </div>\n }\n </div>\n </div>\n }\n </div><!-- End Scrollable Content -->\n\n <!-- User Create/Edit Dialog -->\n <mj-user-dialog\n [data]=\"userDialogData\"\n [visible]=\"showUserDialog\"\n (result)=\"onUserDialogResult($event)\">\n </mj-user-dialog>\n\n <!-- Delete Confirmation Dialog -->\n @if (showDeleteConfirm && selectedUser) {\n <div\n class=\"modal-backdrop\"\n (click)=\"showDeleteConfirm = false\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"delete-dialog-title\"\n aria-describedby=\"delete-dialog-desc\"\n >\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3 class=\"modal-title\" id=\"delete-dialog-title\">\n <i class=\"fa-solid fa-exclamation-triangle text-danger\" aria-hidden=\"true\"></i>\n Confirm Delete\n </h3>\n <button\n class=\"modal-close\"\n (click)=\"showDeleteConfirm = false\"\n aria-label=\"Close dialog\"\n >\n <i class=\"fa-solid fa-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"modal-body\" id=\"delete-dialog-desc\">\n <p>Are you sure you want to delete user <strong>{{ selectedUser.Name }}</strong>?</p>\n <p class=\"text-muted\">This action cannot be undone.</p>\n </div>\n <div class=\"modal-footer\">\n <button class=\"mj-btn mj-btn-danger\" (click)=\"deleteUser()\">\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n Delete User\n </button>\n <button class=\"mj-btn mj-btn-secondary\" (click)=\"showDeleteConfirm = false\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n\n <!-- Bulk Action Confirmation Dialog -->\n @if (showBulkActionConfirm) {\n <div\n class=\"modal-backdrop\"\n (click)=\"cancelBulkAction()\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"bulk-action-dialog-title\"\n aria-describedby=\"bulk-action-dialog-desc\"\n >\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3 class=\"modal-title\" id=\"bulk-action-dialog-title\">\n @if (bulkActionType === 'delete') {\n <i class=\"fa-solid fa-exclamation-triangle text-danger\" aria-hidden=\"true\"></i>\n } @else if (bulkActionType === 'enable') {\n <i class=\"fa-solid fa-toggle-on text-success\" aria-hidden=\"true\"></i>\n } @else {\n <i class=\"fa-solid fa-toggle-off text-warning\" aria-hidden=\"true\"></i>\n }\n {{ getBulkActionTitle() }}\n </h3>\n <button\n class=\"modal-close\"\n (click)=\"cancelBulkAction()\"\n aria-label=\"Close dialog\"\n >\n <i class=\"fa-solid fa-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"modal-body\" id=\"bulk-action-dialog-desc\">\n <p>{{ getBulkActionMessage() }}</p>\n @if (bulkActionType === 'delete') {\n <p class=\"text-muted\">This action cannot be undone.</p>\n }\n </div>\n <div class=\"modal-footer\">\n <button\n [class]=\"bulkActionType === 'delete' ? 'mj-btn mj-btn-danger' : 'mj-btn mj-btn-primary'\"\n (click)=\"executeBulkAction()\"\n [disabled]=\"isLoading\"\n >\n @if (isLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n Processing...\n } @else {\n @if (bulkActionType === 'delete') {\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n } @else if (bulkActionType === 'enable') {\n <i class=\"fa-solid fa-toggle-on\" aria-hidden=\"true\"></i>\n } @else {\n <i class=\"fa-solid fa-toggle-off\" aria-hidden=\"true\"></i>\n }\n {{ getBulkActionButtonText() }}\n }\n </button>\n <button class=\"mj-btn mj-btn-secondary\" (click)=\"cancelBulkAction()\" [disabled]=\"isLoading\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n\n <!-- Bulk Role Assignment Dialog -->\n @if (showBulkRoleAssign) {\n <div\n class=\"modal-backdrop\"\n (click)=\"cancelBulkRoleAssign()\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"bulk-role-dialog-title\"\n aria-describedby=\"bulk-role-dialog-desc\"\n >\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3 class=\"modal-title\" id=\"bulk-role-dialog-title\">\n <i class=\"fa-solid fa-user-tag\" aria-hidden=\"true\"></i>\n Assign Role to {{ selectedCount }} User{{ selectedCount > 1 ? 's' : '' }}\n </h3>\n <button\n class=\"modal-close\"\n (click)=\"cancelBulkRoleAssign()\"\n aria-label=\"Close dialog\"\n >\n <i class=\"fa-solid fa-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"modal-body\" id=\"bulk-role-dialog-desc\">\n <p>Select a role to assign to the selected users:</p>\n <div class=\"form-field\">\n <label class=\"field-label\" for=\"bulk-role-select\">Role</label>\n <select\n id=\"bulk-role-select\"\n class=\"field-select\"\n [(ngModel)]=\"bulkRoleId\"\n aria-label=\"Select role to assign\"\n >\n <option value=\"\">Select a role...</option>\n @for (role of roles; track role.ID) {\n <option [value]=\"role.ID\">{{ role.Name }}</option>\n }\n </select>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button\n class=\"mj-btn mj-btn-primary\"\n (click)=\"executeBulkRoleAssign()\"\n [disabled]=\"!bulkRoleId || isLoading\"\n >\n @if (isLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n Assigning...\n } @else {\n <i class=\"fa-solid fa-user-tag\" aria-hidden=\"true\"></i>\n Assign Role\n }\n </button>\n <button class=\"mj-btn mj-btn-secondary\" (click)=\"cancelBulkRoleAssign()\" [disabled]=\"isLoading\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n</div>\n", styles: ["/* =============================================================================\n User Management Component - MD3 Design System\n Unified Expandable Card List Pattern\n ============================================================================= */\n\n/* -----------------------------------------------------------------------------\n MD3 Design Tokens (Local)\n ----------------------------------------------------------------------------- */\n:host {\n /* Primary - Deep Blue */\n --md-primary: #0076B6;\n --md-on-primary: #FFFFFF;\n --md-primary-container: #AAE7FD;\n --md-on-primary-container: #001F2A;\n\n /* Secondary - Light Orange */\n --md-secondary: #F5A623;\n --md-on-secondary: #FFFFFF;\n --md-secondary-container: #FFECD6;\n --md-on-secondary-container: #2D1600;\n\n /* Tertiary - Light Green */\n --md-tertiary: #4CAF50;\n --md-on-tertiary: #FFFFFF;\n --md-tertiary-container: #C8E6C9;\n --md-on-tertiary-container: #002204;\n\n /* Error - Red */\n --md-error: #D32F2F;\n --md-on-error: #FFFFFF;\n --md-error-container: #FFCDD2;\n --md-on-error-container: #410002;\n\n /* Surface Colors */\n --md-surface: #FAFCFF;\n --md-surface-container-lowest: #FFFFFF;\n --md-surface-container-low: #F3F5F9;\n --md-surface-container: #EDF0F4;\n --md-surface-container-high: #E7EAEE;\n --md-surface-container-highest: #E1E3E8;\n --md-on-surface: #191C20;\n --md-on-surface-variant: #43474E;\n --md-outline: #74777F;\n --md-outline-variant: #C4C6D0;\n\n /* Elevation */\n --md-elevation-1: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n --md-elevation-2: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n --md-elevation-3: 0 4px 8px rgba(0, 0, 0, 0.1), 0 8px 16px rgba(0, 0, 0, 0.08);\n --md-elevation-4: 0 6px 12px rgba(0, 0, 0, 0.1), 0 12px 24px rgba(0, 0, 0, 0.08);\n --md-elevation-5: 0 8px 16px rgba(0, 0, 0, 0.12), 0 16px 32px rgba(0, 0, 0, 0.1);\n\n /* Corner Radii */\n --md-corner-extra-small: 4px;\n --md-corner-small: 8px;\n --md-corner-medium: 12px;\n --md-corner-large: 16px;\n --md-corner-extra-large: 28px;\n --md-corner-full: 9999px;\n\n /* Host Layout */\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n overflow: hidden;\n}\n\n/* -----------------------------------------------------------------------------\n Container & Layout\n ----------------------------------------------------------------------------- */\n.user-management-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n position: relative;\n width: 100%;\n background: var(--md-surface);\n}\n\n/* -----------------------------------------------------------------------------\n Sticky Header - Always visible controls\n ----------------------------------------------------------------------------- */\n.sticky-header {\n flex-shrink: 0;\n background: var(--md-surface);\n border-bottom: 1px solid var(--md-outline-variant);\n box-shadow: var(--md-elevation-1);\n z-index: 10;\n}\n\n/* -----------------------------------------------------------------------------\n Scrollable Content - Users list area\n ----------------------------------------------------------------------------- */\n.scrollable-content {\n flex: 1;\n overflow-y: auto;\n overflow-x: hidden;\n -webkit-overflow-scrolling: touch;\n padding: 1rem;\n background: var(--md-surface-container-lowest);\n}\n\n@media (min-width: 768px) {\n .scrollable-content {\n padding: 1.5rem 2rem;\n }\n}\n\n@media (min-width: 1024px) {\n .scrollable-content {\n padding: 2rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Action Buttons (In Sticky Header)\n ----------------------------------------------------------------------------- */\n.action-buttons {\n flex-shrink: 0;\n display: flex;\n gap: 0.75rem;\n justify-content: flex-end;\n padding: 0.75rem 1rem;\n background: var(--md-surface);\n}\n\n@media (min-width: 768px) {\n .action-buttons {\n padding: 1rem 1.5rem;\n }\n}\n\n@media (max-width: 639px) {\n .action-buttons {\n justify-content: center;\n flex-wrap: wrap;\n }\n\n .mj-btn-icon-mobile .btn-text {\n display: none;\n }\n\n .mj-btn-icon-mobile {\n width: 48px;\n height: 48px;\n padding: 0;\n border-radius: var(--md-corner-full);\n min-width: 48px;\n min-height: 48px;\n }\n\n .mj-btn-icon-mobile i {\n font-size: 1.25rem;\n }\n\n .mj-btn-primary.mj-btn-icon-mobile {\n box-shadow: var(--md-elevation-2);\n }\n\n .mj-btn-primary.mj-btn-icon-mobile:hover {\n box-shadow: var(--md-elevation-3);\n transform: scale(1.05);\n }\n\n .mj-btn-secondary.mj-btn-icon-mobile {\n background: var(--md-surface);\n border: 1px solid var(--md-outline);\n }\n\n .mj-btn-secondary.mj-btn-icon-mobile:hover {\n background: var(--md-primary);\n color: var(--md-on-primary);\n border-color: var(--md-primary);\n }\n}\n\n/* -----------------------------------------------------------------------------\n Bulk Action Toolbar\n ----------------------------------------------------------------------------- */\n.bulk-action-toolbar {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n background: var(--md-primary-container);\n border-bottom: 1px solid var(--md-outline-variant);\n animation: slideDown 0.2s ease;\n}\n\n@media (min-width: 768px) {\n .bulk-action-toolbar {\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n padding: 1rem 1.5rem;\n }\n}\n\n.bulk-selection-info {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--md-on-primary-container);\n}\n\n.bulk-selection-info i {\n font-size: 1.25rem;\n}\n\n.bulk-action-buttons {\n display: flex;\n gap: 0.5rem;\n flex-wrap: wrap;\n}\n\n@media (max-width: 639px) {\n .bulk-action-buttons .btn-text {\n display: none;\n }\n\n .bulk-action-buttons .mj-btn-sm {\n padding: 0.5rem;\n min-width: 36px;\n }\n}\n\n@keyframes slideDown {\n from {\n transform: translateY(-10px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Statistics Cards - Static Display (Non-interactive)\n ----------------------------------------------------------------------------- */\n.mj-grid-4 {\n display: none;\n grid-template-columns: repeat(2, 1fr);\n gap: 0.5rem;\n padding: 0 1rem 0.75rem 1rem;\n background: var(--md-surface);\n}\n\n@media (min-width: 768px) {\n .mj-grid-4 {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n padding: 0 1.5rem 1rem 1.5rem;\n gap: 0.75rem;\n }\n}\n\n@media (min-width: 1024px) {\n .mj-grid-4 {\n gap: 1rem;\n }\n}\n\n/* Static Card - No hover effects */\n.mj-card {\n background: var(--md-surface-container-low);\n border-radius: var(--md-corner-medium);\n padding: 1rem;\n box-shadow: none;\n display: flex;\n align-items: center;\n gap: 1rem;\n border: 1px solid var(--md-outline-variant);\n cursor: default;\n pointer-events: none;\n}\n\n@media (min-width: 768px) {\n .mj-card {\n padding: 1rem 1.25rem;\n }\n}\n\n.stat-icon {\n width: 48px;\n height: 48px;\n border-radius: var(--md-corner-medium);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 1.25rem;\n flex-shrink: 0;\n}\n\n@media (min-width: 768px) {\n .stat-icon {\n width: 48px;\n height: 48px;\n font-size: 1.25rem;\n }\n}\n\n.stat-icon-total {\n background: var(--md-primary-container);\n color: var(--md-primary);\n}\n\n.stat-icon-active {\n background: var(--md-tertiary-container);\n color: var(--md-tertiary);\n}\n\n.stat-icon-inactive {\n background: var(--md-error-container);\n color: var(--md-error);\n}\n\n.stat-icon-admin {\n background: var(--md-secondary-container);\n color: #B5751A;\n}\n\n.stat-content {\n flex: 1;\n min-width: 0;\n}\n\n.stat-content .stat-value {\n font-size: 1.75rem;\n font-weight: 700;\n color: var(--md-on-surface);\n line-height: 1;\n letter-spacing: -0.02em;\n}\n\n@media (min-width: 768px) {\n .stat-content .stat-value {\n font-size: 2rem;\n }\n}\n\n.stat-content .stat-label {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--md-on-surface-variant);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin-top: 0.25rem;\n}\n\n@media (min-width: 768px) {\n .stat-content .stat-label {\n font-size: 0.8125rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Filters Section\n ----------------------------------------------------------------------------- */\n.filters-section {\n flex-shrink: 0;\n background: var(--md-surface-container);\n margin: 0 1rem 0.75rem 1rem;\n padding: 0.75rem;\n border-radius: var(--md-corner-medium);\n border: 1px solid var(--md-outline-variant);\n}\n\n@media (min-width: 768px) {\n .filters-section {\n margin: 0 1.5rem 1rem 1.5rem;\n padding: 1rem 1.25rem;\n }\n}\n\n.filters-row {\n display: flex;\n gap: 1rem;\n align-items: flex-end;\n flex-wrap: wrap;\n}\n\n@media (min-width: 768px) {\n .filters-row {\n gap: 1.5rem;\n }\n}\n\n@media (max-width: 767px) {\n .filters-section {\n padding: 0.75rem;\n }\n\n .filters-row {\n display: flex;\n flex-direction: row;\n gap: 0.75rem;\n align-items: center;\n }\n\n .filters-row .mj-search {\n flex: 1;\n min-width: 0;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Search Input\n ----------------------------------------------------------------------------- */\n.mj-search {\n position: relative;\n flex: 1;\n min-width: 200px;\n max-width: 100%;\n}\n\n@media (min-width: 640px) {\n .mj-search {\n min-width: 280px;\n max-width: 500px;\n }\n}\n\n@media (min-width: 768px) {\n .mj-search {\n min-width: 320px;\n max-width: 600px;\n }\n}\n\n@media (max-width: 767px) {\n .mj-search {\n width: 100%;\n max-width: none;\n min-width: 0;\n }\n}\n\n.mj-search .mj-search-icon {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: var(--md-on-surface-variant);\n font-size: 1rem;\n pointer-events: none;\n transition: color 0.2s ease;\n}\n\n.mj-search .mj-search-input {\n width: 100%;\n padding: 0.875rem 1rem 0.875rem 2.75rem;\n border: 2px solid var(--md-outline-variant);\n border-radius: var(--md-corner-full);\n font-size: 1rem;\n background: var(--md-surface);\n color: var(--md-on-surface);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 48px;\n}\n\n@media (min-width: 768px) {\n .mj-search .mj-search-input {\n padding: 1rem 1.25rem 1rem 3rem;\n min-height: 52px;\n font-size: 1.0625rem;\n }\n\n .mj-search .mj-search-icon {\n left: 1.125rem;\n font-size: 1.125rem;\n }\n}\n\n.mj-search .mj-search-input::placeholder {\n color: var(--md-on-surface-variant);\n}\n\n.mj-search .mj-search-input:hover {\n border-color: var(--md-primary);\n background: var(--md-surface-container-lowest);\n}\n\n.mj-search .mj-search-input:focus {\n outline: none;\n border-color: var(--md-primary);\n box-shadow: 0 0 0 3px rgba(0, 118, 182, 0.2);\n background: var(--md-surface);\n}\n\n.mj-search:focus-within .mj-search-icon {\n color: var(--md-primary);\n}\n\n/* -----------------------------------------------------------------------------\n Mobile Filter Toggle Button\n ----------------------------------------------------------------------------- */\n.mobile-filter-toggle {\n display: none;\n align-items: center;\n justify-content: center;\n position: relative;\n width: 48px;\n height: 48px;\n min-width: 48px;\n border: 1px solid var(--md-outline-variant);\n border-radius: var(--md-corner-small);\n background: var(--md-surface-container-low);\n color: var(--md-on-surface-variant);\n font-size: 1.125rem;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n box-shadow: var(--md-elevation-1);\n flex-shrink: 0;\n}\n\n.mobile-filter-toggle:hover {\n background: var(--md-surface-container);\n border-color: var(--md-primary);\n color: var(--md-primary);\n}\n\n.mobile-filter-toggle.active {\n background: var(--md-primary);\n color: var(--md-on-primary);\n border-color: var(--md-primary);\n}\n\n.filter-badge {\n position: absolute;\n top: -4px;\n right: -4px;\n min-width: 18px;\n height: 18px;\n padding: 0 5px;\n border-radius: var(--md-corner-full);\n background: var(--md-error);\n color: var(--md-on-error);\n font-size: 0.6875rem;\n font-weight: 700;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n}\n\n/* -----------------------------------------------------------------------------\n Mobile Filter Dropdown Panel\n ----------------------------------------------------------------------------- */\n.mobile-filter-dropdown {\n display: none;\n margin-top: 0.75rem;\n padding-top: 0.75rem;\n border-top: 1px solid var(--md-outline-variant);\n animation: slideDown 0.2s ease;\n}\n\n/* Mobile only - show filter toggle and dropdown */\n@media (max-width: 767px) {\n .mobile-filter-toggle {\n display: flex !important;\n }\n\n .mobile-filter-dropdown {\n display: block;\n }\n\n .desktop-filter-group {\n display: none !important;\n }\n}\n\n.mobile-filter-content {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.mobile-filter-content .mj-filter-group {\n width: 100%;\n}\n\n.mobile-filter-content .mj-filter-select {\n width: 100%;\n}\n\n.clear-filters-btn {\n align-self: flex-start;\n margin-top: 0.25rem;\n}\n\n/* -----------------------------------------------------------------------------\n Filter Controls - Mobile/Desktop visibility\n ----------------------------------------------------------------------------- */\n\n/* Desktop filter groups - hidden by default, shown on desktop */\n.desktop-filter-group {\n display: none !important;\n}\n\n/* Desktop only - show filter groups, hide mobile toggle */\n@media screen and (min-width: 768px) {\n .desktop-filter-group {\n display: flex !important;\n flex-direction: column;\n gap: 0.375rem;\n }\n\n .mobile-filter-toggle {\n display: none !important;\n }\n\n .mobile-filter-dropdown {\n display: none !important;\n }\n}\n\n.mj-filter-group {\n display: flex;\n flex-direction: column;\n gap: 0.375rem;\n}\n\n@media (max-width: 767px) {\n .mj-filter-group {\n flex: 1;\n min-width: 100px;\n }\n}\n\n.mj-filter-label {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--md-on-surface);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.mj-filter-buttons {\n display: flex;\n background: var(--md-surface-container);\n border-radius: var(--md-corner-full);\n padding: 4px;\n gap: 2px;\n}\n\n.mj-filter-buttons .mj-btn {\n border-radius: var(--md-corner-full);\n}\n\n.mj-filter-buttons .mj-btn-primary {\n background-color: var(--md-primary);\n color: var(--md-on-primary);\n box-shadow: var(--md-elevation-1);\n}\n\n.mj-filter-select {\n padding: 0.625rem 1rem;\n border: 1px solid var(--md-outline-variant);\n border-radius: var(--md-corner-small);\n background: var(--md-surface-container-low);\n font-size: 0.875rem;\n font-weight: 500;\n color: var(--md-on-surface);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 120px;\n box-shadow: var(--md-elevation-1);\n}\n\n.mj-filter-select:hover {\n background: var(--md-surface-container);\n border-color: var(--md-primary);\n}\n\n@media (max-width: 767px) {\n .mj-filter-select {\n width: 100%;\n padding: 0.5rem 0.75rem;\n font-size: 0.8125rem;\n }\n}\n\n.mj-filter-select:focus {\n outline: none;\n border-color: var(--md-primary);\n box-shadow: 0 0 0 3px rgba(0, 118, 182, 0.2);\n}\n\n/* -----------------------------------------------------------------------------\n Content Area\n ----------------------------------------------------------------------------- */\n.content-area {\n flex: 1 1 auto;\n overflow: visible;\n position: relative;\n background: var(--md-surface);\n border-radius: var(--md-corner-large);\n box-shadow: var(--md-elevation-1);\n padding: 1rem;\n border: 1px solid var(--md-outline-variant);\n}\n\n@media (min-width: 768px) {\n .content-area {\n padding: 1.5rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Users List - Unified Expandable Card Pattern\n ----------------------------------------------------------------------------- */\n.users-list {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n/* List Header with Select All */\n.list-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.75rem 1rem;\n background: var(--md-surface-container);\n border-radius: var(--md-corner-small);\n border: 1px solid var(--md-outline-variant);\n margin-bottom: 0.5rem;\n}\n\n.select-all-label {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n cursor: pointer;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--md-on-surface);\n}\n\n.select-all-text {\n font-weight: 500;\n}\n\n.selection-count {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--md-primary);\n background: var(--md-primary-container);\n padding: 0.25rem 0.75rem;\n border-radius: var(--md-corner-full);\n}\n\n/* User Card - Interactive */\n.user-card {\n background: var(--md-surface);\n border: 1px solid var(--md-outline-variant);\n border-radius: var(--md-corner-large);\n overflow: hidden;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.user-card:hover {\n box-shadow: var(--md-elevation-2);\n border-color: var(--md-primary);\n}\n\n.user-card.expanded {\n box-shadow: var(--md-elevation-3);\n border-color: var(--md-primary);\n}\n\n.user-card.selected {\n background: var(--md-primary-container);\n border-color: var(--md-primary);\n}\n\n.user-card.selected .user-header {\n background: transparent;\n}\n\n.user-card.selected:hover .user-header {\n background: rgba(0, 118, 182, 0.08);\n}\n\n/* User Card Header */\n.user-header {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 1.25rem 1.5rem;\n cursor: pointer;\n background: var(--md-surface-container-lowest);\n transition: background-color 0.2s ease;\n}\n\n.user-header:hover {\n background: var(--md-surface-container-low);\n}\n\n@media (max-width: 639px) {\n .user-header {\n padding: 0.875rem 1rem;\n gap: 0.625rem;\n }\n}\n\n/* User Selection */\n.user-selection {\n flex-shrink: 0;\n}\n\n.checkbox {\n width: 20px;\n height: 20px;\n cursor: pointer;\n accent-color: var(--md-primary);\n}\n\n/* User Info */\n.user-info {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n flex: 1;\n min-width: 0;\n}\n\n.user-avatar {\n width: 48px;\n height: 48px;\n border-radius: var(--md-corner-full);\n background: linear-gradient(135deg, var(--md-primary) 0%, #3395C8 100%);\n color: var(--md-on-primary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 0.875rem;\n font-weight: 600;\n flex-shrink: 0;\n}\n\n@media (max-width: 639px) {\n .user-avatar {\n width: 40px;\n height: 40px;\n font-size: 0.8125rem;\n }\n\n .user-details {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n }\n\n .user-name {\n font-size: 0.9375rem;\n font-weight: 600;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .user-email {\n font-size: 0.8125rem;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n}\n\n.user-details {\n flex: 1;\n min-width: 0;\n}\n\n.user-name {\n font-size: 1rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.user-email {\n font-size: 0.875rem;\n color: var(--md-on-surface-variant);\n margin: 0.125rem 0 0 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* User Meta */\n.user-meta {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n flex-shrink: 0;\n}\n\n@media (max-width: 767px) {\n .user-meta .status-badge,\n .user-meta .user-actions {\n display: none !important;\n }\n\n .user-meta {\n gap: 0;\n }\n}\n\n/* Desktop Actions */\n.desktop-only {\n display: none;\n}\n\n@media (min-width: 768px) {\n .desktop-only {\n display: flex;\n gap: 0.25rem;\n }\n}\n\n.user-actions {\n display: flex;\n gap: 0.25rem;\n}\n\n/* Expand Button */\n.expand-btn {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--md-on-surface-variant);\n font-size: 1rem;\n cursor: pointer;\n transition: all 0.2s ease;\n border-radius: var(--md-corner-full);\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.expand-btn:hover {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.expand-btn i {\n transition: transform 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n.user-card.expanded .expand-btn i {\n transform: rotate(180deg);\n}\n\n/* User Card Content - Expanded */\n.user-content {\n padding: 1.25rem 1.5rem;\n background: var(--md-surface);\n border-top: 1px solid var(--md-outline-variant);\n animation: slideDown 0.3s cubic-bezier(0, 0, 0.2, 1);\n}\n\n/* Mobile Actions Bar */\n.mobile-actions-bar {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-bottom: 1rem;\n margin-bottom: 1rem;\n border-bottom: 1px solid var(--md-outline-variant);\n}\n\n@media (min-width: 768px) {\n .mobile-actions-bar {\n display: none;\n }\n}\n\n.mobile-action-buttons {\n display: flex;\n gap: 0.5rem;\n}\n\n.mobile-action-buttons .btn-label {\n margin-left: 0.375rem;\n}\n\n/* Status Badge */\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.875rem;\n border-radius: var(--md-corner-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n.status-badge.status-active {\n background: var(--md-tertiary-container);\n color: #1B5E20;\n border: 1px solid var(--md-tertiary);\n}\n\n.status-badge.status-inactive {\n background: var(--md-error-container);\n color: var(--md-on-error-container);\n border: 1px solid var(--md-error);\n}\n\n.status-badge i {\n font-size: 0.625rem;\n}\n\n/* User Stats in Expanded Content */\n.user-stats {\n display: flex;\n flex-wrap: wrap;\n gap: 1rem;\n margin-bottom: 1rem;\n}\n\n.user-stats .stat-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.875rem;\n color: var(--md-on-surface-variant);\n}\n\n.user-stats .stat-item i {\n color: var(--md-primary);\n font-size: 0.875rem;\n}\n\n.user-stats .stat-label {\n color: var(--md-on-surface-variant);\n}\n\n.user-stats .stat-value {\n color: var(--md-on-surface);\n font-weight: 500;\n display: flex;\n align-items: center;\n gap: 0.25rem;\n}\n\n.user-stats .stat-value i {\n font-size: 0.75rem;\n}\n\n/* Roles Section */\n.roles-section {\n padding-top: 1rem;\n border-top: 1px solid var(--md-outline-variant);\n}\n\n.section-title {\n display: flex;\n align-items: center;\n gap: 0.625rem;\n font-size: 1rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0 0 0.75rem 0;\n}\n\n.section-title i {\n color: var(--md-primary);\n font-size: 1.125rem;\n}\n\n.roles-grid {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n}\n\n.role-item {\n display: inline-flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.875rem;\n background: var(--md-secondary-container);\n color: #7A4D0C;\n border: 1px solid var(--md-secondary);\n border-radius: var(--md-corner-full);\n font-size: 0.75rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n}\n\n.role-item i {\n font-size: 0.625rem;\n}\n\n.no-roles {\n font-size: 0.875rem;\n color: var(--md-on-surface-variant);\n margin: 0;\n}\n\n/* -----------------------------------------------------------------------------\n Empty State\n ----------------------------------------------------------------------------- */\n.empty-state {\n text-align: center;\n padding: 4rem 2rem;\n}\n\n.empty-state .empty-icon {\n font-size: 4rem;\n color: var(--md-outline-variant);\n margin-bottom: 1.5rem;\n}\n\n.empty-state .empty-text {\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0 0 0.5rem 0;\n}\n\n.empty-state .empty-subtext {\n font-size: 1rem;\n color: var(--md-on-surface-variant);\n margin: 0;\n}\n\n/* -----------------------------------------------------------------------------\n Loading State\n ----------------------------------------------------------------------------- */\n.loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n}\n\n/* -----------------------------------------------------------------------------\n Error State\n ----------------------------------------------------------------------------- */\n.error-container {\n text-align: center;\n padding: 4rem 2rem;\n}\n\n.error-container .error-content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.error-container .error-icon {\n font-size: 3.5rem;\n color: var(--md-error);\n margin-bottom: 1rem;\n}\n\n.error-container .error-message {\n font-size: 1.0625rem;\n color: var(--md-on-surface);\n margin: 0 0 1.5rem 0;\n}\n\n.error-container .retry-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n font-size: 0.875rem;\n font-weight: 600;\n border: none;\n border-radius: var(--md-corner-full);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n background: var(--md-primary);\n color: var(--md-on-primary);\n box-shadow: var(--md-elevation-1);\n min-height: 44px;\n}\n\n.error-container .retry-button:hover {\n background: #3395C8;\n box-shadow: var(--md-elevation-2);\n}\n\n.error-container .retry-button:active {\n background: #4BA5D4;\n transform: scale(0.98);\n}\n\n/* -----------------------------------------------------------------------------\n Modal Dialog\n ----------------------------------------------------------------------------- */\n.modal-backdrop {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 1000;\n padding: 1rem;\n animation: fadeIn 0.2s ease;\n}\n\n.modal-dialog {\n background: var(--md-surface);\n border-radius: var(--md-corner-extra-large);\n box-shadow: var(--md-elevation-5);\n max-width: 500px;\n width: 100%;\n max-height: 90vh;\n overflow: hidden;\n animation: slideUp 0.3s ease;\n}\n\n.modal-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 1.5rem;\n border-bottom: 1px solid var(--md-outline-variant);\n}\n\n.modal-header .modal-title {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n font-size: 1.375rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0;\n}\n\n.modal-header .modal-close {\n padding: 0.625rem;\n border: none;\n background: transparent;\n color: var(--md-on-surface-variant);\n font-size: 1.25rem;\n cursor: pointer;\n border-radius: var(--md-corner-full);\n min-width: 44px;\n min-height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n}\n\n.modal-header .modal-close:hover {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.modal-body {\n padding: 1.5rem;\n}\n\n.modal-body p {\n font-size: 1rem;\n color: var(--md-on-surface);\n margin: 0 0 1rem 0;\n line-height: 1.5;\n}\n\n.modal-body p:last-child {\n margin-bottom: 0;\n}\n\n.modal-body .text-muted {\n font-size: 0.875rem;\n color: var(--md-on-surface-variant);\n}\n\n.modal-footer {\n display: flex;\n justify-content: flex-start;\n gap: 0.75rem;\n padding: 1.5rem;\n border-top: 1px solid var(--md-outline-variant);\n background: var(--md-surface-container-low);\n}\n\n@media (max-width: 639px) {\n .modal-dialog {\n width: 95%;\n max-height: 85vh;\n }\n\n .modal-header {\n padding: 1rem;\n }\n\n .modal-header .modal-title {\n font-size: 1.125rem;\n }\n\n .modal-body {\n padding: 1rem;\n }\n\n .modal-body p {\n font-size: 0.9375rem;\n }\n\n .modal-footer {\n padding: 1rem;\n flex-wrap: wrap;\n }\n\n .modal-footer .mj-btn {\n flex: 1;\n min-width: 100px;\n }\n}\n\n/* Form Field in Modal */\n.form-field {\n margin-bottom: 1rem;\n}\n\n.form-field .field-label {\n display: block;\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--md-on-surface);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n margin-bottom: 0.5rem;\n}\n\n.form-field .field-select {\n width: 100%;\n padding: 0.75rem 1rem;\n border: 1px solid var(--md-outline);\n border-radius: var(--md-corner-small);\n background: var(--md-surface);\n font-size: 1rem;\n color: var(--md-on-surface);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.form-field .field-select:focus {\n outline: none;\n border-color: var(--md-primary);\n box-shadow: 0 0 0 3px rgba(0, 118, 182, 0.2);\n}\n\n/* -----------------------------------------------------------------------------\n MJ Button System - MD3 Compliant\n ----------------------------------------------------------------------------- */\n.mj-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n font-size: 0.875rem;\n font-weight: 600;\n border: none;\n border-radius: var(--md-corner-full);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n white-space: nowrap;\n min-height: 44px;\n}\n\n.mj-btn:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n/* Primary Button - Dark, lightens on hover */\n.mj-btn-primary {\n background: var(--md-primary);\n color: var(--md-on-primary);\n box-shadow: var(--md-elevation-1);\n}\n\n.mj-btn-primary:hover:not(:disabled) {\n background: #3395C8;\n box-shadow: var(--md-elevation-2);\n}\n\n.mj-btn-primary:active:not(:disabled) {\n background: #4BA5D4;\n transform: scale(0.98);\n}\n\n/* Secondary Button - Light, fills with primary on hover */\n.mj-btn-secondary {\n background: var(--md-surface);\n color: var(--md-primary);\n border: 1px solid var(--md-outline);\n}\n\n.mj-btn-secondary:hover:not(:disabled) {\n background: var(--md-primary);\n color: var(--md-on-primary);\n border-color: var(--md-primary);\n}\n\n.mj-btn-secondary:active:not(:disabled) {\n background: #005A8C;\n border-color: #005A8C;\n}\n\n/* Ghost Button - Transparent, fills with primary on hover */\n.mj-btn-ghost {\n background: transparent;\n color: var(--md-on-surface-variant);\n}\n\n.mj-btn-ghost:hover:not(:disabled) {\n background: var(--md-primary);\n color: var(--md-on-primary);\n}\n\n.mj-btn-ghost:active:not(:disabled) {\n background: #005A8C;\n}\n\n/* Danger Button - Dark red, lightens on hover */\n.mj-btn-danger {\n background: var(--md-error);\n color: var(--md-on-error);\n box-shadow: var(--md-elevation-1);\n}\n\n.mj-btn-danger:hover:not(:disabled) {\n background: #E57373;\n box-shadow: var(--md-elevation-2);\n}\n\n.mj-btn-danger:active:not(:disabled) {\n background: #EF9A9A;\n transform: scale(0.98);\n}\n\n/* Small Button */\n.mj-btn-sm {\n padding: 0.5rem 0.875rem;\n font-size: 0.8125rem;\n min-height: 36px;\n}\n\n/* Ghost Danger Button */\n.mj-btn-ghost.mj-btn-danger {\n background: transparent;\n color: var(--md-error);\n box-shadow: none;\n}\n\n.mj-btn-ghost.mj-btn-danger:hover:not(:disabled) {\n background: var(--md-error-container);\n color: var(--md-error);\n}\n\n/* -----------------------------------------------------------------------------\n Utility Classes\n ----------------------------------------------------------------------------- */\n.text-danger {\n color: var(--md-error);\n}\n\n.text-success {\n color: var(--md-tertiary);\n}\n\n.text-warning {\n color: var(--md-secondary);\n}\n\n/* -----------------------------------------------------------------------------\n Animations\n ----------------------------------------------------------------------------- */\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n@keyframes slideUp {\n from {\n transform: translateY(20px);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Accessibility: Focus Indicators\n ----------------------------------------------------------------------------- */\n.mj-search-input:focus-visible,\n.mj-filter-select:focus-visible,\nbutton:focus-visible,\n.checkbox:focus-visible,\n.user-header:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\n}\n\n/* -----------------------------------------------------------------------------\n Accessibility: Reduced Motion\n ----------------------------------------------------------------------------- */\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Large Desktop (1440px+)\n ----------------------------------------------------------------------------- */\n@media (min-width: 1440px) {\n .user-management-container {\n max-width: 1920px;\n margin: 0 auto;\n }\n\n .action-buttons {\n padding: 1.25rem 2rem;\n }\n\n .bulk-action-toolbar {\n padding: 1.25rem 2rem;\n }\n\n .mj-grid-4 {\n gap: 1.5rem;\n padding: 0 2rem 1rem 2rem;\n }\n\n .filters-section {\n margin: 0 2rem 1rem 2rem;\n padding: 1rem 1.5rem;\n }\n\n .scrollable-content {\n padding: 2rem;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Mobile (< 640px) - Compact adjustments\n ----------------------------------------------------------------------------- */\n@media (max-width: 639px) {\n .sticky-header {\n padding-bottom: 0;\n }\n\n .mj-grid-4 {\n grid-template-columns: repeat(2, 1fr);\n gap: 0.5rem;\n padding: 0 0.75rem 0.5rem 0.75rem;\n }\n\n .mj-card {\n padding: 0.75rem;\n gap: 0.75rem;\n }\n\n .stat-icon {\n width: 40px;\n height: 40px;\n font-size: 1.125rem;\n }\n\n .stat-content .stat-value {\n font-size: 1.5rem;\n }\n\n .stat-content .stat-label {\n font-size: 0.6875rem;\n }\n\n .filters-section {\n margin: 0 0.75rem 0.5rem 0.75rem;\n padding: 0.75rem;\n }\n\n .scrollable-content {\n padding: 0.75rem;\n }\n\n .content-area {\n padding: 0.875rem;\n border-radius: var(--md-corner-medium);\n }\n\n .list-header {\n padding: 0.625rem 0.75rem;\n }\n\n .empty-state {\n padding: 2rem 1rem;\n }\n\n .empty-state .empty-icon {\n font-size: 3rem;\n }\n\n .empty-state .empty-text {\n font-size: 1.0625rem;\n }\n\n .empty-state .empty-subtext {\n font-size: 0.875rem;\n }\n}\n"] }]
764
1289
  }], () => [], null); })();
765
1290
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(UserManagementComponent, { className: "UserManagementComponent", filePath: "src/lib/user-management/user-management.component.ts", lineNumber: 29 }); })();
766
1291
  //# sourceMappingURL=user-management.component.js.map