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": { "redemption": {
"title": "Redemption Management", "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": { "edit": {
"title_edit": "Update Redemption Code", "title_edit": "Update Redemption Code",
"title_create": "Create New Redemption Code", "title_create": "Create New Redemption Code",
@@ -256,6 +284,10 @@
"submit": "Submit", "submit": "Submit",
"cancel": "Cancel" "cancel": "Cancel"
} }
},
"messages": {
"update_success": "Redemption code updated successfully!",
"create_success": "Redemption code created successfully!"
} }
}, },
"log": { "log": {

View File

@@ -243,6 +243,34 @@
}, },
"redemption": { "redemption": {
"title": "兑换管理", "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": { "edit": {
"title_edit": "更新兑换码信息", "title_edit": "更新兑换码信息",
"title_create": "创建新的兑换码", "title_create": "创建新的兑换码",
@@ -256,6 +284,10 @@
"submit": "提交", "submit": "提交",
"cancel": "取消" "cancel": "取消"
} }
},
"messages": {
"update_success": "兑换码更新成功!",
"create_success": "兑换码创建成功!"
} }
}, },
"log": { "log": {

View File

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

View File

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

View File

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