From 24edfcb7d7b3af7a22067dcfef05f9464ac6ccce Mon Sep 17 00:00:00 2001
From: Etienne LOUPIAS <eloupias@grandlyon.com>
Date: Tue, 17 Sep 2024 12:59:00 +0000
Subject: [PATCH] fix(profile): input confirmation and status

---
 .../account-credentials.component.html        |  1 +
 ...ture-web-and-social-network.component.html |  5 ++++
 .../structure-orientator.component.html       |  4 +--
 .../structure-orientator.component.ts         |  7 ------
 .../mediation-beneficiary-info.component.html |  6 ++---
 src/app/login/login.component.html            | 12 ++++-----
 src/app/login/login.component.ts              | 13 +++++++---
 src/app/profile/edit/edit.component.html      | 21 +++++++++-------
 src/app/profile/edit/edit.component.ts        | 25 +++++++++++++------
 .../structure-add-member-modal.component.html |  2 +-
 .../structure-add-member-modal.component.ts   |  4 ---
 .../address-autocomplete.component.html       |  1 +
 .../hour-picker/hour-picker.component.html    |  2 ++
 .../components/input/input.component.ts       |  5 ++--
 .../select-or-create.component.html           |  2 +-
 15 files changed, 61 insertions(+), 49 deletions(-)

diff --git a/src/app/form/form-view/account-form/account-credentials/account-credentials.component.html b/src/app/form/form-view/account-form/account-credentials/account-credentials.component.html
index dca668295..85267a4bd 100644
--- a/src/app/form/form-view/account-form/account-credentials/account-credentials.component.html
+++ b/src/app/form/form-view/account-form/account-credentials/account-credentials.component.html
@@ -81,6 +81,7 @@
       label="Vérification du mot de passe"
       size="large"
       type="password"
+      [externalStatusControl]="true"
       [status]="getStatus(accountForm.get('confirmPassword'))"
       [value]="accountForm.get('confirmPassword').value"
       (valueChange)="accountForm.get('confirmPassword').setValue($event); setValidationsForm()"
diff --git a/src/app/form/form-view/structure-form/structure-web-and-social-network/structure-web-and-social-network.component.html b/src/app/form/form-view/structure-form/structure-web-and-social-network/structure-web-and-social-network.component.html
index 7384aac97..38ec4c4f7 100644
--- a/src/app/form/form-view/structure-form/structure-web-and-social-network/structure-web-and-social-network.component.html
+++ b/src/app/form/form-view/structure-form/structure-web-and-social-network/structure-web-and-social-network.component.html
@@ -24,6 +24,7 @@
           label="Adresse du site web"
           placeholder="exemple : resin.grandlyon.com"
           size="large"
+          [externalStatusControl]="true"
           [status]="
             structureForm.get('website').value ? (structureForm.get('website').valid ? 'success' : 'error') : null
           "
@@ -51,6 +52,7 @@
           label="Adresse du compte X/Twitter"
           placeholder="exemple : twitter.com/resin"
           size="large"
+          [externalStatusControl]="true"
           [status]="
             structureForm.get('twitter').value ? (structureForm.get('twitter').valid ? 'success' : 'error') : null
           "
@@ -74,6 +76,7 @@
           label="Adresse du compte Facebook"
           placeholder="exemple : facebook.com/resin"
           size="large"
+          [externalStatusControl]="true"
           [status]="
             structureForm.get('facebook').value ? (structureForm.get('facebook').valid ? 'success' : 'error') : null
           "
@@ -97,6 +100,7 @@
           label="Adresse du compte Linkedin"
           placeholder="exemple : linkedin.com/in/resin"
           size="large"
+          [externalStatusControl]="true"
           [status]="
             structureForm.get('linkedin').value ? (structureForm.get('linkedin').valid ? 'success' : 'error') : null
           "
@@ -120,6 +124,7 @@
           label="Adresse du compte Instagram"
           placeholder="exemple : instagram.com/resin"
           size="large"
+          [externalStatusControl]="true"
           [status]="
             structureForm.get('instagram').value ? (structureForm.get('instagram').valid ? 'success' : 'error') : null
           "
