diff options
Diffstat (limited to 'client/src/components/SubmitBidPage.jsx')
-rw-r--r-- | client/src/components/SubmitBidPage.jsx | 136 |
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> |