@memberjunction/ng-explorer-core 5.31.0 → 5.33.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/generated/lazy-feature-config.d.ts +1 -1
- package/dist/generated/lazy-feature-config.d.ts.map +1 -1
- package/dist/generated/lazy-feature-config.js +13 -2
- package/dist/generated/lazy-feature-config.js.map +1 -1
- package/dist/lib/about/about-dialog.component.d.ts +82 -0
- package/dist/lib/about/about-dialog.component.d.ts.map +1 -0
- package/dist/lib/about/about-dialog.component.js +689 -0
- package/dist/lib/about/about-dialog.component.js.map +1 -0
- package/dist/lib/profile/profile-dialog.component.d.ts +72 -0
- package/dist/lib/profile/profile-dialog.component.d.ts.map +1 -0
- package/dist/lib/profile/profile-dialog.component.js +722 -0
- package/dist/lib/profile/profile-dialog.component.js.map +1 -0
- package/dist/lib/services/lazy-module-registry.d.ts +20 -0
- package/dist/lib/services/lazy-module-registry.d.ts.map +1 -1
- package/dist/lib/services/lazy-module-registry.js +43 -0
- package/dist/lib/services/lazy-module-registry.js.map +1 -1
- package/dist/lib/shell/services/about-dialog.service.d.ts +23 -0
- package/dist/lib/shell/services/about-dialog.service.d.ts.map +1 -0
- package/dist/lib/shell/services/about-dialog.service.js +45 -0
- package/dist/lib/shell/services/about-dialog.service.js.map +1 -0
- package/dist/lib/shell/services/profile-dialog.service.d.ts +22 -0
- package/dist/lib/shell/services/profile-dialog.service.d.ts.map +1 -0
- package/dist/lib/shell/services/profile-dialog.service.js +49 -0
- package/dist/lib/shell/services/profile-dialog.service.js.map +1 -0
- package/dist/lib/shell/shell.component.d.ts +7 -11
- package/dist/lib/shell/shell.component.d.ts.map +1 -1
- package/dist/lib/shell/shell.component.js +69 -54
- package/dist/lib/shell/shell.component.js.map +1 -1
- package/dist/lib/user-menu/base-user-menu.d.ts +4 -13
- package/dist/lib/user-menu/base-user-menu.d.ts.map +1 -1
- package/dist/lib/user-menu/base-user-menu.js +26 -75
- package/dist/lib/user-menu/base-user-menu.js.map +1 -1
- package/dist/public-api.d.ts +4 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +6 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +42 -42
- package/dist/lib/shell/services/settings-dialog.service.d.ts +0 -28
- package/dist/lib/shell/services/settings-dialog.service.d.ts.map +0 -1
- package/dist/lib/shell/services/settings-dialog.service.js +0 -61
- package/dist/lib/shell/services/settings-dialog.service.js.map +0 -1
|
@@ -0,0 +1,722 @@
|
|
|
1
|
+
import { Component, EventEmitter, Input, Output, ChangeDetectorRef, inject } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { UUIDsEqual } from '@memberjunction/global';
|
|
4
|
+
import { UserInfoEngine } from '@memberjunction/core-entities';
|
|
5
|
+
import { MJAuthBase } from '@memberjunction/ng-auth-services';
|
|
6
|
+
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
7
|
+
import { ThemeService, SharedService } from '@memberjunction/ng-shared';
|
|
8
|
+
import { ExplorerSettingsModule } from '@memberjunction/ng-explorer-settings';
|
|
9
|
+
import * as i0 from "@angular/core";
|
|
10
|
+
import * as i1 from "@memberjunction/ng-explorer-settings";
|
|
11
|
+
const _forTrack0 = ($index, $item) => $item.label;
|
|
12
|
+
const _forTrack1 = ($index, $item) => $item.key;
|
|
13
|
+
const _forTrack2 = ($index, $item) => $item.id;
|
|
14
|
+
function ProfileDialogComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
15
|
+
const _r1 = i0.ɵɵgetCurrentView();
|
|
16
|
+
i0.ɵɵelementStart(0, "img", 44);
|
|
17
|
+
i0.ɵɵlistener("error", function ProfileDialogComponent_Conditional_8_Template_img_error_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.OnAvatarLoadError()); });
|
|
18
|
+
i0.ɵɵelementEnd();
|
|
19
|
+
} if (rf & 2) {
|
|
20
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
21
|
+
i0.ɵɵproperty("src", ctx_r1.AvatarUrl, i0.ɵɵsanitizeUrl);
|
|
22
|
+
} }
|
|
23
|
+
function ProfileDialogComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
|
|
24
|
+
i0.ɵɵelementStart(0, "div", 8);
|
|
25
|
+
i0.ɵɵelement(1, "i");
|
|
26
|
+
i0.ɵɵelementEnd();
|
|
27
|
+
} if (rf & 2) {
|
|
28
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
29
|
+
i0.ɵɵadvance();
|
|
30
|
+
i0.ɵɵclassMap(ctx_r1.AvatarIconClass);
|
|
31
|
+
} }
|
|
32
|
+
function ProfileDialogComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
|
|
33
|
+
i0.ɵɵelementStart(0, "div", 9);
|
|
34
|
+
i0.ɵɵtext(1);
|
|
35
|
+
i0.ɵɵelementEnd();
|
|
36
|
+
} if (rf & 2) {
|
|
37
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
38
|
+
i0.ɵɵadvance();
|
|
39
|
+
i0.ɵɵtextInterpolate(ctx_r1.UserInitials);
|
|
40
|
+
} }
|
|
41
|
+
function ProfileDialogComponent_Conditional_18_For_2_Conditional_1_Template(rf, ctx) { if (rf & 1) {
|
|
42
|
+
i0.ɵɵelement(0, "i");
|
|
43
|
+
} if (rf & 2) {
|
|
44
|
+
const chip_r3 = i0.ɵɵnextContext().$implicit;
|
|
45
|
+
i0.ɵɵclassMap(chip_r3.icon);
|
|
46
|
+
} }
|
|
47
|
+
function ProfileDialogComponent_Conditional_18_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
48
|
+
i0.ɵɵelementStart(0, "span", 46);
|
|
49
|
+
i0.ɵɵconditionalCreate(1, ProfileDialogComponent_Conditional_18_For_2_Conditional_1_Template, 1, 2, "i", 47);
|
|
50
|
+
i0.ɵɵtext(2);
|
|
51
|
+
i0.ɵɵelementEnd();
|
|
52
|
+
} if (rf & 2) {
|
|
53
|
+
const chip_r3 = ctx.$implicit;
|
|
54
|
+
i0.ɵɵclassMap("mj-profile__chip--" + chip_r3.tone);
|
|
55
|
+
i0.ɵɵadvance();
|
|
56
|
+
i0.ɵɵconditional(chip_r3.icon ? 1 : -1);
|
|
57
|
+
i0.ɵɵadvance();
|
|
58
|
+
i0.ɵɵtextInterpolate1(" ", chip_r3.label, " ");
|
|
59
|
+
} }
|
|
60
|
+
function ProfileDialogComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
|
|
61
|
+
i0.ɵɵelementStart(0, "div", 15);
|
|
62
|
+
i0.ɵɵrepeaterCreate(1, ProfileDialogComponent_Conditional_18_For_2_Template, 3, 4, "span", 45, _forTrack0);
|
|
63
|
+
i0.ɵɵelementEnd();
|
|
64
|
+
} if (rf & 2) {
|
|
65
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
66
|
+
i0.ɵɵadvance();
|
|
67
|
+
i0.ɵɵrepeater(ctx_r1.RoleChips);
|
|
68
|
+
} }
|
|
69
|
+
function ProfileDialogComponent_Conditional_28_Template(rf, ctx) { if (rf & 1) {
|
|
70
|
+
i0.ɵɵelementStart(0, "span", 23);
|
|
71
|
+
i0.ɵɵtext(1);
|
|
72
|
+
i0.ɵɵelementEnd();
|
|
73
|
+
} if (rf & 2) {
|
|
74
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
75
|
+
i0.ɵɵadvance();
|
|
76
|
+
i0.ɵɵtextInterpolate1(" \u00B7 ", ctx_r1.MemberSince);
|
|
77
|
+
} }
|
|
78
|
+
function ProfileDialogComponent_Conditional_42_Template(rf, ctx) { if (rf & 1) {
|
|
79
|
+
i0.ɵɵelementStart(0, "span", 29);
|
|
80
|
+
i0.ɵɵtext(1);
|
|
81
|
+
i0.ɵɵelementEnd();
|
|
82
|
+
} if (rf & 2) {
|
|
83
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
84
|
+
i0.ɵɵadvance();
|
|
85
|
+
i0.ɵɵtextInterpolate1("", ctx_r1.UnreadCount, " unread");
|
|
86
|
+
} }
|
|
87
|
+
function ProfileDialogComponent_Conditional_43_Template(rf, ctx) { if (rf & 1) {
|
|
88
|
+
i0.ɵɵelementStart(0, "div", 30);
|
|
89
|
+
i0.ɵɵelement(1, "i", 48);
|
|
90
|
+
i0.ɵɵtext(2, " Loading\u2026 ");
|
|
91
|
+
i0.ɵɵelementEnd();
|
|
92
|
+
} }
|
|
93
|
+
function ProfileDialogComponent_Conditional_44_For_2_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
94
|
+
i0.ɵɵelement(0, "i", 48);
|
|
95
|
+
} }
|
|
96
|
+
function ProfileDialogComponent_Conditional_44_For_2_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
97
|
+
i0.ɵɵelementStart(0, "span", 55);
|
|
98
|
+
i0.ɵɵelement(1, "span", 56);
|
|
99
|
+
i0.ɵɵelementEnd();
|
|
100
|
+
} if (rf & 2) {
|
|
101
|
+
const ch_r5 = i0.ɵɵnextContext().$implicit;
|
|
102
|
+
i0.ɵɵclassProp("mj-profile__switch--on", ch_r5.enabled);
|
|
103
|
+
} }
|
|
104
|
+
function ProfileDialogComponent_Conditional_44_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
105
|
+
const _r4 = i0.ɵɵgetCurrentView();
|
|
106
|
+
i0.ɵɵelementStart(0, "button", 50);
|
|
107
|
+
i0.ɵɵlistener("click", function ProfileDialogComponent_Conditional_44_For_2_Template_button_click_0_listener() { const ch_r5 = i0.ɵɵrestoreView(_r4).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ToggleChannel(ch_r5)); });
|
|
108
|
+
i0.ɵɵelementStart(1, "div", 51);
|
|
109
|
+
i0.ɵɵelement(2, "i");
|
|
110
|
+
i0.ɵɵelementEnd();
|
|
111
|
+
i0.ɵɵelementStart(3, "div", 52);
|
|
112
|
+
i0.ɵɵtext(4);
|
|
113
|
+
i0.ɵɵelementEnd();
|
|
114
|
+
i0.ɵɵelementStart(5, "div", 53);
|
|
115
|
+
i0.ɵɵconditionalCreate(6, ProfileDialogComponent_Conditional_44_For_2_Conditional_6_Template, 1, 0, "i", 48)(7, ProfileDialogComponent_Conditional_44_For_2_Conditional_7_Template, 2, 2, "span", 54);
|
|
116
|
+
i0.ɵɵelementEnd()();
|
|
117
|
+
} if (rf & 2) {
|
|
118
|
+
const ch_r5 = ctx.$implicit;
|
|
119
|
+
i0.ɵɵclassProp("mj-profile__channel--on", ch_r5.enabled);
|
|
120
|
+
i0.ɵɵproperty("disabled", ch_r5.saving);
|
|
121
|
+
i0.ɵɵadvance(2);
|
|
122
|
+
i0.ɵɵclassMap(ch_r5.icon);
|
|
123
|
+
i0.ɵɵadvance(2);
|
|
124
|
+
i0.ɵɵtextInterpolate(ch_r5.label);
|
|
125
|
+
i0.ɵɵadvance(2);
|
|
126
|
+
i0.ɵɵconditional(ch_r5.saving ? 6 : 7);
|
|
127
|
+
} }
|
|
128
|
+
function ProfileDialogComponent_Conditional_44_Template(rf, ctx) { if (rf & 1) {
|
|
129
|
+
i0.ɵɵelementStart(0, "div", 31);
|
|
130
|
+
i0.ɵɵrepeaterCreate(1, ProfileDialogComponent_Conditional_44_For_2_Template, 8, 7, "button", 49, _forTrack1);
|
|
131
|
+
i0.ɵɵelementEnd();
|
|
132
|
+
} if (rf & 2) {
|
|
133
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
134
|
+
i0.ɵɵadvance();
|
|
135
|
+
i0.ɵɵrepeater(ctx_r1.Channels);
|
|
136
|
+
} }
|
|
137
|
+
function ProfileDialogComponent_Conditional_59_Template(rf, ctx) { if (rf & 1) {
|
|
138
|
+
i0.ɵɵelement(0, "mj-user-profile-settings");
|
|
139
|
+
} }
|
|
140
|
+
function ProfileDialogComponent_Conditional_60_For_2_Conditional_6_Template(rf, ctx) { if (rf & 1) {
|
|
141
|
+
i0.ɵɵelementStart(0, "div", 62);
|
|
142
|
+
i0.ɵɵtext(1);
|
|
143
|
+
i0.ɵɵelementEnd();
|
|
144
|
+
} if (rf & 2) {
|
|
145
|
+
const theme_r7 = i0.ɵɵnextContext().$implicit;
|
|
146
|
+
i0.ɵɵadvance();
|
|
147
|
+
i0.ɵɵtextInterpolate(theme_r7.description);
|
|
148
|
+
} }
|
|
149
|
+
function ProfileDialogComponent_Conditional_60_For_2_Conditional_7_Template(rf, ctx) { if (rf & 1) {
|
|
150
|
+
i0.ɵɵelement(0, "i", 63);
|
|
151
|
+
} }
|
|
152
|
+
function ProfileDialogComponent_Conditional_60_For_2_Conditional_8_Template(rf, ctx) { if (rf & 1) {
|
|
153
|
+
i0.ɵɵelement(0, "i", 64);
|
|
154
|
+
} }
|
|
155
|
+
function ProfileDialogComponent_Conditional_60_For_2_Template(rf, ctx) { if (rf & 1) {
|
|
156
|
+
const _r6 = i0.ɵɵgetCurrentView();
|
|
157
|
+
i0.ɵɵelementStart(0, "button", 58);
|
|
158
|
+
i0.ɵɵlistener("click", function ProfileDialogComponent_Conditional_60_For_2_Template_button_click_0_listener() { const theme_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SelectTheme(theme_r7.id)); });
|
|
159
|
+
i0.ɵɵelementStart(1, "div", 59);
|
|
160
|
+
i0.ɵɵelement(2, "i");
|
|
161
|
+
i0.ɵɵelementEnd();
|
|
162
|
+
i0.ɵɵelementStart(3, "div", 60)(4, "div", 61);
|
|
163
|
+
i0.ɵɵtext(5);
|
|
164
|
+
i0.ɵɵelementEnd();
|
|
165
|
+
i0.ɵɵconditionalCreate(6, ProfileDialogComponent_Conditional_60_For_2_Conditional_6_Template, 2, 1, "div", 62);
|
|
166
|
+
i0.ɵɵelementEnd();
|
|
167
|
+
i0.ɵɵconditionalCreate(7, ProfileDialogComponent_Conditional_60_For_2_Conditional_7_Template, 1, 0, "i", 63)(8, ProfileDialogComponent_Conditional_60_For_2_Conditional_8_Template, 1, 0, "i", 64);
|
|
168
|
+
i0.ɵɵelementEnd();
|
|
169
|
+
} if (rf & 2) {
|
|
170
|
+
const theme_r7 = ctx.$implicit;
|
|
171
|
+
const ctx_r1 = i0.ɵɵnextContext(2);
|
|
172
|
+
i0.ɵɵclassProp("mj-profile__theme--active", theme_r7.id === ctx_r1.ThemePreference)("mj-profile__theme--saving", ctx_r1.SavingTheme === theme_r7.id);
|
|
173
|
+
i0.ɵɵproperty("disabled", !!ctx_r1.SavingTheme);
|
|
174
|
+
i0.ɵɵadvance();
|
|
175
|
+
i0.ɵɵclassMap("mj-profile__theme-swatch--" + theme_r7.swatch);
|
|
176
|
+
i0.ɵɵadvance();
|
|
177
|
+
i0.ɵɵclassMap(theme_r7.icon);
|
|
178
|
+
i0.ɵɵadvance(3);
|
|
179
|
+
i0.ɵɵtextInterpolate(theme_r7.name);
|
|
180
|
+
i0.ɵɵadvance();
|
|
181
|
+
i0.ɵɵconditional(theme_r7.description ? 6 : -1);
|
|
182
|
+
i0.ɵɵadvance();
|
|
183
|
+
i0.ɵɵconditional(ctx_r1.SavingTheme === theme_r7.id ? 7 : theme_r7.id === ctx_r1.ThemePreference ? 8 : -1);
|
|
184
|
+
} }
|
|
185
|
+
function ProfileDialogComponent_Conditional_60_Template(rf, ctx) { if (rf & 1) {
|
|
186
|
+
i0.ɵɵelementStart(0, "div", 43);
|
|
187
|
+
i0.ɵɵrepeaterCreate(1, ProfileDialogComponent_Conditional_60_For_2_Template, 9, 12, "button", 57, _forTrack2);
|
|
188
|
+
i0.ɵɵelementEnd();
|
|
189
|
+
} if (rf & 2) {
|
|
190
|
+
const ctx_r1 = i0.ɵɵnextContext();
|
|
191
|
+
i0.ɵɵadvance();
|
|
192
|
+
i0.ɵɵrepeater(ctx_r1.ThemeOptions);
|
|
193
|
+
} }
|
|
194
|
+
/**
|
|
195
|
+
* "Identity Card" profile dialog with slide-in detail panels for editing
|
|
196
|
+
* profile photo and switching theme. Replaces the legacy multi-tab Settings
|
|
197
|
+
* dialog entirely. Brand-aligned with the About dialog.
|
|
198
|
+
*/
|
|
199
|
+
export class ProfileDialogComponent extends BaseAngularComponent {
|
|
200
|
+
CloseRequested = new EventEmitter();
|
|
201
|
+
AvatarUrl = null;
|
|
202
|
+
AvatarIconClass = null;
|
|
203
|
+
UserName = '';
|
|
204
|
+
UserEmail = '';
|
|
205
|
+
UserInitials = '?';
|
|
206
|
+
AccountType = '';
|
|
207
|
+
AccountStatus = '';
|
|
208
|
+
MemberSince = '';
|
|
209
|
+
ThemeLabel = '';
|
|
210
|
+
RoleChips = [];
|
|
211
|
+
LoadingNotifications = true;
|
|
212
|
+
Channels = [
|
|
213
|
+
{ key: 'InApp', label: 'In-app', icon: 'fa-solid fa-bell', enabled: false, saving: false },
|
|
214
|
+
{ key: 'Email', label: 'Email', icon: 'fa-solid fa-envelope', enabled: false, saving: false },
|
|
215
|
+
{ key: 'SMS', label: 'SMS', icon: 'fa-solid fa-mobile', enabled: false, saving: false }
|
|
216
|
+
];
|
|
217
|
+
UnreadCount = 0;
|
|
218
|
+
// Slide-in panel state
|
|
219
|
+
ActivePanel = 'none';
|
|
220
|
+
ThemeOptions = [];
|
|
221
|
+
ThemePreference = '';
|
|
222
|
+
SavingTheme = null;
|
|
223
|
+
get PanelTitle() {
|
|
224
|
+
switch (this.ActivePanel) {
|
|
225
|
+
case 'photo': return 'Profile photo';
|
|
226
|
+
case 'theme': return 'Theme';
|
|
227
|
+
default: return '';
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
authBase = inject(MJAuthBase);
|
|
231
|
+
themeService = inject(ThemeService);
|
|
232
|
+
sharedService = inject(SharedService);
|
|
233
|
+
cdr = inject(ChangeDetectorRef);
|
|
234
|
+
themeSub;
|
|
235
|
+
ngOnInit() {
|
|
236
|
+
this.populateIdentity();
|
|
237
|
+
this.populateThemeOptions();
|
|
238
|
+
this.loadNotifications();
|
|
239
|
+
this.themeSub = this.themeService.Preference$.subscribe(pref => {
|
|
240
|
+
this.ThemePreference = pref;
|
|
241
|
+
this.ThemeLabel = this.computeThemeLabel();
|
|
242
|
+
this.cdr.markForCheck();
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
ngOnDestroy() {
|
|
246
|
+
this.themeSub?.unsubscribe();
|
|
247
|
+
}
|
|
248
|
+
OnCloseClick() {
|
|
249
|
+
if (this.ActivePanel !== 'none') {
|
|
250
|
+
this.ClosePanel();
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
this.CloseRequested.emit();
|
|
254
|
+
}
|
|
255
|
+
OnAvatarLoadError() {
|
|
256
|
+
this.AvatarUrl = null;
|
|
257
|
+
this.cdr.markForCheck();
|
|
258
|
+
}
|
|
259
|
+
OpenPanel(panel) {
|
|
260
|
+
this.ActivePanel = panel;
|
|
261
|
+
}
|
|
262
|
+
ClosePanel() {
|
|
263
|
+
this.ActivePanel = 'none';
|
|
264
|
+
}
|
|
265
|
+
async OnSignOut() {
|
|
266
|
+
try {
|
|
267
|
+
localStorage.removeItem('auth');
|
|
268
|
+
localStorage.removeItem('claims');
|
|
269
|
+
await this.authBase.logout();
|
|
270
|
+
}
|
|
271
|
+
catch (err) {
|
|
272
|
+
const msg = err instanceof Error ? err.message : 'Unknown error';
|
|
273
|
+
this.sharedService.CreateSimpleNotification(`Sign out failed: ${msg}`, 'error', 3000);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
async SelectTheme(themeId) {
|
|
277
|
+
if (this.SavingTheme)
|
|
278
|
+
return;
|
|
279
|
+
if (themeId === this.ThemePreference)
|
|
280
|
+
return;
|
|
281
|
+
this.SavingTheme = themeId;
|
|
282
|
+
this.cdr.markForCheck();
|
|
283
|
+
try {
|
|
284
|
+
await this.themeService.SetTheme(themeId);
|
|
285
|
+
}
|
|
286
|
+
catch (err) {
|
|
287
|
+
const msg = err instanceof Error ? err.message : 'Unknown error';
|
|
288
|
+
this.sharedService.CreateSimpleNotification(`Theme change failed: ${msg}`, 'error', 3000);
|
|
289
|
+
}
|
|
290
|
+
finally {
|
|
291
|
+
this.SavingTheme = null;
|
|
292
|
+
this.cdr.markForCheck();
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
async ToggleChannel(channel) {
|
|
296
|
+
if (channel.saving)
|
|
297
|
+
return;
|
|
298
|
+
const newState = !channel.enabled;
|
|
299
|
+
channel.saving = true;
|
|
300
|
+
this.cdr.markForCheck();
|
|
301
|
+
const provider = this.ProviderToUse;
|
|
302
|
+
const currentUser = provider?.CurrentUser;
|
|
303
|
+
if (!provider || !currentUser) {
|
|
304
|
+
channel.saving = false;
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
try {
|
|
308
|
+
const transGroup = await provider.CreateTransactionGroup();
|
|
309
|
+
const types = UserInfoEngine.Instance.NotificationTypes;
|
|
310
|
+
const preferences = UserInfoEngine.Instance.NotificationPreferences;
|
|
311
|
+
for (const type of types) {
|
|
312
|
+
if (type.AllowUserPreference === false)
|
|
313
|
+
continue;
|
|
314
|
+
let pref = preferences.find(p => UUIDsEqual(p.NotificationTypeID, type.ID));
|
|
315
|
+
if (!pref) {
|
|
316
|
+
pref = await provider.GetEntityObject('MJ: User Notification Preferences');
|
|
317
|
+
pref.UserID = currentUser.ID;
|
|
318
|
+
pref.NotificationTypeID = type.ID;
|
|
319
|
+
pref.InAppEnabled = type.DefaultInApp ?? true;
|
|
320
|
+
pref.EmailEnabled = type.DefaultEmail ?? false;
|
|
321
|
+
pref.SMSEnabled = type.DefaultSMS ?? false;
|
|
322
|
+
}
|
|
323
|
+
if (channel.key === 'InApp')
|
|
324
|
+
pref.InAppEnabled = newState;
|
|
325
|
+
else if (channel.key === 'Email')
|
|
326
|
+
pref.EmailEnabled = newState;
|
|
327
|
+
else
|
|
328
|
+
pref.SMSEnabled = newState;
|
|
329
|
+
pref.Enabled = pref.InAppEnabled || pref.EmailEnabled || pref.SMSEnabled;
|
|
330
|
+
pref.TransactionGroup = transGroup;
|
|
331
|
+
pref.Save();
|
|
332
|
+
}
|
|
333
|
+
const success = await transGroup.Submit();
|
|
334
|
+
if (success) {
|
|
335
|
+
channel.enabled = newState;
|
|
336
|
+
this.sharedService.CreateSimpleNotification(`${channel.label} notifications ${newState ? 'enabled' : 'disabled'}`, 'success', 2000);
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
throw new Error('Save failed');
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
catch (err) {
|
|
343
|
+
const msg = err instanceof Error ? err.message : 'Unknown error';
|
|
344
|
+
this.sharedService.CreateSimpleNotification(`Update failed: ${msg}`, 'error', 3000);
|
|
345
|
+
await this.loadNotifications();
|
|
346
|
+
}
|
|
347
|
+
finally {
|
|
348
|
+
channel.saving = false;
|
|
349
|
+
this.cdr.markForCheck();
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
// ---------- private helpers ----------
|
|
353
|
+
populateIdentity() {
|
|
354
|
+
const provider = this.ProviderToUse;
|
|
355
|
+
const user = provider?.CurrentUser;
|
|
356
|
+
if (user) {
|
|
357
|
+
const name = user.Name || `${user.FirstName ?? ''} ${user.LastName ?? ''}`.trim();
|
|
358
|
+
this.UserName = name || 'User';
|
|
359
|
+
this.UserEmail = user.Email || '';
|
|
360
|
+
this.UserInitials = this.computeInitials(this.UserName);
|
|
361
|
+
this.AccountType = user.Type || 'User';
|
|
362
|
+
this.AccountStatus = user.IsActive ? 'Active' : 'Inactive';
|
|
363
|
+
this.MemberSince = this.formatMemberSince(user.__mj_CreatedAt);
|
|
364
|
+
this.RoleChips = this.computeRoleChips(user.UserRoles);
|
|
365
|
+
}
|
|
366
|
+
this.ThemePreference = this.themeService.Preference;
|
|
367
|
+
this.ThemeLabel = this.computeThemeLabel();
|
|
368
|
+
}
|
|
369
|
+
populateThemeOptions() {
|
|
370
|
+
const themes = this.themeService.AvailableThemes ?? [];
|
|
371
|
+
this.ThemeOptions = themes.map(t => ({
|
|
372
|
+
id: t.Id,
|
|
373
|
+
name: t.Name,
|
|
374
|
+
description: t.Description ?? (t.BaseTheme === 'dark' ? 'Dark interface' : 'Light interface'),
|
|
375
|
+
icon: t.BaseTheme === 'dark' ? 'fa-solid fa-moon' : 'fa-solid fa-sun',
|
|
376
|
+
swatch: t.BaseTheme
|
|
377
|
+
}));
|
|
378
|
+
this.ThemeOptions.push({
|
|
379
|
+
id: 'system',
|
|
380
|
+
name: 'System',
|
|
381
|
+
description: 'Follow your operating system',
|
|
382
|
+
icon: 'fa-solid fa-desktop',
|
|
383
|
+
swatch: 'system'
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
async loadNotifications() {
|
|
387
|
+
this.LoadingNotifications = true;
|
|
388
|
+
try {
|
|
389
|
+
this.UnreadCount = UserInfoEngine.Instance.UnreadNotificationCount ?? 0;
|
|
390
|
+
const preferences = UserInfoEngine.Instance.NotificationPreferences;
|
|
391
|
+
const types = UserInfoEngine.Instance.NotificationTypes;
|
|
392
|
+
let inApp, email, sms;
|
|
393
|
+
if (preferences.length === 0 && types.length > 0) {
|
|
394
|
+
inApp = types.some(t => t.DefaultInApp ?? true);
|
|
395
|
+
email = types.some(t => t.DefaultEmail ?? false);
|
|
396
|
+
sms = types.some(t => t.DefaultSMS ?? false);
|
|
397
|
+
}
|
|
398
|
+
else {
|
|
399
|
+
inApp = preferences.some(p => p.InAppEnabled);
|
|
400
|
+
email = preferences.some(p => p.EmailEnabled);
|
|
401
|
+
sms = preferences.some(p => p.SMSEnabled);
|
|
402
|
+
}
|
|
403
|
+
this.Channels[0].enabled = inApp;
|
|
404
|
+
this.Channels[1].enabled = email;
|
|
405
|
+
this.Channels[2].enabled = sms;
|
|
406
|
+
}
|
|
407
|
+
catch {
|
|
408
|
+
// non-fatal; leave defaults
|
|
409
|
+
}
|
|
410
|
+
finally {
|
|
411
|
+
this.LoadingNotifications = false;
|
|
412
|
+
this.cdr.markForCheck();
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
computeInitials(name) {
|
|
416
|
+
const parts = name.trim().split(/\s+/).filter(Boolean);
|
|
417
|
+
if (parts.length === 0)
|
|
418
|
+
return '?';
|
|
419
|
+
if (parts.length === 1)
|
|
420
|
+
return parts[0].slice(0, 2).toUpperCase();
|
|
421
|
+
return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
|
|
422
|
+
}
|
|
423
|
+
computeRoleChips(roles) {
|
|
424
|
+
if (!roles || roles.length === 0)
|
|
425
|
+
return [];
|
|
426
|
+
return roles
|
|
427
|
+
.map(r => r.Role)
|
|
428
|
+
.filter((n) => !!n)
|
|
429
|
+
.map(roleName => {
|
|
430
|
+
const lower = roleName.toLowerCase();
|
|
431
|
+
if (lower.includes('admin'))
|
|
432
|
+
return { label: roleName, tone: 'admin', icon: 'fa-solid fa-shield' };
|
|
433
|
+
if (lower.includes('developer') || lower.includes('integration'))
|
|
434
|
+
return { label: roleName, tone: 'dev', icon: 'fa-solid fa-code' };
|
|
435
|
+
return { label: roleName, tone: '', icon: null };
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
formatMemberSince(date) {
|
|
439
|
+
if (!date)
|
|
440
|
+
return '';
|
|
441
|
+
const d = date instanceof Date ? date : new Date(date);
|
|
442
|
+
if (isNaN(d.getTime()))
|
|
443
|
+
return '';
|
|
444
|
+
return d.toLocaleDateString(undefined, { month: 'short', year: 'numeric' });
|
|
445
|
+
}
|
|
446
|
+
computeThemeLabel() {
|
|
447
|
+
const applied = this.themeService.AppliedTheme;
|
|
448
|
+
const preference = this.themeService.Preference;
|
|
449
|
+
const def = this.themeService.GetThemeDefinition(applied);
|
|
450
|
+
const themeName = def?.Name ?? applied;
|
|
451
|
+
return preference === 'system' ? `${themeName} · System` : themeName;
|
|
452
|
+
}
|
|
453
|
+
static ɵfac = /*@__PURE__*/ (() => { let ɵProfileDialogComponent_BaseFactory; return function ProfileDialogComponent_Factory(__ngFactoryType__) { return (ɵProfileDialogComponent_BaseFactory || (ɵProfileDialogComponent_BaseFactory = i0.ɵɵgetInheritedFactory(ProfileDialogComponent)))(__ngFactoryType__ || ProfileDialogComponent); }; })();
|
|
454
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ProfileDialogComponent, selectors: [["mj-profile-dialog"]], inputs: { AvatarUrl: "AvatarUrl", AvatarIconClass: "AvatarIconClass" }, outputs: { CloseRequested: "CloseRequested" }, features: [i0.ɵɵInheritDefinitionFeature], decls: 61, vars: 16, consts: [["role", "document", 1, "mj-profile"], ["type", "button", "aria-label", "Close", 1, "mj-profile__close", 3, "click"], [1, "fa-solid", "fa-xmark"], [1, "mj-profile__main"], [1, "mj-profile__hero"], [1, "mj-profile__hero-title"], [1, "mj-profile__avatar-zone"], ["alt", "", 1, "mj-profile__avatar", "mj-profile__avatar--img", 3, "src"], [1, "mj-profile__avatar", "mj-profile__avatar--icon"], [1, "mj-profile__avatar"], ["type", "button", "title", "Change photo", 1, "mj-profile__avatar-edit", 3, "click"], [1, "fa-solid", "fa-camera"], [1, "mj-profile__identity"], [1, "mj-profile__name"], [1, "mj-profile__email"], [1, "mj-profile__chips"], [1, "mj-profile__field-list"], [1, "mj-profile__field"], [1, "mj-profile__field-icon"], [1, "fa-solid", "fa-id-badge"], [1, "mj-profile__field-body"], [1, "mj-profile__field-label"], [1, "mj-profile__field-value"], [1, "mj-profile__field-muted"], ["type", "button", 1, "mj-profile__field", "mj-profile__field--button", 3, "click"], [1, "fa-solid", "fa-palette"], [1, "fa-solid", "fa-chevron-right", "mj-profile__field-chev"], [1, "mj-profile__section"], [1, "mj-profile__section-head"], [1, "mj-profile__unread"], [1, "mj-profile__channels-loading"], [1, "mj-profile__channels"], [1, "mj-profile__footer"], ["type", "button", 1, "mj-profile__btn", "mj-profile__btn--danger", 3, "click"], [1, "fa-solid", "fa-arrow-right-from-bracket"], [1, "mj-profile__spacer"], ["type", "button", 1, "mj-profile__btn", "mj-profile__btn--primary", 3, "click"], [1, "mj-profile__panel"], [1, "mj-profile__panel-header"], ["type", "button", "aria-label", "Back", 1, "mj-profile__panel-back", 3, "click"], [1, "fa-solid", "fa-arrow-left"], [1, "mj-profile__panel-title"], [1, "mj-profile__panel-body"], [1, "mj-profile__themes"], ["alt", "", 1, "mj-profile__avatar", "mj-profile__avatar--img", 3, "error", "src"], [1, "mj-profile__chip", 3, "class"], [1, "mj-profile__chip"], [3, "class"], [1, "fa-solid", "fa-spinner", "fa-spin"], ["type", "button", 1, "mj-profile__channel", 3, "mj-profile__channel--on", "disabled"], ["type", "button", 1, "mj-profile__channel", 3, "click", "disabled"], [1, "mj-profile__channel-icon"], [1, "mj-profile__channel-label"], [1, "mj-profile__channel-state"], [1, "mj-profile__switch", 3, "mj-profile__switch--on"], [1, "mj-profile__switch"], [1, "mj-profile__switch-knob"], ["type", "button", 1, "mj-profile__theme", 3, "mj-profile__theme--active", "mj-profile__theme--saving", "disabled"], ["type", "button", 1, "mj-profile__theme", 3, "click", "disabled"], [1, "mj-profile__theme-swatch"], [1, "mj-profile__theme-info"], [1, "mj-profile__theme-name"], [1, "mj-profile__theme-desc"], [1, "fa-solid", "fa-spinner", "fa-spin", "mj-profile__theme-check"], [1, "fa-solid", "fa-check", "mj-profile__theme-check"]], template: function ProfileDialogComponent_Template(rf, ctx) { if (rf & 1) {
|
|
455
|
+
i0.ɵɵelementStart(0, "div", 0)(1, "button", 1);
|
|
456
|
+
i0.ɵɵlistener("click", function ProfileDialogComponent_Template_button_click_1_listener() { return ctx.OnCloseClick(); });
|
|
457
|
+
i0.ɵɵelement(2, "i", 2);
|
|
458
|
+
i0.ɵɵelementEnd();
|
|
459
|
+
i0.ɵɵelementStart(3, "div", 3)(4, "div", 4)(5, "h3", 5);
|
|
460
|
+
i0.ɵɵtext(6, "My Profile");
|
|
461
|
+
i0.ɵɵelementEnd()();
|
|
462
|
+
i0.ɵɵelementStart(7, "div", 6);
|
|
463
|
+
i0.ɵɵconditionalCreate(8, ProfileDialogComponent_Conditional_8_Template, 1, 1, "img", 7)(9, ProfileDialogComponent_Conditional_9_Template, 2, 2, "div", 8)(10, ProfileDialogComponent_Conditional_10_Template, 2, 1, "div", 9);
|
|
464
|
+
i0.ɵɵelementStart(11, "button", 10);
|
|
465
|
+
i0.ɵɵlistener("click", function ProfileDialogComponent_Template_button_click_11_listener() { return ctx.OpenPanel("photo"); });
|
|
466
|
+
i0.ɵɵelement(12, "i", 11);
|
|
467
|
+
i0.ɵɵelementEnd()();
|
|
468
|
+
i0.ɵɵelementStart(13, "div", 12)(14, "h2", 13);
|
|
469
|
+
i0.ɵɵtext(15);
|
|
470
|
+
i0.ɵɵelementEnd();
|
|
471
|
+
i0.ɵɵelementStart(16, "p", 14);
|
|
472
|
+
i0.ɵɵtext(17);
|
|
473
|
+
i0.ɵɵelementEnd();
|
|
474
|
+
i0.ɵɵconditionalCreate(18, ProfileDialogComponent_Conditional_18_Template, 3, 0, "div", 15);
|
|
475
|
+
i0.ɵɵelementEnd();
|
|
476
|
+
i0.ɵɵelementStart(19, "div", 16)(20, "div", 17)(21, "div", 18);
|
|
477
|
+
i0.ɵɵelement(22, "i", 19);
|
|
478
|
+
i0.ɵɵelementEnd();
|
|
479
|
+
i0.ɵɵelementStart(23, "div", 20)(24, "div", 21);
|
|
480
|
+
i0.ɵɵtext(25, "Account");
|
|
481
|
+
i0.ɵɵelementEnd();
|
|
482
|
+
i0.ɵɵelementStart(26, "div", 22);
|
|
483
|
+
i0.ɵɵtext(27);
|
|
484
|
+
i0.ɵɵconditionalCreate(28, ProfileDialogComponent_Conditional_28_Template, 2, 1, "span", 23);
|
|
485
|
+
i0.ɵɵelementEnd()()();
|
|
486
|
+
i0.ɵɵelementStart(29, "button", 24);
|
|
487
|
+
i0.ɵɵlistener("click", function ProfileDialogComponent_Template_button_click_29_listener() { return ctx.OpenPanel("theme"); });
|
|
488
|
+
i0.ɵɵelementStart(30, "div", 18);
|
|
489
|
+
i0.ɵɵelement(31, "i", 25);
|
|
490
|
+
i0.ɵɵelementEnd();
|
|
491
|
+
i0.ɵɵelementStart(32, "div", 20)(33, "div", 21);
|
|
492
|
+
i0.ɵɵtext(34, "Theme");
|
|
493
|
+
i0.ɵɵelementEnd();
|
|
494
|
+
i0.ɵɵelementStart(35, "div", 22);
|
|
495
|
+
i0.ɵɵtext(36);
|
|
496
|
+
i0.ɵɵelementEnd()();
|
|
497
|
+
i0.ɵɵelement(37, "i", 26);
|
|
498
|
+
i0.ɵɵelementEnd()();
|
|
499
|
+
i0.ɵɵelementStart(38, "div", 27)(39, "div", 28)(40, "h4");
|
|
500
|
+
i0.ɵɵtext(41, "Notifications");
|
|
501
|
+
i0.ɵɵelementEnd();
|
|
502
|
+
i0.ɵɵconditionalCreate(42, ProfileDialogComponent_Conditional_42_Template, 2, 1, "span", 29);
|
|
503
|
+
i0.ɵɵelementEnd();
|
|
504
|
+
i0.ɵɵconditionalCreate(43, ProfileDialogComponent_Conditional_43_Template, 3, 0, "div", 30)(44, ProfileDialogComponent_Conditional_44_Template, 3, 0, "div", 31);
|
|
505
|
+
i0.ɵɵelementEnd();
|
|
506
|
+
i0.ɵɵelementStart(45, "div", 32)(46, "button", 33);
|
|
507
|
+
i0.ɵɵlistener("click", function ProfileDialogComponent_Template_button_click_46_listener() { return ctx.OnSignOut(); });
|
|
508
|
+
i0.ɵɵelement(47, "i", 34);
|
|
509
|
+
i0.ɵɵtext(48, " Sign out ");
|
|
510
|
+
i0.ɵɵelementEnd();
|
|
511
|
+
i0.ɵɵelement(49, "span", 35);
|
|
512
|
+
i0.ɵɵelementStart(50, "button", 36);
|
|
513
|
+
i0.ɵɵlistener("click", function ProfileDialogComponent_Template_button_click_50_listener() { return ctx.OnCloseClick(); });
|
|
514
|
+
i0.ɵɵtext(51, " Done ");
|
|
515
|
+
i0.ɵɵelementEnd()()();
|
|
516
|
+
i0.ɵɵelementStart(52, "div", 37)(53, "div", 38)(54, "button", 39);
|
|
517
|
+
i0.ɵɵlistener("click", function ProfileDialogComponent_Template_button_click_54_listener() { return ctx.ClosePanel(); });
|
|
518
|
+
i0.ɵɵelement(55, "i", 40);
|
|
519
|
+
i0.ɵɵelementEnd();
|
|
520
|
+
i0.ɵɵelementStart(56, "h3", 41);
|
|
521
|
+
i0.ɵɵtext(57);
|
|
522
|
+
i0.ɵɵelementEnd()();
|
|
523
|
+
i0.ɵɵelementStart(58, "div", 42);
|
|
524
|
+
i0.ɵɵconditionalCreate(59, ProfileDialogComponent_Conditional_59_Template, 1, 0, "mj-user-profile-settings")(60, ProfileDialogComponent_Conditional_60_Template, 3, 0, "div", 43);
|
|
525
|
+
i0.ɵɵelementEnd()()();
|
|
526
|
+
} if (rf & 2) {
|
|
527
|
+
i0.ɵɵclassProp("mj-profile--panel-open", ctx.ActivePanel !== "none");
|
|
528
|
+
i0.ɵɵadvance(8);
|
|
529
|
+
i0.ɵɵconditional(ctx.AvatarUrl ? 8 : ctx.AvatarIconClass ? 9 : 10);
|
|
530
|
+
i0.ɵɵadvance(7);
|
|
531
|
+
i0.ɵɵtextInterpolate(ctx.UserName);
|
|
532
|
+
i0.ɵɵadvance(2);
|
|
533
|
+
i0.ɵɵtextInterpolate(ctx.UserEmail);
|
|
534
|
+
i0.ɵɵadvance();
|
|
535
|
+
i0.ɵɵconditional(ctx.RoleChips.length > 0 ? 18 : -1);
|
|
536
|
+
i0.ɵɵadvance(9);
|
|
537
|
+
i0.ɵɵtextInterpolate2(" ", ctx.AccountType, " \u00B7 ", ctx.AccountStatus, " ");
|
|
538
|
+
i0.ɵɵadvance();
|
|
539
|
+
i0.ɵɵconditional(ctx.MemberSince ? 28 : -1);
|
|
540
|
+
i0.ɵɵadvance(8);
|
|
541
|
+
i0.ɵɵtextInterpolate(ctx.ThemeLabel);
|
|
542
|
+
i0.ɵɵadvance(6);
|
|
543
|
+
i0.ɵɵconditional(ctx.UnreadCount > 0 ? 42 : -1);
|
|
544
|
+
i0.ɵɵadvance();
|
|
545
|
+
i0.ɵɵconditional(ctx.LoadingNotifications ? 43 : 44);
|
|
546
|
+
i0.ɵɵadvance(9);
|
|
547
|
+
i0.ɵɵclassProp("mj-profile__panel--open", ctx.ActivePanel !== "none");
|
|
548
|
+
i0.ɵɵadvance(5);
|
|
549
|
+
i0.ɵɵtextInterpolate(ctx.PanelTitle);
|
|
550
|
+
i0.ɵɵadvance(2);
|
|
551
|
+
i0.ɵɵconditional(ctx.ActivePanel === "photo" ? 59 : ctx.ActivePanel === "theme" ? 60 : -1);
|
|
552
|
+
} }, dependencies: [CommonModule, ExplorerSettingsModule, i1.UserProfileSettingsComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n width: 100%;\n height: 100%;\n}\n.mj-profile[_ngcontent-%COMP%] {\n display: block;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n height: 100%;\n min-height: 0;\n position: relative;\n font-family: inherit;\n overflow: hidden;\n}\n.mj-profile__close[_ngcontent-%COMP%] {\n position: absolute;\n top: 12px; right: 12px;\n width: 36px; height: 36px;\n border: none; border-radius: 8px;\n background: rgba(255, 255, 255, 0.18);\n backdrop-filter: blur(8px);\n color: #fff;\n cursor: pointer;\n font-size: 16px;\n display: flex; align-items: center; justify-content: center;\n transition: background 0.15s, opacity 0.2s;\n z-index: 4;\n}\n.mj-profile__close[_ngcontent-%COMP%]:hover { background: rgba(255, 255, 255, 0.3); }\n.mj-profile--panel-open[_ngcontent-%COMP%] .mj-profile__close[_ngcontent-%COMP%] { opacity: 0; pointer-events: none; }\n\n\n\n.mj-profile__main[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n transition: transform 0.32s cubic-bezier(0.4, 0, 0.2, 1);\n}\n.mj-profile--panel-open[_ngcontent-%COMP%] .mj-profile__main[_ngcontent-%COMP%] {\n transform: translateX(-12%);\n pointer-events: none;\n}\n\n.mj-profile__hero[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #264FAF 0%, #0076b6 100%);\n color: #fff;\n padding: 22px 24px 56px;\n position: relative;\n overflow: hidden;\n flex-shrink: 0;\n}\n.mj-profile__hero[_ngcontent-%COMP%]::before {\n content: '';\n position: absolute;\n inset: -50%;\n background: radial-gradient(circle, rgba(255, 255, 255, 0.10) 0%, transparent 60%);\n animation: _ngcontent-%COMP%_mj-profile-rotate 24s linear infinite;\n pointer-events: none;\n}\n@media (prefers-reduced-motion: reduce) {\n .mj-profile__hero[_ngcontent-%COMP%]::before { animation: none; }\n}\n@keyframes _ngcontent-%COMP%_mj-profile-rotate { to { transform: rotate(360deg); } }\n\n.mj-profile__hero-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 1.2px;\n opacity: 0.85;\n position: relative;\n z-index: 1;\n}\n\n.mj-profile__avatar-zone[_ngcontent-%COMP%] {\n position: relative;\n width: 96px;\n height: 96px;\n margin: -48px auto 12px;\n z-index: 2;\n}\n.mj-profile__avatar[_ngcontent-%COMP%] {\n width: 96px;\n height: 96px;\n border-radius: 50%;\n background: linear-gradient(135deg, #264FAF 0%, #0076b6 100%);\n color: #fff;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 32px;\n font-weight: 700;\n border: 4px solid var(--mj-bg-surface);\n box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);\n object-fit: cover;\n overflow: hidden;\n}\nimg.mj-profile__avatar[_ngcontent-%COMP%] { background: var(--mj-bg-surface-card); }\n.mj-profile__avatar--icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] { font-size: 36px; }\n\n.mj-profile__avatar-edit[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 2px; right: 2px;\n width: 30px; height: 30px;\n border-radius: 50%;\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border: 2px solid var(--mj-bg-surface);\n cursor: pointer;\n display: flex; align-items: center; justify-content: center;\n font-size: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);\n transition: transform 0.15s;\n}\n.mj-profile__avatar-edit[_ngcontent-%COMP%]:hover { transform: scale(1.1); }\n\n.mj-profile__identity[_ngcontent-%COMP%] {\n text-align: center;\n padding: 0 24px 16px;\n flex-shrink: 0;\n}\n.mj-profile__name[_ngcontent-%COMP%] {\n margin: 0 0 4px;\n font-size: 22px;\n font-weight: 700;\n letter-spacing: -0.4px;\n color: var(--mj-text-primary);\n}\n.mj-profile__email[_ngcontent-%COMP%] {\n margin: 0 0 12px;\n color: var(--mj-text-muted);\n font-size: 13px;\n word-break: break-all;\n}\n.mj-profile__chips[_ngcontent-%COMP%] {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n justify-content: center;\n}\n.mj-profile__chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 9px;\n border-radius: 100px;\n font-size: 11px;\n font-weight: 600;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n color: var(--mj-brand-primary);\n}\n.mj-profile__chip--admin[_ngcontent-%COMP%] {\n background: color-mix(in srgb, #f59e0b 14%, transparent);\n color: #b45309;\n}\n.mj-profile__chip--dev[_ngcontent-%COMP%] {\n background: color-mix(in srgb, #10b981 14%, transparent);\n color: #047857;\n}\n\n.mj-profile__field-list[_ngcontent-%COMP%] {\n padding: 0 24px;\n flex-shrink: 0;\n}\n.mj-profile__field[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 12px 0;\n gap: 14px;\n border-top: 1px solid var(--mj-border-subtle);\n width: 100%;\n text-align: left;\n background: transparent;\n border-left: none;\n border-right: none;\n border-bottom: none;\n font-family: inherit;\n color: inherit;\n}\n.mj-profile__field[_ngcontent-%COMP%]:first-child { border-top: none; }\n.mj-profile__field--button[_ngcontent-%COMP%] {\n cursor: pointer;\n transition: background 0.12s;\n margin: 0 -8px;\n padding-left: 8px;\n padding-right: 8px;\n border-radius: 8px;\n border-top: none;\n}\n.mj-profile__field--button[_ngcontent-%COMP%] + .mj-profile__field--button[_ngcontent-%COMP%] { margin-top: 0; }\n.mj-profile__field--button[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); }\n.mj-profile__field--button[_ngcontent-%COMP%]:hover .mj-profile__field-chev[_ngcontent-%COMP%] { color: var(--mj-brand-primary); }\n.mj-profile__field-icon[_ngcontent-%COMP%] {\n width: 32px; height: 32px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n color: var(--mj-text-secondary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n flex-shrink: 0;\n}\n.mj-profile__field-body[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n.mj-profile__field-label[_ngcontent-%COMP%] {\n font-size: 10.5px;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n font-weight: 600;\n letter-spacing: 0.5px;\n}\n.mj-profile__field-value[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--mj-text-primary);\n margin-top: 2px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.mj-profile__field-muted[_ngcontent-%COMP%] { color: var(--mj-text-muted); }\n.mj-profile__field-chev[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 11px;\n transition: color 0.15s;\n}\n\n.mj-profile__section[_ngcontent-%COMP%] {\n padding: 16px 24px 8px;\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n}\n.mj-profile__section-head[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 10px;\n}\n.mj-profile__section-head[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 11px;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.6px;\n}\n.mj-profile__unread[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n padding: 2px 8px;\n border-radius: 100px;\n}\n.mj-profile__channels-loading[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n font-size: 12.5px;\n padding: 12px;\n text-align: center;\n}\n.mj-profile__channels[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.mj-profile__channel[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 14px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.15s;\n font-family: inherit;\n text-align: left;\n width: 100%;\n}\n.mj-profile__channel[_ngcontent-%COMP%]:hover:not(:disabled) {\n border-color: var(--mj-border-default);\n background: var(--mj-bg-surface-hover);\n}\n.mj-profile__channel[_ngcontent-%COMP%]:disabled { cursor: wait; opacity: 0.7; }\n.mj-profile__channel-icon[_ngcontent-%COMP%] {\n width: 32px; height: 32px;\n border-radius: 8px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n display: flex; align-items: center; justify-content: center;\n font-size: 13px;\n flex-shrink: 0;\n transition: all 0.15s;\n}\n.mj-profile__channel--on[_ngcontent-%COMP%] .mj-profile__channel-icon[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, transparent);\n color: var(--mj-brand-primary);\n}\n.mj-profile__channel-label[_ngcontent-%COMP%] {\n flex: 1;\n font-size: 13.5px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n.mj-profile__channel-state[_ngcontent-%COMP%] {\n flex-shrink: 0;\n color: var(--mj-text-muted);\n font-size: 13px;\n min-width: 36px;\n display: flex; justify-content: flex-end; align-items: center;\n}\n\n.mj-profile__switch[_ngcontent-%COMP%] {\n width: 36px;\n height: 20px;\n background: var(--mj-border-strong);\n border-radius: 100px;\n position: relative;\n transition: background 0.2s;\n display: inline-block;\n}\n.mj-profile__switch-knob[_ngcontent-%COMP%] {\n position: absolute;\n top: 2px; left: 2px;\n width: 16px; height: 16px;\n background: white;\n border-radius: 50%;\n transition: transform 0.2s;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);\n}\n.mj-profile__switch--on[_ngcontent-%COMP%] { background: var(--mj-brand-primary); }\n.mj-profile__switch--on[_ngcontent-%COMP%] .mj-profile__switch-knob[_ngcontent-%COMP%] { transform: translateX(16px); }\n\n.mj-profile__footer[_ngcontent-%COMP%] {\n border-top: 1px solid var(--mj-border-subtle);\n padding: 14px 20px;\n display: flex;\n gap: 8px;\n align-items: center;\n flex-shrink: 0;\n}\n.mj-profile__spacer[_ngcontent-%COMP%] { flex: 1; }\n.mj-profile__btn[_ngcontent-%COMP%] {\n padding: 9px 16px;\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n font-family: inherit;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n transition: all 0.15s;\n}\n.mj-profile__btn[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); border-color: var(--mj-border-strong); }\n.mj-profile__btn--primary[_ngcontent-%COMP%] {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n.mj-profile__btn--primary[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 88%, black);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 88%, black);\n}\n.mj-profile__btn--danger[_ngcontent-%COMP%] {\n color: var(--mj-status-error);\n border-color: color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-border-default));\n}\n.mj-profile__btn--danger[_ngcontent-%COMP%]:hover {\n background: color-mix(in srgb, var(--mj-status-error) 8%, transparent);\n border-color: var(--mj-status-error);\n}\n\n\n\n.mj-profile__panel[_ngcontent-%COMP%] {\n position: absolute;\n inset: 0;\n background: var(--mj-bg-surface);\n transform: translateX(100%);\n transition: transform 0.32s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n flex-direction: column;\n z-index: 3;\n}\n.mj-profile__panel--open[_ngcontent-%COMP%] {\n transform: translateX(0);\n box-shadow: -8px 0 24px rgba(0, 0, 0, 0.06);\n}\n.mj-profile__panel-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 14px 18px;\n border-bottom: 1px solid var(--mj-border-subtle);\n background: var(--mj-bg-surface-card);\n flex-shrink: 0;\n}\n.mj-profile__panel-back[_ngcontent-%COMP%] {\n width: 34px; height: 34px;\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n cursor: pointer;\n display: flex; align-items: center; justify-content: center;\n font-size: 13px;\n transition: all 0.15s;\n font-family: inherit;\n}\n.mj-profile__panel-back[_ngcontent-%COMP%]:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n.mj-profile__panel-title[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n letter-spacing: -0.2px;\n}\n.mj-profile__panel-body[_ngcontent-%COMP%] {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: 16px 20px 20px;\n}\n\n\n\n.mj-profile__themes[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.mj-profile__theme[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 12px 14px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.15s;\n text-align: left;\n width: 100%;\n font-family: inherit;\n}\n.mj-profile__theme[_ngcontent-%COMP%]:hover:not(:disabled) {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface-hover);\n}\n.mj-profile__theme[_ngcontent-%COMP%]:disabled { cursor: wait; opacity: 0.7; }\n.mj-profile__theme--active[_ngcontent-%COMP%] {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface-card));\n}\n.mj-profile__theme-swatch[_ngcontent-%COMP%] {\n width: 40px; height: 40px;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n flex-shrink: 0;\n border: 1px solid var(--mj-border-default);\n}\n.mj-profile__theme-swatch--light[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #ffffff 0%, #f1f5f9 100%);\n color: #f59e0b;\n}\n.mj-profile__theme-swatch--dark[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%);\n color: #94a3b8;\n border-color: #334155;\n}\n.mj-profile__theme-swatch--system[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #ffffff 0%, #ffffff 49%, #1e293b 51%, #0f172a 100%);\n color: var(--mj-text-secondary);\n}\n.mj-profile__theme-info[_ngcontent-%COMP%] { flex: 1; min-width: 0; }\n.mj-profile__theme-name[_ngcontent-%COMP%] {\n font-size: 13.5px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n.mj-profile__theme-desc[_ngcontent-%COMP%] {\n font-size: 11.5px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.mj-profile__theme-check[_ngcontent-%COMP%] {\n color: var(--mj-brand-primary);\n font-size: 14px;\n flex-shrink: 0;\n}\n\n@media (max-width: 480px) {\n .mj-profile__hero[_ngcontent-%COMP%] { padding: 20px 18px 48px; }\n .mj-profile__avatar-zone[_ngcontent-%COMP%] { width: 88px; height: 88px; margin-top: -44px; }\n .mj-profile__avatar[_ngcontent-%COMP%] { width: 88px; height: 88px; font-size: 28px; }\n .mj-profile__name[_ngcontent-%COMP%] { font-size: 19px; }\n .mj-profile__field-list[_ngcontent-%COMP%], \n .mj-profile__section[_ngcontent-%COMP%] { padding-left: 18px; padding-right: 18px; }\n .mj-profile__footer[_ngcontent-%COMP%] { padding: 12px 16px; }\n .mj-profile--panel-open[_ngcontent-%COMP%] .mj-profile__main[_ngcontent-%COMP%] { transform: translateX(-20%); }\n .mj-profile__panel-body[_ngcontent-%COMP%] { padding: 14px 16px 16px; }\n}"] });
|
|
553
|
+
}
|
|
554
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ProfileDialogComponent, [{
|
|
555
|
+
type: Component,
|
|
556
|
+
args: [{ selector: 'mj-profile-dialog', standalone: true, imports: [CommonModule, ExplorerSettingsModule], template: `
|
|
557
|
+
<div class="mj-profile" [class.mj-profile--panel-open]="ActivePanel !== 'none'" role="document">
|
|
558
|
+
<button class="mj-profile__close" type="button" aria-label="Close" (click)="OnCloseClick()">
|
|
559
|
+
<i class="fa-solid fa-xmark"></i>
|
|
560
|
+
</button>
|
|
561
|
+
|
|
562
|
+
<!-- ===== MAIN VIEW ===== -->
|
|
563
|
+
<div class="mj-profile__main">
|
|
564
|
+
<div class="mj-profile__hero">
|
|
565
|
+
<h3 class="mj-profile__hero-title">My Profile</h3>
|
|
566
|
+
</div>
|
|
567
|
+
|
|
568
|
+
<div class="mj-profile__avatar-zone">
|
|
569
|
+
@if (AvatarUrl) {
|
|
570
|
+
<img class="mj-profile__avatar mj-profile__avatar--img"
|
|
571
|
+
[src]="AvatarUrl" alt="" (error)="OnAvatarLoadError()" />
|
|
572
|
+
} @else if (AvatarIconClass) {
|
|
573
|
+
<div class="mj-profile__avatar mj-profile__avatar--icon">
|
|
574
|
+
<i [class]="AvatarIconClass"></i>
|
|
575
|
+
</div>
|
|
576
|
+
} @else {
|
|
577
|
+
<div class="mj-profile__avatar">{{ UserInitials }}</div>
|
|
578
|
+
}
|
|
579
|
+
<button class="mj-profile__avatar-edit" type="button" title="Change photo"
|
|
580
|
+
(click)="OpenPanel('photo')">
|
|
581
|
+
<i class="fa-solid fa-camera"></i>
|
|
582
|
+
</button>
|
|
583
|
+
</div>
|
|
584
|
+
|
|
585
|
+
<div class="mj-profile__identity">
|
|
586
|
+
<h2 class="mj-profile__name">{{ UserName }}</h2>
|
|
587
|
+
<p class="mj-profile__email">{{ UserEmail }}</p>
|
|
588
|
+
@if (RoleChips.length > 0) {
|
|
589
|
+
<div class="mj-profile__chips">
|
|
590
|
+
@for (chip of RoleChips; track chip.label) {
|
|
591
|
+
<span class="mj-profile__chip" [class]="'mj-profile__chip--' + chip.tone">
|
|
592
|
+
@if (chip.icon) { <i [class]="chip.icon"></i> }
|
|
593
|
+
{{ chip.label }}
|
|
594
|
+
</span>
|
|
595
|
+
}
|
|
596
|
+
</div>
|
|
597
|
+
}
|
|
598
|
+
</div>
|
|
599
|
+
|
|
600
|
+
<div class="mj-profile__field-list">
|
|
601
|
+
<div class="mj-profile__field">
|
|
602
|
+
<div class="mj-profile__field-icon"><i class="fa-solid fa-id-badge"></i></div>
|
|
603
|
+
<div class="mj-profile__field-body">
|
|
604
|
+
<div class="mj-profile__field-label">Account</div>
|
|
605
|
+
<div class="mj-profile__field-value">
|
|
606
|
+
{{ AccountType }} · {{ AccountStatus }}
|
|
607
|
+
@if (MemberSince) {
|
|
608
|
+
<span class="mj-profile__field-muted"> · {{ MemberSince }}</span>
|
|
609
|
+
}
|
|
610
|
+
</div>
|
|
611
|
+
</div>
|
|
612
|
+
</div>
|
|
613
|
+
|
|
614
|
+
<button class="mj-profile__field mj-profile__field--button" type="button" (click)="OpenPanel('theme')">
|
|
615
|
+
<div class="mj-profile__field-icon"><i class="fa-solid fa-palette"></i></div>
|
|
616
|
+
<div class="mj-profile__field-body">
|
|
617
|
+
<div class="mj-profile__field-label">Theme</div>
|
|
618
|
+
<div class="mj-profile__field-value">{{ ThemeLabel }}</div>
|
|
619
|
+
</div>
|
|
620
|
+
<i class="fa-solid fa-chevron-right mj-profile__field-chev"></i>
|
|
621
|
+
</button>
|
|
622
|
+
</div>
|
|
623
|
+
|
|
624
|
+
<div class="mj-profile__section">
|
|
625
|
+
<div class="mj-profile__section-head">
|
|
626
|
+
<h4>Notifications</h4>
|
|
627
|
+
@if (UnreadCount > 0) {
|
|
628
|
+
<span class="mj-profile__unread">{{ UnreadCount }} unread</span>
|
|
629
|
+
}
|
|
630
|
+
</div>
|
|
631
|
+
@if (LoadingNotifications) {
|
|
632
|
+
<div class="mj-profile__channels-loading">
|
|
633
|
+
<i class="fa-solid fa-spinner fa-spin"></i> Loading…
|
|
634
|
+
</div>
|
|
635
|
+
} @else {
|
|
636
|
+
<div class="mj-profile__channels">
|
|
637
|
+
@for (ch of Channels; track ch.key) {
|
|
638
|
+
<button type="button"
|
|
639
|
+
class="mj-profile__channel"
|
|
640
|
+
[class.mj-profile__channel--on]="ch.enabled"
|
|
641
|
+
[disabled]="ch.saving"
|
|
642
|
+
(click)="ToggleChannel(ch)">
|
|
643
|
+
<div class="mj-profile__channel-icon"><i [class]="ch.icon"></i></div>
|
|
644
|
+
<div class="mj-profile__channel-label">{{ ch.label }}</div>
|
|
645
|
+
<div class="mj-profile__channel-state">
|
|
646
|
+
@if (ch.saving) {
|
|
647
|
+
<i class="fa-solid fa-spinner fa-spin"></i>
|
|
648
|
+
} @else {
|
|
649
|
+
<span class="mj-profile__switch" [class.mj-profile__switch--on]="ch.enabled">
|
|
650
|
+
<span class="mj-profile__switch-knob"></span>
|
|
651
|
+
</span>
|
|
652
|
+
}
|
|
653
|
+
</div>
|
|
654
|
+
</button>
|
|
655
|
+
}
|
|
656
|
+
</div>
|
|
657
|
+
}
|
|
658
|
+
</div>
|
|
659
|
+
|
|
660
|
+
<div class="mj-profile__footer">
|
|
661
|
+
<button class="mj-profile__btn mj-profile__btn--danger" type="button" (click)="OnSignOut()">
|
|
662
|
+
<i class="fa-solid fa-arrow-right-from-bracket"></i>
|
|
663
|
+
Sign out
|
|
664
|
+
</button>
|
|
665
|
+
<span class="mj-profile__spacer"></span>
|
|
666
|
+
<button class="mj-profile__btn mj-profile__btn--primary" type="button" (click)="OnCloseClick()">
|
|
667
|
+
Done
|
|
668
|
+
</button>
|
|
669
|
+
</div>
|
|
670
|
+
</div>
|
|
671
|
+
|
|
672
|
+
<!-- ===== SLIDE-IN PANEL ===== -->
|
|
673
|
+
<div class="mj-profile__panel" [class.mj-profile__panel--open]="ActivePanel !== 'none'">
|
|
674
|
+
<div class="mj-profile__panel-header">
|
|
675
|
+
<button class="mj-profile__panel-back" type="button" aria-label="Back" (click)="ClosePanel()">
|
|
676
|
+
<i class="fa-solid fa-arrow-left"></i>
|
|
677
|
+
</button>
|
|
678
|
+
<h3 class="mj-profile__panel-title">{{ PanelTitle }}</h3>
|
|
679
|
+
</div>
|
|
680
|
+
<div class="mj-profile__panel-body">
|
|
681
|
+
@if (ActivePanel === 'photo') {
|
|
682
|
+
<mj-user-profile-settings></mj-user-profile-settings>
|
|
683
|
+
} @else if (ActivePanel === 'theme') {
|
|
684
|
+
<div class="mj-profile__themes">
|
|
685
|
+
@for (theme of ThemeOptions; track theme.id) {
|
|
686
|
+
<button type="button"
|
|
687
|
+
class="mj-profile__theme"
|
|
688
|
+
[class.mj-profile__theme--active]="theme.id === ThemePreference"
|
|
689
|
+
[class.mj-profile__theme--saving]="SavingTheme === theme.id"
|
|
690
|
+
[disabled]="!!SavingTheme"
|
|
691
|
+
(click)="SelectTheme(theme.id)">
|
|
692
|
+
<div class="mj-profile__theme-swatch" [class]="'mj-profile__theme-swatch--' + theme.swatch">
|
|
693
|
+
<i [class]="theme.icon"></i>
|
|
694
|
+
</div>
|
|
695
|
+
<div class="mj-profile__theme-info">
|
|
696
|
+
<div class="mj-profile__theme-name">{{ theme.name }}</div>
|
|
697
|
+
@if (theme.description) {
|
|
698
|
+
<div class="mj-profile__theme-desc">{{ theme.description }}</div>
|
|
699
|
+
}
|
|
700
|
+
</div>
|
|
701
|
+
@if (SavingTheme === theme.id) {
|
|
702
|
+
<i class="fa-solid fa-spinner fa-spin mj-profile__theme-check"></i>
|
|
703
|
+
} @else if (theme.id === ThemePreference) {
|
|
704
|
+
<i class="fa-solid fa-check mj-profile__theme-check"></i>
|
|
705
|
+
}
|
|
706
|
+
</button>
|
|
707
|
+
}
|
|
708
|
+
</div>
|
|
709
|
+
}
|
|
710
|
+
</div>
|
|
711
|
+
</div>
|
|
712
|
+
</div>
|
|
713
|
+
`, styles: ["\n:host {\n display: block;\n width: 100%;\n height: 100%;\n}\n.mj-profile {\n display: block;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n height: 100%;\n min-height: 0;\n position: relative;\n font-family: inherit;\n overflow: hidden;\n}\n.mj-profile__close {\n position: absolute;\n top: 12px; right: 12px;\n width: 36px; height: 36px;\n border: none; border-radius: 8px;\n background: rgba(255, 255, 255, 0.18);\n backdrop-filter: blur(8px);\n color: #fff;\n cursor: pointer;\n font-size: 16px;\n display: flex; align-items: center; justify-content: center;\n transition: background 0.15s, opacity 0.2s;\n z-index: 4;\n}\n.mj-profile__close:hover { background: rgba(255, 255, 255, 0.3); }\n.mj-profile--panel-open .mj-profile__close { opacity: 0; pointer-events: none; }\n\n/* ============ MAIN VIEW ============ */\n.mj-profile__main {\n display: flex;\n flex-direction: column;\n height: 100%;\n transition: transform 0.32s cubic-bezier(0.4, 0, 0.2, 1);\n}\n.mj-profile--panel-open .mj-profile__main {\n transform: translateX(-12%);\n pointer-events: none;\n}\n\n.mj-profile__hero {\n background: linear-gradient(135deg, #264FAF 0%, #0076b6 100%);\n color: #fff;\n padding: 22px 24px 56px;\n position: relative;\n overflow: hidden;\n flex-shrink: 0;\n}\n.mj-profile__hero::before {\n content: '';\n position: absolute;\n inset: -50%;\n background: radial-gradient(circle, rgba(255, 255, 255, 0.10) 0%, transparent 60%);\n animation: mj-profile-rotate 24s linear infinite;\n pointer-events: none;\n}\n@media (prefers-reduced-motion: reduce) {\n .mj-profile__hero::before { animation: none; }\n}\n@keyframes mj-profile-rotate { to { transform: rotate(360deg); } }\n\n.mj-profile__hero-title {\n margin: 0;\n font-size: 12px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 1.2px;\n opacity: 0.85;\n position: relative;\n z-index: 1;\n}\n\n.mj-profile__avatar-zone {\n position: relative;\n width: 96px;\n height: 96px;\n margin: -48px auto 12px;\n z-index: 2;\n}\n.mj-profile__avatar {\n width: 96px;\n height: 96px;\n border-radius: 50%;\n background: linear-gradient(135deg, #264FAF 0%, #0076b6 100%);\n color: #fff;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 32px;\n font-weight: 700;\n border: 4px solid var(--mj-bg-surface);\n box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);\n object-fit: cover;\n overflow: hidden;\n}\nimg.mj-profile__avatar { background: var(--mj-bg-surface-card); }\n.mj-profile__avatar--icon i { font-size: 36px; }\n\n.mj-profile__avatar-edit {\n position: absolute;\n bottom: 2px; right: 2px;\n width: 30px; height: 30px;\n border-radius: 50%;\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border: 2px solid var(--mj-bg-surface);\n cursor: pointer;\n display: flex; align-items: center; justify-content: center;\n font-size: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);\n transition: transform 0.15s;\n}\n.mj-profile__avatar-edit:hover { transform: scale(1.1); }\n\n.mj-profile__identity {\n text-align: center;\n padding: 0 24px 16px;\n flex-shrink: 0;\n}\n.mj-profile__name {\n margin: 0 0 4px;\n font-size: 22px;\n font-weight: 700;\n letter-spacing: -0.4px;\n color: var(--mj-text-primary);\n}\n.mj-profile__email {\n margin: 0 0 12px;\n color: var(--mj-text-muted);\n font-size: 13px;\n word-break: break-all;\n}\n.mj-profile__chips {\n display: flex;\n gap: 6px;\n flex-wrap: wrap;\n justify-content: center;\n}\n.mj-profile__chip {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 3px 9px;\n border-radius: 100px;\n font-size: 11px;\n font-weight: 600;\n background: color-mix(in srgb, var(--mj-brand-primary) 12%, transparent);\n color: var(--mj-brand-primary);\n}\n.mj-profile__chip--admin {\n background: color-mix(in srgb, #f59e0b 14%, transparent);\n color: #b45309;\n}\n.mj-profile__chip--dev {\n background: color-mix(in srgb, #10b981 14%, transparent);\n color: #047857;\n}\n\n.mj-profile__field-list {\n padding: 0 24px;\n flex-shrink: 0;\n}\n.mj-profile__field {\n display: flex;\n align-items: center;\n padding: 12px 0;\n gap: 14px;\n border-top: 1px solid var(--mj-border-subtle);\n width: 100%;\n text-align: left;\n background: transparent;\n border-left: none;\n border-right: none;\n border-bottom: none;\n font-family: inherit;\n color: inherit;\n}\n.mj-profile__field:first-child { border-top: none; }\n.mj-profile__field--button {\n cursor: pointer;\n transition: background 0.12s;\n margin: 0 -8px;\n padding-left: 8px;\n padding-right: 8px;\n border-radius: 8px;\n border-top: none;\n}\n.mj-profile__field--button + .mj-profile__field--button { margin-top: 0; }\n.mj-profile__field--button:hover { background: var(--mj-bg-surface-hover); }\n.mj-profile__field--button:hover .mj-profile__field-chev { color: var(--mj-brand-primary); }\n.mj-profile__field-icon {\n width: 32px; height: 32px;\n background: var(--mj-bg-surface-sunken);\n border-radius: 8px;\n color: var(--mj-text-secondary);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n flex-shrink: 0;\n}\n.mj-profile__field-body { flex: 1; min-width: 0; }\n.mj-profile__field-label {\n font-size: 10.5px;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n font-weight: 600;\n letter-spacing: 0.5px;\n}\n.mj-profile__field-value {\n font-size: 13px;\n color: var(--mj-text-primary);\n margin-top: 2px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.mj-profile__field-muted { color: var(--mj-text-muted); }\n.mj-profile__field-chev {\n color: var(--mj-text-muted);\n font-size: 11px;\n transition: color 0.15s;\n}\n\n.mj-profile__section {\n padding: 16px 24px 8px;\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n}\n.mj-profile__section-head {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 10px;\n}\n.mj-profile__section-head h4 {\n margin: 0;\n font-size: 11px;\n font-weight: 700;\n color: var(--mj-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.6px;\n}\n.mj-profile__unread {\n font-size: 11px;\n font-weight: 600;\n color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n padding: 2px 8px;\n border-radius: 100px;\n}\n.mj-profile__channels-loading {\n color: var(--mj-text-muted);\n font-size: 12.5px;\n padding: 12px;\n text-align: center;\n}\n.mj-profile__channels {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.mj-profile__channel {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 14px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.15s;\n font-family: inherit;\n text-align: left;\n width: 100%;\n}\n.mj-profile__channel:hover:not(:disabled) {\n border-color: var(--mj-border-default);\n background: var(--mj-bg-surface-hover);\n}\n.mj-profile__channel:disabled { cursor: wait; opacity: 0.7; }\n.mj-profile__channel-icon {\n width: 32px; height: 32px;\n border-radius: 8px;\n background: var(--mj-bg-surface-sunken);\n color: var(--mj-text-secondary);\n display: flex; align-items: center; justify-content: center;\n font-size: 13px;\n flex-shrink: 0;\n transition: all 0.15s;\n}\n.mj-profile__channel--on .mj-profile__channel-icon {\n background: color-mix(in srgb, var(--mj-brand-primary) 14%, transparent);\n color: var(--mj-brand-primary);\n}\n.mj-profile__channel-label {\n flex: 1;\n font-size: 13.5px;\n font-weight: 500;\n color: var(--mj-text-primary);\n}\n.mj-profile__channel-state {\n flex-shrink: 0;\n color: var(--mj-text-muted);\n font-size: 13px;\n min-width: 36px;\n display: flex; justify-content: flex-end; align-items: center;\n}\n\n.mj-profile__switch {\n width: 36px;\n height: 20px;\n background: var(--mj-border-strong);\n border-radius: 100px;\n position: relative;\n transition: background 0.2s;\n display: inline-block;\n}\n.mj-profile__switch-knob {\n position: absolute;\n top: 2px; left: 2px;\n width: 16px; height: 16px;\n background: white;\n border-radius: 50%;\n transition: transform 0.2s;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);\n}\n.mj-profile__switch--on { background: var(--mj-brand-primary); }\n.mj-profile__switch--on .mj-profile__switch-knob { transform: translateX(16px); }\n\n.mj-profile__footer {\n border-top: 1px solid var(--mj-border-subtle);\n padding: 14px 20px;\n display: flex;\n gap: 8px;\n align-items: center;\n flex-shrink: 0;\n}\n.mj-profile__spacer { flex: 1; }\n.mj-profile__btn {\n padding: 9px 16px;\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n cursor: pointer;\n font-size: 13px;\n font-weight: 500;\n font-family: inherit;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n transition: all 0.15s;\n}\n.mj-profile__btn:hover { background: var(--mj-bg-surface-hover); border-color: var(--mj-border-strong); }\n.mj-profile__btn--primary {\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border-color: var(--mj-brand-primary);\n}\n.mj-profile__btn--primary:hover {\n background: color-mix(in srgb, var(--mj-brand-primary) 88%, black);\n border-color: color-mix(in srgb, var(--mj-brand-primary) 88%, black);\n}\n.mj-profile__btn--danger {\n color: var(--mj-status-error);\n border-color: color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-border-default));\n}\n.mj-profile__btn--danger:hover {\n background: color-mix(in srgb, var(--mj-status-error) 8%, transparent);\n border-color: var(--mj-status-error);\n}\n\n/* ============ SLIDE-IN PANEL ============ */\n.mj-profile__panel {\n position: absolute;\n inset: 0;\n background: var(--mj-bg-surface);\n transform: translateX(100%);\n transition: transform 0.32s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex;\n flex-direction: column;\n z-index: 3;\n}\n.mj-profile__panel--open {\n transform: translateX(0);\n box-shadow: -8px 0 24px rgba(0, 0, 0, 0.06);\n}\n.mj-profile__panel-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 14px 18px;\n border-bottom: 1px solid var(--mj-border-subtle);\n background: var(--mj-bg-surface-card);\n flex-shrink: 0;\n}\n.mj-profile__panel-back {\n width: 34px; height: 34px;\n border-radius: 8px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n cursor: pointer;\n display: flex; align-items: center; justify-content: center;\n font-size: 13px;\n transition: all 0.15s;\n font-family: inherit;\n}\n.mj-profile__panel-back:hover {\n background: var(--mj-bg-surface-hover);\n border-color: var(--mj-brand-primary);\n color: var(--mj-brand-primary);\n}\n.mj-profile__panel-title {\n margin: 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--mj-text-primary);\n letter-spacing: -0.2px;\n}\n.mj-profile__panel-body {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: 16px 20px 20px;\n}\n\n/* Theme picker */\n.mj-profile__themes {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.mj-profile__theme {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 12px 14px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-subtle);\n border-radius: 10px;\n cursor: pointer;\n transition: all 0.15s;\n text-align: left;\n width: 100%;\n font-family: inherit;\n}\n.mj-profile__theme:hover:not(:disabled) {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface-hover);\n}\n.mj-profile__theme:disabled { cursor: wait; opacity: 0.7; }\n.mj-profile__theme--active {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 5%, var(--mj-bg-surface-card));\n}\n.mj-profile__theme-swatch {\n width: 40px; height: 40px;\n border-radius: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 16px;\n flex-shrink: 0;\n border: 1px solid var(--mj-border-default);\n}\n.mj-profile__theme-swatch--light {\n background: linear-gradient(135deg, #ffffff 0%, #f1f5f9 100%);\n color: #f59e0b;\n}\n.mj-profile__theme-swatch--dark {\n background: linear-gradient(135deg, #1e293b 0%, #0f172a 100%);\n color: #94a3b8;\n border-color: #334155;\n}\n.mj-profile__theme-swatch--system {\n background: linear-gradient(135deg, #ffffff 0%, #ffffff 49%, #1e293b 51%, #0f172a 100%);\n color: var(--mj-text-secondary);\n}\n.mj-profile__theme-info { flex: 1; min-width: 0; }\n.mj-profile__theme-name {\n font-size: 13.5px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n.mj-profile__theme-desc {\n font-size: 11.5px;\n color: var(--mj-text-muted);\n margin-top: 2px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.mj-profile__theme-check {\n color: var(--mj-brand-primary);\n font-size: 14px;\n flex-shrink: 0;\n}\n\n@media (max-width: 480px) {\n .mj-profile__hero { padding: 20px 18px 48px; }\n .mj-profile__avatar-zone { width: 88px; height: 88px; margin-top: -44px; }\n .mj-profile__avatar { width: 88px; height: 88px; font-size: 28px; }\n .mj-profile__name { font-size: 19px; }\n .mj-profile__field-list,\n .mj-profile__section { padding-left: 18px; padding-right: 18px; }\n .mj-profile__footer { padding: 12px 16px; }\n .mj-profile--panel-open .mj-profile__main { transform: translateX(-20%); }\n .mj-profile__panel-body { padding: 14px 16px 16px; }\n}\n "] }]
|
|
714
|
+
}], null, { CloseRequested: [{
|
|
715
|
+
type: Output
|
|
716
|
+
}], AvatarUrl: [{
|
|
717
|
+
type: Input
|
|
718
|
+
}], AvatarIconClass: [{
|
|
719
|
+
type: Input
|
|
720
|
+
}] }); })();
|
|
721
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ProfileDialogComponent, { className: "ProfileDialogComponent", filePath: "src/lib/profile/profile-dialog.component.ts", lineNumber: 720 }); })();
|
|
722
|
+
//# sourceMappingURL=profile-dialog.component.js.map
|