aboutsummaryrefslogtreecommitdiff
path: root/client/src/components/BidsPage.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/components/BidsPage.jsx')
-rw-r--r--client/src/components/BidsPage.jsx134
1 files changed, 82 insertions, 52 deletions
diff --git a/client/src/components/BidsPage.jsx b/client/src/components/BidsPage.jsx
index 2b97e99..3e596f0 100644
--- a/client/src/components/BidsPage.jsx
+++ b/client/src/components/BidsPage.jsx
@@ -1,56 +1,75 @@
-import React, { useEffect, useState } from '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';
+import React, { useEffect, useState } from "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 = (bids) => [
{
- title: 'Timestamp',
- dataIndex: 'timestamp',
+ title: "Timestamp",
+ dataIndex: "timestamp",
sorter: (a, b) => new Date(a.timestamp) - new Date(b.timestamp),
render: (val) => new Date(val).toLocaleString(),
width: 180,
},
{
- title: 'Quantity (MW)',
- dataIndex: 'quantity',
+ title: "Quantity (MW)",
+ dataIndex: "quantity",
sorter: (a, b) => a.quantity - b.quantity,
render: (val) => val.toFixed(2),
width: 180,
},
{
- title: 'Price ($/MWh)',
- dataIndex: 'price',
+ title: "Price ($/MWh)",
+ dataIndex: "price",
sorter: (a, b) => a.price - b.price,
render: (val) => `$${val.toFixed(2)}`,
width: 180,
},
{
- title: 'Status',
- dataIndex: 'status',
+ title: "Status",
+ dataIndex: "status",
sorter: (a, b) => a.status.localeCompare(b.status),
filters: [
- { text: 'Submitted', value: 'Submitted' },
- { text: 'Success', value: 'Success' },
- { text: 'Fail', value: 'Fail' },
+ { 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} />
+ <Badge
+ status={
+ val === "Success"
+ ? "success"
+ : val === "Fail"
+ ? "error"
+ : "processing"
+ }
+ text={val}
+ />
),
width: 180,
},
{
- title: 'PnL',
- dataIndex: 'pnl',
+ title: "PnL",
+ dataIndex: "pnl",
sorter: (a, b) => (a.pnl || 0) - (b.pnl || 0),
render: (val) => {
- if (val === null) return 'N/A';
+ if (val === null) return "N/A";
const isProfit = val >= 0;
- const color = isProfit ? 'green' : 'red';
+ const color = isProfit ? "green" : "red";
return (
- <Typography.Text style={{ color, display: 'flex', alignItems: 'center', gap: 4 }}>
+ <Typography.Text
+ style={{ color, display: "flex", alignItems: "center", gap: 4 }}
+ >
{isProfit ? <IconArrowRise /> : <IconArrowFall />}
{val.toFixed(2)}
</Typography.Text>
@@ -59,13 +78,13 @@ const columns = (bids) => [
width: 180,
},
{
- title: 'Market',
- dataIndex: 'market',
+ 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' },
+ { text: "ISONE", value: "ISONE" },
+ { text: "NYISO", value: "NYISO" },
+ { text: "MISO", value: "MISO" },
],
onFilter: (value, record) => record.market === value,
render: (val) => val,
@@ -80,20 +99,30 @@ function BidsPage() {
useEffect(() => {
fetch(`${API_BASE_URL}/bids/`)
.then((res) => {
- if (!res.ok) throw new Error('Failed to fetch bids');
+ if (!res.ok) throw new Error("Failed to fetch bids");
return res.json();
})
.then((json) => setBids(json))
.catch((err) => {
console.error(err);
- Message.error('Failed to load bids.');
+ Message.error("Failed to load bids.");
})
.finally(() => setLoading(false));
}, []);
return (
- <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 }}>
+ <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>
@@ -101,37 +130,38 @@ function BidsPage() {
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
+ 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 ? (
- <div style={{ textAlign: 'center', padding: 80 }}>
+ <div style={{ textAlign: "center", padding: 80 }}>
<Spin />
</div>
) : bids.length === 0 ? (
- <div style={{ textAlign: 'center', padding: 80 }}>
+ <div style={{ textAlign: "center", padding: 80 }}>
<Empty description="No bids found yet." />
</div>
) : (
<div className="responsive-table-wrapper">
- <Table
- columns={columns(bids)}
- data={bids}
- rowKey="id"
- pagination={{
- pageSize: 50,
- sizeCanChange: true,
- showTotal: true,
- }}
- scroll={{ x: true }}
- border
- style={{ transition: 'opacity 0.5s ease-in-out' }}
- rowClassName={() => 'table-row-hover'}
- />
+ <Table
+ columns={columns(bids)}
+ data={bids}
+ rowKey="id"
+ pagination={{
+ pageSize: 50,
+ sizeCanChange: true,
+ showTotal: true,
+ }}
+ scroll={{ x: true }}
+ border
+ style={{ transition: "opacity 0.5s ease-in-out" }}
+ rowClassName={() => "table-row-hover"}
+ />
</div>
)}
</Card>