vineelagampa TheFrogGod commited on
Commit
2d9266b
·
verified ·
1 Parent(s): c095422

Second Changes of ChatBot (#25)

Browse files

- Second Changes of ChatBot (4f5622ae8b9a8ffe00729e9174605873e974d2eb)


Co-authored-by: Aanya Choudhary <TheFrogGod@users.noreply.huggingface.co>

Files changed (1) hide show
  1. web/past_data.html +251 -105
web/past_data.html CHANGED
@@ -4,6 +4,7 @@
4
  <meta charset="UTF-8" />
5
  <title>Past Analyzes - CTRL + ALT + HEAL</title>
6
  <script src="https://cdn.tailwindcss.com"></script>
 
7
  <link rel="stylesheet" href="style.css" />
8
  </head>
9
  <body class="bg-[#F7F8F9] min-h-screen">
@@ -11,11 +12,14 @@
11
  class="fixed top-0 left-0 w-full z-50 backdrop-blur-md bg-white/20 border-b border-white/30 shadow-md"
12
  >
13
  <div class="flex justify-between items-center w-full px-6 py-4">
 
14
  <a
15
  href="index.html"
16
  class="text-2xl font-bold text-black hover:text-[var(--tropical-indigo)] transition"
17
- >CTRL + ALT + HEAL</a
18
  >
 
 
 
19
  <ul class="hidden md:flex space-x-6 font-medium text-gray-800">
20
  <li><a href="index.html" class="nav-link">Home</a></li>
21
  <li><a href="profile.html" class="nav-link">Profile</a></li>
@@ -25,6 +29,8 @@
25
  <a href="login.html" class="nav-link">Login</a>
26
  </li>
27
  </ul>
 
 
28
  <button
29
  id="hamburger"
30
  class="md:hidden text-[var(--latte-cream)] text-2xl"
@@ -32,6 +38,8 @@
32
 
33
  </button>
34
  </div>
 
 
35
  <ul
36
  id="mobile-menu"
37
  class="hidden flex-col space-y-4 bg-white/30 backdrop-blur-lg border border-white/20 rounded-xl shadow-lg mt-2 p-4 mx-6 md:hidden"
@@ -76,10 +84,13 @@
76
 
77
  <main class="max-w-4xl mx-auto px-4 pt-24 text-gray-800">
78
  <div class="bg-white border border-gray-200 rounded-lg p-6 shadow mb-6">
79
- <h2 class="text-xl font-semibold mb-4">Your Past Analyzes</h2>
 
 
80
  <p id="auth-status" class="text-sm text-gray-500 mb-6">
81
  Checking sign-in status…
82
  </p>
 
83
  <div id="recs-container" class="space-y-4">
84
  <p class="text-sm text-gray-500">
85
  Sign in to view your saved analyzes.
@@ -87,7 +98,7 @@
87
  </div>
88
  </div>
89
  </main>
90
-
91
  <!-- Floating Chat Button -->
92
  <button
93
  id="chat-toggle"
@@ -134,12 +145,6 @@
134
  </script>
135
 
136
  <script type="module">
137
- import { initializeApp } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-app.js";
138
- import {
139
- getAuth,
140
- onAuthStateChanged,
141
- signOut,
142
- } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-auth.js";
143
  import {
144
  getFirestore,
145
  collection,
@@ -147,9 +152,15 @@
147
  orderBy,
148
  getDocs,
149
  } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-firestore.js";
 
 
 
 
 
 
150
 
151
  const firebaseConfig = {
152
- apiKey: "AIzaSyDNXm6ewXWMdIIAyC0q83ZspBfwmP30UJQ",
153
  authDomain: "appchallenge-c8fe3.firebaseapp.com",
154
  projectId: "appchallenge-c8fe3",
155
  storageBucket: "appchallenge-c8fe3.firebasestorage.app",
@@ -161,13 +172,10 @@
161
  const app = initializeApp(firebaseConfig);
162
  const auth = getAuth(app);
163
  const db = getFirestore(app);
164
-
165
- const statusEl = document.getElementById("auth-status");
166
- const recsEl = document.getElementById("recs-container");
167
-
168
  window.chatContext = null;
169
  window.setChatContextFromId = function (id) {
170
- const pre = document.querySelector(`#content-${id} pre`);
171
  window.chatContext = pre ? pre.textContent.trim() : null;
172
  const chatOutput = document.getElementById("chat-output");
173
  if (chatOutput) {
@@ -175,128 +183,266 @@
175
  chatOutput.scrollTop = chatOutput.scrollHeight;
176
  }
177
  };
178
-
179
- function toggleOCR(id) {
180
- const content = document.getElementById(`content-${id}`);
181
- const arrow = document.getElementById(`arrow-${id}`);
182
- if (content.style.maxHeight && content.style.maxHeight !== "0px") {
183
- content.style.maxHeight = "0px";
184
- arrow.style.transform = "rotate(0deg)";
185
  } else {
186
- content.style.maxHeight = content.scrollHeight + "px";
187
- arrow.style.transform = "rotate(90deg)";
188
  }
189
- }
190
 
191
- function renderAnalysisSafe(item) {
192
- console.log("Rendering report:", item);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
 
194
- const createdAt =
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
  item.createdAt && item.createdAt.toDate
196
  ? item.createdAt.toDate().toLocaleString()
197
- : "Date unknown";
198
-
199
  const uniqueId = `ocr-${Date.now()}-${Math.random()
200
  .toString(36)
201
- .substr(2, 9)}`;
202
- const ocrText = item.ocr_text || "No OCR text available.";
203
- const reportDate = item.reportDate || "N/A";
204
-
205
- const anomalies = Array.isArray(item.Detected_Anomalies)
206
- ? item.Detected_Anomalies
207
- : [];
208
 
209
  return `
210
- <div class="bg-white border border-gray-200 rounded-lg p-4 shadow">
211
- <div class="flex justify-between mb-2">
212
- <div class="text-xs text-gray-500">${createdAt}</div>
 
 
 
 
 
 
 
 
213
  </div>
214
-
215
- <div class="mb-4">
216
- <div class="font-semibold text-green-700 cursor-pointer hover:text-green-800 py-2 flex justify-between items-center"
217
- onclick="toggleOCR('${uniqueId}')">
218
- <span>Report: ${reportDate}</span>
219
- <span class="arrow transition-transform duration-300" id="arrow-${uniqueId}">▶</span>
220
- </div>
221
- <div class="ocr-content overflow-hidden transition-all duration-300 max-h-0" id="content-${uniqueId}">
222
- <div class="mt-2 p-3 bg-gray-50 rounded border">
223
- <pre class="whitespace-pre-wrap text-sm text-gray-700">${ocrText}</pre>
224
- </div>
225
  </div>
226
  </div>
227
-
228
- ${anomalies
229
- .map(
230
- (r, i) => `
231
- <div class="border-t border-gray-200 pt-2 mt-2">
232
- <div class="font-medium">Finding ${i + 1}: ${
233
- r.findings || "N/A"
234
- }</div>
235
- <div class="text-sm text-gray-600">Severity: ${
236
- r.severity || "N/A"
237
- }</div>
238
- <div class="text-sm text-gray-600">Recommendations: ${(
239
- r.recommendations || []
240
- ).join(", ")}</div>
241
- </div>
242
- `
243
- )
244
- .join("")}
245
-
246
- <button onclick="setChatContextFromId('${uniqueId}')"
247
- class="mt-3 px-4 py-2 bg-[var(--tropical-indigo)] text-white rounded hover:bg-indigo-600">
248
- Chat about this report
249
- </button>
250
  </div>
251
- `;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
  }
253
 
254
  onAuthStateChanged(auth, async (user) => {
255
- const authNavItem = document.getElementById("authNavItem");
256
  if (user) {
257
- authNavItem.innerHTML =
258
- '<button onclick="logout()" class="hover:text-[#6B9080] text-red-600">Logout</button>';
259
  statusEl.textContent = `Signed in as ${user.email || user.uid}`;
260
 
261
- try {
262
- const q = query(
263
- collection(db, "users", user.uid, "analyses"),
264
- orderBy("createdAt", "desc")
265
- );
266
- const snap = await getDocs(q);
267
-
268
- if (snap.empty) {
 
 
 
 
 
 
 
 
 
 
 
269
  recsEl.innerHTML =
270
  '<p class="text-sm text-gray-500">No saved analyses yet.</p>';
271
- return;
272
  }
 
 
273
 
 
 
 
 
 
 
 
 
 
 
274
  const analyses = [];
275
- snap.forEach((doc) => analyses.push({ id: doc.id, ...doc.data() }));
276
- recsEl.innerHTML = analyses.map(renderAnalysisSafe).join("");
277
- } catch (err) {
278
- console.error("Error fetching reports:", err);
279
- recsEl.innerHTML =
280
- '<p class="text-sm text-red-500">Error loading analyses.</p>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
281
  }
 
 
 
 
282
  } else {
283
- authNavItem.innerHTML =
284
- '<a href="login.html" class="hover:text-[#6B9080]">Login</a>';
285
  statusEl.textContent = "Not signed in.";
286
  recsEl.innerHTML =
287
  '<p class="text-sm text-gray-500">Please sign in to see your analyses.</p>';
288
  }
289
- });
 
 
290
 
291
- window.logout = async () => {
292
- try {
293
- await signOut(auth);
294
- localStorage.clear();
295
- window.location.href = "login.html";
296
- } catch (err) {
297
- console.error("Error signing out:", err);
298
- }
299
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
300
  </script>
301
  </body>
302
  </html>
 
4
  <meta charset="UTF-8" />
5
  <title>Past Analyzes - CTRL + ALT + HEAL</title>
6
  <script src="https://cdn.tailwindcss.com"></script>
7
+ <script src="script.js"></script>
8
  <link rel="stylesheet" href="style.css" />
9
  </head>
10
  <body class="bg-[#F7F8F9] min-h-screen">
 
12
  class="fixed top-0 left-0 w-full z-50 backdrop-blur-md bg-white/20 border-b border-white/30 shadow-md"
13
  >
14
  <div class="flex justify-between items-center w-full px-6 py-4">
15
+ <!-- Logo -->
16
  <a
17
  href="index.html"
18
  class="text-2xl font-bold text-black hover:text-[var(--tropical-indigo)] transition"
 
19
  >
20
+ CTRL + ALT + HEAL
21
+ </a>
22
+
23
  <ul class="hidden md:flex space-x-6 font-medium text-gray-800">
24
  <li><a href="index.html" class="nav-link">Home</a></li>
25
  <li><a href="profile.html" class="nav-link">Profile</a></li>
 
29
  <a href="login.html" class="nav-link">Login</a>
30
  </li>
31
  </ul>
32
+
33
+ <!-- Hamburger Menu -->
34
  <button
35
  id="hamburger"
36
  class="md:hidden text-[var(--latte-cream)] text-2xl"
 
38
 
39
  </button>
40
  </div>
41
+
42
+ <!-- Mobile Menu -->
43
  <ul
44
  id="mobile-menu"
45
  class="hidden flex-col space-y-4 bg-white/30 backdrop-blur-lg border border-white/20 rounded-xl shadow-lg mt-2 p-4 mx-6 md:hidden"
 
84
 
85
  <main class="max-w-4xl mx-auto px-4 pt-24 text-gray-800">
86
  <div class="bg-white border border-gray-200 rounded-lg p-6 shadow mb-6">
87
+ <h2 class="text-xl font-semibold mb-4">
88
+ Your Past Analyzes
89
+ </h1>
90
  <p id="auth-status" class="text-sm text-gray-500 mb-6">
91
  Checking sign-in status…
92
  </p>
93
+
94
  <div id="recs-container" class="space-y-4">
95
  <p class="text-sm text-gray-500">
96
  Sign in to view your saved analyzes.
 
98
  </div>
99
  </div>
100
  </main>
101
+
102
  <!-- Floating Chat Button -->
103
  <button
104
  id="chat-toggle"
 
145
  </script>
146
 
147
  <script type="module">
 
 
 
 
 
 
148
  import {
149
  getFirestore,
150
  collection,
 
152
  orderBy,
153
  getDocs,
154
  } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-firestore.js";
155
+ import { initializeApp } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-app.js";
156
+ import {
157
+ getAuth,
158
+ onAuthStateChanged,
159
+ signOut,
160
+ } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-auth.js";
161
 
162
  const firebaseConfig = {
163
+ apiKey: "AIzaSyAKWstCc7HqMgV8DmH2Sy6QwUP3JvZxu9g",
164
  authDomain: "appchallenge-c8fe3.firebaseapp.com",
165
  projectId: "appchallenge-c8fe3",
166
  storageBucket: "appchallenge-c8fe3.firebasestorage.app",
 
172
  const app = initializeApp(firebaseConfig);
173
  const auth = getAuth(app);
174
  const db = getFirestore(app);
175
+ window.currentUser = null;
 
 
 
176
  window.chatContext = null;
177
  window.setChatContextFromId = function (id) {
178
+ const pre = document.querySelector(`#content-${id} .ocr-pre`);
179
  window.chatContext = pre ? pre.textContent.trim() : null;
180
  const chatOutput = document.getElementById("chat-output");
181
  if (chatOutput) {
 
183
  chatOutput.scrollTop = chatOutput.scrollHeight;
184
  }
185
  };
186
+ onAuthStateChanged(auth, (user) => {
187
+ const authNavItem = document.getElementById("authNavItem");
188
+ if (user) {
189
+ authNavItem.innerHTML =
190
+ '<button onclick="logout()" class="hover:text-[#6B9080] text-red-600">Logout</button>';
 
 
191
  } else {
192
+ authNavItem.innerHTML =
193
+ '<a href="login.html" class="hover:text-[#6B9080]">Login</a>';
194
  }
195
+ });
196
 
197
+ window.logout = async () => {
198
+ try {
199
+ await signOut(auth);
200
+ localStorage.clear();
201
+ window.location.href = "login.html";
202
+ } catch (error) {
203
+ console.error("Error signing out:", error);
204
+ }
205
+ };
206
+
207
+ const statusEl = document.getElementById("auth-status");
208
+ const recsEl = document.getElementById("recs-container");
209
+ async function sendReportToBackend(report, userId) {
210
+ try {
211
+ const response = await fetch("http://localhost:9000/save_report/", {
212
+ method: "POST",
213
+ headers: {
214
+ "Content-Type": "application/json",
215
+ },
216
+ body: JSON.stringify({
217
+ ...report,
218
+ user_id: userId,
219
+ sync_timestamp: new Date().toISOString(),
220
+ }),
221
+ });
222
 
223
+ if (!response.ok) {
224
+ console.warn(
225
+ `Failed to sync report to backend: ${response.status}`
226
+ );
227
+ } else {
228
+ console.log("Report successfully synced to backend");
229
+ }
230
+ } catch (error) {
231
+ console.warn(
232
+ "Error syncing report to backend (continuing anyway):",
233
+ error
234
+ );
235
+ }
236
+ }
237
+
238
+ function renderAnalysisWithCustomToggle(item) {
239
+ const d =
240
  item.createdAt && item.createdAt.toDate
241
  ? item.createdAt.toDate().toLocaleString()
242
+ : "";
 
243
  const uniqueId = `ocr-${Date.now()}-${Math.random()
244
  .toString(36)
245
+ .substr(2, 9)}`; // Generate unique ID
 
 
 
 
 
 
246
 
247
  return `
248
+ <div class="bg-white border border-gray-200 rounded-lg p-4 shadow">
249
+ <div class="flex justify-between mb-2">
250
+ <div class="text-xs text-gray-500">${d}</div>
251
+ </div>
252
+
253
+ <!-- Collapsible OCR Text Section with Custom Toggle -->
254
+ <div class="mb-4">
255
+ <div class="font-semibold text-green-700 cursor-pointer hover:text-green-800 py-2 flex justify-between items-center"
256
+ onclick="toggleOCR('${uniqueId}')">
257
+ <span>Report ${item.reportDate || "N/A"}</span>
258
+ <span class="arrow transition-transform duration-300" id="arrow-${uniqueId}">▶</span>
259
  </div>
260
+ <div class="ocr-content overflow-hidden transition-all duration-300 max-h-0" id="content-${uniqueId}">
261
+ <div class="mt-2 p-3 bg-gray-50 rounded border">
262
+ <pre class="whitespace-pre-wrap text-sm text-gray-700">${
263
+ item.ocr_text || ""
264
+ }</pre>
 
 
 
 
 
 
265
  </div>
266
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
  </div>
268
+
269
+ <!-- Findings Section -->
270
+ ${(Array.isArray(item.Detected_Anomolies)
271
+ ? item.Detected_Anomolies
272
+ : []
273
+ )
274
+ .map(
275
+ (r, i) => `
276
+ <div class="border-t border-gray-200 pt-2 mt-2">
277
+ <div class="font-medium">Finding ${i + 1}: ${
278
+ r.findings || ""
279
+ }</div>
280
+ <div class="text-sm text-gray-600">Severity: ${
281
+ r.severity || ""
282
+ }</div>
283
+ <div class="text-sm text-gray-600">Recommendations: ${(
284
+ r.recommendations || []
285
+ ).join(", ")}</div>
286
+ </div>
287
+ `
288
+ )
289
+ .join("")}
290
+ </div>
291
+ `;
292
+ }
293
+
294
+ function toggleOCR(id) {
295
+ const content = document.getElementById(`content-${id}`);
296
+ const arrow = document.getElementById(`arrow-${id}`);
297
+
298
+ if (content.style.maxHeight && content.style.maxHeight !== "0px") {
299
+ content.style.maxHeight = "0px";
300
+ arrow.style.transform = "rotate(0deg)";
301
+ } else {
302
+ content.style.maxHeight = content.scrollHeight + "px";
303
+ arrow.style.transform = "rotate(90deg)";
304
+ }
305
  }
306
 
307
  onAuthStateChanged(auth, async (user) => {
 
308
  if (user) {
 
 
309
  statusEl.textContent = `Signed in as ${user.email || user.uid}`;
310
 
311
+ async function getPastReports() {
312
+ try {
313
+ const url = api("reports/", { user_id: user.email });
314
+ const response = await fetch(url, {
315
+ method: "GET",
316
+ headers: {
317
+ "Content-Type": "application/json",
318
+ },
319
+ });
320
+ if (!response.ok) {
321
+ throw new Error(`HTTP error! status: ${response.status}`);
322
+ }
323
+ const data = await response.json();
324
+ console.log("Report successfully sent to backend:", data);
325
+ recsEl.innerHTML = data
326
+ .map((doc) => renderAnalysisWithCustomToggle(doc))
327
+ .join("");
328
+ } catch (error) {
329
+ console.error("Error sending report to backend:", error);
330
  recsEl.innerHTML =
331
  '<p class="text-sm text-gray-500">No saved analyses yet.</p>';
 
332
  }
333
+ }
334
+ getPastReports();
335
 
336
+ /* try {
337
+ const q = query(
338
+ collection(db, "users", user.uid, "analyses"),
339
+ orderBy("createdAt", "desc")
340
+ );
341
+ const snap = await getDocs(q);
342
+
343
+ if (snap.empty) {
344
+ recsEl.innerHTML = '<p class="text-sm text-gray-500">No saved analyses yet.</p>';
345
+ } else {
346
  const analyses = [];
347
+
348
+ snap.forEach(doc => {
349
+ const data = { id: doc.id, ...doc.data() };
350
+ analyses.push(data);
351
+
352
+ sendReportToBackend(data, user.uid);
353
+ });
354
+
355
+ recsEl.innerHTML = analyses.map(doc => renderAnalysis(doc)).join("");
356
+
357
+ const syncStatus = document.createElement('p');
358
+ syncStatus.className = 'text-xs text-blue-500 mt-2';
359
+ syncStatus.textContent = `Syncing ${analyses.length} reports to backend...`;
360
+ recsEl.appendChild(syncStatus);
361
+
362
+ setTimeout(() => {
363
+ if (syncStatus.parentNode) {
364
+ syncStatus.remove();
365
+ }
366
+ }, 3000);
367
  }
368
+ } catch (error) {
369
+ console.error('Error fetching analyses:', error);
370
+ recsEl.innerHTML = '<p class="text-sm text-red-500">Error loading analyses.</p>';
371
+ }*/
372
  } else {
 
 
373
  statusEl.textContent = "Not signed in.";
374
  recsEl.innerHTML =
375
  '<p class="text-sm text-gray-500">Please sign in to see your analyses.</p>';
376
  }
377
+ document.getElementById("ask-btn").onclick = async () => {
378
+ const q = document.getElementById("user-question").value.trim();
379
+ if (!q) return;
380
 
381
+ // require a selected report as context
382
+ if (!window.chatContext) {
383
+ alert(
384
+ "Please click 'Chat about this report' on a saved report first to set context."
385
+ );
386
+ return;
387
+ }
388
+
389
+ document.getElementById("ask-btn").onclick = async () => {
390
+ const q = document.getElementById("user-question").value.trim();
391
+ if (!q) return;
392
+
393
+ // require a selected report as context
394
+ if (!window.chatContext) {
395
+ alert(
396
+ "Please click 'Chat about this report' on a saved report first to set context."
397
+ );
398
+ return;
399
+ }
400
+
401
+ const chat = document.getElementById("chat-output");
402
+ chat.innerHTML += `<p><strong>You:</strong> ${q}</p>`;
403
+ chat.scrollTop = chat.scrollHeight;
404
+
405
+ chat.innerHTML += `<p><strong>Chatbot:</strong> <em>Thinking...</em></p>`;
406
+ chat.scrollTop = chat.scrollHeight;
407
+
408
+ try {
409
+ const response = await fetch(api("chat/"), {
410
+ method: "POST",
411
+ headers: {
412
+ "Content-Type": "application/json",
413
+ },
414
+ body: JSON.stringify({
415
+ question: q,
416
+ user_id:
417
+ auth && auth.currentUser
418
+ ? auth.currentUser.uid || auth.currentUser.email
419
+ : "anonymous",
420
+ context: window.chatContext,
421
+ }),
422
+ });
423
+
424
+ if (!response.ok) {
425
+ throw new Error(`HTTP error! status: ${response.status}`);
426
+ }
427
+
428
+ const data = await response.json();
429
+
430
+ //now addign acctual reposnse
431
+ const messages = chat.querySelectorAll("p");
432
+ const lastMessage = messages[messages.length - 1];
433
+ lastMessage.innerHTML = `<strong>Chatbot:</strong> ${data.answer}`;
434
+ } catch (error) {
435
+ console.error("Error:", error);
436
+ const messages = chat.querySelectorAll("p");
437
+ const lastMessage = messages[messages.length - 1];
438
+ lastMessage.innerHTML = `<strong>Chatbot:</strong> Sorry, I encountered an error: ${error.message}`;
439
+ }
440
+
441
+ document.getElementById("user-question").value = "";
442
+ chat.scrollTop = chat.scrollHeight;
443
+ };
444
+ };
445
+ });
446
  </script>
447
  </body>
448
  </html>