118 lines
3.5 KiB
TypeScript
118 lines
3.5 KiB
TypeScript
|
|
import { useRouter } from "@tanstack/react-router";
|
||
|
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||
|
|
import { useForm } from "react-hook-form";
|
||
|
|
import { z } from "zod";
|
||
|
|
import {
|
||
|
|
Form,
|
||
|
|
FormField,
|
||
|
|
FormItem,
|
||
|
|
FormLabel,
|
||
|
|
FormControl,
|
||
|
|
FormMessage,
|
||
|
|
} from "@/components/ui/form";
|
||
|
|
import { Button } from "@/components/ui/button";
|
||
|
|
import { Input } from "@/components/ui/input";
|
||
|
|
import { Spinner } from "@/components/ui/spinner";
|
||
|
|
import { initUserPassword } from "@/apis/user";
|
||
|
|
import { useMutation } from "@tanstack/react-query";
|
||
|
|
import { toast } from "sonner";
|
||
|
|
import logo from "@/assets/image/logo.png";
|
||
|
|
import { useUserStore } from "@/stores/user";
|
||
|
|
|
||
|
|
const formSchema = z.object({
|
||
|
|
rePassword: z.string().nonempty({
|
||
|
|
message: "确认密码不能为空",
|
||
|
|
}),
|
||
|
|
password: z.string().nonempty({
|
||
|
|
message: "密码不能为空",
|
||
|
|
}),
|
||
|
|
});
|
||
|
|
|
||
|
|
const title = import.meta.env.VITE_APP_TITLE;
|
||
|
|
|
||
|
|
export function InitPassword() {
|
||
|
|
const router = useRouter();
|
||
|
|
const user = useUserStore((state) => state.user);
|
||
|
|
|
||
|
|
const form = useForm<z.infer<typeof formSchema>>({
|
||
|
|
resolver: zodResolver(formSchema),
|
||
|
|
defaultValues: {
|
||
|
|
password: "",
|
||
|
|
rePassword: "",
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
const { mutateAsync, isPending } = useMutation({
|
||
|
|
mutationFn: initUserPassword,
|
||
|
|
onSuccess() {
|
||
|
|
router.navigate({ to: "/", replace: true });
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
const onSubmit = (values: z.infer<typeof formSchema>) => {
|
||
|
|
toast.promise(mutateAsync({ ...values, username: user?.username }), {
|
||
|
|
loading: "提交中...",
|
||
|
|
success: "设置成功",
|
||
|
|
});
|
||
|
|
};
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className="flex items-center justify-center min-h-screen box-border">
|
||
|
|
<div>
|
||
|
|
<div className="flex justify-center items-center mb-4 gap-2">
|
||
|
|
<img
|
||
|
|
src={logo}
|
||
|
|
alt=""
|
||
|
|
className="size-12 object-contain rounded-full bg-white overflow-hidden"
|
||
|
|
/>
|
||
|
|
<div className="text-3xl">{title}</div>
|
||
|
|
</div>
|
||
|
|
<div className="w-[480px] p-10 bg-white rounded-xl">
|
||
|
|
<div className="text-center text-2xl">设置密码</div>
|
||
|
|
<Form {...form}>
|
||
|
|
<form
|
||
|
|
onSubmit={form.handleSubmit(onSubmit)}
|
||
|
|
className="space-y-8 mt-12"
|
||
|
|
>
|
||
|
|
<FormField
|
||
|
|
control={form.control}
|
||
|
|
name="password"
|
||
|
|
render={({ field }) => (
|
||
|
|
<FormItem>
|
||
|
|
<FormLabel>密码</FormLabel>
|
||
|
|
<FormControl>
|
||
|
|
<Input type="password" placeholder="密码" {...field} />
|
||
|
|
</FormControl>
|
||
|
|
<FormMessage />
|
||
|
|
</FormItem>
|
||
|
|
)}
|
||
|
|
/>
|
||
|
|
<FormField
|
||
|
|
control={form.control}
|
||
|
|
name="rePassword"
|
||
|
|
render={({ field }) => (
|
||
|
|
<FormItem>
|
||
|
|
<FormLabel>确认密码</FormLabel>
|
||
|
|
<FormControl>
|
||
|
|
<Input
|
||
|
|
type="password"
|
||
|
|
placeholder="确认密码"
|
||
|
|
{...field}
|
||
|
|
/>
|
||
|
|
</FormControl>
|
||
|
|
<FormMessage />
|
||
|
|
</FormItem>
|
||
|
|
)}
|
||
|
|
/>
|
||
|
|
<Button type="submit" className="w-full" disabled={isPending}>
|
||
|
|
{isPending && <Spinner />}
|
||
|
|
提交
|
||
|
|
</Button>
|
||
|
|
</form>
|
||
|
|
</Form>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|