brainworm2024 commited on
Commit
f21e0aa
·
1 Parent(s): b7e0aa2

Fix UI: switch to plain fetch, works now

Browse files
Files changed (1) hide show
  1. static/index.html +62 -58
static/index.html CHANGED
@@ -5,16 +5,13 @@
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>RustVital‑AMD | Zero‑Trust Medical AI</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
- <script src="https://unpkg.com/htmx.org@1.9.10"></script>
9
  <style>
10
- .htmx-indicator { display: none; }
11
- .htmx-request .htmx-indicator { display: inline; }
12
- .htmx-request.htmx-indicator { display: inline; }
13
  .pii-highlight { background-color: #fee2e2; padding: 0 2px; border-radius: 3px; font-weight: bold; }
14
  </style>
15
  </head>
16
  <body class="bg-gray-50 min-h-screen flex flex-col items-center p-4">
17
  <div class="max-w-3xl w-full">
 
18
  <div id="device-banner" class="bg-purple-100 text-purple-800 px-4 py-2 rounded-lg mb-2 text-sm text-center font-medium"></div>
19
  <script>
20
  fetch('/status')
@@ -35,7 +32,7 @@
35
  <div class="flex flex-col md:flex-row gap-4">
36
  <div class="flex-1">
37
  <label class="block text-sm font-medium text-gray-700 mb-1">Original Note</label>
38
- <textarea id="patient-note" name="patient_note" rows="5"
39
  class="w-full border border-gray-300 rounded-lg p-3 focus:ring-2 focus:ring-purple-500 focus:border-transparent"
40
  placeholder="Enter patient note...">Patient John Smith, 45 yo, chest pain</textarea>
41
  </div>
@@ -45,14 +42,9 @@
45
  </div>
46
  </div>
47
 
48
- <button hx-post="/triage" hx-trigger="click" hx-target="#result" hx-indicator="#spinner"
49
- hx-vals='{"patient_note": document.getElementById("patient-note").value, "consent_hash": "abc123"}'
50
  class="mt-4 w-full bg-purple-600 hover:bg-purple-700 text-white font-semibold py-3 rounded-lg transition flex items-center justify-center gap-2">
51
- <span>Start Triage</span>
52
- <svg id="spinner" class="htmx-indicator animate-spin h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
53
- <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
54
- <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path>
55
- </svg>
56
  </button>
57
  </div>
58
 
@@ -64,58 +56,70 @@
64
  return text.replace(/\[([A-Z_]+)_(\d+)\]/g, '<span class="pii-highlight">[$1_$2]</span>');
65
  }
66
 
67
- document.body.addEventListener('htmx:afterOnLoad', function(evt) {
68
- if (evt.detail.target.id === 'result' && evt.detail.xhr.status === 200) {
69
- try {
70
- const data = JSON.parse(evt.detail.xhr.responseText);
71
- const redactedDiv = document.getElementById('redacted-preview');
72
- redactedDiv.classList.remove('hidden');
73
- document.getElementById('redacted-text').innerHTML = highlightPlaceholders(data.redacted_prompt);
74
 
75
- const stepsHtml = data.agent_steps.map(step => `
76
- <div class="flex items-center gap-2 text-sm">
77
- <span class="px-2 py-1 bg-green-100 text-green-700 rounded-full">✅ ${step.name}</span>
78
- <span class="text-gray-500">${step.reasoning} (${step.duration_ms}ms)</span>
79
- </div>
80
- `).join('');
 
 
81
 
82
- const piiHtml = data.pii_map.map(p => `
83
- <li class="text-sm">🔴 <strong>${p.original}</strong> → <code>${p.placeholder}</code></li>
84
- `).join('');
 
85
 
86
- document.getElementById('result').innerHTML = `
87
- <div class="bg-white rounded-2xl shadow-xl p-6 space-y-4">
88
- <div class="text-sm text-purple-700 bg-purple-50 px-3 py-1 rounded-full inline-block">
89
- ${data.device_info} · Model: Qwen2.5-${data.model_used}
90
- </div>
91
- <div>
92
- <h3 class="font-semibold text-gray-700 mb-2">Agent Progress</h3>
93
- <div class="space-y-1">${stepsHtml}</div>
94
- </div>
95
- <div>
96
- <h3 class="font-semibold text-gray-700">Triage Result</h3>
97
- <div class="bg-purple-50 p-3 rounded-lg text-lg font-medium">${data.triage_result}</div>
98
- </div>
99
- <div>
100
- <h3 class="font-semibold text-gray-700">PII Redaction Map</h3>
101
- <ul class="list-disc list-inside text-sm text-gray-600">${piiHtml}</ul>
102
- </div>
103
- <div>
104
- <h3 class="font-semibold text-gray-700">Redaction Proof (SHA‑256)</h3>
105
- <code class="text-xs bg-gray-100 p-2 rounded block mt-1">${data.redaction_proof}</code>
106
- </div>
107
- <div>
108
- <h3 class="font-semibold text-gray-700">On‑Chain Audit</h3>
109
- <div class="text-sm">
110
- <p><strong>CID:</strong> <code>${data.cid}</code></p>
111
- <p><strong>Transaction:</strong> <a href="https://sepolia.basescan.org/tx/${data.transaction_hash}" target="_blank" class="text-purple-600 underline">${data.transaction_hash}</a></p>
112
- </div>
 
 
 
 
 
 
 
 
 
 
113
  </div>
114
  </div>
115
- `;
116
- } catch(e) {}
 
 
117
  }
118
- });
119
  </script>
