mirror of
https://github.com/acedanger/finance.git
synced 2026-03-25 01:41:51 -07:00
Initial commit - Basic bank transactions dashboard structure with Astro and TypeScript
This commit is contained in:
@@ -1,16 +1,108 @@
|
||||
---
|
||||
import BaseLayout from '../layouts/BaseLayout.astro';
|
||||
import Sidebar from '../components/Sidebar.astro';
|
||||
import MainContent from '../components/MainContent.astro';
|
||||
import type { Account, Transaction } from '../types';
|
||||
import { formatCurrency, formatDate } from '../utils';
|
||||
|
||||
// Initialize with empty arrays until API integration
|
||||
const accounts: Account[] = [];
|
||||
const allTransactions: Transaction[] = [];
|
||||
|
||||
// Create an empty initial account
|
||||
const initialAccount: Account = {
|
||||
id: '',
|
||||
name: 'No accounts available',
|
||||
last4: '0000',
|
||||
balance: 0
|
||||
};
|
||||
const initialTransactions: Transaction[] = [];
|
||||
---
|
||||
<BaseLayout title="Bank Transactions Dashboard">
|
||||
<div class="dashboard-layout">
|
||||
<Sidebar accounts={accounts} initialAccount={initialAccount} />
|
||||
<MainContent account={initialAccount} transactions={initialTransactions} />
|
||||
</div>
|
||||
</BaseLayout>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<meta name="generator" content={Astro.generator} />
|
||||
<title>Astro</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Astro</h1>
|
||||
</body>
|
||||
</html>
|
||||
<script define:vars={{ allAccounts: accounts, allTransactions }}>
|
||||
// Client-side script to handle account switching and updating the UI
|
||||
|
||||
// --- DOM Elements ---
|
||||
const accountSelect = document.getElementById('account-select');
|
||||
const currentAccountNameSpan = document.getElementById('current-account-name');
|
||||
const accountBalanceSpan = document.getElementById('account-balance');
|
||||
const transactionTableBody = document.getElementById('transaction-table-body');
|
||||
|
||||
// --- Helper Functions (mirror utils.ts for client-side use) ---
|
||||
function formatCurrency(amount) {
|
||||
return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(amount);
|
||||
}
|
||||
|
||||
function formatDate(dateString) {
|
||||
const date = new Date(dateString + 'T00:00:00'); // Ensure local date
|
||||
return new Intl.DateTimeFormat('en-US', { year: 'numeric', month: 'short', day: 'numeric' }).format(date);
|
||||
}
|
||||
|
||||
// --- Update UI Function ---
|
||||
function updateUIForAccount(accountId) {
|
||||
console.log("Updating UI for account:", accountId); // Debug log
|
||||
|
||||
const selectedAccount = allAccounts.find(acc => acc.id === accountId);
|
||||
const accountTransactions = allTransactions
|
||||
.filter(txn => txn.accountId === accountId)
|
||||
.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()); // Sort desc
|
||||
|
||||
if (!selectedAccount || !transactionTableBody || !currentAccountNameSpan || !accountBalanceSpan) {
|
||||
console.error("Required UI elements not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Update header
|
||||
currentAccountNameSpan.textContent = `${selectedAccount.name} (***${selectedAccount.last4})`;
|
||||
|
||||
// Update summary
|
||||
accountBalanceSpan.textContent = formatCurrency(selectedAccount.balance);
|
||||
|
||||
// Update table
|
||||
transactionTableBody.innerHTML = ''; // Clear existing rows
|
||||
|
||||
if (accountTransactions.length === 0) {
|
||||
transactionTableBody.innerHTML = `<tr><td colspan="4" style="text-align: center; font-style: italic; color: #777;">No transactions found for this account.</td></tr>`;
|
||||
} else {
|
||||
accountTransactions.forEach(txn => {
|
||||
const row = document.createElement('tr');
|
||||
row.setAttribute('data-txn-id', txn.id);
|
||||
row.innerHTML = `
|
||||
<td>${formatDate(txn.date)}</td>
|
||||
<td>${txn.description}</td>
|
||||
<td class="amount-col ${txn.amount >= 0 ? 'amount-positive' : 'amount-negative'}">
|
||||
${formatCurrency(txn.amount)}
|
||||
</td>
|
||||
<td>
|
||||
<button class="action-btn edit-btn" title="Edit transaction (not implemented)">Edit</button>
|
||||
<button class="action-btn delete-btn" title="Delete transaction (not implemented)">Delete</button>
|
||||
</td>
|
||||
`;
|
||||
transactionTableBody.appendChild(row);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// --- Event Listener ---
|
||||
if (accountSelect) {
|
||||
accountSelect.addEventListener('change', (event) => {
|
||||
const selectedAccountId = event.target.value;
|
||||
updateUIForAccount(selectedAccountId);
|
||||
});
|
||||
} else {
|
||||
console.error("Account select element not found");
|
||||
}
|
||||
|
||||
// --- Initial Load (Optional but good practice) ---
|
||||
// The page already renders the initial state server-side,
|
||||
// so no need to call updateUIForAccount() immediately unless
|
||||
// there's a chance the JS loads before initial render completes fully.
|
||||
// console.log("Account switcher script loaded.");
|
||||
|
||||
</script>
|
||||
Reference in New Issue
Block a user