Marwan Alwali b9b8c69129 update
2025-08-31 10:47:23 +03:00

1010 lines
40 KiB
HTML

{% extends 'base.html' %}
{% load static %}
{% block title %}{% if note.pk %}Edit{% else %}Create{% endif %} Surgical Note{% endblock %}
{% block css %}
<link href="{% static 'assets/plugins/select2/dist/css/select2.min.css' %}" rel="stylesheet" />
<link href="{% static 'assets/plugins/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css' %}" rel="stylesheet" />
<link href="{% static 'assets/plugins/bootstrap-timepicker/css/bootstrap-timepicker.min.css' %}" rel="stylesheet" />
<style>
.form-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-radius: 0.5rem;
padding: 2rem;
margin-bottom: 2rem;
}
.form-section {
background: white;
border: 1px solid #dee2e6;
border-radius: 0.375rem;
margin-bottom: 1.5rem;
}
.section-header {
background: #f8f9fa;
border-bottom: 1px solid #dee2e6;
padding: 1rem 1.5rem;
font-weight: 600;
color: #495057;
display: flex;
align-items: center;
}
.section-content {
padding: 1.5rem;
}
.required-field::after {
content: " *";
color: #dc3545;
}
.form-floating > .form-control:focus ~ label,
.form-floating > .form-control:not(:placeholder-shown) ~ label {
opacity: .65;
transform: scale(.85) translateY(-0.5rem) translateX(0.15rem);
}
.signature-pad {
border: 2px dashed #dee2e6;
border-radius: 0.375rem;
background: #f8f9fa;
padding: 1rem;
text-align: center;
min-height: 200px;
position: relative;
}
.signature-canvas {
border: 1px solid #dee2e6;
border-radius: 0.25rem;
background: white;
cursor: crosshair;
}
.template-selector {
background: #e3f2fd;
border: 1px solid #bbdefb;
border-radius: 0.375rem;
padding: 1rem;
margin-bottom: 1.5rem;
}
.auto-save-indicator {
position: fixed;
top: 20px;
right: 20px;
background: #28a745;
color: white;
padding: 0.5rem 1rem;
border-radius: 0.25rem;
font-size: 0.875rem;
z-index: 1050;
display: none;
}
.field-help {
font-size: 0.875rem;
color: #6c757d;
margin-top: 0.25rem;
}
@media (max-width: 768px) {
.form-header {
padding: 1.5rem;
}
.section-content {
padding: 1rem;
}
.signature-pad {
min-height: 150px;
}
}
@media print {
.btn, .form-actions, .template-selector {
display: none !important;
}
.form-section {
border: none;
box-shadow: none;
}
.section-header {
background: none;
border-bottom: 2px solid #000;
color: #000;
}
}
</style>
{% endblock %}
{% block content %}
<div id="content" class="app-content">
<!-- Auto-save indicator -->
<div class="auto-save-indicator" id="auto-save-indicator">
<i class="fas fa-check me-1"></i>Auto-saved
</div>
<!-- Page Header -->
<div class="d-flex align-items-center mb-3">
<div>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
<li class="breadcrumb-item"><a href="{% url 'operating_theatre:dashboard' %}">Operating Theatre</a></li>
<li class="breadcrumb-item"><a href="{% url 'operating_theatre:surgical_note_list' %}">Surgical Notes</a></li>
<li class="breadcrumb-item active">{% if note.pk %}Edit{% else %}Create{% endif %} Note</li>
</ol>
<h1 class="page-header mb-0">
<i class="fas fa-file-medical me-2"></i>
{% if note.pk %}Edit Surgical Note{% else %}Create Surgical Note{% 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-1"></i>Save Draft
</button>
<a href="{% url 'operating_theatre:surgical_note_list' %}" class="btn btn-outline-primary">
<i class="fas fa-arrow-left me-1"></i>Back to List
</a>
</div>
</div>
<form method="post" id="surgical-note-form" novalidate>
{% csrf_token %}
<!-- Template Selector -->
{% if not note.pk %}
<div class="template-selector">
<div class="row align-items-center">
<div class="col-md-8">
<h6 class="mb-1">
<i class="fas fa-clipboard-list me-2"></i>Use Template
</h6>
<p class="mb-0 text-muted">Start with a pre-defined template to speed up note creation</p>
</div>
<div class="col-md-4">
<select class="form-select" id="template-selector">
<option value="">Select Template...</option>
{% for template in templates %}
<option value="{{ template.id }}" data-content="{{ template.content }}">
{{ template.name }}
</option>
{% endfor %}
</select>
</div>
</div>
</div>
{% endif %}
<!-- Basic Information -->
<div class="form-section">
<div class="section-header">
<i class="fas fa-info-circle me-2"></i>Basic Information
</div>
<div class="section-content">
<div class="row">
<div class="col-md-6">
<div class="form-floating mb-3">
{{ form.patient }}
<label for="{{ form.patient.id_for_label }}" class="required-field">Patient</label>
{% if form.patient.errors %}
<div class="invalid-feedback d-block">{{ form.patient.errors.0 }}</div>
{% endif %}
<div class="field-help">Search and select the patient for this surgical note</div>
</div>
</div>
<div class="col-md-6">
<div class="form-floating mb-3">
{{ form.surgeon }}
<label for="{{ form.surgeon.id_for_label }}" class="required-field">Primary Surgeon</label>
{% if form.surgeon.errors %}
<div class="invalid-feedback d-block">{{ form.surgeon.errors.0 }}</div>
{% endif %}
<div class="field-help">Select the primary surgeon performing the procedure</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-floating mb-3">
{{ form.procedure_name }}
<label for="{{ form.procedure_name.id_for_label }}" class="required-field">Procedure Name</label>
{% if form.procedure_name.errors %}
<div class="invalid-feedback d-block">{{ form.procedure_name.errors.0 }}</div>
{% endif %}
<div class="field-help">Enter the name of the surgical procedure</div>
</div>
</div>
<div class="col-md-6">
<div class="form-floating mb-3">
{{ form.procedure_code }}
<label for="{{ form.procedure_code.id_for_label }}">Procedure Code</label>
{% if form.procedure_code.errors %}
<div class="invalid-feedback d-block">{{ form.procedure_code.errors.0 }}</div>
{% endif %}
<div class="field-help">CPT or ICD-10 procedure code (optional)</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="mb-3">
<label for="{{ form.surgery_date.id_for_label }}" class="form-label required-field">Surgery Date</label>
{{ form.surgery_date }}
{% if form.surgery_date.errors %}
<div class="invalid-feedback d-block">{{ form.surgery_date.errors.0 }}</div>
{% endif %}
<div class="field-help">Date when the surgery was performed</div>
</div>
</div>
<div class="col-md-4">
<div class="mb-3">
<label for="{{ form.start_time.id_for_label }}" class="form-label">Start Time</label>
{{ form.start_time }}
{% if form.start_time.errors %}
<div class="invalid-feedback d-block">{{ form.start_time.errors.0 }}</div>
{% endif %}
<div class="field-help">Time when the surgery started</div>
</div>
</div>
<div class="col-md-4">
<div class="mb-3">
<label for="{{ form.end_time.id_for_label }}" class="form-label">End Time</label>
{{ form.end_time }}
{% if form.end_time.errors %}
<div class="invalid-feedback d-block">{{ form.end_time.errors.0 }}</div>
{% endif %}
<div class="field-help">Time when the surgery ended</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.status.id_for_label }}" class="form-label required-field">Status</label>
{{ form.status }}
{% if form.status.errors %}
<div class="invalid-feedback d-block">{{ form.status.errors.0 }}</div>
{% endif %}
<div class="field-help">Current status of the surgical note</div>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.priority.id_for_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 class="field-help">Priority level for this surgical note</div>
</div>
</div>
</div>
</div>
</div>
<!-- Surgical Team -->
<div class="form-section">
<div class="section-header">
<i class="fas fa-users me-2"></i>Surgical Team
</div>
<div class="section-content">
<div class="row">
<div class="col-md-6">
<div class="form-floating mb-3">
{{ form.assistant_surgeon }}
<label for="{{ form.assistant_surgeon.id_for_label }}">Assistant Surgeon</label>
{% if form.assistant_surgeon.errors %}
<div class="invalid-feedback d-block">{{ form.assistant_surgeon.errors.0 }}</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="form-floating mb-3">
{{ form.anesthesiologist }}
<label for="{{ form.anesthesiologist.id_for_label }}">Anesthesiologist</label>
{% if form.anesthesiologist.errors %}
<div class="invalid-feedback d-block">{{ form.anesthesiologist.errors.0 }}</div>
{% endif %}
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-floating mb-3">
{{ form.scrub_nurse }}
<label for="{{ form.scrub_nurse.id_for_label }}">Scrub Nurse</label>
{% if form.scrub_nurse.errors %}
<div class="invalid-feedback d-block">{{ form.scrub_nurse.errors.0 }}</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="form-floating mb-3">
{{ form.circulating_nurse }}
<label for="{{ form.circulating_nurse.id_for_label }}">Circulating Nurse</label>
{% if form.circulating_nurse.errors %}
<div class="invalid-feedback d-block">{{ form.circulating_nurse.errors.0 }}</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
<!-- Pre-operative Information -->
<div class="form-section">
<div class="section-header">
<i class="fas fa-clipboard-check me-2"></i>Pre-operative Information
</div>
<div class="section-content">
<div class="mb-3">
<label for="{{ form.preoperative_diagnosis.id_for_label }}" class="form-label required-field">Pre-operative Diagnosis</label>
{{ form.preoperative_diagnosis }}
{% if form.preoperative_diagnosis.errors %}
<div class="invalid-feedback d-block">{{ form.preoperative_diagnosis.errors.0 }}</div>
{% endif %}
<div class="field-help">Enter the diagnosis before surgery</div>
</div>
<div class="mb-3">
<label for="{{ form.indication.id_for_label }}" class="form-label">Indication for Surgery</label>
{{ form.indication }}
{% if form.indication.errors %}
<div class="invalid-feedback d-block">{{ form.indication.errors.0 }}</div>
{% endif %}
<div class="field-help">Reason or indication for performing the surgery</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-floating mb-3">
{{ form.anesthesia_type }}
<label for="{{ form.anesthesia_type.id_for_label }}">Anesthesia Type</label>
{% if form.anesthesia_type.errors %}
<div class="invalid-feedback d-block">{{ form.anesthesia_type.errors.0 }}</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="form-floating mb-3">
{{ form.patient_position }}
<label for="{{ form.patient_position.id_for_label }}">Patient Position</label>
{% if form.patient_position.errors %}
<div class="invalid-feedback d-block">{{ form.patient_position.errors.0 }}</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
<!-- Operative Procedure -->
<div class="form-section">
<div class="section-header">
<i class="fas fa-procedures me-2"></i>Operative Procedure
</div>
<div class="section-content">
<div class="mb-3">
<label for="{{ form.procedure_description.id_for_label }}" class="form-label required-field">Procedure Description</label>
{{ form.procedure_description }}
{% if form.procedure_description.errors %}
<div class="invalid-feedback d-block">{{ form.procedure_description.errors.0 }}</div>
{% endif %}
<div class="field-help">Detailed description of the surgical procedure performed</div>
</div>
<div class="mb-3">
<label for="{{ form.technique.id_for_label }}" class="form-label">Surgical Technique</label>
{{ form.technique }}
{% if form.technique.errors %}
<div class="invalid-feedback d-block">{{ form.technique.errors.0 }}</div>
{% endif %}
<div class="field-help">Specific surgical techniques and approaches used</div>
</div>
<div class="mb-3">
<label for="{{ form.findings.id_for_label }}" class="form-label">Operative Findings</label>
{{ form.findings }}
{% if form.findings.errors %}
<div class="invalid-feedback d-block">{{ form.findings.errors.0 }}</div>
{% endif %}
<div class="field-help">Findings discovered during the surgical procedure</div>
</div>
<div class="mb-3">
<label for="{{ form.specimens.id_for_label }}" class="form-label">Specimens Removed</label>
{{ form.specimens }}
{% if form.specimens.errors %}
<div class="invalid-feedback d-block">{{ form.specimens.errors.0 }}</div>
{% endif %}
<div class="field-help">Description of any specimens removed during surgery</div>
</div>
</div>
</div>
<!-- Post-operative Information -->
<div class="form-section">
<div class="section-header">
<i class="fas fa-heartbeat me-2"></i>Post-operative Information
</div>
<div class="section-content">
<div class="mb-3">
<label for="{{ form.postoperative_diagnosis.id_for_label }}" class="form-label">Post-operative Diagnosis</label>
{{ form.postoperative_diagnosis }}
{% if form.postoperative_diagnosis.errors %}
<div class="invalid-feedback d-block">{{ form.postoperative_diagnosis.errors.0 }}</div>
{% endif %}
<div class="field-help">Final diagnosis after surgery completion</div>
</div>
<div class="mb-3">
<label for="{{ form.complications.id_for_label }}" class="form-label">Complications</label>
{{ form.complications }}
{% if form.complications.errors %}
<div class="invalid-feedback d-block">{{ form.complications.errors.0 }}</div>
{% endif %}
<div class="field-help">Any complications that occurred during or after surgery</div>
</div>
<div class="mb-3">
<label for="{{ form.postoperative_instructions.id_for_label }}" class="form-label">Post-operative Instructions</label>
{{ form.postoperative_instructions }}
{% if form.postoperative_instructions.errors %}
<div class="invalid-feedback d-block">{{ form.postoperative_instructions.errors.0 }}</div>
{% endif %}
<div class="field-help">Instructions for post-operative care and recovery</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-floating mb-3">
{{ form.estimated_blood_loss }}
<label for="{{ form.estimated_blood_loss.id_for_label }}">Estimated Blood Loss (mL)</label>
{% if form.estimated_blood_loss.errors %}
<div class="invalid-feedback d-block">{{ form.estimated_blood_loss.errors.0 }}</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="form-floating mb-3">
{{ form.fluids_given }}
<label for="{{ form.fluids_given.id_for_label }}">Fluids Given (mL)</label>
{% if form.fluids_given.errors %}
<div class="invalid-feedback d-block">{{ form.fluids_given.errors.0 }}</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
<!-- Equipment and Implants -->
<div class="form-section">
<div class="section-header">
<i class="fas fa-tools me-2"></i>Equipment and Implants
</div>
<div class="section-content">
<div class="mb-3">
<label for="{{ form.equipment_used.id_for_label }}" class="form-label">Equipment Used</label>
{{ form.equipment_used }}
{% if form.equipment_used.errors %}
<div class="invalid-feedback d-block">{{ form.equipment_used.errors.0 }}</div>
{% endif %}
<div class="field-help">List of surgical equipment and instruments used</div>
</div>
<div class="mb-3">
<label for="{{ form.implants.id_for_label }}" class="form-label">Implants and Prosthetics</label>
{{ form.implants }}
{% if form.implants.errors %}
<div class="invalid-feedback d-block">{{ form.implants.errors.0 }}</div>
{% endif %}
<div class="field-help">Details of any implants or prosthetic devices used</div>
</div>
<div class="mb-3">
<label for="{{ form.suture_materials.id_for_label }}" class="form-label">Suture Materials</label>
{{ form.suture_materials }}
{% if form.suture_materials.errors %}
<div class="invalid-feedback d-block">{{ form.suture_materials.errors.0 }}</div>
{% endif %}
<div class="field-help">Types and sizes of suture materials used</div>
</div>
</div>
</div>
<!-- Additional Notes -->
<div class="form-section">
<div class="section-header">
<i class="fas fa-sticky-note me-2"></i>Additional Information
</div>
<div class="section-content">
<div class="mb-3">
<label for="{{ form.additional_notes.id_for_label }}" class="form-label">Additional Notes</label>
{{ form.additional_notes }}
{% if form.additional_notes.errors %}
<div class="invalid-feedback d-block">{{ form.additional_notes.errors.0 }}</div>
{% endif %}
<div class="field-help">Any additional observations or notes</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-check mb-3">
{{ form.is_emergency }}
<label class="form-check-label" for="{{ form.is_emergency.id_for_label }}">
Emergency Surgery
</label>
<div class="field-help">Check if this was an emergency surgical procedure</div>
</div>
</div>
<div class="col-md-6">
<div class="form-check mb-3">
{{ form.requires_followup }}
<label class="form-check-label" for="{{ form.requires_followup.id_for_label }}">
Requires Follow-up
</label>
<div class="field-help">Check if patient requires follow-up care</div>
</div>
</div>
</div>
</div>
</div>
<!-- Electronic Signature -->
{% if note.pk and note.status == 'completed' %}
<div class="form-section">
<div class="section-header">
<i class="fas fa-signature me-2"></i>Electronic Signature
</div>
<div class="section-content">
<div class="signature-pad">
<h6 class="mb-3">Surgeon's Signature</h6>
<canvas id="signature-canvas" class="signature-canvas" width="600" height="150"></canvas>
<div class="mt-3">
<button type="button" class="btn btn-outline-secondary btn-sm me-2" onclick="clearSignature()">
<i class="fas fa-eraser me-1"></i>Clear
</button>
<button type="button" class="btn btn-primary btn-sm" onclick="saveSignature()">
<i class="fas fa-save me-1"></i>Save Signature
</button>
</div>
<input type="hidden" id="signature-data" name="signature_data">
</div>
<div class="row mt-3">
<div class="col-md-6">
<div class="form-floating">
<input type="text" class="form-control" id="signature-name"
value="{{ user.get_full_name }}" readonly>
<label for="signature-name">Signatory Name</label>
</div>
</div>
<div class="col-md-6">
<div class="form-floating">
<input type="datetime-local" class="form-control" id="signature-date"
value="{% now 'Y-m-d\TH:i' %}" readonly>
<label for="signature-date">Signature Date & Time</label>
</div>
</div>
</div>
</div>
</div>
{% endif %}
<!-- Form Actions -->
<div class="form-actions d-flex justify-content-between align-items-center">
<div>
<button type="button" class="btn btn-outline-secondary" onclick="previewNote()">
<i class="fas fa-eye me-1"></i>Preview
</button>
<button type="button" class="btn btn-outline-info" onclick="validateForm()">
<i class="fas fa-check-circle me-1"></i>Validate
</button>
</div>
<div>
<a href="{% url 'operating_theatre:surgical_note_list' %}" class="btn btn-outline-secondary me-2">
<i class="fas fa-times me-1"></i>Cancel
</a>
<button type="submit" name="action" value="save_draft" class="btn btn-outline-primary me-2">
<i class="fas fa-save me-1"></i>Save Draft
</button>
<button type="submit" name="action" value="save_complete" class="btn btn-success">
<i class="fas fa-check me-1"></i>
{% if note.pk %}Update Note{% else %}Create Note{% endif %}
</button>
</div>
</div>
</form>
</div>
<!-- Preview Modal -->
<div class="modal fade" id="previewModal" tabindex="-1">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
<i class="fas fa-eye me-2"></i>Surgical Note Preview
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body" id="preview-content">
<!-- Preview content will be loaded here -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">
<i class="fas fa-times me-1"></i>Close
</button>
<button type="button" class="btn btn-primary" onclick="printPreview()">
<i class="fas fa-print me-1"></i>Print Preview
</button>
</div>
</div>
</div>
</div>
<!-- Validation Modal -->
<div class="modal fade" id="validationModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">
<i class="fas fa-check-circle me-2"></i>Form Validation
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body" id="validation-content">
<!-- Validation results will be loaded here -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">
<i class="fas fa-check me-1"></i>OK
</button>
</div>
</div>
</div>
</div>
{% endblock %}
{% block js %}
<script src="{% static 'assets/plugins/select2/dist/js/select2.min.js' %}"></script>
<script src="{% static 'assets/plugins/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js' %}"></script>
<script src="{% static 'assets/plugins/bootstrap-timepicker/js/bootstrap-timepicker.min.js' %}"></script>
<script>
$(document).ready(function() {
// Initialize Select2 for dropdowns
$('.form-select').select2({
theme: 'bootstrap-5',
width: '100%'
});
// Initialize date picker
$('input[type="date"]').datepicker({
format: 'yyyy-mm-dd',
autoclose: true,
todayHighlight: true
});
// Initialize time picker
$('input[type="time"]').timepicker({
showMeridian: false,
defaultTime: false
});
// Template selector
$('#template-selector').on('change', function() {
const templateContent = $(this).find(':selected').data('content');
if (templateContent) {
loadTemplate(templateContent);
}
});
// Auto-save functionality
let autoSaveTimer;
$('form input, form textarea, form select').on('input change', function() {
clearTimeout(autoSaveTimer);
autoSaveTimer = setTimeout(autoSave, 30000); // Auto-save after 30 seconds of inactivity
});
// Form validation
$('#surgical-note-form').on('submit', function(e) {
if (!validateRequiredFields()) {
e.preventDefault();
showValidationErrors();
}
});
// Initialize signature pad if present
if (document.getElementById('signature-canvas')) {
initializeSignaturePad();
}
});
function loadTemplate(templateContent) {
if (confirm('Loading a template will replace current content. Continue?')) {
try {
const template = JSON.parse(templateContent);
// Populate form fields from template
Object.keys(template).forEach(key => {
const field = document.querySelector(`[name="${key}"]`);
if (field) {
field.value = template[key];
$(field).trigger('change');
}
});
showAlert('Template loaded successfully', 'success');
} catch (error) {
showAlert('Error loading template', 'danger');
}
}
}
function autoSave() {
const formData = new FormData(document.getElementById('surgical-note-form'));
formData.append('action', 'auto_save');
fetch(window.location.href, {
method: 'POST',
body: formData,
headers: {
'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
showAutoSaveIndicator();
}
})
.catch(error => {
console.error('Auto-save failed:', error);
});
}
function showAutoSaveIndicator() {
const indicator = document.getElementById('auto-save-indicator');
indicator.style.display = 'block';
setTimeout(() => {
indicator.style.display = 'none';
}, 2000);
}
function saveDraft() {
const form = document.getElementById('surgical-note-form');
const actionInput = document.createElement('input');
actionInput.type = 'hidden';
actionInput.name = 'action';
actionInput.value = 'save_draft';
form.appendChild(actionInput);
form.submit();
}
function previewNote() {
const formData = new FormData(document.getElementById('surgical-note-form'));
fetch('{% url "operating_theatre:surgical_note_preview" %}', {
method: 'POST',
body: formData,
headers: {
'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value
}
})
.then(response => response.text())
.then(html => {
document.getElementById('preview-content').innerHTML = html;
new bootstrap.Modal(document.getElementById('previewModal')).show();
})
.catch(error => {
showAlert('Error generating preview', 'danger');
});
}
function validateForm() {
const errors = [];
const requiredFields = document.querySelectorAll('[required]');
requiredFields.forEach(field => {
if (!field.value.trim()) {
errors.push(`${field.labels[0].textContent} is required`);
}
});
// Custom validation rules
const startTime = document.querySelector('[name="start_time"]').value;
const endTime = document.querySelector('[name="end_time"]').value;
if (startTime && endTime && startTime >= endTime) {
errors.push('End time must be after start time');
}
const bloodLoss = document.querySelector('[name="estimated_blood_loss"]').value;
if (bloodLoss && (isNaN(bloodLoss) || bloodLoss < 0)) {
errors.push('Blood loss must be a positive number');
}
// Display validation results
let content = '';
if (errors.length === 0) {
content = `
<div class="alert alert-success">
<i class="fas fa-check-circle me-2"></i>
All form fields are valid and ready for submission.
</div>
`;
} else {
content = `
<div class="alert alert-danger">
<h6><i class="fas fa-exclamation-triangle me-2"></i>Validation Errors:</h6>
<ul class="mb-0">
${errors.map(error => `<li>${error}</li>`).join('')}
</ul>
</div>
`;
}
document.getElementById('validation-content').innerHTML = content;
new bootstrap.Modal(document.getElementById('validationModal')).show();
}
function validateRequiredFields() {
const requiredFields = document.querySelectorAll('[required]');
let isValid = true;
requiredFields.forEach(field => {
if (!field.value.trim()) {
field.classList.add('is-invalid');
isValid = false;
} else {
field.classList.remove('is-invalid');
}
});
return isValid;
}
function showValidationErrors() {
showAlert('Please fill in all required fields', 'danger');
}
function printPreview() {
const printContent = document.getElementById('preview-content').innerHTML;
const printWindow = window.open('', '_blank');
printWindow.document.write(`
<html>
<head>
<title>Surgical Note Preview</title>
<link href="{% static 'assets/css/vendor.min.css' %}" rel="stylesheet">
<link href="{% static 'assets/css/app.min.css' %}" rel="stylesheet">
<style>
body { font-family: Arial, sans-serif; }
@media print {
.no-print { display: none !important; }
}
</style>
</head>
<body>
${printContent}
</body>
</html>
`);
printWindow.document.close();
printWindow.print();
}
// Signature pad functionality
let signaturePad;
function initializeSignaturePad() {
const canvas = document.getElementById('signature-canvas');
const ctx = canvas.getContext('2d');
let isDrawing = false;
let lastX = 0;
let lastY = 0;
canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', stopDrawing);
canvas.addEventListener('mouseout', stopDrawing);
// Touch events for mobile
canvas.addEventListener('touchstart', handleTouch);
canvas.addEventListener('touchmove', handleTouch);
canvas.addEventListener('touchend', stopDrawing);
function startDrawing(e) {
isDrawing = true;
[lastX, lastY] = getMousePos(e);
}
function draw(e) {
if (!isDrawing) return;
const [currentX, currentY] = getMousePos(e);
ctx.beginPath();
ctx.moveTo(lastX, lastY);
ctx.lineTo(currentX, currentY);
ctx.strokeStyle = '#000';
ctx.lineWidth = 2;
ctx.lineCap = 'round';
ctx.stroke();
[lastX, lastY] = [currentX, currentY];
}
function stopDrawing() {
isDrawing = false;
}
function getMousePos(e) {
const rect = canvas.getBoundingClientRect();
return [
e.clientX - rect.left,
e.clientY - rect.top
];
}
function handleTouch(e) {
e.preventDefault();
const touch = e.touches[0];
const mouseEvent = new MouseEvent(e.type === 'touchstart' ? 'mousedown' :
e.type === 'touchmove' ? 'mousemove' : 'mouseup', {
clientX: touch.clientX,
clientY: touch.clientY
});
canvas.dispatchEvent(mouseEvent);
}
}
function clearSignature() {
const canvas = document.getElementById('signature-canvas');
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
document.getElementById('signature-data').value = '';
}
function saveSignature() {
const canvas = document.getElementById('signature-canvas');
const signatureData = canvas.toDataURL();
document.getElementById('signature-data').value = signatureData;
showAlert('Signature saved', 'success');
}
function showAlert(message, type) {
const alertDiv = document.createElement('div');
alertDiv.className = `alert alert-${type} alert-dismissible fade show position-fixed`;
alertDiv.style.cssText = 'top: 20px; right: 20px; z-index: 1060; min-width: 300px;';
alertDiv.innerHTML = `
${message}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
`;
document.body.appendChild(alertDiv);
setTimeout(() => {
if (alertDiv.parentNode) {
alertDiv.remove();
}
}, 5000);
}
</script>
{% endblock %}