Add Lock Invoice box

This commit is contained in:
Reckless_Satoshi 2022-11-02 10:32:32 -07:00
parent 040ecaeca7
commit b25d59ba38
No known key found for this signature in database
GPG Key ID: 9C4585B561315571
4 changed files with 262 additions and 135 deletions

View File

@ -0,0 +1,44 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Box, Typography } from '@mui/material';
import { Lock, LockOpen, Balance } from '@mui/icons-material';
interface BondStatusProps {
status: 'locked' | 'settled' | 'returned' | 'hide';
isMaker: boolean;
}
const BondStatus = ({ status, isMaker }: BondStatusProps): JSX.Element => {
const { t } = useTranslation();
let Icon = Lock;
if (status === 'returned') {
Icon = LockOpen;
} else if (status === 'settled') {
Icon = Balance;
}
if (status === 'hide') {
return <></>;
} else {
return (
<Box>
<Typography color='primary' variant='subtitle1' align='center'>
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexWrap: 'wrap',
}}
>
<Icon />
{t(`Your ${isMaker ? 'maker' : 'taker'} bond is ${status}`)}
</div>
</Typography>
</Box>
);
}
};
export default BondStatus;

View File

@ -0,0 +1,148 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import {
Button,
Grid,
Link,
Typography,
TextField,
Tooltip,
useTheme,
Divider,
} from '@mui/material';
import { AccountBalanceWallet, ContentCopy } from '@mui/icons-material';
import { NewTabIcon } from '../Icons';
import QRCode from 'react-qr-code';
import { Order } from '../../models';
import { systemClient } from '../../services/System';
import currencyDict from '../../../static/assets/currencies.json';
import stepXofY from './stepXofY';
import { pn } from '../../utils';
interface LockInvoiceBoxProps {
order: Order;
concept: 'bond' | 'escrow';
}
export const LockInvoiceBox = ({ order, concept }: LockInvoiceBoxProps): JSX.Element => {
const { t } = useTranslation();
const theme = useTheme();
const currencyCode = currencyDict[order.currency.toString()];
const invoice = concept === 'bond' ? order.bond_invoice : order.escrow_invoice;
const amountSats = concept === 'bond' ? order.bond_satoshis : order.escrow_satoshis;
const helperText =
concept === 'bond'
? t(
'This is a hold invoice, it will freeze in your wallet. It will be charged only if you cancel or lose a dispute.',
)
: t(
'This is a hold invoice, it will freeze in your wallet. It will be released to the buyer once you confirm to have received the {{currencyCode}}.',
{ currencyCode },
);
const Title = function () {
let text = `Lock {{amountSats}} Sats to ${order.is_maker ? 'PUBLISH' : 'TAKE'} order`;
if (concept === 'escrow') {
text = 'Lock {{amountSats}} Sats as collateral';
}
return (
<Typography color='primary' variant='subtitle1'>
<b>
{t(text, {
amountSats: pn(amountSats),
})}
</b>
{` ${stepXofY(order)}`}
</Typography>
);
};
const CompatibleWalletsButton = function () {
return (
<Button
color='primary'
component={Link}
href={'https://learn.robosats.com/docs/wallets/'}
target='_blank'
align='center'
>
<AccountBalanceWallet />
{t('See Compatible Wallets')}
<NewTabIcon sx={{ width: '1.1em', height: '1.1em' }} />
</Button>
);
};
const depositHoursMinutes = function () {
const hours = parseInt(order.escrow_duration / 3600);
const minutes = parseInt((order.escrow_duration - hours * 3600) / 60);
const dict = { deposit_timer_hours: hours, deposit_timer_minutes: minutes };
return dict;
};
const ExpirationWarning = function () {
return (
<Typography variant='body2'>
{t(
'You risk losing your bond if you do not lock the collateral. Total time available is {{deposit_timer_hours}}h {{deposit_timer_minutes}}m.',
depositHoursMinutes(),
)}
</Typography>
);
};
return (
<Grid container spacing={1}>
<Grid item xs={12}>
<Title />
</Grid>
<Divider />
<Grid item xs={12}>
{concept === 'bond' ? <CompatibleWalletsButton /> : <ExpirationWarning />}
</Grid>
<Grid item xs={12}>
<Tooltip disableHoverListener enterTouchDelay={0} title={t('Copied!')}>
<QRCode
bgColor={'rgba(255, 255, 255, 0)'}
fgColor={theme.palette.text.primary}
value={invoice}
size={theme.typography.fontSize * 21.8}
onClick={() => {
systemClient.copyToClipboard(invoice);
}}
/>
</Tooltip>
<Tooltip disableHoverListener enterTouchDelay={0} title={t('Copied!')}>
<Button
size='small'
color='inherit'
onClick={() => {
systemClient.copyToClipboard(invoice);
}}
>
<ContentCopy />
{t('Copy to clipboard')}
</Button>
</Tooltip>
</Grid>
<Grid item xs={12}>
<TextField
hiddenLabel
variant='standard'
size='small'
defaultValue={invoice}
disabled={true}
helperText={helperText}
color='secondary'
/>
</Grid>
</Grid>
);
};
export default LockInvoiceBox;

View File

@ -26,6 +26,7 @@ import {
DialogContent, DialogContent,
DialogContentText, DialogContentText,
DialogTitle, DialogTitle,
dividerClasses,
} from '@mui/material'; } from '@mui/material';
import { LoadingButton } from '@mui/lab'; import { LoadingButton } from '@mui/lab';
import QRCode from 'react-qr-code'; import QRCode from 'react-qr-code';
@ -35,6 +36,7 @@ import TradeSummary from './TradeSummary';
import { systemClient } from '../../services/System'; import { systemClient } from '../../services/System';
import { apiClient } from '../../services/api'; import { apiClient } from '../../services/api';
import { ConfirmDisputeDialog, ConfirmFiatReceivedDialog } from './Dialogs'; import { ConfirmDisputeDialog, ConfirmFiatReceivedDialog } from './Dialogs';
import BondStatus from './BondStatus';
// Icons // Icons
import { import {
@ -120,50 +122,6 @@ const defaultLightning: LightningFormProps = {
badLnproxy: '', badLnproxy: '',
}; };
const stepXofY = function (order: Order) {
// set y value
let x = null;
let y = null;
if (order.is_maker) {
y = 5;
} else if (order.is_taker) {
y = 4;
}
// set x values
if (order.is_maker) {
if (order.status === 0) {
x = 1;
} else if ([1, 2, 3].includes(order.status)) {
x = 2;
} else if ([6, 7, 8].includes(order.status)) {
x = 3;
} else if (order.status === 9) {
x = 4;
} else if (order.status === 10) {
x = 5;
}
} else if (order.is_taker) {
if (order.status === 3) {
x = 1;
} else if ([6, 7, 8].includes(order.status)) {
x = 2;
} else if (order.status === 9) {
x = 3;
} else if (order.status === 10) {
x = 4;
}
}
// Return "(x/y)"
if (x != null && y != null) {
return `(${x}/${y})`;
} else {
return '';
}
};
interface TradeBoxProps { interface TradeBoxProps {
order: Order; order: Order;
setOrder: (state: Order) => void; setOrder: (state: Order) => void;
@ -217,6 +175,11 @@ const TradeBox = ({ order, setOrder }: TradeBoxProps): JSX.Element => {
onClose={() => setOpen(closeAll)} onClose={() => setOpen(closeAll)}
onAgreeClick={onClickAgreeOpenDispute} onAgreeClick={onClickAgreeOpenDispute}
/> />
<StepContent />
<Divider />
<BondStatus />
<ConfirmFiatReceivedDialog <ConfirmFiatReceivedDialog
open={open.confirmFiatReceived} open={open.confirmFiatReceived}
order={order} order={order}
@ -229,17 +192,13 @@ const TradeBox = ({ order, setOrder }: TradeBoxProps): JSX.Element => {
}; };
export default TradeBox; export default TradeBox;
// class TradeBox extends Component { // class TradeBox extends Component {
// showQRInvoice = () => { // showQRInvoice = () => {
// const { t } = this.props; // const { t } = this.props;
// return ( // return (
// <Grid container spacing={1}> // <Grid container spacing={1}>
// {/* <Grid item xs={12} align="center">
// <Typography variant="body2">
// {t("Robots show commitment to their peers")}
// </Typography>
// </Grid> */}
// <Grid item xs={12} align='center'> // <Grid item xs={12} align='center'>
// {this.props.data.is_maker ? ( // {this.props.data.is_maker ? (
// <Typography color='primary' variant='subtitle1'> // <Typography color='primary' variant='subtitle1'>
@ -305,77 +264,6 @@ export default TradeBox;
// ); // );
// }; // };
// showBondIsLocked = () => {
// const { t } = this.props;
// return (
// <Grid item xs={12} align='center'>
// <Typography color='primary' variant='subtitle1' align='center'>
// <div
// style={{
// display: 'flex',
// alignItems: 'center',
// justifyContent: 'center',
// flexWrap: 'wrap',
// }}
// >
// <LockIcon />
// {this.props.data.is_maker
// ? t('Your maker bond is locked')
// : t('Your taker bond is locked')}
// </div>
// </Typography>
// </Grid>
// );
// };
// showBondIsSettled = () => {
// const { t } = this.props;
// return (
// <Grid item xs={12} align='center'>
// <Typography color='error' variant='subtitle1' align='center'>
// <div
// style={{
// display: 'flex',
// alignItems: 'center',
// justifyContent: 'center',
// flexWrap: 'wrap',
// align: 'center',
// }}
// align='center'
// >
// <BalanceIcon />
// {this.props.data.is_maker
// ? t('Your maker bond was settled')
// : t('Your taker bond was settled')}
// </div>
// </Typography>
// </Grid>
// );
// };
// showBondIsReturned = () => {
// const { t } = this.props;
// return (
// <Grid item xs={12} align='center'>
// <Typography color='green' variant='subtitle1' align='center'>
// <div
// style={{
// display: 'flex',
// alignItems: 'center',
// justifyContent: 'center',
// flexWrap: 'wrap',
// }}
// >
// <LockOpenIcon />
// {this.props.data.is_maker
// ? t('Your maker bond was unlocked')
// : t('Your taker bond was unlocked')}
// </div>
// </Typography>
// </Grid>
// );
// };
// showEscrowQRInvoice = () => { // showEscrowQRInvoice = () => {
// const { t } = this.props; // const { t } = this.props;
// return ( // return (
@ -436,7 +324,7 @@ export default TradeBox;
// color='secondary' // color='secondary'
// /> // />
// </Grid> // </Grid>
// {this.showBondIsLocked()} // <BondStatus status={'locked'} isMaker={order.is_maker}/>
// </Grid> // </Grid>
// ); // );
// }; // };
@ -460,7 +348,7 @@ export default TradeBox;
// )} // )}
// </Typography> // </Typography>
// </Grid> // </Grid>
// {this.showBondIsLocked()} // // <BondStatus status={'locked'} isMaker={order.is_maker}/>
// </Grid> // </Grid>
// ); // );
// }; // };
@ -567,7 +455,7 @@ export default TradeBox;
// <Divider /> // <Divider />
// </List> // </List>
// </Grid> // </Grid>
// {this.showBondIsLocked()} // // <BondStatus status={'locked'} isMaker={order.is_maker}/>
// </Grid> // </Grid>
// ); // );
// }; // };
@ -607,7 +495,7 @@ export default TradeBox;
// <Divider /> // <Divider />
// </List> // </List>
// </Grid> // </Grid>
// {this.showBondIsLocked()} // // <BondStatus status={'locked'} isMaker={order.is_maker}/>
// </Grid> // </Grid>
// ); // );
// }; // };
@ -950,7 +838,7 @@ export default TradeBox;
// <Divider /> // <Divider />
// </List> // </List>
// {this.showBondIsLocked()} // // <BondStatus status={'locked'} isMaker={order.is_maker}/>
// </Grid> // </Grid>
// ); // );
// } // }
@ -986,7 +874,7 @@ export default TradeBox;
// <Divider /> // <Divider />
// </List> // </List>
// </Grid> // </Grid>
// {this.showBondIsSettled()} // // <BondStatus status={'settled'} isMaker={order.is_maker}/>
// </Grid> // </Grid>
// ); // );
// } else { // } else {
@ -1033,7 +921,7 @@ export default TradeBox;
// </Button> // </Button>
// </Grid> // </Grid>
// </List> // </List>
// {this.showBondIsSettled()} // // <BondStatus status={'settled'} isMaker={order.is_maker}/>
// </Grid> // </Grid>
// ); // );
// } // }
@ -1068,7 +956,7 @@ export default TradeBox;
// <Divider /> // <Divider />
// </List> // </List>
// </Grid> // </Grid>
// {this.showBondIsSettled()} // // <BondStatus status={'settled'} isMaker={order.is_maker}/>
// </Grid> // </Grid>
// ); // );
// }; // };
@ -1089,7 +977,7 @@ export default TradeBox;
// )} // )}
// </Typography> // </Typography>
// </Grid> // </Grid>
// {this.showBondIsSettled()} // // <BondStatus status={'settled'} isMaker={order.is_maker}/>
// </Grid> // </Grid>
// ); // );
// }; // };
@ -1110,7 +998,7 @@ export default TradeBox;
// )} // )}
// </Typography> // </Typography>
// </Grid> // </Grid>
// {this.showBondIsSettled()} // // <BondStatus status={'settled'} isMaker={order.is_maker}/>
// </Grid> // </Grid>
// ); // );
// }; // };
@ -1142,7 +1030,7 @@ export default TradeBox;
// <Divider /> // <Divider />
// </List> // </List>
// </Grid> // </Grid>
// {this.showBondIsLocked()} // // <BondStatus status={'locked'} isMaker={order.is_maker}/>
// </Grid> // </Grid>
// ); // );
// } // }
@ -1179,7 +1067,7 @@ export default TradeBox;
// <Divider /> // <Divider />
// </List> // </List>
// </Grid> // </Grid>
// {this.showBondIsLocked()} // // <BondStatus status={'locked'} isMaker={order.is_maker}/>
// </Grid> // </Grid>
// ); // );
// } // }
@ -1456,7 +1344,7 @@ export default TradeBox;
// {showSendButton ? this.showFiatSentButton() : ''} // {showSendButton ? this.showFiatSentButton() : ''}
// {showReveiceButton ? this.showFiatReceivedButton() : ''} // {showReveiceButton ? this.showFiatReceivedButton() : ''}
// </Grid> // </Grid>
// {this.showBondIsLocked()} // // <BondStatus status={'locked'} isMaker={order.is_maker}/>
// </Grid> // </Grid>
// ); // );
// }; // };
@ -1746,7 +1634,7 @@ export default TradeBox;
// {t('Submit')} // {t('Submit')}
// </LoadingButton> // </LoadingButton>
// </Grid> // </Grid>
// {this.showBondIsReturned()} // // <BondStatus status={'returned'} isMaker={order.is_maker}/>
// </Grid> // </Grid>
// ); // );
// } else { // } else {
@ -1776,7 +1664,7 @@ export default TradeBox;
// </ListItemText> // </ListItemText>
// </List> // </List>
// </Grid> // </Grid>
// {this.showBondIsReturned()} // // <BondStatus status={'returned'} isMaker={order.is_maker}/>
// </Grid> // </Grid>
// ); // );
// } // }

View File

@ -0,0 +1,47 @@
import { Order } from '../../models';
const stepXofY = function (order: Order): string {
// set y value
let x: number | null = null;
let y: number | null = null;
if (order.is_maker) {
y = 5;
} else if (order.is_taker) {
y = 4;
}
// set x values
if (order.is_maker) {
if (order.status === 0) {
x = 1;
} else if ([1, 2, 3].includes(order.status)) {
x = 2;
} else if ([6, 7, 8].includes(order.status)) {
x = 3;
} else if (order.status === 9) {
x = 4;
} else if (order.status === 10) {
x = 5;
}
} else if (order.is_taker) {
if (order.status === 3) {
x = 1;
} else if ([6, 7, 8].includes(order.status)) {
x = 2;
} else if (order.status === 9) {
x = 3;
} else if (order.status === 10) {
x = 4;
}
}
// Return "(x/y)"
if (x != null && y != null) {
return `(${x}/${y})`;
} else {
return '';
}
};
export default stepXofY;