feat(slots): add slot machine component with styling and logic
This commit is contained in:
parent
4a312dda35
commit
a622dbc7f4
3 changed files with 282 additions and 48 deletions
|
@ -1,50 +1,178 @@
|
|||
<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 class="container mx-auto px-4 py-6 space-y-8">
|
||||
<h1 class="text-3xl font-bold text-white mb-6">Spielautomaten</h1>
|
||||
|
||||
<div>
|
||||
<div class="grid grid-cols-3 gap-1">
|
||||
@for (row of slotResult().resultMatrix; track $index) {
|
||||
@for (cell of row; track $index) {
|
||||
<div class="text-center">{{ cell }}</div>
|
||||
}
|
||||
}
|
||||
<div class="grid grid-cols-1 lg:grid-cols-4 gap-6">
|
||||
<!-- Slot Machine Display -->
|
||||
<div class="lg:col-span-3 space-y-6 flex flex-col">
|
||||
<div class="card">
|
||||
<!-- Slot Machine Top -->
|
||||
<div class="p-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<h2 class="text-xl font-bold text-white">Slot Machine</h2>
|
||||
<div
|
||||
[ngClass]="{
|
||||
'bg-emerald': slotResult().status === 'win',
|
||||
'bg-accent-red': slotResult().status === 'lose',
|
||||
'bg-deep-blue-light': slotResult().status === 'start',
|
||||
}"
|
||||
class="px-3 py-1 rounded-full text-sm font-semibold"
|
||||
>
|
||||
<span class="text-white">
|
||||
{{
|
||||
slotResult().status === 'win'
|
||||
? 'Gewonnen!'
|
||||
: slotResult().status === 'lose'
|
||||
? 'Verloren'
|
||||
: 'Bereit'
|
||||
}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Slot Display -->
|
||||
<div class="p-6">
|
||||
<div class="bg-deep-blue-light rounded-lg p-4 shadow-inner mb-6">
|
||||
<div class="grid grid-cols-3 gap-3">
|
||||
@for (row of slotResult().resultMatrix; track $index) {
|
||||
@for (cell of row; track $index) {
|
||||
<div
|
||||
class="bg-deep-blue-contrast rounded-lg shadow-md p-2 flex items-center justify-center"
|
||||
>
|
||||
<span class="text-2xl font-bold" [ngClass]="getSymbolClass(cell)">{{
|
||||
cell
|
||||
}}</span>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Game Result -->
|
||||
<div class="text-center mb-6" *ngIf="slotResult().status === 'win'">
|
||||
<div class="text-emerald text-xl font-bold">
|
||||
+{{ slotResult().amount | currency: 'EUR' }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Controls -->
|
||||
<div class="flex flex-col sm:flex-row gap-4 items-center justify-center">
|
||||
<div class="flex items-center bg-deep-blue-light rounded-lg p-2 flex-1">
|
||||
<label for="betAmount" class="text-text-secondary mr-3">Einsatz:</label>
|
||||
<input
|
||||
id="betAmount"
|
||||
type="number"
|
||||
[ngModel]="betAmount()"
|
||||
(ngModelChange)="betAmount.set($event)"
|
||||
step="0.01"
|
||||
min="0.01"
|
||||
class="w-full bg-deep-blue-light text-white focus:outline-none focus:ring-1 focus:ring-emerald"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button
|
||||
(click)="spin()"
|
||||
class="px-4 py-1.5 font-bold rounded"
|
||||
[ngClass]="{
|
||||
'open-btn': hasEnoughBalance(),
|
||||
'bg-gray-500 cursor-not-allowed': !hasEnoughBalance(),
|
||||
}"
|
||||
[disabled]="isSpinning || !hasEnoughBalance()"
|
||||
>
|
||||
@if (!isSpinning) {
|
||||
<span>{{ hasEnoughBalance() ? 'SPIN' : 'Nicht genug Guthaben' }}</span>
|
||||
} @else {
|
||||
<div
|
||||
class="w-6 h-6 border-2 border-white border-t-transparent rounded-full animate-spin"
|
||||
></div>
|
||||
}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p>
|
||||
Game result: <strong>{{ slotResult().status | uppercase }}</strong>
|
||||
</p>
|
||||
<p>
|
||||
Amount: <strong>{{ slotResult().amount }}</strong>
|
||||
</p>
|
||||
</div>
|
||||
<!-- Game Info Panel -->
|
||||
<div class="lg:col-span-1">
|
||||
<div class="card p-4">
|
||||
<h3 class="section-heading text-xl mb-4">Spiel Informationen</h3>
|
||||
<div class="space-y-4">
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="text-text-secondary">Kontostand:</span>
|
||||
<span class="text-emerald">
|
||||
<app-animated-number [value]="balance()" [duration]="0.5"></app-animated-number>
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="text-text-secondary">Einsatz:</span>
|
||||
<span [class]="betAmount() > 0 ? 'text-accent-red' : 'text-text-secondary'">
|
||||
<app-animated-number [value]="betAmount()" [duration]="0.5"></app-animated-number>
|
||||
</span>
|
||||
</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>
|
||||
<div class="grid grid-cols-2 gap-2 mb-4">
|
||||
<button
|
||||
(click)="setBetAmount(0.1)"
|
||||
class="button-primary py-2 text-sm"
|
||||
[disabled]="isSpinning"
|
||||
>
|
||||
10%
|
||||
</button>
|
||||
<button
|
||||
(click)="setBetAmount(0.25)"
|
||||
class="button-primary py-2 text-sm"
|
||||
[disabled]="isSpinning"
|
||||
>
|
||||
25%
|
||||
</button>
|
||||
<button
|
||||
(click)="setBetAmount(0.5)"
|
||||
class="button-primary py-2 text-sm"
|
||||
[disabled]="isSpinning"
|
||||
>
|
||||
50%
|
||||
</button>
|
||||
<button
|
||||
(click)="setBetAmount(1)"
|
||||
class="button-primary py-2 text-sm"
|
||||
[disabled]="isSpinning"
|
||||
>
|
||||
100%
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button (click)="spin()">SPIN</button>
|
||||
<h3 class="text-lg font-semibold text-white mb-2">Auszahlungen:</h3>
|
||||
|
||||
@if (slotInfo(); as info) {
|
||||
<ul class="space-y-1">
|
||||
@for (item of info | keyvalue; track item.key) {
|
||||
<li class="flex justify-between items-center py-1 border-b border-deep-blue-light">
|
||||
<div class="bg-deep-blue-contrast px-2 py-1 rounded text-center w-12">
|
||||
<span [ngClass]="getSymbolClass(item.key)">{{ item.key }}</span>
|
||||
</div>
|
||||
<span class="text-emerald">{{ item.value }}x</span>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
} @else {
|
||||
<div class="flex justify-center py-4">
|
||||
<div
|
||||
class="w-4 h-4 border-2 border-deep-blue-contrast border-t-emerald rounded-full animate-spin"
|
||||
></div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="mt-4 pt-2">
|
||||
<h4 class="text-sm font-semibold text-white mb-2">Spielregeln:</h4>
|
||||
<ul class="text-text-secondary text-xs space-y-1">
|
||||
<li>• Gewinne mit 3 gleichen Symbolen</li>
|
||||
<li>• Höhere Symbole = höhere Gewinne</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Reference in a new issue