TD-4: Admin kann spieler bannen, unbannen und filtern
All checks were successful
Quality Check / Linting (push) Successful in 22s
Quality Check / Linting (pull_request) Successful in 23s

This commit is contained in:
Dorian Nemec 2025-03-12 14:33:57 +01:00
parent 078ceb3465
commit bfa46ccb98
5 changed files with 61 additions and 17 deletions

View file

@ -1,6 +1,8 @@
interface UserData { interface UserData {
username: string, username: string,
verified: boolean verified: boolean,
id: number,
banned: boolean
} }
export default UserData; export default UserData;

View file

@ -22,7 +22,9 @@ export class AuthService implements CanActivate {
const isLoggedIn = isAuthenticated && userData != null && accessToken != ''; const isLoggedIn = isAuthenticated && userData != null && accessToken != '';
this.$user.next(isLoggedIn ? { this.$user.next(isLoggedIn ? {
username: userData.preferred_username, username: userData.preferred_username,
verified: userData.email_verified verified: userData.email_verified,
id: userData.id,
banned: userData.banned
} : undefined); } : undefined);
}); });
} }

View file

@ -6,11 +6,11 @@
<input matInput placeholder="" #searchbar> <input matInput placeholder="" #searchbar>
</mat-form-field> </mat-form-field>
<mat-form-field> <mat-form-field>
<mat-label>Banned</mat-label> <mat-label>Filter</mat-label>
<mat-select> <mat-select #filter (selectionChange)="applyFilter(filter.value)">
<mat-option>Reset</mat-option> <mat-option value="all">All</mat-option>
<mat-option>Banned</mat-option> <mat-option value="banned">Banned</mat-option>
<mat-option>Not Banned</mat-option> <mat-option value="notBanned">Not Banned</mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<button mat-fab class="shadowless" (click)="onSearch(searchbar)"> <button mat-fab class="shadowless" (click)="onSearch(searchbar)">
@ -21,17 +21,27 @@
</button> </button>
</div> </div>
<mat-table [dataSource]="usersDataSource" class="dashboard__table"> <mat-table [dataSource]="filteredUsersDataSource" class="dashboard__table">
<ng-container matColumnDef="username"> <ng-container matColumnDef="username">
<th mat-header-cell *matHeaderCellDef>Username</th> <th mat-header-cell *matHeaderCellDef>Username</th>
<td mat-cell *matCellDef="let user"> {{ user.username }}</td> <td mat-cell *matCellDef="let user"> {{ user.username }}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="banned">
<th mat-header-cell *matHeaderCellDef>Banned</th>
<td mat-cell *matCellDef="let user"></td>
</ng-container>
<ng-container matColumnDef="actions"> <ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef>Actions</th> <th mat-header-cell *matHeaderCellDef>Actions</th>
<td mat-cell *matCellDef="let user"> <td mat-cell *matCellDef="let user">
@if (user.banned == false) {
<button mat-mini-fab class="warn shadowless" (click)="banPlayer(user)"> <button mat-mini-fab class="warn shadowless" (click)="banPlayer(user)">
<mat-icon>block</mat-icon> <mat-icon>block</mat-icon>
</button> </button>
} @else {
<button mat-mini-fab class="unbanned shadowless" (click)="unbanPlayer(user)">
<mat-icon>check</mat-icon>
</button>
}
</td> </td>
</ng-container> </ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>

View file

@ -30,4 +30,8 @@
padding: 0.25rem 0; padding: 0.25rem 0;
} }
} }
}
.unbanned {
color:green;
} }

View file

@ -1,5 +1,5 @@
import {AsyncPipe} from '@angular/common'; import {AsyncPipe} from '@angular/common';
import {Component, OnInit} from '@angular/core'; import {ChangeDetectorRef, Component, OnInit} from '@angular/core';
import {MatFabButton, MatMiniFabButton} from '@angular/material/button'; import {MatFabButton, MatMiniFabButton} from '@angular/material/button';
import {MatFormFieldModule} from '@angular/material/form-field'; import {MatFormFieldModule} from '@angular/material/form-field';
import {MatIcon} from '@angular/material/icon'; import {MatIcon} from '@angular/material/icon';
@ -28,10 +28,12 @@ import {AdministratablePlayer, AdminService, PlayerFilter} from '@core/server';
styleUrl: './dashboard.component.scss' styleUrl: './dashboard.component.scss'
}) })
export class DashboardComponent implements OnInit { export class DashboardComponent implements OnInit {
displayedColumns: Array<string> = ['username', 'actions']; displayedColumns: Array<string> = ['username', 'actions', 'banned'];
usersDataSource: MatTableDataSource<AdministratablePlayer> = new MatTableDataSource<AdministratablePlayer>([]); selectedFilter: string = 'all';
originalUsersDataSource: MatTableDataSource<AdministratablePlayer> = new MatTableDataSource<AdministratablePlayer>([]);
filteredUsersDataSource: MatTableDataSource<AdministratablePlayer> = new MatTableDataSource<AdministratablePlayer>([]);
constructor(private adminService: AdminService, protected authService: AuthService) { constructor(private adminService: AdminService, protected authService: AuthService, private cdr: ChangeDetectorRef) {
} }
ngOnInit(): void { ngOnInit(): void {
@ -42,18 +44,19 @@ export class DashboardComponent implements OnInit {
}); });
} }
fetchPlayers(querry: string): void { fetchPlayers(query: string): void {
const filter: PlayerFilter = { const filter: PlayerFilter = {
page: 0, page: 0,
pageSize: 32, pageSize: 32,
order: PlayerFilter.OrderEnum.Ascending, order: PlayerFilter.OrderEnum.Ascending,
username: querry, username: query,
sortBy: 'username' sortBy: 'username'
}; };
this.adminService.getAllPlayers(filter).subscribe( this.adminService.getAllPlayers(filter).subscribe(
(players) => { (players) => {
this.usersDataSource = new MatTableDataSource<AdministratablePlayer>(players); this.originalUsersDataSource.data = players; // Store original data
this.filteredUsersDataSource.data = [...players]; // Apply initial filter
}, },
(error) => { (error) => {
console.error('Error fetching players:', error); console.error('Error fetching players:', error);
@ -62,8 +65,19 @@ export class DashboardComponent implements OnInit {
} }
banPlayer(user: UserData): void { banPlayer(user: UserData): void {
console.log(`Banning user: ${user.username}`); this.adminService.banPlayer(user.id).subscribe(() => {
// TODO: implement banning logic user.banned = true;
this.originalUsersDataSource.data = [...this.originalUsersDataSource.data];
this.applyFilter(this.selectedFilter);
});
}
unbanPlayer(user: UserData): void {
this.adminService.unbanPlayer(user.id).subscribe(() => {
user.banned = false;
this.originalUsersDataSource.data = [...this.originalUsersDataSource.data];
this.applyFilter(this.selectedFilter);
});
} }
onSearch(searchbar: HTMLInputElement): void { onSearch(searchbar: HTMLInputElement): void {
@ -75,4 +89,16 @@ export class DashboardComponent implements OnInit {
this.fetchPlayers(''); this.fetchPlayers('');
} }
applyFilter(filter: string): void {
this.selectedFilter = filter; // Store filter selection
let filteredUsers = this.originalUsersDataSource.data;
if (filter === 'banned') {
filteredUsers = filteredUsers.filter(user => user.banned);
} else if (filter === 'notBanned') {
filteredUsers = filteredUsers.filter(user => !user.banned);
}
this.filteredUsersDataSource.data = [...filteredUsers];
}
} }