Browse Source

Layout UI

The Grid was restrictive and caused problems overlapping things.
We can achieve better layouting with flex components (for now mostly HStack and VStack flexes).
We can eventually also add space bounds to the flexes for more layourting (i.e. graph should take 70% on right...), but for now I kept it rather simple.

I experimented with Grids for the tiles where we group information (i.e. Buy, Order) but it did not look good, so I amd using flexes with fixed label width for better looks.
fix-bad-api-calls
Daniel Karzel 3 years ago
parent
commit
410ded4a24
No known key found for this signature in database GPG Key ID: 30C3FC2E438ADB6E
  1. 88
      frontend/src/MakerApp.tsx
  2. 159
      frontend/src/TakerApp.tsx
  3. 78
      frontend/src/components/OrderTile.tsx

88
frontend/src/MakerApp.tsx

@ -1,9 +1,8 @@
import {
Box,
Button,
Container,
Flex,
Grid,
GridItem,
Divider,
HStack,
Tab,
TabList,
@ -74,67 +73,70 @@ export default function App() {
!runningStates.includes(value.state) && !closedStates.includes(value.state) && !openStates.includes(value.state)
);
const labelWidth = 110;
return (
<Container maxWidth="120ch" marginTop="1rem">
<Grid templateColumns="repeat(6, 1fr)" gap={4}>
<GridItem colStart={1} colSpan={2}>
<HStack spacing={5}>
<VStack>
<Wallet walletInfo={walletInfo} />
<VStack spacing={5} shadow={"md"} padding={5} align={"stretch"}>
<VStack spacing={5} shadow={"md"} padding={5} width="100%" align={"stretch"}>
<HStack>
<Text align={"left"}>Current Price:</Text>
<Text width={labelWidth} align={"left"}>Current Price:</Text>
<Text>{49000}</Text>
</HStack>
<HStack>
<Text>Min Quantity:</Text>
<Text width={labelWidth}>Min Quantity:</Text>
<CurrencyInputField
onChange={(valueString: string) => setMinQuantity(parse(valueString))}
value={format(minQuantity)}
/>
</HStack>
<HStack>
<Text>Min Quantity:</Text>
<Text width={labelWidth}>Min Quantity:</Text>
<CurrencyInputField
onChange={(valueString: string) => setMaxQuantity(parse(valueString))}
value={format(maxQuantity)}
/>
</HStack>
<HStack>
<Text>Order Price:</Text>
<Text width={labelWidth}>Order Price:</Text>
<CurrencyInputField
onChange={(valueString: string) => setOrderPrice(parse(valueString))}
value={format(orderPrice)}
/>
</HStack>
<HStack>
<Text width={labelWidth}>Leverage:</Text>
<HStack spacing={5}>
<Button disabled={true}>x1</Button>
<Button disabled={true}>x2</Button>
<Button colorScheme="blue" variant="solid">x{5}</Button>
</HStack>
</HStack>
<CurrencyInputField
onChange={(valueString: string) => setOrderPrice(parse(valueString))}
value={format(orderPrice)}
/>
<Text>Leverage:</Text>
<Flex justifyContent={"space-between"}>
<Button disabled={true}>x1</Button>
<Button disabled={true}>x2</Button>
<Button colorScheme="blue" variant="solid">x{5}</Button>
</Flex>
<VStack>
<Button
disabled={isCreatingNewCfdOrder}
variant={"solid"}
colorScheme={"blue"}
onClick={() => {
let payload: CfdSellOrderPayload = {
price: Number.parseFloat(orderPrice),
min_quantity: Number.parseFloat(minQuantity),
max_quantity: Number.parseFloat(maxQuantity),
};
makeNewCfdSellOrder(payload);
}}
>
{order ? "Update Sell Order" : "Create Sell Order"}
</Button>
</VStack>
<Divider />
<Button
disabled={isCreatingNewCfdOrder}
variant={"solid"}
colorScheme={"blue"}
onClick={() => {
let payload: CfdSellOrderPayload = {
price: Number.parseFloat(orderPrice),
min_quantity: Number.parseFloat(minQuantity),
max_quantity: Number.parseFloat(maxQuantity),
};
makeNewCfdSellOrder(payload);
}}
>
{order ? "Update Sell Order" : "Create Sell Order"}
</Button>
</VStack>
</GridItem>
<GridItem colStart={3} colSpan={2}>
{order && <OrderTile order={order} />}
</GridItem>
</Grid>
<Tabs>
</VStack>
{order && <OrderTile order={order} />}
<Box width="40%" />
</HStack>
<Tabs marginTop={5}>
<TabList>
<Tab>Running [{running.length}]</Tab>
<Tab>Open [{open.length}]</Tab>

159
frontend/src/TakerApp.tsx

@ -1,9 +1,8 @@
import {
Box,
Button,
Container,
Flex,
Grid,
GridItem,
Divider,
HStack,
Tab,
TabList,
@ -117,89 +116,87 @@ export default function App() {
!runningStates.includes(value.state) && !closedStates.includes(value.state)
);
const labelWidth = 120;
return (
<Container maxWidth="120ch" marginTop="1rem">
<VStack>
<Grid templateColumns="repeat(6, 1fr)" gap={4}>
<GridItem colStart={1} colSpan={2}>
<Wallet walletInfo={walletInfo} />
<VStack shadow={"md"} padding={5} align="stretch" spacing={4}>
<HStack>
{/*TODO: Do we need this? does it make sense to only display the price from the order?*/}
<Text align={"left"}>Current Price (Kraken):</Text>
<Text>tbd</Text>
</HStack>
<HStack>
<Text align={"left"}>Order Price:</Text>
<Text>{order?.price}</Text>
</HStack>
<HStack>
<Text>Quantity:</Text>
<CurrencyInputField
onChange={(valueString: string) => {
setQuantity(parse(valueString));
if (!order) {
return;
}
let quantity = valueString ? Number.parseFloat(valueString) : 0;
let payload: MarginRequestPayload = {
leverage: order.leverage,
price: order.price,
quantity,
};
calculateMargin(payload);
}}
value={format(quantity)}
/>
</HStack>
<HStack>
<Text>Margin in BTC:</Text>
<Text>{margin}</Text>
</HStack>
<Text>Leverage:</Text>
{/* TODO: consider button group */}
<Flex justifyContent={"space-between"}>
<HStack spacing={5}>
<VStack>
<Wallet walletInfo={walletInfo} />
<VStack shadow={"md"} padding={5} align="stretch" spacing={5} width="100%">
<HStack>
<Text align={"left"} width={labelWidth}>Order Price:</Text>
<Text>{order?.price}</Text>
</HStack>
<HStack>
<Text width={labelWidth}>Quantity:</Text>
<CurrencyInputField
onChange={(valueString: string) => {
setQuantity(parse(valueString));
if (!order) {
return;
}
let quantity = valueString ? Number.parseFloat(valueString) : 0;
let payload: MarginRequestPayload = {
leverage: order.leverage,
price: order.price,
quantity,
};
calculateMargin(payload);
}}
value={format(quantity)}
/>
</HStack>
<HStack>
<Text width={labelWidth}>Margin in BTC:</Text>
<Text>{margin}</Text>
</HStack>
<HStack>
<Text width={labelWidth}>Leverage:</Text>
<HStack spacing={5}>
<Button disabled={true}>x1</Button>
<Button disabled={true}>x2</Button>
<Button colorScheme="blue" variant="solid">x{order?.leverage}</Button>
</Flex>
{<Button
disabled={isCreatingNewOrderRequest || !order}
variant={"solid"}
colorScheme={"blue"}
onClick={() => {
let payload: CfdOrderRequestPayload = {
order_id: order!.id,
quantity: Number.parseFloat(quantity),
};
makeNewOrderRequest(payload);
}}
>
BUY
</Button>}
</VStack>
</GridItem>
</Grid>
<Tabs>
<TabList>
<Tab>Running [{running.length}]</Tab>
<Tab>Closed [{closed.length}]</Tab>
<Tab>Unsorted [{unsorted.length}] (should be empty)</Tab>
</TabList>
<TabPanels>
<TabPanel>
<CfdTable data={running} />
</TabPanel>
<TabPanel>
<CfdTable data={closed} />
</TabPanel>
<TabPanel>
<CfdTable data={unsorted} />
</TabPanel>
</TabPanels>
</Tabs>
</VStack>
</HStack>
</HStack>
<Divider />
<Button
disabled={isCreatingNewOrderRequest || !order}
variant={"solid"}
colorScheme={"blue"}
onClick={() => {
let payload: CfdOrderRequestPayload = {
order_id: order!.id,
quantity: Number.parseFloat(quantity),
};
makeNewOrderRequest(payload);
}}
>
BUY
</Button>
</VStack>
</VStack>
<Box width="100%" />
</HStack>
<Tabs marginTop={5}>
<TabList>
<Tab>Running [{running.length}]</Tab>
<Tab>Closed [{closed.length}]</Tab>
<Tab>Unsorted [{unsorted.length}] (should be empty)</Tab>
</TabList>
<TabPanels>
<TabPanel>
<CfdTable data={running} />
</TabPanel>
<TabPanel>
<CfdTable data={closed} />
</TabPanel>
<TabPanel>
<CfdTable data={unsorted} />
</TabPanel>
</TabPanels>
</Tabs>
</Container>
);
}

78
frontend/src/components/OrderTile.tsx

@ -1,4 +1,4 @@
import { Box, SimpleGrid, Text, VStack } from "@chakra-ui/react";
import { Box, HStack, Text, VStack } from "@chakra-ui/react";
import React from "react";
import { Order } from "./Types";
@ -11,42 +11,58 @@ function OrderTile(
order,
}: OrderProps,
) {
const labelWidth = 140;
return (
<Box borderRadius={"md"} borderColor={"blue.800"} borderWidth={2} bg={"gray.50"}>
<VStack>
<Box bg="blue.800" w="100%">
<Text padding={2} color={"white"} fontWeight={"bold"}>Current CFD Sell Order</Text>
</Box>
<SimpleGrid padding={5} columns={2} spacing={5}>
<Text>ID</Text>
<Text
overflow="hidden"
textOverflow="ellipsis"
whiteSpace="nowrap"
_hover={{ overflow: "visible" }}
>
{order.id}
</Text>
<Text>Trading Pair</Text>
<Text>{order.trading_pair}</Text>
<Text>Price</Text>
<Text>{order.price}</Text>
<Text>Min Quantity</Text>
<Text>{order.min_quantity}</Text>
<Text>Max Quantity</Text>
<Text>{order.max_quantity}</Text>
<Text>Leverage</Text>
<Text>{order.leverage}</Text>
<Text>Liquidation Price</Text>
<Text
overflow="hidden"
textOverflow="ellipsis"
whiteSpace="nowrap"
_hover={{ overflow: "visible" }}
>
{order.liquidation_price}
</Text>
</SimpleGrid>
<VStack padding={5} spacing={5} align={"stretch"}>
<HStack>
<Text width={labelWidth}>ID</Text>
<Text
overflow="hidden"
textOverflow="ellipsis"
whiteSpace="nowrap"
_hover={{ overflow: "visible" }}
>
{order.id}
</Text>
</HStack>
<HStack>
<Text width={labelWidth}>Trading Pair</Text>
<Text>{order.trading_pair}</Text>
</HStack>
<HStack>
<Text width={labelWidth}>Price</Text>
<Text>{order.price}</Text>
</HStack>
<HStack>
<Text width={labelWidth}>Min Quantity</Text>
<Text>{order.min_quantity}</Text>
</HStack>
<HStack>
<Text width={labelWidth}>Max Quantity</Text>
<Text>{order.max_quantity}</Text>
</HStack>
<HStack>
<Text width={labelWidth}>Leverage</Text>
<Text>{order.leverage}</Text>
</HStack>
<HStack>
<Text width={labelWidth}>Liquidation Price</Text>
<Text
overflow="hidden"
textOverflow="ellipsis"
whiteSpace="nowrap"
_hover={{ overflow: "visible" }}
>
{order.liquidation_price}
</Text>
</HStack>
</VStack>
</VStack>
</Box>
);

Loading…
Cancel
Save