diff --git a/src/components/main-menu.tsx b/src/components/main-menu.tsx
deleted file mode 100644
index 016c60b..0000000
--- a/src/components/main-menu.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import { observer } from "mobx-react-lite";
-import { useAccountStore } from "@/contexts/AccountContext";
-import { Button } from "./ui/button";
-
-export const MainMenu = observer(() => {
- const { isMainMenuOpen, setIsMainMenuOpen } = useAccountStore();
- return (
-
-
-
- );
-});
diff --git a/src/components/main-menu/collapsed-menu.tsx b/src/components/main-menu/collapsed-menu.tsx
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/src/components/main-menu/collapsed-menu.tsx
@@ -0,0 +1 @@
+
diff --git a/src/components/main-menu/main-menu.tsx b/src/components/main-menu/main-menu.tsx
new file mode 100644
index 0000000..f3682e2
--- /dev/null
+++ b/src/components/main-menu/main-menu.tsx
@@ -0,0 +1,199 @@
+import { observer } from "mobx-react-lite";
+import { useAccountStore } from "@/contexts/AccountContext";
+import Plus from "@/icons/plus.svg?react";
+import Books from "@/icons/books.svg?react";
+import Discord from "@/icons/discord.svg?react";
+import Profile from "@/icons/profile.svg?react";
+
+import { LINKS } from "@/lib/constants";
+import { useEffect, useRef, useState, type ReactNode } from "react";
+import { Button, type ButtonVariantType } from "../ui/button";
+import { Link } from "@tanstack/react-router";
+
+import Logo from "@/icons/logo.svg?react";
+import LogoWithText from "@/icons/logo-with-text.svg?react";
+import Sidebar from "@/icons/sidebar.svg?react";
+
+interface MenuItemType extends ButtonVariantType {
+ name: string;
+ icon: ReactNode;
+ path: string;
+}
+
+const MENU_ITEMS: MenuItemType[] = [
+ {
+ name: "New Chat",
+ icon: ,
+ path: "/",
+ variant: "primary",
+ },
+ {
+ name: "All chats",
+ icon: ,
+ path: "/all-chats",
+ variant: "secondary",
+ },
+ {
+ name: "Support",
+ icon: ,
+ path: LINKS.discord,
+ variant: "secondary",
+ },
+];
+
+const MenuItem = ({ item }: { item: MenuItemType }) => {
+ const { isMainMenuOpen } = useAccountStore();
+
+ return (
+
+
+
+ {item.name}
+
+
+ );
+};
+
+const MainMenu = observer(() => {
+ const { isMainMenuOpen } = useAccountStore();
+
+ return (
+
+
+
+ );
+});
+
+const MOCK_CHATS = Array.from({ length: 20 }, (_, i) => ({
+ id: i,
+ title: `Chat ${i + 1}`,
+ subtitle: `Last message preview...`,
+}));
+
+const MainMenuContent = observer(() => {
+ const { isMainMenuOpen, setIsMainMenuOpen } = useAccountStore();
+ const containerRef = useRef(null);
+ const [hasScrolled, setHasScrolled] = useState(false);
+
+ useEffect(() => {
+ const container = containerRef.current;
+ if (!container) return;
+
+ const handleScroll = () => {
+ setHasScrolled(container.scrollTop > 0);
+ };
+
+ container.addEventListener("scroll", handleScroll);
+ handleScroll();
+
+ return () => {
+ container.removeEventListener("scroll", handleScroll);
+ };
+ }, []);
+
+ return (
+
+
+
+
+
+ Recent
+
+
+
+ {MOCK_CHATS.map((chat) => (
+ -
+
+ {chat.title}
+
+
+ {chat.subtitle}
+
+
+ ))}
+
+
+
+
+
+ );
+});
+
+export { MainMenu, MenuItem, MENU_ITEMS, MainMenuContent };
diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx
index 4aeeaf0..d7540f2 100644
--- a/src/components/ui/button.tsx
+++ b/src/components/ui/button.tsx
@@ -3,6 +3,8 @@ import { cva, type VariantProps } from "class-variance-authority";
import * as React from "react";
import { cn } from "@/lib/utils";
+type ButtonVariantType = VariantProps;
+
const buttonVariants = cva(
"h-[52px] inline-flex items-center justify-center gap-2 font-medium whitespace-nowrap rounded-[8px] px-4 text-[14px] leading-[130%] tracking-[0.01em] transition-colors hover:cursor-pointer focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:*:fill-text-secondary [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
{
@@ -45,4 +47,4 @@ const Button = React.forwardRef(
);
Button.displayName = "Button";
-export { Button, buttonVariants };
+export { Button, buttonVariants, type ButtonVariantType };
diff --git a/src/components/ui/toaster.tsx b/src/components/ui/toaster.tsx
index 19acb44..5661e0f 100644
--- a/src/components/ui/toaster.tsx
+++ b/src/components/ui/toaster.tsx
@@ -16,6 +16,7 @@ import { useToast } from "@/lib/hooks/use-toast";
import Discord from "@/icons/discord.svg?react";
import Copy from "@/icons/copy.svg?react";
import { TextLink } from "./text-link";
+import { LINKS } from "@/lib/constants";
const ToastProvider = ToastPrimitives.Provider;
@@ -308,10 +309,7 @@ const TOASTER_DESCRIPTION_PATTERNS = {
Error code ]
-
+
[
Support ]
diff --git a/src/icons/books.svg b/src/icons/books.svg
new file mode 100644
index 0000000..6f6cb14
--- /dev/null
+++ b/src/icons/books.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/icons/plus.svg b/src/icons/plus.svg
new file mode 100644
index 0000000..206f28c
--- /dev/null
+++ b/src/icons/plus.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/icons/profile.svg b/src/icons/profile.svg
new file mode 100644
index 0000000..4d9b524
--- /dev/null
+++ b/src/icons/profile.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/icons/sidebar.svg b/src/icons/sidebar.svg
new file mode 100644
index 0000000..bb13921
--- /dev/null
+++ b/src/icons/sidebar.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/lib/constants.ts b/src/lib/constants.ts
index 589bc33..62406c9 100644
--- a/src/lib/constants.ts
+++ b/src/lib/constants.ts
@@ -2,3 +2,7 @@ export const LS_TOKENS = {
isMainMenuOpen: "isMainMenuOpen",
userId: "userId",
};
+
+export const LINKS = {
+ discord: "https://discord.gg/cytonic",
+};
diff --git a/src/routes/__root.tsx b/src/routes/__root.tsx
index 23c47d7..094d416 100644
--- a/src/routes/__root.tsx
+++ b/src/routes/__root.tsx
@@ -2,7 +2,7 @@
import { Outlet, createRootRoute } from "@tanstack/react-router";
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
import { useAccountStore } from "@/contexts/AccountContext";
-import { MainMenu } from "@/components/main-menu";
+import { MainMenu } from "@/components/main-menu/main-menu";
export const Route = createRootRoute({
component: RootLayout,
@@ -21,7 +21,7 @@ function RootLayout() {
-
+ {/* */}
);
}
diff --git a/src/routes/index.tsx b/src/routes/index.tsx
index e9bdda5..1db4189 100644
--- a/src/routes/index.tsx
+++ b/src/routes/index.tsx
@@ -2,22 +2,27 @@ import { Chat } from "@/components/interaction-panel/chat";
import { createFileRoute, Link } from "@tanstack/react-router";
import LogoWithText from "@/icons/logo-with-text.svg?react";
import { Button } from "@/components/ui/button";
+import { useAccountStore } from "@/contexts/AccountContext";
export const Route = createFileRoute("/")({
component: App,
});
function App() {
+ const { userId } = useAccountStore();
+
return (
-
+ {!userId && (
+
+ )}
);
diff --git a/src/routes/magic-link/$magic-link.tsx b/src/routes/magic-link/$magic-link.tsx
index 3cebf86..96a833c 100644
--- a/src/routes/magic-link/$magic-link.tsx
+++ b/src/routes/magic-link/$magic-link.tsx
@@ -115,6 +115,7 @@ function RouteComponent() {
};
const handleConfirm = (fullCode: string) => {
+ console.log(fullCode);
navigate({
to: "/auth/username",
viewTransition: { types: ["warp"] },