import { useState, useEffect } from 'react' import { numWithUnits } from '@/lib/format' import AccordianItem from './accordian-item' import Qr, { QrSkeleton } from './qr' import { CompactLongCountdown } from './countdown' import PayerData from './payer-data' import Bolt11Info from './bolt11-info' import { useQuery } from '@apollo/client' import { INVOICE } from '@/fragments/wallet' import { FAST_POLL_INTERVAL, SSR } from '@/lib/constants' import { NoAttachedWalletError } from '@/wallets/errors' import ItemJob from './item-job' import Item from './item' import { CommentFlat } from './comment' import classNames from 'classnames' import Moon from '@/svgs/moon-fill.svg' export default function Invoice ({ id, query = INVOICE, modal, onPayment, onCanceled, info, successVerb = 'deposited', heldVerb = 'settling', useWallet = true, walletError, poll, waitFor, ...props }) { const [expired, setExpired] = useState(false) const { data, error } = useQuery(query, SSR ? {} : { pollInterval: FAST_POLL_INTERVAL, variables: { id }, nextFetchPolicy: 'cache-and-network', skip: !poll }) const invoice = data?.invoice useEffect(() => { if (!invoice) { return } if (waitFor?.(invoice)) { onPayment?.(invoice) } if (invoice.cancelled || invoice.actionError) { onCanceled?.(invoice) } setExpired(new Date(invoice.expiredAt) <= new Date()) }, [invoice, onPayment, setExpired]) if (error) { return
{error.message}
} if (!invoice) { return } let variant = 'default' let status = 'waiting for you' if (invoice.confirmedAt) { variant = 'confirmed' status = `${numWithUnits(invoice.satsReceived, { abbreviate: false })} ${successVerb}` useWallet = false } else if (invoice.cancelled) { variant = 'failed' status = 'cancelled' useWallet = false } else if (invoice.isHeld) { variant = 'pending' status = (
{heldVerb}
) useWallet = false } else if (expired) { variant = 'failed' status = 'expired' useWallet = false } else { variant = 'pending' status = ( { setExpired(true) }} /> ) } const { nostr, comment, lud18Data, bolt11, confirmedPreimage } = invoice return ( <> {walletError && !(walletError instanceof NoAttachedWalletError) &&
Paying from attached wallet failed: {walletError.message}
} {!modal && <> {info &&
{info}
}
{nostr ? {JSON.stringify(nostr, null, 2)} } /> : null}
{lud18Data &&
} className='mb-3' />
} {comment &&
{comment}} className='mb-3' />
} {invoice?.item && } } ) } function ActionInfo ({ invoice }) { if (!invoice.actionType) return null let className = 'text-info' let actionString = '' switch (invoice.actionState) { case 'FAILED': case 'RETRYING': actionString += 'attempted ' className = 'text-warning' break case 'PAID': actionString += 'successful ' className = 'text-success' break default: actionString += 'pending ' } switch (invoice.actionType) { case 'ITEM_CREATE': actionString += 'item creation' break case 'ZAP': actionString += 'zap on item' break case 'DOWN_ZAP': actionString += 'downzap on item' break case 'POLL_VOTE': actionString += 'poll vote' break } return (
{actionString}
{(invoice.item?.isJob && ) || (invoice.item?.title && ) || }
) }