update routing

This commit is contained in:
yzned
2025-07-20 18:09:45 +03:00
committed by yzned
parent 42b27b7ddc
commit bba27be7e2
10 changed files with 229 additions and 145 deletions

View File

@@ -4,11 +4,12 @@ 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 ThreeDots from "@/icons/three-dots.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 { Link, useMatchRoute, useParams } from "@tanstack/react-router";
import Logo from "@/icons/logo.svg?react";
import LogoWithText from "@/icons/logo-with-text.svg?react";
@@ -41,39 +42,13 @@ const MENU_ITEMS: MenuItemType[] = [
},
];
const MenuItem = ({ item }: { item: MenuItemType }) => {
const { isMainMenuOpen } = useAccountStore();
return (
<Link
to={item.path}
className="group flex items-center gap-3 w-full whitespace-nowrap"
viewTransition={{ types: ["warp"] }}
>
<Button
data-variant={item.variant}
variant={item.variant}
className="w-8 h-8 data-[variant=secondary]:group-hover:bg-fill-150 data-[variant=primary]:group-hover:bg-fill-700 transition-colors"
>
{item.icon}
</Button>
<div
data-open={isMainMenuOpen}
className="data-[open=true]:opacity-100 opacity-0 transition-opacity duration-200 font-[500] text-[14px]"
>
{item.name}
</div>
</Link>
);
};
const MainMenu = observer(() => {
const { isMainMenuOpen } = useAccountStore();
return (
<div
data-open={isMainMenuOpen}
className="w-[64px] data-[open=true]:w-[227px] transition-all border-r border-r border-fill-150"
className="w-[64px] data-[open=true]:w-[227px] transition-all border-r border-r border-fill-150"
>
<MainMenuContent />
</div>
@@ -83,7 +58,6 @@ const MainMenu = observer(() => {
const MOCK_CHATS = Array.from({ length: 20 }, (_, i) => ({
id: i,
title: `Chat ${i + 1}`,
subtitle: `Last message preview...`,
}));
const MainMenuContent = observer(() => {
@@ -109,8 +83,9 @@ const MainMenuContent = observer(() => {
return (
<div
data-open={isMainMenuOpen}
ref={containerRef}
className="relative w-full h-full overflow-auto flex flex-col"
className="relative w-full h-full overflow-x-hidden data-[open=true]:overflow-y-auto overflow-y-hidden flex flex-col"
>
<header
data-scrolled={hasScrolled}
@@ -160,19 +135,12 @@ const MainMenuContent = observer(() => {
Recent
</p>
<ul className="space-y-2 pb-10">
<ul className=" pb-10">
{MOCK_CHATS.map((chat) => (
<li
<ChatCell
chat={{ id: chat.id.toString(), title: chat.title }}
key={chat.id}
className="rounded-md px-3 py-2 hover:bg-fill-100 cursor-pointer transition-colors"
>
<p className="text-sm font-medium text-text-light-900 truncate">
{chat.title}
</p>
<p className="text-xs text-text-light-400 truncate">
{chat.subtitle}
</p>
</li>
/>
))}
</ul>
</div>
@@ -196,4 +164,63 @@ const MainMenuContent = observer(() => {
);
});
const MenuItem = ({ item }: { item: MenuItemType }) => {
const { isMainMenuOpen } = useAccountStore();
return (
<Link
to={item.path}
className="group flex items-center gap-3 w-full whitespace-nowrap"
viewTransition={{ types: ["warp"] }}
>
<Button
data-variant={item.variant}
variant={item.variant}
className="w-8 h-8 data-[variant=secondary]:group-hover:bg-fill-150 data-[variant=primary]:group-hover:bg-fill-700 transition-colors"
>
{item.icon}
</Button>
<div
data-open={isMainMenuOpen}
className="data-[open=true]:opacity-100 opacity-0 transition-opacity duration-200 font-[500] text-[14px]"
>
{item.name}
</div>
</Link>
);
};
const ChatCell = ({ chat }: { chat: { id: string; title: string } }) => {
const matchRoute = useMatchRoute();
const match = matchRoute({ to: "/interaction-panel/$id", fuzzy: true });
const activeChatId = match ? match.id : undefined;
return (
<div
data-active={activeChatId === chat.id}
className="data-[active=true]:bg-fill-150 block rounded-md h-10 hover:bg-fill-100 cursor-pointer transition-colors group flex items-center"
>
<Link
to="/interaction-panel/$id"
params={{ id: chat.id }}
viewTransition={{ types: ["warp"] }}
key={chat.id}
className="flex-1 h-full items-center flex pl-3"
>
<div className="text-sm font-medium text-text-light-900 truncate">
{chat.title}
</div>
</Link>
<button
className="opacity-0 group-hover:opacity-100 duration-300 cursor-pointer flex items-center pr-3 justify-end w-5 h-full"
type="button"
>
<ThreeDots />
</button>
</div>
);
};
export { MainMenu, MenuItem, MENU_ITEMS, MainMenuContent };