@eo4geo/ngx-bok-utils 1.0.10 → 1.1.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.
@@ -1,14 +1,37 @@
1
1
  import * as i0 from '@angular/core';
2
- import { EventEmitter, Component, Output, Input, HostListener } from '@angular/core';
2
+ import { EventEmitter, Output, Component, inject, Injectable, Input, HostListener } from '@angular/core';
3
3
  import * as i1 from 'primeng/toolbar';
4
4
  import { ToolbarModule } from 'primeng/toolbar';
5
- import * as i3 from '@angular/common';
5
+ import * as i4$1 from '@angular/common';
6
6
  import { CommonModule } from '@angular/common';
7
- import * as i1$1 from 'primeng/button';
7
+ import * as i2 from 'primeng/button';
8
8
  import { ButtonModule } from 'primeng/button';
9
- import * as i2 from 'primeng/tieredmenu';
9
+ import * as i3$1 from 'primeng/tieredmenu';
10
10
  import { TieredMenuModule } from 'primeng/tieredmenu';
11
- import * as i1$2 from '@angular/router';
11
+ import * as i5$1 from 'primeng/avatar';
12
+ import { AvatarModule } from 'primeng/avatar';
13
+ import { AvatarGroupModule } from 'primeng/avatargroup';
14
+ import * as i6 from 'primeng/inputtext';
15
+ import { InputTextModule } from 'primeng/inputtext';
16
+ import * as i3 from 'primeng/dialog';
17
+ import { DialogModule } from 'primeng/dialog';
18
+ import * as i7 from 'primeng/floatlabel';
19
+ import { FloatLabelModule } from 'primeng/floatlabel';
20
+ import * as i8 from '@angular/forms';
21
+ import { FormsModule } from '@angular/forms';
22
+ import * as i4 from 'primeng/inputicon';
23
+ import { InputIconModule } from 'primeng/inputicon';
24
+ import * as i5 from 'primeng/iconfield';
25
+ import { IconFieldModule } from 'primeng/iconfield';
26
+ import { Message } from 'primeng/message';
27
+ import { Auth, authState, signInWithEmailAndPassword, createUserWithEmailAndPassword, signInWithPopup, GoogleAuthProvider, sendPasswordResetEmail, signOut, updateProfile } from '@angular/fire/auth';
28
+ import { Firestore, collection, doc, getDoc, setDoc, updateDoc, docData } from '@angular/fire/firestore';
29
+ import { BehaviorSubject, switchMap, of } from 'rxjs';
30
+ import * as i1$1 from '@angular/router';
31
+ import * as i9 from 'primeng/toast';
32
+ import { ToastModule } from 'primeng/toast';
33
+ import * as i2$1 from 'primeng/api';
34
+ import { MessageService } from 'primeng/api';
12
35
 
13
36
  class FooterComponent {
14
37
  openReleaseNotes = new EventEmitter();
@@ -19,19 +42,252 @@ class FooterComponent {
19
42
  clickUserManual() {
20
43
  this.openUserManual.emit();
21
44
  }
22
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.1", ngImport: i0, type: FooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
23
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.1", type: FooterComponent, isStandalone: true, selector: "footer", outputs: { openReleaseNotes: "openReleaseNotes", openUserManual: "openUserManual" }, ngImport: i0, template: "<div class=\"footer\">\r\n <p-toolbar [style]=\"{'color': 'white', 'background': 'none', 'border': '0px', 'gap': '3rem'}\">\r\n <ng-template #start>\r\n <div class=\"flex flex-column align-items-center gap-1\">\r\n <div class=\"inline\">\r\n <a href=\"http://www.eo4geo.eu/\" target=\"_blank\"><img class=\"logo\" src=\"assets/images/EO4GEO_LOGO_WHITE.png\" alt=\"LogoEO4GEO\"></a>\r\n <a href=\"https://www.spacesuite-project.eu/\" target=\"_blank\"><img class=\"logo\" src=\"assets/images/SpaceSUITE_horizontal_white.png\" alt=\"LogoSpaceSUITE\"></a>\r\n </div>\r\n <span style=\"font-size: x-small;\">All tools were developed by <a href=\"https://geotec.uji.es/\" target=\"_blank\">GEOTEC</a></span>\r\n </div>\r\n </ng-template>\r\n <ng-template #center>\r\n <div style=\"font-size: smaller;\" class=\"flex flex-wrap gap-1\">\r\n <span>\u00A9 2025 spaceSUITE</span>\r\n <span class=\"link-separator\">\r\n | <a (click)=\"clickUserManual()\">User Manual</a>\r\n </span>\r\n <span class=\"link-separator\">\r\n | <a (click)=\"clickReleaseNotes()\">Release Notes</a>\r\n </span>\r\n <span class=\"link-separator\">\r\n | <a href=\"mailto:eo4geo@gmail.com?subject=EO4GEO%20Tools%20Contact\">Contact</a>\r\n </span>\r\n <span class=\"link-separator\">\r\n | <a href=\"https://www.spacesuite-project.eu/privacy-policy/\" target=\"_blank\">Privacy Policy</a>\r\n </span>\r\n </div>\r\n </ng-template>\r\n <ng-template #end>\r\n <div class=\"flex flex-column align-items-center gap-1 max-w-20rem\">\r\n <img class=\"logo\" src=\"assets/images/EU_Funding.png\" alt=\"LogoEU\">\r\n <span class=\"white-space-normal\" style=\"font-size: xx-small;\">Views and opinions expressed are however those of the author(s) only and do not necessarily reflect those of the European Union or the European Education and Culture Executive Agency (EACEA). Neither the European Union nor EACEA can be held responsible for them.</span>\r\n </div>\r\n </ng-template>\r\n </p-toolbar>\r\n</div>", styles: [".footer{background-color:var(--primary-color);box-shadow:0 -4px 6px #0000001a;color:#fff;padding:1.25rem;position:relative;bottom:0;left:0;width:100%}.footer a{color:gray;cursor:pointer;text-decoration:none}.footer a:hover{color:#fff}.logo{width:auto;height:2vw;margin:1rem;min-height:40px}.toolbar{background:var(--primary-color)!important;color:#fff!important;border:0px!important}.link-separator{color:gray}.link-separator:hover{color:var(--hover-color);cursor:default}\n"], dependencies: [{ kind: "ngmodule", type: ToolbarModule }, { kind: "component", type: i1.Toolbar, selector: "p-toolbar", inputs: ["style", "styleClass", "ariaLabelledBy"] }] });
45
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: FooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
46
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: FooterComponent, isStandalone: true, selector: "footer", outputs: { openReleaseNotes: "openReleaseNotes", openUserManual: "openUserManual" }, ngImport: i0, template: "<div class=\"footer\">\r\n <p-toolbar [style]=\"{'color': 'white', 'background': 'none', 'border': '0px', 'gap': '3rem'}\">\r\n <ng-template #start>\r\n <div class=\"flex flex-column align-items-center gap-1\">\r\n <div class=\"inline\">\r\n <a href=\"http://www.eo4geo.eu/\" target=\"_blank\"><img class=\"logo\" src=\"assets/images/EO4GEO_LOGO_WHITE.png\" alt=\"LogoEO4GEO\"></a>\r\n <a href=\"https://www.spacesuite-project.eu/\" target=\"_blank\"><img class=\"logo\" src=\"assets/images/SpaceSUITE_horizontal_white.png\" alt=\"LogoSpaceSUITE\"></a>\r\n </div>\r\n <span style=\"font-size: x-small;\">All tools were developed by <a href=\"https://geotec.uji.es/\" target=\"_blank\">GEOTEC</a></span>\r\n </div>\r\n </ng-template>\r\n <ng-template #center>\r\n <div style=\"font-size: smaller;\" class=\"flex flex-wrap gap-1\">\r\n <span>\u00A9 2025 spaceSUITE</span>\r\n <span class=\"link-separator\">\r\n | <a (click)=\"clickUserManual()\">User Manual</a>\r\n </span>\r\n <span class=\"link-separator\">\r\n | <a (click)=\"clickReleaseNotes()\">Release Notes</a>\r\n </span>\r\n <span class=\"link-separator\">\r\n | <a href=\"mailto:eo4geo@gmail.com?subject=EO4GEO%20Tools%20Contact\">Contact</a>\r\n </span>\r\n <span class=\"link-separator\">\r\n | <a href=\"https://www.spacesuite-project.eu/privacy-policy/\" target=\"_blank\">Privacy Policy</a>\r\n </span>\r\n </div>\r\n </ng-template>\r\n <ng-template #end>\r\n <div class=\"flex flex-column align-items-center gap-1 max-w-20rem\">\r\n <img class=\"logo\" src=\"assets/images/EU_Funding.png\" alt=\"LogoEU\">\r\n <span class=\"white-space-normal\" style=\"font-size: xx-small;\">Views and opinions expressed are however those of the author(s) only and do not necessarily reflect those of the European Union or the European Education and Culture Executive Agency (EACEA). Neither the European Union nor EACEA can be held responsible for them.</span>\r\n </div>\r\n </ng-template>\r\n </p-toolbar>\r\n</div>", styles: [".footer{background-color:var(--primary-color);color:#fff;padding:1.25rem;position:relative;bottom:0;left:0;width:100%}.footer a{color:gray;cursor:pointer;text-decoration:none}.footer a:hover{color:#fff}.logo{width:auto;height:2vw;margin:1rem;min-height:40px}.toolbar{background:var(--primary-color)!important;color:#fff!important;border:0px!important}.link-separator{color:gray}.link-separator:hover{color:var(--hover-color);cursor:default}\n"], dependencies: [{ kind: "ngmodule", type: ToolbarModule }, { kind: "component", type: i1.Toolbar, selector: "p-toolbar", inputs: ["style", "styleClass", "ariaLabelledBy"] }] });
24
47
  }
25
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.1", ngImport: i0, type: FooterComponent, decorators: [{
48
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: FooterComponent, decorators: [{
26
49
  type: Component,
27
- args: [{ standalone: true, selector: 'footer', imports: [ToolbarModule], template: "<div class=\"footer\">\r\n <p-toolbar [style]=\"{'color': 'white', 'background': 'none', 'border': '0px', 'gap': '3rem'}\">\r\n <ng-template #start>\r\n <div class=\"flex flex-column align-items-center gap-1\">\r\n <div class=\"inline\">\r\n <a href=\"http://www.eo4geo.eu/\" target=\"_blank\"><img class=\"logo\" src=\"assets/images/EO4GEO_LOGO_WHITE.png\" alt=\"LogoEO4GEO\"></a>\r\n <a href=\"https://www.spacesuite-project.eu/\" target=\"_blank\"><img class=\"logo\" src=\"assets/images/SpaceSUITE_horizontal_white.png\" alt=\"LogoSpaceSUITE\"></a>\r\n </div>\r\n <span style=\"font-size: x-small;\">All tools were developed by <a href=\"https://geotec.uji.es/\" target=\"_blank\">GEOTEC</a></span>\r\n </div>\r\n </ng-template>\r\n <ng-template #center>\r\n <div style=\"font-size: smaller;\" class=\"flex flex-wrap gap-1\">\r\n <span>\u00A9 2025 spaceSUITE</span>\r\n <span class=\"link-separator\">\r\n | <a (click)=\"clickUserManual()\">User Manual</a>\r\n </span>\r\n <span class=\"link-separator\">\r\n | <a (click)=\"clickReleaseNotes()\">Release Notes</a>\r\n </span>\r\n <span class=\"link-separator\">\r\n | <a href=\"mailto:eo4geo@gmail.com?subject=EO4GEO%20Tools%20Contact\">Contact</a>\r\n </span>\r\n <span class=\"link-separator\">\r\n | <a href=\"https://www.spacesuite-project.eu/privacy-policy/\" target=\"_blank\">Privacy Policy</a>\r\n </span>\r\n </div>\r\n </ng-template>\r\n <ng-template #end>\r\n <div class=\"flex flex-column align-items-center gap-1 max-w-20rem\">\r\n <img class=\"logo\" src=\"assets/images/EU_Funding.png\" alt=\"LogoEU\">\r\n <span class=\"white-space-normal\" style=\"font-size: xx-small;\">Views and opinions expressed are however those of the author(s) only and do not necessarily reflect those of the European Union or the European Education and Culture Executive Agency (EACEA). Neither the European Union nor EACEA can be held responsible for them.</span>\r\n </div>\r\n </ng-template>\r\n </p-toolbar>\r\n</div>", styles: [".footer{background-color:var(--primary-color);box-shadow:0 -4px 6px #0000001a;color:#fff;padding:1.25rem;position:relative;bottom:0;left:0;width:100%}.footer a{color:gray;cursor:pointer;text-decoration:none}.footer a:hover{color:#fff}.logo{width:auto;height:2vw;margin:1rem;min-height:40px}.toolbar{background:var(--primary-color)!important;color:#fff!important;border:0px!important}.link-separator{color:gray}.link-separator:hover{color:var(--hover-color);cursor:default}\n"] }]
50
+ args: [{ standalone: true, selector: 'footer', imports: [ToolbarModule], template: "<div class=\"footer\">\r\n <p-toolbar [style]=\"{'color': 'white', 'background': 'none', 'border': '0px', 'gap': '3rem'}\">\r\n <ng-template #start>\r\n <div class=\"flex flex-column align-items-center gap-1\">\r\n <div class=\"inline\">\r\n <a href=\"http://www.eo4geo.eu/\" target=\"_blank\"><img class=\"logo\" src=\"assets/images/EO4GEO_LOGO_WHITE.png\" alt=\"LogoEO4GEO\"></a>\r\n <a href=\"https://www.spacesuite-project.eu/\" target=\"_blank\"><img class=\"logo\" src=\"assets/images/SpaceSUITE_horizontal_white.png\" alt=\"LogoSpaceSUITE\"></a>\r\n </div>\r\n <span style=\"font-size: x-small;\">All tools were developed by <a href=\"https://geotec.uji.es/\" target=\"_blank\">GEOTEC</a></span>\r\n </div>\r\n </ng-template>\r\n <ng-template #center>\r\n <div style=\"font-size: smaller;\" class=\"flex flex-wrap gap-1\">\r\n <span>\u00A9 2025 spaceSUITE</span>\r\n <span class=\"link-separator\">\r\n | <a (click)=\"clickUserManual()\">User Manual</a>\r\n </span>\r\n <span class=\"link-separator\">\r\n | <a (click)=\"clickReleaseNotes()\">Release Notes</a>\r\n </span>\r\n <span class=\"link-separator\">\r\n | <a href=\"mailto:eo4geo@gmail.com?subject=EO4GEO%20Tools%20Contact\">Contact</a>\r\n </span>\r\n <span class=\"link-separator\">\r\n | <a href=\"https://www.spacesuite-project.eu/privacy-policy/\" target=\"_blank\">Privacy Policy</a>\r\n </span>\r\n </div>\r\n </ng-template>\r\n <ng-template #end>\r\n <div class=\"flex flex-column align-items-center gap-1 max-w-20rem\">\r\n <img class=\"logo\" src=\"assets/images/EU_Funding.png\" alt=\"LogoEU\">\r\n <span class=\"white-space-normal\" style=\"font-size: xx-small;\">Views and opinions expressed are however those of the author(s) only and do not necessarily reflect those of the European Union or the European Education and Culture Executive Agency (EACEA). Neither the European Union nor EACEA can be held responsible for them.</span>\r\n </div>\r\n </ng-template>\r\n </p-toolbar>\r\n</div>", styles: [".footer{background-color:var(--primary-color);color:#fff;padding:1.25rem;position:relative;bottom:0;left:0;width:100%}.footer a{color:gray;cursor:pointer;text-decoration:none}.footer a:hover{color:#fff}.logo{width:auto;height:2vw;margin:1rem;min-height:40px}.toolbar{background:var(--primary-color)!important;color:#fff!important;border:0px!important}.link-separator{color:gray}.link-separator:hover{color:var(--hover-color);cursor:default}\n"] }]
28
51
  }], propDecorators: { openReleaseNotes: [{
29
52
  type: Output
30
53
  }], openUserManual: [{
31
54
  type: Output
32
55
  }] } });
