Styling publications on home page.
This commit is contained in:
@@ -2,6 +2,10 @@
|
||||
"/api": {
|
||||
"target": "http://localhost:8987",
|
||||
"secure": false
|
||||
},
|
||||
"/pictures": {
|
||||
"target": "http://localhost:8987/api",
|
||||
"secure": false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export interface Author {
|
||||
id: string;
|
||||
name: string;
|
||||
image: string;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { Author } from "./author";
|
||||
|
||||
export interface Publication {
|
||||
id: string;
|
||||
key: string;
|
||||
title: string;
|
||||
text: string;
|
||||
parsedText: string;
|
||||
description: string;
|
||||
creationDate: Date;
|
||||
illustrationId: string;
|
||||
categoryId: string;
|
||||
author: Author;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { lastValueFrom } from 'rxjs';
|
||||
import { Publication } from './model/publication';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class PublicationRestService {
|
||||
private httpClient = inject(HttpClient);
|
||||
|
||||
getLatest(): Promise<Publication[]> {
|
||||
return lastValueFrom(this.httpClient.get<Publication[]>('/api/publications/latest'));
|
||||
}
|
||||
}
|
||||
@@ -1 +1,15 @@
|
||||
<h1>Welcome to Codiki application!</h1>
|
||||
<h1>Last articles</h1>
|
||||
<div class="publication-container">
|
||||
<a *ngFor="let publication of publications$ | async" [routerLink]="['']" class="publication">
|
||||
<img src="/pictures/{{publication.illustrationId}}"/>
|
||||
<h1>{{publication.title}}</h1>
|
||||
<h2>{{publication.description}}</h2>
|
||||
<div class="footer">
|
||||
<img src="/pictures/{{publication.author.image}}" [matTooltip]="publication.author.name"/>
|
||||
Publication posted by {{publication.author.name}}
|
||||
<span class="publication-date">
|
||||
({{publication.creationDate}})
|
||||
</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
@@ -3,4 +3,46 @@
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.publication-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2em;
|
||||
max-width: 40em;
|
||||
margin: auto;
|
||||
|
||||
.publication {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-radius: .5em;
|
||||
box-shadow: 0 2px 5px 0 rgba(0,0,0,.16),0 2px 10px 0 rgba(0,0,0,.12);
|
||||
|
||||
img {
|
||||
object-fit: cover;
|
||||
height: 25em;
|
||||
border-radius: .5em .5em 0 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.4em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.6em;
|
||||
}
|
||||
|
||||
.footer {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
border-radius: 10em;
|
||||
width: 5em;
|
||||
height: 5em;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,31 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, OnInit, inject } from '@angular/core';
|
||||
import { HomeService } from './home.service';
|
||||
import { Observable } from 'rxjs';
|
||||
import { Publication } from '../../core/rest-services/publications/model/publication';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@Component({
|
||||
selector: 'app-home',
|
||||
standalone: true,
|
||||
imports: [],
|
||||
imports: [CommonModule, RouterModule, MatTooltipModule],
|
||||
templateUrl: './home.component.html',
|
||||
styleUrl: './home.component.scss'
|
||||
styleUrl: './home.component.scss',
|
||||
providers: [HomeService]
|
||||
})
|
||||
export class HomeComponent {
|
||||
export class HomeComponent implements OnInit {
|
||||
private homeService = inject(HomeService);
|
||||
|
||||
get isLoading$(): Observable<boolean> {
|
||||
return this.homeService.isLoading$;
|
||||
}
|
||||
|
||||
get publications$(): Observable<Publication[]> {
|
||||
return this.homeService.publications$;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.homeService.startLatestPublicationsRetrieving();
|
||||
}
|
||||
}
|
||||
|
||||
34
frontend/src/app/pages/home/home.service.ts
Normal file
34
frontend/src/app/pages/home/home.service.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { Injectable, inject } from "@angular/core";
|
||||
import { PublicationRestService } from "../../core/rest-services/publications/publication.rest-service";
|
||||
import { BehaviorSubject, Observable } from "rxjs";
|
||||
import { MatSnackBar } from "@angular/material/snack-bar"
|
||||
import { Publication } from "../../core/rest-services/publications/model/publication";
|
||||
|
||||
@Injectable()
|
||||
export class HomeService {
|
||||
private publicationRestService = inject(PublicationRestService);
|
||||
private snackBar = inject(MatSnackBar);
|
||||
|
||||
private publicationsSubject = new BehaviorSubject<Publication[]>([]);
|
||||
private isLoadingSubject = new BehaviorSubject<boolean>(false);
|
||||
|
||||
get isLoading$(): Observable<boolean> {
|
||||
return this.isLoadingSubject.asObservable();
|
||||
}
|
||||
|
||||
get publications$(): Observable<Publication[]> {
|
||||
return this.publicationsSubject.asObservable();
|
||||
}
|
||||
|
||||
startLatestPublicationsRetrieving(): void {
|
||||
this.isLoadingSubject.next(true);
|
||||
|
||||
this.publicationRestService.getLatest()
|
||||
.then(publications => this.publicationsSubject.next(publications))
|
||||
.catch(error => {
|
||||
this.snackBar.open('An error occurred while retrieving latest publications...');
|
||||
console.error('An error occurred while retrieving latest publications...', error);
|
||||
})
|
||||
.finally(() => this.isLoadingSubject.next(false));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user