Add punishment details and history retrieval functionality

This commit introduces a new `DetailsComponent` for displaying detailed punishment data and establishes a route to view punishment history by ID and type. It also updates the API to support fetching individual punishment records and refines database mappings for improved data handling.
This commit is contained in:
2025-04-19 04:02:51 +02:00
parent a1912b96d8
commit 3babde5513
22 changed files with 547 additions and 165 deletions
@@ -1,11 +1,14 @@
import {Component, EventEmitter, Input, OnChanges, OnInit, Output} from '@angular/core';
import {BASE_PATH, HistoryService, PunishmentHistoryInner} from '../../../api';
import {BASE_PATH, HistoryService, PunishmentHistory} from '../../../api';
import {catchError, map, Observable, shareReplay} from 'rxjs';
import {NgForOf, NgIf, NgOptimizedImage} from '@angular/common';
import {CookieService} from 'ngx-cookie-service';
import {RemoveTrailingPeriodPipe} from '../../util/RemoveTrailingPeriodPipe';
import {HttpErrorResponse} from '@angular/common/http';
import {environment} from '../../../environments/environment';
import {HistoryFormatService} from '../history-format.service';
import {SearchParams} from '../search-terms';
import {Router} from '@angular/router';
@Component({
selector: 'app-history',
@@ -30,12 +33,13 @@ export class HistoryComponent implements OnInit, OnChanges {
@Input() searchTerm: string = '';
@Output() pageChange = new EventEmitter<number>();
@Output() selectItem = new EventEmitter<SearchParams>();
private uuidRegex = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
public history: PunishmentHistoryInner[] = []
public history: PunishmentHistory[] = []
constructor(private historyApi: HistoryService) {
constructor(private historyApi: HistoryService, public historyFormat: HistoryFormatService, private router: Router) {
}
ngOnChanges(): void {
@@ -47,7 +51,7 @@ export class HistoryComponent implements OnInit, OnChanges {
}
private reloadHistory(): void {
let historyObservable: Observable<PunishmentHistoryInner[]>;
let historyObservable: Observable<PunishmentHistory[]>;
if (this.searchTerm.length === 0) {
historyObservable = this.historyApi.getHistoryForAll(this.userType, this.punishmentType, this.page);
} else {
@@ -89,42 +93,31 @@ export class HistoryComponent implements OnInit, OnChanges {
).subscribe();
}
public getPunishmentTime(entry: PunishmentHistoryInner) {
const date = new Date(entry.punishmentTime);
return date.toLocaleString(navigator.language, {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
hour12: false
});
}
public getType(entry: PunishmentHistoryInner) {
return entry.type.charAt(0).toUpperCase() + entry.type.slice(1);
}
public getExpiredTime(entry: PunishmentHistoryInner) {
if (entry.expiryTime <= 0) {
return "Permanent " + this.getType(entry);
setSearch(type: PunishmentHistory.TypeEnum, name: string, userType: 'player' | 'staff') {
let punishmentType: 'all' | 'ban' | 'mute' | 'kick' | 'warn' = 'all';
switch (type) {
case 'ban':
punishmentType = 'ban';
break;
case 'mute':
punishmentType = 'mute';
break;
case 'kick':
punishmentType = 'kick';
break;
case 'warn':
punishmentType = 'warn';
break;
}
const date = new Date(entry.expiryTime);
return date.toLocaleString(navigator.language, {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
hour12: false
});
let searchParams: SearchParams = {
userType: userType,
punishmentType: punishmentType,
searchTerm: name
}
this.selectItem.emit(searchParams);
}
public getAvatarUrl(entry: string): string {
let uuid = entry.replace('-', '');
if (uuid === 'C') {
uuid = "f78a4d8dd51b4b3998a3230f2de0c670"
}
return `https://crafatar.com/avatars/${uuid}?size=25&overlay`;
public showDetailedPunishment(entry: PunishmentHistory) {
this.router.navigate([`bans/${entry.type}/${entry.id}`]).then();
}
}