Replace deprecated Angular directives (*ngFor, *ngIf) with modern Angular template syntax. Remove unused CommonModule imports across components for optimization. Clean up excess spacing and formatting in HTML files.

This commit is contained in:
akastijn 2025-07-15 21:48:23 +02:00
parent d3ef296784
commit c2b9a8a574
37 changed files with 689 additions and 646 deletions

View File

@ -15,11 +15,12 @@
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"builder": "@angular/build:application",
"options": {
"outputPath": "dist",
"outputPath": {
"base": "dist"
},
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": [
"zone.js"
],
@ -34,7 +35,8 @@
"styles": [
"src/styles.scss"
],
"scripts": []
"scripts": [],
"browser": "src/main.ts"
},
"configurations": {
"production": {
@ -47,9 +49,7 @@
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"vendorChunk": false,
"buildOptimizer": true
"namedChunks": false
},
"development": {
"sourceMap": true,
@ -71,14 +71,12 @@
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"vendorChunk": false,
"buildOptimizer": true
"namedChunks": false
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"builder": "@angular/build:dev-server",
"configurations": {
"production": {
"buildTarget": "frontend:build:production"
@ -90,10 +88,10 @@
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n"
"builder": "@angular/build:extract-i18n"
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"builder": "@angular/build:karma",
"options": {
"polyfills": [
"zone.js",
@ -119,5 +117,31 @@
},
"cli": {
"analytics": false
},
"schematics": {
"@schematics/angular:component": {
"type": "component"
},
"@schematics/angular:directive": {
"type": "directive"
},
"@schematics/angular:service": {
"type": "service"
},
"@schematics/angular:guard": {
"typeSeparator": "."
},
"@schematics/angular:interceptor": {
"typeSeparator": "."
},
"@schematics/angular:module": {
"typeSeparator": "."
},
"@schematics/angular:pipe": {
"typeSeparator": "."
},
"@schematics/angular:resolver": {
"typeSeparator": "."
}
}
}

View File

@ -14,14 +14,14 @@
"private": true,
"dependencies": {
"@angular/cdk": "^19.2.18",
"@angular/common": "^19.2.0",
"@angular/compiler": "^19.2.0",
"@angular/core": "^19.2.0",
"@angular/forms": "^19.2.0",
"@angular/common": "^20.1.0",
"@angular/compiler": "^20.1.0",
"@angular/core": "^20.1.0",
"@angular/forms": "^20.1.0",
"@angular/material": "^19.2.19",
"@angular/platform-browser": "^19.2.0",
"@angular/platform-browser-dynamic": "^19.2.0",
"@angular/router": "^19.2.0",
"@angular/platform-browser": "^20.1.0",
"@angular/platform-browser-dynamic": "^20.1.0",
"@angular/router": "^20.1.0",
"@auth0/angular-jwt": "^5.2.0",
"@types/three": "^0.177.0",
"ngx-cookie-service": "^19.1.2",
@ -31,9 +31,9 @@
"zone.js": "~0.15.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^19.2.5",
"@angular/cli": "^19.2.5",
"@angular/compiler-cli": "^19.2.0",
"@angular/build": "^20.1.0",
"@angular/cli": "^20.1.0",
"@angular/compiler-cli": "^20.1.0",
"@types/jasmine": "~5.1.0",
"jasmine-core": "~5.6.0",
"karma": "~6.4.0",

View File

@ -1,15 +1,14 @@
import {Component} from '@angular/core';
import {ScrollService} from '@services/scroll.service';
import {CommonModule} from '@angular/common';
import {HeaderComponent} from '@header/header.component';
@Component({
selector: 'app-about',
standalone: true,
imports: [
CommonModule,
HeaderComponent
],
],
templateUrl: './about.component.html',
styleUrl: './about.component.scss'
})

View File

@ -1,15 +1,14 @@
import {Component} from '@angular/core';
import {ScrollService} from '@services/scroll.service';
import {CommonModule} from '@angular/common';
import {HeaderComponent} from '@header/header.component';
@Component({
selector: 'app-birthdays',
standalone: true,
imports: [
CommonModule,
HeaderComponent
],
],
templateUrl: './birthdays.component.html',
styleUrl: './birthdays.component.scss'
})

View File

@ -1,16 +1,15 @@
import {Component} from '@angular/core';
import {ScrollService} from '@services/scroll.service';
import {CommonModule, NgOptimizedImage} from '@angular/common';
import { NgOptimizedImage } from '@angular/common';
import {HeaderComponent} from '@header/header.component';
@Component({
selector: 'app-socials',
standalone: true,
imports: [
CommonModule,
HeaderComponent,
NgOptimizedImage
],
],
templateUrl: './socials.component.html',
styleUrl: './socials.component.scss'
})

View File

@ -12,61 +12,75 @@
<section class="darkmodeSection">
<div class="container teamContainer">
<h2 class="sectionTitle">Management</h2>
<div *ngFor="let member of getTeamMembers('owner') | async" class="member">
@for (member of getTeamMembers('owner') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2>
<p>Owner</p>
</div>
<div *ngFor="let member of getTeamMembers('manager') | async" class="member">
}
@for (member of getTeamMembers('manager') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2>
<p>Manager</p>
</div>
}
</div>
</section>
<section class="darkmodeSectionThree">
<div class="container teamContainer">
<h2 class="sectionTitle">Admins</h2>
<div *ngFor="let member of getTeamMembers('admin') | async" class="member">
@for (member of getTeamMembers('admin') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2>
<p>Admin</p>
</div>
}
</div>
</section>
<section class="darkmodeSection">
<div class="container teamContainer">
<h2 class="sectionTitle">Head Moderators</h2>
<div *ngFor="let member of getTeamMembers('headmod') | async" class="member">
@for (member of getTeamMembers('headmod') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2>
<p>Head Mod</p>
</div>
}
</div>
</section>
<section class="darkmodeSectionThree">
<div class="container teamContainer">
<h2 class="sectionTitle">Moderators</h2>
<div *ngFor="let member of getTeamMembers('moderator') | async" class="member">
@for (member of getTeamMembers('moderator') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2>
</div>
}
</div>
</section>
<section *ngIf="(getTeamMembers('trainee') | async)?.length ?? 0 > 0" class="darkmodeSection">
@if ((getTeamMembers('trainee') | async)?.length ?? 0 > 0) {
<section class="darkmodeSection">
<div class="container teamContainer">
<h2 class="sectionTitle">Trainees</h2>
<div *ngFor="let member of getTeamMembers('trainee') | async" class="member">
@for (member of getTeamMembers('trainee') | async; track member) {
<div class="member">
<img [ngSrc]="getAvatarUrl(member)" alt="{{member.name}}'s Minecraft skin"
height="160" width="160" style="width: 160px;">
<h2>{{ member.name }}</h2>
</div>
}
</div>
</section>
}
</main>
</ng-container>
</ng-container>

View File

@ -1,7 +1,7 @@
import {Component} from '@angular/core';
import {ScrollService} from '@services/scroll.service';
import {BASE_PATH, Player, TeamService} from '@api';
import {CommonModule, NgOptimizedImage} from '@angular/common';
import { CommonModule, NgOptimizedImage } from '@angular/common';
import {HeaderComponent} from '@header/header.component';
import {CookieService} from 'ngx-cookie-service';
import {map, Observable, shareReplay} from 'rxjs';

View File

@ -1,13 +1,12 @@
import {Component} from '@angular/core';
import {CommonModule} from '@angular/common';
import {HeaderComponent} from '@header/header.component';
@Component({
standalone: true,
imports: [
CommonModule,
HeaderComponent
],
],
selector: 'app-map',
templateUrl: './map.component.html',
styleUrl: './map.component.scss'

View File

@ -1,16 +1,15 @@
import {Component} from '@angular/core';
import {ALTITUDE_VERSION} from '@custom-types/constant';
import {CommonModule, NgOptimizedImage} from '@angular/common';
import { NgOptimizedImage } from '@angular/common';
import {RouterLink} from '@angular/router';
@Component({
selector: 'app-footer',
standalone: true,
imports: [
CommonModule,
RouterLink,
NgOptimizedImage
],
],
templateUrl: './footer.component.html',
styleUrl: './footer.component.scss'
})

View File

@ -1,6 +1,6 @@
import {Component} from '@angular/core';
import {ScrollService} from '@services/scroll.service';
import {CommonModule} from '@angular/common';
import {HeaderComponent} from '@header/header.component';
import {RouterLink} from '@angular/router';
@ -8,10 +8,9 @@ import {RouterLink} from '@angular/router';
selector: 'app-privacy',
standalone: true,
imports: [
CommonModule,
HeaderComponent,
RouterLink
],
],
templateUrl: './privacy.component.html',
styleUrl: './privacy.component.scss'
})