33
56
 
57
+ class UserService {
58
+ auth = inject(Auth);
59
+ db = inject(Firestore);
60
+ userCollection;
61
+ errorMessages = new Map([
62
+ ["auth/user-not-found", "Invalid email."],
63
+ ["auth/wrong-password", "Incorrect password."],
64
+ ["auth/missing-password", "Incorrect password."],
65
+ ["auth/invalid-email", "Invalid email."],
66
+ ["auth/email-already-in-use", "This email is already in use."],
67
+ ["auth/weak-password", "Weak password. Use at least 6 characters."],
68
+ ["auth/passwords-do-not-match", "Passwords do not match."],
69
+ ["auth/cancelled-popup-request", "The popup request was canceled."],
70
+ ["auth/network-request-failed", "Network error."],
71
+ ]);
72
+ userStateSubject = new BehaviorSubject({
73
+ logged: false,
74
+ nameInitial: 'A'
75
+ });
76
+ constructor() {
77
+ this.userCollection = collection(this.db, 'Users');
78
+ authState(this.auth).subscribe(user => {
79
+ const logged = !!user;
80
+ const nameInitial = user?.displayName ? user.displayName[0].toUpperCase() : 'A';
81
+ this.userStateSubject.next({ logged, nameInitial });
82
+ });
83
+ }
84
+ async loginWithEmailAndPassword(email, password) {
85
+ try {
86
+ if (!this.isValidEmail(email))
87
+ throw { code: "auth/invalid-email" };
88
+ await signInWithEmailAndPassword(this.auth, email, password);
89
+ }
90
+ catch (error) {
91
+ throw this.handleAuthError(error);
92
+ }
93
+ }
94
+ async registerWithEmailAndPassword(email, password, repeatPassword) {
95
+ try {
96
+ if (!this.isValidEmail(email))
97
+ throw { code: "auth/invalid-email" };
98
+ if (password.length < 6)
99
+ throw { code: "auth/weak-password" };
100
+ if (password !== repeatPassword)
101
+ throw { code: "auth/passwords-do-not-match" };
102
+ await createUserWithEmailAndPassword(this.auth, email, password);
103
+ await this.checkUser();
104
+ }
105
+ catch (error) {
106
+ throw this.handleAuthError(error);
107
+ }
108
+ }
109
+ async loginWithGoogle() {
110
+ try {
111
+ await signInWithPopup(this.auth, new GoogleAuthProvider());
112
+ await this.checkUser();
113
+ }
114
+ catch (error) {
115
+ throw this.handleAuthError(error);
116
+ }
117
+ }
118
+ async recoverPassword(email) {
119
+ try {
120
+ if (!this.isValidEmail(email))
121
+ throw { code: "auth/invalid-email" };
122
+ await sendPasswordResetEmail(this.auth, email);
123
+ }
124
+ catch (error) {
125
+ throw this.handleAuthError(error);
126
+ }
127
+ }
128
+ async checkUser() {
129
+ if (!this.auth.currentUser)
130
+ return;
131
+ const userDocRef = doc(this.userCollection, this.auth.currentUser.uid);
132
+ const userDocSnap = await getDoc(userDocRef);
133
+ if (!userDocSnap.exists()) {
134
+ await setDoc(userDocRef, {
135
+ _id: this.auth.currentUser.uid,
136
+ email: this.auth.currentUser.email,
137
+ name: this.auth.currentUser.displayName || "",
138
+ });
139
+ }
140
+ }
141
+ handleAuthError(error) {
142
+ if (error.code === "auth/popup-closed-by-user")
143
+ return '';
144
+ return this.errorMessages.get(error.code) || "An error occurred. Please try again.";
145
+ }
146
+ isValidEmail(email) {
147
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
148
+ return emailRegex.test(email);
149
+ }
150
+ getUserState() {
151
+ return this.userStateSubject.asObservable();
152
+ }
153
+ async logout() {
154
+ await signOut(this.auth);
155
+ }
156
+ async updateUserName(newName) {
157
+ const user = this.auth.currentUser;
158
+ if (user) {
159
+ try {
160
+ const userDocRef = doc(this.userCollection, user.uid);
161
+ await updateDoc(userDocRef, { name: newName });
162
+ await updateProfile(user, { displayName: newName });
163
+ this.userStateSubject.next({ logged: true, nameInitial: newName[0].toUpperCase() });
164
+ }
165
+ catch (error) {
166
+ console.error('Error updating name:', error);
167
+ throw error;
168
+ }
169
+ }
170
+ }
171
+ getNameAndEmail() {
172
+ return authState(this.auth).pipe(switchMap(user => {
173
+ if (user) {
174
+ const userDocRef = doc(this.userCollection, user.uid);
175
+ return docData(userDocRef);
176
+ }
177
+ return of(null);
178
+ }));
179
+ }
180
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: UserService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
181
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: UserService, providedIn: 'root' });
182
+ }
183
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: UserService, decorators: [{
184
+ type: Injectable,
185
+ args: [{
186
+ providedIn: 'root',
187
+ }]
188
+ }], ctorParameters: () => [] });
189
+
190
+ class SessionModalComponent {
191
+ userService;
192
+ visible = false;
193
+ visibleChange = new EventEmitter();
194
+ login = true;
195
+ resetpassword = false;
196
+ email = '';
197
+ password = '';
198
+ repeatPassword = '';
199
+ error = null;
200
+ constructor(userService) {
201
+ this.userService = userService;
202
+ }
203
+ ngOnChanges(changes) {
204
+ this.login = changes['visible'].currentValue;
205
+ this.resetpassword = !changes['visible'].currentValue;
206
+ this.email = '';
207
+ this.password = '';
208
+ this.repeatPassword = '';
209
+ this.error = null;
210
+ }
211
+ getHeader() {
212
+ if (this.resetpassword)
213
+ return 'Recover Password';
214
+ if (this.login)
215
+ return 'Login';
216
+ return 'Register';
217
+ }
218
+ getSwitchLabel() {
219
+ if (this.resetpassword)
220
+ return 'Return';
221
+ if (!this.login)
222
+ return 'Login';
223
+ return 'Register';
224
+ }
225
+ clickSwitchButton() {
226
+ this.error = null;
227
+ if (this.resetpassword)
228
+ this.resetpassword = !this.resetpassword;
229
+ else
230
+ this.login = !this.login;
231
+ }
232
+ clickMainButton() {
233
+ if (this.resetpassword)
234
+ return this.recoverPassword();
235
+ if (this.login)
236
+ return this.loginWithEmailAndPassword();
237
+ return this.registerWithEmailAndPassword();
238
+ }
239
+ async loginWithGoogle() {
240
+ try {
241
+ await this.userService.loginWithGoogle();
242
+ this.visibleChange.emit(false);
243
+ }
244
+ catch (error) {
245
+ this.error = error;
246
+ }
247
+ }
248
+ async loginWithEmailAndPassword() {
249
+ try {
250
+ await this.userService.loginWithEmailAndPassword(this.email, this.password);
251
+ this.visibleChange.emit(false);
252
+ }
253
+ catch (error) {
254
+ this.error = error;
255
+ }
256
+ }
257
+ async registerWithEmailAndPassword() {
258
+ try {
259
+ await this.userService.registerWithEmailAndPassword(this.email, this.password, this.repeatPassword);
260
+ this.visibleChange.emit(false);
261
+ }
262
+ catch (error) {
263
+ this.error = error;
264
+ }
265
+ }
266
+ async recoverPassword() {
267
+ try {
268
+ await this.userService.recoverPassword(this.email);
269
+ this.password = '';
270
+ this.repeatPassword = '';
271
+ this.resetpassword = !this.resetpassword;
272
+ }
273
+ catch (error) {
274
+ this.error = error;
275
+ }
276
+ }
277
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SessionModalComponent, deps: [{ token: UserService }], target: i0.ɵɵFactoryTarget.Component });
278
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: SessionModalComponent, isStandalone: true, selector: "sessionModal", inputs: { visible: "visible" }, outputs: { visibleChange: "visibleChange" }, usesOnChanges: true, ngImport: i0, template: "<p-dialog [header]=\"getHeader()\" [modal]=\"true\" [visible]=\"visible\" resizable=\"false\" (visibleChange)=\"visibleChange.emit($event)\" [style]=\"{color: 'var(--primary-color)'}\">\r\n <p-message *ngIf=\"error\" severity=\"error\" variant=\"simple\" styleClass=\"mb-4 white-space-normal\" class=\"error-info\">{{error}}</p-message>\r\n <div class=\"flex items-center gap-4 mt-2 mb-1\">\r\n <p-floatlabel variant=\"on\" [class]=\"error ? 'custom-floatlabel error-floatlabel' : 'custom-floatlabel'\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-user\" />\r\n <input pInputText id=\"email\" autocomplete=\"off\" [class]=\"error ? 'custom-input error-input' : 'custom-input'\" [(ngModel)]=\"email\"/>\r\n </p-iconfield>\r\n <label for=\"email\">Email</label>\r\n </p-floatlabel>\r\n </div>\r\n <div *ngIf=\"!resetpassword\" class=\"flex items-center gap-4 mt-4 mb-1\">\r\n <p-floatlabel variant=\"on\" [class]=\"error ? 'custom-floatlabel error-floatlabel' : 'custom-floatlabel'\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-lock\" />\r\n <input pInputText id=\"password\" autocomplete=\"off\" [class]=\"error ? 'custom-input error-input' : 'custom-input'\" [(ngModel)]=\"password\"/>\r\n </p-iconfield>\r\n <label for=\"password\">Password</label>\r\n </p-floatlabel>\r\n </div>\r\n <div *ngIf=\"!login\" class=\"flex items-center gap-4 mt-4 mb-1\">\r\n <p-floatlabel variant=\"on\" [class]=\"error ? 'custom-floatlabel error-floatlabel' : 'custom-floatlabel'\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-lock\" />\r\n <input pInputText id=\"rPassword\" autocomplete=\"off\" [class]=\"error ? 'custom-input error-input' : 'custom-input'\" [(ngModel)]=\"repeatPassword\"/>\r\n </p-iconfield>\r\n <label for=\"rPassword\">Repeat Password</label>\r\n </p-floatlabel>\r\n </div>\r\n <a *ngIf=\"login && !resetpassword\" class=\"inline-flex ml-2 text-sm\" (click)=\"resetpassword = !resetpassword; error = null;\">Forgot Password?</a>\r\n <div class=\"flex align-items-center justify-content-between gap-2 mt-4\">\r\n <div class=\"flex justify-end gap-2\">\r\n <p-button class=\"custom-button\" [label]=\"getHeader()\" (click)=\"clickMainButton()\" />\r\n <p-button severity=\"secondary\" class=\"custom-secondary-button\" [label]=\"getSwitchLabel()\" (click)=\"clickSwitchButton()\" />\r\n </div>\r\n <p-button *ngIf=\"!resetpassword\" class=\"custom-button\" icon=\"pi pi-google\" label=\"Google\" (click)=\"loginWithGoogle()\" />\r\n </div>\r\n</p-dialog>", styles: [".custom-input{--p-inputtext-focus-border-color: var(--hover-color);--p-inputtext-hover-border-color: var(--hover-color)}.custom-floatlabel{--p-floatlabel-focus-color: var(--hover-color)}.custom-secondary-button{--p-button-secondary-hover-color: var(--primary-color);--p-button-secondary-active-color: var(--primary-color)}.custom-button{--p-button-primary-background: var(--secondary-color);--p-button-primary-border-color: var(--secondary-color);--p-button-primary-hover-background: var(--hover-color);--p-button-primary-hover-border-color: var(--hover-color);--p-button-primary-active-background: color-mix(in srgb, var(--hover-color) 80%, black 20%);--p-button-primary-active-border-color: color-mix(in srgb, var(--hover-color) 90%, black 10%)}a{cursor:pointer}a:hover{color:var(--hover-color)}.error-info{--p-message-error-simple-color: var(--danger-color)}.error-input{--p-inputtext-border-color: var(--danger-color)}.error-floatlabel{--p-floatlabel-color: var(--danger-color)}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i3.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: InputIconModule }, { kind: "component", type: i4.InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["styleClass"] }, { kind: "ngmodule", type: IconFieldModule }, { kind: "component", type: i5.IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["iconPosition", "styleClass"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i6.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: FloatLabelModule }, { kind: "component", type: i7.FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i8.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i4$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant"], outputs: ["onClose"] }] });
279
+ }
280
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SessionModalComponent, decorators: [{
281
+ type: Component,
282
+ args: [{ standalone: true, selector: 'sessionModal', imports: [ButtonModule, DialogModule, InputIconModule, IconFieldModule, InputTextModule, FloatLabelModule, FormsModule, CommonModule, Message], template: "<p-dialog [header]=\"getHeader()\" [modal]=\"true\" [visible]=\"visible\" resizable=\"false\" (visibleChange)=\"visibleChange.emit($event)\" [style]=\"{color: 'var(--primary-color)'}\">\r\n <p-message *ngIf=\"error\" severity=\"error\" variant=\"simple\" styleClass=\"mb-4 white-space-normal\" class=\"error-info\">{{error}}</p-message>\r\n <div class=\"flex items-center gap-4 mt-2 mb-1\">\r\n <p-floatlabel variant=\"on\" [class]=\"error ? 'custom-floatlabel error-floatlabel' : 'custom-floatlabel'\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-user\" />\r\n <input pInputText id=\"email\" autocomplete=\"off\" [class]=\"error ? 'custom-input error-input' : 'custom-input'\" [(ngModel)]=\"email\"/>\r\n </p-iconfield>\r\n <label for=\"email\">Email</label>\r\n </p-floatlabel>\r\n </div>\r\n <div *ngIf=\"!resetpassword\" class=\"flex items-center gap-4 mt-4 mb-1\">\r\n <p-floatlabel variant=\"on\" [class]=\"error ? 'custom-floatlabel error-floatlabel' : 'custom-floatlabel'\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-lock\" />\r\n <input pInputText id=\"password\" autocomplete=\"off\" [class]=\"error ? 'custom-input error-input' : 'custom-input'\" [(ngModel)]=\"password\"/>\r\n </p-iconfield>\r\n <label for=\"password\">Password</label>\r\n </p-floatlabel>\r\n </div>\r\n <div *ngIf=\"!login\" class=\"flex items-center gap-4 mt-4 mb-1\">\r\n <p-floatlabel variant=\"on\" [class]=\"error ? 'custom-floatlabel error-floatlabel' : 'custom-floatlabel'\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-lock\" />\r\n <input pInputText id=\"rPassword\" autocomplete=\"off\" [class]=\"error ? 'custom-input error-input' : 'custom-input'\" [(ngModel)]=\"repeatPassword\"/>\r\n </p-iconfield>\r\n <label for=\"rPassword\">Repeat Password</label>\r\n </p-floatlabel>\r\n </div>\r\n <a *ngIf=\"login && !resetpassword\" class=\"inline-flex ml-2 text-sm\" (click)=\"resetpassword = !resetpassword; error = null;\">Forgot Password?</a>\r\n <div class=\"flex align-items-center justify-content-between gap-2 mt-4\">\r\n <div class=\"flex justify-end gap-2\">\r\n <p-button class=\"custom-button\" [label]=\"getHeader()\" (click)=\"clickMainButton()\" />\r\n <p-button severity=\"secondary\" class=\"custom-secondary-button\" [label]=\"getSwitchLabel()\" (click)=\"clickSwitchButton()\" />\r\n </div>\r\n <p-button *ngIf=\"!resetpassword\" class=\"custom-button\" icon=\"pi pi-google\" label=\"Google\" (click)=\"loginWithGoogle()\" />\r\n </div>\r\n</p-dialog>", styles: [".custom-input{--p-inputtext-focus-border-color: var(--hover-color);--p-inputtext-hover-border-color: var(--hover-color)}.custom-floatlabel{--p-floatlabel-focus-color: var(--hover-color)}.custom-secondary-button{--p-button-secondary-hover-color: var(--primary-color);--p-button-secondary-active-color: var(--primary-color)}.custom-button{--p-button-primary-background: var(--secondary-color);--p-button-primary-border-color: var(--secondary-color);--p-button-primary-hover-background: var(--hover-color);--p-button-primary-hover-border-color: var(--hover-color);--p-button-primary-active-background: color-mix(in srgb, var(--hover-color) 80%, black 20%);--p-button-primary-active-border-color: color-mix(in srgb, var(--hover-color) 90%, black 10%)}a{cursor:pointer}a:hover{color:var(--hover-color)}.error-info{--p-message-error-simple-color: var(--danger-color)}.error-input{--p-inputtext-border-color: var(--danger-color)}.error-floatlabel{--p-floatlabel-color: var(--danger-color)}\n"] }]
283
+ }], ctorParameters: () => [{ type: UserService }], propDecorators: { visible: [{
284
+ type: Input
285
+ }], visibleChange: [{
286
+ type: Output
287
+ }] } });
288
+
34
289
  class HeaderComponent {
290
+ userService;
35
291
  items = [
36
292
  {
37
293
  label: 'Tools',
@@ -55,7 +311,7 @@ class HeaderComponent {
55
311
  },
56
312
  {
57
313
  label: 'Curriculum Design Tool',
58
- icon: 'pi pi-sitemap',
314
+ icon: 'pi pi-graduation-cap',
59
315
  url: 'https://eo4geo-cdt.web.app',
60
316
  },
61
317
  {
@@ -67,12 +323,7 @@ class HeaderComponent {
67
323
  label: 'BoK Matching Tool',
68
324
  icon: 'pi pi-equals',
69
325
  url: 'https://eo4geo-bmt.web.app',
70
- },
71
- {
72
- label: 'Training Catalog Tool',
73
- icon: 'pi pi-graduation-cap',
74
- disabled: true,
75
- },
326
+ }
76
327
  ]
77
328
  },
78
329
  {
@@ -102,23 +353,62 @@ class HeaderComponent {
102
353
  ]
103
354
  }
104
355
  ];
