From a62d2092b3a1e5f47a7a7cf229349ced6e0ed2dc Mon Sep 17 00:00:00 2001 From: Phan Huy Tran Date: Wed, 21 May 2025 10:23:03 +0200 Subject: [PATCH 01/10] feat: implement basic dice frontend funcionality --- frontend/src/app/app.routes.ts | 5 + .../app/feature/game/dice/dice.component.html | 52 ++++++++ .../app/feature/game/dice/dice.component.ts | 118 ++++++++++++++++++ .../src/app/feature/game/dice/dice.model.ts | 11 ++ .../src/app/feature/game/dice/dice.service.ts | 17 +++ 5 files changed, 203 insertions(+) create mode 100644 frontend/src/app/feature/game/dice/dice.component.html create mode 100644 frontend/src/app/feature/game/dice/dice.component.ts create mode 100644 frontend/src/app/feature/game/dice/dice.model.ts create mode 100644 frontend/src/app/feature/game/dice/dice.service.ts diff --git a/frontend/src/app/app.routes.ts b/frontend/src/app/app.routes.ts index 39c5b1c..397d7c9 100644 --- a/frontend/src/app/app.routes.ts +++ b/frontend/src/app/app.routes.ts @@ -61,4 +61,9 @@ export const routes: Routes = [ loadComponent: () => import('./feature/lootboxes/lootbox-opening/lootbox-opening.component'), canActivate: [authGuard], }, + { + path: 'game/dice', + loadComponent: () => import('./feature/game/dice/dice.component').then(m => m.DiceComponent), + canActivate: [authGuard], + }, ]; diff --git a/frontend/src/app/feature/game/dice/dice.component.html b/frontend/src/app/feature/game/dice/dice.component.html new file mode 100644 index 0000000..4278fb1 --- /dev/null +++ b/frontend/src/app/feature/game/dice/dice.component.html @@ -0,0 +1,52 @@ +
+

Dice Game

+ +
+
+ + + @if (hasError('betAmount', 'required')) { + Bet Amount is required + } + @if (hasError('betAmount', 'min')) { + Bet Amount must be at least 0.01 + } + +
+ + +
+ + + + @if (hasError('targetValue', 'required')) { + Target Value is required + } + @if (hasError('targetValue', 'min')) { + Target Value must be at least 1 + } + @if (hasError('targetValue', 'max')) { + Target Value must be at most 100 + } +
+ +
+

Win Chance: {{ winChance() | number:'1.0-2' }}%

+

Potential Win: {{ potentialWin() | currency:'EUR':'symbol':'1.2-2' }}

