NodeAlias.tsx raw

   1  import React, { useState } from "react";
   2  import { toast } from "sonner";
   3  import AppHeader from "src/components/AppHeader";
   4  import { Button } from "src/components/ui/button";
   5  import { Input } from "src/components/ui/input";
   6  import { Label } from "src/components/ui/label";
   7  import { useAlbyMe } from "src/hooks/useAlbyMe";
   8  import { useInfo } from "src/hooks/useInfo";
   9  
  10  import { handleRequestError } from "src/utils/handleRequestError";
  11  import { request } from "src/utils/request";
  12  
  13  export default function NodeAlias() {
  14    const { data: info, mutate: reloadInfo } = useInfo();
  15    const { data: albyMe } = useAlbyMe();
  16    const [nodeAlias, setNodeAlias] = useState("");
  17    const [isLoading, setIsLoading] = useState(false);
  18  
  19    // Initialize nodeAlias with current value when info loads
  20    React.useEffect(() => {
  21      if (info?.nodeAlias !== undefined) {
  22        setNodeAlias(info.nodeAlias);
  23      }
  24    }, [info?.nodeAlias]);
  25  
  26    const hasPaid = albyMe?.subscription?.plan_code;
  27  
  28    const handleSubmit = async (e: React.FormEvent) => {
  29      e.preventDefault();
  30  
  31      if (!hasPaid) {
  32        toast.error("Please upgrade to change your node alias");
  33        return;
  34      }
  35  
  36      setIsLoading(true);
  37      try {
  38        await request("/api/node/alias", {
  39          method: "POST",
  40          headers: {
  41            "Content-Type": "application/json",
  42          },
  43          body: JSON.stringify({ nodeAlias }),
  44        });
  45  
  46        await reloadInfo();
  47        toast("Alias changed. Restart your node to apply the change.", {
  48          description: "Your node alias has been updated successfully.",
  49        });
  50      } catch (error) {
  51        console.error("Failed to update node alias:", error);
  52        handleRequestError("Failed to update node alias", error);
  53      } finally {
  54        setIsLoading(false);
  55      }
  56    };
  57  
  58    return (
  59      <div className="grid gap-5">
  60        <AppHeader
  61          pageTitle="Node Alias"
  62          title="Node Alias"
  63          description="Set a human-readable name for your lightning node"
  64        />
  65        <div className="max-w-lg">
  66          <form onSubmit={handleSubmit} className="w-full flex flex-col gap-4">
  67            <div className="grid gap-2">
  68              <Label htmlFor="nodeAlias">Node Alias</Label>
  69              <Input
  70                id="nodeAlias"
  71                type="text"
  72                value={nodeAlias}
  73                onChange={(e) => setNodeAlias(e.target.value)}
  74                placeholder="Alby Hub"
  75                className="w-full md:w-60"
  76              />
  77              <p className="text-sm text-muted-foreground">
  78                Your lightning node alias will appear to your channel partners,
  79                connected peers, and on lightning network explorers such as
  80                amboss.space.
  81              </p>
  82            </div>
  83            <Button type="submit" disabled={isLoading} className="w-fit">
  84              {isLoading ? "Updating..." : "Update Alias"}
  85            </Button>
  86          </form>
  87        </div>
  88      </div>
  89    );
  90  }
  91