Spaces:
Sleeping
Sleeping
File size: 5,638 Bytes
d09f9ae 3e28faa d09f9ae 1d9fbb6 c24f5d5 1d9fbb6 c24f5d5 1d9fbb6 d09f9ae 1d9fbb6 d09f9ae f94c359 d09f9ae f94c359 d09f9ae | 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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | import React, { useState, useEffect } from 'react';
import { FaPaperPlane } from "react-icons/fa";
import { FiMenu } from 'react-icons/fi';
import { SunIcon, MoonIcon } from '@heroicons/react/24/outline';
import chatbotIcon from './assets/chatbot-icon.png';
import './App.css';
import logo from './assets/chatbot-icon.png';
import ReactMarkdown from "react-markdown";
function App() {
const [userInput, setUserInput] = useState('');
const [chatLog, setChatLog] = useState([]);
const [loading, setLoading] = useState(false);
const [darkMode, setDarkMode] = useState(false);
// Generate a sessionId for this browser session
const [sessionId] = useState(() => `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`);
//console.log(sessionId);
// Load theme from localStorage on mount
useEffect(() => {
const savedTheme = localStorage.getItem('theme');
if (savedTheme === 'dark') {
setDarkMode(true);
document.documentElement.classList.add('dark');
}
}, []);
// On mount, start with an empty chat window (do NOT load previous messages)
useEffect(() => {
//localStorage.removeItem('chatLog'); // Optional: ensures no old data
setChatLog([]);
}, []);
// Toggle theme and persist
const toggleTheme = () => {
const newTheme = darkMode ? 'light' : 'dark';
setDarkMode(!darkMode);
localStorage.setItem('theme', newTheme);
document.documentElement.classList.toggle('dark', newTheme === 'dark');
};
const handleSubmit = async (event) => {
event.preventDefault();
if (!userInput.trim()) return; // Don't send empty messages
const userMessage = { type: 'user', text: userInput, ts: Date.now(), sessionId };
const newChatLog = [...chatLog, userMessage];
setChatLog(newChatLog);
setUserInput('');
setLoading(true);
try {
// The API call to our FastAPI backend
const response = await fetch('https://nova-chatbot-chatbot-backend.hf.space/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ user_message: userInput }),
});
//console.log("response",response);
//console.log("response.json()",response.json())
//if (!response.ok) {
// Read raw text so HTML errors don’t crash JSON parsing
// const text = await response.text();
// throw new Error(`Backend ${response.status}: ${text}`);
//} else {
// data = await response.json(); // safe now
//}
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
//consoloe.log("data",data)
const botMessage = { type: 'bot', text: data.bot_response, ts: Date.now(), sessionId };
// Update the chat log with the bot's response
const finalChatLog = [...newChatLog, botMessage];
setChatLog(finalChatLog);
// Save both messages to history (not loaded on refresh)
const history = JSON.parse(localStorage.getItem('chatHistory') || '[]');
const updatedHistory = [...history, userMessage, botMessage];
localStorage.setItem('chatHistory', JSON.stringify(updatedHistory));
} catch (error) {
console.error('Error fetching chat response:', error);
const errorMessage = { type: 'error', text: 'Sorry, something went wrong. Please try again.' };
setChatLog(prev => [...prev, errorMessage]);
// Save error to history if needed
const history = JSON.parse(localStorage.getItem('chatHistory') || '[]');
localStorage.setItem('chatHistory', JSON.stringify([...history, errorMessage]));
} finally {
setLoading(false);
}
};
return (
<div className="App">
<div className="header">
<img src={logo} alt="Logo" className="logo" />
<h1>NOVA</h1>
</div>
<div className="chat-window">
{chatLog.map((message, index) => (
<div key={index} className={`message ${message.type}`}>
<ReactMarkdown>{message.text}</ReactMarkdown>
</div>
))}
{loading && <div className="message bot">Loading...</div>}
</div>
<form onSubmit={handleSubmit} className="chat-form">
<input
type="text"
value={userInput}
onChange={(e) => setUserInput(e.target.value)}
placeholder="Type your message..."
disabled={loading}
/>
{/*<button type="submit" disabled={loading}>Send</button>*/}
<button
onClick={handleSubmit}
className="send-button"
aria-label="Send"
style={{
backgroundColor: "#007bff",
color: "#fff",
padding: "10px 15px",
borderRadius: "8px",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<FaPaperPlane size={18} />
</button>
</form>
</div>
);
}
export default App; |