+
+ + +
+ + @if (rolledValue() !== null) { +
+

Result

+

Rolled Value: {{ rolledValue() }}

+ @if (win()) { +

You Won! Payout: {{ payout() | currency:'EUR':'symbol':'1.2-2' }}

+ } @else { +

You Lost.

+ } +
+ } +
diff --git a/frontend/src/app/feature/game/dice/dice.component.ts b/frontend/src/app/feature/game/dice/dice.component.ts new file mode 100644 index 0000000..fae1051 --- /dev/null +++ b/frontend/src/app/feature/game/dice/dice.component.ts @@ -0,0 +1,118 @@ +import { Component, signal, inject, OnInit } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; +import { DiceService } from './dice.service'; +import { DiceDto, DiceResult } from './dice.model'; +import { debounceTime, tap } from 'rxjs/operators'; +import {UserService} from "@service/user.service"; + +type DiceFormGroup = FormGroup<{ + betAmount: FormControl; + rollOver: FormControl; + targetValue: FormControl; +}>; + +@Component({ + selector: 'app-dice', + standalone: true, + imports: [CommonModule, ReactiveFormsModule], + templateUrl: './dice.component.html', +}) +export class DiceComponent implements OnInit { + private readonly formBuilder = inject(FormBuilder); + private readonly diceService = inject(DiceService); + private readonly userService = inject(UserService); + + + rolledValue = signal(null); + win = signal(null); + payout = signal(null); + winChance = signal(0); + potentialWin = signal(0); + + readonly diceForm: DiceFormGroup = this.createDiceForm(); + + private readonly MAX_DICE_VALUE = 100; + + constructor() { + } + + ngOnInit(): void { + this.diceForm.valueChanges.pipe( + debounceTime(100), + tap(() => this.calculateWinChanceAndPotentialWin()) + ).subscribe(); + + this.calculateWinChanceAndPotentialWin(); + } + + createDiceForm(): DiceFormGroup { + return this.formBuilder.group({ + betAmount: new FormControl(1.00, { + validators: [Validators.required, Validators.min(0.01)], + nonNullable: true, + }), + rollOver: new FormControl(true, { + validators: [Validators.required], + nonNullable: true, + }), + targetValue: new FormControl(50.50, { + validators: [Validators.required, Validators.min(1), Validators.max(100)], + nonNullable: true, + }), + }); + } + + toggleRollMode(): void { + const currentMode = this.diceForm.get('rollOver')?.value; + this.diceForm.get('rollOver')?.setValue(!currentMode); + } + + calculateWinChanceAndPotentialWin(): void { + const formValues = this.diceForm.value; + const target = formValues.targetValue ?? 0; + const bet = formValues.betAmount ?? 0; + const isOver = formValues.rollOver ?? true; + + const calculatedWinChance = isOver ? this.MAX_DICE_VALUE - target : target - 1; + + this.winChance.set(Math.max(0, calculatedWinChance)); + + let multiplier = 0; + if (calculatedWinChance > 0) { + multiplier = (this.MAX_DICE_VALUE - 1) / calculatedWinChance; + } + + this.potentialWin.set(bet * multiplier); + } + + roll(): void { + if (this.diceForm.invalid) { + this.diceForm.markAllAsTouched(); + return; + } + + const diceDto: DiceDto = this.diceForm.getRawValue() as DiceDto; + + this.rolledValue.set(null); + this.win.set(null); + this.payout.set(null); + + this.diceService.rollDice(diceDto).subscribe({ + next: (result: DiceResult) => { + this.rolledValue.set(result.rolledValue); + this.win.set(result.win); + this.payout.set(result.payout); + this.userService.refreshCurrentUser(); + }, + error: (error) => { + console.error('Dice roll failed:', error); + } + }); + } + + hasError(controlName: string, errorName: string): boolean { + const control = this.diceForm.get(controlName); + return control !== null && control.touched && control.hasError(errorName); + } +} diff --git a/frontend/src/app/feature/game/dice/dice.model.ts b/frontend/src/app/feature/game/dice/dice.model.ts new file mode 100644 index 0000000..f85eac1 --- /dev/null +++ b/frontend/src/app/feature/game/dice/dice.model.ts @@ -0,0 +1,11 @@ +export interface DiceDto { + betAmount: number; + rollOver: boolean; + targetValue: number; +} + +export interface DiceResult { + win: boolean; + payout: number; + rolledValue: number; +} diff --git a/frontend/src/app/feature/game/dice/dice.service.ts b/frontend/src/app/feature/game/dice/dice.service.ts new file mode 100644 index 0000000..d621f1a --- /dev/null +++ b/frontend/src/app/feature/game/dice/dice.service.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { DiceDto, DiceResult } from './dice.model'; + +@Injectable({ + providedIn: 'root' +}) +export class DiceService { + private apiUrl = '/backend/dice'; + + constructor(private http: HttpClient) { } + + rollDice(diceDto: DiceDto): Observable { + return this.http.post(this.apiUrl, diceDto); + } +} From d58f24ccbf16a7ea7e347f80cf03361d7a36d537 Mon Sep 17 00:00:00 2001 From: Phan Huy Tran Date: Wed, 21 May 2025 10:36:32 +0200 Subject: [PATCH 02/10] feat: style dice game page --- .../app/feature/game/dice/dice.component.html | 97 ++++++++++++------- 1 file changed, 60 insertions(+), 37 deletions(-) diff --git a/frontend/src/app/feature/game/dice/dice.component.html b/frontend/src/app/feature/game/dice/dice.component.html index 4278fb1..6506f8d 100644 --- a/frontend/src/app/feature/game/dice/dice.component.html +++ b/frontend/src/app/feature/game/dice/dice.component.html @@ -1,51 +1,74 @@ -
-

Dice Game

+
+

Dice Game

