hospital-management/templates/emr/clinical_note_form.html
2025-08-12 13:33:25 +03:00

623 lines
26 KiB
HTML

{% extends "base.html" %}
{% load static %}
{% block title %}{% if object %}Edit Clinical Note{% else %}New Clinical Note{% endif %}{% endblock %}
{% block content %}
<div class="d-flex align-items-center mb-3">
<div>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'emr:dashboard' %}">EMR</a></li>
<li class="breadcrumb-item"><a href="{% url 'emr:clinical_note_list' %}">Clinical Notes</a></li>
<li class="breadcrumb-item active">{% if object %}Edit{% else %}New{% endif %}</li>
</ol>
<h1 class="page-header mb-0">
{% if object %}Edit Clinical Note{% else %}Create Clinical Note{% endif %}
</h1>
</div>
<div class="ms-auto">
<a href="{% url 'emr:clinical_note_list' %}" class="btn btn-secondary">
<i class="fas fa-arrow-left me-2"></i>Back to List
</a>
</div>
</div>
<div class="row">
<div class="col-xl-8">
<div class="card">
<div class="card-header">
<h4 class="card-title">
<i class="fas fa-notes-medical me-2"></i>
Clinical Note Details
</h4>
</div>
<div class="card-body">
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
{% endfor %}
{% endif %}
<form method="post" novalidate>
{% csrf_token %}
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.patient.id_for_label }}" class="form-label">Patient *</label>
<select class="form-select {% if form.patient.errors %}is-invalid{% endif %}"
id="{{ form.patient.id_for_label }}"
name="{{ form.patient.name }}"
required>
<option value="">Select Patient</option>
{% for choice in form.patient.field.choices %}
{% if choice.0 %}
<option value="{{ choice.0 }}" {% if choice.0 == form.patient.value %}selected{% endif %}>
{{ choice.1 }}
</option>
{% endif %}
{% endfor %}
</select>
{% if form.patient.errors %}
<div class="invalid-feedback">
{{ form.patient.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.encounter.id_for_label }}" class="form-label">Encounter</label>
<select class="form-select {% if form.encounter.errors %}is-invalid{% endif %}"
id="{{ form.encounter.id_for_label }}"
name="{{ form.encounter.name }}">
<option value="">Select Encounter (Optional)</option>
{% for choice in form.encounter.field.choices %}
{% if choice.0 %}
<option value="{{ choice.0 }}" {% if choice.0 == form.encounter.value %}selected{% endif %}>
{{ choice.1 }}
</option>
{% endif %}
{% endfor %}
</select>
{% if form.encounter.errors %}
<div class="invalid-feedback">
{{ form.encounter.errors.0 }}
</div>
{% endif %}
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.note_type.id_for_label }}" class="form-label">Note Type *</label>
<select class="form-select {% if form.note_type.errors %}is-invalid{% endif %}"
id="{{ form.note_type.id_for_label }}"
name="{{ form.note_type.name }}"
required>
<option value="">Select Note Type</option>
{% for choice in form.note_type.field.choices %}
<option value="{{ choice.0 }}" {% if choice.0 == form.note_type.value %}selected{% endif %}>
{{ choice.1 }}
</option>
{% endfor %}
</select>
{% if form.note_type.errors %}
<div class="invalid-feedback">
{{ form.note_type.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.template.id_for_label }}" class="form-label">Template</label>
<select class="form-select {% if form.template.errors %}is-invalid{% endif %}"
id="{{ form.template.id_for_label }}"
name="{{ form.template.name }}">
<option value="">Select Template (Optional)</option>
{% for choice in form.template.field.choices %}
{% if choice.0 %}
<option value="{{ choice.0 }}" {% if choice.0 == form.template.value %}selected{% endif %}>
{{ choice.1 }}
</option>
{% endif %}
{% endfor %}
</select>
{% if form.template.errors %}
<div class="invalid-feedback">
{{ form.template.errors.0 }}
</div>
{% endif %}
</div>
</div>
</div>
<div class="mb-3">
<label for="{{ form.title.id_for_label }}" class="form-label">Title *</label>
<input type="text"
class="form-control {% if form.title.errors %}is-invalid{% endif %}"
id="{{ form.title.id_for_label }}"
name="{{ form.title.name }}"
value="{{ form.title.value|default:'' }}"
placeholder="Enter note title"
required>
{% if form.title.errors %}
<div class="invalid-feedback">
{{ form.title.errors.0 }}
</div>
{% endif %}
</div>
<div class="mb-3">
<label for="{{ form.content.id_for_label }}" class="form-label">Content *</label>
<textarea class="form-control {% if form.content.errors %}is-invalid{% endif %}"
id="{{ form.content.id_for_label }}"
name="{{ form.content.name }}"
rows="12"
placeholder="Enter clinical note content..."
required>{{ form.content.value|default:'' }}</textarea>
{% if form.content.errors %}
<div class="invalid-feedback">
{{ form.content.errors.0 }}
</div>
{% endif %}
<div class="form-text">
Use the toolbar above for formatting options. You can also use templates to speed up documentation.
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.status.id_for_label }}" class="form-label">Status</label>
<select class="form-select {% if form.status.errors %}is-invalid{% endif %}"
id="{{ form.status.id_for_label }}"
name="{{ form.status.name }}">
{% for choice in form.status.field.choices %}
<option value="{{ choice.0 }}" {% if choice.0 == form.status.value %}selected{% endif %}>
{{ choice.1 }}
</option>
{% endfor %}
</select>
{% if form.status.errors %}
<div class="invalid-feedback">
{{ form.status.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.priority.id_for_label }}" class="form-label">Priority</label>
<select class="form-select {% if form.priority.errors %}is-invalid{% endif %}"
id="{{ form.priority.id_for_label }}"
name="{{ form.priority.name }}">
{% for choice in form.priority.field.choices %}
<option value="{{ choice.0 }}" {% if choice.0 == form.priority.value %}selected{% endif %}>
{{ choice.1 }}
</option>
{% endfor %}
</select>
{% if form.priority.errors %}
<div class="invalid-feedback">
{{ form.priority.errors.0 }}
</div>
{% endif %}
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-check mb-3">
<input class="form-check-input"
type="checkbox"
id="{{ form.is_confidential.id_for_label }}"
name="{{ form.is_confidential.name }}"
{% if form.is_confidential.value %}checked{% endif %}>
<label class="form-check-label" for="{{ form.is_confidential.id_for_label }}">
Confidential Note
</label>
<div class="form-text">
Confidential notes have restricted access
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-check mb-3">
<input class="form-check-input"
type="checkbox"
id="{{ form.requires_cosign.id_for_label }}"
name="{{ form.requires_cosign.name }}"
{% if form.requires_cosign.value %}checked{% endif %}>
<label class="form-check-label" for="{{ form.requires_cosign.id_for_label }}">
Requires Co-signature
</label>
<div class="form-text">
Note requires approval from supervising physician
</div>
</div>
</div>
</div>
<div class="mb-3">
<label for="{{ form.tags.id_for_label }}" class="form-label">Tags</label>
<input type="text"
class="form-control {% if form.tags.errors %}is-invalid{% endif %}"
id="{{ form.tags.id_for_label }}"
name="{{ form.tags.name }}"
value="{{ form.tags.value|default:'' }}"
placeholder="Enter tags separated by commas">
{% if form.tags.errors %}
<div class="invalid-feedback">
{{ form.tags.errors.0 }}
</div>
{% endif %}
<div class="form-text">
Tags help categorize and search notes (e.g., follow-up, urgent, consultation)
</div>
</div>
<div class="d-flex justify-content-between">
<div>
{% if object %}
<a href="{% url 'emr:clinical_note_detail' object.pk %}" class="btn btn-secondary">
<i class="fas fa-times me-2"></i>Cancel
</a>
{% else %}
<a href="{% url 'emr:clinical_note_list' %}" class="btn btn-secondary">
<i class="fas fa-times me-2"></i>Cancel
</a>
{% endif %}
</div>
<div>
<button type="button" class="btn btn-outline-primary me-2" onclick="saveDraft()">
<i class="fas fa-save me-2"></i>Save as Draft
</button>
<button type="submit" class="btn btn-primary">
<i class="fas fa-check me-2"></i>
{% if object %}Update Note{% else %}Create Note{% endif %}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
<div class="col-xl-4">
<!-- Note Templates -->
<div class="card mb-4">
<div class="card-header">
<h5 class="card-title">
<i class="fas fa-file-medical me-2"></i>
Quick Templates
</h5>
</div>
<div class="card-body">
<div class="d-grid gap-2">
<button type="button" class="btn btn-outline-primary btn-sm" onclick="loadTemplate('soap')">
<i class="fas fa-notes-medical me-2"></i>SOAP Note
</button>
<button type="button" class="btn btn-outline-primary btn-sm" onclick="loadTemplate('progress')">
<i class="fas fa-chart-line me-2"></i>Progress Note
</button>
<button type="button" class="btn btn-outline-primary btn-sm" onclick="loadTemplate('discharge')">
<i class="fas fa-sign-out-alt me-2"></i>Discharge Summary
</button>
<button type="button" class="btn btn-outline-primary btn-sm" onclick="loadTemplate('consultation')">
<i class="fas fa-user-md me-2"></i>Consultation Note
</button>
</div>
</div>
</div>
<!-- Patient Information -->
<div class="card mb-4">
<div class="card-header">
<h5 class="card-title">
<i class="fas fa-user me-2"></i>
Patient Information
</h5>
</div>
<div class="card-body">
<div id="patient-info">
<div class="text-center text-muted">
<i class="fas fa-user fa-2x mb-2"></i>
<div>Select a patient to view information</div>
</div>
</div>
</div>
</div>
<!-- Recent Notes -->
<div class="card mb-4">
<div class="card-header">
<h5 class="card-title">
<i class="fas fa-history me-2"></i>
Recent Notes
</h5>
</div>
<div class="card-body">
<div id="recent-notes">
<div class="text-center text-muted">
<i class="fas fa-notes-medical fa-2x mb-2"></i>
<div>Select a patient to view recent notes</div>
</div>
</div>
</div>
</div>
<!-- Documentation Guidelines -->
<div class="card">
<div class="card-header">
<h5 class="card-title">
<i class="fas fa-info-circle me-2"></i>
Documentation Guidelines
</h5>
</div>
<div class="card-body">
<ul class="list-unstyled mb-0">
<li class="mb-2">
<i class="fas fa-check text-success me-2"></i>
Use clear, objective language
</li>
<li class="mb-2">
<i class="fas fa-check text-success me-2"></i>
Include relevant clinical details
</li>
<li class="mb-2">
<i class="fas fa-check text-success me-2"></i>
Document patient responses
</li>
<li class="mb-2">
<i class="fas fa-check text-success me-2"></i>
Note any changes in condition
</li>
<li>
<i class="fas fa-check text-success me-2"></i>
Include follow-up plans
</li>
</ul>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const patientSelect = document.getElementById('{{ form.patient.id_for_label }}');
const encounterSelect = document.getElementById('{{ form.encounter.id_for_label }}');
const templateSelect = document.getElementById('{{ form.template.id_for_label }}');
const contentTextarea = document.getElementById('{{ form.content.id_for_label }}');
// Load patient information when patient changes
patientSelect.addEventListener('change', function() {
const patientId = this.value;
if (patientId) {
loadPatientInfo(patientId);
loadRecentNotes(patientId);
loadPatientEncounters(patientId);
} else {
clearPatientInfo();
}
});
// Load template content when template changes
templateSelect.addEventListener('change', function() {
const templateId = this.value;
if (templateId) {
loadTemplateContent(templateId);
}
});
// Auto-save functionality
let autoSaveTimer;
contentTextarea.addEventListener('input', function() {
clearTimeout(autoSaveTimer);
autoSaveTimer = setTimeout(autoSave, 30000); // Auto-save after 30 seconds of inactivity
});
});
function loadPatientInfo(patientId) {
// Simulate loading patient information
const patientInfoDiv = document.getElementById('patient-info');
patientInfoDiv.innerHTML = `
<div class="text-center">
<div class="spinner-border spinner-border-sm text-primary mb-2" role="status"></div>
<div class="small">Loading patient information...</div>
</div>
`;
// Simulate API call
setTimeout(() => {
patientInfoDiv.innerHTML = `
<div class="mb-2">
<strong>Name:</strong> John Doe
</div>
<div class="mb-2">
<strong>DOB:</strong> 01/15/1980
</div>
<div class="mb-2">
<strong>MRN:</strong> MRN123456
</div>
<div class="mb-2">
<strong>Allergies:</strong> Penicillin
</div>
<div>
<strong>Current Medications:</strong> Lisinopril, Metformin
</div>
`;
}, 1000);
}
function loadRecentNotes(patientId) {
const recentNotesDiv = document.getElementById('recent-notes');
recentNotesDiv.innerHTML = `
<div class="text-center">
<div class="spinner-border spinner-border-sm text-primary mb-2" role="status"></div>
<div class="small">Loading recent notes...</div>
</div>
`;
setTimeout(() => {
recentNotesDiv.innerHTML = `
<div class="small mb-2">
<strong>Progress Note</strong> - 2 days ago
<div class="text-muted">Patient improving, continue current treatment...</div>
</div>
<div class="small mb-2">
<strong>Consultation</strong> - 1 week ago
<div class="text-muted">Cardiology consultation for chest pain...</div>
</div>
<div class="small">
<strong>Admission Note</strong> - 2 weeks ago
<div class="text-muted">Admitted for acute exacerbation...</div>
</div>
`;
}, 1000);
}
function loadPatientEncounters(patientId) {
// Update encounter dropdown with patient's encounters
const encounterSelect = document.getElementById('{{ form.encounter.id_for_label }}');
// In a real implementation, this would fetch encounters via AJAX
}
function clearPatientInfo() {
document.getElementById('patient-info').innerHTML = `
<div class="text-center text-muted">
<i class="fas fa-user fa-2x mb-2"></i>
<div>Select a patient to view information</div>
</div>
`;
document.getElementById('recent-notes').innerHTML = `
<div class="text-center text-muted">
<i class="fas fa-notes-medical fa-2x mb-2"></i>
<div>Select a patient to view recent notes</div>
</div>
`;
}
function loadTemplate(templateType) {
const contentTextarea = document.getElementById('{{ form.content.id_for_label }}');
const titleInput = document.getElementById('{{ form.title.id_for_label }}');
let templateContent = '';
let templateTitle = '';
switch(templateType) {
case 'soap':
templateTitle = 'SOAP Note';
templateContent = `SUBJECTIVE:
Patient reports...
OBJECTIVE:
Vital Signs:
Physical Examination:
ASSESSMENT:
1.
2.
PLAN:
1.
2. `;
break;
case 'progress':
templateTitle = 'Progress Note';
templateContent = `PROGRESS NOTE
Current Status:
Patient continues to...
Interval History:
Since last visit...
Physical Examination:
General appearance:
Vital signs:
Assessment and Plan:
1.
2. `;
break;
case 'discharge':
templateTitle = 'Discharge Summary';
templateContent = `DISCHARGE SUMMARY
Admission Date:
Discharge Date:
Length of Stay:
Admitting Diagnosis:
Discharge Diagnosis:
Hospital Course:
Patient was admitted for...
Discharge Medications:
1.
2.
Follow-up:
-
- `;
break;
case 'consultation':
templateTitle = 'Consultation Note';
templateContent = `CONSULTATION NOTE
Reason for Consultation:
Patient referred for...
History of Present Illness:
Past Medical History:
Physical Examination:
Impression:
1.
2.
Recommendations:
1.
2. `;
break;
}
if (confirm(`Load ${templateTitle} template? This will replace current content.`)) {
titleInput.value = templateTitle;
contentTextarea.value = templateContent;
}
}
function loadTemplateContent(templateId) {
// In a real implementation, this would fetch template content via AJAX
console.log('Loading template:', templateId);
}
function saveDraft() {
const statusSelect = document.getElementById('{{ form.status.id_for_label }}');
statusSelect.value = 'draft';
// Submit form
document.querySelector('form').submit();
}
function autoSave() {
// In a real implementation, this would save draft via AJAX
console.log('Auto-saving draft...');
}
</script>
{% endblock %}