Unlock.tsx raw

   1  import React from "react";
   2  import { useLocation, useNavigate } from "react-router";
   3  import PasswordInput from "src/components/password/PasswordInput";
   4  import TwoColumnLayoutHeader from "src/components/TwoColumnLayoutHeader";
   5  import { LoadingButton } from "src/components/ui/custom/loading-button";
   6  import { Label } from "src/components/ui/label";
   7  
   8  import { useInfo } from "src/hooks/useInfo";
   9  import { saveAuthToken } from "src/lib/auth";
  10  import { AuthTokenResponse } from "src/types";
  11  import { handleRequestError } from "src/utils/handleRequestError";
  12  import { request } from "src/utils/request";
  13  
  14  export default function Unlock() {
  15    const [unlockPassword, setUnlockPassword] = React.useState("");
  16    const [loading, setLoading] = React.useState(false);
  17    const navigate = useNavigate();
  18    const location = useLocation();
  19  
  20    const { data: info } = useInfo();
  21    const { mutate: refetchInfo } = useInfo();
  22  
  23    React.useEffect(() => {
  24      if (!info || info.running) {
  25        return;
  26      }
  27      navigate("/");
  28    }, [info, location, navigate]);
  29  
  30    async function onSubmit(e: React.FormEvent) {
  31      e.preventDefault();
  32      try {
  33        setLoading(true);
  34  
  35        const authTokenResponse = await request<AuthTokenResponse>(
  36          "/api/unlock",
  37          {
  38            method: "POST",
  39            headers: {
  40              "Content-Type": "application/json",
  41            },
  42            body: JSON.stringify({
  43              unlockPassword,
  44              permission: "full",
  45            }),
  46          }
  47        );
  48        if (authTokenResponse) {
  49          saveAuthToken(authTokenResponse.token);
  50        }
  51        await refetchInfo();
  52        navigate("/");
  53      } catch (error) {
  54        handleRequestError("Failed to connect", error);
  55      } finally {
  56        setLoading(false);
  57      }
  58    }
  59  
  60    return (
  61      <form onSubmit={onSubmit} className="w-full p-5">
  62        <div className="mx-auto grid w-80 max-w-full gap-6">
  63          <TwoColumnLayoutHeader
  64            title="Login"
  65            pageTitle="Login"
  66            description="Enter your unlock password to continue"
  67          />
  68          <div className="grid gap-4">
  69            <div className="grid gap-1.5">
  70              <Label htmlFor="password">Password</Label>
  71              <PasswordInput
  72                id="password"
  73                onChange={setUnlockPassword}
  74                autoFocus
  75                value={unlockPassword}
  76              />
  77            </div>
  78            <LoadingButton type="submit" loading={loading}>
  79              Login
  80            </LoadingButton>
  81          </div>
  82        </div>
  83      </form>
  84    );
  85  }
  86