AltitudeWeb/frontend/src/app/pages/forms/appeal/appeal.component.ts

193 lines
5.7 KiB
TypeScript

import {AfterViewInit, Component, ElementRef, OnInit, Renderer2, signal} from '@angular/core';
import {FormControl, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms';
import {AppealsService, HistoryService, MinecraftAppeal, PunishmentHistory} from '@api';
import {HeaderComponent} from '@header/header.component';
import {NgOptimizedImage} from '@angular/common';
import {MatButtonModule} from '@angular/material/button';
import {MatIconModule} from '@angular/material/icon';
import {AuthService} from '@services/auth.service';
import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';
import {MatFormFieldModule} from '@angular/material/form-field';
import {MatSelectModule} from '@angular/material/select';
import {MatInputModule} from '@angular/material/input';
@Component({
selector: 'app-appeal',
imports: [
HeaderComponent,
NgOptimizedImage,
MatButtonModule,
MatIconModule,
MatProgressSpinnerModule,
MatFormFieldModule,
MatSelectModule,
MatInputModule,
ReactiveFormsModule,
],
templateUrl: './appeal.component.html',
styleUrl: './appeal.component.scss'
})
export class AppealComponent implements OnInit, AfterViewInit {
public form: FormGroup<Appeal>;
private resizeObserver: ResizeObserver | null = null;
private boundHandleResize: any;
protected history = signal<PunishmentHistory[] | null>(null);
protected selectedPunishment = signal<PunishmentHistory | null>(null);
constructor(
private appealApi: AppealsService,
private historyApi: HistoryService,
protected authService: AuthService,
private elementRef: ElementRef,
private renderer: Renderer2
) {
this.form = new FormGroup({
email: new FormControl('', {nonNullable: true, validators: [Validators.required, Validators.email]}),
appeal: new FormControl('', {nonNullable: true, validators: [Validators.required, Validators.minLength(10)]})
});
}
ngOnInit() {
const uuid = this.authService.getUuid();
if (uuid === null) {
throw new Error('JWT subject is null, are you logged in?');
}
this.historyApi.getAllHistoryForUUID(uuid).subscribe(history => {
this.history.set(history);
})
}
ngAfterViewInit() {
this.setupResizeObserver();
this.updateContainerHeight();
this.boundHandleResize = this.handleResize.bind(this);
window.addEventListener('resize', this.boundHandleResize);
setTimeout(() => this.updateContainerHeight(), 0);
}
ngOnDestroy() {
if (this.resizeObserver) {
this.resizeObserver.disconnect();
this.resizeObserver = null;
}
if (this.boundHandleResize) {
window.removeEventListener('resize', this.boundHandleResize);
}
}
private handleResize() {
this.updateContainerHeight();
}
private setupResizeObserver() {
this.resizeObserver = new ResizeObserver(() => {
this.updateContainerHeight();
});
const headerElement = document.querySelector('app-header');
if (headerElement) {
this.resizeObserver.observe(headerElement);
}
const footerElement = document.querySelector('footer');
if (footerElement) {
this.resizeObserver.observe(footerElement);
}
}
private updateContainerHeight() {
const headerElement = document.querySelector('app-header');
const footerElement = document.querySelector('footer');
const container = this.elementRef.nativeElement.querySelector('.appeal-container');
if (headerElement && footerElement && container) {
const headerHeight = headerElement.getBoundingClientRect().height;
const footerHeight = footerElement.getBoundingClientRect().height;
const calculatedHeight = `calc(100vh - ${headerHeight}px - ${footerHeight}px)`;
this.renderer.setStyle(container, 'min-height', calculatedHeight);
}
}
public onSubmit() {
if (this.form === undefined) {
console.error('Form is undefined');
return
}
if (this.form.valid) {
this.sendForm()
} else {
Object.keys(this.form.controls).forEach(field => {
const control = this.form!.get(field);
if (!(control instanceof FormGroup)) {
console.error('Control [' + control + '] is not a FormGroup');
return;
}
control.markAsTouched({onlySelf: true});
});
}
}
private sendForm() {
const rawValue = this.form.getRawValue();
const uuid = this.authService.getUuid();
if (uuid === null) {
throw new Error('JWT subject is null, are you logged in?');
}
const appeal: MinecraftAppeal = {
appeal: rawValue.appeal,
email: rawValue.email,
punishmentId: this.selectedPunishment()!.id,
username: this.authService.username()!,
uuid: uuid
}
this.appealApi.submitMinecraftAppeal(appeal).subscribe()
}
public currentPageIndex: number = 0;
public totalPages: number[] = [0];
public goToPage(pageIndex: number): void {
if (pageIndex >= 0 && pageIndex < this.totalPages.length) {
this.currentPageIndex = pageIndex;
}
}
public previousPage() {
this.goToPage(this.currentPageIndex - 1);
}
public nextPage() {
if (this.currentPageIndex === this.totalPages.length - 1) {
console.log('Adding page');
this.totalPages.push(this.currentPageIndex + 1);
console.log(this.totalPages);
}
this.goToPage(this.currentPageIndex + 1);
}
public isFirstPage(): boolean {
return this.currentPageIndex === 0;
}
public isLastPage(): boolean {
return this.currentPageIndex === this.totalPages.length - 1;
}
protected readonly length = length;
onPunishmentSelected($event: PunishmentHistory) {
this.selectedPunishment.set($event);
}
}
interface Appeal {
email: FormControl<string>;
appeal: FormControl<string>;
}