import { ChatContext } from '@/app/chat-context'; import { DarkSvg, SunnySvg } from '@/components/icons'; import UserBar from '@/new-components/layout/UserBar'; import { STORAGE_LANG_KEY, STORAGE_THEME_KEY, STORAGE_USERINFO_KEY } from '@/utils/constants/index'; import Icon, { GlobalOutlined, MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons'; import { Popover, Tooltip } from 'antd'; import { ItemType } from 'antd/es/menu/hooks/useItems'; import cls from 'classnames'; import moment from 'moment'; import 'moment/locale/zh-cn'; import Image from 'next/image'; import Link from 'next/link'; import { useRouter } from 'next/router'; import { ReactNode, useCallback, useContext, useEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; type SettingItem = { key: string; name: string; icon: ReactNode; noDropdownItem?: boolean; onClick?: () => void; items?: ItemType[]; onSelect?: (p: { key: string }) => void; defaultSelectedKeys?: string[]; placement?: 'top' | 'topLeft'; }; type RouteItem = { key: string; name: string; icon: ReactNode; path: string; isActive?: boolean; }; // TODO: unused function // function menuItemStyle(active?: boolean) { // return `flex items-center h-12 hover:bg-[#F1F5F9] dark:hover:bg-theme-dark text-base w-full transition-colors whitespace-nowrap px-4 ${ // active ? 'bg-[#F1F5F9] dark:bg-theme-dark' : '' // }`; // } function smallMenuItemStyle(active?: boolean) { return `flex items-center justify-center mx-auto rounded w-14 h-14 text-xl hover:bg-[#F1F5F9] dark:hover:bg-theme-dark transition-colors cursor-pointer ${ active ? 'bg-[#F1F5F9] dark:bg-theme-dark' : '' }`; } function SideBar() { // const { chatId, scene, isMenuExpand, refreshDialogList, setIsMenuExpand, setAgent, mode, setMode, adminList } = // useContext(ChatContext); const { isMenuExpand, setIsMenuExpand, mode, setMode, adminList } = useContext(ChatContext); const { pathname } = useRouter(); const { t, i18n } = useTranslation(); const [logo, setLogo] = useState('/logo_zh_latest.png'); const hasAdmin = useMemo(() => { const { user_id } = JSON.parse(localStorage.getItem(STORAGE_USERINFO_KEY) || '{}'); return adminList.some(admin => admin.user_id === user_id); }, [adminList]); // TODO: unused function // const routes = useMemo(() => { // const items: RouteItem[] = [ // { // key: 'app', // name: t('App'), // path: '/app', // icon: , // }, // { // key: 'flow', // name: t('awel_flow'), // icon: , // path: '/flow', // }, // { // key: 'models', // name: t('model_manage'), // path: '/models', // icon: , // }, // { // key: 'database', // name: t('Database'), // icon: , // path: '/database', // }, // { // key: 'knowledge', // name: t('Knowledge_Space'), // icon: , // path: '/knowledge', // }, // { // key: 'agent', // name: t('Plugins'), // path: '/agent', // icon: , // }, // { // key: 'prompt', // name: t('Prompt'), // icon: , // path: '/prompt', // }, // ]; // return items; // }, [t]); const handleToggleMenu = useCallback(() => { setIsMenuExpand(!isMenuExpand); }, [isMenuExpand, setIsMenuExpand]); const handleToggleTheme = useCallback(() => { const theme = mode === 'light' ? 'dark' : 'light'; setMode(theme); localStorage.setItem(STORAGE_THEME_KEY, theme); }, [mode, setMode]); const handleChangeLang = useCallback(() => { const language = i18n.language === 'en' ? 'zh' : 'en'; i18n.changeLanguage(language); if (language === 'zh') moment.locale('zh-cn'); if (language === 'en') moment.locale('en'); localStorage.setItem(STORAGE_LANG_KEY, language); }, [i18n]); const settings = useMemo(() => { const items: SettingItem[] = [ { key: 'theme', name: t('Theme'), icon: mode === 'dark' ? : , items: [ { key: 'light', label: (
english Light
), }, { key: 'dark', label: (
english Dark
), }, ], onClick: handleToggleTheme, onSelect: ({ key }: { key: string }) => { if (mode === key) return; setMode(key as 'light' | 'dark'); localStorage.setItem(STORAGE_THEME_KEY, key); }, defaultSelectedKeys: [mode], placement: 'topLeft', }, { key: 'language', name: t('language'), icon: , items: [ { key: 'en', label: (
english English
), }, { key: 'zh', label: (
english 简体中文
), }, ], onSelect: ({ key }: { key: string }) => { if (i18n.language === key) return; i18n.changeLanguage(key); if (key === 'zh') moment.locale('zh-cn'); if (key === 'en') moment.locale('en'); localStorage.setItem(STORAGE_LANG_KEY, key); }, onClick: handleChangeLang, defaultSelectedKeys: [i18n.language], }, { key: 'fold', name: t(isMenuExpand ? 'Close_Sidebar' : 'Show_Sidebar'), icon: isMenuExpand ? : , onClick: handleToggleMenu, noDropdownItem: true, }, ]; return items; }, [t, mode, handleToggleTheme, i18n, handleChangeLang, isMenuExpand, handleToggleMenu, setMode]); const functions = useMemo(() => { const items: RouteItem[] = [ { key: 'chat', name: t('chat_online'), icon: ( chat_image ), path: '/chat', isActive: pathname.startsWith('/chat'), }, { key: 'explore', name: t('explore'), isActive: pathname === '/', icon: ( construct_image ), path: '/', }, { key: 'construct', name: t('construct'), isActive: pathname.startsWith('/construct'), icon: ( construct_image ), path: '/construct/app', }, ]; if (hasAdmin) { items.push({ key: 'evaluation', name: '场景评测', icon: ( construct_image ), path: '/evaluation', isActive: pathname === '/evaluation', }); } return items; }, [t, pathname, hasAdmin]); // TODO: unused function // const dropDownRoutes: ItemType[] = useMemo(() => { // return routes.map(item => ({ // key: item.key, // label: ( // // {item.icon} // {item.name} // // ), // })); // }, [routes]); // TODO: unused function // const dropDownSettings: ItemType[] = useMemo(() => { // return settings // .filter(item => !item.noDropdownItem) // .map(item => ({ // key: item.key, // label: ( //
// {item.icon} // {item.name} //
// ), // })); // }, [settings]); // TODO: unused function // const dropDownFunctions: ItemType[] = useMemo(() => { // return functions.map(item => ({ // key: item.key, // label: ( // // {item.icon} // {item.name} // // ), // })); // }, [functions]); // TODO: unused function // const handleDelChat = useCallback( // (dialogue: IChatDialogueSchema) => { // Modal.confirm({ // title: 'Delete Chat', // content: 'Are you sure delete this chat?', // width: '276px', // centered: true, // onOk() { // return new Promise(async (resolve, reject) => { // try { // const [err] = await apiInterceptors(delDialogue(dialogue.conv_uid)); // if (err) { // reject(); // return; // } // message.success('success'); // refreshDialogList(); // dialogue.chat_mode === scene && dialogue.conv_uid === chatId && replace('/'); // resolve(); // } catch (e) { // reject(); // } // }); // }, // }); // }, // [chatId, refreshDialogList, replace, scene], // ); // TODO: unused function // const handleClickChatItem = (item: IChatDialogueSchema) => { // if (item.chat_mode === 'chat_agent' && item.select_param) { // setAgent?.(item.select_param); // } // }; // TODO: unused function // const copyLink = useCallback((item: IChatDialogueSchema) => { // const success = copy(`${location.origin}/chat?scene=${item.chat_mode}&id=${item.conv_uid}`); // message[success ? 'success' : 'error'](success ? 'Copy success' : 'Copy failed'); // }, []); // useEffect(() => { // queryDialogueList(); // }, [queryDialogueList]); useEffect(() => { const language = i18n.language; if (language === 'zh') moment.locale('zh-cn'); if (language === 'en') moment.locale('en'); }, []); useEffect(() => { setLogo(mode === 'dark' ? '/logo_s_latest.png' : '/logo_zh_latest.png'); }, [mode]); if (!isMenuExpand) { return (
{ // setIsMenuExpand(true); // }} >
DB-GPT
{functions.map(i => ( {i?.icon} ))}
{settings .filter(item => item.noDropdownItem) .map(item => (
{item.icon}
))}
); } return (
{ // setIsMenuExpand(false); // }} >
{/* LOGO */} DB-GPT {/* functions */}
{functions.map(item => { return (
{item.icon}
{t(item.name as any)} ); })}
{/* Settings */}
{settings.map(item => (
{item.icon}
{/* {item.items ? ( {item.icon} ) : (
{item.icon}
)} */}
))}
); } export default SideBar;