diff --git a/app/src/components/admin/MenuBar.tsx b/app/src/components/admin/MenuBar.tsx
new file mode 100644
index 0000000..12dac19
--- /dev/null
+++ b/app/src/components/admin/MenuBar.tsx
@@ -0,0 +1,50 @@
+import {useSelector} from "react-redux";
+import {selectMenu} from "@/store/menu.ts";
+import React, {useEffect, useMemo, useState} from "react";
+import {LayoutDashboard, Settings} from "lucide-react";
+import router from "@/router.tsx";
+import {useLocation} from "react-router-dom";
+
+type MenuItemProps = {
+ title: string;
+ icon: React.ReactNode;
+ path: string;
+}
+
+function MenuItem({ title, icon, path }: MenuItemProps) {
+ const location = useLocation();
+ const active = useMemo(() => (
+ location.pathname === `/admin${path}` || (location.pathname + "/") === `/admin${path}`
+ ), [location.pathname, path]);
+
+ return (
+
router.navigate(`/admin${path}`)}
+ >
+
+ {icon}
+
+
+ {title}
+
+
+ )
+}
+
+function MenuBar() {
+ const open = useSelector(selectMenu);
+ const [close, setClose] = useState(false);
+ useEffect(() => {
+ if (open) setClose(false);
+ else setTimeout(() => setClose(true), 200);
+ }, [open]);
+
+ return (
+
+ } path={"/"} />
+ } path={"/config"} />
+
+ )
+}
+
+export default MenuBar;
diff --git a/app/src/components/home/ChatWrapper.tsx b/app/src/components/home/ChatWrapper.tsx
index 0f6cec4..8417184 100644
--- a/app/src/components/home/ChatWrapper.tsx
+++ b/app/src/components/home/ChatWrapper.tsx
@@ -15,12 +15,12 @@ import { useToast } from "@/components/ui/use-toast.ts";
import { ToastAction } from "@/components/ui/toast.tsx";
import { alignSelector, contextSelector } from "@/store/settings.ts";
import { FileArray } from "@/conversation/file.ts";
-import WebToggle from "@/components/home/components/WebToggle.tsx";
+import WebToggle from "@/components/home/assemblies/WebToggle.tsx";
import ChatSpace from "@/components/home/ChatSpace.tsx";
import ChatFooter from "@/components/home/ChatFooter.tsx";
-import SendButton from "@/components/home/components/SendButton.tsx";
-import ChatInput from "@/components/home/components/ChatInput.tsx";
-import ScrollAction from "@/components/home/components/ScrollAction.tsx";
+import SendButton from "@/components/home/assemblies/SendButton.tsx";
+import ChatInput from "@/components/home/assemblies/ChatInput.tsx";
+import ScrollAction from "@/components/home/assemblies/ScrollAction.tsx";
function ChatWrapper() {
const { t } = useTranslation();
@@ -127,7 +127,7 @@ function ChatWrapper() {
await handleSend(auth, model, web)}
diff --git a/app/src/components/home/SideBar.tsx b/app/src/components/home/SideBar.tsx
index f1d8397..d26a228 100644
--- a/app/src/components/home/SideBar.tsx
+++ b/app/src/components/home/SideBar.tsx
@@ -1,6 +1,5 @@
import { useTranslation } from "react-i18next";
import { useDispatch, useSelector } from "react-redux";
-import { RootState } from "@/store";
import { selectAuthenticated, selectUsername } from "@/store/auth.ts";
import { selectCurrent, selectHistory } from "@/store/chat.ts";
import { useRef, useState } from "react";
@@ -17,7 +16,7 @@ import {
updateConversationList,
} from "@/conversation/history.ts";
import { Button } from "@/components/ui/button.tsx";
-import { setMenu } from "@/store/menu.ts";
+import {selectMenu, setMenu} from "@/store/menu.ts";
import {
Copy,
Eraser,
@@ -340,7 +339,7 @@ function SidebarMenu() {
function SideBar() {
const { t } = useTranslation();
const dispatch = useDispatch();
- const open = useSelector((state: RootState) => state.menu.open);
+ const open = useSelector(selectMenu);
const auth = useSelector(selectAuthenticated);
const [operateConversation, setOperateConversation] = useState({
target: null,
diff --git a/app/src/components/home/components/ChatInput.tsx b/app/src/components/home/assemblies/ChatInput.tsx
similarity index 92%
rename from app/src/components/home/components/ChatInput.tsx
rename to app/src/components/home/assemblies/ChatInput.tsx
index f349bf6..20c0762 100644
--- a/app/src/components/home/components/ChatInput.tsx
+++ b/app/src/components/home/assemblies/ChatInput.tsx
@@ -5,7 +5,7 @@ import { useTranslation } from "react-i18next";
type ChatInputProps = {
className?: string;
- ref?: React.RefObject;
+ target?: React.RefObject;
value: string;
onValueChange: (value: string) => void;
onEnterPressed: () => void;
@@ -13,7 +13,7 @@ type ChatInputProps = {
function ChatInput({
className,
- ref,
+ target,
value,
onValueChange,
onEnterPressed,
@@ -24,7 +24,7 @@ function ChatInput({
) => {
onValueChange(e.target.value);
diff --git a/app/src/components/home/components/ScrollAction.tsx b/app/src/components/home/assemblies/ScrollAction.tsx
similarity index 100%
rename from app/src/components/home/components/ScrollAction.tsx
rename to app/src/components/home/assemblies/ScrollAction.tsx
diff --git a/app/src/components/home/components/SendButton.tsx b/app/src/components/home/assemblies/SendButton.tsx
similarity index 100%
rename from app/src/components/home/components/SendButton.tsx
rename to app/src/components/home/assemblies/SendButton.tsx
diff --git a/app/src/components/home/components/WebToggle.tsx b/app/src/components/home/assemblies/WebToggle.tsx
similarity index 100%
rename from app/src/components/home/components/WebToggle.tsx
rename to app/src/components/home/assemblies/WebToggle.tsx
diff --git a/app/src/conf.ts b/app/src/conf.ts
index 58c2e7b..f831127 100644
--- a/app/src/conf.ts
+++ b/app/src/conf.ts
@@ -8,7 +8,7 @@ import {
} from "@/utils/env.ts";
import { getMemory } from "@/utils/memory.ts";
-export const version = "3.6.13rc";
+export const version = "3.6.13rc1";
export const dev: boolean = getDev();
export const deploy: boolean = true;
export let rest_api: string = getRestApi(deploy);
diff --git a/app/src/router.tsx b/app/src/router.tsx
index ddc0096..5ccf419 100644
--- a/app/src/router.tsx
+++ b/app/src/router.tsx
@@ -2,9 +2,12 @@ import { createBrowserRouter, RouterProvider } from "react-router-dom";
import Home from "./routes/Home.tsx";
import NotFound from "./routes/NotFound.tsx";
import Auth from "./routes/Auth.tsx";
-import Generation from "./routes/Generation.tsx";
-import Sharing from "./routes/Sharing.tsx";
-import Article from "@/routes/Article.tsx";
+import { lazy, Suspense } from "react";
+
+const Generation = lazy(() => import("@/routes/Generation.tsx"));
+const Sharing = lazy(() => import("@/routes/Sharing.tsx"));
+const Article = lazy(() => import("@/routes/Article.tsx"));
+const Admin = lazy(() => import("@/routes/Admin.tsx"));
const router = createBrowserRouter([
{
@@ -22,17 +25,43 @@ const router = createBrowserRouter([
{
id: "generation",
path: "/generate",
- Component: Generation,
+ element: (
+
+
+
+ ),
+ ErrorBoundary: NotFound,
},
{
id: "share",
path: "/share/:hash",
- Component: Sharing,
+ element: (
+
+
+
+ ),
+ ErrorBoundary: NotFound,
},
{
id: "article",
path: "/article",
- Component: Article,
+ element: (
+
+
+
+ ),
+ ErrorBoundary: NotFound,
+ },
+ {
+ id: "admin",
+ path: "/admin",
+ element: (
+
+
+
+ ),
+ children: [],
+ ErrorBoundary: NotFound,
},
]);
diff --git a/app/src/routes/Admin.tsx b/app/src/routes/Admin.tsx
new file mode 100644
index 0000000..015553f
--- /dev/null
+++ b/app/src/routes/Admin.tsx
@@ -0,0 +1,12 @@
+import "@/assets/admin/all.less";
+import MenuBar from "@/components/admin/MenuBar.tsx";
+
+function Admin() {
+ return (
+
+
+
+ )
+}
+
+export default Admin;
diff --git a/app/src/store/menu.ts b/app/src/store/menu.ts
index 9f3aac4..365d04f 100644
--- a/app/src/store/menu.ts
+++ b/app/src/store/menu.ts
@@ -24,3 +24,5 @@ export const menuSlice = createSlice({
export const { toggleMenu, closeMenu, openMenu, setMenu } = menuSlice.actions;
export default menuSlice.reducer;
+
+export const selectMenu = (state: any) => state.menu.open;