Add separate wallet page and fix username display

- Create wallet.html with full wallet management UI
- Fix player.js to show actual username (real_name or username) instead of 'Player'
- Add Wallet links to player.html and broker.html headers
- Wallet page includes balance overview, deposit/withdraw modals, transaction history
parent 63393234
......@@ -16,6 +16,7 @@
<div class="user-info">
<span id="user-name">Welcome, Broker</span>
<span id="user-balance" class="balance-display">Balance: $0.00</span>
<a href="wallet.html" class="btn btn-primary btn-sm">Wallet</a>
<a href="profile.html" class="btn btn-secondary btn-sm">Profile</a>
<button class="logout-btn" onclick="logout()">Logout</button>
</div>
......
......@@ -17,6 +17,7 @@
<div class="user-info">
<span id="user-name">Welcome, Player</span>
<span id="user-balance" class="balance-display">Balance: $0.00</span>
<a href="wallet.html" class="btn btn-primary btn-sm">Wallet</a>
<a href="profile.html" class="btn btn-secondary btn-sm">Profile</a>
<button class="logout-btn" onclick="logout()">Logout</button>
</div>
......
......@@ -520,8 +520,9 @@ async function loadPlayerData() {
profitLossElement.style.color = profitLoss >= 0 ? 'var(--success-color)' : 'var(--error-color)';
// Update user name
if (currentUser && currentUser.name) {
document.getElementById('user-name').textContent = `Welcome, ${currentUser.name}`;
if (currentUser) {
const displayName = currentUser.real_name || currentUser.username || 'Player';
document.getElementById('user-name').textContent = `Welcome, ${displayName}`;
}
} catch (error) {
console.error('Error loading player data:', error);
......
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Wallet - Townships Combat League</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<header class="dashboard-header">
<div>
<h1 class="dashboard-title">My Wallet</h1>
<p class="tagline">Manage your funds</p>
</div>
<div class="user-info">
<span id="user-name">Welcome</span>
<a href="player.html" class="btn btn-secondary" id="back-to-dashboard">Back to Dashboard</a>
<button class="logout-btn" onclick="logout()">Logout</button>
</div>
</header>
<main class="dashboard-content">
<!-- Wallet Overview -->
<section class="wallet-overview">
<div class="wallet-balance">
<h3>Available Balance</h3>
<p class="balance-amount" id="wallet-balance">$0.00</p>
</div>
<div class="wallet-stats">
<div class="stat-item">
<span class="stat-label">Pending Balance</span>
<span class="stat-value" id="pending-balance">$0.00</span>
</div>
<div class="stat-item">
<span class="stat-label">Total Deposited</span>
<span class="stat-value" id="total-deposited">$0.00</span>
</div>
<div class="stat-item">
<span class="stat-label">Total Withdrawn</span>
<span class="stat-value" id="total-withdrawn">$0.00</span>
</div>
<div class="stat-item">
<span class="stat-label">Total Wagered</span>
<span class="stat-value" id="total-wagered">$0.00</span>
</div>
</div>
</section>
<!-- Wallet Actions -->
<section class="card">
<div class="card-header">
<h2>Quick Actions</h2>
</div>
<div class="card-body">
<div class="wallet-actions">
<button class="btn btn-primary" onclick="showDepositModal()">Deposit Funds</button>
<button class="btn btn-secondary" onclick="showWithdrawModal()">Withdraw Funds</button>
<a href="profile.html" class="btn btn-outline">Profile Settings</a>
</div>
</div>
</section>
<!-- Transaction History -->
<section class="card">
<div class="card-header">
<h2>Transaction History</h2>
</div>
<div class="card-body">
<div class="transaction-filters">
<label for="transaction-type-filter">Filter by type:</label>
<select id="transaction-type-filter" onchange="loadTransactions()">
<option value="">All Transactions</option>
<option value="deposit">Deposits</option>
<option value="withdrawal">Withdrawals</option>
<option value="bet">Bets</option>
<option value="winnings">Winnings</option>
<option value="refund">Refunds</option>
</select>
</div>
<div id="transaction-list" class="transaction-list">
<p>Loading transactions...</p>
</div>
<div class="pagination">
<button class="btn btn-sm" id="prev-page" onclick="previousPage()" disabled>Previous</button>
<span class="page-info" id="page-info">Page 1</span>
<button class="btn btn-sm" id="next-page" onclick="nextPage()">Next</button>
</div>
</div>
</section>
</main>
</div>
<!-- Deposit Modal -->
<div id="deposit-modal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h2>Deposit Funds</h2>
<button class="close-btn" onclick="closeModal('deposit-modal')">&times;</button>
</div>
<div class="modal-body">
<form id="deposit-form" onsubmit="processDeposit(event)">
<div class="form-group">
<label for="deposit-amount">Amount</label>
<input type="number" id="deposit-amount" min="1" step="0.01" required placeholder="Enter amount">
<span class="form-hint">Minimum deposit: $1.00</span>
</div>
<div class="form-group">
<label for="payment-method">Payment Method</label>
<select id="payment-method" required>
<option value="">Select payment method</option>
<option value="mobile_money">Mobile Money</option>
<option value="bank_transfer">Bank Transfer</option>
<option value="card">Credit/Debit Card</option>
</select>
</div>
<div class="form-group">
<label for="deposit-reference">Reference (Optional)</label>
<input type="text" id="deposit-reference" placeholder="Payment reference">
</div>
<div id="deposit-message" class="message" style="display: none;"></div>
<button type="submit" class="btn btn-primary btn-block">Process Deposit</button>
</form>
</div>
</div>
</div>
<!-- Withdraw Modal -->
<div id="withdraw-modal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h2>Withdraw Funds</h2>
<button class="close-btn" onclick="closeModal('withdraw-modal')">&times;</button>
</div>
<div class="modal-body">
<form id="withdraw-form" onsubmit="processWithdrawal(event)">
<div class="form-group">
<label for="withdraw-amount">Amount</label>
<input type="number" id="withdraw-amount" min="1" step="0.01" required placeholder="Enter amount">
<span class="form-hint">Available: <span id="available-for-withdraw">$0.00</span></span>
</div>
<div class="form-group">
<label for="withdraw-method">Withdrawal Method</label>
<select id="withdraw-method" required>
<option value="">Select withdrawal method</option>
<option value="mobile_money">Mobile Money</option>
<option value="bank_transfer">Bank Transfer</option>
</select>
</div>
<div class="form-group">
<label for="withdraw-details">Account Details</label>
<input type="text" id="withdraw-details" required placeholder="Phone number or account number">
</div>
<div id="withdraw-message" class="message" style="display: none;"></div>
<button type="submit" class="btn btn-primary btn-block">Request Withdrawal</button>
</form>
</div>
</div>
</div>
<script src="app.js"></script>
<script>
// Wallet page specific JavaScript
let currentPage = 1;
const transactionsPerPage = 20;
let totalTransactions = 0;
// Initialize wallet page
document.addEventListener('DOMContentLoaded', async function() {
const token = localStorage.getItem('access_token');
if (!token) {
window.location.href = 'index.html';
return;
}
// Load wallet data
await loadWalletData();
await loadTransactions();
// Update username display
const storedUser = localStorage.getItem('currentUser');
if (storedUser) {
const user = JSON.parse(storedUser);
const displayName = user.real_name || user.username || 'User';
document.getElementById('user-name').textContent = `Welcome, ${displayName}`;
// Update back button based on role
const backBtn = document.getElementById('back-to-dashboard');
if (user.role === 'broker') {
backBtn.href = 'broker.html';
}
}
});
// Load wallet data
async function loadWalletData() {
try {
const response = await getWallet();
if (response) {
updateWalletDisplay();
}
} catch (error) {
console.error('Error loading wallet data:', error);
showNotification('Failed to load wallet data', 'error');
}
}
// Update wallet display
function updateWalletDisplay() {
if (!walletData) return;
document.getElementById('wallet-balance').textContent = formatCurrency(walletData.balance || 0);
document.getElementById('pending-balance').textContent = formatCurrency(walletData.pending_balance || 0);
document.getElementById('total-deposited').textContent = formatCurrency(walletData.total_deposited || 0);
document.getElementById('total-withdrawn').textContent = formatCurrency(walletData.total_withdrawn || 0);
document.getElementById('total-wagered').textContent = formatCurrency(walletData.total_wagered || 0);
document.getElementById('available-for-withdraw').textContent = formatCurrency(walletData.balance || 0);
}
// Load transactions
async function loadTransactions() {
const transactionType = document.getElementById('transaction-type-filter').value;
const offset = (currentPage - 1) * transactionsPerPage;
try {
const response = await getWalletTransactions(transactionsPerPage, offset, transactionType);
if (response && response.transactions) {
displayTransactions(response.transactions);
totalTransactions = response.total || response.transactions.length;
updatePagination();
} else {
document.getElementById('transaction-list').innerHTML = '<p>No transactions found.</p>';
}
} catch (error) {
console.error('Error loading transactions:', error);
document.getElementById('transaction-list').innerHTML = '<p>Failed to load transactions.</p>';
}
}
// Display transactions
function displayTransactions(transactions) {
const container = document.getElementById('transaction-list');
if (!transactions || transactions.length === 0) {
container.innerHTML = '<p>No transactions found.</p>';
return;
}
container.innerHTML = transactions.map(tx => {
const isCredit = ['deposit', 'winnings', 'refund'].includes(tx.transaction_type);
const amountClass = isCredit ? 'positive' : 'negative';
const itemClass = isCredit ? 'credit' : 'debit';
const amountPrefix = isCredit ? '+' : '-';
const date = new Date(tx.created_at).toLocaleString();
return `
<div class="transaction-item ${itemClass}">
<div class="transaction-info">
<span class="transaction-type">${formatTransactionType(tx.transaction_type)}</span>
<span class="transaction-date">${date}</span>
${tx.description ? `<span class="transaction-description">${tx.description}</span>` : ''}
</div>
<div class="transaction-details">
<span class="transaction-amount ${amountClass}">${amountPrefix}${formatCurrency(Math.abs(tx.amount))}</span>
<span class="transaction-status status-${tx.status}">${tx.status}</span>
</div>
</div>
`;
}).join('');
}
// Format transaction type
function formatTransactionType(type) {
const types = {
'deposit': 'Deposit',
'withdrawal': 'Withdrawal',
'bet': 'Bet Placed',
'winnings': 'Winnings',
'refund': 'Refund',
'adjustment': 'Adjustment'
};
return types[type] || type;
}
// Pagination
function updatePagination() {
const totalPages = Math.ceil(totalTransactions / transactionsPerPage);
document.getElementById('page-info').textContent = `Page ${currentPage} of ${totalPages || 1}`;
document.getElementById('prev-page').disabled = currentPage <= 1;
document.getElementById('next-page').disabled = currentPage >= totalPages;
}
function previousPage() {
if (currentPage > 1) {
currentPage--;
loadTransactions();
}
}
function nextPage() {
const totalPages = Math.ceil(totalTransactions / transactionsPerPage);
if (currentPage < totalPages) {
currentPage++;
loadTransactions();
}
}
// Modal functions
function showDepositModal() {
document.getElementById('deposit-modal').style.display = 'flex';
}
function showWithdrawModal() {
document.getElementById('withdraw-modal').style.display = 'flex';
}
function closeModal(modalId) {
document.getElementById(modalId).style.display = 'none';
}
// Process deposit
async function processDeposit(event) {
event.preventDefault();
const amount = parseFloat(document.getElementById('deposit-amount').value);
const method = document.getElementById('payment-method').value;
const reference = document.getElementById('deposit-reference').value;
if (!amount || amount < 1) {
showFormMessage('deposit-message', 'Minimum deposit is $1.00', 'error');
return;
}
const result = await depositToWallet(amount, method, reference);
if (result.success) {
showFormMessage('deposit-message', 'Deposit processed successfully!', 'success');
setTimeout(() => {
closeModal('deposit-modal');
loadWalletData();
loadTransactions();
}, 1500);
} else {
showFormMessage('deposit-message', result.error || 'Deposit failed', 'error');
}
}
// Process withdrawal
async function processWithdrawal(event) {
event.preventDefault();
const amount = parseFloat(document.getElementById('withdraw-amount').value);
const method = document.getElementById('withdraw-method').value;
const details = document.getElementById('withdraw-details').value;
if (!amount || amount < 1) {
showFormMessage('withdraw-message', 'Minimum withdrawal is $1.00', 'error');
return;
}
if (walletData && amount > walletData.balance) {
showFormMessage('withdraw-message', 'Insufficient balance', 'error');
return;
}
const result = await withdrawFromWallet(amount, `Withdrawal to ${method}: ${details}`);
if (result.success) {
showFormMessage('withdraw-message', 'Withdrawal request submitted!', 'success');
setTimeout(() => {
closeModal('withdraw-modal');
loadWalletData();
loadTransactions();
}, 1500);
} else {
showFormMessage('withdraw-message', result.error || 'Withdrawal failed', 'error');
}
}
// Show form message
function showFormMessage(elementId, message, type) {
const element = document.getElementById(elementId);
element.textContent = message;
element.className = `message ${type}`;
element.style.display = 'block';
}
// Close modals when clicking outside
window.addEventListener('click', (e) => {
if (e.target.classList.contains('modal')) {
e.target.style.display = 'none';
}
});
// Close modals with ESC key
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') {
document.querySelectorAll('.modal').forEach(modal => {
modal.style.display = 'none';
});
}
});
</script>
</body>
</html>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment