feat: i18n support

This commit is contained in:
JustSong
2025-02-02 00:05:40 +08:00
parent e183e3b9b0
commit b1fe81a84f
5 changed files with 558 additions and 241 deletions

View File

@@ -1,4 +1,5 @@
import React, { useContext, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Button, Divider, Form, Header, Image, Message, Modal } from 'semantic-ui-react';
import { Link, useNavigate } from 'react-router-dom';
import { API, copy, showError, showInfo, showNotice, showSuccess } from '../helpers';
@@ -7,6 +8,7 @@ import { UserContext } from '../context/User';
import { onGitHubOAuthClicked, onLarkOAuthClicked } from './utils';
const PersonalSetting = () => {
const { t } = useTranslation();
const [userState, userDispatch] = useContext(UserContext);
let navigate = useNavigate();
@@ -169,18 +171,24 @@ const PersonalSetting = () => {
return (
<div style={{ lineHeight: '40px' }}>
<Header as='h3'>通用设置</Header>
<Header as='h3'>{t('setting.personal.general.title')}</Header>
<Message>
注意此处生成的令牌用于系统管理而非用于请求 OpenAI 相关的服务请知悉
{t('setting.personal.general.system_token_notice')}
</Message>
<Button as={Link} to={`/user/edit/`}>
更新个人信息
{t('setting.personal.general.buttons.update_profile')}
</Button>
<Button onClick={generateAccessToken}>
{t('setting.personal.general.buttons.generate_token')}
</Button>
<Button onClick={getAffLink}>
{t('setting.personal.general.buttons.copy_invite')}
</Button>
<Button onClick={generateAccessToken}>生成系统访问令牌</Button>
<Button onClick={getAffLink}>复制邀请链接</Button>
<Button onClick={() => {
setShowAccountDeleteModal(true);
}}>删除个人账户</Button>
}}>
{t('setting.personal.general.buttons.delete_account')}
</Button>
{systemToken && (
<Form.Input
@@ -201,18 +209,12 @@ const PersonalSetting = () => {
/>
)}
<Divider />
<Header as='h3'>账号绑定</Header>
{
status.wechat_login && (
<Button
onClick={() => {
setShowWeChatBindModal(true);
}}
>
绑定微信账号
</Button>
)
}
<Header as='h3'>{t('setting.personal.binding.title')}</Header>
{status.wechat_login && (
<Button onClick={() => setShowWeChatBindModal(true)}>
{t('setting.personal.binding.buttons.bind_wechat')}
</Button>
)}
<Modal
onClose={() => setShowWeChatBindModal(false)}
onOpen={() => setShowWeChatBindModal(true)}
@@ -223,41 +225,35 @@ const PersonalSetting = () => {
<Modal.Description>
<Image src={status.wechat_qrcode} fluid />
<div style={{ textAlign: 'center' }}>
<p>
微信扫码关注公众号输入验证码获取验证码三分钟内有效
</p>
<p>{t('setting.personal.binding.wechat.description')}</p>
</div>
<Form size='large'>
<Form.Input
fluid
placeholder='验证码'
placeholder={t('setting.personal.binding.wechat.verification_code')}
name='wechat_verification_code'
value={inputs.wechat_verification_code}
onChange={handleInputChange}
/>
<Button color='' fluid size='large' onClick={bindWeChat}>
绑定
{t('setting.personal.binding.wechat.bind')}
</Button>
</Form>
</Modal.Description>
</Modal.Content>
</Modal>
{
status.github_oauth && (
<Button onClick={()=>{onGitHubOAuthClicked(status.github_client_id)}}>绑定 GitHub 账号</Button>
)
}
{
status.lark_client_id && (
<Button onClick={()=>{onLarkOAuthClicked(status.lark_client_id)}}>绑定飞书账号</Button>
)
}
<Button
onClick={() => {
setShowEmailBindModal(true);
}}
>
绑定邮箱地址
{status.github_oauth && (
<Button onClick={() => onGitHubOAuthClicked(status.github_client_id)}>
{t('setting.personal.binding.buttons.bind_github')}
</Button>
)}
{status.lark_client_id && (
<Button onClick={() => onLarkOAuthClicked(status.lark_client_id)}>
{t('setting.personal.binding.buttons.bind_lark')}
</Button>
)}
<Button onClick={() => setShowEmailBindModal(true)}>
{t('setting.personal.binding.buttons.bind_email')}
</Button>
<Modal
onClose={() => setShowEmailBindModal(false)}
@@ -266,57 +262,57 @@ const PersonalSetting = () => {
size={'tiny'}
style={{ maxWidth: '450px' }}
>
<Modal.Header>绑定邮箱地址</Modal.Header>
<Modal.Header>{t('setting.personal.binding.email.title')}</Modal.Header>
<Modal.Content>
<Modal.Description>
<Form size='large'>
<Form.Input
fluid
placeholder='输入邮箱地址'
placeholder={t('setting.personal.binding.email.email_placeholder')}
onChange={handleInputChange}
name='email'
type='email'
action={
<Button onClick={sendVerificationCode} disabled={disableButton || loading}>
{disableButton ? `重新发送(${countdown})` : '获取验证码'}
{disableButton
? t('setting.personal.binding.email.get_code_retry', { countdown })
: t('setting.personal.binding.email.get_code')}
</Button>
}
/>
<Form.Input
fluid
placeholder='验证码'
placeholder={t('setting.personal.binding.email.code_placeholder')}
name='email_verification_code'
value={inputs.email_verification_code}
onChange={handleInputChange}
/>
{turnstileEnabled ? (
{turnstileEnabled && (
<Turnstile
sitekey={turnstileSiteKey}
onVerify={(token) => {
setTurnstileToken(token);
}}
/>
) : (
<></>
)}
<div style={{ display: 'flex', justifyContent: 'space-between', marginTop: '1rem' }}>
<Button
color=''
fluid
size='large'
onClick={bindEmail}
loading={loading}
>
确认绑定
</Button>
<div style={{ width: '1rem' }}></div>
<Button
fluid
size='large'
onClick={() => setShowEmailBindModal(false)}
>
取消
</Button>
<Button
color=''
fluid
size='large'
onClick={bindEmail}
loading={loading}
>
{t('setting.personal.binding.email.bind')}
</Button>
<div style={{ width: '1rem' }}></div>
<Button
fluid
size='large'
onClick={() => setShowEmailBindModal(false)}
>
{t('setting.personal.binding.email.cancel')}
</Button>
</div>
</Form>
</Modal.Description>
@@ -329,27 +325,27 @@ const PersonalSetting = () => {
size={'tiny'}
style={{ maxWidth: '450px' }}
>
<Modal.Header>危险操作</Modal.Header>
<Modal.Header>{t('setting.personal.delete_account.title')}</Modal.Header>
<Modal.Content>
<Message>您正在删除自己的帐户将清空所有数据且不可恢复</Message>
<Message>{t('setting.personal.delete_account.warning')}</Message>
<Modal.Description>
<Form size='large'>
<Form.Input
fluid
placeholder={`输入你的账户名 ${userState?.user?.username} 以确认删除`}
placeholder={t('setting.personal.delete_account.confirm_placeholder', {
username: userState?.user?.username
})}
name='self_account_deletion_confirmation'
value={inputs.self_account_deletion_confirmation}
onChange={handleInputChange}
/>
{turnstileEnabled ? (
{turnstileEnabled && (
<Turnstile
sitekey={turnstileSiteKey}
onVerify={(token) => {
setTurnstileToken(token);
}}
/>
) : (
<></>
)}
<div style={{ display: 'flex', justifyContent: 'space-between', marginTop: '1rem' }}>
<Button
@@ -359,7 +355,7 @@ const PersonalSetting = () => {
onClick={deleteAccount}
loading={loading}
>
确认删除
{t('setting.personal.delete_account.buttons.confirm')}
</Button>
<div style={{ width: '1rem' }}></div>
<Button
@@ -367,7 +363,7 @@ const PersonalSetting = () => {
size='large'
onClick={() => setShowAccountDeleteModal(false)}
>
取消
{t('setting.personal.delete_account.buttons.cancel')}
</Button>
</div>
</Form>