certimate/ui/src/pages/setting/Password.tsx
2024-10-14 21:00:50 +08:00

174 lines
4.8 KiB
TypeScript

import { Button } from "@/components/ui/button";
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { useToast } from "@/components/ui/use-toast";
import { getErrMessage } from "@/lib/error";
import { getPb } from "@/repository/api";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
import { z } from "zod";
const formSchema = z
.object({
oldPassword: z.string().min(10, {
message: "settings.password.password.errmsg.length",
}),
newPassword: z.string().min(10, {
message: "settings.password.password.errmsg.length",
}),
confirmPassword: z.string().min(10, {
message: "settings.password.password.errmsg.length",
}),
})
.refine((data) => data.newPassword === data.confirmPassword, {
message: "settings.password.password.errmsg.not_matched",
path: ["confirmPassword"],
});
const Password = () => {
const { toast } = useToast();
const navigate = useNavigate();
const { t } = useTranslation();
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
oldPassword: "",
newPassword: "",
confirmPassword: "",
},
});
const onSubmit = async (values: z.infer<typeof formSchema>) => {
try {
await getPb().admins.authWithPassword(
getPb().authStore.model?.email,
values.oldPassword
);
} catch (e) {
const message = getErrMessage(e);
form.setError("oldPassword", { message });
}
try {
await getPb().admins.update(getPb().authStore.model?.id, {
password: values.newPassword,
passwordConfirm: values.confirmPassword,
});
getPb().authStore.clear();
toast({
title: t("settings.password.changed.message"),
description: t("settings.account.relogin.message"),
});
setTimeout(() => {
navigate("/login");
}, 500);
} catch (e) {
const message = getErrMessage(e);
toast({
title: t("settings.password.failed.message"),
description: message,
variant: "destructive",
});
}
};
return (
<>
<div className="w-full md:max-w-[35em]">
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="space-y-8 dark:text-stone-200"
>
<FormField
control={form.control}
name="oldPassword"
render={({ field }) => (
<FormItem>
<FormLabel>
{t("settings.password.current_password.label")}
</FormLabel>
<FormControl>
<Input
placeholder={t(
"settings.password.current_password.placeholder"
)}
{...field}
type="password"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="newPassword"
render={({ field }) => (
<FormItem>
<FormLabel>
{t("settings.password.new_password.label")}
</FormLabel>
<FormControl>
<Input
placeholder={t(
"settings.password.new_password.placeholder"
)}
{...field}
type="password"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="confirmPassword"
render={({ field }) => (
<FormItem>
<FormLabel>
{t("settings.password.confirm_password.label")}
</FormLabel>
<FormControl>
<Input
placeholder={t(
"settings.password.confirm_password.placeholder"
)}
{...field}
type="password"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<div className="flex justify-end">
<Button type="submit">{t("common.update")}</Button>
</div>
</form>
</Form>
</div>
</>
);
};
export default Password;