aboutsummaryrefslogtreecommitdiff
path: root/client/src/BidsPage.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/BidsPage.jsx')
-rw-r--r--client/src/BidsPage.jsx99
1 files changed, 80 insertions, 19 deletions
diff --git a/client/src/BidsPage.jsx b/client/src/BidsPage.jsx
index 3a40f41..fad3989 100644
--- a/client/src/BidsPage.jsx
+++ b/client/src/BidsPage.jsx
@@ -1,49 +1,70 @@
import React, { useEffect, useState } from 'react';
-import { Table, Typography, Spin, Message, Card } from '@arco-design/web-react';
+import { Table, Typography, Spin, Message, Card, Empty, Badge } from '@arco-design/web-react';
+import { IconArrowRise, IconArrowFall } from '@arco-design/web-react/icon';
import '@arco-design/web-react/dist/css/arco.css';
import API_BASE_URL from './config';
-const columns = [
+const columns = (bids) => [
{
title: 'Timestamp',
dataIndex: 'timestamp',
+ sorter: (a, b) => new Date(a.timestamp) - new Date(b.timestamp),
render: (val) => new Date(val).toLocaleString(),
},
{
title: 'Quantity (MW)',
dataIndex: 'quantity',
+ sorter: (a, b) => a.quantity - b.quantity,
render: (val) => val.toFixed(2),
},
{
title: 'Price ($/MWh)',
dataIndex: 'price',
+ sorter: (a, b) => a.price - b.price,
render: (val) => `$${val.toFixed(2)}`,
},
{
title: 'Status',
dataIndex: 'status',
- render: (val) => {
- let color = 'gray';
- if (val === 'Success') color = 'green';
- else if (val === 'Fail') color = 'red';
- else if (val === 'Submitted') color = 'blue';
- return <Typography.Text style={{ color }}>{val}</Typography.Text>;
- }
+ sorter: (a, b) => a.status.localeCompare(b.status),
+ filters: [
+ { text: 'Submitted', value: 'Submitted' },
+ { text: 'Success', value: 'Success' },
+ { text: 'Fail', value: 'Fail' },
+ ],
+ onFilter: (value, record) => record.status === value,
+ render: (val) => (
+ <Badge status={val === 'Success' ? 'success' : val === 'Fail' ? 'error' : 'processing'} text={val} />
+ ),
},
{
title: 'PnL',
dataIndex: 'pnl',
+ sorter: (a, b) => (a.pnl || 0) - (b.pnl || 0),
render: (val) => {
if (val === null) return 'N/A';
- const color = val >= 0 ? 'green' : 'red';
- return <Typography.Text style={{ color }}>{val.toFixed(2)}</Typography.Text>;
- }
+ const isProfit = val >= 0;
+ const color = isProfit ? 'green' : 'red';
+ return (
+ <Typography.Text style={{ color, display: 'flex', alignItems: 'center', gap: 4 }}>
+ {isProfit ? <IconArrowRise /> : <IconArrowFall />}
+ {val.toFixed(2)}
+ </Typography.Text>
+ );
+ },
},
{
title: 'Market',
dataIndex: 'market',
+ sorter: (a, b) => a.market.localeCompare(b.market),
+ filters: [
+ { text: 'ISONE', value: 'ISONE' },
+ { text: 'NYISO', value: 'NYISO' },
+ { text: 'MISO', value: 'MISO' },
+ ],
+ onFilter: (value, record) => record.market === value,
render: (val) => val,
- }
+ },
];
function BidsPage() {
@@ -65,24 +86,64 @@ function BidsPage() {
}, []);
return (
- <div style={{ padding: 20, backgroundColor: 'var(--color-fill-2)' }}>
- <Typography.Title heading={4}>Your Submitted Bids</Typography.Title>
- <Card style={{ marginTop: 16 }}>
+ <div style={{ padding: 20, backgroundColor: 'var(--color-fill-2)', minHeight: 'calc(100vh - 150px)', animation: 'fadeSlideIn 0.6s ease' }}>
+ <Typography.Title heading={3} style={{ textAlign: 'center', marginBottom: 20 }}>
+ Your Submitted Bids
+ </Typography.Title>
+
+ <Card
+ style={{
+ marginTop: 16,
+ borderRadius: 16,
+ boxShadow: '0 8px 24px rgba(0,0,0,0.08)',
+ background: 'linear-gradient(135deg, rgba(255,255,255,0.95) 0%, rgba(245,245,245,0.95) 100%)',
+ backdropFilter: 'blur(8px)',
+ overflow: 'hidden',
+ padding: 20
+ }}
+ >
{loading ? (
- <Spin />
+ <div style={{ textAlign: 'center', padding: 80 }}>
+ <Spin />
+ </div>
+ ) : bids.length === 0 ? (
+ <div style={{ textAlign: 'center', padding: 80 }}>
+ <Empty description="No bids found yet." />
+ </div>
) : (
<Table
- columns={columns}
+ columns={columns(bids)}
data={bids}
rowKey="id"
pagination={{
- pageSize: 10,
+ pageSize: 50,
sizeCanChange: true,
showTotal: true,
}}
+ scroll={{ x: true }}
+ border
+ style={{ transition: 'opacity 0.5s ease-in-out' }}
+ rowClassName={() => 'table-row-hover'}
/>
)}
</Card>
+
+ <style>{`
+ @keyframes fadeSlideIn {
+ 0% {
+ opacity: 0;
+ transform: translateY(20px);
+ }
+ 100% {
+ opacity: 1;
+ transform: translateY(0);
+ }
+ }
+ .table-row-hover:hover {
+ background-color: var(--color-fill-3);
+ transition: background-color 0.3s ease;
+ }
+ `}</style>
</div>
);
}