Compare commits

...

3 Commits

9 changed files with 251 additions and 200 deletions

View File

@ -6,6 +6,7 @@
</div> </div>
</app-header> </app-header>
<main> <main>
<app-full-size>
<section class="darkmodeSection appeal-container"> <section class="darkmodeSection appeal-container">
<div class="form-container"> <div class="form-container">
<div class="pages"> <div class="pages">
@ -35,7 +36,8 @@
@if (currentPageIndex === 1) { @if (currentPageIndex === 1) {
<section class="formPage"> <section class="formPage">
<div class="description"> <div class="description">
<p>You are logged in as <strong>{{ authService.username() }}</strong>. If this is the correct account <p>You are logged in as <strong>{{ authService.username() }}</strong>. If this is the correct
account
please continue</p> please continue</p>
<br> <br>
<p><strong>Notice: </strong> Submitting an appeal is <strong>not</strong> an instant process. <p><strong>Notice: </strong> Submitting an appeal is <strong>not</strong> an instant process.
@ -101,7 +103,8 @@
</div> </div>
} }
</div> </div>
<button mat-raised-button (click)="validateMailOrNextPage()" [disabled]="form.controls.email.invalid"> <button mat-raised-button (click)="validateMailOrNextPage()"
[disabled]="form.controls.email.invalid">
Next Next
</button> </button>
</section> </section>
@ -157,5 +160,7 @@
} }
</div> </div>
</section> </section>
</app-full-size>
</main> </main>
</div> </div>

View File

