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