From 2bc0555caa595967a28593aec2abd52500c5ddf9 Mon Sep 17 00:00:00 2001
From: Navan Chauhan <navanchauhan@gmail.com>
Date: Sun, 27 Apr 2025 20:44:14 -0600
Subject: switch markets for market data

---
 client/src/MarketDataPage.jsx | 141 ++++++++++++++++++++++++------------------
 1 file changed, 82 insertions(+), 59 deletions(-)

(limited to 'client/src/MarketDataPage.jsx')

diff --git a/client/src/MarketDataPage.jsx b/client/src/MarketDataPage.jsx
index 3ffa099..76d8284 100644
--- a/client/src/MarketDataPage.jsx
+++ b/client/src/MarketDataPage.jsx
@@ -1,73 +1,99 @@
-import React, { useEffect, useState } from 'react';
+import React, { useEffect, useState, useContext } from 'react';
 import { Typography, Spin, Message, Card, Grid } from '@arco-design/web-react';
 import '@arco-design/web-react/dist/css/arco.css';
 import { initVChartArcoTheme } from '@visactor/vchart-arco-theme';
 import { VChart } from '@visactor/react-vchart';
 import API_BASE_URL from './config';
+import { MarketContext, MARKET_FULL_NAMES } from './App';
+
 
 const { Row, Col } = Grid;
 
