597 lines
21 KiB
HTML
597 lines
21 KiB
HTML
{% extends 'base.html' %}
|
|
{% load static %}
|
|
|
|
{% block title %}Delete Surgical Note - {{ note.patient.get_full_name }}{% endblock %}
|
|
|
|
{% block css %}
|
|
<style>
|
|
.delete-header {
|
|
background: linear-gradient(135deg, #dc3545 0%, #c82333 100%);
|
|
color: white;
|
|
border-radius: 0.5rem;
|
|
padding: 2rem;
|
|
margin-bottom: 2rem;
|
|
}
|
|
|
|
.warning-section {
|
|
background: #fff3cd;
|
|
border: 1px solid #ffeaa7;
|
|
border-radius: 0.375rem;
|
|
padding: 1.5rem;
|
|
margin-bottom: 2rem;
|
|
}
|
|
|
|
.note-details {
|
|
background: white;
|
|
border: 1px solid #dee2e6;
|
|
border-radius: 0.375rem;
|
|
margin-bottom: 2rem;
|
|
}
|
|
|
|
.detail-header {
|
|
background: #f8f9fa;
|
|
border-bottom: 1px solid #dee2e6;
|
|
padding: 1rem 1.5rem;
|
|
font-weight: 600;
|
|
color: #495057;
|
|
}
|
|
|
|
.detail-content {
|
|
padding: 1.5rem;
|
|
}
|
|
|
|
.info-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
gap: 1rem;
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
|
|
.info-item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.info-label {
|
|
font-size: 0.875rem;
|
|
color: #6c757d;
|
|
font-weight: 600;
|
|
margin-bottom: 0.25rem;
|
|
}
|
|
|
|
.info-value {
|
|
color: #495057;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.note-status {
|
|
padding: 0.5rem 1rem;
|
|
border-radius: 0.25rem;
|
|
font-size: 0.875rem;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
display: inline-block;
|
|
}
|
|
|
|
.status-draft { background: #f8f9fa; color: #6c757d; }
|
|
.status-in-progress { background: #fff3cd; color: #856404; }
|
|
.status-completed { background: #d4edda; color: #155724; }
|
|
.status-signed { background: #d1ecf1; color: #0c5460; }
|
|
.status-amended { background: #f8d7da; color: #721c24; }
|
|
|
|
.priority-badge {
|
|
padding: 0.25rem 0.75rem;
|
|
border-radius: 0.25rem;
|
|
font-size: 0.75rem;
|
|
font-weight: 600;
|
|
display: inline-block;
|
|
}
|
|
|
|
.priority-low { background: #d4edda; color: #155724; }
|
|
.priority-medium { background: #fff3cd; color: #856404; }
|
|
.priority-high { background: #f8d7da; color: #721c24; }
|
|
.priority-critical { background: #f5c6cb; color: #721c24; }
|
|
|
|
.consequences-list {
|
|
background: #f8d7da;
|
|
border: 1px solid #f5c6cb;
|
|
border-radius: 0.375rem;
|
|
padding: 1.5rem;
|
|
margin-bottom: 2rem;
|
|
}
|
|
|
|
.consequences-list h6 {
|
|
color: #721c24;
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
.consequences-list ul {
|
|
color: #721c24;
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.confirmation-section {
|
|
background: #fff;
|
|
border: 2px solid #dc3545;
|
|
border-radius: 0.375rem;
|
|
padding: 2rem;
|
|
margin-bottom: 2rem;
|
|
}
|
|
|
|
.confirmation-checkbox {
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
.confirmation-checkbox .form-check-input:checked {
|
|
background-color: #dc3545;
|
|
border-color: #dc3545;
|
|
}
|
|
|
|
.delete-reason {
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
|
|
.action-buttons {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding-top: 2rem;
|
|
border-top: 1px solid #dee2e6;
|
|
}
|
|
|
|
.btn-delete {
|
|
background: #dc3545;
|
|
border-color: #dc3545;
|
|
color: white;
|
|
}
|
|
|
|
.btn-delete:hover {
|
|
background: #c82333;
|
|
border-color: #bd2130;
|
|
color: white;
|
|
}
|
|
|
|
.btn-delete:disabled {
|
|
background: #6c757d;
|
|
border-color: #6c757d;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.delete-header {
|
|
padding: 1.5rem;
|
|
}
|
|
|
|
.detail-content {
|
|
padding: 1rem;
|
|
}
|
|
|
|
.info-grid {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.action-buttons {
|
|
flex-direction: column;
|
|
gap: 1rem;
|
|
}
|
|
|
|
.action-buttons .btn {
|
|
width: 100%;
|
|
}
|
|
}
|
|
|
|
@media print {
|
|
.action-buttons, .confirmation-section {
|
|
display: none !important;
|
|
}
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div id="content" class="app-content">
|
|
<!-- 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"><a href="{% url 'operating_theatre:surgical_note_detail' note.pk %}">{{ note.patient.get_full_name }}</a></li>
|
|
<li class="breadcrumb-item active">Delete</li>
|
|
</ol>
|
|
<h1 class="page-header mb-0">
|
|
<i class="fas fa-trash-alt me-2"></i>Delete Surgical Note
|
|
</h1>
|
|
</div>
|
|
<div class="ms-auto">
|
|
<a href="{% url 'operating_theatre:surgical_note_detail' note.pk %}" class="btn btn-outline-primary">
|
|
<i class="fas fa-arrow-left me-1"></i>Back to Note
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Delete Warning Header -->
|
|
<div class="delete-header text-center">
|
|
<div class="mb-3">
|
|
<i class="fas fa-exclamation-triangle fa-4x"></i>
|
|
</div>
|
|
<h2 class="mb-2">Confirm Deletion</h2>
|
|
<p class="mb-0 fs-5">You are about to permanently delete this surgical note</p>
|
|
</div>
|
|
|
|
<!-- Warning Section -->
|
|
<div class="warning-section">
|
|
<div class="d-flex align-items-center mb-3">
|
|
<i class="fas fa-exclamation-triangle fa-2x text-warning me-3"></i>
|
|
<div>
|
|
<h5 class="mb-1 text-warning">Warning: This action cannot be undone</h5>
|
|
<p class="mb-0">Deleting this surgical note will permanently remove all associated data from the system.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Note Details -->
|
|
<div class="note-details">
|
|
<div class="detail-header">
|
|
<i class="fas fa-file-medical me-2"></i>Surgical Note Details
|
|
</div>
|
|
<div class="detail-content">
|
|
<div class="info-grid">
|
|
<div class="info-item">
|
|
<div class="info-label">Patient</div>
|
|
<div class="info-value">
|
|
<strong>{{ note.patient.get_full_name }}</strong><br>
|
|
<small class="text-muted">ID: {{ note.patient.patient_id }}</small>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="info-item">
|
|
<div class="info-label">Procedure</div>
|
|
<div class="info-value">
|
|
<strong>{{ note.procedure_name }}</strong><br>
|
|
{% if note.procedure_code %}
|
|
<small class="text-muted">Code: {{ note.procedure_code }}</small>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="info-item">
|
|
<div class="info-label">Surgeon</div>
|
|
<div class="info-value">
|
|
<strong>{{ note.surgeon.get_full_name }}</strong><br>
|
|
{% if note.surgeon.specialization %}
|
|
<small class="text-muted">{{ note.surgeon.specialization }}</small>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="info-item">
|
|
<div class="info-label">Surgery Date</div>
|
|
<div class="info-value">
|
|
<strong>{{ note.surgery_date|date:"F d, Y" }}</strong><br>
|
|
<small class="text-muted">{{ note.surgery_date|time:"g:i A" }}</small>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="info-item">
|
|
<div class="info-label">Status</div>
|
|
<div class="info-value">
|
|
<span class="note-status status-{{ note.status }}">
|
|
{{ note.get_status_display }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="info-item">
|
|
<div class="info-label">Priority</div>
|
|
<div class="info-value">
|
|
<span class="priority-badge priority-{{ note.priority }}">
|
|
{{ note.get_priority_display }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="info-item">
|
|
<div class="info-label">Created</div>
|
|
<div class="info-value">
|
|
<strong>{{ note.created_at|date:"M d, Y" }}</strong><br>
|
|
<small class="text-muted">{{ note.created_at|time:"g:i A" }}</small>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="info-item">
|
|
<div class="info-label">Last Modified</div>
|
|
<div class="info-value">
|
|
<strong>{{ note.updated_at|date:"M d, Y" }}</strong><br>
|
|
<small class="text-muted">{{ note.updated_at|time:"g:i A" }}</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{% if note.preoperative_diagnosis %}
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="info-item">
|
|
<div class="info-label">Pre-operative Diagnosis</div>
|
|
<div class="info-value">{{ note.preoperative_diagnosis|truncatewords:10 }}</div>
|
|
</div>
|
|
</div>
|
|
{% if note.postoperative_diagnosis %}
|
|
<div class="col-md-6">
|
|
<div class="info-item">
|
|
<div class="info-label">Post-operative Diagnosis</div>
|
|
<div class="info-value">{{ note.postoperative_diagnosis|truncatewords:10 }}</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Consequences -->
|
|
<div class="consequences-list">
|
|
<h6><i class="fas fa-exclamation-circle me-2"></i>Consequences of Deletion</h6>
|
|
<ul>
|
|
<li><strong>Permanent Data Loss:</strong> All surgical note content will be permanently deleted</li>
|
|
<li><strong>Audit Trail:</strong> The deletion will be logged for compliance purposes</li>
|
|
<li><strong>Patient Records:</strong> This note will no longer appear in the patient's medical history</li>
|
|
<li><strong>Reporting:</strong> This note will be excluded from all future reports and statistics</li>
|
|
{% if note.status == 'signed' %}
|
|
<li><strong>Legal Implications:</strong> Deleting a signed surgical note may have legal consequences</li>
|
|
{% endif %}
|
|
{% if note.is_emergency %}
|
|
<li><strong>Emergency Record:</strong> This emergency surgical record will be permanently lost</li>
|
|
{% endif %}
|
|
</ul>
|
|
</div>
|
|
|
|
<!-- Special Warnings -->
|
|
{% if note.status == 'signed' %}
|
|
<div class="alert alert-danger">
|
|
<h6><i class="fas fa-signature me-2"></i>Signed Document Warning</h6>
|
|
<p class="mb-0">This surgical note has been electronically signed. Deleting signed medical documents may violate regulatory requirements and institutional policies. Please consult with your compliance officer before proceeding.</p>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if note.is_emergency %}
|
|
<div class="alert alert-warning">
|
|
<h6><i class="fas fa-ambulance me-2"></i>Emergency Surgery Record</h6>
|
|
<p class="mb-0">This is an emergency surgical note. Emergency records are often subject to additional regulatory scrutiny and may be required for quality assurance reviews.</p>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Confirmation Form -->
|
|
<form method="post" id="delete-form">
|
|
{% csrf_token %}
|
|
|
|
<div class="confirmation-section">
|
|
<h5 class="mb-3"><i class="fas fa-check-square me-2"></i>Confirmation Required</h5>
|
|
|
|
<div class="confirmation-checkbox">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="confirm-understanding" required>
|
|
<label class="form-check-label" for="confirm-understanding">
|
|
I understand that this action will permanently delete the surgical note and cannot be undone
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="confirmation-checkbox">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="confirm-authority" required>
|
|
<label class="form-check-label" for="confirm-authority">
|
|
I have the authority to delete this surgical note
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
{% if note.status == 'signed' %}
|
|
<div class="confirmation-checkbox">
|
|
<div class="form-check">
|
|
<input class="form-check-input" type="checkbox" id="confirm-signed" required>
|
|
<label class="form-check-label" for="confirm-signed">
|
|
I acknowledge the legal implications of deleting a signed medical document
|
|
</label>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="delete-reason">
|
|
<label for="deletion-reason" class="form-label">
|
|
<i class="fas fa-comment me-1"></i>Reason for Deletion <span class="text-danger">*</span>
|
|
</label>
|
|
<textarea class="form-control" id="deletion-reason" name="deletion_reason" rows="3"
|
|
placeholder="Please provide a detailed reason for deleting this surgical note..." required></textarea>
|
|
<div class="form-text">This reason will be logged for audit purposes</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label for="confirmation-text" class="form-label">
|
|
Type "DELETE" to confirm <span class="text-danger">*</span>
|
|
</label>
|
|
<input type="text" class="form-control" id="confirmation-text"
|
|
placeholder="Type DELETE in capital letters" required>
|
|
<div class="form-text">This additional confirmation helps prevent accidental deletions</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Action Buttons -->
|
|
<div class="action-buttons">
|
|
<div>
|
|
<a href="{% url 'operating_theatre:surgical_note_detail' note.pk %}" class="btn btn-outline-secondary btn-lg">
|
|
<i class="fas fa-times me-2"></i>Cancel
|
|
</a>
|
|
<a href="{% url 'operating_theatre:surgical_note_list' %}" class="btn btn-outline-primary btn-lg ms-2">
|
|
<i class="fas fa-list me-2"></i>Back to List
|
|
</a>
|
|
</div>
|
|
|
|
<div>
|
|
<button type="button" class="btn btn-outline-info btn-lg me-2" onclick="printRecord()">
|
|
<i class="fas fa-print me-2"></i>Print Record First
|
|
</button>
|
|
<button type="submit" class="btn btn-delete btn-lg" id="delete-button" disabled>
|
|
<i class="fas fa-trash-alt me-2"></i>Delete Surgical Note
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Confirmation Modal -->
|
|
<div class="modal fade" id="finalConfirmationModal" tabindex="-1">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header bg-danger text-white">
|
|
<h5 class="modal-title">
|
|
<i class="fas fa-exclamation-triangle me-2"></i>Final Confirmation
|
|
</h5>
|
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body text-center">
|
|
<div class="mb-3">
|
|
<i class="fas fa-trash-alt fa-4x text-danger"></i>
|
|
</div>
|
|
<h5>Are you absolutely sure?</h5>
|
|
<p class="text-muted">This surgical note will be permanently deleted. This action cannot be undone.</p>
|
|
|
|
<div class="alert alert-danger">
|
|
<strong>Patient:</strong> {{ note.patient.get_full_name }}<br>
|
|
<strong>Procedure:</strong> {{ note.procedure_name }}<br>
|
|
<strong>Date:</strong> {{ note.surgery_date|date:"F d, Y" }}
|
|
</div>
|
|
</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>Cancel
|
|
</button>
|
|
<button type="button" class="btn btn-danger" onclick="confirmDelete()">
|
|
<i class="fas fa-trash-alt me-1"></i>Yes, Delete Permanently
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block js %}
|
|
<script>
|
|
$(document).ready(function() {
|
|
// Enable/disable delete button based on confirmations
|
|
function checkConfirmations() {
|
|
const checkboxes = document.querySelectorAll('.confirmation-checkbox input[type="checkbox"]');
|
|
const confirmationText = document.getElementById('confirmation-text').value.trim();
|
|
const deletionReason = document.getElementById('deletion-reason').value.trim();
|
|
const deleteButton = document.getElementById('delete-button');
|
|
|
|
let allChecked = true;
|
|
checkboxes.forEach(checkbox => {
|
|
if (!checkbox.checked) {
|
|
allChecked = false;
|
|
}
|
|
});
|
|
|
|
const isValid = allChecked &&
|
|
confirmationText === 'DELETE' &&
|
|
deletionReason.length >= 10;
|
|
|
|
deleteButton.disabled = !isValid;
|
|
|
|
if (isValid) {
|
|
deleteButton.classList.remove('btn-secondary');
|
|
deleteButton.classList.add('btn-delete');
|
|
} else {
|
|
deleteButton.classList.remove('btn-delete');
|
|
deleteButton.classList.add('btn-secondary');
|
|
}
|
|
}
|
|
|
|
// Attach event listeners
|
|
document.querySelectorAll('.confirmation-checkbox input[type="checkbox"]').forEach(checkbox => {
|
|
checkbox.addEventListener('change', checkConfirmations);
|
|
});
|
|
|
|
document.getElementById('confirmation-text').addEventListener('input', checkConfirmations);
|
|
document.getElementById('deletion-reason').addEventListener('input', checkConfirmations);
|
|
|
|
// Form submission
|
|
document.getElementById('delete-form').addEventListener('submit', function(e) {
|
|
e.preventDefault();
|
|
|
|
// Show final confirmation modal
|
|
const modal = new bootstrap.Modal(document.getElementById('finalConfirmationModal'));
|
|
modal.show();
|
|
});
|
|
|
|
// Initial check
|
|
checkConfirmations();
|
|
});
|
|
|
|
function confirmDelete() {
|
|
// Close modal
|
|
const modal = bootstrap.Modal.getInstance(document.getElementById('finalConfirmationModal'));
|
|
modal.hide();
|
|
|
|
// Show loading state
|
|
const deleteButton = document.getElementById('delete-button');
|
|
const originalText = deleteButton.innerHTML;
|
|
deleteButton.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>Deleting...';
|
|
deleteButton.disabled = true;
|
|
|
|
// Submit form
|
|
setTimeout(() => {
|
|
document.getElementById('delete-form').submit();
|
|
}, 1000);
|
|
}
|
|
|
|
function printRecord() {
|
|
// Open the surgical note detail page in a new window for printing
|
|
const printUrl = "{% url 'operating_theatre:surgical_note_detail' note.pk %}?print=1";
|
|
const printWindow = window.open(printUrl, '_blank');
|
|
|
|
printWindow.onload = function() {
|
|
setTimeout(() => {
|
|
printWindow.print();
|
|
}, 1000);
|
|
};
|
|
}
|
|
|
|
// Prevent accidental page navigation
|
|
window.addEventListener('beforeunload', function(e) {
|
|
const form = document.getElementById('delete-form');
|
|
const formData = new FormData(form);
|
|
|
|
// Check if user has started filling the form
|
|
if (formData.get('deletion_reason') ||
|
|
document.getElementById('confirmation-text').value ||
|
|
document.querySelector('.confirmation-checkbox input:checked')) {
|
|
|
|
e.preventDefault();
|
|
e.returnValue = 'You have unsaved changes. Are you sure you want to leave?';
|
|
return e.returnValue;
|
|
}
|
|
});
|
|
|
|
// Auto-save draft reason (for audit purposes)
|
|
let autoSaveTimer;
|
|
document.getElementById('deletion-reason').addEventListener('input', function() {
|
|
clearTimeout(autoSaveTimer);
|
|
autoSaveTimer = setTimeout(() => {
|
|
// Save draft reason to session storage
|
|
sessionStorage.setItem('deletion_reason_draft', this.value);
|
|
}, 2000);
|
|
});
|
|
|
|
// Restore draft reason on page load
|
|
window.addEventListener('load', function() {
|
|
const draftReason = sessionStorage.getItem('deletion_reason_draft');
|
|
if (draftReason) {
|
|
document.getElementById('deletion-reason').value = draftReason;
|
|
}
|
|
});
|
|
</script>
|
|
{% endblock %}
|
|
|