feat translation of the user module

Signed-off-by: jingyang <3161362058@qq.com>
This commit is contained in:
jingyang
2023-08-02 10:50:38 +08:00
parent 911c5c00ba
commit 2f28f57d78
8 changed files with 111 additions and 25 deletions

View File

@@ -39,6 +39,21 @@
"Set OpenAI Account Failed": "Set OpenAI account failed",
"Update Password": "Update Password",
"Update password failed": "Update password failed",
"Update password succseful": "Update password succseful"
"Update password succseful": "Update password succseful",
"Personal Information": "Personal",
"Usage Record": "Usage",
"Recharge Record": "Recharge",
"Notice": "Notice",
"Sign Out": "Sign Out",
"Avatar": "Avatar",
"Account": "Account",
"Balance": "Balance",
"Time": "Time",
"Source": "Source",
"Application Name": "Application Name",
"Total Amount": "Total Amount",
"Change": "Change",
"Password": "Password",
"Replace": "Replace"
}
}
}

View File

@@ -39,6 +39,21 @@
"Set OpenAI Account Failed": "设置 OpenAI 账号异常",
"Update Password": "修改密码",
"Update password failed": "修改密码异常",
"Update password succseful": "修改密码成功"
"Update password succseful": "修改密码成功",
"Personal Information": "个人信息",
"Usage Record": "使用记录",
"Recharge Record": "充值记录",
"Notice": "通知",
"Sign Out": "登出",
"Avatar": "头像",
"Account": "账号",
"Balance": "余额",
"Time": "时间",
"Source": "来源",
"Application Name": "应用名",
"Total Amount": "总金额",
"Change": "变更",
"Password": "密码",
"Replace": "更换"
}
}
}

View File

@@ -2,6 +2,7 @@ import React, { useMemo } from 'react';
import { Box, Flex, useTheme } from '@chakra-ui/react';
import type { GridProps } from '@chakra-ui/react';
import MyIcon, { type IconName } from '../Icon';
import { useTranslation } from 'next-i18next';
// @ts-ignore
export interface Props extends GridProps {
@@ -12,6 +13,7 @@ export interface Props extends GridProps {
}
const SideTabs = ({ list, size = 'md', activeId, onChange, ...props }: Props) => {
const { t } = useTranslation();
const sizeMap = useMemo(() => {
switch (size) {
case 'sm':
@@ -61,7 +63,7 @@ const SideTabs = ({ list, size = 'md', activeId, onChange, ...props }: Props) =>
}}
>
<MyIcon mr={2} name={item.icon as IconName} w={'16px'} />
{item.label}
{t(item.label)}
</Flex>
))}
</Box>

View File

