fix: News now display author

This commit is contained in:
2025-06-13 16:07:23 +02:00
parent 5cd31a4981
commit 3b3f4fd3b1
10 changed files with 124 additions and 75 deletions

View File

@@ -1,15 +1,15 @@
<button mat-raised-button (click)="newPost()" color="accent">Nowy post</button> <button mat-raised-button (click)="newPost()" color="accent" class="newPost">Nowy post</button>
@if (loading) { <div class="mainc">
<mat-spinner></mat-spinner> @if (ac.state() != 2) {
<app-load-shade [state]="ac.state()" [error]="ac.error()" (refresh)="ac.refresh()"/>
} }
@for (item of news; track item) { @for (item of ac.news | async; track item) {
<mat-card> <mat-card>
<mat-card-header> <mat-card-header>
<mat-card-title>{{item.title}}</mat-card-title> <mat-card-title>{{item.title}}</mat-card-title>
@if (item.pinned) { @if (item.pinned) {
<mat-icon>push_pin</mat-icon> <mat-icon>push_pin</mat-icon>
} }
<!-- <mat-card-subtitle>{{item._id}}</mat-card-subtitle> -->
</mat-card-header> </mat-card-header>
<mat-card-content [innerHTML]="item.formatted"></mat-card-content> <mat-card-content [innerHTML]="item.formatted"></mat-card-content>
<mat-card-actions> <mat-card-actions>
@@ -30,14 +30,14 @@
<button mat-mini-fab (click)="delete(item._id)"><mat-icon>delete_forever</mat-icon></button> <button mat-mini-fab (click)="delete(item._id)"><mat-icon>delete_forever</mat-icon></button>
</mat-card-actions> </mat-card-actions>
<mat-card-footer> <mat-card-footer>
<p>{{item.date | date:'d-LL-yyyy HH:mm'}}</p> <p>{{fullName(item)}} {{item.date | date:'d-LL-yyyy HH:mm'}}</p>
</mat-card-footer> </mat-card-footer>
</mat-card> </mat-card>
} } @empty {
@if (news.length == 0) {
<mat-card> <mat-card>
<p> <p>
Brak wiadomości. Brak wiadomości.
</p> </p>
</mat-card> </mat-card>
} }
</div>

View File

@@ -1,7 +1,6 @@
mat-card { mat-card {
margin: 15px; margin: 15px;
padding: 1ch; padding: 1ch;
width: 100%;
} }
mat-card-title { mat-card-title {
@@ -31,8 +30,19 @@ button {
} }
:host { :host {
padding: 8pt;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
height: 100%;
width: 100%;
}
.mainc {
position: relative;
height: 100%;
width: 100%;
}
.newPost {
margin: 1ch;
} }

View File

@@ -3,8 +3,7 @@ import { MatDialog } from '@angular/material/dialog'
import { NewPostComponent } from './new-post/edit-post.component' import { NewPostComponent } from './new-post/edit-post.component'
import { catchError, throwError } from 'rxjs' import { catchError, throwError } from 'rxjs'
import { MatSnackBar } from '@angular/material/snack-bar' import { MatSnackBar } from '@angular/material/snack-bar'
import { News } from 'src/app/types/news' import { News } from 'src/app/types/news.model'
import { marked } from 'marked'
import { NewsEditService } from './news-edit.service' import { NewsEditService } from './news-edit.service'
@Component({ @Component({
@@ -14,29 +13,15 @@ import { NewsEditService } from './news-edit.service'
standalone: false, standalone: false,
}) })
export class NewsEditComponent implements OnInit { export class NewsEditComponent implements OnInit {
news: Array<News & { formatted: string }> = new Array<
News & { formatted: string }
>()
loading = true
constructor( constructor(
private ac: NewsEditService, protected ac: NewsEditService,
private dialog: MatDialog, private dialog: MatDialog,
private sb: MatSnackBar private sb: MatSnackBar
) { } ) { }
ngOnInit() { ngOnInit() {
this.loading = true this.ac.refresh()
this.ac.getNews().subscribe(data => {
this.loading = false
this.news = data.map(v => {
var nd: News & { formatted: string } = {
...v,
formatted: marked.parse(v.content, { breaks: true }).toString(),
}
return nd
})
})
} }
newPost() { newPost() {
@@ -131,4 +116,12 @@ export class NewsEditComponent implements OnInit {
} }
}) })
} }
fullName(n: News): string {
const { author: { fname, surname, uname } } = n;
if (fname || surname) {
return [fname, surname].filter(Boolean).join(' ');
}
return uname;
}
} }

