118 lines
4.1 KiB
TypeScript
118 lines
4.1 KiB
TypeScript
import React, {Component} from "react";
|
||
import {Col, Container, Navbar, Row} from "react-bootstrap";
|
||
import HCard from "./HCard";
|
||
import RPlot from "./RPlot";
|
||
import {FirstConnectMessage, NewEventMessage, NewTickMessage, PositionState, socket} from "../";
|
||
import {PositionTable} from "./Tables";
|
||
import {EventData, Events} from "./Events";
|
||
import {Helmet} from "react-helmet";
|
||
|
||
type AppState = {
|
||
current_price: number,
|
||
current_tick: number,
|
||
last_update: Date,
|
||
positions: Array<PositionState>,
|
||
events: Array<EventData>
|
||
}
|
||
|
||
let event_id = 0;
|
||
|
||
class App extends Component<{}, AppState> {
|
||
state = {
|
||
current_price: 0,
|
||
current_tick: 0,
|
||
last_update: new Date(),
|
||
positions: [],
|
||
events: []
|
||
}
|
||
|
||
constructor(props) {
|
||
super(props)
|
||
}
|
||
|
||
componentDidMount() {
|
||
console.log(this)
|
||
|
||
socket.on("first_connect", (data: FirstConnectMessage) => {
|
||
this.setState({
|
||
current_price: data.prices[data.prices.length - 1],
|
||
current_tick: data.ticks[data.ticks.length - 1],
|
||
last_update: new Date(),
|
||
positions: data.positions
|
||
})
|
||
})
|
||
|
||
socket.on("new_tick", (data: NewTickMessage) => {
|
||
this.setState({
|
||
current_price: data.price,
|
||
current_tick: data.tick,
|
||
last_update: new Date(),
|
||
positions: data.positions,
|
||
})
|
||
})
|
||
|
||
socket.on("new_event", (data: NewEventMessage) => {
|
||
// ignore new tick
|
||
if (!data.kind.toLowerCase().includes("new_tick")) {
|
||
const new_event: EventData = {
|
||
id: event_id,
|
||
name: data.kind,
|
||
tick: data.tick
|
||
}
|
||
|
||
event_id += 1
|
||
|
||
this.setState({
|
||
events: [...this.state.events, new_event]
|
||
})
|
||
}
|
||
})
|
||
}
|
||
|
||
render() {
|
||
return (
|
||
<div className="d-flex flex-fill flex-column">
|
||
<Helmet>
|
||
{/* TODO: fix currency */}
|
||
<title> Rustico - USD {String(this.state.current_price)} </title>
|
||
</Helmet>
|
||
<Navbar bg="light" expand="lg" className="border-bottom">
|
||
<Navbar.Brand href="#">Rustico - BfxBot</Navbar.Brand>
|
||
</Navbar>
|
||
|
||
<Container fluid className="mt-2 border flex-fill d-flex">
|
||
<Row className="flex-fill">
|
||
{/* Toolbar column */}
|
||
<Col md={4} lg={4} className="border-right d-flex flex-column">
|
||
<Row className="justify-content-center border-bottom py-2">
|
||
<HCard title="Current tick:" content={String(this.state.current_tick)}
|
||
update={this.state.last_update}/>
|
||
<HCard title="Current price:" content={String(this.state.current_price)}
|
||
update={this.state.last_update}/>
|
||
</Row>
|
||
<Row className={"flex-fill"}>
|
||
{this.state.positions.length > 0 ?
|
||
<PositionTable positions={this.state.positions}/> : null}
|
||
</Row>
|
||
<Row className={"my-2"}>
|
||
{this.state.events.length > 0 ? <Events events={this.state.events}/> : null}
|
||
</Row>
|
||
</Col>
|
||
|
||
{/* Graph column */}
|
||
<Col md={8} lg={8} className="flex-fill">
|
||
<RPlot/>
|
||
</Col>
|
||
</Row>
|
||
</Container>
|
||
<footer className="footer py-3 bg-light border-top">
|
||
<Container className="text-center">
|
||
<span className="text-muted">Made with ❤️ by the Pepe</span>
|
||
</Container>
|
||
</footer>
|
||
</div>
|
||
)
|
||
}
|
||
}
|
||
|
||
export default App; |