feat(ui): new SettingsAccount using antd

This commit is contained in:
Fu Diwei 2024-12-19 10:50:42 +08:00
parent df57c196e9
commit 8b7295d77e
7 changed files with 87 additions and 116 deletions

View File

@ -36,8 +36,8 @@
"common.theme.system": "System",
"common.errmsg.string_max": "Please enter no more than {{max}} characters",
"common.errmsg.email_invalid": "Please enter a valid email address",
"common.errmsg.email_empty": "Please enter email",
"common.errmsg.email_invalid": "Please enter a valid email address",
"common.errmsg.email_duplicate": "Email already exists",
"common.errmsg.domain_invalid": "Please enter domain",
"common.errmsg.host_invalid": "Please enter a valid domain name or IP",

View File

@ -4,11 +4,8 @@
"settings.account.relogin.message": "Please login again",
"settings.account.tab": "Account",
"settings.account.email.label": "Email",
"settings.account.email.placeholder": "Please enter email",
"settings.account.email.errmsg.invalid": "Please enter a valid email address",
"settings.account.email.changed.message": "Account email altered successfully",
"settings.account.email.failed.message": "Account email alteration failed",
"settings.account.form.email.label": "Email",
"settings.account.form.email.placeholder": "Please enter email",
"settings.password.tab": "Password",
"settings.password.current_password.label": "Current Password",

View File

@ -1,5 +1,5 @@
{
"login.username.label": "用户名",
"login.username.label": "用户名/邮箱",
"login.username.placeholder": "请输入用户名/邮箱",
"login.username.errmsg.invalid": "请输入正确的用户名/邮箱",
"login.password.label": "密码",

View File

@ -3,14 +3,11 @@
"settings.account.relogin.message": "请重新登录",
"settings.account.tab": "账号",
"settings.account.email.label": "登录邮箱",
"settings.account.email.errmsg.invalid": "请输入正确的邮箱地址",
"settings.account.email.placeholder": "请输入邮箱",
"settings.account.email.changed.message": "修改账户邮箱成功",
"settings.account.email.failed.message": "修改账户邮箱失败",
"settings.account.tab": "登录账号",
"settings.account.form.email.label": "登录邮箱",
"settings.account.form.email.placeholder": "请输入邮箱",
"settings.password.tab": "密码",
"settings.password.tab": "登录密码",
"settings.password.password.errmsg.length": "密码至少10个字符",
"settings.password.password.errmsg.not_matched": "两次密码不一致",
"settings.password.current_password.label": "当前密码",

View File

@ -1,101 +0,0 @@
import { useState } from "react";
import { useNavigate } from "react-router-dom";
import { useForm } from "react-hook-form";
import { useTranslation } from "react-i18next";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
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 { getErrMsg } from "@/utils/error";
import { getPocketBase } from "@/repository/pocketbase";
const formSchema = z.object({
email: z.string().email("settings.account.email.errmsg.invalid"),
});
const Account = () => {
const { toast } = useToast();
const navigate = useNavigate();
const { t } = useTranslation();
const [changed, setChanged] = useState(false);
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
email: getPocketBase().authStore.model?.email,
},
});
const onSubmit = async (values: z.infer<typeof formSchema>) => {
try {
await getPocketBase().admins.update(getPocketBase().authStore.model?.id, {
email: values.email,
});
getPocketBase().authStore.clear();
toast({
title: t("settings.account.email.changed.message"),
description: t("settings.account.relogin.message"),
});
setTimeout(() => {
navigate("/login");
}, 500);
} catch (e) {
const message = getErrMsg(e);
toast({
title: t("settings.account.email.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="email"
render={({ field }) => (
<FormItem>
<FormLabel>{t("settings.account.email.label")}</FormLabel>
<FormControl>
<Input
placeholder={t("settings.account.email.placeholder")}
{...field}
type="email"
onChange={(e) => {
setChanged(true);
form.setValue("email", e.target.value);
}}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<div className="flex justify-end">
{changed ? (
<Button type="submit">{t("common.button.save")}</Button>
) : (
<Button type="submit" disabled variant={"secondary"}>
{t("common.button.save")}
</Button>
)}
</div>
</form>
</Form>
</div>
</>
);
};
export default Account;

View File

@ -0,0 +1,78 @@
import { useState } from "react";
import { useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
import { Button, Form, Input, message, notification } from "antd";
import { createSchemaFieldRule } from "antd-zod";
import { z } from "zod";
import { getErrMsg } from "@/utils/error";
import { getPocketBase } from "@/repository/pocketbase";
const SettingsAccount = () => {
const navigate = useNavigate();
const { t } = useTranslation();
const [messageApi, MessageContextHolder] = message.useMessage();
const [notificationApi, NotificationContextHolder] = notification.useNotification();
const formSchema = z.object({
username: z.string().email(t("common.errmsg.email_invalid")),
});
const formRule = createSchemaFieldRule(formSchema);
const [form] = Form.useForm<z.infer<typeof formSchema>>();
const [formPending, setFormPending] = useState(false);
const [initialValues] = useState<Partial<z.infer<typeof formSchema>>>({
username: getPocketBase().authStore.model?.email,
});
const [initialChanged, setInitialChanged] = useState(false);
const handleInputChange = () => {
setInitialChanged(form.getFieldValue("username") !== initialValues.username);
};
const handleFormFinish = async (values: z.infer<typeof formSchema>) => {
setFormPending(true);
try {
await getPocketBase().admins.update(getPocketBase().authStore.model?.id, {
email: values.username,
});
messageApi.success(t("common.text.operation_succeeded"));
setTimeout(() => {
getPocketBase().authStore.clear();
navigate("/login");
}, 500);
} catch (err) {
notificationApi.error({ message: t("common.text.request_error"), description: <>{getErrMsg(err)}</> });
} finally {
setFormPending(false);
}
};
return (
<>
{MessageContextHolder}
{NotificationContextHolder}
<div className="w-full md:max-w-[35em]">
<Form form={form} disabled={formPending} initialValues={initialValues} layout="vertical" onFinish={handleFormFinish}>
<Form.Item name="username" label={t("settings.account.form.email.label")} rules={[formRule]}>
<Input placeholder={t("settings.account.form.email.placeholder")} onChange={handleInputChange} />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" disabled={!initialChanged} loading={formPending}>
{t("common.button.save")}
</Button>
</Form.Item>
</Form>
</div>
</>
);
};
export default SettingsAccount;

View File

@ -9,7 +9,7 @@ import WorkflowList from "./pages/workflows/WorkflowList";
import WorkflowDetail from "./pages/workflows/WorkflowDetail";
import CertificateList from "./pages/certificates/CertificateList";
import Settings from "./pages/settings/Settings";
import SettingsAccount from "./pages/settings/Account";
import SettingsAccount from "./pages/settings/SettingsAccount";
import SettingsPassword from "./pages/settings/Password";
import SettingsNotification from "./pages/settings/Notification";
import SettingsSSLProvider from "./pages/settings/SSLProvider";