@@ -22,10 +22,11 @@ import DateRangePicker, { type DateRangeType } from '@/components/DateRangePicke
import { addDays } from 'date-fns';
import dynamic from 'next/dynamic';
import { useGlobalStore } from '@/store/global';
import { useTranslation } from 'next-i18next';
const BillDetail = dynamic(() => import('./BillDetail'));
const BillTable = () => {
const { t } = useTranslation();
const { Loading } = useLoading();
const [dateRange, setDateRange] = useState<DateRangeType>({
from: addDays(new Date(), -7),
@@ -55,10 +56,10 @@ const BillTable = () => {
<Table>
<Thead>
<Tr>
<Th></Th>
<Th></Th>
<Th></Th>
<Th></Th>
<Th>{t('user.Time')}</Th>
<Th>{t('user.Source')}</Th>
<Th>{t('user.Application Name')}</Th>
<Th>{t('user.Total Amount')}</Th>
<Th></Th>
</Tr>
</Thead>

View File

@@ -10,8 +10,7 @@ import dynamic from 'next/dynamic';
import { useSelectFile } from '@/hooks/useSelectFile';
import { compressImg } from '@/utils/file';
import { feConfigs } from '@/store/static';
import { useTranslation } from 'react-i18next';
import { useTranslation } from 'next-i18next';
import Loading from '@/components/Loading';
import Avatar from '@/components/Avatar';
import MyIcon from '@/components/Icon';
@@ -125,7 +124,7 @@ const UserInfo = () => {
<Flex alignItems={'center'} fontSize={'sm'} color={'myGray.600'}>
<MyIcon mr={1} name={'edit'} w={'14px'} />
{t('user.Replace')}
</Flex>
</Flex>
<Box
@@ -136,26 +135,26 @@ const UserInfo = () => {
mt={[6, 0]}
>
<Flex alignItems={'center'} w={['85%', '300px']}>
<Box flex={'0 0 50px'}>:</Box>
<Box flex={'0 0 50px'}>{t('user.Account')}:&nbsp;</Box>
<Box flex={1}>{userInfo?.username}</Box>
</Flex>
<Flex mt={6} alignItems={'center'} w={['85%', '300px']}>
<Box flex={'0 0 50px'}>:</Box>
<Box flex={'0 0 50px'}>{t('user.Password')}:&nbsp;</Box>
<Box flex={1}>*****</Box>
<Button size={['sm', 'md']} variant={'base'} ml={5} onClick={onOpenUpdatePsw}>
{t('user.Change')}
</Button>
</Flex>
{feConfigs?.show_userDetail && (
<>
<Box mt={6} whiteSpace={'nowrap'} w={['85%', '300px']}>
<Flex alignItems={'center'}>
<Box flex={'0 0 50px'}>:</Box>
<Box flex={'0 0 50px'}>{t('user.Balance')}:&nbsp;</Box>
<Box flex={1}>
<strong>{userInfo?.balance.toFixed(3)}</strong>
</Box>
<Button size={['sm', 'md']} ml={5} onClick={onOpenPayModal}>
{t('user.Pay')}
</Button>
</Flex>
</Box>

View File

@@ -32,11 +32,36 @@ enum TabEnum {
const Account = ({ currentTab }: { currentTab: `${TabEnum}` }) => {
const tabList = useRef([
{ icon: 'meLight', label: '个人信息', id: TabEnum.info, Component: <BillTable /> },
{ icon: 'billRecordLight', label: '使用记录', id: TabEnum.bill, Component: <BillTable /> },
{ icon: 'payRecordLight', label: '充值记录', id: TabEnum.pay, Component: <PayRecordTable /> },
{ icon: 'informLight', label: '通知', id: TabEnum.inform, Component: <InformTable /> },
{ icon: 'loginoutLight', label: '登出', id: TabEnum.loginout, Component: () => <></> }
{
icon: 'meLight',
label: 'user.Personal Information',
id: TabEnum.info,
Component: <BillTable />
},
{
icon: 'billRecordLight',
label: 'user.Usage Record',
id: TabEnum.bill,
Component: <BillTable />
},
{
icon: 'payRecordLight',
label: 'user.Recharge Record',
id: TabEnum.pay,
Component: <PayRecordTable />
},
{
icon: 'informLight',
label: 'user.Notice',
id: TabEnum.inform,
Component: <InformTable />
},
{
icon: 'loginoutLight',
label: 'user.Sign Out',
id: TabEnum.loginout,
Component: () => <></>
}
]);
const { openConfirm, ConfirmModal } = useConfirm({

View File

@@ -13,7 +13,7 @@ import { TrainingModeEnum } from '@/constants/plugin';
import FileSelect from './FileSelect';
import { useRouter } from 'next/router';
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 12);
import { readCsvContent } from '@/utils/file';
import { fileDownload, readCsvContent } from '@/utils/file';
const fileExtension = '.csv';
@@ -137,6 +137,7 @@ const CsvImport = ({ kbId }: { kbId: string }) => {
isLoading={selecting}
tipText={'如果导入文件乱码,请将 CSV 转成 utf-8 编码格式'}
py={emptyFiles ? '100px' : 5}
isCsv
/>
{!emptyFiles && (

View File

@@ -4,16 +4,26 @@ import { useLoading } from '@/hooks/useLoading';
import { useSelectFile } from '@/hooks/useSelectFile';
import MyIcon from '@/components/Icon';
import { fileDownload } from '@/utils/file';
interface Props extends BoxProps {
fileExtension: string;
tipText?: string;
onSelectFile: (files: File[]) => Promise<void>;
isLoading?: boolean;
isCsv?: boolean;
}
const FileSelect = ({ fileExtension, onSelectFile, isLoading, tipText, ...props }: Props) => {
const FileSelect = ({
fileExtension,
onSelectFile,
isLoading,
tipText,
isCsv = false,
...props
}: Props) => {
const { Loading: FileSelectLoading } = useLoading();
const csvTemplate = `question,answer\n"什么是 laf","laf 是一个云函数开发平台……"\n"什么是 sealos","Sealos 是以 kubernetes 为内核的云操作系统发行版,可以……"`;
const { File, onOpen } = useSelectFile({
fileType: fileExtension,
@@ -47,6 +57,24 @@ const FileSelect = ({ fileExtension, onSelectFile, isLoading, tipText, ...props
{tipText}
</Box>
)}
{isCsv && (
<Box
my={3}
cursor={'pointer'}
textDecoration={'underline'}
color={'myBlue.600'}
fontSize={'12px'}
onClick={() =>
fileDownload({
text: csvTemplate,
type: 'text/csv',
filename: 'template.csv'
})
}
>
csv模板
</Box>
)}
<FileSelectLoading loading={isLoading} fixed={false} />
<File onSelect={onSelectFile} />
</Box>