client/addons/bank/ui/_site/script.js
Jacob Schmidt f8391463b2
All checks were successful
Build / Build (push) Successful in 28s
feat: Implement timesheets and pending payments in bank UI
This commit introduces the timesheet submission feature and displays pending payments in the bank UI.

The following changes were made:

- Added a "Submit Timesheet" action tile to the bank UI.
- Implemented the `handleTimesheet` function in `script.js` to handle timesheet submissions.
- Updated the UI to display pending payments based on player rating and a server-side multiplier.
- Modified server-side event handling to process timesheet submissions and calculate payments.
- Added a refresh timer to update player data every 30 seconds.
- Updated the player load event to include the player's rating.
2025-05-11 01:19:44 -05:00

305 lines
8.5 KiB
JavaScript

/**
* Bank Management Script
* This script handles the bank interface functionality for the Arma 3 game interface.
* It provides wallet/account management, transfers, and transaction history.
*/
//=============================================================================
// #region DATA STRUCTURES AND VARIABLES
//=============================================================================
/**
* Bank state - will be populated from game events
*/
let bankState = {
wallet: 0,
account: 0,
pending: 0,
players: [],
transactions: []
};
// #endregion
//=============================================================================
// #region INITIALIZATION AND DATA REQUESTS
//=============================================================================
/**
* Initialize the bank interface
* Sets up the UI and requests initial data from the game engine
*/
function initializeBank() {
// Request initial data from the game
requestPlayerFunds();
requestPlayerData();
requestTransactionHistory();
}
/**
* Request player funds data from the game engine
*/
function requestPlayerFunds() {
const message = {
event: "REQUEST::PLAYER::FUNDS",
data: {}
};
A3API.SendAlert(JSON.stringify(message));
}
/**
* Request player data from the game engine
*/
function requestPlayerData() {
const message = {
event: "REQUEST::PLAYER::DATA",
data: {}
};
A3API.SendAlert(JSON.stringify(message));
}
/**
* Request transaction history from the game engine
*/
function requestTransactionHistory() {
const message = {
event: "REQUEST::TRANSACTION::HISTORY",
data: {}
};
A3API.SendAlert(JSON.stringify(message));
}
/**
* Set up a timer to refresh player data every 30 seconds
* Ensures the UI is updated with the latest information
*/
function setupRefreshTimer() {
setInterval(requestPlayerData, 30000); // Refresh every 30 seconds
}
// #endregion
//=============================================================================
// #region DATA HANDLERS
//=============================================================================
/**
* Handle player data received from the game engine
* @param {Array} data - List of player objects
*/
function handlePlayerDataRequest(data) {
bankState.players = data;
populatePlayerList();
}
/**
* Handle player funds data received from the game engine
* @param {Object} data - Object containing cash and balance
*/
function handlePlayerFundsRequest(data) {
console.log('Received funds data:', data);
// Parse the data if it's a string
if (typeof data === 'string') {
try {
data = JSON.parse(data);
} catch (e) {
console.error('Failed to parse data:', e);
return;
}
}
// Ensure we have valid numbers, default to 0 if null
bankState.wallet = data.cash !== null ? Number(data.cash) : 0;
bankState.account = data.balance !== null ? Number(data.balance) : 0;
bankState.pending = data.pending !== null ? Number(data.pending) : 0;
updateBalanceDisplays();
}
/**
* Handle transaction history data received from the game engine
* @param {Object} data - Object containing transaction history
*/
function handleTransactionHistoryRequest(data) {
console.log('Received transaction history:', data);
// Parse the data if it's a string
if (typeof data === 'string') {
try {
data = JSON.parse(data);
} catch (e) {
console.error('Failed to parse transaction history:', e);
return;
}
}
// Initialize empty array if history is null
bankState.transactions = [];
updateTransactionHistory();
}
// #endregion
//=============================================================================
// #region UI UPDATES AND DISPLAY
//=============================================================================
/**
* Update balance displays in the header
*/
function updateBalanceDisplays() {
const walletElement = document.getElementById('walletBalance');
const accountElement = document.getElementById('accountBalance');
const pendingElement = document.getElementById('pending');
if (walletElement && accountElement && pendingElement) {
walletElement.textContent = `$${(bankState.wallet || 0).toLocaleString()}`;
accountElement.textContent = `$${(bankState.account || 0).toLocaleString()}`;
pendingElement.textContent = `$${(bankState.pending || 0).toLocaleString()}`;
}
}
/**
* Populate the player selection dropdown
*/
function populatePlayerList() {
const playerSelect = document.getElementById('playerSelect');
playerSelect.innerHTML = '<option value="" disabled selected>Select Player</option>';
bankState.players.forEach(player => {
const option = document.createElement('option');
option.value = player.uid;
option.textContent = player.name;
playerSelect.appendChild(option);
});
}
/**
* Update the transaction history display
*/
function updateTransactionHistory() {
const historyList = document.getElementById('transactionHistory');
if (!historyList) return;
historyList.innerHTML = '';
if (!Array.isArray(bankState.transactions)) {
console.error('Transaction history is not an array:', bankState.transactions);
return;
}
if (bankState.transactions.length === 0) {
const li = document.createElement('li');
li.className = 'history-item empty';
li.textContent = 'No transactions yet';
historyList.appendChild(li);
return;
}
bankState.transactions.forEach(transaction => {
if (!transaction) return;
const li = document.createElement('li');
li.className = 'history-item';
const isNegative = ['transfer_out', 'to_wallet'].includes(transaction.type);
const amountClass = isNegative ? 'amount-negative' : 'amount-positive';
const amountPrefix = isNegative ? '-' : '+';
const amount = Math.abs(Number(transaction.amount) || 0);
li.innerHTML = `
<span class="transaction-type">${formatTransactionType(transaction.type)}</span>
<span class="transaction-details">${transaction.details || ''}</span>
<span class="amount ${amountClass}">${amountPrefix}$${amount.toLocaleString()}</span>
`;
historyList.appendChild(li);
});
}
/**
* Format transaction type for display
* @param {string} type - Transaction type code
* @returns {string} Formatted transaction type
*/
function formatTransactionType(type) {
const types = {
'to_wallet': 'To Wallet',
'to_account': 'To Account',
'transfer_out': 'Transfer Out',
'transfer_in': 'Transfer In',
'timesheet': 'Timesheet'
};
return types[type] || type;
}
// #endregion
//=============================================================================
// #region ACTION HANDLERS
//=============================================================================
/**
* Handle transfer between wallet and account
*/
function handleTransfer() {
const amount = parseInt(document.getElementById('transferAmount').value);
const transferType = document.getElementById('transferType').value;
const event = transferType === 'to_wallet' ? 'WITHDRAW::FUNDS' : 'DEPOSIT::FUNDS';
const message = {
event: event,
data: [amount]
};
A3API.SendAlert(JSON.stringify(message));
document.getElementById('transferAmount').value = '';
setTimeout(requestPlayerFunds, 500);
}
/**
* Handle transfer to another player
*/
function handlePlayerTransfer() {
const amount = parseInt(document.getElementById('playerTransferAmount').value);
const playerUid = document.getElementById('playerSelect').value;
const message = {
event: 'TRANSFER::FUNDS',
data: [amount, playerUid]
};
A3API.SendAlert(JSON.stringify(message));
document.getElementById('playerTransferAmount').value = '';
setTimeout(requestPlayerFunds, 500);
}
/**
* Handle timesheet submission
*/
function handleTimesheet() {
const message = {
event: 'SUBMIT::TIMESHEET',
data: {}
};
A3API.SendAlert(JSON.stringify(message));
setTimeout(requestPlayerFunds, 500);
}
// #endregion
//=============================================================================
// #region INITIALIZATION
//=============================================================================
/**
* Initialize when DOM is loaded
*/
document.addEventListener('DOMContentLoaded', () => {
initializeBank()
setupRefreshTimer();
});
// #endregion