mirror of
https://github.com/Zproger/Aurum.git
synced 2026-10-13 02:56:39 +07:00
feat: click a coin row to view its trade history; edit transactions
Matches CoinMarketCap's flow: clicking anywhere on a coin's row in the
holdings table opens its transaction history (previously only a dedicated
icon button did). The table's own History icon is gone since the row now
does that job; the remaining "+"/delete icons get stopPropagation so they
don't also trigger the row click.
Adds the missing piece: transactions could be viewed and deleted but not
edited. New PATCH /crypto/transactions/{id} (partial update, never calls
CoinGecko, same oversell guard as creating a sell) backs a pencil button on
each history row that opens CryptoTransactionModal pre-filled — the same
dialog used for "+", now doing double duty as create/edit.
86/86 backend tests passing (4 new). Verified live against the real API:
create, edit quantity/note, 404 on unknown id, cleanup — real user data
untouched throughout.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01855PiW5Wd8n4aRW4n9kByY
This commit is contained in:
@@ -11,7 +11,7 @@ import { CryptoTransactionModal } from "@/components/crypto/CryptoTransactionMod
|
||||
import { useCryptoHistory, useCryptoHoldings, useDeleteCryptoHolding, useRefreshCryptoPrices } from "@/hooks/useCrypto";
|
||||
import { getIntlLocale } from "@/lib/format";
|
||||
import { useTranslation } from "@/lib/i18n";
|
||||
import type { CryptoHolding, CryptoRange } from "@/types";
|
||||
import type { CryptoHolding, CryptoRange, CryptoTransaction } from "@/types";
|
||||
|
||||
function formatSyncedAt(iso: string): string {
|
||||
return new Intl.DateTimeFormat(getIntlLocale(), { dateStyle: "medium", timeStyle: "short" }).format(new Date(iso));
|
||||
@@ -33,6 +33,11 @@ export function CryptoPage() {
|
||||
const [addOpen, setAddOpen] = useState(false);
|
||||
const [tradingHolding, setTradingHolding] = useState<CryptoHolding | null>(null);
|
||||
const [historyHolding, setHistoryHolding] = useState<CryptoHolding | null>(null);
|
||||
// Set together with tradingHolding when editing an entry from the history
|
||||
// list — CryptoTransactionModal is the same dialog for both "+" (new
|
||||
// trade, transaction stays null) and this (pre-filled, PATCHes instead of
|
||||
// POSTing). Cleared whenever that dialog closes, same as tradingHolding.
|
||||
const [editingTransaction, setEditingTransaction] = useState<CryptoTransaction | null>(null);
|
||||
|
||||
const holdings = data?.holdings ?? [];
|
||||
const totalValue = holdings.reduce((sum, holding) => sum + (holding.value !== null ? Number(holding.value) : 0), 0);
|
||||
@@ -43,6 +48,22 @@ export function CryptoPage() {
|
||||
}
|
||||
}
|
||||
|
||||
function handleEditTransaction(transaction: CryptoTransaction) {
|
||||
setEditingTransaction(transaction);
|
||||
setTradingHolding(historyHolding);
|
||||
setHistoryHolding(null);
|
||||
}
|
||||
|
||||
function closeTradeModal() {
|
||||
setTradingHolding(null);
|
||||
setEditingTransaction(null);
|
||||
}
|
||||
|
||||
function openTradeModal(holding: CryptoHolding) {
|
||||
setEditingTransaction(null);
|
||||
setTradingHolding(holding);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-5">
|
||||
<CryptoOverviewCard
|
||||
@@ -89,7 +110,7 @@ export function CryptoPage() {
|
||||
<CryptoHoldingsTable
|
||||
items={holdings}
|
||||
hidden={hidden}
|
||||
onTrade={setTradingHolding}
|
||||
onTrade={openTradeModal}
|
||||
onViewHistory={setHistoryHolding}
|
||||
onDelete={handleDelete}
|
||||
/>
|
||||
@@ -99,12 +120,18 @@ export function CryptoPage() {
|
||||
</Card>
|
||||
|
||||
<CryptoAddModal open={addOpen} onClose={() => setAddOpen(false)} />
|
||||
<CryptoTransactionModal open={tradingHolding !== null} onClose={() => setTradingHolding(null)} holding={tradingHolding} />
|
||||
<CryptoTransactionModal
|
||||
open={tradingHolding !== null}
|
||||
onClose={closeTradeModal}
|
||||
holding={tradingHolding}
|
||||
transaction={editingTransaction}
|
||||
/>
|
||||
<CryptoTransactionHistoryModal
|
||||
open={historyHolding !== null}
|
||||
onClose={() => setHistoryHolding(null)}
|
||||
holding={historyHolding}
|
||||
hidden={hidden}
|
||||
onEdit={handleEditTransaction}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user