356
+ userItems = [
357
+ {
358
+ label: 'Profile',
359
+ icon: 'pi pi-user'
360
+ },
361
+ {
362
+ label: 'Organization',
363
+ icon: 'pi pi-users'
364
+ },
365
+ {
366
+ label: 'Logout',
367
+ icon: 'pi pi-sign-out',
368
+ command: () => {
369
+ this.logout();
370
+ }
371
+ }
372
+ ];
105
373
  toolName = "BoK Visualization & Search";
374
+ login = false;
106
375
  hideMenu = true;
376
+ logged = false;
377
+ nameInitial = 'A';
378
+ showLoginModal = false;
379
+ userStateSubscription;
380
+ constructor(userService) {
381
+ this.userService = userService;
382
+ }
383
+ ngOnInit() {
384
+ this.userStateSubscription = this.userService.getUserState().subscribe(({ logged, nameInitial }) => {
385
+ this.logged = logged;
386
+ this.nameInitial = nameInitial;
387
+ });
388
+ }
389
+ ngOnDestroy() {
390
+ this.userStateSubscription?.unsubscribe();
391
+ }
392
+ async logout() {
393
+ await this.userService.logout();
394
+ }
107
395
  clickout(event) {
108
396
  if (!event.target.closest("p-tieredmenu") && !event.target.closest("p-button.custom-header-button")) {
109
397
  this.hideMenu = true;
110
398
  }
111
399
  }
112
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.1", ngImport: i0, type: HeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
113
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.1", type: HeaderComponent, isStandalone: true, selector: "header", inputs: { items: "items", toolName: "toolName" }, host: { listeners: { "document:click": "clickout($event)" } }, ngImport: i0, template: "<div class=\"header\">\r\n <div class=\"flex justify-content-between align-content-center p-4 mx-4\">\r\n <a href=\"https://www.spacesuite-project.eu/\" target=\"_blank\" class=\"align-self-center\"><img class=\"logo flex align-items-center justify-content-center\" src=\"assets/images/SpaceSUITE_horizontal_color.png\" alt=\"LogoSpaceSUITE\"></a>\r\n <h1 class=\"hidden xl:flex m-0 align-self-center\">{{toolName}}</h1>\r\n <div class=\"flex gap-8\">\r\n <div class=\"justify-content-center hidden md:flex\" *ngFor=\"let item of items;\">\r\n <div class=\"flex align-items-center justify-content-center gap-2 text-xl font-bold header-option\" (click)=\"subMenu.toggle($event)\" *ngIf=\"item.label != 'Share'; else share\">\r\n <i [class]=\"item.icon\"></i>\r\n <div>{{item.label}}</div>\r\n <i *ngIf=\"item.items\" class=\"pi pi-angle-down\"></i>\r\n </div>\r\n <p-tieredmenu #subMenu [model]=\"item.items\" [breakpoint]=\"'767px'\" class=\"custom-p-tieredmenu\" [popup]=\"true\" />\r\n <ng-template #share>\r\n <div class=\"flex align-items-center justify-content-center gap-3\">\r\n <div *ngFor=\"let social of item.items;\">\r\n <a [href]=\"social.url\" target=\"_blank\">\r\n <i [class]=\"social.icon\" style=\"font-size: 1.25rem\"></i>\r\n </a>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n \r\n <p-button #menuButton (click)=\"hideMenu = !hideMenu\" class=\"md:hidden flex align-items-center justify-content-center custom-header-button\" icon=\"pi pi-bars\" aria-label=\"Menu\"></p-button>\r\n </div>\r\n <p-tieredmenu #menu [hidden]=\"hideMenu\" [model]=\"items\" class=\"md:hidden custom-p-tieredmenu\"/>\r\n</div>\r\n", styles: [".header{background-color:#fff;color:var(--primary-color);position:relative;top:0;left:0;width:100%}.header:after{content:\"\";position:absolute;bottom:0;left:2rem;right:2rem;height:1px;background-color:#0000001a}.header a{color:var(--primary-color);cursor:pointer;text-decoration:none}.header a:hover{color:var(--hover-color)}.logo{width:auto;height:3.5vw;min-height:50px}.custom-header-button{--p-button-primary-background: var(--secondary-color);--p-button-primary-border-color: var(--secondary-color);--p-button-primary-hover-background: var(--hover-color);--p-button-primary-hover-border-color: var(--hover-color);--p-button-primary-active-background: color-mix(in srgb, var(--hover-color) 80%, black 20%);--p-button-primary-active-border-color: color-mix(in srgb, var(--hover-color) 90%, black 10%)}.header-option:hover{color:var(--hover-color);cursor:pointer}.custom-p-tieredmenu{--p-tieredmenu-item-icon-color: var(--primary-color);--p-tieredmenu-item-icon-active-color: var(--hover-color);--p-tieredmenu-item-icon-focus-color: var(--hover-color);--p-tieredmenu-item-color: var(--primary-color);--p-tieredmenu-item-active-color: var(--hover-color);--p-tieredmenu-item-focus-color: var(--hover-color)}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TieredMenuModule }, { kind: "component", type: i2.TieredMenu, selector: "p-tieredMenu, p-tieredmenu, p-tiered-menu", inputs: ["model", "popup", "style", "styleClass", "appendTo", "breakpoint", "autoZIndex", "baseZIndex", "autoDisplay", "showTransitionOptions", "hideTransitionOptions", "id", "ariaLabel", "ariaLabelledBy", "disabled", "tabindex"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
400
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: HeaderComponent, deps: [{ token: UserService }], target: i0.ɵɵFactoryTarget.Component });
401
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: HeaderComponent, isStandalone: true, selector: "header", inputs: { items: "items", toolName: "toolName", login: "login" }, host: { listeners: { "document:click": "clickout($event)" } }, ngImport: i0, template: "<div class=\"header\">\r\n <div class=\"flex align-content-center p-4 mx-4\">\r\n <a href=\"https://www.spacesuite-project.eu/\" target=\"_blank\" class=\"align-self-center\"><img class=\"logo flex align-items-center justify-content-center\" src=\"assets/images/SpaceSUITE_horizontal_color.png\" alt=\"LogoSpaceSUITE\"></a>\r\n <div class=\"hidden xl:flex align-self-center fixed-text\">\r\n <strong class=\"text-2xl overflow-hidden white-space-nowrap text-overflow-ellipsis\">\r\n {{toolName}}\r\n </strong>\r\n </div>\r\n <div class=\"flex gap-6 ml-auto\">\r\n <div class=\"justify-content-center hidden md:flex\" *ngFor=\"let item of items;\">\r\n <div class=\"flex align-items-center justify-content-center gap-2 text-xl font-bold header-option\" (click)=\"subMenu.toggle($event)\" *ngIf=\"item.label != 'Share'; else share\">\r\n <i [class]=\"item.icon\"></i>\r\n <div>{{item.label}}</div>\r\n <i *ngIf=\"item.items\" class=\"pi pi-angle-down\"></i>\r\n </div>\r\n <p-tieredmenu #subMenu [model]=\"item.items\" [breakpoint]=\"'767px'\" class=\"custom-p-tieredmenu\" [popup]=\"true\" />\r\n <ng-template #share>\r\n <div class=\"flex align-items-center justify-content-center gap-3\">\r\n <div *ngFor=\"let social of item.items;\">\r\n <a [href]=\"social.url\" target=\"_blank\" class=\"flex\">\r\n <i [class]=\"social.icon\" style=\"font-size: 1.25rem\"></i>\r\n </a>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n <div *ngIf=\"login\" class=\"hidden md:flex align-items-center justify-content-center\">\r\n <p-avatar *ngIf=\"logged; else login\" [label]=\"nameInitial\" class=\"custom-p-avatar\" shape=\"circle\" (click)=\"userMenu.toggle($event)\"></p-avatar>\r\n </div>\r\n <p-tieredmenu #userMenu [model]=\"userItems\" [breakpoint]=\"'767px'\" class=\"custom-p-tieredmenu\" [popup]=\"true\" />\r\n <ng-template #login>\r\n <p-button class=\"custom-header-button\" size=\"small\" label=\"Login\" aria-label=\"Login\" (onClick)=\"showLoginModal = !showLoginModal\"></p-button>\r\n </ng-template>\r\n </div>\r\n \r\n <p-button #menuButton (click)=\"hideMenu = !hideMenu\" class=\"md:hidden flex align-items-center custom-header-button ml-auto\" icon=\"pi pi-bars\" aria-label=\"Menu\"></p-button>\r\n </div>\r\n <p-tieredmenu #menu [hidden]=\"hideMenu\" [model]=\"items\" class=\"md:hidden custom-p-tieredmenu\"/>\r\n</div>\r\n\r\n<sessionModal [(visible)]=\"showLoginModal\"></sessionModal>\r\n", styles: [".header{background-color:#fff;color:var(--primary-color);position:relative;top:0;left:0;width:100%}.header:after{content:\"\";position:absolute;bottom:0;left:2rem;right:2rem;height:1px;background-color:#0000001a}.header a{color:var(--primary-color);cursor:pointer;text-decoration:none}.header a:hover{color:var(--hover-color)}.logo{width:auto;height:50px}.custom-header-button{--p-button-primary-background: var(--secondary-color);--p-button-primary-border-color: var(--secondary-color);--p-button-primary-hover-background: var(--hover-color);--p-button-primary-hover-border-color: var(--hover-color);--p-button-primary-active-background: color-mix(in srgb, var(--hover-color) 80%, black 20%);--p-button-primary-active-border-color: color-mix(in srgb, var(--hover-color) 90%, black 10%)}.header-option:hover{color:var(--hover-color);cursor:pointer}.custom-p-tieredmenu{--p-tieredmenu-item-icon-color: var(--primary-color);--p-tieredmenu-item-icon-active-color: var(--hover-color);--p-tieredmenu-item-icon-focus-color: var(--hover-color);--p-tieredmenu-item-color: var(--primary-color);--p-tieredmenu-item-active-color: var(--hover-color);--p-tieredmenu-item-focus-color: var(--hover-color)}.custom-p-avatar{color:var(--primary-color);cursor:pointer}.custom-p-avatar:hover{color:var(--hover-color)}.fixed-text{position:absolute;left:50%;transform:translate(-50%);z-index:10;max-width:20%}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TieredMenuModule }, { kind: "component", type: i3$1.TieredMenu, selector: "p-tieredMenu, p-tieredmenu, p-tiered-menu", inputs: ["model", "popup", "style", "styleClass", "appendTo", "breakpoint", "autoZIndex", "baseZIndex", "autoDisplay", "showTransitionOptions", "hideTransitionOptions", "id", "ariaLabel", "ariaLabelledBy", "disabled", "tabindex"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i4$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: AvatarModule }, { kind: "component", type: i5$1.Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "style", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }, { kind: "ngmodule", type: AvatarGroupModule }, { kind: "component", type: SessionModalComponent, selector: "sessionModal", inputs: ["visible"], outputs: ["visibleChange"] }] });
114
402
  }
