File size: 2,950 Bytes
effe6e2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e6cfea8
 
 
 
 
effe6e2
 
e6cfea8
 
 
 
effe6e2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import React, { useState } from 'react';
import './ChatPage.css'; // η’ΊδΏδ½ ζœ‰ι€™ε€‹ζ¨£εΌζͺ”ζ‘ˆ
import { useNavigate } from 'react-router-dom';

// frontend message type
interface Message {
  sender: 'user' | 'ai';
  text: string;
}

// Type definition of backend return data
interface AskResponse {
  answer: string;
  source_documents: string[];
}

const ChatPage: React.FC = () => {
  const [messages, setMessages] = useState<Message[]>([]);
  const [input, setInput] = useState('');
  const [loading, setLoading] = useState(false);
  const navigate = useNavigate();

  const handleSend = async () => {
    if (input.trim() === '') return;

    const userMessage: Message = { sender: 'user', text: input };
    setMessages((prev) => [...prev, userMessage]);
    setInput('');
    setLoading(true);

    try {

      const res = await fetch('/ask', {  // ζ”Ήζˆη›Έε°θ·―εΎ‘
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ query: input }),
      });


      if (!res.ok) throw new Error('Backend error');

      const data: AskResponse = await res.json();
     
      let aiText = data.answer;
      if (aiText.includes("πŸ“š Source Snippets")) {
      aiText = aiText.split("πŸ“š Source Snippets")[0].trim();
    }

      const aiMessage: Message = { sender: 'ai', text: aiText };
      setMessages((prev) => [...prev, aiMessage]);

      // const aiText = `${data.answer}\n\nπŸ“š Source Snippets:\n${data.source_documents.slice(0, 2).join('\n\n')}`;
      // const aiMessage: Message = { sender: 'ai', text: aiText };

      setMessages((prev) => [...prev, aiMessage]);
    } catch (err) {
      console.error('Fetch error:', err);
      const errorMessage: Message = { sender: 'ai', text: '❌ Unable to get a response, please try again later.' };
      setMessages((prev) => [...prev, errorMessage]);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="chat-container">
      <div className="back-button-container">
        <button className="back-button" onClick={() => navigate('/')}>
          πŸ”™ Back to Home Page
        </button>
      </div>  
      <header className="chat-header">LabAid AI Chat</header>
      <div className="chat-messages">
        {messages.map((msg, idx) => (
          <div key={idx} className={`chat-bubble ${msg.sender}`}>
            {msg.text}
          </div>
        ))}
        {loading && <div className="chat-bubble ai loading">πŸ’¬ thinking...</div>}
      </div>

      <div className="chat-input-area">
        <input
          type="text"
          value={input}
          onChange={(e) => setInput(e.target.value)}
          onKeyDown={(e) => {
            if (e.key === 'Enter') handleSend();
          }}
          placeholder="please enter your question..."
        />
        <button onClick={handleSend} disabled={loading}>send</button>
      </div>
    </div>
  );
};

export default ChatPage;