feat: add bare slots frontend, remove bun start warnings (CAS-61) #164

Merged
ptran merged 8 commits from slots-frontend into main 2025-05-07 12:32:53 +00:00
8 changed files with 139 additions and 37 deletions
Showing only changes of commit bc56b498ee - Show all commits

View file

@ -21,4 +21,9 @@ export const routes: Routes = [
loadComponent: () => import('./feature/game/blackjack/blackjack.component'), loadComponent: () => import('./feature/game/blackjack/blackjack.component'),
canActivate: [authGuard], canActivate: [authGuard],
}, },
{
path: 'game/slots',
loadComponent: () => import('./feature/game/slots/slots.component'),
canActivate: [authGuard],
},
]; ];

View file

@ -1,7 +1,6 @@
import {ChangeDetectionStrategy, Component, inject, OnInit, signal} from '@angular/core'; import {ChangeDetectionStrategy, Component, inject, OnInit, signal} from '@angular/core';
import {CommonModule} from '@angular/common'; import {CommonModule} from '@angular/common';
import {Router} from '@angular/router'; import {Router} from '@angular/router';
import { PlayingCardComponent } from './components/playing-card/playing-card.component';
import {DealerHandComponent} from './components/dealer-hand/dealer-hand.component'; import {DealerHandComponent} from './components/dealer-hand/dealer-hand.component';
import {PlayerHandComponent} from './components/player-hand/player-hand.component'; import {PlayerHandComponent} from './components/player-hand/player-hand.component';
import {GameControlsComponent} from './components/game-controls/game-controls.component'; import {GameControlsComponent} from './components/game-controls/game-controls.component';
@ -22,7 +21,6 @@ import { DebtDialogComponent } from '@shared/components/debt-dialog/debt-dialog.
imports: [ imports: [
CommonModule, CommonModule,
NavbarComponent, NavbarComponent,
PlayingCardComponent,
DealerHandComponent, DealerHandComponent,
PlayerHandComponent, PlayerHandComponent,
GameControlsComponent, GameControlsComponent,

View file

@ -8,13 +8,13 @@ import {
SimpleChanges, SimpleChanges,
ViewChild, ViewChild,
} from '@angular/core'; } from '@angular/core';
import { CommonModule, CurrencyPipe } from '@angular/common'; import {CommonModule} from '@angular/common';
import {CountUp} from 'countup.js'; import {CountUp} from 'countup.js';
@Component({ @Component({
selector: 'app-animated-number', selector: 'app-animated-number',
standalone: true, standalone: true,
imports: [CommonModule, CurrencyPipe], imports: [CommonModule],
template: ` <span #numberElement>{{ formattedValue }}</span> `, template: ` <span #numberElement>{{ formattedValue }}</span> `,
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
}) })

View file

@ -7,7 +7,7 @@ import { AnimatedNumberComponent } from '../animated-number/animated-number.comp
@Component({ @Component({
selector: 'app-game-result', selector: 'app-game-result',
standalone: true, standalone: true,
imports: [CommonModule, CurrencyPipe, AnimatedNumberComponent], imports: [CommonModule, AnimatedNumberComponent],
template: ` template: `
<div *ngIf="visible" [@fadeInOut] class="modal-bg" style="z-index: 1000; position: fixed;"> <div *ngIf="visible" [@fadeInOut] class="modal-bg" style="z-index: 1000; position: fixed;">
<div class="modal-card" [@cardAnimation]> <div class="modal-card" [@cardAnimation]>

View file

@ -0,0 +1,52 @@
<app-navbar></app-navbar>
<div>
<h2>Payouts</h2>
@if (slotInfo(); as info) {
<table>
<tbody>
@for (item of info | keyvalue; track item.key) {
<tr>
<td>{{ item.key }}</td>
<td>{{ item.value }}</td>
</tr>
}
</tbody>
</table>
}
<div>
<div class="grid grid-cols-3 gap-1">
<div class="text-center">{{ slotResult().resultMatrix[0][0] }}</div>
<div class="text-center">{{ slotResult().resultMatrix[0][1] }}</div>
<div class="text-center">{{ slotResult().resultMatrix[0][2] }}</div>
<div class="text-center">{{ slotResult().resultMatrix[1][0] }}</div>
<div class="text-center">{{ slotResult().resultMatrix[1][1] }}</div>
<div class="text-center">{{ slotResult().resultMatrix[1][2] }}</div>
<div class="text-center">{{ slotResult().resultMatrix[2][0] }}</div>
<div class="text-center">{{ slotResult().resultMatrix[2][1] }}</div>
<div class="text-center">{{ slotResult().resultMatrix[2][2] }}</div>
</div>
<div [ngClass]="slotResult().status === 'win' ? 'text-green-500' : 'text-red-500'">
<p>Game result: <strong>{{ slotResult().status | uppercase }}</strong></p>
<p>Amount: <strong>{{ slotResult().amount }}</strong></p>
</div>
<div>
<label for="betAmount">Bet Amount: </label>
<input
id="betAmount"
type="number"
[ngModel]="betAmount()"
(ngModelChange)="betAmount.set($event)"
step="0.01"
min="0.01"
/>
</div>
<button (click)="spin()">SPIN</button>
</div>
</div>

View file

@ -0,0 +1,55 @@
import {ChangeDetectionStrategy, Component, inject, OnInit, signal} from "@angular/core";
import {NavbarComponent} from "@shared/components/navbar/navbar.component";
import {HttpClient} from "@angular/common/http";
import {KeyValuePipe, NgClass, UpperCasePipe} from "@angular/common";
import {FormsModule} from "@angular/forms";
interface SlotResult {
status: 'win' | 'lose';
amount: number;
resultMatrix: string[][];
}
@Component({
selector: 'app-slots',
standalone: true,
imports: [
NavbarComponent,
KeyValuePipe,
UpperCasePipe,
NgClass,
FormsModule
],
templateUrl: './slots.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export default class SlotsComponent implements OnInit {
private httpClient: HttpClient = inject(HttpClient);
slotInfo = signal<Record<string, number> | null>(null);
slotResult = signal<SlotResult>({
status: 'lose',
amount: 12,
resultMatrix: [
["BAR", "BAR", "BAR"],
["SEVEN", "SEVEN", "SEVEN"],
["BELL", "BELL", "BELL"]
]
});
betAmount = signal<number>(1);
ngOnInit(): void {
this.httpClient.get<Record<string, number>>('/backend/slots/info').subscribe(data => {
this.slotInfo.set(data);
});
}
spin(): void {
const payload = {
betAmount: this.betAmount()
};
this.httpClient.post<SlotResult>('/backend/slots/spin', payload).subscribe(result => {
this.slotResult.set(result);
});
}
}

View file

@ -1,15 +1,7 @@
import { import {ChangeDetectionStrategy, Component, EventEmitter, inject, Input, Output,} from '@angular/core';
ChangeDetectionStrategy,
Component,
EventEmitter,
inject,
Input,
Output,
} from '@angular/core';
import {TransactionService} from '@service/transaction.service'; import {TransactionService} from '@service/transaction.service';
import {Observable} from 'rxjs'; import {Observable} from 'rxjs';
import { AsyncPipe, CurrencyPipe, DatePipe, NgForOf, NgIf } from '@angular/common'; import {AsyncPipe, CurrencyPipe, DatePipe, NgIf} from '@angular/common';
import { AnimatedNumberComponent } from '@blackjack/components/animated-number/animated-number.component';
import {TransactionData} from '../../model/TransactionData'; import {TransactionData} from '../../model/TransactionData';
const PER_PAGE = 5; const PER_PAGE = 5;
@ -17,7 +9,7 @@ const PER_PAGE = 5;
@Component({ @Component({
standalone: true, standalone: true,
selector: 'app-transaction-history', selector: 'app-transaction-history',
imports: [NgForOf, AsyncPipe, CurrencyPipe, DatePipe, AnimatedNumberComponent, NgIf], imports: [AsyncPipe, CurrencyPipe, DatePipe, NgIf],
templateUrl: './transaction-history.component.html', templateUrl: './transaction-history.component.html',
styleUrl: './transaction-history.component.css', styleUrl: './transaction-history.component.css',
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,

View file

@ -17,7 +17,7 @@ import { AnimatedNumberComponent } from '@blackjack/components/animated-number/a
selector: 'app-navbar', selector: 'app-navbar',
templateUrl: './navbar.component.html', templateUrl: './navbar.component.html',
standalone: true, standalone: true,
imports: [RouterModule, CurrencyPipe, AnimatedNumberComponent], imports: [RouterModule, AnimatedNumberComponent],
changeDetection: ChangeDetectionStrategy.OnPush, changeDetection: ChangeDetectionStrategy.OnPush,
}) })
export class NavbarComponent implements OnInit, OnDestroy { export class NavbarComponent implements OnInit, OnDestroy {