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 758 additions and 0 deletions
<h2>Sur quel créneau horaire le bénéficiaire souhaite-t-il être rappelé ?</h2>
<div class="subtitle">Horaires de la Hotline</div>
<div class="container">
<div *ngFor="let slot of timeSlots" class="slot">
<div class="day">{{ slot.day }}</div>
<button class="time" [ngClass]="{ selected: isSelected(slot) }" (click)="selectHour(slot)">
{{ slot.hours }}
</button>
</div>
</div>
@import '../../../../../assets/scss/color';
@import '../../../../../assets/scss/typography';
@import '../../../../../assets/scss/breakpoint';
.subtitle {
color: $grey-3;
text-transform: uppercase;
@include lato-regular-14;
}
.container {
display: flex;
justify-content: center;
align-items: center;
gap: 0.5rem;
margin: 1.5rem 0;
flex-wrap: wrap;
.slot {
transition: all 300ms ease;
border-right: solid 1px $red;
padding-right: 0.5rem;
height: 85px;
&:last-child {
border: none;
}
@media #{$phone} {
&:nth-child(even) {
border: none;
}
}
.day {
@include lato-regular-13;
color: $grey-3;
text-align: center;
margin-bottom: 1rem;
}
.time {
cursor: pointer;
width: 125px;
height: 37px;
text-align: center;
border: 1px solid $grey-1;
border-radius: 4px;
color: $grey-1;
@include lato-regular-14;
background: $white;
&.selected {
background: $green-1 !important;
color: $white;
border-color: $green-1;
}
}
}
}
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MediationHoursSelectionComponent } from './mediation-hours-selection.component';
describe('MediationHoursSelectionComponent', () => {
let component: MediationHoursSelectionComponent;
let fixture: ComponentFixture<MediationHoursSelectionComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ MediationHoursSelectionComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(MediationHoursSelectionComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { UntypedFormGroup } from '@angular/forms';
import { DateTime } from 'luxon';
@Component({
selector: 'app-mediation-hours-selection',
templateUrl: './mediation-hours-selection.component.html',
styleUrls: ['./mediation-hours-selection.component.scss'],
})
export class MediationHoursSelectionComponent implements OnInit {
@Input() form: UntypedFormGroup;
@Output() checkValidation = new EventEmitter<any>();
public selected: string;
public timeSlots = [
{ day: 'Lundi', hours: '15h00-17h00' },
{ day: 'Mardi', hours: '15h00-17h00' },
{ day: 'Mercredi', hours: '15h00-17h00' },
{ day: 'Jeudi', hours: '15h00-19h00' },
{ day: 'Vendredi', hours: '15h00-17h00' },
{ day: 'Samedi', hours: '10h00-12h00' },
];
ngOnInit(): void {
this.checkValidation.emit();
if (this.form.get('dateSlot').value) {
this.selected = this.form.get('dateSlot').value.day;
}
const today = DateTime.local().weekday;
if (today > 1) {
const temp = this.timeSlots.splice(today, this.timeSlots.length);
this.timeSlots = temp.concat(this.timeSlots);
}
}
public selectHour(slot: any): void {
this.selected = slot.day;
this.form.get('dateSlot').patchValue(slot);
this.checkValidation.emit();
}
public isSelected(slot: any): boolean {
return this.selected === slot.day;
}
}
<app-print-header></app-print-header>
<div class="container">
<!-- <div class="oriented" *ngIf="profile"><h3>Orienté par</h3></div> -->
<div class="beneficiary">
<h3>Bénéficiaire</h3>
<div class="content">
<div class="labels">
<div>Nom</div>
<div>Besoin(s) d'aide</div>
</div>
<div class="infos">
<div>{{ beneficiary.name | uppercase }} {{ beneficiary.surname }}</div>
<div class="needs">
<div class="need" *ngFor="let need of needs">{{ need.displayText }}</div>
</div>
</div>
</div>
</div>
</div>
<div class="date">
<div>Rappel</div>
<div>{{ date.day }} prochain</div>
<div>entre {{ date.hours }}</div>
</div>
<div class="service-info">
<div class="img">
<img src="../../../../../assets/ico/mediation1.svg" alt="Image Mediation" />
</div>
<div class="content">
<div class="txt1">Besoin d’aide avec vos outils numériques ?</div>
<div class="txt2">
Votre numéro <span>gratuit</span> <br />
d’assistance numérique :
</div>
<div class="txt3">04 83 43 90 40</div>
<div class="txt4">
Appel gratuit de 15h à 17h du lundi au vendredi,<br />le jeudi jusqu’à 19h et le samedi matin de 10h à 12h.
</div>
</div>
<div class="logo">
<div class="text">Service gratuit</div>
<img src="../../../../../assets/logos/metropoleGrandLyon.svg" alt="logo métropole" />
</div>
</div>
@import '../../../../../assets/scss/color';
@import '../../../../../assets/scss/typography';
@import '../../../../../assets/scss/breakpoint';
.container {
display: flex;
gap: 1.5rem;
padding: 1rem 0;
* {
-webkit-print-color-adjust: exact;
}
h3 {
@include lato-bold-14;
color: $grey-3;
margin-bottom: 1.5rem;
margin-top: 0.5rem;
text-transform: uppercase;
}
.oriented {
background-color: $grey-7;
max-width: 300px;
width: 100%;
padding: 1rem 1.5rem;
}
.beneficiary {
background-color: $grey-7;
padding: 1rem 1.5rem;
flex: 1;
.content {
color: $black;
display: flex;
gap: 2rem;
.labels {
@include lato-regular-14;
& > div {
margin-bottom: 1rem;
}
}
.infos {
@include lato-bold-14;
& > div {
margin-bottom: 1rem;
}
}
}
}
}
.date {
max-width: 350px;
margin: 1rem auto 2rem auto;
@include lato-bold-18;
}
.service-info {
max-width: 680px;
width: 100%;
border-radius: 24px;
border: 1.5px solid $black;
display: flex;
justify-content: space-evenly;
align-items: center;
padding: 1.5rem 1rem;
margin: auto;
gap: 1.5rem;
@media #{$tablet} {
flex-direction: column;
width: auto;
}
.content {
.txt1 {
@include lato-regular-14;
color: $grey-2;
margin-bottom: 1rem;
}
.txt2 {
color: $black;
@include lato-bold-18;
span {
color: $red;
}
}
.txt3 {
@include lato-bold-24;
color: $red;
}
.txt4 {
@include lato-regular-15;
margin-top: 1rem;
color: $grey-2;
}
}
.logo {
width: 120px;
height: 65px;
border: 1px solid;
border-radius: 3px;
padding: 0.25rem;
.text {
@include lato-regular-10;
text-align: center;
}
img {
width: 120px;
margin-top: 0.2rem;
}
}
}
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MediationRecapComponent } from './mediation-recap.component';
describe('MediationRecapComponent', () => {
let component: MediationRecapComponent;
let fixture: ComponentFixture<MediationRecapComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ MediationRecapComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(MediationRecapComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { UntypedFormGroup } from '@angular/forms';
import { User } from '../../../../models/user.model';
import { ProfileService } from '../../../../profile/services/profile.service';
import { AuthService } from '../../../../services/auth.service';
import { Module } from '../../../../structure-list/models/module.model';
@Component({
selector: 'app-mediation-recap',
templateUrl: './mediation-recap.component.html',
styleUrls: ['./mediation-recap.component.scss'],
})
export class MediationRecapComponent implements OnInit {
@Input() form: UntypedFormGroup;
@Output() checkValidation = new EventEmitter<any>();
public needs: Module[];
public beneficiary: any;
public date: any;
public profile: User;
constructor(public authService: AuthService, private profileService: ProfileService) {}
async ngOnInit(): Promise<void> {
this.checkValidation.emit();
this.needs = this.form.get('onlineDemarchType').value;
this.beneficiary = {
name: this.form.get('name').value,
surname: this.form.get('surname').value,
};
this.date = {
day: this.form.get('dateSlot').value.day,
hours: this.form.get('dateSlot').value.hours.replace('-', ' et '),
};
if (this.authService.isLoggedIn()) {
this.profile = await this.profileService.getProfile();
}
}
}
<h2>Quelle démarche en ligne le bénéficiaire a-t-il besoin de réaliser ?</h2>
<div fxLayout="column" fxLayoutGap="32px">
<div class="btn-grid">
<span *ngFor="let module of accompanimentType">
<app-button
[ngClass]="{ selectedChoice: true }"
[extraClass]="isSelectedModule(module.id) ? 'selected' : ''"
[style]="buttonTypeEnum.CheckButton"
[text]="module.text"
(action)="handleClick(module)"
></app-button>
</span>
</div>
</div>
@import '../../../../../assets/scss/buttons';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { OnlineDemarchComponent } from './online-demarch.component';
describe('OnlineDemarchComponent', () => {
let component: OnlineDemarchComponent;
let fixture: ComponentFixture<OnlineDemarchComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ OnlineDemarchComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(OnlineDemarchComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, Input, OnInit, Output, EventEmitter } from '@angular/core';
import { UntypedFormGroup } from '@angular/forms';
import { ButtonType } from '../../../../shared/components/button/buttonType.enum';
import { Category } from '../../../../structure-list/models/category.model';
import { Module } from '../../../../structure-list/models/module.model';
import { SearchService } from '../../../../structure-list/services/search.service';
@Component({
selector: 'app-online-demarch',
templateUrl: './online-demarch.component.html',
styleUrls: ['./online-demarch.component.scss'],
})
export class OnlineDemarchComponent implements OnInit {
@Input() form: UntypedFormGroup;
@Output() checkValidation = new EventEmitter<any>();
constructor(private searchService: SearchService) {}
public accompanimentType: Module[];
public buttonTypeEnum = ButtonType;
public selectedModules: Module[] = [];
ngOnInit(): void {
this.selectedModules = this.form.get('onlineDemarchType').value;
this.searchService.getCategoriesAccompaniment().subscribe((categories: Category[]) => {
this.accompanimentType = categories[0].modules;
});
this.checkValidation.emit();
}
public handleClick(module: Module): void {
if (this.isSelectedModule(module.id)) {
const index = this.selectedModules.findIndex((_module) => _module.id === module.id);
this.selectedModules.splice(index, 1);
} else {
this.selectedModules.push(module);
}
this.form.get('onlineDemarchType').patchValue(this.selectedModules);
this.checkValidation.emit();
}
public isSelectedModule(moduleId: string): boolean {
if (this.selectedModules && this.selectedModules.map((module) => module.id).includes(moduleId)) return true;
return false;
}
}
<app-online-demarch
*ngIf="currentStep === mediationStepsEnum.onlineDemarch"
[form]="form"
(checkValidation)="checkValidation()"
></app-online-demarch>
<app-accompaniment-type
*ngIf="currentStep === mediationStepsEnum.accompanimentType"
[form]="form"
(checkValidation)="checkValidation()"
></app-accompaniment-type>
<app-mediation-beneciary-info
*ngIf="currentStep === mediationStepsEnum.mediationBeneciaryInfo"
[form]="form"
(checkValidation)="checkValidation()"
></app-mediation-beneciary-info>
<app-mediation-hours-selection
*ngIf="currentStep === mediationStepsEnum.mediationHoursSelection"
[form]="form"
(checkValidation)="checkValidation()"
></app-mediation-hours-selection>
<app-mediation-recap
*ngIf="currentStep === mediationStepsEnum.mediationRecap"
[form]="form"
(checkValidation)="checkValidation()"
></app-mediation-recap>
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { UntypedFormGroup } from '@angular/forms';
import { OrientationUtils } from '../../../utils/orientationUtils';
import { mediationSteps } from '../enums/mediationSteps.enum';
@Component({
selector: 'app-onlineDemarch-form',
templateUrl: './onlineDemarch-form.component.html',
})
export class OnlineDemarchFormComponent {
@Input() currentStep: mediationSteps;
@Input() form: UntypedFormGroup;
@Output() validatePage = new EventEmitter<any>();
public mediationStepsEnum = mediationSteps;
public orientationUtils = new OrientationUtils();
public pagesValidation: any[] = [];
public checkValidation(): void {
this.orientationUtils.setValidationsOnlineDemarchForm(
this.pagesValidation,
this.form,
(isValid) => this.validatePage.emit(isValid),
this.currentStep
);
}
}
<div class="orientation">
<app-progress-bar [currentPage]="currentStep"></app-progress-bar>
<div class="content">
<app-needs-selection
*ngIf="currentStep === null"
[form]="orientationForm"
(setNeedType)="setCurrentNeedType($event)"
[currentNeed]="needType"
(validate)="validatePage(true)"
></app-needs-selection>
<app-onlineDemarch-form
*ngIf="needType == needEnum.onlineDemarch && currentStep !== null"
[currentStep]="currentStep"
[form]="onlineDemarchForm"
(validatePage)="validatePage($event)"
></app-onlineDemarch-form>
</div>
<div class="navButtons">
<app-navigation
[currentStep]="currentStep"
[needType]="needType"
[isPageValid]="isPageValid"
(goNext)="nextPage()"
(goPrev)="prevPage()"
></app-navigation>
</div>
<app-modal-confirmation
[openned]="showConfirmationModal"
[content]="'Il vous faudra de nouveau remplir le formulaire si vous quittez'"
(closed)="hasRedirectionAccepted($event)"
></app-modal-confirmation>
<app-login-modal [openned]="showLoginModal"></app-login-modal>
</div>
@import '../../../assets/scss/color';
@import '../../../assets/scss/breakpoint';
@import '../../../assets/scss/layout';
@import '../../../assets//scss/typography';
.orientation {
height: 100%;
display: flex;
flex-direction: column;
.content {
box-sizing: border-box;
max-width: 980px;
width: 100%;
height: 100%;
margin: auto;
overflow-y: auto;
color: $grey-1;
background: $white;
border-radius: 8px;
border: 1px solid $grey-6;
padding: 2rem 3rem;
@media #{$tablet} {
padding: 1rem;
}
}
.navButtons {
margin-top: auto;
padding: 1rem;
}
}
div.titleform {
color: red;
}
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { OrientationFormViewComponent } from './orientation-form-view.component';
describe('OrientationFormViewComponent', () => {
let component: OrientationFormViewComponent;
let fixture: ComponentFixture<OrientationFormViewComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ OrientationFormViewComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(OrientationFormViewComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { AfterContentChecked, ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { UntypedFormGroup } from '@angular/forms';
import { Router } from '@angular/router';
import { OnlineMediationService } from '../../services/online-mediation.service';
import { Module } from '../../structure-list/models/module.model';
import { OrientationUtils } from '../../utils/orientationUtils';
import { mediationSteps } from './enums/mediationSteps.enum';
import { needsType } from './enums/needs.enum';
import { IOnlineMediation } from './interfaces/onlineMediation.interface';
import { NotificationService } from '../../services/notification.service';
import { AuthService } from '../../services/auth.service';
@Component({
selector: 'app-orientation-form-view',
templateUrl: './orientation-form-view.component.html',
styleUrls: ['./orientation-form-view.component.scss'],
})
export class OrientationFormViewComponent implements OnInit, AfterContentChecked {
public orientationUtils = new OrientationUtils();
public onlineDemarchForm: UntypedFormGroup;
public equipmentBuyForm: UntypedFormGroup;
public equipmentAccessForm: UntypedFormGroup;
public learnSkillsForm: UntypedFormGroup;
public orientationStepEnum = mediationSteps;
public currentStep: mediationSteps = null;
public nbSteps: number = Object.keys(mediationSteps).length / 2;
public isPageValid: boolean = false;
public needType: needsType;
public needEnum = needsType;
public canDeactivate: boolean = false;
public showLoginModal: boolean = false;
// Modal canExit var
public showConfirmationModal = false;
private resolve: Function;
constructor(
private onlineMediationService: OnlineMediationService,
private router: Router,
private notificationService: NotificationService,
private authService: AuthService,
private cdref: ChangeDetectorRef
) {}
ngOnInit() {
if (!this.authService.isLoggedIn()) {
this.showLoginModal = true;
}
}
ngAfterContentChecked() {
this.cdref.detectChanges();
}
public validatePage(event: boolean) {
this.isPageValid = event;
}
public setCurrentNeedType(needType: needsType): void {
this.needType = needType;
this.validatePage(true);
switch (needType) {
case needsType.onlineDemarch:
if (!this.onlineDemarchForm) this.onlineDemarchForm = this.orientationUtils.createOnlineDemarchForm();
break;
// case needsType.equipmentBuy:
// this.equipmentBuyForm = this.orientationUtils.createOnlineDemarchForm();
// break;
// case needsType.equipmentAccess:
// this.equipmentAccessForm = this.orientationUtils.createOnlineDemarchForm();
// break;
// case needsType.learnSkills:
// this.learnSkillsForm = this.orientationUtils.createOnlineDemarchForm();
// break;
}
}
public handleFinishForm(): void {
switch (this.needType) {
case needsType.onlineDemarch:
const toCreate: IOnlineMediation = {
...this.onlineDemarchForm.value,
onlineDemarchType: this.onlineDemarchForm.value.onlineDemarchType.map((module: Module) => module.displayText),
};
this.onlineMediationService.createOnlineMediation(toCreate).subscribe((data) => {
if (data) {
this.canDeactivate = true;
this.notificationService.showSuccess('Votre démarche en ligne a bien été enregistrée');
} else {
this.notificationService.showError('Echec de la création de votre démarche en ligne');
}
window.print();
setTimeout(() => {
this.router.navigateByUrl('/acteurs');
}, 100);
});
}
}
public nextPage(): void {
this.isPageValid = false;
if (this.currentStep === mediationSteps.mediationRecap) {
this.handleFinishForm();
return;
}
if (this.currentStep === null) {
//handle the form start
this.currentStep = 0;
return;
}
if (this.currentStep < this.nbSteps) {
this.currentStep++;
}
}
public prevPage(): void {
if (this.currentStep === 0) {
//handle the form start
this.currentStep = null;
return;
}
if (this.currentStep > 0) {
this.currentStep--;
}
}
public canExit(): Promise<boolean> {
// Avoid confirmation when user submit form and leave.
if (this.canDeactivate || this.currentStep === null) {
return new Promise((resolve) => resolve(true));
} else {
return new Promise((resolve) => this.showModal(resolve));
}
}
private showModal(resolve: Function): void {
this.showConfirmationModal = true;
this.resolve = resolve;
}
public hasRedirectionAccepted(hasAccept: boolean): void {
this.resolve(hasAccept);
this.showConfirmationModal = false;
}
}
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { DeactivateGuard } from '../../guards/deactivate.guard';
import { OrientationFormViewComponent } from './orientation-form-view.component';
const routes: Routes = [
{
path: '',
component: OrientationFormViewComponent,
canDeactivate: [DeactivateGuard],
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class OrientationRoutingModule {}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { OrientationFormViewComponent } from './orientation-form-view.component';
import { SharedModule } from '../../shared/shared.module';
import { OrientationRoutingModule } from './orientation-routing.module';
import { NeedsSelectionComponent } from './global-components/needs-selection/needs-selection.component';
import { AccompanimentTypeComponent } from './online-demarch/accompaniment-type/accompaniment-type.component';
import { ProgressBarComponent } from './global-components/progress-bar/progress-bar.component';
import { NavigationComponent } from './global-components/navigation/navigation.component';
import { MediationBeneciaryInfoComponent } from './online-demarch/mediation-beneciary-info/mediation-beneciary-info.component';
import { MediationHoursSelectionComponent } from './online-demarch/mediation-hours-selection/mediation-hours-selection.component';
import { MediationRecapComponent } from './online-demarch/mediation-recap/mediation-recap.component';
import { OnlineDemarchComponent } from './online-demarch/online-demarch/online-demarch.component';
import { OnlineDemarchFormComponent } from './online-demarch/onlineDemarch-form.component';
import { MultiRadioFormComponent } from './global-components/multi-radio-form/multi-radio-form.component';
import { PrintHeaderComponent } from './global-components/print-header/print-header.component';
import { LoginModalComponent } from './global-components/login-modal/login-modal.component';
@NgModule({
declarations: [
OrientationFormViewComponent,
ProgressBarComponent,
NeedsSelectionComponent,
NavigationComponent,
MultiRadioFormComponent,
OnlineDemarchComponent,
AccompanimentTypeComponent,
MediationBeneciaryInfoComponent,
MediationHoursSelectionComponent,
MediationRecapComponent,
OnlineDemarchFormComponent,
PrintHeaderComponent,
LoginModalComponent,
],
imports: [CommonModule, OrientationRoutingModule, SharedModule],
})
export class OrientationModule {}