import { useState } from 'react'; interface AIPanelProps { text: string; loading: boolean; error: string | null; isFallback: boolean; question: string; onCopy: (text: string) => void; onStop: () => void; onClose: () => void; } export default function AIPanel({ text, loading, error, isFallback, question, onCopy, onStop, onClose, }: AIPanelProps) { const [copied, setCopied] = useState(false); const handleCopy = () => { onCopy(text); setCopied(true); setTimeout(() => setCopied(false), 1000); }; return (
{/* Header */}
DeepSeek RAG {/* Animated loading dots */} {loading && (
{[0, 1, 2].map(i => ( ))}
)} {/* Fallback badge */} {isFallback && !loading && ( 本地降级 )}
{/* Stop button — only visible while streaming */} {loading && ( )}
{/* Question context */} {question && (

针对:{question}

)} {/* Fallback notice */} {isFallback && (
⚠️ DeepSeek 暂时不可用,已显示知识库原始答案
)} {/* Error state */} {error && !isFallback ? (

⚠️ AI 服务暂时不可用

{error}

请直接使用上方知识库原始答案。

) : ( /* Content panel with typewriter effect */
{loading && !text ? (

正在检索知识库并调用 DeepSeek…

) : (

{text} {/* Blinking cursor while streaming */} {loading && ( )}

)}
)} {/* Copy button */} {text && !error && ( )}
); }