hospital-management/templates/radiology/reports/radiology_report_form.html
2025-08-12 13:33:25 +03:00

515 lines
23 KiB
HTML

{% extends "base.html" %}
{% load static %}
{% block title %}{% if object %}Edit Report - {{ object.report_id }}{% else %}Create Radiology Report{% endif %}{% endblock %}
{% block content %}
<div class="d-flex align-items-center mb-3">
<div>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'radiology:dashboard' %}">Radiology</a></li>
<li class="breadcrumb-item"><a href="{% url 'radiology:radiology_report_list' %}">Reports</a></li>
{% if object %}
<li class="breadcrumb-item"><a href="{% url 'radiology:radiology_report_detail' object.pk %}">{{ object.report_id }}</a></li>
<li class="breadcrumb-item active">Edit</li>
{% else %}
<li class="breadcrumb-item active">Create</li>
{% endif %}
</ol>
<h1 class="page-header mb-0">
{% if object %}Edit Radiology Report{% else %}Create Radiology Report{% endif %}
</h1>
</div>
<div class="ms-auto">
<button type="button" class="btn btn-outline-secondary me-2" onclick="saveDraft()">
<i class="fas fa-save me-2"></i>Save Draft
</button>
{% if object %}
<a href="{% url 'radiology:radiology_report_detail' object.pk %}" class="btn btn-secondary">
<i class="fas fa-times me-2"></i>Cancel
</a>
{% else %}
<a href="{% url 'radiology:radiology_report_list' %}" class="btn btn-secondary">
<i class="fas fa-times me-2"></i>Cancel
</a>
{% endif %}
</div>
</div>
<form method="post" id="reportForm" novalidate>
{% csrf_token %}
<div class="row">
<div class="col-xl-8">
<!-- Study Information -->
<div class="card mb-4">
<div class="card-header">
<h4 class="card-title">
<i class="fas fa-x-ray me-2"></i>
Study Information
</h4>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Study <span class="text-danger">*</span></label>
{{ form.study }}
{% if form.study.errors %}
<div class="invalid-feedback d-block">{{ form.study.errors.0 }}</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Report ID</label>
{{ form.report_id }}
{% if form.report_id.errors %}
<div class="invalid-feedback d-block">{{ form.report_id.errors.0 }}</div>
{% endif %}
<div class="form-text">Auto-generated if left blank</div>
</div>
</div>
</div>
<!-- Patient Information Display -->
<div id="patientInfo" style="display: none;">
<div class="alert alert-info">
<h6><i class="fas fa-user me-2"></i>Patient Information</h6>
<div class="row">
<div class="col-md-6">
<p class="mb-1"><strong>Name:</strong> <span id="patientName"></span></p>
<p class="mb-1"><strong>DOB:</strong> <span id="patientDOB"></span></p>
<p class="mb-0"><strong>Gender:</strong> <span id="patientGender"></span></p>
</div>
<div class="col-md-6">
<p class="mb-1"><strong>MRN:</strong> <span id="patientMRN"></span></p>
<p class="mb-1"><strong>Study Date:</strong> <span id="studyDate"></span></p>
<p class="mb-0"><strong>Modality:</strong> <span id="studyModality"></span></p>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Report Content -->
<div class="card mb-4">
<div class="card-header">
<h4 class="card-title">
<i class="fas fa-file-medical me-2"></i>
Report Content
</h4>
<div class="card-toolbar">
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-outline-primary" onclick="insertTemplate('normal')">
<i class="fas fa-file-alt me-1"></i>Normal Template
</button>
<button type="button" class="btn btn-outline-secondary" onclick="insertTemplate('abnormal')">
<i class="fas fa-exclamation-triangle me-1"></i>Abnormal Template
</button>
<button type="button" class="btn btn-outline-info" onclick="insertTemplate('comparison')">
<i class="fas fa-balance-scale me-1"></i>Comparison Template
</button>
</div>
</div>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Clinical History</label>
{{ form.clinical_history }}
{% if form.clinical_history.errors %}
<div class="invalid-feedback d-block">{{ form.clinical_history.errors.0 }}</div>
{% endif %}
<div class="form-text">Patient's clinical background and reason for study</div>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Technique</label>
{{ form.technique }}
{% if form.technique.errors %}
<div class="invalid-feedback d-block">{{ form.technique.errors.0 }}</div>
{% endif %}
<div class="form-text">Technical parameters and methodology</div>
</div>
</div>
</div>
<div class="mb-3">
<label class="form-label">Findings <span class="text-danger">*</span></label>
{{ form.findings }}
{% if form.findings.errors %}
<div class="invalid-feedback d-block">{{ form.findings.errors.0 }}</div>
{% endif %}
<div class="form-text">Detailed description of imaging findings</div>
</div>
<div class="mb-3">
<label class="form-label">Impression <span class="text-danger">*</span></label>
{{ form.impression }}
{% if form.impression.errors %}
<div class="invalid-feedback d-block">{{ form.impression.errors.0 }}</div>
{% endif %}
<div class="form-text">Clinical interpretation and diagnosis</div>
</div>
<div class="mb-3">
<label class="form-label">Recommendations</label>
{{ form.recommendations }}
{% if form.recommendations.errors %}
<div class="invalid-feedback d-block">{{ form.recommendations.errors.0 }}</div>
{% endif %}
<div class="form-text">Follow-up recommendations and additional studies</div>
</div>
</div>
</div>
<!-- Critical Findings -->
<div class="card mb-4">
<div class="card-header">
<h4 class="card-title">
<i class="fas fa-exclamation-triangle text-danger me-2"></i>
Critical Findings
</h4>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<div class="form-check">
{{ form.has_critical_findings }}
<label class="form-check-label" for="{{ form.has_critical_findings.id_for_label }}">
This report contains critical findings
</label>
</div>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Critical Finding Type</label>
{{ form.critical_finding_type }}
{% if form.critical_finding_type.errors %}
<div class="invalid-feedback d-block">{{ form.critical_finding_type.errors.0 }}</div>
{% endif %}
</div>
</div>
</div>
<div class="mb-3" id="criticalFindingsDetails" style="display: none;">
<label class="form-label">Critical Findings Details</label>
{{ form.critical_findings_details }}
{% if form.critical_findings_details.errors %}
<div class="invalid-feedback d-block">{{ form.critical_findings_details.errors.0 }}</div>
{% endif %}
<div class="form-text">Detailed description of critical findings requiring immediate attention</div>
</div>
<div class="mb-3" id="notificationDetails" style="display: none;">
<label class="form-label">Notification Time</label>
{{ form.critical_notification_time }}
{% if form.critical_notification_time.errors %}
<div class="invalid-feedback d-block">{{ form.critical_notification_time.errors.0 }}</div>
{% endif %}
<div class="form-text">Time when referring physician was notified</div>
</div>
</div>
</div>
</div>
<div class="col-xl-4">
<!-- Report Status -->
<div class="card mb-4">
<div class="card-header">
<h4 class="card-title">Report Status</h4>
</div>
<div class="card-body">
<div class="mb-3">
<label class="form-label">Status</label>
{{ form.status }}
{% if form.status.errors %}
<div class="invalid-feedback d-block">{{ form.status.errors.0 }}</div>
{% endif %}
</div>
<div class="mb-3">
<label class="form-label">Priority</label>
{{ form.priority }}
{% if form.priority.errors %}
<div class="invalid-feedback d-block">{{ form.priority.errors.0 }}</div>
{% endif %}
</div>
<div class="mb-3">
<label class="form-label">Radiologist</label>
{{ form.radiologist }}
{% if form.radiologist.errors %}
<div class="invalid-feedback d-block">{{ form.radiologist.errors.0 }}</div>
{% endif %}
</div>
<div class="mb-3">
<label class="form-label">Dictated Date</label>
{{ form.dictated_date }}
{% if form.dictated_date.errors %}
<div class="invalid-feedback d-block">{{ form.dictated_date.errors.0 }}</div>
{% endif %}
</div>
</div>
</div>
<!-- Quality Assurance -->
<div class="card mb-4">
<div class="card-header">
<h4 class="card-title">Quality Assurance</h4>
</div>
<div class="card-body">
<div class="mb-3">
<div class="form-check">
{{ form.peer_reviewed }}
<label class="form-check-label" for="{{ form.peer_reviewed.id_for_label }}">
Peer reviewed
</label>
</div>
</div>
<div class="mb-3" id="peerReviewDetails" style="display: none;">
<label class="form-label">Peer Reviewer</label>
{{ form.peer_reviewer }}
{% if form.peer_reviewer.errors %}
<div class="invalid-feedback d-block">{{ form.peer_reviewer.errors.0 }}</div>
{% endif %}
</div>
<div class="mb-3">
<label class="form-label">Quality Score</label>
{{ form.quality_score }}
{% if form.quality_score.errors %}
<div class="invalid-feedback d-block">{{ form.quality_score.errors.0 }}</div>
{% endif %}
<div class="form-text">1-5 scale (5 = excellent)</div>
</div>
</div>
</div>
<!-- Actions -->
<div class="card">
<div class="card-header">
<h4 class="card-title">Actions</h4>
</div>
<div class="card-body">
<div class="d-grid gap-2">
<button type="submit" name="action" value="save_draft" class="btn btn-outline-secondary">
<i class="fas fa-save me-2"></i>Save as Draft
</button>
<button type="submit" name="action" value="submit_review" class="btn btn-outline-warning">
<i class="fas fa-eye me-2"></i>Submit for Review
</button>
<button type="submit" name="action" value="finalize" class="btn btn-success">
<i class="fas fa-check me-2"></i>Finalize Report
</button>
{% if object %}
<button type="button" class="btn btn-outline-info" onclick="previewReport()">
<i class="fas fa-print me-2"></i>Preview
</button>
{% endif %}
</div>
<hr>
<div class="text-center">
<small class="text-muted">
<i class="fas fa-info-circle me-1"></i>
Auto-save every 30 seconds
</small>
</div>
</div>
</div>
</div>
</div>
</form>
<!-- Report Templates Modal -->
<div class="modal fade" id="templateModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Report Templates</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-4">
<div class="list-group" id="templateList">
<button type="button" class="list-group-item list-group-item-action active" data-template="chest_xray">
Chest X-Ray Normal
</button>
<button type="button" class="list-group-item list-group-item-action" data-template="ct_head">
CT Head Normal
</button>
<button type="button" class="list-group-item list-group-item-action" data-template="mri_brain">
MRI Brain Normal
</button>
</div>
</div>
<div class="col-md-8">
<div id="templatePreview">
<h6>Chest X-Ray Normal Template</h6>
<p><strong>Technique:</strong> PA and lateral chest radiographs</p>
<p><strong>Findings:</strong> The lungs are clear bilaterally. No focal consolidation, pleural effusion, or pneumothorax. The cardiac silhouette is normal in size and configuration. The mediastinal contours are unremarkable.</p>
<p><strong>Impression:</strong> Normal chest radiograph.</p>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" onclick="useTemplate()">Use Template</button>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Study selection change handler
const studySelect = document.querySelector('select[name="study"]');
if (studySelect) {
studySelect.addEventListener('change', function() {
if (this.value) {
loadStudyInfo(this.value);
} else {
document.getElementById('patientInfo').style.display = 'none';
}
});
}
// Critical findings checkbox handler
const criticalCheckbox = document.querySelector('input[name="has_critical_findings"]');
if (criticalCheckbox) {
criticalCheckbox.addEventListener('change', function() {
const details = document.getElementById('criticalFindingsDetails');
const notification = document.getElementById('notificationDetails');
if (this.checked) {
details.style.display = 'block';
notification.style.display = 'block';
} else {
details.style.display = 'none';
notification.style.display = 'none';
}
});
}
// Peer review checkbox handler
const peerReviewCheckbox = document.querySelector('input[name="peer_reviewed"]');
if (peerReviewCheckbox) {
peerReviewCheckbox.addEventListener('change', function() {
const details = document.getElementById('peerReviewDetails');
details.style.display = this.checked ? 'block' : 'none';
});
}
// Auto-save functionality
let autoSaveTimer;
const form = document.getElementById('reportForm');
const formInputs = form.querySelectorAll('input, textarea, select');
formInputs.forEach(input => {
input.addEventListener('input', function() {
clearTimeout(autoSaveTimer);
autoSaveTimer = setTimeout(autoSave, 30000); // 30 seconds
});
});
// Character counting for text areas
const textAreas = document.querySelectorAll('textarea');
textAreas.forEach(textarea => {
const maxLength = textarea.getAttribute('maxlength');
if (maxLength) {
const counter = document.createElement('div');
counter.className = 'form-text text-end';
counter.innerHTML = `<span class="char-count">0</span>/${maxLength} characters`;
textarea.parentNode.appendChild(counter);
textarea.addEventListener('input', function() {
const count = this.value.length;
const span = counter.querySelector('.char-count');
span.textContent = count;
span.className = count > maxLength * 0.9 ? 'text-warning' : '';
});
}
});
});
function loadStudyInfo(studyId) {
// Simulate loading study information
fetch(`/api/studies/${studyId}/`)
.then(response => response.json())
.then(data => {
document.getElementById('patientName').textContent = data.patient.name;
document.getElementById('patientDOB').textContent = data.patient.dob;
document.getElementById('patientGender').textContent = data.patient.gender;
document.getElementById('patientMRN').textContent = data.patient.mrn;
document.getElementById('studyDate').textContent = data.study_date;
document.getElementById('studyModality').textContent = data.modality;
document.getElementById('patientInfo').style.display = 'block';
})
.catch(error => {
console.error('Error loading study info:', error);
});
}
function saveDraft() {
const form = document.getElementById('reportForm');
const formData = new FormData(form);
formData.append('action', 'save_draft');
fetch(form.action, {
method: 'POST',
body: formData,
headers: {
'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
showNotification('Draft saved successfully', 'success');
}
})
.catch(error => {
showNotification('Error saving draft', 'error');
});
}
function autoSave() {
saveDraft();
}
function insertTemplate(type) {
const modal = new bootstrap.Modal(document.getElementById('templateModal'));
modal.show();
}
function useTemplate() {
// Implement template insertion logic
const modal = bootstrap.Modal.getInstance(document.getElementById('templateModal'));
modal.hide();
}
function previewReport() {
const reportId = '{{ object.pk }}';
window.open(`/radiology/reports/${reportId}/preview/`, '_blank');
}
function showNotification(message, type) {
// Implement notification system
console.log(`${type}: ${message}`);
}
</script>
{% endblock %}