View File

@ -1,7 +1,7 @@
import {Component} from '@angular/core';
import {ScrollService} from '@services/scroll.service';
import {HeaderComponent} from '@header/header.component';
import {CommonModule} from '@angular/common';
import {RouterLink} from '@angular/router';
@Component({
@ -9,10 +9,9 @@ import {RouterLink} from '@angular/router';
standalone: true,
templateUrl: './terms.component.html',
imports: [
CommonModule,
HeaderComponent,
RouterLink
],
],
styleUrl: './terms.component.scss'
})
export class TermsComponent {

View File

@ -5,13 +5,13 @@
<h1>{{ formTitle }}</h1>
</div>
</app-header>
<ng-container *ngIf="!type">
<ng-container *ngFor="let formType of FormType | keyvalue">
@if (!type) {
@for (formType of FormType | keyvalue; track formType) {
<button mat-raised-button (click)="setFormType(formType.value)">
{{ formType }}
</button>
</ng-container>
</ng-container>
}
}
<div>
<ng-content select="[form-content]"></ng-content>
</div>

View File

@ -3,7 +3,7 @@ import {HeaderComponent} from '@header/header.component';
import {MatDialog} from '@angular/material/dialog';
import {ActivatedRoute} from '@angular/router';
import {LoginDialogComponent} from '@shared-components/login/login.component';
import {KeyValuePipe, NgForOf, NgIf} from '@angular/common';
import { KeyValuePipe } from '@angular/common';
import {FormType} from './form_type';
import {MatButton} from '@angular/material/button';
import {AuthService} from '@services/auth.service';
@ -12,11 +12,9 @@ import {AuthService} from '@services/auth.service';
selector: 'app-forms',
imports: [
HeaderComponent,
NgIf,
NgForOf,
MatButton,
KeyValuePipe
],
],
templateUrl: './forms.component.html',
styleUrl: './forms.component.scss'
})

View File

@ -62,11 +62,13 @@
<li><a href="https://alttd.com/blog/">Blog</a></li>
</ul>
</li>
<li *ngIf="!isAuthenticated">
@if (!isAuthenticated) {
<li>
<a (click)="openLoginDialog()">
Login
</a>
</li>
}
</ul>
</div>
</div>
@ -135,25 +137,31 @@
<li class="nav_li"><a class="nav_link2" target="_blank" href="https://alttd.com/blog/">Blog</a></li>
</ul>
</li>
<li class="nav_li" *ngIf="isAuthenticated">
@if (isAuthenticated) {
<li class="nav_li">
<a [id]="getCurrentPageId(['particles'])"
class="nav_link fake_link" [ngClass]="active">Special</a>
<ul class="dropdown" *ngIf="hasAccess(['HEAD_MOD'])">
@if (hasAccess(['HEAD_MOD'])) {
<ul class="dropdown">
<li class="nav_li"><a class="nav_link2" [routerLink]="['/particles']">Particles</a></li>
</ul>
}
</li>
<li class="nav_li login-button" *ngIf="!isAuthenticated">
}
@if (!isAuthenticated) {
<li class="nav_li login-button">
<a class="nav_link fake_link" (click)="openLoginDialog()">
Login
</a>
</li>
}
</ul>
<app-theme></app-theme>
</div>
</nav>
</nav>
<ng-content select="[header-content]"></ng-content>
<ng-content select="[header-content]"></ng-content>
</header>
</header>
</ng-container>

