PROJECTS / src /components /Sidebar.tsx
Adeen
Initial Deployment
bb17288
import React from 'react';
import { Plus, MessageSquare, Menu, ChevronLeft } from 'lucide-react';
interface SidebarProps {
isOpen: boolean;
setIsOpen: (isOpen: boolean) => void;
onNewChat: () => void;
sessions: Array<{ id: string; preview: string; timestamp: number }>;
currentSessionId: string | null;
onSelectSession: (id: string) => void;
}
export const Sidebar: React.FC<SidebarProps> = ({
isOpen,
setIsOpen,
onNewChat,
sessions,
currentSessionId,
onSelectSession
}) => {
return (
<>
{/* Mobile Overlay */}
{isOpen && (
<div
className="fixed inset-0 bg-black/50 z-40 md:hidden"
onClick={() => setIsOpen(false)}
/>
)}
{/* Sidebar Container */}
<div className={`
fixed md:static inset-y-0 left-0 z-50
h-screen bg-background/95 backdrop-blur-xl
transition-all duration-300 ease-in-out
flex flex-col border-r border-white/5 shadow-[4px_0_24px_rgba(0,0,0,0.2)]
${isOpen ? 'w-[280px] translate-x-0' : 'w-0 -translate-x-full md:w-[68px] md:translate-x-0'}
`}>
{/* Header (Hamburger Menu) */}
<div className="p-3 flex items-center h-[60px]">
<button
onClick={() => setIsOpen(!isOpen)}
className="p-2.5 hover:bg-white/5 rounded-full transition-transform active:scale-95 text-slate-400 hover:text-slate-200"
>
<Menu size={20} />
</button>
{isOpen && (
<div className="flex-1 flex justify-end md:hidden">
<button
onClick={() => setIsOpen(false)}
className="p-2.5 hover:bg-white/5 rounded-full transition-transform active:scale-95 text-slate-400"
>
<ChevronLeft size={20} />
</button>
</div>
)}
</div>
{/* New Chat Button */}
<div className="px-3 mt-4">
<button
onClick={onNewChat}
className={`
flex items-center gap-3 bg-white/5 hover:bg-white/10
text-slate-200 font-medium transition-all active:scale-95
${isOpen ? 'w-full py-3 px-4 rounded-2xl' : 'w-11 h-11 justify-center rounded-full ml-1'}
`}
>
<Plus size={isOpen ? 18 : 20} className="shrink-0 text-blue-400" />
{isOpen && <span>New Chat</span>}
</button>
</div>
{/* Recent Chats Section */}
<div className="flex-1 overflow-y-auto mt-6 px-3 custom-scrollbar">
{isOpen && (
<div>
<p className="text-xs font-semibold text-gray-400 mb-2 px-2 uppercase tracking-wider">
Recent
</p>
<div className="flex flex-col gap-1">
{sessions.length === 0 ? (
<p className="text-sm text-zinc-500 px-2 mt-2">No previous chats</p>
) : (
sessions.map(session => (
<button
key={session.id}
onClick={() => onSelectSession(session.id)}
className={`
flex items-center gap-3 w-full p-2.5 rounded-xl text-left transition-all active:scale-95
${currentSessionId === session.id
? 'bg-primary/20 text-white font-medium shadow-[0_0_10px_rgba(139,92,246,0.1)]'
: 'hover:bg-white/5 text-gray-300 hover:text-white'}
`}
>
<MessageSquare size={16} className="shrink-0 opacity-70" />
<span className="text-sm truncate pr-2">
{session.preview || "New Conversation"}
</span>
</button>
))
)}
</div>
</div>
)}
</div>
</div>
</>
);
};