115
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.1", ngImport: i0, type: HeaderComponent, decorators: [{
403
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: HeaderComponent, decorators: [{
116
404
  type: Component,
117
- args: [{ standalone: true, selector: 'header', imports: [ButtonModule, TieredMenuModule, CommonModule], template: "<div class=\"header\">\r\n <div class=\"flex justify-content-between align-content-center p-4 mx-4\">\r\n <a href=\"https://www.spacesuite-project.eu/\" target=\"_blank\" class=\"align-self-center\"><img class=\"logo flex align-items-center justify-content-center\" src=\"assets/images/SpaceSUITE_horizontal_color.png\" alt=\"LogoSpaceSUITE\"></a>\r\n <h1 class=\"hidden xl:flex m-0 align-self-center\">{{toolName}}</h1>\r\n <div class=\"flex gap-8\">\r\n <div class=\"justify-content-center hidden md:flex\" *ngFor=\"let item of items;\">\r\n <div class=\"flex align-items-center justify-content-center gap-2 text-xl font-bold header-option\" (click)=\"subMenu.toggle($event)\" *ngIf=\"item.label != 'Share'; else share\">\r\n <i [class]=\"item.icon\"></i>\r\n <div>{{item.label}}</div>\r\n <i *ngIf=\"item.items\" class=\"pi pi-angle-down\"></i>\r\n </div>\r\n <p-tieredmenu #subMenu [model]=\"item.items\" [breakpoint]=\"'767px'\" class=\"custom-p-tieredmenu\" [popup]=\"true\" />\r\n <ng-template #share>\r\n <div class=\"flex align-items-center justify-content-center gap-3\">\r\n <div *ngFor=\"let social of item.items;\">\r\n <a [href]=\"social.url\" target=\"_blank\">\r\n <i [class]=\"social.icon\" style=\"font-size: 1.25rem\"></i>\r\n </a>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n \r\n <p-button #menuButton (click)=\"hideMenu = !hideMenu\" class=\"md:hidden flex align-items-center justify-content-center custom-header-button\" icon=\"pi pi-bars\" aria-label=\"Menu\"></p-button>\r\n </div>\r\n <p-tieredmenu #menu [hidden]=\"hideMenu\" [model]=\"items\" class=\"md:hidden custom-p-tieredmenu\"/>\r\n</div>\r\n", styles: [".header{background-color:#fff;color:var(--primary-color);position:relative;top:0;left:0;width:100%}.header:after{content:\"\";position:absolute;bottom:0;left:2rem;right:2rem;height:1px;background-color:#0000001a}.header a{color:var(--primary-color);cursor:pointer;text-decoration:none}.header a:hover{color:var(--hover-color)}.logo{width:auto;height:3.5vw;min-height:50px}.custom-header-button{--p-button-primary-background: var(--secondary-color);--p-button-primary-border-color: var(--secondary-color);--p-button-primary-hover-background: var(--hover-color);--p-button-primary-hover-border-color: var(--hover-color);--p-button-primary-active-background: color-mix(in srgb, var(--hover-color) 80%, black 20%);--p-button-primary-active-border-color: color-mix(in srgb, var(--hover-color) 90%, black 10%)}.header-option:hover{color:var(--hover-color);cursor:pointer}.custom-p-tieredmenu{--p-tieredmenu-item-icon-color: var(--primary-color);--p-tieredmenu-item-icon-active-color: var(--hover-color);--p-tieredmenu-item-icon-focus-color: var(--hover-color);--p-tieredmenu-item-color: var(--primary-color);--p-tieredmenu-item-active-color: var(--hover-color);--p-tieredmenu-item-focus-color: var(--hover-color)}\n"] }]
118
- }], propDecorators: { items: [{
405
+ args: [{ standalone: true, selector: 'header', imports: [ButtonModule, TieredMenuModule, CommonModule, AvatarModule, AvatarGroupModule, SessionModalComponent], template: "<div class=\"header\">\r\n <div class=\"flex align-content-center p-4 mx-4\">\r\n <a href=\"https://www.spacesuite-project.eu/\" target=\"_blank\" class=\"align-self-center\"><img class=\"logo flex align-items-center justify-content-center\" src=\"assets/images/SpaceSUITE_horizontal_color.png\" alt=\"LogoSpaceSUITE\"></a>\r\n <div class=\"hidden xl:flex align-self-center fixed-text\">\r\n <strong class=\"text-2xl overflow-hidden white-space-nowrap text-overflow-ellipsis\">\r\n {{toolName}}\r\n </strong>\r\n </div>\r\n <div class=\"flex gap-6 ml-auto\">\r\n <div class=\"justify-content-center hidden md:flex\" *ngFor=\"let item of items;\">\r\n <div class=\"flex align-items-center justify-content-center gap-2 text-xl font-bold header-option\" (click)=\"subMenu.toggle($event)\" *ngIf=\"item.label != 'Share'; else share\">\r\n <i [class]=\"item.icon\"></i>\r\n <div>{{item.label}}</div>\r\n <i *ngIf=\"item.items\" class=\"pi pi-angle-down\"></i>\r\n </div>\r\n <p-tieredmenu #subMenu [model]=\"item.items\" [breakpoint]=\"'767px'\" class=\"custom-p-tieredmenu\" [popup]=\"true\" />\r\n <ng-template #share>\r\n <div class=\"flex align-items-center justify-content-center gap-3\">\r\n <div *ngFor=\"let social of item.items;\">\r\n <a [href]=\"social.url\" target=\"_blank\" class=\"flex\">\r\n <i [class]=\"social.icon\" style=\"font-size: 1.25rem\"></i>\r\n </a>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n <div *ngIf=\"login\" class=\"hidden md:flex align-items-center justify-content-center\">\r\n <p-avatar *ngIf=\"logged; else login\" [label]=\"nameInitial\" class=\"custom-p-avatar\" shape=\"circle\" (click)=\"userMenu.toggle($event)\"></p-avatar>\r\n </div>\r\n <p-tieredmenu #userMenu [model]=\"userItems\" [breakpoint]=\"'767px'\" class=\"custom-p-tieredmenu\" [popup]=\"true\" />\r\n <ng-template #login>\r\n <p-button class=\"custom-header-button\" size=\"small\" label=\"Login\" aria-label=\"Login\" (onClick)=\"showLoginModal = !showLoginModal\"></p-button>\r\n </ng-template>\r\n </div>\r\n \r\n <p-button #menuButton (click)=\"hideMenu = !hideMenu\" class=\"md:hidden flex align-items-center custom-header-button ml-auto\" icon=\"pi pi-bars\" aria-label=\"Menu\"></p-button>\r\n </div>\r\n <p-tieredmenu #menu [hidden]=\"hideMenu\" [model]=\"items\" class=\"md:hidden custom-p-tieredmenu\"/>\r\n</div>\r\n\r\n<sessionModal [(visible)]=\"showLoginModal\"></sessionModal>\r\n", styles: [".header{background-color:#fff;color:var(--primary-color);position:relative;top:0;left:0;width:100%}.header:after{content:\"\";position:absolute;bottom:0;left:2rem;right:2rem;height:1px;background-color:#0000001a}.header a{color:var(--primary-color);cursor:pointer;text-decoration:none}.header a:hover{color:var(--hover-color)}.logo{width:auto;height:50px}.custom-header-button{--p-button-primary-background: var(--secondary-color);--p-button-primary-border-color: var(--secondary-color);--p-button-primary-hover-background: var(--hover-color);--p-button-primary-hover-border-color: var(--hover-color);--p-button-primary-active-background: color-mix(in srgb, var(--hover-color) 80%, black 20%);--p-button-primary-active-border-color: color-mix(in srgb, var(--hover-color) 90%, black 10%)}.header-option:hover{color:var(--hover-color);cursor:pointer}.custom-p-tieredmenu{--p-tieredmenu-item-icon-color: var(--primary-color);--p-tieredmenu-item-icon-active-color: var(--hover-color);--p-tieredmenu-item-icon-focus-color: var(--hover-color);--p-tieredmenu-item-color: var(--primary-color);--p-tieredmenu-item-active-color: var(--hover-color);--p-tieredmenu-item-focus-color: var(--hover-color)}.custom-p-avatar{color:var(--primary-color);cursor:pointer}.custom-p-avatar:hover{color:var(--hover-color)}.fixed-text{position:absolute;left:50%;transform:translate(-50%);z-index:10;max-width:20%}\n"] }]
406
+ }], ctorParameters: () => [{ type: UserService }], propDecorators: { items: [{
119
407
  type: Input
120
408
  }], toolName: [{
121
409
  type: Input
410
+ }], login: [{
411
+ type: Input
122
412
  }], clickout: [{
123
413
  type: HostListener,
124
414
  args: ['document:click', ['$event']]
@@ -132,13 +422,63 @@ class NotFoundPageComponent {
132
422
  goToHomepage() {
133
423
  this.router.navigate([''], { replaceUrl: true });
134
424
  }
135
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.1", ngImport: i0, type: NotFoundPageComponent, deps: [{ token: i1$2.Router }], target: i0.ɵɵFactoryTarget.Component });
136
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.1", type: NotFoundPageComponent, isStandalone: true, selector: "not-found-page", ngImport: i0, template: "<div class=\"flex flex-column justify-content-center align-items-center m-8\">\r\n <img src=\"assets/images/hosting-404-error-1.png\" alt=\"not Found\" class=\"w-4 m-4\">\r\n <h1>page not found</h1>\r\n <p-button label=\"Go To Homepage\" size=\"large\" class=\"custom-button\" (onClick)=\"goToHomepage()\"></p-button>\r\n</div>", styles: [".custom-button{--p-button-primary-color: white;--p-button-primary-background: var(--secondary-color);--p-button-primary-border-color: var(--secondary-color);--p-button-primary-hover-background: var(--hover-color);--p-button-primary-hover-border-color: var(--hover-color);--p-button-primary-active-background: color-mix(in srgb, var(--hover-color) 80%, black 20%);--p-button-primary-active-border-color: color-mix(in srgb, var(--hover-color) 90%, black 10%)}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i1$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }] });
425
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: NotFoundPageComponent, deps: [{ token: i1$1.Router }], target: i0.ɵɵFactoryTarget.Component });
426
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: NotFoundPageComponent, isStandalone: true, selector: "not-found-page", ngImport: i0, template: "<div class=\"flex flex-column justify-content-center align-items-center m-8\">\r\n <img src=\"assets/images/hosting-404-error-1.png\" alt=\"not Found\" class=\"w-4 m-4\">\r\n <h1>page not found</h1>\r\n <p-button label=\"Go To Homepage\" size=\"large\" class=\"custom-button\" (onClick)=\"goToHomepage()\"></p-button>\r\n</div>", styles: [".custom-button{--p-button-primary-color: white;--p-button-primary-background: var(--secondary-color);--p-button-primary-border-color: var(--secondary-color);--p-button-primary-hover-background: var(--hover-color);--p-button-primary-hover-border-color: var(--hover-color);--p-button-primary-active-background: color-mix(in srgb, var(--hover-color) 80%, black 20%);--p-button-primary-active-border-color: color-mix(in srgb, var(--hover-color) 90%, black 10%)}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }] });
137
427
  }
138
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.1", ngImport: i0, type: NotFoundPageComponent, decorators: [{
428
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: NotFoundPageComponent, decorators: [{
139
429
  type: Component,
140
430
  args: [{ standalone: true, selector: 'not-found-page', imports: [ButtonModule], template: "<div class=\"flex flex-column justify-content-center align-items-center m-8\">\r\n <img src=\"assets/images/hosting-404-error-1.png\" alt=\"not Found\" class=\"w-4 m-4\">\r\n <h1>page not found</h1>\r\n <p-button label=\"Go To Homepage\" size=\"large\" class=\"custom-button\" (onClick)=\"goToHomepage()\"></p-button>\r\n</div>", styles: [".custom-button{--p-button-primary-color: white;--p-button-primary-background: var(--secondary-color);--p-button-primary-border-color: var(--secondary-color);--p-button-primary-hover-background: var(--hover-color);--p-button-primary-hover-border-color: var(--hover-color);--p-button-primary-active-background: color-mix(in srgb, var(--hover-color) 80%, black 20%);--p-button-primary-active-border-color: color-mix(in srgb, var(--hover-color) 90%, black 10%)}\n"] }]
141
- }], ctorParameters: () => [{ type: i1$2.Router }] });
431
+ }], ctorParameters: () => [{ type: i1$1.Router }] });
432
+
433
+ class UserPageComponent {
434
+ userService;
435
+ messageService;
436
+ userSubscription;
437
+ email = "";
438
+ name = "";
439
+ newName = "";
440
+ constructor(userService, messageService) {
441
+ this.userService = userService;
442
+ this.messageService = messageService;
443
+ }
444
+ ngOnInit() {
445
+ this.userSubscription = this.userService.getNameAndEmail().subscribe(userData => {
446
+ this.email = userData?.email ?? '';
447
+ this.name = userData?.name ?? '';
448
+ this.newName = this.name;
449
+ });
450
+ }
451
+ ngOnDestroy() {
452
+ this.userSubscription?.unsubscribe();
453
+ }
454
+ async updateName() {
455
+ try {
456
+ await this.userService.updateUserName(this.newName);
457
+ this.messageService.add({
458
+ severity: 'info',
459
+ summary: 'Info',
460
+ detail: `Name updated without problems.`,
461
+ life: 3000,
462
+ closable: true
463
+ });
464
+ }
465
+ catch (error) {
466
+ this.messageService.add({
467
+ severity: 'error',
468
+ summary: 'Error',
469
+ detail: 'Something went wrong. Try again later or contact the administrator.',
470
+ life: 3000,
471
+ closable: true
472
+ });
473
+ }
474
+ }
475
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: UserPageComponent, deps: [{ token: UserService }, { token: i2$1.MessageService }], target: i0.ɵɵFactoryTarget.Component });
476
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: UserPageComponent, isStandalone: true, selector: "user-page", providers: [MessageService], ngImport: i0, template: "<p-toast class=\"custom-toast\" position=\"bottom-right\"/>\r\n<div class=\"flex flex-column align-items-center justify-content-center p-4\">\r\n <h2>User Profile</h2>\r\n <div class=\"flex gap-4\">\r\n <p-floatlabel variant=\"on\" class=\"custom-floatlabel\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-envelope\" />\r\n <input pInputText id=\"email\" [disabled]=\"true\" autocomplete=\"off\" class=\"w-full max-w-25rem custom-input\" [(ngModel)]=\"email\"/>\r\n </p-iconfield>\r\n <label for=\"email\">Email</label>\r\n </p-floatlabel>\r\n </div>\r\n <div class=\"flex gap-4 mt-4 mb-4\">\r\n <p-floatlabel variant=\"on\" class=\"custom-floatlabel\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-user\" />\r\n <input pInputText id=\"password\" [disabled]=\"email == ''\" autocomplete=\"off\" class=\"w-full max-w-25rem custom-input\" [(ngModel)]=\"newName\"/>\r\n </p-iconfield>\r\n <label for=\"password\">Name</label>\r\n </p-floatlabel>\r\n </div>\r\n <p-button class=\"custom-button\" label=\"Update Name\" [disabled]=\"(name == newName || email == '')\" (click)=\"updateName()\" />\r\n</div>", styles: [".custom-input{--p-inputtext-focus-border-color: var(--hover-color);--p-inputtext-hover-border-color: var(--hover-color)}.custom-floatlabel{--p-floatlabel-focus-color: var(--hover-color)}.custom-secondary-button{--p-button-secondary-hover-color: var(--primary-color);--p-button-secondary-active-color: var(--primary-color)}.custom-button{--p-button-primary-background: var(--secondary-color);--p-button-primary-border-color: var(--secondary-color);--p-button-primary-hover-background: var(--hover-color);--p-button-primary-hover-border-color: var(--hover-color);--p-button-primary-active-background: color-mix(in srgb, var(--hover-color) 80%, black 20%);--p-button-primary-active-border-color: color-mix(in srgb, var(--hover-color) 90%, black 10%)}a{cursor:pointer}a:hover{color:var(--hover-color)}.custom-toast{--p-toast-info-background: color-mix(in srgb, var(--secondary-color) 10%, rgba(255, 255, 255, .9) 90%);--p-toast-info-border-color: var(--secondary-color);--p-toast-info-color: var(--secondary-color);--p-toast-info-detail-color: var(--primary-color);--p-toast-error-background: color-mix(in srgb, var(--danger-color) 10%, rgba(255, 255, 255, .9) 90%);--p-toast-error-border-color: var(--danger-color);--p-toast-error-color: var(--danger-color);--p-toast-error-detail-color: var(--primary-color)}::ng-deep .p-toast-close-button .p-button-label{font-size:0}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputIconModule }, { kind: "component", type: i4.InputIcon, selector: "p-inputicon, p-inputIcon", inputs: ["styleClass"] }, { kind: "ngmodule", type: IconFieldModule }, { kind: "component", type: i5.IconField, selector: "p-iconfield, p-iconField, p-icon-field", inputs: ["iconPosition", "styleClass"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i6.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: FloatLabelModule }, { kind: "component", type: i7.FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i8.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ToastModule }, { kind: "component", type: i9.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }] });
477
+ }
478
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: UserPageComponent, decorators: [{
479
+ type: Component,
480
+ args: [{ standalone: true, selector: 'user-page', imports: [ButtonModule, InputIconModule, IconFieldModule, InputTextModule, FloatLabelModule, FormsModule, CommonModule, ToastModule], providers: [MessageService], template: "<p-toast class=\"custom-toast\" position=\"bottom-right\"/>\r\n<div class=\"flex flex-column align-items-center justify-content-center p-4\">\r\n <h2>User Profile</h2>\r\n <div class=\"flex gap-4\">\r\n <p-floatlabel variant=\"on\" class=\"custom-floatlabel\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-envelope\" />\r\n <input pInputText id=\"email\" [disabled]=\"true\" autocomplete=\"off\" class=\"w-full max-w-25rem custom-input\" [(ngModel)]=\"email\"/>\r\n </p-iconfield>\r\n <label for=\"email\">Email</label>\r\n </p-floatlabel>\r\n </div>\r\n <div class=\"flex gap-4 mt-4 mb-4\">\r\n <p-floatlabel variant=\"on\" class=\"custom-floatlabel\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-user\" />\r\n <input pInputText id=\"password\" [disabled]=\"email == ''\" autocomplete=\"off\" class=\"w-full max-w-25rem custom-input\" [(ngModel)]=\"newName\"/>\r\n </p-iconfield>\r\n <label for=\"password\">Name</label>\r\n </p-floatlabel>\r\n </div>\r\n <p-button class=\"custom-button\" label=\"Update Name\" [disabled]=\"(name == newName || email == '')\" (click)=\"updateName()\" />\r\n</div>", styles: [".custom-input{--p-inputtext-focus-border-color: var(--hover-color);--p-inputtext-hover-border-color: var(--hover-color)}.custom-floatlabel{--p-floatlabel-focus-color: var(--hover-color)}.custom-secondary-button{--p-button-secondary-hover-color: var(--primary-color);--p-button-secondary-active-color: var(--primary-color)}.custom-button{--p-button-primary-background: var(--secondary-color);--p-button-primary-border-color: var(--secondary-color);--p-button-primary-hover-background: var(--hover-color);--p-button-primary-hover-border-color: var(--hover-color);--p-button-primary-active-background: color-mix(in srgb, var(--hover-color) 80%, black 20%);--p-button-primary-active-border-color: color-mix(in srgb, var(--hover-color) 90%, black 10%)}a{cursor:pointer}a:hover{color:var(--hover-color)}.custom-toast{--p-toast-info-background: color-mix(in srgb, var(--secondary-color) 10%, rgba(255, 255, 255, .9) 90%);--p-toast-info-border-color: var(--secondary-color);--p-toast-info-color: var(--secondary-color);--p-toast-info-detail-color: var(--primary-color);--p-toast-error-background: color-mix(in srgb, var(--danger-color) 10%, rgba(255, 255, 255, .9) 90%);--p-toast-error-border-color: var(--danger-color);--p-toast-error-color: var(--danger-color);--p-toast-error-detail-color: var(--primary-color)}::ng-deep .p-toast-close-button .p-button-label{font-size:0}\n"] }]
481
+ }], ctorParameters: () => [{ type: UserService }, { type: i2$1.MessageService }] });
142
482
 