-
-
- - - @if (hasError('betAmount', 'required')) { - Bet Amount is required - } - @if (hasError('betAmount', 'min')) { - Bet Amount must be at least 0.01 - } +
+
+ +
+
+ + + @if (hasError('betAmount', 'required')) { + Bet Amount is required + } + @if (hasError('betAmount', 'min')) { + Bet Amount must be at least 0.01 + } +
-
- - -
+
+ +
+ + +
+
- - - @if (hasError('targetValue', 'required')) { - Target Value is required - } - @if (hasError('targetValue', 'min')) { - Target Value must be at least 1 - } - @if (hasError('targetValue', 'max')) { - Target Value must be at most 100 - } +
+ + + @if (hasError('targetValue', 'required')) { + Target Value is required + } + @if (hasError('targetValue', 'min')) { + Target Value must be at least 1 + } + @if (hasError('targetValue', 'max')) { + Target Value must be at most 100 + } +
+
+ +
+

Win Chance: {{ winChance() | number:'1.0-2' }}%

+

Potential Win: {{ potentialWin() | currency:'EUR':'symbol':'1.2-2' }}

+
+ + +
-
-

Win Chance: {{ winChance() | number:'1.0-2' }}%

-

Potential Win: {{ potentialWin() | currency:'EUR':'symbol':'1.2-2' }}