View File

@ -5,7 +5,6 @@ import {RouterLink} from '@angular/router';
import {AuthService} from '@services/auth.service';
import {Subscription} from 'rxjs';
import {LoginDialogComponent} from '@shared-components/login/login.component';
import {MatButton} from '@angular/material/button';
import {MatDialog} from '@angular/material/dialog';
@Component({
@ -14,8 +13,7 @@ import {MatDialog} from '@angular/material/dialog';
CommonModule,
ThemeComponent,
RouterLink,
NgOptimizedImage,
MatButton
NgOptimizedImage
],
selector: 'app-header',
templateUrl: './header.component.html',

View File

@ -125,9 +125,9 @@
</div>
</div>
<div class="dots">
<ng-container *ngFor="let slide of getSlideIndices();">
@for (slide of getSlideIndices(); track slide) {
<span class="dot" (click)="setSlide(slide)" [ngClass]="getDotClass(slide)"></span>
</ng-container>
}
</div>
</div>
</div>
@ -154,4 +154,4 @@
<p style="display: none;">Scroll Down</p>
</a>
</main>
</ng-container>
</ng-container>

View File

@ -2,7 +2,7 @@ import {Component, OnInit} from '@angular/core';
import {Title} from '@angular/platform-browser';
import {ALTITUDE_VERSION} from '@custom-types/constant';
import {ScrollService} from '@services/scroll.service';
import {CommonModule, NgOptimizedImage} from '@angular/common';
import { CommonModule, NgOptimizedImage } from '@angular/common';
import {HeaderComponent} from '@header/header.component';
import {CopyIpComponent} from '@shared-components/copy-ip/copy-ip.component';
import {RouterLink} from '@angular/router';

View File

@ -7,11 +7,13 @@
<div class="frames-container">
<mat-tab-group [selectedIndex]="frames.indexOf(currentFrame)"
(selectedIndexChange)="switchFrame(frames[$event])">
<mat-tab *ngFor="let frameId of frames" [label]="frameId">
@for (frameId of frames; track frameId) {
<mat-tab [label]="frameId">
<div class="frame-content">
<h3>Particles in {{ frameId }}</h3>
<div class="particles-list">
<div *ngFor="let particle of particleData.frames[frameId]; let i = index" class="particle-item">
@for (particle of particleData.frames[frameId]; track particle; let i = $index) {
<div class="particle-item">
<span class="particle-item-text">
Particle {{ i + 1 }}: ({{ particle.x.toFixed(2) }}, {{ particle.y.toFixed(2) }}
, {{ particle.z.toFixed(2) }})
@ -23,10 +25,13 @@
<mat-icon>lightbulb</mat-icon>
</button>
</div>
<div *ngIf="!particleData.frames[frameId] || particleData.frames[frameId].length === 0"
}
@if (!particleData.frames[frameId] || particleData.frames[frameId].length === 0) {
<div
class="no-particles">
No particles in this frame. Click on the plane to add particles.
</div>
}
</div>
<div class="frame-actions">
<button mat-raised-button color="warn" (click)="removeFrame(frameId)"
@ -36,6 +41,7 @@
</div>
</div>
</mat-tab>
}
</mat-tab-group>
<div class="add-frame">
<button mat-raised-button color="primary" (click)="addFrame()">

View File

@ -2,7 +2,7 @@ import {Component} from '@angular/core';
import {MatButton, MatIconButton} from "@angular/material/button";
import {MatCard, MatCardContent, MatCardHeader, MatCardTitle} from "@angular/material/card";
import {MatTab, MatTabGroup} from "@angular/material/tabs";
import {NgForOf, NgIf} from "@angular/common";
import {ParticleData} from '../../models/particle.model';
import {MatIcon} from '@angular/material/icon';
import {ParticleManagerService} from '../../services/particle-manager.service';
@ -19,10 +19,8 @@ import {FrameManagerService} from '../../services/frame-manager.service';
MatIcon,
MatIconButton,
MatTab,
MatTabGroup,
NgForOf,
NgIf
],
MatTabGroup
],
templateUrl: './frames.component.html',
styleUrl: './frames.component.scss'
})

