import React, { useEffect, useRef, useState } from 'react';
import { Sparkles, Trash2, Download } from 'lucide-react';
import { useStore } from '../store/useStore.js';
import MessageItem from './MessageItem.jsx';
import MentionInput from './MentionInput.jsx';
function EmptyState({ models, onCreate }) {
return (
{/* Logo */}
Welcome to IQAI
Your multi-model AI dashboard. Chat with multiple AI models simultaneously, tag them with @mentions, and augment with live web search.
{/* Model grid */}
{models.length > 0 && (
{models.slice(0, 4).map(m => (
{m.avatar}
@{m.tag}
))}
)}
• Type @claude to direct a message to a specific model
• Enable Web Search to inject live results as context
• Select models from the sidebar to run queries in parallel
);
}
export default function ChatArea() {
const {
getActiveConv, activeConvId, sendMessage,
models, createConversation, clearConversation,
setSettingsPanelModel
} = useStore();
const [sending, setSending] = useState(false);
const [error, setError] = useState('');
const bottomRef = useRef(null);
const conv = getActiveConv();
useEffect(() => {
bottomRef.current?.scrollIntoView({ behavior: 'smooth' });
}, [conv?.messages?.length, sending]);
const handleSend = async (text) => {
setError('');
setSending(true);
try {
await sendMessage(text);
} catch (err) {
setError(err.message);
} finally {
setSending(false);
}
};
const exportConv = () => {
if (!conv) return;
const text = conv.messages.map(m => {
const who = m.role === 'user' ? 'You' : (models.find(md => md.id === m.modelId)?.displayName || m.modelId);
return `[${who}]\n${m.content}`;
}).join('\n\n---\n\n');
const blob = new Blob([text], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `${conv.title.slice(0, 30)}.txt`;
a.click();
URL.revokeObjectURL(url);
};
return (
{/* Top bar */}
{conv && (
{conv.title}
{/* Active model tags */}
{conv.activeModelIds.map(id => {
const m = models.find(md => md.id === id);
if (!m) return null;
return (
);
})}
)}
{/* Messages */}
{!conv || conv.messages.length === 0 ? (
) : (
conv.messages.map(msg => (
))
)}
{/* Error banner */}
{error && (
{error}
)}
{/* Input */}
IQAI uses Replicate API · Models may make mistakes · Verify important information
);
}