2022-01-08 13:08:03 +00:00
|
|
|
import React, { Component } from "react";
|
2022-01-17 23:11:41 +00:00
|
|
|
import { Link, Paper, Rating, Button, Grid, Typography, TextField, List, ListItem, ListItemText, Divider, ListItemIcon, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle} from "@mui/material"
|
2022-01-09 01:23:13 +00:00
|
|
|
import QRCode from "react-qr-code";
|
2022-01-08 13:08:03 +00:00
|
|
|
|
2022-01-13 19:22:54 +00:00
|
|
|
import Chat from "./Chat"
|
|
|
|
|
2022-01-14 13:31:54 +00:00
|
|
|
// Icons
|
|
|
|
import SmartToyIcon from '@mui/icons-material/SmartToy';
|
|
|
|
import PercentIcon from '@mui/icons-material/Percent';
|
|
|
|
import BookIcon from '@mui/icons-material/Book';
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-01-09 14:07:05 +00:00
|
|
|
function getCookie(name) {
|
|
|
|
let cookieValue = null;
|
|
|
|
if (document.cookie && document.cookie !== '') {
|
|
|
|
const cookies = document.cookie.split(';');
|
|
|
|
for (let i = 0; i < cookies.length; i++) {
|
|
|
|
const cookie = cookies[i].trim();
|
|
|
|
// Does this cookie string begin with the name we want?
|
|
|
|
if (cookie.substring(0, name.length + 1) === (name + '=')) {
|
|
|
|
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2022-01-09 01:23:13 +00:00
|
|
|
}
|
2022-01-09 14:07:05 +00:00
|
|
|
return cookieValue;
|
|
|
|
}
|
|
|
|
const csrftoken = getCookie('csrftoken');
|
2022-01-09 01:23:13 +00:00
|
|
|
|
2022-01-09 14:07:05 +00:00
|
|
|
// pretty numbers
|
|
|
|
function pn(x) {
|
|
|
|
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
|
|
}
|
2022-01-09 01:23:13 +00:00
|
|
|
|
2022-01-09 14:07:05 +00:00
|
|
|
export default class TradeBox extends Component {
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
2022-01-11 01:02:06 +00:00
|
|
|
this.state = {
|
2022-01-17 23:11:41 +00:00
|
|
|
openConfirmFiatReceived: false,
|
|
|
|
openConfirmDispute: false,
|
2022-01-11 01:02:06 +00:00
|
|
|
badInvoice: false,
|
2022-01-16 21:54:42 +00:00
|
|
|
badStatement: false,
|
2022-01-11 01:02:06 +00:00
|
|
|
}
|
2022-01-09 01:23:13 +00:00
|
|
|
}
|
2022-01-17 23:11:41 +00:00
|
|
|
|
|
|
|
handleClickOpenConfirmDispute = () => {
|
|
|
|
this.setState({openConfirmDispute: true});
|
|
|
|
};
|
|
|
|
handleClickCloseConfirmDispute = () => {
|
|
|
|
this.setState({openConfirmDispute: false});
|
|
|
|
};
|
|
|
|
|
|
|
|
handleClickAgreeDisputeButton=()=>{
|
|
|
|
const requestOptions = {
|
|
|
|
method: 'POST',
|
|
|
|
headers: {'Content-Type':'application/json', 'X-CSRFToken': getCookie('csrftoken'),},
|
|
|
|
body: JSON.stringify({
|
|
|
|
'action': "dispute",
|
|
|
|
}),
|
|
|
|
};
|
|
|
|
fetch('/api/order/' + '?order_id=' + this.props.data.id, requestOptions)
|
|
|
|
.then((response) => response.json())
|
|
|
|
.then((data) => (this.props.data = data));
|
|
|
|
this.handleClickCloseConfirmDispute();
|
|
|
|
}
|
|
|
|
|
|
|
|
ConfirmDisputeDialog =() =>{
|
|
|
|
return(
|
|
|
|
<Dialog
|
|
|
|
open={this.state.openConfirmDispute}
|
|
|
|
onClose={this.handleClickCloseConfirmDispute}
|
|
|
|
aria-labelledby="open-dispute-dialog-title"
|
|
|
|
aria-describedby="open-dispute-dialog-description"
|
|
|
|
>
|
|
|
|
<DialogTitle id="open-dispute-dialog-title">
|
|
|
|
{"Do you want to open a dispute?"}
|
|
|
|
</DialogTitle>
|
|
|
|
<DialogContent>
|
|
|
|
<DialogContentText id="alert-dialog-description">
|
|
|
|
The RoboSats staff will examine the statements and evidence provided by the participants.
|
|
|
|
It is best if you provide a burner contact method on your statement for the staff to contact you.
|
|
|
|
The satoshis in the trade escrow will be sent to the dispute winner, while the dispute
|
|
|
|
loser will lose the bond.
|
|
|
|
</DialogContentText>
|
|
|
|
</DialogContent>
|
|
|
|
<DialogActions>
|
|
|
|
<Button onClick={this.handleClickCloseConfirmDispute} autoFocus>Disagree</Button>
|
|
|
|
<Button onClick={this.handleClickAgreeDisputeButton}> Agree </Button>
|
|
|
|
</DialogActions>
|
|
|
|
</Dialog>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
handleClickOpenConfirmFiatReceived = () => {
|
|
|
|
this.setState({openConfirmFiatReceived: true});
|
|
|
|
};
|
|
|
|
handleClickCloseConfirmFiatReceived = () => {
|
|
|
|
this.setState({openConfirmFiatReceived: false});
|
|
|
|
};
|
|
|
|
|
|
|
|
handleClickTotallyConfirmFiatReceived = () =>{
|
|
|
|
this.handleClickConfirmButton();
|
|
|
|
this.handleClickCloseConfirmFiatReceived();
|
|
|
|
};
|
|
|
|
|
|
|
|
ConfirmFiatReceivedDialog =() =>{
|
|
|
|
return(
|
|
|
|
<Dialog
|
|
|
|
open={this.state.openConfirmFiatReceived}
|
|
|
|
onClose={this.handleClickCloseConfirmFiatReceived}
|
|
|
|
aria-labelledby="fiat-received-dialog-title"
|
|
|
|
aria-describedby="fiat-received-dialog-description"
|
|
|
|
>
|
|
|
|
<DialogTitle id="open-dispute-dialog-title">
|
|
|
|
{"Confirm you received " +this.props.data.currencyCode+ "?"}
|
|
|
|
</DialogTitle>
|
|
|
|
<DialogContent>
|
|
|
|
<DialogContentText id="alert-dialog-description">
|
|
|
|
Confirming that you received the fiat will finalize the trade. The satoshis
|
|
|
|
in the escrow will be released to the buyer. Only confirm after the {this.props.data.currencyCode+ " "}
|
|
|
|
has arrived to your account. In addition, if you have received {this.props.data.currencyCode+ " "}
|
|
|
|
and do not confirm the receipt, you risk losing your bond.
|
|
|
|
</DialogContentText>
|
|
|
|
</DialogContent>
|
|
|
|
<DialogActions>
|
|
|
|
<Button onClick={this.handleClickCloseConfirmFiatReceived} autoFocus>Go back</Button>
|
|
|
|
<Button onClick={this.handleClickTotallyConfirmFiatReceived}> Confirm </Button>
|
|
|
|
</DialogActions>
|
|
|
|
</Dialog>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-01-09 12:14:11 +00:00
|
|
|
showQRInvoice=()=>{
|
2022-01-08 13:08:03 +00:00
|
|
|
return (
|
|
|
|
<Grid container spacing={1}>
|
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
<Typography component="body2" variant="body2">
|
2022-01-10 18:47:16 +00:00
|
|
|
Robosats show commitment to their peers
|
2022-01-08 13:08:03 +00:00
|
|
|
</Typography>
|
|
|
|
</Grid>
|
|
|
|
<Grid item xs={12} align="center">
|
2022-01-09 14:07:05 +00:00
|
|
|
{this.props.data.isMaker ?
|
2022-01-10 18:47:16 +00:00
|
|
|
<Typography color="primary" component="subtitle1" variant="subtitle1">
|
2022-01-09 14:07:05 +00:00
|
|
|
<b>Lock {pn(this.props.data.bondSatoshis)} Sats to PUBLISH order </b>
|
2022-01-08 13:08:03 +00:00
|
|
|
</Typography>
|
|
|
|
:
|
2022-01-10 18:47:16 +00:00
|
|
|
<Typography color="primary" component="subtitle1" variant="subtitle1">
|
2022-01-09 14:07:05 +00:00
|
|
|
<b>Lock {pn(this.props.data.bondSatoshis)} Sats to TAKE the order </b>
|
2022-01-08 13:08:03 +00:00
|
|
|
</Typography>
|
|
|
|
}
|
|
|
|
</Grid>
|
|
|
|
<Grid item xs={12} align="center">
|
2022-01-09 14:07:05 +00:00
|
|
|
<QRCode value={this.props.data.bondInvoice} size={305}/>
|
2022-01-13 20:41:48 +00:00
|
|
|
<Button size="small" color="inherit" onClick={() => {navigator.clipboard.writeText(this.props.data.bondInvoice)}} align="center"> 📋Copy to clipboard</Button>
|
2022-01-08 13:08:03 +00:00
|
|
|
</Grid>
|
|
|
|
<Grid item xs={12} align="center">
|
2022-01-13 20:41:48 +00:00
|
|
|
<TextField
|
2022-01-08 13:08:03 +00:00
|
|
|
hiddenLabel
|
2022-01-14 14:19:25 +00:00
|
|
|
variant="standard"
|
2022-01-08 13:08:03 +00:00
|
|
|
size="small"
|
2022-01-09 14:07:05 +00:00
|
|
|
defaultValue={this.props.data.bondInvoice}
|
2022-01-08 13:08:03 +00:00
|
|
|
disabled="true"
|
2022-01-14 14:19:25 +00:00
|
|
|
helperText="This is a hold invoice. It will be charged only if you cancel or lose a dispute."
|
2022-01-08 13:08:03 +00:00
|
|
|
color = "secondary"
|
|
|
|
/>
|
|
|
|
</Grid>
|
|
|
|
</Grid>
|
|
|
|
);
|
|
|
|
}
|
2022-01-09 20:05:19 +00:00
|
|
|
|
2022-01-12 12:57:03 +00:00
|
|
|
showBondIsLocked=()=>{
|
|
|
|
return (
|
|
|
|
<Grid item xs={12} align="center">
|
2022-01-14 14:19:25 +00:00
|
|
|
<Typography color="primary" component="subtitle1" variant="subtitle1" align="center">
|
|
|
|
🔒 Your {this.props.data.isMaker ? 'maker' : 'taker'} bond is locked
|
|
|
|
</Typography>
|
2022-01-12 12:57:03 +00:00
|
|
|
</Grid>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-01-09 12:14:11 +00:00
|
|
|
showEscrowQRInvoice=()=>{
|
2022-01-08 17:19:30 +00:00
|
|
|
return (
|
|
|
|
<Grid container spacing={1}>
|
|
|
|
<Grid item xs={12} align="center">
|
2022-01-18 15:23:57 +00:00
|
|
|
<Typography color="green" component="subtitle1" variant="subtitle1">
|
2022-01-09 14:07:05 +00:00
|
|
|
<b>Deposit {pn(this.props.data.escrowSatoshis)} Sats as trade collateral </b>
|
2022-01-08 17:19:30 +00:00
|
|
|
</Typography>
|
|
|
|
</Grid>
|
|
|
|
<Grid item xs={12} align="center">
|
2022-01-09 14:07:05 +00:00
|
|
|
<QRCode value={this.props.data.escrowInvoice} size={305}/>
|
2022-01-13 20:41:48 +00:00
|
|
|
<Button size="small" color="inherit" onClick={() => {navigator.clipboard.writeText(this.props.data.escrowInvoice)}} align="center"> 📋Copy to clipboard</Button>
|
2022-01-08 17:19:30 +00:00
|
|
|
</Grid>
|
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
<TextField
|
|
|
|
hiddenLabel
|
|
|
|
variant="filled"
|
|
|
|
size="small"
|
2022-01-09 14:07:05 +00:00
|
|
|
defaultValue={this.props.data.escrowInvoice}
|
2022-01-08 17:19:30 +00:00
|
|
|
disabled="true"
|
2022-01-14 14:19:25 +00:00
|
|
|
helperText="This is a hold invoice. It will be charged once the buyer confirms he sent the fiat."
|
2022-01-08 17:19:30 +00:00
|
|
|
color = "secondary"
|
|
|
|
/>
|
|
|
|
</Grid>
|
2022-01-12 12:57:03 +00:00
|
|
|
{this.showBondIsLocked()}
|
2022-01-08 17:19:30 +00:00
|
|
|
</Grid>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-01-09 01:23:13 +00:00
|
|
|
showTakerFound=()=>{
|
|
|
|
|
2022-01-09 14:07:05 +00:00
|
|
|
// TODO Make some sound here! The maker might have been waiting for long
|
2022-01-09 01:23:13 +00:00
|
|
|
|
|
|
|
return (
|
|
|
|
<Grid container spacing={1}>
|
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
<Typography component="subtitle1" variant="subtitle1">
|
|
|
|
<b>A taker has been found! </b>
|
|
|
|
</Typography>
|
|
|
|
</Grid>
|
|
|
|
<Divider/>
|
|
|
|
<Grid item xs={12} align="center">
|
2022-01-09 15:28:12 +00:00
|
|
|
<Typography component="body2" variant="body2">
|
2022-01-09 01:23:13 +00:00
|
|
|
Please wait for the taker to confirm his commitment by locking a bond.
|
|
|
|
</Typography>
|
|
|
|
</Grid>
|
2022-01-12 12:57:03 +00:00
|
|
|
{this.showBondIsLocked()}
|
2022-01-09 01:23:13 +00:00
|
|
|
</Grid>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-01-08 15:34:09 +00:00
|
|
|
showMakerWait=()=>{
|
|
|
|
return (
|
|
|
|
<Grid container spacing={1}>
|
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
<Typography component="subtitle1" variant="subtitle1">
|
2022-01-10 18:47:16 +00:00
|
|
|
<b> Your order is public. Wait for a taker. </b>
|
2022-01-08 15:34:09 +00:00
|
|
|
</Typography>
|
|
|
|
</Grid>
|
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
|
|
|
|
<List dense="true">
|
|
|
|
<Divider/>
|
|
|
|
<ListItem>
|
|
|
|
<Typography component="body2" variant="body2" align="left">
|
|
|
|
<p>Be patient while robots check the book.
|
|
|
|
It might take some time. This box will ring 🔊 once a robot takes your order. </p>
|
|
|
|
<p>Please note that if your premium is too high, or if your currency or payment
|
|
|
|
methods are not popular, your order might expire untaken. Your bond will
|
|
|
|
return to you (no action needed).</p>
|
|
|
|
</Typography>
|
|
|
|
</ListItem>
|
|
|
|
{/* TODO API sends data for a more confortable wait */}
|
|
|
|
<Divider/>
|
|
|
|
<ListItem>
|
2022-01-14 13:31:54 +00:00
|
|
|
<ListItemIcon>
|
|
|
|
<SmartToyIcon/>
|
|
|
|
</ListItemIcon>
|
2022-01-18 18:24:45 +00:00
|
|
|
<ListItemText primary={'000 coming soon'} secondary="Robots looking at the book"/>
|
2022-01-08 15:34:09 +00:00
|
|
|
</ListItem>
|
|
|
|
|
|
|
|
<Divider/>
|
|
|
|
<ListItem>
|
2022-01-14 13:31:54 +00:00
|
|
|
<ListItemIcon>
|
|
|
|
<BookIcon/>
|
|
|
|
</ListItemIcon>
|
2022-01-14 12:00:53 +00:00
|
|
|
<ListItemText primary={this.props.data.numSimilarOrders} secondary={"Public orders for " + this.props.data.currencyCode}/>
|
2022-01-08 15:34:09 +00:00
|
|
|
</ListItem>
|
|
|
|
|
|
|
|
<Divider/>
|
|
|
|
<ListItem>
|
2022-01-14 13:31:54 +00:00
|
|
|
<ListItemIcon>
|
|
|
|
<PercentIcon/>
|
|
|
|
</ListItemIcon>
|
2022-01-18 18:24:45 +00:00
|
|
|
<ListItemText primary={"Premium rank " + this.props.data.premiumPercentile*100+"%"}
|
|
|
|
secondary={"Among public " + this.props.data.currencyCode + " orders (higher is cheaper)"} />
|
2022-01-08 15:34:09 +00:00
|
|
|
</ListItem>
|
2022-01-12 12:57:03 +00:00
|
|
|
<Divider/>
|
|
|
|
|
2022-01-08 15:34:09 +00:00
|
|
|
</List>
|
|
|
|
</Grid>
|
2022-01-12 12:57:03 +00:00
|
|
|
{this.showBondIsLocked()}
|
2022-01-08 15:34:09 +00:00
|
|
|
</Grid>
|
|
|
|
)
|
|
|
|
}
|
2022-01-08 13:08:03 +00:00
|
|
|
|
2022-01-09 14:07:05 +00:00
|
|
|
handleInputInvoiceChanged=(e)=>{
|
|
|
|
this.setState({
|
2022-01-11 01:02:06 +00:00
|
|
|
invoice: e.target.value,
|
|
|
|
badInvoice: false,
|
2022-01-09 14:07:05 +00:00
|
|
|
});
|
|
|
|
}
|
2022-01-09 12:14:11 +00:00
|
|
|
|
2022-01-09 14:07:05 +00:00
|
|
|
handleClickSubmitInvoiceButton=()=>{
|
2022-01-11 01:02:06 +00:00
|
|
|
this.setState({badInvoice:false});
|
|
|
|
|
2022-01-09 14:07:05 +00:00
|
|
|
const requestOptions = {
|
|
|
|
method: 'POST',
|
|
|
|
headers: {'Content-Type':'application/json', 'X-CSRFToken': getCookie('csrftoken'),},
|
|
|
|
body: JSON.stringify({
|
|
|
|
'action':'update_invoice',
|
|
|
|
'invoice': this.state.invoice,
|
|
|
|
}),
|
|
|
|
};
|
|
|
|
fetch('/api/order/' + '?order_id=' + this.props.data.id, requestOptions)
|
|
|
|
.then((response) => response.json())
|
2022-01-11 01:02:06 +00:00
|
|
|
.then((data) => this.setState({badInvoice:data.bad_invoice})
|
|
|
|
& console.log(data));
|
2022-01-09 14:07:05 +00:00
|
|
|
}
|
2022-01-09 12:14:11 +00:00
|
|
|
|
2022-01-16 21:54:42 +00:00
|
|
|
handleInputDisputeChanged=(e)=>{
|
|
|
|
this.setState({
|
|
|
|
statement: e.target.value,
|
|
|
|
badStatement: false,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
handleClickSubmitStatementButton=()=>{
|
|
|
|
this.setState({badInvoice:false});
|
|
|
|
|
|
|
|
const requestOptions = {
|
|
|
|
method: 'POST',
|
|
|
|
headers: {'Content-Type':'application/json', 'X-CSRFToken': getCookie('csrftoken'),},
|
|
|
|
body: JSON.stringify({
|
|
|
|
'action':'submit_statement',
|
|
|
|
'statement': this.state.statement,
|
|
|
|
}),
|
|
|
|
};
|
|
|
|
fetch('/api/order/' + '?order_id=' + this.props.data.id, requestOptions)
|
|
|
|
.then((response) => response.json())
|
|
|
|
.then((data) => this.setState({badStatement:data.bad_statement})
|
|
|
|
& console.log(data));
|
|
|
|
}
|
|
|
|
|
2022-01-09 14:07:05 +00:00
|
|
|
showInputInvoice(){
|
|
|
|
return (
|
2022-01-09 12:14:11 +00:00
|
|
|
|
2022-01-16 21:54:42 +00:00
|
|
|
// TODO Option to upload files and images
|
2022-01-09 14:07:05 +00:00
|
|
|
|
|
|
|
<Grid container spacing={1}>
|
|
|
|
<Grid item xs={12} align="center">
|
2022-01-10 18:47:16 +00:00
|
|
|
<Typography color="primary" component="subtitle1" variant="subtitle1">
|
2022-01-09 14:07:05 +00:00
|
|
|
<b> Submit a LN invoice for {pn(this.props.data.invoiceAmount)} Sats </b>
|
|
|
|
</Typography>
|
|
|
|
</Grid>
|
|
|
|
<Grid item xs={12} align="left">
|
|
|
|
<Typography component="body2" variant="body2">
|
|
|
|
The taker is committed! Before letting you send {" "+ parseFloat(parseFloat(this.props.data.amount).toFixed(4))+
|
|
|
|
" "+ this.props.data.currencyCode}, we want to make sure you are able to receive the BTC. Please provide a
|
|
|
|
valid invoice for {pn(this.props.data.invoiceAmount)} Satoshis.
|
|
|
|
</Typography>
|
|
|
|
</Grid>
|
2022-01-15 12:00:11 +00:00
|
|
|
|
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
<TextField
|
|
|
|
error={this.state.badInvoice}
|
|
|
|
helperText={this.state.badInvoice ? this.state.badInvoice : "" }
|
|
|
|
label={"Payout Lightning Invoice"}
|
|
|
|
required
|
|
|
|
inputProps={{
|
|
|
|
style: {textAlign:"center"}
|
|
|
|
}}
|
|
|
|
multiline
|
|
|
|
onChange={this.handleInputInvoiceChanged}
|
|
|
|
/>
|
|
|
|
</Grid>
|
|
|
|
<Grid item xs={12} align="center">
|
2022-01-17 23:11:41 +00:00
|
|
|
<Button onClick={this.handleClickSubmitInvoiceButton} variant='contained' color='primary'>Submit</Button>
|
2022-01-16 21:54:42 +00:00
|
|
|
</Grid>
|
|
|
|
|
|
|
|
{this.showBondIsLocked()}
|
|
|
|
</Grid>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Asks the user for a dispute statement.
|
|
|
|
showInDisputeStatement(){
|
|
|
|
return (
|
|
|
|
|
|
|
|
// TODO Option to upload files
|
|
|
|
|
|
|
|
<Grid container spacing={1}>
|
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
<Typography color="primary" component="subtitle1" variant="subtitle1">
|
|
|
|
<b> A dispute has been opened </b>
|
|
|
|
</Typography>
|
|
|
|
</Grid>
|
|
|
|
<Grid item xs={12} align="left">
|
|
|
|
<Typography component="body2" variant="body2">
|
|
|
|
Please, submit your statement. Be clear and specific about what happened and provide the necessary
|
|
|
|
evidence. It is best to provide a burner email, XMPP or telegram username to follow up with the staff.
|
|
|
|
Disputes are solved at the discretion of real robots <i>(aka humans)</i>, so be as helpful
|
|
|
|
as possible to ensure a fair outcome. Max 5000 chars.
|
|
|
|
</Typography>
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
<TextField
|
|
|
|
error={this.state.badStatement}
|
|
|
|
helperText={this.state.badStatement ? this.state.badStatement : "" }
|
|
|
|
label={"Submit dispute statement"}
|
|
|
|
required
|
|
|
|
inputProps={{
|
|
|
|
style: {textAlign:"center"}
|
|
|
|
}}
|
|
|
|
multiline
|
|
|
|
rows={4}
|
|
|
|
onChange={this.handleInputDisputeChanged}
|
|
|
|
/>
|
|
|
|
</Grid>
|
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
<Button onClick={this.handleClickSubmitStatementButton} variant='contained' color='primary'>Submit</Button>
|
2022-01-15 12:00:11 +00:00
|
|
|
</Grid>
|
|
|
|
|
2022-01-12 12:57:03 +00:00
|
|
|
{this.showBondIsLocked()}
|
2022-01-09 14:07:05 +00:00
|
|
|
</Grid>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
showWaitingForEscrow(){
|
2022-01-09 15:28:12 +00:00
|
|
|
return(
|
|
|
|
<Grid container spacing={1}>
|
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
<Typography component="subtitle1" variant="subtitle1">
|
|
|
|
<b>Your invoice looks good!</b>
|
|
|
|
</Typography>
|
|
|
|
</Grid>
|
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
<Typography component="body2" variant="body2" align="left">
|
|
|
|
<p>We are waiting for the seller to deposit the full trade BTC amount
|
|
|
|
into the escrow.</p>
|
|
|
|
<p> Just hang on for a moment. If the seller does not deposit,
|
|
|
|
you will get your bond back automatically.</p>
|
|
|
|
</Typography>
|
|
|
|
</Grid>
|
2022-01-12 12:57:03 +00:00
|
|
|
{this.showBondIsLocked()}
|
2022-01-09 15:28:12 +00:00
|
|
|
</Grid>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
showWaitingForBuyerInvoice(){
|
|
|
|
return(
|
|
|
|
<Grid container spacing={1}>
|
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
<Typography component="subtitle1" variant="subtitle1">
|
|
|
|
<b>The trade collateral is locked! :D </b>
|
|
|
|
</Typography>
|
|
|
|
</Grid>
|
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
<Typography component="body2" variant="body2" align="left">
|
|
|
|
<p> We are waiting for the buyer to post a lightning invoice. Once
|
|
|
|
he does, you will be able to directly communicate the fiat payment
|
|
|
|
details. </p>
|
|
|
|
<p> Just hang on for a moment. If the buyer does not cooperate,
|
|
|
|
you will get back the trade collateral and your bond automatically.</p>
|
|
|
|
</Typography>
|
|
|
|
</Grid>
|
2022-01-12 12:57:03 +00:00
|
|
|
{this.showBondIsLocked()}
|
2022-01-09 15:28:12 +00:00
|
|
|
</Grid>
|
|
|
|
)
|
2022-01-09 14:07:05 +00:00
|
|
|
}
|
2022-01-09 12:14:11 +00:00
|
|
|
|
2022-01-09 20:05:19 +00:00
|
|
|
handleClickConfirmButton=()=>{
|
2022-01-09 15:28:12 +00:00
|
|
|
const requestOptions = {
|
|
|
|
method: 'POST',
|
|
|
|
headers: {'Content-Type':'application/json', 'X-CSRFToken': getCookie('csrftoken'),},
|
|
|
|
body: JSON.stringify({
|
2022-01-09 20:05:19 +00:00
|
|
|
'action': "confirm",
|
2022-01-09 15:28:12 +00:00
|
|
|
}),
|
|
|
|
};
|
|
|
|
fetch('/api/order/' + '?order_id=' + this.props.data.id, requestOptions)
|
|
|
|
.then((response) => response.json())
|
|
|
|
.then((data) => (this.props.data = data));
|
|
|
|
}
|
2022-01-17 23:11:41 +00:00
|
|
|
|
2022-01-11 20:49:53 +00:00
|
|
|
handleRatingChange=(e)=>{
|
|
|
|
const requestOptions = {
|
|
|
|
method: 'POST',
|
|
|
|
headers: {'Content-Type':'application/json', 'X-CSRFToken': getCookie('csrftoken'),},
|
|
|
|
body: JSON.stringify({
|
|
|
|
'action': "rate",
|
|
|
|
'rating': e.target.value,
|
|
|
|
}),
|
|
|
|
};
|
|
|
|
fetch('/api/order/' + '?order_id=' + this.props.data.id, requestOptions)
|
|
|
|
.then((response) => response.json())
|
|
|
|
.then((data) => (this.props.data = data));
|
|
|
|
}
|
2022-01-09 12:14:11 +00:00
|
|
|
|
2022-01-09 15:28:12 +00:00
|
|
|
showFiatSentButton(){
|
|
|
|
return(
|
|
|
|
<Grid container spacing={1}>
|
|
|
|
<Grid item xs={12} align="center">
|
2022-01-13 19:22:54 +00:00
|
|
|
<Button defaultValue="confirm" variant='contained' color='secondary' onClick={this.handleClickConfirmButton}>Confirm {this.props.data.currencyCode} sent</Button>
|
2022-01-09 20:05:19 +00:00
|
|
|
</Grid>
|
|
|
|
</Grid>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
showFiatReceivedButton(){
|
|
|
|
return(
|
|
|
|
<Grid item xs={12} align="center">
|
2022-01-17 23:11:41 +00:00
|
|
|
<Button defaultValue="confirm" variant='contained' color='secondary' onClick={this.handleClickOpenConfirmFiatReceived}>Confirm {this.props.data.currencyCode} received</Button>
|
2022-01-09 20:05:19 +00:00
|
|
|
</Grid>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
showOpenDisputeButton(){
|
|
|
|
// TODO, show alert about how opening a dispute might involve giving away personal data and might mean losing the bond. Ask for double confirmation.
|
|
|
|
return(
|
|
|
|
<Grid item xs={12} align="center">
|
2022-01-17 23:11:41 +00:00
|
|
|
<Button color="inherit" onClick={this.handleClickOpenConfirmDispute}>Open Dispute</Button>
|
2022-01-09 20:05:19 +00:00
|
|
|
</Grid>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-01-18 15:45:04 +00:00
|
|
|
showOrderExpired(){
|
|
|
|
return(
|
|
|
|
<Grid container spacing={1}>
|
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
<Typography component="subtitle1" variant="subtitle1">
|
|
|
|
<b>The order has expired</b>
|
|
|
|
</Typography>
|
|
|
|
</Grid>
|
|
|
|
</Grid>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-01-09 20:05:19 +00:00
|
|
|
showChat(sendFiatButton, receivedFiatButton, openDisputeButton){
|
|
|
|
return(
|
|
|
|
<Grid container spacing={1}>
|
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
<Typography component="subtitle1" variant="subtitle1">
|
|
|
|
<b>Chatting with {this.props.data.isMaker ? this.props.data.takerNick : this.props.data.makerNick}</b>
|
|
|
|
</Typography>
|
|
|
|
</Grid>
|
2022-01-13 20:41:48 +00:00
|
|
|
<Grid item xs={12} align="center">
|
2022-01-09 20:05:19 +00:00
|
|
|
{this.props.data.isSeller ?
|
2022-01-13 20:41:48 +00:00
|
|
|
<Typography component="body2" variant="body2" align="center">
|
|
|
|
Say hi! Be helpful and concise. Let him know how to send you {this.props.data.currencyCode}.
|
2022-01-09 20:05:19 +00:00
|
|
|
</Typography>
|
|
|
|
:
|
2022-01-13 20:41:48 +00:00
|
|
|
<Typography component="body2" variant="body2" align="center">
|
|
|
|
Say hi! Ask for payment details and click "Confirm Sent" as soon as the payment is sent.
|
2022-01-09 20:05:19 +00:00
|
|
|
</Typography>
|
|
|
|
}
|
2022-01-13 20:41:48 +00:00
|
|
|
<Divider/>
|
2022-01-09 20:05:19 +00:00
|
|
|
</Grid>
|
2022-01-13 19:22:54 +00:00
|
|
|
|
2022-01-14 00:43:26 +00:00
|
|
|
<Chat orderId={this.props.data.id} urNick={this.props.data.urNick}/>
|
2022-01-13 19:22:54 +00:00
|
|
|
|
2022-01-09 20:05:19 +00:00
|
|
|
<Grid item xs={12} align="center">
|
2022-01-13 19:22:54 +00:00
|
|
|
{openDisputeButton ? this.showOpenDisputeButton() : ""}
|
|
|
|
{sendFiatButton ? this.showFiatSentButton() : ""}
|
|
|
|
{receivedFiatButton ? this.showFiatReceivedButton() : ""}
|
2022-01-09 15:28:12 +00:00
|
|
|
</Grid>
|
2022-01-12 12:57:03 +00:00
|
|
|
{this.showBondIsLocked()}
|
2022-01-09 15:28:12 +00:00
|
|
|
</Grid>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2022-01-11 20:49:53 +00:00
|
|
|
showRateSelect(){
|
|
|
|
return(
|
|
|
|
<Grid container spacing={1}>
|
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
<Typography component="h6" variant="h6">
|
|
|
|
🎉Trade finished!🥳
|
|
|
|
</Typography>
|
|
|
|
</Grid>
|
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
<Typography component="body2" variant="body2" align="center">
|
|
|
|
What do you think of <b>{this.props.data.isMaker ? this.props.data.takerNick : this.props.data.makerNick}</b>?
|
|
|
|
</Typography>
|
|
|
|
</Grid>
|
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
<Rating name="size-large" defaultValue={2} size="large" onChange={this.handleRatingChange} />
|
|
|
|
</Grid>
|
|
|
|
<Grid item xs={12} align="center">
|
2022-01-17 23:11:41 +00:00
|
|
|
<Button color='primary' href='/' component="a">Start Again</Button>
|
2022-01-11 20:49:53 +00:00
|
|
|
</Grid>
|
|
|
|
</Grid>
|
|
|
|
)
|
|
|
|
}
|
2022-01-09 12:14:11 +00:00
|
|
|
|
2022-01-08 13:08:03 +00:00
|
|
|
render() {
|
|
|
|
return (
|
2022-01-08 15:34:09 +00:00
|
|
|
<Grid container spacing={1} style={{ width:330}}>
|
2022-01-17 23:11:41 +00:00
|
|
|
<this.ConfirmDisputeDialog/>
|
|
|
|
<this.ConfirmFiatReceivedDialog/>
|
2022-01-08 13:08:03 +00:00
|
|
|
<Grid item xs={12} align="center">
|
|
|
|
<Typography component="h5" variant="h5">
|
2022-01-17 16:41:55 +00:00
|
|
|
Contract Box
|
2022-01-08 13:08:03 +00:00
|
|
|
</Typography>
|
|
|
|
<Paper elevation={12} style={{ padding: 8,}}>
|
2022-01-09 12:14:11 +00:00
|
|
|
{/* Maker and taker Bond request */}
|
2022-01-09 14:07:05 +00:00
|
|
|
{this.props.data.bondInvoice ? this.showQRInvoice() : ""}
|
2022-01-09 12:14:11 +00:00
|
|
|
|
|
|
|
{/* Waiting for taker and taker bond request */}
|
2022-01-09 14:07:05 +00:00
|
|
|
{this.props.data.isMaker & this.props.data.statusCode == 1 ? this.showMakerWait() : ""}
|
|
|
|
{this.props.data.isMaker & this.props.data.statusCode == 3 ? this.showTakerFound() : ""}
|
2022-01-09 12:14:11 +00:00
|
|
|
|
|
|
|
{/* Send Invoice (buyer) and deposit collateral (seller) */}
|
2022-01-09 14:07:05 +00:00
|
|
|
{this.props.data.isSeller & this.props.data.escrowInvoice != null ? this.showEscrowQRInvoice() : ""}
|
|
|
|
{this.props.data.isBuyer & this.props.data.invoiceAmount != null ? this.showInputInvoice() : ""}
|
|
|
|
{this.props.data.isBuyer & this.props.data.statusCode == 7 ? this.showWaitingForEscrow() : ""}
|
|
|
|
{this.props.data.isSeller & this.props.data.statusCode == 8 ? this.showWaitingForBuyerInvoice() : ""}
|
2022-01-09 12:14:11 +00:00
|
|
|
|
2022-01-11 20:49:53 +00:00
|
|
|
{/* In Chatroom - No fiat sent - showChat(showSendButton, showReveiceButton, showDisputeButton) */}
|
2022-01-09 20:05:19 +00:00
|
|
|
{this.props.data.isBuyer & this.props.data.statusCode == 9 ? this.showChat(true,false,true) : ""}
|
|
|
|
{this.props.data.isSeller & this.props.data.statusCode == 9 ? this.showChat(false,false,true) : ""}
|
2022-01-11 20:49:53 +00:00
|
|
|
|
|
|
|
{/* In Chatroom - Fiat sent - showChat(showSendButton, showReveiceButton, showDisputeButton) */}
|
2022-01-09 20:05:19 +00:00
|
|
|
{this.props.data.isBuyer & this.props.data.statusCode == 10 ? this.showChat(false,false,true) : ""}
|
|
|
|
{this.props.data.isSeller & this.props.data.statusCode == 10 ? this.showChat(false,true,true) : ""}
|
2022-01-09 12:14:11 +00:00
|
|
|
|
|
|
|
{/* Trade Finished */}
|
2022-01-12 14:26:26 +00:00
|
|
|
{(this.props.data.isSeller & this.props.data.statusCode > 12 & this.props.data.statusCode < 15) ? this.showRateSelect() : ""}
|
|
|
|
{(this.props.data.isBuyer & this.props.data.statusCode == 14) ? this.showRateSelect() : ""}
|
2022-01-11 20:49:53 +00:00
|
|
|
|
|
|
|
{/* Trade Finished - Payment Routing Failed */}
|
|
|
|
{this.props.data.isBuyer & this.props.data.statusCode == 15 ? this.showUpdateInvoice() : ""}
|
|
|
|
|
2022-01-16 21:54:42 +00:00
|
|
|
{/* Trade Finished - TODO Needs more planning */}
|
|
|
|
{this.props.data.statusCode == 11 ? this.showInDisputeStatement() : ""}
|
2022-01-11 20:49:53 +00:00
|
|
|
|
2022-01-18 15:45:04 +00:00
|
|
|
{/* Order has expired */}
|
|
|
|
{this.props.data.statusCode == 5 ? this.showOrderExpired() : ""}
|
2022-01-09 12:14:11 +00:00
|
|
|
{/* TODO */}
|
|
|
|
{/* */}
|
|
|
|
{/* */}
|
|
|
|
|
2022-01-09 12:35:19 +00:00
|
|
|
|
2022-01-08 13:08:03 +00:00
|
|
|
</Paper>
|
|
|
|
</Grid>
|
|
|
|
</Grid>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|