diff --git a/src/app/models/bot.models.ts b/src/app/models/bot.models.ts new file mode 100644 index 0000000..7385545 --- /dev/null +++ b/src/app/models/bot.models.ts @@ -0,0 +1,10 @@ +export interface Bot { + id: string; + name: string; + rating: number; + createdAt: string; +} + +export interface BotWithToken extends Bot { + token: string; +} diff --git a/src/app/models/tournament.models.ts b/src/app/models/tournament.models.ts new file mode 100644 index 0000000..b9ef3e1 --- /dev/null +++ b/src/app/models/tournament.models.ts @@ -0,0 +1,66 @@ +export interface BotRef { + id: string; + name: string; +} + +export interface Clock { + limit: number; + increment: number; +} + +export interface Variant { + key: string; + name: string; +} + +export interface ResultDto { + rank: number; + points: number; + tieBreak: number; + bot: BotRef; + nbGames: number; + wins: number; + draws: number; + losses: number; +} + +export interface Standing { + page: number; + players: ResultDto[]; +} + +export interface Tournament { + id: string; + fullName: string; + clock: Clock; + variant: Variant; + rated: boolean; + nbPlayers: number; + nbRounds: number; + createdBy: string; + startsAt: string | null; + status: string; + round: number; + standing: Standing; + winner: BotRef | null; +} + +export interface TournamentList { + created: Tournament[]; + started: Tournament[]; + finished: Tournament[]; +} + +export interface Pairing { + id: string; + round: number; + white: BotRef | null; + black: BotRef; + gameId: string | null; + winner: string | null; +} + +export interface RoundPairings { + round: number; + pairings: Pairing[]; +} diff --git a/src/app/services/bot.service.ts b/src/app/services/bot.service.ts new file mode 100644 index 0000000..0d7b558 --- /dev/null +++ b/src/app/services/bot.service.ts @@ -0,0 +1,22 @@ +import { Injectable, inject } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { Bot, BotWithToken } from '../models/bot.models'; + +@Injectable({ providedIn: 'root' }) +export class BotService { + private readonly http = inject(HttpClient); + private readonly base = '/api/account/official-bots'; + + list(): Observable { + return this.http.get(this.base); + } + + create(name: string): Observable { + return this.http.post(this.base, { name }); + } + + delete(botId: string): Observable { + return this.http.delete(`${this.base}/${botId}`); + } +} diff --git a/src/app/services/game-api.service.ts b/src/app/services/game-api.service.ts index 833b747..9c242d2 100644 --- a/src/app/services/game-api.service.ts +++ b/src/app/services/game-api.service.ts @@ -40,7 +40,7 @@ export class GameApiService { ? { white: playerInfo, black: botInfo } : { white: botInfo, black: playerInfo }; - return this.http.post(`${this.apiBase}${this.apiPath}`, payload); + return this.http.post(`${this.apiBase}${this.apiPath}/vs-bot`, payload); } getGame(gameId: string): Observable { diff --git a/src/app/services/tournament.service.ts b/src/app/services/tournament.service.ts new file mode 100644 index 0000000..289a27d --- /dev/null +++ b/src/app/services/tournament.service.ts @@ -0,0 +1,50 @@ +import { Injectable, inject } from '@angular/core'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { Tournament, TournamentList, RoundPairings } from '../models/tournament.models'; + +export interface CreateTournamentForm { + name: string; + nbRounds: number; + clockLimitMinutes: number; + clockIncrement: number; + rated: boolean; +} + +@Injectable({ providedIn: 'root' }) +export class TournamentService { + private readonly http = inject(HttpClient); + private readonly base = '/api/tournament'; + + list(): Observable { + return this.http.get(this.base); + } + + get(id: string): Observable { + return this.http.get(`${this.base}/${id}`); + } + + create(form: CreateTournamentForm): Observable { + const body = new URLSearchParams(); + body.set('name', form.name); + body.set('nbRounds', String(form.nbRounds)); + body.set('clockLimit', String(form.clockLimitMinutes * 60)); + body.set('clockIncrement', String(form.clockIncrement)); + body.set('rated', String(form.rated)); + return this.http.post(this.base, body.toString(), { + headers: new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' }) + }); + } + + start(id: string): Observable { + return this.http.post(`${this.base}/${id}/start`, null); + } + + join(id: string, botId: string, botName: string): Observable { + return this.http.post(`${this.base}/${id}/join`, { botId, botName }); + } + + roundPairings(id: string, round: number): Observable { + return this.http.get(`${this.base}/${id}/round/${round}`); + } +}