create main menu and dropdown menu
This commit is contained in:
@@ -4,16 +4,19 @@ 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 Settings from "@/icons/settings.svg?react";
|
||||
import SignOut from "@/icons/sign-out.svg?react";
|
||||
|
||||
import { LINKS } from "@/lib/constants";
|
||||
import { useEffect, useRef, useState, type ReactNode } from "react";
|
||||
import { Button, type ButtonVariantType } from "../ui/button";
|
||||
import { Link, useMatchRoute, useParams } from "@tanstack/react-router";
|
||||
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";
|
||||
import { ChatCell } from "./chat-cell";
|
||||
import { Dropdown } from "../ui/dropdown";
|
||||
|
||||
interface MenuItemType extends ButtonVariantType {
|
||||
name: string;
|
||||
@@ -21,27 +24,6 @@ interface MenuItemType extends ButtonVariantType {
|
||||
path: string;
|
||||
}
|
||||
|
||||
const MENU_ITEMS: MenuItemType[] = [
|
||||
{
|
||||
name: "New Chat",
|
||||
icon: <Plus className="scale-80" />,
|
||||
path: "/",
|
||||
variant: "primary",
|
||||
},
|
||||
{
|
||||
name: "All chats",
|
||||
icon: <Books className="scale-90" />,
|
||||
path: "/all-chats",
|
||||
variant: "secondary",
|
||||
},
|
||||
{
|
||||
name: "Support",
|
||||
icon: <Discord width={12} height={12} className="text-[#5865F2]" />,
|
||||
path: LINKS.discord,
|
||||
variant: "secondary",
|
||||
},
|
||||
];
|
||||
|
||||
const MainMenu = observer(() => {
|
||||
const { isMainMenuOpen } = useAccountStore();
|
||||
|
||||
@@ -61,6 +43,8 @@ const MOCK_CHATS = Array.from({ length: 20 }, (_, i) => ({
|
||||
}));
|
||||
|
||||
const MainMenuContent = observer(() => {
|
||||
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
||||
|
||||
const { isMainMenuOpen, setIsMainMenuOpen } = useAccountStore();
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const [hasScrolled, setHasScrolled] = useState(false);
|
||||
@@ -81,6 +65,25 @@ const MainMenuContent = observer(() => {
|
||||
};
|
||||
}, []);
|
||||
|
||||
const DROPDOWN_OPTIONS = [
|
||||
{
|
||||
name: "user-mail",
|
||||
icon: <Profile />,
|
||||
onClick: () => console.log("1"),
|
||||
className: "text-text-light-500",
|
||||
},
|
||||
{
|
||||
name: "Settings",
|
||||
icon: <Settings />,
|
||||
onClick: () => console.log("2"),
|
||||
},
|
||||
{
|
||||
name: "Sigh out",
|
||||
icon: <SignOut />,
|
||||
onClick: () => console.log("3"),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div
|
||||
data-open={isMainMenuOpen}
|
||||
@@ -145,20 +148,28 @@ const MainMenuContent = observer(() => {
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<footer className="sticky bottom-0 z-10 bg-white w-full p-4 border-t border-fill-150">
|
||||
<Button
|
||||
data-open={isMainMenuOpen}
|
||||
className="w-8 h-8 p-2 transition-all data-[open=true]:w-full data-[open=true]:h-10 items-center justify-start data-[open=true]:py-2 data-[open=true]:px-4"
|
||||
variant="secondary"
|
||||
<footer className="sticky bottom-0 z-10 bg-white w-full p-4 border-t border-fill-150 w-full">
|
||||
<Dropdown
|
||||
options={DROPDOWN_OPTIONS}
|
||||
isOpen={isDropdownOpen}
|
||||
onToggle={() => setIsDropdownOpen(!isDropdownOpen)}
|
||||
classNameContent="min-w-[200px]"
|
||||
classNameTrigger="w-[195px]"
|
||||
>
|
||||
<Profile />
|
||||
<div
|
||||
<Button
|
||||
data-open={isMainMenuOpen}
|
||||
className="data-[open=true]:opacity-100 opacity-0 transition-opacity duration-200 font-[500] text-[14px]"
|
||||
className="w-8 h-8 p-2 transition-all data-[open=true]:w-full data-[open=true]:h-10 items-center justify-start data-[open=true]:py-2 data-[open=true]:px-4"
|
||||
variant="secondary"
|
||||
>
|
||||
username
|
||||
</div>
|
||||
</Button>
|
||||
<Profile />
|
||||
<div
|
||||
data-open={isMainMenuOpen}
|
||||
className="data-[open=true]:opacity-100 opacity-0 transition-opacity duration-200 font-[500] text-[14px]"
|
||||
>
|
||||
username
|
||||
</div>
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
@@ -190,37 +201,25 @@ const MenuItem = ({ item }: { item: MenuItemType }) => {
|
||||
);
|
||||
};
|
||||
|
||||
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>
|
||||
);
|
||||
};
|
||||
const MENU_ITEMS: MenuItemType[] = [
|
||||
{
|
||||
name: "New Chat",
|
||||
icon: <Plus className="scale-80" />,
|
||||
path: "/",
|
||||
variant: "primary",
|
||||
},
|
||||
{
|
||||
name: "All chats",
|
||||
icon: <Books className="scale-90" />,
|
||||
path: "/all-chats",
|
||||
variant: "secondary",
|
||||
},
|
||||
{
|
||||
name: "Support",
|
||||
icon: <Discord width={12} height={12} className="text-[#5865F2]" />,
|
||||
path: LINKS.discord,
|
||||
variant: "secondary",
|
||||
},
|
||||
];
|
||||
|
||||
export { MainMenu, MenuItem, MENU_ITEMS, MainMenuContent };
|
||||
|
||||
Reference in New Issue
Block a user