120
  </body>
121
  </html>
 
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>RustVital‑AMD | Zero‑Trust Medical AI</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
 
8
  <style>
 
 
 
9
  .pii-highlight { background-color: #fee2e2; padding: 0 2px; border-radius: 3px; font-weight: bold; }
10
  </style>
11
  </head>
12
  <body class="bg-gray-50 min-h-screen flex flex-col items-center p-4">
13
  <div class="max-w-3xl w-full">
14
+ <!-- Device banner -->
15
  <div id="device-banner" class="bg-purple-100 text-purple-800 px-4 py-2 rounded-lg mb-2 text-sm text-center font-medium"></div>
16
  <script>
17
  fetch('/status')
 
32
  <div class="flex flex-col md:flex-row gap-4">
33
  <div class="flex-1">
34
  <label class="block text-sm font-medium text-gray-700 mb-1">Original Note</label>
35
+ <textarea id="patient-note" rows="5"
36
  class="w-full border border-gray-300 rounded-lg p-3 focus:ring-2 focus:ring-purple-500 focus:border-transparent"
37
  placeholder="Enter patient note...">Patient John Smith, 45 yo, chest pain</textarea>
38
  </div>
 
42
  </div>
43
  </div>
44
 
45
+ <button onclick="runTriage()"
 
46
  class="mt-4 w-full bg-purple-600 hover:bg-purple-700 text-white font-semibold py-3 rounded-lg transition flex items-center justify-center gap-2">
47
+ Start Triage
 
 
 
 
48
  </button>
49
  </div>
50
 
 
56
  return text.replace(/\[([A-Z_]+)_(\d+)\]/g, '<span class="pii-highlight">[$1_$2]</span>');
57
  }
58
 
59
+ async function runTriage() {
60
+ const note = document.getElementById('patient-note').value;
61
+ const resultDiv = document.getElementById('result');
62
+ resultDiv.innerHTML = '<div class="text-center text-purple-500 py-4">Processing...</div>';
 
 
 
63
 
64
+ try {
65
+ const response = await fetch('/triage', {
66
+ method: 'POST',
67
+ headers: { 'Content-Type': 'application/json' },
68
+ body: JSON.stringify({ patient_note: note, consent_hash: 'abc123' })
69
+ });
70
+ if (!response.ok) throw new Error('Server error');
71
+ const data = await response.json();
72
 
73
+ // Show redacted preview
74
+ const redactedDiv = document.getElementById('redacted-preview');
75
+ redactedDiv.classList.remove('hidden');
76
+ document.getElementById('redacted-text').innerHTML = highlightPlaceholders(data.redacted_prompt);
77
 
78
+ const stepsHtml = data.agent_steps.map(step => `
79
+ <div class="flex items-center gap-2 text-sm">
80
+ <span class="px-2 py-1 bg-green-100 text-green-700 rounded-full">✅ ${step.name}</span>
81
+ <span class="text-gray-500">${step.reasoning} (${step.duration_ms}ms)</span>
82
+ </div>
83
+ `).join('');
84
+
85
+ const piiHtml = data.pii_map.map(p => `
86
+ <li class="text-sm">🔴 <strong>${p.original}</strong> → <code>${p.placeholder}</code></li>
87
+ `).join('');
88
+
89
+ resultDiv.innerHTML = `
90
+ <div class="bg-white rounded-2xl shadow-xl p-6 space-y-4">
91
+ <div class="text-sm text-purple-700 bg-purple-50 px-3 py-1 rounded-full inline-block">
92
+ ${data.device_info} · Model: Qwen2.5-${data.model_used}
93
+ </div>
94
+ <div>
95
+ <h3 class="font-semibold text-gray-700 mb-2">Agent Progress</h3>
96
+ <div class="space-y-1">${stepsHtml}</div>
97
+ </div>
98
+ <div>
99
+ <h3 class="font-semibold text-gray-700">Triage Result</h3>
100
+ <div class="bg-purple-50 p-3 rounded-lg text-lg font-medium">${data.triage_result}</div>
101
+ </div>
102
+ <div>
103
+ <h3 class="font-semibold text-gray-700">PII Redaction Map</h3>
104
+ <ul class="list-disc list-inside text-sm text-gray-600">${piiHtml}</ul>
105
+ </div>
106
+ <div>
107
+ <h3 class="font-semibold text-gray-700">Redaction Proof (SHA‑256)</h3>
108
+ <code class="text-xs bg-gray-100 p-2 rounded block mt-1">${data.redaction_proof}</code>
109
+ </div>
110
+ <div>
111
+ <h3 class="font-semibold text-gray-700">On‑Chain Audit</h3>
112
+ <div class="text-sm">
113
+ <p><strong>CID:</strong> <code>${data.cid}</code></p>
114
+ <p><strong>Transaction:</strong> <a href="https://sepolia.basescan.org/tx/${data.transaction_hash}" target="_blank" class="text-purple-600 underline">${data.transaction_hash}</a></p>
115
  </div>
116
  </div>
117
+ </div>
118
+ `;
119
+ } catch (e) {
120
+ resultDiv.innerHTML = `<div class="bg-red-100 text-red-700 p-4 rounded-lg">Error: ${e.message}</div>`;
121
  }
122
+ }
123
  </script>
124
  </body>
125
  </html>