diff --git a/src/app/post/components/post-card/post-card.component.html b/src/app/post/components/post-card/post-card.component.html index 4ba85dbbe2594f12e428e4bbc2656b2be42b4909..1db7cd7e0401d07effddba763f27f28d020eeae5 100644 --- a/src/app/post/components/post-card/post-card.component.html +++ b/src/app/post/components/post-card/post-card.component.html @@ -1,4 +1,4 @@ -<div fxLayout="column" *ngIf="post" class="post" [ngClass]="class" fxLayoutGap="12px"> +<div fxLayout="column" *ngIf="post" class="post" [ngClass]="class" fxLayoutGap="12px" (click)="showDetails(post)"> <div fxLayout="column" fxLayoutGap="4px"> <div fxLayout="row" diff --git a/src/app/post/components/post-card/post-card.component.scss b/src/app/post/components/post-card/post-card.component.scss index 59ab4c38b4818a7bab8e6d9ecf27c64f54650138..aaf3133afb7c3934b0811019b9fdbb07fbc5a816 100644 --- a/src/app/post/components/post-card/post-card.component.scss +++ b/src/app/post/components/post-card/post-card.component.scss @@ -3,6 +3,7 @@ @import '../../../../assets/scss/breakpoint'; .post { + cursor: pointer; padding: 16px 0px; border-bottom: 1px dashed $grey-3; &.bigNew { @@ -17,6 +18,13 @@ } } } + .title { + @include cn-bold-30; + } + .description { + @include cn-regular-18; + color: $grey-1; + } } .imageContainer { .image { diff --git a/src/app/post/components/post-card/post-card.component.ts b/src/app/post/components/post-card/post-card.component.ts index a7d648e31d3854aa5ec2e7cf97caa39a9e43da9d..e97a5fe74994a03a6177ba277cdaa57496c41d95 100644 --- a/src/app/post/components/post-card/post-card.component.ts +++ b/src/app/post/components/post-card/post-card.component.ts @@ -1,4 +1,5 @@ import { Component, Input, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; import { TagEnum } from '../../enum/tag.enum'; import { Post } from '../../models/post.model'; @@ -11,7 +12,10 @@ export class PostCardComponent implements OnInit { @Input() post: Post; @Input() class: string; public tagEnum = TagEnum; - constructor() {} + constructor(private router: Router) {} ngOnInit(): void {} + public showDetails(post: Post): void { + this.router.navigateByUrl('posts/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 index 11f24be812b5d3336a4faa305b3a7cbfb1cb3388..2e2136a31fe1b742d03da414373b94d6ac6ef80b 100644 --- a/src/app/post/components/post-details/post-details.component.html +++ b/src/app/post/components/post-details/post-details.component.html @@ -1 +1,37 @@ -<p>post-details works!</p> +<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" [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 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4968643522f382caa77aa4b229a281fcb61c2326 100644 --- a/src/app/post/components/post-details/post-details.component.scss +++ b/src/app/post/components/post-details/post-details.component.scss @@ -0,0 +1,72 @@ +@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: 832px; + margin: $margin-post auto; + 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; + font-size: 18px; + } +} diff --git a/src/app/post/components/post-details/post-details.component.ts b/src/app/post/components/post-details/post-details.component.ts index adf283aa1d0ed592aa5ebe4e48d79803b57405d6..31f7b0f6264140035968c940b6f111293cf409a8 100644 --- a/src/app/post/components/post-details/post-details.component.ts +++ b/src/app/post/components/post-details/post-details.component.ts @@ -1,15 +1,36 @@ import { Component, OnInit } from '@angular/core'; +import { DomSanitizer } from '@angular/platform-browser'; +import { ActivatedRoute, Router } from '@angular/router'; +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'] + styleUrls: ['./post-details.component.scss'], }) export class PostDetailsComponent implements OnInit { - - constructor() { } - + constructor( + private activatedRoute: ActivatedRoute, + private router: Router, + private postService: PostService, + private sanitizer: DomSanitizer + ) {} + 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.router.navigateByUrl('/posts'); + } } diff --git a/src/app/post/components/post-header/post-header.component.scss b/src/app/post/components/post-header/post-header.component.scss index e24dbb9e61cf8f527c6c88daaf47f0df0129f8e7..526d1120163fd06547a46203cf6394a4c9ca09b5 100644 --- a/src/app/post/components/post-header/post-header.component.scss +++ b/src/app/post/components/post-header/post-header.component.scss @@ -1,6 +1,7 @@ @import '../../../../assets/scss/color'; +@import '../../../../assets/scss/layout'; .header-container { - height: 180px; + height: #{$header-post-height}; background: $white; } diff --git a/src/app/post/components/post-list/post-list.component.html b/src/app/post/components/post-list/post-list.component.html index 44514f087388d3a957836173c0d9e68894e022a4..190d108eb99494d32bf027791b1009d981b05723 100644 --- a/src/app/post/components/post-list/post-list.component.html +++ b/src/app/post/components/post-list/post-list.component.html @@ -45,12 +45,7 @@ <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]="'appel-a-projet'" - ></app-svg-icon> + <app-svg-icon [iconClass]="'icon-80'" [iconColor]="'inherit'" [type]="'post'" [icon]="'appels'"></app-svg-icon> <h2>appels à projets</h2> <app-post-card [post]="news" diff --git a/src/app/post/components/post-list/post-list.component.scss b/src/app/post/components/post-list/post-list.component.scss index 6478796f4da6b26552a5d7420fdc6f6870294114..27a518b912adfc47476fe0f2b56fe55b5685769c 100644 --- a/src/app/post/components/post-list/post-list.component.scss +++ b/src/app/post/components/post-list/post-list.component.scss @@ -18,6 +18,11 @@ text-transform: uppercase; } } +h2 { + font-style: italic !important; + text-transform: uppercase; +} + .last-child { ::ng-deep .post { border: 0; diff --git a/src/app/post/models/post.model.ts b/src/app/post/models/post.model.ts index 53efadc333d83d11bdad7943a08b49b34b8d20b8..eb13ecef2069a06fbd5845c659539a4829c7d1b2 100644 --- a/src/app/post/models/post.model.ts +++ b/src/app/post/models/post.model.ts @@ -1,3 +1,4 @@ +import { SafeHtml } from '@angular/platform-browser'; import { Tag } from './tag.model'; export class Post { @@ -9,4 +10,9 @@ export class Post { html: string; author: string; tags: Tag[]; + safeHtml: SafeHtml; + + constructor(obj?: any) { + Object.assign(this, obj); + } } diff --git a/src/app/post/news.component.html b/src/app/post/news.component.html index 2ea36328d11da5ce494b8fb63f384c32e39bf5e9..ba58f058ba0384781d74c5390e0ff2d9c0634ac3 100644 --- a/src/app/post/news.component.html +++ b/src/app/post/news.component.html @@ -1,2 +1,4 @@ <app-post-header></app-post-header> -<app-post-list></app-post-list> +<div class="section-container"> + <router-outlet></router-outlet> +</div> diff --git a/src/app/post/post-routing.module.ts b/src/app/post/post-routing.module.ts index 841c89d456cc5778554e6a6bbe6672c7acf1192b..e6f6a3e0098cb96afa1d2ddca401fcfe8e5c1e37 100644 --- a/src/app/post/post-routing.module.ts +++ b/src/app/post/post-routing.module.ts @@ -1,9 +1,25 @@ 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'; -const routes: Routes = [{ path: '', component: NewsComponent }]; - +const routes: Routes = [ + { + path: '', + component: NewsComponent, + children: [ + { + path: '', + component: PostListComponent, + }, + { + path: 'details/:id', + component: PostDetailsComponent, + }, + ], + }, +]; @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule], diff --git a/src/app/post/services/post.service.ts b/src/app/post/services/post.service.ts index 38d9346d010b748dfd0da6beb41d2f55cbf4e4a7..d70e18881db9ddd10f11df0a19db6dc2f47bee44 100644 --- a/src/app/post/services/post.service.ts +++ b/src/app/post/services/post.service.ts @@ -2,6 +2,7 @@ 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'; @@ -12,6 +13,17 @@ 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 @@ -32,4 +44,10 @@ export class PostService { .get<PostWithMeta>(`${this.baseUrl}?include=tags,authors&filter=tag:[${tagsString}]`) .pipe(map((item: PostWithMeta) => new PostWithMeta(item))); } + + private addAuthorToPost(post: Post): Post { + post.author = post.excerpt; + post.excerpt = post.html.replace(/<[^>]*>/g, ''); + return post; + } } diff --git a/src/assets/post/sprite.svg b/src/assets/post/sprite.svg index 7632091da3cbed5b1d60620a16a565340129b65f..fe3e4e45abe4590b91cafff792b4fec8ab443602 100644 --- a/src/assets/post/sprite.svg +++ b/src/assets/post/sprite.svg @@ -1,6 +1,6 @@ <svg xmlns="http://www.w3.org/2000/svg"> -<symbol id="appel-a-projet" viewBox="0 0 80 60" 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"/> 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..2a4a34f6e6a7f63f32a0113379bd9ccc4c302c31 100644 --- a/src/assets/scss/_layout.scss +++ b/src/assets/scss/_layout.scss @@ -3,3 +3,4 @@ $footer-height: 56px; $header-height-phone: 70px; $footer-height-phone: 75px; $progressBar-height: 50px; +$header-post-height: 180px; diff --git a/src/assets/scss/_typography.scss b/src/assets/scss/_typography.scss index b340d5a637e76f1906f491f68e5c517e71f2abeb..b4067a7947b1711598343a1f9b8a2f991bced8a3 100644 --- a/src/assets/scss/_typography.scss +++ b/src/assets/scss/_typography.scss @@ -12,6 +12,7 @@ $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, @@ -44,6 +45,13 @@ 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;