diff --git a/src/components/navbar.tsx b/src/components/navbar.tsx
new file mode 100644
index 0000000..1229a1c
--- /dev/null
+++ b/src/components/navbar.tsx
@@ -0,0 +1,133 @@
+import React from "react";
+import { Badge } from "./ui/badge";
+import {
+ Menubar,
+ MenubarContent,
+ MenubarItem,
+ MenubarMenu,
+ MenubarSeparator,
+ MenubarTrigger,
+ MenubarCheckboxItem,
+} from "@/components/ui/menubar";
+import {
+ Popover,
+ PopoverContent,
+ PopoverTrigger,
+} from "@/components/ui/popover";
+import { ModeToggle } from "@/components/mode-toggle";
+import { SidebarTrigger } from "@/components/ui/sidebar";
+import { Separator } from "@/components/ui/separator";
+import {
+ EllipsisIcon,
+ WholeWordIcon,
+ CircleDollarSignIcon,
+ RulerIcon,
+ ReceiptIcon,
+ WalletIcon,
+ ArrowUpDownIcon,
+ ScissorsIcon,
+} from "lucide-react";
+import { AppContext } from "@/pages/App";
+import { models } from "@/types/models";
+import { getTotalCost } from "@/utils/totalCost";
+import { Tr } from "@/translate";
+
+import { useContext } from "react";
+
+const Navbar: React.FC = () => {
+ const ctx = useContext(AppContext);
+ if (!ctx) return
error
;
+ const { chatStore, setChatStore } = ctx;
+
+ return (
+
+
+
+
+
{chatStore.model}
+
+
+
+
+ {chatStore.totalTokens.toString()}
+
+
+
+
+
+
+
+ Tokens: {chatStore.totalTokens}/{chatStore.maxTokens}
+
+
+ Cut(s): {chatStore.postBeginIndex}/
+ {chatStore.history.filter(({ hide }) => !hide).length}
+
+
+ Cost: ${chatStore.cost?.toFixed(4)} / $
+ {getTotalCost().toFixed(2)}
+
+
+
+
+
+
+
+
+ {" "}
+ {chatStore.totalTokens}
+
+ {chatStore.cost?.toFixed(4)}
+
+
+
+
+ Max Length: {chatStore.maxTokens}
+
+
+
+ Price:{" "}
+ {models[chatStore.model]?.price?.prompt * 1000 * 1000}$ /
+ 1M input tokens
+
+
+
+ Total: {getTotalCost().toFixed(2)}$
+
+
+
+ {chatStore.streamMode ? (
+ <>
+ {Tr("STREAM")}·
+ {Tr("FETCH")}
+ >
+ ) : (
+ <>
+ {Tr("STREAM")}·
+ {Tr("FETCH")}
+ >
+ )}
+
+
+
+ {chatStore.postBeginIndex} / {chatStore.history.length}
+
+
+ Switch to Model (TODO):
+ gpt-4o
+ gpt-o1
+ gpt-o1-mini
+ gpt-o3
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default Navbar;
diff --git a/src/pages/App.tsx b/src/pages/App.tsx
index dc0f33f..c1a0c90 100644
--- a/src/pages/App.tsx
+++ b/src/pages/App.tsx
@@ -115,6 +115,8 @@ import {
import { Badge } from "@/components/ui/badge";
import { ModeToggle } from "@/components/mode-toggle";
+import Navbar from "@/components/navbar";
+
export function App() {
// init selected index
const [selectedChatIndex, setSelectedChatIndex] = useState(
@@ -356,7 +358,27 @@ export function App() {
console.log("[PERFORMANCE!] reading localStorage");
return (
- <>
+
-
-
-
-
-
{chatStore.model}
-
-
-
-
- {chatStore.totalTokens.toString()}
-
-
-
-
-
-
-
- Tokens: {chatStore.totalTokens}/{chatStore.maxTokens}
-
-
- Cut(s): {chatStore.postBeginIndex}/
- {chatStore.history.filter(({ hide }) => !hide).length}
-
-
- Cost: ${chatStore.cost?.toFixed(4)} / $
- {getTotalCost().toFixed(2)}
-
-
-
-
-
-
-
-
- {" "}
- {chatStore.totalTokens}
-
- {chatStore.cost?.toFixed(4)}
-
-
-
-
- Max Length: {chatStore.maxTokens}
-
-
-
- Price:{" "}
- {models[chatStore.model]?.price?.prompt * 1000 * 1000}
- $ / 1M input tokens
-
-
-
- Total: {getTotalCost().toFixed(2)}$
-
-
-
- {chatStore.streamMode ? (
- <>
- {Tr("STREAM")}·
-
- {Tr("FETCH")}
-
- >
- ) : (
- <>
-
- {Tr("STREAM")}
-
- ·{Tr("FETCH")}
- >
- )}
-
-
-
- {chatStore.postBeginIndex} /{" "}
- {chatStore.history.length}
-
-
-
- Switch to Model (TODO):
-
-
- gpt-4o
-
- gpt-o1
- gpt-o1-mini
- gpt-o3
-
-
-
-
-
-
-
-
-
-
-
-
+
+
- >
+
);
}