143
483
  /*
144
484
  * Public API Surface of ngx-bok-utils
@@ -148,5 +488,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.1", ngImpor
148
488
  * Generated bundle index. Do not edit.
149
489
  */
150
490
 
151
- export { FooterComponent, HeaderComponent, NotFoundPageComponent };
491
+ export { FooterComponent, HeaderComponent, NotFoundPageComponent, UserPageComponent };
152
492
  //# sourceMappingURL=eo4geo-ngx-bok-utils.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"eo4geo-ngx-bok-utils.mjs","sources":["../../../../projects/eo4geo/ngx-bok-utils/src/lib/components/footer/footer.component.ts","../../../../projects/eo4geo/ngx-bok-utils/src/lib/components/footer/footer.component.html","../../../../projects/eo4geo/ngx-bok-utils/src/lib/components/header/header.component.ts","../../../../projects/eo4geo/ngx-bok-utils/src/lib/components/header/header.component.html","../../../../projects/eo4geo/ngx-bok-utils/src/lib/components/404/notFoundPage.component.ts","../../../../projects/eo4geo/ngx-bok-utils/src/lib/components/404/notFoundPage.component.html","../../../../projects/eo4geo/ngx-bok-utils/src/public-api.ts","../../../../projects/eo4geo/ngx-bok-utils/src/eo4geo-ngx-bok-utils.ts"],"sourcesContent":["import {Component, EventEmitter, Output} from '@angular/core';\nimport { ToolbarModule } from 'primeng/toolbar';\n\n@Component({\n standalone: true,\n selector: 'footer',\n templateUrl: './footer.component.html',\n styleUrls: ['./footer.component.css'],\n imports: [ToolbarModule],\n})\nexport class FooterComponent {\n @Output() openReleaseNotes = new EventEmitter<void>();\n @Output() openUserManual = new EventEmitter<void>();\n\n\n clickReleaseNotes(): void {\n this.openReleaseNotes.emit();\n }\n\n clickUserManual(): void {\n this.openUserManual.emit();\n }\n}\n","<div class=\"footer\">\r\n <p-toolbar [style]=\"{'color': 'white', 'background': 'none', 'border': '0px', 'gap': '3rem'}\">\r\n <ng-template #start>\r\n <div class=\"flex flex-column align-items-center gap-1\">\r\n <div class=\"inline\">\r\n <a href=\"http://www.eo4geo.eu/\" target=\"_blank\"><img class=\"logo\" src=\"assets/images/EO4GEO_LOGO_WHITE.png\" alt=\"LogoEO4GEO\"></a>\r\n <a href=\"https://www.spacesuite-project.eu/\" target=\"_blank\"><img class=\"logo\" src=\"assets/images/SpaceSUITE_horizontal_white.png\" alt=\"LogoSpaceSUITE\"></a>\r\n </div>\r\n <span style=\"font-size: x-small;\">All tools were developed by <a href=\"https://geotec.uji.es/\" target=\"_blank\">GEOTEC</a></span>\r\n </div>\r\n </ng-template>\r\n <ng-template #center>\r\n <div style=\"font-size: smaller;\" class=\"flex flex-wrap gap-1\">\r\n <span>© 2025 spaceSUITE</span>\r\n <span class=\"link-separator\">\r\n | <a (click)=\"clickUserManual()\">User Manual</a>\r\n </span>\r\n <span class=\"link-separator\">\r\n | <a (click)=\"clickReleaseNotes()\">Release Notes</a>\r\n </span>\r\n <span class=\"link-separator\">\r\n | <a href=\"mailto:eo4geo@gmail.com?subject=EO4GEO%20Tools%20Contact\">Contact</a>\r\n </span>\r\n <span class=\"link-separator\">\r\n | <a href=\"https://www.spacesuite-project.eu/privacy-policy/\" target=\"_blank\">Privacy Policy</a>\r\n </span>\r\n </div>\r\n </ng-template>\r\n <ng-template #end>\r\n <div class=\"flex flex-column align-items-center gap-1 max-w-20rem\">\r\n <img class=\"logo\" src=\"assets/images/EU_Funding.png\" alt=\"LogoEU\">\r\n <span class=\"white-space-normal\" style=\"font-size: xx-small;\">Views and opinions expressed are however those of the author(s) only and do not necessarily reflect those of the European Union or the European Education and Culture Executive Agency (EACEA). Neither the European Union nor EACEA can be held responsible for them.</span>\r\n </div>\r\n </ng-template>\r\n </p-toolbar>\r\n</div>","import { CommonModule } from '@angular/common';\nimport {Component, HostListener, Input} from '@angular/core';\nimport { MenuItem } from 'primeng/api';\nimport { ButtonModule } from 'primeng/button';\nimport { TieredMenuModule } from 'primeng/tieredmenu';\n\n@Component({\n standalone: true,\n selector: 'header',\n templateUrl: './header.component.html',\n styleUrls: ['./header.component.css'],\n imports: [ButtonModule, TieredMenuModule, CommonModule],\n})\nexport class HeaderComponent {\n @Input() items: MenuItem[] = [ \n {\n label: 'Tools',\n icon: 'pi pi-cog',\n items: [\n {\n label: 'BoK Visualization & Search',\n icon: 'pi pi-search',\n style: {'--p-tieredmenu-item-color': 'var(--hover-color)'},\n iconStyle: {'color': 'var(--hover-color)'}\n },\n {\n label: 'Occupational Profile Tool',\n icon: 'pi pi-users',\n url: 'https://eo4geo-opt.web.app',\n },\n {\n label: 'Job Offer Tool',\n icon: 'pi pi-book',\n url: 'https://eo4geo-jot.web.app',\n },\n {\n label: 'Curriculum Design Tool',\n icon: 'pi pi-sitemap',\n url: 'https://eo4geo-cdt.web.app',\n },\n {\n label: 'BoK Annotation Tool',\n icon: 'pi pi-pencil',\n url: 'https://eo4geo-bat.web.app',\n },\n {\n label: 'BoK Matching Tool',\n icon: 'pi pi-equals',\n url: 'https://eo4geo-bmt.web.app',\n },\n {\n label: 'Training Catalog Tool',\n icon: 'pi pi-graduation-cap',\n disabled: true,\n },\n ]\n }, \n {\n label: 'Share',\n icon: 'pi pi-share-alt',\n items: [\n {\n label: 'X',\n icon: 'pi pi-twitter',\n url: 'https://twitter.com/SpaceSUITE_eu',\n },\n {\n label: 'Facebook',\n icon: 'pi pi-facebook',\n url: 'https://www.facebook.com/spacesuiteproject/',\n },\n {\n label: 'Youtube',\n icon: 'pi pi-youtube',\n url: 'https://www.youtube.com/@SpaceSUITE_eu',\n },\n {\n label: 'LinkedIn',\n icon: 'pi pi-linkedin',\n url: 'https://www.linkedin.com/showcase/spacesuite_eu/',\n }\n ]\n }\n ];\n\n @Input() toolName: string = \"BoK Visualization & Search\";\n\n hideMenu: boolean = true;\n\n @HostListener('document:click', ['$event'])\n clickout(event: { target: any }) {\n if (!event.target.closest(\"p-tieredmenu\") && !event.target.closest(\"p-button.custom-header-button\")) {\n this.hideMenu = true;\n }\n}\n}\n","<div class=\"header\">\r\n <div class=\"flex justify-content-between align-content-center p-4 mx-4\">\r\n <a href=\"https://www.spacesuite-project.eu/\" target=\"_blank\" class=\"align-self-center\"><img class=\"logo flex align-items-center justify-content-center\" src=\"assets/images/SpaceSUITE_horizontal_color.png\" alt=\"LogoSpaceSUITE\"></a>\r\n <h1 class=\"hidden xl:flex m-0 align-self-center\">{{toolName}}</h1>\r\n <div class=\"flex gap-8\">\r\n <div class=\"justify-content-center hidden md:flex\" *ngFor=\"let item of items;\">\r\n <div class=\"flex align-items-center justify-content-center gap-2 text-xl font-bold header-option\" (click)=\"subMenu.toggle($event)\" *ngIf=\"item.label != 'Share'; else share\">\r\n <i [class]=\"item.icon\"></i>\r\n <div>{{item.label}}</div>\r\n <i *ngIf=\"item.items\" class=\"pi pi-angle-down\"></i>\r\n </div>\r\n <p-tieredmenu #subMenu [model]=\"item.items\" [breakpoint]=\"'767px'\" class=\"custom-p-tieredmenu\" [popup]=\"true\" />\r\n <ng-template #share>\r\n <div class=\"flex align-items-center justify-content-center gap-3\">\r\n <div *ngFor=\"let social of item.items;\">\r\n <a [href]=\"social.url\" target=\"_blank\">\r\n <i [class]=\"social.icon\" style=\"font-size: 1.25rem\"></i>\r\n </a>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n </div>\r\n \r\n <p-button #menuButton (click)=\"hideMenu = !hideMenu\" class=\"md:hidden flex align-items-center justify-content-center custom-header-button\" icon=\"pi pi-bars\" aria-label=\"Menu\"></p-button>\r\n </div>\r\n <p-tieredmenu #menu [hidden]=\"hideMenu\" [model]=\"items\" class=\"md:hidden custom-p-tieredmenu\"/>\r\n</div>\r\n","import { Component } from \"@angular/core\";\r\nimport { Router } from \"@angular/router\";\r\nimport { ButtonModule } from 'primeng/button';\r\n\r\n@Component({\r\n standalone: true,\r\n selector: 'not-found-page',\r\n templateUrl: './notFoundPage.component.html',\r\n styleUrls: ['./notFoundPage.component.css'],\r\n imports: [ButtonModule],\r\n})\r\nexport class NotFoundPageComponent {\r\n constructor(private router: Router) {}\r\n\r\n goToHomepage() {\r\n this.router.navigate([''], { replaceUrl: true });\r\n }\r\n}","<div class=\"flex flex-column justify-content-center align-items-center m-8\">\r\n <img src=\"assets/images/hosting-404-error-1.png\" alt=\"not Found\" class=\"w-4 m-4\">\r\n <h1>page not found</h1>\r\n <p-button label=\"Go To Homepage\" size=\"large\" class=\"custom-button\" (onClick)=\"goToHomepage()\"></p-button>\r\n</div>","/*\r\n * Public API Surface of ngx-bok-utils\r\n */\r\n\r\nexport * from './lib/components/footer/footer.component';\r\nexport * from './lib/components/header/header.component';\r\nexport * from './lib/components/404/notFoundPage.component';","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1","i2"],"mappings":"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"}
