177 lines
7.4 KiB
TypeScript

import React, { useRef, useEffect } from 'react';
import { Button } from '@/components/ui/button';
import { useTheme } from '../contexts/ThemeContext';
import { FiMenu, FiX, FiHelpCircle, FiUsers, FiDollarSign, FiZap, FiExternalLink, FiMoon, FiSun } from 'react-icons/fi';
import { TbMessageChatbot } from "react-icons/tb";
import { LucideCodeXml } from 'lucide-react';
import { useNavigate } from "react-router-dom";
interface LeftSidebarProps {
onPromptSelect: (prompt: string, content: any) => void;
onStartNewChat?: () => void; // Add this prop
}
const suggestedQuestions = [
{ text: "What is MCP?", icon: FiHelpCircle },
{ text: "Who is this for?", icon: FiUsers },
{ text: "Show me how I can earn", icon: FiDollarSign },
{ text: "What can you help me with?", icon: FiZap },
];
const navLinks = [
{ text: "Chat", icon: TbMessageChatbot , to: "#" },
{ text: "Home", icon: FiHelpCircle, to: "#home" },
{ text: "MCPs", icon: FiUsers, to: "#mcps" },
{ text: "Monetize", icon: FiDollarSign, to: "#monetize" },
];
const LeftSidebar: React.FC<LeftSidebarProps> = ({ onPromptSelect, onStartNewChat }) => {
const { sidebarOpen, setSidebarOpen } = useTheme();
const { isDark, toggleTheme } = useTheme();
const sidebarRef = useRef<HTMLDivElement>(null);
const navigate = useNavigate();
// Close sidebar on outside click
useEffect(() => {
if (!sidebarOpen) return;
const handleClickOutside = (event: MouseEvent) => {
if (
sidebarRef.current &&
!sidebarRef.current.contains(event.target as Node)
) {
setSidebarOpen(false);
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, [sidebarOpen, setSidebarOpen]);
const handlePromptClick = (prompt: string) => {
// Dispatch a custom event to notify ChatInterface
const event = new CustomEvent('leftSidebarPrompt', { detail: { prompt } });
window.dispatchEvent(event);
// Trigger the same logic as in ChatInterface
onPromptSelect(prompt, null);
};
return (
<>
{/* Toggle Button */}
{!sidebarOpen && (
<Button
variant="ghost"
onClick={() => setSidebarOpen(true)}
className="fixed top-24 left-4 z-50 w-10 h-10 rounded-xl border border-gray-200/20 dark:border-gray-700/20 backdrop-blur-md bg-white/80 dark:bg-black/80 hover:bg-white/90 dark:hover:bg-black/90 transition-all duration-300 shadow-lg"
>
<FiMenu className="w-4 h-4" />
</Button>
)}
{/* Sidebar */}
<div
ref={sidebarRef}
className={`fixed left-0 top-0 bg-clip-padding backdrop-filter backdrop-blur-sm bg-opacity-10 border border-gray-200/20 dark:border-gray-700/20 h-screen w-72 transform transition-transform duration-500 ease-in-out z-40 ${
sidebarOpen ? 'translate-x-0' : '-translate-x-full'
}`}
>
<div className="h-full border-r border-gray-200/20 dark:border-gray-700/20 bg-clip-padding backdrop-filter backdrop-blur-sm bg-white/20 dark:bg-black/20 bg-opacity-40 flex flex-col">
{/* Top Section: Logo, Navigation, Theme Toggle */}
<div className="p-6 pb-2 flex items-cneter justify-between">
{/* Logo */}
<div className="flex items-center gap-2">
{/* <img src="/logo.svg" alt="Logo" className="w-8 h-8" /> */}
<LucideCodeXml />
<span className="text-lg text-gray-900 dark:text-white">FastCode</span>
</div>
{/* Theme Toggle */}
<Button
variant="ghost"
size="sm"
onClick={toggleTheme}
className="w-10 h-10 rounded-full border border-gray-200/20 dark:border-gray-700/20 backdrop-blur-sm bg-white/10 dark:bg-black/10 hover:bg-white/20 dark:hover:bg-black/20 transition-all duration-300"
aria-label="Toggle theme"
>
{isDark ? <FiSun className="w-4 h-4" /> : <FiMoon className="w-4 h-4" />}
</Button>
</div>
{/* Questions */}
<div className="px-6 mb-6">
<h3 className="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-4 mt-4">
Quick Start
</h3>
<div className="space-y-2">
{suggestedQuestions.map((question, index) => (
<button
key={index}
onClick={() => handlePromptClick(question.text)}
className="w-full flex justify-start p-4 h-auto text-left border-0 bg-transparent text-gray-500 hover:text-black transition-colors duration-200 group"
>
<question.icon className="w-4 h-4 mr-3 text-gray-400 group-hover:text-black dark:group-hover:text-white transition-colors" />
<span className="text-sm text-gray-500 dark:text-gray-400 group-hover:text-black dark:group-hover:text-white transition-colors">
{question.text}
</span>
</button>
))}
</div>
{/* Start New Chat Button */}
<Button
variant="outline"
className="w-full"
onClick={onStartNewChat}
>
Start New Chat
</Button>
</div>
{/* Nav Section */}
<div className="flex-1 flex flex-col justify-between">
{/* Nav menu */}
<div className="px-6">
<h3 className="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-4 mt-4">
Navigation
</h3>
{navLinks.map((nav, index) => (
<a
href={nav.to}
key={index}
className="w-full flex justify-start p-4 h-auto text-left border-0 bg-transparent text-gray-500 hover:text-black transition-colors duration-200 group"
>
<nav.icon className="w-4 h-4 mr-3 text-gray-400 group-hover:text-black dark:group-hover:text-white transition-colors" />
<span className="text-sm text-gray-500 dark:text-gray-400 group-hover:text-black dark:group-hover:text-white transition-colors">
{nav.text}
</span>
</a>
))}
</div>
{/* Visit Website */}
<div className="p-6 mt-auto">
<h3 className="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-4">
Resources
</h3>
<Button
variant="ghost"
asChild
className="w-full justify-start p-4 h-auto text-left border-0 bg-transparent text-gray-500 hover:text-black dark:text-gray-400 dark:hover:text-white transition-colors duration-200 group"
>
<a href="https://yourdomain.com" target="_blank" rel="noopener noreferrer">
<FiExternalLink className="w-4 h-4 mr-3 text-gray-400 group-hover:text-black dark:group-hover:text-white transition-colors" />
<span className="text-sm text-gray-500 dark:text-gray-400 group-hover:text-black dark:group-hover:text-white transition-colors">
Visit Website
</span>
</a>
</Button>
</div>
</div>
</div>
</div>
</>
);
};
export default LeftSidebar;