From ece56f5aedaea25d353e931bacf4559d40c13c28 Mon Sep 17 00:00:00 2001
From: Etienne LOUPIAS <eloupias@grandlyon.com>
Date: Fri, 16 Sep 2022 08:00:23 +0000
Subject: [PATCH] feat(profile): add structure owners screen

---
 .../form/footer-form/footer-form.component.ts |  20 ++-
 .../account-credentials.component.scss        |   5 +
 .../account-form/account-form.component.html  |   1 +
 .../account-form/account-form.component.ts    |   2 +-
 .../form-view/form-view-routing.module.ts     |  11 ++
 .../form/form-view/form-view.component.html   |   9 +-
 src/app/form/form-view/form-view.component.ts | 151 ++++++++++++------
 src/app/form/form-view/formType.enum.ts       |   1 +
 .../form-view/guards/personalOffer.guard.ts   |   6 +-
 .../personal-offer-form.component.ts          |   4 +-
 src/app/models/owner.model.ts                 |   2 +
 src/app/models/temp-user.model.ts             |   1 +
 src/app/profile/profile-routing.module.ts     |  10 ++
 src/app/profile/profile.module.ts             |  12 +-
 .../structure-add-member-modal.component.html |  32 ++++
 .../structure-add-member-modal.component.scss |  44 +++++
 ...ructure-add-member-modal.component.spec.ts |  24 +++
 .../structure-add-member-modal.component.ts   |  54 +++++++
 ...tructure-members-management.component.html |  92 +++++++++++
 ...tructure-members-management.component.scss |  83 ++++++++++
 ...cture-members-management.component.spec.ts |  24 +++
 .../structure-members-management.component.ts | 112 +++++++++++++
 src/app/resolvers/temp-user.resolver.ts       |   2 +-
 src/app/services/structure.service.ts         |   7 +
 .../modal-options.component.html              |   4 +
 .../structure-options-modal.component.ts      |   3 +
 .../enum/functionTypeModalOptions.enum.ts     |   1 +
 .../structure-details.component.html          |   2 +-
 src/assets/ico/sprite.svg                     |   3 +
 29 files changed, 659 insertions(+), 63 deletions(-)
 create mode 100644 src/app/profile/structure-add-member-modal/structure-add-member-modal.component.html
 create mode 100644 src/app/profile/structure-add-member-modal/structure-add-member-modal.component.scss
 create mode 100644 src/app/profile/structure-add-member-modal/structure-add-member-modal.component.spec.ts
 create mode 100644 src/app/profile/structure-add-member-modal/structure-add-member-modal.component.ts
 create mode 100644 src/app/profile/structure-members-management/structure-members-management.component.html
 create mode 100644 src/app/profile/structure-members-management/structure-members-management.component.scss
 create mode 100644 src/app/profile/structure-members-management/structure-members-management.component.spec.ts
 create mode 100644 src/app/profile/structure-members-management/structure-members-management.component.ts

