diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index a4aa2711f9a1548296459c52ac0922b55bb55ea1..94e70d5fa2efc688b648558604b7d6eb036a67e7 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -1,7 +1,7 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { AboutComponent } from './about/about.component'; -import { FormComponent } from './form/form.component'; +import { FormComponent } from './form/structure-form/form.component'; import { AdminGuard } from './guards/admin.guard'; import { AuthGuard } from './guards/auth.guard'; import { DeactivateGuard } from './guards/deactivate.guard'; @@ -15,9 +15,16 @@ import { StructureDetailsComponent } from './structure-list/components/structure import { StructureListComponent } from './structure-list/structure-list.component'; import { UserVerificationComponent } from './user-verification/user-verification.component'; import { NewsletterSubscriptionComponent } from './newsletter-subscription/newsletter-subscription.component'; +import { OrientationFormComponent } from './form/orientation-form/orientation-form.component'; +import { StructureListPrintComponent } from './form/orientation-form/component/structure-list-print/structure-list-print.component'; const routes: Routes = [ { path: 'print', outlet: 'print', children: [{ path: 'structure', component: StructureDetailsComponent }] }, + { path: 'print', outlet: 'print', children: [{ path: 'structures', component: StructureListPrintComponent }] }, + { + path: 'orientation', + component: OrientationFormComponent, + }, { path: 'acteurs', component: CartoComponent, diff --git a/src/app/app.module.ts b/src/app/app.module.ts index e709b556c7fbc0d52ce526e5672cf568e11d9955..e10d31c7b1227d9cebcc0610f67ff941e21231d9 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -19,7 +19,7 @@ import { StructureOpeningStatusComponent } from './structure-list/components/str import { ModalFilterComponent } from './structure-list/components/modal-filter/modal-filter.component'; import { LegalNoticeComponent } from './legal-notice/legal-notice.component'; import { AboutComponent } from './about/about.component'; -import { FormComponent } from './form/form.component'; +import { FormComponent } from './form/structure-form/form.component'; import { UserVerificationComponent } from './user-verification/user-verification.component'; import { AuthGuard } from './guards/auth.guard'; import { CustomHttpInterceptor } from './config/http-interceptor'; @@ -34,6 +34,10 @@ import { TempUserResolver } from './resolvers/temp-user.resolver'; import { StructureJoinComponent } from './structure-join/structure-join.component'; import { RouterListenerService } from './services/routerListener.service'; import { NewsletterSubscriptionComponent } from './newsletter-subscription/newsletter-subscription.component'; +import { OrientationFormComponent } from './form/orientation-form/orientation-form.component'; +import { StructureDetailPrintComponent } from './form/orientation-form/component/structure-detail-print/structure-detail-print.component'; +import { StructureListPrintComponent } from './form/orientation-form/component/structure-list-print/structure-list-print.component'; +import { StructurePrintHeaderComponent } from './form/orientation-form/component/structure-print-header/structure-print-header.component'; @NgModule({ declarations: [ @@ -56,6 +60,10 @@ import { NewsletterSubscriptionComponent } from './newsletter-subscription/newsl FooterFormComponent, StructureJoinComponent, NewsletterSubscriptionComponent, + OrientationFormComponent, + StructureDetailPrintComponent, + StructureListPrintComponent, + StructurePrintHeaderComponent, ], imports: [BrowserModule, HttpClientModule, AppRoutingModule, SharedModule, MapModule], providers: [ diff --git a/src/app/form/orientation-form/component/structure-detail-print/structure-detail-print.component.html b/src/app/form/orientation-form/component/structure-detail-print/structure-detail-print.component.html new file mode 100644 index 0000000000000000000000000000000000000000..d4778617218616100830522f78ccec64176c7fbe --- /dev/null +++ b/src/app/form/orientation-form/component/structure-detail-print/structure-detail-print.component.html @@ -0,0 +1,158 @@ +<div class="structrue-details-container" *ngIf="structure"> + <!-- Header info --> + <div fxLayout="row" class="structure-details-block" fxLayoutAlign="baseline baseline" fxLayoutGap="8px"> + <div fxLayout="column" fxLayoutGap="10px" fxFlex="100%"> + <div fxLayout="column" class="no-margin" fxLayoutAlign="space-between start"> + <h2 class="bold">{{ structure.structureName }}</h2> + </div> + <div fxLayout="row" fxLayoutAlign="space-between center"> + <div class="typeInformationHeader" fxLayout="column"> + <h3>{{ structure.getLabelTypeStructure() }}</h3> + </div> + </div> + <div fxLayout="row" class="mobile-column"> + <div fxLayout="column" fxFlex="50%"> + <div *ngIf="structure.address" fxLayout="row" fxLayoutAlign="none flex-end" fxLayoutGap="13px"> + <app-svg-icon [type]="'ico'" [icon]="'adress'" [title]="'Adresse'"></app-svg-icon> + <p>{{ structure.address.numero }} {{ structure.address.street }}, {{ structure.address.commune }}</p> + </div> + <div *ngIf="structure.website" fxLayout="row" fxLayoutAlign="none flex-end" fxLayoutGap="13px"> + <app-svg-icon [type]="'ico'" [icon]="'web'" [title]="'Site web'"></app-svg-icon> + <a + target="_blank" + class="custom-link" + rel="noopener noreferrer" + [href]="structure.website.includes('http') ? structure.website : 'http://' + structure.website" + >{{ structure.website | url }}</a + > + </div> + <div *ngIf="structure.hasSocialNetwork()" fxLayout="row" fxLayoutAlign="none baseline" fxLayoutGap="13px"> + <app-svg-icon [type]="'ico'" [icon]="'network'"></app-svg-icon> + <div fxLayout="row" fxLayoutAlign="none baseline" fxLayoutGap="8px"> + <a + *ngIf="structure.facebook" + target="_blank" + class="custom-link" + rel="noopener noreferrer" + [href]="'http://' + structure.facebook" + > + <app-svg-icon [type]="'ico'" [icon]="'facebook'" [title]="'Facebook'"></app-svg-icon + ></a> + <a + *ngIf="structure.twitter" + target="_blank" + class="custom-link" + rel="noopener noreferrer" + [href]="'http://' + structure.twitter" + > + <app-svg-icon [type]="'ico'" [icon]="'twitter'" [title]="'Twitter'"></app-svg-icon + ></a> + <a + *ngIf="structure.instagram" + target="_blank" + class="custom-link" + rel="noopener noreferrer" + [href]="'http://' + structure.instagram" + > + <app-svg-icon [type]="'ico'" [icon]="'instagram'" [title]="'Instagram'"></app-svg-icon + ></a> + <a + *ngIf="structure.linkedin" + target="_blank" + class="custom-link" + rel="noopener noreferrer" + [href]="'http://' + structure.linkedin" + > + <app-svg-icon [type]="'ico'" [icon]="'linkedin'" [title]="'Linkedin'"></app-svg-icon + ></a> + </div> + </div> + <div *ngIf="structure.contactPhone" fxLayout="row" fxLayoutAlign="none flex-end" fxLayoutGap="13px"> + <app-svg-icon [type]="'ico'" [icon]="'tel'" [title]="'Téléphone'"></app-svg-icon> + <p>{{ structure.contactPhone | phone }}</p> + </div> + </div> + <div fxLayout="column" fxFlex="50%"> + <div + *ngIf="structure.contactMail && structure.contactMail !== 'unknown@unknown.com'" + fxLayout="row" + fxLayoutAlign="none center" + fxLayoutGap="13px" + > + <app-svg-icon [type]="'ico'" [iconClass]="'grey-1'" [icon]="'email'" [title]="'Email'"></app-svg-icon> + <p>{{ structure.contactMail }}</p> + </div> + <div *ngIf="structure.hasPassNumeric()" fxLayout="row" fxLayoutAlign="none center" fxLayoutGap="13px"> + <app-svg-icon [type]="'ico'" [icon]="'pass'" [title]="'Pass numérique'"></app-svg-icon> + <p>agréé Pass Numérique</p> + </div> + <div fxLayout="row" fxLayoutAlign="none flex-end" fxLayoutGap="13px"> + <app-svg-icon [type]="'ico'" [icon]="'calendar'"></app-svg-icon> + <p>Mise à jour le {{ structure.updatedAt | date: 'mediumDate' }}</p> + </div> + </div> + </div> + + <div> + {{ structure.description }} + </div> + <div class="info"> + {{ structure.lockdownActivity }} + </div> + </div> + </div> + <!-- Accueil --> + <div + *ngIf="structure.accessModality.length > 0 || structure.hours.hasData() || structure.remoteAccompaniment" + fxLayout="column" + class="structure-details-block" + fxLayoutAlign="baseline baseline" + fxLayoutGap="20px" + > + <!-- Opening Hours --> + <div fxLayout="row" class="w-100 mobile-column"> + <div *ngIf="structure.hours.hasData()" fxFlex="50%"> + <h3 class="subtitle">Horaires d’ouverture au public</h3> + <div fxLayout="column"> + <div *ngFor="let day of structure.hours | keyvalue: keepOriginalOrder"> + <div *ngIf="day.value.open"> + <h4>{{ day.key | day }}</h4> + <div class="opening-time" fxLayout="row" fxLayoutAlign="none flex-end"> + <div *ngFor="let timeRange of day.value.time; let isFirst = first"> + <p *ngIf="isFirst">de {{ timeRange.formatOpeningDate() }} à {{ timeRange.formatClosingDate() }}</p> + <p *ngIf="!isFirst && timeRange.opening"> + et de {{ timeRange.formatOpeningDate() }} à {{ timeRange.formatClosingDate() }} + </p> + </div> + </div> + </div> + </div> + </div> + </div> + <!-- accessModality --> + <div *ngIf="structure.accessModality.length > 0" fxFlex="40%"> + <h3 class="subtitle">Accès transports en commun</h3> + <div fxLayout="column"> + <div *ngFor="let tclStop of tclStopPoints"> + <div fxLayout="row wrap" fxLayoutGap="5px"> + <p>{{ tclStop.name }}:</p> + <p *ngIf="tclStop.subLines.length > 0">Métro</p> + <p *ngFor="let sub of tclStop.subLines">{{ sub }}</p> + <p *ngIf="tclStop.tramLines.length > 0">Tram</p> + <p *ngFor="let tram of tclStop.tramLines">{{ tram }}</p> + <p *ngIf="tclStop.busLines.length > 0">Bus</p> + <p *ngFor="let bus of tclStop.busLines">{{ bus }}</p> + </div> + </div> + </div> + </div> + </div> + <div *ngIf="structure.exceptionalClosures" class="bold-info"> + <h3 class="subtitle">Précisions sur les horaires</h3> + <p>{{ structure.exceptionalClosures }}</p> + </div> + <div *ngIf="structure.remoteAccompaniment" class="bold-info"> + <h3>Cette structure propose un accompagnement à distance.</h3> + </div> + </div> +</div> diff --git a/src/app/form/orientation-form/component/structure-detail-print/structure-detail-print.component.scss b/src/app/form/orientation-form/component/structure-detail-print/structure-detail-print.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..67ce48453c000b5ebf30a163522befae33234de6 --- /dev/null +++ b/src/app/form/orientation-form/component/structure-detail-print/structure-detail-print.component.scss @@ -0,0 +1,139 @@ +@import '../../../../../assets/scss/icons'; +@import '../../../../../assets/scss/color'; +@import '../../../../../assets/scss/typography'; +@import '../../../../../assets/scss/z-index'; +@import '../../../../../assets/scss/layout'; +@import '../../../../../assets/scss/breakpoint'; + +a { + padding: unset; +} + +.structrue-details-container { + border-right: solid 1px $grey-4; + page-break-after: always; + background-color: $white; + top: 0; + left: 0; + max-width: 980px; + width: 100%; + margin-bottom: 50px; + padding: 10px 24px; + @media #{$tablet} { + width: calc(100% - 2 * 24px); + position: fixed; + height: 100%; + .printButton { + display: none !important; + } + } + .printButton { + margin-right: 75px; + } +} + +.structrue-details-container > .structure-details-block { + padding: 0px 0px 24px 0; + border-bottom: 1px dashed $grey-2; + .subtitle { + text-transform: uppercase; + @include cn-bold-16; + margin-bottom: 10px; + color: $grey-3; + } +} + +.structrue-details-container > .structure-details-block ~ .structure-details-block { + padding: 24px 0; +} + +.structure-details-block:last-child { + border-bottom: none; +} + +.opening-time { + p { + margin: 0 5px 12px 0; + } +} +.typeInformationHeader { + color: $grey-3; +} +h2 { + margin-top: 0; + margin-bottom: 5px; + @include cn-regular-26; +} +h3 { + margin: 0 0 8px 0; + @include cn-regular-16; +} +h4 { + margin-left: 0; + margin-bottom: 0; + margin-top: 4px; + @include cn-regular-14; + color: $grey-2; + text-transform: uppercase; +} +p, +.custom-link { + @include cn-regular-16; + margin-top: 9px; + margin-bottom: 9px; + &.no-margin { + margin-top: unset; + margin-bottom: unset; + } + &.no-margin-bottom { + margin-bottom: unset; + } +} + +.bold-info { + @include cn-bold-16; +} + +@media print { + .structrue-details-container { + background-color: unset; + z-index: unset; + position: unset; + top: unset; + left: unset; + max-width: unset; + width: unset; + height: unset; + padding: unset; + overflow: hidden; + border-right: 0; + } + + .hide-on-print { + display: none !important; + } +} + +.info { + color: $ram-hover-principal; +} + +.wrapper { + width: 100%; + display: grid; + gap: 20px 30px; + grid-template-columns: 1fr 1fr; +} + +.tags-cloud { + font-style: normal; + justify-content: center; + align-items: center; + height: 25px; + border-radius: 20px; + padding: 5px 15px; + color: white; + border-style: none; + margin-top: 15px; + background: #348899; +} diff --git a/src/app/form/orientation-form/component/structure-detail-print/structure-detail-print.component.ts b/src/app/form/orientation-form/component/structure-detail-print/structure-detail-print.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..d1e0fb6ed26cd1c7ef6f62685486999cbc090a50 --- /dev/null +++ b/src/app/form/orientation-form/component/structure-detail-print/structure-detail-print.component.ts @@ -0,0 +1,75 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { Structure } from '../../../../models/structure.model'; +import * as _ from 'lodash'; +import { TclService } from '../../../../services/tcl.service'; +import { TclStopPoint } from '../../../../models/tclStopPoint.model'; +import { AuthService } from '../../../../services/auth.service'; +import { AccessModality } from '../../../../structure-list/enum/access-modality.enum'; +import { PublicCategorie } from '../../../../structure-list/enum/public.enum'; +@Component({ + selector: 'app-structure-detail-print', + templateUrl: './structure-detail-print.component.html', + styleUrls: ['./structure-detail-print.component.scss'], +}) +export class StructureDetailPrintComponent implements OnInit { + @Input() public structure: Structure; + @Output() public closeDetails: EventEmitter<boolean> = new EventEmitter<boolean>(); + @Output() public dataReady: EventEmitter<boolean> = new EventEmitter<boolean>(); + public accessModality = AccessModality; + public tclStopPoints: TclStopPoint[] = []; + + constructor(private tclService: TclService, private authService: AuthService) {} + + async ngOnInit(): Promise<void> { + // GetTclStopPoints + this.getTclStopPoints(); + const index = this.structure.proceduresAccompaniment.indexOf('autres'); + if (index > -1) { + this.structure.proceduresAccompaniment.splice(index, 1); + } + } + + public userIsLoggedIn(): boolean { + return this.authService.isLoggedIn(); + } + + public getAccessLabel(accessModality: AccessModality): string { + switch (accessModality) { + case AccessModality.free: + return 'Accès libre'; + case AccessModality.meeting: + return 'Sur rendez-vous'; + case AccessModality.meetingOnly: + return 'Uniquement sur RDV'; + case AccessModality.numeric: + return 'Téléphone / Visio'; + default: + return null; + } + } + + public getPublicLabel(tagetPublic: PublicCategorie): string { + switch (tagetPublic) { + case PublicCategorie.young: + return 'Jeunes (16 - 25 ans)'; + case PublicCategorie.adult: + return 'Adultes'; + case PublicCategorie.elderly: + return 'Séniors (+ de 65 ans)'; + case PublicCategorie.all: + return 'Tout public'; + case PublicCategorie.under16Years: + return 'Moins de 16 ans'; + case PublicCategorie.women: + return 'Uniquement femmes'; + default: + return null; + } + } + + public getTclStopPoints(): void { + this.tclService.getTclStopPointBycoord(this.structure.getLon(), this.structure.getLat()).subscribe((res) => { + this.tclStopPoints = res; + }); + } +} diff --git a/src/app/form/orientation-form/component/structure-list-print/structure-list-print.component.html b/src/app/form/orientation-form/component/structure-list-print/structure-list-print.component.html new file mode 100644 index 0000000000000000000000000000000000000000..1c55aece536b001ef45e3800ac5959cbefbda2e9 --- /dev/null +++ b/src/app/form/orientation-form/component/structure-list-print/structure-list-print.component.html @@ -0,0 +1,12 @@ +<app-structure-print-header + class="multi-print" + [beneficiaryNeedCommentary]="beneficiaryNeedCommentary" + [beneficiaryName]="beneficiaryName" + [structureAccompaniment]="structureAccompaniment" + [beneficiaryPassNumeric]="beneficiaryPassNumeric" + [contactAccompaniment]="contactAccompaniment" + [filters]="filters" +></app-structure-print-header> +<div class="multi-print" *ngFor="let structure of structures"> + <app-structure-detail-print [structure]="structure"></app-structure-detail-print> +</div> diff --git a/src/app/form/orientation-form/component/structure-list-print/structure-list-print.component.scss b/src/app/form/orientation-form/component/structure-list-print/structure-list-print.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..768bc8ad13e45d4a93af2e169e6cfd8f1cb26a79 --- /dev/null +++ b/src/app/form/orientation-form/component/structure-list-print/structure-list-print.component.scss @@ -0,0 +1,18 @@ +.list-to-print { + height: 600px; + overflow-x: hidden; + overflow-y: auto; +} + +.multi-print { + ::ng-deep { + .structrue-details-container { + page-break-after: always; + height: 100%; + } + .print-header { + page-break-after: always; + height: 100%; + } + } +} diff --git a/src/app/form/orientation-form/component/structure-list-print/structure-list-print.component.ts b/src/app/form/orientation-form/component/structure-list-print/structure-list-print.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..540db118a50b17302bb3bd4981e59e893726d56d --- /dev/null +++ b/src/app/form/orientation-form/component/structure-list-print/structure-list-print.component.ts @@ -0,0 +1,25 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { Structure } from '../../../../models/structure.model'; +import * as _ from 'lodash'; +import { ActivatedRoute } from '@angular/router'; +import { PrintService } from '../../../../shared/service/print.service'; +import { Filter } from '../../../../structure-list/models/filter.model'; +import Module from 'module'; +@Component({ + selector: 'app-structure-list-print', + templateUrl: './structure-list-print.component.html', + styleUrls: ['./structure-list-print.component.scss'], +}) +export class StructureListPrintComponent implements OnInit { + @Input() public structures: Structure[]; + @Input() public filters: Filter[]; + @Input() public beneficiaryNeedCommentary: string; + @Input() public beneficiaryName: string; + @Input() public structureAccompaniment: string; + @Input() public beneficiaryPassNumeric: boolean; + @Input() public contactAccompaniment: string; + + constructor(private printService: PrintService, private route: ActivatedRoute) {} + + async ngOnInit(): Promise<void> {} +} diff --git a/src/app/form/orientation-form/component/structure-print-header/structure-print-header.component.html b/src/app/form/orientation-form/component/structure-print-header/structure-print-header.component.html new file mode 100644 index 0000000000000000000000000000000000000000..b1c83faf20514cedd941fe0526457082fe65eedc --- /dev/null +++ b/src/app/form/orientation-form/component/structure-print-header/structure-print-header.component.html @@ -0,0 +1,67 @@ +<div class="print-header" fxLayout="column"> + <div class="header-print" fxLayout="row" fxLayoutAlign="space-between center"> + <h3>Fiche d'orientation</h3> + <h4 class="typeInformationHeader">{{ date }}</h4> + </div> + + <!-- Name --> + <div *ngIf="beneficiaryName"> + <p class="bold">{{ beneficiaryName }}</p> + </div> + + <!-- Accompaniment --> + <div *ngIf="structureAccompaniment"> + <div class="typeInformationHeader">Orienté par</div> + <div class="contactAccompaniment" fxLayout="row" fxLayoutAlign="space-between center"> + <div class="bold">{{ structureAccompaniment }}</div> + <!-- Contact --> + <div class="bold" *ngIf="contactAccompaniment">{{ contactAccompaniment }}</div> + </div> + </div> + + <!-- Needs --> + <div *ngIf="equipments.length > 0"> + <p class="typeInformationHeader">Besoins en matériel</p> + <div fxLayout="row wrap" fxLayoutGap="16px"> + <div *ngFor="let equipmentTag of equipments" class="tags-cloud" fxLayout="row"> + {{ equipmentTag.text ? equipmentTag.text : equipmentTag.value }} + </div> + </div> + </div> + <div *ngIf="formations.length > 0"> + <p class="typeInformationHeader">Besoins en formation</p> + <div fxLayout="row wrap" fxLayoutGap="16px"> + <div *ngFor="let formationTag of formations" class="tags-cloud" fxLayout="row"> + {{ formationTag.text ? formationTag.text : formationTag.value }} + </div> + </div> + </div> + <div *ngIf="assistances.length > 0"> + <p class="typeInformationHeader">Besoins d'accompagnement</p> + <div fxLayout="row wrap" fxLayoutGap="16px"> + <div *ngFor="let assistanceTag of assistances" class="tags-cloud" fxLayout="row"> + {{ assistanceTag.text ? assistanceTag.text : assistanceTag.value }} + </div> + </div> + </div> + <div *ngIf="specificNeeds.length > 0"> + <div class="typeInformationHeader">Besoins spécifiques'</div> + <div fxLayout="row wrap" fxLayoutGap="16px"> + <div *ngFor="let specificNeed of specificNeeds" class="tags-cloud" fxLayout="row"> + {{ specificNeed.text ? specificNeed.text : specificNeed.value }} + </div> + </div> + </div> + + <!-- Pass Numeric --> + <div *ngIf="beneficiaryPassNumeric" class="inputRow" fxLayout="row" fxLayoutGap="13px"> + <app-svg-icon [type]="'ico'" [icon]="'passNumeric'"></app-svg-icon> + <p class="bold">Pass Numérique</p> + </div> + + <!-- Comments --> + <div *ngIf="beneficiaryNeedCommentary"> + <div class="typeInformationHeader">Informations à destination de la structure</div> + <p>{{ beneficiaryNeedCommentary }}</p> + </div> +</div> diff --git a/src/app/form/orientation-form/component/structure-print-header/structure-print-header.component.scss b/src/app/form/orientation-form/component/structure-print-header/structure-print-header.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..0c9a98b49fafadf2d5a3437ce62e37d26ff2786e --- /dev/null +++ b/src/app/form/orientation-form/component/structure-print-header/structure-print-header.component.scss @@ -0,0 +1,60 @@ +@import '../../../../../assets/scss/layout'; +@import '../../../../../assets/scss/breakpoint'; +@import '../../../../../assets/scss/color'; +@import '../../../../../assets/scss/typography'; +@import '../../../../../assets/scss/shapes'; +@import '../../../../../assets/scss/z-index'; + +.header-print { + margin-top: 20px; + margin-bottom: 20px; + width: 100%; +} + +.print-header { + page-break-after: always; + height: 100%; +} + +.typeInformationHeader { + @include cn-bold-16; + margin-bottom: 5px; + color: $grey-3; +} + +.contactAccompaniment { + width: 67%; +} + +.tags-cloud { + font-style: normal; + justify-content: center; + align-items: center; + height: 28px; + border-radius: 20px; + padding: 5px 15px; + color: white; + border-style: none; + margin-top: 5px; + background: #348899; + &.unchecked { + background: #bdbdbd; + } +} + +.textareaBlock { + @media #{$tablet} { + max-width: 90%; + } + textarea { + padding: 13px 8px; + background: $grey-6; + border: 1px solid $grey-4; + border-radius: 1px; + resize: none; + @include cn-regular-16; + } + p { + text-align: right; + } +} diff --git a/src/app/form/orientation-form/component/structure-print-header/structure-print-header.component.ts b/src/app/form/orientation-form/component/structure-print-header/structure-print-header.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..5e6ed970b3949748b02b48e2c53e859c73ea9170 --- /dev/null +++ b/src/app/form/orientation-form/component/structure-print-header/structure-print-header.component.ts @@ -0,0 +1,71 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { Structure } from '../../../../models/structure.model'; +import * as _ from 'lodash'; +import { ActivatedRoute } from '@angular/router'; +import { PrintService } from '../../../../shared/service/print.service'; +import Module from 'module'; +import { Filter } from '../../../../structure-list/models/filter.model'; +@Component({ + selector: 'app-structure-print-header', + templateUrl: './structure-print-header.component.html', + styleUrls: ['./structure-print-header.component.scss'], +}) +export class StructurePrintHeaderComponent implements OnInit { + @Input() public beneficiaryNeedCommentary: string | null; + @Input() public beneficiaryName: string | null; + @Input() public structureAccompaniment: string; + @Input() public beneficiaryPassNumeric: boolean; + @Input() public contactAccompaniment: string | null; + @Input() public filters: Filter[]; + + public date: string; + public formations: Filter[] = []; + public assistances: Filter[] = []; + public equipments: Filter[] = []; + public specificNeeds: Filter[] = []; + + constructor(private printService: PrintService, private route: ActivatedRoute) {} + + async ngOnInit(): Promise<void> { + this.date = new Date().toLocaleDateString('fr-FR', { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric', + hour: 'numeric', + minute: 'numeric', + }); + + this.filters.map((elem) => { + switch (elem.name) { + case 'proceduresAccompaniment': + this.assistances.push(elem); + break; + case 'publicsAccompaniment': + this.specificNeeds.push(elem); + break; + case 'equipmentsAndServices': + this.equipments.push(elem); + break; + case 'accessRight': + this.formations.push(elem); + break; + case 'baseSkills': + this.formations.push(elem); + break; + case 'socialAndProfessional': + this.formations.push(elem); + break; + case 'parentingHelp': + this.formations.push(elem); + break; + case 'digitalCultureSecurity': + this.formations.push(elem); + break; + + default: + break; + } + }); + } +} diff --git a/src/app/form/orientation-form/orientation-form.component.html b/src/app/form/orientation-form/orientation-form.component.html new file mode 100644 index 0000000000000000000000000000000000000000..5c163c2a6447344925898634a4c22a01287260a2 --- /dev/null +++ b/src/app/form/orientation-form/orientation-form.component.html @@ -0,0 +1,456 @@ +<div *ngIf="!multiPrint" class="form" fxLayout="column"> + <app-modal-confirmation + [openned]="showConfirmationModal" + [content]="'Il vous faudra de nouveau remplir le formulaire si vous quittez'" + (closed)="hasRedirectionAccepted($event)" + ></app-modal-confirmation> + <div class="content"> + <div class="progressBar" fxLayout="row" fxLayoutAlign="space-between center" fxLayoutGap="20px"> + <label [ngClass]="{ validate: currentPage == nbPagesForm }" for="progressForm" + >{{ progressStatus | number: '1.0-0' }}% + </label> + <progress + id="progressForm" + [ngClass]="{ validate: currentPage == nbPagesForm }" + max="100" + [value]="progressStatus" + ></progress> + </div> + <!-- BESOIN BENEFICIAIRE --> + <div *ngIf="currentPage == pageTypeEnum.beneficiaryNeed" class="page"> + <div class="titleInfo"> + Cet espace vise à favoriser l'orientation de l'usager en partant de son besoin.<br /> + Merci de remplir ces quelques questions qui vous permettront d'identifier le lieu à proximité le plus adapté. + </div> + <div class="title"> + <h3>De quoi le bénéficiaire a-t-il besoin ?</h3> + </div> + <div class="collapse" [ngClass]="{ notCollapsed: !showEquipments }"> + <div fxLayout="column"> + <div + class="collapseHeader" + fxLayout="row" + fxLayoutGap="20px" + fxLayoutAlign=" center" + (click)="toggleEquipments()" + > + <div class="titleCollapse">Accéder à du matériel</div> + <div class="logo"> + <svg class="show" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#show'"></use> + </svg> + <svg class="hide" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#hide'"></use> + </svg> + </div> + </div> + <div *ngIf="showEquipments" class="tags"> + <button + *ngFor="let choice of equipments" + (click)="updateChoice(choice.id, 'equipments')" + [ngClass]="{ selectedChoice: isInArray(choice.id, 'equipments') }" + > + <div fxLayout="row" fxLayoutAlign=" center"> + <svg class="validate" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#checkVector'"></use> + </svg> + <div class="textBtn"> + {{ choice.text }} + </div> + </div> + </button> + </div> + </div> + </div> + <div class="collapse" [ngClass]="{ notCollapsed: !showAssistance }"> + <div fxLayout="column"> + <div + class="collapseHeader" + fxLayout="row" + fxLayoutGap="20px" + fxLayoutAlign=" center" + (click)="toggleAssistance()" + > + <div class="titleCollapse">Être aidé</div> + <div class="logo"> + <svg class="show" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#show'"></use> + </svg> + <svg class="hide" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#hide'"></use> + </svg> + </div> + </div> + <div *ngIf="showAssistance" class="tags"> + <button + *ngFor="let choice of assistance" + (click)="updateChoice(choice.id, 'assistance')" + [ngClass]="{ selectedChoice: isInArray(choice.id, 'assistance') }" + > + <div fxLayout="row" fxLayoutAlign=" center"> + <svg class="validate" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#checkVector'"></use> + </svg> + <div class="textBtn"> + {{ choice.text }} + </div> + </div> + </button> + </div> + </div> + </div> + <div class="collapse" [ngClass]="{ notCollapsed: !showFormation }"> + <div fxLayout="column"> + <div + class="collapseHeader" + fxLayout="row" + fxLayoutGap="20px" + fxLayoutAlign=" center" + (click)="toggleFormation()" + > + <div class="titleCollapse">Être formé</div> + <div class="logo"> + <svg class="show" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#show'"></use> + </svg> + <svg class="hide" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#hide'"></use> + </svg> + </div> + </div> + <div *ngIf="showFormation" class="tags"> + <p class="titleCateg">{{ baseSkillssReferentiel.name }}</p> + <button + *ngFor="let choice of baseSkillssReferentiel.modules" + (click)="updateChoice(choice.id, 'formation')" + [ngClass]="{ selectedChoice: isInArray(choice.id, 'formation') }" + > + <div fxLayout="row" fxLayoutAlign=" center"> + <svg class="validate" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#checkVector'"></use> + </svg> + <div class="textBtn"> + {{ choice.text }} + </div> + </div> + </button> + + <p class="titleCateg">{{ accessRightsReferentiel.name }}</p> + <button + *ngFor="let choice of accessRightsReferentiel.modules" + (click)="updateChoice(choice.id, 'formation')" + [ngClass]="{ selectedChoice: isInArray(choice.id, 'formation') }" + > + <div fxLayout="row" fxLayoutAlign=" center"> + <svg class="validate" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#checkVector'"></use> + </svg> + <div class="textBtn"> + {{ choice.text }} + </div> + </div> + </button> + + <p class="titleCateg">{{ digitalCultureSecuritysReferentiel.name }}</p> + <button + *ngFor="let choice of digitalCultureSecuritysReferentiel.modules" + (click)="updateChoice(choice.id, 'formation')" + [ngClass]="{ selectedChoice: isInArray(choice.id, 'formation') }" + > + <div fxLayout="row" fxLayoutAlign=" center"> + <svg class="validate" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#checkVector'"></use> + </svg> + <div class="textBtn"> + {{ choice.text }} + </div> + </div> + </button> + + <p class="titleCateg">{{ parentingHelpsReferentiel.name }}</p> + <button + *ngFor="let choice of parentingHelpsReferentiel.modules" + (click)="updateChoice(choice.id, 'formation')" + [ngClass]="{ selectedChoice: isInArray(choice.id, 'formation') }" + > + <div fxLayout="row" fxLayoutAlign=" center"> + <svg class="validate" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#checkVector'"></use> + </svg> + <div class="textBtn"> + {{ choice.text }} + </div> + </div> + </button> + + <p class="titleCateg">{{ socialAndProfessionalsReferentiel.name }}</p> + <button + *ngFor="let choice of socialAndProfessionalsReferentiel.modules" + (click)="updateChoice(choice.id, 'formation')" + [ngClass]="{ selectedChoice: isInArray(choice.id, 'formation') }" + > + <div fxLayout="row" fxLayoutAlign=" center"> + <svg class="validate" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#checkVector'"></use> + </svg> + <div class="textBtn"> + {{ choice.text }} + </div> + </div> + </button> + </div> + </div> + </div> + </div> + <!-- NUMERIC PASS --> + <div *ngIf="currentPage == pageTypeEnum.beneficiaryPassNumeric" class="page"> + <div class="title"> + <h3>Le bénéficiaire possède-t-il un Pass numérique ?</h3> + </div> + <app-radio-form + [selectedOption]="getOrientationControl('passNumeric').value" + [horizontal]="true" + (selectedEvent)="onRadioBtnChange('passNumeric', $event)" + > + </app-radio-form> + </div> + <!-- PROFIL BENEFICIAIRE --> + <div *ngIf="currentPage == pageTypeEnum.beneficiaryInfo" class="page"> + <div class="title"> + <h3>Autour de quelle adresse chercher une structure ?</h3> + </div> + <div class="form-group" fxLayout="column"> + <label for="address">Adresse</label> + + <div class="inputRow" fxLayout="row" fxLayoutGap="13px"> + <app-address-autocomplete + [address]="getOrientationControl('address').valid ? getOrientationControl('address').value : null" + (inputAddress)="setAddressBeneficiary()" + (selectedAddress)="setAddressBeneficiary($event)" + ></app-address-autocomplete> + <app-svg-icon + *ngIf="getOrientationControl('address').valid" + [iconClass]="'validation'" + [type]="'form'" + [icon]="'validate'" + class="validateIcon" + ></app-svg-icon> + <div *ngIf="!getOrientationControl('address').valid" (click)="getAddress()"> + <app-svg-icon [type]="'ico'" [icon]="'locateMe'" class="markerIcon"></app-svg-icon> + </div> + </div> + </div> + <div class="title"> + <h3>Le bénéficiaire a-t-il un profil spécifique ?</h3> + <p class="notRequired">facultatif</p> + </div> + + <div class="tags"> + <button + *ngFor="let choice of specificProfile.modules" + (click)="updateChoice(choice.id, 'specificProfile')" + [ngClass]="{ selectedChoice: isInArray(choice.id, 'specificProfile') }" + > + <div fxLayout="row" fxLayoutAlign=" center"> + <svg class="validate" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#checkVector'"></use> + </svg> + <div class="textBtn"> + {{ choice.text }} + </div> + </div> + </button> + </div> + </div> + <!-- STRUCTURE SEARCH --> + <div *ngIf="currentPage == pageTypeEnum.structuresSelection" class="page"> + Filtres séléctionnés + <div fxLayout="row wrap" fxLayoutGap="16px"> + <div *ngFor="let filter of filters" class="tags-cloud" fxLayout="row" (click)="removeFilter(filter)"> + {{ filter.text ? filter.text : filter.value }} + <app-svg-icon [type]="'ico'" [icon]="'delete'" [iconColor]="'white'"></app-svg-icon> + </div> + <div + *ngFor="let uncheckedFilter of uncheckedFilters" + class="tags-cloud unchecked" + fxLayout="row" + (click)="restoreFilter(uncheckedFilter)" + > + {{ uncheckedFilter.text ? uncheckedFilter.text : uncheckedFilter.value }} + <app-svg-icon [type]="'ico'" [icon]="'validate'" [iconColor]="'white'"></app-svg-icon> + </div> + </div> + <div fxLayout="row" class="content-container"> + <div class="nbStructure-panel"> + <div class="nbStructuresLabel" [ngPlural]="structuresList.length"> + <ng-template ngPluralCase="0">0 structure trouvée</ng-template> + <ng-template ngPluralCase="1">1 structure trouvée</ng-template> + <ng-template ngPluralCase="other">{{ structuresList.length }} structures trouvées</ng-template> + </div> + <div id="listCard" class="left-pane" (mouseleave)="mouseLeave()"> + <app-card + *ngFor="let structure of structuresList" + [structure]="structure" + [isOrientation]="true" + [isSelected]="isInPrintList(structure._id)" + (addToList)="addToList($event, structure)" + (hover)="handleCardHover($event)" + (showDetails)="showDetails($event)" + ></app-card> + <p *ngIf="structureList && structureList.length <= 0"> + Il n'y a aucune réponse correspondant à votre recherche + </p> + </div> + </div> + <div class="right-pane"> + <div class="deep-map"> + <app-map + [structures]="structuresList" + [structuresToPrint]="structuresToPrint" + [toogleToolTipId]="displayMapMarkerId" + [selectedMarkerId]="selectedMarkerId" + [locate]="locate" + (locatationTrigger)="locatationTrigger($event)" + (selectedStructure)="showDetailStructure($event)" + [isMapPhone]="isMapPhone" + [searchedValue]="searchedValue" + [ngClass]="{ mapPhone: isMapPhone == true }" + ></app-map> + </div> + </div> + </div> + </div> + <!-- BENEFICIARY ACCOMPANIMENT --> + <div *ngIf="currentPage == pageTypeEnum.beneficiaryAccompaniment" class="page"> + <div class="title"> + <h3>Qui oriente le bénéficiaire ?</h3> + </div> + <label>Votre structure (MDM, Caf, Pôle Emploi...)</label> + <div class="inputRow" fxLayout="row" fxLayoutGap="13px"> + <input + type="text" + [value]="getOrientationControl('structureAccompaniment').value" + (input)="setStructureAccompaniment($event.target.value)" + class="form-input" + /> + </div> + + <div class="title"> + <h3>Comment contacter cette structure ?</h3> + <p class="notRequired">facultatif</p> + </div> + <label>Contact (email ou n° de téléphone)</label> + <div class="inputRow" fxLayout="row" fxLayoutGap="13px"> + <input + type="text" + [value]="getOrientationControl('contactAccompaniment').value" + (input)="setContactAccompaniment($event.target.value)" + class="form-input" + /> + </div> + + <div class="title"> + <h3>Qui est le bénéficiaire ?</h3> + <p class="notRequired">facultatif</p> + </div> + <label>Nom du bénéficiaire</label> + <div class="inputRow" fxLayout="row" fxLayoutGap="13px"> + <input + type="text" + [value]="getOrientationControl('beneficiaryName').value" + (input)="setBeneficiaryName($event.target.value)" + class="form-input" + /> + </div> + </div> + <!-- BENEFICIARY NEEDS COMMENTARY --> + <div *ngIf="currentPage == pageTypeEnum.beneficiaryNeedCommentary" class="page"> + <div class="title"> + <h3>Précisez le besoin</h3> + <p class="notRequired">facultatif</p> + </div> + <label>Ces informations sont à destination de la structure</label> + <div class="textareaBlock" fxLayout="column"> + <textarea + rows="8" + maxlength="500" + [value]="getOrientationControl('beneficiaryNeedCommentary').value" + (input)="setBeneficiaryNeedCommentary($event.target.value)" + ></textarea> + <p> + {{ + getOrientationControl('beneficiaryNeedCommentary').value + ? getOrientationControl('beneficiaryNeedCommentary').value.length + : 0 + }}/500 + </p> + </div> + </div> + <!-- PRINT RESULTS --> + <div *ngIf="currentPage == pageTypeEnum.printResults" class="page"> + <div class="title"> + <app-structure-print-header + [beneficiaryNeedCommentary]="getOrientationControl('beneficiaryNeedCommentary').value" + [beneficiaryName]="getOrientationControl('beneficiaryName').value" + [structureAccompaniment]="getOrientationControl('structureAccompaniment').value" + [beneficiaryPassNumeric]="getOrientationControl('passNumeric').value" + [contactAccompaniment]="getOrientationControl('contactAccompaniment').value" + [filters]="filters" + ></app-structure-print-header> + + <app-structure-detail-print + *ngFor="let structure of structuresToPrint" + [structure]="structure" + ></app-structure-detail-print> + </div> + </div> + </div> + <!-- FOOTER AVEC SUIVANT / PRECEDENT ET VALIDATION --> + <div *ngIf="currentPage == 0" class="footer desktop" fxLayout="column" fxLayoutAlign="space-between"> + <div fxLayout="row" fxLayoutAlign="center center"> + <app-footer-form + [btnName]="['Précédent', 'Suivant']" + (previousPage)="previousUrl()" + (nextPage)="nextPage()" + [isValid]="isPageValid" + ></app-footer-form> + </div> + </div> + <div *ngIf="currentPage != 0 && currentPage != pageTypeEnum.printResults" class="footer desktop"> + <div fxLayout="row" fxLayoutAlign="center center"> + <app-footer-form + [btnName]="['Précédent', 'Suivant']" + (previousPage)="previousPage()" + (nextPage)="nextPage()" + [isValid]="isPageValid" + ></app-footer-form> + </div> + </div> + <div *ngIf="currentPage == pageTypeEnum.printResults" class="footer desktop"> + <div fxLayout="row" fxLayoutAlign="center center"> + <app-footer-form + [btnName]="['Précédent', 'Imprimer']" + (previousPage)="previousPage()" + (nextPage)="runMultiPrint(true)" + [isValid]="isPageValid" + ></app-footer-form> + </div> + </div> +</div> + +<app-structure-list-print + *ngIf="multiPrint" + [structures]="structuresToPrint" + [beneficiaryNeedCommentary]="getOrientationControl('beneficiaryNeedCommentary').value" + [beneficiaryName]="getOrientationControl('beneficiaryName').value" + [structureAccompaniment]="getOrientationControl('structureAccompaniment').value" + [beneficiaryPassNumeric]="getOrientationControl('passNumeric').value" + [contactAccompaniment]="getOrientationControl('contactAccompaniment').value" + [filters]="filters" +></app-structure-list-print> + +<app-structure-details + *ngIf="showStructureDetails" + [structure]="selectedStructure" + (closeDetails)="closeDetails()" +></app-structure-details> diff --git a/src/app/form/orientation-form/orientation-form.component.scss b/src/app/form/orientation-form/orientation-form.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..ced3349a7e0f71253bffb910d2fc989779d24cc5 --- /dev/null +++ b/src/app/form/orientation-form/orientation-form.component.scss @@ -0,0 +1,100 @@ +@import '../../../assets/scss/breakpoint'; +@import '../../../assets/scss/layout'; +@import '../../../assets/scss/z-index'; +@import '../../../assets/scss/color'; +@import '../../../assets/scss/typography'; + +.title { + margin-top: 20px; +} + +.body-wrap { + height: 400px; +} + +.left-pane { + width: 529px; + min-width: 500px; + height: 600px; + overflow: auto; + overflow-x: hidden; + padding: 0 25px 0 0; + @media #{$tablet} { + width: 100%; + min-width: unset; + &.mapPhone { + display: none !important; + } + } +} + +.right-pane { + width: 400px; + max-height: 400px; + padding: 0 16px; + @media #{$tablet} { + display: none; + &.mapPhone { + display: block; + } + width: 100%; + padding: 0; + } +} + +.deep-map ::ng-deep #map { + height: 380px; +} + +.tags-cloud { + font-style: normal; + justify-content: center; + align-items: center; + height: 28px; + border-radius: 20px; + padding: 5px 15px; + color: white; + border-style: none; + margin-top: 15px; + background: #348899; + &.unchecked { + background: #bdbdbd; + } +} + +.titleCateg { + width: 100%; + @include cn-bold-16; + padding: 1.5em; + color: $grey-2; +} + +.titleInfo { + padding: 1em 0; +} + +.inputRow { + height: auto; + .validateIcon { + height: 38px !important; + } + .markerIcon { + height: 38px !important; + cursor: pointer; + } +} + +.nbStructure-panel { + width: 545px; +} + +.nbStructuresLabel { + color: $white; + @include cn-regular-16; + display: grid; + align-items: center; + height: 32px; + background-color: $grey-4; + padding-left: 9px; + width: 100%; +} diff --git a/src/app/form/orientation-form/orientation-form.component.spec.ts b/src/app/form/orientation-form/orientation-form.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..ca358302a5117ff7f9dc736313caf455b27963a2 --- /dev/null +++ b/src/app/form/orientation-form/orientation-form.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { OrientationFormComponent } from './orientation-form.component'; + +describe('OrientationFormComponent', () => { + let component: OrientationFormComponent; + let fixture: ComponentFixture<OrientationFormComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ OrientationFormComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(OrientationFormComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/form/orientation-form/orientation-form.component.ts b/src/app/form/orientation-form/orientation-form.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..83a83bf27a974b65141ea5af1152b2fb40d544eb --- /dev/null +++ b/src/app/form/orientation-form/orientation-form.component.ts @@ -0,0 +1,535 @@ +import { stringify } from '@angular/compiler/src/util'; +import { Component, EventEmitter, HostListener, OnInit, Output } from '@angular/core'; +import { AbstractControl, Form, FormArray, FormControl, FormGroup, Validators } from '@angular/forms'; +import { GeoJson } from '../../map/models/geojson.model'; +import { Address } from '../../models/address.model'; +import { OrientationFormFilters } from '../../models/orientation-filter.object'; +import { Structure } from '../../models/structure.model'; +import { GeojsonService } from '../../services/geojson.service'; +import { RouterListenerService } from '../../services/routerListener.service'; +import { StructureService } from '../../services/structure.service'; +import { CategoryEnum } from '../../shared/enum/category.enum'; +import * as _ from 'lodash'; +import { Category } from '../../structure-list/models/category.model'; +import { Filter } from '../../structure-list/models/filter.model'; +import { Module } from '../../structure-list/models/module.model'; +import { SearchService } from '../../structure-list/services/search.service'; +import { PageTypeEnum } from './pageType.enum'; + +@Component({ + selector: 'app-orientation-form', + templateUrl: './orientation-form.component.html', + styleUrls: ['./orientation-form.component.scss', '../structure-form/form.component.scss'], +}) +export class OrientationFormComponent implements OnInit { + public displayMapMarkerId: string; + public selectedMarkerId: string; + public locate = false; + public noPassNumeric = false; + + public orientationForm: FormGroup; + + // Page and progress var + public currentPage = 0; // Change this value to start on a different page for dev testing + public progressStatus = 0; + public nbPagesForm = 7; + public isPageValid: boolean; + public pagesValidation = []; + + public showStructureDetails = false; + public selectedStructure: Structure; + + // ModalExit var + public showConfirmationModal = false; + private resolve: Function; + + public orientationFormFilters: OrientationFormFilters; + + public pageTypeEnum = PageTypeEnum; + + public numberAssistanceChecked; + public filters: Filter[] = []; + public uncheckedFilters: Filter[] = []; + + public equipments: Module[] = []; + public assistance: Module[] = []; + public formation: Module[] = []; + public baseSkillssReferentiel: Category; + public accessRightsReferentiel: Category; + public digitalCultureSecuritysReferentiel: Category; + public socialAndProfessionalsReferentiel: Category; + public parentingHelpsReferentiel: Category; + + public assistanceReferentiel: Category; + public equipmentReferentiel: Category; + + public specificProfile: Category; + public showEquipments: boolean; + public showAssistance: boolean; + public showFormation: boolean; + + public multiPrint: boolean = false; + + public structuresList: Structure[]; + public structuresToPrint: Structure[] = []; + + constructor( + private routerListener: RouterListenerService, + private searchService: SearchService, + private structureService: StructureService, + private geoJsonService: GeojsonService + ) {} + + ngOnInit(): void { + this.orientationForm = this.createOrientationForm(new OrientationFormFilters()); + this.setValidationsForm(); + this.setCategories(); + } + + private async setCategories(): Promise<void> { + this.searchService.getCategoriesAccompaniment().subscribe((categories: Category[]) => { + this.assistanceReferentiel = categories[0]; + this.assistance = categories[0].modules; + }); + const categs = await this.searchService.getCategoriesTraining().toPromise(); + categs.forEach((categ) => { + categ.modules.forEach((module) => { + this.formation.push(module); + }); + }); + + this.searchService.getCategoriesTraining().subscribe((referentiels) => { + referentiels.forEach((referentiel) => { + if (referentiel.isBaseSkills()) { + this.baseSkillssReferentiel = referentiel; + } else if (referentiel.isRigthtsAccess()) { + this.accessRightsReferentiel = referentiel; + } else if (referentiel.isDigitalCultureSecurity()) { + this.digitalCultureSecuritysReferentiel = referentiel; + } else if (referentiel.isParentingHelp()) { + this.parentingHelpsReferentiel = referentiel; + } else if (referentiel.isSocialAndProfessional()) { + this.socialAndProfessionalsReferentiel = referentiel; + } + }); + }); + + const equipmentsCategs = await this.searchService.getCategoriesMoreFilters().toPromise(); + equipmentsCategs.forEach((categ) => { + if (categ.id == CategoryEnum.equipmentsAndServices) { + categ.modules = this.filterOnlyEquipments(categ.modules); + this.equipmentReferentiel = categ; + categ.modules.forEach((c) => { + this.equipments.push(c); + }); + } + }); + const specificProfileCategs = await this.searchService.getCategoriesMoreFilters().toPromise(); + specificProfileCategs.forEach((categ) => { + switch (categ.id) { + case CategoryEnum.publicsAccompaniment: { + this.specificProfile = categ; + break; + } + } + }); + } + + private createOrientationForm(orientationFormFilters: OrientationFormFilters): FormGroup { + return new FormGroup({ + specificProfile: this.loadArrayForCheckbox([], false), + passNumeric: new FormControl(orientationFormFilters.passNumeric), + equipments: this.loadArrayForCheckbox([], false), + assistance: this.loadArrayForCheckbox([], false), + formation: this.loadArrayForCheckbox([], false), + address: new FormGroup({ + numero: new FormControl(''), + street: new FormControl('', Validators.required), + commune: new FormControl('', Validators.required), + }), + structureAccompaniment: new FormControl(orientationFormFilters.structureAccompaniment, Validators.required), + contactAccompaniment: new FormControl(orientationFormFilters.contactAccompaniment), + beneficiaryName: new FormControl(orientationFormFilters.beneficiaryName), + beneficiaryNeedCommentary: new FormControl(orientationFormFilters.beneficiaryNeedCommentary), + }); + } + + private loadArrayForCheckbox(array: string[], isRequired: boolean): FormArray { + return new FormArray( + array.map((str) => new FormControl(str)), + isRequired ? Validators.required : Validators.nullValidator + ); + } + + public nextPage(): void { + this.searchStructures(); + // Check if going to the last page to submit form and send email verification. + if (this.currentPage === this.nbPagesForm - 1) { + this.validateForm(); + } else { + if ( + this.currentPage === this.pageTypeEnum.beneficiaryNeed && + this.orientationForm.get('assistance').value.length + this.orientationForm.get('formation').value.length == 0 && + this.orientationForm.get('equipments').value.length > 0 + ) { + this.noPassNumeric = true; + this.getOrientationControl('passNumeric').setValue(false); + + this.currentPage++; + this.progressStatus += 100 / this.nbPagesForm; + } + this.currentPage++; + this.progressStatus += 100 / this.nbPagesForm; + this.updatePageValid(); + } + } + + public previousPage(): void { + // Check if going to the first page + if (this.currentPage === 0) { + //go back to home ? previous page + } else { + if (this.currentPage === this.pageTypeEnum.beneficiaryInfo && this.noPassNumeric) { + this.currentPage--; + } + this.currentPage--; + this.progressStatus -= 100 / this.nbPagesForm; + this.updatePageValid(); + } + } + + public validateForm(): void { + if (this.orientationForm.valid) { + //validate form + } + } + + private updatePageValid(): void { + this.isPageValid = this.pagesValidation[this.currentPage].valid; + } + + public previousUrl(): void { + this.routerListener.goToPreviousUrl(); + } + + public setValidationsForm(): void { + this.pagesValidation[PageTypeEnum.beneficiaryNeed] = { + valid: + // this.getOrientationControl('passNumeric').valid && + this.orientationForm.get('equipments').value.length + + this.orientationForm.get('assistance').value.length + + this.orientationForm.get('formation').value.length > + 0, + }; + this.pagesValidation[PageTypeEnum.beneficiaryPassNumeric] = { + valid: this.getOrientationControl('passNumeric').valid, + }; + this.pagesValidation[PageTypeEnum.beneficiaryInfo] = { valid: this.orientationForm.get('address').valid }; + this.pagesValidation[PageTypeEnum.beneficiaryAccompaniment] = { + valid: + this.getOrientationControl('structureAccompaniment').valid && + this.getOrientationControl('contactAccompaniment').valid && + this.getOrientationControl('beneficiaryName').valid, + }; + this.pagesValidation[PageTypeEnum.beneficiaryNeedCommentary] = { + valid: this.getOrientationControl('beneficiaryNeedCommentary').valid, + }; + this.pagesValidation[PageTypeEnum.printResults] = { valid: true }; + this.pagesValidation[PageTypeEnum.structuresSelection] = { valid: this.structuresToPrint.length > 0 }; + + this.updatePageValid(); + } + + public hasRedirectionAccepted(hasAccept: boolean): void { + this.resolve(hasAccept); + this.showConfirmationModal = false; + } + + public getOrientationControl(nameControl: string): AbstractControl { + return this.orientationForm.get(nameControl); + } + public onRadioBtnChange(controlName: string, bool: boolean): void { + this.getOrientationControl(controlName).setValue(bool); + this.setValidationsForm(); + } + + public toggleEquipments(): void { + this.showEquipments = !this.showEquipments; + this.setValidationsForm(); + } + + public toggleAssistance(): void { + this.showAssistance = !this.showAssistance; + this.setValidationsForm(); + } + + public toggleFormation(): void { + this.showFormation = !this.showFormation; + this.setValidationsForm(); + } + + public filterOnlyEquipments(equipmentsAndServices: Module[]): Module[] { + return equipmentsAndServices.filter((eqpt) => + ['ordinateurs', 'imprimantes', 'scanners', 'wifiEnAccesLibre'].includes(eqpt.id) + ); + } + + public isInArray(term: string, formControlName: string): boolean { + if (this.orientationForm.controls[formControlName].value) { + return this.orientationForm.controls[formControlName].value.includes(term); + } + return false; + } + + public updateChoice(choice: string, controlName: string): void { + this.onCheckChange(!this.isInArray(choice, controlName), controlName, choice); + } + + public onCheckChange(event: boolean, formControlName: string, value: string): void { + const formArray: FormArray = this.orientationForm.get(formControlName) as FormArray; + if (event) { + // Add a new control in the arrayForm + formArray.push(new FormControl(value)); + } else { + // Remove uncheck control in the arrayForm + const index = formArray.controls.findIndex((element) => element.value === value); + formArray.removeAt(index); + } + this.setValidationsForm(); + } + + public onProfilChange(event: boolean, formControlName: string): void { + if (event) { + this.orientationForm.get(formControlName).setValue(true); + } else { + this.orientationForm.get(formControlName).setValue(false); + } + this.setValidationsForm(); + } + + public setAddressBeneficiary(address?: Address): void { + if (address) { + this.getOrientationControl('address').get('numero').setValue(address.numero); + this.getOrientationControl('address').get('street').setValue(address.street); + this.getOrientationControl('address').get('commune').setValue(address.commune); + } else { + this.orientationForm.get('address').reset(); + } + this.setValidationsForm(); + } + + public setStructureAccompaniment(structure: string): void { + this.getOrientationControl('structureAccompaniment').setValue(structure); + this.setValidationsForm(); + } + + public setContactAccompaniment(contact: string): void { + this.getOrientationControl('contactAccompaniment').setValue(contact); + this.setValidationsForm(); + } + + public setBeneficiaryName(name: string): void { + this.getOrientationControl('beneficiaryName').setValue(name); + this.setValidationsForm(); + } + + public setBeneficiaryNeedCommentary(comment: string): void { + this.getOrientationControl('beneficiaryNeedCommentary').setValue(comment); + this.setValidationsForm(); + } + + public searchStructures(): void { + this.filters = []; + if (this.orientationForm.value.passNumeric) { + this.filters.push(new Filter('labelsQualifications', 'passNumerique', 'Passe Numérique')); + } + if (this.orientationForm.value.specificProfile) { + this.orientationForm.get('specificProfile').value.forEach((element) => { + this.filters.push(new Filter('publicsAccompaniment', element)); + }); + } + this.orientationForm.get('assistance').value.forEach((element) => { + this.filters.push(new Filter('proceduresAccompaniment', element, this.findAssistanceName(element))); + }); + this.orientationForm.get('equipments').value.forEach((element) => { + this.filters.push(new Filter('equipmentsAndServices', element, this.findEquipmentName(element))); + }); + this.orientationForm.get('formation').value.forEach((element) => { + this.orientationForm.get('formation'); + // Put higher cat like accessRight and so on here + this.filters.push( + new Filter( + this.findTrainingCategoryForSkill(element).categ, + element, + this.findTrainingCategoryForSkill(element).name + ) + ); + }); + + // todo - fix + this.removeDoublonFilters(); + } + + public removeDoublonFilters(): void { + this.uncheckedFilters.map((elem) => { + this.filters = this.filters.filter((filter) => filter.value != elem.value); + }); + this.setStructuresAndCoord(); + } + + public findEquipmentName(equipment): string { + let name; + this.equipmentReferentiel.modules.map((elem) => { + if (elem.id === equipment) { + name = elem.text; + } + }); + return name; + } + + public findAssistanceName(skill): string { + let name; + this.assistanceReferentiel.modules.map((elem) => { + if (elem.id === skill) { + name = elem.text; + } + }); + + return name; + } + + public findTrainingCategoryForSkill(skill): any { + let infos = { categ: '', name: '' }; + this.baseSkillssReferentiel.modules.map((elem) => { + if (elem.id === skill) { + infos.categ = this.baseSkillssReferentiel.id; + infos.name = elem.text; + } + }); + this.accessRightsReferentiel.modules.map((elem) => { + if (elem.id === skill) { + infos.categ = this.accessRightsReferentiel.id; + infos.name = elem.text; + } + }); + this.parentingHelpsReferentiel.modules.map((elem) => { + if (elem.id === skill) { + infos.categ = this.parentingHelpsReferentiel.id; + infos.name = elem.text; + } + }); + this.socialAndProfessionalsReferentiel.modules.map((elem) => { + if (elem.id === skill) { + infos.categ = this.socialAndProfessionalsReferentiel.id; + infos.name = elem.text; + } + }); + this.digitalCultureSecuritysReferentiel.modules.map((elem) => { + if (elem.id === skill) { + infos.categ = this.digitalCultureSecuritysReferentiel.id; + infos.name = elem.text; + } + }); + return infos; + } + + private setStructuresAndCoord(): void { + this.geoJsonService + .getCoord(this.orientationForm.value.address.numero, this.orientationForm.value.address.street, '69000') + .subscribe((res) => { + this.structureService.getStructures(this.filters).subscribe((data) => { + data.map((structure) => { + structure.distance = parseInt( + this.geoJsonService.getDistance( + structure.getLat(), + structure.getLon(), + res.geometry.getLat(), + res.geometry.getLon(), + 'M' + ), + 10 + ); + }); + this.structuresList = data.sort((a, b) => a.distance - b.distance); + }); + }); + } + + public handleCardHover(structure: Structure): void { + this.displayMapMarkerId = structure._id; + } + public mouseLeave(): void { + this.displayMapMarkerId = undefined; + this.structuresToPrint = this.structuresToPrint.slice(); + } + + public addToList(structure: Structure): void { + let index = this.structuresToPrint.findIndex((elem) => elem._id == structure._id); + if (index > -1) { + this.structuresToPrint = this.structuresToPrint.filter((elem) => { + return elem._id != structure._id; + }); + } else { + this.structuresToPrint.push(structure); + } + this.structuresToPrint = this.structuresToPrint.slice(); + this.setValidationsForm(); + } + + public isInPrintList(id: String): boolean { + return this.structuresToPrint.findIndex((elem) => elem._id == id) > -1 ? true : false; + } + + public showDetails(event: Structure): void { + this.showStructureDetails = true; + this.selectedStructure = event; + //TODO Pass marker_id to map component + this.selectedMarkerId = this.selectedStructure._id; + } + + public closeDetails(): void { + this.showStructureDetails = false; + } + + public removeFilter(filter: Filter): void { + this.filters = this.filters.filter((elem) => elem != filter); + this.uncheckedFilters.push(filter); + this.setStructuresAndCoord(); + } + + public restoreFilter(filter: Filter): void { + this.uncheckedFilters = this.uncheckedFilters.filter((elem) => elem != filter); + this.filters.push(filter); + this.setStructuresAndCoord(); + } + + public getAddress(): void { + navigator.geolocation.getCurrentPosition((position) => { + this.geoJsonService.getAddressByCoord(position.coords.longitude, position.coords.latitude).subscribe( + (location) => { + location.properties.housenumber + ? this.getOrientationControl('address').get('numero').setValue(location.properties.housenumber) + : null; + this.getOrientationControl('address').get('street').setValue(location.properties.street); + this.getOrientationControl('address').get('commune').setValue(location.properties.city); + this.setValidationsForm(); + }, + (err) => { + throw new Error(err); + } + ); + }); + } + + public runMultiPrint(event: boolean): void { + this.multiPrint = event; + setTimeout(() => { + window.print(); + }, 1000); + } + + @HostListener('window:afterprint', []) + onWindowAfterPrint() { + this.multiPrint = false; + } +} diff --git a/src/app/form/orientation-form/pageType.enum.ts b/src/app/form/orientation-form/pageType.enum.ts new file mode 100644 index 0000000000000000000000000000000000000000..1a0fc933a378f3b45f4c73b2037cfde20983c050 --- /dev/null +++ b/src/app/form/orientation-form/pageType.enum.ts @@ -0,0 +1,9 @@ +export enum PageTypeEnum { + beneficiaryNeed, + beneficiaryPassNumeric, + beneficiaryInfo, + structuresSelection, + beneficiaryAccompaniment, + beneficiaryNeedCommentary, + printResults, +} diff --git a/src/app/form/form.component.html b/src/app/form/structure-form/form.component.html similarity index 100% rename from src/app/form/form.component.html rename to src/app/form/structure-form/form.component.html diff --git a/src/app/form/form.component.scss b/src/app/form/structure-form/form.component.scss similarity index 97% rename from src/app/form/form.component.scss rename to src/app/form/structure-form/form.component.scss index c17214a051d483e9f3fe747c7fa1273711a0c143..203f6edd61d5a88c84376cff79a20ab058545c37 100644 --- a/src/app/form/form.component.scss +++ b/src/app/form/structure-form/form.component.scss @@ -1,9 +1,9 @@ -@import '../../assets/scss/layout'; -@import '../../assets/scss/breakpoint'; -@import '../../assets/scss/color'; -@import '../../assets/scss/typography'; -@import '../../assets/scss/shapes'; -@import '../../assets/scss/z-index'; +@import '../../../assets/scss/layout'; +@import '../../../assets/scss/breakpoint'; +@import '../../../assets/scss/color'; +@import '../../../assets/scss/typography'; +@import '../../../assets/scss/shapes'; +@import '../../../assets/scss/z-index'; .disabled { opacity: 0.4; diff --git a/src/app/form/form.component.spec.ts b/src/app/form/structure-form/form.component.spec.ts similarity index 98% rename from src/app/form/form.component.spec.ts rename to src/app/form/structure-form/form.component.spec.ts index a3cf40bd4bf5a225beae76d09a25937f1230ea35..665b1baa37b6441a31b69ebc95f2982b3d7635f6 100644 --- a/src/app/form/form.component.spec.ts +++ b/src/app/form/structure-form/form.component.spec.ts @@ -1,7 +1,7 @@ import { HttpClientTestingModule } from '@angular/common/http/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormArray, FormControl, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms'; -import { SharedModule } from '../shared/shared.module'; +import { SharedModule } from '../../shared/shared.module'; import { FormComponent } from './form.component'; diff --git a/src/app/form/form.component.ts b/src/app/form/structure-form/form.component.ts similarity index 97% rename from src/app/form/form.component.ts rename to src/app/form/structure-form/form.component.ts index 21276568cf1007fa76bf05a90e5a75fbf0785d76..93dbede129624581b65a8a18b2206058f72f54eb 100644 --- a/src/app/form/form.component.ts +++ b/src/app/form/structure-form/form.component.ts @@ -1,26 +1,26 @@ import { Component, OnInit } from '@angular/core'; import { AbstractControl, FormArray, FormControl, FormGroup, Validators } from '@angular/forms'; -import { Structure } from '../models/structure.model'; -import { Time } from '../models/time.model'; -import { Day } from '../models/day.model'; -import { StructureService } from '../services/structure.service'; -import { SearchService } from '../structure-list/services/search.service'; -import { Category } from '../structure-list/models/category.model'; -import { CategoryEnum } from '../shared/enum/category.enum'; -import { ProfileService } from '../profile/services/profile.service'; -import { User } from '../models/user.model'; -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 { Structure } from '../../models/structure.model'; +import { Time } from '../../models/time.model'; +import { Day } from '../../models/day.model'; +import { StructureService } from '../../services/structure.service'; +import { SearchService } from '../../structure-list/services/search.service'; +import { Category } from '../../structure-list/models/category.model'; +import { CategoryEnum } from '../../shared/enum/category.enum'; +import { ProfileService } from '../../profile/services/profile.service'; +import { User } from '../../models/user.model'; +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 { ActivatedRoute, Router } from '@angular/router'; -import { AuthService } from '../services/auth.service'; +import { AuthService } from '../../services/auth.service'; import { first } from 'rxjs/operators'; import { PageTypeEnum } from './pageType.enum'; -import { CustomRegExp } from '../utils/CustomRegExp'; -import { StructureWithOwners } from '../models/structureWithOwners.model'; -import { RouterListenerService } from '../services/routerListener.service'; -import { NewsletterService } from '../services/newsletter.service'; +import { CustomRegExp } from '../../utils/CustomRegExp'; +import { StructureWithOwners } from '../../models/structureWithOwners.model'; +import { RouterListenerService } from '../../services/routerListener.service'; +import { NewsletterService } from '../../services/newsletter.service'; @Component({ selector: 'app-structure-form', templateUrl: './form.component.html', diff --git a/src/app/form/pageType.enum.ts b/src/app/form/structure-form/pageType.enum.ts similarity index 100% rename from src/app/form/pageType.enum.ts rename to src/app/form/structure-form/pageType.enum.ts diff --git a/src/app/header/header.component.html b/src/app/header/header.component.html index eafd062767f511334e4b9fe0b5f86bf5ebe47a3a..f763f292d1f689941fda70ad916ff76a651fdcb7 100644 --- a/src/app/header/header.component.html +++ b/src/app/header/header.component.html @@ -18,6 +18,7 @@ <div fxLayout="row" class="right-header" fxLayoutAlign="center center" fxLayoutGap="3vw"> <a routerLink="/news" [routerLinkActive]="'active'" i18n>Actualités</a> <a routerLink="/acteurs" [routerLinkActive]="'active'" i18n>Cartographie des acteurs</a> + <a routerLink="/orientation" [routerLinkActive]="'active'" i18n>Orienter un bénéficiaire</a> <a routerLink="/about" [routerLinkActive]="'active'" i18n>Qui sommes-nous ?</a> <a *ngIf="isAdmin" routerLink="/admin" [routerLinkActive]="'active'">Administration</a> <button *ngIf="isLoggedIn" class="red" routerLink="/profile" [routerLinkActive]="'active'"> @@ -37,6 +38,7 @@ <div fxLayout="column" class="right-header" fxLayoutAlign="none baseline" fxLayoutGap="5vw"> <a routerLink="/news" [routerLinkActive]="'active'" (click)="closeMenu()" i18n>Actualités</a> <a routerLink="/acteurs" [routerLinkActive]="'active'" (click)="closeMenu()" i18n>Cartographie de acteurs</a> + <a routerLink="/orientation" [routerLinkActive]="'active'" i18n>Orienter un bénéficiaire</a> <a routerLink="/about" [routerLinkActive]="'active'" i18n>Qui sommes-nous ?</a> <a *ngIf="isAdmin" routerLink="/admin" [routerLinkActive]="'active'" (click)="closeMenu()">Administration</a> </div> diff --git a/src/app/legal-notice/legal-notice.component.html b/src/app/legal-notice/legal-notice.component.html index a496c40af200a5dd10514c6f7239e91dd9d93a8e..aca06d1cc73d93d3eb318554f3cbba3929fa8ec8 100644 --- a/src/app/legal-notice/legal-notice.component.html +++ b/src/app/legal-notice/legal-notice.component.html @@ -161,18 +161,18 @@ <p> Les bases de données sont protégées par la loi du 1er juillet 1998 et le régime français du droit d'auteur. </p> - <p><strong>Établissements de liens vers le site www.resin.grandlyon.com</strong></p> + <p><strong>Établissements de liens vers le site resin.grandlyon.com</strong></p> <p> - La Métropole de Lyon autorise la mise en place d'un lien hypertexte vers son site www.resin.grandlyon.com pour + La Métropole de Lyon autorise la mise en place d'un lien hypertexte vers son site resin.grandlyon.com pour tous les sites Internet, à l'exclusion de ceux diffusant des informations à caractère polémique, pornographique, xénophobe ou pouvant, dans une plus large mesure porter atteinte à la sensibilité du plus grand - nombre. Le lien doit aboutir à la page d'accueil du site (home page) et le site www.resin.grandlyon.com doit - apparaître dans une nouvelle fenêtre. Les pages du site www.resin.grandlyon.com ne doivent en aucun cas être - intégrées à l'intérieur des pages d'un autre site (Frame). Dans tous les cas d'espèce, la Métropole de - Lyon se réserve le droit de demander la suppression d'un lien si elle estime que le site cible ne respecte pas - les règles ainsi définies. + nombre. Le lien doit aboutir à la page d'accueil du site (home page) et le site resin.grandlyon.com doit + apparaître dans une nouvelle fenêtre. Les pages du site resin.grandlyon.com ne doivent en aucun cas être intégrées + à l'intérieur des pages d'un autre site (Frame). Dans tous les cas d'espèce, la Métropole de Lyon se + réserve le droit de demander la suppression d'un lien si elle estime que le site cible ne respecte pas les + règles ainsi définies. </p> - <p><strong>Liens vers des sites tiers depuis le site www.resin.grandlyon.com</strong></p> + <p><strong>Liens vers des sites tiers depuis le site resin.grandlyon.com</strong></p> <p> Les liens hypertextes mis en œuvre au sein du site en direction d'autres sites et/ou de pages personnelles et d'une manière générale vers toutes ressources existantes sur internet ne sauraient engager la responsabilité diff --git a/src/app/map/components/map.component.scss b/src/app/map/components/map.component.scss index 8134fe5fda885a1e4f7088ef3844dc3e83cf899f..07f80bbd7b20aaa67201d3021b9e9ef940317ba3 100644 --- a/src/app/map/components/map.component.scss +++ b/src/app/map/components/map.component.scss @@ -153,3 +153,7 @@ display: none; } } + +.body-wrap { + height: 400px; +} diff --git a/src/app/map/components/map.component.ts b/src/app/map/components/map.component.ts index 9ca53b1921bcfb3e2a4969fee134a0194153cd09..e432b027e8bab619bbd1aea9443f5e2eacb9a7be 100644 --- a/src/app/map/components/map.component.ts +++ b/src/app/map/components/map.component.ts @@ -18,6 +18,7 @@ import 'leaflet.locatecontrol'; }) export class MapComponent implements OnChanges { @Input() public structures: Structure[] = []; + @Input() public structuresToPrint: Structure[] = []; @Input() public toogleToolTipId: string; @Input() public selectedMarkerId: string; @Input() public isMapPhone: boolean; @@ -80,7 +81,11 @@ export class MapComponent implements OnChanges { // Handle map marker tooltip if (changes.toogleToolTipId && changes.toogleToolTipId.currentValue !== changes.toogleToolTipId.previousValue) { if (changes.toogleToolTipId.previousValue !== undefined) { - this.mapService.setUnactiveMarker(changes.toogleToolTipId.previousValue); + if (this.isToPrint(changes.toogleToolTipId.previousValue)) { + this.mapService.setAddedToListMarker(changes.toogleToolTipId.previousValue); + } else { + this.mapService.setUnactiveMarker(changes.toogleToolTipId.previousValue); + } } if (changes.toogleToolTipId.currentValue !== undefined) { this.mapService.setActiveMarker(changes.toogleToolTipId.currentValue); @@ -97,6 +102,15 @@ export class MapComponent implements OnChanges { this.centerLeafletMapOnMarker(changes.selectedMarkerId.currentValue); } } + + if (changes.structuresToPrint) { + if (changes.structuresToPrint.currentValue < changes.structuresToPrint.previousValue) { + this.mapService.setUnactiveMarker(this.toogleToolTipId); + } + this.structuresToPrint.forEach((structure: Structure) => { + this.mapService.setAddedToListMarker(structure._id); + }); + } } public processTownCoordinate(queryString: string): void { @@ -130,6 +144,10 @@ export class MapComponent implements OnChanges { } } + private isToPrint(id: String): boolean { + return this.structuresToPrint.findIndex((elem) => elem._id == id) > -1 ? true : false; + } + private getStructuresPositions(structureList: Structure[]): void { structureList.forEach((structure: Structure) => { this.mapService diff --git a/src/app/map/services/map.service.ts b/src/app/map/services/map.service.ts index 5918d6a5bd1b49eecb9d62e221d9bdab51a49276..9657aac8411ff2321d03b4d2fbf6fe325e6f626e 100644 --- a/src/app/map/services/map.service.ts +++ b/src/app/map/services/map.service.ts @@ -19,6 +19,14 @@ export class MapService { iconAnchor: [20, 46], popupAnchor: [0, -46], }); + public markerIconAddedToList = divIcon({ + className: null, + html: + '<svg width="40" height="46" fill="#47C562" stroke="#fff" stroke-width="2"><use xlink:href="assets/ico/sprite.svg#map-marker-added"></use></svg>', + iconSize: [40, 46], + iconAnchor: [20, 46], + popupAnchor: [0, -46], + }); public markerIcon = divIcon({ className: null, html: @@ -80,6 +88,10 @@ export class MapService { this.getMarker(id).setIcon(this.markerIconActive); } + public setAddedToListMarker(id: string): void { + this.getMarker(id).setIcon(this.markerIconAddedToList); + } + public setUnactiveMarker(id: string): void { // To skip mouseleave when user emit click on structure list if (!this.isMarkerActive) { diff --git a/src/app/models/orientation-filter.object.ts b/src/app/models/orientation-filter.object.ts new file mode 100644 index 0000000000000000000000000000000000000000..48a52e4acdcc4aab2dbff383d92d2c39ae3e880c --- /dev/null +++ b/src/app/models/orientation-filter.object.ts @@ -0,0 +1,14 @@ +import { Category } from '../structure-list/models/category.model'; +import { Module } from '../structure-list/models/module.model'; +import { Address } from './address.model'; + +export class OrientationFormFilters { + specificProfile: Category; + handicap: boolean; + passNumeric: boolean; + structureAccompaniment: string; + contactAccompaniment: string; + beneficiaryName: string; + beneficiaryNeedCommentary: string; + address: Address; +} diff --git a/src/app/shared/components/address-autocomplete/address-autocomplete.component.scss b/src/app/shared/components/address-autocomplete/address-autocomplete.component.scss index 0c455c90caf7fd72087d89f14c0440c31e2de2a3..5332c145cb11cf5860f2f4310615eb147dd4b472 100644 --- a/src/app/shared/components/address-autocomplete/address-autocomplete.component.scss +++ b/src/app/shared/components/address-autocomplete/address-autocomplete.component.scss @@ -8,6 +8,7 @@ border: 0.0625rem solid #d4d4d4; border-top: none; border-bottom: none; + max-width: 294px; z-index: 99; background-color: #fff; cursor: pointer; diff --git a/src/app/shared/components/address-autocomplete/address-autocomplete.component.ts b/src/app/shared/components/address-autocomplete/address-autocomplete.component.ts index e04af8369835b9022f41bad9143b2c680460b379..8670ecc1f3133fb1ce73723f9b0319f14d7fab13 100644 --- a/src/app/shared/components/address-autocomplete/address-autocomplete.component.ts +++ b/src/app/shared/components/address-autocomplete/address-autocomplete.component.ts @@ -29,6 +29,19 @@ export class AddressAutocompleteComponent implements OnInit { this.searchAddress.nativeElement.value = address_str; } } + + ngOnChanges(): void { + if (this.address) { + let address_str = null; + if (this.address.numero) { + address_str = this.address.numero + ' ' + this.address.street + ' ' + this.address.commune; + } else { + address_str = this.address.street + ' ' + this.address.commune; + } + this.searchAddress.nativeElement.value = address_str; + } + } + public onSearchChange(searchString: string) { if (!this.isAlreadySearching) { this.isAlreadySearching = true; diff --git a/src/app/shared/components/radio-form/radio-form.component.html b/src/app/shared/components/radio-form/radio-form.component.html index 42570b7d703df7efdd97b4cc47e656e9f7152700..b120dde996625149911f38e0edf33c54482ad4e8 100644 --- a/src/app/shared/components/radio-form/radio-form.component.html +++ b/src/app/shared/components/radio-form/radio-form.component.html @@ -1,28 +1,30 @@ -<button - (click)="clicked(true)" - [ngClass]="{ selected: selectedOption && selectedOption != null }" - fxLayout="row" - fxLayoutAlign=" center" - fxLayoutGap="17px" -> - <div class="checkmark"> - <svg class="validate" aria-hidden="true"> - <use [attr.xlink:href]="'assets/form/sprite.svg#checkVector'"></use> - </svg> - </div> - <p>Oui</p> -</button> -<button - (click)="clicked(false)" - [ngClass]="{ selected: !selectedOption && selectedOption != null }" - fxLayout="row" - fxLayoutAlign=" center" - fxLayoutGap="17px" -> - <div class="checkmark"> - <svg class="validate" aria-hidden="true"> - <use [attr.xlink:href]="'assets/form/sprite.svg#checkVector'"></use> - </svg> - </div> - <p>Non</p> -</button> +<div [fxLayout]="horizontal ? 'row' : 'column'" [fxLayoutGap]="horizontal ? '17px' : ''"> + <button + (click)="clicked(true)" + [ngClass]="{ selected: selectedOption && selectedOption != null }" + fxLayout="row" + fxLayoutAlign=" center" + fxLayoutGap="17px" + > + <div class="checkmark"> + <svg class="validate" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#checkVector'"></use> + </svg> + </div> + <p>Oui</p> + </button> + <button + (click)="clicked(false)" + [ngClass]="{ selected: !selectedOption && selectedOption != null }" + fxLayout="row" + fxLayoutAlign=" center" + fxLayoutGap="17px" + > + <div class="checkmark"> + <svg class="validate" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#checkVector'"></use> + </svg> + </div> + <p>Non</p> + </button> +</div> diff --git a/src/app/shared/components/radio-form/radio-form.component.ts b/src/app/shared/components/radio-form/radio-form.component.ts index e0ccbd6cfe7bf62b3f293332da1351ded7df8ef4..84075f64f44017d666e4867ff124654b35ec927e 100644 --- a/src/app/shared/components/radio-form/radio-form.component.ts +++ b/src/app/shared/components/radio-form/radio-form.component.ts @@ -9,6 +9,7 @@ export class RadioFormComponent implements OnInit { constructor() {} @Input() public selectedOption: boolean; + @Input() public horizontal: boolean; @Output() selectedEvent: EventEmitter<boolean> = new EventEmitter<boolean>(); ngOnInit(): void {} diff --git a/src/app/shared/service/print.service.ts b/src/app/shared/service/print.service.ts index f34fa8c2941862aed41f53c4568c522258033b9a..115614975ab825878c8f0f1c6a8205bdad81a8d2 100644 --- a/src/app/shared/service/print.service.ts +++ b/src/app/shared/service/print.service.ts @@ -8,6 +8,7 @@ import { Structure } from '../../models/structure.model'; export class PrintService { public isPrinting = false; public structure: Structure; + public structures: Structure[]; constructor(private router: Router) {} @@ -24,6 +25,19 @@ export class PrintService { ]); } + public printDocuments(documentName: string, structures: Structure[]): void { + this.isPrinting = true; + this.structures = structures; + this.router.navigate([ + '/', + { + outlets: { + print: ['print', documentName], + }, + }, + ]); + } + public onDataReady(): void { setTimeout(() => { window.print(); diff --git a/src/app/structure-list/components/card/card.component.html b/src/app/structure-list/components/card/card.component.html index bf5ea36b4dcd3528839ded34e6fbc8455e767ffb..bfe44fd1aa4821884d0784b90fa9fc3b415361bf 100644 --- a/src/app/structure-list/components/card/card.component.html +++ b/src/app/structure-list/components/card/card.component.html @@ -5,9 +5,26 @@ <span class="typeStructure">{{ structure.getLabelTypeStructure() }}</span> </div> <div class="distanceStructure" fxLayout="column" fxLayoutAlign="none end"> - <div> + <div *ngIf="!isOrientation"> {{ this.structure.address.commune }} </div> + <div + fxLayout="row" + *ngIf="isOrientation && !isSelected" + class="selection-button selected" + (click)="cardAddToList(); $event.stopPropagation()" + > + <app-svg-icon [type]="'ico'" [icon]="'add'" [iconColor]="'black'"></app-svg-icon>ajouter à la liste + </div> + <div + fxLayout="row" + *ngIf="isOrientation && isSelected" + class="selection-button to-select" + (click)="cardAddToList(); $event.stopPropagation()" + > + <app-svg-icon [type]="'ico'" [icon]="'validate'" [iconColor]="'white'"></app-svg-icon> + retirer de la liste + </div> <div *ngIf="structure.distance"> {{ this.formatDistance() }} </div> diff --git a/src/app/structure-list/components/card/card.component.scss b/src/app/structure-list/components/card/card.component.scss index 3ce975805e5d8c218600f1125d2e44a6329cf4bc..7b5fb40ae91f94ee499af869a86bd2cbc5be9814 100644 --- a/src/app/structure-list/components/card/card.component.scss +++ b/src/app/structure-list/components/card/card.component.scss @@ -34,3 +34,28 @@ border-bottom: none; } } + +.selection-button { + font-style: normal; + font-weight: bold; + justify-content: center; + align-items: center; + min-width: 180px; + height: 30px; + border-radius: 20px; + padding: 3px 10px; + margin-bottom: 10px; +} + +.selected { + border-style: solid; + border-width: 2px; + background-color: $white; + border-color: $black; + color: $black; +} +.to-select { + color: white; + border-style: none; + background: #47c562; +} diff --git a/src/app/structure-list/components/card/card.component.ts b/src/app/structure-list/components/card/card.component.ts index 8a1b657e1851ff7c44558373391bea4b6ee73ee9..12e3d46d281c85075158442ab8f64351fb8e8248 100644 --- a/src/app/structure-list/components/card/card.component.ts +++ b/src/app/structure-list/components/card/card.component.ts @@ -11,7 +11,10 @@ import { StructureService } from '../../../services/structure.service'; }) export class CardComponent implements OnInit { @Input() public structure: Structure; + @Input() public isSelected: boolean; + @Input() public isOrientation: boolean; @Output() public showDetails: EventEmitter<Structure> = new EventEmitter<Structure>(); + @Output() public addToList: EventEmitter<Structure> = new EventEmitter<Structure>(); @Output() public hover: EventEmitter<Structure> = new EventEmitter<Structure>(); public isClaimed = true; @@ -45,23 +48,29 @@ export class CardComponent implements OnInit { public cardClicked(): void { this.showDetails.emit(this.structure); - const queryString = this.route.snapshot.queryParamMap.get('search'); - this.router.navigate([], { - relativeTo: this.route, - queryParams: queryString - ? { - id: this.structure._id, - search: queryString, - } - : { - id: this.structure._id, - }, - }); + if (!this.isOrientation) { + const queryString = this.route.snapshot.queryParamMap.get('search'); + this.router.navigate([], { + relativeTo: this.route, + queryParams: queryString + ? { + id: this.structure._id, + search: queryString, + } + : { + id: this.structure._id, + }, + }); + } } public cardHover(): void { this.hover.emit(this.structure); } + + public cardAddToList(): void { + this.addToList.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/modal-filter/modal-filter.component.ts b/src/app/structure-list/components/modal-filter/modal-filter.component.ts index a7df06d0544ba88a61c959686408beebab205075..f48250843c5779a0c98a6fa36d676eeb75ac1209 100644 --- a/src/app/structure-list/components/modal-filter/modal-filter.component.ts +++ b/src/app/structure-list/components/modal-filter/modal-filter.component.ts @@ -26,6 +26,7 @@ export class ModalFilterComponent implements OnInit { // Management of the checkbox event (Check / Uncheck) public onCheckboxChange(event, categ: string): void { const checkValue: string = event.target.value; + console.log(checkValue); if (event.target.checked) { this.checkedModules.push(new Module(checkValue, categ)); } else { 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 330d79cc04137a44f08737c4067991342fbf9e21..5ccbc64f40a8bfc410b34233d07bbc201da618bb 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 @@ -130,12 +130,18 @@ export class StructureDetailsComponent implements OnInit { } public close(): void { - this.router.navigate(['/acteurs'], { - relativeTo: this.route, - queryParams: { - id: null, - }, - queryParamsHandling: 'merge', + this.route.url.subscribe((urls) => { + if (urls[0].path != 'orientation') { + this.router.navigate(['/acteurs'], { + relativeTo: this.route, + queryParams: { + id: null, + }, + queryParamsHandling: 'merge', + }); + } else { + this.closeDetails.emit(); + } }); } diff --git a/src/app/structure-list/models/filter.model.ts b/src/app/structure-list/models/filter.model.ts index 6cf52358a2ad88c4603a61c4ff5d791ab62f042a..9ca53612448c628b8a1b18cfe2514e5cd4e591e3 100644 --- a/src/app/structure-list/models/filter.model.ts +++ b/src/app/structure-list/models/filter.model.ts @@ -1,9 +1,11 @@ export class Filter { name: string; value: string; + text?: string; - constructor(name: string, value: any) { + constructor(name: string, value: any, text?: string) { this.name = name; this.value = value.toString(); + this.text = text; } } diff --git a/src/assets/form/sprite.svg b/src/assets/form/sprite.svg index b74897efc944d573d27ce7b9e9e7b28d7be1ef24..6c117f45273f62b4d5cb533e844383c32b8a3fbf 100644 --- a/src/assets/form/sprite.svg +++ b/src/assets/form/sprite.svg @@ -355,5 +355,24 @@ <path d="M75.2275 24.3398C75.2275 23.2353 74.3321 22.3398 73.2275 22.3398C72.123 22.3398 71.2275 23.2353 71.2275 24.3398H75.2275ZM73.2275 73.8398H71.2275C71.2275 74.4855 71.5392 75.0914 72.0645 75.4669L73.2275 73.8398ZM94.4205 91.4476C95.3191 92.0899 96.5683 91.8822 97.2106 90.9836C97.853 90.085 97.6452 88.8358 96.7466 88.1935L94.4205 91.4476ZM71.2275 24.3398V73.8398H75.2275V24.3398H71.2275ZM72.0645 75.4669L94.4205 91.4476L96.7466 88.1935L74.3906 72.2128L72.0645 75.4669Z" fill="#DC2A59"/> </symbol> +<symbol id="allophone" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 38 38"> + <path stroke="none" d="M33.896 6.667H19.25a.79.79 0 00-.244.038l-.185.062a.77.77 0 00-.488.975l.003.007 7.748 22.642-5.103 5.83a.771.771 0 00.581 1.279h12.334a3.854 3.854 0 003.854-3.854V10.52a3.854 3.854 0 00-3.854-3.854z" fill="#fff"></path> + <path stroke="none" fill-rule="evenodd" clip-rule="evenodd" d="M21.562 37.5h12.334a3.854 3.854 0 003.854-3.854V10.52a3.854 3.854 0 00-3.854-3.854H19.25a.79.79 0 00-.244.038l-.185.062a.77.77 0 00-.488.975l.003.007 7.748 22.642-5.103 5.83a.771.771 0 00.581 1.279zm.505-1h11.829a2.854 2.854 0 002.854-2.854V10.52a2.854 2.854 0 00-2.854-2.854H19.364l7.854 22.948-5.151 5.885z" fill="#4F4F4F"></path> + <path stroke="none" d="M27.66 30.243a.77.77 0 00-.702-.451H19.25a.771.771 0 00-.721 1.042L20.84 37a.77.77 0 001.301.235l5.396-6.166a.77.77 0 00.122-.827z" fill="#117083"></path> + <path stroke="none" d="M33.896 17.458H23.104a.77.77 0 010-1.541h10.792a.77.77 0 010 1.541z" fill="#4F4F4F"></path> + <path stroke="none" d="M27.73 17.458a.77.77 0 01-.772-.77v-1.542a.77.77 0 111.542 0v1.541a.77.77 0 01-.77.771zm-2.313 9.25a.77.77 0 01-.448-1.398c3.377-2.399 5.843-7.289 5.843-8.622a.771.771 0 011.542 0c0 2.031-2.97 7.378-6.49 9.877a.77.77 0 01-.447.143z" fill="#4F4F4F"></path> + <path stroke="none" d="M31.583 28.25a.77.77 0 01-.52-.202c-.559-.512-5.486-5.063-6.36-7.216a.771.771 0 011.429-.582c.63 1.554 4.526 5.334 5.974 6.659a.77.77 0 01-.523 1.341z" fill="#4F4F4F"></path> + <path stroke="none" d="M27.688 30.313L17.666 1.02a.77.77 0 00-.73-.521H4.604A3.854 3.854 0 00.75 4.354V27.48a3.854 3.854 0 003.854 3.854h22.354a.77.77 0 00.73-1.02z" fill="#348899"></path> + <path stroke="none" d="M15.396 22.083a.77.77 0 01-.726-.511l-3.128-8.76-3.128 8.76a.77.77 0 01-1.451-.518l3.854-10.792a.802.802 0 011.45 0l3.855 10.791a.77.77 0 01-.726 1.03z" fill="#FAFAFA"></path> + <path stroke="none" d="M13.083 17.458H10a.77.77 0 010-1.541h3.083a.77.77 0 110 1.541z" fill="#FAFAFA"></path> +</symbol> + +<symbol id="handicap" viewBox="0 0 38 38" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M14.6842 7.66864C16.614 7.66864 18.1784 6.06389 18.1784 4.08432C18.1784 2.10475 16.614 0.5 14.6842 0.5C12.7545 0.5 11.1901 2.10475 11.1901 4.08432C11.1901 6.06389 12.7545 7.66864 14.6842 7.66864Z" fill="#348899"/> +<path stroke="none" d="M11.0934 16.9949C10.829 17.0917 10.5701 17.202 10.3177 17.3252C7.53826 18.6817 5.55162 21.5888 5.42994 25.0418C5.25658 29.9618 8.92462 34.0264 13.5426 34.1976C17.3702 34.3395 20.7328 31.7703 21.8737 28.0773L26.3538 29.5417C24.6038 35.2066 19.4074 39.2554 13.3723 39.0317C6.09047 38.7617 0.467055 32.3856 0.731958 24.8677C0.918664 19.5689 3.97543 15.0672 8.30382 12.9548C8.69872 12.7621 9.10428 12.5891 9.51938 12.4373L11.0934 16.9949Z" fill="#333333"/> +<path d="M17.1672 10.9313C17.016 9.60345 15.8455 8.65494 14.5527 8.81268C13.6717 8.9202 12.9613 9.51373 12.646 10.3012C12.4923 10.5803 12.4335 10.897 12.4695 11.2047C12.469 11.303 12.4743 11.4025 12.4857 11.5026L13.7476 22.5855C13.8759 23.7123 14.749 24.595 15.8478 24.7088L26.2094 25.7814L29.5025 33.4144C30.0295 34.6361 31.4215 35.1857 32.6117 34.6419C33.8018 34.0983 34.3393 32.6672 33.8122 31.4455L29.9653 22.5289C29.6229 21.7351 28.8923 21.1915 28.051 21.1044L18.2096 20.0856L17.8595 17.0114L18.0599 17.21L19.0954 16.1816L18.0599 17.21C18.4504 17.5973 18.9639 17.8388 19.5137 17.8938L23.7649 18.3188C24.6044 18.4027 25.3548 17.7952 25.4409 16.9619C25.527 16.1286 24.9163 15.3851 24.0767 15.3012L20.0573 14.8993L17.3087 12.1738L17.1672 10.9313Z" fill="#348899"/> +</symbol> + </svg> + diff --git a/src/assets/ico/delete.svg b/src/assets/ico/delete.svg new file mode 100644 index 0000000000000000000000000000000000000000..ccb00408b71e48732d4544b7c53164b4a6dfdc7b --- /dev/null +++ b/src/assets/ico/delete.svg @@ -0,0 +1,3 @@ +<svg width="12" height="11" viewBox="0 0 12 11" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M11.0992 0.367228C10.7086 -0.0232964 10.0755 -0.0232962 9.68495 0.367228L6.14941 3.90276L2.61388 0.367228C2.22336 -0.0232967 1.59019 -0.0232967 1.19967 0.367228C0.809143 0.757752 0.809143 1.39092 1.19967 1.78144L4.7352 5.31698L1.19967 8.85251C0.809143 9.24303 0.809142 9.8762 1.19967 10.2667C1.59019 10.6572 2.22336 10.6572 2.61388 10.2667L6.14941 6.73119L9.68495 10.2667C10.0755 10.6572 10.7086 10.6572 11.0992 10.2667C11.4897 9.8762 11.4897 9.24303 11.0992 8.85251L7.56363 5.31698L11.0992 1.78144C11.4897 1.39092 11.4897 0.757752 11.0992 0.367228Z" fill="white"/> +</svg> diff --git a/src/assets/ico/mapMarkerAdded.svg b/src/assets/ico/mapMarkerAdded.svg new file mode 100644 index 0000000000000000000000000000000000000000..43476e7f0aa40b1e85e7a9211bd4dbb135f701b7 --- /dev/null +++ b/src/assets/ico/mapMarkerAdded.svg @@ -0,0 +1,5 @@ +<svg width="49" height="48" viewBox="0 0 49 48" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M24.2664 45.7307L24.9731 46.391L25.6566 45.7067C27.6947 43.6665 29.6963 41.8435 31.5902 40.1188L31.7691 39.9559C38.0892 34.201 43.3939 29.3707 43.3939 21.463C43.3939 11.2671 35.1369 3 24.9491 3C14.7614 3 6.50439 11.2671 6.50439 21.463C6.50439 25.615 7.58413 28.6957 9.68328 31.6153C11.7242 34.454 14.7328 37.1381 18.5168 40.514L18.5946 40.5834C20.3118 42.1155 22.2016 43.8015 24.2664 45.7307Z" fill="#47C562" stroke="white" stroke-width="2"/> +<path d="M24.9487 31.4971C30.4716 31.4971 34.9487 27.0199 34.9487 21.4971C34.9487 15.9742 30.4716 11.4971 24.9487 11.4971C19.4259 11.4971 14.9487 15.9742 14.9487 21.4971C14.9487 27.0199 19.4259 31.4971 24.9487 31.4971Z" fill="white"/> +<path d="M20.1143 21.9233L24.0031 25.0483L30.1143 18.1733" stroke="#47C562" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> +</svg> diff --git a/src/assets/ico/sprite.svg b/src/assets/ico/sprite.svg index a8f21b0b4bfe20ff720b5863195a7fe7d46ebe8a..5fa4fc95c046d8879b07488c84be94810cdcbe7f 100644 --- a/src/assets/ico/sprite.svg +++ b/src/assets/ico/sprite.svg @@ -42,6 +42,15 @@ <path d="M12 5C11.4477 5 11 5.44772 11 6V11H6C5.44772 11 5 11.4477 5 12C5 12.5523 5.44772 13 6 13H11V18C11 18.5523 11.4477 19 12 19C12.5523 19 13 18.5523 13 18V13H18C18.5523 13 19 12.5523 19 12C19 11.4477 18.5523 11 18 11H13V6C13 5.44772 12.5523 5 12 5Z" stroke="none"/> </symbol> +<symbol id="validate" fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> +<path d="M6.5 12.344l4.278 3.437L17.5 8.22" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path> +</symbol> + +<symbol id="delete" viewBox="0 0 27 17" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M18.0992 4.36723C17.7086 3.9767 17.0755 3.9767 16.6849 4.36723L13.1494 7.90276L9.61388 4.36723C9.22336 3.9767 8.59019 3.9767 8.19967 4.36723C7.80914 4.75775 7.80914 5.39092 8.19967 5.78144L11.7352 9.31698L8.19967 12.8525C7.80914 13.243 7.80914 13.8762 8.19967 14.2667C8.59019 14.6572 9.22336 14.6572 9.61388 14.2667L13.1494 10.7312L16.6849 14.2667C17.0755 14.6572 17.7086 14.6572 18.0992 14.2667C18.4897 13.8762 18.4897 13.243 18.0992 12.8525L14.5636 9.31698L18.0992 5.78144C18.4897 5.39092 18.4897 4.75775 18.0992 4.36723Z" fill="white"/> +</symbol> + + <symbol id="remove" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> <path d="M6.97363 12.9062C6.34733 12.9062 5.89876 12.7877 5.62793 12.5507C5.36556 12.3053 5.23438 11.9879 5.23438 11.5986C5.23438 11.2092 5.36556 10.8961 5.62793 10.6591C5.89876 10.4137 6.34733 10.2952 6.97363 10.3036C14.44 10.3036 10.571 10.3036 17.0156 10.3036C17.6419 10.3036 18.0863 10.4221 18.3486 10.6591C18.6195 10.8961 18.7549 11.2092 18.7549 11.5986C18.7549 11.9879 18.6195 12.3053 18.3486 12.5507C18.0863 12.7877 17.6419 12.9062 17.0156 12.9062C9.63742 12.9062 13.3678 12.9062 6.97363 12.9062Z" stroke="none"/> </symbol> @@ -273,5 +282,23 @@ <circle cx="49.5" cy="56.5" r="10.5" fill="#BDBDBD"/> </symbol> +<symbol id="map-marker-added" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg"> +<path d="M24.2664 45.7307L24.9731 46.391L25.6566 45.7067C27.6947 43.6665 29.6963 41.8435 31.5902 40.1188L31.7691 39.9559C38.0892 34.201 43.3939 29.3707 43.3939 21.463C43.3939 11.2671 35.1369 3 24.9491 3C14.7614 3 6.50439 11.2671 6.50439 21.463C6.50439 25.615 7.58413 28.6957 9.68328 31.6153C11.7242 34.454 14.7328 37.1381 18.5168 40.514L18.5946 40.5834C20.3118 42.1155 22.2016 43.8015 24.2664 45.7307Z" fill="#47C562" stroke="white" stroke-width="2"/> +<path d="M24.9487 31.4971C30.4716 31.4971 34.9487 27.0199 34.9487 21.4971C34.9487 15.9742 30.4716 11.4971 24.9487 11.4971C19.4259 11.4971 14.9487 15.9742 14.9487 21.4971C14.9487 27.0199 19.4259 31.4971 24.9487 31.4971Z" fill="white"/> +<path d="M20.1143 21.9233L24.0031 25.0483L30.1143 18.1733" stroke="#47C562" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> +</symbol> + +<symbol id="locateMe" width="25" height="34" viewBox="0 0 24 27" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M15.5591 23.2986C19.8303 19.413 23.125 16.4157 23.125 11.5C23.125 5.14873 17.9763 0 11.625 0C5.27373 0 0.125 5.14873 0.125 11.5C0.125 16.6933 2.79938 19.0768 7.87479 23.6001C9.00649 24.6087 10.2576 25.7237 11.625 27C12.9811 25.6439 14.3117 24.4334 15.5591 23.2986ZM11.625 16C14.1103 16 16.125 13.9853 16.125 11.5C16.125 9.01472 14.1103 7 11.625 7C9.13972 7 7.125 9.01472 7.125 11.5C7.125 13.9853 9.13972 16 11.625 16Z" fill="#828282"/> +</symbol> + +<symbol id="passNumeric" width="25" height="45" viewBox="0 0 38 38" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M1.875 9.49658H35.875V14.8452C34.0229 15.5776 32.7128 17.3841 32.7128 19.4966C32.7128 21.6091 34.0229 23.4157 35.875 24.148V29.4966H1.875V24.148C3.72706 23.4157 5.03717 21.6091 5.03717 19.4966C5.03717 17.3841 3.72706 15.5776 1.875 14.8452V9.49658Z" fill="white"/> +<path d="M35.875 9.49658H36.525C36.525 9.1376 36.234 8.84658 35.875 8.84658V9.49658ZM1.875 9.49658V8.84658C1.51601 8.84658 1.225 9.1376 1.225 9.49658H1.875ZM35.875 14.8452L36.114 15.4497C36.3621 15.3516 36.525 15.1119 36.525 14.8452H35.875ZM35.875 24.148H36.525C36.525 23.8813 36.3621 23.6417 36.114 23.5436L35.875 24.148ZM35.875 29.4966V30.1466C36.234 30.1466 36.525 29.8556 36.525 29.4966H35.875ZM1.875 29.4966H1.225C1.225 29.8556 1.51601 30.1466 1.875 30.1466L1.875 29.4966ZM1.875 24.148L1.63598 23.5436C1.38794 23.6417 1.225 23.8813 1.225 24.148H1.875ZM1.875 14.8452H1.225C1.225 15.1119 1.38794 15.3516 1.63598 15.4497L1.875 14.8452ZM35.875 8.84658H1.875V10.1466H35.875V8.84658ZM36.525 14.8452V9.49658H35.225V14.8452H36.525ZM33.3628 19.4966C33.3628 17.6598 34.5016 16.0873 36.114 15.4497L35.636 14.2407C33.5443 15.0679 32.0628 17.1084 32.0628 19.4966H33.3628ZM36.114 23.5436C34.5016 22.906 33.3628 21.3335 33.3628 19.4966H32.0628C32.0628 21.8848 33.5443 23.9254 35.636 24.7525L36.114 23.5436ZM36.525 29.4966V24.148H35.225V29.4966H36.525ZM1.875 30.1466H35.875V28.8466H1.875V30.1466ZM1.225 24.148V29.4966H2.525V24.148H1.225ZM4.38717 19.4966C4.38717 21.3335 3.24841 22.906 1.63598 23.5436L2.11402 24.7525C4.20571 23.9254 5.68717 21.8848 5.68717 19.4966H4.38717ZM1.63598 15.4497C3.24841 16.0873 4.38717 17.6597 4.38717 19.4966H5.68717C5.68717 17.1084 4.20571 15.0679 2.11402 14.2407L1.63598 15.4497ZM1.225 9.49658V14.8452H2.525V9.49658H1.225Z" fill="#4F4F4F"/> +<line x1="28.6031" y1="10.1466" x2="28.6031" y2="28.8466" stroke="#4F4F4F" stroke-width="1.3" stroke-linecap="round" stroke-dasharray="2 3"/> +<line x1="10.0176" y1="19.9287" x2="20.0176" y2="19.9287" stroke="#348899" stroke-width="2" stroke-linecap="round"/> +<line x1="10.0176" y1="24.9287" x2="16.0176" y2="24.9287" stroke="#348899" stroke-width="2" stroke-linecap="round"/> +</symbol> + </svg> diff --git a/src/index.html b/src/index.html index 6649c5b9e5144d03844caedc88786e90c385b515..19f2458a1b22bfa974f666c111397e8ecf7f63bf 100644 --- a/src/index.html +++ b/src/index.html @@ -5,7 +5,7 @@ <!-- COMMON TAGS --> <meta charset="utf-8" /> - <title>Réseau des Acteurs de la Médiation</title> + <title>Réseau des Acteurs de l'Inclusion Numérique de la Métropole de Lyon</title> <!-- Search Engine --> <meta name="title" content="Réseau des acteurs de la médiation numérique" />