@memberjunction/ng-explorer-settings 3.2.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/application-management/application-dialog/application-dialog.component.d.ts +15 -1
- package/dist/lib/application-management/application-dialog/application-dialog.component.d.ts.map +1 -1
- package/dist/lib/application-management/application-dialog/application-dialog.component.js +329 -190
- package/dist/lib/application-management/application-dialog/application-dialog.component.js.map +1 -1
- package/dist/lib/application-management/application-management.component.d.ts.map +1 -1
- package/dist/lib/application-management/application-management.component.js +265 -184
- package/dist/lib/application-management/application-management.component.js.map +1 -1
- package/dist/lib/entity-permissions/entity-permissions.component.d.ts +1 -0
- package/dist/lib/entity-permissions/entity-permissions.component.d.ts.map +1 -1
- package/dist/lib/entity-permissions/entity-permissions.component.js +369 -192
- package/dist/lib/entity-permissions/entity-permissions.component.js.map +1 -1
- package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.d.ts.map +1 -1
- package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js +160 -143
- package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js.map +1 -1
- package/dist/lib/module.d.ts +20 -25
- package/dist/lib/module.d.ts.map +1 -1
- package/dist/lib/module.js +20 -44
- package/dist/lib/module.js.map +1 -1
- package/dist/lib/notification-preferences/notification-preferences.component.d.ts +77 -0
- package/dist/lib/notification-preferences/notification-preferences.component.d.ts.map +1 -1
- package/dist/lib/notification-preferences/notification-preferences.component.js +153 -77
- package/dist/lib/notification-preferences/notification-preferences.component.js.map +1 -1
- package/dist/lib/role-management/role-dialog/role-dialog.component.d.ts.map +1 -1
- package/dist/lib/role-management/role-dialog/role-dialog.component.js +93 -89
- package/dist/lib/role-management/role-dialog/role-dialog.component.js.map +1 -1
- package/dist/lib/role-management/role-management.component.d.ts +1 -0
- package/dist/lib/role-management/role-management.component.d.ts.map +1 -1
- package/dist/lib/role-management/role-management.component.js +275 -158
- package/dist/lib/role-management/role-management.component.js.map +1 -1
- package/dist/lib/settings/settings.component.d.ts +54 -1
- package/dist/lib/settings/settings.component.d.ts.map +1 -1
- package/dist/lib/settings/settings.component.js +528 -182
- package/dist/lib/settings/settings.component.js.map +1 -1
- package/dist/lib/shared/settings-card.component.d.ts.map +1 -1
- package/dist/lib/shared/settings-card.component.js +21 -18
- package/dist/lib/shared/settings-card.component.js.map +1 -1
- package/dist/lib/sql-logging/sql-logging.component.d.ts +12 -3
- package/dist/lib/sql-logging/sql-logging.component.d.ts.map +1 -1
- package/dist/lib/sql-logging/sql-logging.component.js +318 -245
- package/dist/lib/sql-logging/sql-logging.component.js.map +1 -1
- package/dist/lib/user-app-config/user-app-config.component.d.ts +21 -3
- package/dist/lib/user-app-config/user-app-config.component.d.ts.map +1 -1
- package/dist/lib/user-app-config/user-app-config.component.js +202 -147
- package/dist/lib/user-app-config/user-app-config.component.js.map +1 -1
- package/dist/lib/user-management/user-dialog/user-dialog.component.d.ts.map +1 -1
- package/dist/lib/user-management/user-dialog/user-dialog.component.js +120 -116
- package/dist/lib/user-management/user-dialog/user-dialog.component.js.map +1 -1
- package/dist/lib/user-management/user-management.component.d.ts +32 -2
- package/dist/lib/user-management/user-management.component.d.ts.map +1 -1
- package/dist/lib/user-management/user-management.component.js +822 -297
- package/dist/lib/user-management/user-management.component.js.map +1 -1
- package/dist/lib/user-profile-settings/user-profile-settings.component.d.ts +31 -2
- package/dist/lib/user-profile-settings/user-profile-settings.component.d.ts.map +1 -1
- package/dist/lib/user-profile-settings/user-profile-settings.component.js +213 -80
- package/dist/lib/user-profile-settings/user-profile-settings.component.js.map +1 -1
- package/package.json +21 -20
|
@@ -2,6 +2,8 @@ import { Component } from '@angular/core';
|
|
|
2
2
|
import { Metadata } from '@memberjunction/core';
|
|
3
3
|
import { MJGlobal, MJEventType } from '@memberjunction/global';
|
|
4
4
|
import { EventCodes } from '@memberjunction/ng-shared';
|
|
5
|
+
import { BehaviorSubject, Subject } from 'rxjs';
|
|
6
|
+
import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';
|
|
5
7
|
import * as i0 from "@angular/core";
|
|
6
8
|
import * as i1 from "@memberjunction/ng-user-avatar";
|
|
7
9
|
import * as i2 from "@memberjunction/ng-shared";
|
|
@@ -10,13 +12,13 @@ const _forTrack0 = ($index, $item) => $item.name;
|
|
|
10
12
|
function UserProfileSettingsComponent_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
11
13
|
const _r1 = i0.ɵɵgetCurrentView();
|
|
12
14
|
i0.ɵɵelementStart(0, "div", 4);
|
|
13
|
-
i0.ɵɵelement(1, "i",
|
|
15
|
+
i0.ɵɵelement(1, "i", 29);
|
|
14
16
|
i0.ɵɵelementStart(2, "span");
|
|
15
17
|
i0.ɵɵtext(3);
|
|
16
18
|
i0.ɵɵelementEnd();
|
|
17
|
-
i0.ɵɵelementStart(4, "button",
|
|
19
|
+
i0.ɵɵelementStart(4, "button", 30);
|
|
18
20
|
i0.ɵɵlistener("click", function UserProfileSettingsComponent_Conditional_6_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.errorMessage = ""); });
|
|
19
|
-
i0.ɵɵelement(5, "i",
|
|
21
|
+
i0.ɵɵelement(5, "i", 31);
|
|
20
22
|
i0.ɵɵelementEnd()();
|
|
21
23
|
} if (rf & 2) {
|
|
22
24
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
@@ -25,7 +27,7 @@ function UserProfileSettingsComponent_Conditional_6_Template(rf, ctx) { if (rf &
|
|
|
25
27
|
} }
|
|
26
28
|
function UserProfileSettingsComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
27
29
|
i0.ɵɵelementStart(0, "div", 5);
|
|
28
|
-
i0.ɵɵelement(1, "i",
|
|
30
|
+
i0.ɵɵelement(1, "i", 32);
|
|
29
31
|
i0.ɵɵelementStart(2, "span");
|
|
30
32
|
i0.ɵɵtext(3, "Avatar updated successfully!");
|
|
31
33
|
i0.ɵɵelementEnd()();
|
|
@@ -38,7 +40,7 @@ function UserProfileSettingsComponent_Conditional_12_Template(rf, ctx) { if (rf
|
|
|
38
40
|
} }
|
|
39
41
|
function UserProfileSettingsComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
|
|
40
42
|
i0.ɵɵelementStart(0, "div", 10);
|
|
41
|
-
i0.ɵɵelement(1, "i");
|
|
43
|
+
i0.ɵɵelement(1, "i", 33);
|
|
42
44
|
i0.ɵɵelementEnd();
|
|
43
45
|
} if (rf & 2) {
|
|
44
46
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
@@ -47,21 +49,21 @@ function UserProfileSettingsComponent_Conditional_13_Template(rf, ctx) { if (rf
|
|
|
47
49
|
} }
|
|
48
50
|
function UserProfileSettingsComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
|
|
49
51
|
i0.ɵɵelementStart(0, "div", 11);
|
|
50
|
-
i0.ɵɵelement(1, "i",
|
|
52
|
+
i0.ɵɵelement(1, "i", 34);
|
|
51
53
|
i0.ɵɵelementStart(2, "span");
|
|
52
54
|
i0.ɵɵtext(3, "No avatar selected");
|
|
53
55
|
i0.ɵɵelementEnd()();
|
|
54
56
|
} }
|
|
55
57
|
function UserProfileSettingsComponent_Conditional_33_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
56
58
|
const _r5 = i0.ɵɵgetCurrentView();
|
|
57
|
-
i0.ɵɵelementStart(0, "div",
|
|
58
|
-
i0.ɵɵelement(1, "i",
|
|
59
|
+
i0.ɵɵelementStart(0, "div", 39);
|
|
60
|
+
i0.ɵɵelement(1, "i", 40);
|
|
59
61
|
i0.ɵɵelementStart(2, "span");
|
|
60
62
|
i0.ɵɵtext(3);
|
|
61
63
|
i0.ɵɵelementEnd();
|
|
62
|
-
i0.ɵɵelementStart(4, "button",
|
|
64
|
+
i0.ɵɵelementStart(4, "button", 41);
|
|
63
65
|
i0.ɵɵlistener("click", function UserProfileSettingsComponent_Conditional_33_Conditional_9_Template_button_click_4_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.clearUpload()); });
|
|
64
|
-
i0.ɵɵelement(5, "i",
|
|
66
|
+
i0.ɵɵelement(5, "i", 31);
|
|
65
67
|
i0.ɵɵelementEnd()();
|
|
66
68
|
} if (rf & 2) {
|
|
67
69
|
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
@@ -70,19 +72,19 @@ function UserProfileSettingsComponent_Conditional_33_Conditional_9_Template(rf,
|
|
|
70
72
|
} }
|
|
71
73
|
function UserProfileSettingsComponent_Conditional_33_Template(rf, ctx) { if (rf & 1) {
|
|
72
74
|
const _r3 = i0.ɵɵgetCurrentView();
|
|
73
|
-
i0.ɵɵelementStart(0, "div",
|
|
75
|
+
i0.ɵɵelementStart(0, "div", 22)(1, "input", 35, 0);
|
|
74
76
|
i0.ɵɵlistener("change", function UserProfileSettingsComponent_Conditional_33_Template_input_change_1_listener($event) { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onFileSelected($event)); });
|
|
75
77
|
i0.ɵɵelementEnd();
|
|
76
|
-
i0.ɵɵelementStart(3, "button",
|
|
78
|
+
i0.ɵɵelementStart(3, "button", 36);
|
|
77
79
|
i0.ɵɵlistener("click", function UserProfileSettingsComponent_Conditional_33_Template_button_click_3_listener() { i0.ɵɵrestoreView(_r3); const fileInput_r4 = i0.ɵɵreference(2); return i0.ɵɵresetView(fileInput_r4.click()); });
|
|
78
80
|
i0.ɵɵelement(4, "i", 14);
|
|
79
81
|
i0.ɵɵtext(5, " Choose Image ");
|
|
80
82
|
i0.ɵɵelementEnd();
|
|
81
|
-
i0.ɵɵelementStart(6, "div",
|
|
82
|
-
i0.ɵɵelement(7, "i",
|
|
83
|
-
i0.ɵɵtext(8, " Max 200KB
|
|
83
|
+
i0.ɵɵelementStart(6, "div", 37);
|
|
84
|
+
i0.ɵɵelement(7, "i", 38);
|
|
85
|
+
i0.ɵɵtext(8, " Max 200KB - PNG, JPG, GIF, WEBP ");
|
|
84
86
|
i0.ɵɵelementEnd();
|
|
85
|
-
i0.ɵɵtemplate(9, UserProfileSettingsComponent_Conditional_33_Conditional_9_Template, 6, 1, "div",
|
|
87
|
+
i0.ɵɵtemplate(9, UserProfileSettingsComponent_Conditional_33_Conditional_9_Template, 6, 1, "div", 39);
|
|
86
88
|
i0.ɵɵelementEnd();
|
|
87
89
|
} if (rf & 2) {
|
|
88
90
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
@@ -91,15 +93,15 @@ function UserProfileSettingsComponent_Conditional_33_Template(rf, ctx) { if (rf
|
|
|
91
93
|
} }
|
|
92
94
|
function UserProfileSettingsComponent_Conditional_34_Template(rf, ctx) { if (rf & 1) {
|
|
93
95
|
const _r6 = i0.ɵɵgetCurrentView();
|
|
94
|
-
i0.ɵɵelementStart(0, "div",
|
|
96
|
+
i0.ɵɵelementStart(0, "div", 23)(1, "label", 42);
|
|
95
97
|
i0.ɵɵtext(2, "Image URL");
|
|
96
98
|
i0.ɵɵelementEnd();
|
|
97
|
-
i0.ɵɵelementStart(3, "input",
|
|
99
|
+
i0.ɵɵelementStart(3, "input", 43);
|
|
98
100
|
i0.ɵɵtwoWayListener("ngModelChange", function UserProfileSettingsComponent_Conditional_34_Template_input_ngModelChange_3_listener($event) { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.imageUrlInput, $event) || (ctx_r1.imageUrlInput = $event); return i0.ɵɵresetView($event); });
|
|
99
101
|
i0.ɵɵlistener("input", function UserProfileSettingsComponent_Conditional_34_Template_input_input_3_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onUrlChange()); });
|
|
100
102
|
i0.ɵɵelementEnd();
|
|
101
|
-
i0.ɵɵelementStart(4, "div",
|
|
102
|
-
i0.ɵɵelement(5, "i",
|
|
103
|
+
i0.ɵɵelementStart(4, "div", 44);
|
|
104
|
+
i0.ɵɵelement(5, "i", 38);
|
|
103
105
|
i0.ɵɵtext(6, " Enter a URL to an image hosted online ");
|
|
104
106
|
i0.ɵɵelementEnd()();
|
|
105
107
|
} if (rf & 2) {
|
|
@@ -107,42 +109,85 @@ function UserProfileSettingsComponent_Conditional_34_Template(rf, ctx) { if (rf
|
|
|
107
109
|
i0.ɵɵadvance(3);
|
|
108
110
|
i0.ɵɵtwoWayProperty("ngModel", ctx_r1.imageUrlInput);
|
|
109
111
|
} }
|
|
110
|
-
function
|
|
111
|
-
const
|
|
112
|
-
i0.ɵɵelementStart(0, "button",
|
|
113
|
-
i0.ɵɵlistener("click", function
|
|
114
|
-
i0.ɵɵelement(1, "i");
|
|
112
|
+
function UserProfileSettingsComponent_Conditional_35_Conditional_5_Template(rf, ctx) { if (rf & 1) {
|
|
113
|
+
const _r8 = i0.ɵɵgetCurrentView();
|
|
114
|
+
i0.ɵɵelementStart(0, "button", 53);
|
|
115
|
+
i0.ɵɵlistener("click", function UserProfileSettingsComponent_Conditional_35_Conditional_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r8); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.clearIconSearch()); });
|
|
116
|
+
i0.ɵɵelement(1, "i", 31);
|
|
117
|
+
i0.ɵɵelementEnd();
|
|
118
|
+
} }
|
|
119
|
+
function UserProfileSettingsComponent_Conditional_35_Conditional_9_For_1_For_5_Template(rf, ctx) { if (rf & 1) {
|
|
120
|
+
const _r9 = i0.ɵɵgetCurrentView();
|
|
121
|
+
i0.ɵɵelementStart(0, "button", 58);
|
|
122
|
+
i0.ɵɵlistener("click", function UserProfileSettingsComponent_Conditional_35_Conditional_9_For_1_For_5_Template_button_click_0_listener() { const icon_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r1 = i0.ɵɵnextContext(4); return i0.ɵɵresetView(ctx_r1.selectIcon(icon_r10)); });
|
|
123
|
+
i0.ɵɵelement(1, "i", 33);
|
|
115
124
|
i0.ɵɵelementEnd();
|
|
116
125
|
} if (rf & 2) {
|
|
117
|
-
const
|
|
118
|
-
const ctx_r1 = i0.ɵɵnextContext(
|
|
119
|
-
i0.ɵɵclassProp("selected", ctx_r1.isIconSelected(
|
|
120
|
-
i0.ɵɵproperty("title",
|
|
126
|
+
const icon_r10 = ctx.$implicit;
|
|
127
|
+
const ctx_r1 = i0.ɵɵnextContext(4);
|
|
128
|
+
i0.ɵɵclassProp("selected", ctx_r1.isIconSelected(icon_r10));
|
|
129
|
+
i0.ɵɵproperty("title", ctx_r1.extractIconName(icon_r10));
|
|
130
|
+
i0.ɵɵattribute("aria-checked", ctx_r1.isIconSelected(icon_r10))("aria-label", ctx_r1.extractIconName(icon_r10) + " icon");
|
|
121
131
|
i0.ɵɵadvance();
|
|
122
|
-
i0.ɵɵclassMap(
|
|
132
|
+
i0.ɵɵclassMap(icon_r10);
|
|
123
133
|
} }
|
|
124
|
-
function
|
|
125
|
-
i0.ɵɵelementStart(0, "div",
|
|
134
|
+
function UserProfileSettingsComponent_Conditional_35_Conditional_9_For_1_Template(rf, ctx) { if (rf & 1) {
|
|
135
|
+
i0.ɵɵelementStart(0, "div", 54)(1, "h4", 55);
|
|
126
136
|
i0.ɵɵtext(2);
|
|
127
137
|
i0.ɵɵelementEnd();
|
|
128
|
-
i0.ɵɵelementStart(3, "div",
|
|
129
|
-
i0.ɵɵrepeaterCreate(4,
|
|
138
|
+
i0.ɵɵelementStart(3, "div", 56);
|
|
139
|
+
i0.ɵɵrepeaterCreate(4, UserProfileSettingsComponent_Conditional_35_Conditional_9_For_1_For_5_Template, 2, 7, "button", 57, i0.ɵɵrepeaterTrackByIdentity);
|
|
130
140
|
i0.ɵɵelementEnd()();
|
|
131
141
|
} if (rf & 2) {
|
|
132
|
-
const
|
|
133
|
-
i0.ɵɵadvance(2);
|
|
134
|
-
i0.ɵɵtextInterpolate(category_r9.name);
|
|
142
|
+
const category_r11 = ctx.$implicit;
|
|
135
143
|
i0.ɵɵadvance(2);
|
|
136
|
-
i0.ɵɵ
|
|
144
|
+
i0.ɵɵtextInterpolate(category_r11.name);
|
|
145
|
+
i0.ɵɵadvance();
|
|
146
|
+
i0.ɵɵattribute("aria-label", category_r11.name + " icons");
|
|
147
|
+
i0.ɵɵadvance();
|
|
148
|
+
i0.ɵɵrepeater(category_r11.icons);
|
|
149
|
+
} }
|
|
150
|
+
function UserProfileSettingsComponent_Conditional_35_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
151
|
+
i0.ɵɵrepeaterCreate(0, UserProfileSettingsComponent_Conditional_35_Conditional_9_For_1_Template, 6, 2, "div", 54, _forTrack0);
|
|
152
|
+
} if (rf & 2) {
|
|
153
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
154
|
+
i0.ɵɵrepeater(ctx_r1.filteredIconCategories);
|
|
155
|
+
} }
|
|
156
|
+
function UserProfileSettingsComponent_Conditional_35_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
157
|
+
i0.ɵɵelementStart(0, "div", 52);
|
|
158
|
+
i0.ɵɵelement(1, "i", 59);
|
|
159
|
+
i0.ɵɵelementStart(2, "p", 60);
|
|
160
|
+
i0.ɵɵtext(3, "No icons found");
|
|
161
|
+
i0.ɵɵelementEnd();
|
|
162
|
+
i0.ɵɵelementStart(4, "p", 61);
|
|
163
|
+
i0.ɵɵtext(5, "Try a different search term");
|
|
164
|
+
i0.ɵɵelementEnd()();
|
|
137
165
|
} }
|
|
138
166
|
function UserProfileSettingsComponent_Conditional_35_Template(rf, ctx) { if (rf & 1) {
|
|
139
|
-
i0.ɵɵ
|
|
140
|
-
i0.ɵɵ
|
|
167
|
+
const _r7 = i0.ɵɵgetCurrentView();
|
|
168
|
+
i0.ɵɵelementStart(0, "div", 24)(1, "div", 45)(2, "div", 46);
|
|
169
|
+
i0.ɵɵelement(3, "i", 47);
|
|
170
|
+
i0.ɵɵelementStart(4, "input", 48);
|
|
171
|
+
i0.ɵɵlistener("input", function UserProfileSettingsComponent_Conditional_35_Template_input_input_4_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.onIconSearchChange($event)); });
|
|
141
172
|
i0.ɵɵelementEnd();
|
|
173
|
+
i0.ɵɵtemplate(5, UserProfileSettingsComponent_Conditional_35_Conditional_5_Template, 2, 0, "button", 49);
|
|
174
|
+
i0.ɵɵelementEnd();
|
|
175
|
+
i0.ɵɵelementStart(6, "div", 50);
|
|
176
|
+
i0.ɵɵtext(7);
|
|
177
|
+
i0.ɵɵelementEnd()();
|
|
178
|
+
i0.ɵɵelementStart(8, "div", 51);
|
|
179
|
+
i0.ɵɵtemplate(9, UserProfileSettingsComponent_Conditional_35_Conditional_9_Template, 2, 0)(10, UserProfileSettingsComponent_Conditional_35_Conditional_10_Template, 6, 0, "div", 52);
|
|
180
|
+
i0.ɵɵelementEnd()();
|
|
142
181
|
} if (rf & 2) {
|
|
143
182
|
const ctx_r1 = i0.ɵɵnextContext();
|
|
183
|
+
i0.ɵɵadvance(4);
|
|
184
|
+
i0.ɵɵproperty("value", ctx_r1.iconSearchTerm);
|
|
144
185
|
i0.ɵɵadvance();
|
|
145
|
-
i0.ɵɵ
|
|
186
|
+
i0.ɵɵconditional(ctx_r1.iconSearchTerm ? 5 : -1);
|
|
187
|
+
i0.ɵɵadvance(2);
|
|
188
|
+
i0.ɵɵtextInterpolate2(" ", ctx_r1.totalFilteredIcons, " icon", ctx_r1.totalFilteredIcons !== 1 ? "s" : "", " found ");
|
|
189
|
+
i0.ɵɵadvance(2);
|
|
190
|
+
i0.ɵɵconditional(ctx_r1.filteredIconCategories.length > 0 ? 9 : 10);
|
|
146
191
|
} }
|
|
147
192
|
function UserProfileSettingsComponent_Conditional_36_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
148
193
|
i0.ɵɵelementStart(0, "span");
|
|
@@ -165,30 +210,30 @@ function UserProfileSettingsComponent_Conditional_36_Conditional_17_Template(rf,
|
|
|
165
210
|
i0.ɵɵelementEnd();
|
|
166
211
|
} }
|
|
167
212
|
function UserProfileSettingsComponent_Conditional_36_Template(rf, ctx) { if (rf & 1) {
|
|
168
|
-
const
|
|
169
|
-
i0.ɵɵelementStart(0, "div",
|
|
170
|
-
i0.ɵɵelement(2, "i",
|
|
213
|
+
const _r12 = i0.ɵɵgetCurrentView();
|
|
214
|
+
i0.ɵɵelementStart(0, "div", 25)(1, "div", 62);
|
|
215
|
+
i0.ɵɵelement(2, "i", 38);
|
|
171
216
|
i0.ɵɵelementStart(3, "p");
|
|
172
217
|
i0.ɵɵtext(4, "Sync your avatar from your authentication provider account");
|
|
173
218
|
i0.ɵɵelementEnd()();
|
|
174
|
-
i0.ɵɵelementStart(5, "button",
|
|
175
|
-
i0.ɵɵlistener("click", function UserProfileSettingsComponent_Conditional_36_Template_button_click_5_listener() { i0.ɵɵrestoreView(
|
|
176
|
-
i0.ɵɵelement(6, "i",
|
|
219
|
+
i0.ɵɵelementStart(5, "button", 63);
|
|
220
|
+
i0.ɵɵlistener("click", function UserProfileSettingsComponent_Conditional_36_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.syncFromProvider()); });
|
|
221
|
+
i0.ɵɵelement(6, "i", 20);
|
|
177
222
|
i0.ɵɵtemplate(7, UserProfileSettingsComponent_Conditional_36_Conditional_7_Template, 2, 0, "span")(8, UserProfileSettingsComponent_Conditional_36_Conditional_8_Template, 2, 0, "span");
|
|
178
223
|
i0.ɵɵelementEnd();
|
|
179
|
-
i0.ɵɵelementStart(9, "div",
|
|
180
|
-
i0.ɵɵelement(10, "i",
|
|
224
|
+
i0.ɵɵelementStart(9, "div", 64);
|
|
225
|
+
i0.ɵɵelement(10, "i", 65);
|
|
181
226
|
i0.ɵɵelementStart(11, "small");
|
|
182
227
|
i0.ɵɵtext(12, "This will download your profile photo from Microsoft and save it to your profile");
|
|
183
228
|
i0.ɵɵelementEnd()();
|
|
184
|
-
i0.ɵɵelement(13, "
|
|
185
|
-
i0.ɵɵelementStart(14, "button",
|
|
186
|
-
i0.ɵɵlistener("click", function UserProfileSettingsComponent_Conditional_36_Template_button_click_14_listener() { i0.ɵɵrestoreView(
|
|
187
|
-
i0.ɵɵelement(15, "i",
|
|
229
|
+
i0.ɵɵelement(13, "hr", 66);
|
|
230
|
+
i0.ɵɵelementStart(14, "button", 67);
|
|
231
|
+
i0.ɵɵlistener("click", function UserProfileSettingsComponent_Conditional_36_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r12); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.revertToDefault()); });
|
|
232
|
+
i0.ɵɵelement(15, "i", 68);
|
|
188
233
|
i0.ɵɵtemplate(16, UserProfileSettingsComponent_Conditional_36_Conditional_16_Template, 2, 0, "span")(17, UserProfileSettingsComponent_Conditional_36_Conditional_17_Template, 2, 0, "span");
|
|
189
234
|
i0.ɵɵelementEnd();
|
|
190
|
-
i0.ɵɵelementStart(18, "div",
|
|
191
|
-
i0.ɵɵelement(19, "i",
|
|
235
|
+
i0.ɵɵelementStart(18, "div", 64);
|
|
236
|
+
i0.ɵɵelement(19, "i", 38);
|
|
192
237
|
i0.ɵɵelementStart(20, "small");
|
|
193
238
|
i0.ɵɵtext(21, "Clears your avatar settings and restores the automatic sync from your auth provider");
|
|
194
239
|
i0.ɵɵelementEnd()()();
|
|
@@ -203,14 +248,14 @@ function UserProfileSettingsComponent_Conditional_36_Template(rf, ctx) { if (rf
|
|
|
203
248
|
i0.ɵɵadvance(2);
|
|
204
249
|
i0.ɵɵconditional(ctx_r1.isSaving ? 16 : 17);
|
|
205
250
|
} }
|
|
206
|
-
function
|
|
207
|
-
i0.ɵɵelement(0, "i",
|
|
251
|
+
function UserProfileSettingsComponent_Conditional_39_Template(rf, ctx) { if (rf & 1) {
|
|
252
|
+
i0.ɵɵelement(0, "i", 69);
|
|
208
253
|
i0.ɵɵelementStart(1, "span");
|
|
209
254
|
i0.ɵɵtext(2, "Saving...");
|
|
210
255
|
i0.ɵɵelementEnd();
|
|
211
256
|
} }
|
|
212
|
-
function
|
|
213
|
-
i0.ɵɵelement(0, "i",
|
|
257
|
+
function UserProfileSettingsComponent_Conditional_40_Template(rf, ctx) { if (rf & 1) {
|
|
258
|
+
i0.ɵɵelement(0, "i", 70);
|
|
214
259
|
i0.ɵɵelementStart(1, "span");
|
|
215
260
|
i0.ɵɵtext(2, "Save Changes");
|
|
216
261
|
i0.ɵɵelementEnd();
|
|
@@ -231,6 +276,13 @@ export class UserProfileSettingsComponent {
|
|
|
231
276
|
isSaving = false;
|
|
232
277
|
showSuccessMessage = false;
|
|
233
278
|
errorMessage = '';
|
|
279
|
+
// Icon search state
|
|
280
|
+
iconSearchTerm = '';
|
|
281
|
+
iconSearch$ = new BehaviorSubject('');
|
|
282
|
+
filteredIconCategories = [];
|
|
283
|
+
totalFilteredIcons = 0;
|
|
284
|
+
// Cleanup
|
|
285
|
+
destroy$ = new Subject();
|
|
234
286
|
// Icon picker data
|
|
235
287
|
iconCategories = [
|
|
236
288
|
{
|
|
@@ -319,8 +371,85 @@ export class UserProfileSettingsComponent {
|
|
|
319
371
|
// Load the full UserEntity to access avatar fields
|
|
320
372
|
this.currentUser = await md.GetEntityObject('Users');
|
|
321
373
|
await this.currentUser.Load(currentUserInfo.ID);
|
|
374
|
+
// Initialize filtered icons
|
|
375
|
+
this.filteredIconCategories = [...this.iconCategories];
|
|
376
|
+
this.totalFilteredIcons = this.iconCategories.reduce((sum, cat) => sum + cat.icons.length, 0);
|
|
377
|
+
// Setup icon search subscription
|
|
378
|
+
this.setupIconSearchSubscription();
|
|
322
379
|
this.loadCurrentAvatar();
|
|
323
380
|
}
|
|
381
|
+
ngOnDestroy() {
|
|
382
|
+
this.destroy$.next();
|
|
383
|
+
this.destroy$.complete();
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Initializes the icon search subscription with debounce
|
|
387
|
+
*/
|
|
388
|
+
setupIconSearchSubscription() {
|
|
389
|
+
this.iconSearch$
|
|
390
|
+
.pipe(debounceTime(200), // Faster debounce for local filtering
|
|
391
|
+
distinctUntilChanged(), takeUntil(this.destroy$))
|
|
392
|
+
.subscribe((searchTerm) => {
|
|
393
|
+
this.filterIcons(searchTerm);
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Handles icon search input changes
|
|
398
|
+
*/
|
|
399
|
+
onIconSearchChange(event) {
|
|
400
|
+
const value = event.target.value;
|
|
401
|
+
this.iconSearchTerm = value;
|
|
402
|
+
this.iconSearch$.next(value);
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Filters icons based on search term
|
|
406
|
+
* Matches icon class name parts (e.g., "user" matches "fa-user-tie")
|
|
407
|
+
*/
|
|
408
|
+
filterIcons(searchTerm) {
|
|
409
|
+
if (!searchTerm || searchTerm.trim() === '') {
|
|
410
|
+
// Show all icons
|
|
411
|
+
this.filteredIconCategories = [...this.iconCategories];
|
|
412
|
+
this.totalFilteredIcons = this.iconCategories.reduce((sum, cat) => sum + cat.icons.length, 0);
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
const term = searchTerm.toLowerCase().trim();
|
|
416
|
+
this.filteredIconCategories = [];
|
|
417
|
+
this.totalFilteredIcons = 0;
|
|
418
|
+
for (const category of this.iconCategories) {
|
|
419
|
+
const matchingIcons = category.icons.filter((icon) => {
|
|
420
|
+
// Extract icon name from class (e.g., "fa-solid fa-user-tie" -> "user-tie")
|
|
421
|
+
const iconName = this.extractIconName(icon);
|
|
422
|
+
return iconName.includes(term);
|
|
423
|
+
});
|
|
424
|
+
if (matchingIcons.length > 0) {
|
|
425
|
+
this.filteredIconCategories.push({
|
|
426
|
+
name: category.name,
|
|
427
|
+
icons: matchingIcons
|
|
428
|
+
});
|
|
429
|
+
this.totalFilteredIcons += matchingIcons.length;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Extracts the icon name from a Font Awesome class string
|
|
435
|
+
* e.g., "fa-solid fa-user-tie" -> "user-tie"
|
|
436
|
+
*/
|
|
437
|
+
extractIconName(iconClass) {
|
|
438
|
+
const parts = iconClass.split(' ');
|
|
439
|
+
for (const part of parts) {
|
|
440
|
+
if (part.startsWith('fa-') && !['fa-solid', 'fa-regular', 'fa-light', 'fa-brands'].includes(part)) {
|
|
441
|
+
return part.substring(3); // Remove "fa-" prefix
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
return iconClass.toLowerCase();
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Clears the icon search
|
|
448
|
+
*/
|
|
449
|
+
clearIconSearch() {
|
|
450
|
+
this.iconSearchTerm = '';
|
|
451
|
+
this.iconSearch$.next('');
|
|
452
|
+
}
|
|
324
453
|
/**
|
|
325
454
|
* Loads the current avatar settings from the user entity
|
|
326
455
|
*/
|
|
@@ -606,7 +735,7 @@ export class UserProfileSettingsComponent {
|
|
|
606
735
|
}, 3000);
|
|
607
736
|
}
|
|
608
737
|
static ɵfac = function UserProfileSettingsComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || UserProfileSettingsComponent)(i0.ɵɵdirectiveInject(i1.UserAvatarService), i0.ɵɵdirectiveInject(i2.SharedService)); };
|
|
609
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: UserProfileSettingsComponent, selectors: [["mj-user-profile-settings"]], decls: 43, vars:
|
|
738
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: UserProfileSettingsComponent, selectors: [["mj-user-profile-settings"]], decls: 43, vars: 22, consts: [["fileInput", ""], [1, "user-profile-settings"], [1, "profile-header"], [1, "description"], ["role", "alert", 1, "alert", "alert-error"], ["role", "status", "aria-live", "polite", 1, "alert", "alert-success"], [1, "avatar-preview-section"], [1, "preview-label"], [1, "preview-container"], ["alt", "Avatar preview", 1, "preview-image", 3, "src"], [1, "preview-icon-wrapper"], [1, "preview-placeholder"], ["role", "tablist", "aria-label", "Avatar customization options", 1, "tab-navigation"], ["role", "tab", "aria-controls", "panel-upload", 1, "tab-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-upload"], ["role", "tab", "aria-controls", "panel-url", 1, "tab-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-link"], ["role", "tab", "aria-controls", "panel-icon", 1, "tab-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-icons"], ["role", "tab", "aria-controls", "panel-provider", 1, "tab-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-brands", "fa-microsoft"], [1, "tab-content"], ["id", "panel-upload", "role", "tabpanel", 1, "upload-section"], ["id", "panel-url", "role", "tabpanel", 1, "url-section"], ["id", "panel-icon", "role", "tabpanel", 1, "icon-section"], ["id", "panel-provider", "role", "tabpanel", 1, "provider-section"], [1, "action-buttons"], [1, "mj-btn", "mj-btn-primary", 3, "click", "disabled"], [1, "mj-btn", "mj-btn-secondary", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-exclamation-triangle"], ["aria-label", "Dismiss error", 1, "close-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-xmark"], ["aria-hidden", "true", 1, "fa-solid", "fa-check-circle"], ["aria-hidden", "true"], ["aria-hidden", "true", 1, "fa-solid", "fa-user"], ["type", "file", "accept", "image/png,image/jpeg,image/jpg,image/gif,image/webp", 2, "display", "none", 3, "change"], [1, "upload-btn", 3, "click"], [1, "upload-info"], ["aria-hidden", "true", 1, "fa-solid", "fa-info-circle"], [1, "selected-file"], ["aria-hidden", "true", 1, "fa-solid", "fa-file-image"], ["aria-label", "Remove selected file", 1, "remove-btn", 3, "click"], ["for", "imageUrl"], ["type", "text", "id", "imageUrl", "placeholder", "https://example.com/avatar.jpg", 1, "url-input", 3, "ngModelChange", "input", "ngModel"], [1, "url-info"], [1, "icon-search-container"], [1, "mj-search"], ["aria-hidden", "true", 1, "fa-solid", "fa-search", "mj-search-icon"], ["type", "text", "placeholder", "Search icons by name...", "aria-label", "Search icons", 1, "mj-search-input", 3, "input", "value"], ["aria-label", "Clear search", 1, "mj-search-clear"], [1, "icon-filter-info"], [1, "icon-categories-container"], [1, "empty-state"], ["aria-label", "Clear search", 1, "mj-search-clear", 3, "click"], [1, "icon-category"], [1, "category-title"], ["role", "radiogroup", 1, "icon-grid"], ["role", "radio", 1, "icon-option", 3, "selected", "title"], ["role", "radio", 1, "icon-option", 3, "click", "title"], ["aria-hidden", "true", 1, "fa-solid", "fa-search", "empty-icon"], [1, "empty-text"], [1, "empty-subtext"], [1, "provider-info"], [1, "sync-btn", 3, "click", "disabled"], [1, "provider-note"], ["aria-hidden", "true", 1, "fa-solid", "fa-lightbulb"], [1, "provider-divider"], [1, "revert-btn", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-rotate-left"], ["aria-hidden", "true", 1, "fa-solid", "fa-spinner", "fa-spin"], ["aria-hidden", "true", 1, "fa-solid", "fa-save"]], template: function UserProfileSettingsComponent_Template(rf, ctx) { if (rf & 1) {
|
|
610
739
|
i0.ɵɵelementStart(0, "div", 1)(1, "div", 2)(2, "h3");
|
|
611
740
|
i0.ɵɵtext(3, "Avatar Settings");
|
|
612
741
|
i0.ɵɵelementEnd();
|
|
@@ -626,34 +755,34 @@ export class UserProfileSettingsComponent {
|
|
|
626
755
|
i0.ɵɵelementStart(18, "span");
|
|
627
756
|
i0.ɵɵtext(19, "Upload");
|
|
628
757
|
i0.ɵɵelementEnd()();
|
|
629
|
-
i0.ɵɵelementStart(20, "button",
|
|
758
|
+
i0.ɵɵelementStart(20, "button", 15);
|
|
630
759
|
i0.ɵɵlistener("click", function UserProfileSettingsComponent_Template_button_click_20_listener() { return ctx.selectTab("url"); });
|
|
631
|
-
i0.ɵɵelement(21, "i",
|
|
760
|
+
i0.ɵɵelement(21, "i", 16);
|
|
632
761
|
i0.ɵɵelementStart(22, "span");
|
|
633
762
|
i0.ɵɵtext(23, "URL");
|
|
634
763
|
i0.ɵɵelementEnd()();
|
|
635
|
-
i0.ɵɵelementStart(24, "button",
|
|
764
|
+
i0.ɵɵelementStart(24, "button", 17);
|
|
636
765
|
i0.ɵɵlistener("click", function UserProfileSettingsComponent_Template_button_click_24_listener() { return ctx.selectTab("icon"); });
|
|
637
|
-
i0.ɵɵelement(25, "i",
|
|
766
|
+
i0.ɵɵelement(25, "i", 18);
|
|
638
767
|
i0.ɵɵelementStart(26, "span");
|
|
639
768
|
i0.ɵɵtext(27, "Icon");
|
|
640
769
|
i0.ɵɵelementEnd()();
|
|
641
|
-
i0.ɵɵelementStart(28, "button",
|
|
770
|
+
i0.ɵɵelementStart(28, "button", 19);
|
|
642
771
|
i0.ɵɵlistener("click", function UserProfileSettingsComponent_Template_button_click_28_listener() { return ctx.selectTab("provider"); });
|
|
643
|
-
i0.ɵɵelement(29, "i",
|
|
772
|
+
i0.ɵɵelement(29, "i", 20);
|
|
644
773
|
i0.ɵɵelementStart(30, "span");
|
|
645
774
|
i0.ɵɵtext(31, "Sync");
|
|
646
775
|
i0.ɵɵelementEnd()()();
|
|
647
|
-
i0.ɵɵelementStart(32, "div",
|
|
648
|
-
i0.ɵɵtemplate(33, UserProfileSettingsComponent_Conditional_33_Template, 10, 1, "div",
|
|
776
|
+
i0.ɵɵelementStart(32, "div", 21);
|
|
777
|
+
i0.ɵɵtemplate(33, UserProfileSettingsComponent_Conditional_33_Template, 10, 1, "div", 22)(34, UserProfileSettingsComponent_Conditional_34_Template, 7, 1, "div", 23)(35, UserProfileSettingsComponent_Conditional_35_Template, 11, 5, "div", 24)(36, UserProfileSettingsComponent_Conditional_36_Template, 22, 4, "div", 25);
|
|
649
778
|
i0.ɵɵelementEnd();
|
|
650
|
-
i0.ɵɵelementStart(37, "div",
|
|
651
|
-
i0.ɵɵlistener("click", function UserProfileSettingsComponent_Template_button_click_38_listener() { return ctx.
|
|
652
|
-
i0.ɵɵ
|
|
779
|
+
i0.ɵɵelementStart(37, "div", 26)(38, "button", 27);
|
|
780
|
+
i0.ɵɵlistener("click", function UserProfileSettingsComponent_Template_button_click_38_listener() { return ctx.save(); });
|
|
781
|
+
i0.ɵɵtemplate(39, UserProfileSettingsComponent_Conditional_39_Template, 3, 0)(40, UserProfileSettingsComponent_Conditional_40_Template, 3, 0);
|
|
653
782
|
i0.ɵɵelementEnd();
|
|
654
|
-
i0.ɵɵelementStart(
|
|
655
|
-
i0.ɵɵlistener("click", function
|
|
656
|
-
i0.ɵɵ
|
|
783
|
+
i0.ɵɵelementStart(41, "button", 28);
|
|
784
|
+
i0.ɵɵlistener("click", function UserProfileSettingsComponent_Template_button_click_41_listener() { return ctx.cancel(); });
|
|
785
|
+
i0.ɵɵtext(42, " Cancel ");
|
|
657
786
|
i0.ɵɵelementEnd()()();
|
|
658
787
|
} if (rf & 2) {
|
|
659
788
|
i0.ɵɵadvance(6);
|
|
@@ -664,12 +793,16 @@ export class UserProfileSettingsComponent {
|
|
|
664
793
|
i0.ɵɵconditional(ctx.previewUrl ? 12 : ctx.previewIconClass ? 13 : 14);
|
|
665
794
|
i0.ɵɵadvance(4);
|
|
666
795
|
i0.ɵɵclassProp("active", ctx.selectedTab === "upload");
|
|
796
|
+
i0.ɵɵattribute("aria-selected", ctx.selectedTab === "upload");
|
|
667
797
|
i0.ɵɵadvance(4);
|
|
668
798
|
i0.ɵɵclassProp("active", ctx.selectedTab === "url");
|
|
799
|
+
i0.ɵɵattribute("aria-selected", ctx.selectedTab === "url");
|
|
669
800
|
i0.ɵɵadvance(4);
|
|
670
801
|
i0.ɵɵclassProp("active", ctx.selectedTab === "icon");
|
|
802
|
+
i0.ɵɵattribute("aria-selected", ctx.selectedTab === "icon");
|
|
671
803
|
i0.ɵɵadvance(4);
|
|
672
804
|
i0.ɵɵclassProp("active", ctx.selectedTab === "provider");
|
|
805
|
+
i0.ɵɵattribute("aria-selected", ctx.selectedTab === "provider");
|
|
673
806
|
i0.ɵɵadvance(5);
|
|
674
807
|
i0.ɵɵconditional(ctx.selectedTab === "upload" ? 33 : -1);
|
|
675
808
|
i0.ɵɵadvance();
|
|
@@ -679,16 +812,16 @@ export class UserProfileSettingsComponent {
|
|
|
679
812
|
i0.ɵɵadvance();
|
|
680
813
|
i0.ɵɵconditional(ctx.selectedTab === "provider" ? 36 : -1);
|
|
681
814
|
i0.ɵɵadvance(2);
|
|
682
|
-
i0.ɵɵproperty("disabled", ctx.isSaving);
|
|
683
|
-
i0.ɵɵadvance(2);
|
|
684
815
|
i0.ɵɵproperty("disabled", ctx.isSaving || ctx.selectedTab === "provider");
|
|
685
816
|
i0.ɵɵadvance();
|
|
686
|
-
i0.ɵɵconditional(ctx.isSaving ?
|
|
687
|
-
} }, dependencies: [i3.DefaultValueAccessor, i3.NgControlStatus, i3.NgModel], styles: [".user-profile-settings[_ngcontent-%COMP%] {\n max-width: 800px;\n margin: 0 auto;\n padding: 1.5rem;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .profile-header[_ngcontent-%COMP%] {\n margin-bottom: 1.5rem;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .profile-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 0.5rem 0;\n font-size: 1.5rem;\n font-weight: 600;\n color: #1a1a1a;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .profile-header[_ngcontent-%COMP%] .description[_ngcontent-%COMP%] {\n margin: 0;\n color: #666;\n font-size: 0.9rem;\n}\n\n\n\n.user-profile-settings[_ngcontent-%COMP%] .alert[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n border-radius: 6px;\n margin-bottom: 1rem;\n font-size: 0.9rem;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .alert[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n flex-shrink: 0;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .alert[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .alert[_ngcontent-%COMP%] .close-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0.25rem;\n color: inherit;\n opacity: 0.7;\n transition: opacity 0.2s;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .alert[_ngcontent-%COMP%] .close-btn[_ngcontent-%COMP%]:hover {\n opacity: 1;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .alert.alert-error[_ngcontent-%COMP%] {\n background-color: #fee;\n border: 1px solid #fcc;\n color: #c33;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .alert.alert-success[_ngcontent-%COMP%] {\n background-color: #efe;\n border: 1px solid #cfc;\n color: #3c3;\n}\n\n\n\n.user-profile-settings[_ngcontent-%COMP%] .avatar-preview-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n margin-bottom: 2rem;\n padding: 1.5rem;\n background: #f8f9fa;\n border-radius: 8px;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .avatar-preview-section[_ngcontent-%COMP%] .preview-label[_ngcontent-%COMP%] {\n font-size: 0.85rem;\n font-weight: 600;\n color: #666;\n margin-bottom: 1rem;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .avatar-preview-section[_ngcontent-%COMP%] .preview-container[_ngcontent-%COMP%] {\n width: 120px;\n height: 120px;\n border-radius: 50%;\n overflow: hidden;\n background: white;\n border: 3px solid #e0e0e0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .avatar-preview-section[_ngcontent-%COMP%] .preview-container[_ngcontent-%COMP%] .preview-image[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .avatar-preview-section[_ngcontent-%COMP%] .preview-container[_ngcontent-%COMP%] .preview-icon-wrapper[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .avatar-preview-section[_ngcontent-%COMP%] .preview-container[_ngcontent-%COMP%] .preview-icon-wrapper[_ngcontent-%COMP%] .preview-icon[_ngcontent-%COMP%] {\n font-size: 3.5rem;\n color: #666;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .avatar-preview-section[_ngcontent-%COMP%] .preview-container[_ngcontent-%COMP%] .preview-placeholder[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.5rem;\n color: #999;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .avatar-preview-section[_ngcontent-%COMP%] .preview-container[_ngcontent-%COMP%] .preview-placeholder[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 2.5rem;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .avatar-preview-section[_ngcontent-%COMP%] .preview-container[_ngcontent-%COMP%] .preview-placeholder[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n}\n\n\n\n.user-profile-settings[_ngcontent-%COMP%] .tab-navigation[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.5rem;\n margin-bottom: 1.5rem;\n border-bottom: 2px solid #e0e0e0;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .tab-navigation[_ngcontent-%COMP%] .tab-btn[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n background: none;\n border: none;\n border-bottom: 3px solid transparent;\n cursor: pointer;\n font-size: 0.9rem;\n font-weight: 500;\n color: #666;\n transition: all 0.2s;\n margin-bottom: -2px;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .tab-navigation[_ngcontent-%COMP%] .tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .tab-navigation[_ngcontent-%COMP%] .tab-btn[_ngcontent-%COMP%]:hover {\n color: #333;\n background: #f8f9fa;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .tab-navigation[_ngcontent-%COMP%] .tab-btn.active[_ngcontent-%COMP%] {\n color: #007bff;\n border-bottom-color: #007bff;\n background: #f8f9fa;\n}\n\n\n\n.user-profile-settings[_ngcontent-%COMP%] .tab-content[_ngcontent-%COMP%] {\n min-height: 300px;\n padding: 1.5rem;\n background: #f8f9fa;\n border-radius: 8px;\n margin-bottom: 1.5rem;\n}\n\n\n\n.user-profile-settings[_ngcontent-%COMP%] .upload-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .upload-section[_ngcontent-%COMP%] .upload-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n background: #007bff;\n color: white;\n border: none;\n border-radius: 6px;\n font-size: 0.95rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .upload-section[_ngcontent-%COMP%] .upload-btn[_ngcontent-%COMP%]:hover {\n background: #0056b3;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .upload-section[_ngcontent-%COMP%] .upload-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .upload-section[_ngcontent-%COMP%] .upload-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n color: #666;\n font-size: 0.85rem;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .upload-section[_ngcontent-%COMP%] .upload-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #007bff;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .upload-section[_ngcontent-%COMP%] .selected-file[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n background: white;\n border: 1px solid #ddd;\n border-radius: 6px;\n width: 100%;\n max-width: 400px;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .upload-section[_ngcontent-%COMP%] .selected-file[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #007bff;\n font-size: 1.2rem;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .upload-section[_ngcontent-%COMP%] .selected-file[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 0.9rem;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .upload-section[_ngcontent-%COMP%] .selected-file[_ngcontent-%COMP%] .remove-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0.25rem;\n color: #999;\n transition: color 0.2s;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .upload-section[_ngcontent-%COMP%] .selected-file[_ngcontent-%COMP%] .remove-btn[_ngcontent-%COMP%]:hover {\n color: #c33;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .upload-section[_ngcontent-%COMP%] .selected-file[_ngcontent-%COMP%] .remove-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n color: inherit;\n}\n\n\n\n.user-profile-settings[_ngcontent-%COMP%] .url-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .url-section[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-weight: 600;\n color: #333;\n font-size: 0.9rem;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .url-section[_ngcontent-%COMP%] .url-input[_ngcontent-%COMP%] {\n padding: 0.75rem;\n border: 1px solid #ddd;\n border-radius: 6px;\n font-size: 0.95rem;\n transition: border-color 0.2s;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .url-section[_ngcontent-%COMP%] .url-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: #007bff;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .url-section[_ngcontent-%COMP%] .url-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n color: #666;\n font-size: 0.85rem;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .url-section[_ngcontent-%COMP%] .url-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #007bff;\n}\n\n\n\n.user-profile-settings[_ngcontent-%COMP%] .icon-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n max-height: 400px;\n overflow-y: auto;\n padding-right: 0.5rem;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .icon-section[_ngcontent-%COMP%] .icon-category[_ngcontent-%COMP%] .category-title[_ngcontent-%COMP%] {\n font-size: 0.9rem;\n font-weight: 600;\n color: #333;\n margin: 0 0 0.75rem 0;\n padding-bottom: 0.5rem;\n border-bottom: 1px solid #ddd;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .icon-section[_ngcontent-%COMP%] .icon-category[_ngcontent-%COMP%] .icon-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(50px, 1fr));\n gap: 0.5rem;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .icon-section[_ngcontent-%COMP%] .icon-category[_ngcontent-%COMP%] .icon-grid[_ngcontent-%COMP%] .icon-option[_ngcontent-%COMP%] {\n aspect-ratio: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0.75rem;\n background: white;\n border: 2px solid #ddd;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .icon-section[_ngcontent-%COMP%] .icon-category[_ngcontent-%COMP%] .icon-grid[_ngcontent-%COMP%] .icon-option[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n color: #666;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .icon-section[_ngcontent-%COMP%] .icon-category[_ngcontent-%COMP%] .icon-grid[_ngcontent-%COMP%] .icon-option[_ngcontent-%COMP%]:hover {\n border-color: #007bff;\n background: #f0f8ff;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .icon-section[_ngcontent-%COMP%] .icon-category[_ngcontent-%COMP%] .icon-grid[_ngcontent-%COMP%] .icon-option[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: #007bff;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .icon-section[_ngcontent-%COMP%] .icon-category[_ngcontent-%COMP%] .icon-grid[_ngcontent-%COMP%] .icon-option.selected[_ngcontent-%COMP%] {\n border-color: #007bff;\n background: #007bff;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .icon-section[_ngcontent-%COMP%] .icon-category[_ngcontent-%COMP%] .icon-grid[_ngcontent-%COMP%] .icon-option.selected[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: white;\n}\n\n\n\n.user-profile-settings[_ngcontent-%COMP%] .icon-section[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .icon-section[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: #f1f1f1;\n border-radius: 3px;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .icon-section[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: #ccc;\n border-radius: 3px;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .icon-section[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: #999;\n}\n\n\n\n.user-profile-settings[_ngcontent-%COMP%] .provider-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1.5rem;\n padding: 2rem 1rem;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .provider-section[_ngcontent-%COMP%] .provider-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 1rem;\n background: white;\n border: 1px solid #ddd;\n border-radius: 6px;\n width: 100%;\n max-width: 500px;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .provider-section[_ngcontent-%COMP%] .provider-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #007bff;\n font-size: 1.2rem;\n flex-shrink: 0;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .provider-section[_ngcontent-%COMP%] .provider-info[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n color: #666;\n font-size: 0.9rem;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .provider-section[_ngcontent-%COMP%] .sync-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 1rem 2rem;\n background: #0078d4;\n color: white;\n border: none;\n border-radius: 6px;\n font-size: 1rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .provider-section[_ngcontent-%COMP%] .sync-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #005a9e;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .provider-section[_ngcontent-%COMP%] .sync-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .provider-section[_ngcontent-%COMP%] .sync-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.2rem;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .provider-section[_ngcontent-%COMP%] .provider-note[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n color: #666;\n font-size: 0.85rem;\n max-width: 500px;\n text-align: center;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .provider-section[_ngcontent-%COMP%] .provider-note[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: #ffc107;\n margin-top: 0.1rem;\n flex-shrink: 0;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .provider-section[_ngcontent-%COMP%] .revert-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1.5rem;\n background: #6c757d;\n color: white;\n border: none;\n border-radius: 6px;\n font-size: 0.95rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .provider-section[_ngcontent-%COMP%] .revert-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #5a6268;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .provider-section[_ngcontent-%COMP%] .revert-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .provider-section[_ngcontent-%COMP%] .revert-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n\n\n\n.user-profile-settings[_ngcontent-%COMP%] .action-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 1rem;\n justify-content: flex-end;\n padding-top: 1rem;\n border-top: 1px solid #e0e0e0;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .action-buttons[_ngcontent-%COMP%] .btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n border: none;\n border-radius: 6px;\n font-size: 0.95rem;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .action-buttons[_ngcontent-%COMP%] .btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .action-buttons[_ngcontent-%COMP%] .btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 0.9rem;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .action-buttons[_ngcontent-%COMP%] .btn[_ngcontent-%COMP%] i.fa-spin[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_spin 1s linear infinite;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .action-buttons[_ngcontent-%COMP%] .btn.btn-secondary[_ngcontent-%COMP%] {\n background: #6c757d;\n color: white;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .action-buttons[_ngcontent-%COMP%] .btn.btn-secondary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #5a6268;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .action-buttons[_ngcontent-%COMP%] .btn.btn-primary[_ngcontent-%COMP%] {\n background: #28a745;\n color: white;\n}\n\n.user-profile-settings[_ngcontent-%COMP%] .action-buttons[_ngcontent-%COMP%] .btn.btn-primary[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #218838;\n}\n\n@keyframes _ngcontent-%COMP%_spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\n\n\n@media (max-width: 768px) {\n .user-profile-settings[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .user-profile-settings[_ngcontent-%COMP%] .tab-navigation[_ngcontent-%COMP%] .tab-btn[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 0.25rem;\n padding: 0.5rem;\n font-size: 0.75rem;\n }\n\n .user-profile-settings[_ngcontent-%COMP%] .tab-navigation[_ngcontent-%COMP%] .tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.2rem;\n }\n\n .user-profile-settings[_ngcontent-%COMP%] .tab-navigation[_ngcontent-%COMP%] .tab-btn[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 0.7rem;\n }\n\n .user-profile-settings[_ngcontent-%COMP%] .icon-section[_ngcontent-%COMP%] .icon-category[_ngcontent-%COMP%] .icon-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fill, minmax(45px, 1fr));\n }\n\n .user-profile-settings[_ngcontent-%COMP%] .action-buttons[_ngcontent-%COMP%] {\n flex-direction: column-reverse;\n }\n\n .user-profile-settings[_ngcontent-%COMP%] .action-buttons[_ngcontent-%COMP%] .btn[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: center;\n }\n}"] });
|
|
817
|
+
i0.ɵɵconditional(ctx.isSaving ? 39 : 40);
|
|
818
|
+
i0.ɵɵadvance(2);
|
|
819
|
+
i0.ɵɵproperty("disabled", ctx.isSaving);
|
|
820
|
+
} }, dependencies: [i3.DefaultValueAccessor, i3.NgControlStatus, i3.NgModel], styles: ["\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: block;\n height: 100%;\n width: 100%;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n\n\n\n\n.user-profile-settings[_ngcontent-%COMP%] {\n max-width: 800px;\n margin: 0 auto;\n padding: 1.5rem;\n background: var(--md-surface);\n min-height: 100%;\n}\n\n\n\n\n\n.profile-header[_ngcontent-%COMP%] {\n margin-bottom: 1.5rem;\n}\n\n.profile-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 0.5rem 0;\n font-size: 1.75rem;\n font-weight: 600;\n color: var(--md-on-surface);\n}\n\n.profile-header[_ngcontent-%COMP%] .description[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 1rem;\n color: var(--md-on-surface-variant);\n}\n\n\n\n\n\n.alert[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n border-radius: var(--md-corner-small);\n margin-bottom: 1rem;\n font-size: 0.875rem;\n font-weight: 500;\n animation: _ngcontent-%COMP%_fadeIn 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.alert[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n flex-shrink: 0;\n font-size: 1rem;\n}\n\n.alert[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.alert[_ngcontent-%COMP%] .close-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0.25rem;\n color: inherit;\n opacity: 0.7;\n transition: opacity 0.2s;\n border-radius: var(--md-corner-extra-small);\n min-width: 32px;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.alert[_ngcontent-%COMP%] .close-btn[_ngcontent-%COMP%]:hover {\n opacity: 1;\n}\n\n.alert.alert-error[_ngcontent-%COMP%] {\n background: var(--md-error-container);\n color: var(--md-on-error-container);\n}\n\n.alert.alert-success[_ngcontent-%COMP%] {\n background: var(--md-tertiary-container);\n color: #1B5E20;\n}\n\n\n\n\n\n.avatar-preview-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n margin-bottom: 2rem;\n padding: 1.5rem;\n background: var(--md-surface-container-low);\n border-radius: var(--md-corner-medium);\n border: 1px solid var(--md-outline-variant);\n}\n\n.preview-label[_ngcontent-%COMP%] {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--md-on-surface-variant);\n margin-bottom: 1rem;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.preview-container[_ngcontent-%COMP%] {\n width: 120px;\n height: 120px;\n border-radius: 50%;\n overflow: hidden;\n background: var(--md-surface);\n border: 3px solid var(--md-outline-variant);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: border-color 0.2s;\n}\n\n.preview-container[_ngcontent-%COMP%]:has(.preview-image), \n.preview-container[_ngcontent-%COMP%]:has(.preview-icon) {\n border-color: var(--md-primary);\n}\n\n.preview-image[_ngcontent-%COMP%] {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.preview-icon-wrapper[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n background: var(--md-primary-container);\n}\n\n.preview-icon[_ngcontent-%COMP%] {\n font-size: 3.5rem;\n color: var(--md-primary);\n}\n\n.preview-placeholder[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.5rem;\n color: var(--md-on-surface-variant);\n}\n\n.preview-placeholder[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 2.5rem;\n}\n\n.preview-placeholder[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n}\n\n\n\n\n\n.tab-navigation[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.25rem;\n margin-bottom: 1.5rem;\n border-bottom: 2px solid var(--md-outline-variant);\n background: var(--md-surface);\n}\n\n.tab-btn[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n background: transparent;\n border: none;\n border-bottom: 3px solid transparent;\n cursor: pointer;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--md-on-surface-variant);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n margin-bottom: -2px;\n min-height: 48px;\n}\n\n.tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n\n.tab-btn[_ngcontent-%COMP%]:hover {\n color: var(--md-on-surface);\n background: var(--md-surface-container);\n}\n\n.tab-btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: -2px;\n}\n\n.tab-btn.active[_ngcontent-%COMP%] {\n color: var(--md-primary);\n border-bottom-color: var(--md-primary);\n background: var(--md-primary-container);\n}\n\n\n\n\n\n.tab-content[_ngcontent-%COMP%] {\n min-height: 300px;\n padding: 1.5rem;\n background: var(--md-surface-container);\n border-radius: var(--md-corner-medium);\n margin-bottom: 1.5rem;\n border: 1px solid var(--md-outline-variant);\n}\n\n\n\n\n\n.upload-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.upload-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n background: var(--md-primary);\n color: var(--md-on-primary);\n border: none;\n border-radius: var(--md-corner-full);\n font-size: 0.875rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 44px;\n box-shadow: var(--md-elevation-1);\n}\n\n.upload-btn[_ngcontent-%COMP%]:hover {\n background: #3395C8;\n box-shadow: var(--md-elevation-2);\n}\n\n.upload-btn[_ngcontent-%COMP%]:active {\n background: #4BA5D4;\n transform: scale(0.98);\n}\n\n.upload-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n}\n\n.upload-info[_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.upload-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--md-primary);\n}\n\n.selected-file[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n background: var(--md-surface);\n border: 1px solid var(--md-outline-variant);\n border-radius: var(--md-corner-small);\n width: 100%;\n max-width: 400px;\n}\n\n.selected-file[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--md-primary);\n font-size: 1.2rem;\n}\n\n.selected-file[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 0.875rem;\n color: var(--md-on-surface);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.selected-file[_ngcontent-%COMP%] .remove-btn[_ngcontent-%COMP%] {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0.5rem;\n color: var(--md-on-surface-variant);\n transition: color 0.2s, background 0.2s;\n border-radius: var(--md-corner-extra-small);\n min-width: 32px;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.selected-file[_ngcontent-%COMP%] .remove-btn[_ngcontent-%COMP%]:hover {\n color: var(--md-error);\n background: var(--md-error-container);\n}\n\n.selected-file[_ngcontent-%COMP%] .remove-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1rem;\n color: inherit;\n}\n\n\n\n\n\n.url-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.url-section[_ngcontent-%COMP%] label[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--md-on-surface);\n}\n\n.url-input[_ngcontent-%COMP%] {\n padding: 0.875rem 1rem;\n border: 2px solid var(--md-outline-variant);\n border-radius: var(--md-corner-small);\n font-size: 1rem;\n color: var(--md-on-surface);\n background: var(--md-surface);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.url-input[_ngcontent-%COMP%]::placeholder {\n color: var(--md-on-surface-variant);\n}\n\n.url-input[_ngcontent-%COMP%]:hover {\n border-color: var(--md-primary);\n background: var(--md-surface-container-lowest);\n}\n\n.url-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.url-info[_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.url-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--md-primary);\n}\n\n\n\n\n\n.icon-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.icon-search-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n padding-bottom: 1rem;\n border-bottom: 1px solid var(--md-outline-variant);\n}\n\n\n\n.mj-search[_ngcontent-%COMP%] {\n position: relative;\n width: 100%;\n}\n\n.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-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 0.875rem 2.75rem 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}\n\n.mj-search-input[_ngcontent-%COMP%]::placeholder {\n color: var(--md-on-surface-variant);\n}\n\n.mj-search-input[_ngcontent-%COMP%]:hover {\n border-color: var(--md-primary);\n background: var(--md-surface-container-lowest);\n}\n\n.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.mj-search-clear[_ngcontent-%COMP%] {\n position: absolute;\n right: 0.5rem;\n top: 50%;\n transform: translateY(-50%);\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 0.5rem;\n color: var(--md-on-surface-variant);\n border-radius: var(--md-corner-full);\n min-width: 32px;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n}\n\n.mj-search-clear[_ngcontent-%COMP%]:hover {\n color: var(--md-on-primary);\n background: var(--md-primary);\n}\n\n.icon-filter-info[_ngcontent-%COMP%] {\n font-size: 0.875rem;\n color: var(--md-on-surface-variant);\n padding-left: 0.25rem;\n}\n\n.icon-categories-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n max-height: 350px;\n overflow-y: auto;\n padding-right: 0.5rem;\n -webkit-overflow-scrolling: touch;\n}\n\n.icon-category[_ngcontent-%COMP%] .category-title[_ngcontent-%COMP%] {\n font-size: 1rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0 0 0.75rem 0;\n padding-bottom: 0.5rem;\n border-bottom: 1px solid var(--md-outline-variant);\n}\n\n.icon-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(50px, 1fr));\n gap: 0.5rem;\n}\n\n.icon-option[_ngcontent-%COMP%] {\n aspect-ratio: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0.75rem;\n background: var(--md-surface);\n border: 2px solid var(--md-outline-variant);\n border-radius: var(--md-corner-small);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 44px;\n min-height: 44px;\n}\n\n.icon-option[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.5rem;\n color: var(--md-on-surface-variant);\n transition: color 0.2s;\n}\n\n.icon-option[_ngcontent-%COMP%]:hover {\n border-color: var(--md-primary);\n background: var(--md-primary-container);\n}\n\n.icon-option[_ngcontent-%COMP%]:hover i[_ngcontent-%COMP%] {\n color: var(--md-primary);\n}\n\n.icon-option[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\n}\n\n.icon-option.selected[_ngcontent-%COMP%] {\n border-color: var(--md-primary);\n background: var(--md-primary);\n box-shadow: var(--md-elevation-1);\n}\n\n.icon-option.selected[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--md-on-primary);\n}\n\n\n\n.icon-categories-container[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n}\n\n.icon-categories-container[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: var(--md-surface-container-low);\n border-radius: 3px;\n}\n\n.icon-categories-container[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--md-outline);\n border-radius: 3px;\n}\n\n.icon-categories-container[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--md-on-surface-variant);\n}\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n text-align: center;\n padding: 3rem 1.5rem;\n}\n\n.empty-state[_ngcontent-%COMP%] .empty-icon[_ngcontent-%COMP%] {\n font-size: 3rem;\n color: var(--md-outline-variant);\n margin-bottom: 1rem;\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.provider-section[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1.5rem;\n padding: 1rem 0;\n}\n\n.provider-info[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 1rem;\n background: var(--md-surface);\n border: 1px solid var(--md-outline-variant);\n border-radius: var(--md-corner-small);\n width: 100%;\n max-width: 500px;\n}\n\n.provider-info[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--md-primary);\n font-size: 1.2rem;\n flex-shrink: 0;\n}\n\n.provider-info[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 0.875rem;\n color: var(--md-on-surface-variant);\n}\n\n.sync-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 1rem 2rem;\n background: var(--md-primary);\n color: var(--md-on-primary);\n border: none;\n border-radius: var(--md-corner-full);\n font-size: 0.875rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 48px;\n box-shadow: var(--md-elevation-1);\n}\n\n.sync-btn[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: #3395C8;\n box-shadow: var(--md-elevation-2);\n}\n\n.sync-btn[_ngcontent-%COMP%]:active:not(:disabled) {\n background: #4BA5D4;\n transform: scale(0.98);\n}\n\n.sync-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.sync-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.2rem;\n}\n\n.provider-note[_ngcontent-%COMP%] {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n font-size: 0.875rem;\n color: var(--md-on-surface-variant);\n max-width: 500px;\n text-align: center;\n}\n\n.provider-note[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--md-secondary);\n margin-top: 0.1rem;\n flex-shrink: 0;\n}\n\n.provider-divider[_ngcontent-%COMP%] {\n border: none;\n border-top: 1px solid var(--md-outline-variant);\n width: 100%;\n max-width: 500px;\n margin: 0.5rem 0;\n}\n\n.revert-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1.5rem;\n background: var(--md-surface);\n color: var(--md-primary);\n border: 1px solid var(--md-outline);\n border-radius: var(--md-corner-full);\n font-size: 0.875rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 44px;\n}\n\n.revert-btn[_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.revert-btn[_ngcontent-%COMP%]:active:not(:disabled) {\n background: #005A8C;\n border-color: #005A8C;\n}\n\n.revert-btn[_ngcontent-%COMP%]:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n\n\n\n\n.action-buttons[_ngcontent-%COMP%] {\n display: flex;\n gap: 0.75rem;\n justify-content: flex-start;\n padding-top: 1rem;\n border-top: 1px solid var(--md-outline-variant);\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.mj-btn[_ngcontent-%COMP%]:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\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.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.mj-btn-ghost[_ngcontent-%COMP%] {\n background: transparent;\n color: var(--md-on-surface-variant);\n padding: 0.5rem;\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.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\n\nbutton[_ngcontent-%COMP%]:focus-visible, \ninput[_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@keyframes _ngcontent-%COMP%_fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n\n\n\n\n@media (max-width: 639px) {\n .user-profile-settings[_ngcontent-%COMP%] {\n padding: 1rem;\n }\n\n .tab-navigation[_ngcontent-%COMP%] .tab-btn[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 0.25rem;\n padding: 0.5rem;\n font-size: 0.75rem;\n }\n\n .tab-navigation[_ngcontent-%COMP%] .tab-btn[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 1.2rem;\n }\n\n .icon-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fill, minmax(45px, 1fr));\n }\n\n .icon-categories-container[_ngcontent-%COMP%] {\n max-height: 300px;\n }\n\n .action-buttons[_ngcontent-%COMP%] {\n flex-direction: column;\n }\n\n .action-buttons[_ngcontent-%COMP%] .mj-btn[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: center;\n }\n\n .provider-section[_ngcontent-%COMP%] {\n padding: 0.5rem 0;\n }\n\n .sync-btn[_ngcontent-%COMP%], \n .revert-btn[_ngcontent-%COMP%] {\n width: 100%;\n max-width: 300px;\n justify-content: center;\n }\n}\n\n@media (min-width: 640px) {\n .icon-search-container[_ngcontent-%COMP%] {\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n }\n\n .mj-search[_ngcontent-%COMP%] {\n max-width: 300px;\n }\n}\n\n@media (min-width: 768px) {\n .user-profile-settings[_ngcontent-%COMP%] {\n padding: 2rem;\n }\n\n .icon-categories-container[_ngcontent-%COMP%] {\n max-height: 400px;\n }\n}\n\n@media (min-width: 1024px) {\n .icon-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(auto-fill, minmax(56px, 1fr));\n }\n}"] });
|
|
688
821
|
}
|
|
689
822
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(UserProfileSettingsComponent, [{
|
|
690
823
|
type: Component,
|
|
691
|
-
args: [{ selector: 'mj-user-profile-settings', template: "<div class=\"user-profile-settings\">\n <div class=\"profile-header\">\n <h3>Avatar Settings</h3>\n <p class=\"description\">Customize your profile picture with an image, URL, or icon</p>\n </div>\n\n <!-- Error Message -->\n @if (errorMessage) {\n <div class=\"alert alert-error\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n <span>{{ errorMessage }}</span>\n <button class=\"close-btn\" (click)=\"errorMessage = ''\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n }\n\n <!-- Success Message -->\n @if (showSuccessMessage) {\n <div class=\"alert alert-success\">\n <i class=\"fa-solid fa-check-circle\"></i>\n <span>Avatar updated successfully!</span>\n </div>\n }\n\n <!-- Preview Section -->\n <div class=\"avatar-preview-section\">\n <div class=\"preview-label\">Preview</div>\n <div class=\"preview-container\">\n @if (previewUrl) {\n <img [src]=\"previewUrl\" alt=\"Avatar preview\" class=\"preview-image\" />\n } @else if (previewIconClass) {\n <div class=\"preview-icon-wrapper\">\n <i [class]=\"previewIconClass + ' preview-icon'\"></i>\n </div>\n } @else {\n <div class=\"preview-placeholder\">\n <i class=\"fa-solid fa-user\"></i>\n <span>No avatar selected</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Tab Navigation -->\n <div class=\"tab-navigation\">\n <button\n class=\"tab-btn\"\n [class.active]=\"selectedTab === 'upload'\"\n (click)=\"selectTab('upload')\"\n >\n <i class=\"fa-solid fa-upload\"></i>\n <span>Upload</span>\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"selectedTab === 'url'\"\n (click)=\"selectTab('url')\"\n >\n <i class=\"fa-solid fa-link\"></i>\n <span>URL</span>\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"selectedTab === 'icon'\"\n (click)=\"selectTab('icon')\"\n >\n <i class=\"fa-solid fa-icons\"></i>\n <span>Icon</span>\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"selectedTab === 'provider'\"\n (click)=\"selectTab('provider')\"\n >\n <i class=\"fa-brands fa-microsoft\"></i>\n <span>Sync</span>\n </button>\n </div>\n\n <!-- Tab Content -->\n <div class=\"tab-content\">\n <!-- Upload Tab -->\n @if (selectedTab === 'upload') {\n <div class=\"upload-section\">\n <input\n type=\"file\"\n #fileInput\n accept=\"image/png,image/jpeg,image/jpg,image/gif,image/webp\"\n (change)=\"onFileSelected($event)\"\n style=\"display: none\"\n />\n\n <button class=\"upload-btn\" (click)=\"fileInput.click()\">\n <i class=\"fa-solid fa-upload\"></i>\n Choose Image\n </button>\n\n <div class=\"upload-info\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Max 200KB \u2022 PNG, JPG, GIF, WEBP\n </div>\n\n @if (uploadedFileName) {\n <div class=\"selected-file\">\n <i class=\"fa-solid fa-file-image\"></i>\n <span>{{ uploadedFileName }}</span>\n <button class=\"remove-btn\" (click)=\"clearUpload()\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n </div>\n }\n </div>\n }\n\n <!-- URL Tab -->\n @if (selectedTab === 'url') {\n <div class=\"url-section\">\n <label for=\"imageUrl\">Image URL</label>\n <input\n type=\"text\"\n id=\"imageUrl\"\n class=\"url-input\"\n placeholder=\"https://example.com/avatar.jpg\"\n [(ngModel)]=\"imageUrlInput\"\n (input)=\"onUrlChange()\"\n />\n <div class=\"url-info\">\n <i class=\"fa-solid fa-info-circle\"></i>\n Enter a URL to an image hosted online\n </div>\n </div>\n }\n\n <!-- Icon Tab -->\n @if (selectedTab === 'icon') {\n <div class=\"icon-section\">\n @for (category of iconCategories; track category.name) {\n <div class=\"icon-category\">\n <h4 class=\"category-title\">{{ category.name }}</h4>\n <div class=\"icon-grid\">\n @for (icon of category.icons; track icon) {\n <button\n class=\"icon-option\"\n [class.selected]=\"isIconSelected(icon)\"\n (click)=\"selectIcon(icon)\"\n [title]=\"icon\"\n >\n <i [class]=\"icon\"></i>\n </button>\n }\n </div>\n </div>\n }\n </div>\n }\n\n <!-- Provider Sync Tab -->\n @if (selectedTab === 'provider') {\n <div class=\"provider-section\">\n <div class=\"provider-info\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <p>Sync your avatar from your authentication provider account</p>\n </div>\n\n <button\n class=\"sync-btn\"\n (click)=\"syncFromProvider()\"\n [disabled]=\"isSaving\"\n >\n <i class=\"fa-brands fa-microsoft\"></i>\n @if (isSaving) {\n <span>Syncing...</span>\n } @else {\n <span>Sync from Microsoft Account</span>\n }\n </button>\n\n <div class=\"provider-note\">\n <i class=\"fa-solid fa-lightbulb\"></i>\n <small>This will download your profile photo from Microsoft and save it to your profile</small>\n </div>\n\n <div style=\"border-top: 1px solid #ddd; width: 100%; max-width: 500px; margin: 1rem 0;\"></div>\n\n <button\n class=\"revert-btn\"\n (click)=\"revertToDefault()\"\n [disabled]=\"isSaving\"\n >\n <i class=\"fa-solid fa-rotate-left\"></i>\n @if (isSaving) {\n <span>Reverting...</span>\n } @else {\n <span>Revert to Default</span>\n }\n </button>\n\n <div class=\"provider-note\">\n <i class=\"fa-solid fa-info-circle\"></i>\n <small>Clears your avatar settings and restores the automatic sync from your auth provider</small>\n </div>\n </div>\n }\n </div>\n\n <!-- Action Buttons -->\n <div class=\"action-buttons\">\n <button\n class=\"btn btn-secondary\"\n (click)=\"cancel()\"\n [disabled]=\"isSaving\"\n >\n Cancel\n </button>\n <button\n class=\"btn btn-primary\"\n (click)=\"save()\"\n [disabled]=\"isSaving || selectedTab === 'provider'\"\n >\n @if (isSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Saving...</span>\n } @else {\n <i class=\"fa-solid fa-save\"></i>\n <span>Save Changes</span>\n }\n </button>\n </div>\n</div>\n", styles: [".user-profile-settings {\n max-width: 800px;\n margin: 0 auto;\n padding: 1.5rem;\n}\n\n.user-profile-settings .profile-header {\n margin-bottom: 1.5rem;\n}\n\n.user-profile-settings .profile-header h3 {\n margin: 0 0 0.5rem 0;\n font-size: 1.5rem;\n font-weight: 600;\n color: #1a1a1a;\n}\n\n.user-profile-settings .profile-header .description {\n margin: 0;\n color: #666;\n font-size: 0.9rem;\n}\n\n/* Alert Messages */\n.user-profile-settings .alert {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n border-radius: 6px;\n margin-bottom: 1rem;\n font-size: 0.9rem;\n}\n\n.user-profile-settings .alert i {\n flex-shrink: 0;\n}\n\n.user-profile-settings .alert span {\n flex: 1;\n}\n\n.user-profile-settings .alert .close-btn {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0.25rem;\n color: inherit;\n opacity: 0.7;\n transition: opacity 0.2s;\n}\n\n.user-profile-settings .alert .close-btn:hover {\n opacity: 1;\n}\n\n.user-profile-settings .alert.alert-error {\n background-color: #fee;\n border: 1px solid #fcc;\n color: #c33;\n}\n\n.user-profile-settings .alert.alert-success {\n background-color: #efe;\n border: 1px solid #cfc;\n color: #3c3;\n}\n\n/* Avatar Preview */\n.user-profile-settings .avatar-preview-section {\n display: flex;\n flex-direction: column;\n align-items: center;\n margin-bottom: 2rem;\n padding: 1.5rem;\n background: #f8f9fa;\n border-radius: 8px;\n}\n\n.user-profile-settings .avatar-preview-section .preview-label {\n font-size: 0.85rem;\n font-weight: 600;\n color: #666;\n margin-bottom: 1rem;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.user-profile-settings .avatar-preview-section .preview-container {\n width: 120px;\n height: 120px;\n border-radius: 50%;\n overflow: hidden;\n background: white;\n border: 3px solid #e0e0e0;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.user-profile-settings .avatar-preview-section .preview-container .preview-image {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.user-profile-settings .avatar-preview-section .preview-container .preview-icon-wrapper {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n}\n\n.user-profile-settings .avatar-preview-section .preview-container .preview-icon-wrapper .preview-icon {\n font-size: 3.5rem;\n color: #666;\n}\n\n.user-profile-settings .avatar-preview-section .preview-container .preview-placeholder {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.5rem;\n color: #999;\n}\n\n.user-profile-settings .avatar-preview-section .preview-container .preview-placeholder i {\n font-size: 2.5rem;\n}\n\n.user-profile-settings .avatar-preview-section .preview-container .preview-placeholder span {\n font-size: 0.75rem;\n}\n\n/* Tab Navigation */\n.user-profile-settings .tab-navigation {\n display: flex;\n gap: 0.5rem;\n margin-bottom: 1.5rem;\n border-bottom: 2px solid #e0e0e0;\n}\n\n.user-profile-settings .tab-navigation .tab-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n background: none;\n border: none;\n border-bottom: 3px solid transparent;\n cursor: pointer;\n font-size: 0.9rem;\n font-weight: 500;\n color: #666;\n transition: all 0.2s;\n margin-bottom: -2px;\n}\n\n.user-profile-settings .tab-navigation .tab-btn i {\n font-size: 1rem;\n}\n\n.user-profile-settings .tab-navigation .tab-btn:hover {\n color: #333;\n background: #f8f9fa;\n}\n\n.user-profile-settings .tab-navigation .tab-btn.active {\n color: #007bff;\n border-bottom-color: #007bff;\n background: #f8f9fa;\n}\n\n/* Tab Content */\n.user-profile-settings .tab-content {\n min-height: 300px;\n padding: 1.5rem;\n background: #f8f9fa;\n border-radius: 8px;\n margin-bottom: 1.5rem;\n}\n\n/* Upload Section */\n.user-profile-settings .upload-section {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.user-profile-settings .upload-section .upload-btn {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n background: #007bff;\n color: white;\n border: none;\n border-radius: 6px;\n font-size: 0.95rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s;\n}\n\n.user-profile-settings .upload-section .upload-btn:hover {\n background: #0056b3;\n}\n\n.user-profile-settings .upload-section .upload-btn i {\n font-size: 1rem;\n}\n\n.user-profile-settings .upload-section .upload-info {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n color: #666;\n font-size: 0.85rem;\n}\n\n.user-profile-settings .upload-section .upload-info i {\n color: #007bff;\n}\n\n.user-profile-settings .upload-section .selected-file {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n background: white;\n border: 1px solid #ddd;\n border-radius: 6px;\n width: 100%;\n max-width: 400px;\n}\n\n.user-profile-settings .upload-section .selected-file i {\n color: #007bff;\n font-size: 1.2rem;\n}\n\n.user-profile-settings .upload-section .selected-file span {\n flex: 1;\n font-size: 0.9rem;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.user-profile-settings .upload-section .selected-file .remove-btn {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0.25rem;\n color: #999;\n transition: color 0.2s;\n}\n\n.user-profile-settings .upload-section .selected-file .remove-btn:hover {\n color: #c33;\n}\n\n.user-profile-settings .upload-section .selected-file .remove-btn i {\n font-size: 1rem;\n color: inherit;\n}\n\n/* URL Section */\n.user-profile-settings .url-section {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.user-profile-settings .url-section label {\n font-weight: 600;\n color: #333;\n font-size: 0.9rem;\n}\n\n.user-profile-settings .url-section .url-input {\n padding: 0.75rem;\n border: 1px solid #ddd;\n border-radius: 6px;\n font-size: 0.95rem;\n transition: border-color 0.2s;\n}\n\n.user-profile-settings .url-section .url-input:focus {\n outline: none;\n border-color: #007bff;\n}\n\n.user-profile-settings .url-section .url-info {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n color: #666;\n font-size: 0.85rem;\n}\n\n.user-profile-settings .url-section .url-info i {\n color: #007bff;\n}\n\n/* Icon Section */\n.user-profile-settings .icon-section {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n max-height: 400px;\n overflow-y: auto;\n padding-right: 0.5rem;\n}\n\n.user-profile-settings .icon-section .icon-category .category-title {\n font-size: 0.9rem;\n font-weight: 600;\n color: #333;\n margin: 0 0 0.75rem 0;\n padding-bottom: 0.5rem;\n border-bottom: 1px solid #ddd;\n}\n\n.user-profile-settings .icon-section .icon-category .icon-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(50px, 1fr));\n gap: 0.5rem;\n}\n\n.user-profile-settings .icon-section .icon-category .icon-grid .icon-option {\n aspect-ratio: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0.75rem;\n background: white;\n border: 2px solid #ddd;\n border-radius: 6px;\n cursor: pointer;\n transition: all 0.2s;\n}\n\n.user-profile-settings .icon-section .icon-category .icon-grid .icon-option i {\n font-size: 1.5rem;\n color: #666;\n}\n\n.user-profile-settings .icon-section .icon-category .icon-grid .icon-option:hover {\n border-color: #007bff;\n background: #f0f8ff;\n}\n\n.user-profile-settings .icon-section .icon-category .icon-grid .icon-option:hover i {\n color: #007bff;\n}\n\n.user-profile-settings .icon-section .icon-category .icon-grid .icon-option.selected {\n border-color: #007bff;\n background: #007bff;\n}\n\n.user-profile-settings .icon-section .icon-category .icon-grid .icon-option.selected i {\n color: white;\n}\n\n/* Custom scrollbar */\n.user-profile-settings .icon-section::-webkit-scrollbar {\n width: 6px;\n}\n\n.user-profile-settings .icon-section::-webkit-scrollbar-track {\n background: #f1f1f1;\n border-radius: 3px;\n}\n\n.user-profile-settings .icon-section::-webkit-scrollbar-thumb {\n background: #ccc;\n border-radius: 3px;\n}\n\n.user-profile-settings .icon-section::-webkit-scrollbar-thumb:hover {\n background: #999;\n}\n\n/* Provider Section */\n.user-profile-settings .provider-section {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1.5rem;\n padding: 2rem 1rem;\n}\n\n.user-profile-settings .provider-section .provider-info {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 1rem;\n background: white;\n border: 1px solid #ddd;\n border-radius: 6px;\n width: 100%;\n max-width: 500px;\n}\n\n.user-profile-settings .provider-section .provider-info i {\n color: #007bff;\n font-size: 1.2rem;\n flex-shrink: 0;\n}\n\n.user-profile-settings .provider-section .provider-info p {\n margin: 0;\n color: #666;\n font-size: 0.9rem;\n}\n\n.user-profile-settings .provider-section .sync-btn {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 1rem 2rem;\n background: #0078d4;\n color: white;\n border: none;\n border-radius: 6px;\n font-size: 1rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s;\n}\n\n.user-profile-settings .provider-section .sync-btn:hover:not(:disabled) {\n background: #005a9e;\n}\n\n.user-profile-settings .provider-section .sync-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.user-profile-settings .provider-section .sync-btn i {\n font-size: 1.2rem;\n}\n\n.user-profile-settings .provider-section .provider-note {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n color: #666;\n font-size: 0.85rem;\n max-width: 500px;\n text-align: center;\n}\n\n.user-profile-settings .provider-section .provider-note i {\n color: #ffc107;\n margin-top: 0.1rem;\n flex-shrink: 0;\n}\n\n.user-profile-settings .provider-section .revert-btn {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1.5rem;\n background: #6c757d;\n color: white;\n border: none;\n border-radius: 6px;\n font-size: 0.95rem;\n font-weight: 500;\n cursor: pointer;\n transition: background 0.2s;\n}\n\n.user-profile-settings .provider-section .revert-btn:hover:not(:disabled) {\n background: #5a6268;\n}\n\n.user-profile-settings .provider-section .revert-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.user-profile-settings .provider-section .revert-btn i {\n font-size: 1rem;\n}\n\n/* Action Buttons */\n.user-profile-settings .action-buttons {\n display: flex;\n gap: 1rem;\n justify-content: flex-end;\n padding-top: 1rem;\n border-top: 1px solid #e0e0e0;\n}\n\n.user-profile-settings .action-buttons .btn {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n border: none;\n border-radius: 6px;\n font-size: 0.95rem;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s;\n}\n\n.user-profile-settings .action-buttons .btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.user-profile-settings .action-buttons .btn i {\n font-size: 0.9rem;\n}\n\n.user-profile-settings .action-buttons .btn i.fa-spin {\n animation: spin 1s linear infinite;\n}\n\n.user-profile-settings .action-buttons .btn.btn-secondary {\n background: #6c757d;\n color: white;\n}\n\n.user-profile-settings .action-buttons .btn.btn-secondary:hover:not(:disabled) {\n background: #5a6268;\n}\n\n.user-profile-settings .action-buttons .btn.btn-primary {\n background: #28a745;\n color: white;\n}\n\n.user-profile-settings .action-buttons .btn.btn-primary:hover:not(:disabled) {\n background: #218838;\n}\n\n@keyframes spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\n/* Responsive Design */\n@media (max-width: 768px) {\n .user-profile-settings {\n padding: 1rem;\n }\n\n .user-profile-settings .tab-navigation .tab-btn {\n flex-direction: column;\n gap: 0.25rem;\n padding: 0.5rem;\n font-size: 0.75rem;\n }\n\n .user-profile-settings .tab-navigation .tab-btn i {\n font-size: 1.2rem;\n }\n\n .user-profile-settings .tab-navigation .tab-btn span {\n font-size: 0.7rem;\n }\n\n .user-profile-settings .icon-section .icon-category .icon-grid {\n grid-template-columns: repeat(auto-fill, minmax(45px, 1fr));\n }\n\n .user-profile-settings .action-buttons {\n flex-direction: column-reverse;\n }\n\n .user-profile-settings .action-buttons .btn {\n width: 100%;\n justify-content: center;\n }\n}\n"] }]
|
|
824
|
+
args: [{ selector: 'mj-user-profile-settings', template: "<div class=\"user-profile-settings\">\n <!-- Header Section -->\n <div class=\"profile-header\">\n <h3>Avatar Settings</h3>\n <p class=\"description\">Customize your profile picture with an image, URL, or icon</p>\n </div>\n\n <!-- Error Message -->\n @if (errorMessage) {\n <div class=\"alert alert-error\" role=\"alert\">\n <i class=\"fa-solid fa-exclamation-triangle\" aria-hidden=\"true\"></i>\n <span>{{ errorMessage }}</span>\n <button class=\"close-btn\" (click)=\"errorMessage = ''\" aria-label=\"Dismiss error\">\n <i class=\"fa-solid fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n\n <!-- Success Message -->\n @if (showSuccessMessage) {\n <div class=\"alert alert-success\" role=\"status\" aria-live=\"polite\">\n <i class=\"fa-solid fa-check-circle\" aria-hidden=\"true\"></i>\n <span>Avatar updated successfully!</span>\n </div>\n }\n\n <!-- Avatar Preview Section -->\n <div class=\"avatar-preview-section\">\n <div class=\"preview-label\">Preview</div>\n <div class=\"preview-container\">\n @if (previewUrl) {\n <img [src]=\"previewUrl\" alt=\"Avatar preview\" class=\"preview-image\" />\n } @else if (previewIconClass) {\n <div class=\"preview-icon-wrapper\">\n <i [class]=\"previewIconClass + ' preview-icon'\" aria-hidden=\"true\"></i>\n </div>\n } @else {\n <div class=\"preview-placeholder\">\n <i class=\"fa-solid fa-user\" aria-hidden=\"true\"></i>\n <span>No avatar selected</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Tab Navigation -->\n <div class=\"tab-navigation\" role=\"tablist\" aria-label=\"Avatar customization options\">\n <button\n class=\"tab-btn\"\n [class.active]=\"selectedTab === 'upload'\"\n (click)=\"selectTab('upload')\"\n role=\"tab\"\n [attr.aria-selected]=\"selectedTab === 'upload'\"\n aria-controls=\"panel-upload\"\n >\n <i class=\"fa-solid fa-upload\" aria-hidden=\"true\"></i>\n <span>Upload</span>\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"selectedTab === 'url'\"\n (click)=\"selectTab('url')\"\n role=\"tab\"\n [attr.aria-selected]=\"selectedTab === 'url'\"\n aria-controls=\"panel-url\"\n >\n <i class=\"fa-solid fa-link\" aria-hidden=\"true\"></i>\n <span>URL</span>\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"selectedTab === 'icon'\"\n (click)=\"selectTab('icon')\"\n role=\"tab\"\n [attr.aria-selected]=\"selectedTab === 'icon'\"\n aria-controls=\"panel-icon\"\n >\n <i class=\"fa-solid fa-icons\" aria-hidden=\"true\"></i>\n <span>Icon</span>\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"selectedTab === 'provider'\"\n (click)=\"selectTab('provider')\"\n role=\"tab\"\n [attr.aria-selected]=\"selectedTab === 'provider'\"\n aria-controls=\"panel-provider\"\n >\n <i class=\"fa-brands fa-microsoft\" aria-hidden=\"true\"></i>\n <span>Sync</span>\n </button>\n </div>\n\n <!-- Tab Content -->\n <div class=\"tab-content\">\n <!-- Upload Tab -->\n @if (selectedTab === 'upload') {\n <div class=\"upload-section\" id=\"panel-upload\" role=\"tabpanel\">\n <input\n type=\"file\"\n #fileInput\n accept=\"image/png,image/jpeg,image/jpg,image/gif,image/webp\"\n (change)=\"onFileSelected($event)\"\n style=\"display: none\"\n />\n\n <button class=\"upload-btn\" (click)=\"fileInput.click()\">\n <i class=\"fa-solid fa-upload\" aria-hidden=\"true\"></i>\n Choose Image\n </button>\n\n <div class=\"upload-info\">\n <i class=\"fa-solid fa-info-circle\" aria-hidden=\"true\"></i>\n Max 200KB - PNG, JPG, GIF, WEBP\n </div>\n\n @if (uploadedFileName) {\n <div class=\"selected-file\">\n <i class=\"fa-solid fa-file-image\" aria-hidden=\"true\"></i>\n <span>{{ uploadedFileName }}</span>\n <button class=\"remove-btn\" (click)=\"clearUpload()\" aria-label=\"Remove selected file\">\n <i class=\"fa-solid fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n </div>\n }\n\n <!-- URL Tab -->\n @if (selectedTab === 'url') {\n <div class=\"url-section\" id=\"panel-url\" role=\"tabpanel\">\n <label for=\"imageUrl\">Image URL</label>\n <input\n type=\"text\"\n id=\"imageUrl\"\n class=\"url-input\"\n placeholder=\"https://example.com/avatar.jpg\"\n [(ngModel)]=\"imageUrlInput\"\n (input)=\"onUrlChange()\"\n />\n <div class=\"url-info\">\n <i class=\"fa-solid fa-info-circle\" aria-hidden=\"true\"></i>\n Enter a URL to an image hosted online\n </div>\n </div>\n }\n\n <!-- Icon Tab -->\n @if (selectedTab === 'icon') {\n <div class=\"icon-section\" id=\"panel-icon\" role=\"tabpanel\">\n <!-- Icon Search -->\n <div class=\"icon-search-container\">\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 icons by name...\"\n [value]=\"iconSearchTerm\"\n (input)=\"onIconSearchChange($event)\"\n aria-label=\"Search icons\"\n />\n @if (iconSearchTerm) {\n <button\n class=\"mj-search-clear\"\n (click)=\"clearIconSearch()\"\n aria-label=\"Clear search\"\n >\n <i class=\"fa-solid fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n <div class=\"icon-filter-info\">\n {{ totalFilteredIcons }} icon{{ totalFilteredIcons !== 1 ? 's' : '' }} found\n </div>\n </div>\n\n <!-- Icon Categories -->\n <div class=\"icon-categories-container\">\n @if (filteredIconCategories.length > 0) {\n @for (category of filteredIconCategories; track category.name) {\n <div class=\"icon-category\">\n <h4 class=\"category-title\">{{ category.name }}</h4>\n <div class=\"icon-grid\" role=\"radiogroup\" [attr.aria-label]=\"category.name + ' icons'\">\n @for (icon of category.icons; track icon) {\n <button\n class=\"icon-option\"\n [class.selected]=\"isIconSelected(icon)\"\n (click)=\"selectIcon(icon)\"\n [title]=\"extractIconName(icon)\"\n role=\"radio\"\n [attr.aria-checked]=\"isIconSelected(icon)\"\n [attr.aria-label]=\"extractIconName(icon) + ' icon'\"\n >\n <i [class]=\"icon\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n </div>\n }\n } @else {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-search empty-icon\" aria-hidden=\"true\"></i>\n <p class=\"empty-text\">No icons found</p>\n <p class=\"empty-subtext\">Try a different search term</p>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Provider Sync Tab -->\n @if (selectedTab === 'provider') {\n <div class=\"provider-section\" id=\"panel-provider\" role=\"tabpanel\">\n <div class=\"provider-info\">\n <i class=\"fa-solid fa-info-circle\" aria-hidden=\"true\"></i>\n <p>Sync your avatar from your authentication provider account</p>\n </div>\n\n <button\n class=\"sync-btn\"\n (click)=\"syncFromProvider()\"\n [disabled]=\"isSaving\"\n >\n <i class=\"fa-brands fa-microsoft\" aria-hidden=\"true\"></i>\n @if (isSaving) {\n <span>Syncing...</span>\n } @else {\n <span>Sync from Microsoft Account</span>\n }\n </button>\n\n <div class=\"provider-note\">\n <i class=\"fa-solid fa-lightbulb\" aria-hidden=\"true\"></i>\n <small>This will download your profile photo from Microsoft and save it to your profile</small>\n </div>\n\n <hr class=\"provider-divider\" />\n\n <button\n class=\"revert-btn\"\n (click)=\"revertToDefault()\"\n [disabled]=\"isSaving\"\n >\n <i class=\"fa-solid fa-rotate-left\" aria-hidden=\"true\"></i>\n @if (isSaving) {\n <span>Reverting...</span>\n } @else {\n <span>Revert to Default</span>\n }\n </button>\n\n <div class=\"provider-note\">\n <i class=\"fa-solid fa-info-circle\" aria-hidden=\"true\"></i>\n <small>Clears your avatar settings and restores the automatic sync from your auth provider</small>\n </div>\n </div>\n }\n </div>\n\n <!-- Action Buttons -->\n <div class=\"action-buttons\">\n <button\n class=\"mj-btn mj-btn-primary\"\n (click)=\"save()\"\n [disabled]=\"isSaving || selectedTab === 'provider'\"\n >\n @if (isSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n <span>Saving...</span>\n } @else {\n <i class=\"fa-solid fa-save\" aria-hidden=\"true\"></i>\n <span>Save Changes</span>\n }\n </button>\n <button\n class=\"mj-btn mj-btn-secondary\"\n (click)=\"cancel()\"\n [disabled]=\"isSaving\"\n >\n Cancel\n </button>\n </div>\n</div>\n", styles: ["/* =============================================================================\n User Profile Settings Component - Material Design 3\n Following MD3 Design System Guidelines\n ============================================================================= */\n\n/* MD3 Color Tokens */\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 (Box Shadows) */\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 element must be scrollable */\n display: block;\n height: 100%;\n width: 100%;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n/* -----------------------------------------------------------------------------\n Container & Layout\n ----------------------------------------------------------------------------- */\n.user-profile-settings {\n max-width: 800px;\n margin: 0 auto;\n padding: 1.5rem;\n background: var(--md-surface);\n min-height: 100%;\n}\n\n/* -----------------------------------------------------------------------------\n Header Section\n ----------------------------------------------------------------------------- */\n.profile-header {\n margin-bottom: 1.5rem;\n}\n\n.profile-header h3 {\n margin: 0 0 0.5rem 0;\n font-size: 1.75rem;\n font-weight: 600;\n color: var(--md-on-surface);\n}\n\n.profile-header .description {\n margin: 0;\n font-size: 1rem;\n color: var(--md-on-surface-variant);\n}\n\n/* -----------------------------------------------------------------------------\n Alert Messages\n ----------------------------------------------------------------------------- */\n.alert {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n border-radius: var(--md-corner-small);\n margin-bottom: 1rem;\n font-size: 0.875rem;\n font-weight: 500;\n animation: fadeIn 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.alert i {\n flex-shrink: 0;\n font-size: 1rem;\n}\n\n.alert span {\n flex: 1;\n}\n\n.alert .close-btn {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0.25rem;\n color: inherit;\n opacity: 0.7;\n transition: opacity 0.2s;\n border-radius: var(--md-corner-extra-small);\n min-width: 32px;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.alert .close-btn:hover {\n opacity: 1;\n}\n\n.alert.alert-error {\n background: var(--md-error-container);\n color: var(--md-on-error-container);\n}\n\n.alert.alert-success {\n background: var(--md-tertiary-container);\n color: #1B5E20;\n}\n\n/* -----------------------------------------------------------------------------\n Avatar Preview Section\n ----------------------------------------------------------------------------- */\n.avatar-preview-section {\n display: flex;\n flex-direction: column;\n align-items: center;\n margin-bottom: 2rem;\n padding: 1.5rem;\n background: var(--md-surface-container-low);\n border-radius: var(--md-corner-medium);\n border: 1px solid var(--md-outline-variant);\n}\n\n.preview-label {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--md-on-surface-variant);\n margin-bottom: 1rem;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.preview-container {\n width: 120px;\n height: 120px;\n border-radius: 50%;\n overflow: hidden;\n background: var(--md-surface);\n border: 3px solid var(--md-outline-variant);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: border-color 0.2s;\n}\n\n.preview-container:has(.preview-image),\n.preview-container:has(.preview-icon) {\n border-color: var(--md-primary);\n}\n\n.preview-image {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.preview-icon-wrapper {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n background: var(--md-primary-container);\n}\n\n.preview-icon {\n font-size: 3.5rem;\n color: var(--md-primary);\n}\n\n.preview-placeholder {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.5rem;\n color: var(--md-on-surface-variant);\n}\n\n.preview-placeholder i {\n font-size: 2.5rem;\n}\n\n.preview-placeholder span {\n font-size: 0.875rem;\n}\n\n/* -----------------------------------------------------------------------------\n Tab Navigation\n ----------------------------------------------------------------------------- */\n.tab-navigation {\n display: flex;\n gap: 0.25rem;\n margin-bottom: 1.5rem;\n border-bottom: 2px solid var(--md-outline-variant);\n background: var(--md-surface);\n}\n\n.tab-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n background: transparent;\n border: none;\n border-bottom: 3px solid transparent;\n cursor: pointer;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--md-on-surface-variant);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n margin-bottom: -2px;\n min-height: 48px;\n}\n\n.tab-btn i {\n font-size: 1rem;\n}\n\n.tab-btn:hover {\n color: var(--md-on-surface);\n background: var(--md-surface-container);\n}\n\n.tab-btn:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: -2px;\n}\n\n.tab-btn.active {\n color: var(--md-primary);\n border-bottom-color: var(--md-primary);\n background: var(--md-primary-container);\n}\n\n/* -----------------------------------------------------------------------------\n Tab Content\n ----------------------------------------------------------------------------- */\n.tab-content {\n min-height: 300px;\n padding: 1.5rem;\n background: var(--md-surface-container);\n border-radius: var(--md-corner-medium);\n margin-bottom: 1.5rem;\n border: 1px solid var(--md-outline-variant);\n}\n\n/* -----------------------------------------------------------------------------\n Upload Section\n ----------------------------------------------------------------------------- */\n.upload-section {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.upload-btn {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n background: var(--md-primary);\n color: var(--md-on-primary);\n border: none;\n border-radius: var(--md-corner-full);\n font-size: 0.875rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 44px;\n box-shadow: var(--md-elevation-1);\n}\n\n.upload-btn:hover {\n background: #3395C8;\n box-shadow: var(--md-elevation-2);\n}\n\n.upload-btn:active {\n background: #4BA5D4;\n transform: scale(0.98);\n}\n\n.upload-btn i {\n font-size: 1rem;\n}\n\n.upload-info {\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.upload-info i {\n color: var(--md-primary);\n}\n\n.selected-file {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n background: var(--md-surface);\n border: 1px solid var(--md-outline-variant);\n border-radius: var(--md-corner-small);\n width: 100%;\n max-width: 400px;\n}\n\n.selected-file i {\n color: var(--md-primary);\n font-size: 1.2rem;\n}\n\n.selected-file span {\n flex: 1;\n font-size: 0.875rem;\n color: var(--md-on-surface);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.selected-file .remove-btn {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0.5rem;\n color: var(--md-on-surface-variant);\n transition: color 0.2s, background 0.2s;\n border-radius: var(--md-corner-extra-small);\n min-width: 32px;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.selected-file .remove-btn:hover {\n color: var(--md-error);\n background: var(--md-error-container);\n}\n\n.selected-file .remove-btn i {\n font-size: 1rem;\n color: inherit;\n}\n\n/* -----------------------------------------------------------------------------\n URL Section\n ----------------------------------------------------------------------------- */\n.url-section {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.url-section label {\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--md-on-surface);\n}\n\n.url-input {\n padding: 0.875rem 1rem;\n border: 2px solid var(--md-outline-variant);\n border-radius: var(--md-corner-small);\n font-size: 1rem;\n color: var(--md-on-surface);\n background: var(--md-surface);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.url-input::placeholder {\n color: var(--md-on-surface-variant);\n}\n\n.url-input:hover {\n border-color: var(--md-primary);\n background: var(--md-surface-container-lowest);\n}\n\n.url-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.url-info {\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.url-info i {\n color: var(--md-primary);\n}\n\n/* -----------------------------------------------------------------------------\n Icon Section (with Search)\n ----------------------------------------------------------------------------- */\n.icon-section {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.icon-search-container {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n padding-bottom: 1rem;\n border-bottom: 1px solid var(--md-outline-variant);\n}\n\n/* Search Component - MD3 Pattern */\n.mj-search {\n position: relative;\n width: 100%;\n}\n\n.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-input {\n width: 100%;\n padding: 0.875rem 2.75rem 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}\n\n.mj-search-input::placeholder {\n color: var(--md-on-surface-variant);\n}\n\n.mj-search-input:hover {\n border-color: var(--md-primary);\n background: var(--md-surface-container-lowest);\n}\n\n.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.mj-search-clear {\n position: absolute;\n right: 0.5rem;\n top: 50%;\n transform: translateY(-50%);\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 0.5rem;\n color: var(--md-on-surface-variant);\n border-radius: var(--md-corner-full);\n min-width: 32px;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n}\n\n.mj-search-clear:hover {\n color: var(--md-on-primary);\n background: var(--md-primary);\n}\n\n.icon-filter-info {\n font-size: 0.875rem;\n color: var(--md-on-surface-variant);\n padding-left: 0.25rem;\n}\n\n.icon-categories-container {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n max-height: 350px;\n overflow-y: auto;\n padding-right: 0.5rem;\n -webkit-overflow-scrolling: touch;\n}\n\n.icon-category .category-title {\n font-size: 1rem;\n font-weight: 600;\n color: var(--md-on-surface);\n margin: 0 0 0.75rem 0;\n padding-bottom: 0.5rem;\n border-bottom: 1px solid var(--md-outline-variant);\n}\n\n.icon-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(50px, 1fr));\n gap: 0.5rem;\n}\n\n.icon-option {\n aspect-ratio: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0.75rem;\n background: var(--md-surface);\n border: 2px solid var(--md-outline-variant);\n border-radius: var(--md-corner-small);\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 44px;\n min-height: 44px;\n}\n\n.icon-option i {\n font-size: 1.5rem;\n color: var(--md-on-surface-variant);\n transition: color 0.2s;\n}\n\n.icon-option:hover {\n border-color: var(--md-primary);\n background: var(--md-primary-container);\n}\n\n.icon-option:hover i {\n color: var(--md-primary);\n}\n\n.icon-option:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\n}\n\n.icon-option.selected {\n border-color: var(--md-primary);\n background: var(--md-primary);\n box-shadow: var(--md-elevation-1);\n}\n\n.icon-option.selected i {\n color: var(--md-on-primary);\n}\n\n/* Custom Scrollbar for Icon Section */\n.icon-categories-container::-webkit-scrollbar {\n width: 6px;\n}\n\n.icon-categories-container::-webkit-scrollbar-track {\n background: var(--md-surface-container-low);\n border-radius: 3px;\n}\n\n.icon-categories-container::-webkit-scrollbar-thumb {\n background: var(--md-outline);\n border-radius: 3px;\n}\n\n.icon-categories-container::-webkit-scrollbar-thumb:hover {\n background: var(--md-on-surface-variant);\n}\n\n/* Empty State */\n.empty-state {\n text-align: center;\n padding: 3rem 1.5rem;\n}\n\n.empty-state .empty-icon {\n font-size: 3rem;\n color: var(--md-outline-variant);\n margin-bottom: 1rem;\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 Provider Section\n ----------------------------------------------------------------------------- */\n.provider-section {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1.5rem;\n padding: 1rem 0;\n}\n\n.provider-info {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 1rem;\n background: var(--md-surface);\n border: 1px solid var(--md-outline-variant);\n border-radius: var(--md-corner-small);\n width: 100%;\n max-width: 500px;\n}\n\n.provider-info i {\n color: var(--md-primary);\n font-size: 1.2rem;\n flex-shrink: 0;\n}\n\n.provider-info p {\n margin: 0;\n font-size: 0.875rem;\n color: var(--md-on-surface-variant);\n}\n\n.sync-btn {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 1rem 2rem;\n background: var(--md-primary);\n color: var(--md-on-primary);\n border: none;\n border-radius: var(--md-corner-full);\n font-size: 0.875rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 48px;\n box-shadow: var(--md-elevation-1);\n}\n\n.sync-btn:hover:not(:disabled) {\n background: #3395C8;\n box-shadow: var(--md-elevation-2);\n}\n\n.sync-btn:active:not(:disabled) {\n background: #4BA5D4;\n transform: scale(0.98);\n}\n\n.sync-btn:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.sync-btn i {\n font-size: 1.2rem;\n}\n\n.provider-note {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n font-size: 0.875rem;\n color: var(--md-on-surface-variant);\n max-width: 500px;\n text-align: center;\n}\n\n.provider-note i {\n color: var(--md-secondary);\n margin-top: 0.1rem;\n flex-shrink: 0;\n}\n\n.provider-divider {\n border: none;\n border-top: 1px solid var(--md-outline-variant);\n width: 100%;\n max-width: 500px;\n margin: 0.5rem 0;\n}\n\n.revert-btn {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1.5rem;\n background: var(--md-surface);\n color: var(--md-primary);\n border: 1px solid var(--md-outline);\n border-radius: var(--md-corner-full);\n font-size: 0.875rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 44px;\n}\n\n.revert-btn:hover:not(:disabled) {\n background: var(--md-primary);\n color: var(--md-on-primary);\n border-color: var(--md-primary);\n}\n\n.revert-btn:active:not(:disabled) {\n background: #005A8C;\n border-color: #005A8C;\n}\n\n.revert-btn:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n/* -----------------------------------------------------------------------------\n Action Buttons\n ----------------------------------------------------------------------------- */\n.action-buttons {\n display: flex;\n gap: 0.75rem;\n justify-content: flex-start;\n padding-top: 1rem;\n border-top: 1px solid var(--md-outline-variant);\n}\n\n/* -----------------------------------------------------------------------------\n Button System - MD3 Patterns\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.mj-btn:focus-visible {\n outline: 2px solid var(--md-primary);\n outline-offset: 2px;\n}\n\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.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.mj-btn-ghost {\n background: transparent;\n color: var(--md-on-surface-variant);\n padding: 0.5rem;\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.mj-btn-sm {\n padding: 0.5rem 0.875rem;\n font-size: 0.8125rem;\n min-height: 36px;\n}\n\n/* -----------------------------------------------------------------------------\n Accessibility: Focus Indicators\n ----------------------------------------------------------------------------- */\nbutton:focus-visible,\ninput: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 Animations\n ----------------------------------------------------------------------------- */\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Responsive Design - Mobile First\n ----------------------------------------------------------------------------- */\n@media (max-width: 639px) {\n .user-profile-settings {\n padding: 1rem;\n }\n\n .tab-navigation .tab-btn {\n flex-direction: column;\n gap: 0.25rem;\n padding: 0.5rem;\n font-size: 0.75rem;\n }\n\n .tab-navigation .tab-btn i {\n font-size: 1.2rem;\n }\n\n .icon-grid {\n grid-template-columns: repeat(auto-fill, minmax(45px, 1fr));\n }\n\n .icon-categories-container {\n max-height: 300px;\n }\n\n .action-buttons {\n flex-direction: column;\n }\n\n .action-buttons .mj-btn {\n width: 100%;\n justify-content: center;\n }\n\n .provider-section {\n padding: 0.5rem 0;\n }\n\n .sync-btn,\n .revert-btn {\n width: 100%;\n max-width: 300px;\n justify-content: center;\n }\n}\n\n@media (min-width: 640px) {\n .icon-search-container {\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n }\n\n .mj-search {\n max-width: 300px;\n }\n}\n\n@media (min-width: 768px) {\n .user-profile-settings {\n padding: 2rem;\n }\n\n .icon-categories-container {\n max-height: 400px;\n }\n}\n\n@media (min-width: 1024px) {\n .icon-grid {\n grid-template-columns: repeat(auto-fill, minmax(56px, 1fr));\n }\n}\n"] }]
|
|
692
825
|
}], () => [{ type: i1.UserAvatarService }, { type: i2.SharedService }], null); })();
|
|
693
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(UserProfileSettingsComponent, { className: "UserProfileSettingsComponent", filePath: "src/lib/user-profile-settings/user-profile-settings.component.ts", lineNumber:
|
|
826
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(UserProfileSettingsComponent, { className: "UserProfileSettingsComponent", filePath: "src/lib/user-profile-settings/user-profile-settings.component.ts", lineNumber: 22 }); })();
|
|
694
827
|
//# sourceMappingURL=user-profile-settings.component.js.map
|