AppCardConnectionInfo.tsx raw
1 import dayjs from "dayjs";
2 import { BrickWallIcon, CircleCheckIcon, PlusCircleIcon } from "lucide-react";
3 import { FormattedBitcoinAmount } from "src/components/FormattedBitcoinAmount";
4 import { LinkButton } from "src/components/ui/custom/link-button";
5 import { Progress } from "src/components/ui/progress";
6 import { SUBWALLET_APPSTORE_APP_ID } from "src/constants";
7 import { getBudgetRenewalLabel } from "src/lib/utils";
8 import { App } from "src/types";
9
10 type AppCardConnectionInfoProps = {
11 connection: App;
12 budgetRemainingText?: string | React.ReactNode;
13 readonly?: boolean;
14 };
15
16 export function AppCardConnectionInfo({
17 connection,
18 budgetRemainingText = "Left in budget",
19 readonly = false,
20 }: AppCardConnectionInfoProps) {
21 return (
22 <>
23 {connection.isolated ? (
24 <>
25 <div className="text-sm text-secondary-foreground font-medium w-full h-full flex flex-col gap-2">
26 <div className="flex flex-row items-center gap-2">
27 <BrickWallIcon className="size-4" />
28
29 {connection.metadata?.app_store_app_id ===
30 SUBWALLET_APPSTORE_APP_ID
31 ? "Sub-wallet"
32 : "Isolated App"}
33 </div>
34 </div>
35 <div className="flex flex-row justify-between text-xs items-end mt-2">
36 <div className="text-muted-foreground">
37 Last used:{" "}
38 {connection.lastUsedAt
39 ? dayjs(connection.lastUsedAt).fromNow()
40 : "Never"}
41 </div>
42 <div className="flex flex-col items-end justify-end">
43 <p>Balance</p>
44 <p className="text-xl font-medium">
45 <FormattedBitcoinAmount amountMsat={connection.balanceMsat} />
46 </p>
47 </div>
48 </div>
49 </>
50 ) : connection.maxAmountSat > 0 ? (
51 <>
52 <div className="flex flex-row justify-between">
53 <div className="mb-2">
54 <p className="text-xs text-secondary-foreground font-medium">
55 {budgetRemainingText}
56 </p>
57 <p className="text-xl font-medium">
58 <FormattedBitcoinAmount
59 amountMsat={
60 connection.maxAmountMsat - connection.budgetUsageMsat
61 }
62 />
63 </p>
64 </div>
65 </div>
66 <Progress
67 className="h-4"
68 value={
69 100 - (connection.budgetUsageSat * 100) / connection.maxAmountSat
70 }
71 />
72 <div className="flex flex-row justify-between text-xs items-center text-muted-foreground mt-2">
73 <div>
74 Last used:{" "}
75 {connection.lastUsedAt
76 ? dayjs(connection.lastUsedAt).fromNow()
77 : "Never"}
78 </div>
79 <div>
80 {connection.maxAmountSat && (
81 <>
82 <FormattedBitcoinAmount
83 amountMsat={connection.maxAmountMsat}
84 />
85 {connection.budgetRenewal !== "never" && (
86 <> / {getBudgetRenewalLabel(connection.budgetRenewal)}</>
87 )}
88 </>
89 )}
90 </div>
91 </div>
92 </>
93 ) : connection.scopes.indexOf("pay_invoice") > -1 ? (
94 <>
95 <div className="flex flex-row justify-between">
96 <div className="mb-2">
97 <p className="text-xs text-secondary-foreground font-medium">
98 You've spent
99 </p>
100 <p className="text-xl font-medium">
101 <FormattedBitcoinAmount
102 amountMsat={connection.budgetUsageMsat}
103 />
104 </p>
105 </div>
106 </div>
107 <div className="flex flex-row justify-between items-center">
108 <div className="text-muted-foreground text-xs">
109 Last used:{" "}
110 {connection.lastUsedAt
111 ? dayjs(connection.lastUsedAt).fromNow()
112 : "Never"}
113 </div>
114 {!readonly && (
115 <LinkButton
116 to={`/apps/${connection.id}?edit=true`}
117 variant="outline"
118 >
119 <PlusCircleIcon />
120 Set Budget
121 </LinkButton>
122 )}
123 </div>
124 </>
125 ) : (
126 <>
127 <div className="text-sm text-secondary-foreground font-medium w-full h-full flex flex-col gap-2">
128 <div className="flex flex-row items-center gap-2">
129 <CircleCheckIcon className="size-4" />
130 Share wallet information
131 </div>
132 {connection.scopes.indexOf("make_invoice") > -1 && (
133 <div className="flex flex-row items-center gap-2">
134 <CircleCheckIcon className="size-4" />
135 Receive payments
136 </div>
137 )}
138 {connection.scopes.indexOf("list_transactions") > -1 && (
139 <div className="flex flex-row items-center gap-2">
140 <CircleCheckIcon className="size-4" />
141 Read transaction history
142 </div>
143 )}
144 </div>
145 <div className="flex flex-row justify-between items-center">
146 <div className="flex flex-row justify-between text-xs items-center text-muted-foreground">
147 Last used:{" "}
148 {connection.lastUsedAt
149 ? dayjs(connection.lastUsedAt).fromNow()
150 : "Never"}
151 </div>
152 {!readonly && (
153 <LinkButton
154 to={`/apps/${connection.id}?edit=true`}
155 variant="outline"
156 >
157 <PlusCircleIcon />
158 Enable Payments
159 </LinkButton>
160 )}
161 </div>
162 </>
163 )}
164 </>
165 );
166 }
167