This commit is contained in:
an-lee
2024-04-11 17:02:36 +08:00
parent 4497360ae0
commit b4767a9c7a
4 changed files with 82 additions and 59 deletions

View File

@@ -531,8 +531,8 @@
"AiTranslate": "AI translate",
"cambridgeDictionary": "Cambridge dictionary",
"customizeShortcuts": "Customize shortcuts",
"customizeShortcutsTip":"Click to change",
"customizeShortcutsRecordingTip":"Recording new shortcut",
"customizeShortcutsTip": "Click to change",
"customizeShortcutsRecordingTip": "Recording new shortcut",
"customizeShortcutsInvalidToast": "Your shortcut should only have one modifier (Ctrl, Alt, Shift, or Meta) and one key, like 'Ctrl+C'.",
"customizeShortcutsConflictToast": "{{input}} conflicts with the existing {{otherHotkeyName}} shortcut.",
"customizeShortcutsUpdated": "Changes saved",

View File

@@ -530,9 +530,9 @@
"AiTranslate": "智能翻译",
"cambridgeDictionary": "剑桥词典",
"customizeShortcuts": "自定义快捷键",
"customizeShortcutsTip":"点击重新录制",
"customizeShortcutsRecordingTip":"正在录制快捷键",
"customizeShortcutsInvalidToast":"快捷键应最多含一个修饰键Ctrl, Alt, Shift 或 Meta和一个键如 'Ctrl+C'",
"customizeShortcutsTip": "点击重新录制",
"customizeShortcutsRecordingTip": "正在录制快捷键",
"customizeShortcutsInvalidToast": "快捷键应最多含一个修饰键Ctrl, Alt, Shift 或 Meta和一个键如 'Ctrl+C'",
"customizeShortcutsConflictToast": "{{input}} 和已有 {{otherHotkeyName}} 的键位冲突了",
"customizeShortcutsUpdated": "设置成功",
"following": "关注中",

View File

@@ -17,7 +17,7 @@ export const EmailSettings = () => {
const { user, login, webApi } = useContext(AppSettingsProviderContext);
const [editing, setEditing] = useState(false);
const [email, setEmail] = useState(user.email);
const [code, setCode] = useState('');
const [code, setCode] = useState("");
const [codeSent, setCodeSent] = useState<boolean>(false);
const [countdown, setCountdown] = useState<number>(0);
@@ -38,7 +38,7 @@ export const EmailSettings = () => {
return () => {
if (timeout) clearTimeout(timeout);
}
};
}, [countdown]);
if (!user) return null;
@@ -47,78 +47,89 @@ export const EmailSettings = () => {
<div className="flex items-start justify-between py-4">
<div className="">
<div className="mb-2">{t("email")}</div>
<div className="text-sm text-muted-foreground mb-2">{user.email || '-'}</div>
<div className="text-sm text-muted-foreground mb-2">
{user.email || "-"}
</div>
</div>
<Dialog open={editing} onOpenChange={(value) => setEditing(value)}>
<DialogTrigger asChild>
<Button variant="secondary" size="sm">
{t('edit')}
{t("edit")}
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>
{t('editEmail')}
</DialogTitle>
<DialogTitle>{t("editEmail")}</DialogTitle>
</DialogHeader>
<div className="w-full max-w-sm mx-auto py-6">
<div className="grid gap-4 mb-6">
<div className="grid gap-2">
<Label htmlFor="email">{t('email')}</Label>
<Label htmlFor="email">{t("email")}</Label>
<Input
id="email"
required
value={email}
onChange={e => setEmail(e.target.value)}
placeholder="m@example.com" />
onChange={(e) => setEmail(e.target.value)}
placeholder="m@example.com"
/>
</div>
<div className="grid gap-2">
<Label htmlFor="code">{t('verificationCode')}</Label>
<Label htmlFor="code">{t("verificationCode")}</Label>
<Input
id="code"
required
value={code}
onChange={e => setCode(e.target.value)}
placeholder={t('verificationCode')}
onChange={(e) => setCode(e.target.value)}
placeholder={t("verificationCode")}
/>
</div>
</div>
<div className="grid grid-cols-2 gap-4">
<Button variant="secondary" disabled={!email} onClick={() => {
webApi
.loginCode({ email })
.then(() => {
toast.success(t("codeSent"));
setCodeSent(true);
setCountdown(120);
})
.catch((err) => {
toast.error(err.message);
});
}}>
<Button
variant="secondary"
disabled={!email}
onClick={() => {
webApi
.loginCode({ email })
.then(() => {
toast.success(t("codeSent"));
setCodeSent(true);
setCountdown(120);
})
.catch((err) => {
toast.error(err.message);
});
}}
>
{countdown > 0 && <span className="mr-2">{countdown}</span>}
<span>{codeSent ? t("resend") : t("sendCode")}</span>
</Button>
<Button disabled={!code} onClick={() => {
webApi.updateProfile(user.id, {
email,
code
})
.then(() => {
toast.success(t("emailUpdated"));
refreshProfile();
setEditing(false);
})
.catch((err) => {
toast.error(err.message);
});
}}>{t("confirm")}</Button>
<Button
disabled={!code}
onClick={() => {
webApi
.updateProfile(user.id, {
email,
code,
})
.then(() => {
toast.success(t("emailUpdated"));
refreshProfile();
setEditing(false);
})
.catch((err) => {
toast.error(err.message);
});
}}
>
{t("confirm")}
</Button>
</div>
</div>
</DialogContent>

View File

@@ -27,7 +27,9 @@ import { useContext, useState } from "react";
import { redirect } from "react-router-dom";
export const UserSettings = () => {
const { user, login, logout, webApi } = useContext(AppSettingsProviderContext);
const { user, login, logout, webApi } = useContext(
AppSettingsProviderContext
);
const [name, setName] = useState(user.name);
const [editing, setEditing] = useState(false);
@@ -66,12 +68,12 @@ export const UserSettings = () => {
<DialogContent>
<DialogHeader>
<DialogTitle>{t('editUserName')}</DialogTitle>
<DialogTitle>{t("editUserName")}</DialogTitle>
</DialogHeader>
<div className="w-full max-w-sm mx-auto py-6">
<div className="grid gap-2 mb-6">
<Label htmlFor="name">{t('userName')}</Label>
<Label htmlFor="name">{t("userName")}</Label>
<Input
id="name"
value={name}
@@ -79,17 +81,23 @@ export const UserSettings = () => {
/>
</div>
<div className="">
<Button className="w-full" onClick={() => {
webApi
.updateProfile(user.id, { name })
.then(() => {
toast.success('profileUpdated')
setEditing(false);
refreshProfile();
}).catch(err => {
toast.error(err.message);
})
}}>{t('save')}</Button>
<Button
className="w-full"
onClick={() => {
webApi
.updateProfile(user.id, { name })
.then(() => {
toast.success("profileUpdated");
setEditing(false);
refreshProfile();
})
.catch((err) => {
toast.error(err.message);
});
}}
>
{t("save")}
</Button>
</div>
</div>
</DialogContent>
@@ -97,7 +105,11 @@ export const UserSettings = () => {
<AlertDialog>
<AlertDialogTrigger asChild>
<Button variant="secondary" className="text-destructive" size="sm">
<Button
variant="secondary"
className="text-destructive"
size="sm"
>
{t("logout")}
</Button>
</AlertDialogTrigger>