durukan commited on
Commit
b4e7a11
·
verified ·
1 Parent(s): a875d67

Upload components/ChatWindow.jsx with huggingface_hub

Browse files
Files changed (1) hide show
  1. components/ChatWindow.jsx +103 -0
components/ChatWindow.jsx ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useState, useEffect, useRef } from 'react';
2
+ import ChatMessage from './ChatMessage';
3
+ import ChatInput from './ChatInput';
4
+ import { motion } from 'framer-motion';
5
+
6
+ export default function ChatWindow() {
7
+ const [messages, setMessages] = useState([]);
8
+ const [isLoading, setIsLoading] = useState(false);
9
+ const messagesEndRef = useRef(null);
10
+
11
+ const scrollToBottom = () => {
12
+ messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
13
+ };
14
+
15
+ useEffect(() => {
16
+ scrollToBottom();
17
+ }, [messages]);
18
+
19
+ const handleSendMessage = async (text) => {
20
+ const userMessage = {
21
+ text,
22
+ timestamp: new Date().toISOString(),
23
+ isUser: true,
24
+ };
25
+
26
+ setMessages(prev => [...prev, userMessage]);
27
+ setIsLoading(true);
28
+
29
+ try {
30
+ const response = await fetch('/api/chat', {
31
+ method: 'POST',
32
+ headers: {
33
+ 'Content-Type': 'application/json',
34
+ },
35
+ body: JSON.stringify({ message: text }),
36
+ });
37
+
38
+ if (!response.ok) throw new Error('Failed to get response');
39
+
40
+ const data = await response.json();
41
+ const botMessage = {
42
+ text: data.response,
43
+ timestamp: new Date().toISOString(),
44
+ isUser: false,
45
+ };
46
+
47
+ setMessages(prev => [...prev, botMessage]);
48
+ } catch (error) {
49
+ console.error('Error:', error);
50
+ const errorMessage = {
51
+ text: "Sorry, I'm having trouble responding right now. Please try again later.",
52
+ timestamp: new Date().toISOString(),
53
+ isUser: false,
54
+ };
55
+ setMessages(prev => [...prev, errorMessage]);
56
+ } finally {
57
+ setIsLoading(false);
58
+ }
59
+ };
60
+
61
+ return (
62
+ <div className="flex flex-col h-screen bg-gray-50">
63
+ <div className="flex-1 overflow-y-auto p-4 space-y-4">
64
+ {messages.length === 0 ? (
65
+ <motion.div
66
+ initial={{ opacity: 0 }}
67
+ animate={{ opacity: 1 }}
68
+ className="flex flex-col items-center justify-center h-full"
69
+ >
70
+ <div className="w-24 h-24 bg-primary rounded-full flex items-center justify-center mb-4">
71
+ <span className="text-white text-4xl font-bold">R</span>
72
+ </div>
73
+ <h2 className="text-2xl font-semibold text-gray-700 mb-2">Welcome to Replika Clone</h2>
74
+ <p className="text-gray-500 text-center max-w-md">
75
+ Start chatting with your virtual companion. She's here to listen and talk about anything!
76
+ </p>
77
+ </motion.div>
78
+ ) : (
79
+ messages.map((message, index) => (
80
+ <ChatMessage
81
+ key={index}
82
+ message={message}
83
+ isUser={message.isUser}
84
+ />
85
+ ))
86
+ )}
87
+ {isLoading && (
88
+ <div className="flex justify-start mb-4">
89
+ <div className="bg-gray-100 text-gray-800 rounded-lg p-3 rounded-bl-none max-w-xs">
90
+ <div className="flex space-x-2">
91
+ <div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce"></div>
92
+ <div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style={{ animationDelay: '0.2s' }}></div>
93
+ <div className="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style={{ animationDelay: '0.4s' }}></div>
94
+ </div>
95
+ </div>
96
+ </div>
97
+ )}
98
+ <div ref={messagesEndRef} />
99
+ </div>
100
+ <ChatInput onSendMessage={handleSendMessage} />
101
+ </div>
102
+ );
103
+ }