FixedFloatSwapInFlow.tsx raw

   1  import {
   2    ArrowLeftIcon,
   3    CopyIcon,
   4    ExternalLinkIcon,
   5    HandCoinsIcon,
   6  } from "lucide-react";
   7  import { useEffect, useState } from "react";
   8  import { FixedFloatButton } from "src/components/FixedFloatButton";
   9  import { FormattedBitcoinAmount } from "src/components/FormattedBitcoinAmount";
  10  import FormattedFiatAmount from "src/components/FormattedFiatAmount";
  11  import LottieLoading from "src/components/LottieLoading";
  12  import LottieSuccess from "src/components/LottieSuccess";
  13  import { Button } from "src/components/ui/button";
  14  import {
  15    Card,
  16    CardContent,
  17    CardFooter,
  18    CardHeader,
  19    CardTitle,
  20  } from "src/components/ui/card";
  21  import { LinkButton } from "src/components/ui/custom/link-button";
  22  import { LoadingButton } from "src/components/ui/custom/loading-button";
  23  import { Label } from "src/components/ui/label";
  24  import { useTransaction } from "src/hooks/useTransaction";
  25  import { copyToClipboard } from "src/lib/clipboard";
  26  import { Transaction } from "src/types";
  27  
  28  export function FixedFloatSwapInFlow({
  29    loading,
  30    transaction,
  31    onReset,
  32    resetLabel,
  33  }: {
  34    loading: boolean;
  35    transaction: Transaction | null;
  36    onReset: () => void;
  37    resetLabel: string;
  38    feeLabel?: string;
  39  }) {
  40    const { data: invoiceData } = useTransaction(
  41      transaction ? transaction.paymentHash : "",
  42      true
  43    );
  44    const [paymentDone, setPaymentDone] = useState(false);
  45  
  46    useEffect(() => {
  47      if (invoiceData?.settledAt) {
  48        setPaymentDone(true);
  49      }
  50    }, [invoiceData]);
  51  
  52    if (!transaction) {
  53      return (
  54        <>
  55          <div className="border-t pt-4 text-sm grid gap-2">
  56            <div className="flex items-center justify-between">
  57              <Label>Swap Fee</Label>
  58              <p className="text-muted-foreground">1% + on-chain fees</p>
  59            </div>
  60          </div>
  61  
  62          <div className="grid gap-2">
  63            <LoadingButton className="w-full" loading={loading}>
  64              Continue
  65              <ExternalLinkIcon className="size-4" />
  66            </LoadingButton>
  67            <p className="text-xs text-muted-foreground text-center">
  68              powered by{" "}
  69              <span className="font-medium text-foreground">Fixed Float</span>
  70            </p>
  71          </div>
  72        </>
  73      );
  74    }
  75  
  76    if (!paymentDone) {
  77      return (
  78        <Card>
  79          <CardHeader>
  80            <CardTitle className="text-center">Waiting for Payment...</CardTitle>
  81          </CardHeader>
  82          <CardContent className="flex flex-col items-center gap-6">
  83            <LottieLoading size={288} />
  84            <div className="flex flex-col gap-1 items-center">
  85              <p className="text-2xl font-medium slashed-zero">
  86                <FormattedBitcoinAmount amountMsat={transaction.amountMsat} />
  87              </p>
  88              <FormattedFiatAmount
  89                amountSat={transaction.amountSat}
  90                className="text-xl"
  91              />
  92            </div>
  93          </CardContent>
  94          <CardFooter className="flex flex-col gap-3 pt-2">
  95            <Button
  96              type="button"
  97              className="w-full"
  98              onClick={() => {
  99                copyToClipboard(transaction.invoice);
 100              }}
 101              variant="secondary"
 102            >
 103              <CopyIcon className="w-4 h-4" />
 104              Copy Invoice
 105            </Button>
 106            <FixedFloatButton
 107              to="BTCLN"
 108              address={transaction.invoice}
 109              variant="outline"
 110              className="w-full"
 111            >
 112              <ExternalLinkIcon className="size-4" />
 113              Open Fixed Float
 114            </FixedFloatButton>
 115          </CardFooter>
 116        </Card>
 117      );
 118    }
 119  
 120    return (
 121      <Card className="w-full">
 122        <CardHeader>
 123          <CardTitle className="text-center">Transaction Received!</CardTitle>
 124        </CardHeader>
 125        <CardContent className="flex flex-col items-center gap-6">
 126          <LottieSuccess />
 127          <div className="flex flex-col gap-1 items-center">
 128            <p className="text-2xl font-medium slashed-zero">
 129              <FormattedBitcoinAmount amountMsat={transaction.amountMsat} />
 130            </p>
 131            <FormattedFiatAmount
 132              amountSat={transaction.amountSat}
 133              className="text-xl"
 134            />
 135          </div>
 136        </CardContent>
 137        <CardFooter className="flex flex-col gap-3 pt-2">
 138          <Button
 139            type="button"
 140            onClick={() => {
 141              onReset();
 142              setPaymentDone(false);
 143            }}
 144            variant="outline"
 145            className="w-full"
 146          >
 147            <HandCoinsIcon className="size-4" />
 148            {resetLabel}
 149          </Button>
 150          <LinkButton to="/wallet" variant="link" className="w-full">
 151            <ArrowLeftIcon className="size-4" />
 152            Back to Wallet
 153          </LinkButton>
 154        </CardFooter>
 155      </Card>
 156    );
 157  }
 158