fix: positions totals row aligned with DataTable columns, restore $ prefix
This commit is contained in:
@@ -17,6 +17,7 @@ interface Props<T> {
|
|||||||
onRowClick?: (row: T) => void;
|
onRowClick?: (row: T) => void;
|
||||||
filterFn?: (row: T, query: string) => boolean;
|
filterFn?: (row: T, query: string) => boolean;
|
||||||
emptyMessage?: string;
|
emptyMessage?: string;
|
||||||
|
footerRow?: ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function DataTable<T extends object>({
|
export function DataTable<T extends object>({
|
||||||
@@ -27,6 +28,7 @@ export function DataTable<T extends object>({
|
|||||||
onRowClick,
|
onRowClick,
|
||||||
filterFn,
|
filterFn,
|
||||||
emptyMessage = 'No data',
|
emptyMessage = 'No data',
|
||||||
|
footerRow,
|
||||||
}: Props<T>) {
|
}: Props<T>) {
|
||||||
const [sortKey, setSortKey] = useState<string | null>(null);
|
const [sortKey, setSortKey] = useState<string | null>(null);
|
||||||
const [sortDir, setSortDir] = useState<'asc' | 'desc'>('asc');
|
const [sortDir, setSortDir] = useState<'asc' | 'desc'>('asc');
|
||||||
@@ -122,6 +124,11 @@ export function DataTable<T extends object>({
|
|||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
{footerRow && (
|
||||||
|
<tfoot className="border-t border-surface-700 bg-surface-900">
|
||||||
|
{footerRow}
|
||||||
|
</tfoot>
|
||||||
|
)}
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,18 @@ export function PositionsPage() {
|
|||||||
{ quantity: 0, unrealized_pnl: 0, realized_pnl: 0, market_value: 0, cost_basis: 0 },
|
{ quantity: 0, unrealized_pnl: 0, realized_pnl: 0, market_value: 0, cost_basis: 0 },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const footer = positions.length > 0 ? (
|
||||||
|
<tr className="font-semibold text-gray-200">
|
||||||
|
<td className="px-3 py-2">Totals</td>
|
||||||
|
<td className="px-3 py-2">{totals.quantity}</td>
|
||||||
|
<td className="px-3 py-2">{fmtUsd(totals.cost_basis)}</td>
|
||||||
|
<td className="px-3 py-2">{fmtUsd(totals.market_value)}</td>
|
||||||
|
<td className={`px-3 py-2 ${pnlColor(totals.unrealized_pnl)}`}>{fmtUsd(totals.unrealized_pnl)}</td>
|
||||||
|
<td className={`px-3 py-2 ${pnlColor(totals.realized_pnl)}`}>{fmtUsd(totals.realized_pnl)}</td>
|
||||||
|
<td className="px-3 py-2" />
|
||||||
|
</tr>
|
||||||
|
) : undefined;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h1 className="mb-4 text-xl font-semibold text-gray-100">Positions</h1>
|
<h1 className="mb-4 text-xl font-semibold text-gray-100">Positions</h1>
|
||||||
@@ -48,24 +60,8 @@ export function PositionsPage() {
|
|||||||
data={positions}
|
data={positions}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
keyField="id"
|
keyField="id"
|
||||||
|
footerRow={footer}
|
||||||
/>
|
/>
|
||||||
{positions.length > 0 && (
|
|
||||||
<div className="mt-px overflow-x-auto rounded-b-lg border border-t-0 border-surface-700 bg-surface-900">
|
|
||||||
<table className="w-full text-sm">
|
|
||||||
<tfoot>
|
|
||||||
<tr className="font-semibold text-gray-200">
|
|
||||||
<td className="px-3 py-2">Totals</td>
|
|
||||||
<td className="px-3 py-2">{totals.quantity}</td>
|
|
||||||
<td className="px-3 py-2">{fmtUsd(totals.cost_basis)}</td>
|
|
||||||
<td className="px-3 py-2">{fmtUsd(totals.market_value)}</td>
|
|
||||||
<td className={`px-3 py-2 ${pnlColor(totals.unrealized_pnl)}`}>{fmtUsd(totals.unrealized_pnl)}</td>
|
|
||||||
<td className={`px-3 py-2 ${pnlColor(totals.realized_pnl)}`}>{fmtUsd(totals.realized_pnl)}</td>
|
|
||||||
<td className="px-3 py-2" />
|
|
||||||
</tr>
|
|
||||||
</tfoot>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user