init
This commit is contained in:
93
frontend/dev_chatbot/ChatInput.jsx
Normal file
93
frontend/dev_chatbot/ChatInput.jsx
Normal file
@@ -0,0 +1,93 @@
|
||||
// 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;
|
||||
Reference in New Issue
Block a user