diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a26c75de8187a47ae38d200b3551943d02d4d5b..f18a921dc9c661196efd4299a7464153d01b454e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,30 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [1.6.0](https://forge.grandlyon.com///compare/v1.5.0...v1.6.0) (2021-03-15) + + +### Features + +* add jpg logo for mail ([431a07f](https://forge.grandlyon.com///commit/431a07fd8324099f0ecf22af102f7b52c1a0f1ff)) +* **post:** fix design html ([78d7e6c](https://forge.grandlyon.com///commit/78d7e6c50e4ceac4e2a902bb5747ee78db1db151)) + + +### Bug Fixes + +* bug on admin validation ([05a578b](https://forge.grandlyon.com///commit/05a578b79e3194e78b8ec6536a038c1775a3615d)) +* filter chevron margin + add structure link width ([012a5f0](https://forge.grandlyon.com///commit/012a5f0f17dbc28d5d57d8f80c4fd8746ad353ca)) +* header name display + address-autocomplete bug ([3827b09](https://forge.grandlyon.com///commit/3827b09673684feee871b939b4d104c24282052e)) +* remove commented code ([5b6c51e](https://forge.grandlyon.com///commit/5b6c51e73c7a9c24f28f5a5a36c829411bca3d5e)) +* remove consolelog ([bf474b7](https://forge.grandlyon.com///commit/bf474b7e0afe053b521420cbef63877a187725b3)) +* remove profil picture from profil page ([24a2f9f](https://forge.grandlyon.com///commit/24a2f9f7a1e7a4e48bfd3a7291d60ee62b6bd1b0)) +* search title ([e739dec](https://forge.grandlyon.com///commit/e739decf8fa52b3d47304ef2503031afaef1db9f)) +* temp hide of news features ([0ce9fb5](https://forge.grandlyon.com///commit/0ce9fb5c95a29ea800ccc96b88aaeefbf6504a3b)) +* update logo ([26e9943](https://forge.grandlyon.com///commit/26e9943f9c38e80e05be9cdb5a684259c5143662)) +* use profileImage attribute for profile picture ([7ac3511](https://forge.grandlyon.com///commit/7ac35111081af41bc95d072956dbe165b6397b07)) +* **task:** fix only first letter Upper on structure name ([5a29be5](https://forge.grandlyon.com///commit/5a29be5d857b9899af3532bed57cc4ac240ea153)) +* **task:** fix public name ([284c002](https://forge.grandlyon.com///commit/284c0024c7682acb4d40eb8fa34a5f09b033d29f)) + ## [1.5.0](https://forge.grandlyon.com///compare/v1.4.0...v1.5.0) (2021-02-25) diff --git a/package-lock.json b/package-lock.json index cb903debf0cb4efcac23e87d6aa7c8ccfc476c4d..57417f0b9582601ef5559fed51a06b8649ea3032 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "pamn", - "version": "1.5.0", + "version": "1.6.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 4f2d1c0ae932561731438efb546541fe31193fe3..17f0aff734b13d1f2b0f9f0b6f5414c0b5c172c8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pamn", - "version": "1.5.0", + "version": "1.6.0", "scripts": { "ng": "ng", "start": "ng serve --configuration=fr --proxy-config proxy.conf.json", diff --git a/src/app/admin/components/claim-structure/claim-structure.component.ts b/src/app/admin/components/claim-structure/claim-structure.component.ts index e6e8f1338949af736a38bdc97e159870bd54c018..28e1701d0d63a3ecc84731ba756d734d90d6732c 100644 --- a/src/app/admin/components/claim-structure/claim-structure.component.ts +++ b/src/app/admin/components/claim-structure/claim-structure.component.ts @@ -17,14 +17,18 @@ export class ClaimStructureComponent implements OnInit { } public acceptDemand(demand: DemandAttachment): void { - this.adminService.acceptStructureClaim(demand.userEmail, demand.structureId).subscribe((data) => { - this.demandsAttachment = data; - }); + this.adminService + .acceptStructureClaim(demand.userEmail, demand.structureId, demand.structureName) + .subscribe((data) => { + this.demandsAttachment = data; + }); } public refuseDemand(demand: DemandAttachment): void { - this.adminService.refuseStructureClaim(demand.userEmail, demand.structureId).subscribe((data) => { - this.demandsAttachment = data; - }); + this.adminService + .refuseStructureClaim(demand.userEmail, demand.structureId, demand.structureName) + .subscribe((data) => { + this.demandsAttachment = data; + }); } } diff --git a/src/app/admin/services/admin.service.ts b/src/app/admin/services/admin.service.ts index 0167109c5db0f424f33bfff31dcae7ae38086541..cdea9a41bafe956e74a11c854f61b50bf173bec9 100644 --- a/src/app/admin/services/admin.service.ts +++ b/src/app/admin/services/admin.service.ts @@ -15,11 +15,27 @@ export class AdminService { return this.http.get<DemandAttachment[]>(`${this.baseUrl}/pendingStructures`); } - public acceptStructureClaim(userEmail: string, structureId: number): Observable<DemandAttachment[]> { - return this.http.post<DemandAttachment[]>(`${this.baseUrl}/validatePendingStructure`, { userEmail, structureId }); + public acceptStructureClaim( + userEmail: string, + structureId: number, + structureName: string + ): Observable<DemandAttachment[]> { + return this.http.post<DemandAttachment[]>(`${this.baseUrl}/validatePendingStructure`, { + userEmail, + structureId, + structureName, + }); } - public refuseStructureClaim(userEmail: string, structureId: number): Observable<DemandAttachment[]> { - return this.http.post<DemandAttachment[]>(`${this.baseUrl}/rejectPendingStructure`, { userEmail, structureId }); + public refuseStructureClaim( + userEmail: string, + structureId: number, + structureName: string + ): Observable<DemandAttachment[]> { + return this.http.post<DemandAttachment[]>(`${this.baseUrl}/rejectPendingStructure`, { + userEmail, + structureId, + structureName, + }); } } diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 045be83e7bbd0f56c3f29a5805bd5d48fe7b6ed6..c0890bbf96bc578c154f282e20ffbdcecad0f54b 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -87,6 +87,11 @@ const routes: Routes = [ component: FormComponent, canDeactivate: [DeactivateGuard], }, + { + path: 'news', + canActivate: [AdminGuard], + loadChildren: () => import('./post/post.module').then((m) => m.PostModule), + }, { path: '**', redirectTo: 'home', diff --git a/src/app/app.component.html b/src/app/app.component.html index f4d4b7c94d52798f4b87edb0e1160486c03c25b2..aa331e09ed89df3e4e5049eaa2a392e6d8d06e35 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,8 +1,8 @@ <div class="app-container"> <app-header></app-header> - <div class="app-body"> + <div (scroll)="onScrollDown($event)" class="app-body"> <router-outlet></router-outlet> <router-outlet name="print"></router-outlet> + <app-footer></app-footer> </div> - <app-footer></app-footer> </div> diff --git a/src/app/app.component.scss b/src/app/app.component.scss index 29e32a153bb71497f6fc87bdc4f1d46be4da47eb..f6a2d3edfa97ff90f40610254e9685406ff05517 100644 --- a/src/app/app.component.scss +++ b/src/app/app.component.scss @@ -3,17 +3,21 @@ @import '../assets/scss/layout'; .app-container { - height: 100%; display: block; flex-direction: column; - overflow-y: auto; } +@media print { + .app-body { + height: 100% !important; + } +} .app-body { flex: 1 1 auto; - overflow-y: hidden; + overflow-y: auto; overflow-x: hidden; position: relative; + height: calc(var(--vh, 1vh) * 100 - #{$header-height}); } .motif { diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 13fba3cf1c27833e321c5e9802f1cd6bcfe30c5c..b2a85d16fd6905ec02a1440ad9b62fc6a52b8812 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,8 +1,8 @@ import { Component } from '@angular/core'; import { ProfileService } from './profile/services/profile.service'; import { AuthService } from './services/auth.service'; -import { RouterListenerService } from './services/routerListener.service'; import { PrintService } from './shared/service/print.service'; +import { WindowScrollService } from './shared/service/windowScroll.service'; @Component({ selector: 'app-root', @@ -16,10 +16,22 @@ export class AppComponent { public printService: PrintService, private authService: AuthService, private profilService: ProfileService, - private routerListenerService: RouterListenerService + private windowScrollService: WindowScrollService ) { if (this.authService.isLoggedIn()) { this.profilService.getProfile(); } + this.setHeightApp(); + window.addEventListener('resize', () => { + this.setHeightApp(); + }); + } + + private setHeightApp(): void { + const vh = window.innerHeight * 0.01; + document.documentElement.style.setProperty('--vh', `${vh}px`); + } + public onScrollDown(event): void { + this.windowScrollService.scrollY.next(event); } } diff --git a/src/app/form/form.component.html b/src/app/form/form.component.html index 2bea200b728d9f6bc64473137bb2b9704fc71ef5..24a36a2122e8296b621993379d3e89820e3e3774 100644 --- a/src/app/form/form.component.html +++ b/src/app/form/form.component.html @@ -62,7 +62,7 @@ fxLayoutAlign="space-between center" fxLayoutAlign.lt-sm="center" > - <h2 class="no-wrap"> + <h2> {{ isJoinMode ? 'Rejoindre' : 'Revendiquer' }} la structure <span>{{ claimStructure.structureName }}</span> </h2> <div> @@ -331,7 +331,7 @@ </div> <div *ngIf="currentPage == pageTypeEnum.structurePhone" class="page"> <div class="title"> - <h3>Quel numéro appelé pour joindre votre structure ?</h3> + <h3>Quel numéro appeler pour joindre votre structure ?</h3> </div> <div class="form-group" fxLayout="column"> <label for="contactPhone">Téléphone de la structure</label> @@ -1098,25 +1098,27 @@ <svg aria-hidden="true"> <use [attr.xlink:href]="'assets/form/sprite.svg#emailVerification'"></use> </svg> - <h3>Un courriel vous a été envoyé afin de finaliser votre inscription</h3> + <h3>Un courriel vous a été envoyé afin de valider votre inscription</h3> </div> - <div *ngIf="currentPage == nbPagesForm && profile" class="page"> - <div class="title"> - <h3> - Bravo !<br /> - Votre structure a bien été référencée. - </h3> - </div> - - <div class="structureInfoBlock" fxLayout="row" fxLayoutAlign="center"> - <div class="structureInfoContent" fxLayout="column"> - {{ getStructureControl('structureName').value }} - <span>{{ getStructureControl('structureType').value }}</span> + <div *ngIf="currentPage == nbPagesForm && profile" class="lastPage"> + <div class="lastPage"> + <div class="title"> + <h3> + Bravo !<br /> + Votre structure a bien été référencée. + </h3> </div> - <div class="validateSvg"> - <svg class="validate" aria-hidden="true"> - <use [attr.xlink:href]="'assets/form/sprite.svg#checkVector'"></use> - </svg> + + <div class="structureInfoBlock" fxLayout="row" fxLayoutAlign="center"> + <div class="structureInfoContent" fxLayout="column"> + {{ getStructureControl('structureName').value }} + <span>{{ getStructureControl('structureType').value }}</span> + </div> + <div class="validateSvg"> + <svg class="validate" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#checkVector'"></use> + </svg> + </div> </div> </div> </div> @@ -1151,6 +1153,7 @@ *ngIf="currentPage == nbPagesForm && profile" class="btn-primary unique" routerLink="/home" + [queryParams]="{ id: createdStructure._id }" [state]="{ data: createdStructure }" > Voir ma structure @@ -1193,6 +1196,7 @@ *ngIf="currentPage == nbPagesForm && profile" class="btn-primary unique" routerLink="/home" + [queryParams]="{ id: createdStructure._id }" [state]="{ data: createdStructure }" > Voir ma structure diff --git a/src/app/form/form.component.scss b/src/app/form/form.component.scss index d32ba5a2cc79f9c57c473f12142886501002b6e7..f8e9ca1652f43e1ffcb10945978429bdd38135cc 100644 --- a/src/app/form/form.component.scss +++ b/src/app/form/form.component.scss @@ -16,11 +16,11 @@ h3 { .form { background: white; width: 100vw; - height: calc(100vh - #{$header-height} - #{$footer-height}); + height: calc(var(--vh, 1vh) * 100 - #{$header-height} - #{$footer-height}); top: #{$header-height}; z-index: $structure-details-z-index; @media #{$tablet} { - height: calc(100vh - #{$header-height}); + height: calc(var(--vh, 1vh) * 100 - #{$header-height}); position: fixed; //Hide default header app. } } @@ -115,9 +115,6 @@ h3 { span { color: $secondary-color; } - &.no-wrap { - white-space: nowrap; - } } h3 { @include cn-bold-26; @@ -137,7 +134,6 @@ h3 { height: auto; color: $grey-1; &.home { - height: 100%; .btnStart { margin-top: 90px; margin-bottom: 10px; @@ -535,3 +531,8 @@ img { overflow: hidden; } } + +.lastPage { + max-width: 530px; + margin: 0 auto; +} diff --git a/src/app/header/header.component.html b/src/app/header/header.component.html index 9d31ad373f001e665fc94c0dd52a5943ca6c0b4e..bffc482571030c720b7ef2ff93f395f62ea670f9 100644 --- a/src/app/header/header.component.html +++ b/src/app/header/header.component.html @@ -9,14 +9,10 @@ <app-svg-icon (click)="openMenu()" [type]="'ico'" [icon]="'menu'" [iconClass]="'icon-32'"></app-svg-icon> </div> <div fxLayout="row" class="right-header" fxLayoutAlign="center center" fxLayoutGap="3vw"> - <a routerLink="/home" [routerLinkActive]="'active'" i18n>Les acteurs</a> - <a routerLink="/about" [routerLinkActive]="'active'" i18n>Qui sommes-nous ?</a> <!-- <a routerLink="/news" [routerLinkActive]="'active'" i18n>Actualités</a> --> - <!-- <a routerLink="/resources" [routerLinkActive]="'active'" i18n>Ressources</a> --> + <a routerLink="/home" [routerLinkActive]="'active'" i18n>Cartographie de acteurs</a> + <a routerLink="/about" [routerLinkActive]="'active'" i18n>Qui sommes-nous ?</a> <a *ngIf="isAdmin" routerLink="/admin" [routerLinkActive]="'active'">Administration</a> - <!-- <a *ngIf="isLoggedIn" routerLink="/profile" [routerLinkActive]="'active'" fxLayout="row" fxLayoutGap="1.5vh"> - <app-svg-icon [type]="'ico'" [iconClass]="'icon-32'" [icon]="'user'" [iconColor]="'currentColor'"></app-svg-icon> - </a> --> <button *ngIf="isLoggedIn" class="red" routerLink="/profile" [routerLinkActive]="'active'"> {{ displayName }} </button> @@ -32,7 +28,8 @@ <div (click)="closeMenu()" class="ico-close-details"></div> </div> <div fxLayout="column" class="right-header" fxLayoutAlign="none baseline" fxLayoutGap="5vw"> - <a routerLink="/home" [routerLinkActive]="'active'" (click)="closeMenu()" i18n>Les acteurs</a> + <!-- <a routerLink="/news" [routerLinkActive]="'active'" (click)="closeMenu()" i18n>Actualités</a> --> + <a routerLink="/home" [routerLinkActive]="'active'" (click)="closeMenu()" i18n>Cartographie de acteurs</a> <a routerLink="/about" [routerLinkActive]="'active'" i18n>Qui sommes-nous ?</a> <a *ngIf="isAdmin" routerLink="/admin" [routerLinkActive]="'active'" (click)="closeMenu()">Administration</a> </div> @@ -47,7 +44,6 @@ </div> <app-signup-modal *ngIf="displaySignUp" [openned]="isPopUpOpen" (closed)="closeSignUpModal($event)"></app-signup-modal> -<!-- <app-signin-modal *ngIf="!displaySignUp" [openned]="isPopUpOpen" (closed)="closeSignInModal()"></app-signin-modal> --> <ng-template #customTitle> <img class="desktop-show logo-grand-lyon" src="/assets/logos/resin.svg" alt /> diff --git a/src/app/header/header.component.scss b/src/app/header/header.component.scss index 7470c080a1e12b117c225ac5910cdbc98606a54f..6a991d53b94f128faca52e2aa178ae1258504d87 100644 --- a/src/app/header/header.component.scss +++ b/src/app/header/header.component.scss @@ -41,6 +41,11 @@ button { &.red { @include btn-red; border: none; + // user name ellipsis handling + white-space: nowrap; + width: 100px; + overflow: hidden; + text-overflow: ellipsis; } } @@ -101,7 +106,7 @@ a { animation: slideMenu 0.5s; .menu-content { background-color: $white; - height: 100vh; + height: calc(var(--vh, 1vh) * 100); width: 350px; padding: 27px 25px; } diff --git a/src/app/home/home.component.scss b/src/app/home/home.component.scss index 82bdfafba43c0b89380cb1a19ee1f36c53120def..eb5f97b21e571114d361a3e105a98e9e0bdbc8fa 100644 --- a/src/app/home/home.component.scss +++ b/src/app/home/home.component.scss @@ -15,7 +15,7 @@ } .right-pane { width: 80%; - padding: 0 40px; + padding: 0 16px; @media #{$tablet} { display: none; &.mapPhone { diff --git a/src/app/map/components/map.component.scss b/src/app/map/components/map.component.scss index cb53c0d90700caed57c3f469322e1b66bfcd58b3..8134fe5fda885a1e4f7088ef3844dc3e83cf899f 100644 --- a/src/app/map/components/map.component.scss +++ b/src/app/map/components/map.component.scss @@ -13,7 +13,7 @@ } #map { - height: calc(100vh - #{$header-height} - #{$footer-height} - 87px); + height: calc(100vh - #{$header-height} - #{$footer-height} - 60px); border: 10px solid $white; border-radius: 6px; @media #{$tablet} { @@ -69,6 +69,15 @@ } } +::ng-deep .leaflet-control-zoom { + a { + color: $grey-3; + &:hover { + color: $blue-hover; + } + } +} + ::ng-deep .leaflet-marker-icon { &.leaflet-interactive { circle { diff --git a/src/app/models/user.model.ts b/src/app/models/user.model.ts index d4c4b9a58ec6a5d41bea93d69302150fc6aba921..ed5b7aa02ddf13100b7b3b8974b29b0e62c4cc81 100644 --- a/src/app/models/user.model.ts +++ b/src/app/models/user.model.ts @@ -10,6 +10,7 @@ export class User { validationToken: string; structuresLink: string[]; pendingStructuresLink: string[] = []; + profileImage: string; constructor(obj?: any) { Object.assign(this, obj); diff --git a/src/app/post/components/post-card/post-card.component.html b/src/app/post/components/post-card/post-card.component.html new file mode 100644 index 0000000000000000000000000000000000000000..78a4c3ef0fedf1dd43c8e3e02be1cacc5071363e --- /dev/null +++ b/src/app/post/components/post-card/post-card.component.html @@ -0,0 +1,34 @@ +<div fxLayout="column" *ngIf="post" class="post" [ngClass]="class" fxLayoutGap="12px" (click)="showDetails(post)"> + <div fxLayout="column" fxLayoutGap="4px"> + <div + fxLayout="row" + class="tag" + fxLayoutAlign=" center" + fxLayoutGap="12px" + *ngIf="post.tags[0].slug != tagEnum.appels" + > + <app-svg-icon + [iconClass]="'icon-32'" + [iconColor]="'inherit'" + [type]="'post'" + [icon]="post.tags[0].slug" + ></app-svg-icon> + <span>{{ post.tags[0].name }}</span> + </div> + <div fxLayout="row" class="imageContainer" *ngIf="post.feature_image"> + <img class="image" alt="image about the news" [src]="post.feature_image" /> + </div> + <div fxLayout="row" class="title"> + {{ post.title }} + </div> + </div> + <div fxLayout="row" class="description"> + {{ post.excerpt }} + </div> + <div fxLayout="column" class="informations"> + <div fxLayout="row"> + {{ post.published_at | date: 'shortDate' }} + </div> + <div fxLayout="row">par {{ post.author }}</div> + </div> +</div> diff --git a/src/app/post/components/post-card/post-card.component.scss b/src/app/post/components/post-card/post-card.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..8aad13d4bdaaeb7315519ef4bf95a9a9e8d52cdd --- /dev/null +++ b/src/app/post/components/post-card/post-card.component.scss @@ -0,0 +1,81 @@ +@import '../../../../assets/scss/color'; +@import '../../../../assets/scss/typography'; +@import '../../../../assets/scss/breakpoint'; + +.post { + cursor: pointer; + padding: 16px 0px; + border-bottom: 1px dashed $grey-3; + &.bigNew { + border: 0; + .imageContainer { + .image { + object-fit: cover; + height: 360px; + width: 100%; + @media #{$large-phone} { + height: 147px; + } + } + } + .title { + @media #{$large-phone} { + @include cn-bold-22; + } + @include cn-bold-30; + } + .description { + @include cn-regular-18; + color: $grey-1; + } + } + .imageContainer { + margin-bottom: 12px !important; + .image { + object-fit: cover; + height: 88px; + width: 195px; + @media #{$large-phone} { + height: 70px; + } + } + } + .tag { + @include cn-bold-16; + text-transform: uppercase; + color: $secondary-color; + fill: $secondary-color; + stroke: $secondary-color; + } + .title { + @media #{$large-phone} { + @include cn-bold-18; + } + @include cn-bold-20; + color: $grey-1; + } + .description { + @media #{$large-phone} { + display: none !important; + } + @include cn-regular-16; + color: $black; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box !important; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + } + .informations { + @include cn-regular-16; + color: $grey-3; + font-style: italic; + } +} +.project { + text-align: left; + .imageContainer, + .informations { + display: none !important; + } +} diff --git a/src/app/post/components/post-card/post-card.component.spec.ts b/src/app/post/components/post-card/post-card.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..d4d019381c7c0b19f28870d734dd304b07335d83 --- /dev/null +++ b/src/app/post/components/post-card/post-card.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PostCardComponent } from './post-card.component'; + +describe('PostCardComponent', () => { + let component: PostCardComponent; + let fixture: ComponentFixture<PostCardComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ PostCardComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(PostCardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/post/components/post-card/post-card.component.ts b/src/app/post/components/post-card/post-card.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..78970f17fde1248ad7c9604de683217b361ce432 --- /dev/null +++ b/src/app/post/components/post-card/post-card.component.ts @@ -0,0 +1,21 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; +import { TagEnum } from '../../enum/tag.enum'; +import { Post } from '../../models/post.model'; + +@Component({ + selector: 'app-post-card', + templateUrl: './post-card.component.html', + styleUrls: ['./post-card.component.scss'], +}) +export class PostCardComponent implements OnInit { + @Input() post: Post; + @Input() class: string; + public tagEnum = TagEnum; + constructor(private router: Router) {} + + ngOnInit(): void {} + public showDetails(post: Post): void { + this.router.navigateByUrl('news/details/' + post.id, { state: { data: post } }); + } +} diff --git a/src/app/post/components/post-details/post-details.component.html b/src/app/post/components/post-details/post-details.component.html new file mode 100644 index 0000000000000000000000000000000000000000..dee0903eebfbe31baec840cb88047f446f239ad9 --- /dev/null +++ b/src/app/post/components/post-details/post-details.component.html @@ -0,0 +1,37 @@ +<div class="postContainer" *ngIf="post" fxLayout="column" fxLayoutGap="16px"> + <div fxLayout="row"> + <div class="backLink" fxLayout="row" fxLayoutAlign=" center" (click)="backToPosts()"> + <svg class="chevronLeft" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#chevronLeft'"></use> + </svg> + <span>Retour à la liste d'acutalités</span> + </div> + </div> + <div fxLayout="column"> + <div fxLayout="row" class="tag" fxLayoutAlign=" center" fxLayoutGap="12px"> + <app-svg-icon + [iconClass]="'icon-32'" + [iconColor]="'inherit'" + [type]="'post'" + [icon]="post.tags[0].slug" + ></app-svg-icon> + <span>{{ post.tags[0].name }}</span> + </div> + <div fxLayout="row" class="title"> + {{ post.title }} + </div> + </div> + + <div fxLayout="column" class="informations" *ngIf="post.tags[0].slug != 'appels'"> + <div fxLayout="row"> + {{ post.published_at | date: 'shortDate' }} + </div> + <div fxLayout="row">par {{ post.author }}</div> + </div> + <div fxLayout="row" class="imageContainer" *ngIf="post.feature_image"> + <img class="image" alt="image about the news" [src]="post.feature_image" /> + </div> + <div fxLayout="row" class="description"> + <div [innerHtml]="post.safeHtml"></div> + </div> +</div> diff --git a/src/app/post/components/post-details/post-details.component.scss b/src/app/post/components/post-details/post-details.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..27e6544e52c89eaa6b5a05e0224630bd4a7fee56 --- /dev/null +++ b/src/app/post/components/post-details/post-details.component.scss @@ -0,0 +1,74 @@ +@import '../../../../assets/scss/color'; +@import '../../../../assets/scss/typography'; +@import '../../../../assets/scss/layout'; +@import '../../../../assets/scss/breakpoint'; +@import '../../../../assets/scss/hyperlink'; + +$margin-post: 20px; + +.postContainer { + max-width: 860px; + margin: $margin-post 0; + min-height: calc( + var(--vh, 1vh) * 100 - #{$header-height} - #{$footer-height} - #{$header-post-height} - #{$margin-post} * 3 + ); + .chevronLeft { + height: 24px; + width: 24px; + stroke: $black; + margin-right: 10px; + } + .backLink { + cursor: pointer; + color: $grey-2; + @include cn-bold-16; + &:hover { + opacity: 0.4; + } + } +} +.tag { + @include cn-bold-16; + text-transform: uppercase; + color: $secondary-color; + fill: $secondary-color; + stroke: $secondary-color; +} +.title { + @include cn-bold-30; + color: $grey-1; +} +.informations { + @include cn-regular-16; + color: $grey-3; + font-style: italic; +} +.imageContainer { + .image { + object-fit: cover; + height: 360px; + width: 100%; + @media #{$large-phone} { + height: 147px; + } + } +} +.description { + div { + width: 100%; + } + ::ng-deep figure { + margin: 0; + img { + object-fit: cover; + max-width: 100%; + } + } + ::ng-deep a { + @include hyperlink; + padding: 0; + } + ::ng-deep p { + @include cn-regular-18; + } +} diff --git a/src/app/post/components/post-details/post-details.component.spec.ts b/src/app/post/components/post-details/post-details.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..90f92b94c0e46f064508801e1d57403a5fb1c26d --- /dev/null +++ b/src/app/post/components/post-details/post-details.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PostDetailsComponent } from './post-details.component'; + +describe('PostDetailsComponent', () => { + let component: PostDetailsComponent; + let fixture: ComponentFixture<PostDetailsComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ PostDetailsComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(PostDetailsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/post/components/post-details/post-details.component.ts b/src/app/post/components/post-details/post-details.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..317585f7003799f50a5f31ee0fbb68dcd50f9122 --- /dev/null +++ b/src/app/post/components/post-details/post-details.component.ts @@ -0,0 +1,38 @@ +import { Component, OnInit } from '@angular/core'; +import { DomSanitizer } from '@angular/platform-browser'; +import { ActivatedRoute, Router } from '@angular/router'; +import { RouterListenerService } from '../../../services/routerListener.service'; +import { Post } from '../../models/post.model'; +import { PostService } from '../../services/post.service'; + +@Component({ + selector: 'app-post-details', + templateUrl: './post-details.component.html', + styleUrls: ['./post-details.component.scss'], +}) +export class PostDetailsComponent implements OnInit { + constructor( + private activatedRoute: ActivatedRoute, + private router: Router, + private postService: PostService, + private sanitizer: DomSanitizer, + private routerListener: RouterListenerService + ) {} + post: Post; + ngOnInit(): void { + if (history.state.data) { + this.post = new Post(history.state.data); + this.post.safeHtml = this.sanitizer.bypassSecurityTrustHtml(this.post.html); + } else { + const postId = this.activatedRoute.snapshot.paramMap.get('id'); + this.postService.getPost(postId).subscribe((post) => { + this.post = post.posts[0]; + this.post.safeHtml = this.sanitizer.bypassSecurityTrustHtml(this.post.html); + }); + } + } + + public backToPosts(): void { + this.routerListener.goToPreviousUrl(); + } +} diff --git a/src/app/post/components/post-header/post-header.component.html b/src/app/post/components/post-header/post-header.component.html new file mode 100644 index 0000000000000000000000000000000000000000..ae793b227d69c38fd322ea32c32ef2e2ed400ddb --- /dev/null +++ b/src/app/post/components/post-header/post-header.component.html @@ -0,0 +1,78 @@ +<div class="header-container"> + <div class="section-container" fxLayout="column" fxLayoutAlign="space-between"> + <h1> + Fil d’actualité + <p class="onlyOnDesktop">du réseau d’inclusion numérique</p> + </h1> + <div fxLayout="row" fxLayoutGap="5px" fxLayoutAlign="space-between flex-end" class="overflow"> + <div fxLayout="row" class="row-mobile"> + <div fxLayout="row" fxLayoutAlign="center center" *ngFor="let tag of tags.others"> + <span + class="tag-button" + tabindex="0" + (click)="activateTag(tag)" + (keydown.enter)="activateTag(tag)" + [ngClass]="{ active: tag.slug === mainActiveTag.slug || tag.name === mainActiveTag.slug }" + >{{ tag.name }}</span + > + </div> + </div> + <div + class="btnSection" + fxLayout="row" + fxLayoutAlign="space-between center" + fxLayoutGap="16px" + (clickOutside)="closeModal()" + > + <button + type="button" + fxLayout="row" + [ngClass]="{ + selected: modalTypeOpened === TypeModal.public, + containCheckedFilters: checkedPublicTags.length > 0 + }" + fxLayoutAlign="space-between center" + (click)="openModal(TypeModal.public)" + > + <span class="text">Tout public</span> + <app-svg-icon + class="icon" + [type]="'ico'" + [iconClass]="modalTypeOpened === TypeModal.public ? 'white icon-32' : 'grey-1 icon-32'" + [icon]="'news-public'" + ></app-svg-icon> + <div class="arrow"></div> + </button> + <button + class="btn-filter-no-margin" + type="button" + fxLayout="row" + [ngClass]="{ + selected: modalTypeOpened === TypeModal.location, + containCheckedFilters: checkedLocationTags.length > 0 + }" + fxLayoutAlign="space-between center" + (click)="openModal(TypeModal.location)" + > + <span class="text">Toutes les communes</span> + <app-svg-icon + class="icon" + [type]="'ico'" + [iconClass]="modalTypeOpened === TypeModal.location ? 'white' : 'grey-1'" + [icon]="'news-location'" + ></app-svg-icon> + <div class="arrow"></div> + </button> + <div *ngIf="modalTypeOpened"> + <app-post-modal-filters + [modalType]="modalTypeOpened" + [tags]="getModalData()" + [inputCheckedTags]="getCheckedModalData()" + (searchEvent)="filter($event)" + (closeEvent)="closeModal()" + ></app-post-modal-filters> + </div> + </div> + </div> + </div> +</div> diff --git a/src/app/post/components/post-header/post-header.component.scss b/src/app/post/components/post-header/post-header.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..7a51cec87a45e457f3d996b3a8acbb4ffd9bd023 --- /dev/null +++ b/src/app/post/components/post-header/post-header.component.scss @@ -0,0 +1,126 @@ +@import '../../../../assets/scss/color'; +@import '../../../../assets/scss/buttons'; +@import '../../../../assets/scss/typography'; +@import '../../../../assets/scss/breakpoint'; +@import '../../../../assets/scss/layout'; + +h1 { + margin-top: 25px; + margin-bottom: 0px; + .onlyOnDesktop { + margin: 0; + } + @media #{$large-phone} { + @include cn-bold-28; + .onlyOnDesktop { + display: none; + } + } +} + +.header-container { + height: #{$header-post-height}; + @media #{$large-phone} { + height: #{$header-post-height-mobile}; + } + background: $white; +} + +.section-container { + height: 100%; +} + +.btnSection { + padding: 16px 0 0px 0; + button { + background: $white; + height: 40px; + width: 210px; + border: 1px solid $grey-4; + padding: 3px 16px 3px 16px; + outline: none; + border-radius: 4px; + cursor: pointer; + white-space: nowrap; + @include btn-normal; + .arrow { + background-color: transparent; + border-bottom: 1px solid $grey-2; + border-right: 1px solid $grey-2; + transform: translateY(-25%) rotate(45deg); + margin: 0 5px 0 10px; + height: 7px; + width: 7px; + } + &:focus { + border-color: $blue-hover; + } + } + .selected { + background-color: $secondary-color; + border-color: $secondary-color !important; + color: $white; + .arrow { + background-color: transparent; + border-bottom: 1px solid $white; + border-right: 1px solid $white; + transform: translateY(25%) rotate(-135deg); + margin: 0 5px 0 10px; + height: 7px; + width: 7px; + } + } + .containCheckedFilters { + border-color: $secondary-color; + } + .icon { + display: none !important; + } + @media #{$desktop} { + button { + width: 90px; + } + .text { + display: none !important; + } + .icon { + display: inherit !important; + } + } + @media #{$tablet} { + button { + display: none !important; + } + } +} + +.tag-button { + padding: 8px 10px; + @include cn-regular-16; + cursor: pointer; + white-space: nowrap; + &.active { + background-color: $secondary-color; + color: $white; + } + &:focus { + outline-color: $secondary-color; + } +} + +// Remove margin right on filter pop-up trigger +.btn-filter-no-margin { + margin-right: 0 !important; +} + +.row-mobile { + @media #{$tablet} { + width: 100%; + justify-content: space-between; + } +} +.overflow { + @media #{$tablet} { + overflow-y: scroll; + } +} diff --git a/src/app/post/components/post-header/post-header.component.spec.ts b/src/app/post/components/post-header/post-header.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..a2ba8e0b6838fb77e83d1644ca8dd73734b087eb --- /dev/null +++ b/src/app/post/components/post-header/post-header.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PostHeaderComponent } from './post-header.component'; + +describe('PostHeaderComponent', () => { + let component: PostHeaderComponent; + let fixture: ComponentFixture<PostHeaderComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ PostHeaderComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(PostHeaderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/post/components/post-header/post-header.component.ts b/src/app/post/components/post-header/post-header.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..21ef7a3886d7c40fa1b0a54f2676cc1555f48a41 --- /dev/null +++ b/src/app/post/components/post-header/post-header.component.ts @@ -0,0 +1,120 @@ +import { Component, EventEmitter, OnInit, Output } from '@angular/core'; +import { Tag } from '../../models/tag.model'; +import { TagWithMeta } from '../../models/tagWithMeta.model'; +import * as _ from 'lodash'; +import { TypeModalNews } from '../../enum/typeModalNews.enum'; +import { ActivatedRoute, Router } from '@angular/router'; +import { TagEnum } from '../../enum/tag.enum'; +import { parseSlugToTag } from '../utils/NewsUtils'; + +@Component({ + selector: 'app-post-header', + templateUrl: './post-header.component.html', + styleUrls: ['./post-header.component.scss'], +}) +export class PostHeaderComponent implements OnInit { + public modalTypeOpened: TypeModalNews; + public tags: TagWithMeta; + public mainActiveTag: Tag = new Tag({ slug: TagEnum.aLaUne }); + public tagEnum = TagEnum; + + public checkedPublicTags: Tag[] = []; + public checkedLocationTags: Tag[] = []; + + constructor(private route: ActivatedRoute, private router: Router) {} + + ngOnInit(): void { + this.route.data.subscribe((data) => { + if (data.tags) { + this.tags = data.tags; + this.tags.others.forEach((tag) => { + tag.slug == TagEnum.aLaUne ? (tag.name = 'Les + récentes') : tag.name; + }); + this.tags.commune.sort((tagA, tagB) => { + return this.sortArray(tagA, tagB); + }); + } + }); + + this.route.queryParams.subscribe((queryParams) => { + if (queryParams.mainTag) { + this.mainActiveTag = new Tag({ slug: queryParams.mainTag }); + } + if (queryParams.publicTags) { + this.checkedPublicTags = parseSlugToTag(queryParams.publicTags); + } + if (queryParams.locationTags) { + this.checkedLocationTags = parseSlugToTag(queryParams.locationTags); + } + }); + } + + private sortArray(tagA: Tag, tagB: Tag): number { + const nameTagA = tagA.name.toUpperCase(); + const nameTagB = tagB.name.toUpperCase(); + if (nameTagA < nameTagB) { + return -1; + } + return 1; + } + // Open the modal and display the list according to the right filter button + public openModal(modalType: TypeModalNews): void { + // if modal already opened, reset type + if (this.modalTypeOpened === modalType) { + this.closeModal(); + } else if (this.modalTypeOpened !== modalType) { + this.modalTypeOpened = modalType; + } + } + + public closeModal(): void { + this.modalTypeOpened = undefined; + } + + // Accessor to template angular. + public get TypeModal(): typeof TypeModalNews { + return TypeModalNews; + } + + public getModalData(): Tag[] { + if (this.modalTypeOpened === this.TypeModal.public) { + return this.tags.public; + } + return this.tags.commune; + } + + public getCheckedModalData(): Tag[] { + if (this.modalTypeOpened === this.TypeModal.public) { + return this.checkedPublicTags; + } + return this.checkedLocationTags; + } + + public activateTag(tag: Tag): void { + this.mainActiveTag = tag; + this.setQueryParam(); + } + + public filter(data: Tag[]): void { + if (this.modalTypeOpened === this.TypeModal.public) { + this.checkedPublicTags = data; + } else { + this.checkedLocationTags = data; + } + + this.setQueryParam(); + this.closeModal(); + } + + private setQueryParam(): void { + this.router.navigate([], { + relativeTo: this.route, + queryParams: { + mainTag: this.mainActiveTag.slug == this.tagEnum.etudes ? this.mainActiveTag.name : this.mainActiveTag.slug, + publicTags: this.checkedPublicTags.map((tag) => tag.slug), + locationTags: this.checkedLocationTags.map((tag) => tag.slug), + }, + queryParamsHandling: 'merge', + }); + } +} diff --git a/src/app/post/components/post-list/post-list.component.html b/src/app/post/components/post-list/post-list.component.html new file mode 100644 index 0000000000000000000000000000000000000000..2d6c15596f98a52c5ea0e3b483ee85358844cbbe --- /dev/null +++ b/src/app/post/components/post-list/post-list.component.html @@ -0,0 +1,99 @@ +<div *ngIf="!isPublishMode" class="section-container" fxLayout="row" fxLayoutGap="32px"> + <div fxLayout="column" class="list-container" fxLayoutGap="16px"> + <div fxLayout="column" *ngIf="displayTags()"> + <div fxLayout="row wrap" fxLayoutAlign="none center" fxLayoutGap="8px"> + <div + fxLayout="row" + fxLayoutAlign="start center" + fxLayoutGap="9px" + *ngFor="let filter of filters | slice: 1" + class="tag" + (click)="removeTag(filter)" + > + <p>{{ filter.slug | titlecase }}</p> + <app-svg-icon [type]="'ico'" [iconColor]="'currentColor'" [icon]="'cancel'"></app-svg-icon> + </div> + </div> + </div> + <div fxLayout="column" *ngIf="isALaUneTag() && !displayTags()"> + <div fxLayout="row" class="row-border" fxLayoutAlign="space-between center"> + <h2>dernières actualités</h2> + <app-button + [type]="'button'" + [style]="'buttonWithHash'" + [text]="'Publier votre actu'" + (action)="togglePublishNews()" + ></app-button> + </div> + <app-post-card *ngIf="bigNews" [class]="'bigNew'" [post]="bigNews"></app-post-card> + </div> + <div fxLayout="column" fxLayoutAlign=" center" class="project-container mobile"> + <div class="background-project-container"> + <div class="project-content mobile" fxLayout="column"> + <h2>appels à projets</h2> + <div *ngIf="projectsNew.length !== 0"> + <app-post-card + [post]="news" + [class]="'project'" + [ngClass]="{ 'last-child': last }" + *ngFor="let news of projectsNew; let last = last" + ></app-post-card> + </div> + <div *ngIf="projectsNew.length === 0"> + <p>Aucun appels à projet pour le moment.</p> + </div> + </div> + </div> + </div> + <div fxLayout="column"> + <div + *ngIf="!isALaUneTag() || displayTags()" + fxLayout="row" + class="row-border" + fxLayoutAlign="space-between center" + > + <h2>{{ getDisplayedTag() }}</h2> + <app-button + [type]="'button'" + [style]="'buttonWithHash'" + [text]="'Publier votre actu'" + (action)="togglePublishNews()" + ></app-button> + </div> + <div *ngIf="leftColumnPosts.length <= 0" fxLayout="column"> + <p>Aucun résultat ne correspond à votre recherche.</p> + </div> + <div fxLayout="row" fxLayoutGap="33px"> + <div fxLayout="column" class="columnPosts"> + <app-post-card [post]="news" *ngFor="let news of leftColumnPosts"></app-post-card> + </div> + <div fxLayout="column" class="columnPosts"> + <app-post-card [post]="news" *ngFor="let news of rightColumnPosts"></app-post-card> + </div> + <div fxLayout="column" class="columnPostsMobile"> + <app-post-card [post]="news" *ngFor="let news of postsMobileView"></app-post-card> + </div> + </div> + </div> + </div> + <div fxLayout="column" fxLayoutAlign=" center" class="project-container desktop"> + <div class="background-project-container"> + <div class="project-content" fxLayout="column"> + <app-svg-icon [iconClass]="'icon-80'" [iconColor]="'inherit'" [type]="'post'" [icon]="'appels'"></app-svg-icon> + <h2>appels à projets</h2> + <div *ngIf="projectsNew.length !== 0"> + <app-post-card + [post]="news" + [class]="'project'" + [ngClass]="{ 'last-child': last }" + *ngFor="let news of projectsNew; let last = last" + ></app-post-card> + </div> + <div *ngIf="projectsNew.length === 0"> + <p>Aucun appels à projet pour le moment.</p> + </div> + </div> + </div> + </div> +</div> +<app-post-publish *ngIf="isPublishMode" (closePublish)="togglePublishNews()"></app-post-publish> diff --git a/src/app/post/components/post-list/post-list.component.scss b/src/app/post/components/post-list/post-list.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..38cf7dc0002250f8fb520bc674865deb169aa518 --- /dev/null +++ b/src/app/post/components/post-list/post-list.component.scss @@ -0,0 +1,112 @@ +@import '../../../../assets/scss/color'; +@import '../../../../assets/scss/typography'; +@import '../../../../assets/scss/shapes'; +@import '../../../../assets/scss/breakpoint'; + +.section-container { + background: $grey-6; + min-height: 68vh; + width: 100%; + .row-border { + border-bottom: 1px dashed $grey-4; + padding-bottom: 16px; + } + h2 { + font-style: italic !important; + text-transform: uppercase; + } +} +h2 { + font-style: italic !important; + text-transform: uppercase; +} + +.last-child { + ::ng-deep .post { + border: 0; + } +} +.list-container { + @media #{$tablet} { + width: 100%; + } + width: 80%; + h2 { + @media #{$large-phone} { + @include cn-bold-22; + } + @include cn-bold-28; + color: $grey-2; + margin: 0; + } + .columnPosts { + @media #{$large-phone} { + display: none !important; + } + width: 50%; + } + .columnPostsMobile { + display: none !important; + @media #{$large-phone} { + display: flex !important; + } + } +} +.project-container { + &.desktop { + @media #{$tablet} { + display: none !important; + } + } + &.mobile { + display: none !important; + @media #{$tablet} { + display: flex !important; + width: 100%; + } + } + width: 20%; + height: 100%; + min-width: 306px; + @include background-hash($secondary-color); + border: 1px solid $secondary-color; + border-radius: 6px; + .background-project-container { + width: 100%; + height: 100%; + background: $white; + border-radius: 6px; + .project-content { + @media #{$large-phone} { + padding: 38px 32px 14px 36px; + } + padding: 39px 32px 26px 36px; + fill: $secondary-color; + stroke: $secondary-color; + &.mobile { + text-align: left; + } + text-align: center; + h2 { + @media #{$large-phone} { + @include cn-bold-22; + } + @include cn-bold-26; + color: $secondary-color; + margin-bottom: 0; + } + } + } +} +.tag { + background: $grey-3; + color: $white; + border-radius: 20px; + cursor: pointer; + margin-bottom: 10px; + padding: 0 20px; + p { + margin-top: 0; + margin-bottom: 0; + } +} diff --git a/src/app/post/components/post-list/post-list.component.spec.ts b/src/app/post/components/post-list/post-list.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..2d39c24944619ae92c499e826d476de93f005a4c --- /dev/null +++ b/src/app/post/components/post-list/post-list.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PostListComponent } from './post-list.component'; + +describe('PostListComponent', () => { + let component: PostListComponent; + let fixture: ComponentFixture<PostListComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ PostListComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(PostListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/post/components/post-list/post-list.component.ts b/src/app/post/components/post-list/post-list.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..7703df2157496f0e71fdfdbe3fa546c5c14c4c65 --- /dev/null +++ b/src/app/post/components/post-list/post-list.component.ts @@ -0,0 +1,185 @@ +import { Component, OnInit } from '@angular/core'; +import { WindowScrollService } from '../../../shared/service/windowScroll.service'; +import { TagEnum } from '../../enum/tag.enum'; +import { Pagination } from '../../models/pagination.model'; +import { Post } from '../../models/post.model'; +import { Tag } from '../../models/tag.model'; +import { PostWithMeta } from '../../models/postWithMeta.model'; +import { PostService } from '../../services/post.service'; +import { ActivatedRoute, Router } from '@angular/router'; +import * as _ from 'lodash'; +import { parseSlugToTag } from '../utils/NewsUtils'; + +@Component({ + selector: 'app-post-list', + templateUrl: './post-list.component.html', + styleUrls: ['./post-list.component.scss'], +}) +export class PostListComponent implements OnInit { + public selectedMainTagSlug = ''; + public selectedLocationTagSlug = []; + public selectedPublicTagsSlug = []; + public filters: Tag[]; + public postsMobileView: Post[] = []; + public leftColumnPosts: Post[] = []; + public rightColumnPosts: Post[] = []; + public projectsNew: Post[] = []; + public bigNews: Post; + public pagination: Pagination; + public isLoading = false; + public isPublishMode = false; + + constructor( + private postService: PostService, + private windowScrollService: WindowScrollService, + private route: ActivatedRoute, + private router: Router + ) { + this.windowScrollService.scrollY$.subscribe((evt: any) => { + if (evt && evt.target.offsetHeight + evt.target.scrollTop >= evt.target.scrollHeight - 200) { + if (!this.isLoading) { + this.loadMore(); + } + } + }); + } + + ngOnInit(): void { + this.isLoading = true; + // Init APP news list + this.postService.getPosts(1, [TagEnum.appels]).subscribe((news) => { + let projectNews = news.posts.map((news) => (news = this.addAuthorToPost(news))); + this.projectsNew = projectNews; + }); + this.postService.getPosts(1, [TagEnum.aLaUne]).subscribe((news) => { + if (news.posts[0]) { + this.bigNews = this.addAuthorToPost(news.posts[0]); + } + }); + this.route.queryParams.subscribe((queryParams) => { + this.isPublishMode = false; + // If main tag is in route, set it + if (queryParams.mainTag) { + this.selectedMainTagSlug = queryParams.mainTag; + this.selectedPublicTagsSlug = parseSlugToTag(queryParams.publicTags); + this.selectedLocationTagSlug = parseSlugToTag(queryParams.locationTags); + // Set filters for search and display + this.filters = [ + new Tag({ slug: queryParams.mainTag }), + ...this.selectedLocationTagSlug, + ...this.selectedPublicTagsSlug, + ]; + // Apply search + this.getPosts(this.filters); + } else { + // Init default news list + this.postService.getPosts(1).subscribe((news) => { + this.setNews(news); + }); + } + }); + } + + public togglePublishNews(): void { + this.isPublishMode = !this.isPublishMode; + } + public getPosts(filters?: Tag[]): void { + // Parse filter + let parsedFilters = null; + if (filters) { + parsedFilters = filters.map((filter) => { + return filter.slug; + }); + + // remove 'a la une' filter + parsedFilters = parsedFilters.filter((item) => { + return item !== TagEnum.aLaUne; + }); + + if (parsedFilters.length <= 0) { + parsedFilters = null; + } + } + + // Reset posts + this.resetPosts(); + + this.postService.getPosts(1, parsedFilters).subscribe((news) => { + this.setNews(news); + }); + } + + public getDisplayedTag(): string { + if (!this.isALaUneTag()) { + return this.selectedMainTagSlug; + } + return 'autres actualités'; + } + + public isALaUneTag(): boolean { + if (!this.filters || this.filters[0].slug === TagEnum.aLaUne) { + return true; + } + return false; + } + + public resetPosts(): void { + this.leftColumnPosts = []; + this.rightColumnPosts = []; + this.postsMobileView = []; + } + + public publishNews(): void {} + + //Transform excerpt post to have a custom author. + private addAuthorToPost(post: Post): Post { + post.author = post.excerpt; + post.excerpt = post.html.replace(/<[^>]*>/g, ''); + return post; + } + + // Load more news on scroll event. + private loadMore(): void { + if (this.pagination.page < this.pagination.pages) { + this.isLoading = true; + this.postService.getPosts(this.pagination.next).subscribe((news) => { + this.setNews(news); + }); + } + } + + // Split news on two columns on desktop mode or one column in mobile mode. + private setNews(news: PostWithMeta): void { + this.pagination = news.meta.pagination; + const customIndex = this.postsMobileView.length; // For scroll loading, start with previous index. + news.posts.forEach((val, index) => { + val = this.addAuthorToPost(val); + index += customIndex; + if (index % 2 == 0) { + this.leftColumnPosts.push(val); + } else { + this.rightColumnPosts.push(val); + } + this.postsMobileView.push(val); + }); + this.isLoading = false; + } + + public removeTag(tagToRemove: Tag): void { + _.remove(this.selectedPublicTagsSlug, { slug: tagToRemove.slug }); + _.remove(this.selectedLocationTagSlug, { slug: tagToRemove.slug }); + this.router.navigate([], { + relativeTo: this.route, + queryParams: { + mainTag: this.selectedMainTagSlug, + publicTags: this.selectedPublicTagsSlug.map((tag) => tag.slug), + locationTags: this.selectedLocationTagSlug.map((tag) => tag.slug), + }, + queryParamsHandling: 'merge', + }); + } + + public displayTags(): boolean { + return this.selectedLocationTagSlug.length > 0 || this.selectedPublicTagsSlug.length > 0; + } +} diff --git a/src/app/post/components/post-modal-filters/post-modal-filters.component.html b/src/app/post/components/post-modal-filters/post-modal-filters.component.html new file mode 100644 index 0000000000000000000000000000000000000000..7ee54d56c10e422264d97c78d783c8dc4dd70f15 --- /dev/null +++ b/src/app/post/components/post-modal-filters/post-modal-filters.component.html @@ -0,0 +1,34 @@ +<div *ngIf="modalType" fxLayout="column" fxLayoutAlign="space-between" [ngClass]="['modal', 'modal' + getModalType()]"> + <div class="body-wrap" fxLayout="column" fxLayoutAlign="space-between"> + <div class="titleFilter" fxLayout="row" fxLayoutAlign="space-between"> + <span>Filtres</span> + <div (click)="closeModal()" class="ico-close-details"></div> + </div> + <div class="contentModal" fxLayout="row wrap" fxLayoutAlign="flex-start" *ngIf="tags.length > 0"> + <div class="blockFiltre"> + <ul class="blockLigne"> + <div fxLayout="row" class="ligneFiltre" *ngFor="let tag of tags"> + <li class="checkbox"> + <div class="checkboxItem"> + <label> + <input + type="checkbox" + [checked]="getIndex(checkedTags, tag.slug) > -1" + [value]="tag.id" + (change)="onCheckboxChange($event, tag)" + /> + <span class="customCheck"></span> + <div class="label">{{ tag.name }}</div> + </label> + </div> + </li> + </div> + </ul> + </div> + </div> + <div class="footer" fxLayout="row" fxLayoutAlign="end center" fxLayoutGap="3vw"> + <a (click)="clearFilters()" tabindex="0">Effacer</a> + <app-button [style]="'button'" [text]="'Appliquer'" (click)="emit(checkedTags)"></app-button> + </div> + </div> +</div> diff --git a/src/app/post/components/post-modal-filters/post-modal-filters.component.scss b/src/app/post/components/post-modal-filters/post-modal-filters.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..c897edd1c2a742c12ad461c4fc9acead50512623 --- /dev/null +++ b/src/app/post/components/post-modal-filters/post-modal-filters.component.scss @@ -0,0 +1,132 @@ +@import '../../../../assets/scss/icons'; +@import '../../../../assets/scss/color'; +@import '../../../../assets/scss/typography'; +@import '../../../../assets/scss/breakpoint'; +@import '../../../../assets/scss/shapes'; +@import '../../../../assets/scss/hyperlink'; +@import '../../../../assets/scss/z-index'; + +.modallocation { + margin-left: -341px; +} +.modalpublic { + @media #{$desktop} { + margin-left: -446px; + } + margin-left: -566px; +} +.modal { + max-width: 341px; + width: 94%; + z-index: $modal-z-index !important; + position: absolute; + border-radius: 6px; + margin-top: 24px; + @media #{$large-phone} { + height: 100%; + max-height: auto; + max-width: auto; + width: 100%; + position: fixed; + top: 0; + left: 0; + border: none; + padding: 0; + } + @include background-hash($grey-2); + border: 1px solid $grey-4; + ::-webkit-scrollbar { + width: 16px; + } + ::-webkit-scrollbar-track { + background: $grey-6; + } + ::-webkit-scrollbar-thumb { + background: $grey; + border-radius: 6px; + } + .body-wrap { + @media #{$large-phone} { + height: 100vh; + height: -webkit-fill-available; + } + .titleFilter { + display: none !important; + margin: 27px 25px 0px 25px; + @include cn-bold-26; + @media #{$large-phone} { + display: flex !important; + } + } + } + .contentModal { + overflow-y: auto; + max-width: 1100px; + border-bottom: 1px solid $grey; + margin-bottom: 16px; + max-height: 40vh; + @media #{$large-phone} { + max-height: none; + height: 100%; + } + .blockFiltre { + width: 100%; + margin: 0 32px; + padding: 40px 0; + border-bottom: 1px dashed $grey-4; + + &:last-child { + padding-bottom: 32px; + border-bottom: none; + } + @media #{$large-phone} { + margin: 0 18px; + padding: 25px 0; + } + } + .blockLigne { + padding-left: 0; + -moz-column-count: 1; + -moz-column-gap: 46px; + -webkit-column-count: 1; + -webkit-column-gap: 46px; + column-count: 1; + column-gap: 46px; + margin: 0px; + @media #{$large-phone} { + -moz-column-count: 1; + -webkit-column-count: 1; + column-count: 1; + } + } + .ligneFiltre { + padding: 5px 0; + } + h4 { + @include cn-bold-16; + line-height: 17px; + text-transform: uppercase; + color: $grey-3; + display: flex; + align-items: center; + margin-top: 0; + margin-bottom: 9px; + } + .nbResult { + @include cn-regular-14; + line-height: 16px; + color: $grey-3; + padding-top: 3px; + } + label { + @include cn-regular-14; + } + } + .footer { + margin: 0px 20px 16px 0; + height: 32px; + } +} +a { + @include hyperlink; +} diff --git a/src/app/post/components/post-modal-filters/post-modal-filters.component.spec.ts b/src/app/post/components/post-modal-filters/post-modal-filters.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..601a25abe56e12ba27750f23a88fb3fa9c4e9ecc --- /dev/null +++ b/src/app/post/components/post-modal-filters/post-modal-filters.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PostModalFiltersComponent } from './post-modal-filters.component'; + +describe('PostModalFiltersComponent', () => { + let component: PostModalFiltersComponent; + let fixture: ComponentFixture<PostModalFiltersComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ PostModalFiltersComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(PostModalFiltersComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/post/components/post-modal-filters/post-modal-filters.component.ts b/src/app/post/components/post-modal-filters/post-modal-filters.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..6624c5d0e7e2c021ac81839cb620a7ee9ae9f00c --- /dev/null +++ b/src/app/post/components/post-modal-filters/post-modal-filters.component.ts @@ -0,0 +1,72 @@ +import { Component, EventEmitter, Input, OnInit, Output, SimpleChanges } from '@angular/core'; +import { Tag } from '../../models/tag.model'; +import { TypeModalNews } from '../../enum/typeModalNews.enum'; +import { OnChanges } from '@angular/core'; + +@Component({ + selector: 'app-post-modal-filters', + templateUrl: './post-modal-filters.component.html', + styleUrls: ['./post-modal-filters.component.scss'], +}) +export class PostModalFiltersComponent implements OnInit, OnChanges { + @Input() public modalType: TypeModalNews; + @Input() public tags: Tag[]; + @Output() searchEvent = new EventEmitter(); + @Output() closeEvent = new EventEmitter(); + // Checkbox variable + @Input() public inputCheckedTags: Tag[] = []; + public checkedTags: Tag[] = []; + + constructor() {} + + ngOnChanges(changes: SimpleChanges): void { + if (changes.inputCheckedTags) { + this.checkedTags = this.inputCheckedTags; + } + } + + ngOnInit(): void { + this.checkedTags = this.inputCheckedTags; + } + + // Management of the checkbox event (Check / Uncheck) + public onCheckboxChange(event, tag: Tag): void { + if (event.target.checked) { + this.checkedTags.push(tag); + } else { + // Check if the module is present in the list and remove it + if (this.getIndex(this.checkedTags, tag.slug) > -1) { + this.checkedTags.splice(this.getIndex(this.checkedTags, tag.slug), 1); + } + } + } + + // Clear only filters in the current modal + public clearFilters(): void { + this.checkedTags = []; + this.searchEvent.emit(this.checkedTags); + } + + public getModalType(): string { + switch (this.modalType) { + case TypeModalNews.location: + return 'location'; + case TypeModalNews.public: + return 'public'; + default: + return ''; + } + } + + public emit(data: Tag[]): void { + this.searchEvent.emit(data); + } + + public getIndex(array: Tag[], slug: string): number { + return array.findIndex((tag: Tag) => tag.slug === slug); + } + + public closeModal(): void { + this.closeEvent.emit(); + } +} diff --git a/src/app/post/components/post-publish/post-publish.component.html b/src/app/post/components/post-publish/post-publish.component.html new file mode 100644 index 0000000000000000000000000000000000000000..7c28907ac8b5a4e3bf06c711ca18e5e32b0fde5b --- /dev/null +++ b/src/app/post/components/post-publish/post-publish.component.html @@ -0,0 +1,37 @@ +<div class="container" fxLayout="column" fxLayoutGap="16px"> + <div fxLayout="row"> + <div class="backLink" fxLayout="row" fxLayoutAlign=" center" (click)="backToPosts()"> + <svg class="chevronLeft" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#chevronLeft'"></use> + </svg> + <span>Retour à la liste d'acutalités</span> + </div> + </div> + <div fxLayout="column" class="content" fxLayoutGap="16px"> + <h2>Publier votre actualité</h2> + <div class="image"> + <svg aria-hidden="true"> + <use [attr.xlink:href]="'../../../../assets/post/sprite.svg#publishLogo'"></use> + </svg> + </div> + <div class="informations"> + <p>Vous pouvez nous envoyer votre actualité en distinguant ces 4 éléments :</p> + <ul> + <li>- le titre</li> + <li>- le texte</li> + <li>- l’auteur</li> + <li>- l’image (facultatif)</li> + </ul> + <br /> + <p>Si votre actualité existe déjà sur un autre site, envoyez-nous simplement son adresse URL</p> + <br /> + </div> + <div> + <a + class="btn-primary" + [href]="'mailto:inclusionnumerique@grandlyon.com?subject=Nouvelle actualité à intégrer&body=' + bodyMail" + >Envoyer votre actu par mail</a + > + </div> + </div> +</div> diff --git a/src/app/post/components/post-publish/post-publish.component.scss b/src/app/post/components/post-publish/post-publish.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..1868e8d4a32642747876d0497836cb35a85987e2 --- /dev/null +++ b/src/app/post/components/post-publish/post-publish.component.scss @@ -0,0 +1,61 @@ +@import '../../../../assets/scss/color'; +@import '../../../../assets/scss/typography'; +@import '../../../../assets/scss/layout'; + +$margin-post: 20px; + +.container { + max-width: 860px; + margin: $margin-post 0 100px 0; + min-height: calc( + var(--vh, 1vh) * 100 - #{$header-height} - #{$footer-height} - #{$header-post-height} - #{$margin-post} * 2 + ); +} +.chevronLeft { + height: 24px; + width: 24px; + stroke: $black; + margin-right: 10px; +} +.backLink { + cursor: pointer; + color: $grey-2; + @include cn-bold-16; + &:hover { + opacity: 0.4; + } +} +.content { + color: $grey-1; + h2 { + @include cn-bold-30; + margin: 0; + } + .image { + width: 100%; + text-align: center; + svg { + max-width: 300px; + height: 300px; + } + } + .informations { + @include cn-regular-18; + ul { + margin: 0; + padding: 0; + list-style: none; + } + p { + margin: 0; + } + } + + a { + text-decoration: none; + width: auto; + padding: 10.5px 24px; + @include cn-regular-16; + font-size: 16px; + } +} diff --git a/src/app/post/components/post-publish/post-publish.component.spec.ts b/src/app/post/components/post-publish/post-publish.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..ed2451eff03e05dd0f15a691aafe36e625dd1cb3 --- /dev/null +++ b/src/app/post/components/post-publish/post-publish.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PostPublishComponent } from './post-publish.component'; + +describe('PostPublishComponent', () => { + let component: PostPublishComponent; + let fixture: ComponentFixture<PostPublishComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ PostPublishComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(PostPublishComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/post/components/post-publish/post-publish.component.ts b/src/app/post/components/post-publish/post-publish.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..061bc66988fdb53f99e288c6f559dc7ecd04bfe6 --- /dev/null +++ b/src/app/post/components/post-publish/post-publish.component.ts @@ -0,0 +1,18 @@ +import { Component, EventEmitter, OnInit, Output } from '@angular/core'; + +@Component({ + selector: 'app-post-publish', + templateUrl: './post-publish.component.html', + styleUrls: ['./post-publish.component.scss'], +}) +export class PostPublishComponent implements OnInit { + @Output() closePublish = new EventEmitter<boolean>(); + constructor() {} + public bodyMail = + "Bonjour,%0D Je souhaite ajouter cette publication sur Rés'in :%0D- Titre :%0D- Texte :%0D- Auteur :%0D- Image : à joindre en pièce jointe"; + ngOnInit(): void {} + + public backToPosts(): void { + this.closePublish.emit(true); + } +} diff --git a/src/app/post/components/utils/NewsUtils.ts b/src/app/post/components/utils/NewsUtils.ts new file mode 100644 index 0000000000000000000000000000000000000000..4bb4eea6b9bada44033a1746d1eb200fd1dfd032 --- /dev/null +++ b/src/app/post/components/utils/NewsUtils.ts @@ -0,0 +1,11 @@ +import { Tag } from '../../models/tag.model'; + +export function parseSlugToTag(data: Tag[] | string): Tag[] { + let otherTags = []; + if (Array.isArray(data)) { + otherTags = data.map((slug) => new Tag({ slug: slug })); + } else if (data) { + otherTags = [new Tag({ slug: data })]; + } + return otherTags; +} diff --git a/src/app/post/enum/tag.enum.ts b/src/app/post/enum/tag.enum.ts new file mode 100644 index 0000000000000000000000000000000000000000..8b95ae41bf996f7e1f5614333f5973b905a26d29 --- /dev/null +++ b/src/app/post/enum/tag.enum.ts @@ -0,0 +1,10 @@ +export enum TagEnum { + aLaUne = 'a-la-une', + appels = 'appels', + projets = 'projets', + formations = 'formations', + infos = 'infos', + dossiers = 'dossiers', + etudes = 'etudes', + ressources = 'ressources', +} diff --git a/src/app/post/enum/typeModalNews.enum.ts b/src/app/post/enum/typeModalNews.enum.ts new file mode 100644 index 0000000000000000000000000000000000000000..d15c4e7022702da270c81011d06dfe0bb185243d --- /dev/null +++ b/src/app/post/enum/typeModalNews.enum.ts @@ -0,0 +1,4 @@ +export enum TypeModalNews { + public = 1, + location, +} diff --git a/src/app/post/models/pagination.model.ts b/src/app/post/models/pagination.model.ts new file mode 100644 index 0000000000000000000000000000000000000000..4f9ecaaec31d12a488d1ea219500d1fef26da007 --- /dev/null +++ b/src/app/post/models/pagination.model.ts @@ -0,0 +1,8 @@ +export class Pagination { + limit: number; + next: any; + page: number; + pages: number; + prev: any; + total: number; +} diff --git a/src/app/post/models/post.model.ts b/src/app/post/models/post.model.ts new file mode 100644 index 0000000000000000000000000000000000000000..eb13ecef2069a06fbd5845c659539a4829c7d1b2 --- /dev/null +++ b/src/app/post/models/post.model.ts @@ -0,0 +1,18 @@ +import { SafeHtml } from '@angular/platform-browser'; +import { Tag } from './tag.model'; + +export class Post { + id: number; + published_at: Date; + title: string; + excerpt: string; + feature_image: string; + html: string; + author: string; + tags: Tag[]; + safeHtml: SafeHtml; + + constructor(obj?: any) { + Object.assign(this, obj); + } +} diff --git a/src/app/post/models/postWithMeta.model.ts b/src/app/post/models/postWithMeta.model.ts new file mode 100644 index 0000000000000000000000000000000000000000..b8dcb357850a343c8fe624f133f868924ebd33c8 --- /dev/null +++ b/src/app/post/models/postWithMeta.model.ts @@ -0,0 +1,11 @@ +import { Pagination } from './pagination.model'; +import { Post } from './post.model'; + +export class PostWithMeta { + posts: Post[]; + meta: { pagination: Pagination }; + + constructor(obj?: any) { + Object.assign(this, obj); + } +} diff --git a/src/app/post/models/tag.model.ts b/src/app/post/models/tag.model.ts new file mode 100644 index 0000000000000000000000000000000000000000..53b77b9e07a0012f14068f6af1333f8d32fdf229 --- /dev/null +++ b/src/app/post/models/tag.model.ts @@ -0,0 +1,10 @@ +export class Tag { + id: string; + name: string; + slug: string; + description: string; // Description is used to ut categories on tags + + constructor(obj?: any) { + Object.assign(this, obj); + } +} diff --git a/src/app/post/models/tagWithMeta.model.ts b/src/app/post/models/tagWithMeta.model.ts new file mode 100644 index 0000000000000000000000000000000000000000..6b28aa489dd4c663bd6074ac66b6db4bd458ecaf --- /dev/null +++ b/src/app/post/models/tagWithMeta.model.ts @@ -0,0 +1,7 @@ +import { Tag } from './tag.model'; + +export class TagWithMeta { + commune: Tag[]; + public: Tag[]; + others: Tag[]; +} diff --git a/src/app/post/news.component.html b/src/app/post/news.component.html new file mode 100644 index 0000000000000000000000000000000000000000..93d25593614704c3f94172331359df4dcc1bacec --- /dev/null +++ b/src/app/post/news.component.html @@ -0,0 +1,5 @@ +<app-post-header (filterTags)="setFilters($event)"></app-post-header> +<div class="section-container"> + <!-- <app-post-list [filters]="filters"></app-post-list> --> + <router-outlet></router-outlet> +</div> diff --git a/src/app/post/news.component.scss b/src/app/post/news.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/app/post/news.component.spec.ts b/src/app/post/news.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..4ce0f02289a107ba1ded4f4b07debf6b43915fa5 --- /dev/null +++ b/src/app/post/news.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { NewsComponent } from './news.component'; + +describe('PostsComponent', () => { + let component: NewsComponent; + let fixture: ComponentFixture<NewsComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [NewsComponent], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(NewsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/post/news.component.ts b/src/app/post/news.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..40e2377766e92e84c50eb184be8f87604c2a288b --- /dev/null +++ b/src/app/post/news.component.ts @@ -0,0 +1,18 @@ +import { Component, OnInit } from '@angular/core'; +import { Tag } from './models/tag.model'; + +@Component({ + selector: 'app-news', + templateUrl: './news.component.html', + styleUrls: ['./news.component.scss'], +}) +export class NewsComponent implements OnInit { + public filters: Tag[]; + constructor() {} + + ngOnInit(): void {} + + public setFilters(tags: Tag[]): void { + this.filters = tags; + } +} diff --git a/src/app/post/post-routing.module.ts b/src/app/post/post-routing.module.ts new file mode 100644 index 0000000000000000000000000000000000000000..c95c0ba7cbea2c96e03ae08ecea77819b367b348 --- /dev/null +++ b/src/app/post/post-routing.module.ts @@ -0,0 +1,31 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; +import { PostDetailsComponent } from './components/post-details/post-details.component'; +import { PostListComponent } from './components/post-list/post-list.component'; +import { NewsComponent } from './news.component'; +import { TagResolver } from './resolvers/tags.resolver'; + +const routes: Routes = [ + { + path: '', + component: NewsComponent, + resolve: { + tags: TagResolver, + }, + children: [ + { + path: '', + component: PostListComponent, + }, + { + path: 'details/:id', + component: PostDetailsComponent, + }, + ], + }, +]; +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class PostRoutingModule {} diff --git a/src/app/post/post.module.ts b/src/app/post/post.module.ts new file mode 100644 index 0000000000000000000000000000000000000000..a4f19045817563190f78f433ecca44d8bf0b1cf1 --- /dev/null +++ b/src/app/post/post.module.ts @@ -0,0 +1,27 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { NewsComponent } from './news.component'; +import { PostRoutingModule } from './post-routing.module'; +import { PostHeaderComponent } from './components/post-header/post-header.component'; +import { PostListComponent } from './components/post-list/post-list.component'; +import { PostDetailsComponent } from './components/post-details/post-details.component'; +import { SharedModule } from '../shared/shared.module'; +import { PostCardComponent } from './components/post-card/post-card.component'; +import { PostPublishComponent } from './components/post-publish/post-publish.component'; +import { PostModalFiltersComponent } from './components/post-modal-filters/post-modal-filters.component'; +import { TagResolver } from './resolvers/tags.resolver'; + +@NgModule({ + declarations: [ + NewsComponent, + PostHeaderComponent, + PostListComponent, + PostDetailsComponent, + PostCardComponent, + PostModalFiltersComponent, + PostPublishComponent, + ], + imports: [CommonModule, PostRoutingModule, SharedModule], + providers: [TagResolver], +}) +export class PostModule {} diff --git a/src/app/post/resolvers/tags.resolver.ts b/src/app/post/resolvers/tags.resolver.ts new file mode 100644 index 0000000000000000000000000000000000000000..6f92f989e8b3b4d3b4a12a9322ef41f0a19d91bf --- /dev/null +++ b/src/app/post/resolvers/tags.resolver.ts @@ -0,0 +1,21 @@ +import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, Resolve, Router } from '@angular/router'; +import { Observable } from 'rxjs'; +import { map, catchError } from 'rxjs/operators'; +import { TagWithMeta } from '../models/tagWithMeta.model'; +import { PostService } from '../services/post.service'; + +@Injectable() +export class TagResolver implements Resolve<TagWithMeta> { + constructor(private postService: PostService, private router: Router) {} + + resolve(): Observable<TagWithMeta> { + return this.postService.getTags().pipe( + map((res) => res), + catchError(() => { + this.router.navigate(['/home']); + return new Observable<TagWithMeta>(); + }) + ); + } +} diff --git a/src/app/post/services/post.service.spec.ts b/src/app/post/services/post.service.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..913642b87e73bd219c4d1f0d2c6e6d161662583f --- /dev/null +++ b/src/app/post/services/post.service.spec.ts @@ -0,0 +1,16 @@ +import { TestBed } from '@angular/core/testing'; + +import { PostService } from './post.service'; + +describe('PostService', () => { + let service: PostService; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(PostService); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/post/services/post.service.ts b/src/app/post/services/post.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..b0fc02fb257ff31679d55e5ca1f0b63a9b0e0439 --- /dev/null +++ b/src/app/post/services/post.service.ts @@ -0,0 +1,59 @@ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; +import { Post } from '../models/post.model'; +import { TagEnum } from '../enum/tag.enum'; +import { PostWithMeta } from '../models/postWithMeta.model'; +import { Tag } from '../models/tag.model'; +import { TagWithMeta } from '../models/tagWithMeta.model'; + +@Injectable({ + providedIn: 'root', +}) +export class PostService { + private readonly baseUrl = 'api/posts'; + constructor(private http: HttpClient) {} + + public getPost(idPost: string): Observable<PostWithMeta> { + return this.http.get<PostWithMeta>(`${this.baseUrl}/` + idPost).pipe( + map((item: PostWithMeta) => { + item.posts.forEach((post) => { + post = this.addAuthorToPost(post); + }); + return new PostWithMeta(item); + }) + ); + } + + public getPosts(page: number, tags?: string[]): Observable<PostWithMeta> { + if (!tags) { + return this.http + .get<PostWithMeta>( + `${this.baseUrl}?page=${page}&include=tags,authors&filter=tag:-[${TagEnum.aLaUne},${TagEnum.appels}]` + ) + .pipe(map((item: PostWithMeta) => new PostWithMeta(item))); + } + let tagsString = ''; + // Transform tab filters to string filters + tags.forEach((tag, index) => { + tagsString += tag; + if (index != tags.length - 1) { + tagsString += '+tags:'; + } + }); + return this.http + .get<PostWithMeta>(`${this.baseUrl}?include=tags,authors&filter=tags:${encodeURIComponent(tagsString)}`) + .pipe(map((item: PostWithMeta) => new PostWithMeta(item))); + } + + public getTags(): Observable<TagWithMeta> { + return this.http.get<TagWithMeta>(`${this.baseUrl}/tags`); + } + + private addAuthorToPost(post: Post): Post { + post.author = post.excerpt; + post.excerpt = post.html.replace(/<[^>]*>/g, ''); + return post; + } +} diff --git a/src/app/profile/profile.component.html b/src/app/profile/profile.component.html index da389cd0f772d5f24178acc9d757e6eb1c6b074e..66be72664b42d3c789ddd3e652bc1d05581d41c1 100644 --- a/src/app/profile/profile.component.html +++ b/src/app/profile/profile.component.html @@ -1,9 +1,9 @@ <div fxLayout="column" class="content-container full-screen" *ngIf="userProfile"> <div class="profileSection"> <div class="section-container" fxLayout="row"> - <svg class="cameraProfile" aria-hidden="true"> - <use [attr.xlink:href]="'assets/ico/sprite.svg#camera'"></use> - </svg> + <ng-container *ngIf="userProfile.profileImage"> + <img class="cameraProfile" alt="image of profile" src="userProfile.profileImage" /> + </ng-container> <div class="profileInformation" fxLayoutGap="18px" fxLayout="column"> <div fxLayout="row" fxLayoutAlign="space-between center"> <p class="profileName">{{ userProfile.name | titlecase }} {{ userProfile.surname | titlecase }}</p> diff --git a/src/app/profile/services/profile.service.ts b/src/app/profile/services/profile.service.ts index 370137312c0da1f504f624ec8be949cfc7683559..2f044a5f52502d5d275524387de0ec6d6bacf647 100644 --- a/src/app/profile/services/profile.service.ts +++ b/src/app/profile/services/profile.service.ts @@ -40,7 +40,6 @@ export class ProfileService { if (!this.currentProfile) { return false; } - console.log(this.currentProfile.pendingStructuresLink); return this.currentProfile.pendingStructuresLink.includes(idStructure); } 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 5bfb99bbf029f3be7c478223e83dddfe3b800a30..e04af8369835b9022f41bad9143b2c680460b379 100644 --- a/src/app/shared/components/address-autocomplete/address-autocomplete.component.ts +++ b/src/app/shared/components/address-autocomplete/address-autocomplete.component.ts @@ -20,7 +20,12 @@ export class AddressAutocompleteComponent implements OnInit { ngOnInit(): void { if (this.address) { - const address_str = this.address.numero + ' ' + this.address.street + ' ' + this.address.commune; + 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; } } @@ -28,7 +33,7 @@ export class AddressAutocompleteComponent implements OnInit { if (!this.isAlreadySearching) { this.isAlreadySearching = true; this.addressService.searchAddress(searchString).subscribe((data) => { - this.data = data.hits.hits.slice(0, this.AUTOCOMPLETE_NBR); + this.data = data.features; this.isAlreadySearching = false; }); } @@ -37,9 +42,9 @@ export class AddressAutocompleteComponent implements OnInit { public selectedResult(hit: any): void { const address = new Address(); - address.numero = hit._source['data-fr'].properties.numero_str; - address.street = hit._source['data-fr'].properties.voie_str; - address.commune = hit._source['data-fr'].properties.commune_str; + address.numero = hit.properties.housenumber ? hit.properties.housenumber : null; + address.street = hit.properties.street; + address.commune = hit.properties.city; const value = this.parseHitToAddress(hit); // Set input value this.searchAddress.nativeElement.value = value; @@ -50,6 +55,9 @@ export class AddressAutocompleteComponent implements OnInit { } public parseHitToAddress(hit: any): string { - return `${hit._source['data-fr'].properties.numero_str} ${hit._source['data-fr'].properties.voie_str} ${hit._source['data-fr'].properties.commune_str}`; + if (hit.properties.housenumber) { + return `${hit.properties.housenumber} ${hit.properties.street} ${hit.properties.city}`; + } + return `${hit.properties.street} ${hit.properties.city}`; } } diff --git a/src/app/shared/components/button/button.component.scss b/src/app/shared/components/button/button.component.scss index 04a71d5474b03e28d28e5f30fb4f697387116d54..4cea9a7352ddd480b6aa1f64232a1fe4c0fefe45 100644 --- a/src/app/shared/components/button/button.component.scss +++ b/src/app/shared/components/button/button.component.scss @@ -48,7 +48,6 @@ button { border-radius: 4px; @include btn-bold; font-size: 16px; - border-radius: 4px; &.withIcon { color: $black; height: 36px; diff --git a/src/app/shared/components/svg-icon/svg-icon.component.scss b/src/app/shared/components/svg-icon/svg-icon.component.scss index e688256ea4c086a50b6e48e39f31194ed42bdfcc..ceb7b8decc61a40756a3bcedb75648657f63d89b 100644 --- a/src/app/shared/components/svg-icon/svg-icon.component.scss +++ b/src/app/shared/components/svg-icon/svg-icon.component.scss @@ -3,12 +3,20 @@ display: inline-block; height: 2em; width: 1.5em; + &.icon-28 { + width: 28px; + height: 28px; + } &.icon-32 { width: 2em; } &.icon-75 { width: 4.688em; } + &.icon-80 { + height: 80px; + width: 80px; + } &.validation { height: 100%; width: 26px; @@ -19,6 +27,14 @@ opacity: 0.8; } } + &.white { + fill: $white; + stroke: $white; + path { + stroke: $white; + fill: $white; + } + } &.grey { fill: $grey-3; stroke: $grey-3; diff --git a/src/app/shared/service/windowScroll.service.ts b/src/app/shared/service/windowScroll.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..ebdf325b8451d76da2c2750878956c9ad5d15b2d --- /dev/null +++ b/src/app/shared/service/windowScroll.service.ts @@ -0,0 +1,16 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; + +@Injectable({ + providedIn: 'root', +}) +export class WindowScrollService { + scrollY = new BehaviorSubject(null); + scrollY$ = this.scrollY.asObservable(); + + constructor() {} + + public updateScrollY(value: Event): void { + this.scrollY.next(value); + } +} diff --git a/src/app/structure-list/components/card/card.component.html b/src/app/structure-list/components/card/card.component.html index 1111644351601efa7e80b94c4aed177aa1b68b5d..ca492505150b2e60a136b393172950367583a457 100644 --- a/src/app/structure-list/components/card/card.component.html +++ b/src/app/structure-list/components/card/card.component.html @@ -1,6 +1,6 @@ <div class="structure" fxLayout="column" (click)="cardClicked()" (mouseenter)="cardHover()"> <div class="headerStructure" fxLayout="row" fxLayoutAlign="space-between center" fxLayoutGap="16px"> - <span class="structure-name">{{ structure.structureName }}</span> + <span class="structure-name" [ngClass]="{ notClaimed: !isClaimed }">{{ structure.structureName }}</span> <div *ngIf="structure.distance" class="distanceStructure" diff --git a/src/app/structure-list/components/card/card.component.scss b/src/app/structure-list/components/card/card.component.scss index 687abf098d16804365bd2c3b0d1dd13940809f52..fe17d873498c1c91b65ba030f42843cfd067253b 100644 --- a/src/app/structure-list/components/card/card.component.scss +++ b/src/app/structure-list/components/card/card.component.scss @@ -17,11 +17,17 @@ font-style: italic; } .structure-name { + &.notClaimed { + color: $red-info; + } color: $grey-1; @include cn-bold-18; padding-bottom: 5px; width: 100%; - text-transform: capitalize; + text-transform: lowercase; + &::first-letter { + text-transform: uppercase; + } } .distanceStructure { @include cn-regular-16; diff --git a/src/app/structure-list/components/card/card.component.ts b/src/app/structure-list/components/card/card.component.ts index ed8b3158f0c7c573c571d644a3c6eb1a1bbc3206..b3a414f4a8fd446011c456f9652fe29a26ae8f7a 100644 --- a/src/app/structure-list/components/card/card.component.ts +++ b/src/app/structure-list/components/card/card.component.ts @@ -1,6 +1,9 @@ import { Component, Input, Output, OnInit, EventEmitter } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; import { Structure } from '../../../models/structure.model'; +import { ProfileService } from '../../../profile/services/profile.service'; import { GeojsonService } from '../../../services/geojson.service'; +import { StructureService } from '../../../services/structure.service'; @Component({ selector: 'app-card', @@ -11,9 +14,24 @@ export class CardComponent implements OnInit { @Input() public structure: Structure; @Output() public showDetails: EventEmitter<Structure> = new EventEmitter<Structure>(); @Output() public hover: EventEmitter<Structure> = new EventEmitter<Structure>(); + public isClaimed = true; - constructor(private geoJsonService: GeojsonService) {} - ngOnInit(): void {} + constructor( + private route: ActivatedRoute, + private router: Router, + private profileService: ProfileService, + private structureService: StructureService + ) {} + ngOnInit(): void { + if (this.profileService.isAdmin()) { + this.setClaimIndicator(); + } + } + + // Check if structure haven't owners to help admin vision. + async setClaimIndicator() { + this.isClaimed = await this.structureService.isClaimed(this.structure._id, null).toPromise(); + } /** * Display distance in m or km according to value @@ -28,6 +46,12 @@ export class CardComponent implements OnInit { public cardClicked(): void { this.showDetails.emit(this.structure); + this.router.navigate([], { + relativeTo: this.route, + queryParams: { + id: this.structure._id, + }, + }); } public cardHover(): void { diff --git a/src/app/structure-list/components/search/search.component.html b/src/app/structure-list/components/search/search.component.html index 5294bc01946780b19cc205741efe82869243ec0b..f333a5f73879143aff92319dbbf9bd5ace099416 100644 --- a/src/app/structure-list/components/search/search.component.html +++ b/src/app/structure-list/components/search/search.component.html @@ -1,6 +1,9 @@ <div class="block"> <div class="header"> - <span class="title">Acteurs de la médiation numérique</span> + <span class="title" + >Recherche d’acteur <br /> + du réseau d’inclusion numérique</span + > </div> <div class="content" fxLayout="column"> <div class="searchSection"> @@ -12,7 +15,7 @@ (ngSubmit)="applyFilter(searchForm.value.searchTerm)" > <div class="inputSection" fxLayout="row" fxLayoutAlign="space-between center"> - <input type="text" formControlName="searchTerm" placeholder="Rechercher une commune, une association..." /> + <input type="text" formControlName="searchTerm" placeholder="Une commune, une association..." /> <button (click)="clearInput()" class="icon close" type="button"><div class="ico-close-search"></div></button> </div> <app-button @@ -91,7 +94,7 @@ </div> </div> <div class="footerSearchSection isntPhoneContent" fxLayout="row" fxLayoutAlign="space-between center"> - <div class="checkbox"> + <div class="checkbox no-width"> <div class="checkboxItem"> <label> <input diff --git a/src/app/structure-list/components/search/search.component.scss b/src/app/structure-list/components/search/search.component.scss index 657eeeffebacdf3e224e973e42a0044e3630e76e..30116fa01b02b8d72a836fb5e1dff70cdebd1113 100644 --- a/src/app/structure-list/components/search/search.component.scss +++ b/src/app/structure-list/components/search/search.component.scss @@ -10,10 +10,9 @@ .header { .title { @include cn-bold-26; - padding: 16px 0 16px 0; + padding-bottom: 16px; display: flex; align-items: center; - text-transform: uppercase; } } .content { @@ -60,12 +59,13 @@ } } .selected { - border-color: $primary-color !important; - color: inherit; + background-color: $secondary-color; + border-color: $secondary-color !important; + color: $white; .arrow { background-color: transparent; - border-bottom: 1px solid $primary-color; - border-right: 1px solid $primary-color; + border-bottom: 1px solid $white; + border-right: 1px solid $white; transform: translateY(25%) rotate(-135deg); margin: 0 5px 0 10px; height: 7px; @@ -118,7 +118,6 @@ } a { @include hyperlink; - width: 100%; text-align: right; } diff --git a/src/app/structure-list/components/structure-details/structure-details.component.html b/src/app/structure-list/components/structure-details/structure-details.component.html index 2e865d93f5335b273cd93956684749734cf5af3b..160c48a0b30d7d0a7d4442e9d6e546c97bf10a8d 100644 --- a/src/app/structure-list/components/structure-details/structure-details.component.html +++ b/src/app/structure-list/components/structure-details/structure-details.component.html @@ -1,7 +1,7 @@ <div class="structrue-details-container" *ngIf="structure && !isLoading"> <!-- Header info --> <div fxLayout="row" fxLayoutAlign="end center"> - <div (click)="close(false)" class="ico-close-details"></div> + <div (click)="close()" class="ico-close-details"></div> </div> <div fxLayout="row" class="structure-details-block" fxLayoutAlign="baseline baseline" fxLayoutGap="8px"> <div fxLayout="column" fxLayoutGap="10px" fxFlex="100%"> @@ -196,6 +196,14 @@ <div *ngFor="let public of structure.publics" fxLayout="row" fxLayoutAlign="none flex-end" fxLayoutGap="8px"> <p class="no-margin">{{ getPublicLabel(public) }}</p> </div> + <div + *ngFor="let accompaniment of structure.publicsAccompaniment" + fxLayout="row" + fxLayoutAlign="none flex-end" + fxLayoutGap="8px" + > + <p class="no-margin">{{ accompaniment }}</p> + </div> </div> </div> </div> @@ -328,7 +336,7 @@ <app-modal-confirmation [openned]="claimModalOpenned" [content]=" - 'Voulez-vous vraiment revendiquer cette structure ? Une demande sera envoyée a l\'administrateur pour validation' + 'Voulez-vous vraiment revendiquer cette structure ? Une demande sera envoyée à l\'administrateur pour validation' " (closed)="claimStructure($event)" ></app-modal-confirmation> diff --git a/src/app/structure-list/components/structure-details/structure-details.component.scss b/src/app/structure-list/components/structure-details/structure-details.component.scss index 19284a7cc69c13612863296b2667cefa0dfa7332..77a9025cc2ea1a08097687f61b7cfa76d1b9acda 100644 --- a/src/app/structure-list/components/structure-details/structure-details.component.scss +++ b/src/app/structure-list/components/structure-details/structure-details.component.scss @@ -18,7 +18,7 @@ a { left: 0; max-width: 980px; width: 100%; - height: calc(100vh - #{$header-height} - #{$footer-height}); + height: calc(100vh - #{$header-height} - #{$footer-height} - 20px); padding: 10px 24px; overflow: auto; @media #{$tablet} { 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 9604623b998ad702839646fcd29bad779078a6e6..2bea610b866f383a497841222d6c0497d8b063ae 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 @@ -107,8 +107,10 @@ export class StructureDetailsComponent implements OnInit { } } - public close(refreshRequired: boolean): void { - this.closeDetails.emit(refreshRequired); + public close(): void { + this.router.navigate([], { + relativeTo: this.route, + }); } public print(): void { @@ -202,7 +204,7 @@ export class StructureDetailsComponent implements OnInit { case PublicCategorie.young: return 'Jeunes (16 - 25 ans)'; case PublicCategorie.adult: - return 'Adultes (25 - 65 ans)'; + return 'Adultes'; case PublicCategorie.elderly: return 'Séniors (+ de 65 ans)'; case PublicCategorie.all: diff --git a/src/app/structure-list/structure-list.component.ts b/src/app/structure-list/structure-list.component.ts index 45624ec9e82de52c0c5bb07504e1ae6719840317..22404f28f83b5e1d3da84f4b27216dc6b0a024b0 100644 --- a/src/app/structure-list/structure-list.component.ts +++ b/src/app/structure-list/structure-list.component.ts @@ -3,6 +3,8 @@ import { Filter } from './models/filter.model'; import { Structure } from '../models/structure.model'; import { GeoJson } from '../map/models/geojson.model'; import * as _ from 'lodash'; +import { ActivatedRoute, Router } from '@angular/router'; +import { StructureService } from '../services/structure.service'; @Component({ selector: 'app-structure-list', @@ -28,11 +30,29 @@ export class StructureListComponent implements OnChanges { private arrayChunked: Structure[][] = []; private chunck = 10; - constructor() {} + constructor(private route: ActivatedRoute, private router: Router, private structureService: StructureService) { + this.route.queryParams.subscribe((queryParams) => { + if (queryParams.id) { + if (!this.structure) { + this.structureService.getStructure(queryParams.id).subscribe((s) => { + this.showDetails(new Structure(s)); + }); + } + } else { + this.closeDetails(); + } + }); + } ngOnChanges(changes: SimpleChanges): void { if (changes.selectedStructure && this.selectedStructure) { this.showDetails(this.selectedStructure); + this.router.navigate([], { + relativeTo: this.route, + queryParams: { + id: this.selectedStructure._id, + }, + }); } if (changes.structureList) { this.structuresListChunked = this.chunckAnArray(this.structureList); diff --git a/src/app/user-verification/user-verification.component.html b/src/app/user-verification/user-verification.component.html index 628bb8efe98b0575616bac18c89923a28424e1f0..63417c23d5c855dabf6714a97a14fc85df52be3d 100644 --- a/src/app/user-verification/user-verification.component.html +++ b/src/app/user-verification/user-verification.component.html @@ -1,44 +1,74 @@ <div fxLayout="column" class="content-container full-screen"> <p *ngIf="!verificationSuccess && !verificationIssue">Votre email est en cours de vérification ...</p> - <div *ngIf="verificationSuccess"> - <div class="title"> - <h3 *ngIf="structure"> - Bravo !<br /> - Votre compte et votre structure ont bien été référencés. - </h3> - <h3 *ngIf="!structure"> - Bravo !<br /> - Votre compte a bien été créé. - </h3> - </div> - <div *ngIf="structure" class="structureCard"> - <div class="structureInfo" fxLayout="column" fxLayoutGap="14px"> - <div fxLayout="row" fxLayoutAlign="space-between start" fxLayoutGap="20px"> - <a class="structureName" routerLink="/home" [state]="{ data: structure }">{{ structure.structureName }}</a> + <div class="formDiv" *ngIf="verificationSuccess"> + <div *ngIf="structure"> + <div class="title"> + <h1 class="title-form">Bravo, votre compte et votre structure ont bien été référencés !</h1> + </div> + <div class="structureInfoBlock" fxLayout="row" fxLayoutAlign="center"> + <div class="structureInfoContent" fxLayout="column"> + {{ structure.structureName }} + <span>{{ structure.structureType }}</span> + </div> + <div class="validateSvg"> + <svg class="validate" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#checkVector'"></use> + </svg> </div> </div> + <div class="btnSection" fxLayout="row" fxLayoutAlign="space-around center"> + <button + *ngIf="verificationSuccess" + class="btn" + routerLink="/home" + [queryParams]="{ id: structure._id }" + [state]="{ data: structure }" + > + Voir ma structure + </button> + </div> + </div> + <div *ngIf="!structure"> + <div> + <h1 class="title-form">Une dernière validation de Rés'in et votre structure vous sera attribuée !</h1> + <div style="font-style: italic">Cela prendra 3 jours maximum si nous ne sommes pas le weekend ;)</div> + <svg class="formClock" aria-hidden="true"> + <use [attr.xlink:href]="'assets/form/sprite.svg#formClock'"></use> + </svg> + </div> </div> </div> <p *ngIf="verificationIssue"> Une erreur est survenue lors de la validation de votre email... Veuillez envoyer un mail au support. </p> - <!-- TypeForm --> - <div *ngIf="!verificationIssue"> - <iframe - *ngIf="structure" - class="typeform-widget custom-form" - title="typeform" - src="https://form.typeform.com/to/m7DV3CdW?typeform-medium=embed-snippet" - ></iframe> - <div - *ngIf="!structure" - class="typeform-widget custom-form" - data-url="https://form.typeform.com/to/ASJH3B7Z?typeform-medium=embed-snippet" - ></div> - </div> - <div class="btnSection" fxLayout="row" fxLayoutAlign="space-around center"> - <button *ngIf="structure && verificationSuccess" class="btn" routerLink="/home" [state]="{ data: structure }"> - Voir ma structure - </button> + <!-- formulaire --> + <div class="formDiv" *ngIf="!verificationIssue"> + <div *ngIf="!structure"> + En attendant, vous pouvez participer à l'amélioration de Rés'in en répondant à ces quelques questions + </div> + <div *ngIf="structure"> + Donnez nous votre avis: vous pouvez participer à l'amélioration de Rés'in en répondant à ces quelques questions + </div> + <div fxLayout="row" fxLayoutAlign="center center" fxLayoutGap="24px" [style.margin-top]="'50px'"> + <button class="button" routerLink="/home">Je passe mon tour</button> + <a + *ngIf="structure" + target="_blank" + class="btn custom-link" + rel="noopener noreferrer" + [href]="'https://form.typeform.com/to/m7DV3CdW?typeform-medium=embed-snippet'" + > + Nous aider + </a> + <a + *ngIf="!structure" + target="_blank" + class="btn custom-link" + rel="noopener noreferrer" + [href]="'https://form.typeform.com/to/ASJH3B7Z?typeform-medium=embed-snippet'" + > + Nous aider + </a> + </div> </div> </div> diff --git a/src/app/user-verification/user-verification.component.scss b/src/app/user-verification/user-verification.component.scss index 8fb73ba431f51da2407dd97c5b93067df7e95554..701ffdf0907969999c328afff40031e0dcd7d98e 100644 --- a/src/app/user-verification/user-verification.component.scss +++ b/src/app/user-verification/user-verification.component.scss @@ -16,8 +16,9 @@ border: 0; color: $white; height: 40px; - width: 192px; - @include btn-bold; + width: 244px; + text-decoration: none; + font-size: 16px !important; } .btnSection { @media #{$large-phone} { @@ -46,9 +47,58 @@ // Override button style to be the same as typeform button button { margin: 0px; + border: none; + background: none; max-width: 100%; - font-size: 24px !important; + cursor: pointer; + text-decoration: underline; + font-size: 16px !important; line-height: 32px !important; - min-height: 48px; - width: 245px !important; + min-height: 40px; + width: 244 !important; +} + +.formDiv { + max-width: 530px; + padding-bottom: 30px; + margin: 0 auto; +} + +.title-form { + font-size: 26px; +} + +.structureInfoBlock { + background: $green-1; + color: $white; + padding: 16px; + border-radius: 6px; + @include cn-bold-18; + .structureInfoContent { + width: 100%; + } + span { + font-style: italic; + @include cn-regular-14; + } + .validateSvg { + stroke: $white; + text-align: right; + svg { + height: 14px; + width: 14px; + } + } +} + +.formClock { + width: 100%; + height: 146px; + margin: 24px; +} + +.custom-link { + display: flex; + align-items: center; + justify-content: center; } diff --git a/src/assets/form/sprite.svg b/src/assets/form/sprite.svg index 1008b4e01af58916b33decdb18da3caa89c2a926..b351b70d147e51774524c0c489d11230d537d96a 100644 --- a/src/assets/form/sprite.svg +++ b/src/assets/form/sprite.svg @@ -343,4 +343,10 @@ <path d="M8 13.8182L11.8889 17L18 10" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/> </symbol> +<symbol id="formClock" viewBox="0 0 146 146" fill="none" xmlns="http://www.w3.org/2000/svg"> +<circle cx="73.2273" cy="73.8401" r="67.2273" fill="#EAF8FB" stroke="#348899" stroke-width="12"/> +<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> + + </svg> diff --git a/src/assets/ico/sprite.svg b/src/assets/ico/sprite.svg index 748235c0a0461254caeaa04b05c826036ee2ebb0..a8f21b0b4bfe20ff720b5863195a7fe7d46ebe8a 100644 --- a/src/assets/ico/sprite.svg +++ b/src/assets/ico/sprite.svg @@ -204,6 +204,26 @@ <rect x="5" y="21" width="23" height="2" rx="1" fill="#333333"/> </symbol> +<symbol id="news-location" viewBox="0 0 29 31" xmlns="http://www.w3.org/2000/svg"> +<path d="M13.8789 7.40777L13.8789 1.18555" stroke-linecap="round" stroke-linejoin="round"/> +<path d="M13.3789 3.44639V1.86578C13.3665 1.85795 13.3533 1.84995 13.3392 1.84189C13.2087 1.76732 13.0017 1.68555 12.7122 1.68555C12.4228 1.68555 12.2158 1.76732 12.0853 1.84189C12.0712 1.84995 12.058 1.85795 12.0456 1.86578V3.44639C12.2373 3.38974 12.4598 3.35221 12.7122 3.35221C12.9647 3.35221 13.1872 3.38974 13.3789 3.44639Z"/> +<path d="M11.0469 2.81338V4.39398C11.0345 4.40181 11.0212 4.40981 11.0071 4.41787C10.8766 4.49245 10.6696 4.57422 10.3802 4.57422C10.0908 4.57422 9.88378 4.49245 9.75328 4.41787C9.73917 4.40981 9.72592 4.40181 9.71354 4.39398V2.81338C9.90529 2.87003 10.1278 2.90755 10.3802 2.90755C10.6326 2.90755 10.8551 2.87003 11.0469 2.81338Z"/> +<path d="M4.34813 13.1299L14.2096 7.21298L24.0711 13.1299H4.34813Z"/> +<path d="M3.04297 14.1299H25.3763V14.1854C25.3763 14.4616 25.1524 14.6854 24.8763 14.6854H3.54297C3.26683 14.6854 3.04297 14.4616 3.04297 14.1854V14.1299Z" stroke-width="0.777778"/> +<path d="M3.04297 27.3521H25.3763V27.9076H3.04297V27.3521Z" stroke-width="0.777778"/> +<path d="M0.710938 29.6855H27.7109V30.2411H0.710938V29.6855Z" stroke-width="0.777778"/> +<rect x="5.37891" y="16.4634" width="1.33333" height="9.11111"/> +<rect x="10.8203" y="16.4634" width="1.33333" height="9.11111"/> +<rect x="16.2656" y="16.4634" width="1.33333" height="9.11111"/> +<rect x="21.7109" y="16.4634" width="1.33333" height="9.11111"/> +</symbol> + +<symbol id="news-public" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"> +<path d="M23.5985 23.9446C24.6326 23.3273 25.3251 22.1973 25.3251 20.9055C25.3251 18.9522 23.7416 17.3687 21.7882 17.3687C19.8349 17.3687 18.2514 18.9522 18.2514 20.9055C18.2514 22.1973 18.9439 23.3273 19.9779 23.9446C18.4389 24.6362 17.3672 26.1825 17.3672 27.9792V29.5265H26.2093V27.9792C26.2093 26.1825 25.1376 24.6362 23.5985 23.9446Z" stroke="none"/> +<path d="M11.4423 23.9446C12.4763 23.3273 13.1688 22.1973 13.1688 20.9055C13.1688 18.9522 11.5853 17.3687 9.63199 17.3687C7.67865 17.3687 6.09515 18.9522 6.09515 20.9055C6.09515 22.1973 6.78766 23.3273 7.82169 23.9446C6.28266 24.6362 5.21094 26.1825 5.21094 27.9792V29.5265H14.053V27.9792C14.053 26.1825 12.9813 24.6362 11.4423 23.9446Z" stroke="none"/> +<path d="M16.9696 9.5759C18.0037 8.95863 18.6962 7.82861 18.6962 6.53684C18.6962 4.5835 17.1127 3 15.1593 3C13.206 3 11.6225 4.5835 11.6225 6.53684C11.6225 7.82861 12.315 8.95863 13.349 9.5759C11.81 10.2675 10.7383 11.8139 10.7383 13.6105V15.1579H19.5804V13.6105C19.5804 11.8139 18.5087 10.2675 16.9696 9.5759Z" stroke="none"/> +</symbol> + <symbol id="calendar" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"> <path d="M8 10H5V13H8V10Z" fill="#333333"/> diff --git a/src/assets/logos/logo_1200.svg b/src/assets/logos/logo_1200.svg new file mode 100644 index 0000000000000000000000000000000000000000..91b2e0d3fce7350ee13d4af9d9a56d705b88d292 --- /dev/null +++ b/src/assets/logos/logo_1200.svg @@ -0,0 +1,5 @@ +<svg width="1200" height="1200" viewBox="0 0 1200 1200" fill="none" xmlns="http://www.w3.org/2000/svg"> +<rect width="1200" height="1200" fill="white"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M1081.08 485.317C1088.76 491.865 1095.17 500.125 1100.06 509.914C1104.88 519.765 1107.23 530.889 1107.43 543.279V742.456C1107.43 755.871 1096.57 766.675 1083.24 766.675H1082.8C1069.4 766.675 1058.61 755.803 1058.61 742.456V543.279C1058.48 532.219 1055.18 524.021 1048.51 518.808C1042.17 513.343 1034.23 510.736 1025.35 510.611C1016.46 510.548 1008.84 513.285 1002.24 518.305C995.637 523.325 992.396 531.527 992.464 542.52L992.841 742.334C992.841 755.682 982.049 766.554 968.654 766.554C955.259 766.554 944.467 755.745 944.467 742.334C944.467 722.215 944.521 696.098 944.533 690.574L944.535 689.522L944.153 542.138C944.086 529.302 946.308 517.797 951.07 508.139C955.829 498.413 961.862 490.279 969.731 483.987C977.286 477.69 985.918 472.926 995.821 469.686C1005.73 466.508 1015.38 465.048 1025.28 465.174C1035.18 465.3 1045.08 466.949 1054.8 470.383C1064.51 473.879 1073.14 478.836 1081.08 485.317ZM784.166 503.878C784.166 482.584 766.896 465.3 745.632 465.3C724.368 465.3 707.099 482.584 707.099 503.878V542.452H746.203V542.389C767.22 542.07 784.166 524.979 784.166 503.878ZM857.103 465.3C872.087 465.3 884.212 477.438 884.212 492.436V739.408C884.212 754.41 872.087 766.549 857.103 766.549C842.123 766.549 829.998 754.41 829.998 739.408V492.436C829.998 477.438 842.127 465.3 857.103 465.3Z" fill="#E30613"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M446.65 460.46C452.452 449.493 448.275 435.894 437.321 430.085C426.367 424.276 412.783 428.457 406.981 439.425L406.981 439.425C406.976 439.434 406.887 439.597 406.679 439.92C406.467 440.249 406.171 440.684 405.778 441.22C404.985 442.302 403.912 443.642 402.557 445.183C399.837 448.274 396.282 451.83 392.17 455.353C385.43 461.126 378.253 465.906 371.735 468.791C370.172 469.266 368.626 469.796 367.098 470.383C357.133 473.942 348.626 478.265 340.757 484.62C332.951 491.038 326.536 498.858 321.522 508.835C316.508 518.817 314.411 530.192 314.411 542.327L313.716 689.077V689.522V689.779C313.716 724.223 336.951 753.777 368.562 762.486L369.325 762.869L369.451 762.931C378.151 765.605 386.72 766.747 394.841 766.747C394.978 766.747 395.113 766.729 395.239 766.712C395.349 766.698 395.451 766.684 395.541 766.684C395.576 766.684 395.609 766.685 395.642 766.687C395.685 766.69 395.726 766.694 395.767 766.699C395.808 766.704 395.848 766.71 395.889 766.716C396 766.731 396.111 766.747 396.236 766.747C406.202 766.747 416.167 765.286 425.437 761.727C435.407 758.167 443.909 753.848 451.783 747.489C459.271 741.202 464.985 734.847 469.811 725.184C470.448 723.912 471.081 722.515 471.588 721.117C477.559 705.917 465.623 689.711 449.436 689.711C439.659 689.711 430.582 695.621 427.466 704.902C422.578 719.202 410.332 724.667 395.98 724.667C382.837 724.667 371.601 717.103 366.017 706.173C365.191 704.645 364.558 702.996 363.988 701.279C362.906 697.976 362.21 694.542 362.21 690.916C362.21 690.821 362.227 690.743 362.244 690.664C362.26 690.585 362.277 690.507 362.277 690.412C362.277 690.326 362.27 690.247 362.26 690.17C362.255 690.132 362.249 690.095 362.243 690.058C362.227 689.947 362.21 689.836 362.21 689.711V621.327H395.092C405.569 621.327 415.916 619.358 425.626 615.61C434.833 612.05 444.04 607.794 451.846 601.439C459.72 595.017 466.067 587.202 471.082 577.22C476.096 567.243 478.192 555.868 478.192 543.729V543.028C478.192 542.891 478.173 542.755 478.155 542.629V542.628C478.145 542.558 478.135 542.49 478.13 542.426C478.126 542.392 478.125 542.358 478.125 542.327H478.192C478.192 530.192 476.033 518.817 471.082 508.835C466.067 498.858 459.72 491.038 451.846 484.62C447.062 480.684 441.99 477.3 436.486 474.61C440.777 469.702 444.337 464.833 446.65 460.46ZM277.53 509.981C272.641 500.193 266.226 491.928 258.546 485.384C250.609 478.904 241.981 473.942 232.267 470.45C222.553 467.016 212.65 465.362 202.748 465.237C192.845 465.111 183.198 466.572 173.291 469.749C163.388 472.994 154.756 477.758 147.201 484.05C144.862 485.919 142.686 487.951 140.657 490.138C136.083 486.053 130.913 482.435 125.187 479.34C124.877 479.205 124.505 479.003 124.195 478.8C109.13 471.21 91.3711 482.477 91.03 499.312L91.0031 502.112C90.846 511.262 96.6367 519.069 104.964 522.83C108.968 524.61 112.254 527.257 114.754 530.641C118.392 535.157 120.639 540.387 121.628 546.129L122 689.585L121.998 690.651C121.986 696.204 121.932 722.298 121.932 742.402C121.932 755.808 132.724 766.617 146.124 766.617C159.514 766.617 170.31 755.75 170.31 742.339L169.929 542.524C169.861 531.531 173.102 523.329 179.706 518.309C186.309 513.289 193.927 510.552 202.81 510.615C211.694 510.741 219.631 513.348 225.978 518.813C229.277 521.419 231.823 524.79 233.47 528.853C236.963 537.307 244.581 543.347 253.72 543.473L256.516 543.535C273.337 543.729 285.143 526.314 278.037 510.997C277.844 510.678 277.655 510.296 277.53 509.981ZM419.09 567.881C425.505 562.919 429.055 554.34 429.055 543.661V542.902C429.055 532.223 425.505 523.707 419.09 518.687C411.979 513.667 404.869 510.804 395.603 510.804C386.338 510.804 378.532 513.667 372.117 518.687C365.707 523.644 362.151 532.223 362.151 542.902V575.696H395.603C404.869 575.696 412.675 572.901 419.09 567.881ZM635.244 612.814L583.378 564.96C572.712 555.297 568.654 545.634 568.654 535.468C568.654 519.199 579.823 505.474 597.599 505.474C613.028 505.474 621.979 514.88 627.496 529.877C630.418 537.823 637.717 543.288 646.161 543.288H646.349C659.875 543.288 669.265 530.003 665.014 517.105C655.112 487.043 632.191 465.241 595.566 465.241C549.854 465.241 519.832 491.173 519.832 537.504C519.832 572.074 535.575 591.97 555.887 609.259L606.164 652.476C622.921 666.709 630.032 679.419 630.032 696.201C630.032 715.018 619.366 727.216 600.068 727.216C584.006 727.216 573.278 719.526 566.356 703.953C562.486 695.311 554.294 689.527 544.835 689.527H543.57C526.3 689.527 515.253 707.639 522.745 723.211C535.947 750.604 561.211 767.444 595.494 767.444C643.737 767.444 676.812 742.532 676.812 692.134C676.951 654.566 656.126 632.131 635.244 612.814Z" fill="black"/> +</svg> diff --git a/src/assets/logos/resin.jpg b/src/assets/logos/resin.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2e7db87ce1a2a1c6359b707d9e8a6bc599f3ad42 Binary files /dev/null and b/src/assets/logos/resin.jpg differ diff --git a/src/assets/post/sprite.svg b/src/assets/post/sprite.svg new file mode 100644 index 0000000000000000000000000000000000000000..53003c36700969b4c82ee8a2e8ee9de0ed0c77da --- /dev/null +++ b/src/assets/post/sprite.svg @@ -0,0 +1,107 @@ +<svg xmlns="http://www.w3.org/2000/svg"> + +<symbol id="appels" viewBox="0 0 80 60" xmlns="http://www.w3.org/2000/svg"> +<path d="M1.66016 23.2006C4.67429 23.0597 8.52282 22.3132 12.7892 21.1547C17.5608 19.8591 22.9197 18.0302 28.3314 15.8906C38.369 11.9223 48.6614 6.85659 55.7703 2.08884V2.14843V2.22928V2.31051V2.39211V2.47407V2.5564V2.6391V2.72216V2.80559V2.88938V2.97352V3.05802V3.14288V3.2281V3.31367V3.39959V3.48586V3.57248V3.65944V3.74676V3.83441V3.92241V4.01075V4.09943V4.18845V4.27781V4.3675V4.45752V4.54788V4.63856V4.72958V4.82092V4.91259V5.00458V5.0969V5.18954V5.2825V5.37577V5.46937V5.56327V5.6575V5.75203V5.84688V5.94203V6.03749V6.13326V6.22933V6.32571V6.42239V6.51937V6.61664V6.71422V6.81209V6.91025V7.0087V7.10745V7.20649V7.30581V7.40542V7.50532V7.6055V7.70596V7.8067V7.90772V8.00901V8.11059V8.21243V8.31455V8.41694V8.5196V8.62253V8.72573V8.82918V8.93291V9.03689V9.14114V9.24565V9.35041V9.45543V9.5607V9.66622V9.772V9.87803V9.9843V10.0908V10.1976V10.3046V10.4119V10.5194V10.6271V10.7351V10.8433V10.9517V11.0604V11.1693V11.2784V11.3878V11.4974V11.6072V11.7172V11.8275V11.938V12.0487V12.1596V12.2708V12.3821V12.4937V12.6054V12.7174V12.8296V12.942V13.0546V13.1675V13.2805V13.3937V13.5071V13.6207V13.7345V13.8485V13.9628V14.0771V14.1917V14.3065V14.4215V14.5366V14.6519V14.7674V14.8831V14.999V15.1151V15.2313V15.3477V15.4643V15.581V15.6979V15.815V15.9323V16.0497V16.1673V16.2851V16.403V16.521V16.6393V16.7577V16.8762V16.9949V17.1137V17.2327V17.3519V17.4712V17.5906V17.7102V17.83V17.9498V18.0698V18.19V18.3103V18.4307V18.5513V18.672V18.7928V18.9137V19.0348V19.156V19.2774V19.3988V19.5204V19.6421V19.7639V19.8858V20.0079V20.1301V20.2523V20.3747V20.4972V20.6198V20.7425V20.8654V20.9883V21.1113V21.2344V21.3576V21.481V21.6044V21.7279V21.8515V21.9752V22.099V22.2229V22.3468V22.4709V22.595V22.7192V22.8435V22.9679V23.0923V23.2169V23.3415V23.4661V23.5909V23.7157V23.8406V23.9655V24.0905V24.2156V24.3408V24.466V24.5912V24.7166V24.8419V24.9674V25.0929V25.2184V25.344V25.4696V25.5953V25.7211V25.8468V25.9726V26.0985V26.2244V26.3503V26.4763V26.6023V26.7284V26.8544V26.9806V27.1067V27.2328V27.359V27.4852V27.6115V27.7377V27.864V27.9903V28.1166V28.243V28.3693V28.4956V28.622V28.7484V28.8748V29.0012V29.1275V29.2539V29.3803V29.5067V29.6331V29.7595V29.8859V30.0123V30.1387V30.265V30.3914V30.5177V30.6441V30.7704V30.8967V31.023V31.1492V31.2754V31.4017V31.5279V31.654V31.7802V31.9063V32.0323V32.1584V32.2844V32.4104V32.5363V32.6622V32.7881V32.9139V33.0397V33.1654V33.2911V33.4168V33.5424V33.6679V33.7934V33.9188V34.0442V34.1696V34.2948V34.42V34.5452V34.6703V34.7953V34.9203V35.0452V35.17V35.2947V35.4194V35.544V35.6686V35.793V35.9174V36.0417V36.1659V36.2901V36.4141V36.5381V36.662V36.7858V36.9095V37.0331V37.1566V37.2801V37.4034V37.5266V37.6498V37.7728V37.8957V38.0186V38.1413V38.2639V38.3864V38.5088V38.6311V38.7533V38.8754V38.9973V39.1191V39.2408V39.3624V39.4839V39.6053V39.7265V39.8476V39.9685V40.0894V40.2101V40.3307V40.4511V40.5714V40.6916V40.8116V40.9315V41.0512V41.1708V41.2903V41.4096V41.5288V41.6478V41.7667V41.8854V42.004V42.1224V42.2406V42.3587V42.4766V42.5944V42.712V42.8294V42.9467V43.0638V43.1808V43.2975V43.4141V43.5306V43.6468V43.7629V43.8788V43.9945V44.11V44.2254V44.3406V44.4555V44.5703V44.6849V44.7993V44.9136V45.0276V45.1414V45.2551V45.3685V45.4818V45.5948V45.7076V45.8203V45.9327V46.0449V46.1569V46.2687V46.3803V46.4917V46.6029V46.7138V46.8245V46.9351V47.0453V47.1554V47.2653V47.3749V47.4843V47.5934V47.7024V47.8111V47.9195V48.0278V48.1358V48.2435V48.3511V48.4583V48.5654V48.6722V48.7787V48.885V48.9911V49.0969V49.2024V49.3078V49.4128V49.5176V49.6221V49.7264V49.8304V49.9342V50.0377V50.1409V50.2439V50.3465V50.449V50.5511V50.653V50.7546V50.8559V50.957V51.0578V51.1582V51.2585V51.3584V51.458V51.5574V51.6565V51.7552V51.8537V51.9519V52.0498V52.1474V52.2448V52.3418V52.4385V52.5349V52.631V52.7268V52.8223V52.9175V53.0124V53.1069V53.2012V53.2952V53.3888V53.4821V53.5751V53.6678V53.7601V53.8521V53.9439V54.0352V54.1263V54.217V54.3074V54.3975V54.4872V54.5766V54.5932C48.6675 50.7584 38.3441 46.5962 28.2733 43.3173C18.0609 39.9923 7.95384 37.5244 1.66016 37.2769V23.2006Z" fill="none" stroke-width="2"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M56.7703 0.181641C42.7428 10.2013 12.6838 22.2249 0.660156 22.2249V38.2564C3.19182 38.2564 8.06936 39.0833 11.8822 39.8595L6.27117 53.4863C5.78047 56.4517 7.78661 59.2534 10.752 59.7441C13.7174 60.2349 16.5192 58.2287 17.0099 55.2633L19.8979 41.4627L19.6442 39.9086L19.5098 39.51L41.2658 9.45105H45.2737L21.5122 42.2809C34.1261 45.936 48.342 51.4756 56.7703 56.2918V28.5373L42.6898 47.8979H38.682L55.0188 25.106L56.7703 28.386V11.4099L32.9349 43.1831H28.9271L55.4659 7.44562L56.7703 10.1451V0.181641ZM25.4388 18.068H21.4309L12.6838 31.1271V37.1106L25.4388 18.068Z" stroke="none"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M64.9531 28.002C64.9531 29.1368 65.919 30.0566 67.1105 30.0566L77.178 30.0566C78.3695 30.0566 79.3353 29.1368 79.3353 28.002C79.3353 26.8673 78.3695 25.9474 77.178 25.9474L67.1105 25.9474C65.919 25.9474 64.9531 26.8673 64.9531 28.002Z" stroke="none"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M63.6036 16.1736C64.0749 17.2789 65.353 17.7927 66.4582 17.3214L75.7969 13.3389C76.9021 12.8675 77.416 11.5895 76.9447 10.4843C76.4734 9.37908 75.1953 8.86521 74.0901 9.33653L64.7514 13.3191C63.6462 13.7904 63.1323 15.0684 63.6036 16.1736Z" stroke="none"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M63.6036 39.4919C64.0749 38.3867 65.353 37.8728 66.4582 38.3441L75.7969 42.3267C76.9021 42.798 77.416 44.076 76.9447 45.1812C76.4734 46.2864 75.1953 46.8003 74.0901 46.329L64.7514 42.3464C63.6462 41.8751 63.1323 40.5971 63.6036 39.4919Z" stroke="none"/> +</symbol> + +<symbol id="projets" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"> +<mask id="path-1-inside-1" fill="white"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M4 7C4 5.34315 5.34315 4 7 4C8.65685 4 10 5.34315 10 7V24C10 25.6569 8.65685 27 7 27C5.34315 27 4 25.6569 4 24V7ZM7 26C8.10457 26 9 25.1046 9 24C9 22.8954 8.10457 22 7 22C5.89543 22 5 22.8954 5 24C5 25.1046 5.89543 26 7 26Z"/> +</mask> +<path d="M7 3C4.79086 3 3 4.79086 3 7H5C5 5.89543 5.89543 5 7 5V3ZM11 7C11 4.79086 9.20914 3 7 3V5C8.10457 5 9 5.89543 9 7H11ZM11 24V7H9V24H11ZM7 28C9.20914 28 11 26.2091 11 24H9C9 25.1046 8.10457 26 7 26V28ZM3 24C3 26.2091 4.79086 28 7 28V26C5.89543 26 5 25.1046 5 24H3ZM3 7V24H5V7H3ZM8 24C8 24.5523 7.55228 25 7 25V27C8.65685 27 10 25.6569 10 24H8ZM7 23C7.55228 23 8 23.4477 8 24H10C10 22.3431 8.65685 21 7 21V23ZM6 24C6 23.4477 6.44771 23 7 23V21C5.34315 21 4 22.3431 4 24H6ZM7 25C6.44772 25 6 24.5523 6 24H4C4 25.6569 5.34315 27 7 27V25Z" stroke="none" mask="url(#path-1-inside-1)"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M7 27H10L24 7H25.5L11.5 27H14L27.5 8L28 9.5L15.5 27H18L27.5 14L28 15.5L19.5 27H22L27.5 19.5L28 21L23.5 27H28V21V15.5V9.5V6H9.82929C9.93985 6.31278 10 6.64936 10 7V9L11.5 7H13L10 11.0909V14.4412L15.5 7H17L10 16.5789V21.0909L20 7H21.5L10 23.56V24C10 25.6569 8.65685 27 7 27Z" stroke="none"/> +<path d="M7 27H28V6.5H9.95852C9.9858 6.6626 10 6.82964 10 7V7.5H27V26H9.23611C8.68679 26.6137 7.8885 27 7 27Z" stroke="none"/> +<path d="M9 24C9 25.1046 8.10457 26 7 26C5.89543 26 5 25.1046 5 24C5 22.8954 5.89543 22 7 22C8.10457 22 9 22.8954 9 24Z" stroke="none"/> +</symbol> + +<symbol id="ressources" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"> +<path d="M3.5 25V13.0495C7.32281 13.9728 11.7651 14.5 16.5 14.5C20.828 14.5 24.9112 14.0595 28.5 13.2789V25C28.5 25.2761 28.2761 25.5 28 25.5H4C3.72386 25.5 3.5 25.2761 3.5 25Z" fill="none"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M20 6H13V8H20V6ZM13 4C11.8954 4 11 4.89543 11 6V9H22V6C22 4.89543 21.1046 4 20 4H13Z" stroke="none"/> +<path d="M28.5 13.2602C27.6168 13.4803 26.8068 13.7326 26.0024 13.9831L25.9955 13.9852C24.3831 14.4874 22.7659 14.9905 20.5 15.2722V15C20.5 14.1716 19.8284 13.5 19 13.5H14C13.1716 13.5 12.5 14.1716 12.5 15V15.2709C9.84798 14.949 7.85358 14.3349 5.87723 13.7256L5.87212 13.724C5.09326 13.4839 4.31292 13.2433 3.5 13.0242V9C3.5 8.72386 3.72386 8.5 4 8.5H28C28.2761 8.5 28.5 8.72386 28.5 9V13.2602Z"/> +<path d="M3 13.4095C3.7817 13.6107 4.59178 13.795 5.42722 13.9611L3 17.4286V13.4095Z" stroke="none"/> +<path d="M29 13.6541V16L22 26L18.5 26L26.8278 14.1031C27.5713 13.9674 28.296 13.8174 29 13.6541Z" stroke="none"/> +<path d="M29 18.1429V23.1429L27 26H23.5L29 18.1429Z" stroke="none"/> +<path d="M28.7003 25.7138C28.788 25.6278 28.8598 25.5259 28.9112 25.4126L28.7003 25.7138Z" stroke="none"/> +<path d="M21.3318 14.8118C22.6365 14.7087 23.9059 14.5647 25.1318 14.3832L17 26H13.5L19.1037 17.9947C19.6073 17.9428 20 17.5173 20 17V16.7143L21.3318 14.8118Z" stroke="none"/> +<path d="M17.6 18L12 26H8.50001L14.1 18H17.6Z" stroke="none"/> +<path d="M13.0602 17.3426L7.00001 26H4C3.84543 26 3.69905 25.9649 3.56839 25.9023L11.35 14.7858C11.8954 14.8318 12.4472 14.8707 13.0047 14.9022C13.0016 14.9344 13 14.967 13 15V17C13 17.1203 13.0213 17.2357 13.0602 17.3426Z" stroke="none"/> +<path d="M6.75572 14.2061C7.78653 14.3818 8.8514 14.5304 9.94511 14.6498L3 24.5714V19.5714L6.75572 14.2061Z" stroke="none"/> +<rect x="13.5" y="14.5" width="6" height="3" rx="0.5" fill="none"/> +</symbol> + +<symbol id="infos" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"> +<path d="M23 25.5H9.44949C10.0978 24.8647 10.5 23.9793 10.5 23V5.5H25.5V23C25.5 24.3807 24.3807 25.5 23 25.5Z" fill="none"/> +<rect x="12" y="16" width="12" height="1" rx="0.5" stroke="none"/> +<rect x="12" y="19" width="12" height="1" rx="0.5" stroke="none"/> +<rect x="12" y="22" width="12" height="1" rx="0.5" stroke="none"/> +<rect x="12" y="8" width="12" height="6" rx="1" stroke="none"/> +<path d="M11 12V13.5L5.00001 20.5V17.2273L9.60001 12H11Z" stroke="none"/> +<path d="M5.00001 22.5V22.2273L11 15.4091L11 18.5L6 24.5C5.48214 24.0507 5.00001 23.1722 5.00001 22.5Z" stroke="none"/> +<path d="M7.06819 24.8771C7.36151 24.9569 7.67471 25 8.00001 25C9.65686 25 11 23.8807 11 22.5V20.4091L7.06819 24.8771Z" stroke="none"/> +<path d="M8 12H5.00001L5 15.5L8 12Z" stroke="none"/> +<path d="M5.5 12.5H10.5V23C10.5 24.3807 9.38071 25.5 8 25.5C6.61929 25.5 5.5 24.3807 5.5 23V12.5Z" fill="none"/> +</symbol> + +<symbol id="formations" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M3 28V24.4C3 22.1088 4.1007 20.0762 5.79995 18.7998C4.80938 17.7598 4.2 16.3513 4.2 14.8C4.2 11.5967 6.79675 9 10 9C13.2033 9 15.8 11.5967 15.8 14.8C15.8 16.3513 15.1906 17.7598 14.2001 18.7998C15.8993 20.0762 17 22.1088 17 24.4V28H3ZM13.4307 19.4769C13.1256 19.2639 12.7998 19.0785 12.4568 18.9244C12.7774 18.7331 13.0738 18.5054 13.3403 18.2471C14.2405 17.3746 14.8 16.1527 14.8 14.8C14.8 12.149 12.651 10 10 10C7.34903 10 5.2 12.149 5.2 14.8C5.2 16.1527 5.75951 17.3746 6.65971 18.2471C6.92623 18.5054 7.2226 18.7331 7.54316 18.9244C7.20024 19.0785 6.87441 19.2639 6.56931 19.4769C5.01609 20.5613 4 22.362 4 24.4V27H16V24.4C16 22.362 14.9839 20.5613 13.4307 19.4769Z" stroke="none"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M2 6H30V22H16.5777C16.3879 21.4799 16.1381 20.9887 15.8369 20.5348L25.6379 7H24.1379L15.0488 19.5516C14.7868 19.2788 14.503 19.0273 14.2001 18.7998C15.1906 17.7598 15.8 16.3513 15.8 14.8C15.8 14.4589 15.7705 14.1246 15.7141 13.7996L20.6379 7H19.1379L15.2607 12.3543C14.8403 11.4515 14.1943 10.675 13.3952 10.0971L15.6379 7H14.1379L12.3353 9.48933C11.6208 9.17468 10.8308 9 10 9C9.70926 9 9.42352 9.02139 9.14426 9.06269L10.6379 7H9.13793L7.14742 9.74881C5.70291 10.5663 4.64387 11.9856 4.3108 13.666L3 15.4762V17.5476L4.28201 15.7772C4.46929 16.8805 4.96816 17.8775 5.68402 18.6744L5.28319 19.228C4.45784 19.9811 3.81311 20.9293 3.4223 22H2V6ZM29 7.19048V9.2619L20.5 21H19L29 7.19048ZM25.5 21H24L29 14.0952V16.1667L25.5 21ZM5.63793 7L3 10.6429V8.57143L4.13793 7H5.63793Z" stroke="none"/> +</symbol> + +<symbol id="etudes" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"> +<path d="M27.722 26.2329L22.4916 21.0959C24.0154 19.2877 24.9215 16.9452 24.9215 14.4384C24.8803 8.68493 20.2265 4 14.4607 4C8.69498 4 4 8.68493 4 14.4384C4 20.1918 8.69498 24.8767 14.4607 24.8767C16.9318 24.8767 19.2381 24.0137 21.009 22.5753L26.2394 27.7123C26.4453 27.9178 26.6924 28 26.9807 28C27.2278 28 27.5161 27.9178 27.722 27.7123C28.0927 27.3014 28.0927 26.6438 27.722 26.2329ZM6.0592 14.4384C6.0592 9.79452 9.80695 6.05479 14.4607 6.05479C19.1145 6.05479 22.8623 9.79452 22.8623 14.4384C22.8623 19.0822 19.1145 22.8219 14.4607 22.8219C9.80695 22.8219 6.0592 19.0411 6.0592 14.4384Z" stroke="none"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M14.7457 5.3282C14.0022 5.11446 13.2157 5 12.4015 5C12.2296 5 12.0588 5.00511 11.8895 5.01518L10.4509 6.97689C11.5862 6.37483 12.878 6.02499 14.2521 6.00129L14.7457 5.3282ZM13.0585 7.62894C9.87909 8.24863 7.5 11.0292 7.5 14.3836C7.5 14.6426 7.51448 14.8985 7.5427 15.1504L13.0585 7.62894ZM7.97683 16.8961L14.8566 7.51456C15.8686 7.57953 16.8194 7.85975 17.6638 8.30994L9.59266 19.316C8.89414 18.6378 8.33923 17.8141 7.97683 16.8961ZM6.34942 16.7776C6.12204 16.018 6 15.2141 6 14.3836C6 13.8626 6.04717 13.353 6.13749 12.8588L4.25314 15.4284C4.49144 16.3727 4.89089 17.2551 5.42099 18.0437L6.34942 16.7776ZM6.96335 18.2781C7.41071 19.1257 7.99942 19.8888 8.69862 20.5352L8.49887 20.8076C7.68288 20.3787 6.94656 19.8199 6.31708 19.1594L6.96335 18.2781ZM17.141 6.45253C16.8055 6.22416 16.4523 6.01946 16.084 5.84081L15.874 6.12727C16.3089 6.20341 16.7322 6.31273 17.141 6.45253ZM13.3275 21.1841C12.3621 21.0332 11.464 20.6823 10.6762 20.1762L18.8131 9.08041C19.5054 9.65324 20.0826 10.359 20.5064 11.159C20.5221 11.2167 20.5373 11.2746 20.5518 11.3328L13.3275 21.1841ZM21.157 12.9614C21.2528 13.4201 21.3031 13.8957 21.3031 14.3836C21.3031 17.9947 18.5458 20.9409 15.0011 21.2418L21.157 12.9614ZM9.9145 5.37067C6.48201 6.42403 4 9.60441 4 13.3836L4.00016 13.4357L9.9145 5.37067Z" stroke="none"/> +</symbol> + +<symbol id="dossiers" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M2 9C2 7.89543 2.89543 7 4 7H8C9.10457 7 10 7.89543 10 9V10H27C27.5523 10 28 10.4477 28 11V13H6.32973C5.84861 13 5.43568 13.3426 5.34691 13.8155L3.28171 24.8155C3.16616 25.431 3.63831 26 4.26454 26H3C2.44772 26 2 25.5523 2 25V9Z" stroke="none"/> +<path d="M5.72708 13.8721C5.78513 13.6528 5.98357 13.5 6.21044 13.5H29.1416C29.4697 13.5 29.7089 13.8107 29.6249 14.1279L26.7136 25.1279C26.6555 25.3472 26.4571 25.5 26.2302 25.5H3.2991C2.97097 25.5 2.73179 25.1893 2.81574 24.8721L5.72708 13.8721Z" fill="none"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M29.2607 17.2341L30.049 14.2559C30.1737 13.7846 29.9418 13.3205 29.5453 13.113L20.8378 26H23.3378L29.2607 17.2341ZM24.8378 26H26.1709C26.6247 26 27.0215 25.6945 27.1376 25.2559L28.2948 20.8837L24.8378 26ZM25.6216 13H28.1216L19.3378 26H16.8378L25.6216 13ZM24.1216 13H21.6216L12.8378 26H15.3378L24.1216 13ZM17.6216 13H20.1216L11.3378 26H8.83784L17.6216 13ZM16.1216 13H13.6216L4.83784 26H7.33784L16.1216 13ZM9.62162 13H12.1216L3.33784 26H3.20521C2.57898 26 2.10683 25.431 2.22239 24.8155L2.44717 23.6182L9.62162 13ZM8.12162 13H5.27041C5.26124 13 5.2521 13.0001 5.24299 13.0004L4.13187 14.6448L3.02434 20.544L8.12162 13Z" stroke="none"/> +</symbol> + +<symbol id="publishLogo" viewBox="0 0 310 273" fill="none" xmlns="http://www.w3.org/2000/svg"> +<g opacity="0.35" filter="url(#filter0_f)"> +<path d="M12 76.7061L181.621 30.7062L283.777 208.44L114.155 254.44L12 76.7061Z" fill="#348899"/> +</g> +<path d="M114.638 253.273L13.5131 77.3318L181.138 31.8732L282.263 207.814L114.638 253.273Z" fill="#EAF8FB" stroke="#79ACB6" stroke-width="2"/> +<path d="M56.0084 117.902C54.7257 115.671 55.8543 112.826 58.3181 112.08L188.148 72.8014C189.929 72.2624 191.847 73.0232 192.774 74.6367L215.093 113.467C216.376 115.699 215.247 118.544 212.783 119.289L82.9533 158.568C81.172 159.107 79.2544 158.346 78.327 156.733L56.0084 117.902Z" fill="#ABE6F2"/> +<path d="M72.5 81.3037L150.685 57.8712L154.671 64.8072L76.4866 88.2397L72.5 81.3037Z" fill="#117083"/> +<path d="M86.5 167.953L139.359 152.241L142.5 157.706L89.6408 173.418L86.5 167.953Z" fill="#117083"/> +<path d="M91.5 176.445L144.359 160.733L147.5 166.198L94.6408 181.91L91.5 176.445Z" fill="#117083"/> +<path d="M96.5 185.445L149.359 169.733L152.5 175.198L99.6408 190.91L96.5 185.445Z" fill="#117083"/> +<path d="M102.5 193.444L155.359 177.732L158.5 183.197L105.641 198.909L102.5 193.444Z" fill="#117083"/> +<path d="M107.5 202.444L160.359 186.732L163.5 192.197L110.641 207.909L107.5 202.444Z" fill="#117083"/> +<path d="M112.5 211.444L165.359 195.732L168.5 201.197L115.641 216.909L112.5 211.444Z" fill="#117083"/> +<path d="M116.5 221.444L169.359 205.732L172.5 211.197L119.641 226.909L116.5 221.444Z" fill="#117083"/> +<path d="M145.5 150.444L198.359 134.732L201.5 140.197L148.641 155.909L145.5 150.444Z" fill="#117083"/> +<path d="M151.5 158.444L204.359 142.732L207.5 148.197L154.641 163.909L151.5 158.444Z" fill="#117083"/> +<path d="M156.5 167.444L178.359 161.241L181.5 166.706L159.641 172.909L156.5 167.444Z" fill="#117083"/> +<path d="M100 84.6553L139.091 72.7225L143.078 79.6584L103.987 91.5912L100 84.6553Z" fill="#117083"/> +<g opacity="0.35" filter="url(#filter1_f)"> +<path d="M252.112 73.7334C249.503 71.652 246.024 71.6753 244.34 73.7856L235.054 85.4249L235.088 85.4519L190.698 141.075L205.252 152.855L190.571 141.242L189.299 142.837C188.606 143.704 188.299 144.837 188.429 146.05L186.205 161.648L185.788 163.604C185.445 165.216 187.089 166.528 188.585 165.835L189.273 165.516C189.436 165.526 189.6 165.521 189.763 165.502L205.18 159.287C206.391 159.144 207.427 158.594 208.12 157.726L209.393 156.131L209.391 156.129L253.778 100.509L253.779 100.51L263.064 88.8704C264.748 86.7602 263.999 83.3622 261.391 81.2807L252.112 73.7334Z" fill="#DC2A59"/> +</g> +<path d="M252.739 72.9577L252.739 72.9576L252.732 72.9518C249.854 70.6558 245.7 70.4733 243.554 73.1618L243.554 73.1619L234.269 84.8012L233.648 85.5792L233.682 85.6061L189.913 140.452L189.293 141.228L189.297 141.231L188.513 142.213C187.666 143.275 187.298 144.626 187.418 146.026L185.216 161.473L184.806 163.395C184.291 165.813 186.758 167.781 189.001 166.743L189.48 166.521C189.612 166.519 189.744 166.511 189.876 166.495L190.009 166.48L190.133 166.43L205.432 160.262C206.819 160.067 208.052 159.409 208.898 158.35L210.17 156.755L210.798 155.969L210.796 155.967L253.929 101.918L253.93 101.918L254.557 101.133L263.842 89.4942C265.986 86.807 264.889 82.7988 262.014 80.5023C262.013 80.5013 262.012 80.5002 262.01 80.4991L252.739 72.9577Z" fill="#E04971" stroke="#E0718E" stroke-width="2"/> +<path d="M244.336 73.7856C246.02 71.6754 249.499 71.652 252.108 73.7335L261.386 81.2808C263.995 83.3622 264.744 86.7602 263.06 88.8705L253.775 100.51L235.05 85.4249L244.336 73.7856Z" fill="#E04971"/> +<path d="M254.161 100.03L235.505 84.9298L190.698 141.076L209.354 156.176L254.161 100.03Z" fill="#E0718E"/> +<path d="M209.393 156.131L190.571 141.242L189.298 142.837C188.606 143.705 188.299 144.838 188.429 146.05L186.075 162.56C186.257 164.27 188.054 165.704 189.762 165.503L205.18 159.288C206.391 159.145 207.427 158.594 208.12 157.727L209.393 156.131Z" fill="#FDECF0"/> +<path d="M185.399 164.08C185.176 165.596 186.672 166.789 188.101 166.236L194.734 163.665C194.734 163.665 194.763 161.501 191.65 159.018C188.537 156.534 186.434 157.041 186.434 157.041L185.399 164.08Z" fill="#E04971"/> +<rect x="190.742" y="140.706" width="24.0099" height="2" transform="rotate(38.3738 190.742 140.706)" fill="white"/> +<rect x="236.152" y="84.0303" width="24.0422" height="2" transform="rotate(38.3738 236.152 84.0303)" fill="white"/> +<defs> +<filter id="filter0_f" x="0" y="18.7061" width="295.777" height="247.734" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"> +<feFlood flood-opacity="0" result="BackgroundImageFix"/> +<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/> +<feGaussianBlur stdDeviation="6" result="effect1_foregroundBlur"/> +</filter> +<filter id="filter1_f" x="173.742" y="60.1875" width="102.221" height="117.837" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"> +<feFlood flood-opacity="0" result="BackgroundImageFix"/> +<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/> +<feGaussianBlur stdDeviation="6" result="effect1_foregroundBlur"/> +</filter> +</defs> +</symbol> + +</svg> diff --git a/src/assets/scss/_buttons.scss b/src/assets/scss/_buttons.scss index e17ec875cd592b90d0a853044e9e0c36a1e6224e..3c972d529bd2e937982fb9d71c53e1893fd92483 100644 --- a/src/assets/scss/_buttons.scss +++ b/src/assets/scss/_buttons.scss @@ -7,7 +7,7 @@ height: 40px; width: 190px; border: 1px solid $grey-4; - padding: 3px 16px 3px 16px; + padding: 3px 8px 3px 16px; outline: none; border-radius: 4px; cursor: pointer; diff --git a/src/assets/scss/_color.scss b/src/assets/scss/_color.scss index 75dd41e99e0493162e4156be96636a3c079c64a3..7b72d6a99b74d8253d4dd1dd61560951700cd455 100644 --- a/src/assets/scss/_color.scss +++ b/src/assets/scss/_color.scss @@ -7,7 +7,7 @@ $grey-1: #333333; $grey-2: #4f4f4f; $grey-3: #828282; $grey-4: #bdbdbd; -$grey-6: #f2f2f2; +$grey-6: #f8f8f8; /* form colors */ $green-1: #47c562; /* Status colors */ diff --git a/src/assets/scss/_layout.scss b/src/assets/scss/_layout.scss index 94ebedd43f510c2edad4ae2edb0202c2c49bc8d9..d8f402ac2af754d5866c26ec9bf2c3bff5356053 100644 --- a/src/assets/scss/_layout.scss +++ b/src/assets/scss/_layout.scss @@ -3,3 +3,5 @@ $footer-height: 56px; $header-height-phone: 70px; $footer-height-phone: 75px; $progressBar-height: 50px; +$header-post-height: 180px; +$header-post-height-mobile: 140px; diff --git a/src/assets/scss/_typography.scss b/src/assets/scss/_typography.scss index d5f92bac1c01e01d894fd86e494968119698381b..b4067a7947b1711598343a1f9b8a2f991bced8a3 100644 --- a/src/assets/scss/_typography.scss +++ b/src/assets/scss/_typography.scss @@ -11,6 +11,8 @@ $font-size-medium: 1.25em; // 20px $font-size-xmedium: 1.375em; // 22px $font-size-large: 1.625em; // 26px +$font-size-xlarge: 1.75em; // 28px +$font-size-xxlarge: 1.875em; // 28px html, body, @@ -43,6 +45,20 @@ h6, font-size: $font-size-small; } +@mixin cn-bold-30 { + font-family: $title-font; + font-style: normal; + font-weight: bold; + font-size: $font-size-xxlarge; +} + +@mixin cn-bold-28 { + font-family: $title-font; + font-style: normal; + font-weight: bold; + font-size: $font-size-xlarge; +} + @mixin cn-bold-26 { font-family: $title-font; font-style: normal; diff --git a/src/index.html b/src/index.html index 1dfbff37e98e160421dc47c16ab7c8bb99dff3ef..7a2041e9771b12f05c52401b5b56a440c11229c9 100644 --- a/src/index.html +++ b/src/index.html @@ -5,6 +5,12 @@ <title>Réseau des Acteurs de la Médiation</title> <base href="/" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta property="og:title" content="Réseau des Acteurs de la Médiation" /> + <meta + property="og:description" + content="Plateforme à destination des acteurs de l'inclusion numérique de la métropole de Lyon" + /> + <meta property="og:image" content="https://resin.grandlyon.com/assets/logos/logo_1200.svg" /> <link rel="icon" type="image/x-icon" href="favicon.ico" /> <link rel="stylesheet" href="https://openlayers.org/en/v4.6.5/css/ol.css" type="text/css" /> <link diff --git a/src/styles.scss b/src/styles.scss index 747d5da15a984bd5b107acc00ceaaeabe882de53..53df89909ff242ab624a1f1ce679cb844c2936f8 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -59,9 +59,8 @@ a { // Containers .content-container { margin: 0; - padding-top: 30px; + padding-top: 16px; width: 100%; - height: 100%; &.medium-pt { padding: 25px 0 30px 0; } @@ -74,9 +73,6 @@ a { &.full-screen { min-height: calc(100vh - #{$header-height} - #{$footer-height}); } - @media #{$phone} { - padding-top: 30px; - } } .section-container { width: 80%; @@ -110,7 +106,7 @@ button { opacity: 0; display: none; &:checked ~ .customCheck { - background-color: $primary-color; + background-color: $green-1; border-color: transparent; } &:checked ~ .customCheck:after { @@ -159,6 +155,9 @@ button { -ms-transform: rotate(45deg); } } + &.no-width { + width: unset; + } } // Layout