1
+ {"version":3,"file":"eo4geo-ngx-bok-utils.mjs","sources":["../../../../projects/eo4geo/ngx-bok-utils/src/lib/components/footer/footer.component.ts","../../../../projects/eo4geo/ngx-bok-utils/src/lib/components/footer/footer.component.html","../../../../projects/eo4geo/ngx-bok-utils/src/lib/services/user.service.ts","../../../../projects/eo4geo/ngx-bok-utils/src/lib/components/signInModal/sessionModal.component.ts","../../../../projects/eo4geo/ngx-bok-utils/src/lib/components/signInModal/sessionModal.component.html","../../../../projects/eo4geo/ngx-bok-utils/src/lib/components/header/header.component.ts","../../../../projects/eo4geo/ngx-bok-utils/src/lib/components/header/header.component.html","../../../../projects/eo4geo/ngx-bok-utils/src/lib/components/404/notFoundPage.component.ts","../../../../projects/eo4geo/ngx-bok-utils/src/lib/components/404/notFoundPage.component.html","../../../../projects/eo4geo/ngx-bok-utils/src/lib/components/userPage/userPage.component.ts","../../../../projects/eo4geo/ngx-bok-utils/src/lib/components/userPage/userPage.component.html","../../../../projects/eo4geo/ngx-bok-utils/src/public-api.ts","../../../../projects/eo4geo/ngx-bok-utils/src/eo4geo-ngx-bok-utils.ts"],"sourcesContent":["import {Component, EventEmitter, Output} from '@angular/core';\nimport { ToolbarModule } from 'primeng/toolbar';\n\n@Component({\n standalone: true,\n selector: 'footer',\n templateUrl: './footer.component.html',\n styleUrls: ['./footer.component.css'],\n imports: [ToolbarModule],\n})\nexport class FooterComponent {\n @Output() openReleaseNotes = new EventEmitter<void>();\n @Output() openUserManual = new EventEmitter<void>();\n\n\n clickReleaseNotes(): void {\n this.openReleaseNotes.emit();\n }\n\n clickUserManual(): void {\n this.openUserManual.emit();\n }\n}\n","<div class=\"footer\">\r\n <p-toolbar [style]=\"{'color': 'white', 'background': 'none', 'border': '0px', 'gap': '3rem'}\">\r\n <ng-template #start>\r\n <div class=\"flex flex-column align-items-center gap-1\">\r\n <div class=\"inline\">\r\n <a href=\"http://www.eo4geo.eu/\" target=\"_blank\"><img class=\"logo\" src=\"assets/images/EO4GEO_LOGO_WHITE.png\" alt=\"LogoEO4GEO\"></a>\r\n <a href=\"https://www.spacesuite-project.eu/\" target=\"_blank\"><img class=\"logo\" src=\"assets/images/SpaceSUITE_horizontal_white.png\" alt=\"LogoSpaceSUITE\"></a>\r\n </div>\r\n <span style=\"font-size: x-small;\">All tools were developed by <a href=\"https://geotec.uji.es/\" target=\"_blank\">GEOTEC</a></span>\r\n </div>\r\n </ng-template>\r\n <ng-template #center>\r\n <div style=\"font-size: smaller;\" class=\"flex flex-wrap gap-1\">\r\n <span>© 2025 spaceSUITE</span>\r\n <span class=\"link-separator\">\r\n | <a (click)=\"clickUserManual()\">User Manual</a>\r\n </span>\r\n <span class=\"link-separator\">\r\n | <a (click)=\"clickReleaseNotes()\">Release Notes</a>\r\n </span>\r\n <span class=\"link-separator\">\r\n | <a href=\"mailto:eo4geo@gmail.com?subject=EO4GEO%20Tools%20Contact\">Contact</a>\r\n </span>\r\n <span class=\"link-separator\">\r\n | <a href=\"https://www.spacesuite-project.eu/privacy-policy/\" target=\"_blank\">Privacy Policy</a>\r\n </span>\r\n </div>\r\n </ng-template>\r\n <ng-template #end>\r\n <div class=\"flex flex-column align-items-center gap-1 max-w-20rem\">\r\n <img class=\"logo\" src=\"assets/images/EU_Funding.png\" alt=\"LogoEU\">\r\n <span class=\"white-space-normal\" style=\"font-size: xx-small;\">Views and opinions expressed are however those of the author(s) only and do not necessarily reflect those of the European Union or the European Education and Culture Executive Agency (EACEA). Neither the European Union nor EACEA can be held responsible for them.</span>\r\n </div>\r\n </ng-template>\r\n </p-toolbar>\r\n</div>","import { inject, Injectable } from '@angular/core';\r\nimport { Auth, authState, createUserWithEmailAndPassword, GoogleAuthProvider, sendPasswordResetEmail, signInWithEmailAndPassword, signInWithPopup, signOut, updateProfile } from '@angular/fire/auth';\r\nimport { Firestore, collection, CollectionReference, doc, getDoc, setDoc, updateDoc, docData, DocumentReference } from '@angular/fire/firestore';\r\nimport { BehaviorSubject, Observable, of, switchMap } from 'rxjs';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class UserService {\r\n private auth = inject(Auth);\r\n private db = inject(Firestore);\r\n\r\n private userCollection: CollectionReference;\r\n private errorMessages = new Map<string, string>([\r\n [\"auth/user-not-found\", \"Invalid email.\"],\r\n [\"auth/wrong-password\", \"Incorrect password.\"],\r\n [\"auth/missing-password\", \"Incorrect password.\"],\r\n [\"auth/invalid-email\", \"Invalid email.\"],\r\n [\"auth/email-already-in-use\", \"This email is already in use.\"],\r\n [\"auth/weak-password\", \"Weak password. Use at least 6 characters.\"],\r\n [\"auth/passwords-do-not-match\", \"Passwords do not match.\"],\r\n [\"auth/cancelled-popup-request\", \"The popup request was canceled.\"],\r\n [\"auth/network-request-failed\", \"Network error.\"],\r\n ]);\r\n\r\n private userStateSubject = new BehaviorSubject<{ logged: boolean; nameInitial: string }>({\r\n logged: false,\r\n nameInitial: 'A'\r\n });\r\n \r\n constructor() {\r\n this.userCollection = collection(this.db, 'Users');\r\n\r\n authState(this.auth).subscribe(user => {\r\n const logged = !!user;\r\n const nameInitial = user?.displayName ? user.displayName[0].toUpperCase() : 'A';\r\n this.userStateSubject.next({ logged, nameInitial });\r\n });\r\n }\r\n\r\n async loginWithEmailAndPassword(email: string, password: string): Promise<void> {\r\n try {\r\n if (!this.isValidEmail(email)) throw { code: \"auth/invalid-email\" };\r\n await signInWithEmailAndPassword(this.auth, email, password);\r\n } catch (error: any) {\r\n throw this.handleAuthError(error);\r\n }\r\n }\r\n\r\n async registerWithEmailAndPassword(email: string, password: string, repeatPassword: string): Promise<void> {\r\n try {\r\n if (!this.isValidEmail(email)) throw { code: \"auth/invalid-email\" };\r\n if (password.length < 6) throw { code: \"auth/weak-password\" };\r\n if (password !== repeatPassword) throw { code: \"auth/passwords-do-not-match\" };\r\n await createUserWithEmailAndPassword(this.auth, email, password);\r\n await this.checkUser();\r\n } catch (error: any) {\r\n throw this.handleAuthError(error);\r\n }\r\n }\r\n\r\n async loginWithGoogle(): Promise<void> {\r\n try {\r\n await signInWithPopup(this.auth, new GoogleAuthProvider());\r\n await this.checkUser();\r\n } catch (error: any) {\r\n throw this.handleAuthError(error);\r\n }\r\n }\r\n\r\n async recoverPassword(email: string): Promise<void> {\r\n try {\r\n if (!this.isValidEmail(email)) throw { code: \"auth/invalid-email\" };\r\n await sendPasswordResetEmail(this.auth, email);\r\n } catch (error: any) {\r\n throw this.handleAuthError(error);\r\n }\r\n }\r\n\r\n private async checkUser(): Promise<void> {\r\n if (!this.auth.currentUser) return;\r\n\r\n const userDocRef = doc(this.userCollection, this.auth.currentUser.uid);\r\n const userDocSnap = await getDoc(userDocRef);\r\n\r\n if (!userDocSnap.exists()) {\r\n await setDoc(userDocRef, {\r\n _id: this.auth.currentUser.uid,\r\n email: this.auth.currentUser.email,\r\n name: this.auth.currentUser.displayName || \"\",\r\n });\r\n }\r\n }\r\n\r\n private handleAuthError(error: any): string {\r\n if (error.code === \"auth/popup-closed-by-user\") return '';\r\n return this.errorMessages.get(error.code) || \"An error occurred. Please try again.\";\r\n }\r\n\r\n private isValidEmail(email: string): boolean {\r\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\r\n return emailRegex.test(email);\r\n }\r\n\r\n getUserState(): Observable<{ logged: boolean; nameInitial: string }> {\r\n return this.userStateSubject.asObservable();\r\n }\r\n\r\n async logout(): Promise<void> {\r\n await signOut(this.auth);\r\n }\r\n\r\n async updateUserName(newName: string): Promise<void> {\r\n const user = this.auth.currentUser;\r\n if (user) {\r\n try {\r\n const userDocRef = doc(this.userCollection, user.uid);\r\n await updateDoc(userDocRef, { name: newName });\r\n await updateProfile(user, { displayName: newName });\r\n this.userStateSubject.next({ logged: true, nameInitial: newName[0].toUpperCase() });\r\n } catch (error) {\r\n console.error('Error updating name:', error);\r\n throw error;\r\n }\r\n }\r\n }\r\n\r\n getNameAndEmail(): Observable<{ email: string; name: string } | null> {\r\n return authState(this.auth).pipe(\r\n switchMap(user => {\r\n if (user) {\r\n const userDocRef: DocumentReference = doc(this.userCollection, user.uid);\r\n return docData(userDocRef) as Observable<{ email: string; name: string }>;\r\n }\r\n return of(null);\r\n })\r\n );\r\n }\r\n}\r\n","import { Component, EventEmitter, Input, Output, SimpleChanges } from \"@angular/core\";\r\nimport { ButtonModule } from \"primeng/button\";\r\nimport { InputTextModule } from \"primeng/inputtext\";\r\nimport { DialogModule } from 'primeng/dialog';\r\nimport { FloatLabelModule } from \"primeng/floatlabel\";\r\nimport { FormsModule } from \"@angular/forms\";\r\nimport { InputIconModule } from 'primeng/inputicon';\r\nimport { IconFieldModule } from 'primeng/iconfield';\r\nimport { Message } from 'primeng/message';\r\nimport { CommonModule } from \"@angular/common\";\r\nimport { UserService } from \"../../services/user.service\";\r\n\r\n@Component({\r\n standalone: true,\r\n selector: 'sessionModal',\r\n templateUrl: './sessionModal.component.html',\r\n styleUrls: ['./sessionModal.component.css'],\r\n imports: [ButtonModule, DialogModule, InputIconModule, IconFieldModule, InputTextModule, FloatLabelModule, FormsModule, CommonModule, Message],\r\n})\r\nexport class SessionModalComponent {\r\n\r\n @Input() visible: boolean = false;\r\n @Output() visibleChange = new EventEmitter<boolean>();\r\n\r\n login: boolean = true;\r\n resetpassword: boolean = false;\r\n\r\n email: string = '';\r\n password: string = '';\r\n repeatPassword: string = '';\r\n\r\n error: string | null = null;\r\n\r\n constructor(private userService: UserService) {}\r\n\r\n ngOnChanges(changes: SimpleChanges) {\r\n this.login = changes['visible'].currentValue;\r\n this.resetpassword = !changes['visible'].currentValue;\r\n this.email = '';\r\n this.password = '';\r\n this.repeatPassword = '';\r\n this.error = null;\r\n }\r\n\r\n getHeader(): string {\r\n if (this.resetpassword) return 'Recover Password';\r\n if (this.login) return 'Login';\r\n return 'Register';\r\n }\r\n\r\n getSwitchLabel() {\r\n if (this.resetpassword) return 'Return';\r\n if (!this.login) return 'Login';\r\n return 'Register';\r\n }\r\n\r\n clickSwitchButton() {\r\n this.error = null;\r\n if (this.resetpassword) this.resetpassword = !this.resetpassword;\r\n else this.login = !this.login;\r\n }\r\n\r\n clickMainButton() {\r\n if (this.resetpassword) return this.recoverPassword();\r\n if (this.login) return this.loginWithEmailAndPassword();\r\n return this.registerWithEmailAndPassword();\r\n }\r\n\r\n async loginWithGoogle() {\r\n try {\r\n await this.userService.loginWithGoogle();\r\n this.visibleChange.emit(false);\r\n } catch (error: any) {\r\n this.error = error;\r\n }\r\n }\r\n\r\n async loginWithEmailAndPassword() {\r\n try {\r\n await this.userService.loginWithEmailAndPassword(this.email, this.password);\r\n this.visibleChange.emit(false);\r\n } catch (error: any) {\r\n this.error = error;\r\n }\r\n }\r\n\r\n async registerWithEmailAndPassword() {\r\n try {\r\n await this.userService.registerWithEmailAndPassword(this.email, this.password, this.repeatPassword);\r\n this.visibleChange.emit(false);\r\n } catch (error: any) {\r\n this.error = error;\r\n }\r\n }\r\n\r\n async recoverPassword() {\r\n try {\r\n await this.userService.recoverPassword(this.email);\r\n this.password = '';\r\n this.repeatPassword = '';\r\n this.resetpassword = !this.resetpassword;\r\n } catch (error: any) {\r\n this.error = error;\r\n }\r\n }\r\n}","<p-dialog [header]=\"getHeader()\" [modal]=\"true\" [visible]=\"visible\" resizable=\"false\" (visibleChange)=\"visibleChange.emit($event)\" [style]=\"{color: 'var(--primary-color)'}\">\r\n <p-message *ngIf=\"error\" severity=\"error\" variant=\"simple\" styleClass=\"mb-4 white-space-normal\" class=\"error-info\">{{error}}</p-message>\r\n <div class=\"flex items-center gap-4 mt-2 mb-1\">\r\n <p-floatlabel variant=\"on\" [class]=\"error ? 'custom-floatlabel error-floatlabel' : 'custom-floatlabel'\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-user\" />\r\n <input pInputText id=\"email\" autocomplete=\"off\" [class]=\"error ? 'custom-input error-input' : 'custom-input'\" [(ngModel)]=\"email\"/>\r\n </p-iconfield>\r\n <label for=\"email\">Email</label>\r\n </p-floatlabel>\r\n </div>\r\n <div *ngIf=\"!resetpassword\" class=\"flex items-center gap-4 mt-4 mb-1\">\r\n <p-floatlabel variant=\"on\" [class]=\"error ? 'custom-floatlabel error-floatlabel' : 'custom-floatlabel'\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-lock\" />\r\n <input pInputText id=\"password\" autocomplete=\"off\" [class]=\"error ? 'custom-input error-input' : 'custom-input'\" [(ngModel)]=\"password\"/>\r\n </p-iconfield>\r\n <label for=\"password\">Password</label>\r\n </p-floatlabel>\r\n </div>\r\n <div *ngIf=\"!login\" class=\"flex items-center gap-4 mt-4 mb-1\">\r\n <p-floatlabel variant=\"on\" [class]=\"error ? 'custom-floatlabel error-floatlabel' : 'custom-floatlabel'\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-lock\" />\r\n <input pInputText id=\"rPassword\" autocomplete=\"off\" [class]=\"error ? 'custom-input error-input' : 'custom-input'\" [(ngModel)]=\"repeatPassword\"/>\r\n </p-iconfield>\r\n <label for=\"rPassword\">Repeat Password</label>\r\n </p-floatlabel>\r\n </div>\r\n <a *ngIf=\"login && !resetpassword\" class=\"inline-flex ml-2 text-sm\" (click)=\"resetpassword = !resetpassword; error = null;\">Forgot Password?</a>\r\n <div class=\"flex align-items-center justify-content-between gap-2 mt-4\">\r\n <div class=\"flex justify-end gap-2\">\r\n <p-button class=\"custom-button\" [label]=\"getHeader()\" (click)=\"clickMainButton()\" />\r\n <p-button severity=\"secondary\" class=\"custom-secondary-button\" [label]=\"getSwitchLabel()\" (click)=\"clickSwitchButton()\" />\r\n </div>\r\n <p-button *ngIf=\"!resetpassword\" class=\"custom-button\" icon=\"pi pi-google\" label=\"Google\" (click)=\"loginWithGoogle()\" />\r\n </div>\r\n</p-dialog>","import { CommonModule } from '@angular/common';\nimport {Component, HostListener, inject, Input} from '@angular/core';\nimport { MenuItem } from 'primeng/api';\nimport { ButtonModule } from 'primeng/button';\nimport { TieredMenuModule } from 'primeng/tieredmenu';\nimport { AvatarModule } from 'primeng/avatar';\nimport { AvatarGroupModule } from 'primeng/avatargroup';\nimport { Subscription } from 'rxjs';\nimport { SessionModalComponent } from \"../signInModal/sessionModal.component\";\nimport { UserService } from '../../services/user.service';\n\n@Component({\n standalone: true,\n selector: 'header',\n templateUrl: './header.component.html',\n styleUrls: ['./header.component.css'],\n imports: [ButtonModule, TieredMenuModule, CommonModule, AvatarModule, AvatarGroupModule, SessionModalComponent],\n})\nexport class HeaderComponent {\n @Input() items: MenuItem[] = [ \n {\n label: 'Tools',\n icon: 'pi pi-cog',\n items: [\n {\n label: 'BoK Visualization & Search',\n icon: 'pi pi-search',\n style: {'--p-tieredmenu-item-color': 'var(--hover-color)'},\n iconStyle: {'color': 'var(--hover-color)'}\n },\n {\n label: 'Occupational Profile Tool',\n icon: 'pi pi-users',\n url: 'https://eo4geo-opt.web.app',\n },\n {\n label: 'Job Offer Tool',\n icon: 'pi pi-book',\n url: 'https://eo4geo-jot.web.app',\n },\n {\n label: 'Curriculum Design Tool',\n icon: 'pi pi-graduation-cap',\n url: 'https://eo4geo-cdt.web.app',\n },\n {\n label: 'BoK Annotation Tool',\n icon: 'pi pi-pencil',\n url: 'https://eo4geo-bat.web.app',\n },\n {\n label: 'BoK Matching Tool',\n icon: 'pi pi-equals',\n url: 'https://eo4geo-bmt.web.app',\n }\n ]\n }, \n {\n label: 'Share',\n icon: 'pi pi-share-alt',\n items: [\n {\n label: 'X',\n icon: 'pi pi-twitter',\n url: 'https://twitter.com/SpaceSUITE_eu',\n },\n {\n label: 'Facebook',\n icon: 'pi pi-facebook',\n url: 'https://www.facebook.com/spacesuiteproject/',\n },\n {\n label: 'Youtube',\n icon: 'pi pi-youtube',\n url: 'https://www.youtube.com/@SpaceSUITE_eu',\n },\n {\n label: 'LinkedIn',\n icon: 'pi pi-linkedin',\n url: 'https://www.linkedin.com/showcase/spacesuite_eu/',\n }\n ]\n }\n ];\n\n userItems: MenuItem[] = [\n {\n label: 'Profile', \n icon: 'pi pi-user'\n },\n {\n label: 'Organization', \n icon: 'pi pi-users'\n }, \n {\n label: 'Logout', \n icon: 'pi pi-sign-out', \n command: () => {\n this.logout();\n }\n }\n ];\n\n @Input() toolName: string = \"BoK Visualization & Search\";\n @Input() login: boolean = false;\n \n hideMenu: boolean = true;\n logged: boolean = false;\n nameInitial: string = 'A';\n\n showLoginModal: boolean = false;\n\n private userStateSubscription!: Subscription;\n\n constructor(private userService: UserService) {}\n\n ngOnInit() {\n this.userStateSubscription = this.userService.getUserState().subscribe(({ logged, nameInitial }) => {\n this.logged = logged;\n this.nameInitial = nameInitial;\n });\n }\n\n ngOnDestroy() {\n this.userStateSubscription?.unsubscribe();\n }\n\n async logout() {\n await this.userService.logout();\n }\n\n @HostListener('document:click', ['$event'])\n clickout(event: { target: any }) {\n if (!event.target.closest(\"p-tieredmenu\") && !event.target.closest(\"p-button.custom-header-button\")) {\n this.hideMenu = true;\n }\n }\n}\n","<div class=\"header\">\r\n <div class=\"flex align-content-center p-4 mx-4\">\r\n <a href=\"https://www.spacesuite-project.eu/\" target=\"_blank\" class=\"align-self-center\"><img class=\"logo flex align-items-center justify-content-center\" src=\"assets/images/SpaceSUITE_horizontal_color.png\" alt=\"LogoSpaceSUITE\"></a>\r\n <div class=\"hidden xl:flex align-self-center fixed-text\">\r\n <strong class=\"text-2xl overflow-hidden white-space-nowrap text-overflow-ellipsis\">\r\n {{toolName}}\r\n </strong>\r\n </div>\r\n <div class=\"flex gap-6 ml-auto\">\r\n <div class=\"justify-content-center hidden md:flex\" *ngFor=\"let item of items;\">\r\n <div class=\"flex align-items-center justify-content-center gap-2 text-xl font-bold header-option\" (click)=\"subMenu.toggle($event)\" *ngIf=\"item.label != 'Share'; else share\">\r\n <i [class]=\"item.icon\"></i>\r\n <div>{{item.label}}</div>\r\n <i *ngIf=\"item.items\" class=\"pi pi-angle-down\"></i>\r\n </div>\r\n <p-tieredmenu #subMenu [model]=\"item.items\" [breakpoint]=\"'767px'\" class=\"custom-p-tieredmenu\" [popup]=\"true\" />\r\n <ng-template #share>\r\n <div class=\"flex align-items-center justify-content-center gap-3\">\r\n <div *ngFor=\"let social of item.items;\">\r\n <a [href]=\"social.url\" target=\"_blank\" class=\"flex\">\r\n <i [class]=\"social.icon\" style=\"font-size: 1.25rem\"></i>\r\n </a>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </div>\r\n <div *ngIf=\"login\" class=\"hidden md:flex align-items-center justify-content-center\">\r\n <p-avatar *ngIf=\"logged; else login\" [label]=\"nameInitial\" class=\"custom-p-avatar\" shape=\"circle\" (click)=\"userMenu.toggle($event)\"></p-avatar>\r\n </div>\r\n <p-tieredmenu #userMenu [model]=\"userItems\" [breakpoint]=\"'767px'\" class=\"custom-p-tieredmenu\" [popup]=\"true\" />\r\n <ng-template #login>\r\n <p-button class=\"custom-header-button\" size=\"small\" label=\"Login\" aria-label=\"Login\" (onClick)=\"showLoginModal = !showLoginModal\"></p-button>\r\n </ng-template>\r\n </div>\r\n \r\n <p-button #menuButton (click)=\"hideMenu = !hideMenu\" class=\"md:hidden flex align-items-center custom-header-button ml-auto\" icon=\"pi pi-bars\" aria-label=\"Menu\"></p-button>\r\n </div>\r\n <p-tieredmenu #menu [hidden]=\"hideMenu\" [model]=\"items\" class=\"md:hidden custom-p-tieredmenu\"/>\r\n</div>\r\n\r\n<sessionModal [(visible)]=\"showLoginModal\"></sessionModal>\r\n","import { Component } from \"@angular/core\";\r\nimport { Router } from \"@angular/router\";\r\nimport { ButtonModule } from 'primeng/button';\r\n\r\n@Component({\r\n standalone: true,\r\n selector: 'not-found-page',\r\n templateUrl: './notFoundPage.component.html',\r\n styleUrls: ['./notFoundPage.component.css'],\r\n imports: [ButtonModule],\r\n})\r\nexport class NotFoundPageComponent {\r\n constructor(private router: Router) {}\r\n\r\n goToHomepage() {\r\n this.router.navigate([''], { replaceUrl: true });\r\n }\r\n}","<div class=\"flex flex-column justify-content-center align-items-center m-8\">\r\n <img src=\"assets/images/hosting-404-error-1.png\" alt=\"not Found\" class=\"w-4 m-4\">\r\n <h1>page not found</h1>\r\n <p-button label=\"Go To Homepage\" size=\"large\" class=\"custom-button\" (onClick)=\"goToHomepage()\"></p-button>\r\n</div>","import { Component} from \"@angular/core\";\r\nimport { ButtonModule } from \"primeng/button\";\r\nimport { InputTextModule } from \"primeng/inputtext\";\r\nimport { FloatLabelModule } from \"primeng/floatlabel\";\r\nimport { FormsModule } from \"@angular/forms\";\r\nimport { InputIconModule } from 'primeng/inputicon';\r\nimport { IconFieldModule } from 'primeng/iconfield';\r\nimport { CommonModule } from \"@angular/common\";\r\nimport { Subscription } from \"rxjs\";\r\nimport { UserService } from \"../../services/user.service\";\r\nimport { ToastModule } from 'primeng/toast';\r\nimport { MessageService } from \"primeng/api\";\r\n\r\n\r\n@Component({\r\n standalone: true,\r\n selector: 'user-page',\r\n templateUrl: './userPage.component.html',\r\n styleUrls: ['./userPage.component.css'],\r\n imports: [ButtonModule, InputIconModule, IconFieldModule, InputTextModule, FloatLabelModule, FormsModule, CommonModule, ToastModule],\r\n providers: [MessageService]\r\n})\r\nexport class UserPageComponent {\r\n userSubscription!: Subscription;\r\n\r\n\r\n email: string = \"\";\r\n name: string = \"\";\r\n newName: string = \"\";\r\n\r\n constructor(private userService: UserService, private messageService: MessageService) {}\r\n \r\n ngOnInit() {\r\n this.userSubscription = this.userService.getNameAndEmail().subscribe(userData => {\r\n this.email = userData?.email ?? '';\r\n this.name = userData?.name ?? '';\r\n this.newName = this.name;\r\n });\r\n }\r\n\r\n ngOnDestroy() {\r\n this.userSubscription?.unsubscribe();\r\n }\r\n\r\n async updateName() {\r\n try {\r\n await this.userService.updateUserName(this.newName);\r\n this.messageService.add({ \r\n severity: 'info', \r\n summary: 'Info', \r\n detail: `Name updated without problems.`,\r\n life: 3000, \r\n closable: true \r\n });\r\n } catch (error) {\r\n this.messageService.add({ \r\n severity: 'error', \r\n summary: 'Error', \r\n detail: 'Something went wrong. Try again later or contact the administrator.', \r\n life: 3000, \r\n closable: true \r\n });\r\n }\r\n }\r\n\r\n}","<p-toast class=\"custom-toast\" position=\"bottom-right\"/>\r\n<div class=\"flex flex-column align-items-center justify-content-center p-4\">\r\n <h2>User Profile</h2>\r\n <div class=\"flex gap-4\">\r\n <p-floatlabel variant=\"on\" class=\"custom-floatlabel\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-envelope\" />\r\n <input pInputText id=\"email\" [disabled]=\"true\" autocomplete=\"off\" class=\"w-full max-w-25rem custom-input\" [(ngModel)]=\"email\"/>\r\n </p-iconfield>\r\n <label for=\"email\">Email</label>\r\n </p-floatlabel>\r\n </div>\r\n <div class=\"flex gap-4 mt-4 mb-4\">\r\n <p-floatlabel variant=\"on\" class=\"custom-floatlabel\">\r\n <p-iconfield>\r\n <p-inputicon class=\"pi pi-user\" />\r\n <input pInputText id=\"password\" [disabled]=\"email == ''\" autocomplete=\"off\" class=\"w-full max-w-25rem custom-input\" [(ngModel)]=\"newName\"/>\r\n </p-iconfield>\r\n <label for=\"password\">Name</label>\r\n </p-floatlabel>\r\n </div>\r\n <p-button class=\"custom-button\" label=\"Update Name\" [disabled]=\"(name == newName || email == '')\" (click)=\"updateName()\" />\r\n</div>","/*\r\n * Public API Surface of ngx-bok-utils\r\n */\r\n\r\nexport * from './lib/components/footer/footer.component';\r\nexport * from './lib/components/header/header.component';\r\nexport * from './lib/components/404/notFoundPage.component';\r\nexport * from './lib/components/userPage/userPage.component';","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.UserService","i3","i4","i5","i1","i2"],"mappings":"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"}
@@ -1,12 +1,24 @@
1
1
  import { MenuItem } from 'primeng/api';
