diff --git a/src/app/form/form.component.html b/src/app/form/form.component.html index 9a6d244c7d9d5666b640eef486cd03474112e216..8f4e22987f51292ced36f519b919aaa130c04de5 100644 --- a/src/app/form/form.component.html +++ b/src/app/form/form.component.html @@ -35,7 +35,12 @@ [value]="progressStatus" ></progress> </div> - <div *ngIf="currentPage == 0 && !isEditMode" class="home page" fxLayout="column" fxLayoutAlign="space-between"> + <div + *ngIf="currentPage == pageTypeEnum.summary && !isEditMode" + class="home page" + fxLayout="column" + fxLayoutAlign="space-between" + > <h2>Ajouter votre structure</h2> <img src="../../assets/form/schedule.svg" alt="logo schedule" /> <div> @@ -932,36 +937,6 @@ </p> </div> </div> - <div *ngIf="currentPage == pageTypeEnum.cgu" class="page"> - <div class="title"> - <h3> - Acceptez-vous que les informations saisies soient enregistrées par la Métropole de Lyon<span - class="asterisk" - >*</span - > - ? - </h3> - </div> - <app-checkbox-form - [isChecked]="userAcceptSavedDate" - [text]="'J\'accepte'" - (checkEvent)="acceptDataBeSaved($event)" - > - </app-checkbox-form> - <p class="informationEndForm"> - <span class="asterisk">*</span> Les informations recueillies sont enregistrées dans un fichier par la - Métropole de Lyon en vue de l'animation du réseau des acteurs de la médiation numérique. Elles sont conservées - pendant 24 mois et sont destinées aux seuls intervenants habilités de la Métropole de Lyon. Vos données - personnelles sont traitées dans ce cadre aux fins de Ârecensement des actions de médiation numérique sur le - territoire de la métropole. Conformément à la loi 78-17 du 6 janvier 1978 modifiée relative à l'information, - aux fichiers et aux libertés, et au Règlement Général européen à la Protection des Données, vous avez la - possibilité d’exercer vos droits d’accès, de rectification, d’effacement, d’opposition, de limitation du - traitement et de révocation de votre consentement. Afin d'exercer vos droits, vous pouvez vous adresser : par - courrier postal à : Métropole de Lyon - Direction des Affaires Juridiques et de la Commande Publique - 20, rue - du Lac - BP 33569 - 69505 Lyon Cedex par courrier électronique en remplissant le formulaire dédié sur Toodego, - le site des services et démarches en ligne dans la Métropole de Lyon - </p> - </div> <div *ngIf="false" class="page"> <div class="title"> <h3>Voulez-vous inviter d’autres personnes dans cette structure ?</h3> @@ -983,33 +958,62 @@ </div> </div> </div> - <div *ngIf="currentPage == nbPagesForm && !profile" class="page" fxLayout="column" fxLayoutGap="69px"> - <svg aria-hidden="true"> - <use [attr.xlink:href]="'assets/form/sprite.svg#emailVerification'"></use> - </svg> - <h3>Un courriel vous a été envoyé afin de finaliser votre inscription</h3> + </form> + <div *ngIf="currentPage == pageTypeEnum.cgu" class="page"> + <div class="title"> + <h3> + Acceptez-vous que les informations saisies soient enregistrées par la Métropole de Lyon<span class="asterisk" + >*</span + > + ? + </h3> + </div> + <app-checkbox-form + [isChecked]="userAcceptSavedDate" + [text]="'J\'accepte'" + (checkEvent)="acceptDataBeSaved($event)" + > + </app-checkbox-form> + <p class="informationEndForm"> + <span class="asterisk">*</span> Les informations recueillies sont enregistrées dans un fichier par la Métropole + de Lyon en vue de l'animation du réseau des acteurs de la médiation numérique. Elles sont conservées pendant 24 + mois et sont destinées aux seuls intervenants habilités de la Métropole de Lyon. Vos données personnelles sont + traitées dans ce cadre aux fins de Ârecensement des actions de médiation numérique sur le territoire de la + métropole. Conformément à la loi 78-17 du 6 janvier 1978 modifiée relative à l'information, aux fichiers et aux + libertés, et au Règlement Général européen à la Protection des Données, vous avez la possibilité d’exercer vos + droits d’accès, de rectification, d’effacement, d’opposition, de limitation du traitement et de révocation de + votre consentement. Afin d'exercer vos droits, vous pouvez vous adresser : par courrier postal à : Métropole de + Lyon - Direction des Affaires Juridiques et de la Commande Publique - 20, rue du Lac - BP 33569 - 69505 Lyon + Cedex par courrier électronique en remplissant le formulaire dédié sur Toodego, le site des services et + démarches en ligne dans la Métropole de Lyon + </p> + </div> + <div *ngIf="currentPage == nbPagesForm && !profile" class="page" fxLayout="column" fxLayoutGap="69px"> + <svg aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#emailVerification'"></use> + </svg> + <h3>Un courriel vous a été envoyé afin de finaliser votre inscription</h3> + </div> + <div *ngIf="currentPage == nbPagesForm && profile" class="page"> + <div class="title"> + <h3> + Bravo !<br /> + Votre structure a bien été référencée. + </h3> </div> - <div *ngIf="currentPage == nbPagesForm && profile" class="page"> - <div class="title"> - <h3> - Bravo !<br /> - Votre structure a bien été référencée. - </h3> - </div> - <div class="structureInfoBlock" fxLayout="row" fxLayoutAlign=" center"> - <div class="structureInfoContent" fxLayout="column"> - {{ getStructureControl('structureName').value }} - <span>{{ getStructureControl('structureType').value }}</span> - </div> - <div class="validateSvg"> - <svg class="validate" aria-hidden="true"> - <use [attr.xlink:href]="'assets/form/sprite.svg#checkVector'"></use> - </svg> - </div> + <div class="structureInfoBlock" fxLayout="row" fxLayoutAlign=" center"> + <div class="structureInfoContent" fxLayout="column"> + {{ getStructureControl('structureName').value }} + <span>{{ getStructureControl('structureType').value }}</span> + </div> + <div class="validateSvg"> + <svg class="validate" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#checkVector'"></use> + </svg> </div> </div> - </form> + </div> <div *ngIf="currentPage != 0" class="footer desktop"> <div fxLayout="row" fxLayoutAlign="center center" *ngIf="currentPage != nbPagesForm && !isEditMode"> <app-footer-form diff --git a/src/app/form/form.component.ts b/src/app/form/form.component.ts index dfc550c6dba2cefabcf968c3d7705ae17be0a8fc..a3b3c84dcb4b09db7517a3a4a386e15d18286005 100644 --- a/src/app/form/form.component.ts +++ b/src/app/form/form.component.ts @@ -41,6 +41,7 @@ export class FormComponent implements OnInit { public equipmentsAndServices: { module: Module; openned: boolean }[] = []; public trainingCategories: { category: Category; openned: boolean }[] = []; public pageTypeEnum = PageTypeEnum; + public claimStructureId = null; // Page and progress var public currentPage = 0; @@ -65,6 +66,7 @@ export class FormComponent implements OnInit { public userAcceptSavedDate = false; public showMenu = false; public isEditMode = false; + public isClaimMode = false; public isLoading = false; constructor( @@ -86,8 +88,11 @@ export class FormComponent implements OnInit { if (history.state.data) { this.isEditMode = true; this.initForm(new Structure(history.state.data)); - } else if (history.state.new) { - console.log('Create user only'); + } else if (history.state.newUser) { + this.isClaimMode = true; + this.createAccountForm(); + this.claimStructureId = history.state.newUser; + this.setValidationsForm(); } else { this.initForm(new Structure()); } @@ -132,20 +137,7 @@ export class FormComponent implements OnInit { private initForm(structure: Structure): void { // Init account Form - this.accountForm = new FormGroup( - { - email: new FormControl('', [Validators.required, Validators.pattern(Regex.email)]), //NOSONAR - name: new FormControl('', [Validators.required, Validators.pattern(Regex.textWithoutNumber)]), //NOSONAR - surname: new FormControl('', [Validators.required, Validators.pattern(Regex.textWithoutNumber)]), //NOSONAR - phone: new FormControl('', [Validators.required, Validators.pattern(Regex.phone)]), //NOSONAR - password: new FormControl('', [ - Validators.required, - Validators.pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*])(?=.{8,})/), //NOSONAR - ]), - confirmPassword: new FormControl(''), - }, - [MustMatch('password', 'confirmPassword')] - ); + this.createAccountForm(); // Init form this.structureForm = this.createStructureForm(structure); @@ -167,6 +159,24 @@ export class FormComponent implements OnInit { this.setValidationsForm(); } + + private createAccountForm(): void { + this.accountForm = new FormGroup( + { + email: new FormControl('', [Validators.required, Validators.pattern(Regex.email)]), //NOSONAR + name: new FormControl('', [Validators.required, Validators.pattern(Regex.textWithoutNumber)]), //NOSONAR + surname: new FormControl('', [Validators.required, Validators.pattern(Regex.textWithoutNumber)]), //NOSONAR + phone: new FormControl('', [Validators.required, Validators.pattern(Regex.phone)]), //NOSONAR + password: new FormControl('', [ + Validators.required, + Validators.pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*])(?=.{8,})/), //NOSONAR + ]), + confirmPassword: new FormControl(''), + }, + [MustMatch('password', 'confirmPassword')] + ); + } + private createStructureForm(structure): FormGroup { const form = new FormGroup({ _id: new FormControl(structure._id), @@ -367,142 +377,197 @@ export class FormComponent implements OnInit { } public setValidationsForm(): void { - this.pagesValidation[PageTypeEnum.summary] = { valid: true }; - this.pagesValidation[PageTypeEnum.info] = { valid: true }; - this.pagesValidation[PageTypeEnum.accountInfo] = { - valid: - this.accountForm.get('surname').valid && - this.accountForm.get('name').valid && - this.accountForm.get('phone').valid, - }; - this.pagesValidation[PageTypeEnum.accountCredentials] = { - valid: - this.accountForm.get('email').valid && - this.accountForm.get('password').valid && - this.accountForm.get('confirmPassword').valid, - }; - this.pagesValidation[PageTypeEnum.structureNameAndAddress] = { - valid: this.getStructureControl('structureName').valid && this.getStructureControl('address').valid, - name: 'Nom et adresse', - }; - this.pagesValidation[PageTypeEnum.structurePhone] = { - valid: this.getStructureControl('contactPhone').valid, - name: 'Téléphone', - }; - this.pagesValidation[PageTypeEnum.structureType] = { - valid: this.getStructureControl('structureType').valid, - name: 'Type de structure', - }; - this.pagesValidation[PageTypeEnum.structureAccessModality] = { - valid: this.getStructureControl('accessModality').valid, - name: "Modalités d'accueil ", - }; - this.pagesValidation[PageTypeEnum.structureHours] = { valid: this.hoursForm.valid, name: "Horaires d'ouverture" }; - this.pagesValidation[PageTypeEnum.structureHoursDetails] = { - valid: this.getStructureControl('exceptionalClosures').valid, - name: 'Précisions sur les horaires', - }; - this.pagesValidation[PageTypeEnum.structurePmr] = { - valid: this.getStructureControl('pmrAccess').valid, - name: 'Accessibilité pour les personnes à mobilité réduite', - }; - this.pagesValidation[PageTypeEnum.structureWebAndSocialNetwork] = { - valid: - this.getStructureControl('contactMail').valid && - (this.getStructureControl('website').valid || !this.showWebsite) && - ((this.getStructureControl('facebook').valid && - this.getStructureControl('twitter').valid && - this.getStructureControl('instagram').valid) || - !this.showSocialNetwork), - name: 'Présence sur internet', - }; - this.pagesValidation[PageTypeEnum.structurePublicTarget] = { - valid: this.getStructureControl('publics').valid, - name: 'Public admis', - }; - this.pagesValidation[PageTypeEnum.structureAccompaniment] = { - valid: - this.getStructureControl('publicsAccompaniment').valid && - this.getStructureControl('proceduresAccompaniment').valid, - name: 'Accompagnements proposés', - }; - this.pagesValidation[PageTypeEnum.structureOtherAccompaniment] = { - valid: this.getStructureControl('otherDescription').value, - name: 'Autres démarches proposés', - }; - this.pagesValidation[PageTypeEnum.structureWorkshop] = { - valid: - this.getStructureControl('accessRight').valid && - this.getStructureControl('socialAndProfessional').valid && - this.getStructureControl('baseSkills').valid && - this.getStructureControl('parentingHelp').valid && - this.getStructureControl('digitalCultureSecurity').valid, - name: 'Ateliers au numérique proposés', - }; - this.pagesValidation[PageTypeEnum.structureWorkshopPrice] = { - valid: this.getStructureControl('freeWorkShop').valid, - name: 'Gratuité des ateliers', - }; - this.pagesValidation[PageTypeEnum.structureWifi] = { - valid: this.getStructureControl('equipmentsAndServices').valid, - name: 'Gratuité du wifi', - }; - this.pagesValidation[PageTypeEnum.structureEquipments] = { - valid: - this.getStructureControl('equipmentsAndServices').valid && - this.getStructureControl('nbComputers').valid && - this.getStructureControl('nbPrinters').valid && - this.getStructureControl('nbTablets').valid && - this.getStructureControl('nbNumericTerminal').valid && - this.getStructureControl('nbScanners').valid, - name: 'Matériels mis à disposition', - }; - this.pagesValidation[PageTypeEnum.structureLabels] = { - valid: this.getStructureControl('labelsQualifications').valid, - name: 'Labélisations proposées', - }; - this.pagesValidation[PageTypeEnum.structureOtherServices] = { - valid: this.getStructureControl('equipmentsAndServices').valid, - name: 'Autres services proposés', - }; - this.pagesValidation[PageTypeEnum.structureDescription] = { - valid: this.getStructureControl('description').valid, - name: 'Présentation de la structure', - }; - this.pagesValidation[PageTypeEnum.structureCovidInfo] = { - valid: this.getStructureControl('lockdownActivity').valid, - name: 'Informations spécifiques à la période COVID', - }; - this.pagesValidation[PageTypeEnum.cgu] = { valid: this.userAcceptSavedDate }; - //this.pagesValidation[PageTypeEnum.addUserToStructure] = { valid: true }; - this.updatePageValid(); + if (this.isClaimMode) { + this.pagesValidation[PageTypeEnum.summary] = { valid: true }; + this.pagesValidation[PageTypeEnum.accountInfo] = { + valid: + this.accountForm.get('surname').valid && + this.accountForm.get('name').valid && + this.accountForm.get('phone').valid, + }; + this.pagesValidation[PageTypeEnum.accountCredentials] = { + valid: + this.accountForm.get('email').valid && + this.accountForm.get('password').valid && + this.accountForm.get('confirmPassword').valid, + }; + this.pagesValidation[PageTypeEnum.cgu] = { valid: this.userAcceptSavedDate }; + this.updatePageValid(); + } else { + this.pagesValidation[PageTypeEnum.summary] = { valid: true }; + this.pagesValidation[PageTypeEnum.info] = { valid: true }; + this.pagesValidation[PageTypeEnum.accountInfo] = { + valid: + this.accountForm.get('surname').valid && + this.accountForm.get('name').valid && + this.accountForm.get('phone').valid, + }; + this.pagesValidation[PageTypeEnum.accountCredentials] = { + valid: + this.accountForm.get('email').valid && + this.accountForm.get('password').valid && + this.accountForm.get('confirmPassword').valid, + }; + this.pagesValidation[PageTypeEnum.structureNameAndAddress] = { + valid: this.getStructureControl('structureName').valid && this.getStructureControl('address').valid, + name: 'Nom et adresse', + }; + this.pagesValidation[PageTypeEnum.structurePhone] = { + valid: this.getStructureControl('contactPhone').valid, + name: 'Téléphone', + }; + this.pagesValidation[PageTypeEnum.structureType] = { + valid: this.getStructureControl('structureType').valid, + name: 'Type de structure', + }; + this.pagesValidation[PageTypeEnum.structureAccessModality] = { + valid: this.getStructureControl('accessModality').valid, + name: "Modalités d'accueil ", + }; + this.pagesValidation[PageTypeEnum.structureHours] = { valid: this.hoursForm.valid, name: "Horaires d'ouverture" }; + this.pagesValidation[PageTypeEnum.structureHoursDetails] = { + valid: this.getStructureControl('exceptionalClosures').valid, + name: 'Précisions sur les horaires', + }; + this.pagesValidation[PageTypeEnum.structurePmr] = { + valid: this.getStructureControl('pmrAccess').valid, + name: 'Accessibilité pour les personnes à mobilité réduite', + }; + this.pagesValidation[PageTypeEnum.structureWebAndSocialNetwork] = { + valid: + this.getStructureControl('contactMail').valid && + (this.getStructureControl('website').valid || !this.showWebsite) && + ((this.getStructureControl('facebook').valid && + this.getStructureControl('twitter').valid && + this.getStructureControl('instagram').valid) || + !this.showSocialNetwork), + name: 'Présence sur internet', + }; + this.pagesValidation[PageTypeEnum.structurePublicTarget] = { + valid: this.getStructureControl('publics').valid, + name: 'Public admis', + }; + this.pagesValidation[PageTypeEnum.structureAccompaniment] = { + valid: + this.getStructureControl('publicsAccompaniment').valid && + this.getStructureControl('proceduresAccompaniment').valid, + name: 'Accompagnements proposés', + }; + this.pagesValidation[PageTypeEnum.structureOtherAccompaniment] = { + valid: this.getStructureControl('otherDescription').value, + name: 'Autres démarches proposés', + }; + this.pagesValidation[PageTypeEnum.structureWorkshop] = { + valid: + this.getStructureControl('accessRight').valid && + this.getStructureControl('socialAndProfessional').valid && + this.getStructureControl('baseSkills').valid && + this.getStructureControl('parentingHelp').valid && + this.getStructureControl('digitalCultureSecurity').valid, + name: 'Ateliers au numérique proposés', + }; + this.pagesValidation[PageTypeEnum.structureWorkshopPrice] = { + valid: this.getStructureControl('freeWorkShop').valid, + name: 'Gratuité des ateliers', + }; + this.pagesValidation[PageTypeEnum.structureWifi] = { + valid: this.getStructureControl('equipmentsAndServices').valid, + name: 'Gratuité du wifi', + }; + this.pagesValidation[PageTypeEnum.structureEquipments] = { + valid: + this.getStructureControl('equipmentsAndServices').valid && + this.getStructureControl('nbComputers').valid && + this.getStructureControl('nbPrinters').valid && + this.getStructureControl('nbTablets').valid && + this.getStructureControl('nbNumericTerminal').valid && + this.getStructureControl('nbScanners').valid, + name: 'Matériels mis à disposition', + }; + this.pagesValidation[PageTypeEnum.structureLabels] = { + valid: this.getStructureControl('labelsQualifications').valid, + name: 'Labélisations proposées', + }; + this.pagesValidation[PageTypeEnum.structureOtherServices] = { + valid: this.getStructureControl('equipmentsAndServices').valid, + name: 'Autres services proposés', + }; + this.pagesValidation[PageTypeEnum.structureDescription] = { + valid: this.getStructureControl('description').valid, + name: 'Présentation de la structure', + }; + this.pagesValidation[PageTypeEnum.structureCovidInfo] = { + valid: this.getStructureControl('lockdownActivity').valid, + name: 'Informations spécifiques à la période COVID', + }; + this.pagesValidation[PageTypeEnum.cgu] = { valid: this.userAcceptSavedDate }; + //this.pagesValidation[PageTypeEnum.addUserToStructure] = { valid: true }; + this.updatePageValid(); + } } private updatePageValid(): void { this.isPageValid = this.pagesValidation[this.currentPage].valid; } - public nextPage(): void { - // Check if user already connected to skip accountForm pages. - if (this.currentPage == PageTypeEnum.info && this.profile) { - this.currentPage += 2; // Skip accountInfo pages from AccountForm - this.progressStatus += 2 * (100 / this.nbPagesForm); + + /** + * Pgae algo for claim structure case + */ + public nextPageClaim(): void { + if (this.currentPage == this.nbPagesForm - 1) { + const user = new User(this.accountForm.value); + // Create user and claim structure + this.authService.register(user).subscribe(() => { + this.structureService.claimStructureWithAccount(this.claimStructureId, user).subscribe(() => { + this.progressStatus = 100; + }); + }); } - // Check if "other" isn't check to hide "other description" page - if ( - this.currentPage == PageTypeEnum.structureAccompaniment && - !this.isInArray('autres', 'proceduresAccompaniment') - ) { - this.currentPage++; // page structureOtherAccompaniment skip and go to page structureWorkshop - this.progressStatus += 100 / this.nbPagesForm; + + if (this.currentPage == PageTypeEnum.summary) { + this.currentPage = PageTypeEnum.accountInfo; + this.updatePageValid(); + } else if (this.currentPage == PageTypeEnum.accountInfo) { + this.currentPage = PageTypeEnum.accountCredentials; + this.updatePageValid(); + } else if (this.currentPage == PageTypeEnum.accountCredentials) { + this.currentPage = PageTypeEnum.cgu; + this.updatePageValid(); + } else if (this.currentPage == PageTypeEnum.cgu) { + this.currentPage = this.nbPagesForm; } - // Check if going to the last page to submit form and send email verification. - if (this.currentPage == this.nbPagesForm - 1) { - this.validateForm(); + if (this.currentPage !== this.nbPagesForm - 1) { + this.progressStatus += 25; + } + } + + public nextPage(): void { + if (this.isClaimMode) { + this.nextPageClaim(); } else { - this.currentPage++; - this.progressStatus += 100 / this.nbPagesForm; - this.updatePageValid(); + // Check if user already connected to skip accountForm pages. + if (this.currentPage == PageTypeEnum.info && this.profile) { + this.currentPage += 2; // Skip accountInfo pages from AccountForm + this.progressStatus += 2 * (100 / this.nbPagesForm); + } + // Check if "other" isn't check to hide "other description" page + if ( + this.currentPage == PageTypeEnum.structureAccompaniment && + !this.isInArray('autres', 'proceduresAccompaniment') + ) { + this.currentPage++; // page structureOtherAccompaniment skip and go to page structureWorkshop + this.progressStatus += 100 / this.nbPagesForm; + } + + // Check if going to the last page to submit form and send email verification. + if (this.currentPage == this.nbPagesForm - 1) { + this.validateForm(); + } else { + this.currentPage++; + this.progressStatus += 100 / this.nbPagesForm; + this.updatePageValid(); + } } } public previousPage(): void { 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 effd118fd8cdaa53d2bb3a8a79ea5f3755755262..12b27e22e5be3ebea69dcd32ddde30642a094d22 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 @@ -76,9 +76,7 @@ </div> </div> <div fxLayout="row" fxLayoutAlign="center center" class="hide-on-print"> - <a *ngIf="!isClaimed && userIsLoggedIn()" (click)="toggleClaimModal()" class="primary" tabindex="0" - >Revendiquer cette structure</a - > + <a *ngIf="!isClaimed" (click)="handleClaim()" class="primary" tabindex="0">Revendiquer cette structure</a> <!-- temporary remove edit --> <a *ngIf="profileService.isLinkedToStructure(structure._id) || profileService.isAdmin()" diff --git a/src/app/structure-list/components/structure-details/structure-details.component.ts b/src/app/structure-list/components/structure-details/structure-details.component.ts index 2b4bb09e5b93881655b18d01e7ac57f5e1911727..adcac606abfb0ca0b3b2e6de1810705b2144f23c 100644 --- a/src/app/structure-list/components/structure-details/structure-details.component.ts +++ b/src/app/structure-list/components/structure-details/structure-details.component.ts @@ -124,6 +124,14 @@ export class StructureDetailsComponent implements OnInit { this.claimModalOpenned = !this.claimModalOpenned; } + public handleClaim(): void { + if (this.userIsLoggedIn()) { + this.toggleClaimModal(); + } else { + this.router.navigate(['create-structure'], { state: { newUser: this.structure._id } }); + } + } + public deleteStructure(shouldDelete: boolean): void { this.toggleDeleteModal(); if (shouldDelete) {