anycoder-82c661ce / components /ChatWindow.jsx
durukan's picture
Upload components/ChatWindow.jsx with huggingface_hub
b4e7a11 verified
import { useState, useEffect, useRef } from 'react';
import ChatMessage from './ChatMessage';
import ChatInput from './ChatInput';
import { motion } from 'framer-motion';
export default function ChatWindow() {
const [messages, setMessages] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const messagesEndRef = useRef(null);
const scrollToBottom = () => {
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
};
useEffect(() => {
scrollToBottom();
}, [messages]);
const handleSendMessage = async (text) => {
const userMessage = {
text,
timestamp: new Date().toISOString(),
isUser: true,
};
setMessages(prev => [...prev, userMessage]);
setIsLoading(true);
try {
const response = await fetch('/api/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ message: text }),
});
if (!response.ok) throw new Error('Failed to get response');
const data = await response.json();
const botMessage = {
text: data.response,
timestamp: new Date().toISOString(),
isUser: false,
};
setMessages(prev => [...prev, botMessage]);
} catch (error) {
console.error('Error:', error);
const errorMessage = {
text: "Sorry, I'm having trouble responding right now. Please try again later.",
timestamp: new Date().toISOString(),
isUser: false,
};
setMessages(prev => [...prev, errorMessage]);
} finally {
setIsLoading(false);
}
};
return (
<div className="flex flex-col h-screen bg-gray-50">
<div className="flex-1 overflow-y-auto p-4 space-y-4">
{messages.length === 0 ? (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
className="flex flex-col items-center justify-center h-full"
>
<div className="w-24 h-24 bg-primary rounded-full flex items-center justify-center mb-4">
<span className="text-white text-4xl font-bold">R</span>
</div>
<h2 className="text-2xl font-semibold text-gray-700 mb-2">Welcome to Replika Clone</h2>
<p className="text-gray-500 text-center max-w-md">
Start chatting with your virtual companion. She's here to listen and talk about anything!
</p>
</motion.div>
) : (
messages.map((message, index) => (
<ChatMessage
key={index}
message={message}
isUser={message.isUser}
/>
))
)}
{isLoading && (
<div className="flex justify-start mb-4">
<div className="bg-gray-100 text-gray-800 rounded-lg p-3 rounded-bl-none max-w-xs">
<div className="flex space-x-2">
<div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce"></div>
<div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style={{ animationDelay: '0.2s' }}></div>
<div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style={{ animationDelay: '0.4s' }}></div>
</div>
</div>
</div>
)}
<div ref={messagesEndRef} />
</div>
<ChatInput onSendMessage={handleSendMessage} />
</div>
);
}