View File

@@ -1,6 +1,9 @@
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core'; import { Injectable, signal } from '@angular/core';
import { News } from 'src/app/types/news'; import { marked } from 'marked';
import { BehaviorSubject, catchError, map, of } from 'rxjs';
import { News } from 'src/app/types/news.model';
import { STATE } from 'src/app/types/state';
import { environment } from 'src/environments/environment'; import { environment } from 'src/environments/environment';
@Injectable({ @Injectable({
@@ -8,11 +11,40 @@ import { environment } from 'src/environments/environment';
}) })
export class NewsEditService { export class NewsEditService {
private _news = new BehaviorSubject<(News & {formatted: string})[]>([])
public readonly news = this._news.asObservable()
private _state = signal(STATE.NOT_LOADED);
public readonly state = this._state.asReadonly();
private _error = signal<string | undefined>(undefined);
public readonly error = this._error.asReadonly();
constructor(private http: HttpClient) { } constructor(private http: HttpClient) { }
getNews() { public refresh() {
return this.http.get<News[]>(environment.apiEndpoint + `/admin/news`, { this.getNews()
withCredentials: true, }
private getNews() {
this._state.set(STATE.PENDING)
this.http.get
<News[]>
(environment.apiEndpoint + `/admin/news`, { withCredentials: true, })
.pipe(
catchError((err: Error) => {
this._state.set(STATE.ERROR)
this._error.set(err.message)
return of()
}),
map(i => {
return i.map(v => ({
...v,
formatted: marked.parse(v.content, { breaks: true }).toString()
}))
})
).subscribe(v => {
this._error.set(undefined)
this._news.next(v ?? [])
this._state.set(STATE.LOADED)
}) })
} }

View File

@@ -12,7 +12,7 @@
<mat-card-content [innerHTML]="item.content"> <mat-card-content [innerHTML]="item.content">
</mat-card-content> </mat-card-content>
<mat-card-footer> <mat-card-footer>
<p>{{item.date | date:'d-LL-yyyy HH:mm'}}</p> <p>{{fullName(item)}} {{item.date | date:'d-LL-yyyy HH:mm'}}</p>
</mat-card-footer> </mat-card-footer>
</mat-card> </mat-card>
} }

View File

@@ -1,7 +1,7 @@
import { Component, OnInit } from '@angular/core' import { Component, OnInit } from '@angular/core'
import { UpdatesService } from '../../services/updates.service' import { UpdatesService } from '../../services/updates.service'
import { LocalStorageService } from 'src/app/services/local-storage.service' import { LocalStorageService } from 'src/app/services/local-storage.service'
import { News } from 'src/app/types/news' import { News } from 'src/app/types/news.model'
import { marked } from 'marked' import { marked } from 'marked'
@Component({ @Component({
@@ -31,4 +31,12 @@ export class NewsComponent implements OnInit {
this.ls.news = this.news this.ls.news = this.news
}) })
} }
fullName(n: News): string {
const { author: { fname, surname, uname } } = n;
if (fname || surname) {
return [fname, surname].filter(Boolean).join(' ');
}
return uname;
}
} }

View File

@@ -8,4 +8,5 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
z-index: 10;
} }

View File

@@ -1,5 +1,5 @@
import { Injectable } from '@angular/core' import { Injectable } from '@angular/core'
import { News } from '../types/news' import { News } from '../types/news.model'
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',

View File

@@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'
import { HttpClient } from '@angular/common/http' import { HttpClient } from '@angular/common/http'
import { Menu } from '../types/menu' import { Menu } from '../types/menu'
import { environment } from 'src/environments/environment' import { environment } from 'src/environments/environment'
import { News } from '../types/news' import { News } from '../types/news.model'
import { UKey } from '../types/key' import { UKey } from '../types/key'
import { CleanNote } from '../types/clean-note' import { CleanNote } from '../types/clean-note'
import { Status } from '../types/status' import { Status } from '../types/status'

View File

@@ -4,5 +4,10 @@ export interface News {
content: string content: string
date: string date: string
visible?: boolean visible?: boolean
pinned?: boolean pinned?: boolean,
author: {
fname?: string,
surname?: string,
uname: string
}
} }