View File

@ -18,9 +18,11 @@
[formControl]="particleTypeControl"
[matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
<mat-option *ngFor="let type of filteredParticleTypes | async" [value]="type">
@for (type of filteredParticleTypes | async; track type) {
<mat-option [value]="type">
{{ type }}
</mat-option>
}
</mat-autocomplete>
</mat-form-field>
</div>
@ -34,4 +36,4 @@
</div>
</mat-card-content>
</mat-card>
</div>
</div>

View File

@ -10,7 +10,7 @@ import {MatInputModule} from '@angular/material/input';
import {MatAutocompleteModule} from '@angular/material/autocomplete';
import {Observable} from 'rxjs';
import {map, startWith} from 'rxjs/operators';
import {AsyncPipe, NgForOf} from '@angular/common';
import { AsyncPipe } from '@angular/common';
@Component({
selector: 'app-particle',
@ -26,9 +26,8 @@ import {AsyncPipe, NgForOf} from '@angular/common';
MatFormFieldModule,
MatInputModule,
MatAutocompleteModule,
NgForOf,
AsyncPipe
],
],
templateUrl: './particle.component.html',
styleUrl: './particle.component.scss'
})

View File

@ -22,7 +22,9 @@
<mat-form-field appearance="outline">
<mat-label>Particle Type</mat-label>
<mat-select [(ngModel)]="particleData.particle_type">
<mat-option *ngFor="let type of particleTypes" [value]="type">{{ type }}</mat-option>
@for (type of particleTypes; track type) {
<mat-option [value]="type">{{ type }}</mat-option>
}
</mat-select>
</mat-form-field>
</div>
@ -90,4 +92,4 @@
</div>
</mat-card-content>
</mat-card>
</div>
</div>

View File

@ -2,7 +2,7 @@ import {Component} from '@angular/core';
import {MatCard, MatCardContent, MatCardHeader, MatCardTitle} from "@angular/material/card";
import {MatCheckbox} from "@angular/material/checkbox";
import {MatFormField, MatInput, MatLabel} from "@angular/material/input";
import {NgForOf} from "@angular/common";
import {FormsModule, ReactiveFormsModule} from "@angular/forms";
import {ParticleData, ParticleType} from '../../models/particle.model';
import {MatSelect} from '@angular/material/select';
@ -22,10 +22,9 @@ import {ParticleManagerService} from '../../services/particle-manager.service';
MatLabel,
MatOption,
MatSelect,
NgForOf,
ReactiveFormsModule,
FormsModule
],
],
templateUrl: './properties.component.html',
styleUrl: './properties.component.scss'
})

View File

@ -18,7 +18,8 @@
</button>
</div>
<div *ngIf="isPlaneLocked" class="plane-orientation-buttons">
@if (isPlaneLocked) {
<div class="plane-orientation-buttons">
<button mat-mini-fab color="warn" (click)="setPlaneOrientation(planeOrientations.VERTICAL_ABOVE)"
[class.active]="currentPlaneOrientation === planeOrientations.VERTICAL_ABOVE"
matTooltip="Vertical Above">
@ -50,5 +51,6 @@
<mat-icon>arrow_left</mat-icon>
</button>
</div>
}
</div>
</div>

