AxL95 commited on
Commit
6217553
·
verified ·
1 Parent(s): 7e3cbc2

Update frontend/src/App.js

Browse files
Files changed (1) hide show
  1. frontend/src/App.js +283 -100
frontend/src/App.js CHANGED
@@ -1,101 +1,284 @@
1
- import React, { useState } from 'react';
2
- import './App.css';
3
- import ChatInterface from './components/ChatInterface';
4
- import Panel from './components/Panel';
5
- import Login from './components/Login';
6
- import Signin from './components/Signin';
7
-
8
-
9
- function App() {
10
- const [isCollapsed, setIsCollapsed] = useState(false);
11
- const [messages, setMessages] = useState([]);
12
- const [conversations, setConversations] = useState([
13
- { id: 1, title: "Premier diagnostic", date: "12 Mar" },
14
- { id: 2, title: "Question sur les symptômes", date: "11 Mar" },
15
- { id: 3, title: "Consultation générale", date: "10 Mar" }
16
- ]);
17
- const [activeConversationId, setActiveConversationId] = useState(null);
18
-
19
- const toggleCollapse = () => {
20
- setIsCollapsed(!isCollapsed);
21
- };
22
-
23
- const handleNewChat = () => {
24
- setActiveConversationId(null);
25
- setMessages([]);
26
- };
27
-
28
- const handleMessageSent = (message) => {
29
-
30
- if (!activeConversationId) {
31
- const newChat = {
32
- id: Date.now(),
33
- title: message.length > 15 ? message.substring(0, 15) + "..." : message,
34
- date: new Date().toLocaleDateString('fr-FR', { day: '2-digit', month: 'short' }),
35
- time: new Date().toLocaleTimeString('fr-FR', { hour: 'numeric', minute: 'numeric' })
36
-
37
- };
38
- setConversations([newChat, ...conversations]);
39
- setActiveConversationId(newChat.id);
40
- }
41
- };
42
-
43
- const [page, setPage] = useState("chat");
44
-
45
- return (
46
- <div className={`App ${isCollapsed ? 'panel-collapsed' : ''}`}>
47
-
48
- {page === "chat" && (
49
- <Panel
50
- conversations={conversations}
51
- setConversations={setConversations}
52
- activeConversationId={activeConversationId}
53
- setActiveConversationId={setActiveConversationId}
54
- onNewChat={handleNewChat}
55
- onToggleCollapse={toggleCollapse}
56
- isCollapsed={isCollapsed}
57
- />
58
- )}
59
-
60
- <div className="main-content">
61
- {isCollapsed && (
62
- <button className="collapse-button-main" onClick={toggleCollapse}>
63
- <span className="material-icons">
64
- <svg
65
- fill="#FFFF"
66
- width="20"
67
- height="20"
68
- viewBox="0 0 32 32"
69
- xmlns="http://www.w3.org/2000/svg"
70
- >
71
- <defs>
72
- <style>{`.cls-1{fill:none;}`}</style>
73
- </defs>
74
- <title>open-panel--solid--left</title>
75
- <path d="M28,4H4A2,2,0,0,0,2,6V26a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V6A2,2,0,0,0,28,4Zm0,22H12V6H28Z" />
76
- <rect
77
- id="_Transparent_Rectangle_"
78
- data-name="<Transparent Rectangle>"
79
- className="cls-1"
80
- width="20"
81
- height="20"
82
- />
83
- </svg>
84
- </span>
85
- </button>
86
- )}
87
-
88
- {page === "chat" &&
89
- <ChatInterface
90
- messages={messages}
91
- setMessages={setMessages}
92
- onMessageSent={handleMessageSent}
93
- toLogin={() => setPage("login")}/>}
94
- {page === "login" && <Login toSignin={() => setPage("signin")}/>}
95
- {page === "signin" && <Signin toLogin={() => setPage("login")}/>}
96
- </div>
97
- </div>
98
- );
99
- }
100
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  export default App;
 
