mirror of
https://github.com/Reckless-Satoshi/robosats.git
synced 2024-09-11 11:55:26 +03:00
Add Maker and Book page to new main.tsx
This commit is contained in:
parent
037d46ceef
commit
1e257d1924
@ -5,7 +5,7 @@ import { useHistory } from 'react-router-dom';
|
||||
import currencyDict from '../../../static/assets/currencies.json';
|
||||
import DepthChart from '../Charts/DepthChart';
|
||||
|
||||
import { Book, Order, LimitList, Maker } from '../../models';
|
||||
import { Book, Favorites, LimitList, Maker } from '../../models';
|
||||
|
||||
// Icons
|
||||
import { BarChart, FormatListBulleted } from '@mui/icons-material';
|
||||
@ -13,40 +13,37 @@ import BookTable from './BookTable';
|
||||
import { MakerForm } from '../MakerPage';
|
||||
|
||||
interface BookPageProps {
|
||||
bookRefreshing?: boolean;
|
||||
loadingLimits: boolean;
|
||||
lastDayPremium: number;
|
||||
book: Book;
|
||||
limits: LimitList;
|
||||
limits: { list: LimitList; loading: boolean };
|
||||
fetchLimits: () => void;
|
||||
type: number;
|
||||
currency: number;
|
||||
windowWidth: number;
|
||||
windowHeight: number;
|
||||
fav: Favorites;
|
||||
setFav: (state: Favorites) => void;
|
||||
fetchBook: () => void;
|
||||
setAppState: (state: object) => void;
|
||||
windowSize: { width: number; height: number };
|
||||
lastDayPremium: number;
|
||||
maker: Maker;
|
||||
setMaker: (state: Maker) => void;
|
||||
}
|
||||
|
||||
const BookPage = ({
|
||||
lastDayPremium = 0,
|
||||
loadingLimits,
|
||||
book = { orders: [], loading: true },
|
||||
limits,
|
||||
fetchLimits,
|
||||
type,
|
||||
currency,
|
||||
windowWidth,
|
||||
windowHeight,
|
||||
setAppState,
|
||||
book = { orders: [], loading: true },
|
||||
fetchBook,
|
||||
fetchLimits,
|
||||
fav,
|
||||
setFav,
|
||||
maker,
|
||||
setMaker,
|
||||
windowSize,
|
||||
}: BookPageProps): JSX.Element => {
|
||||
const { t } = useTranslation();
|
||||
const history = useHistory();
|
||||
const [view, setView] = useState<'list' | 'depth'>('list');
|
||||
const [openMaker, setOpenMaker] = useState<boolean>(false);
|
||||
|
||||
const doubleView = windowWidth > 115;
|
||||
const width = windowWidth * 0.9;
|
||||
const doubleView = windowSize.width > 115;
|
||||
const width = windowSize.width * 0.9;
|
||||
const maxBookTableWidth = 85;
|
||||
const chartWidthEm = width - maxBookTableWidth;
|
||||
|
||||
@ -69,8 +66,6 @@ const BookPage = ({
|
||||
badSatoshisText: '',
|
||||
};
|
||||
|
||||
const [maker, setMaker] = useState<Maker>(defaultMaker);
|
||||
|
||||
useEffect(() => {
|
||||
if (book.orders.length < 1) {
|
||||
fetchBook(true, false);
|
||||
@ -81,11 +76,11 @@ const BookPage = ({
|
||||
|
||||
const handleCurrencyChange = function (e) {
|
||||
const currency = e.target.value;
|
||||
setAppState({ currency });
|
||||
setFav({ ...fav, currency });
|
||||
};
|
||||
|
||||
const handleTypeChange = function (mouseEvent, val) {
|
||||
setAppState({ type: val });
|
||||
setFav({ ...fav, type: val });
|
||||
};
|
||||
|
||||
const NoOrdersFound = function () {
|
||||
@ -99,12 +94,14 @@ const BookPage = ({
|
||||
>
|
||||
<Grid item>
|
||||
<Typography align='center' component='h5' variant='h5'>
|
||||
{type == 0
|
||||
{fav.type == 0
|
||||
? t('No orders found to sell BTC for {{currencyCode}}', {
|
||||
currencyCode: currency == 0 ? t('ANY') : currencyDict[currency.toString()],
|
||||
currencyCode:
|
||||
fav.currency == 0 ? t('ANY') : currencyDict[fav.currency.toString()],
|
||||
})
|
||||
: t('No orders found to buy BTC for {{currencyCode}}', {
|
||||
currencyCode: currency == 0 ? t('ANY') : currencyDict[currency.toString()],
|
||||
currencyCode:
|
||||
fav.currency == 0 ? t('ANY') : currencyDict[fav.currency.toString()],
|
||||
})}
|
||||
</Typography>
|
||||
</Grid>
|
||||
@ -156,14 +153,11 @@ const BookPage = ({
|
||||
<MakerForm
|
||||
limits={limits}
|
||||
fetchLimits={fetchLimits}
|
||||
loadingLimits={loadingLimits}
|
||||
pricingMethods={false}
|
||||
setAppState={setAppState}
|
||||
maker={maker}
|
||||
defaultMaker={defaultMaker}
|
||||
setMaker={setMaker}
|
||||
type={type}
|
||||
currency={currency}
|
||||
fav={fav}
|
||||
setFav={setFav}
|
||||
/>
|
||||
</Box>
|
||||
</Dialog>
|
||||
@ -177,18 +171,17 @@ const BookPage = ({
|
||||
justifyContent='center'
|
||||
spacing={1}
|
||||
direction='row'
|
||||
style={{ width: `${windowWidth}em` }}
|
||||
style={{ width: `${windowSize.width}em` }}
|
||||
>
|
||||
<Grid item>
|
||||
<BookTable
|
||||
clickRefresh={() => fetchBook()}
|
||||
book={book}
|
||||
type={type}
|
||||
currency={currency}
|
||||
fav={fav}
|
||||
maxWidth={maxBookTableWidth} // EM units
|
||||
maxHeight={windowHeight * 0.825 - 5} // EM units
|
||||
fullWidth={windowWidth} // EM units
|
||||
fullHeight={windowHeight} // EM units
|
||||
maxHeight={windowSize.height * 0.825 - 5} // EM units
|
||||
fullWidth={windowSize.width} // EM units
|
||||
fullHeight={windowSize.height} // EM units
|
||||
defaultFullscreen={false}
|
||||
onCurrencyChange={handleCurrencyChange}
|
||||
onTypeChange={handleTypeChange}
|
||||
@ -197,38 +190,33 @@ const BookPage = ({
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<DepthChart
|
||||
orders={orders}
|
||||
orders={book.orders}
|
||||
lastDayPremium={lastDayPremium}
|
||||
currency={currency}
|
||||
compact={true}
|
||||
setAppState={setAppState}
|
||||
limits={limits}
|
||||
currency={fav.currency}
|
||||
limitList={limits.list}
|
||||
maxWidth={chartWidthEm} // EM units
|
||||
maxHeight={windowHeight * 0.825 - 5} // EM units
|
||||
maxHeight={windowSize.height * 0.825 - 5} // EM units
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
) : view === 'depth' ? (
|
||||
<DepthChart
|
||||
book={book}
|
||||
orders={book.orders}
|
||||
lastDayPremium={lastDayPremium}
|
||||
currency={currency}
|
||||
compact={true}
|
||||
setAppState={setAppState}
|
||||
limits={limits}
|
||||
maxWidth={windowWidth * 0.8} // EM units
|
||||
maxHeight={windowHeight * 0.825 - 5} // EM units
|
||||
currency={fav.currency}
|
||||
limitList={limits.list}
|
||||
maxWidth={windowSize.width * 0.8} // EM units
|
||||
maxHeight={windowSize.height * 0.825 - 5} // EM units
|
||||
/>
|
||||
) : (
|
||||
<BookTable
|
||||
book={book}
|
||||
clickRefresh={() => fetchBook()}
|
||||
type={type}
|
||||
currency={currency}
|
||||
maxWidth={windowWidth * 0.97} // EM units
|
||||
maxHeight={windowHeight * 0.825 - 5} // EM units
|
||||
fullWidth={windowWidth} // EM units
|
||||
fullHeight={windowHeight} // EM units
|
||||
fav={fav}
|
||||
maxWidth={windowSize.width * 0.97} // EM units
|
||||
maxHeight={windowSize.height * 0.825 - 5} // EM units
|
||||
fullWidth={windowSize.width} // EM units
|
||||
fullHeight={windowSize.height} // EM units
|
||||
defaultFullscreen={false}
|
||||
onCurrencyChange={handleCurrencyChange}
|
||||
onTypeChange={handleTypeChange}
|
||||
|
@ -18,7 +18,7 @@ import {
|
||||
} from '@mui/material';
|
||||
import { DataGrid, GridPagination } from '@mui/x-data-grid';
|
||||
import currencyDict from '../../../static/assets/currencies.json';
|
||||
import { Book, Order } from '../../models';
|
||||
import { Book, Favorites } from '../../models';
|
||||
import filterOrders from '../../utils/filterOrders';
|
||||
import BookControl from './BookControl';
|
||||
|
||||
@ -35,8 +35,7 @@ import { Fullscreen, FullscreenExit, Refresh } from '@mui/icons-material';
|
||||
interface Props {
|
||||
clickRefresh?: () => void;
|
||||
book: Book;
|
||||
type: number;
|
||||
currency: number;
|
||||
fav?: Favorites;
|
||||
maxWidth: number;
|
||||
maxHeight: number;
|
||||
fullWidth?: number;
|
||||
@ -44,16 +43,15 @@ interface Props {
|
||||
defaultFullscreen: boolean;
|
||||
showControls?: boolean;
|
||||
showFooter?: boolean;
|
||||
onCurrencyChange?: () => void;
|
||||
onTypeChange?: () => void;
|
||||
noResultsOverlay?: JSX.Element;
|
||||
onCurrencyChange?: (e: any) => void;
|
||||
onTypeChange?: (mouseEvent: any, val: number) => void;
|
||||
noResultsOverlay?: () => JSX.Element;
|
||||
}
|
||||
|
||||
const BookTable = ({
|
||||
clickRefresh,
|
||||
book,
|
||||
type,
|
||||
currency,
|
||||
fav,
|
||||
maxWidth,
|
||||
maxHeight,
|
||||
fullWidth,
|
||||
@ -662,8 +660,8 @@ const BookTable = ({
|
||||
return (
|
||||
<BookControl
|
||||
width={width}
|
||||
type={type}
|
||||
currency={currency}
|
||||
type={fav.type}
|
||||
currency={fav.currency}
|
||||
onCurrencyChange={onCurrencyChange}
|
||||
onTypeChange={onTypeChange}
|
||||
paymentMethod={paymentMethods}
|
||||
@ -699,7 +697,7 @@ const BookTable = ({
|
||||
showControls
|
||||
? filterOrders({
|
||||
orders: book.orders,
|
||||
baseFilter: { currency, type },
|
||||
baseFilter: fav,
|
||||
paymentMethods,
|
||||
})
|
||||
: book.orders
|
||||
@ -728,7 +726,7 @@ const BookTable = ({
|
||||
showControls
|
||||
? filterOrders({
|
||||
orders: book.orders,
|
||||
baseFilter: { currency, type },
|
||||
baseFilter: fav,
|
||||
paymentMethods,
|
||||
})
|
||||
: book.orders
|
||||
|
@ -28,15 +28,13 @@ import currencyDict from '../../../../static/assets/currencies.json';
|
||||
import PaymentText from '../../PaymentText';
|
||||
import getNivoScheme from '../NivoScheme';
|
||||
import median from '../../../utils/match';
|
||||
import { apiClient } from '../../../services/api/index';
|
||||
import statusBadgeColor from '../../../utils/statusBadgeColor';
|
||||
|
||||
interface DepthChartProps {
|
||||
orders: Order[];
|
||||
lastDayPremium: number | undefined;
|
||||
currency: number;
|
||||
setAppState: (state: object) => void;
|
||||
limits: LimitList;
|
||||
limitList: LimitList;
|
||||
maxWidth: number;
|
||||
maxHeight: number;
|
||||
}
|
||||
@ -45,8 +43,7 @@ const DepthChart: React.FC<DepthChartProps> = ({
|
||||
orders,
|
||||
lastDayPremium,
|
||||
currency,
|
||||
setAppState,
|
||||
limits,
|
||||
limitList,
|
||||
maxWidth,
|
||||
maxHeight,
|
||||
}) => {
|
||||
@ -58,37 +55,25 @@ const DepthChart: React.FC<DepthChartProps> = ({
|
||||
const [rangeSteps, setRangeSteps] = useState<number>(8);
|
||||
const [xRange, setXRange] = useState<number>(8);
|
||||
const [xType, setXType] = useState<string>('premium');
|
||||
const [currencyCode, setCurrencyCode] = useState<number>(1);
|
||||
const [center, setCenter] = useState<number>();
|
||||
|
||||
const height = maxHeight < 20 ? 20 : maxHeight;
|
||||
const width = maxWidth < 20 ? 20 : maxWidth > 72.8 ? 72.8 : maxWidth;
|
||||
|
||||
useEffect(() => {
|
||||
if (Object.keys(limits).length === 0) {
|
||||
apiClient.get('/api/limits/').then((data) => {
|
||||
setAppState({ limits: data });
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setCurrencyCode(currency === 0 ? 1 : currency);
|
||||
}, [currency]);
|
||||
|
||||
useEffect(() => {
|
||||
if (Object.keys(limits).length > 0) {
|
||||
if (Object.keys(limitList).length > 0) {
|
||||
const enriched = orders.map((order) => {
|
||||
// We need to transform all currencies to the same base (ex. USD), we don't have the exchange rate
|
||||
// for EUR -> USD, but we know the rate of both to BTC, so we get advantage of it and apply a
|
||||
// simple rule of three
|
||||
order.base_amount =
|
||||
(order.price * limits[currencyCode].price) / limits[order.currency].price;
|
||||
(order.price * limitList[currency === 0 ? 1 : currency].price) /
|
||||
limitList[order.currency].price;
|
||||
return order;
|
||||
});
|
||||
setEnrichedOrders(enriched);
|
||||
}
|
||||
}, [limits, orders, currencyCode]);
|
||||
}, [limitList, orders, currency]);
|
||||
|
||||
useEffect(() => {
|
||||
if (enrichedOrders.length > 0) {
|
||||
@ -113,7 +98,7 @@ const DepthChart: React.FC<DepthChartProps> = ({
|
||||
setXRange(8);
|
||||
setRangeSteps(0.5);
|
||||
}
|
||||
}, [enrichedOrders, xType, lastDayPremium, currencyCode]);
|
||||
}, [enrichedOrders, xType, lastDayPremium, currency]);
|
||||
|
||||
const generateSeries: () => void = () => {
|
||||
const sortedOrders: Order[] =
|
||||
@ -338,7 +323,7 @@ const DepthChart: React.FC<DepthChartProps> = ({
|
||||
<Grid item>
|
||||
<Box justifyContent='center'>
|
||||
{xType === 'base_amount'
|
||||
? `${center} ${currencyDict[currencyCode]}`
|
||||
? `${center} ${currencyDict[currency === 0 ? 1 : currency]}`
|
||||
: `${center}%`}
|
||||
</Box>
|
||||
</Grid>
|
||||
|
@ -12,13 +12,13 @@ export const getNivoScheme: (theme: MuiTheme) => NivoTheme = (theme) => {
|
||||
axis: {
|
||||
ticks: {
|
||||
line: {
|
||||
strokeWidth: '1',
|
||||
strokeWidth: 1,
|
||||
stroke: 'rgb(0, 0, 0)',
|
||||
},
|
||||
},
|
||||
domain: {
|
||||
line: {
|
||||
strokeWidth: '1',
|
||||
strokeWidth: 1,
|
||||
stroke: 'rgb(0, 0, 0)',
|
||||
},
|
||||
},
|
||||
@ -36,13 +36,13 @@ export const getNivoScheme: (theme: MuiTheme) => NivoTheme = (theme) => {
|
||||
fill: 'rgb(255, 255, 255)',
|
||||
},
|
||||
line: {
|
||||
strokeWidth: '1',
|
||||
strokeWidth: 1,
|
||||
stroke: 'rgb(255, 255, 255)',
|
||||
},
|
||||
},
|
||||
domain: {
|
||||
line: {
|
||||
strokeWidth: '1',
|
||||
strokeWidth: 1,
|
||||
stroke: 'rgb(255, 255, 255)',
|
||||
},
|
||||
},
|
||||
|
@ -10,41 +10,49 @@ import BottomBar from './BottomBar';
|
||||
|
||||
import { apiClient } from '../services/api';
|
||||
|
||||
import { Book, LimitList } from '../models';
|
||||
|
||||
interface Limits {
|
||||
list: LimitList;
|
||||
loading: boolean;
|
||||
}
|
||||
import {
|
||||
Book,
|
||||
LimitList,
|
||||
Maker,
|
||||
Robot,
|
||||
Info,
|
||||
Settings,
|
||||
Favorites,
|
||||
defaultMaker,
|
||||
defaultRobot,
|
||||
defaultInfo,
|
||||
defaultSettings,
|
||||
} from '../models';
|
||||
|
||||
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<number[]>(); // EM values
|
||||
|
||||
// All app data structured
|
||||
const [book, setBook] = useState<Book>({ orders: [], loading: true });
|
||||
const [limits, setLimits] = useState<Limits>({ list: [], loading: true });
|
||||
const [robot, setRobot] = useState();
|
||||
const [maker, setMaker] = useState();
|
||||
const [info, setInfo] = useState();
|
||||
const [favorites, setFavorites] = useState();
|
||||
const [settings, setSettings] = useState();
|
||||
const [limits, setLimits] = useState<{ list: LimitList; loading: boolean }>({
|
||||
list: [],
|
||||
loading: true,
|
||||
});
|
||||
const [robot, setRobot] = useState<Robot>(defaultRobot);
|
||||
const [maker, setMaker] = useState<Maker>(defaultMaker);
|
||||
const [info, setInfo] = useState<Info>(defaultInfo);
|
||||
const [fav, setFav] = useState<Favorites>({ type: null, currency: 0 });
|
||||
const [settings, setSettings] = useState<Settings>(defaultSettings);
|
||||
|
||||
// constructor(props) {
|
||||
// super(props);
|
||||
// this.state = {
|
||||
// type: null,
|
||||
// currency: 0,
|
||||
// lastDayPremium: 0,
|
||||
// };
|
||||
// }
|
||||
console.log(info);
|
||||
const initialWindowSize = {
|
||||
width: window.innerWidth / theme.typography.fontSize,
|
||||
height: window.innerHeight / theme.typography.fontSize,
|
||||
}; // EM values
|
||||
const [windowSize, setWindowSize] = useState<{ width: number; height: number }>(
|
||||
initialWindowSize,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window !== undefined) {
|
||||
onResize();
|
||||
window.addEventListener('resize', onResize);
|
||||
}
|
||||
fetchBook();
|
||||
@ -57,10 +65,10 @@ const Main = (): JSX.Element => {
|
||||
}, []);
|
||||
|
||||
const onResize = function () {
|
||||
setWindowSize([
|
||||
window.innerWidth / theme.typography.fontSize,
|
||||
window.innerHeight / theme.typography.fontSize,
|
||||
]);
|
||||
setWindowSize({
|
||||
width: window.innerWidth / theme.typography.fontSize,
|
||||
height: window.innerHeight / theme.typography.fontSize,
|
||||
});
|
||||
};
|
||||
|
||||
const fetchBook = function () {
|
||||
@ -76,7 +84,7 @@ const Main = (): JSX.Element => {
|
||||
const fetchLimits = () => {
|
||||
setLimits({ ...limits, loading: true });
|
||||
const data = apiClient.get('/api/limits/').then((data) => {
|
||||
setLimits({ limits: data, loading: false });
|
||||
setLimits({ list: data, loading: false });
|
||||
return data;
|
||||
});
|
||||
return data;
|
||||
@ -86,6 +94,7 @@ const Main = (): JSX.Element => {
|
||||
<Router basename={basename}>
|
||||
<div className='appCenter'>
|
||||
<Switch>
|
||||
{/*
|
||||
<Route
|
||||
exact
|
||||
path='/'
|
||||
@ -108,33 +117,40 @@ const Main = (): JSX.Element => {
|
||||
setAppState={this.setAppState}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
/> */}
|
||||
<Route
|
||||
path='/make'
|
||||
render={() => (
|
||||
<MakerPage
|
||||
orders={book.orders}
|
||||
limits={limits}
|
||||
fetchLimits={fetchLimits}
|
||||
maker={maker}
|
||||
setMaker={setMaker}
|
||||
fav={fav}
|
||||
setFav={setFav}
|
||||
windowSize={windowSize}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
path='/book'
|
||||
render={(props) => (
|
||||
render={() => (
|
||||
<BookPage
|
||||
{...props}
|
||||
{...this.state}
|
||||
{...this.props}
|
||||
book={book}
|
||||
fetchBook={this.fetchBook}
|
||||
fetchLimits={this.fetchLimits}
|
||||
setAppState={this.setAppState}
|
||||
fetchBook={fetchBook}
|
||||
limits={limits}
|
||||
fetchLimits={fetchLimits}
|
||||
fav={fav}
|
||||
setFav={setFav}
|
||||
maker={maker}
|
||||
setMaker={setMaker}
|
||||
lastDayPremium={info.last_day_nonkyc_btc_premium}
|
||||
windowSize={windowSize}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
{/* <Route
|
||||
path='/order/:orderId'
|
||||
render={(props) => (
|
||||
<OrderPage
|
||||
@ -145,22 +161,18 @@ const Main = (): JSX.Element => {
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
*/}
|
||||
</Switch>
|
||||
</div>
|
||||
<div
|
||||
{/* <div
|
||||
className='bottomBar'
|
||||
style={{
|
||||
height: '2.857em',
|
||||
width: `${(windowSize[0] / 16) * 14}em`,
|
||||
width: `${(windowSize.width / 16) * 14}em`,
|
||||
}}
|
||||
>
|
||||
<BottomBar
|
||||
redirectTo={(location) => history.push(location)}
|
||||
{...this.state}
|
||||
{...this.props}
|
||||
setAppState={this.setAppState}
|
||||
/>
|
||||
</div>
|
||||
<BottomBar redirectTo={(location) => history.push(location)} info={info} />
|
||||
</div> */}
|
||||
</Router>
|
||||
);
|
||||
};
|
||||
|
@ -24,7 +24,7 @@ import {
|
||||
IconButton,
|
||||
} from '@mui/material';
|
||||
|
||||
import { LimitList, Maker, defaultMaker } from '../../models';
|
||||
import { LimitList, Maker, Favorites, defaultMaker } from '../../models';
|
||||
|
||||
import { LocalizationProvider, TimePicker } from '@mui/x-date-pickers';
|
||||
import DateFnsUtils from '@date-io/date-fns';
|
||||
@ -44,12 +44,11 @@ import { LoadingButton } from '@mui/lab';
|
||||
|
||||
interface MakerFormProps {
|
||||
limits: { list: LimitList; loading: boolean };
|
||||
fetchLimits: () => LimitList;
|
||||
fetchLimits: () => void;
|
||||
pricingMethods: boolean;
|
||||
maker: Maker;
|
||||
type: number;
|
||||
currency: number;
|
||||
setAppState: (state: object) => void;
|
||||
fav: Favorites;
|
||||
setFav: (state: Favorites) => void;
|
||||
setMaker: (state: Maker) => void;
|
||||
disableRequest?: boolean;
|
||||
collapseAll?: boolean;
|
||||
@ -62,9 +61,8 @@ const MakerForm = ({
|
||||
limits,
|
||||
fetchLimits,
|
||||
pricingMethods,
|
||||
currency,
|
||||
type,
|
||||
setAppState,
|
||||
fav,
|
||||
setFav,
|
||||
maker,
|
||||
setMaker,
|
||||
disableRequest = false,
|
||||
@ -91,26 +89,26 @@ const MakerForm = ({
|
||||
const amountSafeThresholds = [1.03, 0.98];
|
||||
|
||||
useEffect(() => {
|
||||
setCurrencyCode(currencyDict[currency == 0 ? 1 : currency]);
|
||||
setCurrencyCode(currencyDict[fav.currency == 0 ? 1 : fav.currency]);
|
||||
if (Object.keys(limits.list).length === 0) {
|
||||
fetchLimits().then((data) => {
|
||||
updateAmountLimits(data, currency, maker.premium);
|
||||
updateCurrentPrice(data, currency, maker.premium);
|
||||
updateAmountLimits(data, fav.currency, maker.premium);
|
||||
updateCurrentPrice(data, fav.currency, maker.premium);
|
||||
updateSatoshisLimits(data);
|
||||
});
|
||||
} else {
|
||||
updateAmountLimits(limits.list, currency, maker.premium);
|
||||
updateCurrentPrice(limits.list, currency, maker.premium);
|
||||
updateAmountLimits(limits.list, fav.currency, maker.premium);
|
||||
updateCurrentPrice(limits.list, fav.currency, maker.premium);
|
||||
updateSatoshisLimits(limits.list);
|
||||
|
||||
fetchLimits();
|
||||
}
|
||||
}, []);
|
||||
|
||||
const updateAmountLimits = function (limits: LimitList, currency: number, premium: number) {
|
||||
const index = currency === 0 ? 1 : currency;
|
||||
let minAmountLimit: number = limits[index].min_amount * (1 + premium / 100);
|
||||
let maxAmountLimit: number = limits[index].max_amount * (1 + premium / 100);
|
||||
const updateAmountLimits = function (limitList: LimitList, currency: number, premium: number) {
|
||||
const index = currency == 0 ? 1 : currency;
|
||||
let minAmountLimit: number = limitList[index].min_amount * (1 + premium / 100);
|
||||
let maxAmountLimit: number = limitList[index].max_amount * (1 + premium / 100);
|
||||
|
||||
// apply thresholds to ensure good request
|
||||
minAmountLimit = minAmountLimit * amountSafeThresholds[0];
|
||||
@ -118,19 +116,19 @@ const MakerForm = ({
|
||||
setAmountLimits([minAmountLimit, maxAmountLimit]);
|
||||
};
|
||||
|
||||
const updateSatoshisLimits = function (limits: LimitList) {
|
||||
const minAmount: number = limits[1000].min_amount * 100000000;
|
||||
const maxAmount: number = limits[1000].max_amount * 100000000;
|
||||
const updateSatoshisLimits = function (limitList: LimitList) {
|
||||
const minAmount: number = limitList[1000].min_amount * 100000000;
|
||||
const maxAmount: number = limitList[1000].max_amount * 100000000;
|
||||
setSatoshisLimits([minAmount, maxAmount]);
|
||||
};
|
||||
|
||||
const updateCurrentPrice = function (limits: LimitList, currency: number, premium: number) {
|
||||
const index = currency === 0 ? 1 : currency;
|
||||
const updateCurrentPrice = function (limitsList: LimitList, currency: number, premium: number) {
|
||||
const index = currency == 0 ? 1 : currency;
|
||||
let price = '...';
|
||||
if (maker.isExplicit && maker.amount > 0 && maker.satoshis > 0) {
|
||||
price = maker.amount / (maker.satoshis / 100000000);
|
||||
} else if (!maker.is_explicit) {
|
||||
price = limits.list[index].price * (1 + premium / 100);
|
||||
price = limitsList[index].price * (1 + premium / 100);
|
||||
}
|
||||
setCurrentPrice(parseFloat(Number(price).toPrecision(5)));
|
||||
};
|
||||
@ -138,9 +136,9 @@ const MakerForm = ({
|
||||
const handleCurrencyChange = function (newCurrency: number) {
|
||||
const currencyCode: string = currencyDict[newCurrency];
|
||||
setCurrencyCode(currencyCode);
|
||||
setAppState({
|
||||
setFav({
|
||||
...fav,
|
||||
currency: newCurrency,
|
||||
bookCurrencyCode: currencyCode,
|
||||
});
|
||||
updateAmountLimits(limits.list, newCurrency, maker.premium);
|
||||
updateCurrentPrice(limits.list, newCurrency, maker.premium);
|
||||
@ -195,8 +193,8 @@ const MakerForm = ({
|
||||
badPremiumText = t('Must be more than {{min}}%', { min });
|
||||
premium = -99.99;
|
||||
}
|
||||
updateCurrentPrice(limits.list, currency, premium);
|
||||
updateAmountLimits(limits.list, currency, premium);
|
||||
updateCurrentPrice(limits.list, fav.currency, premium);
|
||||
updateAmountLimits(limits.list, fav.currency, premium);
|
||||
setMaker({
|
||||
...maker,
|
||||
premium,
|
||||
@ -244,8 +242,8 @@ const MakerForm = ({
|
||||
if (!disableRequest) {
|
||||
setSubmittingRequest(true);
|
||||
const body = {
|
||||
type: type == 0 ? 1 : 0,
|
||||
currency: currency == 0 ? 1 : currency,
|
||||
type: fav.type == 0 ? 1 : 0,
|
||||
currency: fav.currency == 0 ? 1 : fav.currency,
|
||||
amount: advancedOptions ? null : maker.amount,
|
||||
has_range: advancedOptions,
|
||||
min_amount: advancedOptions ? maker.minAmount : null,
|
||||
@ -325,7 +323,7 @@ const MakerForm = ({
|
||||
};
|
||||
|
||||
const resetRange = function () {
|
||||
const index = currency === 0 ? 1 : currency;
|
||||
const index = fav.currency === 0 ? 1 : fav.currency;
|
||||
const minAmount = maker.amount
|
||||
? parseFloat((maker.amount / 2).toPrecision(2))
|
||||
: parseFloat(Number(limits.list[index].max_amount * 0.25).toPrecision(2));
|
||||
@ -376,11 +374,11 @@ const MakerForm = ({
|
||||
|
||||
const disableSubmit = function () {
|
||||
return (
|
||||
type == null ||
|
||||
fav.type == null ||
|
||||
(maker.amount != '' &&
|
||||
!advancedOptions &&
|
||||
(maker.amount < amountLimits[0] || maker.amount > amountLimits[1])) ||
|
||||
(maker.amount == null && (!advancedOptions || loadingLimits)) ||
|
||||
(maker.amount == null && (!advancedOptions || limits.loading)) ||
|
||||
(advancedOptions && (minAmountError() || maxAmountError())) ||
|
||||
(maker.amount <= 0 && !advancedOptions) ||
|
||||
(maker.isExplicit && (maker.badSatoshisText != '' || maker.satoshis == '')) ||
|
||||
@ -389,7 +387,7 @@ const MakerForm = ({
|
||||
};
|
||||
|
||||
const clearMaker = function () {
|
||||
setAppState({ type: null });
|
||||
setFav({ ...fav, type: null });
|
||||
setMaker(defaultMaker);
|
||||
};
|
||||
|
||||
@ -401,7 +399,11 @@ const MakerForm = ({
|
||||
align='center'
|
||||
color={disableSubmit() ? 'text.secondary' : 'text.primary'}
|
||||
>
|
||||
{type == null ? t('Order for ') : type == 1 ? t('Buy order for ') : t('Sell order for ')}
|
||||
{fav.type == null
|
||||
? t('Order for ')
|
||||
: fav.type == 1
|
||||
? t('Buy order for ')
|
||||
: t('Sell order for ')}
|
||||
{advancedOptions && maker.minAmount != ''
|
||||
? pn(maker.minAmount) + '-' + pn(maker.maxAmount)
|
||||
: pn(maker.amount)}
|
||||
@ -434,12 +436,12 @@ const MakerForm = ({
|
||||
return (
|
||||
<Box>
|
||||
<ConfirmationDialogs />
|
||||
<Collapse in={limits.loading}>
|
||||
<div style={{ display: limits.loading ? '' : 'none' }}>
|
||||
<Collapse in={limits.list.length == 0}>
|
||||
<div style={{ display: limits.list.length == 0 ? '' : 'none' }}>
|
||||
<LinearProgress />
|
||||
</div>
|
||||
</Collapse>
|
||||
<Collapse in={!(limits.loading || collapseAll)}>
|
||||
<Collapse in={!(limits.list.length == 0 || collapseAll)}>
|
||||
<Grid container justifyContent='space-between' spacing={0} sx={{ maxHeight: '1em' }}>
|
||||
<Grid item>
|
||||
<IconButton
|
||||
@ -475,7 +477,7 @@ const MakerForm = ({
|
||||
>
|
||||
<Switch
|
||||
size='small'
|
||||
disabled={limits.loading}
|
||||
disabled={limits.list.length == 0}
|
||||
checked={advancedOptions}
|
||||
onChange={handleClickAdvanced}
|
||||
/>
|
||||
@ -499,14 +501,15 @@ const MakerForm = ({
|
||||
size={advancedOptions ? 'small' : 'large'}
|
||||
variant='contained'
|
||||
onClick={() =>
|
||||
setAppState({
|
||||
setFav({
|
||||
...fav,
|
||||
type: 1,
|
||||
})
|
||||
}
|
||||
disableElevation={type == 1}
|
||||
disableElevation={fav.type == 1}
|
||||
sx={{
|
||||
backgroundColor: type == 1 ? 'primary.main' : 'background.paper',
|
||||
color: type == 1 ? 'background.paper' : 'text.secondary',
|
||||
backgroundColor: fav.type == 1 ? 'primary.main' : 'background.paper',
|
||||
color: fav.type == 1 ? 'background.paper' : 'text.secondary',
|
||||
':hover': {
|
||||
color: 'background.paper',
|
||||
},
|
||||
@ -518,15 +521,16 @@ const MakerForm = ({
|
||||
size={advancedOptions ? 'small' : 'large'}
|
||||
variant='contained'
|
||||
onClick={() =>
|
||||
setAppState({
|
||||
setFav({
|
||||
...fav,
|
||||
type: 0,
|
||||
})
|
||||
}
|
||||
disableElevation={type == 0}
|
||||
disableElevation={fav.type == 0}
|
||||
color='secondary'
|
||||
sx={{
|
||||
backgroundColor: type == 0 ? 'secondary.main' : 'background.paper',
|
||||
color: type == 0 ? 'background.secondary' : 'text.secondary',
|
||||
backgroundColor: fav.type == 0 ? 'secondary.main' : 'background.paper',
|
||||
color: fav.type == 0 ? 'background.secondary' : 'text.secondary',
|
||||
':hover': {
|
||||
color: 'background.paper',
|
||||
},
|
||||
@ -544,7 +548,7 @@ const MakerForm = ({
|
||||
<AmountRange
|
||||
minAmount={maker.minAmount}
|
||||
handleRangeAmountChange={handleRangeAmountChange}
|
||||
currency={currency}
|
||||
currency={fav.currency}
|
||||
currencyCode={currencyCode}
|
||||
handleCurrencyChange={handleCurrencyChange}
|
||||
amountLimits={amountLimits}
|
||||
@ -610,7 +614,7 @@ const MakerForm = ({
|
||||
inputProps={{
|
||||
style: { textAlign: 'center' },
|
||||
}}
|
||||
value={currency == 0 ? 1 : currency}
|
||||
value={fav.currency == 0 ? 1 : fav.currency}
|
||||
onChange={(e) => handleCurrencyChange(e.target.value)}
|
||||
>
|
||||
{Object.entries(currencyDict).map(([key, value]) => (
|
||||
@ -632,10 +636,10 @@ const MakerForm = ({
|
||||
<AutocompletePayments
|
||||
onAutocompleteChange={handlePaymentMethodChange}
|
||||
// listBoxProps={{ sx: { width: '15.3em', maxHeight: '20em' } }}
|
||||
optionsType={currency == 1000 ? 'swap' : 'fiat'}
|
||||
optionsType={fav.currency == 1000 ? 'swap' : 'fiat'}
|
||||
error={maker.badPaymentMethod}
|
||||
helperText={maker.badPaymentMethod ? t('Must be shorter than 65 characters') : ''}
|
||||
label={currency == 1000 ? t('Swap Destination(s)') : t('Fiat Payment Method(s)')}
|
||||
label={fav.currency == 1000 ? t('Swap Destination(s)') : t('Fiat Payment Method(s)')}
|
||||
tooltipTitle={t(
|
||||
'Enter your preferred fiat payment methods. Fast methods are highly recommended.',
|
||||
)}
|
||||
@ -941,7 +945,7 @@ const MakerForm = ({
|
||||
</Typography>
|
||||
</Grid>
|
||||
|
||||
<Collapse in={!limits.loading}>
|
||||
<Collapse in={!(limits.list.length == 0)}>
|
||||
<Tooltip
|
||||
placement='top'
|
||||
enterTouchDelay={0}
|
||||
|
@ -2,7 +2,7 @@ import React, { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button, Grid, Paper, Collapse, Typography } from '@mui/material';
|
||||
|
||||
import { LimitList, Maker, Order, defaultMaker } from '../../models';
|
||||
import { LimitList, Maker, Order, Favorites, defaultMaker } from '../../models';
|
||||
import MakerForm from './MakerForm';
|
||||
import BookTable from '../BookPage/BookTable';
|
||||
|
||||
@ -13,33 +13,32 @@ interface MakerPageProps {
|
||||
limits: { list: LimitList; loading: boolean };
|
||||
fetchLimits: () => void;
|
||||
orders: Order[];
|
||||
type: number;
|
||||
windowHeight: number;
|
||||
windowWidth: number;
|
||||
currency: number;
|
||||
setAppState: (state: object) => void;
|
||||
fav: Favorites;
|
||||
maker: Maker;
|
||||
setFav: (state: Favorites) => void;
|
||||
setMaker: (state: Maker) => void;
|
||||
windowSize: { width: number; height: number };
|
||||
}
|
||||
|
||||
const MakerPage = ({
|
||||
limits,
|
||||
fetchLimits,
|
||||
orders,
|
||||
currency,
|
||||
type,
|
||||
setAppState,
|
||||
windowHeight,
|
||||
windowWidth,
|
||||
fav,
|
||||
maker,
|
||||
setFav,
|
||||
setMaker,
|
||||
windowSize,
|
||||
}: MakerPageProps): JSX.Element => {
|
||||
const { t } = useTranslation();
|
||||
const history = useHistory();
|
||||
|
||||
const [maker, setMaker] = useState<Maker>(defaultMaker);
|
||||
const maxHeight = windowHeight ? windowHeight * 0.85 - 7 : 1000;
|
||||
const maxHeight = windowSize.height * 0.85 - 7;
|
||||
const [showMatches, setShowMatches] = useState<boolean>(false);
|
||||
|
||||
const matches = filterOrders({
|
||||
orders,
|
||||
baseFilter: { currency: currency == 0 ? 1 : currency, type },
|
||||
baseFilter: { currency: fav.currency == 0 ? 1 : fav.currency, type: fav.type },
|
||||
paymentMethods: maker.paymentMethods,
|
||||
amountFilter: {
|
||||
amount: maker.amount,
|
||||
@ -59,10 +58,11 @@ const MakerPage = ({
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<BookTable
|
||||
orders={matches.slice(0, matches.length > 4 ? 4 : matches.length)}
|
||||
type={type}
|
||||
currency={currency}
|
||||
maxWidth={Math.min(windowWidth, 60)} // EM units
|
||||
book={{
|
||||
orders: matches.slice(0, matches.length > 4 ? 4 : matches.length),
|
||||
loading: false,
|
||||
}}
|
||||
maxWidth={Math.min(windowSize.width, 60)} // EM units
|
||||
maxHeight={Math.min(matches.length * 3.25 + 3.575, 16.575)} // EM units
|
||||
defaultFullscreen={false}
|
||||
showControls={false}
|
||||
@ -81,11 +81,10 @@ const MakerPage = ({
|
||||
limits={limits}
|
||||
fetchLimits={fetchLimits}
|
||||
pricingMethods={false}
|
||||
setAppState={setAppState}
|
||||
fav={fav}
|
||||
setFav={setFav}
|
||||
maker={maker}
|
||||
setMaker={setMaker}
|
||||
type={type}
|
||||
currency={currency}
|
||||
disableRequest={matches.length > 0 && !showMatches}
|
||||
collapseAll={showMatches}
|
||||
onSubmit={() => setShowMatches(matches.length > 0)}
|
||||
|
6
frontend/src/models/Favorites.model.ts
Normal file
6
frontend/src/models/Favorites.model.ts
Normal file
@ -0,0 +1,6 @@
|
||||
export interface Favorites {
|
||||
type: number | null;
|
||||
currency: number;
|
||||
}
|
||||
|
||||
export default Favorites;
|
75
frontend/src/models/Info.model.ts
Normal file
75
frontend/src/models/Info.model.ts
Normal file
@ -0,0 +1,75 @@
|
||||
export interface Info {
|
||||
num_public_buy_orders: number;
|
||||
num_public_sell_orders: number;
|
||||
book_liquidity: number;
|
||||
active_robots_today: number;
|
||||
last_day_nonkyc_btc_premium: number;
|
||||
last_day_volume: number;
|
||||
lifetime_volume: number;
|
||||
lnd_version: string;
|
||||
robosats_running_commit_hash: string;
|
||||
alternative_site: string;
|
||||
alternative_name: string;
|
||||
node_alias: string;
|
||||
node_id: string;
|
||||
version: { major: number | null; minor: number | null; patch: number | null };
|
||||
maker_fee: number;
|
||||
taker_fee: number;
|
||||
bond_size: number;
|
||||
current_swap_fee_rate: number;
|
||||
|
||||
// Other keys that do not belong here. TODO on NavBar PR.
|
||||
coordinatorVersion: string;
|
||||
clientVersion: string;
|
||||
profileShown: boolean;
|
||||
openStatsForNerds: boolean;
|
||||
openCommuniy: boolean;
|
||||
openExchangeSummary: boolean;
|
||||
openClaimRewards: boolean;
|
||||
openUpdateClient: boolean;
|
||||
openProfile: boolean;
|
||||
showRewards: boolean;
|
||||
rewardInvoice: string | null;
|
||||
badInvoice: boolean;
|
||||
showRewardsSpinner: boolean;
|
||||
withdrawn: boolean;
|
||||
}
|
||||
|
||||
export const defaultInfo: Info = {
|
||||
num_public_buy_orders: 0,
|
||||
num_public_sell_orders: 0,
|
||||
book_liquidity: 0,
|
||||
active_robots_today: 0,
|
||||
last_day_nonkyc_btc_premium: 0,
|
||||
last_day_volume: 0,
|
||||
lifetime_volume: 0,
|
||||
lnd_version: 'v0.0.0-beta',
|
||||
robosats_running_commit_hash: '000000000000000',
|
||||
alternative_site: 'RoboSats6tkf3eva7x2voqso3a5wcorsnw34jveyxfqi2fu7oyheasid.onion',
|
||||
alternative_name: 'RoboSats Mainnet',
|
||||
node_alias: '🤖RoboSats⚡(RoboDevs)',
|
||||
node_id: '033b58d7681fe5dd2fb21fd741996cda5449616f77317dd1156b80128d6a71b807',
|
||||
version: { major: null, minor: null, patch: null },
|
||||
maker_fee: 0,
|
||||
taker_fee: 0,
|
||||
bond_size: 0,
|
||||
current_swap_fee_rate: 0,
|
||||
|
||||
// Other keys that do not belong here. TODO on NavBar PR.
|
||||
coordinatorVersion: 'v?.?.?',
|
||||
clientVersion: 'v?.?.?',
|
||||
profileShown: false,
|
||||
openStatsForNerds: false,
|
||||
openCommuniy: false,
|
||||
openExchangeSummary: false,
|
||||
openClaimRewards: false,
|
||||
openUpdateClient: false,
|
||||
openProfile: false,
|
||||
showRewards: false,
|
||||
rewardInvoice: null,
|
||||
badInvoice: false,
|
||||
showRewardsSpinner: false,
|
||||
withdrawn: false,
|
||||
};
|
||||
|
||||
export default Info;
|
5
frontend/src/models/Settings.model.ts
Normal file
5
frontend/src/models/Settings.model.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export interface Settings {}
|
||||
|
||||
export const defaultSettings: Settings = {};
|
||||
|
||||
export default Settings;
|
@ -1,8 +1,14 @@
|
||||
export type { LimitList } from './Limit.model';
|
||||
export type { Limit } from './Limit.model';
|
||||
export type { Maker } from './Maker.model';
|
||||
export { defaultMaker } from './Maker.model';
|
||||
export type { Order } from './Order.model';
|
||||
export type { Book } from './Order.model';
|
||||
export type { Order } from './Book.model';
|
||||
export type { Book } from './Book.model';
|
||||
export type { Robot } from './Robot.model';
|
||||
export type { Info } from './Info.model';
|
||||
export type { Settings } from './Settings.model';
|
||||
export type { Favorites } from './Favorites.model';
|
||||
|
||||
export { defaultMaker } from './Maker.model';
|
||||
export { defaultRobot } from './Robot.model';
|
||||
export { defaultSettings } from './Settings.model';
|
||||
export { defaultInfo } from './Info.model';
|
||||
|
@ -1,9 +1,4 @@
|
||||
import Order from '../models/Order.model';
|
||||
|
||||
interface BaseFilter {
|
||||
currency: number;
|
||||
type: number | null;
|
||||
}
|
||||
import { Order, Favorites } from '../models';
|
||||
|
||||
interface AmountFilter {
|
||||
amount: string;
|
||||
@ -14,7 +9,7 @@ interface AmountFilter {
|
||||
|
||||
interface FilterOrders {
|
||||
orders: Order[];
|
||||
baseFilter: BaseFilter;
|
||||
baseFilter: Favorites;
|
||||
amountFilter?: AmountFilter | null;
|
||||
paymentMethods?: string[];
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user