diff --git a/frontend/src/components/App.tsx b/frontend/src/components/App.tsx index 76dadbe6..603fd9cd 100644 --- a/frontend/src/components/App.tsx +++ b/frontend/src/components/App.tsx @@ -1,6 +1,6 @@ import React, { Suspense, useState } from 'react'; import ReactDOM from 'react-dom/client'; -import HomePage from './HomePage'; +import Main from './Main'; import { CssBaseline, IconButton } from '@mui/material'; import { ThemeProvider, createTheme } from '@mui/material/styles'; import UnsafeAlert from './UnsafeAlert'; @@ -83,7 +83,7 @@ const App = (): JSX.Element => { {theme.palette.mode === 'dark' ? : } - +
diff --git a/frontend/src/components/BookPage/BookPage.tsx b/frontend/src/components/BookPage/BookPage.tsx index e760c854..0a51831f 100644 --- a/frontend/src/components/BookPage/BookPage.tsx +++ b/frontend/src/components/BookPage/BookPage.tsx @@ -5,7 +5,7 @@ import { useHistory } from 'react-router-dom'; import currencyDict from '../../../static/assets/currencies.json'; import DepthChart from '../Charts/DepthChart'; -import { Order, LimitList, Maker } from '../../models'; +import { Book, Order, LimitList, Maker } from '../../models'; // Icons import { BarChart, FormatListBulleted } from '@mui/icons-material'; @@ -13,27 +13,24 @@ import BookTable from './BookTable'; import { MakerForm } from '../MakerPage'; interface BookPageProps { - bookLoading?: boolean; bookRefreshing?: boolean; loadingLimits: boolean; lastDayPremium: number; - orders: Order[]; + book: Book; limits: LimitList; fetchLimits: () => void; type: number; currency: number; windowWidth: number; windowHeight: number; - fetchBook: (loading: boolean, refreshing: boolean) => void; + fetchBook: () => void; setAppState: (state: object) => void; } const BookPage = ({ - bookLoading = false, - bookRefreshing = false, lastDayPremium = 0, loadingLimits, - orders = [], + book = { orders: [], loading: true }, limits, fetchLimits, type, @@ -75,7 +72,7 @@ const BookPage = ({ const [maker, setMaker] = useState(defaultMaker); useEffect(() => { - if (orders.length < 1) { + if (book.orders.length < 1) { fetchBook(true, false); } else { fetchBook(false, true); @@ -184,10 +181,8 @@ const BookPage = ({ > fetchBook(false, true)} - orders={orders} + clickRefresh={() => fetchBook()} + book={book} type={type} currency={currency} maxWidth={maxBookTableWidth} // EM units @@ -215,8 +210,7 @@ const BookPage = ({ ) : view === 'depth' ? ( ) : ( fetchBook(false, true)} - orders={orders} + book={book} + clickRefresh={() => fetchBook()} type={type} currency={currency} maxWidth={windowWidth * 0.97} // EM units diff --git a/frontend/src/components/BookPage/BookTable.tsx b/frontend/src/components/BookPage/BookTable.tsx index 4bf5602f..3377f98c 100644 --- a/frontend/src/components/BookPage/BookTable.tsx +++ b/frontend/src/components/BookPage/BookTable.tsx @@ -18,7 +18,7 @@ import { } from '@mui/material'; import { DataGrid, GridPagination } from '@mui/x-data-grid'; import currencyDict from '../../../static/assets/currencies.json'; -import { Order } from '../../models'; +import { Book, Order } from '../../models'; import filterOrders from '../../utils/filterOrders'; import BookControl from './BookControl'; @@ -30,13 +30,11 @@ import hexToRgb from '../../utils/hexToRgb'; import statusBadgeColor from '../../utils/statusBadgeColor'; // Icons -import { Fullscreen, FullscreenExit, Refresh, WidthFull } from '@mui/icons-material'; +import { Fullscreen, FullscreenExit, Refresh } from '@mui/icons-material'; interface Props { - loading?: boolean; - refreshing?: boolean; clickRefresh?: () => void; - orders: Order[]; + book: Book; type: number; currency: number; maxWidth: number; @@ -52,10 +50,8 @@ interface Props { } const BookTable = ({ - loading = false, - refreshing = false, clickRefresh, - orders, + book, type, currency, maxWidth, @@ -702,17 +698,17 @@ const BookTable = ({ rows={ showControls ? filterOrders({ - orders, + orders: book.orders, baseFilter: { currency, type }, paymentMethods, }) - : orders + : book.orders } - loading={loading || refreshing} + loading={book.loading} columns={columns} hideFooter={!showFooter} components={gridComponents()} - pageSize={loading ? 0 : pageSize} + pageSize={book.loading && book.orders.length == 0 ? 0 : pageSize} rowsPerPageOptions={width < 22 ? [] : [0, pageSize, defaultPageSize * 2, 50, 100]} onPageSizeChange={(newPageSize) => { setPageSize(newPageSize); @@ -728,16 +724,20 @@ const BookTable = ({ - (order.type == type || type == null) && - (order.currency == currency || currency == 0), - )} - loading={loading || refreshing} + rows={ + showControls + ? filterOrders({ + orders: book.orders, + baseFilter: { currency, type }, + paymentMethods, + }) + : book.orders + } + loading={book.loading} columns={columns} hideFooter={!showFooter} components={gridComponents()} - pageSize={loading ? 0 : pageSize} + pageSize={book.loading && book.orders.length == 0 ? 0 : pageSize} rowsPerPageOptions={[0, pageSize, defaultPageSize * 2, 50, 100]} onPageSizeChange={(newPageSize) => { setPageSize(newPageSize); diff --git a/frontend/src/components/HomePage.js b/frontend/src/components/HomePage.js deleted file mode 100644 index ff23a840..00000000 --- a/frontend/src/components/HomePage.js +++ /dev/null @@ -1,187 +0,0 @@ -import React, { Component } from 'react'; -import { HashRouter, BrowserRouter, Switch, Route } from 'react-router-dom'; - -import UserGenPage from './UserGenPage'; -import MakerPage from './MakerPage'; -import BookPage from './BookPage'; -import OrderPage from './OrderPage'; -import BottomBar from './BottomBar'; - -import { apiClient } from '../services/api'; - -export default class HomePage extends Component { - constructor(props) { - super(props); - this.state = { - nickname: null, - token: null, - copiedToken: false, - avatarLoaded: false, - buyChecked: false, - sellChecked: false, - type: null, - currency: 0, - bookCurrencyCode: 'ANY', - orders: new Array(), - bookLoading: true, - bookRefreshing: false, - activeOrderId: null, - lastOrderId: null, - earnedRewards: 0, - referralCode: '', - lastDayPremium: 0, - limits: {}, - loadingLimits: true, - maker: {}, - }; - } - - componentDidMount = () => { - if (typeof window !== undefined) { - this.setState({ - windowWidth: window.innerWidth / this.props.theme.typography.fontSize, - windowHeight: window.innerHeight / this.props.theme.typography.fontSize, - }); - window.addEventListener('resize', this.onResize); - } - this.fetchBook(true, false); - this.fetchLimits(true); - }; - - componentWillUnmount = () => { - if (typeof window !== undefined) { - window.removeEventListener('resize', this.onResize); - } - }; - - onResize = () => { - this.setState({ - windowWidth: window.innerWidth / this.props.theme.typography.fontSize, - windowHeight: window.innerHeight / this.props.theme.typography.fontSize, - }); - }; - - setAppState = (newState) => { - this.setState(newState); - }; - - redirectTo(location) { - this.props.history.push(location); - } - - getBasename() { - if (window.NativeRobosats) { - // Only for Android - return window.location.pathname; - } - return ''; - } - - fetchBook = (loading, refreshing) => { - this.setState({ bookLoading: loading, bookRefreshing: refreshing }); - apiClient.get('/api/book/').then((data) => - this.setState({ - bookLoading: false, - bookRefreshing: false, - orders: data.not_found ? [] : data, - }), - ); - }; - - fetchLimits = (loading) => { - this.setState({ loadingLimits: loading }); - const limits = apiClient.get('/api/limits/').then((data) => { - this.setState({ limits: data, loadingLimits: false }); - return data; - }); - return limits; - }; - - render() { - const fontSize = this.props.theme.typography.fontSize; - const fontSizeFactor = fontSize / 14; // default fontSize is 14 - const Router = window.NativeRobosats ? HashRouter : BrowserRouter; - - return ( - -
- - ( - - )} - /> - ( - - )} - /> - ( - - )} - /> - ( - - )} - /> - ( - - )} - /> - -
-
- -
-
- ); - } -} diff --git a/frontend/src/components/Main.tsx b/frontend/src/components/Main.tsx new file mode 100644 index 00000000..0f0fa671 --- /dev/null +++ b/frontend/src/components/Main.tsx @@ -0,0 +1,168 @@ +import React, { useEffect, useState } from 'react'; +import { HashRouter, BrowserRouter, Switch, Route, useHistory } from 'react-router-dom'; +import { useTheme } from '@mui/material'; + +import UserGenPage from './UserGenPage'; +import MakerPage from './MakerPage'; +import BookPage from './BookPage'; +import OrderPage from './OrderPage'; +import BottomBar from './BottomBar'; + +import { apiClient } from '../services/api'; + +import { Book, LimitList } from '../models'; + +interface Limits { + list: LimitList; + loading: boolean; +} + +const Main = (): JSX.Element => { + const theme = useTheme(); + const history = useHistory(); + const Router = window.NativeRobosats ? HashRouter : BrowserRouter; + const basename = window.NativeRobosats ? window.location.pathname : ''; + const [windowSize, setWindowSize] = useState(); // EM values + + // All app data structured + const [book, setBook] = useState({ orders: [], loading: true }); + const [limits, setLimits] = useState({ list: [], loading: true }); + const [robot, setRobot] = useState(); + const [maker, setMaker] = useState(); + const [info, setInfo] = useState(); + const [favorites, setFavorites] = useState(); + const [settings, setSettings] = useState(); + + // constructor(props) { + // super(props); + // this.state = { + // type: null, + // currency: 0, + // lastDayPremium: 0, + // }; + // } + + useEffect(() => { + if (typeof window !== undefined) { + onResize(); + window.addEventListener('resize', onResize); + } + fetchBook(); + fetchLimits(); + return () => { + if (typeof window !== undefined) { + window.removeEventListener('resize', onResize); + } + }; + }, []); + + const onResize = function () { + setWindowSize([ + window.innerWidth / theme.typography.fontSize, + window.innerHeight / theme.typography.fontSize, + ]); + }; + + const fetchBook = function () { + setBook({ ...book, loading: true }); + apiClient.get('/api/book/').then((data) => + setBook({ + loading: false, + orders: data.not_found ? [] : data, + }), + ); + }; + + const fetchLimits = () => { + setLimits({ ...limits, loading: true }); + const data = apiClient.get('/api/limits/').then((data) => { + setLimits({ limits: data, loading: false }); + return data; + }); + return data; + }; + + return ( + +
+ + ( + + )} + /> + ( + + )} + /> + ( + + )} + /> + ( + + )} + /> + ( + + )} + /> + +
+
+ history.push(location)} + {...this.state} + {...this.props} + setAppState={this.setAppState} + /> +
+
+ ); +}; + +export default Main; diff --git a/frontend/src/components/MakerPage/MakerForm.tsx b/frontend/src/components/MakerPage/MakerForm.tsx index 29676f9d..605996c6 100644 --- a/frontend/src/components/MakerPage/MakerForm.tsx +++ b/frontend/src/components/MakerPage/MakerForm.tsx @@ -43,9 +43,8 @@ import { SelfImprovement, Lock, HourglassTop, DeleteSweep, Edit } from '@mui/ico import { LoadingButton } from '@mui/lab'; interface MakerFormProps { - limits: LimitList; - fetchLimits: (loading) => void; - loadingLimits: boolean; + limits: { list: LimitList; loading: boolean }; + fetchLimits: () => LimitList; pricingMethods: boolean; maker: Maker; type: number; @@ -62,7 +61,6 @@ interface MakerFormProps { const MakerForm = ({ limits, fetchLimits, - loadingLimits, pricingMethods, currency, type, @@ -94,19 +92,18 @@ const MakerForm = ({ useEffect(() => { setCurrencyCode(currencyDict[currency == 0 ? 1 : currency]); - if (Object.keys(limits).length === 0) { - setAppState({ loadingLimits: true }); - fetchLimits(true).then((data) => { + if (Object.keys(limits.list).length === 0) { + fetchLimits().then((data) => { updateAmountLimits(data, currency, maker.premium); updateCurrentPrice(data, currency, maker.premium); updateSatoshisLimits(data); }); } else { - updateAmountLimits(limits, currency, maker.premium); - updateCurrentPrice(limits, currency, maker.premium); - updateSatoshisLimits(limits); + updateAmountLimits(limits.list, currency, maker.premium); + updateCurrentPrice(limits.list, currency, maker.premium); + updateSatoshisLimits(limits.list); - fetchLimits(false); + fetchLimits(); } }, []); @@ -130,10 +127,10 @@ const MakerForm = ({ const updateCurrentPrice = function (limits: LimitList, currency: number, premium: number) { const index = currency === 0 ? 1 : currency; let price = '...'; - if (maker.is_explicit && maker.amount > 0 && maker.satoshis > 0) { + if (maker.isExplicit && maker.amount > 0 && maker.satoshis > 0) { price = maker.amount / (maker.satoshis / 100000000); } else if (!maker.is_explicit) { - price = limits[index].price * (1 + premium / 100); + price = limits.list[index].price * (1 + premium / 100); } setCurrentPrice(parseFloat(Number(price).toPrecision(5))); }; @@ -145,13 +142,13 @@ const MakerForm = ({ currency: newCurrency, bookCurrencyCode: currencyCode, }); - updateAmountLimits(limits, newCurrency, maker.premium); - updateCurrentPrice(limits, newCurrency, maker.premium); + updateAmountLimits(limits.list, newCurrency, maker.premium); + updateCurrentPrice(limits.list, newCurrency, maker.premium); if (advancedOptions) { setMaker({ ...maker, - minAmount: parseFloat(Number(limits[newCurrency].max_amount * 0.25).toPrecision(2)), - maxAmount: parseFloat(Number(limits[newCurrency].max_amount * 0.75).toPrecision(2)), + minAmount: parseFloat(Number(limits.list[newCurrency].max_amount * 0.25).toPrecision(2)), + maxAmount: parseFloat(Number(limits.list[newCurrency].max_amount * 0.75).toPrecision(2)), }); } }; @@ -198,8 +195,8 @@ const MakerForm = ({ badPremiumText = t('Must be more than {{min}}%', { min }); premium = -99.99; } - updateCurrentPrice(limits, currency, premium); - updateAmountLimits(limits, currency, premium); + updateCurrentPrice(limits.list, currency, premium); + updateAmountLimits(limits.list, currency, premium); setMaker({ ...maker, premium, @@ -331,10 +328,10 @@ const MakerForm = ({ const index = currency === 0 ? 1 : currency; const minAmount = maker.amount ? parseFloat((maker.amount / 2).toPrecision(2)) - : parseFloat(Number(limits[index].max_amount * 0.25).toPrecision(2)); + : parseFloat(Number(limits.list[index].max_amount * 0.25).toPrecision(2)); const maxAmount = maker.amount ? parseFloat(maker.amount) - : parseFloat(Number(limits[index].max_amount * 0.75).toPrecision(2)); + : parseFloat(Number(limits.list[index].max_amount * 0.75).toPrecision(2)); setMaker({ ...maker, @@ -437,12 +434,12 @@ const MakerForm = ({ return ( - -
+ +
- + @@ -944,7 +941,7 @@ const MakerForm = ({ - + void; orders: Order[]; - loadingLimits: boolean; type: number; windowHeight: number; windowWidth: number; @@ -25,7 +24,6 @@ const MakerPage = ({ limits, fetchLimits, orders, - loadingLimits, currency, type, setAppState, @@ -82,7 +80,6 @@ const MakerPage = ({