1
+ import React, { useState, useEffect } from 'react';
2
+ import './App.css';
3
+ import ChatInterface from './components/ChatInterface';
4
+ import Panel from './components/Panel';
5
+ import Login from './components/Login';
6
+ import Signin from './components/Signin';
7
+
8
+ function App() {
9
+ const [isCollapsed, setIsCollapsed] = useState(false);
10
+ const [messages, setMessages] = useState([]);
11
+ const [conversations, setConversations] = useState([]);
12
+ const [activeConversationId, setActiveConversationId] = useState(null);
13
+ const [isAuthenticated, setIsAuthenticated] = useState(false);
14
+ const [userName, setUserName] = useState('');
15
+ const [page, setPage] = useState("login"); // Démarrer sur login par défaut
16
+
17
+ // Vérifier si l'utilisateur est déjà connecté au chargement
18
+ useEffect(() => {
19
+ const storedUserName = localStorage.getItem('userName');
20
+ if (storedUserName) {
21
+ setUserName(storedUserName);
22
+ setIsAuthenticated(true);
23
+ setPage("chat");
24
+
25
+ // Charger les conversations de l'utilisateur
26
+ fetchConversations();
27
+ }
28
+ }, []);
29
+
30
+ // Fonction pour récupérer les conversations depuis l'API
31
+ const fetchConversations = async () => {
32
+ try {
33
+ const response = await fetch('http://localhost:7860/api/conversations', {
34
+ credentials: 'include', // Important pour envoyer les cookies
35
+ });
36
+
37
+ if (response.ok) {
38
+ const data = await response.json();
39
+ // Formater les données pour correspondre à votre format de conversation
40
+ const formattedConversations = data.conversations.map(conv => ({
41
+ id: conv._id,
42
+ title: conv.title,
43
+ date: conv.date,
44
+ time: conv.time,
45
+ lastMessage: conv.last_message
46
+ }));
47
+ setConversations(formattedConversations);
48
+ } else {
49
+ console.error('Erreur lors de la récupération des conversations');
50
+ }
51
+ } catch (error) {
52
+ console.error('Erreur:', error);
53
+ }
54
+ };
55
+
56
+ // Fonction pour charger les messages d'une conversation sélectionnée
57
+ const loadConversationMessages = async (conversationId) => {
58
+ try {
59
+ const response = await fetch(`http://localhost:7860/api/conversations/${conversationId}/messages`, {
60
+ credentials: 'include',
61
+ });
62
+
63
+ if (response.ok) {
64
+ const data = await response.json();
65
+ // Formater les messages pour correspondre à votre format
66
+ const formattedMessages = data.messages.map(msg => ({
67
+ sender: msg.sender,
68
+ text: msg.text,
69
+ timestamp: new Date(msg.timestamp)
70
+ }));
71
+ setMessages(formattedMessages);
72
+ }
73
+ } catch (error) {
74
+ console.error('Erreur lors du chargement des messages:', error);
75
+ }
76
+ };
77
+
78
+ // Au changement de conversation active
79
+ useEffect(() => {
80
+ if (activeConversationId && isAuthenticated) {
81
+ loadConversationMessages(activeConversationId);
82
+ }
83
+ }, [activeConversationId, isAuthenticated]);
84
+
85
+ const toggleCollapse = () => {
86
+ setIsCollapsed(!isCollapsed);
87
+ };
88
+
89
+ const handleNewChat = () => {
90
+ setActiveConversationId(null);
91
+ setMessages([]);
92
+ };
93
+
94
+ const handleMessageSent = async (message) => {
95
+ let conversationId = activeConversationId;
96
+
97
+ if (!conversationId) {
98
+ // Créer une nouvelle conversation
99
+ const newChatData = {
100
+ title: message.length > 15 ? message.substring(0, 15) + "..." : message,
101
+ date: new Date().toLocaleDateString('fr-FR', { day: '2-digit', month: 'short' }),
102
+ time: new Date().toLocaleTimeString('fr-FR', { hour: 'numeric', minute: 'numeric' }),
103
+ message: message
104
+ };
105
+
106
+ try {
107
+ // Enregistrer la nouvelle conversation dans MongoDB
108
+ const response = await fetch('http://localhost:7860/api/conversations', {
109
+ method: 'POST',
110
+ headers: {
111
+ 'Content-Type': 'application/json',
112
+ },
113
+ credentials: 'include',
114
+ body: JSON.stringify(newChatData)
115
+ });
116
+
117
+ if (response.ok) {
118
+ const data = await response.json();
119
+ conversationId = data.conversation_id; // Important: stocker l'ID dans une variable locale
120
+
121
+ const newChat = {
122
+ id: conversationId,
123
+ title: newChatData.title,
124
+ date: newChatData.date,
125
+ time: newChatData.time
126
+ };
127
+
128
+ setConversations([newChat, ...conversations]);
129
+ setActiveConversationId(conversationId);
130
+
131
+ // IMPORTANT: Enregistrer le message utilisateur une fois l'ID disponible
132
+ await fetch(`http://localhost:7860/api/conversations/${conversationId}/messages`, {
133
+ method: 'POST',
134
+ headers: { 'Content-Type': 'application/json' },
135
+ credentials: 'include',
136
+ body: JSON.stringify({
137
+ sender: 'user',
138
+ text: message
139
+ })
140
+ });
141
+ }
142
+ } catch (error) {
143
+ console.error('Erreur lors de la création de la conversation:', error);
144
+ return; // Arrêter si on ne peut pas créer la conversation
145
+ }
146
+ } else {
147
+ // Sauvegarder le message utilisateur pour une conversation existante
148
+ try {
149
+ await fetch(`http://localhost:7860/api/conversations/${conversationId}/messages`, {
150
+ method: 'POST',
151
+ headers: { 'Content-Type': 'application/json' },
152
+ credentials: 'include',
153
+ body: JSON.stringify({
154
+ sender: 'user',
155
+ text: message
156
+ })
157
+ });
158
+ } catch (error) {
159
+ console.error('Erreur lors de l\'enregistrement du message:', error);
160
+ }
161
+ }
162
+
163
+ return conversationId; // Retourner l'ID pour le composant ChatInterface
164
+ };
165
+
166
+ // Fonction pour sauvegarder la réponse du bot
167
+ const saveBotResponse = async (conversationId, botResponse) => {
168
+ if (!conversationId) return;
169
+
170
+ try {
171
+ await fetch(`http://localhost:7860/api/conversations/${conversationId}/messages`, {
172
+ method: 'POST',
173
+ headers: {
174
+ 'Content-Type': 'application/json',
175
+ },
176
+ credentials: 'include',
177
+ body: JSON.stringify({
178
+ sender: 'bot',
179
+ text: botResponse
180
+ })
181
+ });
182
+ } catch (error) {
183
+ console.error('Erreur lors de l\'enregistrement de la réponse du bot:', error);
184
+ }
185
+ };
186
+
187
+ const handleLoginSuccess = () => {
188
+ // Récupérer le nom d'utilisateur stocké par le composant Login
189
+ const storedUserName = localStorage.getItem('userName');
190
+ setUserName(storedUserName);
191
+ setIsAuthenticated(true);
192
+ setPage("chat");
193
+
194
+ // Charger les conversations de l'utilisateur
195
+ fetchConversations();
196
+ };
197
+
198
+ const handleLogout = async () => {
199
+ try {
200
+ // Appeler l'API de déconnexion
201
+ await fetch('http://localhost:7860/api/logout', {
202
+ method: 'POST',
203
+ credentials: 'include',
204
+ });
205
+
206
+ // Nettoyer le stockage local
207
+ localStorage.removeItem('userName');
208
+ localStorage.removeItem('userId');
209
+
210
+ // Réinitialiser l'état
211
+ setIsAuthenticated(false);
212
+ setUserName('');
213
+ setConversations([]);
214
+ setMessages([]);
215
+ setActiveConversationId(null);
216
+ setPage("login");
217
+ } catch (error) {
218
+ console.error("Erreur lors de la déconnexion:", error);
219
+ }
220
+ };
221
+
222
+ return (
223
+ <div className={`App ${isCollapsed ? 'panel-collapsed' : ''}`}>
224
+ {page === "chat" && (
225
+ <Panel
226
+ conversations={conversations}
227
+ setConversations={setConversations}
228
+ activeConversationId={activeConversationId}
229
+ setActiveConversationId={setActiveConversationId}
230
+ onNewChat={handleNewChat}
231
+ onToggleCollapse={toggleCollapse}
232
+ isCollapsed={isCollapsed}
233
+ userName={userName}
234
+ onLogout={handleLogout}
235
+ />
236
+ )}
237
+
238
+ <div className="main-content">
239
+ {isCollapsed && page === "chat" && (
240
+ <button className="collapse-button-main" onClick={toggleCollapse}>
241
+ <span className="material-icons">
242
+ <svg
243
+ fill="#FFFF"
244
+ width="20"
245
+ height="20"
246
+ viewBox="0 0 32 32"
247
+ xmlns="http://www.w3.org/2000/svg"
248
+ >
249
+ <defs>
250
+ <style>{`.cls-1{fill:none;}`}</style>
251
+ </defs>
252
+ <title>open-panel--solid--left</title>
253
+ <path d="M28,4H4A2,2,0,0,0,2,6V26a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V6A2,2,0,0,0,28,4Zm0,22H12V6H28Z" />
254
+ <rect
255
+ id="_Transparent_Rectangle_"
256
+ data-name="<Transparent Rectangle>"
257
+ className="cls-1"
258
+ width="20"
259
+ height="20"
260
+ />
261
+ </svg>
262
+ </span>
263
+ </button>
264
+ )}
265
+
266
+ {page === "chat" &&
267
+ <ChatInterface
268
+ messages={messages}
269
+ setMessages={setMessages}
270
+ onMessageSent={handleMessageSent}
271
+ activeConversationId={activeConversationId}
272
+ saveBotResponse={saveBotResponse}
273
+ userName={userName}
274
+ toLogin={handleLogout}
275
+ />
276
+ }
277
+ {page === "login" && <Login toSignin={() => setPage("signin")} onLoginSuccess={handleLoginSuccess}/>}
278
+ {page === "signin" && <Signin toLogin={() => setPage("login")}/>}
279
+ </div>
280
+ </div>
281
+ );
282
+ }
283
+
284
  export default App;