Spaces:
Sleeping
Sleeping
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Synthex Medical Text Generator</title> | |
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"> | |
<style> | |
body { | |
padding: 20px; | |
background-color: #f8f9fa; | |
} | |
.container { | |
max-width: 1200px; | |
background-color: white; | |
padding: 30px; | |
border-radius: 10px; | |
box-shadow: 0 0 10px rgba(0,0,0,0.1); | |
} | |
.result-box { | |
background-color: #f8f9fa; | |
padding: 15px; | |
border-radius: 5px; | |
margin-top: 20px; | |
white-space: pre-wrap; | |
} | |
.loading { | |
display: none; | |
text-align: center; | |
margin: 20px 0; | |
} | |
.nav-tabs { | |
margin-bottom: 20px; | |
} | |
.plot-container { | |
margin-top: 20px; | |
text-align: center; | |
} | |
.plot-container img { | |
max-width: 100%; | |
height: auto; | |
border-radius: 5px; | |
box-shadow: 0 0 5px rgba(0,0,0,0.1); | |
} | |
.stats-card { | |
margin-bottom: 15px; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container"> | |
<h1 class="mb-4">Synthex Medical Text Generator</h1> | |
<!-- Navigation Tabs --> | |
<ul class="nav nav-tabs" id="myTab" role="tablist"> | |
<li class="nav-item" role="presentation"> | |
<button class="nav-link active" id="generation-tab" data-bs-toggle="tab" data-bs-target="#generation" type="button" role="tab">Generation</button> | |
</li> | |
<li class="nav-item" role="presentation"> | |
<button class="nav-link" id="analysis-tab" data-bs-toggle="tab" data-bs-target="#analysis" type="button" role="tab">Analysis</button> | |
</li> | |
</ul> | |
<!-- Tab Content --> | |
<div class="tab-content" id="myTabContent"> | |
<!-- Generation Tab --> | |
<div class="tab-pane fade show active" id="generation" role="tabpanel"> | |
<div class="mb-3"> | |
<label for="recordType" class="form-label">Record Type</label> | |
<select class="form-select" id="recordType"> | |
<option value="clinical_note">Clinical Note</option> | |
<option value="discharge_summary">Discharge Summary</option> | |
<option value="lab_report">Lab Report</option> | |
<option value="prescription">Prescription</option> | |
<option value="patient_intake">Patient Intake</option> | |
</select> | |
</div> | |
<div class="mb-3"> | |
<label for="quantity" class="form-label">Quantity</label> | |
<input type="number" class="form-control" id="quantity" value="1" min="1" max="10"> | |
</div> | |
<div class="mb-3 form-check"> | |
<input type="checkbox" class="form-check-input" id="useGemini"> | |
<label class="form-check-label" for="useGemini">Use Gemini (if available)</label> | |
</div> | |
<div class="mb-3 form-check"> | |
<input type="checkbox" class="form-check-input" id="includeMetadata" checked> | |
<label class="form-check-label" for="includeMetadata">Include Metadata</label> | |
</div> | |
<button class="btn btn-primary" onclick="generateRecords()">Generate Records</button> | |
<div class="loading" id="loading"> | |
<div class="spinner-border text-primary" role="status"> | |
<span class="visually-hidden">Loading...</span> | |
</div> | |
<p class="mt-2">Generating records...</p> | |
</div> | |
<div id="result" class="result-box"></div> | |
</div> | |
<!-- Analysis Tab --> | |
<div class="tab-pane fade" id="analysis" role="tabpanel"> | |
<div class="row mb-4"> | |
<div class="col"> | |
<button class="btn btn-primary" onclick="runAnalysis()">Run Analysis</button> | |
<button class="btn btn-secondary" onclick="checkStatus()">Check Status</button> | |
</div> | |
</div> | |
<div class="loading" id="analysisLoading"> | |
<div class="spinner-border text-primary" role="status"> | |
<span class="visually-hidden">Loading...</span> | |
</div> | |
<p class="mt-2">Running analysis...</p> | |
</div> | |
<!-- Analysis Results --> | |
<div id="analysisResult"> | |
<!-- Summary Stats --> | |
<div class="row mb-4" id="summaryStats"></div> | |
<!-- Dataset List --> | |
<div class="mb-4"> | |
<h3>Available Datasets</h3> | |
<div id="datasetList" class="list-group"></div> | |
</div> | |
<!-- Plots --> | |
<div class="mb-4"> | |
<h3>Analysis Plots</h3> | |
<div id="plotGallery" class="row"></div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script> | |
<script> | |
// Generation Functions | |
async function generateRecords() { | |
const recordType = document.getElementById('recordType').value; | |
const quantity = parseInt(document.getElementById('quantity').value); | |
const useGemini = document.getElementById('useGemini').checked; | |
const includeMetadata = document.getElementById('includeMetadata').checked; | |
document.getElementById('loading').style.display = 'block'; | |
document.getElementById('result').innerHTML = ''; | |
try { | |
const response = await fetch('/generate', { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json', | |
'Accept': 'application/json' | |
}, | |
body: JSON.stringify({ | |
record_type: recordType, | |
quantity: quantity, | |
use_gemini: useGemini, | |
include_metadata: includeMetadata | |
}) | |
}); | |
const data = await response.json(); | |
let resultHtml = '<h3>Generated Records:</h3>'; | |
data.records.forEach(record => { | |
resultHtml += ` | |
<div class="mb-4"> | |
<strong>ID:</strong> ${record.id}<br> | |
<strong>Type:</strong> ${record.type}<br> | |
<strong>Source:</strong> ${record.source}<br> | |
<strong>Timestamp:</strong> ${record.timestamp}<br> | |
<strong>Text:</strong><br> | |
<pre>${record.text}</pre> | |
</div> | |
`; | |
}); | |
document.getElementById('result').innerHTML = resultHtml; | |
} catch (error) { | |
document.getElementById('result').innerHTML = `<div class="alert alert-danger">Error: ${error.message}</div>`; | |
} finally { | |
document.getElementById('loading').style.display = 'none'; | |
} | |
} | |
// Analysis Functions | |
async function runAnalysis() { | |
document.getElementById('analysisLoading').style.display = 'block'; | |
document.getElementById('analysisResult').style.display = 'none'; | |
try { | |
const response = await fetch('http://localhost:8001/analyze', { | |
method: 'POST' | |
}); | |
const data = await response.json(); | |
displayAnalysisResults(data); | |
} catch (error) { | |
alert(`Error running analysis: ${error.message}`); | |
} finally { | |
document.getElementById('analysisLoading').style.display = 'none'; | |
document.getElementById('analysisResult').style.display = 'block'; | |
} | |
} | |
async function checkStatus() { | |
try { | |
const response = await fetch('http://localhost:8001/analysis/status'); | |
const data = await response.json(); | |
if (data.is_analyzed) { | |
displayAnalysisResults(data); | |
} else { | |
alert('No analysis has been run yet.'); | |
} | |
} catch (error) { | |
alert(`Error checking status: ${error.message}`); | |
} | |
} | |
function displayAnalysisResults(data) { | |
// Display summary stats | |
const summaryHtml = ` | |
<div class="col-md-4"> | |
<div class="card stats-card"> | |
<div class="card-body"> | |
<h5 class="card-title">Total Samples</h5> | |
<p class="card-text">${data.summary.total_samples}</p> | |
</div> | |
</div> | |
</div> | |
<div class="col-md-4"> | |
<div class="card stats-card"> | |
<div class="card-body"> | |
<h5 class="card-title">Total Datasets</h5> | |
<p class="card-text">${data.summary.total_datasets}</p> | |
</div> | |
</div> | |
</div> | |
<div class="col-md-4"> | |
<div class="card stats-card"> | |
<div class="card-body"> | |
<h5 class="card-title">Last Updated</h5> | |
<p class="card-text">${new Date(data.timestamp).toLocaleString()}</p> | |
</div> | |
</div> | |
</div> | |
`; | |
document.getElementById('summaryStats').innerHTML = summaryHtml; | |
// Display datasets | |
const datasetList = document.getElementById('datasetList'); | |
datasetList.innerHTML = ''; | |
Object.entries(data.datasets).forEach(([name, stats]) => { | |
datasetList.innerHTML += ` | |
<div class="list-group-item"> | |
<h5>${name}</h5> | |
<p>Samples: ${stats.total_samples}</p> | |
${stats.abstract ? `<p>Avg Abstract Length: ${stats.abstract.avg_length.toFixed(1)}</p>` : ''} | |
</div> | |
`; | |
}); | |
// Display plots | |
const plotGallery = document.getElementById('plotGallery'); | |
plotGallery.innerHTML = ''; | |
data.plots_available.forEach(plotName => { | |
plotGallery.innerHTML += ` | |
<div class="col-md-6 mb-4"> | |
<div class="plot-container"> | |
<img src="http://localhost:8001/plots/${plotName}" alt="${plotName}" class="img-fluid"> | |
<p class="mt-2">${plotName.replace(/_/g, ' ').replace('.png', '')}</p> | |
</div> | |
</div> | |
`; | |
}); | |
} | |
// Initial status check | |
checkStatus(); | |
</script> | |
</body> | |
</html> |