2
+ import { UserService } from '../../services/user.service';
2
3
  import * as i0 from "@angular/core";
3
4
  export declare class HeaderComponent {
5
+ private userService;
4
6
  items: MenuItem[];
7
+ userItems: MenuItem[];
5
8
  toolName: string;
9
+ login: boolean;
6
10
  hideMenu: boolean;
11
+ logged: boolean;
12
+ nameInitial: string;
13
+ showLoginModal: boolean;
14
+ private userStateSubscription;
15
+ constructor(userService: UserService);
16
+ ngOnInit(): void;
17
+ ngOnDestroy(): void;
18
+ logout(): Promise<void>;
7
19
  clickout(event: {
8
20
  target: any;
9
21
  }): void;
10
22
  static ɵfac: i0.ɵɵFactoryDeclaration<HeaderComponent, never>;
11
- static ɵcmp: i0.ɵɵComponentDeclaration<HeaderComponent, "header", never, { "items": { "alias": "items"; "required": false; }; "toolName": { "alias": "toolName"; "required": false; }; }, {}, never, never, true, never>;
23
+ static ɵcmp: i0.ɵɵComponentDeclaration<HeaderComponent, "header", never, { "items": { "alias": "items"; "required": false; }; "toolName": { "alias": "toolName"; "required": false; }; "login": { "alias": "login"; "required": false; }; }, {}, never, never, true, never>;
12
24
  }