View File

@ -1,6 +1,6 @@
import {AfterViewInit, Component, ElementRef, OnDestroy, ViewChild} from '@angular/core';
import {MatMiniFabButton} from '@angular/material/button';
import {NgIf} from '@angular/common';
import {IntersectionPlaneService, PlaneOrientation} from '../../services/intersection-plane.service';
import {MatIcon} from '@angular/material/icon';
import {MatTooltip} from '@angular/material/tooltip';
@ -16,12 +16,11 @@ import {MatFormField, MatInput, MatLabel} from '@angular/material/input';
MatIcon,
MatMiniFabButton,
MatTooltip,
NgIf,
FormsModule,
MatInput,
MatFormField,
MatLabel
],
],
templateUrl: './render-container.component.html',
styleUrl: './render-container.component.scss'
})

View File

@ -1,5 +1,5 @@
import {Component, ElementRef, ViewChild} from '@angular/core';
import {CommonModule} from '@angular/common';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
import {MatButtonModule} from '@angular/material/button';
import {MatInputModule} from '@angular/material/input';
@ -28,7 +28,6 @@ import {ParticlesService} from '@api';
selector: 'app-particles',
standalone: true,
imports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
MatButtonModule,
@ -44,8 +43,8 @@ import {ParticlesService} from '@api';
PropertiesComponent,
ParticleComponent,
FramesComponent,
RenderContainerComponent,
],
RenderContainerComponent
],
templateUrl: './particles.component.html',
styleUrl: './particles.component.scss'
})

View File

@ -45,14 +45,17 @@
(input)="filterNames()"
(keyup.enter)="search()"
>
<div class="dropdown-results" *ngIf="filteredNames.length > 0 && searchTerm">
@if (filteredNames.length > 0 && searchTerm) {
<div class="dropdown-results">
@for (name of filteredNames; track name) {
<div
class="dropdown-item"
*ngFor="let name of filteredNames"
(mousedown)="selectName(name)">
{{ name }}
</div>
}
</div>
}
</div>
</div>
<div class="historyTable">
@ -87,4 +90,4 @@
</div>
</section>
</main>
</ng-container>
</ng-container>

View File

@ -2,7 +2,7 @@ import {Component, OnInit} from '@angular/core';
import {HeaderComponent} from "@header/header.component";
import {HistoryComponent} from './history/history.component';
import {HistoryCount, HistoryService} from '@api';
import {NgClass, NgForOf, NgIf} from '@angular/common';
import { NgClass } from '@angular/common';
import {FormsModule} from '@angular/forms';
import {catchError, map, Observable} from 'rxjs';
import {SearchParams} from './search-terms';
@ -12,11 +12,9 @@ import {SearchParams} from './search-terms';
imports: [
HeaderComponent,
HistoryComponent,
NgIf,
FormsModule,
NgForOf,
NgClass
],
],
templateUrl: './bans.component.html',
styleUrl: './bans.component.scss'
})

View File

