Three system confirm() dialogs sat in the middle of dealing. The worst was on Next Hand — the most-pressed button in a session, asking "are you sure?" every single time, stealing focus and, on a phone, taking over the screen. Next Hand now just happens, and a toast says where the button landed with an Undo beside it for the few seconds anyone would notice a misclick. The same undo covers the pot wizard, which is the more valuable case: paying the wrong player is a real mistake, and rolling it back restores the hand history entry and the session standings along with the seats. The snapshot is in-memory only — an undo is for the mistake you just made, not one from last night. The two genuinely destructive actions keep a confirmation, but as an in-page dialog that matches the table instead of the browser's own: Escape or the backdrop cancels, Enter confirms, and on a phone the buttons go full width with Cancel nearest the thumb. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_015bnp7xKUPFFSpwkYNFaPgb
250 lines
11 KiB
Plaintext
250 lines
11 KiB
Plaintext
@page
|
||
@model JoshHeaps.Net.Pages.Casino.TexasHoldemModel
|
||
@{
|
||
ViewData["Title"] = "Texas Hold'em Dealer";
|
||
Layout = "_Layout";
|
||
}
|
||
|
||
<div id="holdemApp">
|
||
<header id="holdemHeader">
|
||
<div id="holdemHeaderLeft">
|
||
<h1>Texas Hold'em Dealer</h1>
|
||
<p class="holdemSubtitle">Seat your players, track the action, split the pot.</p>
|
||
<span id="handCounterBadge" class="handCounterBadge">Hand #1</span>
|
||
</div>
|
||
<div id="holdemHeaderActions">
|
||
<a href="/casino/texasholdem/quicksplit" class="holdemBtn" title="Chop a pot without setting up a table">Quick Split</a>
|
||
<button id="nextHandBtn" class="holdemBtn" title="Move the button, small blind and big blind to the next occupied seat">Next Hand ⟳</button>
|
||
<button id="resolvePotBtn" class="holdemBtn holdemBtnAccent">Resolve Pot</button>
|
||
<button id="resetTableBtn" class="holdemBtn holdemBtnDanger">Reset Table</button>
|
||
<a href="/casino" class="holdemBtn holdemBtnGhost">← Casino</a>
|
||
</div>
|
||
</header>
|
||
|
||
<div id="holdemLayout">
|
||
<section id="tableSection">
|
||
<div id="pokerTableWrap">
|
||
<div id="pokerTable">
|
||
<div id="tableWatermark">Texas Hold'em</div>
|
||
<div id="potBadge">
|
||
<span id="potBadgeLabel">Pot</span>
|
||
<span id="potBadgeAmount">$0</span>
|
||
</div>
|
||
</div>
|
||
<div id="seatsLayer"></div>
|
||
</div>
|
||
<p id="tableHint" class="tableHint"></p>
|
||
</section>
|
||
|
||
<aside id="holdemSidebar">
|
||
<section id="seatEditorPanel" class="sidebarPanel seatEditorPanel">
|
||
<div class="seatSheetGrip" aria-hidden="true"></div>
|
||
<div class="seatEditorHeader">
|
||
<h2 id="seatEditorTitle">Select a seat</h2>
|
||
<button id="closeSeatEditorBtn" class="seatSheetClose" aria-label="Done editing this seat">Done</button>
|
||
</div>
|
||
<div id="seatEditorBody">
|
||
<p class="fieldHint">Click a seat at the table to edit their name, cards, chips and anything else.</p>
|
||
</div>
|
||
</section>
|
||
|
||
<details class="sidebarPanel" open>
|
||
<summary>Table Setup</summary>
|
||
<div class="panelBody">
|
||
<label class="fieldRow">
|
||
<span>Seats at table</span>
|
||
<input type="number" id="seatCountInput" min="2" max="24" value="10" />
|
||
</label>
|
||
<label class="fieldRow">
|
||
<span>Blinds move</span>
|
||
<select id="directionSelect">
|
||
<option value="clockwise" selected>Clockwise</option>
|
||
<option value="counterclockwise">Counterclockwise</option>
|
||
</select>
|
||
</label>
|
||
<label class="fieldRow">
|
||
<span>Dedicated dealer (not a seat)</span>
|
||
<input type="checkbox" id="dedicatedDealerToggle" />
|
||
</label>
|
||
<p class="fieldHint">Turn this on if a person outside the game deals — no seat shows the dealer button, but blinds still rotate automatically each hand.</p>
|
||
<label class="fieldRow">
|
||
<span>Base pot amount ($)</span>
|
||
<input type="number" id="basePotInput" min="0" step="1" placeholder="e.g. 500" />
|
||
</label>
|
||
<p class="fieldHint">Every player who didn't go all-in short is assumed to have put in this amount. Enter a smaller amount on a seat only if that player is all-in for less.</p>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="sidebarPanel">
|
||
<summary>Chip Legend</summary>
|
||
<div class="panelBody">
|
||
<div id="chipLegendList"></div>
|
||
<button id="addChipColorBtn" class="holdemBtn holdemBtnSmall">+ Add chip color</button>
|
||
<p class="fieldHint">Give each chip color a dollar value, then count chips per seat instead of typing a total.</p>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="sidebarPanel">
|
||
<summary>Table Notes</summary>
|
||
<div class="panelBody">
|
||
<textarea id="tableNotes" rows="4" placeholder="Anything else worth tracking — side bets, IOUs, running totals..."></textarea>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="sidebarPanel">
|
||
<summary>Session Standings</summary>
|
||
<div class="panelBody">
|
||
<div id="standingsTable">
|
||
<div class="standingsRow standingsHeader">
|
||
<span>Player</span>
|
||
<span>In</span>
|
||
<span>Won</span>
|
||
<span>Net</span>
|
||
</div>
|
||
<div id="standingsList"></div>
|
||
</div>
|
||
<p id="standingsEmptyHint" class="fieldHint">Once you resolve a pot, everyone's running total for the night shows up here.</p>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="sidebarPanel">
|
||
<summary>Hand History</summary>
|
||
<div class="panelBody">
|
||
<div id="handHistoryList"></div>
|
||
<p id="handHistoryEmptyHint" class="fieldHint">Resolved pots show up here as you play, in case a chip count is disputed later.</p>
|
||
<div class="handHistoryActions">
|
||
<button id="exportHistoryBtn" class="holdemBtn holdemBtnSmall">Export CSV</button>
|
||
<button id="clearHistoryBtn" class="holdemBtn holdemBtnSmall holdemBtnDanger">Clear history</button>
|
||
</div>
|
||
</div>
|
||
</details>
|
||
</aside>
|
||
</div>
|
||
</div>
|
||
|
||
<template id="seatTemplate">
|
||
<div class="seat" draggable="true">
|
||
<div class="seatChairNumber"></div>
|
||
<button class="dealerChip" title="Make this seat the dealer button">D</button>
|
||
<span class="blindBadge sbBadge">SB</span>
|
||
<span class="blindBadge bbBadge">BB</span>
|
||
<div class="seatPuckName"></div>
|
||
<div class="seatPuckCards"></div>
|
||
<div class="seatPuckTotal"></div>
|
||
</div>
|
||
</template>
|
||
|
||
<template id="seatEditorTemplate">
|
||
<div class="seatEditorForm">
|
||
<label class="fieldRow">
|
||
<span>Name</span>
|
||
<input type="text" class="seatNameInput" placeholder="Seat" maxlength="24" />
|
||
</label>
|
||
<div class="seatCardToggles">
|
||
<label class="inHandToggle" title="This seat is playing the current hand">
|
||
<input type="checkbox" class="inHandCheckbox" />
|
||
<span>In hand</span>
|
||
</label>
|
||
<label class="foldToggle" title="Folded">
|
||
<input type="checkbox" class="foldCheckbox" />
|
||
<span>Fold</span>
|
||
</label>
|
||
</div>
|
||
<div class="seatCards">
|
||
<input type="text" class="cardInput card1Input" maxlength="2" placeholder="__" />
|
||
<input type="text" class="cardInput card2Input" maxlength="2" placeholder="__" />
|
||
</div>
|
||
<div class="seatContribution">
|
||
<div class="chipCounts"></div>
|
||
<label class="fieldRow amountOverrideRow">
|
||
<span>$ amount</span>
|
||
<input type="number" class="amountOverrideInput" min="0" step="1" placeholder="auto" />
|
||
</label>
|
||
<div class="seatTotal">Total: <span class="seatTotalAmount">$0</span></div>
|
||
</div>
|
||
<div class="customFields"></div>
|
||
<button class="holdemBtn holdemBtnSmall addFieldBtn">+ field</button>
|
||
</div>
|
||
</template>
|
||
|
||
<template id="chipLegendRowTemplate">
|
||
<div class="chipLegendRow">
|
||
<input type="color" class="chipColorInput" />
|
||
<input type="number" class="chipValueInput" min="0" step="0.01" placeholder="value" />
|
||
<button class="holdemBtn holdemBtnSmall holdemBtnDanger removeChipColorBtn">×</button>
|
||
</div>
|
||
</template>
|
||
|
||
<template id="chipCountTemplate">
|
||
<label class="chipCountRow">
|
||
<span class="chipSwatch"></span>
|
||
<input type="number" class="chipCountInput" min="0" step="1" value="0" />
|
||
</label>
|
||
</template>
|
||
|
||
<template id="customFieldTemplate">
|
||
<div class="customFieldRow">
|
||
<input type="text" class="customFieldLabel" placeholder="Label" maxlength="20" />
|
||
<input type="text" class="customFieldValue" placeholder="Value" maxlength="40" />
|
||
<button class="holdemBtn holdemBtnSmall holdemBtnDanger removeFieldBtn">×</button>
|
||
</div>
|
||
</template>
|
||
|
||
<template id="standingsRowTemplate">
|
||
<div class="standingsRow">
|
||
<span class="standingsName"></span>
|
||
<span class="standingsIn"></span>
|
||
<span class="standingsWon"></span>
|
||
<span class="standingsNet"></span>
|
||
</div>
|
||
</template>
|
||
|
||
<template id="handHistoryRowTemplate">
|
||
<div class="handHistoryRow">
|
||
<div class="handHistoryRowHeader">
|
||
<span class="handHistoryHandNumber"></span>
|
||
<span class="handHistoryPot"></span>
|
||
<span class="handHistoryTime"></span>
|
||
</div>
|
||
<div class="handHistoryPayouts"></div>
|
||
</div>
|
||
</template>
|
||
|
||
<div id="toastHost" aria-live="polite"></div>
|
||
|
||
<div id="confirmOverlay" hidden>
|
||
<div id="confirmModal" role="alertdialog" aria-labelledby="confirmTitle" aria-describedby="confirmMessage" tabindex="-1">
|
||
<h2 id="confirmTitle"></h2>
|
||
<p id="confirmMessage"></p>
|
||
<div class="confirmActions">
|
||
<button id="confirmCancelBtn" class="holdemBtn holdemBtnGhost" type="button">Cancel</button>
|
||
<button id="confirmAcceptBtn" class="holdemBtn holdemBtnDanger" type="button">Confirm</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="potWizardOverlay" hidden>
|
||
<div id="potWizardModal">
|
||
<div class="potWizardHeader">
|
||
<h2>Resolve the Pot</h2>
|
||
<button id="closePotWizardBtn" class="holdemBtn holdemBtnGhost">✕</button>
|
||
</div>
|
||
<div id="potWizardBody"></div>
|
||
</div>
|
||
</div>
|
||
|
||
@section Styles {
|
||
<link href="/css/casino/holdem.css?v=@ViewData["cssVersion"]" rel="stylesheet" type="text/css" />
|
||
}
|
||
|
||
@section Scripts {
|
||
<script src="~/js/casino/holdem/money.js?v=@ViewData["cssVersion"]"></script>
|
||
<script src="~/js/casino/holdem/feedback.js?v=@ViewData["cssVersion"]"></script>
|
||
<script src="~/js/casino/holdem/potCalculator.js?v=@ViewData["cssVersion"]"></script>
|
||
<script src="~/js/casino/holdem/state.js?v=@ViewData["cssVersion"]"></script>
|
||
<script src="~/js/casino/holdem/render.js?v=@ViewData["cssVersion"]"></script>
|
||
<script src="~/js/casino/holdem/potWizard.js?v=@ViewData["cssVersion"]"></script>
|
||
<script src="~/js/casino/holdem/handHistoryExport.js?v=@ViewData["cssVersion"]"></script>
|
||
<script src="~/js/casino/holdem/main.js?v=@ViewData["cssVersion"]"></script>
|
||
}
|