@ -5,7 +5,7 @@
.appeal-container { .appeal-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
min-height: 80vh; height: 100%;
} }
main { main {

View File

@ -1,14 +1,4 @@
import { import {Component, computed, inject, OnDestroy, OnInit, signal} from '@angular/core';
AfterViewInit,
Component,
computed,
ElementRef,
inject,
OnDestroy,
OnInit,
Renderer2,
signal
} from '@angular/core';
import {FormControl, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms'; import {FormControl, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms';
import {AppealsService, EmailEntry, HistoryService, MailService, MinecraftAppeal, PunishmentHistory} from '@api'; import {AppealsService, EmailEntry, HistoryService, MailService, MinecraftAppeal, PunishmentHistory} from '@api';
import {HeaderComponent} from '@header/header.component'; import {HeaderComponent} from '@header/header.component';
@ -24,6 +14,7 @@ import {HistoryFormatService} from '@pages/reference/bans/history-format.service
import {MatDialog} from '@angular/material/dialog'; import {MatDialog} from '@angular/material/dialog';
import {VerifyMailDialogComponent} from '@pages/forms/verify-mail-dialog/verify-mail-dialog.component'; import {VerifyMailDialogComponent} from '@pages/forms/verify-mail-dialog/verify-mail-dialog.component';
import {Router} from '@angular/router'; import {Router} from '@angular/router';
import {FullSizeComponent} from '@shared-components/full-size/full-size.component';
@Component({ @Component({
selector: 'app-appeal', selector: 'app-appeal',
@ -37,11 +28,12 @@ import {Router} from '@angular/router';
MatSelectModule, MatSelectModule,
MatInputModule, MatInputModule,
ReactiveFormsModule, ReactiveFormsModule,
FullSizeComponent,
], ],
templateUrl: './appeal.component.html', templateUrl: './appeal.component.html',
styleUrl: './appeal.component.scss' styleUrl: './appeal.component.scss'
}) })
export class AppealComponent implements OnInit, OnDestroy, AfterViewInit { export class AppealComponent implements OnInit, OnDestroy {
private mailService = inject(MailService); private mailService = inject(MailService);
private historyFormatService = inject(HistoryFormatService); private historyFormatService = inject(HistoryFormatService);
@ -61,10 +53,7 @@ export class AppealComponent implements OnInit, OnDestroy, AfterViewInit {
protected emailIsValid = signal<boolean>(false); protected emailIsValid = signal<boolean>(false);
protected dialog = inject(MatDialog); protected dialog = inject(MatDialog);
constructor( constructor() {
private elementRef: ElementRef,
private renderer: Renderer2
) {
this.form = new FormGroup({ this.form = new FormGroup({
email: new FormControl('', {nonNullable: true, validators: [Validators.required, Validators.email]}), email: new FormControl('', {nonNullable: true, validators: [Validators.required, Validators.email]}),
appeal: new FormControl('', {nonNullable: true, validators: [Validators.required, Validators.minLength(10)]}) appeal: new FormControl('', {nonNullable: true, validators: [Validators.required, Validators.minLength(10)]})
@ -97,16 +86,6 @@ export class AppealComponent implements OnInit, OnDestroy, AfterViewInit {
}) })
} }
ngAfterViewInit() {
this.setupResizeObserver();
this.updateContainerHeight();
this.boundHandleResize = this.handleResize.bind(this);
window.addEventListener('resize', this.boundHandleResize);
setTimeout(() => this.updateContainerHeight(), 0);
}
ngOnDestroy() { ngOnDestroy() {
if (this.resizeObserver) { if (this.resizeObserver) {
this.resizeObserver.disconnect(); this.resizeObserver.disconnect();
@ -118,41 +97,6 @@ export class AppealComponent implements OnInit, OnDestroy, AfterViewInit {
} }
} }
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() { public onSubmit() {
if (this.form === undefined) { if (this.form === undefined) {
console.error('Form is undefined'); console.error('Form is undefined');

View File

@ -6,8 +6,13 @@
</div> </div>
</app-header> </app-header>
<main> <main>
<section class="darkmodeSection"> <app-full-size>
<section class="darkmodeSection full-height flex">
<div class="margin-auto">
<p>{{ message }}</p> <p>{{ message }}</p>
</div>
</section> </section>
</app-full-size>
</main> </main>
</div> </div>

View File

@ -1,11 +1,13 @@
import {Component, inject, OnInit} from '@angular/core'; import {Component, inject, OnInit} from '@angular/core';
import {Router} from '@angular/router'; import {Router} from '@angular/router';
import {FullSizeComponent} from '@shared-components/full-size/full-size.component';
import {HeaderComponent} from '@header/header.component'; import {HeaderComponent} from '@header/header.component';
@Component({ @Component({
selector: 'app-sent', selector: 'app-sent',
imports: [ imports: [
HeaderComponent HeaderComponent,
FullSizeComponent
], ],
templateUrl: './sent.component.html', templateUrl: './sent.component.html',
styleUrl: './sent.component.scss', styleUrl: './sent.component.scss',

View File

@ -0,0 +1,3 @@
<div class="full-size-container">
<ng-content></ng-content>
</div>

View File

@ -0,0 +1,8 @@
:host {
display: block;
}
.full-size-container {
display: flex;
flex-direction: column;
}

View File

@ -0,0 +1,80 @@
import {AfterViewInit, Component, ElementRef, Input, OnDestroy, Renderer2} from '@angular/core';
@Component({
selector: 'app-full-size',
standalone: true,
imports: [],
templateUrl: './full-size.component.html',
styleUrl: './full-size.component.scss'
})
export class FullSizeComponent implements AfterViewInit, OnDestroy {
private resizeObserver: ResizeObserver | null = null;
private boundHandleResize: any;
// Optional extra offset in pixels to subtract from available height
@Input() extraOffset: number = 0;
constructor(
private elementRef: ElementRef,
private renderer: Renderer2
) {
}
ngAfterViewInit(): void {
this.setupResizeObserver();
this.updateContainerHeight();
this.boundHandleResize = this.handleResize.bind(this);
window.addEventListener('resize', this.boundHandleResize);
// Ensure first paint sets correct height
setTimeout(() => this.updateContainerHeight(), 0);
}
ngOnDestroy(): void {
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: HTMLElement | null = this.elementRef.nativeElement.querySelector('.full-size-container');
if (container) {
const headerHeight = headerElement ? headerElement.getBoundingClientRect().height : 0;
const footerHeight = footerElement ? footerElement.getBoundingClientRect().height : 0;
const totalOffset = headerHeight + footerHeight + (this.extraOffset || 0);
const calculatedHeight = `calc(100vh - ${totalOffset}px)`;
this.renderer.setStyle(container, 'height', calculatedHeight);
}
}
}

View File

@ -479,3 +479,7 @@ main .container {
width: 100%; width: 100%;
} }
} }
.margin-auto {
margin: auto
}