import { useEffect, useState } from 'react'; import { ChevronDown, Plus, Folder, Check, Brain } from 'lucide-react'; import { useProjectStore } from '@/store/projectStore'; import { useTranslation } from "react-i18next"; import { api } from "@/lib/api"; import { cn } from "@/lib/utils"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, DropdownMenuGroup, } from '@/components/ui/dropdown-menu'; import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command'; interface ModelConfig { id: string; name: string; model: string; provider: string; is_active: boolean; } export function ProjectSwitcher() { const { t } = useTranslation(); const { projects, currentProject, fetchProjects, setCurrentProject, addProject } = useProjectStore(); const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false); const [newProjectName, setNewProjectName] = useState(''); const [isSubmitting, setIsSubmitting] = useState(false); // Model Selection State const [models, setModels] = useState([]); const [selectedModelId, setSelectedModelId] = useState(""); const [modelOpen, setModelOpen] = useState(false); useEffect(() => { fetchProjects(); }, [fetchProjects]); useEffect(() => { const fetchModels = async () => { try { const data = await api.get("/api/v1/llm"); setModels(data); const active = data.find(m => m.is_active); if (active) { setSelectedModelId(active.id); } else if (data.length > 0) { setSelectedModelId(data[0].id); } } catch (e) { console.error("Failed to fetch models", e); } }; fetchModels(); }, []); const handleCreateProject = async () => { if (!newProjectName.trim()) return; setIsSubmitting(true); try { await addProject(newProjectName); setNewProjectName(''); setIsCreateDialogOpen(false); } catch (error) { console.error('Failed to create project:', error); } finally { setIsSubmitting(false); } }; return (
{currentProject?.name || 'Select Project'} PROJECTS
{projects.map((project) => ( { setCurrentProject(project); }} className={currentProject?.id === project.id ? 'bg-accent' : ''} > {project.name} ))} {projects.length === 0 && (
No projects found
)}
{selectedModelId ? (models.find(m => m.id === selectedModelId)?.name || models.find(m => m.id === selectedModelId)?.model || 'DataClaw') : 'DataClaw'} {t('modelNotFound')} {models.map((model) => ( { setSelectedModelId(model.id); setModelOpen(false); // Fire custom event to notify ChatInterface if needed window.dispatchEvent(new CustomEvent("nanobot:model-changed", { detail: model.id })); }} className="flex items-center gap-2 py-2.5 cursor-pointer" >
{model.name || model.model} {model.provider}
))}
Create New Project
setNewProjectName(e.target.value)} placeholder="Enter project name" autoFocus />
); }