From 917a0044d31d124df50ab21ac31fa7a49e63e122 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bastienxs@gmail.com> Date: Tue, 10 May 2022 14:12:51 +0200 Subject: [PATCH 01/47] profile edit layout --- src/app/app-routing.module.ts | 6 ++ src/app/profile/edit/edit.component.html | 24 ++++++ src/app/profile/edit/edit.component.scss | 74 +++++++++++++++++++ src/app/profile/edit/edit.component.spec.ts | 25 +++++++ src/app/profile/edit/edit.component.ts | 22 ++++++ src/app/profile/profile.module.ts | 3 +- .../components/button/button.component.html | 24 ++++++ .../components/button/button.component.scss | 22 ++++++ .../components/button/buttonType.enum.ts | 1 + src/assets/ico/sprite.svg | 11 +++ 10 files changed, 211 insertions(+), 1 deletion(-) create mode 100644 src/app/profile/edit/edit.component.html create mode 100644 src/app/profile/edit/edit.component.scss create mode 100644 src/app/profile/edit/edit.component.spec.ts create mode 100644 src/app/profile/edit/edit.component.ts diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 7bc8c50b9..086acf579 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -23,6 +23,7 @@ import { RouteRole } from './shared/enum/routeRole.enum'; import { LoginComponent } from './login/login.component'; import { PasswordFormComponent } from './shared/components'; import { FooterComponent } from './footer/footer.component'; +import { EditComponent } from './profile/edit/edit.component'; const footerOutletRoute: Route = { path: '', @@ -147,6 +148,11 @@ const routes: Routes = [ canActivate: [AuthGuard], loadChildren: () => import('./profile/profile.module').then((m) => m.ProfileModule), }, + { + path: 'edit', + canActivate: [AuthGuard], + component: EditComponent, + }, footerOutletRoute, ], }, diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html new file mode 100644 index 000000000..9260006a0 --- /dev/null +++ b/src/app/profile/edit/edit.component.html @@ -0,0 +1,24 @@ +<div fxLayout="column" class="edit-profile"> + <div class="header"> + <div class="title"> + <svg class="leftArrow" aria-hidden="true"> + <use [attr.xlink:href]="'assets/ico/sprite.svg#leftArrow'"></use> + </svg> + <h1>Modifier mon profil</h1> + </div> + <app-button + [style]="buttonTypeEnum.SecondaryDelete" + [text]="'Supprimer mon compte'" + [iconType]="'ico'" + [iconBtn]="'removeCross'" + ></app-button> + </div> + <div class="navigation"> + <span class="tab selected">Coordonnées</span> + <span class="tab">Email et mot de passe</span> + <span class="tab">Employeur et fonction</span> + <span class="tab">Description</span> + <span class="tab">Avatar</span> + </div> + <div class="content"></div> +</div> diff --git a/src/app/profile/edit/edit.component.scss b/src/app/profile/edit/edit.component.scss new file mode 100644 index 000000000..6f42db811 --- /dev/null +++ b/src/app/profile/edit/edit.component.scss @@ -0,0 +1,74 @@ +@import '../../../assets/scss/color'; +@import '../../../assets/scss/typography'; +@import '../../../assets/scss/hyperlink'; +@import '../../../assets/scss/shapes'; +@import '../../../assets/scss/breakpoint'; + +.edit-profile { + margin: 16px auto 0 auto; + background: $white; + border-bottom: 1px solid $grey-4; + width: 70%; + min-height: 585px; + padding: 40px; + + @media #{$tablet} { + width: 70%; + } + @media #{$large-phone} { + width: 90%; + } + + .header, + .navigation, + .title { + display: flex; + } + .header { + justify-content: space-between; + + .title { + align-items: center; + h1 { + color: $grey-1; + font-weight: lighter; + } + svg { + stroke: $black; + height: 40px; + width: 40px; + margin-right: 14px; + cursor: pointer; + } + } + + app-button { + align-items: center; + display: flex; + ::ng-deep div svg { + height: 22px; + margin-right: 4px; + } + } + } + .navigation { + justify-content: flex-start; + } + + .navigation { + border-bottom: 1px solid $grey-4; + + .tab { + color: $grey-3; + margin-right: 40px; + padding-bottom: 8px; + &:hover { + cursor: pointer; + } + &.selected { + color: $grey-1; + border-bottom: 1px solid $grey-1; + } + } + } +} diff --git a/src/app/profile/edit/edit.component.spec.ts b/src/app/profile/edit/edit.component.spec.ts new file mode 100644 index 000000000..5a24d45a2 --- /dev/null +++ b/src/app/profile/edit/edit.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { EditComponent } from './edit.component'; + +describe('EditComponent', () => { + let component: EditComponent; + let fixture: ComponentFixture<EditComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ EditComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(EditComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts new file mode 100644 index 000000000..2b1f8d747 --- /dev/null +++ b/src/app/profile/edit/edit.component.ts @@ -0,0 +1,22 @@ +import { Component, OnInit, Input } from '@angular/core'; +import { User } from '../../models/user.model'; +import { ButtonType } from '../../shared/components/button/buttonType.enum'; +import { ProfileService } from '../services/profile.service'; + +@Component({ + selector: 'app-edit', + templateUrl: './edit.component.html', + styleUrls: ['./edit.component.scss'], +}) +export class EditComponent implements OnInit { + @Input() userProfile: User; + public buttonTypeEnum = ButtonType; + + constructor(private profileService: ProfileService) {} + + ngOnInit(): void { + this.profileService.getProfile().then((profile) => { + this.userProfile = profile; + }); + } +} diff --git a/src/app/profile/profile.module.ts b/src/app/profile/profile.module.ts index 0de33f82d..8e3485135 100644 --- a/src/app/profile/profile.module.ts +++ b/src/app/profile/profile.module.ts @@ -3,9 +3,10 @@ import { ProfileComponent } from './profile.component'; import { SharedModule } from '../shared/shared.module'; import { CommonModule } from '@angular/common'; import { ProfileRoutingModule } from './profile-routing.module'; +import { EditComponent } from './edit/edit.component'; @NgModule({ - declarations: [ProfileComponent], + declarations: [ProfileComponent, EditComponent], imports: [CommonModule, ProfileRoutingModule, SharedModule], }) export class ProfileModule {} diff --git a/src/app/shared/components/button/button.component.html b/src/app/shared/components/button/button.component.html index aef5c8276..a30bc4d6f 100644 --- a/src/app/shared/components/button/button.component.html +++ b/src/app/shared/components/button/button.component.html @@ -118,6 +118,30 @@ </button> </ng-container> +<ng-container *ngIf="style === buttonTypeEnum.SecondaryDelete"> + <button class="btn-regular secondary-delete" type="{{ type }}" (click)="doAction()" [disabled]="disabled"> + <div *ngIf="!iconBtn" [ngClass]="extraClass" class="text">{{ text }}</div> + <div + *ngIf="iconBtn && iconPos === 'left'" + fxLayout="row center" + class="text withIcon left" + fxLayoutAlign="space-around center" + > + <app-svg-icon [type]="iconType" [icon]="iconBtn" [iconColor]="'currentColor'"></app-svg-icon> + <span>{{ text }}</span> + </div> + <div + *ngIf="iconBtn && iconPos === 'right'" + fxLayout="row center" + class="text withIcon right" + fxLayoutAlign="space-around center" + > + <span>{{ text }}</span> + <app-svg-icon [type]="iconType" [icon]="iconBtn" [iconColor]="'currentColor'"></app-svg-icon> + </div> + </button> +</ng-container> + <ng-container *ngIf="style === buttonTypeEnum.ButtonPhone"> <button [disabled]="disabled" class="btn-switch-phone" type="{{ type }}" (click)="doAction()"> <div *ngIf="!iconBtn" class="text">{{ text }}</div> diff --git a/src/app/shared/components/button/button.component.scss b/src/app/shared/components/button/button.component.scss index 61843219e..0fddccb02 100644 --- a/src/app/shared/components/button/button.component.scss +++ b/src/app/shared/components/button/button.component.scss @@ -127,6 +127,28 @@ button { height: 22px !important; } } + &.secondary-delete { + div:first-child { + width: unset; + } + border: 0; + background: $white; + @include btn-regular; + .text { + background: $white; + border: 1px solid $grey-1; + color: $red; + font-size: 14px; + // @include btn-regular; + &.withIcon { + color: $red; + fill: $red; + } + } + .small-text { + height: 22px !important; + } + } &.tertiary { div:first-child { min-width: 50px; diff --git a/src/app/shared/components/button/buttonType.enum.ts b/src/app/shared/components/button/buttonType.enum.ts index 93b2cba45..9b84f5a57 100644 --- a/src/app/shared/components/button/buttonType.enum.ts +++ b/src/app/shared/components/button/buttonType.enum.ts @@ -2,6 +2,7 @@ export enum ButtonType { Regular, Primary, Secondary, + SecondaryDelete, Tertiary, ButtonPhone, Filter, diff --git a/src/assets/ico/sprite.svg b/src/assets/ico/sprite.svg index 7bc59a3ee..1c8cfdd98 100644 --- a/src/assets/ico/sprite.svg +++ b/src/assets/ico/sprite.svg @@ -74,6 +74,12 @@ <path d="M6.97363 12.9062C6.34733 12.9062 5.89876 12.7877 5.62793 12.5507C5.36556 12.3053 5.23438 11.9879 5.23438 11.5986C5.23438 11.2092 5.36556 10.8961 5.62793 10.6591C5.89876 10.4137 6.34733 10.2952 6.97363 10.3036C14.44 10.3036 10.571 10.3036 17.0156 10.3036C17.6419 10.3036 18.0863 10.4221 18.3486 10.6591C18.6195 10.8961 18.7549 11.2092 18.7549 11.5986C18.7549 11.9879 18.6195 12.3053 18.3486 12.5507C18.0863 12.7877 17.6419 12.9062 17.0156 12.9062C9.63742 12.9062 13.3678 12.9062 6.97363 12.9062Z" stroke="none"/> </symbol> +<symbol id="removeCross" width="22" height="23" viewBox="0 0 22 23" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M6.5 7L15.5 16" stroke="#DA3635" stroke-width="1.5" stroke-linecap="round"/> +<path d="M15.5 7L6.5 16" stroke="#DA3635" stroke-width="1.5" stroke-linecap="round"/> +</symbol> + + <symbol id="edit" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" clip-rule="evenodd" d="M17.3745 2.62547C17.72 2.28003 18.3461 2.34613 18.7731 2.7731L20.3193 4.3193C20.7463 4.74627 20.8124 5.37243 20.4669 5.71787L18.6115 7.57331L15.5191 4.48091L17.3745 2.62547ZM17.993 8.1918L14.9006 5.0994L5.62344 14.3766L8.71584 17.469L17.993 8.1918ZM8.09736 18.0874L5.00496 14.995L4.74469 15.2553C4.60266 15.3973 4.52461 15.5949 4.52337 15.8155L3.77535 18.7134C3.7736 19.0246 4.0678 19.3188 4.37904 19.3171L7.27695 18.569C7.49751 18.5678 7.69506 18.4897 7.83709 18.3477L8.09736 18.0874Z" stroke="none"/> </symbol> @@ -428,4 +434,9 @@ <path d="M28.0279 27.0279C28.5486 27.5486 28.6541 28.2873 28.2636 28.6778C27.8731 29.0683 27.1344 28.9628 26.6137 28.4421L11.5287 13.3572C11.008 12.8365 10.9025 12.0978 11.293 11.7072C11.6836 11.3167 12.4223 11.4222 12.943 11.9429L28.0279 27.0279Z" fill="#333333"/> </symbol> +<symbol id="leftArrow" width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M20 11L11 20L20 29" stroke="black" stroke-width="1.5" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/> +<line x1="12.5679" y1="20.0684" x2="29.8861" y2="20.0684" stroke="black" stroke-width="1.5" stroke-linecap="round"/> +</symbol> + </svg> -- GitLab From 78a3c10940657c0299ffbda4bccb4b17b81875ce Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bastienxs@gmail.com> Date: Tue, 10 May 2022 14:39:10 +0200 Subject: [PATCH 02/47] navigation between tabs --- src/app/profile/edit/edit.component.html | 34 ++++++++++++++++++------ src/app/profile/edit/edit.component.scss | 2 +- src/app/profile/edit/edit.component.ts | 13 +++++++++ 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index 9260006a0..e552b1f10 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -1,9 +1,11 @@ <div fxLayout="column" class="edit-profile"> <div class="header"> <div class="title"> - <svg class="leftArrow" aria-hidden="true"> - <use [attr.xlink:href]="'assets/ico/sprite.svg#leftArrow'"></use> - </svg> + <a routerLink="/profile"> + <svg class="leftArrow" aria-hidden="true"> + <use [attr.xlink:href]="'assets/ico/sprite.svg#leftArrow'"></use> + </svg> + </a> <h1>Modifier mon profil</h1> </div> <app-button @@ -14,11 +16,27 @@ ></app-button> </div> <div class="navigation"> - <span class="tab selected">Coordonnées</span> - <span class="tab">Email et mot de passe</span> - <span class="tab">Employeur et fonction</span> - <span class="tab">Description</span> - <span class="tab">Avatar</span> + <span + [ngClass]="{ tab: true, selected: currentTab === tabsEnum.coordinates }" + (click)="navigateTo(tabsEnum.coordinates)" + >Coordonnées</span + > + <span + [ngClass]="{ tab: true, selected: currentTab === tabsEnum.credentials }" + (click)="navigateTo(tabsEnum.credentials)" + >Email et mot de passe</span + > + <span [ngClass]="{ tab: true, selected: currentTab === tabsEnum.employer }" (click)="navigateTo(tabsEnum.employer)" + >Employeur et fonction</span + > + <span + [ngClass]="{ tab: true, selected: currentTab === tabsEnum.description }" + (click)="navigateTo(tabsEnum.description)" + >Description</span + > + <span [ngClass]="{ tab: true, selected: currentTab === tabsEnum.avatar }" (click)="navigateTo(tabsEnum.avatar)" + >Avatar</span + > </div> <div class="content"></div> </div> diff --git a/src/app/profile/edit/edit.component.scss b/src/app/profile/edit/edit.component.scss index 6f42db811..59baee71c 100644 --- a/src/app/profile/edit/edit.component.scss +++ b/src/app/profile/edit/edit.component.scss @@ -67,7 +67,7 @@ } &.selected { color: $grey-1; - border-bottom: 1px solid $grey-1; + border-bottom: 2px solid $grey-1; } } } diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index 2b1f8d747..d672725a6 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -3,6 +3,13 @@ import { User } from '../../models/user.model'; import { ButtonType } from '../../shared/components/button/buttonType.enum'; import { ProfileService } from '../services/profile.service'; +enum tabsEnum { + coordinates, + credentials, + employer, + description, + avatar, +} @Component({ selector: 'app-edit', templateUrl: './edit.component.html', @@ -11,6 +18,8 @@ import { ProfileService } from '../services/profile.service'; export class EditComponent implements OnInit { @Input() userProfile: User; public buttonTypeEnum = ButtonType; + public currentTab: tabsEnum = tabsEnum.coordinates; + public tabsEnum = tabsEnum; constructor(private profileService: ProfileService) {} @@ -19,4 +28,8 @@ export class EditComponent implements OnInit { this.userProfile = profile; }); } + + public navigateTo(tab: tabsEnum): void { + this.currentTab = tab; + } } -- GitLab From 56a410b408ca07c89161d2de790804efb4e5c4af Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bastienxs@gmail.com> Date: Tue, 10 May 2022 16:10:33 +0200 Subject: [PATCH 03/47] footer buttons --- src/app/profile/edit/edit.component.html | 92 +++++++++++++++++++++++- src/app/profile/edit/edit.component.scss | 11 +++ src/app/profile/edit/edit.component.ts | 4 ++ src/assets/form/sprite.svg | 5 ++ src/assets/ico/sprite.svg | 6 ++ 5 files changed, 116 insertions(+), 2 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index e552b1f10..c2223b759 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -1,4 +1,4 @@ -<div fxLayout="column" class="edit-profile"> +<div fxLayout="column" class="edit-profile" *ngIf="userProfile"> <div class="header"> <div class="title"> <a routerLink="/profile"> @@ -15,6 +15,7 @@ [iconBtn]="'removeCross'" ></app-button> </div> + <!-- Navigation --> <div class="navigation"> <span [ngClass]="{ tab: true, selected: currentTab === tabsEnum.coordinates }" @@ -38,5 +39,92 @@ >Avatar</span > </div> - <div class="content"></div> + <!-- Content of tabs --> + <div class="content"> + <!-- TODO: refacto this with account-info.component --> + <div *ngIf="currentTab === tabsEnum.coordinates"> + <div class="form-group" fxLayout="column"> + <label for="name">Prénom</label> + <div fxLayout="row" fxLayoutGap="13px"> + <input type="text" class="form-input" [(ngModel)]="userProfile.name" /> + <!-- <app-svg-icon + *ngIf="userProfile.get('name').valid" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'validate'" + ></app-svg-icon> + <app-svg-icon + *ngIf="userProfile.get('name').invalid && userProfile.get('name').value" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'notValidate'" + ></app-svg-icon> --> + </div> + </div> + <div class="form-group" fxLayout="column"> + <label for="surname">Nom</label> + <div fxLayout="row" fxLayoutGap="13px"> + <input type="text" class="form-input" [(ngModel)]="userProfile.surname" /> + <!-- <app-svg-icon + *ngIf="userProfile.get('surname').valid" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'validate'" + ></app-svg-icon> + <app-svg-icon + *ngIf="userProfile.get('surname').invalid && userProfile.get('surname').value" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'notValidate'" + ></app-svg-icon> --> + </div> + </div> + <div class="form-group" fxLayout="column"> + <label for="phone">Téléphone</label> + <div fxLayout="row" fxLayoutGap="13px"> + <input type="text" class="form-input phone" [(ngModel)]="userProfile.phone" /> + <!-- <app-svg-icon + *ngIf="userProfile.get('phone').valid" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'validate'" + ></app-svg-icon> + <app-svg-icon + *ngIf="userProfile.get('phone').invalid && userProfile.get('phone').value" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'notValidate'" + ></app-svg-icon> --> + </div> + </div> + </div> + <!-- + <div *ngIf="currentTab === tabsEnum.credentials">Credentials container</div> + + <div *ngIf="currentTab === tabsEnum.employer">Employer container</div> + + <div *ngIf="currentTab === tabsEnum.description">Description container</div> + + <div *ngIf="currentTab === tabsEnum.avatar">Avater container</div> --> + </div> + <!-- Footer --> + <div class="footer" fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center"> + <app-button + [text]="'Annuler'" + [disabled]="true" + (action)="cancel()" + [iconType]="'ico'" + [iconBtn]="'removeCrossBlack'" + ></app-button> + <app-button + [text]="'Valider'" + [disabled]="false" + (action)="confirm()" + [iconBtn]="'checkWhite'" + [iconType]="'form'" + [style]="buttonTypeEnum.Primary" + [extraClass]="svgCheck" + > + </app-button> + </div> </div> diff --git a/src/app/profile/edit/edit.component.scss b/src/app/profile/edit/edit.component.scss index 59baee71c..9ebdb6c17 100644 --- a/src/app/profile/edit/edit.component.scss +++ b/src/app/profile/edit/edit.component.scss @@ -26,6 +26,7 @@ } .header { justify-content: space-between; + padding-bottom: 18px; .title { align-items: center; @@ -71,4 +72,14 @@ } } } + + .content { + padding-top: 24px; + } + + .footer { + ::ng-deep div svg { + height: 22px; + } + } } diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index d672725a6..55ac0bc32 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -32,4 +32,8 @@ export class EditComponent implements OnInit { public navigateTo(tab: tabsEnum): void { this.currentTab = tab; } + + public cancel(): void {} + + public confirm(): void {} } diff --git a/src/assets/form/sprite.svg b/src/assets/form/sprite.svg index 05cb2231f..5215a2992 100644 --- a/src/assets/form/sprite.svg +++ b/src/assets/form/sprite.svg @@ -27,6 +27,11 @@ <path d="M7 12.8182L10.8889 16L17 9" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </symbol> +<symbol id="checkWhite" width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M18.9977 6.2526C19.4105 6.61952 19.4477 7.25159 19.0808 7.66437L10.9326 16.831C10.5785 17.2294 9.97428 17.28 9.55883 16.9462L4.37364 12.7795C3.94313 12.4336 3.87458 11.8041 4.22053 11.3736C4.56647 10.9431 5.19592 10.8746 5.62643 11.2205L10.0699 14.7912L17.586 6.33565C17.9529 5.92286 18.585 5.88568 18.9977 6.2526Z" fill="white"/> +</symbol> + + <symbol id="typeStructure_privateLucratif" viewBox="0 0 20 45" xmlns="http://www.w3.org/2000/svg"> <path d="M3.56201 15.4203L16.562 10V43H3.56201V15.4203Z" stroke="none"/> <rect x="0.562012" y="44" width="19" height="1" stroke="none"/> diff --git a/src/assets/ico/sprite.svg b/src/assets/ico/sprite.svg index 1c8cfdd98..184e27ab3 100644 --- a/src/assets/ico/sprite.svg +++ b/src/assets/ico/sprite.svg @@ -79,6 +79,12 @@ <path d="M15.5 7L6.5 16" stroke="#DA3635" stroke-width="1.5" stroke-linecap="round"/> </symbol> +<symbol id="removeCrossBlack" width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M6.5 6.5L15.5 15.5" stroke="#333333" stroke-width="1.5" stroke-linecap="round"/> +<path d="M15.5 6.5L6.5 15.5" stroke="#333333" stroke-width="1.5" stroke-linecap="round"/> +</symbol> + + <symbol id="edit" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" clip-rule="evenodd" d="M17.3745 2.62547C17.72 2.28003 18.3461 2.34613 18.7731 2.7731L20.3193 4.3193C20.7463 4.74627 20.8124 5.37243 20.4669 5.71787L18.6115 7.57331L15.5191 4.48091L17.3745 2.62547ZM17.993 8.1918L14.9006 5.0994L5.62344 14.3766L8.71584 17.469L17.993 8.1918ZM8.09736 18.0874L5.00496 14.995L4.74469 15.2553C4.60266 15.3973 4.52461 15.5949 4.52337 15.8155L3.77535 18.7134C3.7736 19.0246 4.0678 19.3188 4.37904 19.3171L7.27695 18.569C7.49751 18.5678 7.69506 18.4897 7.83709 18.3477L8.09736 18.0874Z" stroke="none"/> -- GitLab From 820646ba78bf5f5f3d79de0f70eb9380ba55b4b5 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bastienxs@gmail.com> Date: Thu, 12 May 2022 14:25:14 +0200 Subject: [PATCH 04/47] hr sparator --- src/app/profile/edit/edit.component.scss | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/app/profile/edit/edit.component.scss b/src/app/profile/edit/edit.component.scss index 9ebdb6c17..13e61ef47 100644 --- a/src/app/profile/edit/edit.component.scss +++ b/src/app/profile/edit/edit.component.scss @@ -11,6 +11,7 @@ width: 70%; min-height: 585px; padding: 40px; + padding-bottom: 0px; @media #{$tablet} { width: 70%; @@ -75,9 +76,16 @@ .content { padding-top: 24px; + flex: 1; } .footer { + padding: 16px; + // <hr/> like + width: 110%; + position: relative; + left: -5%; + border-top: 1px solid $grey-4; ::ng-deep div svg { height: 22px; } -- GitLab From ced5645ec69018858f7044e4e04de69294c3fa47 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bastienxs@gmail.com> Date: Thu, 12 May 2022 14:36:14 +0200 Subject: [PATCH 05/47] api call coordinates --- src/app/profile/edit/edit.component.html | 18 ++++++++-------- src/app/profile/edit/edit.component.ts | 20 ++++++++++++++++-- src/app/profile/services/profile.service.ts | 23 ++++++++++++++++++--- 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index c2223b759..be1bf9a31 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -47,36 +47,36 @@ <label for="name">Prénom</label> <div fxLayout="row" fxLayoutGap="13px"> <input type="text" class="form-input" [(ngModel)]="userProfile.name" /> - <!-- <app-svg-icon - *ngIf="userProfile.get('name').valid" + <app-svg-icon + *ngIf="userProfile.name !== ''" [iconClass]="'icon-26'" [type]="'form'" [icon]="'validate'" ></app-svg-icon> <app-svg-icon - *ngIf="userProfile.get('name').invalid && userProfile.get('name').value" + *ngIf="userProfile.name === ''" [iconClass]="'icon-26'" [type]="'form'" [icon]="'notValidate'" - ></app-svg-icon> --> + ></app-svg-icon> </div> </div> <div class="form-group" fxLayout="column"> <label for="surname">Nom</label> <div fxLayout="row" fxLayoutGap="13px"> <input type="text" class="form-input" [(ngModel)]="userProfile.surname" /> - <!-- <app-svg-icon - *ngIf="userProfile.get('surname').valid" + <app-svg-icon + *ngIf="userProfile.surname !== ''" [iconClass]="'icon-26'" [type]="'form'" [icon]="'validate'" ></app-svg-icon> <app-svg-icon - *ngIf="userProfile.get('surname').invalid && userProfile.get('surname').value" + *ngIf="userProfile.surname === ''" [iconClass]="'icon-26'" [type]="'form'" [icon]="'notValidate'" - ></app-svg-icon> --> + ></app-svg-icon> </div> </div> <div class="form-group" fxLayout="column"> @@ -99,7 +99,7 @@ </div> </div> <!-- - <div *ngIf="currentTab === tabsEnum.credentials">Credentials container</div> + <div *ngIf="currentTab === tabsEnum.credentials"><app-structure-options-modal></div> <div *ngIf="currentTab === tabsEnum.employer">Employer container</div> diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index 55ac0bc32..8ffeaf54e 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -1,5 +1,9 @@ +import { HttpErrorResponse } from '@angular/common/http'; import { Component, OnInit, Input } from '@angular/core'; +import { Observable } from 'rxjs'; +import { catchError } from 'rxjs/operators'; import { User } from '../../models/user.model'; +import { NotificationService } from '../../services/notification.service'; import { ButtonType } from '../../shared/components/button/buttonType.enum'; import { ProfileService } from '../services/profile.service'; @@ -21,7 +25,7 @@ export class EditComponent implements OnInit { public currentTab: tabsEnum = tabsEnum.coordinates; public tabsEnum = tabsEnum; - constructor(private profileService: ProfileService) {} + constructor(private profileService: ProfileService, private notificationService: NotificationService) {} ngOnInit(): void { this.profileService.getProfile().then((profile) => { @@ -35,5 +39,17 @@ export class EditComponent implements OnInit { public cancel(): void {} - public confirm(): void {} + public confirm(): any { + if (this.currentTab === tabsEnum.coordinates) { + return this.profileService + .updateCoordinates({ + name: this.userProfile.name, + surname: this.userProfile.surname, + phone: this.userProfile.phone, + }) + .subscribe(() => { + this.notificationService.showSuccess('L’action a bien été effectuée', ''); + }); + } + } } diff --git a/src/app/profile/services/profile.service.ts b/src/app/profile/services/profile.service.ts index ab75df01c..8865d8351 100644 --- a/src/app/profile/services/profile.service.ts +++ b/src/app/profile/services/profile.service.ts @@ -1,6 +1,6 @@ -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpErrorResponse } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { Observable } from 'rxjs'; +import { Observable, of } from 'rxjs'; import { User } from '../../models/user.model'; import decode from 'jwt-decode'; import { UserRole } from '../../shared/enum/userRole.enum'; @@ -8,6 +8,8 @@ import { AuthService } from '../../services/auth.service'; import { Structure } from '../../models/structure.model'; import { Employer } from '../../models/employer.model'; import { Job } from '../../models/job.model'; +import { catchError, map } from 'rxjs/operators'; +import { NotificationService } from '../../services/notification.service'; @Injectable({ providedIn: 'root', @@ -15,7 +17,11 @@ import { Job } from '../../models/job.model'; export class ProfileService { private readonly baseUrl = 'api/users'; private currentProfile: User = null; - constructor(private http: HttpClient, private authService: AuthService) {} + constructor( + private http: HttpClient, + private authService: AuthService, + private notificationService: NotificationService + ) {} public async getProfile(): Promise<User> { if (this.authService.isLoggedIn()) { @@ -108,4 +114,15 @@ export class ProfileService { public updateProfile(employerName: string, jobName: string): Observable<User> { return this.http.post<User>(`${this.baseUrl}/profile`, { employerName, jobName }); } + + public updateCoordinates(newCoordinates: { name: string; surname: string; phone: string }): Observable<User | Error> { + console.log('profile service updates coords'); + return this.http.post<User>(`${this.baseUrl}/update-coordinates`, newCoordinates).pipe( + map((user) => user), + catchError(() => { + this.notificationService.showError('Une erreur est survenue', ''); + return new Observable<Error>(); + }) + ); + } } -- GitLab From 131db0464d7a97bd53a81fd5f95e96b57c6c8dfe Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bastienxs@gmail.com> Date: Thu, 12 May 2022 15:26:41 +0200 Subject: [PATCH 06/47] check if form is valid --- src/app/profile/edit/edit.component.html | 26 +++++++-------------- src/app/profile/edit/edit.component.ts | 20 +++++++++++++--- src/app/profile/services/profile.service.ts | 4 ++-- 3 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index be1bf9a31..07fd65b5c 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -47,14 +47,9 @@ <label for="name">Prénom</label> <div fxLayout="row" fxLayoutGap="13px"> <input type="text" class="form-input" [(ngModel)]="userProfile.name" /> + <app-svg-icon *ngIf="nameValid()" [iconClass]="'icon-26'" [type]="'form'" [icon]="'validate'"></app-svg-icon> <app-svg-icon - *ngIf="userProfile.name !== ''" - [iconClass]="'icon-26'" - [type]="'form'" - [icon]="'validate'" - ></app-svg-icon> - <app-svg-icon - *ngIf="userProfile.name === ''" + *ngIf="!nameValid()" [iconClass]="'icon-26'" [type]="'form'" [icon]="'notValidate'" @@ -66,13 +61,13 @@ <div fxLayout="row" fxLayoutGap="13px"> <input type="text" class="form-input" [(ngModel)]="userProfile.surname" /> <app-svg-icon - *ngIf="userProfile.surname !== ''" + *ngIf="surnameValid()" [iconClass]="'icon-26'" [type]="'form'" [icon]="'validate'" ></app-svg-icon> <app-svg-icon - *ngIf="userProfile.surname === ''" + *ngIf="!surnameValid()" [iconClass]="'icon-26'" [type]="'form'" [icon]="'notValidate'" @@ -83,18 +78,13 @@ <label for="phone">Téléphone</label> <div fxLayout="row" fxLayoutGap="13px"> <input type="text" class="form-input phone" [(ngModel)]="userProfile.phone" /> - <!-- <app-svg-icon - *ngIf="userProfile.get('phone').valid" - [iconClass]="'icon-26'" - [type]="'form'" - [icon]="'validate'" - ></app-svg-icon> + <app-svg-icon *ngIf="phoneValid()" [iconClass]="'icon-26'" [type]="'form'" [icon]="'validate'"></app-svg-icon> <app-svg-icon - *ngIf="userProfile.get('phone').invalid && userProfile.get('phone').value" + *ngIf="!phoneValid()" [iconClass]="'icon-26'" [type]="'form'" [icon]="'notValidate'" - ></app-svg-icon> --> + ></app-svg-icon> </div> </div> </div> @@ -118,7 +108,7 @@ ></app-button> <app-button [text]="'Valider'" - [disabled]="false" + [disabled]="!isPageValid()" (action)="confirm()" [iconBtn]="'checkWhite'" [iconType]="'form'" diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index 8ffeaf54e..7053362c0 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -1,11 +1,9 @@ -import { HttpErrorResponse } from '@angular/common/http'; import { Component, OnInit, Input } from '@angular/core'; -import { Observable } from 'rxjs'; -import { catchError } from 'rxjs/operators'; import { User } from '../../models/user.model'; import { NotificationService } from '../../services/notification.service'; import { ButtonType } from '../../shared/components/button/buttonType.enum'; import { ProfileService } from '../services/profile.service'; +import { CustomRegExp } from '../../utils/CustomRegExp'; enum tabsEnum { coordinates, @@ -33,6 +31,16 @@ export class EditComponent implements OnInit { }); } + public phoneValid(): boolean { + return !!this.userProfile.phone.match(CustomRegExp.PHONE); + } + public nameValid(): boolean { + return this.userProfile.name !== ''; + } + public surnameValid(): boolean { + return this.userProfile.surname !== ''; + } + public navigateTo(tab: tabsEnum): void { this.currentTab = tab; } @@ -52,4 +60,10 @@ export class EditComponent implements OnInit { }); } } + + public isPageValid(): boolean { + if (this.currentTab === tabsEnum.coordinates) { + return this.phoneValid() && this.nameValid() && this.surnameValid(); + } + } } diff --git a/src/app/profile/services/profile.service.ts b/src/app/profile/services/profile.service.ts index 8865d8351..7d59f6d70 100644 --- a/src/app/profile/services/profile.service.ts +++ b/src/app/profile/services/profile.service.ts @@ -1,6 +1,6 @@ -import { HttpClient, HttpErrorResponse } from '@angular/common/http'; +import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { Observable, of } from 'rxjs'; +import { Observable } from 'rxjs'; import { User } from '../../models/user.model'; import decode from 'jwt-decode'; import { UserRole } from '../../shared/enum/userRole.enum'; -- GitLab From 40d2247de48db24b68ea42317b5eb2a9bd727bda Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bastienxs@gmail.com> Date: Thu, 12 May 2022 15:30:04 +0200 Subject: [PATCH 07/47] cancel button --- src/app/profile/edit/edit.component.html | 8 +------- src/app/profile/edit/edit.component.ts | 7 ++++++- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index 07fd65b5c..2a13dea0d 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -99,13 +99,7 @@ </div> <!-- Footer --> <div class="footer" fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center"> - <app-button - [text]="'Annuler'" - [disabled]="true" - (action)="cancel()" - [iconType]="'ico'" - [iconBtn]="'removeCrossBlack'" - ></app-button> + <app-button [text]="'Annuler'" (action)="cancel()" [iconType]="'ico'" [iconBtn]="'removeCrossBlack'"></app-button> <app-button [text]="'Valider'" [disabled]="!isPageValid()" diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index 7053362c0..bf29f5729 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -19,6 +19,7 @@ enum tabsEnum { }) export class EditComponent implements OnInit { @Input() userProfile: User; + public initialUserProfile: User; public buttonTypeEnum = ButtonType; public currentTab: tabsEnum = tabsEnum.coordinates; public tabsEnum = tabsEnum; @@ -28,6 +29,7 @@ export class EditComponent implements OnInit { ngOnInit(): void { this.profileService.getProfile().then((profile) => { this.userProfile = profile; + this.initialUserProfile = { ...profile }; }); } @@ -45,7 +47,10 @@ export class EditComponent implements OnInit { this.currentTab = tab; } - public cancel(): void {} + public cancel(): void { + console.log('cancel'); + this.userProfile = { ...this.initialUserProfile }; + } public confirm(): any { if (this.currentTab === tabsEnum.coordinates) { -- GitLab From 1aa1c97a56e0cc38ce9cc334073f37591736537e Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bastienxs@gmail.com> Date: Thu, 12 May 2022 15:30:15 +0200 Subject: [PATCH 08/47] remove console.log --- src/app/profile/edit/edit.component.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index bf29f5729..2275e43d7 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -48,7 +48,6 @@ export class EditComponent implements OnInit { } public cancel(): void { - console.log('cancel'); this.userProfile = { ...this.initialUserProfile }; } -- GitLab From 1151ed6d9180d5905b4826a553b04c3f8b01d517 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bastienxs@gmail.com> Date: Thu, 12 May 2022 15:59:34 +0200 Subject: [PATCH 09/47] update localstorage --- src/app/profile/edit/edit.component.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index 2275e43d7..a783099b4 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -4,6 +4,8 @@ import { NotificationService } from '../../services/notification.service'; import { ButtonType } from '../../shared/components/button/buttonType.enum'; import { ProfileService } from '../services/profile.service'; import { CustomRegExp } from '../../utils/CustomRegExp'; +import { BehaviorSubject } from 'rxjs'; +import { UserAuth } from '../../models/user-auth.model'; enum tabsEnum { coordinates, @@ -23,8 +25,11 @@ export class EditComponent implements OnInit { public buttonTypeEnum = ButtonType; public currentTab: tabsEnum = tabsEnum.coordinates; public tabsEnum = tabsEnum; + private userSubject: BehaviorSubject<UserAuth>; - constructor(private profileService: ProfileService, private notificationService: NotificationService) {} + constructor(private profileService: ProfileService, private notificationService: NotificationService) { + this.userSubject = new BehaviorSubject<UserAuth>(JSON.parse(localStorage.getItem('user'))); + } ngOnInit(): void { this.profileService.getProfile().then((profile) => { @@ -59,8 +64,17 @@ export class EditComponent implements OnInit { surname: this.userProfile.surname, phone: this.userProfile.phone, }) - .subscribe(() => { + .subscribe((user: User) => { this.notificationService.showSuccess('L’action a bien été effectuée', ''); + //Update localstorage + const updatedUser = { + ...this.userSubject.value, + name: user.name, + surname: user.surname, + phone: user.phone, + }; + localStorage.setItem('user', JSON.stringify(updatedUser)); + this.userSubject.next(updatedUser); }); } } -- GitLab From ec5a68b86764d8e660d99d03d852c92ab5acfc7f Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bastienxs@gmail.com> Date: Thu, 12 May 2022 16:07:03 +0200 Subject: [PATCH 10/47] page changed --- src/app/profile/edit/edit.component.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index a783099b4..99a79b792 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -20,11 +20,12 @@ enum tabsEnum { styleUrls: ['./edit.component.scss'], }) export class EditComponent implements OnInit { - @Input() userProfile: User; - public initialUserProfile: User; + public tabsEnum = tabsEnum; public buttonTypeEnum = ButtonType; public currentTab: tabsEnum = tabsEnum.coordinates; - public tabsEnum = tabsEnum; + + @Input() userProfile: User; + public initialUserProfile: User; private userSubject: BehaviorSubject<UserAuth>; constructor(private profileService: ProfileService, private notificationService: NotificationService) { @@ -48,6 +49,10 @@ export class EditComponent implements OnInit { return this.userProfile.surname !== ''; } + public pageChanged(): boolean { + return JSON.stringify(this.initialUserProfile) !== JSON.stringify(this.userProfile); + } + public navigateTo(tab: tabsEnum): void { this.currentTab = tab; } @@ -81,7 +86,7 @@ export class EditComponent implements OnInit { public isPageValid(): boolean { if (this.currentTab === tabsEnum.coordinates) { - return this.phoneValid() && this.nameValid() && this.surnameValid(); + return this.pageChanged() && this.phoneValid() && this.nameValid() && this.surnameValid(); } } } -- GitLab From 8db0f3d1862b1889c85a7b76469dc370edf3d1af Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bastienxs@gmail.com> Date: Thu, 12 May 2022 16:44:42 +0200 Subject: [PATCH 11/47] description page --- src/app/profile/edit/edit.component.html | 21 +++++++++++++----- src/app/profile/edit/edit.component.scss | 28 ++++++++++++++++++------ src/app/profile/edit/edit.component.ts | 2 +- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index 2a13dea0d..75dd1b4ae 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -88,14 +88,25 @@ </div> </div> </div> - <!-- - <div *ngIf="currentTab === tabsEnum.credentials"><app-structure-options-modal></div> - <div *ngIf="currentTab === tabsEnum.employer">Employer container</div> + <!-- <div *ngIf="currentTab === tabsEnum.credentials"><app-structure-options-modal></div> --> - <div *ngIf="currentTab === tabsEnum.description">Description container</div> + <!-- <div *ngIf="currentTab === tabsEnum.employer">Employer container</div> --> - <div *ngIf="currentTab === tabsEnum.avatar">Avater container</div> --> + <div *ngIf="currentTab === tabsEnum.description" class="descriptionTab"> + <p class="subTitle">Description</p> + <div class="textareaBlock" fxLayout="column"> + <textarea + rows="8" + placeholder="Exemple : formateur depuis 2 ans, je participe tous les ans à Super Demain." + maxlength="500" + formControlName="description" + ></textarea> + <p>{{ 0 }} / 500</p> + </div> + </div> + + <!-- <div *ngIf="currentTab === tabsEnum.avatar">Avater container</div> --> </div> <!-- Footer --> <div class="footer" fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center"> diff --git a/src/app/profile/edit/edit.component.scss b/src/app/profile/edit/edit.component.scss index 13e61ef47..ec91c42a0 100644 --- a/src/app/profile/edit/edit.component.scss +++ b/src/app/profile/edit/edit.component.scss @@ -7,7 +7,8 @@ .edit-profile { margin: 16px auto 0 auto; background: $white; - border-bottom: 1px solid $grey-4; + border: 1px solid $grey-6; + border-radius: 8px; width: 70%; min-height: 585px; padding: 40px; @@ -25,6 +26,7 @@ .title { display: flex; } + .header { justify-content: space-between; padding-bottom: 18px; @@ -53,12 +55,12 @@ } } } - .navigation { - justify-content: flex-start; - } .navigation { + justify-content: flex-start; border-bottom: 1px solid $grey-4; + overflow-x: scroll; + white-space: nowrap; .tab { color: $grey-3; @@ -77,14 +79,26 @@ .content { padding-top: 24px; flex: 1; + max-width: 600px; + + .descriptionTab { + .subTitle { + @include lato-regular-16; + text-align: left; + margin-top: 0; + } + p { + text-align: right; + } + } } .footer { padding: 16px; // <hr/> like - width: 110%; - position: relative; - left: -5%; + // width: 110%; + // position: relative; + // left: -5%; border-top: 1px solid $grey-4; ::ng-deep div svg { height: 22px; diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index 99a79b792..1110625cd 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -22,7 +22,7 @@ enum tabsEnum { export class EditComponent implements OnInit { public tabsEnum = tabsEnum; public buttonTypeEnum = ButtonType; - public currentTab: tabsEnum = tabsEnum.coordinates; + public currentTab: tabsEnum = tabsEnum.description; @Input() userProfile: User; public initialUserProfile: User; -- GitLab From 9c9f51993f849e1dda7a3dda852cfdbeb83d4c1e Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bastienxs@gmail.com> Date: Thu, 12 May 2022 17:29:35 +0200 Subject: [PATCH 12/47] display description --- src/app/models/user.model.ts | 1 + src/app/profile/edit/edit.component.html | 2 +- src/app/profile/edit/edit.component.ts | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/app/models/user.model.ts b/src/app/models/user.model.ts index 29b6f3b96..345afb553 100644 --- a/src/app/models/user.model.ts +++ b/src/app/models/user.model.ts @@ -20,4 +20,5 @@ export class User { constructor(obj?: any) { Object.assign(this, obj); } + description?: string; } diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index 75dd1b4ae..32f63e455 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -100,7 +100,7 @@ rows="8" placeholder="Exemple : formateur depuis 2 ans, je participe tous les ans à Super Demain." maxlength="500" - formControlName="description" + [(ngModel)]="userProfile.description" ></textarea> <p>{{ 0 }} / 500</p> </div> diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index 1110625cd..e95cd6397 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -48,6 +48,9 @@ export class EditComponent implements OnInit { public surnameValid(): boolean { return this.userProfile.surname !== ''; } + public descriptionValid(): boolean { + return this.userProfile.description.length <= 500; + } public pageChanged(): boolean { return JSON.stringify(this.initialUserProfile) !== JSON.stringify(this.userProfile); @@ -87,6 +90,8 @@ export class EditComponent implements OnInit { public isPageValid(): boolean { if (this.currentTab === tabsEnum.coordinates) { return this.pageChanged() && this.phoneValid() && this.nameValid() && this.surnameValid(); + } else if (this.currentTab === tabsEnum.description) { + return this.pageChanged() && this.descriptionValid(); } } } -- GitLab From 61560a71ea444a1c286ca3dba73659682841b68d Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bastienxs@gmail.com> Date: Fri, 13 May 2022 09:45:42 +0200 Subject: [PATCH 13/47] send description --- src/app/profile/edit/edit.component.html | 2 +- src/app/profile/edit/edit.component.ts | 21 +++++++++++++++------ src/app/profile/services/profile.service.ts | 12 ++++++++++++ 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index 32f63e455..64a4a6d88 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -102,7 +102,7 @@ maxlength="500" [(ngModel)]="userProfile.description" ></textarea> - <p>{{ 0 }} / 500</p> + <p>{{ userProfile.description.length }} / 500</p> </div> </div> diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index e95cd6397..7378eaa0a 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -64,6 +64,14 @@ export class EditComponent implements OnInit { this.userProfile = { ...this.initialUserProfile }; } + public isPageValid(): boolean { + if (this.currentTab === tabsEnum.coordinates) { + return this.pageChanged() && this.phoneValid() && this.nameValid() && this.surnameValid(); + } else if (this.currentTab === tabsEnum.description) { + return this.pageChanged() && this.descriptionValid(); + } + } + public confirm(): any { if (this.currentTab === tabsEnum.coordinates) { return this.profileService @@ -84,14 +92,15 @@ export class EditComponent implements OnInit { localStorage.setItem('user', JSON.stringify(updatedUser)); this.userSubject.next(updatedUser); }); + } else if (this.currentTab === tabsEnum.description) { + this.confirmDescription(); } } - public isPageValid(): boolean { - if (this.currentTab === tabsEnum.coordinates) { - return this.pageChanged() && this.phoneValid() && this.nameValid() && this.surnameValid(); - } else if (this.currentTab === tabsEnum.description) { - return this.pageChanged() && this.descriptionValid(); - } + public confirmDescription(): any { + return this.profileService.updateDescription(this.userProfile.description).subscribe((user: User) => { + console.log(user); + this.notificationService.showSuccess('L’action a bien été effectuée', ''); + }); } } diff --git a/src/app/profile/services/profile.service.ts b/src/app/profile/services/profile.service.ts index 7d59f6d70..3e550df23 100644 --- a/src/app/profile/services/profile.service.ts +++ b/src/app/profile/services/profile.service.ts @@ -125,4 +125,16 @@ export class ProfileService { }) ); } + + public updateDescription(description: string): Observable<User | Error> { + return this.http + .post<User>(`${this.baseUrl}/description`, { description }) + .pipe( + map((user) => user), + catchError(() => { + this.notificationService.showError('Une erreur est survenue', ''); + return new Observable<Error>(); + }) + ); + } } -- GitLab From 84b46ce283ca6f9bccc5a9ea878499738c738c4a Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bastienxs@gmail.com> Date: Fri, 13 May 2022 10:07:57 +0200 Subject: [PATCH 14/47] updateinitial profile --- src/app/profile/edit/edit.component.ts | 56 +++++++++++++++----------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index 7378eaa0a..7b4dcdd55 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -4,7 +4,7 @@ import { NotificationService } from '../../services/notification.service'; import { ButtonType } from '../../shared/components/button/buttonType.enum'; import { ProfileService } from '../services/profile.service'; import { CustomRegExp } from '../../utils/CustomRegExp'; -import { BehaviorSubject } from 'rxjs'; +import { BehaviorSubject, Observable } from 'rxjs'; import { UserAuth } from '../../models/user-auth.model'; enum tabsEnum { @@ -72,35 +72,45 @@ export class EditComponent implements OnInit { } } - public confirm(): any { + //To disable "Valider" button when the user sends new values + private updateInitialProfile() { + this.initialUserProfile = { ...this.userProfile }; + } + + public confirm(): void { if (this.currentTab === tabsEnum.coordinates) { - return this.profileService - .updateCoordinates({ - name: this.userProfile.name, - surname: this.userProfile.surname, - phone: this.userProfile.phone, - }) - .subscribe((user: User) => { - this.notificationService.showSuccess('L’action a bien été effectuée', ''); - //Update localstorage - const updatedUser = { - ...this.userSubject.value, - name: user.name, - surname: user.surname, - phone: user.phone, - }; - localStorage.setItem('user', JSON.stringify(updatedUser)); - this.userSubject.next(updatedUser); - }); + this.confirmCoordinates(); } else if (this.currentTab === tabsEnum.description) { this.confirmDescription(); } } - public confirmDescription(): any { - return this.profileService.updateDescription(this.userProfile.description).subscribe((user: User) => { - console.log(user); + public confirmCoordinates(): void { + this.profileService + .updateCoordinates({ + name: this.userProfile.name, + surname: this.userProfile.surname, + phone: this.userProfile.phone, + }) + .subscribe((user: User) => { + this.notificationService.showSuccess('L’action a bien été effectuée', ''); + //Update localstorage + const updatedUser = { + ...this.userSubject.value, + name: user.name, + surname: user.surname, + phone: user.phone, + }; + localStorage.setItem('user', JSON.stringify(updatedUser)); + this.userSubject.next(updatedUser); + this.updateInitialProfile(); + }); + } + + public confirmDescription(): void { + this.profileService.updateDescription(this.userProfile.description).subscribe(() => { this.notificationService.showSuccess('L’action a bien été effectuée', ''); + this.updateInitialProfile(); }); } } -- GitLab From 50b86b7a77dc74a35c3b4ee32e24ab265c98eb84 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bastienxs@gmail.com> Date: Fri, 13 May 2022 10:13:15 +0200 Subject: [PATCH 15/47] scrollbar mobile --- src/app/profile/edit/edit.component.scss | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/app/profile/edit/edit.component.scss b/src/app/profile/edit/edit.component.scss index ec91c42a0..dd06dd835 100644 --- a/src/app/profile/edit/edit.component.scss +++ b/src/app/profile/edit/edit.component.scss @@ -58,10 +58,15 @@ .navigation { justify-content: flex-start; - border-bottom: 1px solid $grey-4; overflow-x: scroll; white-space: nowrap; + border-bottom: 1px solid $grey-4; + + &::-webkit-scrollbar { + display: none; + } + .tab { color: $grey-3; margin-right: 40px; -- GitLab From 17517b890d4e2ad6d459e990e1a62dd56f977682 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bastienxs@gmail.com> Date: Fri, 13 May 2022 15:47:05 +0200 Subject: [PATCH 16/47] change email --- src/app/profile/edit/edit.component.ts | 39 ++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index 7b4dcdd55..fc830ecff 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -4,7 +4,7 @@ import { NotificationService } from '../../services/notification.service'; import { ButtonType } from '../../shared/components/button/buttonType.enum'; import { ProfileService } from '../services/profile.service'; import { CustomRegExp } from '../../utils/CustomRegExp'; -import { BehaviorSubject, Observable } from 'rxjs'; +import { BehaviorSubject } from 'rxjs'; import { UserAuth } from '../../models/user-auth.model'; enum tabsEnum { @@ -22,11 +22,15 @@ enum tabsEnum { export class EditComponent implements OnInit { public tabsEnum = tabsEnum; public buttonTypeEnum = ButtonType; - public currentTab: tabsEnum = tabsEnum.description; + public currentTab: tabsEnum = tabsEnum.credentials; @Input() userProfile: User; public initialUserProfile: User; private userSubject: BehaviorSubject<UserAuth>; + private emailModal = false; + private passwordModal = false; + public newEmail = ''; + public newEmailConfirm = ''; constructor(private profileService: ProfileService, private notificationService: NotificationService) { this.userSubject = new BehaviorSubject<UserAuth>(JSON.parse(localStorage.getItem('user'))); @@ -51,6 +55,9 @@ export class EditComponent implements OnInit { public descriptionValid(): boolean { return this.userProfile.description.length <= 500; } + public emailValid(email: string): boolean { + return !!email.match(CustomRegExp.EMAIL); + } public pageChanged(): boolean { return JSON.stringify(this.initialUserProfile) !== JSON.stringify(this.userProfile); @@ -64,11 +71,26 @@ export class EditComponent implements OnInit { this.userProfile = { ...this.initialUserProfile }; } + public showEmailModal(): void { + this.emailModal = true; + } + public showPasswordModal(): void { + this.passwordModal = true; + } + public closeModal(): void { + this.emailModal = false; + this.passwordModal = false; + } + public isPageValid(): boolean { if (this.currentTab === tabsEnum.coordinates) { return this.pageChanged() && this.phoneValid() && this.nameValid() && this.surnameValid(); } else if (this.currentTab === tabsEnum.description) { return this.pageChanged() && this.descriptionValid(); + } else if (this.currentTab === tabsEnum.credentials) { + if (this.emailModal) { + return this.newEmail === this.newEmailConfirm && this.newEmail !== ''; + } } } @@ -82,6 +104,10 @@ export class EditComponent implements OnInit { this.confirmCoordinates(); } else if (this.currentTab === tabsEnum.description) { this.confirmDescription(); + } else if (this.currentTab === tabsEnum.credentials) { + if (this.emailModal) { + this.confirmNewEmail(); + } } } @@ -113,4 +139,13 @@ export class EditComponent implements OnInit { this.updateInitialProfile(); }); } + + public confirmNewEmail(): void { + if (this.newEmail === this.newEmailConfirm) { + this.profileService.changeEmail(this.newEmail, this.userProfile.email).subscribe(() => { + this.closeModal(); + this.notificationService.showSuccess('Veuillez confirmer votre nouvelle adresse grâce au mail envoyé.', ''); + }); + } + } } -- GitLab From d87ece3e3b5b6ee874bf6633ed5a201baeb4e589 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bastienxs@gmail.com> Date: Fri, 13 May 2022 15:48:20 +0200 Subject: [PATCH 17/47] change email --- src/app/profile/edit/edit.component.html | 83 ++++++++++++++++++++++-- src/app/profile/edit/edit.component.scss | 62 ++++++++++++++++-- src/assets/ico/sprite.svg | 15 ++++- 3 files changed, 149 insertions(+), 11 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index 64a4a6d88..c3d12fa17 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -35,9 +35,9 @@ (click)="navigateTo(tabsEnum.description)" >Description</span > - <span [ngClass]="{ tab: true, selected: currentTab === tabsEnum.avatar }" (click)="navigateTo(tabsEnum.avatar)" + <!-- <span [ngClass]="{ tab: true, selected: currentTab === tabsEnum.avatar }" (click)="navigateTo(tabsEnum.avatar)" >Avatar</span - > + > --> </div> <!-- Content of tabs --> <div class="content"> @@ -89,7 +89,28 @@ </div> </div> - <!-- <div *ngIf="currentTab === tabsEnum.credentials"><app-structure-options-modal></div> --> + <div *ngIf="currentTab === tabsEnum.credentials" class="credentialsTab"> + <p class="subTitle">Email</p> + {{ userProfile.email }} + <div class="buttons"> + <app-button + [text]="'Changer mon email'" + (action)="showEmailModal()" + [iconType]="'ico'" + [iconBtn]="'emailOutline'" + [style]="buttonTypeEnum.Secondary" + > + </app-button> + <app-button + [text]="'Changer mon mot de passe'" + (action)="showPasswordModal()" + [iconType]="'ico'" + [iconBtn]="'passwordOutline'" + [style]="buttonTypeEnum.Secondary" + > + </app-button> + </div> + </div> <!-- <div *ngIf="currentTab === tabsEnum.employer">Employer container</div> --> @@ -108,18 +129,70 @@ <!-- <div *ngIf="currentTab === tabsEnum.avatar">Avater container</div> --> </div> + <!-- Footer --> - <div class="footer" fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center"> + <div class="footer" *ngIf="currentTab !== tabsEnum.credentials"> <app-button [text]="'Annuler'" (action)="cancel()" [iconType]="'ico'" [iconBtn]="'removeCrossBlack'"></app-button> <app-button [text]="'Valider'" [disabled]="!isPageValid()" (action)="confirm()" - [iconBtn]="'checkWhite'" [iconType]="'form'" + [iconBtn]="'checkWhite'" [style]="buttonTypeEnum.Primary" [extraClass]="svgCheck" > </app-button> </div> + + <!-- Modals --> + <div class="modalBackground" *ngIf="emailModal" (clickOutside)="closeModal()"> + <div class="modal"> + <div class="modalHeader"> + <div class="empty"></div> + <h3>Changer mon email</h3> + <svg class="close" aria-hidden="true" (click)="closeModal()"> + <use [attr.xlink:href]="'assets/form/sprite.svg#close'"></use> + </svg> + </div> + + <div class="modalContent"> + <div class="form-group" fxLayout="column"> + <label for="email">Nouvel mail</label> + <div fxLayout="row" fxLayoutGap="13px"> + <input id="email" type="text" class="form-input email-placeholder" [(ngModel)]="newEmail" /> + <app-svg-icon + *ngIf="emailValid(newEmail)" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'validate'" + ></app-svg-icon> + </div> + </div> + + <div class="form-group" fxLayout="column"> + <label for="emailConfirm">Confirmer le nouvel mail</label> + <div fxLayout="row" fxLayoutGap="13px"> + <input id="emailConfirm" type="text" class="form-input email-placeholder" [(ngModel)]="newEmailConfirm" /> + <app-svg-icon + *ngIf="emailValid(newEmailConfirm)" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'validate'" + ></app-svg-icon> + </div> + </div> + + <div class="buttons"> + <app-button [text]="'Annuler'" (action)="closeModal()"></app-button> + <app-button + [text]="'Valider'" + [style]="buttonTypeEnum.Primary" + [disabled]="!isPageValid()" + (action)="confirm()" + ></app-button> + </div> + </div> + </div> + </div> </div> diff --git a/src/app/profile/edit/edit.component.scss b/src/app/profile/edit/edit.component.scss index dd06dd835..4045d26e7 100644 --- a/src/app/profile/edit/edit.component.scss +++ b/src/app/profile/edit/edit.component.scss @@ -85,13 +85,22 @@ padding-top: 24px; flex: 1; max-width: 600px; + .subTitle { + @include lato-regular-16; + text-align: left; + margin-top: 0; + } - .descriptionTab { - .subTitle { - @include lato-regular-16; - text-align: left; - margin-top: 0; + .credentialsTab { + .buttons { + margin-top: 25px; + display: flex; + flex-wrap: wrap; + gap: 18px; } + } + + .descriptionTab { p { text-align: right; } @@ -100,6 +109,9 @@ .footer { padding: 16px; + display: flex; + gap: 26px; + justify-content: center; // <hr/> like // width: 110%; // position: relative; @@ -110,3 +122,43 @@ } } } + +.modalBackground { + //bck fade + .modal { + max-width: 390px; + background-color: $white; + .modalHeader { + display: flex; + justify-content: space-between; + align-items: center; + border: 1px solid $grey-6; + padding: 0 8px; + h3 { + @include lato-bold-18; + } + svg, + .empty { + height: 40px; + width: 40px; + } + svg { + cursor: pointer; + } + } + + .modalContent { + padding: 24px 40px; + } + p { + text-align: center; + margin: 10px 0; + } + .buttons { + display: flex; + justify-content: space-between; + align-items: center; + gap: 26px; + } + } +} diff --git a/src/assets/ico/sprite.svg b/src/assets/ico/sprite.svg index 184e27ab3..ad9aff1ba 100644 --- a/src/assets/ico/sprite.svg +++ b/src/assets/ico/sprite.svg @@ -117,15 +117,28 @@ <path fill-rule="evenodd" clip-rule="evenodd" d="M6 2C5.44772 2 5 2.44772 5 3V4H3C2.44771 4 2 4.44772 2 5V19C2 19.5523 2.44771 20 3 20H19C19.5523 20 20 19.5523 20 19V5C20 4.44772 19.5523 4 19 4H17V3C17 2.44772 16.5523 2 16 2C15.4477 2 15 2.44772 15 3V4H7V3C7 2.44772 6.55228 2 6 2ZM4 9V18H18V9H4Z" fill="#333333"/> </symbol> -<symbol id ="email" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> +<symbol id="email" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" clip-rule="evenodd" d="M3.5 4H19.5C20.3284 4 21 4.67157 21 5.5V16.0714C21 16.8998 20.3284 17.5714 19.5 17.5714H3.5C2.67157 17.5714 2 16.8998 2 16.0714V5.5C2 4.67157 2.67157 4 3.5 4ZM2.91716 6.02444C3.04832 5.78143 3.35163 5.69075 3.59464 5.8219L11.2431 9.94966C11.5474 10.1138 11.9148 10.1093 12.2149 9.93753L19.3945 5.82797C19.6341 5.69079 19.9396 5.77387 20.0768 6.01353C20.214 6.25318 20.1309 6.55867 19.8913 6.69585L12.7116 10.8054C12.1116 11.1489 11.3767 11.1581 10.7682 10.8297L3.11971 6.70192C2.8767 6.57077 2.78602 6.26745 2.91716 6.02444Z" stroke="none"/> </symbol> +<symbol id="emailOutline" width="23" height="23" viewBox="0 0 23 23" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect x="3.25" y="6.6875" width="16.5" height="11.6875" rx="3" stroke="#333333" stroke-width="1.5"/> +<path d="M5.5 9.5L10.1086 12.4261C11.1326 13.0762 12.4472 13.0458 13.44 12.3492L17.5 9.5" stroke="#333333" stroke-width="1.5" stroke-linecap="round"/> +</symbol> + + <symbol id="password" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" clip-rule="evenodd" d="M4.89603 10C4.40117 10 4.00001 10.4012 4.00001 10.896L4 18.2042C4 18.699 4.40116 19.1002 4.89602 19.1002H17.1043C17.5992 19.1002 18.0003 18.699 18.0003 18.2042L18.0003 10.896C18.0003 10.4012 17.5992 10 17.1043 10H4.89603ZM12.3442 13.4441C12.3442 13.9365 12.0794 14.367 11.6845 14.6011L12.3442 17.0002H9.65611L10.3158 14.6011C9.92088 14.367 9.65611 13.9365 9.65611 13.4441C9.65611 12.7018 10.2579 12.1 11.0001 12.1C11.7424 12.1 12.3442 12.7018 12.3442 13.4441Z" stroke="none"/> <path d="M13.8017 10.0002V7.90011C13.8017 6.35368 12.5481 5.10005 11.0017 5.10005C9.45524 5.10005 8.20161 6.35368 8.20161 7.90011V10.0002H6.10156V7.90011C6.10156 5.19386 8.29542 3 11.0017 3C13.7079 3 15.9018 5.19385 15.9018 7.90011V10.0002H13.8017Z" stroke="none"/> </symbol> +<symbol id="passwordOutline" width="22" height="23" viewBox="0 0 22 23" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M4.89602 9.5C4.40116 9.5 4 9.90116 4 10.396L4 19.104C4 19.5988 4.40116 20 4.89602 20H17.1043C17.5992 20 18.0003 19.5988 18.0003 19.104V10.396C18.0003 9.90116 17.5992 9.5 17.1043 9.5H4.89602Z" stroke="#333333" stroke-width="1.5"/> +<path d="M12.5382 13.844C12.5382 14.3364 12.2734 14.7669 11.8785 15.001L12.5382 17.4001H9.8501L10.5098 15.001C10.1149 14.7669 9.8501 14.3364 9.8501 13.844C9.8501 13.1017 10.4518 12.5 11.1941 12.5C11.9364 12.5 12.5382 13.1017 12.5382 13.844Z" fill="#333333"/> +<path d="M11 2.5C8.37665 2.5 6.25 4.62665 6.25 7.25V9.25H7.75V7.25C7.75 5.45507 9.20507 4 11 4C12.7949 4 14.25 5.45507 14.25 7.25V9.25H15.75V7.25C15.75 4.62665 13.6234 2.5 11 2.5Z" fill="#333333"/> +</symbol> + + <symbol id="pass" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" clip-rule="evenodd" d="M1.55556 5C1.24873 5 1 5.24873 1 5.55556V14.4444C1 14.7513 1.24873 15 1.55556 15H20.4444C20.7513 15 21 14.7513 21 14.4444V5.55556C21 5.24873 20.7513 5 20.4444 5H1.55556ZM4.77222 8.76388C4.78333 8.77499 4.79722 8.78055 4.81389 8.78055H4.91667C4.93333 8.78055 4.94722 8.77499 4.95833 8.76388C4.96944 8.75277 4.97683 8.73888 4.98055 8.72221L5.03055 8.3861H5.43889L5.38889 8.72221C5.38705 8.73888 5.39167 8.75277 5.40278 8.76388C5.41389 8.77499 5.42778 8.78055 5.44444 8.78055H5.54722C5.56389 8.78055 5.57778 8.77499 5.58889 8.76388C5.6 8.75277 5.60739 8.73888 5.61111 8.72221L5.66111 8.3861H5.99444C6.01294 8.3861 6.02778 8.38055 6.03889 8.36943C6.05183 8.35832 6.05833 8.34349 6.05833 8.32499V8.23055C6.05833 8.21205 6.05183 8.19721 6.03889 8.1861C6.02778 8.17499 6.01294 8.16943 5.99444 8.16943H5.69444L5.76667 7.68055H6.06667C6.08517 7.68055 6.1 7.67499 6.11111 7.66388C6.12406 7.65277 6.13056 7.63793 6.13056 7.61943V7.52499C6.13056 7.50649 6.12406 7.49166 6.11111 7.48055C6.1 7.46943 6.08517 7.46388 6.06667 7.46388H5.79722L5.84722 7.12777C5.84905 7.1111 5.84444 7.09721 5.83333 7.0861C5.82222 7.07499 5.80833 7.06943 5.79167 7.06943H5.68889C5.67222 7.06943 5.65833 7.07499 5.64722 7.0861C5.63794 7.09721 5.6315 7.1111 5.62778 7.12777L5.57778 7.46388H5.16667L5.21667 7.12777C5.2185 7.1111 5.21389 7.09721 5.20278 7.0861C5.19167 7.07499 5.17778 7.06943 5.16111 7.06943H5.05833C5.04167 7.06943 5.02778 7.07499 5.01667 7.0861C5.00739 7.09721 5.00094 7.1111 4.99722 7.12777L4.94722 7.46388H4.60555C4.58705 7.46388 4.57222 7.46943 4.56111 7.48055C4.55 7.49166 4.54444 7.50649 4.54444 7.52499V7.61943C4.54444 7.63793 4.55 7.65277 4.56111 7.66388C4.57222 7.67499 4.58705 7.68055 4.60555 7.68055H4.91389L4.84167 8.16943H4.53333C4.51483 8.16943 4.5 8.17499 4.48889 8.1861C4.47778 8.19721 4.47222 8.21205 4.47222 8.23055V8.32499C4.47222 8.34349 4.47778 8.35832 4.48889 8.36943C4.5 8.38055 4.51483 8.3861 4.53333 8.3861H4.80833L4.75833 8.72221C4.7565 8.73888 4.76111 8.75277 4.77222 8.76388ZM6.34239 8.87221C6.3535 8.88332 6.3665 8.88888 6.38128 8.88888H6.52294C6.5415 8.88888 6.55628 8.88427 6.56739 8.87499C6.58039 8.86388 6.58872 8.85277 6.59239 8.84166L6.74517 8.44721H7.65628L7.80905 8.84166C7.81278 8.85277 7.82017 8.86388 7.83128 8.87499C7.84239 8.88427 7.85817 8.88888 7.8785 8.88888H8.02017C8.035 8.88888 8.04794 8.88332 8.05906 8.87221C8.07017 8.8611 8.07572 8.84816 8.07572 8.83332L8.07017 8.80277L7.38406 7.00555C7.36928 6.96482 7.33961 6.94443 7.29517 6.94443H7.10628C7.06183 6.94443 7.03222 6.96482 7.01739 7.00555L6.3285 8.80277C6.32667 8.80832 6.32572 8.81849 6.32572 8.83332C6.32572 8.84816 6.33128 8.8611 6.34239 8.87221ZM8.38939 8.87221C8.40239 8.88332 8.41811 8.88888 8.43661 8.88888H8.58383C8.60239 8.88888 8.61811 8.88332 8.63106 8.87221C8.64406 8.85927 8.6505 8.84349 8.6505 8.82499V8.13055H9.14217C9.35328 8.13055 9.51811 8.08054 9.63661 7.98054C9.757 7.87871 9.81717 7.73149 9.81717 7.53888C9.81717 7.34627 9.757 7.19904 9.63661 7.09721C9.51628 6.99538 9.35144 6.94443 9.14217 6.94443H8.43661C8.41811 6.94443 8.40239 6.95093 8.38939 6.96388C8.37828 6.97499 8.37272 6.99071 8.37272 7.0111V8.82499C8.37272 8.84349 8.37828 8.85927 8.38939 8.87221ZM10.5966 8.87221C10.6096 8.88332 10.6253 8.88888 10.6438 8.88888H10.7883C10.8068 8.88888 10.8226 8.88332 10.8355 8.87221C10.8485 8.85927 10.8549 8.84349 10.8549 8.82499V7.19166H11.3855C11.4041 7.19166 11.4198 7.1861 11.4327 7.17499C11.4457 7.16205 11.4522 7.14627 11.4522 7.12777V7.0111C11.4522 6.99071 11.4457 6.97499 11.4327 6.96388C11.4216 6.95093 11.4059 6.94443 11.3855 6.94443H10.0466C10.0281 6.94443 10.0124 6.95093 9.99939 6.96388C9.98828 6.97682 9.98272 6.9926 9.98272 7.0111V7.12777C9.98272 7.14627 9.98828 7.16205 9.99939 7.17499C10.0124 7.1861 10.0281 7.19166 10.0466 7.19166H10.5799V8.82499C10.5799 8.84349 10.5855 8.85927 10.5966 8.87221ZM11.7803 8.87221C11.7932 8.88332 11.8089 8.88888 11.8275 8.88888H11.9747C11.9932 8.88888 12.0081 8.88332 12.0192 8.87221C12.0321 8.85927 12.0386 8.84349 12.0386 8.82499V7.00832C12.0386 6.98982 12.0321 6.97499 12.0192 6.96388C12.0081 6.95093 11.9932 6.94443 11.9747 6.94443H11.8275C11.8089 6.94443 11.7932 6.95093 11.7803 6.96388C11.7692 6.97499 11.7636 6.98982 11.7636 7.00832V8.82499C11.7636 8.84349 11.7692 8.85927 11.7803 8.87221ZM12.6564 8.71666C12.7861 8.84999 12.975 8.91666 13.2231 8.91666C13.3879 8.91666 13.5278 8.88793 13.6426 8.83055C13.7574 8.77127 13.8444 8.69443 13.9037 8.59999C13.9629 8.50554 13.9953 8.40371 14.0009 8.29443C14.0028 8.27777 13.9972 8.26482 13.9842 8.25555C13.9731 8.24443 13.9592 8.23888 13.9426 8.23888H13.7898C13.7713 8.23888 13.7564 8.24349 13.7453 8.25277C13.7342 8.26204 13.7259 8.27871 13.7203 8.30277C13.6907 8.44166 13.6342 8.53982 13.5509 8.59721C13.4694 8.65277 13.3602 8.68055 13.2231 8.68055C12.9046 8.68055 12.7398 8.50371 12.7287 8.14999C12.7268 8.09627 12.7259 8.0176 12.7259 7.91388C12.7259 7.81016 12.7268 7.73332 12.7287 7.68332C12.7398 7.3296 12.9046 7.15277 13.2231 7.15277C13.3602 7.15277 13.4694 7.18149 13.5509 7.23888C13.6324 7.29443 13.6889 7.39166 13.7203 7.53055C13.7296 7.57316 13.7528 7.59443 13.7898 7.59443H13.9426C13.9574 7.59443 13.9703 7.58982 13.9814 7.58055C13.9944 7.56943 14.0009 7.55649 14.0009 7.54166V7.5361C13.9953 7.42871 13.9629 7.32777 13.9037 7.23332C13.8444 7.13888 13.7574 7.06293 13.6426 7.00555C13.5278 6.94627 13.3879 6.91666 13.2231 6.91666C12.9768 6.91666 12.7889 6.98427 12.6592 7.11943C12.5296 7.25277 12.4602 7.4361 12.4509 7.66943C12.4491 7.72127 12.4481 7.8046 12.4481 7.91943C12.4481 8.03238 12.4491 8.11388 12.4509 8.16388C12.4602 8.39904 12.5287 8.58332 12.6564 8.71666ZM4.25 11C4.11193 11 4 11.1119 4 11.25C4 11.3881 4.11193 11.5 4.25 11.5H12.7259C12.864 11.5 12.9759 11.3881 12.9759 11.25C12.9759 11.1119 12.864 11 12.7259 11H4.25ZM16.6144 11.9418H16.0068C16.0133 12.1185 16.0594 12.249 16.1451 12.3333C16.2321 12.4177 16.3749 12.4598 16.5735 12.4598C16.702 12.4598 16.8163 12.4398 16.9163 12.3996L17 12.9398C16.8273 12.9799 16.6566 13 16.4878 13C16.1373 13 15.8575 12.9063 15.6485 12.7189C15.4408 12.5315 15.3317 12.2724 15.3213 11.9418H15V11.6205H15.3213V11.3755H15V11.0562H15.3272C15.3518 10.7242 15.4726 10.4652 15.6894 10.2791C15.9062 10.093 16.1925 10 16.5482 10C16.6858 10 16.8364 10.0207 17 10.0622L16.9163 10.6044C16.815 10.5629 16.7066 10.5422 16.591 10.5422C16.4119 10.5422 16.2749 10.5843 16.1801 10.6687C16.0854 10.7517 16.0295 10.8809 16.0127 11.0562H16.6144V11.3755H16.0068V11.6205H16.6144V11.9418ZM9.12828 7.89721C9.2635 7.89721 9.36533 7.86666 9.43383 7.80554C9.50422 7.74443 9.53939 7.65554 9.53939 7.53888C9.53939 7.42221 9.50517 7.33332 9.43661 7.27221C9.36811 7.20927 9.26533 7.17777 9.12828 7.17777H8.64772V7.89721H9.12828ZM7.20072 7.22221L7.57572 8.20832H6.82572L7.20072 7.22221ZM5.54444 7.68055L5.47222 8.16943H5.06389L5.13611 7.68055H5.54444ZM19.75 6C19.6119 6 19.5 6.11193 19.5 6.25V6.75C19.5 6.88807 19.6119 7 19.75 7C19.8881 7 20 6.88807 20 6.75V6.25C20 6.11193 19.8881 6 19.75 6ZM19.5 8.25C19.5 8.11193 19.6119 8 19.75 8C19.8881 8 20 8.11193 20 8.25V10.75C20 10.8881 19.8881 11 19.75 11C19.6119 11 19.5 10.8881 19.5 10.75V8.25ZM19.75 12C19.6119 12 19.5 12.1119 19.5 12.25V13.75C19.5 13.8881 19.6119 14 19.75 14C19.8881 14 20 13.8881 20 13.75V12.25C20 12.1119 19.8881 12 19.75 12Z" fill="#333333"/> </symbol> -- GitLab From c426b7d06ad8a680b02b88957d89d0bed7be3424 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Mon, 16 May 2022 10:07:16 +0200 Subject: [PATCH 18/47] invalid email icon --- src/app/profile/edit/edit.component.html | 67 +++++++++++++++++++++++- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index c3d12fa17..5a49c7895 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -145,8 +145,8 @@ </app-button> </div> - <!-- Modals --> - <div class="modalBackground" *ngIf="emailModal" (clickOutside)="closeModal()"> + <!-- Modal: Email change --> + <div class="modalBackground" *ngIf="emailModal"> <div class="modal"> <div class="modalHeader"> <div class="empty"></div> @@ -156,6 +156,69 @@ </svg> </div> + <div class="modalContent"> + <div class="form-group" fxLayout="column"> + <label for="email">Nouvel mail</label> + <div fxLayout="row" fxLayoutGap="13px"> + <input id="email" type="text" class="form-input email-placeholder" [(ngModel)]="newEmail" /> + <app-svg-icon + *ngIf="emailValid(newEmail)" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'validate'" + ></app-svg-icon> + <app-svg-icon + *ngIf="!emailValid(newEmail)" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'notValidate'" + ></app-svg-icon> + </div> + </div> + + <div class="form-group" fxLayout="column"> + <label for="emailConfirm">Confirmer le nouvel mail</label> + <div fxLayout="row" fxLayoutGap="13px"> + <input id="emailConfirm" type="text" class="form-input email-placeholder" [(ngModel)]="newEmailConfirm" /> + <app-svg-icon + *ngIf="emailValid(newEmailConfirm)" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'validate'" + ></app-svg-icon> + <app-svg-icon + *ngIf="!emailValid(newEmailConfirm)" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'notValidate'" + ></app-svg-icon> + </div> + </div> + + <div class="buttons"> + <app-button [text]="'Annuler'" (action)="closeModal()"></app-button> + <app-button + [text]="'Valider'" + [style]="buttonTypeEnum.Primary" + [disabled]="!isPageValid()" + (action)="confirm()" + ></app-button> + </div> + </div> + </div> + </div> + + <!-- Modal: Password change --> + <div class="modalBackground" *ngIf="passwordModal" (clickOutside)="closeModal()"> + <div class="modal"> + <div class="modalHeader"> + <div class="empty"></div> + <h3>Changer mon mot de passe</h3> + <svg class="close" aria-hidden="true" (click)="closeModal()"> + <use [attr.xlink:href]="'assets/form/sprite.svg#close'"></use> + </svg> + </div> + <div class="modalContent"> <div class="form-group" fxLayout="column"> <label for="email">Nouvel mail</label> -- GitLab From 67d1fbe439a01c85048f672e2845d4d0a149f258 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Mon, 16 May 2022 13:55:23 +0200 Subject: [PATCH 19/47] change password --- src/app/profile/edit/edit.component.html | 103 +++++++++++++++++--- src/app/profile/edit/edit.component.scss | 5 + src/app/profile/edit/edit.component.ts | 58 +++++++++-- src/app/profile/services/profile.service.ts | 2 +- 4 files changed, 142 insertions(+), 26 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index 5a49c7895..7fa9cd0a1 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -158,7 +158,7 @@ <div class="modalContent"> <div class="form-group" fxLayout="column"> - <label for="email">Nouvel mail</label> + <label for="email">Nouvel email</label> <div fxLayout="row" fxLayoutGap="13px"> <input id="email" type="text" class="form-input email-placeholder" [(ngModel)]="newEmail" /> <app-svg-icon @@ -177,7 +177,7 @@ </div> <div class="form-group" fxLayout="column"> - <label for="emailConfirm">Confirmer le nouvel mail</label> + <label for="emailConfirm">Confirmer le nouvel email</label> <div fxLayout="row" fxLayoutGap="13px"> <input id="emailConfirm" type="text" class="form-input email-placeholder" [(ngModel)]="newEmailConfirm" /> <app-svg-icon @@ -221,31 +221,102 @@ <div class="modalContent"> <div class="form-group" fxLayout="column"> - <label for="email">Nouvel mail</label> - <div fxLayout="row" fxLayoutGap="13px"> - <input id="email" type="text" class="form-input email-placeholder" [(ngModel)]="newEmail" /> + <div class="form-group"> + <label for="oldPassword">Ancien mot de passe</label> + <div fxLayout="row" fxLayoutAlign="none center" fxLayoutGap="13px"> + <input + [type]="isShowPassword ? 'text' : 'password'" + [(ngModel)]="oldPassword" + id="oldPassword" + class="form-input password" + autocomplete="on" + /> + <app-svg-icon + [iconClass]="'icon-26 grey hover'" + [type]="'form'" + [icon]="'eyePassword'" + (click)="showPassword()" + ></app-svg-icon> + <app-svg-icon + *ngIf="passwordValid(oldPassword)" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'validate'" + ></app-svg-icon> + <app-svg-icon + *ngIf="!passwordValid(oldPassword)" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'notValidate'" + ></app-svg-icon> + </div> + </div> + + <div class="form-group"> + <label for="newPassword">Nouveau mot de passe</label> + <div fxLayout="row" fxLayoutAlign="none center" fxLayoutGap="13px"> + <input + [type]="isShowPassword ? 'text' : 'password'" + [(ngModel)]="newPassword" + id="newPassword" + class="form-input password" + autocomplete="on" + /> + <app-svg-icon + [iconClass]="'icon-26 grey hover'" + [type]="'form'" + [icon]="'eyePassword'" + (click)="showPassword()" + ></app-svg-icon> + <app-svg-icon + *ngIf="passwordValid(newPassword)" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'validate'" + ></app-svg-icon> + <app-svg-icon + *ngIf="!passwordValid(newPassword)" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'notValidate'" + ></app-svg-icon> + </div> + </div> + </div> + <p class="warn form-group"> + Le mot de passe doit contenir au minimum : 8 caractères dont un caractère spécial, un caractère en majuscule + et un chiffre. + </p> + <div class="form-group"> + <label for="newPasswordConfirm">Confirmer le nouveau mot de passe</label> + <div fxLayout="row" fxLayoutAlign="none center" fxLayoutGap="13px"> + <input + [type]="isShowPassword ? 'text' : 'password'" + [(ngModel)]="newPasswordConfirm" + id="newPasswordConfirm" + class="form-input password" + autocomplete="on" + /> <app-svg-icon - *ngIf="emailValid(newEmail)" + [iconClass]="'icon-26 grey hover'" + [type]="'form'" + [icon]="'eyePassword'" + (click)="showPassword()" + ></app-svg-icon> + <app-svg-icon + *ngIf="passwordValid(newPasswordConfirm)" [iconClass]="'icon-26'" [type]="'form'" [icon]="'validate'" ></app-svg-icon> - </div> - </div> - - <div class="form-group" fxLayout="column"> - <label for="emailConfirm">Confirmer le nouvel mail</label> - <div fxLayout="row" fxLayoutGap="13px"> - <input id="emailConfirm" type="text" class="form-input email-placeholder" [(ngModel)]="newEmailConfirm" /> <app-svg-icon - *ngIf="emailValid(newEmailConfirm)" + *ngIf="!passwordValid(newPasswordConfirm)" [iconClass]="'icon-26'" [type]="'form'" - [icon]="'validate'" + [icon]="'notValidate'" ></app-svg-icon> </div> </div> - <div class="buttons"> <app-button [text]="'Annuler'" (action)="closeModal()"></app-button> <app-button diff --git a/src/app/profile/edit/edit.component.scss b/src/app/profile/edit/edit.component.scss index 4045d26e7..d5ca0f4da 100644 --- a/src/app/profile/edit/edit.component.scss +++ b/src/app/profile/edit/edit.component.scss @@ -153,6 +153,11 @@ p { text-align: center; margin: 10px 0; + &.warn { + @include lato-regular-14; + color: $orange-warning; + text-align: left; + } } .buttons { display: flex; diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index fc830ecff..7b66d87b9 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -6,6 +6,8 @@ import { ProfileService } from '../services/profile.service'; import { CustomRegExp } from '../../utils/CustomRegExp'; import { BehaviorSubject } from 'rxjs'; import { UserAuth } from '../../models/user-auth.model'; +import { catchError, map } from 'rxjs/operators'; +import { HttpErrorResponse } from '@angular/common/http'; enum tabsEnum { coordinates, @@ -29,8 +31,12 @@ export class EditComponent implements OnInit { private userSubject: BehaviorSubject<UserAuth>; private emailModal = false; private passwordModal = false; - public newEmail = ''; - public newEmailConfirm = ''; + private newEmail = ''; + private newEmailConfirm = ''; + private oldPassword = ''; + private newPassword = ''; + private newPasswordConfirm = ''; + private isShowPassword = false; constructor(private profileService: ProfileService, private notificationService: NotificationService) { this.userSubject = new BehaviorSubject<UserAuth>(JSON.parse(localStorage.getItem('user'))); @@ -58,6 +64,14 @@ export class EditComponent implements OnInit { public emailValid(email: string): boolean { return !!email.match(CustomRegExp.EMAIL); } + public passwordValid(password: string): boolean { + return !!( + password.match(CustomRegExp.SPECHAR) && + password.match(CustomRegExp.DIGIT) && + password.match(CustomRegExp.UPPERCASE) && + password.match(CustomRegExp.LOWERCASE) + ); + } public pageChanged(): boolean { return JSON.stringify(this.initialUserProfile) !== JSON.stringify(this.userProfile); @@ -77,6 +91,9 @@ export class EditComponent implements OnInit { public showPasswordModal(): void { this.passwordModal = true; } + public showPassword(): void { + this.isShowPassword = !this.isShowPassword; + } public closeModal(): void { this.emailModal = false; this.passwordModal = false; @@ -89,16 +106,13 @@ export class EditComponent implements OnInit { return this.pageChanged() && this.descriptionValid(); } else if (this.currentTab === tabsEnum.credentials) { if (this.emailModal) { - return this.newEmail === this.newEmailConfirm && this.newEmail !== ''; + return this.emailValid(this.newEmail) && this.newEmail === this.newEmailConfirm; + } else if (this.passwordModal) { + return this.passwordValid(this.newPassword) && this.newPassword == this.newPasswordConfirm; } } } - //To disable "Valider" button when the user sends new values - private updateInitialProfile() { - this.initialUserProfile = { ...this.userProfile }; - } - public confirm(): void { if (this.currentTab === tabsEnum.coordinates) { this.confirmCoordinates(); @@ -107,6 +121,8 @@ export class EditComponent implements OnInit { } else if (this.currentTab === tabsEnum.credentials) { if (this.emailModal) { this.confirmNewEmail(); + } else if (this.passwordModal) { + this.confirmNewPassword(); } } } @@ -140,12 +156,36 @@ export class EditComponent implements OnInit { }); } + // Updates initialProfile so the button "Valider" is disabled after the user sends new values + private updateInitialProfile() { + this.initialUserProfile = { ...this.userProfile }; + } + public confirmNewEmail(): void { - if (this.newEmail === this.newEmailConfirm) { + if (this.emailValid(this.newEmail) && this.newEmail === this.newEmailConfirm) { this.profileService.changeEmail(this.newEmail, this.userProfile.email).subscribe(() => { this.closeModal(); this.notificationService.showSuccess('Veuillez confirmer votre nouvelle adresse grâce au mail envoyé.', ''); }); } } + + public confirmNewPassword(): void { + if (this.passwordValid(this.newPassword) && this.newPassword == this.newPasswordConfirm) { + this.profileService + .changePassword(this.newPassword, this.oldPassword) + .pipe( + catchError(async (response: HttpErrorResponse) => { + if (response.error.statusCode == 401) { + this.notificationService.showError('Une erreur est survenue', ''); + throw new Error('Une erreur est survenue'); + } + }) + ) + .subscribe(() => { + this.notificationService.showSuccess('Votre mot de passe a bien été modifié.', ''); + this.closeModal(); + }); + } + } } diff --git a/src/app/profile/services/profile.service.ts b/src/app/profile/services/profile.service.ts index 3e550df23..8d555406b 100644 --- a/src/app/profile/services/profile.service.ts +++ b/src/app/profile/services/profile.service.ts @@ -75,7 +75,7 @@ export class ProfileService { return false; } - public changePassword(newPassword: string, oldPassword: string): Observable<User> { + public changePassword(newPassword: string, oldPassword: string): Observable<any> { return this.http.post<any>(`${this.baseUrl}/change-password`, { newPassword, oldPassword }); } public verifyAndUpdateEmail(token: string): Observable<User> { -- GitLab From f21db9b9c5f24bc6999ad828e54c4a8ed2cf0397 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Mon, 16 May 2022 16:35:12 +0200 Subject: [PATCH 20/47] job front --- src/app/profile/edit/edit.component.html | 22 +++++++++++++++++- src/app/profile/edit/edit.component.ts | 29 +++++++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index 7fa9cd0a1..3a487b35c 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -112,7 +112,27 @@ </div> </div> - <!-- <div *ngIf="currentTab === tabsEnum.employer">Employer container</div> --> + <div *ngIf="currentTab === tabsEnum.employer"> + <p class="subTitle">Employeur</p> + <p class="subTitle">Fonction</p> + <div fxLayout="column" fxLayoutGap="32px"> + <div class="btn-grid"> + <span *ngFor="let job of jobs"> + <app-button + [ngClass]="{ selectedChoice: true }" + [extraClass]="isSelectedJob(job) ? 'selected' : ''" + [style]="buttonTypeEnum.CheckButton" + [text]="job.name" + (action)="selectedResult(job)" + ></app-button> + </span> + </div> + <div *ngIf="isUnexistingJob()" fxLayout="column" fxLayoutAlign="space-between" class="form-group search"> + <label for="employer">Quelle fonction occupez-vous ?</label> + <input type="text" (input)="newJob($event.target.value)" class="form-input" autocomplete="off" /> + </div> + </div> + </div> <div *ngIf="currentTab === tabsEnum.description" class="descriptionTab"> <p class="subTitle">Description</p> diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index 7b66d87b9..d0c9e628e 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -8,6 +8,7 @@ import { BehaviorSubject } from 'rxjs'; import { UserAuth } from '../../models/user-auth.model'; import { catchError, map } from 'rxjs/operators'; import { HttpErrorResponse } from '@angular/common/http'; +import { Job } from '../../models/job.model'; enum tabsEnum { coordinates, @@ -24,7 +25,7 @@ enum tabsEnum { export class EditComponent implements OnInit { public tabsEnum = tabsEnum; public buttonTypeEnum = ButtonType; - public currentTab: tabsEnum = tabsEnum.credentials; + public currentTab: tabsEnum = tabsEnum.employer; @Input() userProfile: User; public initialUserProfile: User; @@ -37,6 +38,8 @@ export class EditComponent implements OnInit { private newPassword = ''; private newPasswordConfirm = ''; private isShowPassword = false; + private jobs: Job[]; + private selectedJob: Job; constructor(private profileService: ProfileService, private notificationService: NotificationService) { this.userSubject = new BehaviorSubject<UserAuth>(JSON.parse(localStorage.getItem('user'))); @@ -47,6 +50,10 @@ export class EditComponent implements OnInit { this.userProfile = profile; this.initialUserProfile = { ...profile }; }); + + this.profileService.getJobs().subscribe((jobs) => { + this.jobs = [...jobs, new Job({ name: 'Autre' })]; + }); } public phoneValid(): boolean { @@ -188,4 +195,24 @@ export class EditComponent implements OnInit { }); } } + + //Jobs + public selectedResult(job: Job): void { + this.selectedJob = job; + if (!this.isUnexistingJob()) { + } else { + } + } + + public isSelectedJob(job: Job): boolean { + if (this.selectedJob && this.selectedJob.name === job.name) return true; + return false; + } + + public isUnexistingJob(): boolean { + if (this.selectedJob && this.selectedJob.name === 'Autre') return true; + return false; + } + + public newJob(event: any): any {} } -- GitLab From c4bef2b9ee4dc5b8476e4ad844c45bf83685368e Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Mon, 16 May 2022 16:45:30 +0200 Subject: [PATCH 21/47] front structure select --- src/app/profile/edit/edit.component.html | 25 ++++++++++++++++++++++-- src/app/profile/edit/edit.component.scss | 5 +++++ src/app/profile/edit/edit.component.ts | 25 +++++++++++++++++++++++- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index 3a487b35c..03516aba1 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -113,7 +113,28 @@ </div> <div *ngIf="currentTab === tabsEnum.employer"> - <p class="subTitle">Employeur</p> + <div class="search-structure"> + <div fxLayout="column" fxLayoutAlign="space-between" class="form-group search"> + <label for="employer">Employeur</label> + <div fxLayout="row" fxLayoutGap="13px"> + <input + id="search-employer" + type="text" + (input)="onSearchChange($event.target.value)" + class="form-input" + autocomplete="off" + #searchEmployer + /> + </div> + </div> + <div class="structureResults"> + <div class="autocomplete-items" *ngIf="!isAlreadySearching"> + <p *ngFor="let employer of employers" (click)="selectedResult(employer)" class="autocomplete-item"> + {{ employer.name }} + </p> + </div> + </div> + </div> <p class="subTitle">Fonction</p> <div fxLayout="column" fxLayoutGap="32px"> <div class="btn-grid"> @@ -123,7 +144,7 @@ [extraClass]="isSelectedJob(job) ? 'selected' : ''" [style]="buttonTypeEnum.CheckButton" [text]="job.name" - (action)="selectedResult(job)" + (action)="selectJob(job)" ></app-button> </span> </div> diff --git a/src/app/profile/edit/edit.component.scss b/src/app/profile/edit/edit.component.scss index d5ca0f4da..7f4035589 100644 --- a/src/app/profile/edit/edit.component.scss +++ b/src/app/profile/edit/edit.component.scss @@ -105,6 +105,11 @@ text-align: right; } } + + .structureResults { + position: absolute; + width: 600px; + } } .footer { diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index d0c9e628e..ee5a34e1a 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -9,6 +9,7 @@ import { UserAuth } from '../../models/user-auth.model'; import { catchError, map } from 'rxjs/operators'; import { HttpErrorResponse } from '@angular/common/http'; import { Job } from '../../models/job.model'; +import { Employer } from '../../models/employer.model'; enum tabsEnum { coordinates, @@ -40,6 +41,8 @@ export class EditComponent implements OnInit { private isShowPassword = false; private jobs: Job[]; private selectedJob: Job; + public employers: Employer[]; + public isAlreadySearching = false; constructor(private profileService: ProfileService, private notificationService: NotificationService) { this.userSubject = new BehaviorSubject<UserAuth>(JSON.parse(localStorage.getItem('user'))); @@ -197,7 +200,7 @@ export class EditComponent implements OnInit { } //Jobs - public selectedResult(job: Job): void { + public selectJob(job: Job): void { this.selectedJob = job; if (!this.isUnexistingJob()) { } else { @@ -215,4 +218,24 @@ export class EditComponent implements OnInit { } public newJob(event: any): any {} + + //Structures + public onSearchChange(searchString: string): void { + if (searchString.length <= 2) this.getEmployers(); + this.getEmployers(searchString); + } + + public selectedResult(employer: Employer): void { + this.employers = []; + } + + private getEmployers(searchString: string = '') { + if (!this.isAlreadySearching) { + this.isAlreadySearching = true; + this.profileService.getEmployers(searchString).subscribe((employers) => { + this.employers = employers; + this.isAlreadySearching = false; + }); + } + } } -- GitLab From 9e305da58634534308d46a4a998287aaf36d9839 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Mon, 16 May 2022 16:56:51 +0200 Subject: [PATCH 22/47] load current job --- src/app/profile/edit/edit.component.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index ee5a34e1a..58f1500e7 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -52,6 +52,7 @@ export class EditComponent implements OnInit { this.profileService.getProfile().then((profile) => { this.userProfile = profile; this.initialUserProfile = { ...profile }; + this.selectedJob = { ...profile.job }; }); this.profileService.getJobs().subscribe((jobs) => { @@ -134,6 +135,8 @@ export class EditComponent implements OnInit { } else if (this.passwordModal) { this.confirmNewPassword(); } + } else if (this.currentTab === tabsEnum.employer) { + this.confirmEmployer(); } } @@ -159,6 +162,10 @@ export class EditComponent implements OnInit { }); } + public confirmEmployer(): void { + // TODO call profile route + } + public confirmDescription(): void { this.profileService.updateDescription(this.userProfile.description).subscribe(() => { this.notificationService.showSuccess('L’action a bien été effectuée', ''); -- GitLab From 6b0df3a9220959070b525f5c0e9841654710a1d5 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Mon, 16 May 2022 17:39:53 +0200 Subject: [PATCH 23/47] send new employer and job --- .../profile-employer-selection.component.ts | 1 + src/app/profile/edit/edit.component.ts | 28 +++++++++++++------ 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/app/form/form-view/profile-form/profile-employer-selection/profile-employer-selection.component.ts b/src/app/form/form-view/profile-form/profile-employer-selection/profile-employer-selection.component.ts index f7a0a4c52..ac3511ce4 100644 --- a/src/app/form/form-view/profile-form/profile-employer-selection/profile-employer-selection.component.ts +++ b/src/app/form/form-view/profile-form/profile-employer-selection/profile-employer-selection.component.ts @@ -30,6 +30,7 @@ export class ProfileEmployerSelectionComponent { } public selectedResult(employer: Employer): void { + console.log(this.searchEmployer); this.searchEmployer.nativeElement.value = employer.name; this.profileForm.get('employer').patchValue({ name: employer.name, diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index 58f1500e7..913f91ba9 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, Input } from '@angular/core'; +import { Component, OnInit, Input, ViewChild, ElementRef } from '@angular/core'; import { User } from '../../models/user.model'; import { NotificationService } from '../../services/notification.service'; import { ButtonType } from '../../shared/components/button/buttonType.enum'; @@ -39,10 +39,12 @@ export class EditComponent implements OnInit { private newPassword = ''; private newPasswordConfirm = ''; private isShowPassword = false; - private jobs: Job[]; + public jobs: Job[]; private selectedJob: Job; public employers: Employer[]; - public isAlreadySearching = false; + private selectedEmployer: Employer; + private isAlreadySearching = false; + @ViewChild('searchEmployer') searchEmployer: ElementRef; constructor(private profileService: ProfileService, private notificationService: NotificationService) { this.userSubject = new BehaviorSubject<UserAuth>(JSON.parse(localStorage.getItem('user'))); @@ -53,6 +55,7 @@ export class EditComponent implements OnInit { this.userProfile = profile; this.initialUserProfile = { ...profile }; this.selectedJob = { ...profile.job }; + this.selectedEmployer = { ...profile.employer }; }); this.profileService.getJobs().subscribe((jobs) => { @@ -113,22 +116,23 @@ export class EditComponent implements OnInit { public isPageValid(): boolean { if (this.currentTab === tabsEnum.coordinates) { return this.pageChanged() && this.phoneValid() && this.nameValid() && this.surnameValid(); - } else if (this.currentTab === tabsEnum.description) { - return this.pageChanged() && this.descriptionValid(); } else if (this.currentTab === tabsEnum.credentials) { if (this.emailModal) { return this.emailValid(this.newEmail) && this.newEmail === this.newEmailConfirm; } else if (this.passwordModal) { return this.passwordValid(this.newPassword) && this.newPassword == this.newPasswordConfirm; } + } else if (this.currentTab === tabsEnum.employer) { + return true; + } else if (this.currentTab === tabsEnum.description) { + return this.pageChanged() && this.descriptionValid(); } } + //TODO update order public confirm(): void { if (this.currentTab === tabsEnum.coordinates) { this.confirmCoordinates(); - } else if (this.currentTab === tabsEnum.description) { - this.confirmDescription(); } else if (this.currentTab === tabsEnum.credentials) { if (this.emailModal) { this.confirmNewEmail(); @@ -137,6 +141,8 @@ export class EditComponent implements OnInit { } } else if (this.currentTab === tabsEnum.employer) { this.confirmEmployer(); + } else if (this.currentTab === tabsEnum.description) { + this.confirmDescription(); } } @@ -163,7 +169,10 @@ export class EditComponent implements OnInit { } public confirmEmployer(): void { - // TODO call profile route + this.profileService.updateProfile(this.selectedEmployer.name, this.selectedJob.name).subscribe(() => { + this.notificationService.showSuccess('L’action a bien été effectuée', ''); + this.updateInitialProfile(); + }); } public confirmDescription(): void { @@ -233,6 +242,9 @@ export class EditComponent implements OnInit { } public selectedResult(employer: Employer): void { + console.log(this.searchEmployer); + this.searchEmployer.nativeElement.value = employer.name; + this.selectedEmployer = employer; this.employers = []; } -- GitLab From dc1fd831567aed9d5cc910ce10aae3f6791ebe90 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Tue, 17 May 2022 10:04:06 +0200 Subject: [PATCH 24/47] fix: description tab --- src/app/profile/edit/edit.component.html | 2 +- src/app/profile/edit/edit.component.scss | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index 03516aba1..ce9f4f5e2 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -164,7 +164,7 @@ maxlength="500" [(ngModel)]="userProfile.description" ></textarea> - <p>{{ userProfile.description.length }} / 500</p> + <p class="descriptionLength">{{ userProfile.description?.length }} / 500</p> </div> </div> diff --git a/src/app/profile/edit/edit.component.scss b/src/app/profile/edit/edit.component.scss index 7f4035589..68efd1934 100644 --- a/src/app/profile/edit/edit.component.scss +++ b/src/app/profile/edit/edit.component.scss @@ -85,7 +85,7 @@ padding-top: 24px; flex: 1; max-width: 600px; - .subTitle { + p.subTitle { @include lato-regular-16; text-align: left; margin-top: 0; @@ -101,7 +101,7 @@ } .descriptionTab { - p { + p.descriptionLength { text-align: right; } } -- GitLab From 5b2bfd1bd55276cd6485a63ccdfbb70bb97e8597 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Tue, 17 May 2022 10:23:38 +0200 Subject: [PATCH 25/47] update password modal --- src/app/profile/edit/edit.component.html | 14 +++++++------- src/app/profile/edit/edit.component.scss | 6 ++++-- src/app/profile/edit/edit.component.ts | 18 ++++++++++++++---- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index ce9f4f5e2..a078d4cc9 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -266,7 +266,7 @@ <label for="oldPassword">Ancien mot de passe</label> <div fxLayout="row" fxLayoutAlign="none center" fxLayoutGap="13px"> <input - [type]="isShowPassword ? 'text' : 'password'" + [type]="isShowPassword.oldPassword ? 'text' : 'password'" [(ngModel)]="oldPassword" id="oldPassword" class="form-input password" @@ -276,7 +276,7 @@ [iconClass]="'icon-26 grey hover'" [type]="'form'" [icon]="'eyePassword'" - (click)="showPassword()" + (click)="showPassword('oldPassword')" ></app-svg-icon> <app-svg-icon *ngIf="passwordValid(oldPassword)" @@ -297,7 +297,7 @@ <label for="newPassword">Nouveau mot de passe</label> <div fxLayout="row" fxLayoutAlign="none center" fxLayoutGap="13px"> <input - [type]="isShowPassword ? 'text' : 'password'" + [type]="isShowPassword.newPassword ? 'text' : 'password'" [(ngModel)]="newPassword" id="newPassword" class="form-input password" @@ -307,7 +307,7 @@ [iconClass]="'icon-26 grey hover'" [type]="'form'" [icon]="'eyePassword'" - (click)="showPassword()" + (click)="showPassword('newPassword')" ></app-svg-icon> <app-svg-icon *ngIf="passwordValid(newPassword)" @@ -324,7 +324,7 @@ </div> </div> </div> - <p class="warn form-group"> + <p class="form-group passwordInfo" [class.warn]="!passwordValid(newPassword)"> Le mot de passe doit contenir au minimum : 8 caractères dont un caractère spécial, un caractère en majuscule et un chiffre. </p> @@ -332,7 +332,7 @@ <label for="newPasswordConfirm">Confirmer le nouveau mot de passe</label> <div fxLayout="row" fxLayoutAlign="none center" fxLayoutGap="13px"> <input - [type]="isShowPassword ? 'text' : 'password'" + [type]="isShowPassword.newPasswordConfirm ? 'text' : 'password'" [(ngModel)]="newPasswordConfirm" id="newPasswordConfirm" class="form-input password" @@ -342,7 +342,7 @@ [iconClass]="'icon-26 grey hover'" [type]="'form'" [icon]="'eyePassword'" - (click)="showPassword()" + (click)="showPassword('newPasswordConfirm')" ></app-svg-icon> <app-svg-icon *ngIf="passwordValid(newPasswordConfirm)" diff --git a/src/app/profile/edit/edit.component.scss b/src/app/profile/edit/edit.component.scss index 68efd1934..0ec08cc2f 100644 --- a/src/app/profile/edit/edit.component.scss +++ b/src/app/profile/edit/edit.component.scss @@ -158,10 +158,12 @@ p { text-align: center; margin: 10px 0; - &.warn { + &.passwordInfo { @include lato-regular-14; - color: $orange-warning; text-align: left; + &.warn { + color: $orange-warning; + } } } .buttons { diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index 913f91ba9..a7fdd3be2 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -18,6 +18,12 @@ enum tabsEnum { description, avatar, } + +enum showPasswordEnum { + oldPassword, + newPassword, + newPasswordConfirm, +} @Component({ selector: 'app-edit', templateUrl: './edit.component.html', @@ -26,7 +32,7 @@ enum tabsEnum { export class EditComponent implements OnInit { public tabsEnum = tabsEnum; public buttonTypeEnum = ButtonType; - public currentTab: tabsEnum = tabsEnum.employer; + public currentTab: tabsEnum = tabsEnum.credentials; @Input() userProfile: User; public initialUserProfile: User; @@ -38,7 +44,11 @@ export class EditComponent implements OnInit { private oldPassword = ''; private newPassword = ''; private newPasswordConfirm = ''; - private isShowPassword = false; + private isShowPassword = { + oldPassword: false, + newPassword: false, + newPasswordConfirm: false, + }; public jobs: Job[]; private selectedJob: Job; public employers: Employer[]; @@ -105,8 +115,8 @@ export class EditComponent implements OnInit { public showPasswordModal(): void { this.passwordModal = true; } - public showPassword(): void { - this.isShowPassword = !this.isShowPassword; + public showPassword(key: showPasswordEnum): void { + this.isShowPassword[key] = !this.isShowPassword[key]; } public closeModal(): void { this.emailModal = false; -- GitLab From 883b6361a01be81cc1b8de8f844afd4cda4f65f5 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Tue, 17 May 2022 11:45:53 +0200 Subject: [PATCH 26/47] create new job --- src/app/profile/edit/edit.component.html | 2 +- src/app/profile/edit/edit.component.ts | 54 +++++++++++++++--------- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index a078d4cc9..85ab2b405 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -150,7 +150,7 @@ </div> <div *ngIf="isUnexistingJob()" fxLayout="column" fxLayoutAlign="space-between" class="form-group search"> <label for="employer">Quelle fonction occupez-vous ?</label> - <input type="text" (input)="newJob($event.target.value)" class="form-input" autocomplete="off" /> + <input type="text" (input)="createNewJob($event.target.value)" class="form-input" autocomplete="off" /> </div> </div> </div> diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index a7fdd3be2..e99b2d7de 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -1,10 +1,10 @@ -import { Component, OnInit, Input, ViewChild, ElementRef } from '@angular/core'; +import { Component, OnInit, Input, ViewChild, ElementRef, AfterViewInit } from '@angular/core'; import { User } from '../../models/user.model'; import { NotificationService } from '../../services/notification.service'; import { ButtonType } from '../../shared/components/button/buttonType.enum'; import { ProfileService } from '../services/profile.service'; import { CustomRegExp } from '../../utils/CustomRegExp'; -import { BehaviorSubject } from 'rxjs'; +import { BehaviorSubject, forkJoin, of } from 'rxjs'; import { UserAuth } from '../../models/user-auth.model'; import { catchError, map } from 'rxjs/operators'; import { HttpErrorResponse } from '@angular/common/http'; @@ -29,10 +29,10 @@ enum showPasswordEnum { templateUrl: './edit.component.html', styleUrls: ['./edit.component.scss'], }) -export class EditComponent implements OnInit { +export class EditComponent implements OnInit, AfterViewInit { public tabsEnum = tabsEnum; public buttonTypeEnum = ButtonType; - public currentTab: tabsEnum = tabsEnum.credentials; + public currentTab: tabsEnum = tabsEnum.employer; @Input() userProfile: User; public initialUserProfile: User; @@ -50,6 +50,7 @@ export class EditComponent implements OnInit { newPasswordConfirm: false, }; public jobs: Job[]; + private newJob: Job; private selectedJob: Job; public employers: Employer[]; private selectedEmployer: Employer; @@ -73,6 +74,10 @@ export class EditComponent implements OnInit { }); } + ngAfterViewInit(): void { + this.selectedResult(this.userProfile.employer); + } + public phoneValid(): boolean { return !!this.userProfile.phone.match(CustomRegExp.PHONE); } @@ -164,7 +169,7 @@ export class EditComponent implements OnInit { phone: this.userProfile.phone, }) .subscribe((user: User) => { - this.notificationService.showSuccess('L’action a bien été effectuée', ''); + this.notificationService.showSuccess('L’action a bien été effectuée.', ''); //Update localstorage const updatedUser = { ...this.userSubject.value, @@ -179,15 +184,29 @@ export class EditComponent implements OnInit { } public confirmEmployer(): void { - this.profileService.updateProfile(this.selectedEmployer.name, this.selectedJob.name).subscribe(() => { - this.notificationService.showSuccess('L’action a bien été effectuée', ''); - this.updateInitialProfile(); + if (this.newJob) this.selectedJob = this.newJob; + forkJoin({ + employer: this.profileService.createEmployer(this.selectedEmployer).pipe( + map((res) => res), + catchError((e) => of(this.selectedEmployer)) + ), + job: this.profileService.createJob(this.selectedJob).pipe( + map((res) => res), + catchError((e) => of(this.selectJob)) + ), + profile: this.profileService.updateProfile(this.selectedEmployer.name, this.selectedJob.name).pipe( + map((res) => res), + catchError((e) => of()) + ), + }).subscribe(() => { + this.notificationService.showSuccess('L’action a bien été effectuée.', ''); + // this.updateInitialProfile(); }); } public confirmDescription(): void { this.profileService.updateDescription(this.userProfile.description).subscribe(() => { - this.notificationService.showSuccess('L’action a bien été effectuée', ''); + this.notificationService.showSuccess('L’action a bien été effectuée.', ''); this.updateInitialProfile(); }); } @@ -228,22 +247,16 @@ export class EditComponent implements OnInit { //Jobs public selectJob(job: Job): void { this.selectedJob = job; - if (!this.isUnexistingJob()) { - } else { - } } - public isSelectedJob(job: Job): boolean { - if (this.selectedJob && this.selectedJob.name === job.name) return true; - return false; + return this.selectedJob && this.selectedJob.name === job.name; } - public isUnexistingJob(): boolean { - if (this.selectedJob && this.selectedJob.name === 'Autre') return true; - return false; + return this.selectedJob && this.selectedJob.name === 'Autre'; + } + public createNewJob(value: string): void { + this.newJob = new Job({ name: value, validated: false, hasPersonalOffer: true }); } - - public newJob(event: any): any {} //Structures public onSearchChange(searchString: string): void { @@ -252,7 +265,6 @@ export class EditComponent implements OnInit { } public selectedResult(employer: Employer): void { - console.log(this.searchEmployer); this.searchEmployer.nativeElement.value = employer.name; this.selectedEmployer = employer; this.employers = []; -- GitLab From 7c38be5468979387dddb9a4a33236ca8a2b9ac45 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Tue, 17 May 2022 16:04:08 +0200 Subject: [PATCH 27/47] get current employer --- .../profile-employer-selection.component.ts | 1 - src/app/profile/edit/edit.component.html | 2 +- src/app/profile/edit/edit.component.ts | 31 ++++++++++--------- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/app/form/form-view/profile-form/profile-employer-selection/profile-employer-selection.component.ts b/src/app/form/form-view/profile-form/profile-employer-selection/profile-employer-selection.component.ts index ac3511ce4..f7a0a4c52 100644 --- a/src/app/form/form-view/profile-form/profile-employer-selection/profile-employer-selection.component.ts +++ b/src/app/form/form-view/profile-form/profile-employer-selection/profile-employer-selection.component.ts @@ -30,7 +30,6 @@ export class ProfileEmployerSelectionComponent { } public selectedResult(employer: Employer): void { - console.log(this.searchEmployer); this.searchEmployer.nativeElement.value = employer.name; this.profileForm.get('employer').patchValue({ name: employer.name, diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index 85ab2b405..799420abc 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -129,7 +129,7 @@ </div> <div class="structureResults"> <div class="autocomplete-items" *ngIf="!isAlreadySearching"> - <p *ngFor="let employer of employers" (click)="selectedResult(employer)" class="autocomplete-item"> + <p *ngFor="let employer of employers" (click)="selectEmployer(employer)" class="autocomplete-item"> {{ employer.name }} </p> </div> diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index e99b2d7de..c772e25aa 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, Input, ViewChild, ElementRef, AfterViewInit } from '@angular/core'; +import { Component, OnInit, Input, ViewChild, ElementRef, AfterViewInit, ChangeDetectorRef } from '@angular/core'; import { User } from '../../models/user.model'; import { NotificationService } from '../../services/notification.service'; import { ButtonType } from '../../shared/components/button/buttonType.enum'; @@ -29,7 +29,7 @@ enum showPasswordEnum { templateUrl: './edit.component.html', styleUrls: ['./edit.component.scss'], }) -export class EditComponent implements OnInit, AfterViewInit { +export class EditComponent implements OnInit { public tabsEnum = tabsEnum; public buttonTypeEnum = ButtonType; public currentTab: tabsEnum = tabsEnum.employer; @@ -57,7 +57,11 @@ export class EditComponent implements OnInit, AfterViewInit { private isAlreadySearching = false; @ViewChild('searchEmployer') searchEmployer: ElementRef; - constructor(private profileService: ProfileService, private notificationService: NotificationService) { + constructor( + private profileService: ProfileService, + private notificationService: NotificationService, + private cdr: ChangeDetectorRef + ) { this.userSubject = new BehaviorSubject<UserAuth>(JSON.parse(localStorage.getItem('user'))); } @@ -74,10 +78,6 @@ export class EditComponent implements OnInit, AfterViewInit { }); } - ngAfterViewInit(): void { - this.selectedResult(this.userProfile.employer); - } - public phoneValid(): boolean { return !!this.userProfile.phone.match(CustomRegExp.PHONE); } @@ -108,6 +108,10 @@ export class EditComponent implements OnInit, AfterViewInit { public navigateTo(tab: tabsEnum): void { this.currentTab = tab; + if (tab === tabsEnum.employer) { + this.cdr.detectChanges(); + this.selectEmployer(this.userProfile.employer); + } } public cancel(): void { @@ -138,13 +142,12 @@ export class EditComponent implements OnInit, AfterViewInit { return this.passwordValid(this.newPassword) && this.newPassword == this.newPasswordConfirm; } } else if (this.currentTab === tabsEnum.employer) { - return true; + return !!(this.selectedEmployer && this.selectedJob); } else if (this.currentTab === tabsEnum.description) { return this.pageChanged() && this.descriptionValid(); } } - //TODO update order public confirm(): void { if (this.currentTab === tabsEnum.coordinates) { this.confirmCoordinates(); @@ -188,19 +191,18 @@ export class EditComponent implements OnInit, AfterViewInit { forkJoin({ employer: this.profileService.createEmployer(this.selectedEmployer).pipe( map((res) => res), - catchError((e) => of(this.selectedEmployer)) + catchError(() => of(this.selectedEmployer)) ), job: this.profileService.createJob(this.selectedJob).pipe( map((res) => res), - catchError((e) => of(this.selectJob)) + catchError(() => of(this.selectJob)) ), profile: this.profileService.updateProfile(this.selectedEmployer.name, this.selectedJob.name).pipe( map((res) => res), - catchError((e) => of()) + catchError(() => of()) ), }).subscribe(() => { this.notificationService.showSuccess('L’action a bien été effectuée.', ''); - // this.updateInitialProfile(); }); } @@ -262,9 +264,10 @@ export class EditComponent implements OnInit, AfterViewInit { public onSearchChange(searchString: string): void { if (searchString.length <= 2) this.getEmployers(); this.getEmployers(searchString); + this.selectedEmployer = new Employer({ name: searchString, validated: false }); } - public selectedResult(employer: Employer): void { + public selectEmployer(employer: Employer): void { this.searchEmployer.nativeElement.value = employer.name; this.selectedEmployer = employer; this.employers = []; -- GitLab From 82e9ad70dc3cc0094c25fc889d4128aa3d79b968 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Tue, 17 May 2022 16:23:03 +0200 Subject: [PATCH 28/47] mobile buttons --- src/app/profile/edit/edit.component.html | 10 +++++ .../components/button/button.component.html | 44 ++++++++++++++++++- .../components/button/button.component.scss | 23 ++++++++++ .../components/button/buttonType.enum.ts | 3 ++ .../svg-icon/svg-icon.component.scss | 8 ++++ src/assets/ico/sprite.svg | 14 +++++- src/styles.scss | 6 +++ 7 files changed, 105 insertions(+), 3 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index 799420abc..897d4901e 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -9,11 +9,21 @@ <h1>Modifier mon profil</h1> </div> <app-button + class="hide-on-mobile" [style]="buttonTypeEnum.SecondaryDelete" [text]="'Supprimer mon compte'" + [type]="'button'" [iconType]="'ico'" [iconBtn]="'removeCross'" ></app-button> + <app-button + class="hide-on-desktop" + [style]="buttonTypeEnum.SecondaryOnlyIcon" + [type]="'button'" + [iconBtn]="'edit'" + [iconType]="'ico'" + [iconBtn]="'deleteAccount'" + ></app-button> </div> <!-- Navigation --> <div class="navigation"> diff --git a/src/app/shared/components/button/button.component.html b/src/app/shared/components/button/button.component.html index a30bc4d6f..08b616e3f 100644 --- a/src/app/shared/components/button/button.component.html +++ b/src/app/shared/components/button/button.component.html @@ -94,8 +94,16 @@ </button> </ng-container> -<ng-container *ngIf="style === buttonTypeEnum.Secondary"> - <button class="btn-regular secondary" type="{{ type }}" (click)="doAction()" [disabled]="disabled"> +<ng-container *ngIf="style === buttonTypeEnum.Secondary || style === buttonTypeEnum.SecondaryWide"> + <button + [ngClass]="{ + 'btn-regular secondary': true, + wide: style === buttonTypeEnum.SecondaryWide + }" + type="{{ type }}" + (click)="doAction()" + [disabled]="disabled" + > <div *ngIf="!iconBtn" [ngClass]="extraClass" class="text">{{ text }}</div> <div *ngIf="iconBtn && iconPos === 'left'" @@ -118,6 +126,38 @@ </button> </ng-container> +<ng-container *ngIf="style === buttonTypeEnum.SecondaryUltraWide"> + <button class="btn-regular secondary ultrawide" type="{{ type }}" (click)="doAction()" [disabled]="disabled"> + <div *ngIf="!iconBtn" [ngClass]="extraClass" class="text">{{ text }}</div> + <div + *ngIf="iconBtn && iconPos === 'left'" + fxLayout="row center" + class="text withIcon left" + fxLayoutAlign="center center" + > + <app-svg-icon [type]="iconType" [icon]="iconBtn" [iconColor]="'currentColor'"></app-svg-icon> + <span>{{ text }}</span> + </div> + <div + *ngIf="iconBtn && iconPos === 'right'" + fxLayout="row center" + class="text withIcon right" + fxLayoutAlign="center center" + > + <span>{{ text }}</span> + <app-svg-icon [type]="iconType" [icon]="iconBtn" [iconColor]="'currentColor'"></app-svg-icon> + </div> + </button> +</ng-container> + +<ng-container *ngIf="style === buttonTypeEnum.SecondaryOnlyIcon"> + <button class="btn-regular secondary" type="{{ type }}" (click)="doAction()" [disabled]="disabled"> + <div *ngIf="iconBtn" fxLayout="row center" class="text withIcon center" fxLayoutAlign="space-around center"> + <app-svg-icon [type]="iconType" [icon]="iconBtn" [iconColor]="'currentColor'"></app-svg-icon> + </div> + </button> +</ng-container> + <ng-container *ngIf="style === buttonTypeEnum.SecondaryDelete"> <button class="btn-regular secondary-delete" type="{{ type }}" (click)="doAction()" [disabled]="disabled"> <div *ngIf="!iconBtn" [ngClass]="extraClass" class="text">{{ text }}</div> diff --git a/src/app/shared/components/button/button.component.scss b/src/app/shared/components/button/button.component.scss index 0fddccb02..467beb448 100644 --- a/src/app/shared/components/button/button.component.scss +++ b/src/app/shared/components/button/button.component.scss @@ -1,5 +1,6 @@ @import '../../../../assets/scss/typography'; @import '../../../../assets/scss/color'; +@import '../../../../assets/scss/breakpoint'; @import '../../../../assets/scss/shapes'; @mixin btn-bold { @@ -123,6 +124,24 @@ button { color: $grey-1; } } + &.wide { + div:first-child { + min-width: 50px; + width: 184px; + } + } + &.ultrawide { + div:first-child { + min-width: 50px; + width: 400px; + @media #{$tablet} { + width: 200px; + } + span { + padding-inline: 4px; + } + } + } .small-text { height: 22px !important; } @@ -199,6 +218,10 @@ button { background: unset !important; } } + &.center { + padding-left: 6px !important; + padding-right: 6px !important; + } } .text { position: relative; diff --git a/src/app/shared/components/button/buttonType.enum.ts b/src/app/shared/components/button/buttonType.enum.ts index 9b84f5a57..54cc2e4a5 100644 --- a/src/app/shared/components/button/buttonType.enum.ts +++ b/src/app/shared/components/button/buttonType.enum.ts @@ -2,6 +2,9 @@ export enum ButtonType { Regular, Primary, Secondary, + SecondaryWide, + SecondaryUltraWide, + SecondaryOnlyIcon, SecondaryDelete, Tertiary, ButtonPhone, diff --git a/src/app/shared/components/svg-icon/svg-icon.component.scss b/src/app/shared/components/svg-icon/svg-icon.component.scss index 72addb32c..96eb211f8 100644 --- a/src/app/shared/components/svg-icon/svg-icon.component.scss +++ b/src/app/shared/components/svg-icon/svg-icon.component.scss @@ -33,6 +33,10 @@ width: 32px; height: 32px; } + &.icon-40 { + width: 40px; + height: 40px; + } &.icon-75 { width: 4.688em; } @@ -40,6 +44,10 @@ height: 80px; width: 80px; } + &.icon-112 { + height: 112px; + width: 112px; + } &.validation { height: 36px; width: 20px; diff --git a/src/assets/ico/sprite.svg b/src/assets/ico/sprite.svg index ad9aff1ba..010388a65 100644 --- a/src/assets/ico/sprite.svg +++ b/src/assets/ico/sprite.svg @@ -84,7 +84,19 @@ <path d="M15.5 6.5L6.5 15.5" stroke="#333333" stroke-width="1.5" stroke-linecap="round"/> </symbol> - +<symbol id="deleteAccount" width="22" height="23" viewBox="0 0 22 23" fill="none" stroke="none" xmlns="http://www.w3.org/2000/svg"> +<g clip-path="url(#clip0_8047_46397)"> +<path d="M11 20.2498V18.1687C11 17.572 10.7629 16.9997 10.3409 16.5777C9.91899 16.1558 9.3467 15.9187 8.74997 15.9187H4.24999C3.65325 15.9187 3.08096 16.1558 2.65901 16.5777C2.23705 16.9997 2 17.572 2 18.1687V20.2498" stroke="#DA3635" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M10.0999 11.025C10.0999 13.0133 8.48811 14.625 6.49989 14.625C4.51167 14.625 2.8999 13.0133 2.8999 11.025C2.8999 9.03682 4.51167 7.42505 6.49989 7.42505C8.48811 7.42505 10.0999 9.03682 10.0999 11.025ZM8.74988 11.025C8.74988 12.2677 7.74253 13.275 6.49989 13.275C5.25726 13.275 4.2499 12.2677 4.2499 11.025C4.2499 9.7824 5.25726 8.77505 6.49989 8.77505C7.74253 8.77505 8.74988 9.7824 8.74988 11.025Z" fill="#DA3635"/> +<path d="M11.9746 4.52588L20.0259 12.5771" stroke="#DA3635" stroke-width="1.5" stroke-linecap="round"/> +<path d="M20.0254 4.52588L11.9741 12.5771" stroke="#DA3635" stroke-width="1.5" stroke-linecap="round"/> +</g> +<defs> +<clipPath id="clip0_8047_46397"> +<rect width="22" height="22" fill="white" transform="translate(0 0.5)"/> +</clipPath> +</defs> +</symbol> <symbol id="edit" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> <path fill-rule="evenodd" clip-rule="evenodd" d="M17.3745 2.62547C17.72 2.28003 18.3461 2.34613 18.7731 2.7731L20.3193 4.3193C20.7463 4.74627 20.8124 5.37243 20.4669 5.71787L18.6115 7.57331L15.5191 4.48091L17.3745 2.62547ZM17.993 8.1918L14.9006 5.0994L5.62344 14.3766L8.71584 17.469L17.993 8.1918ZM8.09736 18.0874L5.00496 14.995L4.74469 15.2553C4.60266 15.3973 4.52461 15.5949 4.52337 15.8155L3.77535 18.7134C3.7736 19.0246 4.0678 19.3188 4.37904 19.3171L7.27695 18.569C7.49751 18.5678 7.69506 18.4897 7.83709 18.3477L8.09736 18.0874Z" stroke="none"/> diff --git a/src/styles.scss b/src/styles.scss index fc6508419..29d30bff4 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -376,6 +376,12 @@ button { box-shadow: 0 2px 1px rgba(0, 0, 0, 0.6); } +.hide-on-desktop { + display: none; + @media #{$tablet} { + display: block; + } +} .hide-on-mobile { @media #{$tablet} { display: none !important; -- GitLab From b2d6aaa1812fb4985e7945356c91b97b10fe8918 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Tue, 17 May 2022 16:52:57 +0200 Subject: [PATCH 29/47] mobile responsive --- src/app/profile/edit/edit.component.scss | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/app/profile/edit/edit.component.scss b/src/app/profile/edit/edit.component.scss index 0ec08cc2f..40d9a35a0 100644 --- a/src/app/profile/edit/edit.component.scss +++ b/src/app/profile/edit/edit.component.scss @@ -15,10 +15,9 @@ padding-bottom: 0px; @media #{$tablet} { - width: 70%; - } - @media #{$large-phone} { - width: 90%; + margin: 16px 4px 4px 4px; + padding: 16px; + width: auto; } .header, @@ -36,6 +35,9 @@ h1 { color: $grey-1; font-weight: lighter; + @media #{$tablet} { + @include lato-regular-20; + } } svg { stroke: $black; @@ -64,7 +66,7 @@ border-bottom: 1px solid $grey-4; &::-webkit-scrollbar { - display: none; + height: 8px; } .tab { @@ -117,6 +119,7 @@ display: flex; gap: 26px; justify-content: center; + flex-wrap: wrap; // <hr/> like // width: 110%; // position: relative; -- GitLab From 5a911bb40cd17875d43f140ac10835936e1dd3a8 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Tue, 17 May 2022 17:26:34 +0200 Subject: [PATCH 30/47] adjust layout --- src/app/profile/edit/edit.component.html | 604 ++++++++++++----------- src/app/profile/edit/edit.component.scss | 3 +- 2 files changed, 310 insertions(+), 297 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index 897d4901e..7b655d9bc 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -1,301 +1,257 @@ -<div fxLayout="column" class="edit-profile" *ngIf="userProfile"> - <div class="header"> - <div class="title"> - <a routerLink="/profile"> - <svg class="leftArrow" aria-hidden="true"> - <use [attr.xlink:href]="'assets/ico/sprite.svg#leftArrow'"></use> - </svg> - </a> - <h1>Modifier mon profil</h1> +<div fxLayout="column" class="content-container full-screen" *ngIf="userProfile"> + <div class="edit-profile"> + <div class="header"> + <div class="title"> + <a routerLink="/profile"> + <svg class="leftArrow" aria-hidden="true"> + <use [attr.xlink:href]="'assets/ico/sprite.svg#leftArrow'"></use> + </svg> + </a> + <h1>Modifier mon profil</h1> + </div> + <app-button + class="hide-on-mobile" + [style]="buttonTypeEnum.SecondaryDelete" + [text]="'Supprimer mon compte'" + [type]="'button'" + [iconType]="'ico'" + [iconBtn]="'removeCross'" + ></app-button> + <app-button + class="hide-on-desktop" + [style]="buttonTypeEnum.SecondaryOnlyIcon" + [type]="'button'" + [iconBtn]="'edit'" + [iconType]="'ico'" + [iconBtn]="'deleteAccount'" + ></app-button> </div> - <app-button - class="hide-on-mobile" - [style]="buttonTypeEnum.SecondaryDelete" - [text]="'Supprimer mon compte'" - [type]="'button'" - [iconType]="'ico'" - [iconBtn]="'removeCross'" - ></app-button> - <app-button - class="hide-on-desktop" - [style]="buttonTypeEnum.SecondaryOnlyIcon" - [type]="'button'" - [iconBtn]="'edit'" - [iconType]="'ico'" - [iconBtn]="'deleteAccount'" - ></app-button> - </div> - <!-- Navigation --> - <div class="navigation"> - <span - [ngClass]="{ tab: true, selected: currentTab === tabsEnum.coordinates }" - (click)="navigateTo(tabsEnum.coordinates)" - >Coordonnées</span - > - <span - [ngClass]="{ tab: true, selected: currentTab === tabsEnum.credentials }" - (click)="navigateTo(tabsEnum.credentials)" - >Email et mot de passe</span - > - <span [ngClass]="{ tab: true, selected: currentTab === tabsEnum.employer }" (click)="navigateTo(tabsEnum.employer)" - >Employeur et fonction</span - > - <span - [ngClass]="{ tab: true, selected: currentTab === tabsEnum.description }" - (click)="navigateTo(tabsEnum.description)" - >Description</span - > - <!-- <span [ngClass]="{ tab: true, selected: currentTab === tabsEnum.avatar }" (click)="navigateTo(tabsEnum.avatar)" + <!-- Navigation --> + <div class="navigation"> + <span + [ngClass]="{ tab: true, selected: currentTab === tabsEnum.coordinates }" + (click)="navigateTo(tabsEnum.coordinates)" + >Coordonnées</span + > + <span + [ngClass]="{ tab: true, selected: currentTab === tabsEnum.credentials }" + (click)="navigateTo(tabsEnum.credentials)" + >Email et mot de passe</span + > + <span + [ngClass]="{ tab: true, selected: currentTab === tabsEnum.employer }" + (click)="navigateTo(tabsEnum.employer)" + >Employeur et fonction</span + > + <span + [ngClass]="{ tab: true, selected: currentTab === tabsEnum.description }" + (click)="navigateTo(tabsEnum.description)" + >Description</span + > + <!-- <span [ngClass]="{ tab: true, selected: currentTab === tabsEnum.avatar }" (click)="navigateTo(tabsEnum.avatar)" >Avatar</span > --> - </div> - <!-- Content of tabs --> - <div class="content"> - <!-- TODO: refacto this with account-info.component --> - <div *ngIf="currentTab === tabsEnum.coordinates"> - <div class="form-group" fxLayout="column"> - <label for="name">Prénom</label> - <div fxLayout="row" fxLayoutGap="13px"> - <input type="text" class="form-input" [(ngModel)]="userProfile.name" /> - <app-svg-icon *ngIf="nameValid()" [iconClass]="'icon-26'" [type]="'form'" [icon]="'validate'"></app-svg-icon> - <app-svg-icon - *ngIf="!nameValid()" - [iconClass]="'icon-26'" - [type]="'form'" - [icon]="'notValidate'" - ></app-svg-icon> - </div> - </div> - <div class="form-group" fxLayout="column"> - <label for="surname">Nom</label> - <div fxLayout="row" fxLayoutGap="13px"> - <input type="text" class="form-input" [(ngModel)]="userProfile.surname" /> - <app-svg-icon - *ngIf="surnameValid()" - [iconClass]="'icon-26'" - [type]="'form'" - [icon]="'validate'" - ></app-svg-icon> - <app-svg-icon - *ngIf="!surnameValid()" - [iconClass]="'icon-26'" - [type]="'form'" - [icon]="'notValidate'" - ></app-svg-icon> - </div> - </div> - <div class="form-group" fxLayout="column"> - <label for="phone">Téléphone</label> - <div fxLayout="row" fxLayoutGap="13px"> - <input type="text" class="form-input phone" [(ngModel)]="userProfile.phone" /> - <app-svg-icon *ngIf="phoneValid()" [iconClass]="'icon-26'" [type]="'form'" [icon]="'validate'"></app-svg-icon> - <app-svg-icon - *ngIf="!phoneValid()" - [iconClass]="'icon-26'" - [type]="'form'" - [icon]="'notValidate'" - ></app-svg-icon> - </div> - </div> - </div> - - <div *ngIf="currentTab === tabsEnum.credentials" class="credentialsTab"> - <p class="subTitle">Email</p> - {{ userProfile.email }} - <div class="buttons"> - <app-button - [text]="'Changer mon email'" - (action)="showEmailModal()" - [iconType]="'ico'" - [iconBtn]="'emailOutline'" - [style]="buttonTypeEnum.Secondary" - > - </app-button> - <app-button - [text]="'Changer mon mot de passe'" - (action)="showPasswordModal()" - [iconType]="'ico'" - [iconBtn]="'passwordOutline'" - [style]="buttonTypeEnum.Secondary" - > - </app-button> - </div> </div> - - <div *ngIf="currentTab === tabsEnum.employer"> - <div class="search-structure"> - <div fxLayout="column" fxLayoutAlign="space-between" class="form-group search"> - <label for="employer">Employeur</label> + <!-- Content of tabs --> + <div class="content"> + <!-- TODO: refacto this with account-info.component --> + <div *ngIf="currentTab === tabsEnum.coordinates"> + <div class="form-group" fxLayout="column"> + <label for="name">Prénom</label> <div fxLayout="row" fxLayoutGap="13px"> - <input - id="search-employer" - type="text" - (input)="onSearchChange($event.target.value)" - class="form-input" - autocomplete="off" - #searchEmployer - /> - </div> - </div> - <div class="structureResults"> - <div class="autocomplete-items" *ngIf="!isAlreadySearching"> - <p *ngFor="let employer of employers" (click)="selectEmployer(employer)" class="autocomplete-item"> - {{ employer.name }} - </p> + <input type="text" class="form-input" [(ngModel)]="userProfile.name" /> + <app-svg-icon + *ngIf="nameValid()" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'validate'" + ></app-svg-icon> + <app-svg-icon + *ngIf="!nameValid()" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'notValidate'" + ></app-svg-icon> </div> </div> - </div> - <p class="subTitle">Fonction</p> - <div fxLayout="column" fxLayoutGap="32px"> - <div class="btn-grid"> - <span *ngFor="let job of jobs"> - <app-button - [ngClass]="{ selectedChoice: true }" - [extraClass]="isSelectedJob(job) ? 'selected' : ''" - [style]="buttonTypeEnum.CheckButton" - [text]="job.name" - (action)="selectJob(job)" - ></app-button> - </span> - </div> - <div *ngIf="isUnexistingJob()" fxLayout="column" fxLayoutAlign="space-between" class="form-group search"> - <label for="employer">Quelle fonction occupez-vous ?</label> - <input type="text" (input)="createNewJob($event.target.value)" class="form-input" autocomplete="off" /> - </div> - </div> - </div> - - <div *ngIf="currentTab === tabsEnum.description" class="descriptionTab"> - <p class="subTitle">Description</p> - <div class="textareaBlock" fxLayout="column"> - <textarea - rows="8" - placeholder="Exemple : formateur depuis 2 ans, je participe tous les ans à Super Demain." - maxlength="500" - [(ngModel)]="userProfile.description" - ></textarea> - <p class="descriptionLength">{{ userProfile.description?.length }} / 500</p> - </div> - </div> - - <!-- <div *ngIf="currentTab === tabsEnum.avatar">Avater container</div> --> - </div> - - <!-- Footer --> - <div class="footer" *ngIf="currentTab !== tabsEnum.credentials"> - <app-button [text]="'Annuler'" (action)="cancel()" [iconType]="'ico'" [iconBtn]="'removeCrossBlack'"></app-button> - <app-button - [text]="'Valider'" - [disabled]="!isPageValid()" - (action)="confirm()" - [iconType]="'form'" - [iconBtn]="'checkWhite'" - [style]="buttonTypeEnum.Primary" - [extraClass]="svgCheck" - > - </app-button> - </div> - - <!-- Modal: Email change --> - <div class="modalBackground" *ngIf="emailModal"> - <div class="modal"> - <div class="modalHeader"> - <div class="empty"></div> - <h3>Changer mon email</h3> - <svg class="close" aria-hidden="true" (click)="closeModal()"> - <use [attr.xlink:href]="'assets/form/sprite.svg#close'"></use> - </svg> - </div> - - <div class="modalContent"> <div class="form-group" fxLayout="column"> - <label for="email">Nouvel email</label> + <label for="surname">Nom</label> <div fxLayout="row" fxLayoutGap="13px"> - <input id="email" type="text" class="form-input email-placeholder" [(ngModel)]="newEmail" /> + <input type="text" class="form-input" [(ngModel)]="userProfile.surname" /> <app-svg-icon - *ngIf="emailValid(newEmail)" + *ngIf="surnameValid()" [iconClass]="'icon-26'" [type]="'form'" [icon]="'validate'" ></app-svg-icon> <app-svg-icon - *ngIf="!emailValid(newEmail)" + *ngIf="!surnameValid()" [iconClass]="'icon-26'" [type]="'form'" [icon]="'notValidate'" ></app-svg-icon> </div> </div> - <div class="form-group" fxLayout="column"> - <label for="emailConfirm">Confirmer le nouvel email</label> + <label for="phone">Téléphone</label> <div fxLayout="row" fxLayoutGap="13px"> - <input id="emailConfirm" type="text" class="form-input email-placeholder" [(ngModel)]="newEmailConfirm" /> + <input type="text" class="form-input phone" [(ngModel)]="userProfile.phone" /> <app-svg-icon - *ngIf="emailValid(newEmailConfirm)" + *ngIf="phoneValid()" [iconClass]="'icon-26'" [type]="'form'" [icon]="'validate'" ></app-svg-icon> <app-svg-icon - *ngIf="!emailValid(newEmailConfirm)" + *ngIf="!phoneValid()" [iconClass]="'icon-26'" [type]="'form'" [icon]="'notValidate'" ></app-svg-icon> </div> </div> + </div> + <div *ngIf="currentTab === tabsEnum.credentials" class="credentialsTab"> + <p class="subTitle">Email</p> + {{ userProfile.email }} <div class="buttons"> - <app-button [text]="'Annuler'" (action)="closeModal()"></app-button> <app-button - [text]="'Valider'" - [style]="buttonTypeEnum.Primary" - [disabled]="!isPageValid()" - (action)="confirm()" - ></app-button> + [text]="'Changer mon email'" + (action)="showEmailModal()" + [iconType]="'ico'" + [iconBtn]="'emailOutline'" + [style]="buttonTypeEnum.Secondary" + > + </app-button> + <app-button + [text]="'Changer mon mot de passe'" + (action)="showPasswordModal()" + [iconType]="'ico'" + [iconBtn]="'passwordOutline'" + [style]="buttonTypeEnum.Secondary" + > + </app-button> </div> </div> - </div> - </div> - <!-- Modal: Password change --> - <div class="modalBackground" *ngIf="passwordModal" (clickOutside)="closeModal()"> - <div class="modal"> - <div class="modalHeader"> - <div class="empty"></div> - <h3>Changer mon mot de passe</h3> - <svg class="close" aria-hidden="true" (click)="closeModal()"> - <use [attr.xlink:href]="'assets/form/sprite.svg#close'"></use> - </svg> - </div> - - <div class="modalContent"> - <div class="form-group" fxLayout="column"> - <div class="form-group"> - <label for="oldPassword">Ancien mot de passe</label> - <div fxLayout="row" fxLayoutAlign="none center" fxLayoutGap="13px"> + <div *ngIf="currentTab === tabsEnum.employer"> + <div class="search-structure"> + <div fxLayout="column" fxLayoutAlign="space-between" class="form-group search"> + <label for="employer">Employeur</label> + <div fxLayout="row" fxLayoutGap="13px"> <input - [type]="isShowPassword.oldPassword ? 'text' : 'password'" - [(ngModel)]="oldPassword" - id="oldPassword" - class="form-input password" - autocomplete="on" + id="search-employer" + type="text" + (input)="onSearchChange($event.target.value)" + class="form-input" + autocomplete="off" + #searchEmployer /> + </div> + </div> + <div class="structureResults"> + <div class="autocomplete-items" *ngIf="!isAlreadySearching"> + <p *ngFor="let employer of employers" (click)="selectEmployer(employer)" class="autocomplete-item"> + {{ employer.name }} + </p> + </div> + </div> + </div> + <p class="subTitle">Fonction</p> + <div fxLayout="column" fxLayoutGap="32px"> + <div class="btn-grid"> + <span *ngFor="let job of jobs"> + <app-button + [ngClass]="{ selectedChoice: true }" + [extraClass]="isSelectedJob(job) ? 'selected' : ''" + [style]="buttonTypeEnum.CheckButton" + [text]="job.name" + (action)="selectJob(job)" + ></app-button> + </span> + </div> + <div *ngIf="isUnexistingJob()" fxLayout="column" fxLayoutAlign="space-between" class="form-group search"> + <label for="employer">Quelle fonction occupez-vous ?</label> + <input type="text" (input)="createNewJob($event.target.value)" class="form-input" autocomplete="off" /> + </div> + </div> + </div> + + <div *ngIf="currentTab === tabsEnum.description" class="descriptionTab"> + <p class="subTitle">Description</p> + <div class="textareaBlock" fxLayout="column"> + <textarea + rows="8" + placeholder="Exemple : formateur depuis 2 ans, je participe tous les ans à Super Demain." + maxlength="500" + [(ngModel)]="userProfile.description" + ></textarea> + <p class="descriptionLength">{{ userProfile.description?.length }} / 500</p> + </div> + </div> + + <!-- <div *ngIf="currentTab === tabsEnum.avatar">Avater container</div> --> + </div> + + <!-- Footer --> + <div class="footer" *ngIf="currentTab !== tabsEnum.credentials"> + <app-button [text]="'Annuler'" (action)="cancel()" [iconType]="'ico'" [iconBtn]="'removeCrossBlack'"></app-button> + <app-button + [text]="'Valider'" + [disabled]="!isPageValid()" + (action)="confirm()" + [iconType]="'form'" + [iconBtn]="'checkWhite'" + [style]="buttonTypeEnum.Primary" + [extraClass]="svgCheck" + > + </app-button> + </div> + + <!-- Modal: Email change --> + <div class="modalBackground" *ngIf="emailModal"> + <div class="modal"> + <div class="modalHeader"> + <div class="empty"></div> + <h3>Changer mon email</h3> + <svg class="close" aria-hidden="true" (click)="closeModal()"> + <use [attr.xlink:href]="'assets/form/sprite.svg#close'"></use> + </svg> + </div> + + <div class="modalContent"> + <div class="form-group" fxLayout="column"> + <label for="email">Nouvel email</label> + <div fxLayout="row" fxLayoutGap="13px"> + <input id="email" type="text" class="form-input email-placeholder" [(ngModel)]="newEmail" /> <app-svg-icon - [iconClass]="'icon-26 grey hover'" + *ngIf="emailValid(newEmail)" + [iconClass]="'icon-26'" [type]="'form'" - [icon]="'eyePassword'" - (click)="showPassword('oldPassword')" + [icon]="'validate'" ></app-svg-icon> <app-svg-icon - *ngIf="passwordValid(oldPassword)" + *ngIf="!emailValid(newEmail)" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'notValidate'" + ></app-svg-icon> + </div> + </div> + + <div class="form-group" fxLayout="column"> + <label for="emailConfirm">Confirmer le nouvel email</label> + <div fxLayout="row" fxLayoutGap="13px"> + <input id="emailConfirm" type="text" class="form-input email-placeholder" [(ngModel)]="newEmailConfirm" /> + <app-svg-icon + *ngIf="emailValid(newEmailConfirm)" [iconClass]="'icon-26'" [type]="'form'" [icon]="'validate'" ></app-svg-icon> <app-svg-icon - *ngIf="!passwordValid(oldPassword)" + *ngIf="!emailValid(newEmailConfirm)" [iconClass]="'icon-26'" [type]="'form'" [icon]="'notValidate'" @@ -303,13 +259,105 @@ </div> </div> + <div class="buttons"> + <app-button [text]="'Annuler'" (action)="closeModal()"></app-button> + <app-button + [text]="'Valider'" + [style]="buttonTypeEnum.Primary" + [disabled]="!isPageValid()" + (action)="confirm()" + ></app-button> + </div> + </div> + </div> + </div> + + <!-- Modal: Password change --> + <div class="modalBackground" *ngIf="passwordModal" (clickOutside)="closeModal()"> + <div class="modal"> + <div class="modalHeader"> + <div class="empty"></div> + <h3>Changer mon mot de passe</h3> + <svg class="close" aria-hidden="true" (click)="closeModal()"> + <use [attr.xlink:href]="'assets/form/sprite.svg#close'"></use> + </svg> + </div> + + <div class="modalContent"> + <div class="form-group" fxLayout="column"> + <div class="form-group"> + <label for="oldPassword">Ancien mot de passe</label> + <div fxLayout="row" fxLayoutAlign="none center" fxLayoutGap="13px"> + <input + [type]="isShowPassword.oldPassword ? 'text' : 'password'" + [(ngModel)]="oldPassword" + id="oldPassword" + class="form-input password" + autocomplete="on" + /> + <app-svg-icon + [iconClass]="'icon-26 grey hover'" + [type]="'form'" + [icon]="'eyePassword'" + (click)="showPassword('oldPassword')" + ></app-svg-icon> + <app-svg-icon + *ngIf="passwordValid(oldPassword)" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'validate'" + ></app-svg-icon> + <app-svg-icon + *ngIf="!passwordValid(oldPassword)" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'notValidate'" + ></app-svg-icon> + </div> + </div> + + <div class="form-group"> + <label for="newPassword">Nouveau mot de passe</label> + <div fxLayout="row" fxLayoutAlign="none center" fxLayoutGap="13px"> + <input + [type]="isShowPassword.newPassword ? 'text' : 'password'" + [(ngModel)]="newPassword" + id="newPassword" + class="form-input password" + autocomplete="on" + /> + <app-svg-icon + [iconClass]="'icon-26 grey hover'" + [type]="'form'" + [icon]="'eyePassword'" + (click)="showPassword('newPassword')" + ></app-svg-icon> + <app-svg-icon + *ngIf="passwordValid(newPassword)" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'validate'" + ></app-svg-icon> + <app-svg-icon + *ngIf="!passwordValid(newPassword)" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'notValidate'" + ></app-svg-icon> + </div> + </div> + </div> + <p class="form-group passwordInfo" [class.warn]="!passwordValid(newPassword)"> + Le mot de passe doit contenir au minimum : 8 caractères dont un caractère spécial, un caractère en majuscule + et un chiffre. + </p> <div class="form-group"> - <label for="newPassword">Nouveau mot de passe</label> + <label for="newPasswordConfirm">Confirmer le nouveau mot de passe</label> <div fxLayout="row" fxLayoutAlign="none center" fxLayoutGap="13px"> <input - [type]="isShowPassword.newPassword ? 'text' : 'password'" - [(ngModel)]="newPassword" - id="newPassword" + [type]="isShowPassword.newPasswordConfirm ? 'text' : 'password'" + [(ngModel)]="newPasswordConfirm" + id="newPasswordConfirm" class="form-input password" autocomplete="on" /> @@ -317,66 +365,32 @@ [iconClass]="'icon-26 grey hover'" [type]="'form'" [icon]="'eyePassword'" - (click)="showPassword('newPassword')" + (click)="showPassword('newPasswordConfirm')" ></app-svg-icon> <app-svg-icon - *ngIf="passwordValid(newPassword)" + *ngIf="passwordValid(newPasswordConfirm)" [iconClass]="'icon-26'" [type]="'form'" [icon]="'validate'" ></app-svg-icon> <app-svg-icon - *ngIf="!passwordValid(newPassword)" + *ngIf="!passwordValid(newPasswordConfirm)" [iconClass]="'icon-26'" [type]="'form'" [icon]="'notValidate'" ></app-svg-icon> </div> </div> - </div> - <p class="form-group passwordInfo" [class.warn]="!passwordValid(newPassword)"> - Le mot de passe doit contenir au minimum : 8 caractères dont un caractère spécial, un caractère en majuscule - et un chiffre. - </p> - <div class="form-group"> - <label for="newPasswordConfirm">Confirmer le nouveau mot de passe</label> - <div fxLayout="row" fxLayoutAlign="none center" fxLayoutGap="13px"> - <input - [type]="isShowPassword.newPasswordConfirm ? 'text' : 'password'" - [(ngModel)]="newPasswordConfirm" - id="newPasswordConfirm" - class="form-input password" - autocomplete="on" - /> - <app-svg-icon - [iconClass]="'icon-26 grey hover'" - [type]="'form'" - [icon]="'eyePassword'" - (click)="showPassword('newPasswordConfirm')" - ></app-svg-icon> - <app-svg-icon - *ngIf="passwordValid(newPasswordConfirm)" - [iconClass]="'icon-26'" - [type]="'form'" - [icon]="'validate'" - ></app-svg-icon> - <app-svg-icon - *ngIf="!passwordValid(newPasswordConfirm)" - [iconClass]="'icon-26'" - [type]="'form'" - [icon]="'notValidate'" - ></app-svg-icon> + <div class="buttons"> + <app-button [text]="'Annuler'" (action)="closeModal()"></app-button> + <app-button + [text]="'Valider'" + [style]="buttonTypeEnum.Primary" + [disabled]="!isPageValid()" + (action)="confirm()" + ></app-button> </div> </div> - <div class="buttons"> - <app-button [text]="'Annuler'" (action)="closeModal()"></app-button> - <app-button - [text]="'Valider'" - [style]="buttonTypeEnum.Primary" - [disabled]="!isPageValid()" - (action)="confirm()" - ></app-button> - </div> </div> </div> </div> diff --git a/src/app/profile/edit/edit.component.scss b/src/app/profile/edit/edit.component.scss index 40d9a35a0..6c0e6977a 100644 --- a/src/app/profile/edit/edit.component.scss +++ b/src/app/profile/edit/edit.component.scss @@ -5,12 +5,11 @@ @import '../../../assets/scss/breakpoint'; .edit-profile { - margin: 16px auto 0 auto; + margin: 16px auto 8px auto; background: $white; border: 1px solid $grey-6; border-radius: 8px; width: 70%; - min-height: 585px; padding: 40px; padding-bottom: 0px; -- GitLab From 36705fb4f3a55bac0c1e867449654bb585d8654f Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Tue, 17 May 2022 17:31:06 +0200 Subject: [PATCH 31/47] fix mobile button on desktop --- src/app/profile/edit/edit.component.scss | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/app/profile/edit/edit.component.scss b/src/app/profile/edit/edit.component.scss index 6c0e6977a..a80947481 100644 --- a/src/app/profile/edit/edit.component.scss +++ b/src/app/profile/edit/edit.component.scss @@ -28,6 +28,7 @@ .header { justify-content: space-between; padding-bottom: 18px; + align-items: center; .title { align-items: center; @@ -47,14 +48,14 @@ } } - app-button { - align-items: center; - display: flex; - ::ng-deep div svg { - height: 22px; - margin-right: 4px; - } - } + // app-button { + // align-items: center; + // display: flex; + // ::ng-deep div svg { + // height: 22px; + // margin-right: 4px; + // } + // } } .navigation { -- GitLab From 4ca4a016a23a5c1b5cb6b9f332e38c159103d932 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Wed, 18 May 2022 11:48:01 +0200 Subject: [PATCH 32/47] adjust mobile layout --- src/app/profile/edit/edit.component.scss | 6 +++++- src/styles.scss | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/app/profile/edit/edit.component.scss b/src/app/profile/edit/edit.component.scss index a80947481..a057cfdc7 100644 --- a/src/app/profile/edit/edit.component.scss +++ b/src/app/profile/edit/edit.component.scss @@ -12,10 +12,14 @@ width: 70%; padding: 40px; padding-bottom: 0px; + display: flex; + flex-direction: column; + flex: 1; @media #{$tablet} { - margin: 16px 4px 4px 4px; + margin: 0px 4px 4px 4px; padding: 16px; + padding-bottom: 0px; width: auto; } diff --git a/src/styles.scss b/src/styles.scss index 29d30bff4..09e29fb7e 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -92,6 +92,9 @@ a { } &.full-screen { min-height: calc(100vh - #{$header-height} - #{$footer-height}); + @media #{$tablet} { + min-height: calc(100vh - #{$header-height}); + } } } .section-container { -- GitLab From 2788b5bf01a686887f4eedbcda3eb795294b6d21 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Wed, 18 May 2022 13:24:35 +0200 Subject: [PATCH 33/47] separator --- src/app/profile/edit/edit.component.scss | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/app/profile/edit/edit.component.scss b/src/app/profile/edit/edit.component.scss index a057cfdc7..f1de77ad9 100644 --- a/src/app/profile/edit/edit.component.scss +++ b/src/app/profile/edit/edit.component.scss @@ -124,11 +124,12 @@ gap: 26px; justify-content: center; flex-wrap: wrap; - // <hr/> like - // width: 110%; - // position: relative; - // left: -5%; border-top: 1px solid $grey-4; + //To fit border to parent div + margin: 0 -40px; + @media #{$tablet} { + margin: 0 -16px; + } ::ng-deep div svg { height: 22px; } -- GitLab From 5ce4d298e4584c8bb67838766ddbf1a3cb38e7f3 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Wed, 18 May 2022 13:36:27 +0200 Subject: [PATCH 34/47] remove secondary delete --- src/app/profile/edit/edit.component.html | 4 ++-- src/app/profile/edit/edit.component.scss | 19 ++++++++------- .../components/button/button.component.html | 24 ------------------- .../components/button/button.component.scss | 22 ----------------- .../components/button/buttonType.enum.ts | 1 - 5 files changed, 13 insertions(+), 57 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index 7b655d9bc..b1648cd87 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -10,8 +10,8 @@ <h1>Modifier mon profil</h1> </div> <app-button - class="hide-on-mobile" - [style]="buttonTypeEnum.SecondaryDelete" + class="hide-on-mobile deleteAccount" + [style]="buttonTypeEnum.Secondary" [text]="'Supprimer mon compte'" [type]="'button'" [iconType]="'ico'" diff --git a/src/app/profile/edit/edit.component.scss b/src/app/profile/edit/edit.component.scss index f1de77ad9..8097d26d8 100644 --- a/src/app/profile/edit/edit.component.scss +++ b/src/app/profile/edit/edit.component.scss @@ -52,14 +52,16 @@ } } - // app-button { - // align-items: center; - // display: flex; - // ::ng-deep div svg { - // height: 22px; - // margin-right: 4px; - // } - // } + .deleteAccount { + ::ng-deep { + span { + color: $red; + } + svg { + height: 22px; + } + } + } } .navigation { @@ -71,6 +73,7 @@ &::-webkit-scrollbar { height: 8px; + margin-right: 4px; } .tab { diff --git a/src/app/shared/components/button/button.component.html b/src/app/shared/components/button/button.component.html index 08b616e3f..e84957123 100644 --- a/src/app/shared/components/button/button.component.html +++ b/src/app/shared/components/button/button.component.html @@ -158,30 +158,6 @@ </button> </ng-container> -<ng-container *ngIf="style === buttonTypeEnum.SecondaryDelete"> - <button class="btn-regular secondary-delete" type="{{ type }}" (click)="doAction()" [disabled]="disabled"> - <div *ngIf="!iconBtn" [ngClass]="extraClass" class="text">{{ text }}</div> - <div - *ngIf="iconBtn && iconPos === 'left'" - fxLayout="row center" - class="text withIcon left" - fxLayoutAlign="space-around center" - > - <app-svg-icon [type]="iconType" [icon]="iconBtn" [iconColor]="'currentColor'"></app-svg-icon> - <span>{{ text }}</span> - </div> - <div - *ngIf="iconBtn && iconPos === 'right'" - fxLayout="row center" - class="text withIcon right" - fxLayoutAlign="space-around center" - > - <span>{{ text }}</span> - <app-svg-icon [type]="iconType" [icon]="iconBtn" [iconColor]="'currentColor'"></app-svg-icon> - </div> - </button> -</ng-container> - <ng-container *ngIf="style === buttonTypeEnum.ButtonPhone"> <button [disabled]="disabled" class="btn-switch-phone" type="{{ type }}" (click)="doAction()"> <div *ngIf="!iconBtn" class="text">{{ text }}</div> diff --git a/src/app/shared/components/button/button.component.scss b/src/app/shared/components/button/button.component.scss index 467beb448..46cea399a 100644 --- a/src/app/shared/components/button/button.component.scss +++ b/src/app/shared/components/button/button.component.scss @@ -146,28 +146,6 @@ button { height: 22px !important; } } - &.secondary-delete { - div:first-child { - width: unset; - } - border: 0; - background: $white; - @include btn-regular; - .text { - background: $white; - border: 1px solid $grey-1; - color: $red; - font-size: 14px; - // @include btn-regular; - &.withIcon { - color: $red; - fill: $red; - } - } - .small-text { - height: 22px !important; - } - } &.tertiary { div:first-child { min-width: 50px; diff --git a/src/app/shared/components/button/buttonType.enum.ts b/src/app/shared/components/button/buttonType.enum.ts index 54cc2e4a5..99cd644b0 100644 --- a/src/app/shared/components/button/buttonType.enum.ts +++ b/src/app/shared/components/button/buttonType.enum.ts @@ -5,7 +5,6 @@ export enum ButtonType { SecondaryWide, SecondaryUltraWide, SecondaryOnlyIcon, - SecondaryDelete, Tertiary, ButtonPhone, Filter, -- GitLab From 07609819a780f57cb24418f1f3296267a7fd341b Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Wed, 18 May 2022 16:34:54 +0200 Subject: [PATCH 35/47] delete account --- src/app/profile/edit/edit.component.html | 327 +++++++++++++---------- src/app/profile/edit/edit.component.scss | 5 + src/app/profile/edit/edit.component.ts | 34 ++- 3 files changed, 224 insertions(+), 142 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index b1648cd87..c8d3b2249 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -16,6 +16,7 @@ [type]="'button'" [iconType]="'ico'" [iconBtn]="'removeCross'" + (action)="showDeleteAccountModal()" ></app-button> <app-button class="hide-on-desktop" @@ -24,6 +25,7 @@ [iconBtn]="'edit'" [iconType]="'ico'" [iconBtn]="'deleteAccount'" + (action)="showDeleteAccountModal()" ></app-button> </div> <!-- Navigation --> @@ -208,50 +210,108 @@ > </app-button> </div> + </div> - <!-- Modal: Email change --> - <div class="modalBackground" *ngIf="emailModal"> - <div class="modal"> - <div class="modalHeader"> - <div class="empty"></div> - <h3>Changer mon email</h3> - <svg class="close" aria-hidden="true" (click)="closeModal()"> - <use [attr.xlink:href]="'assets/form/sprite.svg#close'"></use> - </svg> + <!-- Modal: Email change --> + <div class="modalBackground" *ngIf="emailModal"> + <div class="modal"> + <div class="modalHeader"> + <div class="empty"></div> + <h3>Changer mon email</h3> + <svg class="close" aria-hidden="true" (click)="closeModal()"> + <use [attr.xlink:href]="'assets/form/sprite.svg#close'"></use> + </svg> + </div> + + <div class="modalContent"> + <div class="form-group" fxLayout="column"> + <label for="email">Nouvel email</label> + <div fxLayout="row" fxLayoutGap="13px"> + <input id="email" type="text" class="form-input email-placeholder" [(ngModel)]="newEmail" /> + <app-svg-icon + *ngIf="emailValid(newEmail)" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'validate'" + ></app-svg-icon> + <app-svg-icon + *ngIf="!emailValid(newEmail)" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'notValidate'" + ></app-svg-icon> + </div> </div> - <div class="modalContent"> - <div class="form-group" fxLayout="column"> - <label for="email">Nouvel email</label> - <div fxLayout="row" fxLayoutGap="13px"> - <input id="email" type="text" class="form-input email-placeholder" [(ngModel)]="newEmail" /> - <app-svg-icon - *ngIf="emailValid(newEmail)" - [iconClass]="'icon-26'" - [type]="'form'" - [icon]="'validate'" - ></app-svg-icon> + <div class="form-group" fxLayout="column"> + <label for="emailConfirm">Confirmer le nouvel email</label> + <div fxLayout="row" fxLayoutGap="13px"> + <input id="emailConfirm" type="text" class="form-input email-placeholder" [(ngModel)]="newEmailConfirm" /> + <app-svg-icon + *ngIf="emailValid(newEmailConfirm)" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'validate'" + ></app-svg-icon> + <app-svg-icon + *ngIf="!emailValid(newEmailConfirm)" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'notValidate'" + ></app-svg-icon> + </div> + </div> + + <div class="buttons"> + <app-button [text]="'Annuler'" (action)="closeModal()"></app-button> + <app-button + [text]="'Valider'" + [style]="buttonTypeEnum.Primary" + [disabled]="!isPageValid()" + (action)="confirm()" + ></app-button> + </div> + </div> + </div> + </div> + + <!-- Modal: Password change --> + <div class="modalBackground" *ngIf="passwordModal" (clickOutside)="closeModal()"> + <div class="modal"> + <div class="modalHeader"> + <div class="empty"></div> + <h3>Changer mon mot de passe</h3> + <svg class="close" aria-hidden="true" (click)="closeModal()"> + <use [attr.xlink:href]="'assets/form/sprite.svg#close'"></use> + </svg> + </div> + + <div class="modalContent"> + <div class="form-group" fxLayout="column"> + <div class="form-group"> + <label for="oldPassword">Ancien mot de passe</label> + <div fxLayout="row" fxLayoutAlign="none center" fxLayoutGap="13px"> + <input + [type]="isShowPassword.oldPassword ? 'text' : 'password'" + [(ngModel)]="oldPassword" + id="oldPassword" + class="form-input password" + autocomplete="on" + /> <app-svg-icon - *ngIf="!emailValid(newEmail)" - [iconClass]="'icon-26'" + [iconClass]="'icon-26 grey hover'" [type]="'form'" - [icon]="'notValidate'" + [icon]="'eyePassword'" + (click)="showPassword('oldPassword')" ></app-svg-icon> - </div> - </div> - - <div class="form-group" fxLayout="column"> - <label for="emailConfirm">Confirmer le nouvel email</label> - <div fxLayout="row" fxLayoutGap="13px"> - <input id="emailConfirm" type="text" class="form-input email-placeholder" [(ngModel)]="newEmailConfirm" /> <app-svg-icon - *ngIf="emailValid(newEmailConfirm)" + *ngIf="passwordValid(oldPassword)" [iconClass]="'icon-26'" [type]="'form'" [icon]="'validate'" ></app-svg-icon> <app-svg-icon - *ngIf="!emailValid(newEmailConfirm)" + *ngIf="!passwordValid(oldPassword)" [iconClass]="'icon-26'" [type]="'form'" [icon]="'notValidate'" @@ -259,105 +319,13 @@ </div> </div> - <div class="buttons"> - <app-button [text]="'Annuler'" (action)="closeModal()"></app-button> - <app-button - [text]="'Valider'" - [style]="buttonTypeEnum.Primary" - [disabled]="!isPageValid()" - (action)="confirm()" - ></app-button> - </div> - </div> - </div> - </div> - - <!-- Modal: Password change --> - <div class="modalBackground" *ngIf="passwordModal" (clickOutside)="closeModal()"> - <div class="modal"> - <div class="modalHeader"> - <div class="empty"></div> - <h3>Changer mon mot de passe</h3> - <svg class="close" aria-hidden="true" (click)="closeModal()"> - <use [attr.xlink:href]="'assets/form/sprite.svg#close'"></use> - </svg> - </div> - - <div class="modalContent"> - <div class="form-group" fxLayout="column"> - <div class="form-group"> - <label for="oldPassword">Ancien mot de passe</label> - <div fxLayout="row" fxLayoutAlign="none center" fxLayoutGap="13px"> - <input - [type]="isShowPassword.oldPassword ? 'text' : 'password'" - [(ngModel)]="oldPassword" - id="oldPassword" - class="form-input password" - autocomplete="on" - /> - <app-svg-icon - [iconClass]="'icon-26 grey hover'" - [type]="'form'" - [icon]="'eyePassword'" - (click)="showPassword('oldPassword')" - ></app-svg-icon> - <app-svg-icon - *ngIf="passwordValid(oldPassword)" - [iconClass]="'icon-26'" - [type]="'form'" - [icon]="'validate'" - ></app-svg-icon> - <app-svg-icon - *ngIf="!passwordValid(oldPassword)" - [iconClass]="'icon-26'" - [type]="'form'" - [icon]="'notValidate'" - ></app-svg-icon> - </div> - </div> - - <div class="form-group"> - <label for="newPassword">Nouveau mot de passe</label> - <div fxLayout="row" fxLayoutAlign="none center" fxLayoutGap="13px"> - <input - [type]="isShowPassword.newPassword ? 'text' : 'password'" - [(ngModel)]="newPassword" - id="newPassword" - class="form-input password" - autocomplete="on" - /> - <app-svg-icon - [iconClass]="'icon-26 grey hover'" - [type]="'form'" - [icon]="'eyePassword'" - (click)="showPassword('newPassword')" - ></app-svg-icon> - <app-svg-icon - *ngIf="passwordValid(newPassword)" - [iconClass]="'icon-26'" - [type]="'form'" - [icon]="'validate'" - ></app-svg-icon> - <app-svg-icon - *ngIf="!passwordValid(newPassword)" - [iconClass]="'icon-26'" - [type]="'form'" - [icon]="'notValidate'" - ></app-svg-icon> - </div> - </div> - </div> - <p class="form-group passwordInfo" [class.warn]="!passwordValid(newPassword)"> - Le mot de passe doit contenir au minimum : 8 caractères dont un caractère spécial, un caractère en majuscule - et un chiffre. - </p> <div class="form-group"> - <label for="newPasswordConfirm">Confirmer le nouveau mot de passe</label> + <label for="newPassword">Nouveau mot de passe</label> <div fxLayout="row" fxLayoutAlign="none center" fxLayoutGap="13px"> <input - [type]="isShowPassword.newPasswordConfirm ? 'text' : 'password'" - [(ngModel)]="newPasswordConfirm" - id="newPasswordConfirm" + [type]="isShowPassword.newPassword ? 'text' : 'password'" + [(ngModel)]="newPassword" + id="newPassword" class="form-input password" autocomplete="on" /> @@ -365,32 +333,113 @@ [iconClass]="'icon-26 grey hover'" [type]="'form'" [icon]="'eyePassword'" - (click)="showPassword('newPasswordConfirm')" + (click)="showPassword('newPassword')" ></app-svg-icon> <app-svg-icon - *ngIf="passwordValid(newPasswordConfirm)" + *ngIf="passwordValid(newPassword)" [iconClass]="'icon-26'" [type]="'form'" [icon]="'validate'" ></app-svg-icon> <app-svg-icon - *ngIf="!passwordValid(newPasswordConfirm)" + *ngIf="!passwordValid(newPassword)" [iconClass]="'icon-26'" [type]="'form'" [icon]="'notValidate'" ></app-svg-icon> </div> </div> - <div class="buttons"> - <app-button [text]="'Annuler'" (action)="closeModal()"></app-button> - <app-button - [text]="'Valider'" - [style]="buttonTypeEnum.Primary" - [disabled]="!isPageValid()" - (action)="confirm()" - ></app-button> + </div> + <p class="form-group passwordInfo" [class.warn]="!passwordValid(newPassword)"> + Le mot de passe doit contenir au minimum : 8 caractères dont un caractère spécial, un caractère en majuscule + et un chiffre. + </p> + <div class="form-group"> + <label for="newPasswordConfirm">Confirmer le nouveau mot de passe</label> + <div fxLayout="row" fxLayoutAlign="none center" fxLayoutGap="13px"> + <input + [type]="isShowPassword.newPasswordConfirm ? 'text' : 'password'" + [(ngModel)]="newPasswordConfirm" + id="newPasswordConfirm" + class="form-input password" + autocomplete="on" + /> + <app-svg-icon + [iconClass]="'icon-26 grey hover'" + [type]="'form'" + [icon]="'eyePassword'" + (click)="showPassword('newPasswordConfirm')" + ></app-svg-icon> + <app-svg-icon + *ngIf="passwordValid(newPasswordConfirm)" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'validate'" + ></app-svg-icon> + <app-svg-icon + *ngIf="!passwordValid(newPasswordConfirm)" + [iconClass]="'icon-26'" + [type]="'form'" + [icon]="'notValidate'" + ></app-svg-icon> + </div> + </div> + <div class="buttons"> + <app-button [text]="'Annuler'" (action)="closeModal()"></app-button> + <app-button + [text]="'Valider'" + [style]="buttonTypeEnum.Primary" + [disabled]="!isPageValid()" + (action)="confirm()" + ></app-button> + </div> + </div> + </div> + </div> + + <!-- Modal: Delete account --> + <div class="modalBackground" *ngIf="deleteAccountModal"> + <div class="modal"> + <div class="modalHeader"> + <div class="empty"></div> + <h3>Supprimer mon compte</h3> + <svg class="close" aria-hidden="true" (click)="closeModal()"> + <use [attr.xlink:href]="'assets/form/sprite.svg#close'"></use> + </svg> + </div> + + <div class="modalContent"> + <p class="warnText"> + Cette action est définitive, veuillez donc entrer votre mot de passe afin de supprimer votre compte + </p> + <div class="form-group"> + <label for="oldPassword">Ancien mot de passe</label> + <div fxLayout="row" fxLayoutAlign="none center" fxLayoutGap="13px"> + <input + [type]="isShowPassword.oldPassword ? 'text' : 'password'" + [(ngModel)]="oldPassword" + id="oldPassword" + class="form-input password" + autocomplete="on" + /> + <app-svg-icon + [iconClass]="'icon-26 grey hover'" + [type]="'form'" + [icon]="'eyePassword'" + (click)="showPassword('oldPassword')" + ></app-svg-icon> </div> </div> + + <div class="buttons"> + <app-button [text]="'Annuler'" (action)="closeModal()"></app-button> + <app-button + [text]="'Supprimer'" + [style]="buttonTypeEnum.Primary" + [disabled]="!passwordValid(oldPassword)" + (action)="confirmDeleteAccount()" + ></app-button> + </div> </div> </div> </div> diff --git a/src/app/profile/edit/edit.component.scss b/src/app/profile/edit/edit.component.scss index 8097d26d8..86dae3565 100644 --- a/src/app/profile/edit/edit.component.scss +++ b/src/app/profile/edit/edit.component.scss @@ -165,6 +165,10 @@ .modalContent { padding: 24px 40px; + + .warnText { + margin: 0 auto 24px auto; + } } p { text-align: center; @@ -182,6 +186,7 @@ justify-content: space-between; align-items: center; gap: 26px; + padding-top: 8px; } } } diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index c772e25aa..5ed70572e 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -6,10 +6,12 @@ import { ProfileService } from '../services/profile.service'; import { CustomRegExp } from '../../utils/CustomRegExp'; import { BehaviorSubject, forkJoin, of } from 'rxjs'; import { UserAuth } from '../../models/user-auth.model'; -import { catchError, map } from 'rxjs/operators'; +import { catchError, first, map } from 'rxjs/operators'; import { HttpErrorResponse } from '@angular/common/http'; import { Job } from '../../models/job.model'; import { Employer } from '../../models/employer.model'; +import { Router } from '@angular/router'; +import { AuthService } from '../../services/auth.service'; enum tabsEnum { coordinates, @@ -32,13 +34,14 @@ enum showPasswordEnum { export class EditComponent implements OnInit { public tabsEnum = tabsEnum; public buttonTypeEnum = ButtonType; - public currentTab: tabsEnum = tabsEnum.employer; + public currentTab: tabsEnum = tabsEnum.coordinates; @Input() userProfile: User; public initialUserProfile: User; private userSubject: BehaviorSubject<UserAuth>; private emailModal = false; private passwordModal = false; + private deleteAccountModal = false; private newEmail = ''; private newEmailConfirm = ''; private oldPassword = ''; @@ -60,7 +63,8 @@ export class EditComponent implements OnInit { constructor( private profileService: ProfileService, private notificationService: NotificationService, - private cdr: ChangeDetectorRef + private cdr: ChangeDetectorRef, + private authService: AuthService ) { this.userSubject = new BehaviorSubject<UserAuth>(JSON.parse(localStorage.getItem('user'))); } @@ -124,12 +128,16 @@ export class EditComponent implements OnInit { public showPasswordModal(): void { this.passwordModal = true; } + public showDeleteAccountModal(): void { + this.deleteAccountModal = true; + } public showPassword(key: showPasswordEnum): void { this.isShowPassword[key] = !this.isShowPassword[key]; } public closeModal(): void { this.emailModal = false; this.passwordModal = false; + this.deleteAccountModal = false; } public isPageValid(): boolean { @@ -243,9 +251,29 @@ export class EditComponent implements OnInit { this.notificationService.showSuccess('Votre mot de passe a bien été modifié.', ''); this.closeModal(); }); + this.oldPassword = ''; + this.isShowPassword.oldPassword = false; } } + public confirmDeleteAccount(): void { + this.authService + .login(this.userProfile.email, this.oldPassword) + .pipe(first()) + .subscribe( + () => { + this.profileService.deleteProfile().subscribe(() => { + this.notificationService.showSuccess('Votre compte a bien été supprimé.', ''); + this.closeModal(); + this.authService.logout(); + }); + }, + () => { + this.notificationService.showError('Une erreur est survenue.', ''); + } + ); + } + //Jobs public selectJob(job: Job): void { this.selectedJob = job; -- GitLab From 548cf3a0e11b58c7e3bbc787d67f5c21e5f491cc Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Wed, 18 May 2022 16:59:33 +0200 Subject: [PATCH 36/47] mobile adjustment --- src/app/profile/edit/edit.component.scss | 5 ++++- src/app/profile/edit/edit.component.ts | 19 +++++++++---------- src/app/profile/services/profile.service.ts | 2 +- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/app/profile/edit/edit.component.scss b/src/app/profile/edit/edit.component.scss index 86dae3565..b2de77c08 100644 --- a/src/app/profile/edit/edit.component.scss +++ b/src/app/profile/edit/edit.component.scss @@ -66,7 +66,7 @@ .navigation { justify-content: flex-start; - overflow-x: scroll; + overflow-x: auto; white-space: nowrap; border-bottom: 1px solid $grey-4; @@ -144,6 +144,9 @@ .modal { max-width: 390px; background-color: $white; + @media #{$tablet} { + width: 85%; + } .modalHeader { display: flex; justify-content: space-between; diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index 5ed70572e..9b7a9a331 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -1,17 +1,16 @@ -import { Component, OnInit, Input, ViewChild, ElementRef, AfterViewInit, ChangeDetectorRef } from '@angular/core'; -import { User } from '../../models/user.model'; -import { NotificationService } from '../../services/notification.service'; -import { ButtonType } from '../../shared/components/button/buttonType.enum'; -import { ProfileService } from '../services/profile.service'; -import { CustomRegExp } from '../../utils/CustomRegExp'; +import { HttpErrorResponse } from '@angular/common/http'; +import { ChangeDetectorRef, Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core'; import { BehaviorSubject, forkJoin, of } from 'rxjs'; -import { UserAuth } from '../../models/user-auth.model'; import { catchError, first, map } from 'rxjs/operators'; -import { HttpErrorResponse } from '@angular/common/http'; -import { Job } from '../../models/job.model'; import { Employer } from '../../models/employer.model'; -import { Router } from '@angular/router'; +import { Job } from '../../models/job.model'; +import { UserAuth } from '../../models/user-auth.model'; +import { User } from '../../models/user.model'; import { AuthService } from '../../services/auth.service'; +import { NotificationService } from '../../services/notification.service'; +import { ButtonType } from '../../shared/components/button/buttonType.enum'; +import { CustomRegExp } from '../../utils/CustomRegExp'; +import { ProfileService } from '../services/profile.service'; enum tabsEnum { coordinates, diff --git a/src/app/profile/services/profile.service.ts b/src/app/profile/services/profile.service.ts index 8d555406b..93d175c98 100644 --- a/src/app/profile/services/profile.service.ts +++ b/src/app/profile/services/profile.service.ts @@ -117,7 +117,7 @@ export class ProfileService { public updateCoordinates(newCoordinates: { name: string; surname: string; phone: string }): Observable<User | Error> { console.log('profile service updates coords'); - return this.http.post<User>(`${this.baseUrl}/update-coordinates`, newCoordinates).pipe( + return this.http.post<User>(`${this.baseUrl}/coordinates`, newCoordinates).pipe( map((user) => user), catchError(() => { this.notificationService.showError('Une erreur est survenue', ''); -- GitLab From f8dbc152725a8fef0ad10183679bf28b51dda3ef Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Thu, 19 May 2022 09:37:17 +0200 Subject: [PATCH 37/47] remove merge conflict --- src/app/models/user.model.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/app/models/user.model.ts b/src/app/models/user.model.ts index 261a5a329..d8b64e6c0 100644 --- a/src/app/models/user.model.ts +++ b/src/app/models/user.model.ts @@ -21,5 +21,4 @@ export class User { constructor(obj?: any) { Object.assign(this, obj); } - description?: string; } -- GitLab From f89e012d4ef996878ce974fb6978077634e482d5 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Thu, 19 May 2022 14:18:25 +0200 Subject: [PATCH 38/47] adjut layout and description length --- src/app/profile/edit/edit.component.scss | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/app/profile/edit/edit.component.scss b/src/app/profile/edit/edit.component.scss index b2de77c08..7b7f66b24 100644 --- a/src/app/profile/edit/edit.component.scss +++ b/src/app/profile/edit/edit.component.scss @@ -5,16 +5,17 @@ @import '../../../assets/scss/breakpoint'; .edit-profile { + display: flex; + flex-direction: column; + flex: 1; + max-width: 980px; + width: 100%; margin: 16px auto 8px auto; + padding: 40px; + padding-bottom: 0px; background: $white; border: 1px solid $grey-6; border-radius: 8px; - width: 70%; - padding: 40px; - padding-bottom: 0px; - display: flex; - flex-direction: column; - flex: 1; @media #{$tablet} { margin: 0px 4px 4px 4px; @@ -112,6 +113,10 @@ .descriptionTab { p.descriptionLength { text-align: right; + @include lato-regular-14; + color: $grey-3; + font-style: italic; + margin-top: 8px; } } -- GitLab From bf9c924e7e2fd94d2e461beeb112f7a39141f124 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Fri, 20 May 2022 14:22:24 +0200 Subject: [PATCH 39/47] =?UTF-8?q?retours=20d=C3=A9mo=20PO?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/profile/edit/edit.component.html | 12 +++++++---- src/app/profile/edit/edit.component.scss | 22 ++++++++++++++----- src/app/profile/edit/edit.component.ts | 27 +++++++++++++++++++----- src/app/profile/profile.component.html | 1 + 4 files changed, 48 insertions(+), 14 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index c8d3b2249..a955ef0a8 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -175,7 +175,13 @@ </div> <div *ngIf="isUnexistingJob()" fxLayout="column" fxLayoutAlign="space-between" class="form-group search"> <label for="employer">Quelle fonction occupez-vous ?</label> - <input type="text" (input)="createNewJob($event.target.value)" class="form-input" autocomplete="off" /> + <input + type="text" + (input)="createNewJob($event.target.value)" + class="form-input" + autocomplete="off" + #newJobInput + /> </div> </div> </div> @@ -198,13 +204,11 @@ <!-- Footer --> <div class="footer" *ngIf="currentTab !== tabsEnum.credentials"> - <app-button [text]="'Annuler'" (action)="cancel()" [iconType]="'ico'" [iconBtn]="'removeCrossBlack'"></app-button> + <app-button [text]="'Annuler'" (action)="cancel()"></app-button> <app-button [text]="'Valider'" [disabled]="!isPageValid()" (action)="confirm()" - [iconType]="'form'" - [iconBtn]="'checkWhite'" [style]="buttonTypeEnum.Primary" [extraClass]="svgCheck" > diff --git a/src/app/profile/edit/edit.component.scss b/src/app/profile/edit/edit.component.scss index 7b7f66b24..767434139 100644 --- a/src/app/profile/edit/edit.component.scss +++ b/src/app/profile/edit/edit.component.scss @@ -55,11 +55,14 @@ .deleteAccount { ::ng-deep { - span { - color: $red; - } svg { height: 22px; + width: 22px; + margin-right: 4px; + } + span { + color: $red; + @include lato-regular-14; } } } @@ -99,6 +102,7 @@ @include lato-regular-16; text-align: left; margin-top: 0; + margin-bottom: 4px; } .credentialsTab { @@ -107,6 +111,13 @@ display: flex; flex-wrap: wrap; gap: 18px; + ::ng-deep { + svg { + height: 22px; + width: 22px; + margin-right: 4px; + } + } } } @@ -123,13 +134,14 @@ .structureResults { position: absolute; width: 600px; + z-index: 1; } } .footer { padding: 16px; display: flex; - gap: 26px; + gap: 24px; justify-content: center; flex-wrap: wrap; border-top: 1px solid $grey-4; @@ -193,7 +205,7 @@ display: flex; justify-content: space-between; align-items: center; - gap: 26px; + gap: 24px; padding-top: 8px; } } diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index 9b7a9a331..e704485d1 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -58,6 +58,7 @@ export class EditComponent implements OnInit { private selectedEmployer: Employer; private isAlreadySearching = false; @ViewChild('searchEmployer') searchEmployer: ElementRef; + @ViewChild('newJobInput') newJobInput: ElementRef; constructor( private profileService: ProfileService, @@ -69,15 +70,27 @@ export class EditComponent implements OnInit { } ngOnInit(): void { + if (history.state.data === 'description') { + this.currentTab = tabsEnum.description; + } + this.profileService.getProfile().then((profile) => { this.userProfile = profile; this.initialUserProfile = { ...profile }; - this.selectedJob = { ...profile.job }; this.selectedEmployer = { ...profile.employer }; - }); - this.profileService.getJobs().subscribe((jobs) => { - this.jobs = [...jobs, new Job({ name: 'Autre' })]; + const otherJob = new Job({ name: 'Autre' }); + this.profileService.getJobs().subscribe((jobs) => { + this.jobs = [...jobs, otherJob]; + + // Select "Autre" job and set the job's name + if (!!this.jobs.indexOf(profile.job)) { + this.selectedJob = otherJob; + this.newJob = profile.job; + } else { + this.selectedJob = { ...profile.job }; + } + }); }); } @@ -114,6 +127,7 @@ export class EditComponent implements OnInit { if (tab === tabsEnum.employer) { this.cdr.detectChanges(); this.selectEmployer(this.userProfile.employer); + this.newJobInput.nativeElement.value = this.userProfile.job.name; } } @@ -149,7 +163,10 @@ export class EditComponent implements OnInit { return this.passwordValid(this.newPassword) && this.newPassword == this.newPasswordConfirm; } } else if (this.currentTab === tabsEnum.employer) { - return !!(this.selectedEmployer && this.selectedJob); + return !!( + this.selectedEmployer.name !== this.userProfile.employer.name || + this.selectedJob.name !== this.userProfile.job.name + ); } else if (this.currentTab === tabsEnum.description) { return this.pageChanged() && this.descriptionValid(); } diff --git a/src/app/profile/profile.component.html b/src/app/profile/profile.component.html index ecb9c9beb..23c9666d4 100644 --- a/src/app/profile/profile.component.html +++ b/src/app/profile/profile.component.html @@ -49,6 +49,7 @@ [text]="'Ajouter une description'" [style]="buttonTypeEnum.SecondaryUltraWide" routerLink="/profile/edit" + [state]="{ data: 'description' }" [routerLinkActive]="'active'" ></app-button> </div> -- GitLab From b9d6d7f9dad01260a1ddc354da9f7e3c36efb273 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Mon, 23 May 2022 13:55:27 +0200 Subject: [PATCH 40/47] update svg --- src/app/profile/edit/edit.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index a955ef0a8..1ffa1e261 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -3,8 +3,8 @@ <div class="header"> <div class="title"> <a routerLink="/profile"> - <svg class="leftArrow" aria-hidden="true"> - <use [attr.xlink:href]="'assets/ico/sprite.svg#leftArrow'"></use> + <svg aria-hidden="true"> + <use [attr.xlink:href]="'assets/ico/sprite.svg#arrowBack'"></use> </svg> </a> <h1>Modifier mon profil</h1> -- GitLab From d29eb73741dd7183ef2c5b73149f7a07f5fb311a Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Mon, 23 May 2022 14:58:42 +0200 Subject: [PATCH 41/47] update coordinates to details --- src/app/profile/edit/edit.component.html | 6 ++---- src/app/profile/edit/edit.component.ts | 14 +++++++------- src/app/profile/services/profile.service.ts | 6 +++--- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index 1ffa1e261..99ac06ee5 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -30,9 +30,7 @@ </div> <!-- Navigation --> <div class="navigation"> - <span - [ngClass]="{ tab: true, selected: currentTab === tabsEnum.coordinates }" - (click)="navigateTo(tabsEnum.coordinates)" + <span [ngClass]="{ tab: true, selected: currentTab === tabsEnum.details }" (click)="navigateTo(tabsEnum.details)" >Coordonnées</span > <span @@ -57,7 +55,7 @@ <!-- Content of tabs --> <div class="content"> <!-- TODO: refacto this with account-info.component --> - <div *ngIf="currentTab === tabsEnum.coordinates"> + <div *ngIf="currentTab === tabsEnum.details"> <div class="form-group" fxLayout="column"> <label for="name">Prénom</label> <div fxLayout="row" fxLayoutGap="13px"> diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index e704485d1..8d02f6bfe 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -13,7 +13,7 @@ import { CustomRegExp } from '../../utils/CustomRegExp'; import { ProfileService } from '../services/profile.service'; enum tabsEnum { - coordinates, + details, credentials, employer, description, @@ -33,7 +33,7 @@ enum showPasswordEnum { export class EditComponent implements OnInit { public tabsEnum = tabsEnum; public buttonTypeEnum = ButtonType; - public currentTab: tabsEnum = tabsEnum.coordinates; + public currentTab: tabsEnum = tabsEnum.details; @Input() userProfile: User; public initialUserProfile: User; @@ -154,7 +154,7 @@ export class EditComponent implements OnInit { } public isPageValid(): boolean { - if (this.currentTab === tabsEnum.coordinates) { + if (this.currentTab === tabsEnum.details) { return this.pageChanged() && this.phoneValid() && this.nameValid() && this.surnameValid(); } else if (this.currentTab === tabsEnum.credentials) { if (this.emailModal) { @@ -173,8 +173,8 @@ export class EditComponent implements OnInit { } public confirm(): void { - if (this.currentTab === tabsEnum.coordinates) { - this.confirmCoordinates(); + if (this.currentTab === tabsEnum.details) { + this.confirmDetails(); } else if (this.currentTab === tabsEnum.credentials) { if (this.emailModal) { this.confirmNewEmail(); @@ -188,9 +188,9 @@ export class EditComponent implements OnInit { } } - public confirmCoordinates(): void { + public confirmDetails(): void { this.profileService - .updateCoordinates({ + .updateDetails({ name: this.userProfile.name, surname: this.userProfile.surname, phone: this.userProfile.phone, diff --git a/src/app/profile/services/profile.service.ts b/src/app/profile/services/profile.service.ts index 93d175c98..50b1dadff 100644 --- a/src/app/profile/services/profile.service.ts +++ b/src/app/profile/services/profile.service.ts @@ -115,9 +115,9 @@ export class ProfileService { return this.http.post<User>(`${this.baseUrl}/profile`, { employerName, jobName }); } - public updateCoordinates(newCoordinates: { name: string; surname: string; phone: string }): Observable<User | Error> { - console.log('profile service updates coords'); - return this.http.post<User>(`${this.baseUrl}/coordinates`, newCoordinates).pipe( + public updateDetails(newDetails: { name: string; surname: string; phone: string }): Observable<User | Error> { + console.log('profile service updates details'); + return this.http.post<User>(`${this.baseUrl}/details`, newDetails).pipe( map((user) => user), catchError(() => { this.notificationService.showError('Une erreur est survenue', ''); -- GitLab From 3fca9b0d523950c338d0b6ed73887ab0033b04f8 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Mon, 23 May 2022 15:38:26 +0200 Subject: [PATCH 42/47] ancien mdp -> Mot de passe --- src/app/profile/edit/edit.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index 99ac06ee5..0a375933a 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -415,7 +415,7 @@ Cette action est définitive, veuillez donc entrer votre mot de passe afin de supprimer votre compte </p> <div class="form-group"> - <label for="oldPassword">Ancien mot de passe</label> + <label for="oldPassword">Mot de passe</label> <div fxLayout="row" fxLayoutAlign="none center" fxLayoutGap="13px"> <input [type]="isShowPassword.oldPassword ? 'text' : 'password'" -- GitLab From 3424a0a99649c3b99d0a6b3cd17d2ab80a09ac9a Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Mon, 23 May 2022 16:07:27 +0200 Subject: [PATCH 43/47] prevent validation when switching pages --- src/app/profile/edit/edit.component.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index 8d02f6bfe..1ecd39880 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -118,8 +118,12 @@ export class EditComponent implements OnInit { ); } - public pageChanged(): boolean { - return JSON.stringify(this.initialUserProfile) !== JSON.stringify(this.userProfile); + public detailsChanged(): boolean { + return ( + this.initialUserProfile.name !== this.userProfile.name || + this.initialUserProfile.surname !== this.userProfile.surname || + this.initialUserProfile.phone !== this.userProfile.phone + ); } public navigateTo(tab: tabsEnum): void { @@ -155,7 +159,7 @@ export class EditComponent implements OnInit { public isPageValid(): boolean { if (this.currentTab === tabsEnum.details) { - return this.pageChanged() && this.phoneValid() && this.nameValid() && this.surnameValid(); + return this.detailsChanged() && this.phoneValid() && this.nameValid() && this.surnameValid(); } else if (this.currentTab === tabsEnum.credentials) { if (this.emailModal) { return this.emailValid(this.newEmail) && this.newEmail === this.newEmailConfirm; @@ -168,7 +172,7 @@ export class EditComponent implements OnInit { this.selectedJob.name !== this.userProfile.job.name ); } else if (this.currentTab === tabsEnum.description) { - return this.pageChanged() && this.descriptionValid(); + return this.descriptionValid() && this.initialUserProfile.description !== this.userProfile.description; } } -- GitLab From 0d223253d8e32771385ddd888a25816fe52a9b1d Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Mon, 23 May 2022 14:41:29 +0000 Subject: [PATCH 44/47] fix error when no jobs or employer --- src/app/profile/edit/edit.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index 1ecd39880..b6da22633 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -168,8 +168,8 @@ export class EditComponent implements OnInit { } } else if (this.currentTab === tabsEnum.employer) { return !!( - this.selectedEmployer.name !== this.userProfile.employer.name || - this.selectedJob.name !== this.userProfile.job.name + this.selectedEmployer?.name !== this.userProfile.employer?.name || + this.selectedJob?.name !== this.userProfile.job?.name ); } else if (this.currentTab === tabsEnum.description) { return this.descriptionValid() && this.initialUserProfile.description !== this.userProfile.description; -- GitLab From 90fc0abfff7896e3826ed04dca4479f32182d3cd Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Mon, 23 May 2022 17:05:02 +0200 Subject: [PATCH 45/47] nullcheck on job and employer --- src/app/profile/edit/edit.component.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index b6da22633..dfd145f65 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -84,11 +84,11 @@ export class EditComponent implements OnInit { this.jobs = [...jobs, otherJob]; // Select "Autre" job and set the job's name - if (!!this.jobs.indexOf(profile.job)) { + if (jobs.some((job) => job.name === profile.job?.name)) { + this.selectedJob = { ...profile.job }; + } else { this.selectedJob = otherJob; this.newJob = profile.job; - } else { - this.selectedJob = { ...profile.job }; } }); }); @@ -131,7 +131,7 @@ export class EditComponent implements OnInit { if (tab === tabsEnum.employer) { this.cdr.detectChanges(); this.selectEmployer(this.userProfile.employer); - this.newJobInput.nativeElement.value = this.userProfile.job.name; + if (this.newJob) this.newJobInput.nativeElement.value = this.userProfile.job.name; } } @@ -316,7 +316,7 @@ export class EditComponent implements OnInit { } public selectEmployer(employer: Employer): void { - this.searchEmployer.nativeElement.value = employer.name; + if (employer) this.searchEmployer.nativeElement.value = employer.name; this.selectedEmployer = employer; this.employers = []; } -- GitLab From b524c5a1cb00762876a11f229be180836c9b617f Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Tue, 24 May 2022 10:06:04 +0200 Subject: [PATCH 46/47] update name in auth service --- src/app/profile/edit/edit.component.ts | 9 +++------ src/app/services/auth.service.ts | 5 ++--- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index dfd145f65..1b52e79f6 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -37,7 +37,6 @@ export class EditComponent implements OnInit { @Input() userProfile: User; public initialUserProfile: User; - private userSubject: BehaviorSubject<UserAuth>; private emailModal = false; private passwordModal = false; private deleteAccountModal = false; @@ -65,9 +64,7 @@ export class EditComponent implements OnInit { private notificationService: NotificationService, private cdr: ChangeDetectorRef, private authService: AuthService - ) { - this.userSubject = new BehaviorSubject<UserAuth>(JSON.parse(localStorage.getItem('user'))); - } + ) {} ngOnInit(): void { if (history.state.data === 'description') { @@ -203,13 +200,13 @@ export class EditComponent implements OnInit { this.notificationService.showSuccess('L’action a bien été effectuée.', ''); //Update localstorage const updatedUser = { - ...this.userSubject.value, + ...this.authService.userSubject.value, name: user.name, surname: user.surname, phone: user.phone, }; localStorage.setItem('user', JSON.stringify(updatedUser)); - this.userSubject.next(updatedUser); + this.authService.userSubject.next(updatedUser); this.updateInitialProfile(); }); } diff --git a/src/app/services/auth.service.ts b/src/app/services/auth.service.ts index 4726f2070..c5b7ec730 100644 --- a/src/app/services/auth.service.ts +++ b/src/app/services/auth.service.ts @@ -1,6 +1,5 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { Router } from '@angular/router'; import { DateTime } from 'luxon'; import { BehaviorSubject, Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @@ -10,10 +9,10 @@ import { User } from '../models/user.model'; providedIn: 'root', }) export class AuthService { - private userSubject: BehaviorSubject<UserAuth>; + public userSubject: BehaviorSubject<UserAuth>; public user: Observable<UserAuth>; - constructor(private http: HttpClient, private router: Router) { + constructor(private http: HttpClient) { this.userSubject = new BehaviorSubject<UserAuth>(JSON.parse(localStorage.getItem('user'))); this.user = this.userSubject.asObservable(); } -- GitLab From b6a3c898b8485e4b1e5a5887b0c2c46b05b42a62 Mon Sep 17 00:00:00 2001 From: Bastien DUMONT <bdumont@grandlyon.com> Date: Tue, 24 May 2022 10:19:09 +0200 Subject: [PATCH 47/47] update notif text --- src/app/profile/edit/edit.component.html | 2 +- src/app/profile/edit/edit.component.ts | 23 +++++++++++------------ src/app/services/notification.service.ts | 4 ++-- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html index 0a375933a..38c78c377 100644 --- a/src/app/profile/edit/edit.component.html +++ b/src/app/profile/edit/edit.component.html @@ -412,7 +412,7 @@ <div class="modalContent"> <p class="warnText"> - Cette action est définitive, veuillez donc entrer votre mot de passe afin de supprimer votre compte + Cette action est définitive, veuillez entrer votre mot de passe afin de supprimer votre compte </p> <div class="form-group"> <label for="oldPassword">Mot de passe</label> diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts index 1b52e79f6..ca4a6e475 100644 --- a/src/app/profile/edit/edit.component.ts +++ b/src/app/profile/edit/edit.component.ts @@ -1,16 +1,15 @@ -import { HttpErrorResponse } from '@angular/common/http'; import { ChangeDetectorRef, Component, ElementRef, Input, OnInit, ViewChild } from '@angular/core'; -import { BehaviorSubject, forkJoin, of } from 'rxjs'; +import { HttpErrorResponse } from '@angular/common/http'; +import { forkJoin, of } from 'rxjs'; import { catchError, first, map } from 'rxjs/operators'; -import { Employer } from '../../models/employer.model'; import { Job } from '../../models/job.model'; -import { UserAuth } from '../../models/user-auth.model'; import { User } from '../../models/user.model'; +import { Employer } from '../../models/employer.model'; import { AuthService } from '../../services/auth.service'; +import { ProfileService } from '../services/profile.service'; import { NotificationService } from '../../services/notification.service'; import { ButtonType } from '../../shared/components/button/buttonType.enum'; import { CustomRegExp } from '../../utils/CustomRegExp'; -import { ProfileService } from '../services/profile.service'; enum tabsEnum { details, @@ -197,7 +196,7 @@ export class EditComponent implements OnInit { phone: this.userProfile.phone, }) .subscribe((user: User) => { - this.notificationService.showSuccess('L’action a bien été effectuée.', ''); + this.notificationService.showSuccess('Vos coordonnées ont bien été mises à jour'); //Update localstorage const updatedUser = { ...this.authService.userSubject.value, @@ -227,13 +226,13 @@ export class EditComponent implements OnInit { catchError(() => of()) ), }).subscribe(() => { - this.notificationService.showSuccess('L’action a bien été effectuée.', ''); + this.notificationService.showSuccess('Vos informations ont bien été enregistrées'); }); } public confirmDescription(): void { this.profileService.updateDescription(this.userProfile.description).subscribe(() => { - this.notificationService.showSuccess('L’action a bien été effectuée.', ''); + this.notificationService.showSuccess('Vos description a bien été enregistrée'); this.updateInitialProfile(); }); } @@ -247,7 +246,7 @@ export class EditComponent implements OnInit { if (this.emailValid(this.newEmail) && this.newEmail === this.newEmailConfirm) { this.profileService.changeEmail(this.newEmail, this.userProfile.email).subscribe(() => { this.closeModal(); - this.notificationService.showSuccess('Veuillez confirmer votre nouvelle adresse grâce au mail envoyé.', ''); + this.notificationService.showSuccess('Veuillez confirmer votre nouvelle adresse grâce au mail envoyé', ''); }); } } @@ -265,7 +264,7 @@ export class EditComponent implements OnInit { }) ) .subscribe(() => { - this.notificationService.showSuccess('Votre mot de passe a bien été modifié.', ''); + this.notificationService.showSuccess('Votre mot de passe a bien été modifié', ''); this.closeModal(); }); this.oldPassword = ''; @@ -280,13 +279,13 @@ export class EditComponent implements OnInit { .subscribe( () => { this.profileService.deleteProfile().subscribe(() => { - this.notificationService.showSuccess('Votre compte a bien été supprimé.', ''); + this.notificationService.showSuccess('Votre compte a bien été supprimé', ''); this.closeModal(); this.authService.logout(); }); }, () => { - this.notificationService.showError('Une erreur est survenue.', ''); + this.notificationService.showError('Une erreur est survenue', ''); } ); } diff --git a/src/app/services/notification.service.ts b/src/app/services/notification.service.ts index fcc0129db..5b491fd86 100644 --- a/src/app/services/notification.service.ts +++ b/src/app/services/notification.service.ts @@ -7,14 +7,14 @@ import { ToastrService } from 'ngx-toastr'; export class NotificationService { constructor(private toastr: ToastrService) {} - public showSuccess(message: string, title: string, timespan: number = 10000): void { + public showSuccess(message: string, title: string = '', timespan: number = 10000): void { this.toastr.success(message, title, { timeOut: timespan, }); } // Par defaut, l'erreur reste affichée jusqu'à ce qu'on clique dessus - public showError(message: string, title: string, timespan: number = 0): void { + public showError(message: string, title: string = '', timespan: number = 0): void { this.toastr.error(message, title, { timeOut: timespan, disableTimeOut: timespan ? false : true, -- GitLab