WIP staff pt
This commit is contained in:
parent
8b0d2f9203
commit
e43cbbf9e4
|
|
@ -16,7 +16,7 @@ export const routes: Routes = [
|
|||
},
|
||||
{
|
||||
path: 'staff-pt',
|
||||
loadComponent: () => import('./pages/particles/particles.component').then(m => m.ParticlesComponent),
|
||||
loadComponent: () => import('./pages/head-mod/staff-pt/staff-pt.component').then(m => m.StaffPtComponent),
|
||||
canActivate: [AuthGuard],
|
||||
data: {
|
||||
requiredAuthorizations: ['SCOPE_head_mod']
|
||||
|
|
|
|||
|
|
@ -1 +1,40 @@
|
|||
<p>staff-pt works!</p>
|
||||
<div class="staff-pt-container">
|
||||
<div class="week-header">
|
||||
<button mat-icon-button (click)="prevWeek()" matTooltip="Previous week" aria-label="Previous week">
|
||||
<mat-icon>chevron_left</mat-icon>
|
||||
</button>
|
||||
|
||||
<div class="week-title">{{ weekLabel() }}</div>
|
||||
|
||||
<button mat-icon-button (click)="nextWeek()" [disabled]="!canGoNextWeek()"
|
||||
matTooltip="Next week" aria-label="Next week">
|
||||
<mat-icon>chevron_right</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<table mat-table [dataSource]="staffPt()" class="mat-elevation-z2 full-width">
|
||||
<ng-container matColumnDef="staff_member">
|
||||
<th mat-header-cell *matHeaderCellDef> Staff Member</th>
|
||||
<td mat-cell *matCellDef="let row"> {{ row.staff_member }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="playtime">
|
||||
<th mat-header-cell *matHeaderCellDef> Playtime (h:mm)</th>
|
||||
<td mat-cell *matCellDef="let row"> {{ minutesToHm(row.playtime) }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="last_played">
|
||||
<th mat-header-cell *matHeaderCellDef> Last Played</th>
|
||||
<td mat-cell *matCellDef="let row"> {{ row.last_played | date:'medium' }}</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
|
||||
@if (!staffPt()?.length) {
|
||||
<tr class="no-data">
|
||||
<td colspan="3">No data for this week.</td>
|
||||
</tr>
|
||||
}
|
||||
</table>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
.staff-pt-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.week-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.week-title {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.full-width {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.no-data td {
|
||||
text-align: center;
|
||||
padding: 16px;
|
||||
}
|
||||
|
|
@ -1,34 +1,104 @@
|
|||
import {Component, inject, OnInit, signal} from '@angular/core';
|
||||
import {Component, computed, inject, OnInit, signal} from '@angular/core';
|
||||
import {CommonModule, DatePipe} from '@angular/common';
|
||||
import {MatTableModule} from '@angular/material/table';
|
||||
import {MatButtonModule} from '@angular/material/button';
|
||||
import {MatIconModule} from '@angular/material/icon';
|
||||
import {MatTooltipModule} from '@angular/material/tooltip';
|
||||
import {SiteService, StaffPlaytime} from '@api';
|
||||
|
||||
@Component({
|
||||
selector: 'app-staff-pt',
|
||||
imports: [],
|
||||
standalone: true,
|
||||
imports: [CommonModule, MatTableModule, MatButtonModule, MatIconModule, MatTooltipModule, DatePipe],
|
||||
templateUrl: './staff-pt.component.html',
|
||||
styleUrl: './staff-pt.component.scss'
|
||||
})
|
||||
export class StaffPtComponent implements OnInit {
|
||||
siteService = inject(SiteService);
|
||||
staffPt = signal<StaffPlaytime[]>([])
|
||||
|
||||
staffPt = signal<StaffPlaytime[]>([]);
|
||||
|
||||
weekStart = signal<Date>(this.getStartOfWeek(new Date()));
|
||||
weekEnd = computed(() => this.getEndOfWeek(this.weekStart()));
|
||||
|
||||
todayStart = signal<Date>(this.startOfDay(new Date()));
|
||||
|
||||
displayedColumns = ['staff_member', 'playtime', 'last_played'];
|
||||
|
||||
ngOnInit(): void {
|
||||
const firstDayOfWeek = new Date();
|
||||
firstDayOfWeek.setDate(firstDayOfWeek.getDate() - firstDayOfWeek.getDay());
|
||||
firstDayOfWeek.setHours(0, 0, 0, 0);
|
||||
const lastDayOfWeek = new Date(firstDayOfWeek);
|
||||
lastDayOfWeek.setDate(firstDayOfWeek.getDate() + 6);
|
||||
lastDayOfWeek.setHours(23, 59, 59, 999);
|
||||
|
||||
this.loadStaffData(firstDayOfWeek, lastDayOfWeek);
|
||||
this.loadCurrentWeek();
|
||||
}
|
||||
|
||||
loadStaffData(from: Date, to: Date) {
|
||||
private loadCurrentWeek() {
|
||||
this.loadStaffData(this.weekStart(), this.weekEnd());
|
||||
}
|
||||
|
||||
prevWeek() {
|
||||
const prev = new Date(this.weekStart());
|
||||
prev.setDate(prev.getDate() - 7);
|
||||
prev.setHours(0, 0, 0, 0);
|
||||
this.weekStart.set(prev);
|
||||
this.loadCurrentWeek();
|
||||
}
|
||||
|
||||
nextWeek() {
|
||||
if (!this.canGoNextWeek()) return;
|
||||
const next = new Date(this.weekStart());
|
||||
next.setDate(next.getDate() + 7);
|
||||
next.setHours(0, 0, 0, 0);
|
||||
this.weekStart.set(next);
|
||||
this.loadCurrentWeek();
|
||||
}
|
||||
|
||||
canGoNextWeek(): boolean {
|
||||
const nextWeekStart = new Date(this.weekStart());
|
||||
nextWeekStart.setDate(nextWeekStart.getDate() + 7);
|
||||
nextWeekStart.setHours(0, 0, 0, 0);
|
||||
return nextWeekStart.getTime() <= this.todayStart().getTime();
|
||||
}
|
||||
|
||||
weekLabel(): string {
|
||||
const start = this.weekStart();
|
||||
const end = this.weekEnd();
|
||||
|
||||
const startFmt = start.toLocaleDateString(undefined, {month: 'short', day: 'numeric'});
|
||||
const endFmt = end.toLocaleDateString(undefined, {month: 'short', day: 'numeric'});
|
||||
const year = end.getFullYear();
|
||||
return `Week ${startFmt} – ${endFmt}, ${year}`;
|
||||
}
|
||||
|
||||
minutesToHm(mins?: number): string {
|
||||
if (mins == null) return '';
|
||||
const h = Math.floor(mins / 60);
|
||||
const m = mins % 60;
|
||||
return `${h}:${m.toString().padStart(2, '0')}`;
|
||||
}
|
||||
|
||||
private loadStaffData(from: Date, to: Date) {
|
||||
this.siteService.getStaffPlaytime(from.toISOString(), to.toISOString())
|
||||
.subscribe({
|
||||
next: data => {
|
||||
this.staffPt.set(data);
|
||||
},
|
||||
next: data => this.staffPt.set(data ?? []),
|
||||
error: err => console.error('Error getting staff playtime:', err)
|
||||
});
|
||||
}
|
||||
|
||||
private getStartOfWeek(date: Date): Date {
|
||||
const d = new Date(date);
|
||||
d.setDate(d.getDate() - d.getDay()); // Sunday start
|
||||
d.setHours(0, 0, 0, 0);
|
||||
return d;
|
||||
}
|
||||
|
||||
private getEndOfWeek(start: Date): Date {
|
||||
const d = new Date(start);
|
||||
d.setDate(start.getDate() + 6);
|
||||
d.setHours(23, 59, 59, 999);
|
||||
return d;
|
||||
}
|
||||
|
||||
private startOfDay(date: Date): Date {
|
||||
const d = new Date(date);
|
||||
d.setHours(0, 0, 0, 0);
|
||||
return d;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user