From 124b97a3974f52c65f9868a34d47d8da3e44c52f Mon Sep 17 00:00:00 2001 From: GitHub Copilot Date: Thu, 24 Apr 2025 16:45:46 -0400 Subject: [PATCH] feat: Enhance AccountSummary and TransactionTable components with refresh functionality and improve loading/empty states --- src/components/AccountSummary.tsx | 8 +- src/components/AddTransactionForm.tsx | 8 +- src/components/TransactionTable.tsx | 119 +++++++++++++++----------- wrangler.jsonc | 6 +- 4 files changed, 82 insertions(+), 59 deletions(-) diff --git a/src/components/AccountSummary.tsx b/src/components/AccountSummary.tsx index 4f5e980..6d16537 100644 --- a/src/components/AccountSummary.tsx +++ b/src/components/AccountSummary.tsx @@ -2,7 +2,10 @@ import React, { useState, useEffect } from "react"; import { useStore } from "@nanostores/react"; import type { Account } from "../types"; import { formatCurrency } from "../utils"; -import { currentAccountId as currentAccountIdStore } from "../stores/transactionStore"; +import { + currentAccountId as currentAccountIdStore, + refreshKey, +} from "../stores/transactionStore"; interface AccountSummaryProps { // No props needed, data comes from store and fetch @@ -10,6 +13,7 @@ interface AccountSummaryProps { export default function AccountSummary({}: AccountSummaryProps) { const currentAccountId = useStore(currentAccountIdStore); + const refreshCounter = useStore(refreshKey); const [account, setAccount] = useState(null); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); @@ -43,7 +47,7 @@ export default function AccountSummary({}: AccountSummaryProps) { }; fetchDetails(); - }, [currentAccountId]); + }, [currentAccountId, refreshCounter]); // Determine content based on state let balanceContent: React.ReactNode; diff --git a/src/components/AddTransactionForm.tsx b/src/components/AddTransactionForm.tsx index 87c83d7..34ed03e 100644 --- a/src/components/AddTransactionForm.tsx +++ b/src/components/AddTransactionForm.tsx @@ -45,10 +45,10 @@ export default function AddTransactionForm({}: AddTransactionFormProps) { const dateObj = new Date(transactionToEdit.date); // Check if date is valid before formatting if (!isNaN(dateObj.getTime())) { - // Adjust for timezone offset to prevent date shifting - const timezoneOffset = dateObj.getTimezoneOffset() * 60000; //offset in milliseconds - const adjustedDate = new Date(dateObj.getTime() - timezoneOffset); - setDate(adjustedDate.toISOString().split("T")[0]); + // Directly format the date object (usually interpreted as UTC midnight) + // into the YYYY-MM-DD format required by the input. + // No timezone adjustment needed here. + setDate(dateObj.toISOString().split("T")[0]); } else { console.warn( "Invalid date received for editing:", diff --git a/src/components/TransactionTable.tsx b/src/components/TransactionTable.tsx index 9d8830e..d4dc935 100644 --- a/src/components/TransactionTable.tsx +++ b/src/components/TransactionTable.tsx @@ -6,12 +6,14 @@ import { startEditingTransaction, currentAccountId as currentAccountIdStore, triggerRefresh, + refreshKey, } from "../stores/transactionStore"; interface TransactionTableProps {} export default function TransactionTable({}: TransactionTableProps) { const currentAccountId = useStore(currentAccountIdStore); + const refreshCounter = useStore(refreshKey); const [transactions, setTransactions] = useState([]); const [isLoading, setIsLoading] = useState(false); @@ -46,7 +48,7 @@ export default function TransactionTable({}: TransactionTableProps) { }; fetchTransactions(); - }, [currentAccountId]); + }, [currentAccountId, refreshCounter]); const sortedTransactions = [...transactions].sort( (a, b) => new Date(b.date).getTime() - new Date(a.date).getTime() @@ -109,6 +111,63 @@ export default function TransactionTable({}: TransactionTableProps) { } }; + // Helper function to render loading state + const renderLoading = () => ( + + + Loading transactions... + + + ); + + // Helper function to render empty state + const renderEmpty = () => ( + + + No transactions found for this account. + + + ); + + // Helper function to render transaction rows + const renderRows = () => + sortedTransactions.map((txn) => ( + + {formatDate(txn.date)} + {txn.description} + = 0 ? "amount-positive" : "amount-negative" + }`} + > + {formatCurrency(txn.amount)} + + + + + + + )); + return (
{error && ( @@ -126,57 +185,13 @@ export default function TransactionTable({}: TransactionTableProps) { - {isLoading ? ( - - - Loading transactions... - - - ) : sortedTransactions.length === 0 && !error ? ( - - - No transactions found for this account. - - - ) : ( - !error && - sortedTransactions.map((txn) => ( - - {formatDate(txn.date)} - {txn.description} - = 0 ? "amount-positive" : "amount-negative" - }`} - > - {formatCurrency(txn.amount)} - - - - - - - )) - )} + {isLoading + ? renderLoading() + : error + ? null // Error message is shown above the table + : sortedTransactions.length === 0 + ? renderEmpty() + : renderRows()}
diff --git a/wrangler.jsonc b/wrangler.jsonc index 0db6970..295f1eb 100644 --- a/wrangler.jsonc +++ b/wrangler.jsonc @@ -1,7 +1,11 @@ { "$schema": "node_modules/wrangler/config-schema.json", "name": "finance", - // Update to today's date + "observability": { + "logs": { + "enabled": true + } + }, "compatibility_date": "2025-04-24", "assets": { "directory": "./dist"