diff --git a/src/app/footer-form/footer-form.component.html b/src/app/footer-form/footer-form.component.html index b4c50c392d10abbdfd41c3cbed5746039a0362ef..c2e91330f1f7027b9dae082ecf2c2467f458b45d 100644 --- a/src/app/footer-form/footer-form.component.html +++ b/src/app/footer-form/footer-form.component.html @@ -1,5 +1,5 @@ <div fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center"> - <button class="btn previous" (click)="goToPreviousPage()"> + <button class="btn-primary small previous" (click)="goToPreviousPage()"> <div class="rowBtn" fxLayout="row" fxLayoutAlign="center center"> <svg class="chevronLeft" aria-hidden="true"> <use [attr.xlink:href]="'assets/form/sprite.svg#chevronLeft'"></use> @@ -7,7 +7,12 @@ Précédent </div> </button> - <button class="btn next" (click)="goToNextPage()" [disabled]="!isValid" [ngClass]="{ invalid: !isValid }"> + <button + class="btn-primary small next" + (click)="goToNextPage()" + [disabled]="!isValid" + [ngClass]="{ invalid: !isValid }" + > <div class="rowBtn" fxLayout="row" fxLayoutAlign="center center"> Suivant<svg class="chevronRight" aria-hidden="true"> <use [attr.xlink:href]="'assets/form/sprite.svg#chevronRight'"></use> diff --git a/src/app/footer-form/footer-form.component.scss b/src/app/footer-form/footer-form.component.scss index dfecb83344d2312d4da1d75544930de155203094..7df6b3dd1ec3f492932fa1c2d6d6f13bab0df59f 100644 --- a/src/app/footer-form/footer-form.component.scss +++ b/src/app/footer-form/footer-form.component.scss @@ -1,16 +1,7 @@ @import '../../assets/scss/color'; @import '../../assets/scss/typography'; -.btn { - background: $secondary-color; - border-radius: 4px; - outline: none; - cursor: pointer; - border: 0; - color: $white; - height: 40px; - width: 149px; - @include btn-bold; +.btn-primary { &.previous { background-color: initial; color: $grey-2; diff --git a/src/app/form/form.component.html b/src/app/form/form.component.html index 1ab1982ba9e350967125465594dd12cb30ba557b..8a89c5a160cb095719b3c9c6082045ba7d8caae9 100644 --- a/src/app/form/form.component.html +++ b/src/app/form/form.component.html @@ -4,10 +4,23 @@ [content]="'Il vous faudra de nouveau remplir le formulaire si vous quittez'" (closed)="hasRedirectionAccepted($event)" ></app-modal-confirmation> - <div class="content"> + <div class="content" *ngIf="!isLoading" [ngClass]="{ editMode: isEditMode }"> + <div class="headerEditMode" *ngIf="isEditMode"> + <h2>Modification de {{ editForm.get('structureName').value }}</h2> + </div> + <div class="returnBtnSection" *ngIf="isEditMode && currentPage != 0"> + <button class="btn-primary previous" (click)="goToSpecificPage(0, false)"> + <div class="rowBtn" fxLayout="row" fxLayoutAlign="center center"> + <svg class="chevronLeft" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#chevronLeft'"></use> + </svg> + Retour + </div> + </button> + </div> <div class="progressBar" - *ngIf="currentPage != 0" + *ngIf="currentPage != 0 && !isEditMode" fxLayout="row" fxLayoutAlign="space-between center" fxLayoutGap="20px" @@ -22,7 +35,7 @@ [value]="progressStatus" ></progress> </div> - <div *ngIf="currentPage == 0" class="home page" fxLayout="column" fxLayoutAlign="space-between"> + <div *ngIf="currentPage == 0 && !isEditMode" class="home page" fxLayout="column" fxLayoutAlign="space-between"> <h2>Ajouter votre structure</h2> <img src="../../assets/form/schedule.svg" alt="logo schedule" /> <div> @@ -30,7 +43,26 @@ <p>Une fois réalisé cela vous permettra d'être référencé sur la platefome</p> </div> <div class="btnStart"> - <button class="btn start" (click)="nextPage()">C'est Parti</button> + <button class="btn-primary start" (click)="nextPage()">C'est Parti</button> + </div> + </div> + <div *ngIf="currentPage == 0 && isEditMode" class="editHome page" fxLayout="column" fxLayoutAlign="space-between"> + <div> + <div class="summary" *ngFor="let page of pagesValidation; let index = index"> + <div + class="itemSummary" + [ngClass]="{ last: index == 22 }" + fxLayout="row" + fxLayoutAlign="space-between center" + *ngIf="page.name" + (click)="goToSpecificPage(index, false)" + > + {{ page.name }} + <svg class="chevronRight" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#chevronRight'"></use> + </svg> + </div> + </div> </div> </div> <div *ngIf="currentPage == 1" class="informations page" fxLayout="column" fxLayoutGap="28px"> @@ -256,7 +288,7 @@ </div> <div *ngIf="currentPage == 7" class="page"> <div class="title"> - <h3>Quels sont les modalités d'accueil ?</h3> + <h3>Quelles sont les modalités d'accueil ?</h3> <p>Plusieurs choix possibles</p> </div> <div *ngIf="accessModality" fxLayout="row wrap" fxLayoutGap="16px" fxLayoutAlign="flex-start"> @@ -280,7 +312,6 @@ (updateForm)="updateHours($event)" (updateFormError)="setHoursError()" [structureInput]="hoursForm" - [isEditMode]="!isEditMode" ></app-hour-picker> </div> <div *ngIf="currentPage == 9" class="page"> @@ -683,8 +714,8 @@ <h3>Proposez-vous le wifi en accès libre ?</h3> </div> <app-radio-form - [selectedOption]="getStructureControl('freeWifi').value" - (selectedEvent)="onRadioBtnChange('freeWifi', $event)" + [selectedOption]="isEditMode ? isInArray('wifiEnAccesLibre', 'equipmentsAndServices') : null" + (selectedEvent)="onCheckChange($event, 'equipmentsAndServices', 'wifiEnAccesLibre')" > </app-radio-form> </div> @@ -983,16 +1014,26 @@ </div> </form> <div *ngIf="currentPage != 0" class="footer desktop"> - <div fxLayout="row" fxLayoutAlign="center center" *ngIf="currentPage != nbPagesForm"> + <div fxLayout="row" fxLayoutAlign="center center" *ngIf="currentPage != nbPagesForm && !isEditMode"> <app-footer-form (previousPage)="previousPage()" (nextPage)="nextPage()" [isValid]="isPageValid" ></app-footer-form> </div> + <div fxLayout="row" fxLayoutAlign="center center" *ngIf="isEditMode"> + <button + class="btn-primary" + [ngClass]="{ invalid: !isPageValid }" + [disabled]="!isPageValid" + (click)="goToSpecificPage(0, true)" + > + Valider + </button> + </div> <button *ngIf="currentPage == nbPagesForm && !profile" - class="btn validate unique" + class="btn-primary validate unique" routerLink="/home" [routerLinkActive]="'active'" > @@ -1000,25 +1041,40 @@ </button> <button *ngIf="currentPage == nbPagesForm && profile" - class="btn unique" + class="btn-primary unique" routerLink="/home" [state]="{ data: createdStructure }" > Voir ma structure </button> </div> + <div *ngIf="isEditMode && currentPage == 0" class="footerEditMode"> + <div fxLayout="row" fxLayoutAlign="center center"> + <button class="btn-primary unique" (click)="closeEditMode()">Terminer</button> + </div> + </div> </div> <div *ngIf="currentPage != 0" class="footer phone"> - <div fxLayout="row" fxLayoutAlign="center center" *ngIf="currentPage != nbPagesForm"> + <div fxLayout="row" fxLayoutAlign="center center" *ngIf="currentPage != nbPagesForm && !isEditMode"> <app-footer-form (previousPage)="previousPage()" (nextPage)="nextPage()" [isValid]="isPageValid" ></app-footer-form> </div> + <div fxLayout="row" fxLayoutAlign="center center" *ngIf="isEditMode"> + <button + class="btn-primary" + [ngClass]="{ invalid: !isPageValid }" + [disabled]="!isPageValid" + (click)="goToSpecificPage(0, true)" + > + Valider + </button> + </div> <button *ngIf="currentPage == nbPagesForm && !profile" - class="btn validate unique" + class="btn-primary validate unique" routerLink="/home" [routerLinkActive]="'active'" > @@ -1026,7 +1082,7 @@ </button> <button *ngIf="currentPage == nbPagesForm && profile" - class="btn unique" + class="btn-primary unique" routerLink="/home" [state]="{ data: createdStructure }" > diff --git a/src/app/form/form.component.scss b/src/app/form/form.component.scss index 7169d27acc9a1ccd471f85e14e1c4e75a1a8c2ee..17ced3d6b57f7035ff1dd40de552ebfad0d56c4a 100644 --- a/src/app/form/form.component.scss +++ b/src/app/form/form.component.scss @@ -5,7 +5,6 @@ @import '../../assets/scss/shapes'; @import '../../assets/scss/z-index'; -$progressBar-height: 50px; h3 { margin: 0; } @@ -27,15 +26,6 @@ h3 { max-width: 960px; margin: 20px auto; text-align: center; - .btn { - width: 149px; - &.validate { - background-color: $green-1; - } - &.unique { - width: 240px; - } - } &.desktop { @media #{$tablet} { display: none; @@ -90,6 +80,23 @@ h3 { } } .content { + .editHome { + height: calc( + 100vh - #{$header-height} - #{$footer-height} - 81px - 1px - 55px + ) !important; // -1px because of header border + } + @media #{$tablet} { + &.editMode { + .page { + height: calc( + 100vh - #{$header-height-phone} - #{$footer-height-phone} - 87px - 1px + ); // -1px because of header border + } + .editHome { + height: calc(100vh - #{$header-height-phone} - 87px - 1px - 55px) !important; // -1px because of header border + } + } + } padding: 0 16px; display: block; overflow-y: auto; @@ -189,21 +196,30 @@ h3 { } } -.btn { - background: $secondary-color; - border-radius: 4px; - outline: none; - cursor: pointer; - border: 0; - color: $white; - height: 40px; - width: 192px; - @include btn-bold; - +.btn-primary { + &.previous { + background-color: initial; + color: $grey-2; + width: 120px; + border-radius: 6px; + border: 1px solid $grey-4; + } &.start { margin-bottom: 26px; } } +.chevronRight { + height: 24px; + width: 24px; + stroke: $grey-2; + margin-left: 10px; +} +.chevronLeft { + height: 24px; + width: 24px; + stroke: $black; + margin-right: 10px; +} .progressBar { height: #{$progressBar-height}; max-width: 960px; @@ -449,3 +465,42 @@ img { } } } +.footerEditMode { + width: 100%; + position: fixed; + bottom: 56px; + margin: 0; + background: $white; + left: 0; + border-top: 1px solid $grey-4; + padding: 20px 0; + @media #{$tablet} { + bottom: 0; + left: 0; + } +} +.returnBtnSection { + max-width: 960px; + margin: 24px auto; +} +.itemSummary { + height: 60px; + border-bottom: 1px solid $grey-4; + @include cn-bold-20; + cursor: pointer; + &:hover { + background: $grey-6; + } + &.last { + border: 0; + } +} +.headerEditMode { + max-width: 960px; + margin: auto; + h2 { + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + } +} diff --git a/src/app/form/form.component.ts b/src/app/form/form.component.ts index 5da4fa9a642de61863a04baec2726e85fb7208a9..91a10097fc79781d7a687c17cc9249fc33d25ddf 100644 --- a/src/app/form/form.component.ts +++ b/src/app/form/form.component.ts @@ -13,18 +13,17 @@ import { MustMatch } from '../shared/validator/form'; import { Address } from '../models/address.model'; import { Module } from '../structure-list/models/module.model'; import { Equipment } from '../structure-list/enum/equipment.enum'; -import { Router } from '@angular/router'; +import { ActivatedRoute, Router } from '@angular/router'; import { AuthService } from '../services/auth.service'; import { first } from 'rxjs/operators'; import { Regex } from '../shared/enum/regex.enum'; +const { DateTime } = require('luxon'); @Component({ selector: 'app-structureForm', templateUrl: './form.component.html', styleUrls: ['./form.component.scss'], }) export class FormComponent implements OnInit { - @Input() public idStructure?: string; - @Input() public isEditMode: boolean = true; public profile: User; public createdStructure: Structure; @@ -32,6 +31,7 @@ export class FormComponent implements OnInit { public structureForm: FormGroup; public accountForm: FormGroup; public hoursForm: FormGroup; + public editForm: FormGroup; public labelsQualifications: Category; public publics: Category; public accessModality: Category; @@ -62,67 +62,69 @@ export class FormComponent implements OnInit { public isShowPassword = false; public userAcceptSavedDate = false; public showMenu = false; + public isEditMode = false; + public isLoading = false; + public isWifiChoosen = false; constructor( private structureService: StructureService, private searchService: SearchService, private profileService: ProfileService, - private authService: AuthService + private authService: AuthService, + private router: Router ) {} - ngOnInit(): void { + async ngOnInit(): Promise<void> { + this.isLoading = true; this.profileService.getProfile().then((user: User) => { this.profile = user; }); - + await this.setCategories(); // Check if it's a new structure or edit structure - if (this.idStructure) { - this.structureService.getStructure(this.idStructure).subscribe((structure) => { - this.initForm(structure); - this.idStructure = structure._id; - }); + this.isLoading = false; + if (history.state.data) { + this.isEditMode = true; + this.isWifiChoosen = true; + this.initForm(new Structure(history.state.data)); } else { this.initForm(new Structure()); } - this.setCategories(); } - private setCategories(): void { + async setCategories(): Promise<void> { this.searchService.getCategoriesAccompaniment().subscribe((categories: Category[]) => { this.proceduresAccompaniment = categories[0]; }); - this.searchService.getCategoriesMoreFilters().subscribe((categories: Category[]) => { - categories.forEach((categ) => { - switch (categ.id) { - case CategoryEnum.accessModality: { - this.accessModality = categ; - break; - } - case CategoryEnum.equipmentsAndServices: { - categ.modules.forEach((c) => { - this.equipmentsAndServices.push({ module: c, openned: false }); - }); - break; - } - case CategoryEnum.labelsQualifications: { - this.labelsQualifications = categ; - break; - } - case CategoryEnum.publics: { - this.publics = categ; - break; - } - case CategoryEnum.publicsAccompaniment: { - this.publicsAccompaniment = categ; - break; - } + const equipmentsCategs = await this.searchService.getCategoriesMoreFilters().toPromise(); + equipmentsCategs.forEach((categ) => { + switch (categ.id) { + case CategoryEnum.accessModality: { + this.accessModality = categ; + break; } - }); + case CategoryEnum.equipmentsAndServices: { + categ.modules.forEach((c) => { + this.equipmentsAndServices.push({ module: c, openned: false }); + }); + break; + } + case CategoryEnum.labelsQualifications: { + this.labelsQualifications = categ; + break; + } + case CategoryEnum.publics: { + this.publics = categ; + break; + } + case CategoryEnum.publicsAccompaniment: { + this.publicsAccompaniment = categ; + break; + } + } }); - this.searchService.getCategoriesTraining().subscribe((categories: Category[]) => { - categories.forEach((categ) => { - this.trainingCategories.push({ category: categ, openned: false }); - }); + let categs = await this.searchService.getCategoriesTraining().toPromise(); + categs.forEach((categ) => { + this.trainingCategories.push({ category: categ, openned: false }); }); } @@ -144,13 +146,33 @@ export class FormComponent implements OnInit { ); // Init form - this.structureForm = new FormGroup({ + this.structureForm = this.createStructureForm(structure); + this.editForm = this.createStructureForm(structure); + + // Init hours form + this.hoursForm = new FormGroup({ + monday: this.createDay(structure.hours.monday), + tuesday: this.createDay(structure.hours.tuesday), + wednesday: this.createDay(structure.hours.wednesday), + thursday: this.createDay(structure.hours.thursday), + friday: this.createDay(structure.hours.friday), + saturday: this.createDay(structure.hours.saturday), + sunday: this.createDay(structure.hours.sunday), + }); + if (this.isEditMode) { + this.showCollapse(structure); + } + + this.setValidationsForm(); + } + private createStructureForm(structure): FormGroup { + const form = new FormGroup({ _id: new FormControl(structure._id), coord: new FormControl(structure.coord), structureType: new FormControl(structure.structureType, Validators.required), structureName: new FormControl(structure.structureName, Validators.required), description: new FormControl(structure.description), - lockdownActivity: new FormControl(structure.description), + lockdownActivity: new FormControl(structure.lockdownActivity), address: new FormGroup({ numero: new FormControl(structure.address.numero), street: new FormControl(structure.address.street, Validators.required), @@ -205,20 +227,82 @@ export class FormComponent implements OnInit { [Validators.required, Validators.pattern(Regex.noNullNumber)] //NOSONAR ), freeWorkShop: new FormControl(structure.freeWorkShop, Validators.required), - freeWifi: new FormControl(structure.freeWifi, Validators.required), }); - - // Init hours form - this.hoursForm = new FormGroup({ - monday: this.createDay(structure.hours.monday), - tuesday: this.createDay(structure.hours.tuesday), - wednesday: this.createDay(structure.hours.wednesday), - thursday: this.createDay(structure.hours.thursday), - friday: this.createDay(structure.hours.friday), - saturday: this.createDay(structure.hours.saturday), - sunday: this.createDay(structure.hours.sunday), + return form; + } + private showCollapse(s: Structure): void { + if (s.website) { + this.showWebsite = true; + } + if (s.facebook || s.twitter || s.instagram || s.linkedin) { + this.showSocialNetwork = true; + } + if (s.publicsAccompaniment.length) { + this.showPublicsAccompaniment = true; + } + if (s.proceduresAccompaniment.length) { + this.showProceduresAccompaniment = true; + } + this.trainingCategories.forEach((categ: { category: Category; openned: boolean }) => { + categ.openned = false; + switch (categ.category.id) { + case 'accessRight': + if (s.accessRight.length) { + categ.openned = true; + } + break; + case 'socialAndProfessional': + if (s.socialAndProfessional.length) { + categ.openned = true; + } + break; + case 'baseSkills': + if (s.baseSkills.length) { + categ.openned = true; + } + break; + case 'parentingHelp': + if (s.parentingHelp.length) { + categ.openned = true; + } + break; + case 'digitalCultureSecurity': + if (s.digitalCultureSecurity.length) { + categ.openned = true; + } + break; + } + }); + this.equipmentsAndServices.forEach((equipment: { module: Module; openned: boolean }) => { + equipment.openned = false; + switch (equipment.module.id) { + case 'ordinateurs': + if (s.equipmentsAndServices.includes('ordinateurs')) { + equipment.openned = true; + } + break; + case 'tablettes': + if (s.equipmentsAndServices.includes('tablettes')) { + equipment.openned = true; + } + break; + case 'bornesNumeriques': + if (s.equipmentsAndServices.includes('bornesNumeriques')) { + equipment.openned = true; + } + break; + case 'imprimantes': + if (s.equipmentsAndServices.includes('imprimantes')) { + equipment.openned = true; + } + break; + case 'scanners': + if (s.equipmentsAndServices.includes('scanners')) { + equipment.openned = true; + } + break; + } }); - this.setValidationsForm(); } private loadArrayForCheckbox(array: string[], isRequired: boolean): FormArray { @@ -254,12 +338,15 @@ export class FormComponent implements OnInit { } private createTime(time: Time): FormGroup { return new FormGroup({ - openning: new FormControl(time.openning, Validators.pattern('[a-z0-9._%+-]+@[a-z0-9.-]+.[a-z]{2,3}$')), //NOSONAR - closing: new FormControl(time.closing, Validators.pattern('[a-z0-9._%+-]+@[a-z0-9.-]+.[a-z]{2,3}$')), //NOSONAR + openning: new FormControl(time.openning), //NOSONAR + closing: new FormControl(time.closing), //NOSONAR }); } public onCheckChange(event: boolean, formControlName: string, value: string): void { + if (value == 'wifiEnAccesLibre') { + this.isWifiChoosen = true; + } const formArray: FormArray = this.structureForm.get(formControlName) as FormArray; if (event) { // Add a new control in the arrayForm @@ -297,13 +384,20 @@ export class FormComponent implements OnInit { }; this.pagesValidation[4] = { valid: this.getStructureControl('structureName').valid && this.getStructureControl('address').valid, + name: 'Nom et adresse', + }; + this.pagesValidation[5] = { valid: this.getStructureControl('contactPhone').valid, name: 'Téléphone' }; + this.pagesValidation[6] = { valid: this.getStructureControl('structureType').valid, name: 'Type de structure' }; + this.pagesValidation[7] = { valid: this.getStructureControl('accessModality').valid, name: "Modalités d'accueil " }; + this.pagesValidation[8] = { valid: this.hoursForm.valid, name: "Horaires d'ouverture" }; + this.pagesValidation[9] = { + valid: this.getStructureControl('exceptionalClosures').valid, + name: 'Précisions sur les horaires', + }; + this.pagesValidation[10] = { + valid: this.getStructureControl('pmrAccess').valid, + name: 'Accessibilité pour les personnes à mobilité réduite', }; - this.pagesValidation[5] = { valid: this.getStructureControl('contactPhone').valid }; - this.pagesValidation[6] = { valid: this.getStructureControl('structureType').valid }; - this.pagesValidation[7] = { valid: this.getStructureControl('accessModality').valid }; - this.pagesValidation[8] = { valid: this.hoursForm.valid }; - this.pagesValidation[9] = { valid: this.getStructureControl('exceptionalClosures').valid }; - this.pagesValidation[10] = { valid: this.getStructureControl('pmrAccess').valid }; this.pagesValidation[11] = { valid: this.getStructureControl('contactMail').valid && @@ -312,15 +406,18 @@ export class FormComponent implements OnInit { this.getStructureControl('twitter').valid && this.getStructureControl('instagram').valid) || !this.showSocialNetwork), + name: 'Présence sur internet', }; - this.pagesValidation[12] = { valid: this.getStructureControl('publics').valid }; + this.pagesValidation[12] = { valid: this.getStructureControl('publics').valid, name: 'Public admis' }; this.pagesValidation[13] = { valid: this.getStructureControl('publicsAccompaniment').valid && this.getStructureControl('proceduresAccompaniment').valid, + name: 'Accompagnements proposés', }; this.pagesValidation[14] = { valid: this.getStructureControl('otherDescription').value, + name: 'Autres démarches proposés', }; this.pagesValidation[15] = { valid: @@ -329,9 +426,13 @@ export class FormComponent implements OnInit { this.getStructureControl('baseSkills').valid && this.getStructureControl('parentingHelp').valid && this.getStructureControl('digitalCultureSecurity').valid, + name: 'Ateliers au numérique proposés', + }; + this.pagesValidation[16] = { valid: this.getStructureControl('freeWorkShop').valid, name: 'Gratuité des ateliers' }; + this.pagesValidation[17] = { + valid: this.getStructureControl('equipmentsAndServices').valid && this.isWifiChoosen, + name: 'Gratuité du wifi', }; - this.pagesValidation[16] = { valid: this.getStructureControl('freeWorkShop').valid }; - this.pagesValidation[17] = { valid: this.getStructureControl('freeWifi').valid }; this.pagesValidation[18] = { valid: this.getStructureControl('equipmentsAndServices').valid && @@ -340,11 +441,24 @@ export class FormComponent implements OnInit { this.getStructureControl('nbTablets').valid && this.getStructureControl('nbNumericTerminal').valid && this.getStructureControl('nbScanners').valid, + name: 'Matériels mis à disposition', + }; + this.pagesValidation[19] = { + valid: this.getStructureControl('labelsQualifications').valid, + name: 'Labélisations proposées', + }; + this.pagesValidation[20] = { + valid: this.getStructureControl('equipmentsAndServices').valid, + name: 'Autres services proposés', + }; + this.pagesValidation[21] = { + valid: this.getStructureControl('description').valid, + name: 'Présentation de la structure', + }; + this.pagesValidation[22] = { + valid: this.getStructureControl('lockdownActivity').valid, + name: 'Informations spécifiques à la période COVID', }; - this.pagesValidation[19] = { valid: this.getStructureControl('labelsQualifications').valid }; - this.pagesValidation[20] = { valid: this.getStructureControl('equipmentsAndServices').valid }; - this.pagesValidation[21] = { valid: this.getStructureControl('description').valid }; - this.pagesValidation[22] = { valid: this.getStructureControl('lockdownActivity').valid }; this.pagesValidation[23] = { valid: this.userAcceptSavedDate }; //this.pagesValidation[24] = { valid: true }; this.updatePageValid(); @@ -507,19 +621,26 @@ export class FormComponent implements OnInit { let structure: Structure = this.structureForm.value; structure.hours = this.hoursForm.value; let user: User; - if (this.profile) { - user = this.profile; - structure.accountVerified = true; - this.createStructure(structure, user); + if (this.isEditMode) { + this.structureService.editStructure(structure).subscribe((s: Structure) => { + this.createdStructure = this.structureService.updateOpeningStructure(s, DateTime.local()); + this.editForm = this.createStructureForm(s); + }); } else { - if (this.accountForm.valid) { - user = new User(this.accountForm.value); - this.authService - .register(user) - .pipe(first()) - .subscribe(() => { - this.createStructure(structure, user); - }); + if (this.profile) { + user = this.profile; + structure.accountVerified = true; + this.createStructure(structure, user); + } else { + if (this.accountForm.valid) { + user = new User(this.accountForm.value); + this.authService + .register(user) + .pipe(first()) + .subscribe(() => { + this.createStructure(structure, user); + }); + } } } } @@ -542,7 +663,7 @@ export class FormComponent implements OnInit { public canExit(): Promise<boolean> { // Avoid confirmation when user submit form and leave. - if (this.currentPage == this.nbPagesForm) { + if (this.currentPage == this.nbPagesForm || this.currentPage < 3 || this.isEditMode) { return new Promise((resolve) => resolve(true)); } else { return new Promise((resolve) => this.showModal(resolve)); @@ -558,6 +679,24 @@ export class FormComponent implements OnInit { this.showConfirmationModal = false; } + // Function for editMode only + + public goToSpecificPage(numPage: number, isSave: boolean): void { + if (isSave) { + this.validateForm(); + } else { + const structure = new Structure(this.editForm.value); + this.structureForm = this.createStructureForm(structure); + this.showCollapse(structure); + } + this.currentPage = numPage; + this.updatePageValid(); + } + + public closeEditMode(): void { + this.router.navigateByUrl('home', { state: { data: this.createdStructure } }); + } + public verifyUserExist(inputEmail): void { if (this.accountForm.get('email').valid) { this.profileService.isEmailAlreadyUsed(inputEmail).subscribe((isExist) => { diff --git a/src/app/models/structure.model.ts b/src/app/models/structure.model.ts index cbf1e4cb284b2e4474d399b34e67fb5a61bd52f9..0e107ba8ac59f949678edc04d93d171e3ca50213 100644 --- a/src/app/models/structure.model.ts +++ b/src/app/models/structure.model.ts @@ -37,7 +37,6 @@ export class Structure { public equipmentsAndServices: string[] = []; public hours: Week; public freeWorkShop: boolean = null; - public freeWifi: boolean = null; public otherDescription: string = null; public isOpen: boolean = false; diff --git a/src/app/services/structure.service.ts b/src/app/services/structure.service.ts index 41a02af5a7952850db348fc08ad30deeea555c62..e370f3c669393d4ecb92c227519ea2b4430cacce 100644 --- a/src/app/services/structure.service.ts +++ b/src/app/services/structure.service.ts @@ -31,8 +31,9 @@ export class StructureService { return this.http.post(`${this.baseUrl}`, { structure, idUser }).pipe(map((item: Structure) => new Structure(item))); } - public editStructure(id: string, structure: Structure): Observable<Structure> { + public editStructure(structure: Structure): Observable<Structure> { structure.updatedAt = new Date().toString(); + const id = structure._id; delete structure._id; // id should not be provided for update return this.http.put(`${this.baseUrl}/${id}`, structure).pipe(map((item: Structure) => new Structure(item))); } 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 0a509ad52dd5895c6d6c3aef3c5de0a915a07dbe..ff785893b3a1f3adaf7b8aea1eda28f3cb06e8f8 100644 --- a/src/app/shared/components/hour-picker/hour-picker.component.html +++ b/src/app/shared/components/hour-picker/hour-picker.component.html @@ -19,7 +19,6 @@ id="{{ day.name }}" (click)="toggleOpenDay(day, $event.target.checked)" [checked]="day.open" - [disabled]="isEditMode" /> <span class="slider"></span> </label> @@ -52,13 +51,13 @@ <div>de</div> <div class="input-container"> - <input type="time" [(ngModel)]="hour.start" (change)="submitForm()" [disabled]="isEditMode" /> + <input type="time" [(ngModel)]="hour.start" (change)="submitForm()" /> </div> <div>à </div> <div class="input-container"> - <input type="time" [(ngModel)]="hour.end" (change)="submitForm()" [disabled]="isEditMode" /> + <input type="time" [(ngModel)]="hour.end" (change)="submitForm()" /> </div> <div> @@ -70,7 +69,7 @@ </div> </div> </div> - <div class="add" *ngIf="day.hours.length === 1 && !isEditMode"> + <div class="add" *ngIf="day.hours.length === 1"> <div (click)="addHours(day)" fxLayout="row" diff --git a/src/app/shared/components/hour-picker/hour-picker.component.ts b/src/app/shared/components/hour-picker/hour-picker.component.ts index 6114ce012c57b7a989b263ced5f0b87428ee49a3..63f42f543c5790b2439704108135b12edbf340b5 100644 --- a/src/app/shared/components/hour-picker/hour-picker.component.ts +++ b/src/app/shared/components/hour-picker/hour-picker.component.ts @@ -14,7 +14,6 @@ import { CheckHours } from '../../validator/form'; export class HourPickerComponent implements OnChanges, OnDestroy { @Input() modifiedFields: any; @Input() structureInput: FormGroup; - @Input() isEditMode: boolean; @Output() updateFormError = new EventEmitter<any>(); @Output() updateForm = new EventEmitter<FormGroup>(); diff --git a/src/app/shared/components/modal-confirmation/modal-confirmation.component.html b/src/app/shared/components/modal-confirmation/modal-confirmation.component.html index d2bc29320a9ffd3cafaf17d0b5d1bc5597795618..018d67fad261bcca0cdc5a6252a94a82ee50ef9a 100644 --- a/src/app/shared/components/modal-confirmation/modal-confirmation.component.html +++ b/src/app/shared/components/modal-confirmation/modal-confirmation.component.html @@ -4,8 +4,8 @@ <h3>ATTENTION</h3> <p>{{ content }}</p> <div class="footerModal" fxLayout="row" fxLayoutAlign="space-around center"> - <button class="btn confirm" (click)="closeModal(true)">Confirmer</button> - <button class="btn" (click)="closeModal(false)">Annuler</button> + <button class="btn-primary small leave" (click)="closeModal(true)">Confirmer</button> + <button class="btn-primary small" (click)="closeModal(false)">Annuler</button> </div> </div> </div> diff --git a/src/app/shared/components/modal-confirmation/modal-confirmation.component.scss b/src/app/shared/components/modal-confirmation/modal-confirmation.component.scss index 5f111d0b57f48fb94e8b7d3c564436bf76760667..8b50ba8f37e2ece4fcd66a534a6e91027d7bc364 100644 --- a/src/app/shared/components/modal-confirmation/modal-confirmation.component.scss +++ b/src/app/shared/components/modal-confirmation/modal-confirmation.component.scss @@ -3,12 +3,45 @@ @import '../../../../assets/scss/shapes'; @import '../../../../assets/scss/z-index'; -h3 { - @include cn-bold-18; - color: $orange-warning; -} -p { - @include cn-bold-16; - color: $grey-1; - text-align: center; +.modalExitContainer { + width: 100%; + height: 100%; + z-index: $modal-z-index; + position: absolute; + content: ''; + top: 0; + background-color: $modal-background; + .modal { + .contentModal { + width: 100%; + background: $white; + padding: 35px 20px 18px 20px; + h3 { + @include cn-bold-18; + color: $orange-warning; + } + p { + @include cn-bold-16; + color: $grey-1; + text-align: center; + } + .footerModal { + width: 100%; + margin-top: 14px; + @include cn-bold-16; + .leave { + background: none; + color: $grey-1; + text-decoration: underline; + } + } + } + width: 350px; + margin: auto; + border-radius: 6px; + @include background-hash; + border: 1px solid $grey-4; + margin-top: 50vh; + transform: translateY(-50%); + } } diff --git a/src/app/shared/components/structure-type-picker/structure-type-picker.component.html b/src/app/shared/components/structure-type-picker/structure-type-picker.component.html index 3c6fa1bb62feabd9dc263db1b43c65c507766189..3613f3efbca5bf4f8735d573dde09087f72dffc8 100644 --- a/src/app/shared/components/structure-type-picker/structure-type-picker.component.html +++ b/src/app/shared/components/structure-type-picker/structure-type-picker.component.html @@ -26,7 +26,7 @@ <svg *ngIf="choice == pickedChoice" class="validate" aria-hidden="true"> <use [attr.xlink:href]="'assets/form/sprite.svg#checkVector'"></use> </svg> - {{ choice }} + {{ getStructureTypeName(choice) }} </button> </div> </div> diff --git a/src/app/shared/components/structure-type-picker/structure-type-picker.component.ts b/src/app/shared/components/structure-type-picker/structure-type-picker.component.ts index 7de31248696706fbd40a1b25dde2dcbf4746542a..b64a4718fdd9a00e6ec230e052f97725312195ec 100644 --- a/src/app/shared/components/structure-type-picker/structure-type-picker.component.ts +++ b/src/app/shared/components/structure-type-picker/structure-type-picker.component.ts @@ -1,6 +1,7 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { StructureType } from '../../../models/structure-type.model'; import { StructureTypeService } from '../../../services/structure-type.service'; +import { typeStructureEnum } from '../../enum/typeStructure.enum'; export enum structureTypes { public = 'Publique', @@ -22,11 +23,11 @@ export class StructureTypePickerComponent implements OnInit { constructor(private structureTypeService: StructureTypeService) {} ngOnInit() { - if (this.pickedChoice) { - this.pickedType = this.getType(this.pickedChoice); - } this.structureTypeService.getStructureTypes().subscribe((types) => { this.structureTypes = types; + if (this.pickedChoice) { + this.pickedType = this.getType(this.pickedChoice); + } }); } @@ -67,4 +68,7 @@ export class StructureTypePickerComponent implements OnInit { throw new Error('Structure type not handle'); } } + public getStructureTypeName(type: string): string { + return typeStructureEnum[type]; + } } diff --git a/src/app/shared/enum/regex.enum.ts b/src/app/shared/enum/regex.enum.ts index 7a564960fa0e226ae58aa94f2f1e728b8d7b5289..6011651df41e73e756b4bacdbcab714fcfe6afe3 100644 --- a/src/app/shared/enum/regex.enum.ts +++ b/src/app/shared/enum/regex.enum.ts @@ -1,11 +1,11 @@ export enum Regex { email = '[a-z0-9.-]+@[a-z0-9.-]+[.][a-z]{2,3}', - textWithoutNumber = '[A-Za-zÀ-ÖØ-öø-ÿ-]{1,}', + textWithoutNumber = '[A-Za-zÀ-ÖØ-öø-ÿ- ]{1,}', phone = '([0-9]{2} ){4}[0-9]{2}', - website = '(www[.])[a-z0-9.-]*[.][a-z]{2,3}', - linkedIn = '(linkedin.com/in/[a-z0-9A-Z.-]{1,})', - facebook = '(facebook.com/[a-z0-9A-Z.-]{1,})', - twitter = '(twitter.com/[a-z0-9A-Z.-]{1,})', - instagram = '(instagram.com/[a-z0-9A-Z.-]{1,})', + website = '(www[.])?(https://)?(http://)?[a-zA-Z0-9.-]*[.][a-z]{2,3}((/)[a-zA-Z0-9-/]*)?', + linkedIn = '(linkedin.com/in/.{1,})', + facebook = '(facebook.com/.{1,})', + twitter = '(twitter.com/.{1,})', + instagram = '(instagram.com/.{1,})', noNullNumber = '[1-9]{1}[0-9]*', } diff --git a/src/app/shared/enum/typeStructure.enum.ts b/src/app/shared/enum/typeStructure.enum.ts index e21c7cb40812286b8a490a5cad92bfbf74aad12c..e23ed6665387765f6a697d4c1773bf2ab2e743ef 100644 --- a/src/app/shared/enum/typeStructure.enum.ts +++ b/src/app/shared/enum/typeStructure.enum.ts @@ -1,19 +1,32 @@ export enum typeStructureEnum { - associationCaritative = 'Association caritative', - centreSocio = 'Centre socio-culturel', - cyber = 'Cyberbase / Cybercentre', - coworking = 'Espace de coworking', fablab = 'Fablab', + // A supprimer ? + + //A remplacer par Association ? + associationQuartier = 'Structure associative de quartier', + associationCaritative = 'Association caritative', + + // En attente de suppression remplacer par CAF CARSAT, Pole Emploi et CCAS grandOrganismePublic = 'Grand organisme public (CAF, CARSAT, Pôle emploi...)', + + mdm = 'Maison de la métropole', mairie = 'Mairie', - mdm = 'Maison de la Métropole (MDM)', - mediatheque = 'Médiathèque / Bibliothèque', + CAF = 'CAF', + CCAS = 'CCAS', + CARSAT = 'CARSAT', + poleEmploi = 'Pole Emploi', + mediatheque = 'Médiathèque/Bibliothèque', + prefecture = 'Préfecture', + bijPij = 'BIJ/PIJ', + logement = 'Logement', + + association = 'Association', + centreSocio = 'Centre socio-culturel', + mjc = 'MJC / Cyberbase', + pimms = 'PIMMS', + sij = 'Structure information jeunesse (SIJ)', missionsLocales = 'Missions locales', - mjc = 'MJC', - pimms = 'Pimms', - ressourcerie = 'Ressourcerie (matériel moindre coût / recyclé)', - associationQuartier = 'Structure associative de quartier', + formation = 'Structure de formation', insertion = "Structure d'insertion", - sij = 'Structure information jeunesse (SIJ)', } diff --git a/src/app/structure-list/components/card/card.component.html b/src/app/structure-list/components/card/card.component.html index b9bc6cc927b00f524f18ec18933add1f2c50e055..2a02fd3a659b8916d32cad1cebfe4fe31de54f6e 100644 --- a/src/app/structure-list/components/card/card.component.html +++ b/src/app/structure-list/components/card/card.component.html @@ -16,7 +16,7 @@ <span class="typeStructure">{{ structure.getLabelTypeStructure() }}</span> <div fxLayout="row" fxLayoutAlign="none flex-end" fxLayoutGap="7px" *ngIf="structure.hasEquipments()"> <app-svg-icon - *ngFor="let equipement of structure.equipmentsAndServices" + *ngFor="let equipement of filterOnlyEquipments(structure.equipmentsAndServices)" [type]="'ico'" [iconColor]="'grey'" [icon]="structure.getEquipmentsIcon(equipement)" diff --git a/src/app/structure-list/components/card/card.component.ts b/src/app/structure-list/components/card/card.component.ts index 58d7f395db867cbfdc9afd51f2a6ea77c455535e..8a64274b6377eaca0cc84eb713dbf5dd4067483e 100644 --- a/src/app/structure-list/components/card/card.component.ts +++ b/src/app/structure-list/components/card/card.component.ts @@ -35,4 +35,9 @@ export class CardComponent implements OnInit { public cardHover(): void { this.hover.emit(this.structure); } + public filterOnlyEquipments(equipmentsAndServices: string[]): string[] { + return equipmentsAndServices.filter((eqpt) => + ['ordinateurs', 'tablettes', 'bornesNumeriques', 'imprimantes', 'scanners', 'wifiEnAccesLibre'].includes(eqpt) + ); + } } 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 5f2d23285cddb815fc937705623d9272c296d691..08b0db06cc9ff66654168d07c206899adf7a7d16 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 @@ -1,11 +1,3 @@ -<app-structureForm - *ngIf="showForm" - [idStructure]="structure._id" - [isEditMode]="isEditMode" - [profile]="currentProfile" - (closeEvent)="updateStructure($event)" - (clickOutside)="displayForm()" -></app-structureForm> <div class="structrue-details-container" *ngIf="structure && !isLoading"> <!-- Header info --> <div fxLayout="row" fxLayoutAlign="end center"> @@ -20,8 +12,9 @@ <div class="typeInformationHeader" fxLayout="column"> <h3>{{ structure.getLabelTypeStructure() }}</h3> <div fxLayout="row" fxLayoutAlign="none flex-end" fxLayoutGap="7px" *ngIf="structure.hasEquipments()"> + <div></div> <app-svg-icon - *ngFor="let equipement of structure.equipmentsAndServices" + *ngFor="let equipement of filterOnlyEquipments(structure.equipmentsAndServices)" [type]="'ico'" [iconColor]="'currentColor'" [icon]="structure.getEquipmentsIcon(equipement)" @@ -128,14 +121,15 @@ >Revendiquer cette structure</a > <!-- temporary remove edit --> - <!-- <a + <a *ngIf="profileService.isLinkedToStructure(structure._id) || profileService.isAdmin()" - (click)="editStructure()" + routerLink="/create-structure" + [state]="{ data: structure }" class="primary" tabindex="0" > Modifier cette structure - </a> --> + </a> <a *ngIf="profileService.isAdmin()" (click)="toggleDeleteModal()" class="primary" tabindex="0"> Supprimer cette structure </a> @@ -261,7 +255,7 @@ <h2>Équipements</h2> </div> <div fxLayout="column"> - <p *ngFor="let equipement of structure.equipmentsAndServices" class="no-margin-bottom"> + <p *ngFor="let equipement of filterOnlyEquipments(structure.equipmentsAndServices)" class="no-margin-bottom"> {{ getEquipmentsLabel(equipement) }} <span *ngIf="equipement == 'ordinateurs' && structure.nbComputers"> : {{ structure.nbComputers }}</span> <span *ngIf="equipement == 'tablettes' && structure.nbTablets"> : {{ structure.nbTablets }}</span> 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 bff893ebc5ddd119d938190c56300fd5bf819460..dc84ff30b68137212e00865c6980ec67642eb45f 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 @@ -23,7 +23,6 @@ import { PublicCategorie } from '../../enum/public.enum'; export class StructureDetailsComponent implements OnInit { @Input() public structure: Structure; @Output() public closeDetails: EventEmitter<boolean> = new EventEmitter<boolean>(); - @Output() public updatedStructure: EventEmitter<Structure> = new EventEmitter<Structure>(); public accessModality = AccessModality; public baseSkillssReferentiel: Category; @@ -32,10 +31,8 @@ export class StructureDetailsComponent implements OnInit { public accessRights: Module[]; public tclStopPoints: TclStopPoint[] = []; public printMode = false; - public showForm = false; public isClaimed: boolean = null; public isLoading: boolean = false; - public isEditMode: boolean = false; public currentProfile: User = null; public deleteModalOpenned = false; public claimModalOpenned = false; @@ -117,11 +114,6 @@ export class StructureDetailsComponent implements OnInit { this.printService.printDocument('structure', this.structure); } - public editStructure(): void { - this.isEditMode = true; - this.displayForm(); - } - public toggleDeleteModal(): void { this.deleteModalOpenned = !this.deleteModalOpenned; } @@ -155,17 +147,6 @@ export class StructureDetailsComponent implements OnInit { }); } } - // Show/hide form structure - public displayForm(): void { - this.showForm = !this.showForm; - } - - public updateStructure(s: Structure): void { - this.structure = new Structure({ ...this.structure, ...s }); - this.updatedStructure.emit(this.structure); - this.displayForm(); - this.ngOnInit(); - } public getAccessLabel(accessModality: AccessModality): string { switch (accessModality) { @@ -192,6 +173,8 @@ export class StructureDetailsComponent implements OnInit { return 'Séniors (+ de 65 ans)'; case PublicCategorie.all: return 'Tout public'; + case PublicCategorie.under16Years: + return 'Moins de 16 ans'; default: return null; } @@ -220,4 +203,9 @@ export class StructureDetailsComponent implements OnInit { this.tclStopPoints = res; }); } + public filterOnlyEquipments(equipmentsAndServices: string[]): string[] { + return equipmentsAndServices.filter((eqpt) => + ['ordinateurs', 'tablettes', 'bornesNumeriques', 'imprimantes', 'scanners', 'wifiEnAccesLibre'].includes(eqpt) + ); + } } diff --git a/src/app/structure-list/enum/public.enum.ts b/src/app/structure-list/enum/public.enum.ts index 1f837130376982ac9fb26266d8218d0aa63dfa66..27256129767d536ed0b9b6974b408fbcedfae7e1 100644 --- a/src/app/structure-list/enum/public.enum.ts +++ b/src/app/structure-list/enum/public.enum.ts @@ -1,4 +1,5 @@ export enum PublicCategorie { + under16Years = 'moinsDe16Ans', young = 'jeunes1625Ans', adult = 'adultes', elderly = 'seniorsPlusDe65Ans', diff --git a/src/assets/scss/_buttons.scss b/src/assets/scss/_buttons.scss index 6f8458fcfb62bf057bf6c802b6df275f3b875901..ec08d9b85f7cd16f8657e20ca299f4e8392773ce 100644 --- a/src/assets/scss/_buttons.scss +++ b/src/assets/scss/_buttons.scss @@ -62,3 +62,21 @@ line-height: 18px; padding: 8px 15px; } + +.btn-primary { + background: $secondary-color; + border-radius: 4px; + outline: none; + cursor: pointer; + border: 0; + color: $white; + height: 40px; + width: 192px; + @include btn-bold; + &.small { + width: 149px; + } + &.invalid { + opacity: 0.4; + } +} diff --git a/src/assets/scss/_layout.scss b/src/assets/scss/_layout.scss index b80043aa24c23f2824ec2e30be3f94cc8d926627..94ebedd43f510c2edad4ae2edb0202c2c49bc8d9 100644 --- a/src/assets/scss/_layout.scss +++ b/src/assets/scss/_layout.scss @@ -1,4 +1,5 @@ $header-height: 70px; $footer-height: 56px; -$header-height-phone: 50px; +$header-height-phone: 70px; $footer-height-phone: 75px; +$progressBar-height: 50px;