From b76a24edba09b374d39e96616cd53324e9198e35 Mon Sep 17 00:00:00 2001 From: GitHub Copilot Date: Thu, 24 Apr 2025 08:19:41 -0400 Subject: [PATCH] #1 Enhance transaction management UI with form validation, loading states, and improved error handling --- src/components/AddTransactionForm.astro | 260 ++++++++++++++++++++-- src/components/TransactionTable.astro | 8 +- src/pages/api/transactions/[id]/index.ts | 22 +- src/pages/index.astro | 261 ++++++++++++++++++----- src/styles/global.css | 45 ++++ 5 files changed, 514 insertions(+), 82 deletions(-) diff --git a/src/components/AddTransactionForm.astro b/src/components/AddTransactionForm.astro index 64123be..5c4c25f 100644 --- a/src/components/AddTransactionForm.astro +++ b/src/components/AddTransactionForm.astro @@ -1,51 +1,281 @@ --- -// This component needs client-side JS for the toggle +// This component handles both creating and editing transactions ---
- -
- \ No newline at end of file diff --git a/src/components/TransactionTable.astro b/src/components/TransactionTable.astro index f62b66b..98b7589 100644 --- a/src/components/TransactionTable.astro +++ b/src/components/TransactionTable.astro @@ -11,9 +11,9 @@ 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()); --- -
+
- + @@ -30,8 +30,8 @@ const sortedTransactions = [...transactions].sort((a, b) => new Date(b.date).get {formatCurrency(txn.amount)} ))} diff --git a/src/pages/api/transactions/[id]/index.ts b/src/pages/api/transactions/[id]/index.ts index 8efd606..dc9665b 100644 --- a/src/pages/api/transactions/[id]/index.ts +++ b/src/pages/api/transactions/[id]/index.ts @@ -6,10 +6,13 @@ export const PUT: APIRoute = async ({ request, params }) => { const { id } = params; if (!id) { - return new Response(JSON.stringify({ error: "Transaction ID is required" }), { - status: 400, - headers: { "Content-Type": "application/json" }, - }); + return new Response( + JSON.stringify({ error: "Transaction ID is required" }), + { + status: 400, + headers: { "Content-Type": "application/json" }, + } + ); } try { @@ -65,10 +68,13 @@ export const DELETE: APIRoute = async ({ params }) => { const { id } = params; if (!id) { - return new Response(JSON.stringify({ error: "Transaction ID is required" }), { - status: 400, - headers: { "Content-Type": "application/json" }, - }); + return new Response( + JSON.stringify({ error: "Transaction ID is required" }), + { + status: 400, + headers: { "Content-Type": "application/json" }, + } + ); } const transactionIndex = transactions.findIndex((t) => t.id === id); diff --git a/src/pages/index.astro b/src/pages/index.astro index dcf9acd..10b6aac 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -16,93 +16,244 @@ const initialAccount: Account = accounts[0] || { last4: '0000', balance: 0 }; -const initialTransactions: Transaction[] = []; + +// Fetch initial transactions if we have an account +let initialTransactions: Transaction[] = []; +if (initialAccount.id) { + const transactionsResponse = await fetch(`http://localhost:4321/api/accounts/${initialAccount.id}/transactions`); + initialTransactions = await transactionsResponse.json(); +} --- -
- - -
+
+ + +
- \ No newline at end of file diff --git a/src/styles/global.css b/src/styles/global.css index 80a8eef..08e85f1 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -232,3 +232,48 @@ tbody tr:hover { padding: 20px; } } + +/* Loading States */ +.loading { + opacity: 0.6; + pointer-events: none; + position: relative; +} + +.loading::after { + content: ""; + position: absolute; + top: 50%; + left: 50%; + width: 1.5em; + height: 1.5em; + margin: -0.75em 0 0 -0.75em; + border: 3px solid rgba(0, 123, 255, 0.2); + border-top-color: #007bff; + border-radius: 50%; + animation: spinner 0.6s linear infinite; +} + +@keyframes spinner { + to { + transform: rotate(360deg); + } +} + +.form-submit-btn { + position: relative; + min-width: 100px; +} + +.form-submit-btn.loading { + padding-right: 35px; +} + +.form-submit-btn.loading::after { + width: 1em; + height: 1em; + margin: -0.5em 0 0 0; + left: auto; + right: 10px; + border-width: 2px; +}
Date Description - - + +