diff --git a/src/app/form/orientation-form-view/global-components/structure-orientator/structure-orientator.component.html b/src/app/form/orientation-form-view/global-components/structure-orientator/structure-orientator.component.html
index 42cc3156b..2e6d0992c 100644
--- a/src/app/form/orientation-form-view/global-components/structure-orientator/structure-orientator.component.html
+++ b/src/app/form/orientation-form-view/global-components/structure-orientator/structure-orientator.component.html
@@ -50,8 +50,8 @@
           size="large"
           sup="1"
           type="email"
+          [externalStatusControl]="true"
           [status]="getStatus('structureMail')"
-          [statusText]="getStatusText('structureMail')"
           [value]="form.get('structureMail').value"
           (valueChange)="updatedForm('structureMail', $event)"
         />
@@ -64,8 +64,8 @@
           size="large"
           sup="1"
           type="tel"
+          [externalStatusControl]="true"
           [status]="getStatus('structurePhone')"
-          [statusText]="getStatusText('structurePhone')"
           [value]="form.get('structurePhone').value"
           (valueChange)="updatedForm('structurePhone', $event)"
         />
diff --git a/src/app/form/orientation-form-view/global-components/structure-orientator/structure-orientator.component.ts b/src/app/form/orientation-form-view/global-components/structure-orientator/structure-orientator.component.ts
index 562921453..40950c1a1 100644
--- a/src/app/form/orientation-form-view/global-components/structure-orientator/structure-orientator.component.ts
+++ b/src/app/form/orientation-form-view/global-components/structure-orientator/structure-orientator.component.ts
@@ -63,11 +63,4 @@ export class StructureOrientatorComponent implements OnInit {
     if (!this.form.get(formName).value) return null;
     return this.form.get(formName).invalid ? 'error' : 'success';
   }
-
-  public getStatusText(formName: string): string {
-    const label = formName === 'structureMail' ? 'Email' : 'Téléphone';
-    const status = this.getStatus(formName);
-    if (status === null) return '';
-    return `${label} ${status === 'success' ? ' valide' : 'invalide'}`;
-  }
 }
diff --git a/src/app/form/orientation-form-view/online-demarch/online-mediation/mediation-beneficiary-info/mediation-beneficiary-info.component.html b/src/app/form/orientation-form-view/online-demarch/online-mediation/mediation-beneficiary-info/mediation-beneficiary-info.component.html
index 753e8eed6..a17c4f225 100644
--- a/src/app/form/orientation-form-view/online-demarch/online-mediation/mediation-beneficiary-info/mediation-beneficiary-info.component.html
+++ b/src/app/form/orientation-form-view/online-demarch/online-mediation/mediation-beneficiary-info/mediation-beneficiary-info.component.html
@@ -39,8 +39,8 @@
       type="email"
       label="Email"
       [sup]="getSup()"
+      [externalStatusControl]="true"
       [status]="form.get('email').value ? (form.get('email').invalid ? 'error' : 'success') : null"
-      [statusText]="form.get('email').value ? (form.get('email').invalid ? 'Email invalide' : 'Email valide') : null"
       [value]="form.get('email').value"
       (valueChange)="updatedForm('email', $event)"
     />
@@ -53,10 +53,8 @@
       label="Téléphone"
       type="tel"
       [sup]="getSup()"
+      [externalStatusControl]="true"
       [status]="form.get('phone').value ? (form.get('phone').invalid ? 'error' : 'success') : null"
-      [statusText]="
-        form.get('phone').value ? (form.get('phone').invalid ? 'Téléphone invalide' : 'Téléphone valide') : null
-      "
       [value]="form.get('phone').value"
       (valueChange)="updatedForm('phone', $event)"
     />
diff --git a/src/app/login/login.component.html b/src/app/login/login.component.html
index 992c1c984..61f010524 100644
--- a/src/app/login/login.component.html
+++ b/src/app/login/login.component.html
@@ -17,7 +17,9 @@
           type="email"
           [externalStatusControl]="authFailed || isUnverifiedEmail"
           [required]="true"