@ -10,15 +10,15 @@
<section class="darkmodeSection">
<section class="columnSection">
<div class="detailsBackButton">
<ng-container *ngIf="punishment === undefined">
@if (punishment === undefined) {
<p>Loading...</p>
</ng-container>
}
<a [routerLink]="['/bans']">< Back</a>
</div>
</section>
<section class="columnSection center">
<ng-container *ngIf="punishment">
@if (punishment) {
<div>
<span class="tag tagInfo"
[ngClass]="{
@ -38,12 +38,12 @@
{{ this.historyFormat.isActive(punishment) ? 'Active' : 'Inactive' }}
</span>
</div>
</ng-container>
}
</section>
<section class="columnSection">
<div class="columnContainer">
<div class="columnParagraph">
<ng-container *ngIf="punishment">
@if (punishment) {
<div class="playerContainer">
<h2>Player</h2>
<img class="avatar" [ngSrc]="this.historyFormat.getAvatarUrl(punishment.uuid, '150')"
@ -53,12 +53,12 @@
>
<h3 class="detailsUsername">{{ punishment.username }}</h3>
</div>
</ng-container>
}
</div>
</div>
<div class="columnContainer">
<div class="columnParagraph">
<ng-container *ngIf="punishment">
@if (punishment) {
<div class="playerContainer">
<h2>Moderator</h2>
<img class="avatar" [ngSrc]="this.historyFormat.getAvatarUrl(punishment.punishedByUuid, '150')"
@ -68,42 +68,42 @@
>
<h3 class="detailsUsername">{{ punishment.punishedBy }}</h3>
</div>
</ng-container>
}
</div>
</div>
<div class="columnContainer">
<div class="columnParagraph">
<ng-container *ngIf="punishment">
@if (punishment) {
<div class="detailsInfo">
<h2>Reason</h2>
<p>{{ punishment.reason | removeTrailingPeriod }}</p>
</div>
</ng-container>
}
</div>
</div>
<div class="columnContainer">
<div class="columnParagraph">
<ng-container *ngIf="punishment">
@if (punishment) {
<div class="detailsInfo">
<h2>Date</h2>
<p>{{ this.historyFormat.getPunishmentTime(punishment) }}</p>
</div>
</ng-container>
}
</div>
</div>
</section>
</section>
</main>
</ng-container>
</ng-container>
<section class="columnSection">
<ng-container *ngIf="punishment">
<section class="columnSection">
@if (punishment) {
<span>Expires</span>
<span>{{ this.historyFormat.getExpiredTime(punishment) }}</span>
<ng-container *ngIf="punishment.removedBy !== undefined && punishment.removedBy.length > 0">
@if (punishment.removedBy !== undefined && punishment.removedBy.length > 0) {
<span>Un{{ this.historyFormat.getType(punishment).toLocaleLowerCase() }} reason</span>
<span>{{ punishment.removedReason == null ? 'No reason specified' : punishment.removedReason }}</span>
</ng-container>
</ng-container>
</section>
}
}
</section>

View File

@ -1,6 +1,6 @@
import {Component, OnInit} from '@angular/core';
import {HistoryService, PunishmentHistory} from '@api';
import {NgClass, NgIf, NgOptimizedImage} from '@angular/common';
import { NgClass, NgOptimizedImage } from '@angular/common';
import {RemoveTrailingPeriodPipe} from '@pipes/RemoveTrailingPeriodPipe';
import {HistoryFormatService} from '../history-format.service';
import {ActivatedRoute, RouterLink} from '@angular/router';
@ -10,13 +10,12 @@ import {HeaderComponent} from '@header/header.component';
@Component({
selector: 'app-details',
imports: [
NgIf,
NgOptimizedImage,
RemoveTrailingPeriodPipe,
HeaderComponent,
RouterLink,
NgClass
],
],
templateUrl: './details.component.html',
styleUrl: './details.component.scss'
})

View File

@ -1,8 +1,8 @@
<ng-container *ngIf="history.length === 0">
@if (history.length === 0) {
<p>No history found</p>
</ng-container>
}
<ng-container *ngIf="history.length > 0">
@if (history.length > 0) {
<table [cellSpacing]="0">
<div class="historyTableHead">
<thead>
@ -18,7 +18,8 @@
</div>
<div>
<tbody>
<tr class="historyPlayerRow" *ngFor="let entry of history">
@for (entry of history; track entry) {
<tr class="historyPlayerRow">
<td class="historyType" (click)="showDetailedPunishment(entry)">
{{ this.historyFormat.getType(entry) }}
</td>
@ -46,8 +47,9 @@
{{ this.historyFormat.getExpiredTime(entry) }}
</td>
</tr>
}
</tbody>
</div>
</table>
</ng-container>
}

View File

