// AI Assistant — conversational chat with Sofia // As respostas vêm de window.SofiaAPI (Edge Function `sofia-chat`). // Se a chave OpenAI não estiver configurada, o client cai automaticamente // num fallback local (mock leve) sem quebrar a experiência. const AIScreen = ({ state, setState, navigate, showToast, user }) => { const [messages, setMessages] = React.useState(aiConversations); const [input, setInput] = React.useState(''); const [typing, setTyping] = React.useState(false); const [voiceMode, setVoiceMode] = React.useState(false); const scrollRef = React.useRef(null); React.useEffect(() => { if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight; }, [messages, typing]); const send = async (text) => { if (!text.trim()) return; const userMsg = { from: 'me', text }; setMessages(m => [...m, userMsg]); setInput(''); setTyping(true); const userName = (user && (user.name || user.email)) || (state && state.userName) || 'Lucas'; const userState = window.SofiaAPI ? window.SofiaAPI.buildUserState(state, userName) : null; try { const res = window.SofiaAPI ? await window.SofiaAPI.chat({ messages, userState, newMessage: text }) : { reply: 'Sofia ainda não está disponível. Volte daqui a pouco ✨', mode: 'mock' }; setTyping(false); setMessages(m => [...m, { from: 'ai', text: res.reply }]); if (res.mode === 'rate_limit' && showToast) { showToast('Limite diário atingido', 'flame'); } } catch (e) { setTyping(false); setMessages(m => [...m, { from: 'ai', text: 'Tive um problema agora, tenta de novo em alguns segundos? ✨' }]); } }; if (voiceMode) return setVoiceMode(false)} onSend={(t) => { setVoiceMode(false); send(t); }} />; return (
{/* Header */}
Sofia
Sua assistente pessoal · Online
Premium
{/* Messages */}
Hoje, 9:24
{messages.map((m, i) => )} {typing && } {/* Suggestions chips */} {messages.length < 8 && !typing && (
Sugestões para você
{suggestionsAI.map((s, i) => ( ))}
)}
{/* Input bar */}