nise/nise-frontend/src/app/view-suspicious-scores/view-suspicious-scores.component.html
2024-07-05 00:47:26 +01:00

136 lines
6.6 KiB
HTML

<div class="main term">
<h1><span class="board">/sus/</span> - Suspicious Scores</h1>
<div class="alert mb-2">
This includes all replays with <25 cvUR. Low values can indicate cheating but always manually review users and
replays before making judgements.
</div>
<fieldset>
<legend>
Filter results
<button [disabled]="!this.filterManager.hasValueChanged()" (click)="this.resetValues()">Clear filters</button>
<button [disabled]="!this.filterManager.hasValueChanged() || this.isUrlFilters" (click)="this.getFiltersUrl()" title="Get a permanent link to the filters. Share or save it to your bookmarks!">Share filters</button>
</legend>
<!-- Min PP -->
<p>
<label for="minPP" class="form-label">Min PP</label>
<input class="form-control" type="number" id="minPP" [(ngModel)]="this.filterManager.filters.minPP" (input)="filterScores()"
[readOnly]="this.isUrlFilters" [disabled]="this.isUrlFilters">
</p>
<!-- Max PP -->
<p>
<label for="maxPP" class="form-label">Max PP</label>
<input class="form-control" type="number" id="maxPP" [(ngModel)]="this.filterManager.filters.maxPP" (input)="filterScores()"
[readOnly]="this.isUrlFilters" [disabled]="this.isUrlFilters">
</p>
<!-- Min cvUR -->
<p>
<label for="minUR" class="form-label">Min cvUR</label>
<input class="form-control" type="number" id="minUR" [(ngModel)]="this.filterManager.filters.minUR" (input)="filterScores()"
[readOnly]="this.isUrlFilters" [disabled]="this.isUrlFilters">
</p>
<!-- Max cvUR -->
<p>
<label for="maxUR" class="form-label">Max cvUR</label>
<input class="form-control" type="number" id="maxUR" [(ngModel)]="this.filterManager.filters.maxUR" (input)="filterScores()"
[readOnly]="this.isUrlFilters" [disabled]="this.isUrlFilters">
</p>
<!-- Search Username -->
<p>
<label for="searchUsername" class="form-label">Username</label>
<input class="form-control" type="text" id="searchUsername" [(ngModel)]="this.filterManager.filters.searchUsername" (input)="filterScores()"
[readOnly]="this.isUrlFilters" [disabled]="this.isUrlFilters">
</p>
<!-- Search Beatmap -->
<p>
<label for="searchBeatmap" class="form-label">Beatmap</label>
<input class="form-control" type="text" id="searchBeatmap" [(ngModel)]="this.filterManager.filters.searchBeatmap" (input)="filterScores()"
[readOnly]="this.isUrlFilters" [disabled]="this.isUrlFilters">
</p>
</fieldset>
<div *ngIf="getTotalPages() > 1" style="padding: 20px">
<p class="text-center">
Page: {{ this.currentPage }} / {{ this.getTotalPages() }}
</p>
<div>
<button (click)="currentPage = currentPage - 1" [disabled]="currentPage === 1" style="float: left">Previous page</button>
<button (click)="currentPage = currentPage + 1" [disabled]="currentPage === getTotalPages()" style="float: right">Next page</button>
</div>
</div>
<table class="table mt-4">
<thead class="text-center">
<tr>
<th>User</th>
<th>Beatmap</th>
<th>Date</th>
<th>cvUR</th>
<th>PP</th>
<th></th>
</tr>
<tr class="filters">
<th>
</th>
<th>
<span title="Sort by beatmap star rating (asc)" class="pointer sorter" [class.disabled]="this.isUrlFilters" [class.active]="this.filterManager.filters.sorting == 'beatmap_star_rating-asc'" (click)="sortScores('beatmap_star_rating', 'asc')"></span>
<span title="Sort by beatmap star rating (desc)" class="pointer sorter" [class.disabled]="this.isUrlFilters" [class.active]="this.filterManager.filters.sorting == 'beatmap_star_rating-desc'" (click)="sortScores('beatmap_star_rating', 'desc')"></span>
</th>
<th>
<span title="Sort by date (asc)" class="pointer sorter" [class.disabled]="this.isUrlFilters" [class.active]="this.filterManager.filters.sorting == 'date-asc'" (click)="sortScores('date', 'asc')"></span>
<span title="Sort by date (desc)" class="pointer sorter" [class.disabled]="this.isUrlFilters" [class.active]="this.filterManager.filters.sorting == 'date-desc'" (click)="sortScores('date', 'desc')"></span>
</th>
<th>
<span title="Sort by cvUR (asc)" class="pointer sorter" [class.disabled]="this.isUrlFilters" [class.active]="this.filterManager.filters.sorting == 'ur-asc'" (click)="sortScores('ur', 'asc')"></span>
<span title="Sort by cvUR (desc)" class="pointer sorter" [class.disabled]="this.isUrlFilters" [class.active]="this.filterManager.filters.sorting == 'ur-desc'" (click)="sortScores('ur', 'desc')"></span>
</th>
<th>
<span title="Sort by PP (asc)" class="pointer sorter" [class.disabled]="this.isUrlFilters" [class.active]="this.filterManager.filters.sorting == 'pp-asc'" (click)="sortScores('pp', 'asc')">▲️</span>
<span title="Sort by PP (desc)" class="pointer sorter" [class.disabled]="this.isUrlFilters" [class.active]="this.filterManager.filters.sorting == 'pp-desc'" (click)="sortScores('pp', 'desc')"></span>
</th>
<th></th>
</tr>
</thead>
<tbody style="font-size: 14px;">
<tr *ngFor="let score of this.getCurrentPage()">
<td>
<a [routerLink]="['/u/' + score.user_id]">
{{ score.username }}
</a>
</td>
<td>
<div class="image-container">
<a href="https://osu.ppy.sh/beatmaps/{{ score.beatmap_id }}?mode=osu" target="_blank">
<img ngSrc="https://assets.ppy.sh/beatmaps/{{ score.beatmap_beatmapset_id }}/covers/cover.jpg" width="260" height="72"
alt="Beatmap Cover" loading="lazy">
<div class="overlay">
{{ score.beatmap_title }}
{{ score.beatmap_star_rating | number: '1.0-1' }}★
</div>
</a>
</div>
</td>
<td>{{ score.date }}</td>
<td class="text-center">{{ score.ur | number: '1.2-2' }}</td>
<td class="text-center">{{ score.pp | number: '1.0-0' }}</td>
<td>
<a [routerLink]="['/s/' + score.replay_id]" class="btn mr-1">
Details
</a>
<a [href]="'https://osu.ppy.sh/scores/osu/' + score.replay_id" class="btn" target="_blank">
osu!web
</a>
</td>
</tr>
</tbody>
</table>
<div *ngIf="getTotalPages() > 1" style="padding: 30px">
<button (click)="currentPage = currentPage - 1" [disabled]="currentPage === 1" style="float: left">Previous page</button>
<button (click)="currentPage = currentPage + 1" [disabled]="currentPage === getTotalPages()" style="float: right">Next page</button>
</div>
</div>