@ -1,7 +1,7 @@
import {Component, EventEmitter, Input, OnChanges, OnInit, Output} from '@angular/core';
import {BASE_PATH, HistoryService, PunishmentHistory} from '@api';
import {catchError, map, Observable, shareReplay} from 'rxjs';
import {NgForOf, NgIf, NgOptimizedImage} from '@angular/common';
import { NgOptimizedImage } from '@angular/common';
import {CookieService} from 'ngx-cookie-service';
import {RemoveTrailingPeriodPipe} from '@pipes/RemoveTrailingPeriodPipe';
import {HttpErrorResponse} from '@angular/common/http';
@ -13,11 +13,9 @@ import {Router} from '@angular/router';
@Component({
selector: 'app-history',
imports: [
NgIf,
NgForOf,
NgOptimizedImage,
RemoveTrailingPeriodPipe
],
],
templateUrl: './history.component.html',
styleUrl: './history.component.scss',
providers: [

View File

@ -1,15 +1,14 @@
import {Component} from '@angular/core';
import {ScrollService} from '@services/scroll.service';
import {CommonModule} from '@angular/common';
import {HeaderComponent} from '@header/header.component';
@Component({
selector: 'app-vote',
standalone: true,
imports: [
CommonModule,
HeaderComponent
],
],
templateUrl: './vote.component.html',
styleUrl: './vote.component.scss'
})

View File

@ -1,13 +1,11 @@
import {Component} from '@angular/core';
import {CommonModule} from '@angular/common';
@Component({
selector: 'app-copy-ip',
templateUrl: './copy-ip.component.html',
standalone: true,
imports: [
CommonModule
],
imports: [],
styleUrl: './copy-ip.component.scss'
})
export class CopyIpComponent {

View File

@ -4,18 +4,26 @@
<mat-form-field appearance="fill" style="width: 100%">
<mat-label>Enter your code</mat-label>
<input matInput formControlName="code" type="text" (keyup)="onKeyUp()">
<mat-error *ngIf="loginForm.get('code')?.errors?.['required']">
@if (loginForm.get('code')?.errors?.['required']) {
<mat-error>
Code is required
</mat-error>
<mat-error *ngIf="loginForm.get('code')?.errors?.['minlength']">
}
@if (loginForm.get('code')?.errors?.['minlength']) {
<mat-error>
Code must be 8 characters
</mat-error>
<mat-error *ngIf="loginForm.get('code')?.errors?.['maxlength']">
}
@if (loginForm.get('code')?.errors?.['maxlength']) {
<mat-error>
Code cannot exceed 8 characters
</mat-error>
<mat-error *ngIf="loginForm.get('code')?.errors?.['pattern']">
}
@if (loginForm.get('code')?.errors?.['pattern']) {
<mat-error>
Code contains invalid characters
</mat-error>
}
</mat-form-field>
</form>
</div>

View File

@ -4,7 +4,7 @@ import {FormBuilder, FormGroup, ReactiveFormsModule, Validators} from '@angular/
import {MatButtonModule} from '@angular/material/button';
import {MatInputModule} from '@angular/material/input';
import {MatFormFieldModule} from '@angular/material/form-field';
import {NgIf} from '@angular/common';
import {MatSnackBar} from '@angular/material/snack-bar';
import {AuthService} from '@services/auth.service';
@ -18,9 +18,8 @@ import {AuthService} from '@services/auth.service';
MatFormFieldModule,
MatDialogTitle,
MatDialogContent,
MatDialogActions,
NgIf
],
MatDialogActions
],
templateUrl: './login.component.html',
styleUrl: './login.component.scss'
})

View File

@ -2,13 +2,11 @@ import {Component, OnDestroy, OnInit} from '@angular/core';
import {Subscription} from 'rxjs';
import {ThemeService} from './theme.service';
import {THEME_MODE} from '@custom-types/constant';
import {CommonModule} from '@angular/common';
@Component({
standalone: true,
imports: [
CommonModule,
],
imports: [],
selector: 'app-theme',
templateUrl: './theme.component.html',
styleUrl: './theme.component.scss'