feat translation of the user module
Signed-off-by: jingyang <3161362058@qq.com>
This commit is contained in:
@@ -39,6 +39,21 @@
|
|||||||
"Set OpenAI Account Failed": "Set OpenAI account failed",
|
"Set OpenAI Account Failed": "Set OpenAI account failed",
|
||||||
"Update Password": "Update Password",
|
"Update Password": "Update Password",
|
||||||
"Update password failed": "Update password failed",
|
"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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,6 +39,21 @@
|
|||||||
"Set OpenAI Account Failed": "设置 OpenAI 账号异常",
|
"Set OpenAI Account Failed": "设置 OpenAI 账号异常",
|
||||||
"Update Password": "修改密码",
|
"Update Password": "修改密码",
|
||||||
"Update password failed": "修改密码异常",
|
"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": "更换"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ import React, { useMemo } from 'react';
|
|||||||
import { Box, Flex, useTheme } from '@chakra-ui/react';
|
import { Box, Flex, useTheme } from '@chakra-ui/react';
|
||||||
import type { GridProps } from '@chakra-ui/react';
|
import type { GridProps } from '@chakra-ui/react';
|
||||||
import MyIcon, { type IconName } from '../Icon';
|
import MyIcon, { type IconName } from '../Icon';
|
||||||
|
import { useTranslation } from 'next-i18next';
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
export interface Props extends GridProps {
|
export interface Props extends GridProps {
|
||||||
@@ -12,6 +13,7 @@ export interface Props extends GridProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const SideTabs = ({ list, size = 'md', activeId, onChange, ...props }: Props) => {
|
const SideTabs = ({ list, size = 'md', activeId, onChange, ...props }: Props) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const sizeMap = useMemo(() => {
|
const sizeMap = useMemo(() => {
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case 'sm':
|
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'} />
|
<MyIcon mr={2} name={item.icon as IconName} w={'16px'} />
|
||||||
{item.label}
|
{t(item.label)}
|
||||||
</Flex>
|
</Flex>
|
||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -22,10 +22,11 @@ import DateRangePicker, { type DateRangeType } from '@/components/DateRangePicke
|
|||||||
import { addDays } from 'date-fns';
|
import { addDays } from 'date-fns';
|
||||||
import dynamic from 'next/dynamic';
|
import dynamic from 'next/dynamic';
|
||||||
import { useGlobalStore } from '@/store/global';
|
import { useGlobalStore } from '@/store/global';
|
||||||
|
import { useTranslation } from 'next-i18next';
|
||||||
const BillDetail = dynamic(() => import('./BillDetail'));
|
const BillDetail = dynamic(() => import('./BillDetail'));
|
||||||
|
|
||||||
const BillTable = () => {
|
const BillTable = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const { Loading } = useLoading();
|
const { Loading } = useLoading();
|
||||||
const [dateRange, setDateRange] = useState<DateRangeType>({
|
const [dateRange, setDateRange] = useState<DateRangeType>({
|
||||||
from: addDays(new Date(), -7),
|
from: addDays(new Date(), -7),
|
||||||
@@ -55,10 +56,10 @@ const BillTable = () => {
|
|||||||
<Table>
|
<Table>
|
||||||
<Thead>
|
<Thead>
|
||||||
<Tr>
|
<Tr>
|
||||||
<Th>时间</Th>
|
<Th>{t('user.Time')}</Th>
|
||||||
<Th>来源</Th>
|
<Th>{t('user.Source')}</Th>
|
||||||
<Th>应用名</Th>
|
<Th>{t('user.Application Name')}</Th>
|
||||||
<Th>总金额</Th>
|
<Th>{t('user.Total Amount')}</Th>
|
||||||
<Th></Th>
|
<Th></Th>
|
||||||
</Tr>
|
</Tr>
|
||||||
</Thead>
|
</Thead>
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ import dynamic from 'next/dynamic';
|
|||||||
import { useSelectFile } from '@/hooks/useSelectFile';
|
import { useSelectFile } from '@/hooks/useSelectFile';
|
||||||
import { compressImg } from '@/utils/file';
|
import { compressImg } from '@/utils/file';
|
||||||
import { feConfigs } from '@/store/static';
|
import { feConfigs } from '@/store/static';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
|
|
||||||
import Loading from '@/components/Loading';
|
import Loading from '@/components/Loading';
|
||||||
import Avatar from '@/components/Avatar';
|
import Avatar from '@/components/Avatar';
|
||||||
import MyIcon from '@/components/Icon';
|
import MyIcon from '@/components/Icon';
|
||||||
@@ -125,7 +124,7 @@ const UserInfo = () => {
|
|||||||
|
|
||||||
<Flex alignItems={'center'} fontSize={'sm'} color={'myGray.600'}>
|
<Flex alignItems={'center'} fontSize={'sm'} color={'myGray.600'}>
|
||||||
<MyIcon mr={1} name={'edit'} w={'14px'} />
|
<MyIcon mr={1} name={'edit'} w={'14px'} />
|
||||||
更换
|
{t('user.Replace')}
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Box
|
<Box
|
||||||
@@ -136,26 +135,26 @@ const UserInfo = () => {
|
|||||||
mt={[6, 0]}
|
mt={[6, 0]}
|
||||||
>
|
>
|
||||||
<Flex alignItems={'center'} w={['85%', '300px']}>
|
<Flex alignItems={'center'} w={['85%', '300px']}>
|
||||||
<Box flex={'0 0 50px'}>账号:</Box>
|
<Box flex={'0 0 50px'}>{t('user.Account')}: </Box>
|
||||||
<Box flex={1}>{userInfo?.username}</Box>
|
<Box flex={1}>{userInfo?.username}</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex mt={6} alignItems={'center'} w={['85%', '300px']}>
|
<Flex mt={6} alignItems={'center'} w={['85%', '300px']}>
|
||||||
<Box flex={'0 0 50px'}>密码:</Box>
|
<Box flex={'0 0 50px'}>{t('user.Password')}: </Box>
|
||||||
<Box flex={1}>*****</Box>
|
<Box flex={1}>*****</Box>
|
||||||
<Button size={['sm', 'md']} variant={'base'} ml={5} onClick={onOpenUpdatePsw}>
|
<Button size={['sm', 'md']} variant={'base'} ml={5} onClick={onOpenUpdatePsw}>
|
||||||
变更
|
{t('user.Change')}
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
{feConfigs?.show_userDetail && (
|
{feConfigs?.show_userDetail && (
|
||||||
<>
|
<>
|
||||||
<Box mt={6} whiteSpace={'nowrap'} w={['85%', '300px']}>
|
<Box mt={6} whiteSpace={'nowrap'} w={['85%', '300px']}>
|
||||||
<Flex alignItems={'center'}>
|
<Flex alignItems={'center'}>
|
||||||
<Box flex={'0 0 50px'}>余额:</Box>
|
<Box flex={'0 0 50px'}>{t('user.Balance')}: </Box>
|
||||||
<Box flex={1}>
|
<Box flex={1}>
|
||||||
<strong>{userInfo?.balance.toFixed(3)}</strong> 元
|
<strong>{userInfo?.balance.toFixed(3)}</strong> 元
|
||||||
</Box>
|
</Box>
|
||||||
<Button size={['sm', 'md']} ml={5} onClick={onOpenPayModal}>
|
<Button size={['sm', 'md']} ml={5} onClick={onOpenPayModal}>
|
||||||
充值
|
{t('user.Pay')}
|
||||||
</Button>
|
</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -32,11 +32,36 @@ enum TabEnum {
|
|||||||
|
|
||||||
const Account = ({ currentTab }: { currentTab: `${TabEnum}` }) => {
|
const Account = ({ currentTab }: { currentTab: `${TabEnum}` }) => {
|
||||||
const tabList = useRef([
|
const tabList = useRef([
|
||||||
{ icon: 'meLight', label: '个人信息', id: TabEnum.info, Component: <BillTable /> },
|
{
|
||||||
{ icon: 'billRecordLight', label: '使用记录', id: TabEnum.bill, Component: <BillTable /> },
|
icon: 'meLight',
|
||||||
{ icon: 'payRecordLight', label: '充值记录', id: TabEnum.pay, Component: <PayRecordTable /> },
|
label: 'user.Personal Information',
|
||||||
{ icon: 'informLight', label: '通知', id: TabEnum.inform, Component: <InformTable /> },
|
id: TabEnum.info,
|
||||||
{ icon: 'loginoutLight', label: '登出', id: TabEnum.loginout, Component: () => <></> }
|
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({
|
const { openConfirm, ConfirmModal } = useConfirm({
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { TrainingModeEnum } from '@/constants/plugin';
|
|||||||
import FileSelect from './FileSelect';
|
import FileSelect from './FileSelect';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 12);
|
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 12);
|
||||||
import { readCsvContent } from '@/utils/file';
|
import { fileDownload, readCsvContent } from '@/utils/file';
|
||||||
|
|
||||||
const fileExtension = '.csv';
|
const fileExtension = '.csv';
|
||||||
|
|
||||||
@@ -137,6 +137,7 @@ const CsvImport = ({ kbId }: { kbId: string }) => {
|
|||||||
isLoading={selecting}
|
isLoading={selecting}
|
||||||
tipText={'如果导入文件乱码,请将 CSV 转成 utf-8 编码格式'}
|
tipText={'如果导入文件乱码,请将 CSV 转成 utf-8 编码格式'}
|
||||||
py={emptyFiles ? '100px' : 5}
|
py={emptyFiles ? '100px' : 5}
|
||||||
|
isCsv
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{!emptyFiles && (
|
{!emptyFiles && (
|
||||||
|
|||||||
@@ -4,16 +4,26 @@ import { useLoading } from '@/hooks/useLoading';
|
|||||||
import { useSelectFile } from '@/hooks/useSelectFile';
|
import { useSelectFile } from '@/hooks/useSelectFile';
|
||||||
|
|
||||||
import MyIcon from '@/components/Icon';
|
import MyIcon from '@/components/Icon';
|
||||||
|
import { fileDownload } from '@/utils/file';
|
||||||
|
|
||||||
interface Props extends BoxProps {
|
interface Props extends BoxProps {
|
||||||
fileExtension: string;
|
fileExtension: string;
|
||||||
tipText?: string;
|
tipText?: string;
|
||||||
onSelectFile: (files: File[]) => Promise<void>;
|
onSelectFile: (files: File[]) => Promise<void>;
|
||||||
isLoading?: boolean;
|
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 { Loading: FileSelectLoading } = useLoading();
|
||||||
|
const csvTemplate = `question,answer\n"什么是 laf","laf 是一个云函数开发平台……"\n"什么是 sealos","Sealos 是以 kubernetes 为内核的云操作系统发行版,可以……"`;
|
||||||
|
|
||||||
const { File, onOpen } = useSelectFile({
|
const { File, onOpen } = useSelectFile({
|
||||||
fileType: fileExtension,
|
fileType: fileExtension,
|
||||||
@@ -47,6 +57,24 @@ const FileSelect = ({ fileExtension, onSelectFile, isLoading, tipText, ...props
|
|||||||
{tipText}
|
{tipText}
|
||||||
</Box>
|
</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} />
|
<FileSelectLoading loading={isLoading} fixed={false} />
|
||||||
<File onSelect={onSelectFile} />
|
<File onSelect={onSelectFile} />
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
Reference in New Issue
Block a user