+
+ + @if (rolledValue() !== null) { +
+ {{ rolledValue() }} +
+ }
+
- - @if (rolledValue() !== null) { -
-

Result

-

Rolled Value: {{ rolledValue() }}

+
@if (win()) { -

You Won! Payout: {{ payout() | currency:'EUR':'symbol':'1.2-2' }}

+

You Won! Payout: {{ payout() | currency:'EUR':'symbol':'1.2-2' }}

} @else { -

You Lost.

+

You Lost.

}
} From bc502612213d0420ec536b6cf115964f40c858d3 Mon Sep 17 00:00:00 2001 From: Phan Huy Tran Date: Wed, 21 May 2025 10:37:49 +0200 Subject: [PATCH 03/10] refactor: remove comment --- frontend/src/app/feature/game/dice/dice.component.html | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/app/feature/game/dice/dice.component.html b/frontend/src/app/feature/game/dice/dice.component.html index 6506f8d..6557b60 100644 --- a/frontend/src/app/feature/game/dice/dice.component.html +++ b/frontend/src/app/feature/game/dice/dice.component.html @@ -53,7 +53,6 @@
- @if (rolledValue() !== null) {
{{ rolledValue() }} From 694787fe07e718afa6520f4e24bacd4960539a36 Mon Sep 17 00:00:00 2001 From: Phan Huy Tran Date: Wed, 21 May 2025 10:39:43 +0200 Subject: [PATCH 04/10] feat: add links pointing to the dice page --- frontend/src/app/feature/home/home.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/app/feature/home/home.component.ts b/frontend/src/app/feature/home/home.component.ts index 07b5f9f..494c03f 100644 --- a/frontend/src/app/feature/home/home.component.ts +++ b/frontend/src/app/feature/home/home.component.ts @@ -72,9 +72,9 @@ export default class HomeComponent implements OnInit { }, { id: '5', - name: 'Liars Dice', + name: 'Dice', image: '/liars-dice.webp', - route: '/game/liars-dice', + route: '/game/dice', }, { id: '6', From b2053acdfe770a1630dad7c058dbb0f3661f49aa Mon Sep 17 00:00:00 2001 From: Phan Huy Tran Date: Wed, 21 May 2025 10:42:24 +0200 Subject: [PATCH 05/10] feat: add links pointing to the dice page on landing page --- frontend/src/app/feature/landing/landing.component.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/feature/landing/landing.component.html b/frontend/src/app/feature/landing/landing.component.html index b7c6a4b..4cc9c52 100644 --- a/frontend/src/app/feature/landing/landing.component.html +++ b/frontend/src/app/feature/landing/landing.component.html @@ -91,10 +91,10 @@
-

Liars Dice

-

Würfelspiel mit Strategie

+

Dice

+

Würfelspiel

Jetzt Spielen From f2aa81b6d2d94e414fad5bdfaa3a011a02d80a02 Mon Sep 17 00:00:00 2001 From: Phan Huy Tran Date: Wed, 21 May 2025 10:42:36 +0200 Subject: [PATCH 06/10] style: format code --- frontend/src/app/app.routes.ts | 2 +- .../app/feature/game/dice/dice.component.html | 195 ++++++++------ .../app/feature/game/dice/dice.component.ts | 242 +++++++++--------- .../src/app/feature/game/dice/dice.model.ts | 22 +- .../src/app/feature/game/dice/dice.service.ts | 34 +-- 5 files changed, 274 insertions(+), 221 deletions(-) diff --git a/frontend/src/app/app.routes.ts b/frontend/src/app/app.routes.ts index 397d7c9..b8adc5f 100644 --- a/frontend/src/app/app.routes.ts +++ b/frontend/src/app/app.routes.ts @@ -63,7 +63,7 @@ export const routes: Routes = [ }, { path: 'game/dice', - loadComponent: () => import('./feature/game/dice/dice.component').then(m => m.DiceComponent), + loadComponent: () => import('./feature/game/dice/dice.component').then((m) => m.DiceComponent), canActivate: [authGuard], }, ]; diff --git a/frontend/src/app/feature/game/dice/dice.component.html b/frontend/src/app/feature/game/dice/dice.component.html index 6557b60..4905c50 100644 --- a/frontend/src/app/feature/game/dice/dice.component.html +++ b/frontend/src/app/feature/game/dice/dice.component.html @@ -1,74 +1,121 @@ -
-

Dice Game

- -
-
-
-
-
- - - @if (hasError('betAmount', 'required')) { - Bet Amount is required - } - @if (hasError('betAmount', 'min')) { - Bet Amount must be at least 0.01 - } -
- -
- -
- - -
-
- -
- - - @if (hasError('targetValue', 'required')) { - Target Value is required - } - @if (hasError('targetValue', 'min')) { - Target Value must be at least 1 - } - @if (hasError('targetValue', 'max')) { - Target Value must be at most 100 - } -
-
- -
-

Win Chance: {{ winChance() | number:'1.0-2' }}%

-

Potential Win: {{ potentialWin() | currency:'EUR':'symbol':'1.2-2' }}

-
- - -
-
- -
- @if (rolledValue() !== null) { -
- {{ rolledValue() }} -
- } -
-
- - - @if (rolledValue() !== null) { -
- @if (win()) { -

You Won! Payout: {{ payout() | currency:'EUR':'symbol':'1.2-2' }}

- } @else { -

You Lost.

- } -
- } -
+
+

Dice Game

+ +
+
+
+
+
+ + + @if (hasError('betAmount', 'required')) { + Bet Amount is required + } + @if (hasError('betAmount', 'min')) { + Bet Amount must be at least 0.01 + } +
+ +
+ +
+ + +
+
+ +
+ + + @if (hasError('targetValue', 'required')) { + Target Value is required + } + @if (hasError('targetValue', 'min')) { + Target Value must be at least 1 + } + @if (hasError('targetValue', 'max')) { + Target Value must be at most 100 + } +
+
+ +
+

+ Win Chance: {{ winChance() | number: '1.0-2' }}% +

+

+ Potential Win: + {{ + potentialWin() | currency: 'EUR' : 'symbol' : '1.2-2' + }} +

+
+ + +
+
+ +
+ @if (rolledValue() !== null) { +
+ {{ rolledValue() }} +
+ } +
+
+ + @if (rolledValue() !== null) { +
+ @if (win()) { +

+ You Won! Payout: {{ payout() | currency: 'EUR' : 'symbol' : '1.2-2' }} +

+ } @else { +

You Lost.

+ } +
+ } +
diff --git a/frontend/src/app/feature/game/dice/dice.component.ts b/frontend/src/app/feature/game/dice/dice.component.ts index fae1051..6b5d4a0 100644 --- a/frontend/src/app/feature/game/dice/dice.component.ts +++ b/frontend/src/app/feature/game/dice/dice.component.ts @@ -1,118 +1,124 @@ -import { Component, signal, inject, OnInit } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { FormBuilder, FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms'; -import { DiceService } from './dice.service'; -import { DiceDto, DiceResult } from './dice.model'; -import { debounceTime, tap } from 'rxjs/operators'; -import {UserService} from "@service/user.service"; - -type DiceFormGroup = FormGroup<{ - betAmount: FormControl; - rollOver: FormControl; - targetValue: FormControl; -}>; - -@Component({ - selector: 'app-dice', - standalone: true, - imports: [CommonModule, ReactiveFormsModule], - templateUrl: './dice.component.html', -}) -export class DiceComponent implements OnInit { - private readonly formBuilder = inject(FormBuilder); - private readonly diceService = inject(DiceService); - private readonly userService = inject(UserService); - - - rolledValue = signal(null); - win = signal(null); - payout = signal(null); - winChance = signal(0); - potentialWin = signal(0); - - readonly diceForm: DiceFormGroup = this.createDiceForm(); - - private readonly MAX_DICE_VALUE = 100; - - constructor() { - } - - ngOnInit(): void { - this.diceForm.valueChanges.pipe( - debounceTime(100), - tap(() => this.calculateWinChanceAndPotentialWin()) - ).subscribe(); - - this.calculateWinChanceAndPotentialWin(); - } - - createDiceForm(): DiceFormGroup { - return this.formBuilder.group({ - betAmount: new FormControl(1.00, { - validators: [Validators.required, Validators.min(0.01)], - nonNullable: true, - }), - rollOver: new FormControl(true, { - validators: [Validators.required], - nonNullable: true, - }), - targetValue: new FormControl(50.50, { - validators: [Validators.required, Validators.min(1), Validators.max(100)], - nonNullable: true, - }), - }); - } - - toggleRollMode(): void { - const currentMode = this.diceForm.get('rollOver')?.value; - this.diceForm.get('rollOver')?.setValue(!currentMode); - } - - calculateWinChanceAndPotentialWin(): void { - const formValues = this.diceForm.value; - const target = formValues.targetValue ?? 0; - const bet = formValues.betAmount ?? 0; - const isOver = formValues.rollOver ?? true; - - const calculatedWinChance = isOver ? this.MAX_DICE_VALUE - target : target - 1; - - this.winChance.set(Math.max(0, calculatedWinChance)); - - let multiplier = 0; - if (calculatedWinChance > 0) { - multiplier = (this.MAX_DICE_VALUE - 1) / calculatedWinChance; - } - - this.potentialWin.set(bet * multiplier); - } - - roll(): void { - if (this.diceForm.invalid) { - this.diceForm.markAllAsTouched(); - return; - } - - const diceDto: DiceDto = this.diceForm.getRawValue() as DiceDto; - - this.rolledValue.set(null); - this.win.set(null); - this.payout.set(null); - - this.diceService.rollDice(diceDto).subscribe({ - next: (result: DiceResult) => { - this.rolledValue.set(result.rolledValue); - this.win.set(result.win); - this.payout.set(result.payout); - this.userService.refreshCurrentUser(); - }, - error: (error) => { - console.error('Dice roll failed:', error); - } - }); - } - - hasError(controlName: string, errorName: string): boolean { - const control = this.diceForm.get(controlName); - return control !== null && control.touched && control.hasError(errorName); - } -} +import { Component, signal, inject, OnInit } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { + FormBuilder, + FormControl, + FormGroup, + ReactiveFormsModule, + Validators, +} from '@angular/forms'; +import { DiceService } from './dice.service'; +import { DiceDto, DiceResult } from './dice.model'; +import { debounceTime, tap } from 'rxjs/operators'; +import { UserService } from '@service/user.service'; + +type DiceFormGroup = FormGroup<{ + betAmount: FormControl; + rollOver: FormControl; + targetValue: FormControl; +}>; + +@Component({ + selector: 'app-dice', + standalone: true, + imports: [CommonModule, ReactiveFormsModule], + templateUrl: './dice.component.html', +}) +export class DiceComponent implements OnInit { + private readonly formBuilder = inject(FormBuilder); + private readonly diceService = inject(DiceService); + private readonly userService = inject(UserService); + + rolledValue = signal(null); + win = signal(null); + payout = signal(null); + winChance = signal(0); + potentialWin = signal(0); + + readonly diceForm: DiceFormGroup = this.createDiceForm(); + + private readonly MAX_DICE_VALUE = 100; + + constructor() {} + + ngOnInit(): void { + this.diceForm.valueChanges + .pipe( + debounceTime(100), + tap(() => this.calculateWinChanceAndPotentialWin()) + ) + .subscribe(); + + this.calculateWinChanceAndPotentialWin(); + } + + createDiceForm(): DiceFormGroup { + return this.formBuilder.group({ + betAmount: new FormControl(1.0, { + validators: [Validators.required, Validators.min(0.01)], + nonNullable: true, + }), + rollOver: new FormControl(true, { + validators: [Validators.required], + nonNullable: true, + }), + targetValue: new FormControl(50.5, { + validators: [Validators.required, Validators.min(1), Validators.max(100)], + nonNullable: true, + }), + }); + } + + toggleRollMode(): void { + const currentMode = this.diceForm.get('rollOver')?.value; + this.diceForm.get('rollOver')?.setValue(!currentMode); + } + + calculateWinChanceAndPotentialWin(): void { + const formValues = this.diceForm.value; + const target = formValues.targetValue ?? 0; + const bet = formValues.betAmount ?? 0; + const isOver = formValues.rollOver ?? true; + + const calculatedWinChance = isOver ? this.MAX_DICE_VALUE - target : target - 1; + + this.winChance.set(Math.max(0, calculatedWinChance)); + + let multiplier = 0; + if (calculatedWinChance > 0) { + multiplier = (this.MAX_DICE_VALUE - 1) / calculatedWinChance; + } + + this.potentialWin.set(bet * multiplier); + } + + roll(): void { + if (this.diceForm.invalid) { + this.diceForm.markAllAsTouched(); + return; + } + + const diceDto: DiceDto = this.diceForm.getRawValue() as DiceDto; + + this.rolledValue.set(null); + this.win.set(null); + this.payout.set(null); + + this.diceService.rollDice(diceDto).subscribe({ + next: (result: DiceResult) => { + this.rolledValue.set(result.rolledValue); + this.win.set(result.win); + this.payout.set(result.payout); + this.userService.refreshCurrentUser(); + }, + error: (error) => { + console.error('Dice roll failed:', error); + }, + }); + } + + hasError(controlName: string, errorName: string): boolean { + const control = this.diceForm.get(controlName); + return control !== null && control.touched && control.hasError(errorName); + } +} diff --git a/frontend/src/app/feature/game/dice/dice.model.ts b/frontend/src/app/feature/game/dice/dice.model.ts index f85eac1..93a1133 100644 --- a/frontend/src/app/feature/game/dice/dice.model.ts +++ b/frontend/src/app/feature/game/dice/dice.model.ts @@ -1,11 +1,11 @@ -export interface DiceDto { - betAmount: number; - rollOver: boolean; - targetValue: number; -} - -export interface DiceResult { - win: boolean; - payout: number; - rolledValue: number; -} +export interface DiceDto { + betAmount: number; + rollOver: boolean; + targetValue: number; +} + +export interface DiceResult { + win: boolean; + payout: number; + rolledValue: number; +} diff --git a/frontend/src/app/feature/game/dice/dice.service.ts b/frontend/src/app/feature/game/dice/dice.service.ts index d621f1a..f89c53d 100644 --- a/frontend/src/app/feature/game/dice/dice.service.ts +++ b/frontend/src/app/feature/game/dice/dice.service.ts @@ -1,17 +1,17 @@ -import { Injectable } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; -import { Observable } from 'rxjs'; -import { DiceDto, DiceResult } from './dice.model'; - -@Injectable({ - providedIn: 'root' -}) -export class DiceService { - private apiUrl = '/backend/dice'; - - constructor(private http: HttpClient) { } - - rollDice(diceDto: DiceDto): Observable { - return this.http.post(this.apiUrl, diceDto); - } -} +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { DiceDto, DiceResult } from './dice.model'; + +@Injectable({ + providedIn: 'root', +}) +export class DiceService { + private apiUrl = '/backend/dice'; + + constructor(private http: HttpClient) {} + + rollDice(diceDto: DiceDto): Observable { + return this.http.post(this.apiUrl, diceDto); + } +} From 329739b103277aaa8e859e1e2ea2137df1e4dfc6 Mon Sep 17 00:00:00 2001 From: Phan Huy Tran Date: Wed, 21 May 2025 10:47:25 +0200 Subject: [PATCH 07/10] style: fix quality tools --- frontend/src/app/feature/game/dice/dice.component.html | 2 +- frontend/src/app/feature/game/dice/dice.component.ts | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/frontend/src/app/feature/game/dice/dice.component.html b/frontend/src/app/feature/game/dice/dice.component.html index 4905c50..5cc7a0e 100644 --- a/frontend/src/app/feature/game/dice/dice.component.html +++ b/frontend/src/app/feature/game/dice/dice.component.html @@ -26,7 +26,7 @@
- +
Roll Mode: