Files
boker/templates/league_session_detail.html
T

595 lines
31 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends "base.html" %}
{% block title %}{{ session_model.display_label }} · {{ league.name }} · myboker.org{% endblock %}
{% block sidebar %}{% include "_league_sidebar.html" %}{% endblock %}
{% block page_class %}page--app{% endblock %}
{% block content %}
<div class="hero" style="padding-top:0;padding-bottom:12px;display:flex;flex-wrap:wrap;gap:12px;align-items:flex-end;justify-content:space-between;">
<div>
<h1 class="hero__title">{{ session_model.display_label }}</h1>
<p class="hero__sub">{{ session_model.session_date.isoformat() | pretty_date }} · <span class="status-badge status-{{ session_model.status }}">{{ session_model.status }}</span></p>
</div>
<div class="button-row">
<a class="btn btn--ghost btn--sm" href="{{ url_for('leagues.session_public_view', league_ref=league.url_ref, session_id=session_model.id) }}">Public view</a>
{% if can_manage %}
<button class="btn btn--ghost btn--sm" type="button" data-modal="modal-edit-session">Edit session</button>
{% if session_model.status == 'open' %}
<form method="post" action="{{ url_for('leagues.close_league_session', league_ref=league.url_ref, session_id=session_model.id) }}" style="margin:0;">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<button class="btn btn--ghost btn--sm" type="submit">Close session</button>
</form>
{% else %}
<button class="btn btn--ghost btn--sm" type="button" data-modal="modal-reopen-session">Reopen session</button>
{% endif %}
{% endif %}
{% if is_owner %}
<button class="btn btn--danger btn--sm" type="button" data-modal="modal-delete-session">Delete session</button>
{% endif %}
</div>
</div>
<div class="cash-strip">
<div class="stat">
<span class="kicker">Cash in</span>
<div class="stat__val" style="color:var(--num)">{{ session.total_buy_in_cents | money }}</div>
{% if session.total_front_cents > 0 %}<div class="stat__sub">+ {{ session.total_front_cents | money }} fronted</div>{% endif %}
</div>
{% if session.total_payout_carry_in_cents > 0 or session.total_rollover_in_cents > 0 %}
<div class="stat">
<span class="kicker">Carry in</span>
<div class="stat__val" style="color:var(--rolled)">{{ (session.total_payout_carry_in_cents + session.total_rollover_in_cents) | money }}</div>
</div>
{% endif %}
<div class="stat">
<span class="kicker">Claimed</span>
<div class="stat__val" style="color:var(--num)">{{ session.total_cash_out_cents | money }}</div>
</div>
<div class="stat">
<span class="kicker">Paid out</span>
<div class="stat__val" style="color:var(--pos)">{{ session.total_paid_out_cents | money }}</div>
</div>
{% set total_unsettled = session.total_current_due_to_player_cents + session.total_current_due_to_house_cents %}
<div class="stat">
<span class="kicker">Unsettled</span>
<div class="stat__val" style="color:{{ 'var(--warn)' if total_unsettled > 0 else 'var(--muted)' }}">{{ total_unsettled | money }}</div>
{% if session.total_current_due_to_house_cents > 0 %}<div class="stat__sub" style="color:var(--neg)">{{ session.total_current_due_to_house_cents | money }} owed to house</div>{% endif %}
{% if session.total_current_due_to_player_cents > 0 %}<div class="stat__sub" style="color:var(--warn)">{{ session.total_current_due_to_player_cents | money }} owed to players</div>{% endif %}
</div>
</div>
<div class="stack">
{% if can_manage %}
<form class="panel form-card ledger-form" method="post" id="appendForm">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<div class="ledger-form__head">
<span class="eyebrow">Ledger entry</span>
{% if session_model.status == 'open' %}
<span class="ledger-form__status ledger-form__status--open">Live</span>
{% else %}
<span class="ledger-form__status ledger-form__status--closed">Closed</span>
{% endif %}
</div>
{% if session_model.status != 'open' %}
<div class="session-locked-banner">
<strong>Session closed</strong>
<span>Reopen to add events.</span>
</div>
{% endif %}
<fieldset {% if session_model.status != 'open' %}disabled{% endif %} style="border:none;padding:0;margin:0;min-width:0;display:grid;gap:10px;">
<label>
<span>Player</span>
<div class="player-picker" id="playerPicker">
<div class="player-picker__input-wrap">
<input
type="text"
id="playerSearch"
class="player-picker__search"
placeholder="Select a player…"
autocomplete="off"
value="{{ players | selectattr('id', 'equalto', append_form.player_id) | map(attribute='display_name') | first | default('') }}"
>
<svg class="player-picker__chevron" width="12" height="12" viewBox="0 0 12 12" fill="none" aria-hidden="true"><path d="M2 4l4 4 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
</div>
<div class="player-picker__dropdown" id="playerDropdown" hidden>
{% for player in players %}
<button type="button" class="player-picker__opt" data-name="{{ player.display_name }}" data-id="{{ player.id }}">{{ player.display_name }}</button>
{% endfor %}
</div>
</div>
<input type="hidden" name="player_id" id="playerIdInput" value="{{ append_form.player_id or '' }}">
</label>
<div class="ledger-form__ta-row">
<div class="ledger-form__inputs">
<label>
<span>Type</span>
<select name="event_type" id="eventTypeSelect" required>
{% for value, label in event_types %}
<option value="{{ value }}" {{ 'selected' if append_form.event_type == value else '' }}>{{ label }}</option>
{% endfor %}
</select>
</label>
<label>
<span>Amount</span>
<input type="number" step="0.01" min="0" name="amount" id="amountInput" value="{{ append_form.amount }}" placeholder="0.00">
</label>
</div>
{% if default_buyin_cents > 0 or default_rebuy_cents > 0 %}
<div class="amount-quickset" id="amountQuickset">
<div class="amount-quickset__presets">
{% if default_buyin_cents > 0 %}
<button type="button" class="amount-quickset__btn"
data-event-type="buyin"
data-base="{{ '%.2f' % (default_buyin_cents / 100) }}">
<span class="amount-quickset__lbl">Buy-in</span>
<span class="amount-quickset__val">${{ '%.2f' % (default_buyin_cents / 100) }}</span>
</button>
{% endif %}
{% if default_rebuy_cents > 0 %}
<button type="button" class="amount-quickset__btn"
data-event-type="buyin"
data-base="{{ '%.2f' % (default_rebuy_cents / 100) }}">
<span class="amount-quickset__lbl">Rebuy</span>
<span class="amount-quickset__val">${{ '%.2f' % (default_rebuy_cents / 100) }}</span>
</button>
{% endif %}
</div>
<div class="amount-quickset__mults">
<button type="button" class="amount-quickpick__btn" data-mult="1">1×</button>
<button type="button" class="amount-quickpick__btn" data-mult="2">2×</button>
</div>
</div>
{% endif %}
</div>
<label>
<span>Note <span class="form-opt-hint">(optional)</span></span>
<textarea name="note" rows="1" placeholder="Optional context" style="resize:vertical;">{{ append_form.note or '' }}</textarea>
</label>
<button class="btn btn--primary ledger-form__submit" type="submit">Append event</button>
</fieldset>
</form>
{% else %}
<div class="panel empty-panel">
<h2 class="panel__title">Read only</h2>
<p class="muted-text">Your role can inspect this session but cannot append ledger events.</p>
</div>
{% endif %}
<div class="panel">
<div class="panel__head">
<div>
<p class="kicker" style="margin:0;">Results</p>
<h2 class="panel__title">Player totals</h2>
</div>
<div style="display:flex;align-items:center;gap:8px;flex-wrap:wrap;">
{% set ns = namespace(playing=0, settled=0, owes=0, owed=0) %}
{% for entry in session.entries %}
{% if entry.cash_out_cents == 0 and entry.invested_cents > 0 %}{% set ns.playing = ns.playing + 1 %}
{% elif entry.current_due_to_house_cents > 0 %}{% set ns.owes = ns.owes + 1 %}
{% elif entry.current_due_to_player_cents > 0 %}{% set ns.owed = ns.owed + 1 %}
{% else %}{% set ns.settled = ns.settled + 1 %}
{% endif %}
{% endfor %}
{% if ns.playing > 0 %}<span class="ledger-tally ledger-tally--playing">{{ ns.playing }} in play</span>{% endif %}
{% if ns.owes > 0 %}<span class="ledger-tally ledger-tally--owes">{{ ns.owes }} owe</span>{% endif %}
{% if ns.owed > 0 %}<span class="ledger-tally ledger-tally--owed">{{ ns.owed }} owed</span>{% endif %}
{% if ns.settled > 0 %}<span class="ledger-tally ledger-tally--settled">{{ ns.settled }} settled</span>{% endif %}
<span class="panel__tag">{{ session.entries|length }} players</span>
</div>
</div>
{% if session.entries %}
<div class="player-ledger-list">
{% for entry in session.entries %}
<div class="player-ledger-row">
<div class="player-ledger-row__who">
<span class="player-ledger-row__name">{{ entry.player_name }}</span>
{% if entry.cash_out_cents == 0 and entry.invested_cents > 0 %}
<span class="badge badge--playing">In play</span>
{% elif entry.current_due_to_house_cents > 0 %}
<span class="badge badge--owes">Owes {{ entry.current_due_to_house_cents | money }}</span>
{% elif entry.current_due_to_player_cents > 0 %}
<span class="badge badge--unpaid">Due {{ entry.current_due_to_player_cents | money }}</span>
{% else %}
<span class="badge badge--settled">Settled</span>
{% endif %}
</div>
<div class="player-ledger-row__stats">
<div class="player-ledger-row__stat">
<span class="player-ledger-row__lbl">In</span>
<span class="player-ledger-row__val">{{ entry.invested_cents | money }}</span>
</div>
<div class="player-ledger-row__stat">
<span class="player-ledger-row__lbl">Cashout</span>
<span class="player-ledger-row__val">{{ entry.cash_out_cents | money }}</span>
</div>
<div class="player-ledger-row__stat">
<span class="player-ledger-row__lbl">Paid out</span>
<span class="player-ledger-row__val" style="color:var(--pos)">{{ entry.paid_out_cents | money if entry.paid_out_cents else '—' }}</span>
</div>
<div class="player-ledger-row__stat player-ledger-row__stat--net">
<span class="player-ledger-row__lbl">Net</span>
<span class="player-ledger-row__val {{ 'num-pos' if entry.net_cents > 0 else 'num-neg' if entry.net_cents < 0 else 'num-muted' }}">{{ '+' if entry.net_cents > 0 else '' }}{{ entry.net_cents | money }}</span>
</div>
{% if entry.rollover_in_cents or entry.rollover_out_cents or entry.payout_carry_in_cents %}
<div class="player-ledger-row__stat">
<span class="player-ledger-row__lbl">Rolled in</span>
<span class="player-ledger-row__val" style="color:var(--rolled)">{{ entry.rollover_in_cents | money }}</span>
</div>
<div class="player-ledger-row__stat">
<span class="player-ledger-row__lbl">Carry in</span>
<span class="player-ledger-row__val" style="color:var(--rolled)">{{ entry.payout_carry_in_cents | money }}</span>
</div>
{% endif %}
</div>
{% if can_manage and session_model.status == 'open' %}
<div class="player-ledger-row__actions">
{% if default_rebuy_cents > 0 %}
<form method="post" style="margin:0;">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<input type="hidden" name="player_id" value="{{ entry.player_id }}">
<input type="hidden" name="event_type" value="buyin">
<input type="hidden" name="amount" value="{{ '%.2f' % (default_rebuy_cents / 100) }}">
<button type="submit" class="btn btn--ghost">Rebuy ${{ '%.2f' % (default_rebuy_cents / 100) }}</button>
</form>
{% elif default_buyin_cents > 0 %}
<form method="post" style="margin:0;">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<input type="hidden" name="player_id" value="{{ entry.player_id }}">
<input type="hidden" name="event_type" value="buyin">
<input type="hidden" name="amount" value="{{ '%.2f' % (default_buyin_cents / 100) }}">
<button type="submit" class="btn btn--ghost">Rebuy ${{ '%.2f' % (default_buyin_cents / 100) }}</button>
</form>
{% else %}
<button type="button" class="btn btn--ghost player-row-prefill"
data-player-id="{{ entry.player_id }}"
data-player-name="{{ entry.player_name }}"
data-event-type="buyin">Rebuy</button>
{% endif %}
<button type="button" class="btn btn--ghost player-row-prefill"
data-player-id="{{ entry.player_id }}"
data-player-name="{{ entry.player_name }}"
data-event-type="cashout">Cash out</button>
</div>
{% endif %}
</div>
{% endfor %}
</div>
{% else %}
<p class="muted-text" style="padding:28px;">No player ledger events yet.</p>
{% endif %}
</div>
</div>
<div class="panel" style="margin-top:20px;">
<div class="panel__head">
<div>
<p class="kicker" style="margin:0;">Audit trail</p>
<h2 class="panel__title">Raw ledger events</h2>
</div>
<span class="badge badge--closed">append-only</span>
</div>
<div class="event-feed feed feed--inline" style="max-height:none;">
{% for event in raw_events | reverse %}
<div class="event-card event-card--inline {% if event.voided_at %}event-card--voided{% endif %}">
<div class="event-card-top">
<strong>{{ event.player_name or "Session" }}</strong>
<span class="pill pill-{{ event.event_type }}">{{ event.event_type | replace('_', ' ') }}</span>
{% if event.voided_at %}<span class="void-badge">voided</span>{% endif %}
{% if event.note and not event.voided_at %}<span class="event-note">{{ event.note }}</span>{% endif %}
</div>
<p class="event-amount">{{ event.amount_cents | money }}</p>
{% if event.voided_at %}
<p class="tiny-text void-reason">{{ event.void_reason }}</p>
{% else %}
<p class="tiny-text">{{ event.created_at }}</p>
{% if is_owner %}
<button class="btn-void-toggle" type="button"
data-void-id="{{ event.id }}"
data-void-player="{{ event.player_name or 'Session' }}"
data-void-type="{{ event.event_type | replace('_', ' ') }}"
data-void-amount="${{ '%.2f' % (event.amount_cents / 100) }}"
data-void-action="{{ url_for('leagues.void_event', league_ref=league.url_ref, event_id=event.id) }}">
void
</button>
{% endif %}
{% endif %}
</div>
{% else %}
<p class="muted-text" style="padding:20px;">No events recorded.</p>
{% endfor %}
</div>
</div>
{% if is_owner %}
<div class="modal-backdrop" id="modal-void-event" hidden>
<div class="modal-card" role="dialog" aria-modal="true" aria-labelledby="modal-void-title">
<div class="modal-card__head">
<span class="kicker" style="margin:0;color:var(--warn);">Correct the record</span>
<h2 class="panel__title" id="modal-void-title">Void event</h2>
</div>
<p class="modal-card__text" id="modal-void-desc">This event will remain visible in the audit trail but will no longer count toward any calculations.</p>
<form id="modal-void-form" method="post" action="">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<label style="display:flex;flex-direction:column;gap:6px;margin-bottom:16px;">
<span style="font:600 12px/1 var(--font-ui);color:var(--text-2);text-transform:uppercase;letter-spacing:.04em;">Reason</span>
<input type="text" name="void_reason" placeholder="What was wrong with this event?" required maxlength="200"
style="background:var(--field);border:1px solid var(--border-strong);border-radius:var(--r-sm);padding:9px 12px;font:400 14px/1.4 var(--font-ui);color:var(--text-1);">
</label>
<div class="modal-card__actions">
<button class="btn btn--ghost btn--sm" type="button" data-close-modal>Cancel</button>
<button class="btn btn--danger btn--sm" type="submit">Void this event</button>
</div>
</form>
</div>
</div>
{% endif %}
<div class="modal-backdrop" id="modal-delete-session" hidden>
<div class="modal-card" role="dialog" aria-modal="true" aria-labelledby="modal-delete-title">
<div class="modal-card__head">
<span class="kicker" style="margin:0;color:var(--neg);">Destructive action</span>
<h2 class="panel__title" id="modal-delete-title">Delete {{ session_model.display_label }}?</h2>
</div>
<p class="modal-card__text">This will permanently delete the session and <strong>all {{ session_model.event_count if session_model.event_count is defined else 'its' }} ledger events</strong> attached to it. There is no undo.</p>
<div class="modal-card__actions">
<button class="btn btn--ghost btn--sm" type="button" data-close-modal>Cancel</button>
<form method="post" action="{{ url_for('leagues.delete_session', league_ref=league.url_ref, session_id=session_model.id) }}" style="margin:0;">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<button class="btn btn--danger btn--sm" type="submit">Yes, delete permanently</button>
</form>
</div>
</div>
</div>
{% if can_manage %}
<div class="modal-backdrop" id="modal-edit-session" hidden>
<div class="modal-card" role="dialog" aria-modal="true" aria-labelledby="modal-edit-session-title">
<div class="modal-card__head">
<span class="kicker" style="margin:0;">Session</span>
<h2 class="panel__title" id="modal-edit-session-title">Edit session</h2>
</div>
<form method="post" action="{{ url_for('leagues.edit_session', league_ref=league.url_ref, session_id=session_model.id) }}">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<div class="form-card" style="padding:0 20px 4px;gap:12px;">
<label>
<span>Date</span>
<input type="date" name="session_date" value="{{ session_model.session_date.isoformat() }}" required>
</label>
{% if seasons %}
<label>
<span>Season <span class="form-opt-hint">(optional)</span></span>
<select name="season_id">
<option value="">No season</option>
{% for s in seasons %}
<option value="{{ s.id }}" {{ 'selected' if session_model.season_id == s.id else '' }}>{{ s.name }}</option>
{% endfor %}
</select>
</label>
{% endif %}
<label>
<span>Label <span class="form-opt-hint">(optional)</span></span>
<input type="text" name="label" value="{{ session_model.label or '' }}" placeholder="e.g. Main table">
</label>
<label>
<span>Notes <span class="form-opt-hint">(optional)</span></span>
<input type="text" name="notes" value="{{ session_model.notes or '' }}" placeholder="Optional context">
</label>
</div>
<div class="modal-card__actions">
<button class="btn btn--ghost btn--sm" type="button" data-close-modal>Cancel</button>
<button class="btn btn--primary btn--sm" type="submit">Save changes</button>
</div>
</form>
</div>
</div>
{% endif %}
<div class="modal-backdrop" id="modal-reopen-session" hidden>
<div class="modal-card" role="dialog" aria-modal="true" aria-labelledby="modal-reopen-title">
<div class="modal-card__head">
<span class="kicker" style="margin:0;">Settled session</span>
<h2 class="panel__title" id="modal-reopen-title">Reopen this session?</h2>
</div>
<p class="modal-card__text">This session has been closed and books are assumed to be settled. Reopening will allow new ledger events to be appended and may affect settlement totals.</p>
<div class="modal-card__actions">
<button class="btn btn--ghost btn--sm" type="button" data-close-modal>Cancel</button>
<form method="post" action="{{ url_for('leagues.open_league_session', league_ref=league.url_ref, session_id=session_model.id) }}" style="margin:0;">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<button class="btn btn--primary btn--sm" type="submit">Reopen session</button>
</form>
</div>
</div>
</div>
<script>
// --- Custom player picker ---
(function () {
const picker = document.getElementById('playerPicker');
if (!picker) return;
const searchInput = document.getElementById('playerSearch');
const idInput = document.getElementById('playerIdInput');
const dropdown = document.getElementById('playerDropdown');
const opts = dropdown ? Array.from(dropdown.querySelectorAll('.player-picker__opt')) : [];
const eventTypeSelect = document.getElementById('eventTypeSelect');
function openDropdown() {
if (!dropdown) return;
dropdown.removeAttribute('hidden');
}
function closeDropdown() {
if (dropdown) dropdown.setAttribute('hidden', '');
}
function filterOpts(q) {
const lq = q.toLowerCase().trim();
opts.forEach(opt => {
opt.style.display = (!lq || opt.dataset.name.toLowerCase().includes(lq)) ? '' : 'none';
});
}
function selectPlayer(name, id) {
searchInput.value = name;
idInput.value = id;
filterOpts(name);
closeDropdown();
}
function clearPlayer() {
searchInput.value = '';
idInput.value = '';
filterOpts('');
}
searchInput.addEventListener('focus', () => { filterOpts(searchInput.value); openDropdown(); });
searchInput.addEventListener('input', function () {
filterOpts(this.value);
openDropdown();
const matched = opts.find(o => o.dataset.name.toLowerCase() === this.value.trim().toLowerCase());
idInput.value = matched ? matched.dataset.id : '';
});
searchInput.addEventListener('keydown', function (e) {
if (e.key === 'Escape') closeDropdown();
if (e.key === 'Enter') {
const visible = opts.filter(o => o.style.display !== 'none');
if (visible.length === 1) { e.preventDefault(); selectPlayer(visible[0].dataset.name, visible[0].dataset.id); }
}
});
opts.forEach(opt => {
opt.addEventListener('mousedown', e => { e.preventDefault(); selectPlayer(opt.dataset.name, opt.dataset.id); });
});
document.addEventListener('click', e => { if (!picker.contains(e.target)) closeDropdown(); });
if (eventTypeSelect) {
eventTypeSelect.addEventListener('change', function () {
if (this.value === 'note') {
clearPlayer();
searchInput.placeholder = 'No player (session note)';
searchInput.disabled = true;
} else {
searchInput.placeholder = 'Search or select a player…';
searchInput.disabled = false;
}
});
if (eventTypeSelect.value === 'note') {
searchInput.placeholder = 'No player (session note)';
searchInput.disabled = true;
}
}
})();
// --- Quick-set amount buttons (Buy-in / Rebuy) + 1x/2x multipliers ---
(function () {
const amountInput = document.getElementById('amountInput');
const eventTypeSelect = document.getElementById('eventTypeSelect');
let quickBase = null;
let currentMult = 1;
function setAmount(val) {
if (!amountInput) return;
amountInput.value = parseFloat(val).toFixed(2);
}
function syncQuicksetActive(activeBtn) {
document.querySelectorAll('.amount-quickset__btn').forEach(b => {
b.classList.toggle('is-active', b === activeBtn);
});
}
function syncMultActive(mult) {
currentMult = mult;
document.querySelectorAll('.amount-quickpick__btn').forEach(b => {
b.classList.toggle('is-active', parseInt(b.dataset.mult) === mult);
});
}
document.querySelectorAll('.amount-quickset__btn').forEach(btn => {
btn.addEventListener('click', function () {
quickBase = parseFloat(this.dataset.base);
if (eventTypeSelect && this.dataset.eventType) {
eventTypeSelect.value = this.dataset.eventType;
}
setAmount(quickBase * currentMult);
syncQuicksetActive(this);
});
});
document.querySelectorAll('.amount-quickpick__btn').forEach(btn => {
btn.addEventListener('click', function () {
const mult = parseInt(this.dataset.mult);
syncMultActive(mult);
if (quickBase !== null) setAmount(quickBase * mult);
});
});
// Reset multiplier to 1× when user types manually
if (amountInput) {
amountInput.addEventListener('input', function () {
syncMultActive(1);
syncQuicksetActive(null);
quickBase = parseFloat(this.value) || null;
});
}
// Auto-select the Buy-in quickset button on load if buyin type and no amount
if (!amountInput || amountInput.value) return;
const buyinBtn = document.querySelector('.amount-quickset__btn[data-event-type="buyin"]');
if (buyinBtn && eventTypeSelect && eventTypeSelect.value === 'buyin') {
quickBase = parseFloat(buyinBtn.dataset.base);
setAmount(quickBase);
syncQuicksetActive(buyinBtn);
}
})();
// --- Per-player quick-action pre-fill ---
document.querySelectorAll('.player-row-prefill').forEach(function(btn) {
btn.addEventListener('click', function() {
var playerId = this.dataset.playerId;
var playerName = this.dataset.playerName;
var eventType = this.dataset.eventType;
var idInput = document.getElementById('playerIdInput');
var searchInput = document.getElementById('playerSearch');
var typeSelect = document.getElementById('eventTypeSelect');
var amountInput = document.getElementById('amountInput');
if (idInput) idInput.value = playerId;
if (searchInput) searchInput.value = playerName;
if (typeSelect) typeSelect.value = eventType;
if (amountInput) { amountInput.value = ''; amountInput.focus(); }
var form = document.getElementById('appendForm');
if (form) form.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
});
});
document.querySelectorAll('[data-modal]').forEach(function(btn) {
btn.addEventListener('click', function() {
var target = document.getElementById(this.dataset.modal);
if (target) target.removeAttribute('hidden');
});
});
document.querySelectorAll('[data-close-modal]').forEach(function(btn) {
btn.addEventListener('click', function() {
this.closest('.modal-backdrop').setAttribute('hidden', '');
});
});
document.querySelectorAll('.modal-backdrop').forEach(function(backdrop) {
backdrop.addEventListener('click', function(e) {
if (e.target === this) this.setAttribute('hidden', '');
});
});
document.querySelectorAll('[data-void-id]').forEach(function(btn) {
btn.addEventListener('click', function() {
var player = this.dataset.voidPlayer;
var type = this.dataset.voidType;
var amount = this.dataset.voidAmount;
document.getElementById('modal-void-title').textContent = 'Void ' + type + ' — ' + player;
document.getElementById('modal-void-desc').textContent =
'The ' + amount + ' ' + type + ' event for ' + player +
' will be marked voided and excluded from all calculations. It stays visible in the audit trail.';
var form = document.getElementById('modal-void-form');
form.action = this.dataset.voidAction;
form.querySelector('[name=void_reason]').value = '';
document.getElementById('modal-void-event').removeAttribute('hidden');
});
});
</script>
{% endblock %}