snort/packages/app/src/Element/Invoice.tsx

90 lines
2.4 KiB
TypeScript
Raw Normal View History

2023-01-02 13:40:42 +00:00
import "./Invoice.css";
2023-01-09 22:26:41 +00:00
import { useState } from "react";
2023-02-08 21:10:26 +00:00
import { useIntl, FormattedMessage } from "react-intl";
2023-01-02 13:40:42 +00:00
import { useMemo } from "react";
2023-03-02 15:23:53 +00:00
2023-02-07 13:32:32 +00:00
import SendSats from "Element/SendSats";
2023-03-02 17:47:02 +00:00
import Icon from "Icons/Icon";
2023-03-02 15:23:53 +00:00
import { useWallet } from "Wallet";
import { decodeInvoice } from "Util";
2023-01-02 13:40:42 +00:00
2023-02-08 21:10:26 +00:00
import messages from "./messages";
2023-01-16 17:48:25 +00:00
export interface InvoiceProps {
invoice: string;
2023-01-16 17:48:25 +00:00
}
2023-02-07 19:47:57 +00:00
2023-01-16 17:48:25 +00:00
export default function Invoice(props: InvoiceProps) {
const invoice = props.invoice;
2023-02-08 21:10:26 +00:00
const { formatMessage } = useIntl();
2023-03-02 15:23:53 +00:00
const [showInvoice, setShowInvoice] = useState(false);
const walletState = useWallet();
const wallet = walletState.wallet;
2023-01-02 13:40:42 +00:00
2023-03-02 15:23:53 +00:00
const info = useMemo(() => decodeInvoice(invoice), [invoice]);
const [isPaid, setIsPaid] = useState(false);
const isExpired = info?.expired;
const amount = info?.amount ?? 0;
const description = info?.description;
2023-02-01 22:42:46 +00:00
function header() {
return (
<>
2023-02-08 21:10:26 +00:00
<h4>
<FormattedMessage {...messages.Invoice} />
</h4>
2023-03-02 17:47:02 +00:00
<Icon name="zapCircle" className="zap-circle" />
<SendSats
2023-02-08 21:10:26 +00:00
title={formatMessage(messages.PayInvoice)}
invoice={invoice}
show={showInvoice}
onClose={() => setShowInvoice(false)}
/>
</>
);
}
2023-01-06 19:57:26 +00:00
2023-02-07 19:47:57 +00:00
async function payInvoice(e: React.MouseEvent<HTMLButtonElement>) {
e.stopPropagation();
2023-03-02 15:23:53 +00:00
if (wallet?.isReady) {
try {
2023-03-02 15:23:53 +00:00
await wallet.payInvoice(invoice);
setIsPaid(true);
} catch (error) {
setShowInvoice(true);
}
} else {
setShowInvoice(true);
}
}
return (
<>
2023-02-09 12:26:54 +00:00
<div className={`note-invoice flex ${isExpired ? "expired" : ""} ${isPaid ? "paid" : ""}`}>
<div className="invoice-header">{header()}</div>
2023-01-06 19:57:26 +00:00
<p className="invoice-amount">
{amount > 0 && (
<>
2023-03-06 10:18:33 +00:00
{(amount / 1_000).toLocaleString()} <span className="sats">sat{amount === 1_000 ? "" : "s"}</span>
</>
)}
</p>
2023-01-12 06:07:48 +00:00
<div className="invoice-body">
{description && <p>{description}</p>}
{isPaid ? (
2023-02-08 21:10:26 +00:00
<div className="paid">
<FormattedMessage {...messages.Paid} />
</div>
) : (
<button disabled={isExpired} type="button" onClick={payInvoice}>
2023-02-09 12:26:54 +00:00
{isExpired ? <FormattedMessage {...messages.Expired} /> : <FormattedMessage {...messages.Pay} />}
</button>
)}
</div>
</div>
</>
);
2023-02-01 22:42:46 +00:00
}