hospital-management/templates/patients/consents/patient_consent_form.html
2025-08-12 13:33:25 +03:00

660 lines
30 KiB
HTML

{% extends "base.html" %}
{% load static %}
{% block title %}{% if object %}Edit{% else %}Request{% endif %} Patient Consent - Patients{% endblock %}
{% block content %}
<!-- BEGIN breadcrumb -->
<ol class="breadcrumb float-xl-end">
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
<li class="breadcrumb-item"><a href="{% url 'patients:patient_list' %}">Patients</a></li>
<li class="breadcrumb-item"><a href="{% url 'patients:patient_consent_list' %}">Patient Consents</a></li>
{% if object %}
<li class="breadcrumb-item"><a href="{% url 'patients:patient_consent_detail' object.pk %}">{{ object.consent_form.title|truncatechars:20 }}</a></li>
<li class="breadcrumb-item active">Edit</li>
{% else %}
<li class="breadcrumb-item active">Request</li>
{% endif %}
</ol>
<!-- END breadcrumb -->
<!-- BEGIN page-header -->
<h1 class="page-header">
{% if object %}Edit Patient Consent{% else %}Request Patient Consent{% endif %}
<small>{% if object %}{{ object.consent_form.title }}{% else %}New consent request{% endif %}</small>
</h1>
<!-- END page-header -->
<div class="row">
<div class="col-xl-8">
<!-- BEGIN panel -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Consent Request Details</h4>
<div class="panel-heading-btn">
<button type="button" class="btn btn-xs btn-info me-2" onclick="previewForm()">
<i class="fa fa-eye"></i> Preview
</button>
<button type="button" class="btn btn-xs btn-secondary me-2" onclick="saveDraft()">
<i class="fa fa-save"></i> Save Draft
</button>
<a href="javascript:;" class="btn btn-xs btn-icon btn-default" data-toggle="panel-expand"><i class="fa fa-expand"></i></a>
</div>
</div>
<div class="panel-body">
<form method="post" id="consent-request-form" novalidate>
{% csrf_token %}
<div class="row mb-3">
<div class="col-md-6">
<div class="form-floating">
{{ form.patient }}
<label for="{{ form.patient.id_for_label }}">Patient <span class="text-danger">*</span></label>
{% if form.patient.errors %}
<div class="invalid-feedback d-block">{{ form.patient.errors.0 }}</div>
{% endif %}
</div>
<div class="form-text">Select the patient who needs to provide consent.</div>
</div>
<div class="col-md-6">
<div class="form-floating">
{{ form.consent_form }}
<label for="{{ form.consent_form.id_for_label }}">Consent Form <span class="text-danger">*</span></label>
{% if form.consent_form.errors %}
<div class="invalid-feedback d-block">{{ form.consent_form.errors.0 }}</div>
{% endif %}
</div>
<div class="form-text">Choose the type of consent form required.</div>
</div>
</div>
<!-- Patient Information Display -->
<div id="patient-info" class="card border-info mb-3" style="display: none;">
<div class="card-header bg-info text-white">
<h6 class="card-title mb-0">
<i class="fa fa-user me-2"></i>Patient Information
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div id="patient-details"></div>
</div>
<div class="col-md-6">
<div id="patient-contact"></div>
</div>
</div>
</div>
</div>
<!-- Consent Form Information Display -->
<div id="consent-form-info" class="card border-primary mb-3" style="display: none;">
<div class="card-header bg-primary text-white">
<h6 class="card-title mb-0">
<i class="fa fa-file-text me-2"></i>Consent Form Information
</h6>
</div>
<div class="card-body">
<div id="consent-form-details"></div>
</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<div class="form-floating">
{{ form.due_date }}
<label for="{{ form.due_date.id_for_label }}">Due Date</label>
{% if form.due_date.errors %}
<div class="invalid-feedback d-block">{{ form.due_date.errors.0 }}</div>
{% endif %}
</div>
<div class="form-text">Optional deadline for signing the consent.</div>
</div>
<div class="col-md-6">
<div class="form-floating">
{{ form.priority }}
<label for="{{ form.priority.id_for_label }}">Priority</label>
{% if form.priority.errors %}
<div class="invalid-feedback d-block">{{ form.priority.errors.0 }}</div>
{% endif %}
</div>
<div class="form-text">Set the urgency level for this consent request.</div>
</div>
</div>
<div class="mb-3">
<label for="{{ form.notes.id_for_label }}" class="form-label">Notes</label>
{{ form.notes }}
{% if form.notes.errors %}
<div class="invalid-feedback d-block">{{ form.notes.errors.0 }}</div>
{% endif %}
<div class="form-text">Additional information or instructions for the patient.</div>
</div>
<div class="row mb-3">
<div class="col-md-4">
<div class="form-check">
{{ form.is_urgent }}
<label class="form-check-label" for="{{ form.is_urgent.id_for_label }}">
<i class="fa fa-exclamation-triangle text-danger me-1"></i>Mark as urgent
</label>
{% if form.is_urgent.errors %}
<div class="invalid-feedback d-block">{{ form.is_urgent.errors.0 }}</div>
{% endif %}
<div class="form-text">Urgent consents receive priority handling.</div>
</div>
</div>
<div class="col-md-4">
<div class="form-check">
{{ form.send_notification }}
<label class="form-check-label" for="{{ form.send_notification.id_for_label }}">
<i class="fa fa-bell text-info me-1"></i>Send notification
</label>
{% if form.send_notification.errors %}
<div class="invalid-feedback d-block">{{ form.send_notification.errors.0 }}</div>
{% endif %}
<div class="form-text">Notify patient via email/SMS.</div>
</div>
</div>
<div class="col-md-4">
<div class="form-check">
{{ form.require_witness }}
<label class="form-check-label" for="{{ form.require_witness.id_for_label }}">
<i class="fa fa-eye text-warning me-1"></i>Require witness
</label>
{% if form.require_witness.errors %}
<div class="invalid-feedback d-block">{{ form.require_witness.errors.0 }}</div>
{% endif %}
<div class="form-text">Signature requires a witness.</div>
</div>
</div>
</div>
<!-- Notification Settings -->
<div id="notification-settings" class="card border-secondary mb-3" style="display: none;">
<div class="card-header">
<h6 class="card-title mb-0">
<i class="fa fa-bell me-2"></i>Notification Settings
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div class="form-check mb-2">
{{ form.notify_via_email }}
<label class="form-check-label" for="{{ form.notify_via_email.id_for_label }}">
<i class="fa fa-envelope me-1"></i>Email notification
</label>
</div>
<div class="form-check mb-2">
{{ form.notify_via_sms }}
<label class="form-check-label" for="{{ form.notify_via_sms.id_for_label }}">
<i class="fa fa-mobile me-1"></i>SMS notification
</label>
</div>
</div>
<div class="col-md-6">
<div class="form-check mb-2">
{{ form.notify_via_portal }}
<label class="form-check-label" for="{{ form.notify_via_portal.id_for_label }}">
<i class="fa fa-globe me-1"></i>Patient portal notification
</label>
</div>
<div class="form-check mb-2">
{{ form.send_reminders }}
<label class="form-check-label" for="{{ form.send_reminders.id_for_label }}">
<i class="fa fa-clock me-1"></i>Send automatic reminders
</label>
</div>
</div>
</div>
</div>
</div>
<!-- Witness Information -->
<div id="witness-info" class="card border-warning mb-3" style="display: none;">
<div class="card-header bg-warning text-dark">
<h6 class="card-title mb-0">
<i class="fa fa-eye me-2"></i>Witness Information
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div class="form-floating mb-3">
{{ form.witness }}
<label for="{{ form.witness.id_for_label }}">Witness</label>
{% if form.witness.errors %}
<div class="invalid-feedback d-block">{{ form.witness.errors.0 }}</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="form-floating mb-3">
{{ form.witness_relationship }}
<label for="{{ form.witness_relationship.id_for_label }}">Witness Relationship</label>
{% if form.witness_relationship.errors %}
<div class="invalid-feedback d-block">{{ form.witness_relationship.errors.0 }}</div>
{% endif %}
</div>
</div>
</div>
<div class="mb-3">
<label for="{{ form.witness_notes.id_for_label }}" class="form-label">Witness Notes</label>
{{ form.witness_notes }}
{% if form.witness_notes.errors %}
<div class="invalid-feedback d-block">{{ form.witness_notes.errors.0 }}</div>
{% endif %}
</div>
</div>
</div>
<!-- Legal Guardian Information -->
<div id="guardian-info" class="card border-success mb-3" style="display: none;">
<div class="card-header bg-success text-white">
<h6 class="card-title mb-0">
<i class="fa fa-shield me-2"></i>Legal Guardian Information
</h6>
</div>
<div class="card-body">
<div class="alert alert-info">
<i class="fa fa-info-circle me-2"></i>
This patient is a minor or requires a legal guardian to provide consent.
</div>
<div class="row">
<div class="col-md-6">
<div class="form-floating mb-3">
{{ form.legal_guardian }}
<label for="{{ form.legal_guardian.id_for_label }}">Legal Guardian</label>
{% if form.legal_guardian.errors %}
<div class="invalid-feedback d-block">{{ form.legal_guardian.errors.0 }}</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="form-floating mb-3">
{{ form.guardian_relationship }}
<label for="{{ form.guardian_relationship.id_for_label }}">Relationship</label>
{% if form.guardian_relationship.errors %}
<div class="invalid-feedback d-block">{{ form.guardian_relationship.errors.0 }}</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
<!-- Form Actions -->
<div class="d-flex justify-content-between">
<div>
<a href="{% if object %}{% url 'patients:patient_consent_detail' object.pk %}{% else %}{% url 'patients:patient_consent_list' %}{% endif %}" class="btn btn-secondary">
<i class="fa fa-arrow-left me-2"></i>Cancel
</a>
</div>
<div>
<button type="button" class="btn btn-info me-2" onclick="saveDraft()">
<i class="fa fa-save me-2"></i>Save Draft
</button>
<button type="submit" class="btn btn-primary">
<i class="fa fa-paper-plane me-2"></i>{% if object %}Update{% else %}Send{% endif %} Request
</button>
</div>
</div>
</form>
</div>
</div>
<!-- END panel -->
</div>
<div class="col-xl-4">
<!-- BEGIN panel -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Request Guidelines</h4>
</div>
<div class="panel-body">
<div class="alert alert-info">
<h6 class="alert-heading">Best Practices</h6>
<ul class="mb-0 small">
<li>Ensure patient contact information is current</li>
<li>Select appropriate consent form for the procedure</li>
<li>Set realistic due dates for non-urgent requests</li>
<li>Include clear notes for complex procedures</li>
<li>Mark urgent only when truly necessary</li>
<li>Consider patient's preferred communication method</li>
</ul>
</div>
<div class="card border-warning mb-3">
<div class="card-header bg-warning text-dark">
<h6 class="card-title mb-0">Legal Requirements</h6>
</div>
<div class="card-body">
<ul class="list-unstyled mb-0 small">
<li><i class="fa fa-check text-success me-2"></i>Patient must be competent to consent</li>
<li><i class="fa fa-check text-success me-2"></i>Information must be clearly explained</li>
<li><i class="fa fa-check text-success me-2"></i>Patient must understand risks and benefits</li>
<li><i class="fa fa-check text-success me-2"></i>Consent must be voluntary</li>
<li><i class="fa fa-check text-success me-2"></i>Witness required for certain procedures</li>
</ul>
</div>
</div>
</div>
</div>
<!-- END panel -->
<!-- BEGIN panel -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Request Status</h4>
</div>
<div class="panel-body">
<div id="request-status">
<div class="alert alert-secondary">
<i class="fa fa-info-circle me-2"></i>
<span id="status-text">Request not sent</span>
</div>
</div>
<div class="small text-muted">
<div>Last saved: <span id="last-saved">Never</span></div>
<div>Auto-save: <span class="text-success">Enabled</span></div>
<div>Validation: <span id="validation-status" class="text-warning">Pending</span></div>
</div>
</div>
</div>
<!-- END panel -->
<!-- BEGIN panel -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">Quick Actions</h4>
</div>
<div class="panel-body">
<div class="d-grid gap-2">
<button type="button" class="btn btn-outline-primary" onclick="previewForm()">
<i class="fa fa-eye me-2"></i>Preview Form
</button>
<button type="button" class="btn btn-outline-info" onclick="checkPatientEligibility()">
<i class="fa fa-user-check me-2"></i>Check Eligibility
</button>
<button type="button" class="btn btn-outline-secondary" onclick="loadTemplate()">
<i class="fa fa-copy me-2"></i>Load Template
</button>
<button type="button" class="btn btn-outline-warning" onclick="validateRequest()">
<i class="fa fa-check-circle me-2"></i>Validate Request
</button>
</div>
</div>
</div>
<!-- END panel -->
</div>
</div>
{% endblock %}
{% block js %}
<script>
var autoSaveTimer;
$(document).ready(function() {
// Initialize form behavior
initializeFormBehavior();
// Auto-save functionality
$('#consent-request-form input, #consent-request-form select, #consent-request-form textarea').on('change input', function() {
clearTimeout(autoSaveTimer);
autoSaveTimer = setTimeout(function() {
saveDraft();
}, 5000);
});
// Form validation
$('#consent-request-form').on('submit', function(e) {
if (!validateForm()) {
e.preventDefault();
}
});
});
function initializeFormBehavior() {
// Patient selection change
$('#{{ form.patient.id_for_label }}').on('change', function() {
var patientId = $(this).val();
if (patientId) {
loadPatientInfo(patientId);
checkPatientEligibility();
} else {
$('#patient-info').hide();
$('#guardian-info').hide();
}
});
// Consent form selection change
$('#{{ form.consent_form.id_for_label }}').on('change', function() {
var formId = $(this).val();
if (formId) {
loadConsentFormInfo(formId);
} else {
$('#consent-form-info').hide();
}
});
// Notification checkbox change
$('#{{ form.send_notification.id_for_label }}').on('change', function() {
if ($(this).is(':checked')) {
$('#notification-settings').show();
} else {
$('#notification-settings').hide();
}
});
// Witness checkbox change
$('#{{ form.require_witness.id_for_label }}').on('change', function() {
if ($(this).is(':checked')) {
$('#witness-info').show();
} else {
$('#witness-info').hide();
}
});
// Initial state
if ($('#{{ form.send_notification.id_for_label }}').is(':checked')) {
$('#notification-settings').show();
}
if ($('#{{ form.require_witness.id_for_label }}').is(':checked')) {
$('#witness-info').show();
}
}
function loadPatientInfo(patientId) {
$.ajax({
url: '{% url "patients:get_patient_info" 0 %}'.replace('0', patientId),
method: 'GET',
success: function(response) {
var patient = response.patient;
$('#patient-details').html(`
<div><strong>Name:</strong> ${patient.full_name}</div>
<div><strong>Patient ID:</strong> ${patient.patient_id}</div>
<div><strong>Date of Birth:</strong> ${patient.date_of_birth}</div>
<div><strong>Age:</strong> ${patient.age} years</div>
<div><strong>Gender:</strong> ${patient.gender}</div>
`);
$('#patient-contact').html(`
<div><strong>Phone:</strong> ${patient.phone_number || 'Not provided'}</div>
<div><strong>Email:</strong> ${patient.email || 'Not provided'}</div>
<div><strong>Address:</strong> ${patient.address || 'Not provided'}</div>
<div><strong>Emergency Contact:</strong> ${patient.emergency_contact || 'Not provided'}</div>
`);
$('#patient-info').show();
// Show guardian info if patient is minor
if (patient.is_minor || patient.requires_guardian) {
$('#guardian-info').show();
} else {
$('#guardian-info').hide();
}
},
error: function() {
toastr.error('Failed to load patient information');
}
});
}
function loadConsentFormInfo(formId) {
$.ajax({
url: '{% url "patients:get_consent_form_info" 0 %}'.replace('0', formId),
method: 'GET',
success: function(response) {
var form = response.consent_form;
$('#consent-form-details').html(`
<div class="row">
<div class="col-md-6">
<div><strong>Category:</strong> <span class="badge bg-primary">${form.category}</span></div>
<div><strong>Version:</strong> <span class="badge bg-light text-dark">v${form.version}</span></div>
<div><strong>Required:</strong> ${form.is_required ? '<span class="text-danger">Yes</span>' : '<span class="text-muted">No</span>'}</div>
<div><strong>Expiration:</strong> ${form.has_expiration ? form.expiration_days + ' days' : 'No expiration'}</div>
</div>
<div class="col-md-6">
<div><strong>Description:</strong></div>
<div class="small text-muted">${form.description}</div>
<div class="mt-2"><strong>Signature Requirements:</strong></div>
<div class="small text-muted">${form.signature_requirements || 'Standard signature'}</div>
</div>
</div>
`);
$('#consent-form-info').show();
},
error: function() {
toastr.error('Failed to load consent form information');
}
});
}
function validateForm() {
var isValid = true;
var errors = [];
// Required field validation
var requiredFields = ['{{ form.patient.id_for_label }}', '{{ form.consent_form.id_for_label }}'];
requiredFields.forEach(function(fieldId) {
var field = $('#' + fieldId);
if (!field.val()) {
field.addClass('is-invalid');
errors.push(field.closest('.form-floating').find('label').text().replace(' *', '') + ' is required');
isValid = false;
} else {
field.removeClass('is-invalid');
}
});
// Due date validation
var dueDate = $('#{{ form.due_date.id_for_label }}').val();
if (dueDate) {
var today = new Date();
var due = new Date(dueDate);
if (due < today) {
$('#{{ form.due_date.id_for_label }}').addClass('is-invalid');
errors.push('Due date cannot be in the past');
isValid = false;
} else {
$('#{{ form.due_date.id_for_label }}').removeClass('is-invalid');
}
}
// Witness validation
if ($('#{{ form.require_witness.id_for_label }}').is(':checked')) {
if (!$('#{{ form.witness.id_for_label }}').val()) {
$('#{{ form.witness.id_for_label }}').addClass('is-invalid');
errors.push('Witness is required when witness is required');
isValid = false;
} else {
$('#{{ form.witness.id_for_label }}').removeClass('is-invalid');
}
}
if (!isValid) {
toastr.error('Please fix the following errors:\n' + errors.join('\n'));
$('#validation-status').text('Failed').removeClass('text-success text-warning').addClass('text-danger');
} else {
$('#validation-status').text('Passed').removeClass('text-danger text-warning').addClass('text-success');
}
return isValid;
}
function saveDraft() {
var formData = $('#consent-request-form').serialize();
$.ajax({
url: '{% url "patients:save_consent_request_draft" %}',
method: 'POST',
data: formData,
success: function(response) {
updateRequestStatus('Draft saved', 'success');
$('#last-saved').text(new Date().toLocaleTimeString());
},
error: function() {
updateRequestStatus('Failed to save draft', 'danger');
}
});
}
function updateRequestStatus(message, type) {
var alertClass = 'alert-' + type;
$('#request-status').html('<div class="alert ' + alertClass + '"><i class="fa fa-info-circle me-2"></i>' + message + '</div>');
}
function previewForm() {
var consentFormId = $('#{{ form.consent_form.id_for_label }}').val();
if (!consentFormId) {
toastr.warning('Please select a consent form first');
return;
}
window.open('{% url "patients:preview_consent_form" 0 %}'.replace('0', consentFormId), '_blank');
}
function checkPatientEligibility() {
var patientId = $('#{{ form.patient.id_for_label }}').val();
if (!patientId) {
toastr.warning('Please select a patient first');
return;
}
$.ajax({
url: '{% url "patients:check_patient_eligibility" 0 %}'.replace('0', patientId),
method: 'GET',
success: function(response) {
if (response.eligible) {
toastr.success('Patient is eligible for consent');
} else {
toastr.warning('Patient eligibility issues: ' + response.issues.join(', '));
}
},
error: function() {
toastr.error('Failed to check patient eligibility');
}
});
}
function loadTemplate() {
// Implementation for loading consent request templates
toastr.info('Template loading feature coming soon');
}
function validateRequest() {
if (validateForm()) {
toastr.success('Request validation passed');
}
}
</script>
{% endblock %}