mirror of
https://github.com/acedanger/finance.git
synced 2025-12-06 07:00:13 -08:00
Initial commit - Basic bank transactions dashboard structure with Astro and TypeScript
This commit is contained in:
14
src/components/AccountSummary.astro
Normal file
14
src/components/AccountSummary.astro
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
import { formatCurrency } from '../utils'; // We'll create this util
|
||||
import type { Account } from '../types';
|
||||
|
||||
interface Props {
|
||||
account: Account;
|
||||
}
|
||||
const { account } = Astro.props;
|
||||
---
|
||||
<div class="account-summary">
|
||||
<h4>Account Summary</h4>
|
||||
<p>Balance: <span id="account-balance">{formatCurrency(account.balance)}</span></p>
|
||||
<!-- Add more summary info if needed -->
|
||||
</div>
|
||||
51
src/components/AddTransactionForm.astro
Normal file
51
src/components/AddTransactionForm.astro
Normal file
@@ -0,0 +1,51 @@
|
||||
---
|
||||
// This component needs client-side JS for the toggle
|
||||
---
|
||||
<section class="add-transaction-section">
|
||||
<button
|
||||
id="toggle-form-btn"
|
||||
class="toggle-form-btn"
|
||||
aria-expanded="false"
|
||||
aria-controls="add-transaction-form"
|
||||
>
|
||||
Add Transaction +
|
||||
</button>
|
||||
<form id="add-transaction-form" class="collapsible-form collapsed">
|
||||
<h4>New Transaction</h4>
|
||||
<div class="form-group">
|
||||
<label for="txn-date">Date</label>
|
||||
<input type="date" id="txn-date" name="date" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="txn-description">Description</label>
|
||||
<input type="text" id="txn-description" name="description" required placeholder="e.g. Groceries">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="txn-amount">Amount</label>
|
||||
<input type="number" id="txn-amount" name="amount" step="0.01" required placeholder="e.g. -25.50 or 1200.00">
|
||||
</div>
|
||||
<!-- In a real app, prevent default and use JS to submit -->
|
||||
<button type="submit">Save</button>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
// Script to handle the collapsible form toggle
|
||||
const toggleBtn = document.getElementById('toggle-form-btn');
|
||||
const form = document.getElementById('add-transaction-form');
|
||||
|
||||
if (toggleBtn && form) {
|
||||
toggleBtn.addEventListener('click', () => {
|
||||
const isExpanded = toggleBtn.getAttribute('aria-expanded') === 'true';
|
||||
toggleBtn.setAttribute('aria-expanded', String(!isExpanded));
|
||||
form.classList.toggle('collapsed');
|
||||
toggleBtn.textContent = isExpanded ? 'Add Transaction +' : 'Hide Form -';
|
||||
// Optional: Focus first input when opening
|
||||
if (!isExpanded) {
|
||||
form.querySelector('input')?.focus();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.error("Toggle button or form not found");
|
||||
}
|
||||
</script>
|
||||
17
src/components/MainContent.astro
Normal file
17
src/components/MainContent.astro
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
import TransactionTable from './TransactionTable.astro';
|
||||
import type { Account, Transaction } from '../types';
|
||||
|
||||
interface Props {
|
||||
account: Account;
|
||||
transactions: Transaction[];
|
||||
}
|
||||
|
||||
const { account, transactions } = Astro.props;
|
||||
---
|
||||
<main class="main-content">
|
||||
<header class="main-header">
|
||||
<h1>Transactions for <span id="current-account-name">{account.name} (***{account.last4})</span></h1>
|
||||
</header>
|
||||
<TransactionTable transactions={transactions} client:load /> {/* Make table updatable */}
|
||||
</main>
|
||||
31
src/components/Sidebar.astro
Normal file
31
src/components/Sidebar.astro
Normal file
@@ -0,0 +1,31 @@
|
||||
---
|
||||
import AddTransactionForm from './AddTransactionForm.astro';
|
||||
import AccountSummary from './AccountSummary.astro';
|
||||
import type { Account } from '../types'; // We'll define this type
|
||||
|
||||
interface Props {
|
||||
accounts: Account[];
|
||||
initialAccount: Account; // Pass the initially selected account
|
||||
}
|
||||
|
||||
const { accounts, initialAccount } = Astro.props;
|
||||
---
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<h2>My Bank</h2>
|
||||
</div>
|
||||
<nav class="account-nav">
|
||||
<h3>Accounts</h3>
|
||||
<select id="account-select" name="account">
|
||||
{accounts.map(account => (
|
||||
<option value={account.id} selected={account.id === initialAccount.id}>
|
||||
{account.name} (***{account.last4})
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</nav>
|
||||
|
||||
<AddTransactionForm client:load /> {/* Make form toggle interactive */}
|
||||
|
||||
<AccountSummary account={initialAccount} client:load /> {/* Make summary updatable */}
|
||||
</aside>
|
||||
45
src/components/TransactionTable.astro
Normal file
45
src/components/TransactionTable.astro
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
import { formatCurrency, formatDate } from '../utils';
|
||||
import type { Transaction } from '../types';
|
||||
|
||||
interface Props {
|
||||
transactions: Transaction[];
|
||||
}
|
||||
|
||||
const { transactions } = Astro.props;
|
||||
|
||||
// Sort transactions by date descending for display
|
||||
const sortedTransactions = [...transactions].sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
|
||||
---
|
||||
<section class="transaction-list">
|
||||
<table id="transaction-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Description</th>
|
||||
<th class="amount-col">Amount</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="transaction-table-body">
|
||||
{sortedTransactions.map(txn => (
|
||||
<tr data-txn-id={txn.id}>
|
||||
<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>
|
||||
</tr>
|
||||
))}
|
||||
{sortedTransactions.length === 0 && (
|
||||
<tr>
|
||||
<td colspan="4" style="text-align: center; font-style: italic; color: #777;">No transactions found for this account.</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
Reference in New Issue
Block a user