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