fixed footer margins. started adding events listgroup, events are not shown correctly yet

This commit is contained in:
Giulio De Pasquale 2020-12-14 20:26:14 +00:00
parent e57daf3760
commit e1323c5961
4 changed files with 119 additions and 21 deletions

View File

@ -4,12 +4,14 @@ import HCard from "./HCard";
import RPlot from "./RPlot"; import RPlot from "./RPlot";
import {NewTickData, PositionState, socket} from "../"; import {NewTickData, PositionState, socket} from "../";
import {PositionTable} from "./Tables"; import {PositionTable} from "./Tables";
import {EventData, Events} from "./Events";
type AppState = { type AppState = {
current_price: number, current_price: number,
current_tick: number, current_tick: number,
last_update: Date, last_update: Date,
positions: Array<PositionState> positions: Array<PositionState>,
events: Array<EventData>
} }
@ -18,7 +20,8 @@ class App extends Component<{}, AppState> {
current_price: 0, current_price: 0,
current_tick: 0, current_tick: 0,
last_update: new Date(), last_update: new Date(),
positions: [] positions: [],
events: []
} }
constructor(props) { constructor(props) {
@ -27,11 +30,14 @@ class App extends Component<{}, AppState> {
componentDidMount() { componentDidMount() {
socket.on("new_tick", (data: NewTickData) => { socket.on("new_tick", (data: NewTickData) => {
const event: EventData = {name: "New Tick", id: data.tick, tick: data.tick}
this.setState({ this.setState({
current_price: data.price, current_price: data.price,
current_tick: data.tick, current_tick: data.tick,
last_update: new Date(), last_update: new Date(),
positions: data.positions positions: data.positions,
events: [...this.state.events, event]
}) })
}) })
} }
@ -40,22 +46,25 @@ class App extends Component<{}, AppState> {
return ( return (
<div className="d-flex flex-fill flex-column"> <div className="d-flex flex-fill flex-column">
<Navbar bg="light" expand="lg" className="border-bottom"> <Navbar bg="light" expand="lg" className="border-bottom">
<Navbar.Brand href="#home">Rustico - BfxBot</Navbar.Brand> <Navbar.Brand href="#">Rustico - BfxBot</Navbar.Brand>
</Navbar> </Navbar>
<Container fluid className="mt-2 border flex-fill d-flex"> <Container fluid className="mt-2 border flex-fill d-flex">
<Row className="flex-fill"> <Row className="flex-fill">
{/* Toolbar column */} {/* Toolbar column */}
<Col md={4} lg={4} className="border-right"> <Col md={4} lg={4} className="border-right d-flex flex-column">
<Row className="justify-content-center border-bottom py-2"> <Row className="justify-content-center border-bottom py-2">
<HCard title="Current tick:" content={String(this.state.current_tick)} <HCard title="Current tick:" content={String(this.state.current_tick)}
update={this.state.last_update}/> update={this.state.last_update}/>
<HCard title="Current price:" content={String(this.state.current_price)} <HCard title="Current price:" content={String(this.state.current_price)}
update={this.state.last_update}/> update={this.state.last_update}/>
</Row> </Row>
<Row> <Row className={"flex-fill"}>
<PositionTable/> <PositionTable/>
</Row> </Row>
<Row className={"my-2"}>
<Events events={this.state.events}/>
</Row>
</Col> </Col>
{/* Graph column */} {/* Graph column */}
@ -71,7 +80,7 @@ class App extends Component<{}, AppState> {
<RPlot /> <RPlot />
</Row> */} </Row> */}
</Container> </Container>
<footer className="footer fixed-bottom py-3 bg-light border-top"> <footer className="footer py-3 bg-light border-top">
<Container className="text-center"> <Container className="text-center">
<span className="text-muted">Made with by the Pepe</span> <span className="text-muted">Made with by the Pepe</span>
</Container> </Container>

View File

@ -0,0 +1,49 @@
import React, {Component} from "react";
import {Container, ListGroup} from "react-bootstrap";
export type EventData = {
id: number,
name: string,
tick: number
}
const testEvent: EventData = {
id: 1,
name: "Test",
tick: 1
}
export class Events extends Component<{ events: Array<EventData> }, { events: Array<EventData> }> {
constructor(props) {
super(props);
}
state = {
events: this.props.events
}
mapEvents() {
return this.state.events.map((event: EventData) => {
return (
<ListGroup.Item action key={event.id}>
{event.name} @ Tick {event.tick}
</ListGroup.Item>
)
})
}
render() {
return (
<Container>
<div className={"border-bottom mb-2"}>
<h2>Events</h2>
</div>
<ListGroup>
{this.mapEvents()}
</ListGroup>
</Container>
)
}
}

View File

@ -1,33 +1,71 @@
import React, {Component} from "react" import React, {Component} from "react"
import {Container, Table} from "react-bootstrap" import {Badge, Button, Container, Table} from "react-bootstrap"
import {NewTickData, PositionState, socket} from '../'; import {PositionState} from '../';
export class PositionTable extends Component<{}, { positions: Array<PositionState> }> { export class PositionTable extends Component<{}, { positions: Array<PositionState> }> {
testPosition: PositionState = {
base_price: 1,
id: 1,
profit_loss: 1000,
profit_loss_percentage: 1000,
state: "loss",
symbol: "PAPARCOIN"
}
state = { state = {
positions: [] positions: [this.testPosition]
} }
constructor(props) { constructor(props) {
super(props) super(props)
} }
stateVariantFromStr(state: string): string {
const lower_state = state.toLowerCase()
let res: string;
if (lower_state.includes("profit")) {
res = "success"
} else if (lower_state.includes("break")) {
res = "primary"
} else {
res = "danger"
}
return res
}
plColorFromStr(amount: number): string {
if (amount > 0) {
return "success"
} else {
return "danger"
}
}
componentDidMount() { componentDidMount() {
socket.on('new_tick', (data: NewTickData) => { this.setState({
this.setState({ positions: [this.testPosition]
positions: data.positions
})
}) })
// socket.on('new_tick', (data: NewTickData) => {
// this.setState({
// positions: [...this.state.positions, data.positions]
// })
// })
} }
tableData() { tableData() {
return this.state.positions.map((position: PositionState) => { return this.state.positions.map((position: PositionState) => {
return (<tr key={position.id}> return (<tr key={position.id}>
<th>{position.id}</th> <td className={"align-middle"}><Badge
<th>{position.symbol}</th> variant={this.stateVariantFromStr(position.state)}>{position.state}</Badge></td>
<th>{position.base_price.toFixed(2)}</th> <td className={"align-middle"}>{position.symbol}</td>
<th>{position.profit_loss.toFixed(2)}</th> <td className={"align-middle"}>{position.base_price.toFixed(2)}</td>
<th>{position.profit_loss_percentage.toFixed(2)} %</th> <td className={"align-middle"}>{position.profit_loss.toFixed(2)}</td>
<td className={"align-middle"}>{position.profit_loss_percentage.toFixed(2)} %</td>
<td className={"align-middle"}><Button size={"sm"} variant={"danger"}>Close</Button></td>
</tr>) </tr>)
}) })
} }
@ -38,14 +76,15 @@ export class PositionTable extends Component<{}, { positions: Array<PositionStat
<div className="border-bottom"> <div className="border-bottom">
<h2>Open positions</h2> <h2>Open positions</h2>
</div> </div>
<Table id="positions" size="sm" hover striped bordered className="mt-2 text-center"> <Table id="positions" size="sm" hover striped bordered className="mt-2 text-center align-middle">
<thead> <thead>
<tr> <tr>
<th>ID</th> <th>State</th>
<th>Symbol</th> <th>Symbol</th>
<th>Base price</th> <th>Base price</th>
<th>P/L</th> <th>P/L</th>
<th>P/L %</th> <th>P/L %</th>
<th>Action</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View File

@ -14,6 +14,7 @@ export type NewTickData = {
export type PositionState = { export type PositionState = {
id: number, id: number,
state: string,
base_price: number, base_price: number,
symbol: string, symbol: string,
profit_loss: number, profit_loss: number,