/** * Banking Interface * Handles transfers, deposits, withdrawals, and account management */ // ============================================================================ // INITIALIZATION // ============================================================================ function initBank() { setupEventHandlers(); // Subscribe to store updates if (typeof store !== 'undefined') { store.subscribe(() => { updateBalances(); renderTransactions(); }); } // Initial render updateBalances(); renderTransactions(); console.log('[Bank] Interface initialized'); } // ============================================================================ // EVENT HANDLERS // ============================================================================ function setupEventHandlers() { // Close button const closeBtn = document.querySelector('.close-btn'); if (closeBtn) { closeBtn.addEventListener('click', () => { sendEvent('bank::close', {}); }); } // Transfer form const transferBtn = document.getElementById('transferBtn'); const transferFrom = document.getElementById('transferFrom'); const amount = document.getElementById('amount'); const playerId = document.getElementById('playerId'); const playerIdGroup = document.getElementById('playerIdGroup'); // Always show player ID field since transfer is only to players if (playerIdGroup) { playerIdGroup.style.display = 'flex'; } // Transfer button if (transferBtn) { transferBtn.addEventListener('click', () => { const from = transferFrom.value; const transferAmount = parseFloat(amount.value); if (!transferAmount || transferAmount <= 0) { console.log('Please enter a valid amount'); return; } if (!playerId.value) { console.log('Please enter a player ID'); return; } const currentState = store.getState(); const fromAccountBalance = currentState.accounts[from]; if (transferAmount > fromAccountBalance) { console.log('Insufficient funds'); return; } const transferData = { from: from, amount: transferAmount, target: playerId.value }; sendEvent('bank::transfer', transferData); // Dispatch to store to update UI store.dispatch(transfer(from, transferAmount, 'player')); // Clear form amount.value = ''; playerId.value = ''; }); } // Quick action buttons const quickActionBtns = document.querySelectorAll('.quick-action-btn'); quickActionBtns.forEach(btn => { btn.addEventListener('click', () => { const action = btn.dataset.action; const currentState = store.getState(); switch (action) { case 'deposit-amount': const depositAmountStr = document.getElementById('amount').value; if (depositAmountStr && parseFloat(depositAmountStr) > 0) { const depositAmount = parseFloat(depositAmountStr); if (depositAmount > currentState.accounts.cash) { console.log('Insufficient cash'); return; } sendEvent('bank::deposit', { amount: depositAmount }); store.dispatch(deposit(depositAmount)); document.getElementById('amount').value = ''; } else { console.log('Please enter a valid amount'); } break; case 'deposit': const cashBalance = currentState.accounts.cash; if (cashBalance <= 0) { console.log('No cash to deposit'); return; } sendEvent('bank::deposit', { amount: cashBalance }); store.dispatch(deposit(cashBalance)); break; case 'withdraw': const amountStr = document.getElementById('amount').value; if (amountStr && parseFloat(amountStr) > 0) { const withdrawAmount = parseFloat(amountStr); sendEvent('bank::withdraw', { amount: withdrawAmount }); store.dispatch(withdraw(withdrawAmount)); document.getElementById('amount').value = ''; } else { console.log('Please enter a valid amount'); } break; default: console.log('Invalid action'); break; } }); }); } // ============================================================================ // UI UPDATES // ============================================================================ function updateBalances() { const currentState = store.getState(); const balanceElements = document.querySelectorAll('.balance-amount'); // The HTML structure has 3 account cards. // 0: Cash, 1: Bank, 2: Org if (balanceElements.length >= 3) { balanceElements[0].textContent = `$${currentState.accounts.cash.toLocaleString()}`; balanceElements[1].textContent = `$${currentState.accounts.bank.toLocaleString()}`; balanceElements[2].textContent = `$${currentState.accounts.org.toLocaleString()}`; } // Update form options const transferFrom = document.getElementById('transferFrom'); if (transferFrom) { const currentSelection = transferFrom.value; transferFrom.innerHTML = ` `; if (currentSelection && (currentSelection === 'cash' || currentSelection === 'bank')) { transferFrom.value = currentSelection; } } // Update player list const playerSelect = document.getElementById('playerId'); if (playerSelect && currentState.accounts.players) { const currentPlayerSelection = playerSelect.value; const players = currentState.accounts.players; const currentPlayerUid = currentState.uid; // Clear existing options playerSelect.innerHTML = ''; // Handle hashmap structure from Arma (UID -> {name, uid}) if (players && typeof players === 'object') { // Convert hashmap to array and iterate Object.keys(players).forEach(uid => { // Skip current player to prevent self-transfers if (uid === currentPlayerUid) { return; } const playerData = players[uid]; if (playerData && playerData.name) { const option = document.createElement('option'); option.value = uid; option.textContent = playerData.name; playerSelect.appendChild(option); } }); } if (currentPlayerSelection) { // Verify if the selected player is still in the list const optionExists = Array.from(playerSelect.options).some(opt => opt.value === currentPlayerSelection); if (optionExists) { playerSelect.value = currentPlayerSelection; } } } } function renderTransactions() { const transactionList = document.querySelector('.transaction-list'); if (!transactionList) return; transactionList.innerHTML = ''; const currentState = store.getState(); currentState.transactions.forEach((transaction, index) => { const item = document.createElement('div'); item.className = 'transaction-item'; // Deposits are gains (green), Withdrawals and Transfers are losses (red) const isGain = transaction.type === 'Deposit'; const amountClass = isGain ? 'positive' : 'negative'; const displayAmount = isGain ? `+$${transaction.amount.toLocaleString()}` : `-$${Math.abs(transaction.amount).toLocaleString()}`; // Map transaction types to CSS classes const typeClassMap = { 'Deposit': 'deposit', 'Withdraw': 'withdrawal', 'Transfer': 'transfer' }; const typeClass = typeClassMap[transaction.type] || transaction.type.toLowerCase(); item.innerHTML = `