Add comprehensive cash savings and transfers system with total holdings tracking
- Add cash accounts management with CRUD operations and account types - Implement date-stamped transfer system with deposits/withdrawals - Add total holdings card combining portfolio and cash values - Create dedicated "Add Transfer" page in navigation - Include automatic balance calculations and transaction history - Add database migrations for cash_accounts and cash_transfers tables - Integrate cash data with dashboard and real-time updates 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+408
-9
@@ -21,22 +21,34 @@
|
||||
<span class="menu-icon">💼</span>
|
||||
<span class="menu-text">Portfolio</span>
|
||||
</li>
|
||||
<li class="menu-item" data-page="trade-history">
|
||||
<span class="menu-icon">📋</span>
|
||||
<span class="menu-text">Trade History</span>
|
||||
<li class="menu-item" data-page="add-trade">
|
||||
<span class="menu-icon">➕</span>
|
||||
<span class="menu-text">Add Trade</span>
|
||||
</li>
|
||||
<li class="menu-item" data-page="cash-accounts">
|
||||
<span class="menu-icon">💰</span>
|
||||
<span class="menu-text">Cash Accounts</span>
|
||||
</li>
|
||||
<li class="menu-item" data-page="add-transfer">
|
||||
<span class="menu-icon">💸</span>
|
||||
<span class="menu-text">Add Transfer</span>
|
||||
</li>
|
||||
<li class="menu-item" data-page="gains-losses">
|
||||
<span class="menu-icon">📈</span>
|
||||
<span class="menu-text">Gains/Losses</span>
|
||||
</li>
|
||||
<li class="menu-item menu-separator" data-page="add-trade">
|
||||
<span class="menu-icon">➕</span>
|
||||
<span class="menu-text">Add Trade</span>
|
||||
<li class="menu-item" data-page="trade-history">
|
||||
<span class="menu-icon">📋</span>
|
||||
<span class="menu-text">Trade History</span>
|
||||
</li>
|
||||
<li class="menu-item" data-page="cgt-settings">
|
||||
<li class="menu-item menu-separator" data-page="cgt-settings">
|
||||
<span class="menu-icon">🧮</span>
|
||||
<span class="menu-text">CGT Settings</span>
|
||||
</li>
|
||||
<li class="menu-item" data-page="tokens">
|
||||
<span class="menu-icon">🔑</span>
|
||||
<span class="menu-text">API Tokens</span>
|
||||
</li>
|
||||
<li class="menu-item admin-only" data-page="admin" style="display: none;">
|
||||
<span class="menu-icon">👥</span>
|
||||
<span class="menu-text">Admin Panel</span>
|
||||
@@ -120,6 +132,53 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Total Holdings Card -->
|
||||
<div class="total-holdings-section">
|
||||
<div class="total-holdings-card">
|
||||
<h3>Total Holdings</h3>
|
||||
<div class="holdings-breakdown">
|
||||
<div class="holdings-item">
|
||||
<span class="holdings-label">Portfolio Value:</span>
|
||||
<span class="holdings-value" id="total-holdings-portfolio">€0.00</span>
|
||||
</div>
|
||||
<div class="holdings-item">
|
||||
<span class="holdings-label">Cash Savings:</span>
|
||||
<span class="holdings-value" id="total-holdings-cash">€0.00</span>
|
||||
</div>
|
||||
<div class="holdings-divider"></div>
|
||||
<div class="holdings-total">
|
||||
<span class="holdings-label">Total Value:</span>
|
||||
<span class="holdings-value total" id="total-holdings-combined">€0.00</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cash-breakdown" id="cash-breakdown" style="display: none;">
|
||||
<h3>Cash Savings Summary</h3>
|
||||
<div class="cash-summary-overview">
|
||||
<div class="cash-total-card">
|
||||
<div class="cash-amount-line" id="dashboard-cash-eur-line">
|
||||
<span class="currency-label">EUR:</span>
|
||||
<span class="amount" id="dashboard-cash-eur">€0.00</span>
|
||||
</div>
|
||||
<div class="cash-amount-line" id="dashboard-cash-usd-line" style="display: none;">
|
||||
<span class="currency-label">USD:</span>
|
||||
<span class="amount" id="dashboard-cash-usd">$0.00</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cash-stats-card">
|
||||
<span class="stat-detail" id="dashboard-account-count">0 accounts</span>
|
||||
<span class="stat-detail" id="dashboard-avg-interest-display" style="display: none;">Avg: 0.0%</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="cash-accounts-breakdown" class="breakdown-list">
|
||||
<div id="dashboard-cash-accounts-list">
|
||||
<p class="no-data">No cash accounts yet</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="etf-breakdown">
|
||||
<h3>ETF Breakdown</h3>
|
||||
<div id="etf-breakdown-list" class="breakdown-list">
|
||||
@@ -257,6 +316,337 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- API Tokens Page -->
|
||||
<div id="tokens-page" class="page">
|
||||
<div class="tokens-container">
|
||||
<h2>API Access Tokens</h2>
|
||||
<div class="tokens-intro">
|
||||
<p>Create access tokens to authenticate API requests for third-party integrations like n8n workflows. Keep your tokens secure and never share them publicly.</p>
|
||||
</div>
|
||||
|
||||
<div class="token-actions">
|
||||
<h3>Create New Token</h3>
|
||||
<form id="create-token-form" class="create-token-form">
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="token-name">Token Name</label>
|
||||
<input type="text" id="token-name" required placeholder="e.g., N8N Workflow Token" maxlength="50">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="token-expires">Expires (optional)</label>
|
||||
<select id="token-expires">
|
||||
<option value="">Never</option>
|
||||
<option value="30">30 days</option>
|
||||
<option value="90">90 days</option>
|
||||
<option value="365">1 year</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="token-scopes">Permissions</label>
|
||||
<select id="token-scopes">
|
||||
<option value="read">Read Only</option>
|
||||
<option value="read,write" selected>Read & Write</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="create-token-btn">Create Token</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="tokens-list-section">
|
||||
<h3>Your Access Tokens</h3>
|
||||
<div id="tokens-list" class="tokens-list">
|
||||
<p class="no-data">Loading tokens...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Token Creation Modal -->
|
||||
<div id="token-modal" class="modal" style="display: none;">
|
||||
<div class="modal-content">
|
||||
<h3>Token Created Successfully</h3>
|
||||
<p><strong>Important:</strong> Copy your token now. You won't be able to see it again!</p>
|
||||
<div class="token-display">
|
||||
<input type="text" id="new-token-value" readonly>
|
||||
<button id="copy-token-btn" class="copy-btn">Copy</button>
|
||||
</div>
|
||||
<div class="token-usage">
|
||||
<h4>Usage Example:</h4>
|
||||
<code class="usage-example">
|
||||
curl -H "Authorization: Bearer YOUR_TOKEN" \<br>
|
||||
http://localhost:3000/api/trades
|
||||
</code>
|
||||
</div>
|
||||
<button id="close-token-modal" class="close-modal-btn">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Cash Accounts Page -->
|
||||
<div id="cash-accounts-page" class="page">
|
||||
<div class="cash-accounts-container">
|
||||
<h2>Cash Savings Accounts</h2>
|
||||
<div class="cash-intro">
|
||||
<p>Track your cash savings accounts alongside your ETF investments. Manage different account types and monitor your total cash position.</p>
|
||||
</div>
|
||||
|
||||
<div class="cash-summary-cards">
|
||||
<div class="cash-summary-card total-cash">
|
||||
<h3>Total Cash</h3>
|
||||
<div class="cash-amounts">
|
||||
<div class="amount-line">
|
||||
<span class="currency">EUR:</span>
|
||||
<span class="amount" id="total-cash-eur">€0.00</span>
|
||||
</div>
|
||||
<div class="amount-line">
|
||||
<span class="currency">USD:</span>
|
||||
<span class="amount" id="total-cash-usd">$0.00</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cash-summary-card account-stats">
|
||||
<h3>Account Stats</h3>
|
||||
<div class="stat-line">
|
||||
<span>Accounts:</span>
|
||||
<span id="account-count">0</span>
|
||||
</div>
|
||||
<div class="stat-line">
|
||||
<span>Avg Interest:</span>
|
||||
<span id="avg-interest">0.0%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cash-actions">
|
||||
<h3>Add New Account</h3>
|
||||
<form id="create-account-form" class="create-account-form">
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="account-name">Account Name</label>
|
||||
<input type="text" id="account-name" required placeholder="e.g., Emergency Savings" maxlength="100">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="account-type">Account Type</label>
|
||||
<select id="account-type">
|
||||
<option value="savings">Savings Account</option>
|
||||
<option value="checking">Checking Account</option>
|
||||
<option value="money_market">Money Market</option>
|
||||
<option value="cd">Certificate of Deposit</option>
|
||||
<option value="other">Other</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="account-balance">Balance</label>
|
||||
<input type="number" id="account-balance" step="0.01" min="0" required placeholder="0.00">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="account-currency">Currency</label>
|
||||
<select id="account-currency">
|
||||
<option value="EUR" selected>EUR (€)</option>
|
||||
<option value="USD">USD ($)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="institution-name">Institution (optional)</label>
|
||||
<input type="text" id="institution-name" placeholder="e.g., Bank of Ireland">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="interest-rate">Interest Rate % (optional)</label>
|
||||
<input type="number" id="interest-rate" step="0.01" min="0" placeholder="0.00">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group full-width">
|
||||
<label for="account-notes">Notes (optional)</label>
|
||||
<textarea id="account-notes" placeholder="Additional notes about this account" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="create-account-btn">Add Account</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="accounts-list-section">
|
||||
<h3>Your Cash Accounts</h3>
|
||||
<div id="accounts-list" class="accounts-list">
|
||||
<p class="no-data">Loading accounts...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Edit Account Modal -->
|
||||
<div id="edit-account-modal" class="modal" style="display: none;">
|
||||
<div class="modal-content">
|
||||
<h3>Edit Cash Account</h3>
|
||||
<form id="edit-account-form">
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="edit-account-name">Account Name</label>
|
||||
<input type="text" id="edit-account-name" required maxlength="100">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="edit-account-type">Account Type</label>
|
||||
<select id="edit-account-type">
|
||||
<option value="savings">Savings Account</option>
|
||||
<option value="checking">Checking Account</option>
|
||||
<option value="money_market">Money Market</option>
|
||||
<option value="cd">Certificate of Deposit</option>
|
||||
<option value="other">Other</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="edit-account-balance">Balance</label>
|
||||
<input type="number" id="edit-account-balance" step="0.01" min="0" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="edit-account-currency">Currency</label>
|
||||
<select id="edit-account-currency">
|
||||
<option value="EUR">EUR (€)</option>
|
||||
<option value="USD">USD ($)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="edit-institution-name">Institution</label>
|
||||
<input type="text" id="edit-institution-name">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="edit-interest-rate">Interest Rate %</label>
|
||||
<input type="number" id="edit-interest-rate" step="0.01" min="0">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group full-width">
|
||||
<label for="edit-account-notes">Notes</label>
|
||||
<textarea id="edit-account-notes" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-buttons">
|
||||
<button type="button" id="cancel-edit-account" class="cancel-btn">Cancel</button>
|
||||
<button type="submit" class="save-btn">Save Changes</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Transfer Modal -->
|
||||
<div id="transfer-modal" class="modal" style="display: none;">
|
||||
<div class="modal-content">
|
||||
<h3>Add Transfer</h3>
|
||||
<form id="transfer-form">
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="transfer-account">Account</label>
|
||||
<select id="transfer-account" required>
|
||||
<option value="">Select Account</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="transfer-type">Transfer Type</label>
|
||||
<select id="transfer-type" required>
|
||||
<option value="">Select Type</option>
|
||||
<option value="deposit">Deposit</option>
|
||||
<option value="withdrawal">Withdrawal</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="transfer-amount">Amount</label>
|
||||
<input type="number" id="transfer-amount" step="0.01" min="0.01" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="transfer-date">Transfer Date</label>
|
||||
<input type="date" id="transfer-date" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group full-width">
|
||||
<label for="transfer-description">Description</label>
|
||||
<textarea id="transfer-description" rows="2" placeholder="Optional description"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-buttons">
|
||||
<button type="button" id="cancel-transfer" class="cancel-btn">Cancel</button>
|
||||
<button type="submit" class="save-btn">Add Transfer</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Transfers Section -->
|
||||
<div class="transfers-section">
|
||||
<div class="section-header">
|
||||
<h3>Recent Transfers</h3>
|
||||
<button id="add-transfer-btn" class="primary-btn">Add Transfer</button>
|
||||
</div>
|
||||
<div id="transfers-list" class="transfers-list">
|
||||
<p class="no-data">No transfers found</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Add Transfer Page -->
|
||||
<div id="add-transfer-page" class="page">
|
||||
<div class="transfer-form-container">
|
||||
<h2>Add Cash Transfer</h2>
|
||||
<div class="transfer-intro">
|
||||
<p>Record deposits and withdrawals for your cash accounts. Transfers will automatically update account balances.</p>
|
||||
</div>
|
||||
|
||||
<form id="standalone-transfer-form" class="transfer-form">
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="standalone-transfer-account">Account</label>
|
||||
<select id="standalone-transfer-account" required>
|
||||
<option value="">Select Account</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="standalone-transfer-type">Transfer Type</label>
|
||||
<select id="standalone-transfer-type" required>
|
||||
<option value="">Select Type</option>
|
||||
<option value="deposit">Deposit</option>
|
||||
<option value="withdrawal">Withdrawal</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="standalone-transfer-amount">Amount</label>
|
||||
<input type="number" id="standalone-transfer-amount" step="0.01" min="0.01" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="standalone-transfer-date">Transfer Date</label>
|
||||
<input type="date" id="standalone-transfer-date" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group full-width">
|
||||
<label for="standalone-transfer-description">Description</label>
|
||||
<textarea id="standalone-transfer-description" rows="3" placeholder="Optional description"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="submit-btn">Add Transfer</button>
|
||||
</form>
|
||||
|
||||
<div class="recent-transfers">
|
||||
<h3>Recent Transfers</h3>
|
||||
<div id="standalone-transfers-list" class="transfers-list">
|
||||
<p class="no-data">No transfers found</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Gains/Losses Page -->
|
||||
<div id="gains-losses-page" class="page">
|
||||
<div class="gains-losses-container">
|
||||
@@ -407,9 +797,14 @@
|
||||
</div>
|
||||
|
||||
<div class="cgt-rate-item">
|
||||
<label for="cgt-longterm">2+ Years (%)</label>
|
||||
<label for="cgt-longterm">2-8 Years (%)</label>
|
||||
<input type="number" id="cgt-longterm" min="0" max="100" step="0.1" value="10" class="cgt-rate-input">
|
||||
</div>
|
||||
|
||||
<div class="cgt-rate-item">
|
||||
<label for="cgt-8years">8+ Years (%)</label>
|
||||
<input type="number" id="cgt-8years" min="0" max="100" step="0.1" value="33" class="cgt-rate-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="cgt-options">
|
||||
@@ -454,9 +849,13 @@
|
||||
<div class="rate-value">20%</div>
|
||||
</div>
|
||||
<div class="rate-bar" data-period="longterm">
|
||||
<span class="period-label">2Y+</span>
|
||||
<span class="period-label">2-8Y</span>
|
||||
<div class="rate-value">10%</div>
|
||||
</div>
|
||||
<div class="rate-bar" data-period="8years">
|
||||
<span class="period-label">8Y+</span>
|
||||
<div class="rate-value">33%</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user