mirror of
https://github.com/RoboSats/robosats.git
synced 2025-01-10 16:21:36 +00:00
Add Lock Invoice box
This commit is contained in:
parent
040ecaeca7
commit
b25d59ba38
44
frontend/src/components/TradeBox/BondStatus.tsx
Normal file
44
frontend/src/components/TradeBox/BondStatus.tsx
Normal 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;
|
148
frontend/src/components/TradeBox/LockInvoiceBox.tsx
Normal file
148
frontend/src/components/TradeBox/LockInvoiceBox.tsx
Normal 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;
|
@ -26,6 +26,7 @@ import {
|
||||
DialogContent,
|
||||
DialogContentText,
|
||||
DialogTitle,
|
||||
dividerClasses,
|
||||
} from '@mui/material';
|
||||
import { LoadingButton } from '@mui/lab';
|
||||
import QRCode from 'react-qr-code';
|
||||
@ -35,6 +36,7 @@ import TradeSummary from './TradeSummary';
|
||||
import { systemClient } from '../../services/System';
|
||||
import { apiClient } from '../../services/api';
|
||||
import { ConfirmDisputeDialog, ConfirmFiatReceivedDialog } from './Dialogs';
|
||||
import BondStatus from './BondStatus';
|
||||
|
||||
// Icons
|
||||
import {
|
||||
@ -120,50 +122,6 @@ const defaultLightning: LightningFormProps = {
|
||||
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 {
|
||||
order: Order;
|
||||
setOrder: (state: Order) => void;
|
||||
@ -217,6 +175,11 @@ const TradeBox = ({ order, setOrder }: TradeBoxProps): JSX.Element => {
|
||||
onClose={() => setOpen(closeAll)}
|
||||
onAgreeClick={onClickAgreeOpenDispute}
|
||||
/>
|
||||
|
||||
<StepContent />
|
||||
<Divider />
|
||||
<BondStatus />
|
||||
|
||||
<ConfirmFiatReceivedDialog
|
||||
open={open.confirmFiatReceived}
|
||||
order={order}
|
||||
@ -229,17 +192,13 @@ const TradeBox = ({ order, setOrder }: TradeBoxProps): JSX.Element => {
|
||||
};
|
||||
|
||||
export default TradeBox;
|
||||
|
||||
// class TradeBox extends Component {
|
||||
|
||||
// showQRInvoice = () => {
|
||||
// const { t } = this.props;
|
||||
// return (
|
||||
// <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'>
|
||||
// {this.props.data.is_maker ? (
|
||||
// <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 = () => {
|
||||
// const { t } = this.props;
|
||||
// return (
|
||||
@ -436,7 +324,7 @@ export default TradeBox;
|
||||
// color='secondary'
|
||||
// />
|
||||
// </Grid>
|
||||
// {this.showBondIsLocked()}
|
||||
// <BondStatus status={'locked'} isMaker={order.is_maker}/>
|
||||
// </Grid>
|
||||
// );
|
||||
// };
|
||||
@ -460,7 +348,7 @@ export default TradeBox;
|
||||
// )}
|
||||
// </Typography>
|
||||
// </Grid>
|
||||
// {this.showBondIsLocked()}
|
||||
// // <BondStatus status={'locked'} isMaker={order.is_maker}/>
|
||||
// </Grid>
|
||||
// );
|
||||
// };
|
||||
@ -567,7 +455,7 @@ export default TradeBox;
|
||||
// <Divider />
|
||||
// </List>
|
||||
// </Grid>
|
||||
// {this.showBondIsLocked()}
|
||||
// // <BondStatus status={'locked'} isMaker={order.is_maker}/>
|
||||
// </Grid>
|
||||
// );
|
||||
// };
|
||||
@ -607,7 +495,7 @@ export default TradeBox;
|
||||
// <Divider />
|
||||
// </List>
|
||||
// </Grid>
|
||||
// {this.showBondIsLocked()}
|
||||
// // <BondStatus status={'locked'} isMaker={order.is_maker}/>
|
||||
// </Grid>
|
||||
// );
|
||||
// };
|
||||
@ -950,7 +838,7 @@ export default TradeBox;
|
||||
// <Divider />
|
||||
// </List>
|
||||
|
||||
// {this.showBondIsLocked()}
|
||||
// // <BondStatus status={'locked'} isMaker={order.is_maker}/>
|
||||
// </Grid>
|
||||
// );
|
||||
// }
|
||||
@ -986,7 +874,7 @@ export default TradeBox;
|
||||
// <Divider />
|
||||
// </List>
|
||||
// </Grid>
|
||||
// {this.showBondIsSettled()}
|
||||
// // <BondStatus status={'settled'} isMaker={order.is_maker}/>
|
||||
// </Grid>
|
||||
// );
|
||||
// } else {
|
||||
@ -1033,7 +921,7 @@ export default TradeBox;
|
||||
// </Button>
|
||||
// </Grid>
|
||||
// </List>
|
||||
// {this.showBondIsSettled()}
|
||||
// // <BondStatus status={'settled'} isMaker={order.is_maker}/>
|
||||
// </Grid>
|
||||
// );
|
||||
// }
|
||||
@ -1068,7 +956,7 @@ export default TradeBox;
|
||||
// <Divider />
|
||||
// </List>
|
||||
// </Grid>
|
||||
// {this.showBondIsSettled()}
|
||||
// // <BondStatus status={'settled'} isMaker={order.is_maker}/>
|
||||
// </Grid>
|
||||
// );
|
||||
// };
|
||||
@ -1089,7 +977,7 @@ export default TradeBox;
|
||||
// )}
|
||||
// </Typography>
|
||||
// </Grid>
|
||||
// {this.showBondIsSettled()}
|
||||
// // <BondStatus status={'settled'} isMaker={order.is_maker}/>
|
||||
// </Grid>
|
||||
// );
|
||||
// };
|
||||
@ -1110,7 +998,7 @@ export default TradeBox;
|
||||
// )}
|
||||
// </Typography>
|
||||
// </Grid>
|
||||
// {this.showBondIsSettled()}
|
||||
// // <BondStatus status={'settled'} isMaker={order.is_maker}/>
|
||||
// </Grid>
|
||||
// );
|
||||
// };
|
||||
@ -1142,7 +1030,7 @@ export default TradeBox;
|
||||
// <Divider />
|
||||
// </List>
|
||||
// </Grid>
|
||||
// {this.showBondIsLocked()}
|
||||
// // <BondStatus status={'locked'} isMaker={order.is_maker}/>
|
||||
// </Grid>
|
||||
// );
|
||||
// }
|
||||
@ -1179,7 +1067,7 @@ export default TradeBox;
|
||||
// <Divider />
|
||||
// </List>
|
||||
// </Grid>
|
||||
// {this.showBondIsLocked()}
|
||||
// // <BondStatus status={'locked'} isMaker={order.is_maker}/>
|
||||
// </Grid>
|
||||
// );
|
||||
// }
|
||||
@ -1456,7 +1344,7 @@ export default TradeBox;
|
||||
// {showSendButton ? this.showFiatSentButton() : ''}
|
||||
// {showReveiceButton ? this.showFiatReceivedButton() : ''}
|
||||
// </Grid>
|
||||
// {this.showBondIsLocked()}
|
||||
// // <BondStatus status={'locked'} isMaker={order.is_maker}/>
|
||||
// </Grid>
|
||||
// );
|
||||
// };
|
||||
@ -1746,7 +1634,7 @@ export default TradeBox;
|
||||
// {t('Submit')}
|
||||
// </LoadingButton>
|
||||
// </Grid>
|
||||
// {this.showBondIsReturned()}
|
||||
// // <BondStatus status={'returned'} isMaker={order.is_maker}/>
|
||||
// </Grid>
|
||||
// );
|
||||
// } else {
|
||||
@ -1776,7 +1664,7 @@ export default TradeBox;
|
||||
// </ListItemText>
|
||||
// </List>
|
||||
// </Grid>
|
||||
// {this.showBondIsReturned()}
|
||||
// // <BondStatus status={'returned'} isMaker={order.is_maker}/>
|
||||
// </Grid>
|
||||
// );
|
||||
// }
|
||||
|
47
frontend/src/components/TradeBox/stepXofY.ts
Normal file
47
frontend/src/components/TradeBox/stepXofY.ts
Normal 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;
|
Loading…
Reference in New Issue
Block a user