diff --git a/projects/v3/src/app/pages/home/home.page.ts b/projects/v3/src/app/pages/home/home.page.ts index 6ad6192bb..ef28d08b7 100644 --- a/projects/v3/src/app/pages/home/home.page.ts +++ b/projects/v3/src/app/pages/home/home.page.ts @@ -95,6 +95,20 @@ export class HomePage implements OnInit, OnDestroy, AfterViewChecked { this.isExpertWithoutTeam = role === 'mentor' && !teamId; this.pulseCheckIndicatorEnabled = this.storageService.getFeature('pulseCheckIndicator'); this.isMobile = this.utils.isMobile(); + + // subscribe to team changes broadcast from shared service + this.sharedService.team$ + .pipe( + filter(team => team !== null), + takeUntil(this.unsubscribe$) + ) + .subscribe(() => { + // re-evaluate expert without team status when team changes + const currentRole = this.storageService.getUser().role; + const currentTeamId = this.storageService.getUser().teamId; + this.isExpertWithoutTeam = currentRole === 'mentor' && !currentTeamId; + }); + this.homeService.milestones$ .pipe( distinctUntilChanged(), @@ -185,6 +199,8 @@ export class HomePage implements OnInit, OnDestroy, AfterViewChecked { }, }); + // call updateDashboard on initial load to ensure fresh data + this.updateDashboard(); } ngOnDestroy(): void { @@ -206,6 +222,13 @@ export class HomePage implements OnInit, OnDestroy, AfterViewChecked { async updateDashboard() { await this.sharedService.refreshJWT(); // refresh JWT token [CORE-6083] + + // re-evaluate user role and team status after JWT refresh updates teamId + const role = this.storageService.getUser().role; + const teamId = this.storageService.getUser().teamId; + this.isParticipant = role === 'participant'; + this.isExpertWithoutTeam = role === 'mentor' && !teamId; + this.experience = this.storageService.get("experience"); this.homeService.getMilestones({ forceRefresh: true }); this.achievementService.getAchievements(); diff --git a/projects/v3/src/app/services/auth.service.ts b/projects/v3/src/app/services/auth.service.ts index ded993515..14fc8becc 100644 --- a/projects/v3/src/app/services/auth.service.ts +++ b/projects/v3/src/app/services/auth.service.ts @@ -126,6 +126,7 @@ interface AuthQuery { apikey?: string; service?: string; experienceUuid?: string; + forceRefresh?: boolean; } @Injectable({ @@ -154,9 +155,14 @@ export class AuthService { const lastFetchTime: number = +this.storage.get('lastAuthFetchTime'); const authCache = this.authCache$.getValue() || this.storage.get('authCache'); - // 2 conditions to pull from server: - // when experienceUuid is not null (required for switch experience) - // when authToken available (directLogin) + // conditions to pull from server: + // - when forceRefresh is true (bypass cache) + // - when experienceUuid is not null (required for switch experience) + // - when authToken available (directLogin) + if (data?.forceRefresh) { + return this.fetchData(data); + } + if (!(data?.experienceUuid || data?.authToken) && lastFetchTime && (currentTime - lastFetchTime) < this.authCacheDuration && authCache) { return of(authCache); } else { diff --git a/projects/v3/src/app/services/shared.service.ts b/projects/v3/src/app/services/shared.service.ts index 083538d9b..3007b3d4c 100644 --- a/projects/v3/src/app/services/shared.service.ts +++ b/projects/v3/src/app/services/shared.service.ts @@ -191,7 +191,7 @@ export class SharedService { * @return {Promise} non-strict return value, we won't use */ async refreshJWT(): Promise { - const res: AuthEndpoint = await firstValueFrom(this.authService.authenticate()); + const res: AuthEndpoint = await firstValueFrom(this.authService.authenticate({ forceRefresh: true })); const auth = res?.data?.auth; const latestTeamId = auth?.experience?.team?.id;