Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • web-et-numerique/factory/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_client
1 result
Show changes
Showing
with 1266 additions and 0 deletions
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { User } from '../../../models/user.model';
import { ProfileService } from '../../../profile/services/profile.service';
import { formType } from '../formType.enum';
import { accountFormStep } from './accountFormStep.enum';
@Component({
selector: 'app-account-form',
templateUrl: './account-form.component.html',
})
export class AccountFormComponent implements OnChanges {
@Input() nbSteps: number;
@Input() currentStep: accountFormStep;
@Input() accountForm: FormGroup;
public isClaimMode = false;
public isAccountMode = false;
public pagesValidation = [];
public userAcceptSavedDate = false;
public isPageValid: boolean;
public profile: User;
public accountFormStepEnum = accountFormStep;
public formType = formType;
@Output() pageValid = new EventEmitter<any>();
@Output() acceptNewsletter = new EventEmitter<any>();
constructor(private profileService: ProfileService) {}
ngOnChanges(changes: SimpleChanges): void {
if (changes.currentStep) {
if (this.currentStep === accountFormStep.accountNewsletter) {
this.pageValid.emit();
}
}
}
public setValidationsForm(): void {
this.pagesValidation[accountFormStep.accountInfo] = {
valid:
this.accountForm.get('surname').valid &&
this.accountForm.get('name').valid &&
this.accountForm.get('phone').valid,
};
this.pagesValidation[accountFormStep.accountCredentials] = {
valid:
this.accountForm.get('email').valid &&
this.accountForm.get('password').valid &&
this.accountForm.get('confirmPassword').valid,
};
this.updatePageValid();
}
public verifyUserExist(inputEmail): void {
if (this.accountForm.get('email').valid) {
this.profileService.isEmailAlreadyUsed(inputEmail).subscribe((isExist) => {
if (isExist) {
this.accountForm.get('email').setErrors({ alreadyExist: true });
this.setValidationsForm();
}
});
}
}
/**
* Update valid page or return page validity of the given index
* @param {number} [index] - Page index
*/
private updatePageValid(index?: number): boolean {
if (index) {
return this.pagesValidation[index].valid;
}
this.isPageValid = this.pagesValidation[this.currentStep].valid;
if (this.isPageValid) this.pageValid.emit();
return this.isPageValid;
}
public acceptReceiveNewsletter(accept: boolean): void {
this.acceptNewsletter.emit(accept);
}
}
<form [formGroup]="accountForm" *ngIf="accountForm && !profile">
<div class="title">
<h3>Qui êtes-vous&nbsp;?</h3>
<p>Vous pourrez choisir de rendre visibles ces informations sur votre profil public</p>
</div>
<div class="form-group" fxLayout="column">
<label for="name">Prénom</label>
<div fxLayout="row" fxLayoutGap="13px">
<input type="text" (input)="setValidationsForm()" formControlName="name" class="form-input" />
<app-svg-icon
*ngIf="accountForm.get('name').valid"
[iconClass]="'icon-26'"
[type]="'form'"
[icon]="'validate'"
></app-svg-icon>
<app-svg-icon
*ngIf="accountForm.get('name').invalid && accountForm.get('name').value"
[iconClass]="'icon-26'"
[type]="'form'"
[icon]="'notValidate'"
></app-svg-icon>
</div>
</div>
<div class="form-group" fxLayout="column">
<label for="surname">Nom</label>
<div fxLayout="row" fxLayoutGap="13px">
<input type="text" (input)="setValidationsForm()" formControlName="surname" class="form-input" />
<app-svg-icon
*ngIf="accountForm.get('surname').valid"
[iconClass]="'icon-26'"
[type]="'form'"
[icon]="'validate'"
></app-svg-icon>
<app-svg-icon
*ngIf="accountForm.get('surname').invalid && accountForm.get('surname').value"
[iconClass]="'icon-26'"
[type]="'form'"
[icon]="'notValidate'"
></app-svg-icon>
</div>
</div>
<div class="form-group" fxLayout="column">
<label for="phone">Téléphone</label>
<div fxLayout="row" fxLayoutGap="13px">
<input
type="text"
formControlName="phone"
class="form-input phone"
(input)="utils.modifyPhoneInput(accountForm, 'phone', $event.target.value); setValidationsForm()"
/>
<app-svg-icon
*ngIf="accountForm.get('phone').valid"
[iconClass]="'icon-26'"
[type]="'form'"
[icon]="'validate'"
></app-svg-icon>
<app-svg-icon
*ngIf="accountForm.get('phone').invalid && accountForm.get('phone').value"
[iconClass]="'icon-26'"
[type]="'form'"
[icon]="'notValidate'"
></app-svg-icon>
</div>
</div>
</form>
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AccountInfoComponent } from './account-info.component';
describe('AccountInfoComponent', () => {
let component: AccountInfoComponent;
let fixture: ComponentFixture<AccountInfoComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ AccountInfoComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(AccountInfoComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { User } from '../../../../models/user.model';
import { Utils } from '../../../../utils/utils';
@Component({
selector: 'app-account-info',
templateUrl: './account-info.component.html',
})
export class AccountInfoComponent {
@Input() accountForm: FormGroup;
@Input() isClaimMode: boolean;
@Input() profile: User;
@Output() validateForm = new EventEmitter<any>();
constructor(public utils: Utils) {}
public setValidationsForm() {
this.validateForm.emit();
}
}
<form
[formGroup]="accountForm"
*ngIf="accountForm && !profile"
(keyup.enter)="isPageValid && !isEditMode ? nextPage() : null"
>
<div class="title">
<h3>Souhaitez-vous vous abonner à la lettre d’information de Res'in&nbsp;?</h3>
<p class="notRequired" *ngIf="!isEditMode">Facultatif</p>
</div>
<app-checkbox-form
[isChecked]="userAcceptNewsletter"
[text]="'J\'accepte'"
(checkEvent)="acceptReceiveNewsletter($event)"
>
</app-checkbox-form>
</form>
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AccountNewsletterComponent } from './account-newsletter.component';
describe('AccountNewsletterComponent', () => {
let component: AccountNewsletterComponent;
let fixture: ComponentFixture<AccountNewsletterComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ AccountNewsletterComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(AccountNewsletterComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { User } from '../../../../models/user.model';
@Component({
selector: 'app-account-newsletter',
templateUrl: './account-newsletter.component.html',
})
export class AccountNewsletterComponent {
@Input() accountForm: FormGroup;
@Input() profile: User;
@Output() acceptNewsletter = new EventEmitter<any>();
public acceptReceiveNewsletter(accepts: boolean) {
this.acceptNewsletter.emit(accepts);
}
}
export enum accountFormStep {
accountInfo,
accountCredentials,
accountNewsletter,
confirmEmailSentInfo,
}
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AuthGuard } from '../../guards/auth.guard';
import { AccountFormComponent } from './account-form/account-form.component';
import { FormViewComponent } from './form-view.component';
import { PersonalOfferGuard } from './guards/personalOffer.guard';
import { PersonalOfferFormComponent } from './personal-offer-form/personal-offer-form.component';
import { ProfileFormComponent } from './profile-form/profile-form.component';
import { StructureFormComponent } from './structure-form/structure-form.component';
const routes: Routes = [
{
path: '',
component: FormViewComponent,
children: [
{
path: 'structure',
canActivate: [AuthGuard],
component: StructureFormComponent,
},
{
path: 'profile',
canActivate: [AuthGuard],
component: ProfileFormComponent,
},
{
path: 'personaloffer',
canActivate: [AuthGuard, PersonalOfferGuard],
component: PersonalOfferFormComponent,
},
{
path: 'account',
component: AccountFormComponent,
},
{
path: '**',
redirectTo: 'account',
},
],
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class FormViewRoutingModule {}
<div>
<app-progress-bar
[formType]="formType[routeParam]"
[isEditMode]="isEditMode"
[currentPage]="currentPage - 1"
[nbSteps]="nbSteps"
></app-progress-bar>
<div class="page">
<ng-container *ngIf="formType[routeParam] === formType.account">
<app-account-form
[nbSteps]="nbSteps"
[accountForm]="accountForm"
[hoursForm]="hoursForm"
[currentStep]="currentPage"
(goNext)="nextPage()"
(pageValid)="validatePage($event)"
(acceptNewsletter)="acceptReceiveNewsletter($event)"
></app-account-form>
</ng-container>
<ng-container *ngIf="formType[routeParam] === formType.profile">
<app-profile-form
[nbSteps]="nbSteps"
[profileForm]="profileForm"
[currentStep]="currentPage"
(goNext)="nextPage()"
(pageValid)="validatePage($event)"
></app-profile-form>
</ng-container>
<ng-container *ngIf="formType[routeParam] === formType.structure">
<app-structure-form
[nbSteps]="nbSteps"
[structureForm]="structureForm"
[hoursForm]="hoursForm"
[currentStep]="currentPage"
[structure]="structure"
(goNext)="nextPage()"
(isNotExistingStructure)="nextPage()"
(pageValid)="validatePage($event)"
(updateHoursForm)="updateHours($event)"
></app-structure-form>
</ng-container>
<ng-container *ngIf="formType[routeParam] === formType.personaloffer">
<app-personal-offer-form
[nbSteps]="nbSteps"
[personalOfferForm]="personalOfferForm"
[currentStep]="currentPage"
[structureName]="structure.structureName"
(setHasOtherOffer)="setHasOtherPersonalOffer($event)"
(pageValid)="validatePage($event)"
></app-personal-offer-form>
</ng-container>
</div>
<app-footer-form
*ngIf="displayFooterForm()"
[currentStep]="currentPage"
[currentForm]="currentFormType"
[form]="currentForm"
[btnName]="['Précédent', 'Suivant']"
[isValid]="isPageValid"
[acceptNewsletter]="userAcceptNewsletter"
[hasOtherPersonalOffer]="hasOtherPersonalOffer"
(goNext)="nextPage()"
(goPrev)="prevPage()"
(endForm)="endForm($event)"
(changeCurrentStep)="setCurrentStep($event)"
></app-footer-form>
</div>
@import '../../../assets/scss/color';
@import '../../../assets/scss/breakpoint';
@import '../../../assets/scss/layout';
@import '../../../assets//scss/typography';
::ng-deep.page {
max-width: 1000px;
box-sizing: border-box;
margin: auto;
min-height: 450px;
max-height: 75vh;
overflow-y: auto;
color: $grey-1;
background: $white;
border-radius: 8px;
border: 1px solid $grey-6;
padding: 32px 48px;
* {
max-width: 600px;
}
.no-max-width {
max-width: none;
}
}
::ng-deep.title {
margin-bottom: 16px;
.overtitle {
@include lato-regular-18;
color: $grey-3;
margin-bottom: 3px;
}
h3 {
@include lato-bold-24;
margin: 0;
@media #{$tablet} {
@include lato-bold-22;
}
}
p {
@include lato-regular-18;
color: $grey-3;
font-style: italic;
margin-top: 4px;
}
}
::ng-deep.textareaBlock {
@media #{$tablet} {
max-width: 90%;
}
p {
text-align: right;
@include lato-regular-14;
color: $grey-3;
font-style: italic;
}
}
@media #{$tablet} {
.page {
height: calc(
100vh - #{$header-height-phone} - #{$footer-height-phone} - 87px - 1px
); // -1px because of header border
}
}
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FormViewComponent } from './form-view.component';
describe('FormViewComponent', () => {
let component: FormViewComponent;
let fixture: ComponentFixture<FormViewComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ FormViewComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(FormViewComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, Validators, FormArray } from '@angular/forms';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { forkJoin, of } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { Day } from '../../models/day.model';
import { PersonalOffer } from '../../models/personalOffer.model';
import { Structure } from '../../models/structure.model';
import { StructureWithOwners } from '../../models/structureWithOwners.model';
import { Time } from '../../models/time.model';
import { User } from '../../models/user.model';
import { ProfileService } from '../../profile/services/profile.service';
import { PersonalOfferService } from '../../services/personal-offer.service';
import { StructureService } from '../../services/structure.service';
import { MustMatch } from '../../shared/validator/form';
import { CustomRegExp } from '../../utils/CustomRegExp';
import { accountFormStep } from './account-form/accountFormStep.enum';
import { formType } from './formType.enum';
import { personalOfferFormStep } from './personal-offer-form/personalOfferFormStep.enum';
import { profileFormStep } from './profile-form/profileFormStep.enum';
import { structureFormStep } from './structure-form/structureFormStep.enum';
@Component({
selector: 'app-form-view',
templateUrl: './form-view.component.html',
styleUrls: ['./form-view.component.scss'],
})
export class FormViewComponent implements OnInit {
public routeParam: string;
public formType = formType;
public currentPage: accountFormStep | profileFormStep | structureFormStep | personalOfferFormStep;
public currentFormType: formType;
public currentForm: FormGroup;
// Account Form
public accountForm: FormGroup;
public userAcceptNewsletter: boolean;
// Profile Form
public profileForm: FormGroup;
public isPersonalOfferProfile: boolean;
// Structure from
public structureForm: FormGroup;
public editForm: FormGroup;
public structure: Structure;
public isEditMode: boolean = false;
public structureFormStep = structureFormStep;
// Personal Offers Form
public personalOfferForm: FormGroup;
public hasOtherPersonalOffer: boolean = false;
// Page and progress var
public pagesValidation = [];
public nbSteps: number;
// Condition form
public userAcceptSavedDate = false;
// Collapse var
public showWebsite: boolean;
public showSocialNetwork: boolean;
public profile: User;
public isAccountMode: boolean = false;
public isClaimMode: boolean = false;
public isJoinMode: boolean = false;
public claimStructure: boolean = false;
public isWifiChoosen: boolean;
public linkedStructureId;
public structureWithOwners: StructureWithOwners;
public isPageValid: boolean = false;
public hoursForm: FormGroup;
constructor(
private router: Router,
private route: ActivatedRoute,
private profileService: ProfileService,
private structureService: StructureService,
private personalOfferService: PersonalOfferService
) {}
async ngOnInit(): Promise<void> {
this.routeParam = this.router.routerState.snapshot.url.split('/')[2];
this.initPage();
this.profileService.getProfile().then((user: User) => {
this.profile = user;
});
// 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;
}
//TODO: Edit mode
// if (data.structure) {
// this.isEditMode = true;
// this.isWifiChoosen = true;
// const editStructure = new Structure(data.structure);
// this.initForm(editStructure);
// this.structureService.getStructureWithOwners(editStructure._id, this.profile).subscribe((s) => {
// this.structureWithOwners = s;
// });
// }
});
this.route.data.subscribe((data) => {
if (data.user) {
this.isAccountMode = true;
}
if (data.structure) {
this.isEditMode = true;
}
});
this.router.events.subscribe((evt) => {
if (!(evt instanceof NavigationEnd)) {
return;
}
this.routeParam = this.router.routerState.snapshot.url.split('/')[2];
this.initPage();
});
}
private initPage(): void {
if (formType[this.routeParam] === formType.account) {
this.nbSteps = 3;
this.currentPage = accountFormStep.accountInfo;
this.currentFormType = formType.account;
this.createAccountForm();
this.currentForm = this.accountForm;
}
if (formType[this.routeParam] === formType.profile) {
this.nbSteps = Object.keys(profileFormStep).length / 2;
this.currentPage = profileFormStep.profileBeginningInfo;
this.currentFormType = formType.profile;
this.createProfileForm();
this.currentForm = this.profileForm;
}
if (formType[this.routeParam] === formType.structure) {
this.nbSteps = 24;
this.currentPage = structureFormStep.structureChoice;
this.currentFormType = formType.structure;
this.structure = new Structure();
this.createStructureForm(this.structure);
this.currentForm = this.structureForm;
//TODO: Edit mode
// if (this.isEditMode) {
// this.editForm = this.createStructureForm(structure);
// }
// Init hours form
this.hoursForm = new FormGroup({
monday: this.createDay(this.structure.hours.monday),
tuesday: this.createDay(this.structure.hours.tuesday),
wednesday: this.createDay(this.structure.hours.wednesday),
thursday: this.createDay(this.structure.hours.thursday),
friday: this.createDay(this.structure.hours.friday),
saturday: this.createDay(this.structure.hours.saturday),
sunday: this.createDay(this.structure.hours.sunday),
});
}
if (formType[this.routeParam] === formType.personaloffer) {
this.nbSteps = 3;
this.currentPage = personalOfferFormStep.personalOfferAccompaniment;
this.currentFormType = formType.personaloffer;
const newPersonalOffer: PersonalOffer = new PersonalOffer();
this.createPersonalOfferForm(newPersonalOffer);
this.currentForm = this.personalOfferForm;
}
}
public updateHours(form: FormGroup): void {
this.hoursForm = form;
}
private createDay(day: Day): FormGroup {
return new FormGroup({
open: new FormControl(day.open, Validators.required),
time: new FormArray(day.time.map((oneTime) => this.createTime(oneTime))) as FormArray,
});
}
private createTime(time: Time): FormGroup {
return new FormGroup({
opening: new FormControl(time.opening),
closing: new FormControl(time.closing),
});
}
private createAccountForm(email?: string): void {
this.accountForm = new FormGroup(
{
email: new FormControl(email ? email : '', [Validators.required, Validators.pattern(CustomRegExp.EMAIL)]),
name: new FormControl('', [Validators.required, Validators.pattern(CustomRegExp.TEXT_WITHOUT_NUMBER)]),
surname: new FormControl('', [Validators.required, Validators.pattern(CustomRegExp.TEXT_WITHOUT_NUMBER)]),
phone: new FormControl('', [Validators.required, Validators.pattern(CustomRegExp.PHONE)]),
password: new FormControl('', [
Validators.required,
Validators.pattern(CustomRegExp.PASSWORD), //NOSONAR
]),
confirmPassword: new FormControl(''),
},
[MustMatch('password', 'confirmPassword')]
);
}
private createProfileForm(): void {
this.profileForm = new FormGroup({
employer: new FormGroup({
name: new FormControl('', [Validators.required]),
validated: new FormControl(false, [Validators.required]),
}),
job: new FormGroup({
name: new FormControl('', [Validators.required]),
validated: new FormControl(true, [Validators.required]),
hasPersonalOffer: new FormControl(true, [Validators.required]),
}),
structure: new FormControl('', [Validators.required]),
});
}
private createStructureForm(structure): void {
this.structureForm = 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.lockdownActivity),
address: new FormGroup({
numero: new FormControl(structure.address.numero),
street: new FormControl(structure.address.street, Validators.required),
commune: new FormControl(structure.address.commune, Validators.required),
}),
contactMail: new FormControl(structure.contactMail, [
Validators.required,
Validators.pattern(CustomRegExp.EMAIL),
]),
contactPhone: new FormControl(structure.contactPhone, [
Validators.required,
Validators.pattern(CustomRegExp.PHONE),
]),
contactPersonFirstname: new FormControl(structure.contactPersonLastname, Validators.required),
contactPersonLastname: new FormControl(structure.contactPersonLastname, Validators.required),
contactPersonEmail: new FormControl(structure.contactPersonEmail, [
Validators.pattern(CustomRegExp.EMAIL),
Validators.required,
]),
website: new FormControl(structure.website, Validators.pattern(CustomRegExp.WEBSITE)),
facebook: new FormControl(structure.facebook, Validators.pattern(CustomRegExp.FACEBOOK)),
twitter: new FormControl(structure.twitter, Validators.pattern(CustomRegExp.TWITTER)),
instagram: new FormControl(structure.instagram, Validators.pattern(CustomRegExp.INSTAGRAM)),
linkedin: new FormControl(structure.linkedin, Validators.pattern(CustomRegExp.LINKEDIN)),
hours: new FormGroup({}),
pmrAccess: new FormControl(structure.pmrAccess, Validators.required),
placeOfReception: new FormControl(structure.placeOfReception, Validators.required),
choiceCompletion: new FormControl(structure.choiceCompletion, Validators.required),
exceptionalClosures: new FormControl(structure.exceptionalClosures),
labelsQualifications: this.loadArrayForCheckbox(structure.labelsQualifications, false),
accessModality: this.loadArrayForCheckbox(structure.accessModality, true),
publicsAccompaniment: this.loadArrayForCheckbox(structure.publicsAccompaniment, false),
proceduresAccompaniment: this.loadArrayForCheckbox(structure.proceduresAccompaniment, false),
//TODO: remettre ou migrer les données de accompagnements à distance
remoteAccompaniment: new FormControl(false),
otherDescription: new FormControl(structure.otherDescription),
equipmentsAndServices: this.loadArrayForCheckbox(structure.equipmentsAndServices, false),
publics: this.loadArrayForCheckbox(structure.publics, true),
baseSkills: new FormControl(structure.baseSkills),
accessRight: new FormControl(structure.accessRight),
parentingHelp: new FormControl(structure.parentingHelp),
socialAndProfessional: new FormControl(structure.socialAndProfessional),
digitalCultureSecurity: new FormControl(structure.digitalCultureSecurity),
nbComputers: new FormControl(
structure.equipmentsAndServices.includes('ordinateurs') ? structure.nbComputers : 0,
[Validators.required, Validators.pattern(CustomRegExp.NO_NEGATIVE_NUMBER), Validators.min(0)]
),
nbPrinters: new FormControl(structure.equipmentsAndServices.includes('imprimantes') ? structure.nbPrinters : 0, [
Validators.required,
Validators.pattern(CustomRegExp.NO_NEGATIVE_NUMBER),
Validators.min(0),
]),
nbTablets: new FormControl(structure.equipmentsAndServices.includes('tablettes') ? structure.nbTablets : 0, [
Validators.required,
Validators.pattern(CustomRegExp.NO_NEGATIVE_NUMBER),
Validators.min(0),
]),
nbNumericTerminal: new FormControl(
structure.equipmentsAndServices.includes('bornesNumeriques') ? structure.nbNumericTerminal : 0,
[Validators.required, Validators.pattern(CustomRegExp.NO_NEGATIVE_NUMBER), Validators.min(0)]
),
nbScanners: new FormControl(structure.equipmentsAndServices.includes('scanners') ? structure.nbScanners : 0, [
Validators.required,
Validators.pattern(CustomRegExp.NO_NEGATIVE_NUMBER),
Validators.min(0),
]),
freeWorkShop: new FormControl(structure.freeWorkShop, [Validators.required]),
dataShareConsentDate: new FormControl(structure.dataShareConsentDate),
personalOffers: new FormControl(structure.personalOffers),
});
}
public acceptReceiveNewsletter(isAccepted: boolean): void {
this.userAcceptNewsletter = isAccepted;
}
private createPersonalOfferForm(personalOffer: PersonalOffer): void {
this.personalOfferForm = new FormGroup({
publicsAccompaniment: new FormControl(personalOffer.publicsAccompaniment),
proceduresAccompaniment: new FormControl(personalOffer.proceduresAccompaniment),
baseSkills: new FormControl(personalOffer.baseSkills),
accessRight: new FormControl(personalOffer.accessRight),
digitalCultureSecurity: new FormControl(personalOffer.digitalCultureSecurity),
socialAndProfessional: new FormControl(personalOffer.socialAndProfessional),
parentingHelp: new FormControl(personalOffer.parentingHelp),
});
}
private loadArrayForCheckbox(array: string[], isRequired: boolean): FormArray {
return new FormArray(
array.map((str) => new FormControl(str)),
isRequired ? Validators.required : Validators.nullValidator
);
}
public validatePage(value: boolean = true): void {
this.isPageValid = value;
}
public nextPage(): void {
this.isPageValid = false;
if (this.currentPage < this.nbSteps) {
this.currentPage++;
}
}
public prevPage(): void {
if (this.currentPage > 0) {
this.currentPage--;
}
}
public displayFooterForm(): boolean {
if (this.currentPage === profileFormStep.profileBeginningInfo && formType[this.routeParam] === formType.profile)
return false;
return true;
}
public setHasOtherPersonalOffer(value: boolean): void {
this.hasOtherPersonalOffer = value;
}
public linkStructureToUser(): void {
this.structureService.joinStructure(this.structureForm.value._id, this.profile.email).subscribe((data) => {
this.currentPage = structureFormStep.mailSentInfo;
this.nbSteps = structureFormStep.mailSentInfo;
this.structure._id = this.structureForm.value._id;
this.structure.structureName = this.structureForm.value.structureName;
});
}
public async endForm(type: {
formType: formType;
formStep?: accountFormStep | profileFormStep | structureFormStep | personalOfferFormStep;
}): Promise<void> {
switch (type.formType) {
case formType.account:
break;
case formType.profile:
this.saveProfileForm();
break;
case formType.structure:
if (type.formStep === structureFormStep.mailSentInfo) {
const user = await this.profileService.getProfile();
if (user.job.hasPersonalOffer) {
this.router.navigateByUrl('form/personaloffer');
} else {
this.router.navigateByUrl('/');
}
}
if (type.formStep === structureFormStep.structureChoice) {
// If structure already exist, join it.
// On first strike the structure._id is not set and is a key to differentiate with other case
if (this.structureForm.value._id && !this.structure._id) {
this.linkStructureToUser();
}
}
if (type.formStep === structureFormStep.structureCreationFinishedInfo) {
this.saveStructureForm();
}
break;
case formType.personaloffer:
this.savePersonalOfferForm();
break;
}
}
public saveProfileForm(): void {
forkJoin({
employer: this.profileService.createEmployer(this.profileForm.get('employer').value).pipe(
map((res) => res),
catchError((e) => of(this.profileForm.get('employer').value))
),
job: this.profileService.createJob(this.profileForm.get('job').value).pipe(
map((res) => res),
catchError((e) => of(this.profileForm.get('job').value))
),
profile: this.profileService
.updateProfile(this.profileForm.get('employer').value.name, this.profileForm.get('job').value.name)
.pipe(
map((res) => res),
catchError((e) => of())
),
}).subscribe(() => {
this.router.navigateByUrl('form/structure');
});
}
public savePersonalOfferForm(): void {
this.personalOfferService.createPersonalOffer(this.structure._id, this.personalOfferForm.value).subscribe(() => {
if (this.hasOtherPersonalOffer) {
this.router.navigateByUrl('form/structure');
} else {
this.nextPage();
}
});
}
public async saveStructureForm(): Promise<void> {
const user = await this.profileService.getProfile();
this.structureService.createStructure(this.structureForm.value, this.profile).subscribe((struct) => {
if (user.job.hasPersonalOffer) {
this.structure = struct;
this.router.navigateByUrl('form/personaloffer');
} else {
this.router.navigateByUrl(`acteurs?id=${struct._id}`);
}
});
}
public setCurrentStep(step: accountFormStep | profileFormStep | structureFormStep | personalOfferFormStep): void {
this.currentPage = step;
}
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormViewComponent } from './form-view.component';
import { ProgressBarComponent } from './global-components/progress-bar/progress-bar.component';
import { NavigationButtonsComponent } from './global-components/navigation-buttons/navigation-buttons.component';
import { StructureFormComponent } from './structure-form/structure-form.component';
import { ProfileFormComponent } from './profile-form/profile-form.component';
import { PersonalOfferFormComponent } from './personal-offer-form/personal-offer-form.component';
import { InformationStepComponent } from './global-components/information-step/information-step.component';
import { AccountFormComponent } from './account-form/account-form.component';
import { ProfileEmployerSelectionComponent } from './profile-form/profile-employer-selection/profile-employer-selection.component';
import { ProfileJobSelectionComponent } from './profile-form/profile-job-selection/profile-job-selection.component';
import { ProfileStructureChoiceComponent } from './profile-form/profile-structure-choice/profile-structure-choice.component';
import { PersonalOfferOtherStructureChoiceComponent } from './personal-offer-form/personal-offer-other-structure-choice/personal-offer-other-structure-choice.component';
import { StructureNameAndAddressComponent } from './structure-form/structure-name-and-address/structure-name-and-address.component';
import { StructureContactComponent } from './structure-form/structure-contact/structure-contact.component';
import { StructureAccompanimentChoiceComponent } from './structure-form/structure-accompaniment-choice/structure-accompaniment-choice.component';
import { StructureChoiceCompletionComponent } from './structure-form/structure-choice-completion/structure-choice-completion.component';
import { StructureContactCompletionComponent } from './structure-form/structure-contact-completion/structure-contact-completion.component';
import { StructureAccessModalityComponent } from './structure-form/structure-access-modality/structure-access-modality.component';
import { StructureHoursComponent } from './structure-form/structure-hours/structure-hours.component';
import { StructurePmrComponent } from './structure-form/structure-pmr/structure-pmr.component';
import { StructureWebAndSocialNetworkComponent } from './structure-form/structure-web-and-social-network/structure-web-and-social-network.component';
import { StructurePublicTargetComponent } from './structure-form/structure-public-target/structure-public-target.component';
import { StructureDigitalHelpingAccompanimentComponent } from './structure-form/structure-digital-helping-accompaniment/structure-digital-helping-accompaniment.component';
import { StructureTrainingPriceComponent } from './structure-form/structure-training-price/structure-training-price.component';
import { StructureWifiComponent } from './structure-form/structure-wifi/structure-wifi.component';
import { StructureEquipmentsComponent } from './structure-form/structure-equipments/structure-equipments.component';
import { StructureLabelsComponent } from './structure-form/structure-labels/structure-labels.component';
import { StructureOtherServicesComponent } from './structure-form/structure-other-services/structure-other-services.component';
import { StructureDescriptionComponent } from './structure-form/structure-description/structure-description.component';
import { StructureCovidInfoComponent } from './structure-form/structure-covid-info/structure-covid-info.component';
import { StructureConsentComponent } from './structure-form/structure-consent/structure-consent.component';
import { AccountInfoComponent } from './account-form/account-info/account-info.component';
import { AccountCredentialsComponent } from './account-form/account-credentials/account-credentials.component';
import { SharedModule } from '../../shared/shared.module';
import { FormViewRoutingModule } from './form-view-routing.module';
import { FooterFormComponent } from '../footer-form/footer-form.component';
import { StructureTypeComponent } from './structure-form/structure-type/structure-type.component';
import { PersonalOfferAccompanimentComponent } from './personal-offer-form/personal-offer-accompaniment/personal-offer-accompaniment.component';
import { PersonalOfferTrainingTypeComponent } from './personal-offer-form/personal-offer-training-type/personal-offer-training-type.component';
import { AccountNewsletterComponent } from './account-form/account-newsletter/account-newsletter.component';
import { StructureTrainingTypeComponent } from './structure-form/structure-training-type/structure-training-type.component';
import { PersonalOfferGuard } from './guards/personalOffer.guard';
@NgModule({
declarations: [
FormViewComponent,
ProgressBarComponent,
NavigationButtonsComponent,
StructureFormComponent,
ProfileFormComponent,
PersonalOfferFormComponent,
PersonalOfferAccompanimentComponent,
PersonalOfferTrainingTypeComponent,
PersonalOfferOtherStructureChoiceComponent,
InformationStepComponent,
AccountFormComponent,
ProfileEmployerSelectionComponent,
ProfileJobSelectionComponent,
ProfileStructureChoiceComponent,
PersonalOfferOtherStructureChoiceComponent,
StructureNameAndAddressComponent,
StructureContactComponent,
StructureAccompanimentChoiceComponent,
StructureChoiceCompletionComponent,
StructureContactCompletionComponent,
StructureAccessModalityComponent,
StructureHoursComponent,
StructurePmrComponent,
StructureWebAndSocialNetworkComponent,
StructurePublicTargetComponent,
StructureDigitalHelpingAccompanimentComponent,
StructureTrainingPriceComponent,
StructureWifiComponent,
StructureEquipmentsComponent,
StructureLabelsComponent,
StructureOtherServicesComponent,
StructureDescriptionComponent,
StructureCovidInfoComponent,
StructureConsentComponent,
AccountInfoComponent,
AccountCredentialsComponent,
FooterFormComponent,
StructureTypeComponent,
AccountNewsletterComponent,
StructureTrainingTypeComponent,
],
imports: [CommonModule, FormViewRoutingModule, SharedModule],
providers: [PersonalOfferGuard],
})
export class FormViewModule {}
export enum formType {
structure,
profile,
personaloffer,
account,
}
<ng-container *ngIf="formType === formTypeEnum.account && step === accountFormStepEnum.confirmEmailSentInfo">
<div class="information-step-container no-max-width">
<svg aria-hidden="true">
<use [attr.xlink:href]="'assets/form/sprite.svg#emailVerification'"></use>
</svg>
<p>
Un email vous a été envoyé<br />
afin de finaliser votre inscription
</p>
</div>
</ng-container>
<ng-container *ngIf="formType === formTypeEnum.profile && step === profileFormStepEnum.profileBeginningInfo">
<div fxLayout="column" fxLayoutGap="18px" class="information-step-container profile-skip">
<p>
Pour compléter votre profil,<br />
nous aimerions vous poser quelques questions
</p>
<svg aria-hidden="true">
<use [attr.xlink:href]="'assets/form/sprite.svg#profileSkip'"></use>
</svg>
<app-navigation-buttons (goNext)="nextPage()"></app-navigation-buttons>
</div>
</ng-container>
<ng-container *ngIf="formType === formTypeEnum.structure && step === structureFormStepEnum.mailSentInfo">
<div class="information-step-container structure-display">
<svg aria-hidden="true">
<use [attr.xlink:href]="'assets/form/sprite.svg#emailVerification'"></use>
</svg>
<p>
Un message a été envoyé aux membres<br />
de la structure :<br />
</p>
<span>{{ structureName }}</span>
</div>
</ng-container>
<ng-container *ngIf="formType === formTypeEnum.structure && step === structureFormStepEnum.structureFormTime">
<div class="information-step-container structure-time no-max-width">
<h3>
Nous vous proposons de prendre 10 minutes afin de renseigner les informations de la structure et la créer sur
Rés’in.
</h3>
<svg aria-hidden="true">
<use [attr.xlink:href]="'assets/form/sprite.svg#formTime'"></use>
</svg>
<p>Informations dont il faut vous munir :</p>
<ul>
<li>les coordonnées de la structure</li>
<li>les horaires d’ouverture</li>
<li>la liste des formations dispensées dans la structure (optionnel)</li>
</ul>
</div>
</ng-container>
<ng-container
*ngIf="formType === formTypeEnum.structure && step === structureFormStepEnum.structureCreationFinishedInfo"
>
<div class="structureCreated no-max-width">
<h3>La structure est désormais référencée sur Rés’in.</h3>
<svg aria-hidden="true">
<use [attr.xlink:href]="'assets/form/sprite.svg#structureCreated'"></use>
</svg>
<p *ngIf="hasPersonalOffer">
Les prochaines questions concernent les services que vous dispensez en tant qu’intervenant dans cette structure.
</p>
</div>
</ng-container>
<ng-container
*ngIf="formType === formTypeEnum.personaloffer && step === personalOfferFormStep.personalOfferFinishedInfo"
>
<div class="information-step-container profile-updated no-max-width">
<h3>Merci, les informations de votre profil ont été mises à jour</h3>
<svg aria-hidden="true">
<use [attr.xlink:href]="'assets/form/sprite.svg#profileUpdated'"></use>
</svg>
<div class="btn">
<app-button [style]="buttonTypeEnum.Primary" [text]="'Voir mon compte'" [iconType]="'form'" (action)="nextPage()">
</app-button>
</div>
</div>
</ng-container>
@import '../../../../../assets/scss/typography';
@import '../../../../../assets/scss/color';
.information-step-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: inherit;
height: 450px;
svg {
width: 100%;
max-width: 200px;
}
p {
@include lato-bold-24;
margin-top: 3rem;
text-align: center;
}
&.profile-skip {
height: unset;
max-width: unset;
p {
margin: 0;
}
svg {
width: 100%;
height: 180px;
max-width: 180px;
}
}
&.structure-display {
height: unset;
max-width: unset;
p {
@include lato-regular-18;
margin: 0;
}
span {
@include lato-bold-24;
margin-top: 16px;
text-align: center;
}
svg {
width: 100%;
height: 180px;
max-width: 180px;
}
}
&.structure-time {
height: unset;
max-width: unset;
h3 {
@include lato-bold-24;
text-align: center;
}
p {
@include lato-bold-18;
margin: 0;
width: 100%;
text-align: left;
}
ul {
width: 100%;
list-style: none;
padding: 0;
}
li {
@include lato-regular-18;
}
ul li::before {
content: '\2022';
color: $red;
margin-right: 12px;
}
svg {
width: 100%;
height: 150px;
max-width: 150px;
margin-bottom: 24px;
}
}
&.profile-updated {
.btn {
margin-top: 17px;
}
svg {
height: 180px;
width: 180px;
}
}
}
.structureCreated {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
max-width: 600px;
margin: auto;
h3 {
@include lato-bold-24;
text-align: center;
}
p {
@include lato-regular-18;
text-align: center;
}
svg {
width: 180px;
height: 180px;
}
}
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { InformationStepComponent } from './information-step.component';
describe('InformationStepComponent', () => {
let component: InformationStepComponent;
let fixture: ComponentFixture<InformationStepComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ InformationStepComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(InformationStepComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { ButtonType } from '../../../../shared/components/button/buttonType.enum';
import { accountFormStep } from '../../account-form/accountFormStep.enum';
import { formType } from '../../formType.enum';
import { personalOfferFormStep } from '../../personal-offer-form/personalOfferFormStep.enum';
import { profileFormStep } from '../../profile-form/profileFormStep.enum';
import { structureFormStep } from '../../structure-form/structureFormStep.enum';
@Component({
selector: 'app-information-step',
templateUrl: './information-step.component.html',
styleUrls: ['./information-step.component.scss'],
})
export class InformationStepComponent {
@Input() step: number;
@Input() formType: formType;
@Input() structureName?: string;
@Input() hasPersonalOffer?: boolean;
@Output() goNext = new EventEmitter<any>();
public formTypeEnum = formType;
public accountFormStepEnum = accountFormStep;
public profileFormStepEnum = profileFormStep;
public structureFormStepEnum = structureFormStep;
public personalOfferFormStep = personalOfferFormStep;
public buttonTypeEnum = ButtonType;
public nextPage(): void {
this.goNext.emit();
}
}
<div class="footerForm" fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center">
<ng-container *ngIf="buttonStyle === 0">
<app-button (action)="goToHome()" [text]="'Plus tard'"></app-button>
<app-button (action)="goToNextPage()" [text]="'C`est parti !'" [style]="buttonTypeEnum.Primary"></app-button>
</ng-container>
</div>