mirror of
https://github.com/RoboSats/robosats.git
synced 2025-01-31 10:31:35 +00:00
Invoice input
This commit is contained in:
parent
185e0af496
commit
5dcb249bb3
@ -86,7 +86,6 @@ class Order(models.Model):
|
|||||||
|
|
||||||
currency_dict = json.load(open('./api/currencies.json'))
|
currency_dict = json.load(open('./api/currencies.json'))
|
||||||
currency_choices = [(int(val), label) for val, label in list(currency_dict.items())]
|
currency_choices = [(int(val), label) for val, label in list(currency_dict.items())]
|
||||||
print(currency_choices)
|
|
||||||
|
|
||||||
# order info
|
# order info
|
||||||
status = models.PositiveSmallIntegerField(choices=Status.choices, null=False, default=Status.WFB)
|
status = models.PositiveSmallIntegerField(choices=Status.choices, null=False, default=Status.WFB)
|
||||||
|
@ -67,7 +67,7 @@ export default class OrderPage extends Component {
|
|||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
isExplicit: false,
|
isExplicit: false,
|
||||||
delay: 5000, // Refresh every 5 seconds
|
delay: 10000, // Refresh every 10 seconds
|
||||||
currencies_dict: {"1":"USD"}
|
currencies_dict: {"1":"USD"}
|
||||||
};
|
};
|
||||||
this.orderId = this.props.match.params.orderId;
|
this.orderId = this.props.match.params.orderId;
|
||||||
@ -79,8 +79,9 @@ export default class OrderPage extends Component {
|
|||||||
this.setState(null)
|
this.setState(null)
|
||||||
fetch('/api/order' + '?order_id=' + this.orderId)
|
fetch('/api/order' + '?order_id=' + this.orderId)
|
||||||
.then((response) => response.json())
|
.then((response) => response.json())
|
||||||
.then((data) => {
|
.then((data) => {console.log(data) &
|
||||||
this.setState({
|
this.setState({
|
||||||
|
id: data.id,
|
||||||
statusCode: data.status,
|
statusCode: data.status,
|
||||||
statusText: data.status_message,
|
statusText: data.status_message,
|
||||||
type: data.type,
|
type: data.type,
|
||||||
@ -203,7 +204,7 @@ export default class OrderPage extends Component {
|
|||||||
src={window.location.origin +'/static/assets/avatars/' + this.state.makerNick + '.png'}
|
src={window.location.origin +'/static/assets/avatars/' + this.state.makerNick + '.png'}
|
||||||
/>
|
/>
|
||||||
</ListItemAvatar>
|
</ListItemAvatar>
|
||||||
<ListItemText primary={this.state.makerNick + (this.state.type ? " (Buyer)" : " (Seller)")} secondary="Order maker" align="right"/>
|
<ListItemText primary={this.state.makerNick + (this.state.type ? " (Seller)" : " (Buyer)")} secondary="Order maker" align="right"/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<Divider />
|
<Divider />
|
||||||
|
|
||||||
@ -212,7 +213,7 @@ export default class OrderPage extends Component {
|
|||||||
{this.state.takerNick!='None' ?
|
{this.state.takerNick!='None' ?
|
||||||
<>
|
<>
|
||||||
<ListItem align="left">
|
<ListItem align="left">
|
||||||
<ListItemText primary={this.state.takerNick + (this.state.type ? " (Seller)" : " (Buyer)")} secondary="Order taker"/>
|
<ListItemText primary={this.state.takerNick + (this.state.type ? " (Buyer)" : " (Seller)")} secondary="Order taker"/>
|
||||||
<ListItemAvatar >
|
<ListItemAvatar >
|
||||||
<Avatar
|
<Avatar
|
||||||
alt={this.state.makerNick}
|
alt={this.state.makerNick}
|
||||||
|
@ -1,36 +1,32 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from "react";
|
||||||
import { Paper, FormControl , Grid, Typography, FormHelperText, TextField, List, ListItem, ListItemText, Divider} from "@material-ui/core"
|
import { Paper, Button, Grid, Typography, TextField, List, ListItem, ListItemText, Divider} from "@material-ui/core"
|
||||||
import QRCode from "react-qr-code";
|
import QRCode from "react-qr-code";
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cookieValue;
|
||||||
|
}
|
||||||
|
const csrftoken = getCookie('csrftoken');
|
||||||
|
|
||||||
|
// pretty numbers
|
||||||
|
function pn(x) {
|
||||||
|
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||||
|
}
|
||||||
|
|
||||||
export default class TradeBox extends Component {
|
export default class TradeBox extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
|
||||||
delay: 100, // checks for new state in OrderPage ever 100 ms
|
|
||||||
};
|
|
||||||
this.data = this.props.data
|
|
||||||
}
|
|
||||||
|
|
||||||
// These are used to refresh the data
|
|
||||||
componentDidMount() {
|
|
||||||
this.interval = setInterval(this.tick, this.state.delay);
|
|
||||||
}
|
|
||||||
componentDidUpdate(prevProps, prevState) {
|
|
||||||
if (prevState.delay !== this.state.delay) {
|
|
||||||
clearInterval(this.interval);
|
|
||||||
this.interval = setInterval(this.tick, this.state.delay);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
componentWillUnmount() {
|
|
||||||
clearInterval(this.interval);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
handleDelayChange = (e) => {
|
|
||||||
this.setState({ delay: Number(e.target.value) });
|
|
||||||
}
|
|
||||||
tick = () => {
|
|
||||||
this.data = this.props.data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
showQRInvoice=()=>{
|
showQRInvoice=()=>{
|
||||||
@ -42,25 +38,25 @@ export default class TradeBox extends Component {
|
|||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} align="center">
|
<Grid item xs={12} align="center">
|
||||||
{this.data.isMaker ?
|
{this.props.data.isMaker ?
|
||||||
<Typography component="subtitle1" variant="subtitle1">
|
<Typography component="subtitle1" variant="subtitle1">
|
||||||
<b>Lock {this.data.bondSatoshis} Sats to PUBLISH order </b>
|
<b>Lock {pn(this.props.data.bondSatoshis)} Sats to PUBLISH order </b>
|
||||||
</Typography>
|
</Typography>
|
||||||
:
|
:
|
||||||
<Typography component="subtitle1" variant="subtitle1">
|
<Typography component="subtitle1" variant="subtitle1">
|
||||||
<b>Lock {this.data.bondSatoshis} Sats to TAKE the order </b>
|
<b>Lock {pn(this.props.data.bondSatoshis)} Sats to TAKE the order </b>
|
||||||
</Typography>
|
</Typography>
|
||||||
}
|
}
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} align="center">
|
<Grid item xs={12} align="center">
|
||||||
<QRCode value={this.data.bondInvoice} size={305}/>
|
<QRCode value={this.props.data.bondInvoice} size={305}/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} align="center">
|
<Grid item xs={12} align="center">
|
||||||
<TextField
|
<TextField
|
||||||
hiddenLabel
|
hiddenLabel
|
||||||
variant="filled"
|
variant="filled"
|
||||||
size="small"
|
size="small"
|
||||||
defaultValue={this.data.bondInvoice}
|
defaultValue={this.props.data.bondInvoice}
|
||||||
disabled="true"
|
disabled="true"
|
||||||
helperText="This is a HODL LN invoice. It will not be charged if the order succeeds or expires.
|
helperText="This is a HODL LN invoice. It will not be charged if the order succeeds or expires.
|
||||||
It will be charged if the order is cancelled or you lose a dispute."
|
It will be charged if the order is cancelled or you lose a dispute."
|
||||||
@ -75,18 +71,18 @@ export default class TradeBox extends Component {
|
|||||||
<Grid container spacing={1}>
|
<Grid container spacing={1}>
|
||||||
<Grid item xs={12} align="center">
|
<Grid item xs={12} align="center">
|
||||||
<Typography component="subtitle1" variant="subtitle1">
|
<Typography component="subtitle1" variant="subtitle1">
|
||||||
<b>Deposit {this.data.escrowSatoshis} Sats as trade collateral </b>
|
<b>Deposit {pn(this.props.data.escrowSatoshis)} Sats as trade collateral </b>
|
||||||
</Typography>
|
</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} align="center">
|
<Grid item xs={12} align="center">
|
||||||
<QRCode value={this.data.escrowInvoice} size={305}/>
|
<QRCode value={this.props.data.escrowInvoice} size={305}/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={12} align="center">
|
<Grid item xs={12} align="center">
|
||||||
<TextField
|
<TextField
|
||||||
hiddenLabel
|
hiddenLabel
|
||||||
variant="filled"
|
variant="filled"
|
||||||
size="small"
|
size="small"
|
||||||
defaultValue={this.data.escrowInvoice}
|
defaultValue={this.props.data.escrowInvoice}
|
||||||
disabled="true"
|
disabled="true"
|
||||||
helperText="This is a HODL LN invoice. It will be charged once the buyer confirms he sent the fiat."
|
helperText="This is a HODL LN invoice. It will be charged once the buyer confirms he sent the fiat."
|
||||||
color = "secondary"
|
color = "secondary"
|
||||||
@ -98,7 +94,7 @@ export default class TradeBox extends Component {
|
|||||||
|
|
||||||
showTakerFound=()=>{
|
showTakerFound=()=>{
|
||||||
|
|
||||||
// Make some sound here! The maker might have been waiting for long
|
// TODO Make some sound here! The maker might have been waiting for long
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid container spacing={1}>
|
<Grid container spacing={1}>
|
||||||
@ -147,7 +143,7 @@ export default class TradeBox extends Component {
|
|||||||
|
|
||||||
<Divider/>
|
<Divider/>
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<ListItemText primary={999} secondary={"Active orders for" + this.data.currencyCode}/>
|
<ListItemText primary={999} secondary={"Active orders for " + this.props.data.currencyCode}/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
|
||||||
<Divider/>
|
<Divider/>
|
||||||
@ -160,13 +156,66 @@ export default class TradeBox extends Component {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// showInputInvoice(){
|
handleInputInvoiceChanged=(e)=>{
|
||||||
|
this.setState({
|
||||||
|
invoice: e.target.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// }
|
handleClickSubmitInvoiceButton=()=>{
|
||||||
|
console.log(this.state)
|
||||||
|
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())
|
||||||
|
.then((data) => (this.props.data = data));
|
||||||
|
}
|
||||||
|
|
||||||
// showWaitingForEscrow(){
|
showInputInvoice(){
|
||||||
|
return (
|
||||||
|
|
||||||
// }
|
// TODO Camera option to read QR
|
||||||
|
|
||||||
|
<Grid container spacing={1}>
|
||||||
|
<Grid item xs={12} align="center">
|
||||||
|
<Typography component="subtitle1" variant="subtitle1">
|
||||||
|
<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>
|
||||||
|
<Grid item xs={12} align="center">
|
||||||
|
<TextField
|
||||||
|
label={"Payout Lightning Invoice"}
|
||||||
|
required
|
||||||
|
inputProps={{
|
||||||
|
style: {textAlign:"center"}
|
||||||
|
}}
|
||||||
|
multiline
|
||||||
|
onChange={this.handleInputInvoiceChanged}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} align="center">
|
||||||
|
<Button variant='contained' color='primary' onClick={this.handleClickSubmitInvoiceButton}>Submit</Button>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
showWaitingForEscrow(){
|
||||||
|
|
||||||
|
}
|
||||||
// showWaitingForBuyerInvoice({
|
// showWaitingForBuyerInvoice({
|
||||||
|
|
||||||
// })
|
// })
|
||||||
@ -196,26 +245,26 @@ export default class TradeBox extends Component {
|
|||||||
</Typography>
|
</Typography>
|
||||||
<Paper elevation={12} style={{ padding: 8,}}>
|
<Paper elevation={12} style={{ padding: 8,}}>
|
||||||
{/* Maker and taker Bond request */}
|
{/* Maker and taker Bond request */}
|
||||||
{this.data.bondInvoice ? this.showQRInvoice() : ""}
|
{this.props.data.bondInvoice ? this.showQRInvoice() : ""}
|
||||||
|
|
||||||
{/* Waiting for taker and taker bond request */}
|
{/* Waiting for taker and taker bond request */}
|
||||||
{this.data.isMaker & this.data.statusCode == 1 ? this.showMakerWait() : ""}
|
{this.props.data.isMaker & this.props.data.statusCode == 1 ? this.showMakerWait() : ""}
|
||||||
{this.data.isMaker & this.data.statusCode == 3 ? this.showTakerFound() : ""}
|
{this.props.data.isMaker & this.props.data.statusCode == 3 ? this.showTakerFound() : ""}
|
||||||
|
|
||||||
{/* Send Invoice (buyer) and deposit collateral (seller) */}
|
{/* Send Invoice (buyer) and deposit collateral (seller) */}
|
||||||
{this.data.isSeller & this.data.escrowInvoice != null ? this.showEscrowQRInvoice() : ""}
|
{this.props.data.isSeller & this.props.data.escrowInvoice != null ? this.showEscrowQRInvoice() : ""}
|
||||||
{this.data.isBuyer & this.data.invoiceAmount != null ? this.showInputInvoice() : ""}
|
{this.props.data.isBuyer & this.props.data.invoiceAmount != null ? this.showInputInvoice() : ""}
|
||||||
{this.data.isBuyer & this.data.statusCode == 7 ? this.showWaitingForEscrow() : ""}
|
{this.props.data.isBuyer & this.props.data.statusCode == 7 ? this.showWaitingForEscrow() : ""}
|
||||||
{this.data.isSeller & this.data.statusCode == 8 ? this.showWaitingForBuyerInvoice() : ""}
|
{this.props.data.isSeller & this.props.data.statusCode == 8 ? this.showWaitingForBuyerInvoice() : ""}
|
||||||
|
|
||||||
{/* In Chatroom */}
|
{/* In Chatroom */}
|
||||||
{this.data.isBuyer & this.data.statusCode == 9 ? this.showChat() & this.showFiatSentButton() : ""}
|
{this.props.data.isBuyer & this.props.data.statusCode == 9 ? this.showChat() & this.showFiatSentButton() : ""}
|
||||||
{this.data.isSeller & this.data.statusCode ==9 ? this.showChat() : ""}
|
{this.props.data.isSeller & this.props.data.statusCode ==9 ? this.showChat() : ""}
|
||||||
{this.data.isBuyer & this.data.statusCode == 10 ? this.showChat() & this.showOpenDisputeButton() : ""}
|
{this.props.data.isBuyer & this.props.data.statusCode == 10 ? this.showChat() & this.showOpenDisputeButton() : ""}
|
||||||
{this.data.isSeller & this.data.statusCode == 10 ? this.showChat() & this.showFiatReceivedButton() & this.showOpenDisputeButton(): ""}
|
{this.props.data.isSeller & this.props.data.statusCode == 10 ? this.showChat() & this.showFiatReceivedButton() & this.showOpenDisputeButton(): ""}
|
||||||
|
|
||||||
{/* Trade Finished */}
|
{/* Trade Finished */}
|
||||||
{this.data.isSeller & this.data.statusCode > 12 & this.data.statusCode < 15 ? this.showRateSelect() : ""}
|
{this.props.data.isSeller & this.props.data.statusCode > 12 & this.props.data.statusCode < 15 ? this.showRateSelect() : ""}
|
||||||
{/* TODO */}
|
{/* TODO */}
|
||||||
{/* */}
|
{/* */}
|
||||||
{/* */}
|
{/* */}
|
||||||
|
4
setup.md
4
setup.md
@ -66,7 +66,9 @@ npm install react-router-dom@5.2.0
|
|||||||
npm install @material-ui/icons
|
npm install @material-ui/icons
|
||||||
npm install material-ui-image
|
npm install material-ui-image
|
||||||
npm install @mui/system @emotion/react @emotion/styled
|
npm install @mui/system @emotion/react @emotion/styled
|
||||||
npm install qrcodejs
|
npm install react-native
|
||||||
|
npm install react-native-svg
|
||||||
|
npm install react-qr-code
|
||||||
```
|
```
|
||||||
|
|
||||||
### Launch the React render
|
### Launch the React render
|
||||||
|
Loading…
Reference in New Issue
Block a user