YuRiVeRTi commited on
Commit
fcbbe44
·
verified ·
1 Parent(s): dc30ea3

Create V1Q

Browse files
Files changed (1) hide show
  1. V1Q +196 -0
V1Q ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import React, { useState, useRef, useEffect } from 'react';
3
+ import { Button } from '@/components/ui/button';
4
+ import { Input } from '@/components/ui/input';
5
+ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
6
+ import { Send, Bot, User, Loader2 } from 'lucide-react';
7
+
8
+ interface Message {
9
+ id: string;
10
+ content: string;
11
+ role: 'user' | 'assistant';
12
+ timestamp: Date;
13
+ }
14
+
15
+ const ChatBot = () => {
16
+ const [messages, setMessages] = useState<Message[]>([
17
+ {
18
+ id: '1',
19
+ content: 'Hello! I\'m your AI assistant powered by V1Q. How can I help you today?',
20
+ role: 'assistant',
21
+ timestamp: new Date()
22
+ }
23
+ ]);
24
+ const [input, setInput] = useState('');
25
+ const [isLoading, setIsLoading] = useState(false);
26
+ const messagesEndRef = useRef<HTMLDivElement>(null);
27
+
28
+ const scrollToBottom = () => {
29
+ messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
30
+ };
31
+
32
+ useEffect(() => {
33
+ scrollToBottom();
34
+ }, [messages]);
35
+
36
+ const sendMessage = async () => {
37
+ if (!input.trim() || isLoading) return;
38
+
39
+ const userMessage: Message = {
40
+ id: Date.now().toString(),
41
+ content: input,
42
+ role: 'user',
43
+ timestamp: new Date()
44
+ };
45
+
46
+ setMessages(prev => [...prev, userMessage]);
47
+ setInput('');
48
+ setIsLoading(true);
49
+
50
+ try {
51
+ // Simulate API call to V1Q model
52
+ await new Promise(resolve => setTimeout(resolve, 1000 + Math.random() * 2000));
53
+
54
+ const assistantMessage: Message = {
55
+ id: (Date.now() + 1).toString(),
56
+ content: generateResponse(input),
57
+ role: 'assistant',
58
+ timestamp: new Date()
59
+ };
60
+
61
+ setMessages(prev => [...prev, assistantMessage]);
62
+ } catch (error) {
63
+ console.error('Error sending message:', error);
64
+ const errorMessage: Message = {
65
+ id: (Date.now() + 1).toString(),
66
+ content: 'Sorry, I encountered an error. Please try again.',
67
+ role: 'assistant',
68
+ timestamp: new Date()
69
+ };
70
+ setMessages(prev => [...prev, errorMessage]);
71
+ } finally {
72
+ setIsLoading(false);
73
+ }
74
+ };
75
+
76
+ const generateResponse = (userInput: string): string => {
77
+ // Simple response generation for demo purposes
78
+ const responses = [
79
+ "That's an interesting question! Let me help you with that.",
80
+ "I understand what you're asking. Here's what I think...",
81
+ "Great question! Based on my knowledge, I can tell you that...",
82
+ "I'd be happy to help you with that. Here's my response...",
83
+ "That's a thoughtful inquiry. Let me provide you with some insights..."
84
+ ];
85
+
86
+ return responses[Math.floor(Math.random() * responses.length)] +
87
+ ` Regarding "${userInput}", I'm processing this with the V1Q model to provide you with the most accurate response possible.`;
88
+ };
89
+
90
+ const handleKeyPress = (e: React.KeyboardEvent) => {
91
+ if (e.key === 'Enter' && !e.shiftKey) {
92
+ e.preventDefault();
93
+ sendMessage();
94
+ }
95
+ };
96
+
97
+ return (
98
+ <div className="max-w-4xl mx-auto h-[600px] flex flex-col">
99
+ <Card className="flex-1 flex flex-col">
100
+ <CardHeader className="border-b">
101
+ <CardTitle className="flex items-center gap-2">
102
+ <Bot className="h-6 w-6 text-primary" />
103
+ AI Assistant (V1Q)
104
+ </CardTitle>
105
+ </CardHeader>
106
+
107
+ <CardContent className="flex-1 flex flex-col p-0">
108
+ <div className="flex-1 overflow-y-auto p-4 space-y-4">
109
+ {messages.map((message) => (
110
+ <div
111
+ key={message.id}
112
+ className={`flex gap-3 ${
113
+ message.role === 'user' ? 'justify-end' : 'justify-start'
114
+ }`}
115
+ >
116
+ <div
117
+ className={`flex gap-3 max-w-[80%] ${
118
+ message.role === 'user' ? 'flex-row-reverse' : 'flex-row'
119
+ }`}
120
+ >
121
+ <div className="flex-shrink-0">
122
+ {message.role === 'user' ? (
123
+ <div className="w-8 h-8 bg-primary rounded-full flex items-center justify-center">
124
+ <User className="h-4 w-4 text-primary-foreground" />
125
+ </div>
126
+ ) : (
127
+ <div className="w-8 h-8 bg-secondary rounded-full flex items-center justify-center">
128
+ <Bot className="h-4 w-4 text-secondary-foreground" />
129
+ </div>
130
+ )}
131
+ </div>
132
+
133
+ <div
134
+ className={`rounded-lg p-3 ${
135
+ message.role === 'user'
136
+ ? 'bg-primary text-primary-foreground'
137
+ : 'bg-muted text-muted-foreground'
138
+ }`}
139
+ >
140
+ <p className="text-sm">{message.content}</p>
141
+ <p className="text-xs opacity-70 mt-1">
142
+ {message.timestamp.toLocaleTimeString([], {
143
+ hour: '2-digit',
144
+ minute: '2-digit'
145
+ })}
146
+ </p>
147
+ </div>
148
+ </div>
149
+ </div>
150
+ ))}
151
+
152
+ {isLoading && (
153
+ <div className="flex gap-3 justify-start">
154
+ <div className="flex gap-3 max-w-[80%]">
155
+ <div className="w-8 h-8 bg-secondary rounded-full flex items-center justify-center">
156
+ <Bot className="h-4 w-4 text-secondary-foreground" />
157
+ </div>
158
+ <div className="rounded-lg p-3 bg-muted">
159
+ <div className="flex items-center gap-2">
160
+ <Loader2 className="h-4 w-4 animate-spin" />
161
+ <span className="text-sm text-muted-foreground">Thinking...</span>
162
+ </div>
163
+ </div>
164
+ </div>
165
+ </div>
166
+ )}
167
+
168
+ <div ref={messagesEndRef} />
169
+ </div>
170
+
171
+ <div className="p-4 border-t">
172
+ <div className="flex gap-2">
173
+ <Input
174
+ value={input}
175
+ onChange={(e) => setInput(e.target.value)}
176
+ onKeyPress={handleKeyPress}
177
+ placeholder="Type your message here..."
178
+ disabled={isLoading}
179
+ className="flex-1"
180
+ />
181
+ <Button
182
+ onClick={sendMessage}
183
+ disabled={!input.trim() || isLoading}
184
+ size="icon"
185
+ >
186
+ <Send className="h-4 w-4" />
187
+ </Button>
188
+ </div>
189
+ </div>
190
+ </CardContent>
191
+ </Card>
192
+ </div>
193
+ );
194
+ };
195
+
196
+ export default ChatBot