diff --git a/frontend/src/App.js b/frontend/src/App.js index 803f738..5532d6d 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -27,10 +27,13 @@ function App() { }); }; - const handleSubmit = async () => { - if (!query.trim() || loading) return; + const handleSubmit = async (fhirData = {}) => { + if ((!query.trim() && !fhirData.has_fhir) || loading) return; - const userMessage = { role: 'user', text: query }; + const userMessage = { + role: 'user', + text: query || `FHIR ${fhirData.fhir_resource_type}/${fhirData.fhir_resource_id}` + }; setMessages(prev => [...prev, userMessage]); setQuery(''); setLoading(true); @@ -40,7 +43,7 @@ function App() { const response = await fetch('http://localhost:8000/query', { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ query: userMessage.text, api_key: apiKey }), + body: JSON.stringify({ query: userMessage.text, api_key: apiKey, ...fhirData }), }); if (!response.ok) throw new Error('Query failed'); diff --git a/frontend/src/components/ChatWindow.js b/frontend/src/components/ChatWindow.js index 770b89d..5e66a51 100644 --- a/frontend/src/components/ChatWindow.js +++ b/frontend/src/components/ChatWindow.js @@ -1,10 +1,15 @@ -import React, { useEffect, useRef } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import ReactMarkdown from 'react-markdown'; import ClaimItem from './ClaimItem'; import DrugCarousel from './DrugCarousel'; +const FHIR_RESOURCE_TYPES = ['Condition', 'MedicationRequest', 'DiagnosticReport']; + function ChatWindow({ messages, query, onQueryChange, onSubmit, loading }) { const bottomRef = useRef(null); + const [showFhir, setShowFhir] = useState(false); + const [fhirType, setFhirType] = useState('Condition'); + const [fhirId, setFhirId] = useState(''); useEffect(() => { bottomRef.current?.scrollIntoView({ behavior: 'smooth' }); @@ -13,10 +18,25 @@ function ChatWindow({ messages, query, onQueryChange, onSubmit, loading }) { const handleKeyDown = (e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); - onSubmit(); + handleSubmit(); } }; + const handleSubmit = () => { + const fhirData = showFhir && fhirId.trim() ? { + has_fhir: true, + fhir_resource_type: fhirType, + fhir_resource_id: fhirId.trim(), + } : { + has_fhir: false, + fhir_resource_type: null, + fhir_resource_id: null, + }; + onSubmit(fhirData); + }; + + const canSubmit = query.trim() || (showFhir && fhirId.trim()); + return (
@@ -24,8 +44,9 @@ function ChatWindow({ messages, query, onQueryChange, onSubmit, loading }) {

Ask a clinical question

- The system will retrieve relevant PubMed abstracts and verify each - claim in the response against medical literature using NLI scoring. + The system retrieves PubMed abstracts and verifies each claim + against medical literature using NLI scoring. Optionally attach + a FHIR resource for structured clinical context.

)} @@ -83,10 +104,83 @@ function ChatWindow({ messages, query, onQueryChange, onSubmit, loading }) {
+ {showFhir && ( +
+
+ + FHIR Resource + + + · HAPI R4 Server + +
+
+ + setFhirId(e.target.value)} + style={{ + flex: 1, + background: 'var(--bg)', + border: '1px solid var(--border)', + borderRadius: 6, + color: 'var(--text)', + fontFamily: 'DM Mono, monospace', + fontSize: 12, + padding: '6px 10px', + outline: 'none', + }} + /> +
+
+ )} +
+