Khushhal1 commited on
Commit
891fe6c
·
verified ·
1 Parent(s): 31e22cd

Upload 2 files

Browse files
Files changed (2) hide show
  1. frontend/ChatInterface.jsx +104 -0
  2. frontend/package.json +23 -0
frontend/ChatInterface.jsx ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, useEffect, useRef } from 'react';
2
+
3
+ const ChatInterface = () => {
4
+ const [messages, setMessages] = useState([
5
+ { role: 'assistant', content: 'Hello! I am your custom LLM. How can I help you today?' }
6
+ ]);
7
+ const [input, setInput] = 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(scrollToBottom, [messages]);
16
+
17
+ const handleSubmit = async (e) => {
18
+ e.preventDefault();
19
+ if (!input.trim()) return;
20
+
21
+ const userMessage = { role: 'user', content: input };
22
+ setMessages(prev => [...prev, userMessage]);
23
+ setInput('');
24
+ setIsLoading(true);
25
+
26
+ try {
27
+ const response = await fetch('/api/chat', { // Proxied to HF/FastAPI
28
+ method: 'POST',
29
+ headers: { 'Content-Type': 'application/json' },
30
+ body: JSON.stringify({
31
+ messages: [...messages, userMessage].map(m => ({
32
+ role: m.role,
33
+ content: m.content
34
+ }))
35
+ }),
36
+ });
37
+
38
+ const data = await response.json();
39
+ setMessages(prev => [...prev, {
40
+ role: 'assistant',
41
+ content: data.choices[0].message.content
42
+ }]);
43
+ } catch (error) {
44
+ console.error('Error:', error);
45
+ setMessages(prev => [...prev, {
46
+ role: 'assistant',
47
+ content: 'Sorry, I encountered an error. Please check your backend connection.'
48
+ }]);
49
+ } finally {
50
+ setIsLoading(false);
51
+ }
52
+ };
53
+
54
+ return (
55
+ <div className="flex flex-col h-screen max-w-4xl mx-auto p-4 font-sans text-gray-800">
56
+ <header className="py-6 border-b">
57
+ <h1 className="text-2xl font-bold text-indigo-600">Custom LLM Studio</h1>
58
+ <p className="text-sm text-gray-500">Connected to HF Spaces / FastAPI Backend</p>
59
+ </header>
60
+
61
+ <div className="flex-1 overflow-y-auto py-6 space-y-4">
62
+ {messages.map((m, i) => (
63
+ <div key={i} className={`flex ${m.role === 'user' ? 'justify-end' : 'justify-start'}`}>
64
+ <div className={`max-w-[80%] rounded-2xl px-4 py-2 ${
65
+ m.role === 'user'
66
+ ? 'bg-indigo-600 text-white rounded-tr-none'
67
+ : 'bg-gray-100 text-gray-800 rounded-tl-none'
68
+ }`}>
69
+ <p className="whitespace-pre-wrap">{m.content}</p>
70
+ </div>
71
+ </div>
72
+ ))}
73
+ {isLoading && (
74
+ <div className="flex justify-start">
75
+ <div className="bg-gray-100 rounded-2xl px-4 py-2 rounded-tl-none animate-pulse">
76
+ Typing...
77
+ </div>
78
+ </div>
79
+ )}
80
+ <div ref={messagesEndRef} />
81
+ </div>
82
+
83
+ <form onSubmit={handleSubmit} className="py-6 border-t flex gap-2">
84
+ <input
85
+ type="text"
86
+ value={input}
87
+ onChange={(e) => setInput(e.target.value)}
88
+ placeholder="Type your message..."
89
+ className="flex-1 border rounded-full px-6 py-2 focus:outline-none focus:ring-2 focus:ring-indigo-500"
90
+ disabled={isLoading}
91
+ />
92
+ <button
93
+ type="submit"
94
+ className="bg-indigo-600 text-white rounded-full px-6 py-2 font-semibold hover:bg-indigo-700 disabled:opacity-50 transition"
95
+ disabled={isLoading}
96
+ >
97
+ Send
98
+ </button>
99
+ </form>
100
+ </div>
101
+ );
102
+ };
103
+
104
+ export default ChatInterface;
frontend/package.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "llm-frontend",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev",
7
+ "build": "next build",
8
+ "start": "next start"
9
+ },
10
+ "dependencies": {
11
+ "react": "^18.2.0",
12
+ "react-dom": "^18.2.0",
13
+ "next": "14.1.0",
14
+ "lucide-react": "^0.330.0",
15
+ "clsx": "^2.1.0",
16
+ "tailwind-merge": "^2.2.1"
17
+ },
18
+ "devDependencies": {
19
+ "autoprefixer": "^10.4.17",
20
+ "postcss": "^8.4.35",
21
+ "tailwindcss": "^3.4.1"
22
+ }
23
+ }