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

159
frontend/src/TakerApp.tsx

@ -1,9 +1,8 @@
import { import {
Box,
Button, Button,
Container, Container,
Flex, Divider,
Grid,
GridItem,
HStack, HStack,
Tab, Tab,
TabList, TabList,
@ -117,89 +116,87 @@ export default function App() {
!runningStates.includes(value.state) && !closedStates.includes(value.state) !runningStates.includes(value.state) && !closedStates.includes(value.state)
); );
const labelWidth = 120;
return ( return (
<Container maxWidth="120ch" marginTop="1rem"> <Container maxWidth="120ch" marginTop="1rem">
<VStack> <HStack spacing={5}>
<Grid templateColumns="repeat(6, 1fr)" gap={4}> <VStack>
<GridItem colStart={1} colSpan={2}> <Wallet walletInfo={walletInfo} />
<Wallet walletInfo={walletInfo} /> <VStack shadow={"md"} padding={5} align="stretch" spacing={5} width="100%">
<VStack shadow={"md"} padding={5} align="stretch" spacing={4}> <HStack>
<HStack> <Text align={"left"} width={labelWidth}>Order Price:</Text>
{/*TODO: Do we need this? does it make sense to only display the price from the order?*/} <Text>{order?.price}</Text>
<Text align={"left"}>Current Price (Kraken):</Text> </HStack>
<Text>tbd</Text> <HStack>
</HStack> <Text width={labelWidth}>Quantity:</Text>
<HStack> <CurrencyInputField
<Text align={"left"}>Order Price:</Text> onChange={(valueString: string) => {
<Text>{order?.price}</Text> setQuantity(parse(valueString));
</HStack> if (!order) {
<HStack> return;
<Text>Quantity:</Text> }
<CurrencyInputField let quantity = valueString ? Number.parseFloat(valueString) : 0;
onChange={(valueString: string) => { let payload: MarginRequestPayload = {
setQuantity(parse(valueString)); leverage: order.leverage,
if (!order) { price: order.price,
return; quantity,
} };
let quantity = valueString ? Number.parseFloat(valueString) : 0; calculateMargin(payload);
let payload: MarginRequestPayload = { }}
leverage: order.leverage, value={format(quantity)}
price: order.price, />
quantity, </HStack>
}; <HStack>
calculateMargin(payload); <Text width={labelWidth}>Margin in BTC:</Text>
}} <Text>{margin}</Text>
value={format(quantity)} </HStack>
/> <HStack>
</HStack> <Text width={labelWidth}>Leverage:</Text>
<HStack> <HStack spacing={5}>
<Text>Margin in BTC:</Text>
<Text>{margin}</Text>
</HStack>
<Text>Leverage:</Text>
{/* TODO: consider button group */}
<Flex justifyContent={"space-between"}>
<Button disabled={true}>x1</Button> <Button disabled={true}>x1</Button>
<Button disabled={true}>x2</Button> <Button disabled={true}>x2</Button>
<Button colorScheme="blue" variant="solid">x{order?.leverage}</Button> <Button colorScheme="blue" variant="solid">x{order?.leverage}</Button>
</Flex> </HStack>
{<Button </HStack>
disabled={isCreatingNewOrderRequest || !order} <Divider />
variant={"solid"} <Button
colorScheme={"blue"} disabled={isCreatingNewOrderRequest || !order}
onClick={() => { variant={"solid"}
let payload: CfdOrderRequestPayload = { colorScheme={"blue"}
order_id: order!.id, onClick={() => {
quantity: Number.parseFloat(quantity), let payload: CfdOrderRequestPayload = {
}; order_id: order!.id,
makeNewOrderRequest(payload); quantity: Number.parseFloat(quantity),
}} };
> makeNewOrderRequest(payload);
BUY }}
</Button>} >
</VStack> BUY
</GridItem> </Button>
</Grid> </VStack>
<Tabs> </VStack>
<TabList> <Box width="100%" />
<Tab>Running [{running.length}]</Tab> </HStack>
<Tab>Closed [{closed.length}]</Tab> <Tabs marginTop={5}>
<Tab>Unsorted [{unsorted.length}] (should be empty)</Tab> <TabList>
</TabList> <Tab>Running [{running.length}]</Tab>
<Tab>Closed [{closed.length}]</Tab>
<TabPanels> <Tab>Unsorted [{unsorted.length}] (should be empty)</Tab>
<TabPanel> </TabList>
<CfdTable data={running} />
</TabPanel> <TabPanels>
<TabPanel> <TabPanel>
<CfdTable data={closed} /> <CfdTable data={running} />
</TabPanel> </TabPanel>
<TabPanel> <TabPanel>
<CfdTable data={unsorted} /> <CfdTable data={closed} />
</TabPanel> </TabPanel>
</TabPanels> <TabPanel>
</Tabs> <CfdTable data={unsorted} />
</VStack> </TabPanel>
</TabPanels>
</Tabs>
</Container> </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 React from "react";
import { Order } from "./Types"; import { Order } from "./Types";
@ -11,42 +11,58 @@ function OrderTile(
order, order,
}: OrderProps, }: OrderProps,
) { ) {
const labelWidth = 140;
return ( return (
<Box borderRadius={"md"} borderColor={"blue.800"} borderWidth={2} bg={"gray.50"}> <Box borderRadius={"md"} borderColor={"blue.800"} borderWidth={2} bg={"gray.50"}>
<VStack> <VStack>
<Box bg="blue.800" w="100%"> <Box bg="blue.800" w="100%">
<Text padding={2} color={"white"} fontWeight={"bold"}>Current CFD Sell Order</Text> <Text padding={2} color={"white"} fontWeight={"bold"}>Current CFD Sell Order</Text>
</Box> </Box>
<SimpleGrid padding={5} columns={2} spacing={5}> <VStack padding={5} spacing={5} align={"stretch"}>
<Text>ID</Text> <HStack>
<Text <Text width={labelWidth}>ID</Text>
overflow="hidden" <Text
textOverflow="ellipsis" overflow="hidden"
whiteSpace="nowrap" textOverflow="ellipsis"
_hover={{ overflow: "visible" }} whiteSpace="nowrap"
> _hover={{ overflow: "visible" }}
{order.id} >
</Text> {order.id}
<Text>Trading Pair</Text> </Text>
<Text>{order.trading_pair}</Text> </HStack>
<Text>Price</Text> <HStack>
<Text>{order.price}</Text> <Text width={labelWidth}>Trading Pair</Text>
<Text>Min Quantity</Text> <Text>{order.trading_pair}</Text>
<Text>{order.min_quantity}</Text> </HStack>
<Text>Max Quantity</Text> <HStack>
<Text>{order.max_quantity}</Text> <Text width={labelWidth}>Price</Text>
<Text>Leverage</Text> <Text>{order.price}</Text>
<Text>{order.leverage}</Text> </HStack>
<Text>Liquidation Price</Text> <HStack>
<Text <Text width={labelWidth}>Min Quantity</Text>
overflow="hidden" <Text>{order.min_quantity}</Text>
textOverflow="ellipsis" </HStack>
whiteSpace="nowrap" <HStack>
_hover={{ overflow: "visible" }} <Text width={labelWidth}>Max Quantity</Text>
> <Text>{order.max_quantity}</Text>
{order.liquidation_price} </HStack>
</Text> <HStack>
</SimpleGrid> <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> </VStack>
</Box> </Box>
); );

Loading…
Cancel
Save