@@ -0,0 +1,26 @@
1
+ import { EventEmitter, SimpleChanges } from "@angular/core";
2
+ import { UserService } from "../../services/user.service";
3
+ import * as i0 from "@angular/core";
4
+ export declare class SessionModalComponent {
5
+ private userService;
6
+ visible: boolean;
7
+ visibleChange: EventEmitter<boolean>;
8
+ login: boolean;
9
+ resetpassword: boolean;
10
+ email: string;
11
+ password: string;
12
+ repeatPassword: string;
13
+ error: string | null;
14
+ constructor(userService: UserService);
15
+ ngOnChanges(changes: SimpleChanges): void;
16
+ getHeader(): string;
17
+ getSwitchLabel(): "Login" | "Register" | "Return";
18
+ clickSwitchButton(): void;
19
+ clickMainButton(): Promise<void>;
20
+ loginWithGoogle(): Promise<void>;
21
+ loginWithEmailAndPassword(): Promise<void>;
22
+ registerWithEmailAndPassword(): Promise<void>;
23
+ recoverPassword(): Promise<void>;
24
+ static ɵfac: i0.ɵɵFactoryDeclaration<SessionModalComponent, never>;
25
+ static ɵcmp: i0.ɵɵComponentDeclaration<SessionModalComponent, "sessionModal", never, { "visible": { "alias": "visible"; "required": false; }; }, { "visibleChange": "visibleChange"; }, never, never, true, never>;
26
+ }
@@ -0,0 +1,18 @@
1
+ import { Subscription } from "rxjs";
2
+ import { UserService } from "../../services/user.service";
3
+ import { MessageService } from "primeng/api";
4
+ import * as i0 from "@angular/core";
5
+ export declare class UserPageComponent {
6
+ private userService;
7
+ private messageService;
8
+ userSubscription: Subscription;
9
+ email: string;
10
+ name: string;
11
+ newName: string;
12
+ constructor(userService: UserService, messageService: MessageService);
13
+ ngOnInit(): void;
14
+ ngOnDestroy(): void;
15
+ updateName(): Promise<void>;
16
+ static ɵfac: i0.ɵɵFactoryDeclaration<UserPageComponent, never>;
17
+ static ɵcmp: i0.ɵɵComponentDeclaration<UserPageComponent, "user-page", never, {}, {}, never, never, true, never>;
18
+ }
@@ -0,0 +1,29 @@
1
+ import { Observable } from 'rxjs';
2
+ import * as i0 from "@angular/core";
3
+ export declare class UserService {
4
+ private auth;
5
+ private db;
6
+ private userCollection;
7
+ private errorMessages;
8
+ private userStateSubject;
9
+ constructor();
10
+ loginWithEmailAndPassword(email: string, password: string): Promise<void>;
11
+ registerWithEmailAndPassword(email: string, password: string, repeatPassword: string): Promise<void>;
12
+ loginWithGoogle(): Promise<void>;
13
+ recoverPassword(email: string): Promise<void>;
14
+ private checkUser;
15
+ private handleAuthError;
16
+ private isValidEmail;
17
+ getUserState(): Observable<{
18
+ logged: boolean;
19
+ nameInitial: string;
20
+ }>;
21
+ logout(): Promise<void>;
22
+ updateUserName(newName: string): Promise<void>;
23
+ getNameAndEmail(): Observable<{
24
+ email: string;
25
+ name: string;
26
+ } | null>;
27
+ static ɵfac: i0.ɵɵFactoryDeclaration<UserService, never>;
28
+ static ɵprov: i0.ɵɵInjectableDeclaration<UserService>;
29
+ }
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@eo4geo/ngx-bok-utils",
3
- "version": "1.0.10",
3
+ "version": "1.1.0",
4
4
  "author": "Marc Pardo Fernández",
5
5
  "license": "MIT",
6
6
  "peerDependencies": {
7
7
  "@angular/common": "^19.1.0",
8
8
  "@angular/core": "^19.1.0",
9
+ "@angular/fire": "^19.0.0",
9
10
  "@angular/animations": "^19.1.0",
10
11
  "primeflex": "^3.3.1",
11
12
  "primeicons": "^7.0.0",
package/public-api.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './lib/components/footer/footer.component';
2
2
  export * from './lib/components/header/header.component';
3
3
  export * from './lib/components/404/notFoundPage.component';
4
+ export * from './lib/components/userPage/userPage.component';