-          [status]="f.email.value ? (f.email.invalid || authFailed || isUnverifiedEmail ? 'error' : 'success') : null"
+          [status]="
+            f.email.value ? (authFailed ? null : f.email.invalid || isUnverifiedEmail ? 'error' : 'success') : null
+          "
           [statusText]="getLoginStatusText()"
           [value]="f.email.value"
           [wide]="true"
@@ -36,12 +38,8 @@
           label="Mot de passe"
           size="large"
           type="password"
-          [externalStatusControl]="f.password.invalid || authFailed || isUnverifiedEmail"
-          [statusText]="
-            f.password.invalid
-              ? 'Le mot de passe doit obligatoirement contenir : 8&nbsp;caractères, une majuscule, une minuscule, un caractère spécial et un chiffre'
-              : ''
-          "
+          [externalStatusControl]="true"
+          [statusText]="getPasswordStatusText()"
           [required]="true"
           [status]="f.password.value ? (f.password.invalid || authFailed ? 'error' : 'success') : 'info'"
           [value]="f.password.value"
diff --git a/src/app/login/login.component.ts b/src/app/login/login.component.ts
index 5f4844aec..8487e0846 100644
--- a/src/app/login/login.component.ts
+++ b/src/app/login/login.component.ts
@@ -114,15 +114,22 @@ export class LoginComponent implements OnInit {
     if (this.f.email.value && this.f.email.invalid) {
       return 'L’identifiant doit être un email valide';
     }
-    if (this.authFailed) {
-      return 'Identifiant ou mot de passe invalide';
-    }
     if (this.isUnverifiedEmail) {
       return 'Votre email n’a jamais été validé';
     }
     return null;
   }
 
