diff --git a/api/models.py b/api/models.py
index bc7edd9f..9ad4be95 100644
--- a/api/models.py
+++ b/api/models.py
@@ -133,6 +133,27 @@ class Order(models.Model):
maker_cancel = models.ForeignKey(LNPayment, related_name='maker_cancel', on_delete=models.SET_NULL, null=True, default=None, blank=True)
taker_cancel = models.ForeignKey(LNPayment, related_name='taker_cancel', on_delete=models.SET_NULL, null=True, default=None, blank=True)
+ total_time_to_expire = {
+ 0 : int(config('EXP_MAKER_BOND_INVOICE')) , # 'Waiting for maker bond'
+ 1 : 60*60*int(config('PUBLIC_ORDER_DURATION')), # 'Public'
+ 2 : 0, # 'Deleted'
+ 3 : int(config('EXP_TAKER_BOND_INVOICE')), # 'Waiting for taker bond'
+ 4 : 0, # 'Cancelled'
+ 5 : 0, # 'Expired'
+ 6 : 60*int(config('INVOICE_AND_ESCROW_DURATION')), # 'Waiting for trade collateral and buyer invoice'
+ 7 : 60*int(config('INVOICE_AND_ESCROW_DURATION')), # 'Waiting only for seller trade collateral'
+ 8 : 60*int(config('INVOICE_AND_ESCROW_DURATION')), # 'Waiting only for buyer invoice'
+ 9 : 60*60*int(config('FIAT_EXCHANGE_DURATION')), # 'Sending fiat - In chatroom'
+ 10 : 60*60*int(config('FIAT_EXCHANGE_DURATION')), # 'Fiat sent - In chatroom'
+ 11 : 24*60*60, # 'In dispute'
+ 12 : 0, # 'Collaboratively cancelled'
+ 13 : 24*60*60, # 'Sending satoshis to buyer'
+ 14 : 24*60*60, # 'Sucessful trade'
+ 15 : 24*60*60, # 'Failed lightning network routing'
+ 16 : 24*60*60, # 'Maker lost dispute'
+ 17 : 24*60*60, # 'Taker lost dispute'
+ }
+
def __str__(self):
# Make relational back to ORDER
return (f'Order {self.id}: {self.Types(self.type).label} BTC for {float(self.amount)} {self.currency_dict[str(self.currency)]}')
diff --git a/api/views.py b/api/views.py
index 46dbd2d3..4d428cab 100644
--- a/api/views.py
+++ b/api/views.py
@@ -106,6 +106,7 @@ class OrderView(viewsets.ViewSet):
return Response({'bad_request':'This order has been cancelled collaborativelly'},status.HTTP_400_BAD_REQUEST)
data = ListOrderSerializer(order).data
+ data['total_secs_exp'] = Order.total_time_to_expire[order.status]
# if user is under a limit (penalty), inform him.
is_penalized, time_out = Logics.is_penalized(request.user)
@@ -116,12 +117,21 @@ class OrderView(viewsets.ViewSet):
data['is_maker'] = order.maker == request.user
data['is_taker'] = order.taker == request.user
data['is_participant'] = data['is_maker'] or data['is_taker']
- data['ur_nick'] = request.user.username
- # 3) If not a participant and order is not public, forbid.
+ # 3.a) If not a participant and order is not public, forbid.
if not data['is_participant'] and order.status != Order.Status.PUB:
return Response({'bad_request':'You are not allowed to see this order'},status.HTTP_403_FORBIDDEN)
+ # 3.b If public
+ if order.status == Order.Status.PUB:
+ data['price_now'], data['premium_now'] = Logics.price_and_premium_now(order)
+
+ # 3. c) If maker and Public, add num robots in book, premium percentile and num similar orders.
+ if data['is_maker']:
+ data['robots_in_book'] = None # TODO
+ data['premium_percentile'] = None # TODO
+ data['num_similar_orders'] = len(Order.objects.filter(currency=order.currency, status=Order.Status.PUB))
+
# 4) Non participants can view details (but only if PUB)
elif not data['is_participant'] and order.status != Order.Status.PUB:
return Response(data, status=status.HTTP_200_OK)
@@ -134,6 +144,7 @@ class OrderView(viewsets.ViewSet):
data['status_message'] = Order.Status(order.status).label
data['is_fiat_sent'] = order.is_fiat_sent
data['is_disputed'] = order.is_disputed
+ data['ur_nick'] = request.user.username
# If both bonds are locked, participants can see the final trade amount in sats.
if order.taker_bond:
@@ -281,14 +292,14 @@ class UserView(APIView):
Response with Avatar and Nickname.
'''
- # if request.user.id:
- # context = {}
- # context['nickname'] = request.user.username
- # participant = not Logics.validate_already_maker_or_taker(request.user)
- # context['bad_request'] = f'You are already logged in as {request.user}'
- # if participant:
- # context['bad_request'] = f'You are already logged in as as {request.user} and have an active order'
- # return Response(context,status.HTTP_200_OK)
+ if request.user.id:
+ context = {}
+ context['nickname'] = request.user.username
+ participant = not Logics.validate_already_maker_or_taker(request.user)
+ context['bad_request'] = f'You are already logged in as {request.user}'
+ if participant:
+ context['bad_request'] = f'You are already logged in as as {request.user} and have an active order'
+ return Response(context,status.HTTP_200_OK)
token = request.GET.get(self.lookup_url_kwarg)
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 90a612e0..cf8cd9f7 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -1581,6 +1581,14 @@
"react-is": "^17.0.2"
}
},
+ "@mui/icons-material": {
+ "version": "5.2.5",
+ "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.2.5.tgz",
+ "integrity": "sha512-uQiUz+l0xy+2jExyKyU19MkMAR2F7bQFcsQ5hdqAtsB14Jw2zlmIAD55mV6f0NxKCut7Rx6cA3ZpfzlzAfoK8Q==",
+ "requires": {
+ "@babel/runtime": "^7.16.3"
+ }
+ },
"@mui/material": {
"version": "5.2.7",
"resolved": "https://registry.npmjs.org/@mui/material/-/material-5.2.7.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index 15fb2128..55a83e36 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -26,6 +26,7 @@
"@emotion/styled": "^11.6.0",
"@material-ui/core": "^4.12.3",
"@material-ui/icons": "^4.11.2",
+ "@mui/icons-material": "^5.2.5",
"@mui/material": "^5.2.7",
"@mui/system": "^5.2.6",
"material-ui-image": "^3.3.2",
diff --git a/frontend/src/components/OrderPage.js b/frontend/src/components/OrderPage.js
index f4bee0a2..5a1820c9 100644
--- a/frontend/src/components/OrderPage.js
+++ b/frontend/src/components/OrderPage.js
@@ -1,8 +1,15 @@
import React, { Component } from "react";
-import { Alert, Paper, CircularProgress, Button , Grid, Typography, List, ListItem, ListItemText, ListItemAvatar, Avatar, Divider, Box, LinearProgress} from "@mui/material"
+import { Alert, Paper, CircularProgress, Button , Grid, Typography, List, ListItem, ListItemIcon, ListItemText, ListItemAvatar, Avatar, Divider, Box, LinearProgress} from "@mui/material"
import Countdown, { zeroPad, calcTimeDelta } from 'react-countdown';
import TradeBox from "./TradeBox";
+// icons
+import AccessTimeIcon from '@mui/icons-material/AccessTime';
+import NumbersIcon from '@mui/icons-material/Numbers';
+import PriceChangeIcon from '@mui/icons-material/PriceChange';
+import PaymentsIcon from '@mui/icons-material/Payments';
+import MoneyIcon from '@mui/icons-material/Money';
+import ArticleIcon from '@mui/icons-material/Article';
function getCookie(name) {
let cookieValue = null;
@@ -75,6 +82,13 @@ export default class OrderPage extends Component {
escrowInvoice: data.escrow_invoice,
escrowSatoshis: data.escrow_satoshis,
invoiceAmount: data.invoice_amount,
+ total_secs_expiry: data.total_secs_exp,
+ numSimilarOrders: data.num_similar_orders,
+ priceNow: data.price_now,
+ premiumNow: data.premium_now,
+ robotsInBook: data.robots_in_book,
+ premiumPercentile: data.premium_percentile,
+ numSimilarOrders: data.num_similar_orders
})
});
}
@@ -106,15 +120,15 @@ export default class OrderPage extends Component {
if (completed) {
// Render a completed state
this.getOrderDetails();
+ return null;
} else {
var col = 'black'
var fraction_left = (total/1000) / this.state.total_secs_expiry
- console.log(fraction_left)
- // Make orange at -25% of time left
+ // Make orange at 25% of time left
if (fraction_left < 0.25){col = 'orange'}
// Make red at 10% of time left
if (fraction_left < 0.1){col = 'red'}
- // Render a countdown
+ // Render a countdown, bold when less than 25%
return (
fraction_left < 0.25 ? {hours}h {zeroPad(minutes)}m {zeroPad(seconds)}s
:{hours}h {zeroPad(minutes)}m {zeroPad(seconds)}s
@@ -226,6 +240,9 @@ export default class OrderPage extends Component {
""
}
+
+
+
@@ -234,28 +251,49 @@ export default class OrderPage extends Component {
}
+
+
+
+
+
+
+
+ {/* If there is live Price and Premium data, show it. Otherwise show the order maker settings */}
- {this.state.isExplicit ?
-
- :
-
- }
+
+
+
+ {this.state.priceNow?
+
+ :
+ (this.state.isExplicit ?
+
+ :
+
+ )
+ }
-
+
+
+
+
-
+
+
+
+
diff --git a/frontend/src/components/TradeBox.js b/frontend/src/components/TradeBox.js
index 450bb0a3..972d3dfe 100644
--- a/frontend/src/components/TradeBox.js
+++ b/frontend/src/components/TradeBox.js
@@ -163,7 +163,7 @@ export default class TradeBox extends Component {
-
+
diff --git a/setup.md b/setup.md
index caca25f6..366747dc 100644
--- a/setup.md
+++ b/setup.md
@@ -115,6 +115,7 @@ npm install @mui/material
npm install react-markdown
npm install websocket
npm install react-countdown
+npm install @mui/icons-material
```
Note we are using mostly MaterialUI V5 (@mui/material) but Image loading from V4 (@material-ui/core) extentions (so both V4 and V5 are needed)