SimpleBoost.tsx raw

   1  import { CopyIcon } from "lucide-react";
   2  import React from "react";
   3  import { toast } from "sonner";
   4  import { AppDetailConnectedApps } from "src/components/connections/AppDetailConnectedApps";
   5  import { AppStoreDetailHeader } from "src/components/connections/AppStoreDetailHeader";
   6  import { appStoreApps } from "src/components/connections/SuggestedAppData";
   7  import ExternalLink from "src/components/ExternalLink";
   8  import { Button } from "src/components/ui/button";
   9  import {
  10    Card,
  11    CardContent,
  12    CardHeader,
  13    CardTitle,
  14  } from "src/components/ui/card";
  15  import { LoadingButton } from "src/components/ui/custom/loading-button";
  16  import { Input } from "src/components/ui/input";
  17  import { Label } from "src/components/ui/label";
  18  import { Textarea } from "src/components/ui/textarea";
  19  import { copyToClipboard } from "src/lib/clipboard";
  20  import { createApp } from "src/requests/createApp";
  21  import { handleRequestError } from "src/utils/handleRequestError";
  22  
  23  export function SimpleBoost() {
  24    const [name, setName] = React.useState("");
  25    const [isLoading, setLoading] = React.useState(false);
  26    const [nwcUri, setNwcUri] = React.useState("");
  27    const [scriptContent, setScriptContent] = React.useState("");
  28  
  29    React.useEffect(() => {
  30      if (nwcUri) {
  31        setScriptContent(`<script type="module" src="https://esm.sh/simple-boost@latest"></script>
  32  <simple-boost currency="usd" amount="1.0" nwc="${nwcUri}">Boost $1.00</simple-boost>`);
  33      }
  34    }, [nwcUri]);
  35  
  36    const appStoreApp = appStoreApps.find((app) => app.id === "simpleboost");
  37    if (!appStoreApp) {
  38      return null;
  39    }
  40  
  41    const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
  42      event.preventDefault();
  43      setLoading(true);
  44      (async () => {
  45        try {
  46          const createAppResponse = await createApp({
  47            name,
  48            scopes: ["lookup_invoice", "make_invoice"],
  49            isolated: true,
  50            metadata: {
  51              app_store_app_id: "simpleboost",
  52            },
  53          });
  54  
  55          setNwcUri(createAppResponse.pairingUri);
  56  
  57          toast("Simple Boost connection created");
  58        } catch (error) {
  59          handleRequestError("Failed to create connection", error);
  60        }
  61        setLoading(false);
  62      })();
  63    };
  64  
  65    return (
  66      <div className="grid gap-5">
  67        <AppStoreDetailHeader appStoreApp={appStoreApp} contentRight={null} />
  68        {nwcUri && (
  69          <Card>
  70            <CardHeader>
  71              <CardTitle>How to Add Widget</CardTitle>
  72            </CardHeader>
  73            <CardContent className="flex flex-col">
  74              <p className="text-foreground">
  75                Paste the following code into an HTML block on your website.
  76              </p>
  77              <div className="flex gap-2 mt-4">
  78                <Textarea
  79                  className="h-36 font-mono"
  80                  value={scriptContent}
  81                  onChange={(e) => setScriptContent(e.target.value)}
  82                />
  83                <Button
  84                  onClick={() => copyToClipboard(scriptContent)}
  85                  variant="outline"
  86                >
  87                  <CopyIcon />
  88                  Copy
  89                </Button>
  90              </div>
  91              <p className="text-sm text-muted-foreground mt-3">
  92                By default the SimpleBoost widget is loaded from a CDN. See other
  93                options{" "}
  94                <ExternalLink
  95                  to="https://getalby.github.io/simple-boost/install/"
  96                  className="font-medium text-foreground underline"
  97                >
  98                  here
  99                </ExternalLink>
 100              </p>
 101            </CardContent>
 102          </Card>
 103        )}
 104        {!nwcUri && (
 105          <>
 106            <div className="max-w-lg flex flex-col gap-5">
 107              <p className="text-muted-foreground">
 108                SimpleBoost is a donation button for your website. Add the widget
 109                to your website and allow your visitors to send sats with the
 110                click of a button.
 111              </p>
 112              <ul className="text-muted-foreground">
 113                <li>⚡ Lightning fast transactions directly to your Alby Hub</li>
 114                <li>🔗 Set amounts in Bitcoin or any other currency</li>
 115                <li>
 116                  🔒 No lightning address required, secure read-only connection
 117                </li>
 118                <li>🤙 Can be paid from any lightning wallet</li>
 119              </ul>
 120              <form
 121                onSubmit={handleSubmit}
 122                className="flex flex-col items-start gap-5 max-w-lg"
 123              >
 124                <div className="w-full grid gap-1.5">
 125                  <Label htmlFor="name">Website name</Label>
 126                  <Input
 127                    autoFocus
 128                    type="text"
 129                    name="name"
 130                    value={name}
 131                    id="name"
 132                    onChange={(e) => setName(e.target.value)}
 133                    required
 134                    autoComplete="off"
 135                  />
 136                </div>
 137                <LoadingButton loading={isLoading} type="submit">
 138                  Next
 139                </LoadingButton>
 140              </form>
 141            </div>
 142            <AppDetailConnectedApps appStoreApp={appStoreApp} showTitle />
 143          </>
 144        )}
 145      </div>
 146    );
 147  }
 148