All checks were successful
CI / Get Changed Files (pull_request) Successful in 8s
CI / Checkstyle Main (pull_request) Has been skipped
CI / Docker backend validation (pull_request) Has been skipped
CI / oxlint (pull_request) Successful in 25s
CI / eslint (pull_request) Successful in 27s
CI / prettier (pull_request) Successful in 31s
CI / Docker frontend validation (pull_request) Successful in 42s
CI / test-build (pull_request) Successful in 44s
141 lines
5.3 KiB
HTML
141 lines
5.3 KiB
HTML
<div class="container mx-auto py-6">
|
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-6">
|
|
<div class="col-span-1 md:col-span-3 w-full flex flex-col items-center justify-center">
|
|
<!-- Game Result Display -->
|
|
@if (gameResult()) {
|
|
<div class="mb-6 text-center result-text">
|
|
<h2 class="text-2xl font-bold mb-2" [class]="getResultClass()">
|
|
{{ gameResult()?.isWin ? 'Du hast gewonnen!' : 'Du hast verloren' }}
|
|
</h2>
|
|
<p class="text-lg">
|
|
Münze zeigt:
|
|
<span class="font-bold">{{ gameResult()?.coinSide === 'HEAD' ? 'KOPF' : 'ZAHL' }}</span>
|
|
</p>
|
|
@if (gameResult()?.isWin) {
|
|
<p class="text-xl mt-2">
|
|
<span class="text-emerald-500">+{{ gameResult()?.payout | currency: 'EUR' }}</span>
|
|
</p>
|
|
}
|
|
</div>
|
|
}
|
|
|
|
<!-- Error message display -->
|
|
@if (errorMessage()) {
|
|
<div class="mb-6 text-center">
|
|
<p class="text-accent-red font-bold">{{ errorMessage() }}</p>
|
|
</div>
|
|
}
|
|
|
|
<!-- Coin animation area -->
|
|
<div class="coin-container mx-auto mb-8">
|
|
<div #coinElement id="coin" class="coin">
|
|
<!-- Head side -->
|
|
<div
|
|
class="front coin-side bg-yellow-500 flex items-center justify-center text-2xl font-bold"
|
|
>
|
|
<div class="coin-text">KOPF</div>
|
|
</div>
|
|
|
|
<!-- Tails side with non-mirrored text -->
|
|
<div
|
|
class="back coin-side bg-gray-700 flex items-center justify-center text-2xl font-bold text-white"
|
|
>
|
|
<!-- Using direct inline transform to counter the mirroring effect -->
|
|
<span style="display: inline-block; transform: scaleX(1)">ZAHL</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Game controls -->
|
|
<div class="flex gap-4 mt-3 mx-auto">
|
|
<button
|
|
(click)="betTails()"
|
|
[disabled]="gameInProgress()"
|
|
class="button-primary py-3 px-6 relative text-lg"
|
|
[class.opacity-50]="gameInProgress()"
|
|
>
|
|
Auf ZAHL setzen
|
|
</button>
|
|
<button
|
|
(click)="betHeads()"
|
|
[disabled]="gameInProgress()"
|
|
class="button-primary py-3 px-6 relative text-lg"
|
|
[class.opacity-50]="gameInProgress()"
|
|
>
|
|
Auf KOPF setzen
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Game information panel -->
|
|
<div class="col-span-1">
|
|
<div class="card p-4">
|
|
<h3 class="section-heading text-xl mb-4">Spielinformationen</h3>
|
|
<div class="space-y-4">
|
|
<!-- Current bet display -->
|
|
<div class="flex justify-between items-center">
|
|
<span class="text-text-secondary">Aktueller Einsatz:</span>
|
|
<span [class]="currentBet() > 0 ? 'text-accent-red' : 'text-text-secondary'">
|
|
<app-animated-number [value]="currentBet()" [duration]="0.5"></app-animated-number> €
|
|
</span>
|
|
</div>
|
|
|
|
<!-- Available balance -->
|
|
<div class="flex justify-between items-center">
|
|
<span class="text-text-secondary">Dein Guthaben:</span>
|
|
<span class="text-white">
|
|
{{ balance() | currency: 'EUR' }}
|
|
</span>
|
|
</div>
|
|
|
|
<!-- Bet amount percentage buttons -->
|
|
@if (!gameInProgress()) {
|
|
<div class="grid grid-cols-2 gap-2 mb-4">
|
|
<button (click)="setBetAmount(0.1)" class="button-primary py-2 text-sm">10%</button>
|
|
<button (click)="setBetAmount(0.25)" class="button-primary py-2 text-sm">25%</button>
|
|
<button (click)="setBetAmount(0.5)" class="button-primary py-2 text-sm">50%</button>
|
|
<button (click)="setBetAmount(1)" class="button-primary py-2 text-sm">100%</button>
|
|
</div>
|
|
}
|
|
|
|
<!-- Custom bet input -->
|
|
<div class="space-y-1">
|
|
<div class="flex justify-between">
|
|
<label for="bet" class="text-sm text-text-secondary">Einsatzbetrag</label>
|
|
<span *ngIf="isInvalidBet()" class="text-xs text-accent-red animate-pulse"
|
|
>Darf Guthaben nicht überschreiten</span
|
|
>
|
|
</div>
|
|
<input
|
|
type="number"
|
|
id="bet"
|
|
class="w-full px-3 py-2 bg-deep-blue-light text-white rounded focus:outline-none focus:ring-2 disabled:opacity-50"
|
|
[ngClass]="{
|
|
'ring-accent-red': isInvalidBet(),
|
|
'ring-emerald': !isInvalidBet(),
|
|
}"
|
|
[min]="1"
|
|
[max]="balance()"
|
|
[ngModel]="betInputValue()"
|
|
(input)="updateBet($event)"
|
|
(keydown)="validateBetInput($event)"
|
|
step="1"
|
|
[disabled]="gameInProgress()"
|
|
[placeholder]="balance() | currency: 'EUR'"
|
|
/>
|
|
</div>
|
|
|
|
<!-- Rules/info section -->
|
|
<div class="mt-6 pt-4 border-t border-gray-700">
|
|
<h4 class="text-lg font-semibold mb-2">Spielregeln</h4>
|
|
<ul class="text-sm text-text-secondary space-y-1">
|
|
<li>• Wähle deinen Einsatzbetrag</li>
|
|
<li>• Wähle Kopf oder Zahl</li>
|
|
<li>• Gewinne das Doppelte deines Einsatzes bei richtiger Wahl</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|