93 lines
3.2 KiB
JavaScript
93 lines
3.2 KiB
JavaScript
// ChatInput.jsx (간단한 상태 기반 데모 컴포넌트)
|
|
// -----------------------------------------------------------------------------
|
|
// • inputText / inputImage 상태 관리
|
|
// • ChatHandler 호출 후 messages 배열에 push
|
|
// • very minimal UI (실제 서비스에서는 스타일·UX 개선 필요)
|
|
// -----------------------------------------------------------------------------
|
|
|
|
import React, { useState } from 'react';
|
|
import ChatHandler from './ChatHandler';
|
|
|
|
const ChatInput = () => {
|
|
// ---------------- state ----------------
|
|
const [inputText, setInputText] = useState('');
|
|
const [selectedFiles, setSelectedFiles] = useState([]); // File[]
|
|
const [messages, setMessages] = useState([]); // {text, files, sender}
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
// ------------- handlers ---------------
|
|
const handleTextChange = e => setInputText(e.target.value);
|
|
|
|
const handleFilesChange = e => {
|
|
const files = Array.from(e.target.files || []);
|
|
if (files.length) {
|
|
setSelectedFiles(prev => [...prev, ...files]);
|
|
}
|
|
};
|
|
|
|
const handleFileRemove = idx => {
|
|
setSelectedFiles(prev => prev.filter((_, i) => i !== idx));
|
|
};
|
|
|
|
// 채팅 보내기
|
|
const handleSend = async () => {
|
|
if (!inputText && selectedFiles.length === 0) return;
|
|
setLoading(true);
|
|
|
|
// 1) 사용자 메시지 화면에 표시
|
|
const userMessage = { text: inputText, files: selectedFiles, sender: 'user' };
|
|
setMessages(prev => [...prev, userMessage]);
|
|
|
|
// 2) ChatHandler 로 AI 답변 요청
|
|
const { response } = await ChatHandler({
|
|
text : inputText,
|
|
files : selectedFiles,
|
|
toolId : 'dev_chatbot', // 데모용 고정
|
|
});
|
|
|
|
// 3) AI 응답 메시지 push
|
|
setMessages(prev => [...prev, userMessage, { text: response, sender: 'ai' }]);
|
|
|
|
// 4) 입력 초기화
|
|
setInputText('');
|
|
setSelectedFiles([]);
|
|
setLoading(false);
|
|
};
|
|
|
|
// ---------------- render --------------
|
|
return (
|
|
<div>
|
|
<div style={{ minHeight: 200, border: '1px solid #ccc', marginBottom: 10, padding: 10 }}>
|
|
{messages.map((msg, idx) => (
|
|
<div key={idx} style={{ marginBottom: 8 }}>
|
|
<b>{msg.sender === 'user' ? '나' : 'AI'}:</b> {msg.text}
|
|
{msg.files && msg.files.length > 0 && (
|
|
<ul style={{ marginTop: 4 }}>
|
|
{msg.files.map((file, fIdx) => (
|
|
<li key={fIdx}>{file.name}</li>
|
|
))}
|
|
</ul>
|
|
)}
|
|
</div>
|
|
))}
|
|
{loading && <div>AI가 응답을 생성하고 있습니다...</div>}
|
|
</div>
|
|
|
|
{/* 입력 영역 */}
|
|
<input type="text" value={inputText} onChange={handleTextChange} placeholder="메시지를 입력하세요" style={{ width: 300 }} />
|
|
<input type="file" multiple onChange={handleFilesChange} />
|
|
{selectedFiles.length > 0 && (
|
|
<ul style={{ marginTop: 4 }}>
|
|
{selectedFiles.map((file, idx) => (
|
|
<li key={idx}>
|
|
{file.name} <button type="button" onClick={() => handleFileRemove(idx)}>삭제</button>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
)}
|
|
<button onClick={handleSend} disabled={loading}>전송</button>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default ChatInput;
|