diff --git a/src/app/annuaire/annuaire.component.html b/src/app/annuaire/annuaire.component.html index 746b9d4ce188b33e06a9d458d73acc80f726c5e4..1ed2fb070f86bc15226733043096c3fc4f547ba9 100644 --- a/src/app/annuaire/annuaire.component.html +++ b/src/app/annuaire/annuaire.component.html @@ -4,9 +4,11 @@ class="hide-on-print" [shouldResetFilters]="resetFilters" [shouldShowMore]="nextPage" - (searchEvent)="getUsers($event)" + (searchEvent)="searchUsers($event)" + (shouldLoad)="shouldLoad($event)" /> <app-result-list + [isLoading]="isLoading" [userList]="userList" [totalUserResult]="totalUserResult" [isLogged]="true" diff --git a/src/app/annuaire/annuaire.component.scss b/src/app/annuaire/annuaire.component.scss index 73c3604f7c172c004ecb6329a807c0ce84909057..b5625868858caf6f219306165b92ac745670fd5f 100644 --- a/src/app/annuaire/annuaire.component.scss +++ b/src/app/annuaire/annuaire.component.scss @@ -2,7 +2,6 @@ .content-container { box-sizing: border-box; - height: calc(100% - $footer-height); display: flex; flex-direction: column; justify-content: center; diff --git a/src/app/annuaire/annuaire.component.ts b/src/app/annuaire/annuaire.component.ts index 217e0ae0a4ba5b8e2820ba3588f576f80a833431..61efe35983601693303118d48055e0025818ccb4 100644 --- a/src/app/annuaire/annuaire.component.ts +++ b/src/app/annuaire/annuaire.component.ts @@ -17,38 +17,53 @@ export class AnnuaireComponent implements OnInit { public resetFilters: number = 0; public nextPage: number = 1; public filterActive: boolean = false; + public isLoading = true; ngOnInit(): void { - this.getUsers({ queryParam: '', page: 1, jobFilters: [], employerFilters: [] }); - } - - public getUsers(params: SearchQuery): void { - if (this.userIsLoggedIn()) { - this.searchService.annuaireSearchQuery = params; - if (params.employerFilters?.length || params.jobFilters?.length) { - this.filterActive = true; - } else { - this.filterActive = false; - } - this.searchService - .searchUserRegistry(params.queryParam, params.page, params.jobFilters, params.employerFilters) - .subscribe((res: SearchResults) => { - this.userList = res.docs; - this.totalUserResult = res.count; - }); - } else { + if (!this.userIsLoggedIn()) { this.searchService.getUserRegistryCount().subscribe((nb: number) => { this.totalUserResult = nb; }); + this.isLoading = false; } } + public userIsLoggedIn(): boolean { return this.authService.isLoggedIn(); } + + private loadParams(params: SearchQuery): void { + this.searchService.annuaireSearchQuery = params; + if (params.employerFilters?.length || params.jobFilters?.length) { + this.filterActive = true; + } else { + this.filterActive = false; + } + } + + public searchUsers(params: SearchQuery): void { + this.loadParams(params); + this.searchService + .searchUserRegistry(params.queryParam, params.page, params.jobFilters, params.employerFilters) + .subscribe((res: SearchResults) => { + this.userList = res.docs; + this.totalUserResult = res.count; + this.isLoading = false; + }); + } + public shouldResetFilters(): void { this.resetFilters++; } public showMore(): void { this.nextPage++; } + + /** + * Should load in specific conditions such as changes in filters and search input. + * Should NOT load when showing more result because it would result in losing scroll position because of the rerender of the list. + */ + public shouldLoad(value: boolean): void { + this.isLoading = value; + } } diff --git a/src/app/annuaire/models/searchQuery.model.ts b/src/app/annuaire/models/searchQuery.model.ts index c9c3cd9698216c3da26ea2125f8c3e6b0a6336ea..91186da0ec65d89d49b30d4ad8d13c2158239009 100644 --- a/src/app/annuaire/models/searchQuery.model.ts +++ b/src/app/annuaire/models/searchQuery.model.ts @@ -2,7 +2,7 @@ import { UserAnnuary } from '../../models/user.model'; export interface SearchQuery { queryParam: string; - page: number; + page?: number; jobFilters?: string[]; employerFilters?: string[]; } diff --git a/src/app/annuaire/result-list/result-list.component.html b/src/app/annuaire/result-list/result-list.component.html index 4deb918c586f5fd07ea5e52206d815a99f027dc1..594be3758831b8450662e4e66cc862caa26d6204 100644 --- a/src/app/annuaire/result-list/result-list.component.html +++ b/src/app/annuaire/result-list/result-list.component.html @@ -1,75 +1,85 @@ -<div *ngIf="isLogged && userList.length" class="results notEmpty" [ngClass]="{ filterActive: filterActive }"> - <div class="userNumber"> - {{ userList.length }} utilisateur(s)<span *ngIf="showPagination"> sur {{ totalUserResult }} </span> +<ng-container *ngIf="isLoading"> + <div class="results"> + <div class="loader"> + <img class="loader-gif" src="/assets/gif/loader_circle.gif" alt /> + </div> </div> - <div - *ngFor="let user of userList; let index = index" - class="singleUser" - tabindex="0" - role="link" - (click)="goToUser(user._id)" - (keyup.enter)="goToUser(user._id)" - > - <div class="avatar-container"> - <app-svg-icon class="avatar" [type]="'avatar'" [icon]="'defaultAvatar'" [iconClass]="'icon-40'" /> +</ng-container> + +<ng-container *ngIf="!isLoading"> + <div *ngIf="isLogged && userList.length" class="results notEmpty" [ngClass]="{ filterActive: filterActive }"> + <div class="userNumber"> + {{ userList.length }} utilisateur(s)<span *ngIf="showPagination"> sur {{ totalUserResult }} </span> </div> - <div class="identity"> - <p class="name">{{ user.name | userName }} {{ user.surname | uppercase }}</p> - <p *ngIf="user.job" class="job">{{ user.job.name }}</p> + <div + *ngFor="let user of userList; let index = index" + class="singleUser" + tabindex="0" + role="link" + (click)="goToUser(user._id)" + (keyup.enter)="goToUser(user._id)" + > + <div class="avatar-container"> + <app-svg-icon class="avatar" [type]="'avatar'" [icon]="'defaultAvatar'" [iconClass]="'icon-40'" /> + </div> + <div class="identity"> + <p class="name">{{ user.name | userName }} {{ user.surname | uppercase }}</p> + <p *ngIf="user.job" class="job">{{ user.job.name }}</p> + </div> + <div *ngIf="user.employer" class="employer">{{ user.employer.name }}</div> </div> - <div *ngIf="user.employer" class="employer">{{ user.employer.name }}</div> - </div> - <div *ngIf="showPagination" class="pagination"> - <div class="text"> - {{ userList.length }} utilisateur(s) affiché(s) sur {{ totalUserResult }} utilisateur(s) trouvé(s). + <div *ngIf="showPagination" class="pagination"> + <div class="text"> + {{ userList.length }} utilisateur(s) affiché(s) sur {{ totalUserResult }} utilisateur(s) trouvé(s). + </div> + <app-button + tabindex="0" + [style]="buttonTypeEnum.modalSecondary" + [type]="'form'" + [text]="'Voir plus'" + (click)="showMore()" + /> </div> + </div> + + <div *ngIf="isLogged && userList.length === 0" class="results empty"> + <div class="userNumber">0 utilisateur</div> + <div class="noUser">Aucun résultat ne correspond à vos filtres</div> <app-button tabindex="0" - [style]="buttonTypeEnum.modalSecondary" + [style]="buttonTypeEnum.modalPrimary" [type]="'form'" - [text]="'Voir plus'" - (click)="showMore()" + [text]="'Réinitialiser les filtres'" + (click)="resetFilters()" /> </div> -</div> -<div *ngIf="isLogged && userList.length === 0" class="results empty"> - <div class="userNumber">0 utilisateur</div> - <div class="noUser">Aucun résultat ne correspond à vos filtres</div> - <app-button - tabindex="0" - [style]="buttonTypeEnum.modalPrimary" - [type]="'form'" - [text]="'Réinitialiser les filtres'" - (click)="resetFilters()" - /> -</div> - -<div *ngIf="!isLogged && totalUserResult" class="results unlogged"> - <img src="../../assets/ico/annuaire-unlogged.svg" alt="Illustration annuaire" /> - <div class="users" [ngPlural]="totalUserResult"> - <ng-template ngPluralCase="0">Aucun utilisateur n'est présent dans l'annuaire Rés'in</ng-template> - <ng-template ngPluralCase="1">1 utilisateur est présent dans l'annuaire Rés'in</ng-template> - <ng-template ngPluralCase="other" - >{{ totalUserResult }} utilisateurs sont présents dans l'annuaire Rés'in</ng-template - > - </div> - <div class="access"> - Pour accéder à l’annuaire de Rés'in et contacter les utilisateurs,<br /> - veuillez vous connecter ou vous créer un compte. - </div> - <div class="buttons"> - <app-button - [text]="'Se créer un compte'" - [style]="buttonTypeEnum.Secondary" - [extraClass]="'fullWidth'" - (action)="goRegister()" - /> - <app-button - [text]="'Se connecter'" - [style]="buttonTypeEnum.Primary" - [extraClass]="'fullWidth'" - (action)="goLogin()" - /> + <div *ngIf="!isLogged && totalUserResult" class="results unlogged"> + <img src="../../assets/ico/annuaire-unlogged.svg" alt="Illustration annuaire" /> + <div class="users" [ngPlural]="totalUserResult"> + <ng-template ngPluralCase="0">Aucun utilisateur n'est présent dans l'annuaire Rés'in</ng-template> + <ng-template ngPluralCase="1">1 utilisateur est présent dans l'annuaire Rés'in</ng-template> + <ng-template ngPluralCase="other" + >{{ totalUserResult }} utilisateurs sont présents dans l'annuaire Rés'in</ng-template + > + </div> + <div class="access"> + Pour accéder à l’annuaire de Rés'in et contacter les utilisateurs,<br /> + veuillez vous connecter ou vous créer un compte. + </div> + <div class="buttons"> + <app-button + [text]="'Se créer un compte'" + [style]="buttonTypeEnum.Secondary" + [extraClass]="'fullWidth'" + (action)="goRegister()" + /> + <app-button + [text]="'Se connecter'" + [style]="buttonTypeEnum.Primary" + [extraClass]="'fullWidth'" + (action)="goLogin()" + /> + </div> </div> -</div> +</ng-container> diff --git a/src/app/annuaire/result-list/result-list.component.scss b/src/app/annuaire/result-list/result-list.component.scss index 3848a1f699ee1803010bd2d947d7b081d22248c2..50c013396defa2348a607b027faa41e3bcd47cbc 100644 --- a/src/app/annuaire/result-list/result-list.component.scss +++ b/src/app/annuaire/result-list/result-list.component.scss @@ -17,6 +17,13 @@ padding: 0.5rem 0 0.5rem 0.5rem; margin: 0; } + + .loader { + display: flex; + justify-content: center; + align-items: center; + height: calc(100vh - $footer-height - $header-height - $header-height - 7rem); + } .userNumber { font-size: 0.875rem; color: $grey-3; @@ -34,7 +41,7 @@ } } &.notEmpty { - //make sure it fits the correct height no matter the content lengtj and screen height + //make sure it fits the correct height no matter the content length and screen height max-height: calc(100vh - $footer-height - $header-height - $header-height - 2rem); &.filterActive { max-height: calc(100vh - $footer-height - $header-height - $header-height - 5rem); @@ -59,14 +66,8 @@ } } &.unlogged { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; text-align: center; - margin: auto; padding: 70px 40px; - border: 1px solid $grey-6; @media #{$tablet} { padding: 30px; } diff --git a/src/app/annuaire/result-list/result-list.component.ts b/src/app/annuaire/result-list/result-list.component.ts index dd1178454912273694def95e695092494ae1ae73..c1237249c93beb9711db62945794dc687dd0364c 100644 --- a/src/app/annuaire/result-list/result-list.component.ts +++ b/src/app/annuaire/result-list/result-list.component.ts @@ -14,6 +14,7 @@ export class ResultListComponent implements OnInit, OnChanges { @Input() totalUserResult: number; @Input() isLogged: boolean; @Input() filterActive: boolean; + @Input() isLoading: boolean; @Output() resetEvent = new EventEmitter<any>(); @Output() showMoreEvent = new EventEmitter<any>(); public maxPerPage: number = 20; diff --git a/src/app/annuaire/search-bar/search-bar.component.html b/src/app/annuaire/search-bar/search-bar.component.html index ff5bbecb6f852206d2dcbfb880042aee19ca349d..75157e8befdfbfa9c3cc1266bb5b259aabd9dd73 100644 --- a/src/app/annuaire/search-bar/search-bar.component.html +++ b/src/app/annuaire/search-bar/search-bar.component.html @@ -32,7 +32,7 @@ fxLayoutAlign="space-between center" [ngClass]="{ selected: modalTypeOpened === TypeModal.jobs, - containCheckedFilters: numberJobChecked + containCheckedFilters: jobsFiltersActive }" (click)="openModal(TypeModal.jobs)" > @@ -46,7 +46,7 @@ fxLayoutAlign="space-between center" [ngClass]="{ selected: modalTypeOpened === TypeModal.employers, - containCheckedFilters: numberEmployersChecked + containCheckedFilters: employersFiltersActive }" (click)="openModal(TypeModal.employers)" > diff --git a/src/app/annuaire/search-bar/search-bar.component.ts b/src/app/annuaire/search-bar/search-bar.component.ts index 01fe43ded406692340b7a14b1844f4d6201b51aa..8b042986ec59e0ab95835b98b0885739444cc53f 100644 --- a/src/app/annuaire/search-bar/search-bar.component.ts +++ b/src/app/annuaire/search-bar/search-bar.component.ts @@ -5,6 +5,7 @@ import { forkJoin, lastValueFrom } from 'rxjs'; import { ButtonType } from '../../shared/components/button/buttonType.enum'; import { SearchService } from '../../structure-list/services/search.service'; import { TypeModal } from '../enums/TypeModal.enum'; +import { SearchQuery } from '../models/searchQuery.model'; @Component({ selector: 'app-search-bar', @@ -14,15 +15,16 @@ import { TypeModal } from '../enums/TypeModal.enum'; export class SearchBarComponent implements OnInit, OnChanges { @Input() shouldResetFilters = 0; @Input() shouldShowMore = 0; - @Output() searchEvent = new EventEmitter(); + @Output() searchEvent = new EventEmitter<SearchQuery>(); + @Output() shouldLoad = new EventEmitter<boolean>(); public locate = false; public addStructureFormModal = false; public buttonTypeEnum = ButtonType; public searchForm: FormGroup; public modalTypeOpened: TypeModal; - public numberEmployersChecked = 0; - public numberJobChecked = 0; + public employersFiltersActive = false; + public jobsFiltersActive = false; public jobTypes: string[] = []; public employerTypes: string[] = []; public TypeModal = TypeModal; @@ -40,7 +42,7 @@ export class SearchBarComponent implements OnInit, OnChanges { async ngOnInit(): Promise<void> { // Will store the different categories - await this.getData(); + await this.loadFilters(); const queryString = this.activatedRoute.snapshot.queryParamMap.get('search'); // Use existing query if back to the page or init the query if (!this.searchService.annuaireSearchQuery) { @@ -62,7 +64,10 @@ export class SearchBarComponent implements OnInit, OnChanges { } ngOnChanges(changes: SimpleChanges): void { - if (changes.shouldResetFilters && changes.shouldResetFilters.currentValue !== 0) this.resetFilters(); + if (changes.shouldResetFilters && changes.shouldResetFilters.currentValue !== 0) { + this.resetFilters(); + this.shouldLoad.emit(true); + } if (changes.shouldShowMore && !changes.shouldShowMore.firstChange) { const term = this.searchForm.get('searchTerm').value || ''; this.searchEvent.emit({ @@ -75,7 +80,7 @@ export class SearchBarComponent implements OnInit, OnChanges { } /** Get the categories for each modal type */ - private async getData(): Promise<void> { + private async loadFilters(): Promise<void> { const { job, employer } = await lastValueFrom( forkJoin({ job: this.searchService.getJobs(), @@ -94,6 +99,7 @@ export class SearchBarComponent implements OnInit, OnChanges { /** Sends an array containing all filters */ public applyFilter(term: string): void { + this.shouldLoad.emit(true); this.shouldResetFilters = 0; // Add search input filter if (term) { @@ -157,18 +163,17 @@ export class SearchBarComponent implements OnInit, OnChanges { /** Check if some modules is checked on filter and store number of modules checked */ private countCheckedFilters(): void { - this.numberJobChecked = this.searchService.checkedFilterList.filter((filter) => - this.jobTypes.includes(filter) - ).length; - this.numberEmployersChecked = this.searchService.checkedFilterList.filter((filter) => + this.jobsFiltersActive = this.searchService.checkedFilterList.some((filter) => this.jobTypes.includes(filter)); + this.employersFiltersActive = this.searchService.checkedFilterList.some((filter) => this.employerTypes.includes(filter) - ).length; + ); } public resetFilters(): void { + this.shouldLoad.emit(true); this.searchService.checkedFilterList = []; - this.numberEmployersChecked = 0; - this.numberJobChecked = 0; + this.employersFiltersActive = false; + this.jobsFiltersActive = false; this.employerFilterChecked = []; this.jobFilterChecked = []; this.searchEvent.emit({ queryParam: '', jobFilters: [], employerFilters: [] }); @@ -177,6 +182,7 @@ export class SearchBarComponent implements OnInit, OnChanges { } public removeFilter(filter: string): void { + this.shouldLoad.emit(true); const index = this.searchService.checkedFilterList.findIndex((checkedFilter: string) => checkedFilter === filter); this.searchService.checkedFilterList.splice(index, 1); const inputTerm = this.searchForm.get('searchTerm').value; diff --git a/src/app/app.component.scss b/src/app/app.component.scss index f6ccc9acce3e15a64cf7aa62f13a4ed52a6797b7..ba071c6113e1dc31914f6dc35440ff49c4690dd4 100644 --- a/src/app/app.component.scss +++ b/src/app/app.component.scss @@ -13,7 +13,8 @@ } } .app-body { - flex: 1 1 auto; + display: flex; + flex-direction: column; overflow-y: auto; overflow-x: hidden; position: relative; diff --git a/src/app/footer/footer.component.html b/src/app/footer/footer.component.html index 9ef74a98980c9c645e531839fc4f74e168b4b1d6..489ee087b881f77161ddb0c5bea2a07518a9ccf3 100644 --- a/src/app/footer/footer.component.html +++ b/src/app/footer/footer.component.html @@ -1,4 +1,4 @@ -<div class="footer"> +<footer class="footer"> <div class="links"> <a class="clickable text-align-center" routerLink="/legal-notice" i18n>Mentions légales</a> <a class="clickable text-align-center" routerLink="/newsletter" i18n>Newsletter</a> @@ -18,4 +18,4 @@ <p class="metro-title" i18n>Un site de la Métropole de Lyon</p> </a> </div> -</div> +</footer> diff --git a/src/app/footer/footer.component.scss b/src/app/footer/footer.component.scss index 73308f291f0232ba9ecddfcaa92936bdccc4159d..ebfea84f21f7904d5e1f7f00a90c98866abaec49 100644 --- a/src/app/footer/footer.component.scss +++ b/src/app/footer/footer.component.scss @@ -3,6 +3,10 @@ @import '../../assets/scss/typography'; @import '../../assets/scss/layout'; +:host { + margin-top: auto; +} + .footer { height: $footer-height; background-color: black; diff --git a/src/app/form/form-view/form-view.component.scss b/src/app/form/form-view/form-view.component.scss index c72784526eb6ac9461646bef969a488e832552ed..33b4865fffa5f9dad44684133040e70826f5ea74 100644 --- a/src/app/form/form-view/form-view.component.scss +++ b/src/app/form/form-view/form-view.component.scss @@ -3,6 +3,10 @@ @import '../../../assets/scss/layout'; @import '../../../assets//scss/typography'; +:host { + height: 100%; +} + .formView { height: 100%; display: flex; diff --git a/src/app/form/orientation-form-view/orientation-form-view.component.scss b/src/app/form/orientation-form-view/orientation-form-view.component.scss index a9be502df016a613c114223f7c267218d31ac545..30bc7595313f56a7e7a35f4550de80c701111d0b 100644 --- a/src/app/form/orientation-form-view/orientation-form-view.component.scss +++ b/src/app/form/orientation-form-view/orientation-form-view.component.scss @@ -3,6 +3,10 @@ @import '../../../assets/scss/layout'; @import '../../../assets//scss/typography'; +:host { + height: 100%; +} + ::ng-deep h2 { margin-top: 0; } diff --git a/src/app/login/login.component.html b/src/app/login/login.component.html index 3c4626d264dc5173d839b7c7b311993ce744d1ce..93cd11c4f64e0291270c7de00a7adb17bd138347 100644 --- a/src/app/login/login.component.html +++ b/src/app/login/login.component.html @@ -1,71 +1,69 @@ -<div class="content"> - <div class="loginPage"> - <div class="form"> - <div class="title"> - <h3>{{ isWelcome ? 'Bienvenue !' : 'Connexion' }}</h3> - <p>Saisissez votre email pour vous connecter</p> - </div> - <p *ngIf="verificationIssue" class="incorrectId"> - Une erreur est survenue lors de la validation de votre email... Veuillez envoyer un mail au support. - </p> - <form [formGroup]="loginForm" (ngSubmit)="onSubmit()"> - <div class="form-group" fxLayout="column"> - <label for="email">Identifiant</label> - <div fxLayout="row" fxLayoutGap="13px"> - <input type="text" autocomplete="on" formControlName="email" class="form-input" /> - <svg *ngIf="f.email.invalid && f.email.value" class="notValidate" aria-hidden="true"> - <use [attr.xlink:href]="'assets/form/sprite.svg#notValidate'"></use> - </svg> - </div> - <div *ngIf="authFailed" class="incorrectId">Identifiant ou mot de passe invalide</div> +<div class="loginPage"> + <div class="form"> + <div class="title"> + <h3>{{ isWelcome ? 'Bienvenue !' : 'Connexion' }}</h3> + <p>Saisissez votre email pour vous connecter</p> + </div> + <p *ngIf="verificationIssue" class="incorrectId"> + Une erreur est survenue lors de la validation de votre email... Veuillez envoyer un mail au support. + </p> + <form [formGroup]="loginForm" (ngSubmit)="onSubmit()"> + <div class="form-group" fxLayout="column"> + <label for="email">Identifiant</label> + <div fxLayout="row" fxLayoutGap="13px"> + <input type="text" autocomplete="on" formControlName="email" class="form-input" /> + <svg *ngIf="f.email.invalid && f.email.value" class="notValidate" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#notValidate'"></use> + </svg> </div> - <div class="form-group password" fxLayout="column"> - <label for="password">Mot de passe</label> - <div fxLayout="row" fxLayoutGap="13px" fxLayoutAlign="default center"> - <input - autocomplete="on" - formControlName="password" - class="form-input" - [type]="isShowPassword ? 'text' : 'password'" - [ngClass]="{ inputInvalid: f.password.invalid && f.password.value }" - /> - <div class="eyePassword"> - <svg aria-hidden="true" preserveAspectRatio="xMinYMid" (click)="toggleShowPassword()"> - <use *ngIf="!isShowPassword" [attr.xlink:href]="'assets/form/sprite.svg#eyePasswordVisible'"></use> - <use *ngIf="isShowPassword" [attr.xlink:href]="'assets/form/sprite.svg#eyePasswordInvisible'"></use> - </svg> - </div> - <svg *ngIf="f.password.invalid && f.password.value" class="notValidate" aria-hidden="true"> - <use [attr.xlink:href]="'assets/form/sprite.svg#notValidate'"></use> + <div *ngIf="authFailed" class="incorrectId">Identifiant ou mot de passe invalide</div> + </div> + <div class="form-group password" fxLayout="column"> + <label for="password">Mot de passe</label> + <div fxLayout="row" fxLayoutGap="13px" fxLayoutAlign="default center"> + <input + autocomplete="on" + formControlName="password" + class="form-input" + [type]="isShowPassword ? 'text' : 'password'" + [ngClass]="{ inputInvalid: f.password.invalid && f.password.value }" + /> + <div class="eyePassword"> + <svg aria-hidden="true" preserveAspectRatio="xMinYMid" (click)="toggleShowPassword()"> + <use *ngIf="!isShowPassword" [attr.xlink:href]="'assets/form/sprite.svg#eyePasswordVisible'"></use> + <use *ngIf="isShowPassword" [attr.xlink:href]="'assets/form/sprite.svg#eyePasswordInvisible'"></use> </svg> </div> - <p class="passHint" [ngClass]="{ invalid: f.password.invalid && f.password.value }"> - Il doit contenir au minimum :<br /> - 8 caractères dont un caractère spécial, un caractère en majuscule et un chiffre. - </p> - </div> - <div class="footer" fxLayout="row" fxLayoutAlign="space-around center"> - <app-button - [text]="'Mot de passe oublié'" - [style]="buttonTypeEnum.Secondary" - [extraClass]="'fullWidth'" - (action)="swithToResetPassword()" - /> - <app-button - [type]="'submit'" - [text]="'Se connecter'" - [disabled]="loginForm.invalid || loading" - [style]="buttonTypeEnum.Primary" - [extraClass]="'fullWidth'" - /> + <svg *ngIf="f.password.invalid && f.password.value" class="notValidate" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#notValidate'"></use> + </svg> </div> + <p class="passHint" [ngClass]="{ invalid: f.password.invalid && f.password.value }"> + Il doit contenir au minimum :<br /> + 8 caractères dont un caractère spécial, un caractère en majuscule et un chiffre. + </p> + </div> + <div class="footer" fxLayout="row" fxLayoutAlign="space-around center"> <app-button - [text]="'Je n’ai pas encore de compte'" - [style]="buttonTypeEnum.Tertiary" + [text]="'Mot de passe oublié'" + [style]="buttonTypeEnum.Secondary" [extraClass]="'fullWidth'" - (action)="goToAccountCreation()" + (action)="swithToResetPassword()" /> - </form> - </div> + <app-button + [type]="'submit'" + [text]="'Se connecter'" + [disabled]="loginForm.invalid || loading" + [style]="buttonTypeEnum.Primary" + [extraClass]="'fullWidth'" + /> + </div> + <app-button + [text]="'Je n’ai pas encore de compte'" + [style]="buttonTypeEnum.Tertiary" + [extraClass]="'fullWidth'" + (action)="goToAccountCreation()" + /> + </form> </div> </div> diff --git a/src/app/login/login.component.scss b/src/app/login/login.component.scss index 4283e56eddb6372985d86bd446f20a995551557d..1258e840698df5ef636cfcd39b76493a08b1f264 100644 --- a/src/app/login/login.component.scss +++ b/src/app/login/login.component.scss @@ -3,19 +3,13 @@ @import '../../assets/scss/layout'; @import '../../assets/scss/typography'; -.content { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - height: calc(100% - $footer-height); -} .loginPage { display: flex; width: 100%; max-width: 980px; box-sizing: border-box; margin: auto; + margin-top: 2rem; min-height: 450px; max-height: 80vh; overflow-y: auto; @@ -26,6 +20,7 @@ padding: 70px 40px; @media #{$desktop} { padding: 1rem; + margin-top: 1rem; } .title { diff --git a/src/app/reset-password/reset-password.component.html b/src/app/reset-password/reset-password.component.html index 835544a90503fe80f71ff402b9dde861ab4e7a3e..49be060520b11a6ee9630604bf1f1d6d8ab31310 100644 --- a/src/app/reset-password/reset-password.component.html +++ b/src/app/reset-password/reset-password.component.html @@ -1,45 +1,43 @@ -<div class="content"> - <div *ngIf="!token" class="resetPage"> - <div class="resetPasswordForm"> - <div class="title"> - <h1>Mot de passe oublié</h1> - <p>Saisissez votre email afin de réinitialiser votre mot de passe</p> - </div> - <div class="fields"> - <form [formGroup]="resetForm" (ngSubmit)="onSubmit()"> - <div class="form-group"> - <label for="email">Email du compte</label> - <div fxLayout="row" fxLayoutGap="13px"> - <input - type="text" - autocomplete="on" - formControlName="email" - class="form-input" - [ngClass]="{ inputInvalid: submitted && f.email.errors }" - /> - </div> - <div *ngIf="submitted && f.email.errors" class="incorrectId"> - <div *ngIf="f.email.errors.required">L'adresse e-mail est requise</div> - </div> - </div> - <div class="footer" fxLayout="row" fxLayoutAlign="space-between center"> - <app-button - [text]="'Annuler'" - [style]="buttonTypeEnum.Secondary" - [extraClass]="'fullButton'" - (action)="goLogin()" - /> - <app-button - [type]="'submit'" - [disabled]="loading" - [text]="'Envoyer'" - [style]="buttonTypeEnum.Primary" - [extraClass]="'fullWidth'" +<div *ngIf="!token" class="resetPage"> + <div class="resetPasswordForm"> + <div class="title"> + <h1>Mot de passe oublié</h1> + <p>Saisissez votre email afin de réinitialiser votre mot de passe</p> + </div> + <div class="fields"> + <form [formGroup]="resetForm" (ngSubmit)="onSubmit()"> + <div class="form-group"> + <label for="email">Email du compte</label> + <div fxLayout="row" fxLayoutGap="13px"> + <input + type="text" + autocomplete="on" + formControlName="email" + class="form-input" + [ngClass]="{ inputInvalid: submitted && f.email.errors }" /> </div> - </form> - </div> + <div *ngIf="submitted && f.email.errors" class="incorrectId"> + <div *ngIf="f.email.errors.required">L'adresse e-mail est requise</div> + </div> + </div> + <div class="footer" fxLayout="row" fxLayoutAlign="space-between center"> + <app-button + [text]="'Annuler'" + [style]="buttonTypeEnum.Secondary" + [extraClass]="'fullButton'" + (action)="goLogin()" + /> + <app-button + [type]="'submit'" + [disabled]="loading" + [text]="'Envoyer'" + [style]="buttonTypeEnum.Primary" + [extraClass]="'fullWidth'" + /> + </div> + </form> </div> </div> - <app-password-form *ngIf="token" /> </div> +<app-password-form *ngIf="token"></app-password-form> diff --git a/src/app/reset-password/reset-password.component.scss b/src/app/reset-password/reset-password.component.scss index 70621e99a16ac129d7281f94baa4b7af1232029c..7a69dc958266bdb65b3033d80bd7734401b49b28 100644 --- a/src/app/reset-password/reset-password.component.scss +++ b/src/app/reset-password/reset-password.component.scss @@ -3,18 +3,12 @@ @import '../../assets/scss/breakpoint'; @import '../../assets/scss/layout'; -.content { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - height: calc(100% - $footer-height); -} .resetPage { width: 100%; max-width: 980px; box-sizing: border-box; margin: auto; + margin-top: 2rem; min-height: 450px; max-height: 75vh; overflow-y: auto; diff --git a/src/app/services/routerListener.service.ts b/src/app/services/routerListener.service.ts index 6d8c817a58c56d1b7fcae517c7294fefda591269..bbfbf10fa22aa493c1c694afb35173ddd65ddc36 100644 --- a/src/app/services/routerListener.service.ts +++ b/src/app/services/routerListener.service.ts @@ -25,7 +25,7 @@ export class RouterListenerService { public goToPreviousUrl(data?: any): void { if (data) { - this.router.navigateByUrl(this.previousUrl, { state: { data: data } }); + this.router.navigateByUrl(this.previousUrl, { state: { data } }); } else { this.router.navigateByUrl(this.previousUrl); }