feat: i18n support

This commit is contained in:
JustSong 2025-02-01 17:04:31 +08:00
parent ae20aea555
commit 2c8c29bfc7
5 changed files with 110 additions and 37 deletions

View File

@ -243,6 +243,34 @@
},
"redemption": {
"title": "Redemption Management",
"search": "Search redemption codes by ID and name ...",
"table": {
"id": "ID",
"name": "Name",
"status": "Status",
"quota": "Quota",
"created_time": "Created Time",
"redeemed_time": "Redeemed Time",
"actions": "Actions",
"no_name": "None",
"not_redeemed": "Not Redeemed"
},
"buttons": {
"copy": "Copy",
"delete": "Delete",
"confirm_delete": "Confirm Delete",
"enable": "Enable",
"disable": "Disable",
"edit": "Edit",
"add": "Add New Code",
"refresh": "Refresh"
},
"status": {
"unused": "Unused",
"disabled": "Disabled",
"used": "Used",
"unknown": "Unknown"
},
"edit": {
"title_edit": "Update Redemption Code",
"title_create": "Create New Redemption Code",
@ -256,6 +284,10 @@
"submit": "Submit",
"cancel": "Cancel"
}
},
"messages": {
"update_success": "Redemption code updated successfully!",
"create_success": "Redemption code created successfully!"
}
},
"log": {

View File

@ -243,6 +243,34 @@
},
"redemption": {
"title": "兑换管理",
"search": "搜索兑换码的 ID 和名称 ...",
"table": {
"id": "ID",
"name": "名称",
"status": "状态",
"quota": "额度",
"created_time": "创建时间",
"redeemed_time": "兑换时间",
"actions": "操作",
"no_name": "无",
"not_redeemed": "尚未兑换"
},
"buttons": {
"copy": "复制",
"delete": "删除",
"confirm_delete": "确认删除",
"enable": "启用",
"disable": "禁用",
"edit": "编辑",
"add": "添加新的兑换码",
"refresh": "刷新"
},
"status": {
"unused": "未使用",
"disabled": "已禁用",
"used": "已使用",
"unknown": "未知状态"
},
"edit": {
"title_edit": "更新兑换码信息",
"title_create": "创建新的兑换码",
@ -256,6 +284,10 @@
"submit": "提交",
"cancel": "取消"
}
},
"messages": {
"update_success": "兑换码更新成功!",
"create_success": "兑换码创建成功!"
}
},
"log": {

View File

@ -176,6 +176,12 @@ const RedemptionsTable = () => {
setLoading(false);
};
const refresh = async () => {
setLoading(true);
await loadRedemptions(0);
setActivePage(1);
};
return (
<>
<Form onSubmit={searchRedemptions}>
@ -183,7 +189,7 @@ const RedemptionsTable = () => {
icon='search'
fluid
iconPosition='left'
placeholder='搜索兑换码的 ID 和名称 ...'
placeholder={t('redemption.search')}
value={searchKeyword}
loading={searching}
onChange={handleKeywordChange}
@ -199,7 +205,7 @@ const RedemptionsTable = () => {
sortRedemption('id');
}}
>
ID
{t('redemption.table.id')}
</Table.HeaderCell>
<Table.HeaderCell
style={{ cursor: 'pointer' }}
@ -207,7 +213,7 @@ const RedemptionsTable = () => {
sortRedemption('name');
}}
>
名称
{t('redemption.table.name')}
</Table.HeaderCell>
<Table.HeaderCell
style={{ cursor: 'pointer' }}
@ -215,7 +221,7 @@ const RedemptionsTable = () => {
sortRedemption('status');
}}
>
状态
{t('redemption.table.status')}
</Table.HeaderCell>
<Table.HeaderCell
style={{ cursor: 'pointer' }}
@ -223,7 +229,7 @@ const RedemptionsTable = () => {
sortRedemption('quota');
}}
>
额度
{t('redemption.table.quota')}
</Table.HeaderCell>
<Table.HeaderCell
style={{ cursor: 'pointer' }}
@ -231,7 +237,7 @@ const RedemptionsTable = () => {
sortRedemption('created_time');
}}
>
创建时间
{t('redemption.table.created_time')}
</Table.HeaderCell>
<Table.HeaderCell
style={{ cursor: 'pointer' }}
@ -239,9 +245,9 @@ const RedemptionsTable = () => {
sortRedemption('redeemed_time');
}}
>
兑换时间
{t('redemption.table.redeemed_time')}
</Table.HeaderCell>
<Table.HeaderCell>操作</Table.HeaderCell>
<Table.HeaderCell>{t('redemption.table.actions')}</Table.HeaderCell>
</Table.Row>
</Table.Header>
@ -276,21 +282,19 @@ const RedemptionsTable = () => {
positive
onClick={async () => {
if (await copy(redemption.key)) {
showSuccess('已复制到剪贴板!');
showSuccess(t('redemption.messages.copy_success'));
} else {
showWarning(
'无法复制到剪贴板,请手动复制,已将兑换码填入搜索框。'
);
showWarning(t('redemption.messages.copy_failed'));
setSearchKeyword(redemption.key);
}
}}
>
复制
{t('redemption.buttons.copy')}
</Button>
<Popup
trigger={
<Button size='small' negative>
删除
{t('redemption.buttons.delete')}
</Button>
}
on='click'
@ -303,7 +307,7 @@ const RedemptionsTable = () => {
manageRedemption(redemption.id, 'delete', idx);
}}
>
确认删除
{t('redemption.buttons.confirm_delete')}
</Button>
</Popup>
<Button
@ -317,14 +321,16 @@ const RedemptionsTable = () => {
);
}}
>
{redemption.status === 1 ? '禁用' : '启用'}
{redemption.status === 1
? t('redemption.buttons.disable')
: t('redemption.buttons.enable')}
</Button>
<Button
size={'small'}
as={Link}
to={'/redemption/edit/' + redemption.id}
>
编辑
{t('redemption.buttons.edit')}
</Button>
</div>
</Table.Cell>
@ -335,14 +341,12 @@ const RedemptionsTable = () => {
<Table.Footer>
<Table.Row>
<Table.HeaderCell colSpan='8'>
<Button
size='small'
as={Link}
to='/redemption/add'
loading={loading}
>
添加新的兑换码
<Table.HeaderCell colSpan='7'>
<Button size='small' as={Link} to='/redemption/add' loading={loading}>
{t('redemption.buttons.add')}
</Button>
<Button size='small' onClick={refresh} loading={loading}>
{t('redemption.buttons.refresh')}
</Button>
<Pagination
floated='right'

View File

@ -63,9 +63,9 @@ const EditRedemption = () => {
const { success, message, data } = res.data;
if (success) {
if (isEdit) {
showSuccess('兑换码更新成功!');
showSuccess(t('redemption.messages.update_success'));
} else {
showSuccess('兑换码创建成功!');
showSuccess(t('redemption.messages.create_success'));
setInputs(originInputs);
}
} else {

View File

@ -1,16 +1,21 @@
import React from 'react';
import { Card } from 'semantic-ui-react';
import { useTranslation } from 'react-i18next';
import RedemptionsTable from '../../components/RedemptionsTable';
const Redemption = () => (
<div className='dashboard-container'>
<Card fluid className='chart-card'>
<Card.Content>
<Card.Header className='header'>兑换管理</Card.Header>
<RedemptionsTable />
</Card.Content>
</Card>
</div>
);
const Redemption = () => {
const { t } = useTranslation();
return (
<div className='dashboard-container'>
<Card fluid className='chart-card'>
<Card.Content>
<Card.Header className='header'>{t('redemption.title')}</Card.Header>
<RedemptionsTable />
</Card.Content>
</Card>
</div>
);
};
export default Redemption;