feat: list and remove umpires from tab 2

This commit is contained in:
2026-05-24 17:47:42 +02:00
parent 0f46cb3c93
commit 56b9a186d4
5 changed files with 242 additions and 12 deletions
+8
View File
@@ -0,0 +1,8 @@
import { FullnamePipe } from './fullname-pipe';
describe('FullnamePipePipe', () => {
it('create an instance', () => {
const pipe = new FullnamePipe();
expect(pipe).toBeTruthy();
});
});
+13
View File
@@ -0,0 +1,13 @@
import { Pipe, PipeTransform } from '@angular/core';
import { Umpire } from 'db';
@Pipe({
name: 'fullname',
standalone: true
})
export class FullnamePipe implements PipeTransform {
transform(value: Umpire, ...args: unknown[]): string {
// TODO: in case of multilang, change here
return value.lastName + ' ' + value.firstName;
}
}
+87 -5
View File
@@ -1,17 +1,99 @@
<ion-header [translucent]="true">
<ion-toolbar>
<ion-title>
Tab 2
</ion-title>
<ion-title> Játékvezetők </ion-title>
<ion-buttons [slot]="'end'">
<ion-button [color]="'primary'" [fill]="'solid'" id="open-modal">
<ion-icon slot="start" name="add"></ion-icon>
Hozzáadás
</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content [fullscreen]="true">
<ion-header collapse="condense">
<ion-toolbar>
<ion-title size="large">Tab 2</ion-title>
<ion-title size="large">Játékvezetők</ion-title>
</ion-toolbar>
</ion-header>
<app-explore-container name="Tab 2 page"></app-explore-container>
<ion-grid>
<ion-row>
<ion-col size="12" sizeMd="6" pushMd="3">
<ion-list>
@for (umpire of umpires(); track umpire.id) {
<ion-item>
<ion-label> {{ umpire | fullname }} </ion-label>
<ion-button
[color]="'danger'"
slot="end"
(click)="showDeleteConfirmation(umpire)">
<ion-icon slot="icon-only" name="trash"></ion-icon>
</ion-button>
</ion-item>
} @empty {
<ion-item> Nincsenek játékvezetők </ion-item>
}
</ion-list>
</ion-col>
</ion-row>
</ion-grid>
<ion-modal trigger="open-modal" (willDismiss)="onWillDismiss($event)">
<ng-template>
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-button (click)="cancel()">Mégse</ion-button>
</ion-buttons>
<ion-title>Új játékvezető</ion-title>
<ion-buttons slot="end">
<ion-button
[disabled]="!isValidUmpire()"
(click)="confirm()"
[strong]="true">
Mentés
</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-list>
<ion-item>
<ion-input
label="Vezetéknév"
labelPlacement="stacked"
type="text"
placeholder="Vezetéknév"
[(ngModel)]="lastName" />
</ion-item>
<ion-item>
<ion-input
label="Keresztnév"
labelPlacement="stacked"
type="text"
placeholder="Keresztnév"
[(ngModel)]="firstName" />
</ion-item>
<ion-item>
<ion-input
label="Ország"
labelPlacement="stacked"
type="text"
placeholder="Ország"
[(ngModel)]="country" />
</ion-item>
<ion-item>
<ion-select label="Nem" placeholder="Válassz" [(ngModel)]="gender">
@for (item of genders; track item.code) {
<ion-select-option [value]="item.code">
{{item.label}}
</ion-select-option>
}
</ion-select>
</ion-item>
</ion-list>
</ion-content>
</ng-template>
</ion-modal>
</ion-content>
+132 -5
View File
@@ -1,15 +1,142 @@
import { Component } from '@angular/core';
import { IonHeader, IonToolbar, IonTitle, IonContent } from '@ionic/angular/standalone';
import { ExploreContainerComponent } from '../explore-container/explore-container.component';
import { Component, ViewChild } from '@angular/core';
import {
IonHeader,
IonToolbar,
IonTitle,
IonContent,
IonButtons,
IonButton,
IonIcon,
IonModal,
IonItem,
IonInput,
IonSelect,
IonSelectOption,
IonList,
IonGrid,
IonRow,
IonCol,
IonLabel,
AlertController
} from '@ionic/angular/standalone';
import { UmpireService } from '../services/umpire.service';
import { Umpire } from 'db';
import { addIcons } from 'ionicons';
import { add, trash } from 'ionicons/icons';
import { OverlayEventDetail } from '@ionic/core/components';
import { FormsModule } from '@angular/forms';
import { FullnamePipe } from '../fullname-pipe';
@Component({
selector: 'app-tab2',
templateUrl: 'tab2.page.html',
styleUrls: ['tab2.page.scss'],
imports: [IonHeader, IonToolbar, IonTitle, IonContent, ExploreContainerComponent]
providers: [FullnamePipe],
imports: [
IonLabel,
IonCol,
IonRow,
IonGrid,
IonInput,
IonItem,
IonModal,
IonIcon,
IonButton,
IonButtons,
IonHeader,
IonToolbar,
IonTitle,
IonContent,
FormsModule,
IonSelect,
IonSelectOption,
IonList,
FullnamePipe
]
})
export class Tab2Page {
@ViewChild(IonModal) modal!: IonModal;
constructor() {}
public readonly umpires = this.umpireService.umpires;
public lastName: string = '';
public firstName: string = '';
public country: string = '';
public gender: string = '';
public genders = [
{ label: 'gender.male', code: 'M' },
{ label: 'gender.female', code: 'W' }
];
constructor(
private umpireService: UmpireService,
private alertController: AlertController,
private fullnamePipe: FullnamePipe
) {
addIcons({ add, trash });
}
public async onWillDismiss(event: CustomEvent<OverlayEventDetail>) {
if (event.detail.role !== 'confirm') {
return;
}
const newUmpire: Umpire = event.detail.data;
await this.umpireService.create({
firstName: newUmpire.firstName,
lastName: newUmpire.lastName,
country: newUmpire.country,
gender: newUmpire.gender
});
}
cancel() {
this.modal.dismiss(null, 'cancel');
}
confirm() {
this.modal.dismiss(
{
lastName: this.lastName,
firstName: this.firstName,
country: this.country,
gender: this.gender
},
'confirm'
);
}
isValidUmpire(): boolean {
return this.lastName !== '' && this.firstName !== '';
}
public async showDeleteConfirmation(umpire: Umpire) {
const alert = await this.alertController.create({
header: 'Megerősítés',
subHeader: 'Biztos törlöd a következő játékvezetőt?',
message: this.fullnamePipe.transform(umpire),
buttons: [
{
text: 'Nem',
role: 'cancel'
},
{
text: 'Igen',
role: 'confirm',
handler: () => {
// TODO: also remove from first tab
this.removeUmpire(umpire);
}
}
]
});
await alert.present();
}
private removeUmpire(umpire: Umpire): void {
this.umpireService.delete(umpire.id);
}
}
+2 -2
View File
@@ -2,12 +2,12 @@
<ion-tab-bar slot="bottom">
<ion-tab-button tab="pilot" href="/tabs/pilot">
<ion-icon aria-hidden="true" name="triangle"></ion-icon>
<ion-label>Tab 1</ion-label>
<ion-label>Pályák</ion-label>
</ion-tab-button>
<ion-tab-button tab="umpires" href="/tabs/umpires">
<ion-icon aria-hidden="true" name="ellipse"></ion-icon>
<ion-label>Tab 2</ion-label>
<ion-label>Játékvezetők</ion-label>
</ion-tab-button>
<ion-tab-button tab="stats" href="/tabs/stats">