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