aboutsummaryrefslogtreecommitdiff
path: root/client/src/components/SubmitBidPage.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/components/SubmitBidPage.jsx')
-rw-r--r--client/src/components/SubmitBidPage.jsx136
1 files changed, 87 insertions, 49 deletions
diff --git a/client/src/components/SubmitBidPage.jsx b/client/src/components/SubmitBidPage.jsx
index bed92be..5d1e642 100644
--- a/client/src/components/SubmitBidPage.jsx
+++ b/client/src/components/SubmitBidPage.jsx
@@ -1,35 +1,43 @@
-import React, { useState, useEffect, useContext } from 'react';
-import { Form, InputNumber, DatePicker, Button, Message, Typography, Card } from '@arco-design/web-react';
-import '@arco-design/web-react/dist/css/arco.css';
-import dayjs from 'dayjs';
-import utc from 'dayjs/plugin/utc';
-import timezone from 'dayjs/plugin/timezone';
-import API_BASE_URL from '../config';
-import { MarketContext, MARKET_FULL_NAMES } from '../App';
+import React, { useState, useEffect, useContext } from "react";
+import {
+ Form,
+ InputNumber,
+ DatePicker,
+ Button,
+ Message,
+ Typography,
+ Card,
+} from "@arco-design/web-react";
+import "@arco-design/web-react/dist/css/arco.css";
+import dayjs from "dayjs";
+import utc from "dayjs/plugin/utc";
+import timezone from "dayjs/plugin/timezone";
+import API_BASE_URL from "../config";
+import { MarketContext, MARKET_FULL_NAMES } from "../App";
dayjs.extend(utc);
dayjs.extend(timezone);
const MARKET_TIMEZONES = {
- ISONE: 'America/New_York',
- NYISO: 'America/New_York',
- MISO: 'America/Chicago'
+ ISONE: "America/New_York",
+ NYISO: "America/New_York",
+ MISO: "America/Chicago",
};
function SubmitBidPage() {
const { selectedMarket } = useContext(MarketContext);
const [form] = Form.useForm();
const [loading, setLoading] = useState(false);
- const [localNow, setLocalNow] = useState('');
- const [marketNow, setMarketNow] = useState('');
+ const [localNow, setLocalNow] = useState("");
+ const [marketNow, setMarketNow] = useState("");
useEffect(() => {
const updateTime = () => {
const now = dayjs();
- const localFormatted = now.format('dddd, MMMM D, h:mm A');
- const marketTz = MARKET_TIMEZONES[selectedMarket] || 'America/New_York';
+ const localFormatted = now.format("dddd, MMMM D, h:mm A");
+ const marketTz = MARKET_TIMEZONES[selectedMarket] || "America/New_York";
const marketTime = now.tz(marketTz);
- const marketFormatted = marketTime.format('dddd, MMMM D, h:mm A');
+ const marketFormatted = marketTime.format("dddd, MMMM D, h:mm A");
setLocalNow(localFormatted);
setMarketNow(marketFormatted);
};
@@ -45,7 +53,7 @@ function SubmitBidPage() {
const picked = dayjs(values.timestamp);
const adjusted = picked.minute(0).second(0).millisecond(0);
- const marketTz = MARKET_TIMEZONES[selectedMarket] || 'America/New_York';
+ const marketTz = MARKET_TIMEZONES[selectedMarket] || "America/New_York";
const timestampInMarketTz = adjusted.tz(marketTz).format();
const payload = {
@@ -53,33 +61,43 @@ function SubmitBidPage() {
quantity: values.quantity,
price: values.price,
market: selectedMarket,
- user_id: 1
+ user_id: 1,
};
const res = await fetch(`${API_BASE_URL}/bids/`, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify(payload)
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify(payload),
});
if (!res.ok) {
const error = await res.json();
- throw new Error(error.detail || 'Failed to submit bid');
+ throw new Error(error.detail || "Failed to submit bid");
}
- Message.success('Bid submitted successfully!');
+ Message.success("Bid submitted successfully!");
form.resetFields();
} catch (err) {
console.error(err);
- Message.error(err.message || 'Submission failed');
+ Message.error(err.message || "Submission failed");
} 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 }}
+ >
Submit New Bid
</Typography.Title>
@@ -87,19 +105,29 @@ function SubmitBidPage() {
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: 32
+ 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: 32,
}}
>
- <div style={{ marginBottom: 32, padding: 16, border: '1px solid var(--color-border)', borderRadius: 8, background: 'var(--color-fill-1)' }}>
+ <div
+ style={{
+ marginBottom: 32,
+ padding: 16,
+ border: "1px solid var(--color-border)",
+ borderRadius: 8,
+ background: "var(--color-fill-1)",
+ }}
+ >
<Typography.Paragraph style={{ marginBottom: 8 }}>
<strong>Current Local Time:</strong> {localNow}
</Typography.Paragraph>
<Typography.Paragraph>
- <strong>Current {MARKET_FULL_NAMES[selectedMarket]} Time:</strong> {marketNow}
+ <strong>Current {MARKET_FULL_NAMES[selectedMarket]} Time:</strong>{" "}
+ {marketNow}
</Typography.Paragraph>
</div>
@@ -108,21 +136,24 @@ function SubmitBidPage() {
layout="vertical"
onSubmit={handleSubmit}
initialValues={{ quantity: 0, price: 0 }}
- style={{ maxWidth: 600, margin: '0 auto' }}
+ style={{ maxWidth: 600, margin: "0 auto" }}
>
<Form.Item
label="Bid Date and Hour"
field="timestamp"
- rules={[{ required: true, message: 'Please select bid date and hour' }]}
+ rules={[
+ { required: true, message: "Please select bid date and hour" },
+ ]}
>
<DatePicker
showTime={{
- format: 'h A',
+ format: "h A",
defaultValue: dayjs().hour(0).minute(0),
- disabledMinutes: () => Array.from({ length: 60 }, (_, i) => i !== 0),
- step: { minute: 60 }
+ disabledMinutes: () =>
+ Array.from({ length: 60 }, (_, i) => i !== 0),
+ step: { minute: 60 },
}}
- style={{ width: '100%' }}
+ style={{ width: "100%" }}
format="YYYY-MM-DD HH:00"
placeholder="Select date and hour"
timezone={MARKET_TIMEZONES[selectedMarket]}
@@ -133,22 +164,25 @@ function SubmitBidPage() {
label="Quantity (MW)"
field="quantity"
rules={[
- { required: true, message: 'Please enter quantity' },
- { type: 'number', min: 0.01, message: 'Quantity must be > 0' }
+ { required: true, message: "Please enter quantity" },
+ { type: "number", min: 0.01, message: "Quantity must be > 0" },
]}
>
- <InputNumber style={{ width: '100%' }} placeholder="Enter quantity" />
+ <InputNumber
+ style={{ width: "100%" }}
+ placeholder="Enter quantity"
+ />
</Form.Item>
<Form.Item
label="Price ($/MWh)"
field="price"
rules={[
- { required: true, message: 'Please enter price' },
- { type: 'number', min: 0, message: 'Price must be >= 0' }
+ { required: true, message: "Please enter price" },
+ { type: "number", min: 0, message: "Price must be >= 0" },
]}
>
- <InputNumber style={{ width: '100%' }} placeholder="Enter price" />
+ <InputNumber style={{ width: "100%" }} placeholder="Enter price" />
</Form.Item>
<Form.Item>
@@ -157,11 +191,15 @@ function SubmitBidPage() {
htmlType="submit"
loading={loading}
style={{
- width: '100%',
- transition: 'transform 0.2s ease',
+ width: "100%",
+ transition: "transform 0.2s ease",
}}
- onMouseEnter={(e) => (e.currentTarget.style.transform = 'scale(1.02)')}
- onMouseLeave={(e) => (e.currentTarget.style.transform = 'scale(1)')}
+ onMouseEnter={(e) =>
+ (e.currentTarget.style.transform = "scale(1.02)")
+ }
+ onMouseLeave={(e) =>
+ (e.currentTarget.style.transform = "scale(1)")
+ }
>
Submit Bid
</Button>