import { TxInfo } from '../api';
import { useState, useCallback } from 'react';
interface HistoryTabProps {
txHistory: TxInfo[];
refreshTxStatus: (txid: string) => Promise<{ txid: string; confirmations: number; status: string }>;
}
function fmtDate(ts: number | null | undefined) {
if (!ts) return '—';
const d = new Date(ts * 1000);
if (isNaN(d.getTime())) return '—';
return d.toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
year: 'numeric',
});
}
function fmtTime(ts: number | null | undefined) {
if (!ts) return '';
const d = new Date(ts * 1000);
if (isNaN(d.getTime())) return '';
return d.toLocaleTimeString('en-US', {
hour: '2-digit',
minute: '2-digit',
});
}
export default function HistoryTab({ txHistory, refreshTxStatus }: HistoryTabProps) {
const [loadingTxid, setLoadingTxid] = useState('');
const [txStatuses, setTxStatuses] = useState<Record<string, { confirmations: number; status: string }>>({});
const handleRefreshTx = useCallback(async (txid: string) => {
setLoadingTxid(txid);
const status = await refreshTxStatus(txid);
setTxStatuses(prev => ({ ...prev, [txid]: { confirmations: status.confirmations, status: status.status } }));
setLoadingTxid('');
}, [refreshTxStatus]);
const getTxStatus = (txid: string) => {
return txStatuses[txid] || null;
};
return (
<div className="tab-content">
<div className="section">
<div className="section-header">
<h3>Transaction History ({txHistory.length})</h3>
</div>
{txHistory.length === 0 ? (
<div className="empty-state">
<div className="empty-state-icon">◷</div>
No transaction history
</div>
) : (
<table className="wallet-table">
<thead>
<tr>
<th>TXID</th>
<th>Date</th>
<th>Amount</th>
<th>Category</th>
<th>Confirmations</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{txHistory.map(tx => {
const status = getTxStatus(tx.txid);
const confs = status ? status.confirmations : tx.confirmations;
return (
<tr key={tx.txid}>
<td className="mono" style={{ fontSize: '12px' }}>
<span
style={{ cursor: 'pointer' }}
onClick={() => { navigator.clipboard.writeText(tx.txid); }}
>
{tx.txid.slice(0, 14)}…{tx.txid.slice(-4)}
</span>
</td>
<td>
<div>{fmtDate(tx.time)}</div>
{fmtTime(tx.time) && (
<div style={{ fontSize: '11px', color: 'var(--text-tertiary)' }}>{fmtTime(tx.time)}</div>
)}
</td>
<td className={`mono ${tx.amount < 0 ? 'text-red' : 'text-green'}`}>
{tx.amount < 0 ? tx.amount.toFixed(8) : `+${tx.amount.toFixed(8)}`}
</td>
<td>
<span className={`badge ${
tx.category === 'receive' ? 'badge-green' :
tx.category === 'send' ? 'badge-red' :
'badge-blue'
}`}>
{tx.category}
</span>
</td>
<td>
<span className={`badge ${confs > 0 ? 'badge-green' : 'badge-yellow'}`}>
{confs > 0 ? `${confs}` : 'unconfirmed'}
</span>
</td>
<td>
<button
className="btn-icon btn-small"
onClick={() => handleRefreshTx(tx.txid)}
disabled={loadingTxid === tx.txid}
title="Refresh status"
style={loadingTxid === tx.txid ? { animation: 'spin 1s linear infinite' } : {}}
>
↻
</button>
</td>
</tr>
);
})}
</tbody>
</table>
)}
</div>
</div>
);
}