-function MarketDataPage() {
-  const [fiveMinData, setFiveMinData] = useState([]);
-  const [dayAheadData, setDayAheadData] = useState([]);
-  const [loading, setLoading] = useState(true);
-  const [fiveMinLastUpdated, setFiveMinLastUpdated] = useState(null);
-  const [dayAheadLastUpdated, setDayAheadLastUpdated] = useState(null);
+function TimeAgo({ timestamp, prefix }) {
   const [now, setNow] = useState(new Date());
 
   useEffect(() => {
-    const fetchFiveMinData = async () => {
-      try {
-        const res = await fetch(`${API_BASE_URL}/market/real-time`);
-        if (!res.ok) throw new Error('Failed to fetch real-time data');
-        const json = await res.json();
-        setFiveMinData(json);
-        setFiveMinLastUpdated(new Date());
-      } catch (err) {
-        console.error(err);
-        Message.error('Failed to load real-time market data.');
-      }
-    };
+    const timer = setInterval(() => setNow(new Date()), 1000);
+    return () => clearInterval(timer);
+  }, []);
 
-    const fetchDayAheadData = async () => {
-      try {
-        const res = await fetch(`${API_BASE_URL}/market/day-ahead`);
-        if (!res.ok) throw new Error('Failed to fetch day-ahead data');
-        const json = await res.json();
-        setDayAheadData(json);
-        setDayAheadLastUpdated(new Date());
-      } catch (err) {
-        console.error(err);
-        Message.error('Failed to load day-ahead market data.');
-      }
-    };
+  const formatTimeAgo = () => {
+    if (!timestamp) return '';
+    const seconds = Math.floor((now - timestamp) / 1000);
+    if (seconds < 60) return `${seconds} sec ago`;
+    const minutes = Math.floor(seconds / 60);
+    if (minutes < 60) return `${minutes} min ago`;
+    const hours = Math.floor(minutes / 60);
+    return `${hours} hr ago`;
+  };
 
-    const initialize = async () => {
-      setLoading(true);
-      await Promise.all([fetchFiveMinData(), fetchDayAheadData()]);
-      setLoading(false);
+  return (
+    <Typography.Text type="secondary" style={{ display: 'block' }}>
+      {prefix}: {formatTimeAgo()}
+    </Typography.Text>
+  );
+}
 
-      initVChartArcoTheme({
-        defaultMode: 'light',
-        isWatchingMode: true
-      });
-    };
 
-    initialize();
+function MarketDataPage() {
+  const { selectedMarket } = useContext(MarketContext);
+    const [fiveMinData, setFiveMinData] = useState([]);
+    const [dayAheadData, setDayAheadData] = useState([]);
+    const [loading, setLoading] = useState(true);
+    const [fiveMinLastUpdated, setFiveMinLastUpdated] = useState(null);
+    const [dayAheadLastUpdated, setDayAheadLastUpdated] = useState(null);
+    const [now, setNow] = useState(new Date());
+
+    useEffect(() => {
+      const fetchFiveMinData = async () => {
+        try {
+          const res = await fetch(`${API_BASE_URL}/market/real-time?market=${selectedMarket}`);
+          if (!res.ok) throw new Error('Failed to fetch real-time data');
+          const json = await res.json();
+          setFiveMinData(json);
+          setFiveMinLastUpdated(new Date());
+        } catch (err) {
+          console.error(err);
+          Message.error('Failed to load real-time market data.');
+        }
+      };
+
+      const fetchDayAheadData = async () => {
+        try {
+          const res = await fetch(`${API_BASE_URL}/market/day-ahead?market=${selectedMarket}`);
+          if (!res.ok) throw new Error('Failed to fetch day-ahead data');
+          const json = await res.json();
+          setDayAheadData(json);
+          setDayAheadLastUpdated(new Date());
+        } catch (err) {
+          console.error(err);
+          Message.error('Failed to load day-ahead market data.');
+        }
+      };
 
-    const fiveMinInterval = setInterval(fetchFiveMinData, 5 * 60 * 1000); // 5 minutes
-    const dayAheadInterval = setInterval(fetchDayAheadData, 60 * 60 * 1000); // 1 hour
+      const initialize = async () => {
+        setLoading(true);
+        await Promise.all([fetchFiveMinData(), fetchDayAheadData()]);
+        setLoading(false);
 
-    const timer = setInterval(() => {
-      setNow(new Date());
-    }, 1000);
+        initVChartArcoTheme({
+          defaultMode: 'light',
+          isWatchingMode: true
+        });
+      };
 
-    return () => {
-      clearInterval(fiveMinInterval);
-      clearInterval(dayAheadInterval);
-      clearInterval(timer);
-    };
-  }, []);
+      initialize();
+
+      const fiveMinInterval = setInterval(fetchFiveMinData, 5 * 60 * 1000); // 5 minutes
+      const dayAheadInterval = setInterval(fetchDayAheadData, 60 * 60 * 1000); // 1 hour
+      const timer = setInterval(() => setNow(new Date()), 1000);
+
+      return () => {
+        clearInterval(fiveMinInterval);
+        clearInterval(dayAheadInterval);
+        clearInterval(timer);
+      };
+    }, [selectedMarket]);
 
   const getChartSpec = (data, title) => ({
     type: 'line',
@@ -151,18 +177,15 @@ function MarketDataPage() {
 
   return (
     <div style={{ padding: 20, backgroundColor: 'var(--color-fill-2)' }}>
-      <Typography.Title heading={4}>Market Data Visualization</Typography.Title>
-      <Typography.Text type="secondary" style={{ marginTop: 10, display: 'block' }}>
-        Real-Time Data Last Updated: {formatTimeAgo(fiveMinLastUpdated)}
-      </Typography.Text>
-      <Typography.Text type="secondary" style={{ marginBottom: 20, display: 'block' }}>
-        Day-Ahead Data Last Updated: {formatTimeAgo(dayAheadLastUpdated)}
-      </Typography.Text>
+      <Typography.Title heading={4}>Market Data for {MARKET_FULL_NAMES[selectedMarket]}</Typography.Title>
+
 
       {loading ? (
         <Spin />
       ) : (
         <>
+          <TimeAgo timestamp={fiveMinLastUpdated} prefix="Real-Time Data Last Updated" />
+          <TimeAgo timestamp={dayAheadLastUpdated} prefix="Day-Ahead Data Last Updated" />
           <Row gutter={24} style={{ marginTop: 20, marginBottom: 20 }}>
                 <Col xs={12} md={6} style={{ marginTop: 10}}>
                   <Card style={{ textAlign: 'center' }} title="Avg Real-Time LMP ($/MWh)">
-- 
cgit v1.2.3

