Skip to content

Commit

Permalink
Fix header account menu (#651)
Browse files Browse the repository at this point in the history
  • Loading branch information
avine authored Aug 6, 2024
1 parent 3dd0260 commit 2cfa6c0
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export class GiveRequestedFeedbackComponent implements GiveRequestedFeedbackData

private formBuilder = inject(NonNullableFormBuilder);

protected anonymous = inject(AuthService).userState().anonymous;
protected anonymous = inject(AuthService).userStatus().anonymous;

private feedbackService = inject(FeedbackService);

Expand Down
104 changes: 41 additions & 63 deletions client/src/app/header/header.component.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div class="app-header__burger">
@if (userState().authenticated) {
@if (userStatus().authenticated) {
<app-burger class="app-header-menu-target" [(active)]="isMenuOpen"></app-burger>
}
</div>
Expand All @@ -11,7 +11,7 @@
</div>

<nav class="app-header__menu app-header-menu-target mat-title-medium" [class.app-header__menu--visible]="isMenuOpen">
@if (userState().authenticated) {
@if (userStatus().authenticated) {
<a
class="app-header__menu-item"
routerLinkActive="app-header__menu-item--active"
Expand Down Expand Up @@ -64,76 +64,54 @@
}

<div class="app-header__account">
@if (!userState().guest) {
@if (userInfo(); as userInfo) {
<button class="gbl-button-less" [matMenuTriggerFor]="accountMenu">
<app-avatar class="app-header__account-photo" [photoUrl]="userInfo.photoURL" [name]="userInfo.displayName" />
</button>
} @else {
<button mat-icon-button [matMenuTriggerFor]="accountMenu">
<mat-icon class="gbl-sys-primary">more_vert</mat-icon>
</button>
}

<mat-menu #accountMenu="matMenu" xPosition="before" class="gbl-overlay-menu">
<button mat-menu-item (click)="languageService.switchLanguage()">
<ng-container [ngTemplateOutlet]="languageMenuItem" />
</button>
@if (userInfo(); as _userInfo) {
<button class="gbl-button-less" [matMenuTriggerFor]="accountMenu">
<app-avatar class="app-header__account-photo" [photoUrl]="_userInfo.photoURL" [name]="_userInfo.displayName" />
</button>
} @else {
<button mat-icon-button [matMenuTriggerFor]="accountMenu">
<mat-icon class="gbl-sys-primary">more_vert</mat-icon>
</button>
}

<button mat-menu-item (click)="themeService.switch()">
<ng-container [ngTemplateOutlet]="themeMenuItem" />
</button>
<mat-menu #accountMenu="matMenu" xPosition="before" class="gbl-overlay-menu">
<button mat-menu-item (click)="languageService.switchLanguage()">
<mat-icon class="gbl-sys-primary">translate</mat-icon>
@switch (languageService.localeId) {
@case ('fr') {
English
}
@case ('en') {
Français
}
}
</button>

@if (userState().authenticated) {
<button mat-menu-item routerLink="/settings">
<mat-icon class="gbl-sys-primary">settings</mat-icon>
<ng-container i18n="@@Title.Settings">Paramètres</ng-container>
</button>
<button mat-menu-item (click)="themeService.switch()">
<mat-icon class="gbl-sys-primary">{{ themeService.theme() === 'light' ? 'dark_mode' : 'light_mode' }}</mat-icon>
@if (themeService.theme() === 'light') {
<ng-container i18n="@@Action.DarkTheme">Thème foncé</ng-container>
} @else {
<ng-container i18n="@@Action.LightTheme">Thème clair</ng-container>
}
</button>

@if (userStatus().authenticated) {
<button mat-menu-item routerLink="/settings">
<mat-icon class="gbl-sys-primary">settings</mat-icon>
<ng-container i18n="@@Title.Settings">Paramètres</ng-container>
</button>
}

@if (!userStatus().guest) {
<button mat-menu-item (click)="signOut()">
<mat-icon class="gbl-sys-primary">logout</mat-icon>
@if (userState().authenticated) {
@if (userStatus().authenticated) {
<ng-container i18n="@@Action.SignOut">Se déconnecter</ng-container>
} @else {
<ng-container i18n="@@Action.CloseSession">Fermer la session</ng-container>
}
</button>
</mat-menu>
} @else {
<button mat-icon-button [matMenuTriggerFor]="guestMenu">
<mat-icon class="gbl-sys-primary">more_vert</mat-icon>
</button>

<mat-menu #guestMenu="matMenu" xPosition="before" class="gbl-overlay-menu">
<button mat-menu-item (click)="languageService.switchLanguage()">
<ng-container [ngTemplateOutlet]="languageMenuItem" />
</button>

<button mat-menu-item (click)="themeService.switch()">
<ng-container [ngTemplateOutlet]="themeMenuItem" />
</button>
</mat-menu>
}
</div>

<ng-template #languageMenuItem>
<mat-icon class="gbl-sys-primary">translate</mat-icon>
@switch (languageService.localeId) {
@case ('fr') {
English
}
@case ('en') {
Français
}
}
</ng-template>

<ng-template #themeMenuItem>
<mat-icon class="gbl-sys-primary">{{ themeService.theme() === 'light' ? 'dark_mode' : 'light_mode' }}</mat-icon>
@if (themeService.theme() === 'light') {
<ng-container i18n="@@Action.DarkTheme">Thème foncé</ng-container>
} @else {
<ng-container i18n="@@Action.LightTheme">Thème clair</ng-container>
}
</ng-template>
</mat-menu>
</div>
4 changes: 1 addition & 3 deletions client/src/app/header/header.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { NgTemplateOutlet } from '@angular/common';
import { Component, ViewEncapsulation, inject } from '@angular/core';
import { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';
import { MatBadgeModule } from '@angular/material/badge';
Expand All @@ -25,7 +24,6 @@ import { headerAnimations } from './header.animations';
},
standalone: true,
imports: [
NgTemplateOutlet,
RouterLink,
RouterLinkActive,
RouterLinkWithHref,
Expand All @@ -50,7 +48,7 @@ export class HeaderComponent {

protected themeService = inject(ThemeService);

protected userState = this.authService.userState;
protected userStatus = this.authService.userStatus;

protected userInfo = this.authService.userInfo;

Expand Down
12 changes: 6 additions & 6 deletions client/src/app/shared/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { GoogleAuthProvider, User, signInAnonymously, signInWithPopup } from 'fi
import { Observable, catchError, concatMap, filter, first, from, map, of, switchMap, tap } from 'rxjs';
import { FirebaseService } from '../firebase';
import { AUTH_REDIRECT_PARAM } from './auth.config';
import { UserState } from './auth.types';
import { buildUserState } from './auth.utils';
import { UserStatus } from './auth.types';
import { buildUserStatus } from './auth.utils';

@Injectable({
providedIn: 'root',
Expand All @@ -33,7 +33,7 @@ export class AuthService {

user = this._user.asReadonly();

userState = computed<UserState>(() => buildUserState(this._user()));
userStatus = computed<UserStatus>(() => buildUserStatus(this._user()));

userEmail = computed(() => this._user()?.email ?? '');

Expand All @@ -54,11 +54,11 @@ export class AuthService {
*/
user$ = toObservable(this._user).pipe(filter((user): user is User | null => user !== undefined));

guest$ = this.user$.pipe(map((user) => buildUserState(user).guest));
guest$ = this.user$.pipe(map((user) => buildUserStatus(user).guest));

anonymous$ = this.user$.pipe(map((user) => buildUserState(user).anonymous));
anonymous$ = this.user$.pipe(map((user) => buildUserStatus(user).anonymous));

authenticated$ = this.user$.pipe(map((user) => buildUserState(user).authenticated));
authenticated$ = this.user$.pipe(map((user) => buildUserStatus(user).authenticated));

constructor() {
this.firebaseAuth.onAuthStateChanged((user) => this._user.set(user));
Expand Down
3 changes: 2 additions & 1 deletion client/src/app/shared/auth/auth.types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export type UserState = {
export type UserStatus = {
guest: boolean;
anonymous: boolean;
authenticated: boolean;
status: 'guest' | 'anonymous' | 'authenticated';
};
7 changes: 4 additions & 3 deletions client/src/app/shared/auth/auth.utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { User } from 'firebase/auth';
import { UserState } from './auth.types';
import { UserStatus } from './auth.types';

export const buildUserState = (user: User | null | undefined) =>
export const buildUserStatus = (user: User | null | undefined) =>
({
guest: user === null,
anonymous: user?.isAnonymous === true,
authenticated: user?.isAnonymous === false,
}) satisfies UserState;
status: user === null ? 'guest' : user?.isAnonymous === true ? 'anonymous' : 'authenticated',
}) satisfies UserStatus;

0 comments on commit 2cfa6c0

Please sign in to comment.