'use client'; import { useState, useEffect, useRef } from 'react'; import { apiClient } from '@/lib/api'; import type { Model, Language } from '@/types'; interface ControlPanelProps { selectedLanguage: Language; selectedModel: string; onLanguageChange: (language: Language) => void; onModelChange: (modelId: string) => void; onClear: () => void; onImport?: (code: string, language: Language, importUrl?: string) => void; isGenerating: boolean; } export default function ControlPanel({ selectedLanguage, selectedModel, onLanguageChange, onModelChange, onClear, onImport, isGenerating, }: ControlPanelProps) { const [models, setModels] = useState([]); const [languages, setLanguages] = useState([]); const [isLoading, setIsLoading] = useState(true); const [showImportModal, setShowImportModal] = useState(false); const [importUrl, setImportUrl] = useState(''); const [isImporting, setIsImporting] = useState(false); const [importError, setImportError] = useState(null); // Dropdown states const [showLanguageDropdown, setShowLanguageDropdown] = useState(false); const [showModelDropdown, setShowModelDropdown] = useState(false); const languageDropdownRef = useRef(null); const modelDropdownRef = useRef(null); useEffect(() => { loadData(); }, []); // Close dropdowns when clicking outside useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (languageDropdownRef.current && !languageDropdownRef.current.contains(event.target as Node)) { setShowLanguageDropdown(false); } if (modelDropdownRef.current && !modelDropdownRef.current.contains(event.target as Node)) { setShowModelDropdown(false); } }; document.addEventListener('mousedown', handleClickOutside); return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, []); const loadData = async () => { setIsLoading(true); await Promise.all([loadModels(), loadLanguages()]); setIsLoading(false); }; const loadModels = async () => { try { console.log('Loading models...'); const modelsList = await apiClient.getModels(); console.log('Models loaded:', modelsList); setModels(modelsList); } catch (error) { console.error('Failed to load models:', error); } }; const loadLanguages = async () => { try { console.log('Loading languages...'); const { languages: languagesList } = await apiClient.getLanguages(); console.log('Languages loaded:', languagesList); setLanguages(languagesList); } catch (error) { console.error('Failed to load languages:', error); } }; const handleImport = async () => { if (!importUrl.trim()) { setImportError('Please enter a valid URL'); return; } setIsImporting(true); setImportError(null); try { console.log('Importing from:', importUrl); const result = await apiClient.importProject(importUrl); if (result.status === 'success') { console.log('Import successful:', result); // Call the onImport callback if provided if (onImport && result.code) { onImport(result.code, result.language || 'html', importUrl); } // Close modal and reset setShowImportModal(false); setImportUrl(''); setImportError(null); } else { setImportError(result.message || 'Import failed'); } } catch (error: any) { console.error('Import error:', error); setImportError(error.response?.data?.message || error.message || 'Failed to import project'); } finally { setIsImporting(false); } }; const formatLanguageName = (lang: Language) => { if (lang === 'html') return 'HTML'; if (lang === 'transformers.js') return 'Transformers.js'; if (lang === 'comfyui') return 'ComfyUI'; return lang.charAt(0).toUpperCase() + lang.slice(1); }; return (
{/* Panel Header */}

Settings

{/* Content */}
{/* Language Selection */}
{/* Language Dropdown Tray */} {showLanguageDropdown && !isLoading && languages.length > 0 && (
{languages.map((lang) => ( ))}
)}
{/* Model Selection */}
{/* Model Dropdown Tray */} {showModelDropdown && models.length > 0 && (
{models.map((model) => ( ))}
)} {/* Model Description */} {!isLoading && models.find(m => m.id === selectedModel) && (

{models.find(m => m.id === selectedModel)?.description}

)}
{/* Action Buttons */}
{/* Import Modal */} {showImportModal && (

Import Project

setImportUrl(e.target.value)} placeholder="https://huggingface.co/spaces/..." disabled={isImporting} className="w-full px-3 py-2.5 bg-[#000000] text-[#f5f5f7] text-sm border border-[#424245] rounded-lg focus:outline-none focus:border-[#424245] disabled:opacity-40 placeholder-[#86868b]" onKeyDown={(e) => e.key === 'Enter' && handleImport()} />

Supported: HF Spaces, HF Models, GitHub repos

{importError && (

{importError}

)}
)}
); }