+  public getPasswordStatusText(): string {
+    if (this.f.password.invalid) {
+      return 'Le mot de passe doit obligatoirement contenir : 8&nbsp;caractères, une majuscule, une minuscule, un caractère spécial et un chiffre';
+    }
+    if (this.authFailed) {
+      return 'Identifiant ou mot de passe invalide';
+    }
+    return null;
+  }
+
   public onChange(): void {
     this.authFailed = false;
     this.isUnverifiedEmail = false;
diff --git a/src/app/profile/edit/edit.component.html b/src/app/profile/edit/edit.component.html
index 9f3c57a6b..a943e19c1 100644
--- a/src/app/profile/edit/edit.component.html
+++ b/src/app/profile/edit/edit.component.html
@@ -174,8 +174,9 @@
         [required]="true"
         [label]="'Nouvel email'"
         [size]="'large'"
-        [status]="getEmailStatus(newEmail)"
-        [statusText]="getEmailStatusText()"
+        [externalStatusControl]="true"
+        [status]="newEmail ? (getNewEmailStatus() ? 'success' : 'error') : null"
+        [statusText]="getNewEmailStatusText()"
         [wide]="true"
         [(value)]="newEmail"
       />
@@ -183,10 +184,11 @@
         id="confirm-email"
         type="email"
         [required]="true"
-        [label]="'Confirmation du nouvel email'"
+        [label]="'Confirmer le nouvel email'"
         [size]="'large'"
-        [status]="getEmailStatus(newEmailConfirm)"
-        [statusText]="getEmailStatusText()"
+        [externalStatusControl]="true"
+        [status]="newEmail && newEmailConfirm ? (getNewEmailConfirmStatus() ? 'success' : 'error') : null"
+        [statusText]="getNewEmailConfirmStatusText()"
         [wide]="true"
         [(value)]="newEmailConfirm"
       />
@@ -208,11 +210,11 @@
         [label]="'Ancien mot de passe'"
         [size]="'large'"
         [autocomplete]="'on'"
+        [externalStatusControl]="true"
         [status]="getPasswordStatus(oldPassword)"
         [statusText]="getOldPasswordStatusText(getPasswordStatus(oldPassword))"
         [type]="'password'"
         [wide]="true"
-        [externalStatusControl]="true"
         [(value)]="oldPassword"
       />
       <app-input
@@ -220,11 +222,11 @@
         [required]="true"
         [label]="'Nouveau mot de passe'"
         [size]="'large'"
+        [externalStatusControl]="true"
         [status]="getPasswordStatus(newPassword)"
         [statusText]="getPasswordStatusText(getPasswordStatus(newPassword))"
         [type]="'password'"
         [wide]="true"
-        [externalStatusControl]="true"
         [(value)]="newPassword"
       />
       <app-input
@@ -233,11 +235,11 @@
         [label]="'Confirmer le nouveau mot de passe'"
         [size]="'large'"
         [autocomplete]="'on'"
+        [externalStatusControl]="true"
         [status]="getPasswordStatus(newPasswordConfirm, newPassword)"
-        [statusText]="getNewPasswordStatusText(getPasswordStatus(newPasswordConfirm, newPassword))"
+        [statusText]="getNewPasswordConfirmStatusText(getPasswordStatus(newPasswordConfirm, newPassword))"
         [type]="'password'"
         [wide]="true"
-        [externalStatusControl]="true"
         [(value)]="newPasswordConfirm"
       />
     </div>
@@ -261,6 +263,7 @@
         [id]="oldPassword"
         [label]="'Mot de passe'"
         [type]="'password'"
+        [externalStatusControl]="true"
         [size]="'large'"
         [wide]="true"
         [(value)]="oldPassword"
diff --git a/src/app/profile/edit/edit.component.ts b/src/app/profile/edit/edit.component.ts
index 1c28692ec..5dee197e5 100644
--- a/src/app/profile/edit/edit.component.ts
+++ b/src/app/profile/edit/edit.component.ts
@@ -130,12 +130,21 @@ export class EditComponent implements OnInit {
     return Boolean(RegExp(CustomRegExp.EMAIL).exec(email));
   }
 
-  public getEmailStatus(email: string): 'success' | 'error' {
-    return this.emailValid(email) ? 'success' : 'error';
+  public getNewEmailStatus(): boolean {
+    return this.emailValid(this.newEmail);
   }
 
-  public getEmailStatusText(): string {
-    return `Nouvel email  ${this.emailValid(this.newEmailConfirm) ? 'valide' : 'invalide'}`;
+  public getNewEmailStatusText(): string {
+    return `Nouvel email ${this.getNewEmailStatus() ? 'valide' : 'invalide'}`;
+  }
+
+  public getNewEmailConfirmStatus(): boolean {
+    return this.emailValid(this.newEmail) && this.newEmailConfirm === this.newEmail;
+  }
+
+  public getNewEmailConfirmStatusText(): string {
+    if (!this.newEmail || !this.newEmailConfirm) return '';
+    return `Confirmation du nouvel email ${this.getNewEmailConfirmStatus() ? 'valide' : 'invalide'}`;
   }
 
   public passwordValid(password: string): boolean {
@@ -171,17 +180,17 @@ export class EditComponent implements OnInit {
   public getPasswordStatusText(status: passwordStatuses): string {
     const statusTexts = {
       info: 'Le mot de passe doit obligatoirement contenir : 8 caractères, une majuscule, un caractère spécial.',
-      error: 'Mot de passe invalide.',
+      error: 'Le mot de passe doit obligatoirement contenir : 8 caractères, une majuscule, un caractère spécial.',
       success: 'Mot de passe valide.',
     };
 
     return statusTexts[status];
   }
 
-  public getNewPasswordStatusText(status: passwordStatuses): string {
+  public getNewPasswordConfirmStatusText(status: passwordStatuses): string {
     const statusTexts = {
-      error: 'Nouveau mot de passe invalide.',
-      success: 'Nouveau mot de passe valide.',
+      error: 'Confirmation du nouveau mot de passe invalide.',
+      success: 'Confirmation du nouveau mot de passe valide.',
     };
 
     return statusTexts[status];
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
index acb6f334f..52c13fffd 100644
--- 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
@@ -11,8 +11,8 @@
     [label]="'Email du membre à ajouter'"
     [size]="'large'"
     [wide]="true"
+    [externalStatusControl]="true"
     [status]="getEmailStatus()"
-    [statusText]="getEmailStatusText()"
     [(value)]="email"
   />
 </app-modal>
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
index fbedc806a..c63575ab4 100644
--- 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
@@ -37,10 +37,6 @@ export class StructureAddMemberModalComponent {
     return this.emailValid() ? 'success' : 'error';
   }
 
-  public getEmailStatusText(): string {
-    return `Email  ${this.emailValid() ? 'valide' : 'invalide'}`;
-  }
-
   public async addOwner(): Promise<void> {
     // stop here if form is invalid
     if (!this.emailValid()) {
diff --git a/src/app/shared/components/address-autocomplete/address-autocomplete.component.html b/src/app/shared/components/address-autocomplete/address-autocomplete.component.html
index 04eb72bd6..920210b53 100644
--- a/src/app/shared/components/address-autocomplete/address-autocomplete.component.html
+++ b/src/app/shared/components/address-autocomplete/address-autocomplete.component.html
@@ -5,6 +5,7 @@
   autocomplete="off"
   size="large"
   [wide]="wide"
+  [externalStatusControl]="true"
   [status]="!required || form.get('address').invalid ? null : 'success'"
   [statusText]="form.get('address').invalid ? null : 'Adresse sélectionnée'"
   [value]="searchString"
diff --git a/src/app/shared/components/hour-picker/hour-picker.component.html b/src/app/shared/components/hour-picker/hour-picker.component.html
index 4cf6b42b8..e54607070 100644
--- a/src/app/shared/components/hour-picker/hour-picker.component.html
+++ b/src/app/shared/components/hour-picker/hour-picker.component.html
@@ -18,6 +18,7 @@
           [type]="'time'"
           [label]="'De :'"
           [size]="'large'"
+          [externalStatusControl]="true"
           [status]="getStatus(hour.start)"
           [statusText]="getStatusText(hour.start)"
           [(value)]="hour.start"
@@ -30,6 +31,7 @@
           [type]="'time'"
           [label]="'Jusqu’à :'"
           [size]="'large'"
+          [externalStatusControl]="true"
           [status]="getStatus(hour.start, hour.end)"
           [statusText]="getStatusText(hour.start, hour.end)"
           [(value)]="hour.end"
diff --git a/src/app/shared/components/input/input.component.ts b/src/app/shared/components/input/input.component.ts
index 9f92ff241..e9def80e3 100644
--- a/src/app/shared/components/input/input.component.ts
+++ b/src/app/shared/components/input/input.component.ts
@@ -68,7 +68,6 @@ export class InputComponent implements OnInit {
   ngOnInit(): void {
     if (this.type === 'password' || this.readonly) this.hasIconInField = true;
     if (this.required) this.sup = '*';
-    console.log({ required: this.required, sup: this.sup });
   }
 
   public onChange(): void {
@@ -98,8 +97,8 @@ export class InputComponent implements OnInit {
   }
 
   getStatusText(): string {
-    if (this.externalStatusControl) {
-      return this.statusText || '';
+    if (this.externalStatusControl && this.statusText) {
+      return this.statusText;
     }
     if (this.value === '') {
       return '';
diff --git a/src/app/shared/components/select-or-create/select-or-create.component.html b/src/app/shared/components/select-or-create/select-or-create.component.html
index 8f4f28d64..66952b746 100644
--- a/src/app/shared/components/select-or-create/select-or-create.component.html
+++ b/src/app/shared/components/select-or-create/select-or-create.component.html
@@ -8,7 +8,7 @@
       [id]="'select-' + name.toLowerCase()"
       [wide]="true"
       [disabled]="isAddingNewItem"
-      [status]="!isAddingNewItem ? (isSelectedItem ? 'success' : 'error') : null"
+      [status]="isAddingNewItem || data.length ? null : isSelectedItem ? 'success' : 'error'"
       [description]="'Recherchez votre ' + name.toLowerCase() + ' dans la liste suivante'"
       [value]="isAddingNewItem ? null : value"
       [externalStatusControl]="true"
-- 
GitLab