Jemayz commited on
Commit
25a747f
·
verified ·
1 Parent(s): 2d375fe

Upload medical_page.html

Browse files
Files changed (1) hide show
  1. templates/medical_page.html +507 -0
templates/medical_page.html ADDED
@@ -0,0 +1,507 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en" class="">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>MultiDom RAG</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link
9
+ rel="stylesheet"
10
+ href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
11
+ />
12
+ <script>
13
+ tailwind.config = {
14
+ darkMode: "class",
15
+ theme: {
16
+ extend: {
17
+ colors: {
18
+ primary: { dark: "#579be8", light: "#3B82F6" },
19
+ secondary: { dark: "#9F1239", light: "#EC4899" },
20
+ accent: { dark: "#047857", light: "#10B981" },
21
+ dark: { 900: "#0F172A", 800: "#1E293B", 700: "#334155" },
22
+ },
23
+ fontFamily: { sans: ["Inter", "sans-serif"] },
24
+ animation: {
25
+ float: "float 6s ease-in-out infinite",
26
+ "spin-slow": "spin 10s linear infinite",
27
+ },
28
+ keyframes: {
29
+ float: {
30
+ "0%, 100%": { transform: "translateY(0)" },
31
+ "50%": { transform: "translateY(-10px)" },
32
+ },
33
+ },
34
+ },
35
+ },
36
+ };
37
+ </script>
38
+ <style>
39
+ @import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap");
40
+ body {
41
+ font-family: "Inter", sans-serif;
42
+ scroll-behavior: smooth;
43
+ }
44
+ details > summary {
45
+ list-style: none;
46
+ }
47
+ details > summary::-webkit-details-marker {
48
+ display: none;
49
+ }
50
+ details > summary::before {
51
+ content: "\f078";
52
+ font-family: "Font Awesome 6 Free";
53
+ font-weight: 900;
54
+ margin-right: 0.5rem;
55
+ display: inline-block;
56
+ transition: transform 0.2s ease-in-out;
57
+ }
58
+ details[open] > summary::before {
59
+ transform: rotate(-180deg);
60
+ }
61
+ .scroll-progress {
62
+ position: fixed;
63
+ top: 0;
64
+ left: 0;
65
+ width: 0%;
66
+ height: 4px;
67
+ background: linear-gradient(90deg, #3b82f6, #ec4899, #10b981);
68
+ z-index: 1000;
69
+ transition: width 0.1s;
70
+ }
71
+ .ripple {
72
+ position: relative;
73
+ overflow: hidden;
74
+ }
75
+ .ripple-effect {
76
+ position: absolute;
77
+ border-radius: 50%;
78
+ background-color: rgba(255, 255, 255, 0.4);
79
+ transform: scale(0);
80
+ animation: ripple 0.6s linear;
81
+ pointer-events: none;
82
+ }
83
+ @keyframes ripple {
84
+ to {
85
+ transform: scale(4);
86
+ opacity: 0;
87
+ }
88
+ }
89
+ </style>
90
+ </head>
91
+ <body
92
+ class="bg-gray-50 dark:bg-dark-900 text-gray-800 dark:text-gray-200"
93
+ id="medical_page"
94
+ >
95
+ <div class="scroll-progress"></div>
96
+ <nav class="bg-white dark:bg-dark-800 shadow-lg sticky top-0 z-40">
97
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
98
+ <div class="flex justify-between h-16 items-center">
99
+ <div class="flex items-center">
100
+ <i
101
+ class="fa-solid fa-file-medical text-primary-light dark:text-primary-dark text-2xl mr-5"
102
+ ></i>
103
+ <span
104
+ class="text-2xl font-bold text-primary-light dark:text-primary-dark"
105
+ >MultiDom RAG</span
106
+ >
107
+ </div>
108
+ <div class="hidden sm:flex flex-1 justify-center space-x-8">
109
+ <a
110
+ href="{{ url_for('homePage') }}"
111
+ class="border-transparent text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 inline-flex items-center px-1 pt-1 border-b-2 text-xl hover:animate-pulse"
112
+ >Home</a
113
+ >
114
+ <div class="relative group">
115
+ <button
116
+ class="border-primary-light dark:border-primary-dark text-gray-900 dark:text-white inline-flex items-center px-1 pt-1 border-b-2 text-xl border-b-2"
117
+ >
118
+ Demo
119
+ <svg
120
+ class="w-4 h-4 ml-1"
121
+ fill="none"
122
+ stroke="currentColor"
123
+ viewBox="0 0 24 24"
124
+ >
125
+ <path
126
+ stroke-linecap="round"
127
+ stroke-linejoin="round"
128
+ stroke-width="2"
129
+ d="M19 9l-7 7-7-7"
130
+ ></path>
131
+ </svg>
132
+ </button>
133
+ <div
134
+ class="absolute left-1/2 transform -translate-x-1/2 mt-2 w-52 rounded-md shadow-lg bg-white dark:bg-dark-700 ring-1 ring-black ring-opacity-5 opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 z-50"
135
+ >
136
+ <div class="py-1">
137
+ <a
138
+ href="{{ url_for('medical_page') }}"
139
+ class="block px-4 py-2 text-lg text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-dark-600 font-semibold"
140
+ >Medical (Active)</a
141
+ >
142
+ <a
143
+ href="{{ url_for('islamic_page') }}"
144
+ class="block px-4 py-2 text-lg text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-dark-600"
145
+ >Islamic</a
146
+ >
147
+ <a
148
+ href="{{ url_for('insurance_page') }}"
149
+ class="block px-4 py-2 text-lg text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-dark-600"
150
+ >Insurance</a
151
+ >
152
+ </div>
153
+ </div>
154
+ </div>
155
+ <a
156
+ href="{{ url_for('about') }}"
157
+ class="border-transparent text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 inline-flex items-center px-1 pt-1 border-b-2 text-xl hover:animate-pulse"
158
+ >About</a
159
+ >
160
+ </div>
161
+ <div class="hidden sm:flex items-center space-x-4">
162
+ <a
163
+ href="{{ url_for('clear_medical_chat') }}"
164
+ class="p-2 text-red-500 dark:text-red-400 hover:bg-red-100 dark:hover:bg-red-700 rounded-full transition-colors"
165
+ title="Clear Chat History"
166
+ >
167
+ <i class="fas fa-trash-alt"></i>
168
+ </a>
169
+ <button
170
+ id="theme-toggle"
171
+ type="button"
172
+ class="p-1 rounded-full text-gray-400 hover:text-gray-500 dark:hover:text-gray-300 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-light dark:focus:ring-primary-dark ripple"
173
+ >
174
+ <i class="fas fa-moon dark:hidden"></i
175
+ ><i class="fas fa-sun hidden dark:block"></i>
176
+ </button>
177
+ <a
178
+ class="ml-4 bg-primary-light dark:bg-primary-dark text-white text-md px-6 py-2 rounded-md font-medium"
179
+ >Medical</a
180
+ >
181
+ </div>
182
+ </div>
183
+ </div>
184
+ </nav>
185
+
186
+ <main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
187
+ <div
188
+ id="chat-history"
189
+ class="max-w-5xl mx-auto px-4 py-8 pt-12 pb-40 space-y-8"
190
+ >
191
+ {% if not history %}
192
+ <div class="text-center py-10">
193
+ <i
194
+ class="fa-solid fa-suitcase-medical text-primary-light dark:text-primary-dark text-6xl mb-4 animate-float"
195
+ ></i>
196
+ <h2 class="text-3xl font-bold text-gray-800 dark:text-white mb-2">
197
+ Medical Assistant (RAG & Swarm)
198
+ </h2>
199
+ <p class="text-lg text-gray-500 dark:text-gray-400">
200
+ Ask a medical question, upload a medical image, or upload a document
201
+ for swarm analysis.
202
+ </p>
203
+ </div>
204
+ {% endif %} {% for chat in history[:-1] %} {% if chat.type == 'human' %}
205
+ <div class="flex justify-end w-full">
206
+ <div
207
+ class="bg-primary-light text-white p-4 rounded-xl shadow-md max-w-2xl"
208
+ >
209
+ <p>
210
+ {{ chat.content if chat.content is string else
211
+ chat.content.content }}
212
+ </p>
213
+ {% if chat.content and '[Document Uploaded]' in chat.content %}<span
214
+ class="text-xs text-blue-200 pt-2 block"
215
+ ><i class="fas fa-file-alt mr-1"></i> Document Uploaded</span
216
+ >{% endif %}
217
+ </div>
218
+ </div>
219
+
220
+ {% elif chat.type == 'ai' %}
221
+ <div class="w-full max-w-2xl space-y-4">
222
+ {% set answer_text = chat.content %}
223
+ <div>
224
+ <div
225
+ class="flex items-center text-sm text-gray-800 dark:text-white mb-2 ml-1"
226
+ >
227
+ <i
228
+ class="fa-solid fa-file-medical text-primary-light dark:text-primary-dark mr-2"
229
+ ></i>
230
+ <strong class="font-semibold">MultiDom RAG</strong>
231
+ </div>
232
+ <div
233
+ class="bg-white dark:bg-dark-700 border dark:border-dark-600 rounded-xl shadow-md p-5"
234
+ >
235
+ <p
236
+ class="text-gray-800 dark:text-white whitespace-pre-wrap text-left"
237
+ >
238
+ {{ answer_text|safe }}
239
+ </p>
240
+ </div>
241
+ </div>
242
+ </div>
243
+ {% endif %} {% endfor %} {% if answer %}
244
+ <div class="w-full max-w-2xl space-y-4">
245
+ <details class="w-full">
246
+ <summary
247
+ class="flex items-center text-sm text-gray-500 dark:text-gray-400 cursor-pointer mb-2 ml-1"
248
+ >
249
+ <i
250
+ class="fas fa-atom mr-2 animate-spin-slow text-primary-light inline-block"
251
+ ></i>
252
+ <span>Thinking... view source & thoughts...</span>
253
+ </summary>
254
+ <div
255
+ class="bg-gray-100 dark:bg-dark-800 border dark:border-dark-700 rounded-xl shadow p-4 space-y-4 ml-1 mt-2"
256
+ >
257
+ {% if source %}
258
+ <div>
259
+ <h4 class="font-semibold text-gray-700 dark:text-gray-300">
260
+ Source:
261
+ </h4>
262
+ <p class="text-sm text-gray-600 dark:text-gray-400">
263
+ {{ source }}
264
+ </p>
265
+ </div>
266
+ {% endif %} {% if thoughts %}
267
+ <details>
268
+ <summary
269
+ class="font-semibold text-medium text-gray-700 dark:text-gray-400 cursor-pointer"
270
+ >
271
+ View Agent Thoughts (ReAct Process):
272
+ </summary>
273
+ <p
274
+ class="text-sm mt-2 p-2 bg-gray-200 dark:bg-dark-900 rounded whitespace-pre-line"
275
+ >
276
+ {{ thoughts | safe }}
277
+ </p>
278
+ </details>
279
+ {% endif %} {% if validation %}
280
+ <div>
281
+ <h4 class="font-semibold text-gray-700 dark:text-gray-300">
282
+ Validation:
283
+ </h4>
284
+ <p class="text-sm text-gray-600 dark:text-gray-400">
285
+ {{ validation }}
286
+ </p>
287
+ </div>
288
+ {% endif %}
289
+ </div>
290
+ </details>
291
+
292
+ <div>
293
+ <div
294
+ class="flex items-center text-sm text-gray-800 dark:text-white mb-2 ml-1"
295
+ >
296
+ <i
297
+ class="fa-solid fa-file-medical text-primary-light dark:text-primary-dark mr-2"
298
+ ></i>
299
+ <strong class="font-semibold">MultiDom RAG</strong>
300
+ </div>
301
+ <div
302
+ class="bg-white dark:bg-dark-700 border dark:border-dark-600 rounded-xl shadow-md p-5"
303
+ >
304
+ <p
305
+ class="text-gray-800 dark:text-white text-left whitespace-pre-line"
306
+ >
307
+ {{ answer|safe }}
308
+ </p>
309
+ </div>
310
+ </div>
311
+ </div>
312
+ {% endif %}
313
+ </div>
314
+ </main>
315
+
316
+ <footer
317
+ class="fixed bottom-0 left-0 w-full z-20 bg-white/80 dark:bg-dark-900/80 backdrop-blur-sm border-t dark:border-dark-700"
318
+ >
319
+ <form
320
+ method="POST"
321
+ action="{{ url_for('medical_page') }}"
322
+ enctype="multipart/form-data"
323
+ class="relative max-w-5xl mx-auto flex items-center space-x-3 p-4"
324
+ >
325
+ <div
326
+ id="upload-menu"
327
+ class="absolute bottom-20 left-0 w-52 bg-white dark:bg-dark-700 border dark:border-dark-600 rounded-lg shadow-lg py-2 z-10 hidden"
328
+ >
329
+ <button
330
+ type="button"
331
+ id="upload-image-btn"
332
+ class="w-full text-left px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-dark-600 flex items-center"
333
+ >
334
+ <i class="fas fa-image mr-3"></i> Upload Image
335
+ </button>
336
+ <button
337
+ type="button"
338
+ id="upload-doc-btn"
339
+ class="w-full text-left px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-dark-600 flex items-center"
340
+ >
341
+ <i class="fas fa-file-alt mr-3"></i> Upload Document
342
+ </button>
343
+ </div>
344
+ <button
345
+ type="button"
346
+ id="upload-toggle"
347
+ class="p-2 text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-dark-700 rounded-full transition-colors"
348
+ >
349
+ <i class="fas fa-plus text-xl"></i>
350
+ </button>
351
+ <input type="file" id="file-upload" name="image" class="hidden" />
352
+ <!-- Renamed to image/document to match Python-->
353
+ <input type="file" id="doc-upload" name="document" class="hidden" />
354
+ <!-- Added hidden doc input -->
355
+ <input
356
+ type="text"
357
+ id="query"
358
+ name="query"
359
+ required
360
+ class="flex-1 px-4 py-3 rounded-lg bg-gray-100 dark:bg-dark-700 border border-gray-300 dark:border-dark-600 focus:outline-none focus:ring-2 focus:ring-primary-light"
361
+ placeholder="Ask a medical question or include an upload..."
362
+ />
363
+ <span
364
+ id="file-name-display"
365
+ class="text-sm text-gray-500 dark:text-gray-400 truncate max-w-xs"
366
+ title=""
367
+ ></span>
368
+ <button
369
+ type="submit"
370
+ class="p-3 bg-primary-light hover:bg-primary-dark text-white rounded-full transition-colors shadow-lg hover:scale-105 transform ripple"
371
+ >
372
+ <i class="fas fa-paper-plane"></i>
373
+ </button>
374
+ </form>
375
+ </footer>
376
+
377
+ <script>
378
+ const themeToggle = document.getElementById("theme-toggle"),
379
+ html = document.documentElement;
380
+ themeToggle.addEventListener("click", () => {
381
+ html.classList.toggle("dark");
382
+ localStorage.setItem(
383
+ "theme",
384
+ html.classList.contains("dark") ? "dark" : "light"
385
+ );
386
+ });
387
+ if (
388
+ localStorage.getItem("theme") === "dark" ||
389
+ (!localStorage.getItem("theme") &&
390
+ window.matchMedia("(prefers-color-scheme: dark)").matches)
391
+ ) {
392
+ html.classList.add("dark");
393
+ }
394
+
395
+ document.addEventListener("DOMContentLoaded", () => {
396
+ window.addEventListener("scroll", () => {
397
+ const scrollTop =
398
+ document.documentElement.scrollTop || document.body.scrollTop;
399
+ const scrollHeight =
400
+ document.documentElement.scrollHeight -
401
+ document.documentElement.clientHeight;
402
+ const scrollProgress =
403
+ scrollHeight > 0 ? (scrollTop / scrollHeight) * 100 : 0;
404
+ const progressBar = document.querySelector(".scroll-progress");
405
+ if (progressBar) progressBar.style.width = scrollProgress + "%";
406
+ });
407
+ document.querySelectorAll(".ripple").forEach((button) => {
408
+ button.addEventListener("click", function (e) {
409
+ const rect = this.getBoundingClientRect(),
410
+ x = e.clientX - rect.left,
411
+ y = e.clientY - rect.top;
412
+ const ripple = document.createElement("span");
413
+ ripple.className = "ripple-effect";
414
+ ripple.style.left = x + "px";
415
+ ripple.style.top = y + "px";
416
+ this.appendChild(ripple);
417
+ setTimeout(() => {
418
+ ripple.remove();
419
+ }, 600);
420
+ });
421
+ });
422
+
423
+ // --- START OF UPLOAD LOGIC ---
424
+ const uploadToggle = document.getElementById("upload-toggle"),
425
+ uploadMenu = document.getElementById("upload-menu"),
426
+ uploadImageBtn = document.getElementById("upload-image-btn"),
427
+ uploadDocBtn = document.getElementById("upload-doc-btn"),
428
+ fileUploadInput = document.getElementById("file-upload"), // For images
429
+ docUploadInput = document.getElementById("doc-upload"), // For documents
430
+ fileNameDisplay = document.getElementById("file-name-display");
431
+
432
+ // Helper to clear both inputs
433
+ const clearFileInputs = () => {
434
+ fileUploadInput.value = null;
435
+ docUploadInput.value = null;
436
+ fileNameDisplay.textContent = "";
437
+ fileNameDisplay.title = "";
438
+ };
439
+
440
+ if (uploadToggle)
441
+ uploadToggle.addEventListener("click", (e) => {
442
+ e.stopPropagation();
443
+ uploadMenu.classList.toggle("hidden");
444
+ });
445
+
446
+ if (uploadImageBtn)
447
+ uploadImageBtn.addEventListener("click", () => {
448
+ clearFileInputs();
449
+ fileUploadInput.accept = "image/*";
450
+ fileUploadInput.click();
451
+ uploadMenu.classList.add("hidden");
452
+ });
453
+
454
+ if (uploadDocBtn)
455
+ uploadDocBtn.addEventListener("click", () => {
456
+ clearFileInputs();
457
+ docUploadInput.accept = ".pdf,.doc,.docx,.txt";
458
+ docUploadInput.click();
459
+ uploadMenu.classList.add("hidden");
460
+ });
461
+
462
+ // Event listener for image input
463
+ if (fileUploadInput)
464
+ fileUploadInput.addEventListener("change", () => {
465
+ const file = fileUploadInput.files[0];
466
+ if (file) {
467
+ fileNameDisplay.textContent = file.name;
468
+ fileNameDisplay.title = file.name;
469
+ docUploadInput.value = null; // Ensure the other input is cleared
470
+ }
471
+ });
472
+
473
+ // Event listener for document input
474
+ if (docUploadInput)
475
+ docUploadInput.addEventListener("change", () => {
476
+ const file = docUploadInput.files[0];
477
+ if (file) {
478
+ fileNameDisplay.textContent = file.name;
479
+ fileNameDisplay.title = file.name;
480
+ fileUploadInput.value = null; // Ensure the other input is cleared
481
+ }
482
+ });
483
+
484
+ document.addEventListener("click", (e) => {
485
+ if (
486
+ uploadMenu &&
487
+ !uploadMenu.classList.contains("hidden") &&
488
+ !uploadToggle.contains(e.target)
489
+ ) {
490
+ uploadMenu.classList.add("hidden");
491
+ }
492
+ });
493
+
494
+ // Scroll to bottom on load
495
+ setTimeout(() => {
496
+ const chatHistoryDiv = document.getElementById("chat-history");
497
+ if (chatHistoryDiv) {
498
+ window.scrollTo({
499
+ top: chatHistoryDiv.scrollHeight,
500
+ behavior: "smooth",
501
+ });
502
+ }
503
+ }, 100);
504
+ });
505
+ </script>
506
+ </body>
507
+ </html>