diff --git a/frontend/public/coinflip.png b/frontend/public/coinflip.png
new file mode 100644
index 0000000..0f39ca8
Binary files /dev/null and b/frontend/public/coinflip.png differ
diff --git a/frontend/public/poker.webp b/frontend/public/poker.webp
deleted file mode 100644
index 329f4da..0000000
Binary files a/frontend/public/poker.webp and /dev/null differ
diff --git a/frontend/src/app/feature/game/coinflip/coinflip.component.html b/frontend/src/app/feature/game/coinflip/coinflip.component.html
index 4501de1..671bc31 100644
--- a/frontend/src/app/feature/game/coinflip/coinflip.component.html
+++ b/frontend/src/app/feature/game/coinflip/coinflip.component.html
@@ -102,15 +102,25 @@
-
+
+
+ Cannot exceed balance
+
(null);
betInputValue = signal(10);
errorMessage = signal('');
+ isInvalidBet = signal(false);
@ViewChild('coinElement') coinElement?: ElementRef;
@@ -62,18 +70,30 @@ export default class CoinflipComponent implements OnInit {
updateBet(event: Event) {
const inputElement = event.target as HTMLInputElement;
- const value = Number(inputElement.value);
-
+ let value = Number(inputElement.value);
+
+ // Reset invalid bet state
+ this.isInvalidBet.set(false);
+
+ // Enforce minimum bet of 1
if (value <= 0) {
- this.betInputValue.set(1);
- this.currentBet.set(1);
- } else if (value > this.balance()) {
- this.betInputValue.set(this.balance());
- this.currentBet.set(this.balance());
- } else {
- this.betInputValue.set(value);
- this.currentBet.set(value);
+ value = 1;
}
+
+ // Cap bet at available balance and show feedback
+ if (value > this.balance()) {
+ value = this.balance();
+ // Show visual feedback
+ this.isInvalidBet.set(true);
+ // Indicate the error briefly
+ setTimeout(() => this.isInvalidBet.set(false), 800);
+ // Update the input field directly to show the user the max value
+ inputElement.value = String(value);
+ }
+
+ // Update signals
+ this.betInputValue.set(value);
+ this.currentBet.set(value);
}
betHeads() {
@@ -191,6 +211,38 @@ export default class CoinflipComponent implements OnInit {
console.log(`Animation applied for result: ${result}`);
}
+ /**
+ * Validates input as the user types to prevent invalid values
+ */
+ validateBetInput(event: KeyboardEvent) {
+ // Allow navigation keys (arrows, delete, backspace, tab)
+ const navigationKeys = ['ArrowLeft', 'ArrowRight', 'Delete', 'Backspace', 'Tab'];
+ if (navigationKeys.includes(event.key)) {
+ return;
+ }
+
+ // Only allow numbers
+ if (!/^\d$/.test(event.key)) {
+ event.preventDefault();
+ return;
+ }
+
+ // Get the value that would result after the keypress
+ const input = event.target as HTMLInputElement;
+ const currentValue = input.value;
+ const cursorPosition = input.selectionStart || 0;
+ const newValue = currentValue.substring(0, cursorPosition) + event.key + currentValue.substring(input.selectionEnd || cursorPosition);
+ const numValue = Number(newValue);
+
+ // Prevent values greater than balance
+ if (numValue > this.balance()) {
+ event.preventDefault();
+ }
+ }
+
+ // We removed the paste handler for simplicity since the updateBet method
+ // will handle any value that gets into the input field
+
getResultClass() {
if (!this.gameResult()) return '';
const result = this.gameResult();
diff --git a/frontend/src/app/feature/home/home.component.ts b/frontend/src/app/feature/home/home.component.ts
index 07b5f9f..9ca6d39 100644
--- a/frontend/src/app/feature/home/home.component.ts
+++ b/frontend/src/app/feature/home/home.component.ts
@@ -48,9 +48,9 @@ export default class HomeComponent implements OnInit {
featuredGames: Game[] = [
{
id: '1',
- name: 'Poker',
- image: '/poker.webp',
- route: '/game/poker',
+ name: 'Coinflip',
+ image: '/coinflip.png',
+ route: '/game/coinflip',
},
{
id: '2',