diff --git a/src/FE/components/Admin/Messages/ChatMessage.tsx b/src/FE/components/Admin/Messages/ChatMessage.tsx index 0005fd91..c158dada 100644 --- a/src/FE/components/Admin/Messages/ChatMessage.tsx +++ b/src/FE/components/Admin/Messages/ChatMessage.tsx @@ -136,9 +136,9 @@ export const ChatMessage: FC = memo( } }} > - + - + {`${currentSelectIndex + 1}/${parentChildrenIds.length }`} @@ -155,7 +155,7 @@ export const ChatMessage: FC = memo( } }} > - + )} @@ -243,9 +243,9 @@ export const ChatMessage: FC = memo( } }} > - + - + {`${assistantCurrentSelectIndex + 1}/${assistantChildrenIds.length }`} @@ -263,7 +263,7 @@ export const ChatMessage: FC = memo( } }} > - + )} diff --git a/src/FE/components/Admin/Models/EditModelModal.tsx b/src/FE/components/Admin/Models/EditModelModal.tsx index e18c5517..60acc246 100644 --- a/src/FE/components/Admin/Models/EditModelModal.tsx +++ b/src/FE/components/Admin/Models/EditModelModal.tsx @@ -157,190 +157,174 @@ export const EditModelModal = (props: IProps) => { {t('Edit Model')} - {loading ? ( -
- -
- - -
-
- ) : ( -
- -
+ + +
+ { + return ( + + ); + }} + > +
{ return ( - + x.modelProviderId === selected.modelProviderId, + ) + .map((keys) => ({ + name: keys.name, + value: keys.id.toString(), + }))} /> ); }} > -
- { - return ( - - x.modelProviderId === selected.modelProviderId, - ) - .map((keys) => ({ - name: keys.name, - value: keys.id.toString(), - }))} - /> - ); - }} - > - +
-
- { - return ( - - ); - }} - > - { - return ( - - ); - }} - > -
-
- { - return ( - - ); - }} - > - { - return ( - - ); - }} - > -
-
+
+
+ { + return ( + + ); + }} + > + { + return ( + + ); + }} + > +
+
+ { + return ( + + ); + }} + > + { + return ( + + ); + }} + > +
+
+ { + return ( + +
+
+
{ return ( -
-
-
- { - return ( - - ); - }} - > -
-
- - - - - - - )} +
+ + + + + + ); diff --git a/src/FE/components/Button/CopyButton.tsx b/src/FE/components/Button/CopyButton.tsx index 769b8a2d..b4ca679e 100644 --- a/src/FE/components/Button/CopyButton.tsx +++ b/src/FE/components/Button/CopyButton.tsx @@ -36,9 +36,9 @@ export default function CopyButton(props: Props) { title={t('Copy')} > {isCopied ? ( - + ) : ( - + )} ); diff --git a/src/FE/components/Chat/ChangeModel.tsx b/src/FE/components/Chat/ChangeModel.tsx index 884eb759..3e0e7bec 100644 --- a/src/FE/components/Chat/ChangeModel.tsx +++ b/src/FE/components/Chat/ChangeModel.tsx @@ -74,11 +74,11 @@ const ChangeModel = ({ diff --git a/src/FE/components/Chat/Chat.tsx b/src/FE/components/Chat/Chat.tsx index 482c9994..88788cc6 100644 --- a/src/FE/components/Chat/Chat.tsx +++ b/src/FE/components/Chat/Chat.tsx @@ -370,37 +370,37 @@ export const Chat = memo(({ stopConversationRef }: Props) => { }; return ( -
+
<>
{selectChat?.id && ( -
-
- {hasModel() && selectMessages?.length != 0 && ( - { - homeDispatch({ - field: 'selectModel', - value: model, - }); - putUserChatModel(selectChat.id, model.modelId); - }} - /> - )} -
-
- {selectMessages?.length === 0 && } +
+
+
+ {hasModel() && ( + { + homeDispatch({ + field: 'selectModel', + value: model, + }); + putUserChatModel(selectChat.id, model.modelId); + }} + /> + )} +
+
{}
)} diff --git a/src/FE/components/Chat/ChatMessage/CopyAction.tsx b/src/FE/components/Chat/ChatMessage/CopyAction.tsx index 647cc128..64994c81 100644 --- a/src/FE/components/Chat/ChatMessage/CopyAction.tsx +++ b/src/FE/components/Chat/ChatMessage/CopyAction.tsx @@ -34,10 +34,7 @@ const CopyAction = (props: Props) => { <> {messagedCopied ? ( ) : ( { className={cn('p-1 m-0 h-auto', triggerClassName)} onClick={() => copyOnClick(text)} > - + } side="bottom" diff --git a/src/FE/components/Chat/ChatMessage/EditAction.tsx b/src/FE/components/Chat/ChatMessage/EditAction.tsx index 5c0319b7..9679f897 100644 --- a/src/FE/components/Chat/ChatMessage/EditAction.tsx +++ b/src/FE/components/Chat/ChatMessage/EditAction.tsx @@ -23,7 +23,7 @@ const EditAction = (props: Props) => { className="p-1 m-0 h-auto invisible group-hover:visible focus:visible" onClick={onToggleEditing} > - + } content={t('Edit message')!} diff --git a/src/FE/components/Chat/ChatMessage/GenerateInformationAction.tsx b/src/FE/components/Chat/ChatMessage/GenerateInformationAction.tsx index d879a121..51576099 100644 --- a/src/FE/components/Chat/ChatMessage/GenerateInformationAction.tsx +++ b/src/FE/components/Chat/ChatMessage/GenerateInformationAction.tsx @@ -35,7 +35,7 @@ export const GenerateInformationAction = (props: Props) => { className="h-[28px]" side="bottom" trigger={ } content={ diff --git a/src/FE/components/Chat/ChatMessage/PaginationAction.tsx b/src/FE/components/Chat/ChatMessage/PaginationAction.tsx index 4f440dfe..e0573f21 100644 --- a/src/FE/components/Chat/ChatMessage/PaginationAction.tsx +++ b/src/FE/components/Chat/ChatMessage/PaginationAction.tsx @@ -34,9 +34,9 @@ export const PaginationAction = (props: Props) => { } }} > - + - + {`${currentSelectIndex + 1}/${messageIds.length}`}
); diff --git a/src/FE/components/Chat/ChatMessage/RegenerateAction.tsx b/src/FE/components/Chat/ChatMessage/RegenerateAction.tsx index 939e5a83..c05ece27 100644 --- a/src/FE/components/Chat/ChatMessage/RegenerateAction.tsx +++ b/src/FE/components/Chat/ChatMessage/RegenerateAction.tsx @@ -25,7 +25,7 @@ export const RegenerateAction = (props: Props) => { onRegenerate && onRegenerate(); }} > - + } content={t('Regenerate')!} diff --git a/src/FE/components/Chat/ModelSelect.tsx b/src/FE/components/Chat/ModelSelect.tsx index 5b6b2e59..1bc843de 100644 --- a/src/FE/components/Chat/ModelSelect.tsx +++ b/src/FE/components/Chat/ModelSelect.tsx @@ -44,12 +44,27 @@ export const ModelSelect = () => { }); }; + const getTitle = () => { + if (modelUsage) { + if (modelUsage.tokens === 0 && modelUsage.counts === 0) { + return t('unit-price'); + } else if (+modelUsage.counts > 0) { + return t('Remaining Chat Counts'); + } else if (+modelUsage.tokens > 0) { + return t('Remaining Tokens'); + } else { + return t('unit-price'); + } + } + return ''; + }; + return (
-
+ {/*
-
+
*/} {modelUsage && modelUsage.tokens === 0 && modelUsage.counts === 0 ? ( - {t('unit-price')}: ¥{modelUsage.inputTokenPrice1M.toFixed(4)}/ + ¥{modelUsage.inputTokenPrice1M.toFixed(4)}/ {modelUsage.outputTokenPrice1M.toFixed(4)} (1M tokens) ) : ( @@ -78,18 +93,12 @@ export const ModelSelect = () => {
{+modelUsage.counts > 0 ? ( - - {t('Remaining Chat Counts')}: {modelUsage.counts} - + {modelUsage.counts} ) : +modelUsage.tokens > 0 ? ( - - {t('Remaining Tokens')}:  - {formatNumberAsMoney(+modelUsage.tokens)} - + {formatNumberAsMoney(+modelUsage.tokens)} ) : ( - {t('unit-price')}: ¥ - {modelUsage.inputTokenPrice1M.toFixed(4)}/ + ¥{modelUsage.inputTokenPrice1M.toFixed(4)}/ {modelUsage.outputTokenPrice1M.toFixed(4)} (1M tokens) )} @@ -99,7 +108,8 @@ export const ModelSelect = () => { <> ) : ( <> - {modelUsage.expires} {` ${t('become due')}`} + {new Date(modelUsage.expires).toLocaleDateString()}{' '} + {` ${t('become due')}`} )}
diff --git a/src/FE/components/Chatbar/ChatbarSettings.tsx b/src/FE/components/Chatbar/ChatbarSettings.tsx index 62542266..1d0da2e3 100644 --- a/src/FE/components/Chatbar/ChatbarSettings.tsx +++ b/src/FE/components/Chatbar/ChatbarSettings.tsx @@ -8,8 +8,6 @@ import { clearUserInfo, clearUserSession, getLoginUrl } from '@/utils/user'; import { UserRole } from '@/types/adminApis'; -import { HomeContext } from '@/contexts/Home.context'; - import { IconBulbFilled, IconKey, @@ -31,6 +29,7 @@ import { import { Separator } from '@/components/ui/separator'; import { getUserBalanceOnly } from '@/apis/clientApis'; +import { HomeContext } from '@/contexts/Home.context'; export const ChatBarSettings = () => { const router = useRouter(); @@ -68,7 +67,7 @@ export const ChatBarSettings = () => { {user?.role === UserRole.admin && ( } + icon={} onClick={() => { router.push('/admin'); }} @@ -81,7 +80,7 @@ export const ChatBarSettings = () => { } + icon={} onClick={handleClickUserMore} /> @@ -90,7 +89,7 @@ export const ChatBarSettings = () => { text={`${t('Account balance')}¥${(+(userBalance || 0)).toFixed( 2, )}`} - icon={} + icon={} onClick={() => { setUserBalanceModalOpen(true); }} @@ -98,14 +97,14 @@ export const ChatBarSettings = () => { } + icon={} onClick={() => { handleUpdateSettings('showPromptBar', !showPromptBar); }} /> } + icon={} onClick={() => { setSettingSheetOpen(true); }} @@ -113,14 +112,14 @@ export const ChatBarSettings = () => { } + icon={} onClick={() => { setChangePwdModalOpen(true); }} /> } + icon={} onClick={logout} /> diff --git a/src/FE/components/Chatbar/ClearConversations.tsx b/src/FE/components/Chatbar/ClearConversations.tsx index df461396..1989ac88 100644 --- a/src/FE/components/Chatbar/ClearConversations.tsx +++ b/src/FE/components/Chatbar/ClearConversations.tsx @@ -50,7 +50,7 @@ export const ClearConversations: FC = ({ onClearConversations }) => { ) : ( } + icon={} onClick={() => setIsConfirming(true)} /> ); diff --git a/src/FE/components/Chatbar/Conversation.tsx b/src/FE/components/Chatbar/Conversation.tsx index 8a9b76e1..43dfb4f8 100644 --- a/src/FE/components/Chatbar/Conversation.tsx +++ b/src/FE/components/Chatbar/Conversation.tsx @@ -174,7 +174,7 @@ export const ConversationComponent = ({ chat }: Props) => { disabled={messageIsStreaming} className="focus:outline-none" > - diff --git a/src/FE/components/Markdown/CodeBlock.tsx b/src/FE/components/Markdown/CodeBlock.tsx index f2fd0a45..f320245f 100644 --- a/src/FE/components/Markdown/CodeBlock.tsx +++ b/src/FE/components/Markdown/CodeBlock.tsx @@ -31,7 +31,7 @@ export const CodeBlock: FC = memo(({ language, value }) => { return (
-
+
{language}
diff --git a/src/FE/components/ModeToggle/ModeTooggle.tsx b/src/FE/components/ModeToggle/ModeTooggle.tsx index c3ca40ba..fc6cb780 100644 --- a/src/FE/components/ModeToggle/ModeTooggle.tsx +++ b/src/FE/components/ModeToggle/ModeTooggle.tsx @@ -11,16 +11,16 @@ export function ModeToggle() { const { setTheme } = useTheme(); return ( - ); diff --git a/src/FE/components/Promptbar/components/Prompt.tsx b/src/FE/components/Promptbar/components/Prompt.tsx index d7ea0490..0e185bf8 100644 --- a/src/FE/components/Promptbar/components/Prompt.tsx +++ b/src/FE/components/Promptbar/components/Prompt.tsx @@ -76,13 +76,13 @@ export const PromptComponent = ({ prompt }: Props) => { const getPromptColor = (prompt: PromptSlim) => { if (prompt.isSystem) { - return '#3b82f6'; + return 'text-green-700'; } else if (prompt.isDefault) { - return '#16a34a'; + return 'text-blue-700'; } else { - return 'grey'; + return 'text-gray-600'; } - } + }; return (
@@ -92,7 +92,7 @@ export const PromptComponent = ({ prompt }: Props) => { handlePromptDetail(e); }} > - +
{prompt.name} diff --git a/src/FE/components/Sidebar/OpenCloseButton.tsx b/src/FE/components/Sidebar/OpenCloseButton.tsx index 9cf9c933..bb4cf537 100644 --- a/src/FE/components/Sidebar/OpenCloseButton.tsx +++ b/src/FE/components/Sidebar/OpenCloseButton.tsx @@ -51,13 +51,13 @@ export const OpenSidebarButton = ({ onClick, side }: Props) => { {side === 'right' ? (
) : (
)} diff --git a/src/FE/components/Sidebar/Sidebar.tsx b/src/FE/components/Sidebar/Sidebar.tsx index b72eb598..11f36044 100644 --- a/src/FE/components/Sidebar/Sidebar.tsx +++ b/src/FE/components/Sidebar/Sidebar.tsx @@ -51,7 +51,7 @@ const Sidebar = ({
({ onClick={toggleOpen} > {side === 'right' ? ( - + ) : ( - + )} } @@ -85,7 +85,7 @@ const Sidebar = ({ variant="ghost" className="p-1 m-0 h-auto" > - + } content={addItemButtonTitle} @@ -124,13 +124,13 @@ const Sidebar = ({ {side === 'right' ? (
) : (
)} @@ -148,7 +148,7 @@ const Sidebar = ({ variant="ghost" className="p-1 m-0 h-auto" > - + } content={addItemButtonTitle} diff --git a/src/FE/hooks/useFetch.ts b/src/FE/hooks/useFetch.ts index 1bd97bf1..2601e46c 100644 --- a/src/FE/hooks/useFetch.ts +++ b/src/FE/hooks/useFetch.ts @@ -17,10 +17,8 @@ export type RequestWithBodyModel = RequestModel & { const readResponse = async (response: Response) => { if (!response.headers) { - console.log(); return response; } - console.log(response.status, [...response.headers.keys()]); const contentType = response.headers.get('content-type'); const contentDisposition = response.headers.get('content-disposition'); @@ -30,7 +28,10 @@ const readResponse = async (response: Response) => { return await response.json(); } else if (contentType.indexOf('text/plain') !== -1) { return await response.text(); - } else if (contentDisposition != null && contentDisposition.indexOf('attachment') !== -1) { + } else if ( + contentDisposition != null && + contentDisposition.indexOf('attachment') !== -1 + ) { return await response.blob(); } else { return null; @@ -77,13 +78,21 @@ export const useFetch = () => { const result = readResponse(response); return result; }) - .catch(async (err) => { - const error = await readResponse(err); - const message = error?.message || error.errMessage || error; + .catch(async (err: Response) => { const { t } = useTranslation(); + const error = await readResponse(err); + let message = error?.message || error?.errMessage || error; + + if (err.status === 500) { + message = 'Internal server error, Please try again later'; + } else if (err.status === 403) { + location.href = '/'; + return; + } + toast.error( t( - typeof message === 'string' + typeof message === 'string' && message !== '' ? message : 'Operation failed, Please try again later, or contact technical personnel', ), diff --git a/src/FE/locales/zh-CN.json b/src/FE/locales/zh-CN.json index 3f7ee86a..614850d8 100644 --- a/src/FE/locales/zh-CN.json +++ b/src/FE/locales/zh-CN.json @@ -95,6 +95,7 @@ "Actions": "操作", "Edit": "编辑", "Operation failed, Please try again later, or contact technical personnel": "操作失败,请稍后再试,或联系技术人员", + "Internal server error, Please try again later": "内部服务器错误,请稍后再试", "Created successful": "创建成功", "Updated successful": "修改成功", "Deleted successful": "删除成功", @@ -355,4 +356,4 @@ "File is empty.": "文件为空。", "File is too large.": "文件过大。", "Invalid file name.": "无效的文件名。" -} \ No newline at end of file +} diff --git a/src/FE/pages/_app.tsx b/src/FE/pages/_app.tsx index cc003b54..8c25e65d 100644 --- a/src/FE/pages/_app.tsx +++ b/src/FE/pages/_app.tsx @@ -1,11 +1,17 @@ +import { useEffect, useState } from 'react'; import { Toaster } from 'react-hot-toast'; import { QueryClient, QueryClientProvider } from 'react-query'; import type { AppProps } from 'next/app'; import { useRouter } from 'next/router'; +import { getUserInfo } from '@/utils/user'; + +import { UserRole } from '@/types/adminApis'; + import { ThemeProvider } from '@/components/Theme/ThemeProvider'; +import ErrorPage from './_error'; import AdminLayout from './admin/layout'; import './globals.css'; @@ -14,6 +20,19 @@ import 'katex/dist/katex.min.css'; function App({ Component, pageProps }: AppProps<{}> | any) { const route = useRouter(); const queryClient = new QueryClient(); + + const [isClient, setIsClient] = useState(false); + + useEffect(() => { + setIsClient(true); + document.title = "Chats"; + }, []); + + const isAdmin = () => { + const user = getUserInfo(); + return user?.role === UserRole.admin; + }; + return ( | any) { disableTransitionOnChange > - - {route.pathname.includes('/admin') ? ( - + {isClient && ( + + {route.pathname.includes('/admin') ? ( + isAdmin() ? ( + + + + ) : ( + + ) + ) : route.pathname.includes('/authorizing') ? ( + + ) : ( - - ) : route.pathname.includes('/authorizing') ? ( - - ) : ( - - )} - + )} + + )} ); } diff --git a/src/FE/pages/_error.tsx b/src/FE/pages/_error.tsx index 61067688..456abe24 100644 --- a/src/FE/pages/_error.tsx +++ b/src/FE/pages/_error.tsx @@ -5,9 +5,11 @@ import useTranslation from '@/hooks/useTranslation'; const Custom404 = () => { const { t } = useTranslation(); return ( -
-

{t('404: Page not found')}

-

{t("Sorry, we couldn't find the page you were trying to access.")}

+
+

{t('404: Page not found')}

+

+ {t("Sorry, we couldn't find the page you were trying to access.")} +

); }; @@ -19,9 +21,14 @@ const ErrorPage = ({ statusCode }: { statusCode: number }) => { } return ( -
-

{statusCode}{t(': An error has occurred')}

-

{t('Sorry, there was an unexpected error, please try again later.')}

+
+

+ {statusCode} + {t(': An error has occurred')} +

+

+ {t('Sorry, there was an unexpected error, please try again later.')} +

); }; diff --git a/src/FE/pages/globals.css b/src/FE/pages/globals.css index 60ccc781..17255b9f 100644 --- a/src/FE/pages/globals.css +++ b/src/FE/pages/globals.css @@ -136,7 +136,7 @@ select:focus { } .md-p { - padding-left: 8px; + padding-left: 6px; white-space: pre-wrap; } diff --git a/src/FE/pages/login/index.tsx b/src/FE/pages/login/index.tsx index 6ed80130..b9af464c 100644 --- a/src/FE/pages/login/index.tsx +++ b/src/FE/pages/login/index.tsx @@ -125,8 +125,8 @@ export default function LoginPage() { <> {!loading && isClient && (
-
-
+
+