diff --git a/src/app/form/footer-form/footer-form.component.ts b/src/app/form/footer-form/footer-form.component.ts
index 67b905386..b83c8bdf0 100644
--- a/src/app/form/footer-form/footer-form.component.ts
+++ b/src/app/form/footer-form/footer-form.component.ts
@@ -17,13 +17,12 @@ import { stepType } from '../step.type';
 @Component({
   selector: 'app-footer-form',
   templateUrl: './footer-form.component.html',
-  styleUrls: ['./footer-form.component.scss']
+  styleUrls: ['./footer-form.component.scss'],
 })
 export class FooterFormComponent implements OnChanges {
   @Input() currentForm: formType;
   @Input() isValid: boolean;
   @Input() isClaimMode: boolean;
-  @Input() isAccountMode: boolean;
   @Input() btnName: string[];
   @Input() nbPagesForm: number;
   @Input() form: UntypedFormGroup;
@@ -74,7 +73,8 @@ export class FooterFormComponent implements OnChanges {
       }
       if (
         this.currentForm === formType.structure &&
-        (this.currentStep === structureFormStep.noStructure || this.currentStep === structureFormStep.StructureInfoUnknown)
+        (this.currentStep === structureFormStep.noStructure ||
+          this.currentStep === structureFormStep.StructureInfoUnknown)
       ) {
         this.isLastFormStep = true;
       }
@@ -134,8 +134,11 @@ export class FooterFormComponent implements OnChanges {
       const user = new User(this.form.value);
       // Create user with structure
       user.structuresLink = this.linkedStructureId;
-      this.authService.register(user).subscribe(() => {});
-      this.newsletterService.newsletterSubscribe(user.email).subscribe(() => {});
+      this.authService.register(user).subscribe(() => {
+        if (this.acceptNewsletter) {
+          this.newsletterService.newsletterSubscribe(user.email).subscribe();
+        }
+      });
       document.getElementsByClassName('page')[0].scrollTo(0, 0);
     }
     if (this.isProfileLastPage()) {
@@ -195,7 +198,9 @@ export class FooterFormComponent implements OnChanges {
 
   private isStructureChoiceValid(): boolean {
     return (
-      this.currentForm === formType.structure && this.currentStep === structureFormStep.structureChoice && this.form.value._id
+      this.currentForm === formType.structure &&
+      this.currentStep === structureFormStep.structureChoice &&
+      this.form.value._id
     );
   }
 
@@ -215,7 +220,8 @@ export class FooterFormComponent implements OnChanges {
 
   private isPersonalOfferpage(): boolean {
     return (
-      this.currentForm === formType.personaloffer && this.currentStep === personalOfferFormStep.personalOfferStructureChoice
+      this.currentForm === formType.personaloffer &&
+      this.currentStep === personalOfferFormStep.personalOfferStructureChoice
     );
   }
   public isPersonalOfferFirstPage(): boolean {
diff --git a/src/app/form/form-view/account-form/account-credentials/account-credentials.component.scss b/src/app/form/form-view/account-form/account-credentials/account-credentials.component.scss
index 6399786d7..26d92dee3 100644
--- a/src/app/form/form-view/account-form/account-credentials/account-credentials.component.scss
+++ b/src/app/form/form-view/account-form/account-credentials/account-credentials.component.scss
@@ -1,6 +1,11 @@
 @import '../../../../../assets/scss/color';
 @import '../../../../../assets/scss/typography';
 
+.disabled {
+  opacity: 0.4;
+  cursor: not-allowed;
+}
+
 p.special {
   @include lato-regular-14;
   color: $grey-3;
diff --git a/src/app/form/form-view/account-form/account-form.component.html b/src/app/form/form-view/account-form/account-form.component.html
index eda10b761..deda50a65 100644
--- a/src/app/form/form-view/account-form/account-form.component.html
+++ b/src/app/form/form-view/account-form/account-form.component.html
@@ -11,6 +11,7 @@
     <app-account-credentials
       [accountForm]="accountForm"
       [profile]="profile"
+      [isAccountMode]="isAccountMode"
       (validateForm)="setValidationsForm($event)"
       (userExists)="verifyUserExist($event)"
     ></app-account-credentials>
diff --git a/src/app/form/form-view/account-form/account-form.component.ts b/src/app/form/form-view/account-form/account-form.component.ts
index 9711d32af..423527209 100644
--- a/src/app/form/form-view/account-form/account-form.component.ts
+++ b/src/app/form/form-view/account-form/account-form.component.ts
@@ -14,8 +14,8 @@ export class AccountFormComponent implements OnChanges {
   @Input() nbSteps: number;
   @Input() currentStep: accountFormStep;
   @Input() accountForm: UntypedFormGroup;
+  @Input() isAccountMode: boolean;
   public isClaimMode = false;
-  public isAccountMode = false;
   public pagesValidation = [];
   public userAcceptSavedDate = false;
   public isPageValid: boolean;
diff --git a/src/app/form/form-view/form-view-routing.module.ts b/src/app/form/form-view/form-view-routing.module.ts
index 12765adf2..57186ba5c 100644
--- a/src/app/form/form-view/form-view-routing.module.ts
+++ b/src/app/form/form-view/form-view-routing.module.ts
@@ -1,8 +1,10 @@
 import { NgModule } from '@angular/core';
 import { Routes, RouterModule } from '@angular/router';
 import { AuthGuard } from '../../guards/auth.guard';
+import { DeactivateGuard } from '../../guards/deactivate.guard';
 import { RoleGuard } from '../../guards/role.guard';
 import { StructureResolver } from '../../resolvers/structure.resolver';
+import { TempUserResolver } from '../../resolvers/temp-user.resolver';
 import { RouteRole } from '../../shared/enum/routeRole.enum';
 import { AccountFormComponent } from './account-form/account-form.component';
 import { FormViewComponent } from './form-view.component';
@@ -21,9 +23,18 @@ const routes: Routes = [
       structure: StructureResolver,
     },
   },
+  {
+    path: 'register/:id',
+    component: FormViewComponent,
+    canDeactivate: [DeactivateGuard],
+    resolve: {
+      user: TempUserResolver,
+    },
+  },
   {
     path: '',
     component: FormViewComponent,
+    canDeactivate: [DeactivateGuard],
     children: [
       {
         path: 'structure',
diff --git a/src/app/form/form-view/form-view.component.html b/src/app/form/form-view/form-view.component.html
index ed72d6c08..a4089fd03 100644
--- a/src/app/form/form-view/form-view.component.html
+++ b/src/app/form/form-view/form-view.component.html
@@ -1,4 +1,9 @@
 <div class="formView">
+  <app-modal-confirmation
+    [openned]="showConfirmationModal"
+    [content]="'Il vous faudra de nouveau remplir le formulaire si vous quittez'"
+    (closed)="hasRedirectionAccepted($event)"
+  ></app-modal-confirmation>
   <app-progress-bar
     [formType]="formType[routeParam]"
     [isEditMode]="isEditMode"
@@ -6,12 +11,13 @@
     [nbSteps]="nbSteps"
   ></app-progress-bar>
   <div class="page">
-    <ng-container *ngIf="formType[routeParam] === formType.account">
+    <ng-container *ngIf="formType[routeParam] === formType.account || formType[this.routeParam] === formType.register">
       <app-account-form
         [nbSteps]="nbSteps"
         [accountForm]="accountForm"
         [hoursForm]="hoursForm"
         [currentStep]="currentPage"
+        [isAccountMode]="isAccountMode"
         (goNext)="nextPage()"
         (pageValid)="validatePage($event)"
         (acceptNewsletter)="acceptReceiveNewsletter($event)"
@@ -57,6 +63,7 @@
     [currentStep]="currentPage"
     [currentForm]="currentFormType"
     [form]="currentForm"
+    [linkedStructureId]="linkedStructureId"
     [btnName]="['Précédent', 'Suivant']"
     [isValid]="isPageValid"
     [acceptNewsletter]="userAcceptNewsletter"
diff --git a/src/app/form/form-view/form-view.component.ts b/src/app/form/form-view/form-view.component.ts
index c9874c160..4c902fe7f 100644
--- a/src/app/form/form-view/form-view.component.ts
+++ b/src/app/form/form-view/form-view.component.ts
@@ -24,7 +24,7 @@ import { structureFormStep } from './structure-form/structureFormStep.enum';
 @Component({
   selector: 'app-form-view',
   templateUrl: './form-view.component.html',
-  styleUrls: ['./form-view.component.scss']
+  styleUrls: ['./form-view.component.scss'],
 })
 export class FormViewComponent implements OnInit {
   public routeParam: string;
@@ -62,6 +62,10 @@ export class FormViewComponent implements OnInit {
   public showWebsite: boolean;
   public showSocialNetwork: boolean;
 
+  // Modal canExit var
+  public showConfirmationModal = false;
+  private resolve: Function;
+
   public profile: User;
   public isAccountMode: boolean = false;
   public isClaimMode: boolean = false;
@@ -71,6 +75,7 @@ export class FormViewComponent implements OnInit {
   public structureWithOwners: StructureWithOwners;
   public isPageValid: boolean = false;
   public hoursForm: UntypedFormGroup;
+  public isRegisterNewMember: boolean = false;
 
   constructor(
     private router: Router,
@@ -87,26 +92,19 @@ export class FormViewComponent implements OnInit {
     this.initPage();
     this.profileService.getProfile().then((user: User) => {
       this.profile = user;
+
+      if (!this.isEditMode && this.profile) {
+        if (this.profile.structuresLink.length) {
+          // if register a new user as a new member structure, no structure to choose
+          this.isRegisterNewMember = true;
+          this.structureService.getStructure(this.profile.structuresLink[0]).subscribe((structure) => {
+            this.structure = new Structure(structure);
+          });
+        }
+      }
     });
     // Check if it's a new structure or edit structure
-    // this.isLoading = false;
-    if (history.state.newUser) {
-      this.isClaimMode = true;
-      // Handle join structure, the case is very similar to claim
-      if (history.state.isJoin) {
-        this.isJoinMode = true;
-      }
-      this.createAccountForm();
-      this.claimStructure = history.state.newUser;
-    }
-    // Handle account creation when pre-register
     this.route.data.subscribe((data) => {
-      if (data.user) {
-        this.isAccountMode = true;
-        this.createAccountForm(data.user.email);
-        this.linkedStructureId = data.user.pendingStructuresLink;
-        this.currentPage = accountFormStep.accountInfo;
-      }
       if (data.structure) {
         this.isEditMode = true;
         this.structure = data.structure;
@@ -138,6 +136,19 @@ export class FormViewComponent implements OnInit {
       this.createAccountForm();
       this.currentForm = this.accountForm;
     }
+    if (formType[this.routeParam] === formType.register) {
+      this.nbSteps = 3;
+      this.currentPage = accountFormStep.accountInfo;
+      this.currentFormType = formType.account;
+      this.route.data.subscribe((data) => {
+        if (data.user) {
+          this.createAccountForm(data.user.email);
+          this.linkedStructureId = data.user.pendingStructuresLink;
+          this.currentForm = this.accountForm;
+          this.isAccountMode = true;
+        }
+      });
+    }
     if (formType[this.routeParam] === formType.profile) {
       this.nbSteps = totalFormSteps;
       this.currentPage = profileFormStep.profileBeginningInfo;
@@ -175,15 +186,21 @@ export class FormViewComponent implements OnInit {
   private createAccountForm(email?: string): void {
     this.accountForm = new UntypedFormGroup(
       {
-        email: new UntypedFormControl(email ? email : '', [Validators.required, Validators.pattern(CustomRegExp.EMAIL)]),
+        email: new UntypedFormControl(email ? email : '', [
+          Validators.required,
+          Validators.pattern(CustomRegExp.EMAIL),
+        ]),
         name: new UntypedFormControl('', [Validators.required, Validators.pattern(CustomRegExp.TEXT_WITHOUT_NUMBER)]),
-        surname: new UntypedFormControl('', [Validators.required, Validators.pattern(CustomRegExp.TEXT_WITHOUT_NUMBER)]),
+        surname: new UntypedFormControl('', [
+          Validators.required,
+          Validators.pattern(CustomRegExp.TEXT_WITHOUT_NUMBER),
+        ]),
         phone: new UntypedFormControl('', [Validators.required, Validators.pattern(CustomRegExp.PHONE)]),
         password: new UntypedFormControl('', [
           Validators.required,
-          Validators.pattern(CustomRegExp.PASSWORD) //NOSONAR
+          Validators.pattern(CustomRegExp.PASSWORD), //NOSONAR
         ]),
-        confirmPassword: new UntypedFormControl('')
+        confirmPassword: new UntypedFormControl(''),
       },
       [MustMatch('password', 'confirmPassword')]
     );
@@ -193,14 +210,14 @@ export class FormViewComponent implements OnInit {
     this.profileForm = new UntypedFormGroup({
       employer: new UntypedFormGroup({
         name: new UntypedFormControl('', [Validators.required]),
-        validated: new UntypedFormControl(false, [Validators.required])
+        validated: new UntypedFormControl(false, [Validators.required]),
       }),
       job: new UntypedFormGroup({
         name: new UntypedFormControl('', [Validators.required]),
         validated: new UntypedFormControl(true, [Validators.required]),
-        hasPersonalOffer: new UntypedFormControl(true, [Validators.required])
+        hasPersonalOffer: new UntypedFormControl(true, [Validators.required]),
       }),
-      structure: new UntypedFormControl('', [Validators.required])
+      structure: new UntypedFormControl('', [Validators.required]),
     });
   }
 
@@ -216,7 +233,7 @@ export class FormViewComponent implements OnInit {
       accessRight: new UntypedFormControl(personalOffer.accessRight),
       digitalCultureSecurity: new UntypedFormControl(personalOffer.digitalCultureSecurity),
       socialAndProfessional: new UntypedFormControl(personalOffer.socialAndProfessional),
-      parentingHelp: new UntypedFormControl(personalOffer.parentingHelp)
+      parentingHelp: new UntypedFormControl(personalOffer.parentingHelp),
     });
   }
 
@@ -316,11 +333,20 @@ export class FormViewComponent implements OnInit {
       profile: this.profileService
         .updateProfile(this.profileForm.get('employer').value.name, this.profileForm.get('job').value.name)
         .pipe(
-          map((res) => res),
+          map((res) => (this.profile = res)),
           catchError((_e) => of())
-        )
-    }).subscribe(() => {
-      this.router.navigateByUrl('form/structure');
+        ),
+    }).subscribe(async () => {
+      // if register a new user as a new member structure, no structure to choose
+      if (this.isRegisterNewMember) {
+        if (this.profile.job && this.profile.job.hasPersonalOffer) {
+          this.router.navigateByUrl('form/personaloffer');
+        } else {
+          this.router.navigateByUrl('/profile');
+        }
+      } else {
+        this.router.navigateByUrl('form/structure');
+      }
     });
   }
 
@@ -338,7 +364,7 @@ export class FormViewComponent implements OnInit {
     const newStructure = new Structure(this.structureForm.value);
     newStructure.hours = this.hoursForm.value;
     this.structureService.createStructure(newStructure, this.profile).subscribe((struct) => {
-      if (user.job.hasPersonalOffer) {
+      if (user.job && user.job.hasPersonalOffer) {
         this.structure = struct;
         this.router.navigateByUrl('form/personaloffer');
       } else {
@@ -365,30 +391,30 @@ export class FormViewComponent implements OnInit {
     switch (currentPage) {
       case structureFormStep.structureChoice:
         return {
-          _id: this.structureForm.get('_id').value
+          _id: this.structureForm.get('_id').value,
         };
       case structureFormStep.structureNameAndAddress:
         return {
           structureName: this.structureForm.get('structureName').value,
-          address: this.structureForm.get('address').value
+          address: this.structureForm.get('address').value,
         };
       case structureFormStep.structureContact:
         return {
           contactPhone: this.structureForm.get('contactPhone').value,
-          contactMail: this.structureForm.get('contactMail').value
+          contactMail: this.structureForm.get('contactMail').value,
         };
       case structureFormStep.structureAccessModality:
         return {
-          accessModality: this.structureForm.get('accessModality').value
+          accessModality: this.structureForm.get('accessModality').value,
         };
       case structureFormStep.structureHours:
         return {
           hours: this.hoursForm.value,
-          exceptionalClosures: this.structureForm.get('exceptionalClosures').value
+          exceptionalClosures: this.structureForm.get('exceptionalClosures').value,
         };
       case structureFormStep.structurePmr:
         return {
-          pmrAccess: this.structureForm.get('pmrAccess').value
+          pmrAccess: this.structureForm.get('pmrAccess').value,
         };
       case structureFormStep.structureWebAndSocialNetwork:
         return {
@@ -396,13 +422,13 @@ export class FormViewComponent implements OnInit {
           instagram: this.structureForm.get('instagram').value,
           linkedin: this.structureForm.get('linkedin').value,
           twitter: this.structureForm.get('twitter').value,
-          website: this.structureForm.get('website').value
+          website: this.structureForm.get('website').value,
         };
       case structureFormStep.structurePublicTarget:
         return { publics: this.structureForm.get('publics').value };
       case structureFormStep.structureDigitalHelpingAccompaniment:
         return {
-          proceduresAccompaniment: this.structureForm.get('proceduresAccompaniment').value
+          proceduresAccompaniment: this.structureForm.get('proceduresAccompaniment').value,
         };
       case structureFormStep.structureTrainingType:
         return {
@@ -410,15 +436,15 @@ export class FormViewComponent implements OnInit {
           baseSkills: this.structureForm.get('baseSkills').value,
           digitalCultureSecurity: this.structureForm.get('digitalCultureSecurity').value,
           parentingHelp: this.structureForm.get('parentingHelp').value,
-          socialAndProfessional: this.structureForm.get('socialAndProfessional').value
+          socialAndProfessional: this.structureForm.get('socialAndProfessional').value,
         };
       case structureFormStep.structureTrainingPrice:
         return {
-          freeWorkShop: this.structureForm.get('freeWorkShop').value
+          freeWorkShop: this.structureForm.get('freeWorkShop').value,
         };
       case structureFormStep.structureWifi:
         return {
-          equipmentsAndServices: this.structureForm.get('equipmentsAndServices').value
+          equipmentsAndServices: this.structureForm.get('equipmentsAndServices').value,
         };
       case structureFormStep.structureEquipments:
         return {
@@ -426,28 +452,57 @@ export class FormViewComponent implements OnInit {
           nbNumericTerminal: this.structureForm.get('nbNumericTerminal').value,
           nbPrinters: this.structureForm.get('nbPrinters').value,
           nbScanners: this.structureForm.get('nbScanners').value,
-          nbTablets: this.structureForm.get('nbTablets').value
+          nbTablets: this.structureForm.get('nbTablets').value,
         };
       case structureFormStep.structureLabels:
         return {
-          labelsQualifications: this.structureForm.get('labelsQualifications').value
+          labelsQualifications: this.structureForm.get('labelsQualifications').value,
         };
       case structureFormStep.structureOtherServices:
         return {
-          equipmentsAndServices: this.structureForm.get('equipmentsAndServices').value
+          equipmentsAndServices: this.structureForm.get('equipmentsAndServices').value,
         };
       case structureFormStep.structureDescription:
         return {
-          description: this.structureForm.get('description').value
+          description: this.structureForm.get('description').value,
         };
       case structureFormStep.structureCovidInfo:
         return {
-          lockdownActivity: this.structureForm.get('lockdownActivity').value
+          lockdownActivity: this.structureForm.get('lockdownActivity').value,
         };
       case structureFormStep.structureConsent:
         return {
-          dataShareConsentDate: this.structureForm.get('dataShareConsentDate').value ? new Date().toString() : null
+          dataShareConsentDate: this.structureForm.get('dataShareConsentDate').value ? new Date().toString() : null,
         };
     }
   }
+
+  public canExit(): Promise<boolean> {
+    // List all exit pages in order to authorise exit
+    const exitPages: stepType[] = [
+      structureFormStep.noStructure,
+      structureFormStep.structureCreationFinishedInfo,
+      profileFormStep.profileJobSelection,
+      personalOfferFormStep.personalOfferFinishedInfo,
+    ];
+    // Avoid confirmation when user submit form and leave.
+    if (
+      this.currentPage === this.nbSteps ||
+      this.currentPage < 1 ||
+      this.isEditMode ||
+      exitPages.includes(this.currentPage)
+    ) {
+      return new Promise((resolve) => resolve(true));
+    } else {
+      return new Promise((resolve) => this.showModal(resolve));
+    }
+  }
+  private showModal(resolve: Function): void {
+    this.showConfirmationModal = true;
+    this.resolve = resolve;
+  }
+  public hasRedirectionAccepted(hasAccept: boolean): void {
+    this.resolve(hasAccept);
+    this.showConfirmationModal = false;
+  }
 }
diff --git a/src/app/form/form-view/formType.enum.ts b/src/app/form/form-view/formType.enum.ts
index c82157735..d5a7dd7dc 100644
--- a/src/app/form/form-view/formType.enum.ts
+++ b/src/app/form/form-view/formType.enum.ts
@@ -3,4 +3,5 @@ export enum formType {
   profile,
   personaloffer,
   account,
+  register,
 }
diff --git a/src/app/form/form-view/guards/personalOffer.guard.ts b/src/app/form/form-view/guards/personalOffer.guard.ts
index 32b7d71c2..d7fc5a8bf 100644
--- a/src/app/form/form-view/guards/personalOffer.guard.ts
+++ b/src/app/form/form-view/guards/personalOffer.guard.ts
@@ -8,7 +8,11 @@ export class PersonalOfferGuard implements CanActivate {
   constructor(private router: Router) {}
 
   canActivate(route: ActivatedRouteSnapshot): UrlTree | boolean {
-    if (route.routeConfig.path === 'personaloffer' && this.router.routerState.snapshot.url === '/form/structure') {
+    if (
+      route.routeConfig.path === 'personaloffer' &&
+      (this.router.routerState.snapshot.url === '/form/profile' ||
+        this.router.routerState.snapshot.url === '/form/structure')
+    ) {
       return true;
     }
     return this.router.parseUrl('/home');
diff --git a/src/app/form/form-view/personal-offer-form/personal-offer-form.component.ts b/src/app/form/form-view/personal-offer-form/personal-offer-form.component.ts
index 9fc9ff204..6312c60da 100644
--- a/src/app/form/form-view/personal-offer-form/personal-offer-form.component.ts
+++ b/src/app/form/form-view/personal-offer-form/personal-offer-form.component.ts
@@ -1,4 +1,4 @@
-import { Component, EventEmitter, Input, Output, SimpleChanges } from '@angular/core';
+import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
 import { UntypedFormGroup } from '@angular/forms';
 import { Router } from '@angular/router';
 import { formType } from '../formType.enum';
@@ -8,7 +8,7 @@ import { personalOfferFormStep } from './personalOfferFormStep.enum';
   selector: 'app-personal-offer-form',
   templateUrl: './personal-offer-form.component.html',
 })
-export class PersonalOfferFormComponent {
+export class PersonalOfferFormComponent implements OnChanges {
   @Input() nbSteps: number;
   @Input() currentStep: personalOfferFormStep;
   @Input() personalOfferForm: UntypedFormGroup;
diff --git a/src/app/models/owner.model.ts b/src/app/models/owner.model.ts
index 45a6de715..7342b3bce 100644
--- a/src/app/models/owner.model.ts
+++ b/src/app/models/owner.model.ts
@@ -1,4 +1,6 @@
 export class Owner {
   email: string;
   _id: string;
+  name: string;
+  surname: string;
 }
diff --git a/src/app/models/temp-user.model.ts b/src/app/models/temp-user.model.ts
index 8540ce74e..6572cb280 100644
--- a/src/app/models/temp-user.model.ts
+++ b/src/app/models/temp-user.model.ts
@@ -2,4 +2,5 @@ export class TempUser {
   _id: string;
   email: string;
   pendingStructuresLink: string[];
+  updatedAt: string;
 }
diff --git a/src/app/profile/profile-routing.module.ts b/src/app/profile/profile-routing.module.ts
index efa2a89b3..688a99bc9 100644
--- a/src/app/profile/profile-routing.module.ts
+++ b/src/app/profile/profile-routing.module.ts
@@ -3,6 +3,7 @@ import { Routes, RouterModule } from '@angular/router';
 import { RoleGuard } from '../guards/role.guard';
 import { StructureResolver } from '../resolvers/structure.resolver';
 import { RouteRole } from '../shared/enum/routeRole.enum';
+import { StructureMembersManagementComponent } from './structure-members-management/structure-members-management.component';
 import { ProfileComponent } from './profile.component';
 import { StructureEditionSummaryComponent } from './structure-edition-summary/structure-edition-summary.component';
 
@@ -29,6 +30,15 @@ const routes: Routes = [
       structure: StructureResolver,
     },
   },
+  {
+    path: 'structure-members-management/:id',
+    component: StructureMembersManagementComponent,
+    canActivate: [RoleGuard],
+    data: { allowedRoles: [RouteRole.structureAdmin] },
+    resolve: {
+      structure: StructureResolver,
+    },
+  },
 ];
 @NgModule({
   imports: [RouterModule.forChild(routes)],
diff --git a/src/app/profile/profile.module.ts b/src/app/profile/profile.module.ts
index 7de2f27ce..1060d16a0 100644
--- a/src/app/profile/profile.module.ts
+++ b/src/app/profile/profile.module.ts
@@ -5,11 +5,21 @@ import { CommonModule } from '@angular/common';
 import { ProfileRoutingModule } from './profile-routing.module';
 import { StructureEditionSummaryComponent } from './structure-edition-summary/structure-edition-summary.component';
 import { EditComponent } from './edit/edit.component';
+import { StructureMembersManagementComponent } from './structure-members-management/structure-members-management.component';
+import { StructureAddMemberModalComponent } from './structure-add-member-modal/structure-add-member-modal.component';
 import { MissingInformationComponent } from './structure-edition-summary/missing-information/missing-information.component';
 import { NoInformationComponent } from './structure-edition-summary/no-information/no-information.component';
 
 @NgModule({
-  declarations: [ProfileComponent, StructureEditionSummaryComponent, EditComponent, MissingInformationComponent, NoInformationComponent],
+  declarations: [
+    ProfileComponent,
+    StructureEditionSummaryComponent,
+    EditComponent,
+    StructureMembersManagementComponent,
+    StructureAddMemberModalComponent,
+    MissingInformationComponent,
+    NoInformationComponent,
+  ],
   imports: [CommonModule, ProfileRoutingModule, SharedModule],
 })
 export class ProfileModule {}
diff --git a/src/app/profile/structure-add-member-modal/structure-add-member-modal.component.html b/src/app/profile/structure-add-member-modal/structure-add-member-modal.component.html
new file mode 100644
index 000000000..b8aea48a5
--- /dev/null
+++ b/src/app/profile/structure-add-member-modal/structure-add-member-modal.component.html
@@ -0,0 +1,32 @@
+<div class="modalBackground">
+  <div class="modal">
+    <div class="modalHeader">
+      <h3>Ajouter un membre</h3>
+    </div>
+    <form [formGroup]="formAddAccount" class="modalContent">
+      <div class="form-group" fxLayout="column">
+        <label for="email">Email de la personne à ajouter</label>
+        <p *ngIf="ownerAlreadyLinked" class="special invalid">L'email est déjà rattaché à la structure.</p>
+        <div fxLayout="row" fxLayoutGap="13px">
+          <input type="text" formControlName="email" class="form-input" autocomplete="on" />
+          <app-svg-icon *ngIf="fAddAccount.email.valid" [type]="'form'" [icon]="'validate'"></app-svg-icon>
+          <app-svg-icon
+            *ngIf="fAddAccount.email.invalid && fAddAccount.email.value"
+            [type]="'form'"
+            [icon]="'notValidate'"
+          ></app-svg-icon>
+        </div>
+      </div>
+      <div class="buttons" fxLayout="row" fxLayoutAlign="space-between center">
+        <app-button [text]="'Annuler'" (action)="closeModal(false)"></app-button>
+        <app-button
+          [text]="'Valider'"
+          [disabled]="formAddAccount.invalid"
+          (action)="addOwner()"
+          [style]="buttonTypeEnum.Primary"
+        >
+        </app-button>
+      </div>
+    </form>
+  </div>
+</div>
diff --git a/src/app/profile/structure-add-member-modal/structure-add-member-modal.component.scss b/src/app/profile/structure-add-member-modal/structure-add-member-modal.component.scss
new file mode 100644
index 000000000..febea28dc
--- /dev/null
+++ b/src/app/profile/structure-add-member-modal/structure-add-member-modal.component.scss
@@ -0,0 +1,44 @@
+@import '../../../assets/scss/color';
+@import '../../../assets/scss/typography';
+@import '../../../assets/scss/shapes';
+@import '../../../assets/scss/z-index';
+
+.modalBackground {
+  .modal {
+    max-width: 390px;
+    background-color: $white;
+    .modalHeader {
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      border: 1px solid $grey-6;
+      padding: 0 8px;
+      h3 {
+        @include lato-bold-18;
+      }
+    }
+
+    .modalContent {
+      padding: 24px 40px;
+    }
+
+    p {
+      text-align: center;
+      margin: 10px 0;
+
+      &.special {
+        margin: 8px 0;
+        @include lato-regular-14;
+        color: $grey-3;
+        &.invalid {
+          color: $orange-warning;
+        }
+      }
+    }
+
+    .buttons {
+      gap: 24px;
+      padding-top: 8px;
+    }
+  }
+}
diff --git a/src/app/profile/structure-add-member-modal/structure-add-member-modal.component.spec.ts b/src/app/profile/structure-add-member-modal/structure-add-member-modal.component.spec.ts
new file mode 100644
index 000000000..c66205e6d
--- /dev/null
+++ b/src/app/profile/structure-add-member-modal/structure-add-member-modal.component.spec.ts
@@ -0,0 +1,24 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { StructureAddMemberModalComponent } from './structure-add-member-modal.component';
+
+describe('StructureMembersManagementComponent', () => {
+  let component: StructureAddMemberModalComponent;
+  let fixture: ComponentFixture<StructureAddMemberModalComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [StructureAddMemberModalComponent],
+    }).compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(StructureAddMemberModalComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/profile/structure-add-member-modal/structure-add-member-modal.component.ts b/src/app/profile/structure-add-member-modal/structure-add-member-modal.component.ts
new file mode 100644
index 000000000..66f7e5d3f
--- /dev/null
+++ b/src/app/profile/structure-add-member-modal/structure-add-member-modal.component.ts
@@ -0,0 +1,54 @@
+import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { StructureWithOwners } from '../../models/structureWithOwners.model';
+import { TempUser } from '../../models/temp-user.model';
+import { StructureService } from '../../services/structure.service';
+import { ButtonType } from '../../shared/components/button/buttonType.enum';
+import { CustomRegExp } from '../../utils/CustomRegExp';
+
+@Component({
+  selector: 'app-structure-add-member-modal',
+  templateUrl: './structure-add-member-modal.component.html',
+  styleUrls: ['./structure-add-member-modal.component.scss'],
+})
+export class StructureAddMemberModalComponent implements OnInit {
+  @Input() public structure: StructureWithOwners;
+  @Output() closed = new EventEmitter();
+  public buttonTypeEnum = ButtonType;
+  public formAddAccount: FormGroup;
+  public ownerAlreadyLinked = false;
+
+  constructor(private formBuilder: FormBuilder, private structureService: StructureService) {}
+
+  ngOnInit(): void {
+    this.formAddAccount = this.formBuilder.group({
+      email: ['', [Validators.required, Validators.pattern(CustomRegExp.EMAIL)]],
+    });
+  }
+
+  public closeModal(value: boolean): void {
+    this.closed.emit(value);
+  }
+
+  // getter for form fields
+  get fAddAccount(): { [key: string]: AbstractControl } {
+    return this.formAddAccount.controls;
+  }
+
+  public addOwner(): void {
+    // stop here if form is invalid
+    if (this.formAddAccount.invalid) {
+      return;
+    }
+    const user = new TempUser();
+    user.email = this.fAddAccount.email.value;
+    this.structureService.addOwnerToStructure(user, this.structure.structure._id).subscribe(
+      () => {
+        this.closed.emit(true);
+      },
+      (err) => {
+        this.ownerAlreadyLinked = true;
+      }
+    );
+  }
+}
diff --git a/src/app/profile/structure-members-management/structure-members-management.component.html b/src/app/profile/structure-members-management/structure-members-management.component.html
new file mode 100644
index 000000000..903dffbfb
--- /dev/null
+++ b/src/app/profile/structure-members-management/structure-members-management.component.html
@@ -0,0 +1,92 @@
+<div class="content-container full-screen">
+  <div class="container members-management">
+    <div class="header">
+      <div fxLayout="row" fxLayoutAlign="space-between center" fxFill>
+        <div fxLayout="row" fxLayoutAlign="start center" class="headerBack">
+          <app-svg-icon [iconClass]="'backArrow'" [type]="'ico'" [icon]="'arrowBack'" (click)="goBack()"></app-svg-icon>
+          <h1>Gérer les membres<br />de {{ structure.structureName }}</h1>
+        </div>
+        <app-button
+          [style]="buttonTypeEnum.Secondary"
+          [text]="'Ajouter un membre'"
+          (click)="addMemberModalOpenned = true"
+          tabindex="0"
+        ></app-button>
+      </div>
+    </div>
+    <div *ngIf="structureWithOwners && tempUsers">
+      <div fxLayout="column" fxLayoutGap="8px" fxLayoutAlign="baseline baseline">
+        <div *ngFor="let member of structureWithOwners.owners" class="member-card">
+          <div fxLayout="row" fxLayoutAlign="space-between center" fxFill>
+            <div fxLayout="row" fxLayoutAlign="start center" class="user">
+              <app-svg-icon
+                class="avatar"
+                [type]="'avatar'"
+                [icon]="'defaultAvatar'"
+                [iconClass]="'icon-40'"
+              ></app-svg-icon>
+              <div class="info-member">
+                <p class="member">{{ displayMemberName(member) }}</p>
+                <p class="job" *ngIf="displayJobEmployer(member)">{{ displayJobEmployer(member) }}</p>
+              </div>
+            </div>
+            <app-button
+              class="button-member"
+              [style]="buttonTypeEnum.Secondary"
+              [text]="'Exclure ce membre'"
+              (click)="memberToExclude = member; excludeModalOpenned = true"
+              tabindex="0"
+            ></app-button>
+          </div>
+        </div>
+        <div *ngFor="let member of tempUsers" class="member-card">
+          <div fxLayout="row" fxLayoutAlign="space-between center" fxFill class="card-container">
+            <div fxLayout="row" fxLayoutAlign="start center" class="user">
+              <app-svg-icon
+                class="avatar"
+                [type]="'avatar'"
+                [icon]="'defaultAvatar'"
+                [iconClass]="'icon-40'"
+              ></app-svg-icon>
+              <div class="info-member">
+                <p class="member">{{ member.email }}</p>
+              </div>
+            </div>
+            <div fxLayout="row" fxLayoutAlign="start center" class="pendingContainer">
+              <div class="info-pendingStructure">
+                <app-svg-icon class="check-icon" [type]="'ico'" [icon]="'check'"></app-svg-icon>
+                <p class="text">Demande de rattachement envoyée le {{ member.updatedAt | date: 'dd/MM/YYYY' }}</p>
+              </div>
+              <app-button
+                [style]="buttonTypeEnum.Secondary"
+                [text]="'Annuler la demande'"
+                (click)="tempUserToCancel = member; cancelAddTempUserModalOpenned = true"
+                tabindex="0"
+              ></app-button>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>
+<app-structure-add-member-modal
+  *ngIf="addMemberModalOpenned"
+  [openned]="addMemberModalOpenned"
+  [structure]="structureWithOwners"
+  (closed)="closeAddMemberModal($event)"
+></app-structure-add-member-modal>
+<app-modal-confirmation
+  *ngIf="excludeModalOpenned"
+  [openned]="excludeModalOpenned"
+  [content]="'Souhaitez-vous exclure ce membre\n(' + displayMemberName(memberToExclude) + ')&nbsp;?'"
+  [customConfirmationText]="'Oui'"
+  (closed)="excludeMember(memberToExclude, $event)"
+></app-modal-confirmation>
+<app-modal-confirmation
+  *ngIf="cancelAddTempUserModalOpenned"
+  [openned]="cancelAddTempUserModalOpenned"
+  [content]="'Souhaitez-vous annuler la demande de rattachement de ce membre\n(' + tempUserToCancel.email + ')&nbsp;?'"
+  [customConfirmationText]="'Oui'"
+  (closed)="cancelAddTempUser(tempUserToCancel, $event)"
+></app-modal-confirmation>
diff --git a/src/app/profile/structure-members-management/structure-members-management.component.scss b/src/app/profile/structure-members-management/structure-members-management.component.scss
new file mode 100644
index 000000000..17db43964
--- /dev/null
+++ b/src/app/profile/structure-members-management/structure-members-management.component.scss
@@ -0,0 +1,83 @@
+@import '../../../assets/scss/color';
+@import '../../../assets/scss/typography';
+@import '../../../assets/scss/breakpoint';
+
+.container {
+  margin: 1rem auto;
+  max-width: 980px;
+  padding: 2rem;
+  background: $white;
+  border-radius: 8px;
+  border: 1px solid $grey-6;
+  .header {
+    margin-bottom: 2rem;
+  }
+  .headerBack {
+    cursor: pointer;
+  }
+  h1 {
+    @include lato-regular-24;
+    color: $grey-1;
+    cursor: initial;
+  }
+
+  .member-card {
+    width: 100%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    .user {
+      margin-right: 1rem;
+    }
+    .avatar {
+      background-color: $grey-8;
+      border-radius: 4px;
+    }
+    .info-member {
+      margin-left: 1rem;
+      p {
+        margin: 0;
+      }
+      .member {
+        @include lato-bold-14;
+      }
+      .job {
+        @include lato-regular-14;
+      }
+    }
+    .info-pendingStructure {
+      display: flex;
+      margin-right: 1rem;
+      max-width: 200px;
+      p {
+        margin: 0;
+      }
+      .text {
+        @include lato-regular-13;
+        color: $grey-3;
+        margin-left: 3px;
+      }
+    }
+    .card-container {
+      @media #{$large-phone} {
+        flex-direction: column !important;
+        align-items: flex-start !important;
+      }
+    }
+  }
+}
+
+.members-management {
+  ::ng-deep .btn-regular.secondary .text {
+    width: 184px !important;
+    height: 24px !important;
+  }
+  .button-member {
+    ::ng-deep .btn-regular.secondary .text {
+      color: $red !important;
+    }
+  }
+  ::ng-deep .modalBackground p {
+    white-space: pre-wrap;
+  }
+}
diff --git a/src/app/profile/structure-members-management/structure-members-management.component.spec.ts b/src/app/profile/structure-members-management/structure-members-management.component.spec.ts
new file mode 100644
index 000000000..d0178b47b
--- /dev/null
+++ b/src/app/profile/structure-members-management/structure-members-management.component.spec.ts
@@ -0,0 +1,24 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { StructureMembersManagementComponent } from './structure-members-management.component';
+
+describe('StructureMembersManagementComponent', () => {
+  let component: StructureMembersManagementComponent;
+  let fixture: ComponentFixture<StructureMembersManagementComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [StructureMembersManagementComponent],
+    }).compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(StructureMembersManagementComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/profile/structure-members-management/structure-members-management.component.ts b/src/app/profile/structure-members-management/structure-members-management.component.ts
new file mode 100644
index 000000000..5292e48f1
--- /dev/null
+++ b/src/app/profile/structure-members-management/structure-members-management.component.ts
@@ -0,0 +1,112 @@
+import { Component, OnInit } from '@angular/core';
+import { ActivatedRoute } from '@angular/router';
+import { Owner } from '../../models/owner.model';
+import { Structure } from '../../models/structure.model';
+import { StructureWithOwners } from '../../models/structureWithOwners.model';
+import { TempUser } from '../../models/temp-user.model';
+import { User } from '../../models/user.model';
+import { NotificationService } from '../../services/notification.service';
+import { StructureService } from '../../services/structure.service';
+import { ButtonType } from '../../shared/components/button/buttonType.enum';
+import { Utils } from '../../utils/utils';
+import { ProfileService } from '../services/profile.service';
+
+@Component({
+  selector: 'app-structure-members-management',
+  templateUrl: './structure-members-management.component.html',
+  styleUrls: ['./structure-members-management.component.scss'],
+})
+export class StructureMembersManagementComponent implements OnInit {
+  public structure: Structure;
+  public structureWithOwners: StructureWithOwners;
+  public tempUsers: TempUser[];
+  public tempUserToCancel: TempUser;
+  public memberToExclude: Owner;
+  public addMemberModalOpenned: boolean = false;
+  public excludeModalOpenned = false;
+  public cancelAddTempUserModalOpenned = false;
+  public buttonTypeEnum = ButtonType;
+
+  constructor(
+    private route: ActivatedRoute,
+    private structureService: StructureService,
+    private profileService: ProfileService,
+    private notificationService: NotificationService
+  ) {}
+
+  ngOnInit(): void {
+    this.route.data.subscribe(async (data) => {
+      if (data.structure) {
+        this.structure = new Structure(data.structure);
+        let currentProfile = await this.profileService.getProfile();
+        this.structureService.getStructureWithOwners(data.structure._id, currentProfile).subscribe((s) => {
+          this.structureWithOwners = s;
+        });
+        this.structureService.getTempUsers(data.structure._id).subscribe((data) => {
+          this.tempUsers = data;
+        });
+      }
+    });
+  }
+  public goBack(): void {
+    history.back();
+  }
+  public displayJobEmployer(profile: User): string {
+    return new Utils().getJobEmployer(profile);
+  }
+  public displayMemberName(member: Owner): string {
+    return member.name + ' ' + member.surname.toUpperCase();
+  }
+
+  public excludeMember(member: Owner, shouldExclude: boolean): void {
+    this.excludeModalOpenned = false;
+    if (shouldExclude) {
+      this.structureService.removeOwnerFromStructure(member._id, this.structure._id).subscribe(
+        () => {
+          this.structureWithOwners.owners = this.structureWithOwners.owners.filter((obj) => obj._id !== member._id);
+          this.notificationService.showSuccess(
+            `${this.displayMemberName(member)} a bien été exclu de ${this.structure.structureName}`,
+            ''
+          );
+        },
+        () => {
+          this.notificationService.showError(
+            `${this.displayMemberName(member)} n'a pas pu être exclu de ${
+              this.structure.structureName
+            }. Merci de réessayer plus tard.`,
+            "Echec de l'exclusion"
+          );
+        }
+      );
+    }
+  }
+
+  public cancelAddTempUser(member: TempUser, shouldExclude: boolean): void {
+    this.cancelAddTempUserModalOpenned = false;
+    if (shouldExclude) {
+      this.structureService.removeTempUserFromStructure(member._id, this.structure._id).subscribe(
+        () => {
+          this.tempUsers = this.tempUsers.filter((obj) => obj._id !== member._id);
+          this.notificationService.showSuccess(
+            `La demande d'ajout de ${member.email} à ${this.structure.structureName} a bien été annulée`,
+            ''
+          );
+        },
+        () => {
+          this.notificationService.showError(
+            `La demande d'ajout de ${member.email} à ${this.structure.structureName} n'a pas pu être annulée. Merci de réessayer plus tard.`,
+            "Echec de l'annulation"
+          );
+        }
+      );
+    }
+  }
+
+  public closeAddMemberModal(memberAddRequested: boolean): void {
+    this.addMemberModalOpenned = false;
+    if (memberAddRequested) {
+      this.ngOnInit();
+      this.notificationService.showSuccess(`La demande d'ajout a bien été effectuée`, '');
+    }
+  }
+}
diff --git a/src/app/resolvers/temp-user.resolver.ts b/src/app/resolvers/temp-user.resolver.ts
index 2ae604aa6..0f2b61a67 100644
--- a/src/app/resolvers/temp-user.resolver.ts
+++ b/src/app/resolvers/temp-user.resolver.ts
@@ -10,7 +10,7 @@ export class TempUserResolver implements Resolve<TempUser> {
   constructor(private tempUserService: TempUserService, private router: Router) {}
 
   resolve(route: ActivatedRouteSnapshot): Observable<TempUser> {
-    const userId = route.queryParams.id;
+    const userId = route.params.id;
     return this.tempUserService.getUser(userId).pipe(
       map((res) => res),
       catchError(() => {
diff --git a/src/app/services/structure.service.ts b/src/app/services/structure.service.ts
index 4c41e148a..662d69955 100644
--- a/src/app/services/structure.service.ts
+++ b/src/app/services/structure.service.ts
@@ -64,6 +64,9 @@ export class StructureService {
     return this.http.delete<Structure>(`${this.baseUrl}/${id}`);
   }
 
+  public removeTempUserFromStructure(idOwner: string, idStructure: string): Observable<any> {
+    return this.http.delete<any>(`${this.baseUrl}/${idStructure}/tempUser/${idOwner}`);
+  }
   public removeOwnerFromStructure(idOwner: string, idStructure: string): Observable<any> {
     return this.http.delete<any>(`${this.baseUrl}/${idStructure}/owner/${idOwner}`);
   }
@@ -174,6 +177,10 @@ export class StructureService {
     return this.http.post<any>(`${this.baseUrl}/${structureId}/withOwners`, { emailUser: profile?.email });
   }
 
+  public getTempUsers(structureId: string): Observable<TempUser[]> {
+    return this.http.get<TempUser[]>(`${this.baseUrl}/${structureId}/tempUsers`);
+  }
+
   public sendMailOnStructureError(structureId: string, content: string): Observable<any> {
     return this.http.post<any>(`${this.baseUrl}/reportStructureError`, {
       structureId,
diff --git a/src/app/shared/components/modal-options/modal-options.component.html b/src/app/shared/components/modal-options/modal-options.component.html
index 0e45ca7cc..b1f514924 100644
--- a/src/app/shared/components/modal-options/modal-options.component.html
+++ b/src/app/shared/components/modal-options/modal-options.component.html
@@ -14,6 +14,10 @@
     </div>
   </div>
   <div *ngIf="!isModalProfileOpts" class="modalContent" fxLayout="column" fxLayoutGap="10px">
+    <div (click)="closeModal(functionType.manageOwners)" fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="9px">
+      <app-svg-icon [type]="'ico'" [iconColor]="'inherit'" [icon]="'edit'"></app-svg-icon>
+      <p>Gérer les membres</p>
+    </div>
     <div (click)="closeModal(functionType.addUser)" fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="9px">
       <app-svg-icon [type]="'ico'" [iconColor]="'inherit'" [icon]="'add'"></app-svg-icon>
       <p>Ajouter un compte</p>
diff --git a/src/app/shared/components/structure-options-modal/structure-options-modal.component.ts b/src/app/shared/components/structure-options-modal/structure-options-modal.component.ts
index 2ff02f91d..1d04371db 100644
--- a/src/app/shared/components/structure-options-modal/structure-options-modal.component.ts
+++ b/src/app/shared/components/structure-options-modal/structure-options-modal.component.ts
@@ -84,6 +84,9 @@ export class StructureOptionsModalComponent implements OnInit {
       case FunctionTypeModalOptions.deleteAccount:
         this.toggleDeleteAccountModal();
         break;
+      case FunctionTypeModalOptions.manageOwners:
+        this.router.navigateByUrl(`/profile/structure-members-management/${this.structure.structure._id}`);
+        break;
       case FunctionTypeModalOptions.addUser:
         this.editModal = TypeModalProfile.addAccount;
         this.ownerAlreadyLinked = false;
diff --git a/src/app/shared/enum/functionTypeModalOptions.enum.ts b/src/app/shared/enum/functionTypeModalOptions.enum.ts
index 2ec4677af..338457416 100644
--- a/src/app/shared/enum/functionTypeModalOptions.enum.ts
+++ b/src/app/shared/enum/functionTypeModalOptions.enum.ts
@@ -2,6 +2,7 @@ export enum FunctionTypeModalOptions {
   changeEmail = 1,
   changePassword,
   deleteAccount,
+  manageOwners,
   addUser,
   removeUser,
   editStructure,
diff --git a/src/app/structure-list/components/structure-details/structure-details.component.html b/src/app/structure-list/components/structure-details/structure-details.component.html
index 785ae3639..f83335702 100644
--- a/src/app/structure-list/components/structure-details/structure-details.component.html
+++ b/src/app/structure-list/components/structure-details/structure-details.component.html
@@ -268,7 +268,7 @@
               [iconClass]="'icon-40'"
             ></app-svg-icon>
             <div class="info-member">
-              <p class="member">{{ member.name | uppercase }} {{ member.surname | titlecase }}</p>
+              <p class="member">{{ member.name }} {{ member.surname | uppercase }}</p>
               <p class="job" *ngIf="displayJobEmployer(member)">{{ displayJobEmployer(member) }}</p>
             </div>
           </div>
diff --git a/src/assets/ico/sprite.svg b/src/assets/ico/sprite.svg
index f585b46db..f28bb7a50 100644
--- a/src/assets/ico/sprite.svg
+++ b/src/assets/ico/sprite.svg
@@ -873,5 +873,8 @@
 </symbol>
 
 
+<symbol id="check" 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="#696969" />
+</symbol>
 
 </svg>
-- 
GitLab