feat: add state filter to trades list
This commit is contained in:
parent
4561f56ed1
commit
6c744cc52a
|
@ -11,6 +11,17 @@ export const tradeStates = {
|
|||
waiting: 'waiting'
|
||||
};
|
||||
|
||||
export const tradeStatesFormatted = {
|
||||
waiting: 'Open',
|
||||
paid: 'Paid',
|
||||
funded: 'Funded',
|
||||
released: 'Done',
|
||||
arbitration_open: 'Arbitration',
|
||||
arbitration_closed: 'Resolved',
|
||||
canceled: 'Canceled',
|
||||
expired: 'Expired'
|
||||
};
|
||||
|
||||
export const eventTypes = {
|
||||
paid: 'Paid',
|
||||
funded: 'Funded',
|
||||
|
|
|
@ -132,7 +132,8 @@
|
|||
"trades": {
|
||||
"title": "My trades",
|
||||
"find": "Find offer",
|
||||
"noOpen": "No open trades"
|
||||
"noOpen": "No open trades",
|
||||
"noFilteredTrades": "No trades with that filter"
|
||||
},
|
||||
"offers": {
|
||||
"title": "My offers",
|
||||
|
|
|
@ -12,7 +12,6 @@ import BuyButton from '../License/components/BuyButton';
|
|||
import Balance from '../License/components/Balance';
|
||||
import Loading from '../../components/Loading';
|
||||
import ErrorInformation from '../../components/ErrorInformation';
|
||||
import license from "../../features/license";
|
||||
|
||||
const LICENSE_TOKEN_SYMBOL = 'SNT';
|
||||
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
import React, {Component} from 'react';
|
||||
import React, {Component, Fragment} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {Card, Row, Col} from 'reactstrap';
|
||||
import {Card, Row, Col, Form, FormGroup, Label, Input} from 'reactstrap';
|
||||
import {Link} from "react-router-dom";
|
||||
import {withNamespaces} from 'react-i18next';
|
||||
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
||||
import {faArrowRight} from "@fortawesome/free-solid-svg-icons";
|
||||
import {faArrowRight, faCaretDown} from "@fortawesome/free-solid-svg-icons";
|
||||
import Identicon from "../../../components/UserInformation/Identicon";
|
||||
import {formatBalance} from "../../../utils/numbers";
|
||||
import {tradeStates} from "../../../features/escrow/helpers";
|
||||
import {tradeStates, tradeStatesFormatted} from "../../../features/escrow/helpers";
|
||||
import {addressCompare} from "../../../utils/address";
|
||||
import {ARBITRATION_SOLVED_BUYER, ARBITRATION_SOLVED_SELLER} from "../../../features/arbitration/constants";
|
||||
|
||||
import './Trades.scss';
|
||||
|
||||
const getTradeStyle = (trade, isBuyer) => {
|
||||
if (trade.mining) {
|
||||
return {text: 'Mining', className: 'bg-info'};
|
||||
|
@ -24,22 +26,16 @@ const getTradeStyle = (trade, isBuyer) => {
|
|||
}
|
||||
}
|
||||
}
|
||||
const tradeStyle = {text: tradeStatesFormatted[trade.status]};
|
||||
|
||||
switch(trade.status){
|
||||
case tradeStates.waiting:
|
||||
return {text: 'Open', className: 'bg-primary'};
|
||||
case tradeStates.funded:
|
||||
return {text: 'Funded', className: 'bg-primary'};
|
||||
case tradeStates.paid:
|
||||
return {text: 'Paid', className: 'bg-primary'};
|
||||
case tradeStates.released:
|
||||
return {text: 'Done', className: 'bg-success'};
|
||||
case tradeStates.canceled:
|
||||
return {text: 'Canceled', className: 'bg-secondary text-black'};
|
||||
case tradeStates.expired:
|
||||
return {text: 'Expired', className: 'bg-secondary text-black'};
|
||||
case tradeStates.arbitration_open:
|
||||
return {text: 'Arbitration', className: 'bg-warning'};
|
||||
case tradeStates.waiting: tradeStyle.className = 'bg-primary'; break;
|
||||
case tradeStates.funded: tradeStyle.className = 'bg-primary'; break;
|
||||
case tradeStates.paid: tradeStyle.className = 'bg-primary'; break;
|
||||
case tradeStates.released: tradeStyle.className = 'bg-success'; break;
|
||||
case tradeStates.canceled: tradeStyle.className = 'bg-secondary text-black'; break;
|
||||
case tradeStates.expired: tradeStyle.className = 'bg-secondary text-black'; break;
|
||||
case tradeStates.arbitration_open: tradeStyle.className = 'bg-warning'; break;
|
||||
case tradeStates.arbitration_closed: {
|
||||
let className;
|
||||
if (trade.arbitration.result.toString() === ARBITRATION_SOLVED_BUYER) {
|
||||
|
@ -49,39 +45,83 @@ const getTradeStyle = (trade, isBuyer) => {
|
|||
} else {
|
||||
className = 'bg-primary';
|
||||
}
|
||||
return {text: 'Resolved', className};
|
||||
tradeStyle.className = className; break;
|
||||
}
|
||||
default:
|
||||
return {text: trade.status, className: 'bg-secondary text-black'};
|
||||
default: tradeStyle.className = 'bg-secondary text-black'; break;
|
||||
}
|
||||
return tradeStyle;
|
||||
};
|
||||
|
||||
class Trades extends Component {
|
||||
state = {
|
||||
filteredState: '',
|
||||
showFilters: false
|
||||
};
|
||||
|
||||
filterState(stateName) {
|
||||
if (stateName === '') {
|
||||
return this.setState({filteredState: ''});
|
||||
}
|
||||
const stateIndex = Object.values(tradeStatesFormatted).findIndex(tradeState => tradeState === stateName);
|
||||
const filteredState = stateIndex === -1 ? '' : Object.keys(tradeStatesFormatted)[stateIndex];
|
||||
this.setState({filteredState});
|
||||
}
|
||||
|
||||
renderTrades() {
|
||||
const address = this.props.address;
|
||||
return (
|
||||
<Card body className="py-2 px-3 shadow-sm">
|
||||
{this.props.trades.map((trade, index) => {
|
||||
const isBuyer = addressCompare(trade.buyer, address);
|
||||
const tradeStyle = getTradeStyle(trade, isBuyer);
|
||||
return <Link key={index} to={"/escrow/" + trade.escrowId}>
|
||||
<Row className="my-1 border-bottom">
|
||||
<Col className="align-self-center pr-0" xs="2">
|
||||
<Identicon seed={ isBuyer ? trade.seller.statusContactCode : trade.buyerInfo.statusContactCode} scale={5} className="align-middle rounded-circle topCircle border"/>
|
||||
</Col>
|
||||
<Col className="align-self-center" xs="3">
|
||||
<span>{isBuyer ? trade.seller.username : trade.buyerInfo.username}</span>
|
||||
</Col>
|
||||
<Col className="align-self-center" xs="3" md={4}>
|
||||
{isBuyer ? 'Buy' : 'Sell' } {formatBalance(trade.tokenAmount)} {trade.token.symbol}
|
||||
</Col>
|
||||
<Col className="align-self-center text-center text-success" xs="4" md={3}>
|
||||
<span className={"p-1 text-uppercase d-inline text-white rounded-sm text-small nowrap " + tradeStyle.className}>{tradeStyle.text}</span>
|
||||
</Col>
|
||||
</Row>
|
||||
</Link>;
|
||||
})}
|
||||
</Card>
|
||||
<Fragment>
|
||||
|
||||
{this.state.showFilters && <Form><b>Filters:</b>
|
||||
<FormGroup row className="state-filters">
|
||||
<Label for="trade-state-filter" xs={2}>States</Label>
|
||||
<Col xs={10}>
|
||||
<Input type="select" name="select" id="trade-state-filter"
|
||||
onChange={(e) => this.filterState(e.target.value)}>
|
||||
<option/>
|
||||
{Object.values(tradeStatesFormatted).map((tradeState, index) => <option
|
||||
key={`tradeState-${index}`}>{tradeState}</option>)}
|
||||
</Input>
|
||||
</Col>
|
||||
</FormGroup>
|
||||
</Form>}
|
||||
|
||||
{!this.state.showFilters && <p className="text-small text-muted mb-1 clickable" onClick={() => this.setState({showFilters: true})}>Show Filters <FontAwesomeIcon icon={faCaretDown}/></p>}
|
||||
|
||||
<Card body className="profile-trades-list py-2 px-3 shadow-sm">
|
||||
{(() => {
|
||||
const trades = this.props.trades.map((trade, index) => {
|
||||
if (this.state.filteredState && trade.status !== this.state.filteredState) {
|
||||
return null;
|
||||
}
|
||||
const isBuyer = addressCompare(trade.buyer, address);
|
||||
const tradeStyle = getTradeStyle(trade, isBuyer);
|
||||
return <Link key={index} to={"/escrow/" + trade.escrowId}>
|
||||
<Row className="my-1 border-bottom">
|
||||
<Col className="align-self-center pr-0" xs="2">
|
||||
<Identicon seed={isBuyer ? trade.seller.statusContactCode : trade.buyerInfo.statusContactCode}
|
||||
scale={5} className="align-middle rounded-circle topCircle border"/>
|
||||
</Col>
|
||||
<Col className="align-self-center" xs="3">
|
||||
<span>{isBuyer ? trade.seller.username : trade.buyerInfo.username}</span>
|
||||
</Col>
|
||||
<Col className="align-self-center" xs="3" md={4}>
|
||||
{isBuyer ? 'Buy' : 'Sell'} {formatBalance(trade.tokenAmount)} {trade.token.symbol}
|
||||
</Col>
|
||||
<Col className="align-self-center text-center text-success" xs="4" md={3}>
|
||||
<span
|
||||
className={"p-1 text-uppercase d-inline text-white rounded-sm text-small nowrap " + tradeStyle.className}>{tradeStyle.text}</span>
|
||||
</Col>
|
||||
</Row>
|
||||
</Link>;
|
||||
});
|
||||
if (trades.every(trade => trade === null)) {
|
||||
return this.props.t('trades.noFilteredTrades');
|
||||
}
|
||||
return trades;
|
||||
})()}
|
||||
</Card>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
.profile-trades-list {
|
||||
overflow-y: auto;
|
||||
max-height: 270px;
|
||||
}
|
||||
|
||||
.state-filters {
|
||||
.form-control {
|
||||
height: 40px;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue