'use client'; import { useState, useRef, useCallback } from 'react'; import { Link2, Upload, LayoutGrid, FileText, X, Loader2 } from 'lucide-react'; type Tab = 'url' | 'file' | 'template'; interface SpecUploaderProps { onAnalyze: (input: { type: 'url' | 'raw'; value: string }) => void; loading?: boolean; } export function SpecUploader({ onAnalyze, loading = false }: SpecUploaderProps) { const [activeTab, setActiveTab] = useState('url'); const [urlInput, setUrlInput] = useState(''); const [dragActive, setDragActive] = useState(false); const [fileName, setFileName] = useState(null); const [fileContent, setFileContent] = useState(null); const fileInputRef = useRef(null); const tabs: { id: Tab; label: string; icon: React.ReactNode }[] = [ { id: 'url', label: 'Paste URL', icon: }, { id: 'file', label: 'Upload File', icon: }, { id: 'template', label: 'Pick Template', icon: }, ]; const handleFileRead = useCallback((file: File) => { const validExts = ['.json', '.yaml', '.yml']; const ext = '.' + file.name.split('.').pop()?.toLowerCase(); if (!validExts.includes(ext)) { alert('Please upload a .json, .yaml, or .yml file'); return; } const reader = new FileReader(); reader.onload = (e) => { const content = e.target?.result as string; setFileName(file.name); setFileContent(content); }; reader.readAsText(file); }, []); const handleDrop = useCallback( (e: React.DragEvent) => { e.preventDefault(); setDragActive(false); const file = e.dataTransfer.files[0]; if (file) handleFileRead(file); }, [handleFileRead], ); const handleSubmitUrl = () => { if (!urlInput.trim()) return; // Auto-detect: if it starts with http(s), it's a URL; otherwise raw spec content const isUrl = /^https?:\/\//i.test(urlInput.trim()); onAnalyze({ type: isUrl ? 'url' : 'raw', value: urlInput.trim(), }); }; const handleSubmitFile = () => { if (!fileContent) return; onAnalyze({ type: 'raw', value: fileContent }); }; const clearFile = () => { setFileName(null); setFileContent(null); if (fileInputRef.current) fileInputRef.current.value = ''; }; return (
{/* Tab header */}
{tabs.map((tab) => ( ))}
{/* Tab content */}
{/* URL Tab */} {activeTab === 'url' && (